doc/logs/2026-05-24-cli-api-parity-e2e-log.md
Full Paperclip CLI/API parity smoke pass against a disposable local source-tree instance.
/Users/aronprins/Documents/PaperclipAI/paperclip/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parityPAPERCLIP_HOME: /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/homePAPERCLIP_INSTANCE_ID: cli-api-parityPAPERCLIP_CONFIG: /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/instances/cli-api-parity/config.jsonPAPERCLIP_CONTEXT: /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/context.jsonPAPERCLIP_AUTH_STORE: /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/auth.jsonPAPERCLIP_API_URL: http://127.0.0.1:3197PAPERCLIP_SERVER_PORT: 3197PORT: 3197CODEX_HOME: /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/codex-homeCLAUDE_HOME: /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/claude-homeDATABASE_URL: unsetDATABASE_MIGRATION_URL: unset12e9db4b-f66c-459b-959e-d645002240fb0bdc6f69-733d-4b1c-b5c6-2246f9582598 (deleted from DB)1dd601a1-031a-4225-b005-419427fd059f5b2a9135-1044-48d6-a17d-6b91dd9fdc74d32032ce-d95e-4c4e-a942-dd98498025fbf0250734-95f1-4c28-9e10-f1954649fffb (CLI-1)1f7540d3-a3d3-48d2-b6c5-00d72c064e8f38b89e46-a775-43bc-a39a-c44ccd1f7f3045d843a2-9334-4dda-b53a-cd6f7e62149a (revoked)d464c3fe-c760-4c1c-b6cd-f8f0cd6c1797 (revoked)sed -n ... paperclip-localdev-runbook.md, doc/DEVELOPING.md, doc/CLI.md, doc/DATABASE.md, doc/GOAL.md, doc/PRODUCT.md, doc/SPEC-implementation.md, doc/DEPLOYMENT-MODES.md, doc/plans/2026-05-23-cli-api-parity-openapi-reference.ts3197, unset database env vars, pnpm paperclipai onboard --yes --run --bind loopback, and pre-test isolation checks.doc/bugs did not exist, so this file defines the log format.env -u DATABASE_URL -u DATABASE_MIGRATION_URL ... zsh -lc 'printf ...'; lsof -nP -iTCP:3197 -sTCP:LISTEN || true/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity; DATABASE_URL and DATABASE_MIGRATION_URL are unset; port 3197 has no listener.<unset>, and no listener was present on 3197.~/.paperclip, ~/.codex, ~/.claude, or localhost:3100.env -u DATABASE_URL -u DATABASE_MIGRATION_URL ... pnpm paperclipai onboard --yes --run --bind loopback.env, secrets key, logs, storage, and embedded DB under the scratch instance; server listens on 127.0.0.1:3197.local_trusted/private mode on 127.0.0.1:3197, with embedded PostgreSQL data at /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/instances/cli-api-parity/db.54330 after 54329 was already in use. Health URL: http://127.0.0.1:3197/api/health.pnpm paperclipai env; pnpm paperclipai context show --json; curl -sS http://127.0.0.1:3197/api/health; find tmp/cli-api-parity/home -maxdepth 4 -type d127.0.0.1:3197; DB directory is under scratch home./Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity; health returned status: ok, version 0.3.1, deploymentMode: local_trusted, companyDeletionEnabled: true.paperclipai env redacted here because it prints the generated PAPERCLIP_AGENT_JWT_SECRET. Context existed at the scratch path with an empty default profile.pnpm paperclipai context set --api-base http://127.0.0.1:3197 --use --json; pnpm paperclipai whoami --json; pnpm paperclipai company list --json; pnpm paperclipai access whoami --jsonwhoami reports the implicit local board; company list is empty; documented access whoami either works or reveals current command drift.context set --api-base wrote apiBase: http://127.0.0.1:3197; whoami returned local-board with isInstanceAdmin: true; company list returned []; access whoami failed with unknown command 'access'.whoami as a top-level command. The runbook/docs command access whoami is stale for this checkout.whoami for access checks and record the mismatch below.pnpm paperclipai company create --payload-json '{"name":"CLI API Parity Test","description":"Disposable company for CLI API parity testing","goal":"Exercise the CLI API surface end to end"}' --json; pnpm paperclipai context set --company-id 12e9db4b-f66c-459b-959e-d645002240fb --use --json; pnpm paperclipai company get 12e9db4b-f66c-459b-959e-d645002240fb --json; pnpm paperclipai company update 12e9db4b-f66c-459b-959e-d645002240fb --payload-json '{"description":"Updated by CLI API parity test","budgetMonthlyCents":12345}' --jsonapiBase and companyId.12e9db4b-f66c-459b-959e-d645002240fb. Update changed description and budgetMonthlyCents to 12345. context set --company-id unexpectedly removed the previously stored apiBase.CLI; status is active.localhost:3100.cli/src/commands/client/context.ts, cli/src/client/context.ts, and cli/src/__tests__/context.test.ts; pnpm exec vitest run cli/src/__tests__/context.test.ts; pnpm --dir cli typecheck; pnpm paperclipai context set --api-base http://127.0.0.1:3197 --company-id 12e9db4b-f66c-459b-959e-d645002240fb --use --json; pnpm paperclipai context show --json12e9db4b-f66c-459b-959e-d645002240fb.apiBase and companyId.apiBase: http://127.0.0.1:3197 and companyId: 12e9db4b-f66c-459b-959e-d645002240fb.dashboard get; goal list/create/get/update; project list/create/get/update; agent list/create/get/update/configuration; issue list/create/get/update/comment/comments/comment:get/checkout; activity list12e9db4b-f66c-459b-959e-d645002240fb; context profile with scratch apiBase; process adapter agent payload.5b2a9135-1044-48d6-a17d-6b91dd9fdc74, agent 1dd601a1-031a-4225-b005-419427fd059f, project d32032ce-d95e-4c4e-a942-dd98498025fb, issue f0250734-95f1-4c28-9e10-f1954649fffb, and comment 231fd48a-9ed2-4e72-a3dc-3b762842f57d were created/updated/read successfully. Explicit checkout of the first issue failed with 409 because assigning it at creation triggered automatic local process runs and checkout first.process adapter agent ran automatically and generated heartbeat runs. The issue later moved to blocked via recovery handling because the smoke process printed output without a concrete Paperclip disposition.issue create --status todo without assignee; issue checkout 1f7540d3-a3d3-48d2-b6c5-00d72c064e8f --agent-id 1dd601a1-031a-4225-b005-419427fd059f --expected-statuses todo --json; issue release 1f7540d3-a3d3-48d2-b6c5-00d72c064e8f --json12e9db4b-f66c-459b-959e-d645002240fb; agent 1dd601a1-031a-4225-b005-419427fd059f; project d32032ce-d95e-4c4e-a942-dd98498025fb; goal 5b2a9135-1044-48d6-a17d-6b91dd9fdc74.in_progress and assigns the agent; release moves issue to todo and clears assignee.status: in_progress with the expected agent ID; release returned status: todo with assigneeAgentId: null.1f7540d3-a3d3-48d2-b6c5-00d72c064e8f.token board create --company-id ... --name cli-parity-board --never-expires --json; token board list --json; whoami --api-key <board-token> --json; token agent create --company-id ... --agent ... --name cli-parity-agent --json; token agent list --company-id ... --agent ... --json; context set --profile cli-agent --persona agent ... --api-key-env-var-name PAPERCLIP_API_KEY --json; agent me --profile cli-agent --json; agent inbox --profile cli-agent --json; issue list --profile cli-agent --company-id ... --json; company list --profile cli-agent --json; token agent revoke ...; token board revoke ...12e9db4b-f66c-459b-959e-d645002240fb; agent 1dd601a1-031a-4225-b005-419427fd059f.whoami; agent token works for agent persona commands and company-scoped issue list; board-only command fails with clear 403; both tokens are revoked.45d843a2-9334-4dda-b53a-cd6f7e62149a was listed and whoami reported source: board_key. Agent token d464c3fe-c760-4c1c-b6cd-f8f0cd6c1797 was listed; agent me, agent inbox, and issue list succeeded; company list failed with API error 403: Board access required; both tokens were revoked and later list output showed revokedAt.board prompt --company-id ... --agent ... --title "CLI parity prompt issue" --no-wake ... --json; agent wake ... --reason "cli parity wake smoke" --payload '{"source":"cli-api-parity"}' --json; run list/get/events/log; dashboard get; activity list; cost summary; cost by-agent; finance summary; budget overview; secrets list/doctor/provider-configs; routine list; adapter list; plugin list; org get; agent-config list12e9db4b-f66c-459b-959e-d645002240fb; agent 1dd601a1-031a-4225-b005-419427fd059f.38b89e46-a775-43bc-a39a-c44ccd1f7f30; wake/run ID 7b18a3ca-9875-4bfc-b910-db31deb2c0fa; run list returned 10 recent runs; activity returned 50 rows; secrets and routines were empty; adapter list returned 13 adapters; plugin list succeeded.run log for the selected run succeeded.company export 12e9db4b-f66c-459b-959e-d645002240fb --out tmp/cli-api-parity/exports/company-package --include company,agents,projects,issues,skills --json; company import <export-dir> --target new --new-company-name "Imported Company" --yes --json; company get <imported-id> --json; company delete <imported-id> --yes --confirm <imported-id> --json; disposable goal create/delete, project create/delete, and issue create/delete; final list checks.12e9db4b-f66c-459b-959e-d645002240fb./Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/exports/company-package; import created company 0bdc6f69-733d-4b1c-b5c6-2246f9582598 named Imported Company; company delete returned ok: true; final list checks confirmed the imported company and disposable goal/project/issue were absent.{ ok: true }, so success was verified by final absence from list commands.agent pause 1dd601a1-031a-4225-b005-419427fd059f --json; agent resume 1dd601a1-031a-4225-b005-419427fd059f --json; agent get ... --json; final curl /api/health; token board list; token agent list; git status --short; targeted verification commands.1dd601a1-031a-4225-b005-419427fd059f.paused, resume returned idle, final agent status is idle; health returned status: ok; board and agent tokens show revokedAt; git status shows only the context fix and this log.127.0.0.1:3197.git status --short --branch; curl -sS http://127.0.0.1:3197/api/health; git diff --stat; pnpm exec vitest run cli/src/__tests__/context.test.ts; pnpm --dir cli typecheck127.0.0.1:3197; branch improvement/cli-api-parity.status: ok; worktree showed modifications to cli/src/__tests__/context.test.ts, cli/src/client/context.ts, cli/src/commands/client/context.ts, and new doc/bugs/; context Vitest file passed 5 tests; pnpm --dir cli typecheck passed.git add cli/src/__tests__/context.test.ts cli/src/client/context.ts cli/src/commands/client/context.ts doc/bugs/2026-05-24-cli-api-parity-e2e-log.md; git commit -m "Fix CLI context profile patching"1da21a91 created with 4 files changed.approval create/list/get/comment/request-revision/resubmit/approve/reject; issue approvals/approval:link/approval:unlink; issue read/unread/archive/unarchive; issue child:create/get; issue document:put/get/lock/unlock/revisions/restore; issue work-product:create/list/update/delete12e9db4b-f66c-459b-959e-d645002240fb; issue f0250734-95f1-4c28-9e10-f1954649fffb; project d32032ce-d95e-4c4e-a942-dd98498025fb; goal 5b2a9135-1044-48d6-a17d-6b91dd9fdc74.c7f19d1c-fcb3-4e4d-87a7-e8a248a9eb09; created/rejected approval bbcfb3ae-38f1-43b0-8f9f-0661e291f29c; linked and unlinked issue approvals successfully. Issue read/unread/archive/unarchive succeeded. Child issue 6e78d443-c9f4-46ba-9137-f1fa2b7a75c5 was created and fetched. Document create/get/lock/unlock/update/revisions/restore succeeded after supplying --base-revision-id; work product create/list/update/delete succeeded.--base-revision-id failed with API error 409: Document update requires baseRevisionId; help/source confirmed the flag exists and is required for updates.issue interaction:create; issue interaction:accept <issue-id> <interaction-id> without --selected-client-keys; edited cli/src/commands/client/issue.ts and cli/src/__tests__/issue-subresources.test.ts; pnpm exec vitest run cli/src/__tests__/issue-subresources.test.ts; pnpm --dir cli typecheckf0250734-95f1-4c28-9e10-f1954649fffb.--selected-client-keys sends no selectedClientKeys field.selectedClientKeys: [] and local validation failed with Array must contain at least 1 element(s). After the fix, the focused issue subresource test passed 4 tests and CLI typecheck passed.undefined for omitted optional CSV input while still parsing provided CSV values.issue interaction:create/accept/reject/respond/cancel; issue tree-state; issue tree-preview; issue tree-hold:create/list/get/releasef0250734-95f1-4c28-9e10-f1954649fffb.interaction:cancel only works for ask_user_questions; trying it against request_confirmation returned API error 422: Only ask_user_questions interactions can be cancelled. A corrected ask-user-question cancel succeeded. Tree hold create/list succeeded, but my script initially parsed the create response as .id; the API returns .hold.id, so the subsequent get used literal null and the server returned 500.8f07dd71-092f-4746-9b6d-27bbb086b305 was later fetched and released using the correct .hold.id/list-derived ID.interaction:cancel kind-specific UX mismatch.server/src/routes/issue-tree-control.ts and server/src/__tests__/issue-tree-control-routes.test.ts; pnpm exec vitest run server/src/__tests__/issue-tree-control-routes.test.ts; pnpm --dir server typecheck/api/issues/<issue-id>/tree-holds/null.GET /tree-holds/null and POST /tree-holds/null/release now validate UUID shape and return 400.issue tree-hold:get/release; issue attachment:upload/list/download/delete; issue label:create/list/delete; issue feedback:vote/votes/list/export; token agent create/revokef0250734-95f1-4c28-9e10-f1954649fffb; tree hold 8f07dd71-092f-4746-9b6d-27bbb086b305; company 12e9db4b-f66c-459b-959e-d645002240fb; agent 1dd601a1-031a-4225-b005-419427fd059f.cmp verified downloaded bytes. Label create/list/delete succeeded. Feedback vote against board-authored comment failed with API error 422: Feedback voting is only available on agent-authored issue comments. A retry that created an isolated temporary agent token a67f4f69-7250-43d6-9988-96e7692da605 still failed because issue comment --api-key <agent-token> did not produce an agent-authored feedback target. The temporary token was revoked immediately after the failure.a67f4f69-7250-43d6-9988-96e7692da605 is revoked.git add cli/src/__tests__/issue-subresources.test.ts cli/src/commands/client/issue.ts server/src/__tests__/issue-tree-control-routes.test.ts server/src/routes/issue-tree-control.ts doc/bugs/2026-05-24-cli-api-parity-e2e-log.md; git commit -m "Fix CLI issue subresource parity bugs"pnpm exec vitest run cli/src/__tests__/issue-subresources.test.ts; pnpm --dir cli typecheck; pnpm exec vitest run server/src/__tests__/issue-tree-control-routes.test.ts; pnpm --dir server typecheck.73997628 created with 5 files changed.token agent create; issue comment --api-key <agent-token>; issue feedback:vote; issue feedback:votes; issue feedback:list; issue feedback:export; token agent revoke; issue recovery-actions; issue recovery:resolve12e9db4b-f66c-459b-959e-d645002240fb; agent 1dd601a1-031a-4225-b005-419427fd059f; issue f0250734-95f1-4c28-9e10-f1954649fffb.token agent create output from .key.token produced agent-authored comment d4e2adbe-d94c-4d87-8205-828f3ddfa033; feedback vote 24843ebd-456d-4534-89ec-bdbc0bb02170 was saved; feedback list/export completed. Temporary token 40e683ec-758f-4964-bdef-544bee16ee5a was revoked. Recovery action 1151475f-c97f-456b-9c6a-8e0f936abe05 resolved after using --source-issue-status todo; the issue moved to todo..vote.id instead of top-level .id) stopped one script after the vote succeeded; the token was manually revoked and the remaining list/export commands were run separately.kill <paperclip pid on 3197>; pnpm paperclipai onboard --yes --run --bind loopback; curl http://127.0.0.1:3197/api/health; issue tree-hold:get <issue-id> null --json73997628.127.0.0.1:3197, using the same embedded DB path and pg port 54330; health returned status: ok; malformed hold ID now returns API error 400: Invalid hold ID.~/.paperclip, ~/.codex, or ~/.claude paths were used. The server session is currently running under the isolated environment.agent create/list/get/update/delete; agent permissions:update; agent configuration; agent config-revisions; agent config-revision:get; agent runtime-state; agent runtime-state:reset-session; agent task-sessions; agent skills; agent skills:sync; agent instructions-path:update; agent instructions-bundle; agent instructions-bundle:update; agent instructions-file:get/put/delete; agent local-cli --no-install-skills; agent approve/pause/resume/heartbeat:invoke/terminate; token agent revoke12e9db4b-f66c-459b-959e-d645002240fb; temp agent f9dfad96-6045-4b97-a548-bdc95fb22ec4.local-cli is revoked; temp agent is deleted.instructions-path:update for process adapter constraints. agent local-cli --no-install-skills created key a9bf0b28-8217-4c60-829c-cb1962203a21, which was revoked. agent heartbeat:invoke passed. Temp agent f9dfad96-6045-4b97-a548-bdc95fb22ec4 was terminated and deleted. A final key list for the main agent showed no unrevoked keys.instructions-path:update attempt without adapterConfigKey failed with No default instructions path key for adapter type 'process'. Provide adapterConfigKey. A second relative-path attempt with adapterConfigKey failed because process adapters without cwd require an absolute path. The successful pass used adapterConfigKey: instructionsFilePath and an absolute scratch path.cost event:create; cost summary; cost by-agent; cost by-agent-model; cost by-provider; cost by-biller; cost by-project; cost window-spend; cost quota-windows; cost issue; finance event:create; finance events; finance summary; finance by-biller; finance by-kind; budget overview; budget policy:upsert; budget company:update; budget agent:update12e9db4b-f66c-459b-959e-d645002240fb; agent 1dd601a1-031a-4225-b005-419427fd059f; issue f0250734-95f1-4c28-9e10-f1954649fffb; project d32032ce-d95e-4c4e-a942-dd98498025fb; goal 5b2a9135-1044-48d6-a17d-6b91dd9fdc74.63d757ae-a7f4-40e1-8ee8-e7d3174be1a4 and finance event bd38c196-7598-4591-8750-f992d4d9babf were created. All listed cost/finance read commands succeeded. Budget policy upsert succeeded. Company budget was changed to 23456 then restored to 12345; agent budget was changed to 4321 then restored to 0.budget incident:resolve was not run because no budget incident was created by this safe smoke path.whoami; auth whoami; profile session/get/update/company-user; invite create/list/show/onboarding/onboarding:text/skills:index/skill/logo/revoke; join list/reject; member list/user-directory/update/permissions/role-and-grants/archive; admin user list/company-access/company-access:update; instance scheduler-heartbeats/settings:general/settings:general:update/settings:experimental/settings:experimental:update/database-backup; sidebar preferences/preferences:update/project-preferences/project-preferences:update/badges; inbox dismissals/dismiss; auth challenge create/get/cancel/approve; auth logout12e9db4b-f66c-459b-959e-d645002240fb; member 373f91e2-a433-46ee-8362-e61ab5e06593; user local-board; project d32032ce-d95e-4c4e-a942-dd98498025fb; approval c7f19d1c-fcb3-4e4d-87a7-e8a248a9eb09.Board. Disposable invite b3317c94-4e46-4ceb-9a5f-6df179c4f77e was created, inspected through show/onboarding/onboarding text/skills index/skill, then revoked. invite logo was treated as optional because the company has no logo. Join list passed; two disposable pending join requests were rejected during cleanup. Member list/user-directory/update/permissions/role-and-grants passed; self archive returned expected 403: You cannot remove yourself. Admin user list/company-access/company-access:update passed with the same company ID. Instance settings read/no-op update and database backup passed. Sidebar preferences/project preferences/badges and inbox dismissal passed. Auth challenge cancel a52af778-39c1-41a4-8f87-46fd7b100d16 and approve 70b51e40-e6d4-4e01-ae5d-16734897375e passed. auth logout completed safely against the isolated auth store.invite test-resolution failed because the CLI does not provide the API-required url query. join approve on a disposable agent join request failed with 409: Join request cannot be approved because this company has no active CEO; the request was rejected afterward.openapi; available-skill list; available-skill index; available-skill get cmux; llm agent-configuration; llm agent-icons; llm agent-configuration:adapter process127.0.0.1:3197.available-skill list and available-skill index passed. openapi returned API error 404: API route not found. available-skill get cmux returned API error 404: Skill not found even though cmux was returned by available-skill list. llm agent-configuration, llm agent-icons, and llm agent-configuration:adapter process returned API error 404: API route not found.curl -sf http://127.0.0.1:3197/api/health; pnpm paperclipai health --json; pnpm paperclipai adapter list/get/config-schema/ui-parser/models/model-profiles/detect-model/test-environment ... --json; pnpm paperclipai environment list/capabilities/probe-config/create ... --json; pnpm paperclipai project-workspace create/list/update/delete ... --json; pnpm paperclipai workspace list --company-id ... --json; pnpm paperclipai plugin list/examples/ui-contributions/tools/init ... --json12e9db4b-f66c-459b-959e-d645002240fb; project d32032ce-d95e-4c4e-a942-dd98498025fb; isolated API http://127.0.0.1:3197.paperclipai health is not registered. Adapter list/get/model commands passed for process; process config schema and UI parser returned expected unsupported 404s. adapter test-environment process returned a structured failure because no process command was supplied. Environment list/capabilities/probe-config passed, but creating a second local environment returned a 500 due to the unique environments_company_driver_idx constraint. Project workspace create/list passed; the first update/delete attempt failed because my shell ID extraction broke, then the workspace was recovered from project-workspace list and deleted successfully with project-workspace delete d32032ce-d95e-4c4e-a942-dd98498025fb e271b6bc-368e-4a89-9824-d9e2b2bedb66 --json. Workspace list passed. Plugin list/examples/ui-contributions/tools passed; plugin init scaffolded a disposable plugin under tmp/cli-api-parity/artifacts/cli-parity-plugin.MISMATCH-008 and BUG-004. No external plugin install was attempted; no built-in adapter delete/reinstall was attempted.pnpm paperclipai asset image:upload --company-id <company-id> --file doc/assets/avatars/zinc.png --namespace cli-parity --alt ... --title ... --json; pnpm paperclipai asset content <asset-id> --out tmp/cli-api-parity/artifacts/asset-download.png --json; pnpm paperclipai asset logo:upload --company-id <company-id> --file ui/public/favicon-32x32.png --json; pnpm paperclipai skill list/create/get/file/file:update/update-status/install-update/delete/scan-projects ... --json12e9db4b-f66c-459b-959e-d645002240fb; image asset 829fbd86-cd5c-4aaa-ad17-276faac7888b; logo asset 1b3e7979-1359-4361-b3f5-c8a845e11659; temporary skill 126ad416-864b-4136-8f48-f5adcf324f20.assetId and content download wrote 27949 bytes. Logo upload returned assetId. Skill list/create/get/file/file:update/update-status/delete/scan-projects passed. skill install-update returned 422: Only GitHub-managed skills support update checks, matching the preceding update-status supported: false result.pnpm exec vitest run server/src/__tests__/environment-routes.test.ts; pnpm --dir server typecheckBUG-004 reproduction from isolated E2E.local environment conflict check and regression coverage.env -u DATABASE_URL -u DATABASE_MIGRATION_URL ... pnpm paperclipai environment create --company-id 12e9db4b-f66c-459b-959e-d645002240fb --payload-json '{"name":"CLI parity local env","description":"Disposable CLI parity environment","driver":"local","config":{"cwd":"/Users/aronprins/Documents/PaperclipAI/paperclip"}}' --jsonBUG-004 against the restarted isolated source-tree server.pnpm paperclipai onboard --yes --run --bind loopback; company 12e9db4b-f66c-459b-959e-d645002240fb.API error 409: A local environment already exists for this company.pnpm paperclipai environment create/get/leases/probe/update/delete ... --json; pnpm paperclipai plugin install/list/inspect/health/config/jobs/local-folders/ui-contributions/disable/enable/uninstall ... --json; pnpm paperclipai secrets list/create/link/declarations/migrate-inline-env ... --json12e9db4b-f66c-459b-959e-d645002240fb; bundled plugin path /Users/aronprins/Documents/PaperclipAI/paperclip/packages/plugins/plugin-workspace-diff; temporary SSH environment cc5ae311-13f5-42b8-8044-11065b4e1af0; temporary plugin install e8421ed5-c103-4950-afb7-1463a0fbb9c5; temporary secret 20c74546-7bec-4766-80cd-0b6c57545f7d.ok: false with connection refused, as expected on this host. Plugin install/list/inspect/health/config/jobs/local-folders/ui-contributions/disable/enable/uninstall passed; final plugin list returned []. Secret create/list/declarations/migrate-inline-env dry-run passed. secrets link --provider local_encrypted --external-ref ... returned 400: local_encrypted does not support external reference secrets, which is expected provider behavior. The batch exposed missing CLI wrappers for secret update/rotate/usage/access-events/delete.BUG-005. Plugin was uninstalled; SSH environment was deleted; one managed secret remained briefly for lifecycle verification.pnpm exec vitest run cli/src/__tests__/secrets.test.ts; pnpm --dir cli typecheckBUG-005 parity gap from OpenAPI reference and E2E.PATCH /api/secrets/:id, POST /api/secrets/:id/rotate, GET /api/secrets/:id/usage, GET /api/secrets/:id/access-events, and DELETE /api/secrets/:id.--yes --confirm <secret-id>.pnpm paperclipai secrets update 20c74546-7bec-4766-80cd-0b6c57545f7d --payload-json ... --json; pnpm paperclipai secrets rotate 20c74546-7bec-4766-80cd-0b6c57545f7d --value ... --json; pnpm paperclipai secrets usage 20c74546-7bec-4766-80cd-0b6c57545f7d --json; pnpm paperclipai secrets access-events 20c74546-7bec-4766-80cd-0b6c57545f7d --json; pnpm paperclipai secrets delete 20c74546-7bec-4766-80cd-0b6c57545f7d --yes --confirm 20c74546-7bec-4766-80cd-0b6c57545f7d --json; pnpm paperclipai secrets list --company-id 12e9db4b-f66c-459b-959e-d645002240fb --json20c74546-7bec-4766-80cd-0b6c57545f7d.[], delete returned { "ok": true }, and final list returned [].pnpm exec vitest run cli/src/__tests__/access-parity.test.ts cli/src/__tests__/issue-subresources.test.ts; pnpm --dir cli typecheckMISMATCH-001, MISMATCH-002, MISMATCH-003, MISMATCH-005, MISMATCH-006, and MISMATCH-008.paperclipai health exists; paperclipai access whoami works; invite test-resolution has a URL option; join list --status pending maps to pending_approval; issue help text no longer overstates valid cancel/recovery inputs.access whoami alias, invite test-resolution --url, pending status normalization, and more precise issue command descriptions.pnpm paperclipai health --json; pnpm paperclipai access whoami --json; pnpm paperclipai join list --company-id 12e9db4b-f66c-459b-959e-d645002240fb --status pending --request-type agent --json; pnpm paperclipai invite create --company-id 12e9db4b-f66c-459b-959e-d645002240fb --payload-json '{}' --json; pnpm paperclipai invite test-resolution <token> --url https://example.com/invite/<token> --json; pnpm paperclipai invite revoke <invite-id> --json; pnpm paperclipai issue recovery:resolve --help; pnpm paperclipai issue interaction:cancel --help12e9db4b-f66c-459b-959e-d645002240fb; disposable invite 57d7fb29-e29e-4327-9d11-7be325831da6 revoked after test. A first test-resolution attempt against http://127.0.0.1:3197/... intentionally hit the server's private-address guard and was replaced with a public HTTPS URL.health, access whoami, and join list --status pending passed. Public invite resolution returned status: reachable, method HEAD, HTTP 404 from example.com, proving the command now supplies the URL. Invite was revoked. Help output includes todo, done, or in_review for restored outcomes; blocked is only valid for blocked outcomes and Cancel an ask_user_questions issue thread interaction.pnpm exec vitest run server/src/__tests__/llms-routes.test.ts cli/src/__tests__/access-parity.test.ts; pnpm --dir server typecheck; pnpm --dir cli typecheckMISMATCH-007 that was straightforward and isolation-sensitive.CLAUDE_HOME=/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/claude-home.~/.claude/skills when CLAUDE_HOME is set.llmRoutes under /api in addition to the existing root mount. Updated available-skill discovery to read CLAUDE_HOME/skills when configured, include built-in Paperclip repo skills in available-skill list, and allow available-skill get for safe listed/built-in skill names.pnpm paperclipai llm agent-configuration --json; pnpm paperclipai llm agent-icons --json; pnpm paperclipai llm agent-configuration:adapter process --json; pnpm paperclipai available-skill list --json; pnpm paperclipai available-skill get paperclip --json; pnpm paperclipai available-skill get cmux --json; pnpm paperclipai openapi --json~/.claude skills are not listed; openapi still documents the unresolved gap if no route exists.available-skill list returned Paperclip repo skills such as diagnose-why-work-stopped; available-skill get paperclip returned markdown. available-skill get cmux now returns 404 because cmux is no longer listed from the real Claude home. openapi still returns 404: API route not found.MISMATCH-007; GET /api/openapi.json remains unresolved.pnpm paperclipai health --json; pnpm paperclipai token board list --json; pnpm paperclipai token board revoke <redacted-board-token-id> --json; pnpm paperclipai token agent list --company-id 12e9db4b-f66c-459b-959e-d645002240fb --agent 1dd601a1-031a-4225-b005-419427fd059f --json; pnpm paperclipai plugin list --json; pnpm paperclipai secrets list --company-id 12e9db4b-f66c-459b-959e-d645002240fb --json; pnpm paperclipai environment list --company-id 12e9db4b-f66c-459b-959e-d645002240fb --json; pnpm paperclipai project-workspace list d32032ce-d95e-4c4e-a942-dd98498025fb --json; pnpm paperclipai openapi --json<redacted-board-token-id>; main agent 1dd601a1-031a-4225-b005-419427fd059f.tmp/cli-api-parity; database env vars remain unset; health passes; no active disposable tokens, plugins, secrets, project workspaces, or non-default environments remain; OpenAPI still fails as the documented unresolved gap.DATABASE_URL/DATABASE_MIGRATION_URL as unset. Health passed. Board token list found one active key (<redacted-board-token-id>) from the earlier board-token test, which was revoked. Agent token list showed only revoked keys. Plugin list and secrets list returned empty arrays. Environment list contains the default local environment only. Project workspace list returned empty. openapi still returned 404: API route not found.http://127.0.0.1:3197.openapi as unfixed and explain that implementing it needs a real OpenAPI generator/route rather than a small CLI wrapper correction.pnpm paperclipai doctor --config <scratch-config>; pnpm paperclipai doctor --config <scratch-config> --repair --yes; pnpm paperclipai env --config <scratch-config>; pnpm paperclipai db:backup --config <scratch-config> --dir tmp/cli-api-parity/artifacts/root-setup/backups --retention-days 1 --filename-prefix cli-parity --json; pnpm paperclipai allowed-hostname cli-parity.test --config <scratch-config>; pnpm paperclipai auth bootstrap-ceo --config <scratch-config> --force --base-url http://127.0.0.1:3197; pnpm paperclipai auth whoami --json; pnpm paperclipai routines disable-all --config <scratch-config> --company-id 12e9db4b-f66c-459b-959e-d645002240fb --json; pnpm paperclipai env-lab doctor --instance cli-api-parity --json; pnpm paperclipai env-lab status --instance cli-api-parity --json/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/instances/cli-api-parity/config.json; company 12e9db4b-f66c-459b-959e-d645002240fb.local_trusted; routines disable-all is harmless with no routines; env-lab reports host capability/status without starting services.doctor and doctor --repair --yes completed. env printed scratch deployment variables; the generated agent JWT secret is not copied here. db:backup created a one-off backup under tmp/cli-api-parity/artifacts/root-setup/backups. allowed-hostname added cli-parity.test to the scratch config and noted a restart is required for it to take effect. auth bootstrap-ceo correctly reported that bootstrap CEO invites are only required in authenticated mode. auth whoami returned the local implicit board identity. routines disable-all reported zero routines. env-lab doctor reported SSH env-lab is disabled on macOS unless explicitly opted in, and env-lab status reported no running fixture.tmp/cli-api-parity/artifacts/root-setup contain command output from the disposable instance.PAPERCLIP_WORKTREES_DIR=tmp/cli-api-parity/worktrees-home pnpm paperclipai worktree:list --json; pnpm paperclipai worktree env --config <scratch-config> --json; pnpm paperclipai worktree:merge-history --from current --to current --company CLI --dry; pnpm paperclipai cloud push --company 12e9db4b-f66c-459b-959e-d645002240fb --dry-run --json/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/instances/cli-api-parity/config.json; scratch worktree root /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/worktrees-home; company 12e9db4b-f66c-459b-959e-d645002240fb.worktree:list passed and showed the current repo branch improvement/cli-api-parity with no Paperclip worktree config. worktree env --config <scratch-config> --json passed and printed the scratch PAPERCLIP_CONFIG plus generated env values; the generated JWT secret is intentionally not copied into this log. worktree:merge-history --from current --to current --company CLI --dry failed as expected with Source and target Paperclip configs are the same. Choose different --from/--to worktrees. cloud push --dry-run failed as expected with Cloud sync is disabled. Enable the cloud sync experimental setting before running paperclipai cloud push.HOME=tmp/cli-api-parity/shell-home PAPERCLIP_WORKTREES_DIR=tmp/cli-api-parity/worktree-instances pnpm paperclipai worktree:make cli-parity-wt --home <scratch-worktree-home> --from-config <scratch-config> --server-port 3198 --db-port 54331 --seed-mode minimal; pkill only for the runaway scratch install attempt; edited cli/src/commands/worktree.ts and cli/src/__tests__/worktree.test.ts; pnpm exec vitest run cli/src/__tests__/worktree.test.ts; pnpm --dir cli typecheck; paperclipai worktree:cleanup cli-parity-wt --home <scratch-worktree-home> --force; reran paperclipai worktree:make ...; paperclipai worktree:list --json; paperclipai worktree env --config <scratch-worktree-config> --json; paperclipai worktree:merge-history --from paperclip-cli-parity-wt --to current --company CLI --dryHOME /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/shell-home; scratch worktree instance home /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/worktree-instances; source config /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/instances/cli-api-parity/config.json; worktree branch/path paperclip-cli-parity-wt.worktree:make creates /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/shell-home/paperclip-cli-parity-wt, installs dependencies once, writes repo-local .paperclip/config.json and .paperclip/.env, seeds a minimal isolated DB on ports 3198/54331, and leaves normal worktree:list, worktree env, and worktree:merge-history --dry usable.HOME was overridden. After the fix, focused worktree tests and CLI typecheck passed. worktree:cleanup --force removed the partial scratch branch/worktree. The rerun completed successfully: dependencies installed, minimal DB seed succeeded, repo config/env were written under the scratch worktree, instance data was written under scratch worktree home, worktree:list showed the new worktree with hasPaperclipConfig: true, worktree env --json printed the scratch worktree env, and worktree:merge-history --dry previewed zero inserts with existing company history already present. The generated worktree JWT secret is intentionally not copied here./Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/shell-home/paperclip-cli-parity-wt; its isolated config is /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/shell-home/paperclip-cli-parity-wt/.paperclip/config.json.token agent create --company-id 12e9db4b-f66c-459b-959e-d645002240fb --agent 1dd601a1-031a-4225-b005-419427fd059f --name cli-agent-prompt-smoke --json; agent-prompt 1dd601a1-031a-4225-b005-419427fd059f <agent-token> "CLI parity agent-prompt smoke without wake" --title "CLI parity agent-prompt smoke" --no-wake --json; token agent revoke <key-id> --company-id ... --agent ... --json; heartbeat run --agent-id 1dd601a1-031a-4225-b005-419427fd059f --source on_demand --trigger manual --timeout-ms 5000 --json; feedback report/export/trace/bundle; company feedback:list; board-claim show invalid-claim-token --json; board-claim claim invalid-claim-token --payload-json '{}' --json; openclaw invite-prompt --company-id ... --payload-json '{"goal":"CLI parity OpenClaw invite prompt smoke"}' --json; configure --config <scratch-config> --section invalid-section12e9db4b-f66c-459b-959e-d645002240fb; agent 1dd601a1-031a-4225-b005-419427fd059f; feedback trace 6193ff3a-55d3-4c01-bfbf-78e82ed55793; temporary agent token stored only under scratch artifacts and revoked after use.agent-prompt creates or updates work through an agent token and no-wake path; heartbeat run returns a bounded on-demand invocation result; feedback report/export/trace/bundle can read the existing feedback trace; invalid board claim calls fail with controlled user-facing errors; OpenClaw invite prompt returns prompt data; invalid configure section should fail non-zero.agent-prompt attempts failed with 401 because the test script passed the wrong token field (.key object / empty shell variable) instead of .key.token. Retrying with .key.token passed and the token was revoked. heartbeat run completed within the timeout. Feedback report/export and trace/bundle passed using the existing trace. board-claim show returned expected 404: Board claim challenge not found; board-claim claim returned expected 400: Claim code is required. OpenClaw invite prompt passed. configure --section invalid-section initially printed an error but exited 0, exposing BUG-008; after the fix, it exits 1.local_trusted.tmp/cli-api-parity/artifacts/agent-prompt-token*.json; the token was revoked. Feedback artifacts are under tmp/cli-api-parity/artifacts/feedback-*. No real home state was used.connect and positive board-claim flows are interactive/bootstrap-token dependent and may remain documented as gated if no disposable token source is available.http://127.0.0.1:3199; instance settings:experimental:update --payload-json '{"enableCloudSync":true}' --json; cloud connect http://127.0.0.1:3199 --no-browser --json; cloud push --company 12e9db4b-f66c-459b-959e-d645002240fb --remote-url http://127.0.0.1:3199 --dry-run --json; run live --company-id ... --limit 5 --min-count 1 --json; run issues 9c686a91-c88a-47aa-9326-a889c4281d2b --json; run workspace-operations 9c686a91-c88a-47aa-9326-a889c4281d2b --json; run workspace-log 00000000-0000-4000-8000-000000000000 --json; run cancel 9c686a91-c88a-47aa-9326-a889c4281d2b --json; run watchdog-decision 9c686a91-c88a-47aa-9326-a889c4281d2b --decision continue --reason "CLI parity watchdog decision smoke" --json; connect --persona board --api-base http://127.0.0.1:3197 --profile cli-connect-smoke --context <scratch-context> --jsonconnect behavior in the non-interactive test runner.3199; company 12e9db4b-f66c-459b-959e-d645002240fb; heartbeat run 9c686a91-c88a-47aa-9326-a889c4281d2b created by heartbeat run; scratch context and config paths.cloud connect stores a fake upstream connection under scratch PAPERCLIP_HOME; cloud push --dry-run exports local company data and posts a preview bundle to the fake upstream; run read/control commands return structured results or controlled 404 for a nonexistent workspace operation; connect refuses non-interactive execution with guidance.enableCloudSync was enabled in the scratch instance. cloud connect --no-browser completed against the fake upstream and stored a fake connection. cloud push --dry-run returned a fake preview response with summary {create:0, update:0, adopt:0, skip:1, conflict:0, staleMapping:0}. run live, run issues, and run workspace-operations passed; workspace operations returned an empty list. run workspace-log on a sentinel ID returned expected 404: Workspace operation not found. run cancel on the already completed run returned the run unchanged with status succeeded. run watchdog-decision created a watchdog decision record. connect returned expected non-interactive error: use --api-base/--api-key or context/token commands for scripts.tmp/cli-api-parity/artifacts/cloud-*. The fake cloud token is synthetic and stored only in scratch Paperclip home. connect remains intentionally interactive; scriptable equivalent coverage is via context set, token commands, whoami, and agent/board prompt flows already tested.127.0.0.1:3197.routine create --company-id 12e9db4b-f66c-459b-959e-d645002240fb --payload-json '{"title":"CLI parity routine smoke",...}' --json; routine list; routine get 8254ead3-7edd-43fc-97ca-cb3f477cefc9; routine update; routine revisions; routine runs; routine trigger:create <routine-id> for API and webhook triggers; routine trigger:update <api-trigger-id>; routine trigger:rotate-secret <api-trigger-id>; routine trigger:rotate-secret <webhook-trigger-id>; routine trigger:fire <webhook-public-id>; routine run <routine-id> without and then with assigneeAgentId; routine trigger:delete for both triggers; final routine update <routine-id> --payload-json '{"status":"archived"}'12e9db4b-f66c-459b-959e-d645002240fb; agent 1dd601a1-031a-4225-b005-419427fd059f; routine 8254ead3-7edd-43fc-97ca-cb3f477cefc9.trigger:rotate-secret on the API trigger returned expected 422: Only webhook triggers can rotate secrets; webhook trigger create and rotate passed. trigger:fire on the disabled webhook returned expected 409: Routine trigger is not active. routine run without assignee returned expected 422: Default agent required; rerun with assigneeAgentId passed and produced one routine run. Both triggers were deleted and the routine was archived.tmp/cli-api-parity/artifacts/routine. No active routine/trigger from this batch remains; the disposable routine is archived.token agent list --company-id 12e9db4b-f66c-459b-959e-d645002240fb --agent 1dd601a1-031a-4225-b005-419427fd059f --json; edited cli/src/commands/client/token.ts and cli/src/__tests__/token.test.ts; pnpm exec vitest run cli/src/__tests__/token.test.ts; pnpm --dir cli typecheck; reran the same live token agent list command.--agent <agent-id> shape during final cleanup.12e9db4b-f66c-459b-959e-d645002240fb; agent 1dd601a1-031a-4225-b005-419427fd059f.404: Agent not found for the agent ID, while agent list showed the agent exists and using --agent "Parity Worker" worked. After BUG-009 fix, the same ID-based command passed and showed no active unrevoked agent keys.tmp/cli-api-parity/artifacts/final-agent-tokens-by-id.json.health --json; token board list --json; token agent list --company-id 12e9db4b-f66c-459b-959e-d645002240fb --agent 1dd601a1-031a-4225-b005-419427fd059f --json; routine list --company-id ... --json; plugin list --json; openapi --json; git status --short --branch; lsof -nP -iTCP:3197 -sTCP:LISTEN; lsof -nP -iTCP:3199 -sTCP:LISTEN127.0.0.1:3197; fake cloud port 3199 is stopped; no active board or agent tokens from the test remain; plugin list is empty; disposable routine is archived; openapi remains the one documented unresolved API route gap.status: ok; process 11566 is listening on 127.0.0.1:3197; no process is listening on 3199; final board token list has 2 revoked keys and no active keys; final agent token list has 4 revoked keys and no active keys; plugin list is empty; routine list contains the archived disposable routine and no active routines; openapi --json still returns 404: API route not found; git status was clean before this final log update.tmp/cli-api-parity/artifacts/final-*.openapi --json as not fixed because the OpenAPI branch/generator has not been integrated into this repo.server/src/routes/openapi.ts from the route inventory in doc/plans/2026-05-23-cli-api-parity-openapi-reference.ts; mounted openApiRoutes() under /api; added server/src/__tests__/openapi-routes.test.ts; ran pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts; pnpm --dir server typecheck; restarted the isolated runbook server with the scratch environment; curl -fsS http://127.0.0.1:3197/api/openapi.json | jq '{openapi, pathCount:(.paths|keys|length)}'; pnpm --silent paperclipai openapi --json > tmp/cli-api-parity/artifacts/openapi-live-after-fix.json.openapi CLI/API parity gap without introducing a new generator dependency during the live parity run.http://127.0.0.1:3197, and local source-tree install./api/openapi.json and paperclipai openapi --json return a valid OpenAPI 3.0 document with the reference route inventory, including representative CLI/API parity paths such as /api/companies/{companyId}/agents and /api/agents/{id}/keys.server typecheck passed. After restart, direct curl returned {"openapi":"3.0.0","pathCount":247}. The CLI command returned openapi: "3.0.0", title Paperclip API, 247 paths, /api/openapi.json summary Get the generated OpenAPI document, and /api/agents/{id}/keys POST summary Create an agent API key.tmp/cli-api-parity/artifacts/openapi-live-after-fix.json. The route exposes operation inventory, tags, summaries, and standard responses from the parity reference; it intentionally does not yet include full request/response schemas.cli/src/commands/client/agent.ts; ran pnpm exec vitest run cli/src/__tests__/agent-lifecycle.test.ts; pnpm --dir cli typecheck; pnpm --silent paperclipai agent instructions-path:update --help.adapterConfigKey, relative paths require adapterConfig.cwd, and the JSON payload option includes a concrete example.adapterConfig.cwd requirement, and example payload {"path":"/tmp/AGENTS.md","adapterConfigKey":"instructionsFilePath"}.company stats; disposable company create; company branding:update; company archive; company delete; company export:preview; company export:api; company import:preview; company import:apply; cleanup company delete; skill import; cleanup skill delete.skill import not explicitly exercised in earlier batches.12e9db4b-f66c-459b-959e-d645002240fb; disposable archive company 342c1b91-0f48-4a63-a9c5-fc7ffc758483; raw-import company dab6758c-dd30-4066-87f0-4df76bd21ea5; imported skill be9538e4-9827-426f-b82a-4228c5d3f851.{"include":["company"]} returned expected API validation include object error, so the test was adapted to raw API shape {"include":{"company":true}}; export preview and export API then passed. Full exported package import via a shell variable was abandoned because markdown code fences in the large JSON payload caused shell transport issues; a minimal inline company package was used instead, and raw import preview/apply/delete passed. skill import imported one local skill and cleanup delete passed.tmp/cli-api-parity/artifacts/residual-company-skill. No disposable company or imported skill from this batch remains active.plugin list/inspect/health/logs/config/jobs/job:runs/job:trigger/webhook/dashboard/bridge:data/data/action/local-folders/upgrade/disable/enable/uninstall; initial plugin config:test/config:set/bridge:action/tool:execute/local-folder:* attempts; corrected config:test, config:set, and bridge:action; final uninstall.packages/plugins/examples/plugin-kitchen-sink-example; company 12e9db4b-f66c-459b-959e-d645002240fb; project d32032ce-d95e-4c4e-a942-dd98498025fb; agent 1dd601a1-031a-4225-b005-419427fd059f; run 9c686a91-c88a-47aa-9326-a889c4281d2b.{"configJson":{...}}; bridge action initially failed until payload used key instead of action. bridge:stream returned expected Plugin stream bridge is not enabled. Local-folder calls returned expected validation because the kitchen-sink manifest declares no local folders. plugin tools listed paperclip-kitchen-sink-example:echo, but plugin tool:execute returned 502: worker for plugin "paperclip-kitchen-sink-example" is not running even though bridge calls to the same plugin worker succeeded.plugin tool:execute, recorded as BUG-010.tmp/cli-api-parity/artifacts/residual-plugin and tmp/cli-api-parity/artifacts/residual-plugin-corrected. The kitchen-sink plugin was uninstalled after each batch.plugin tool:execute live.server/src/services/plugin-tool-dispatcher.ts, server/src/services/plugin-loader.ts, and server/src/__tests__/plugin-database.test.ts; ran pnpm exec vitest run server/src/__tests__/plugin-database.test.ts; pnpm --dir server typecheck; restarted the isolated server; installed kitchen-sink plugin; plugin tools; plugin tool:execute --payload-json '{"tool":"paperclip-kitchen-sink-example:echo",...}'; cleanup plugin uninstall --force.paperclip-kitchen-sink-example:echo.plugin tools listed paperclip-kitchen-sink-example:echo; plugin tool:execute returned content: "CLI parity tool after fix" and the expected run context. The plugin was uninstalled and plugin list returned [].tmp/cli-api-parity/artifacts/residual-plugin-after-fix.156c6074-37b7-4f8e-8619-a62027c2147e; inspected routine trigger secret handling; edited server/src/services/routines.ts and server/src/__tests__/routines-service.test.ts; ran pnpm exec vitest run server/src/__tests__/routines-service.test.ts; pnpm --dir server typecheck; restarted isolated server; deleted the older leaked disposable secret; created temporary routine 60ac06c9-f8c4-4cb1-b9fd-ae52163eb3e6; created webhook trigger 02838bc3-5b48-4f1e-aad0-ca63a48b926b; deleted the trigger; verified secret 140c2608-0d8e-4f1e-aad0-ca63a48b926b was absent from secrets list; archived the temporary routine.12e9db4b-f66c-459b-959e-d645002240fb; scratch server restarted with the patched code.secrets list returned 0 rows. The older leaked disposable secret was deleted through the CLI.tmp/cli-api-parity/artifacts/routine-secret-cleanup-fix.health --json; openapi --json; token board list --json; token agent list --company-id 12e9db4b-f66c-459b-959e-d645002240fb --agent 1dd601a1-031a-4225-b005-419427fd059f --json; plugin list --json; routine list --company-id ... --json; secrets list --company-id ... --json; environment list --company-id ... --json; project-workspace list d32032ce-d95e-4c4e-a942-dd98498025fb --json; git status --short --branch; lsof -nP -iTCP:3197 -sTCP:LISTEN; lsof -nP -iTCP:3199 -sTCP:LISTEN; environment echo for required isolation variables and unset database variables.tmp/cli-api-parity; DATABASE_URL and DATABASE_MIGRATION_URL are unset; no active board/agent tokens, plugins, secrets, non-default environments, project workspaces, or active routines remain; only the scratch server listens on 127.0.0.1:3197; fake cloud port 3199 is stopped; git is clean before this final log update.{health:"ok", openapi:"3.0.0", pathCount:247, activeBoardTokens:0, activeAgentTokens:0, plugins:0, routines:2, activeRoutines:0, secrets:0, environments:1, projectWorkspaces:0}. PAPERCLIP_HOME, PAPERCLIP_CONFIG, PAPERCLIP_CONTEXT, PAPERCLIP_AUTH_STORE, CODEX_HOME, and CLAUDE_HOME all point under the scratch path. DATABASE_URL and DATABASE_MIGRATION_URL were UNSET. node PID 70429 is listening on 127.0.0.1:3197; no process is listening on 3199; git status was clean before this log update.tmp/cli-api-parity/artifacts/final-clean-sweep.http://127.0.0.1:3197; company 12e9db4b-f66c-459b-959e-d645002240fb; agent 1dd601a1-031a-4225-b005-419427fd059f; final clean sweep artifacts under tmp/cli-api-parity/artifacts/final-clean-sweep.http://127.0.0.1:3197, and goal usage was 2,625,855 tokens over about 2h 23m.{
"health": "ok",
"openapi": "3.0.0",
"pathCount": 247,
"activeBoardTokens": 0,
"activeAgentTokens": 0,
"plugins": 0,
"routines": 2,
"activeRoutines": 0,
"secrets": 0,
"environments": 1,
"projectWorkspaces": 0
}
/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/instances/cli-api-parity/config.json/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/context.json/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/auth.json/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/instances/cli-api-parity/db, active on pg port 54330http://127.0.0.1:3197doc/bugs/2026-05-24-cli-api-parity-e2e-log.md01579595 Log final CLI parity sweepce16de70 Clean up routine webhook secrets1de4174f Fix plugin tool worker lookupec3cb727 Clarify instructions path CLI helpc811bf07 Add OpenAPI CLI routeconnect was initially not run because the CLI intentionally rejects non-TTY use; this was resolved in the follow-up with prompt-driven board and agent persona command tests plus the already covered scriptable auth/context/token flows.board-claim claim was initially not run because the live scratch server was local_trusted; this was resolved in the follow-up with an isolated authenticated-mode service test.pnpm exec vitest run server/src/__tests__/openapi-routes.test.tspnpm exec vitest run cli/src/__tests__/agent-lifecycle.test.tspnpm exec vitest run server/src/__tests__/plugin-database.test.tspnpm exec vitest run server/src/__tests__/routines-service.test.tspnpm --dir cli typecheckpnpm --dir server typecheckexport PAPERCLIP_HOME=/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home
export PAPERCLIP_INSTANCE_ID=cli-api-parity
export PAPERCLIP_CONFIG=/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/instances/cli-api-parity/config.json
export PAPERCLIP_CONTEXT=/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/context.json
export PAPERCLIP_AUTH_STORE=/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/auth.json
export PAPERCLIP_API_URL=http://127.0.0.1:3197
export PAPERCLIP_SERVER_PORT=3197
export PORT=3197
export CODEX_HOME=/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/codex-home
export CLAUDE_HOME=/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/claude-home
unset DATABASE_URL DATABASE_MIGRATION_URL
pnpm paperclipai health --json
rg -n "openapi|OpenAPI|board-claim|connect" server cli packages doc/plans/2026-05-23-cli-api-parity-openapi-reference.ts; sed -n ... server/src/routes/openapi.ts; sed -n ... doc/plans/2026-05-23-cli-api-parity-openapi-reference.ts; sed -n ... server/src/board-claim.ts; sed -n ... cli/src/commands/client/connect.ts; lsof -nP -iTCP:3197 -sTCP:LISTEN; git status --short --branch.127.0.0.1:3197, PID 70429; same scratch env and repo branch improvement/cli-api-parity.connect has untested behavior beyond the already verified scriptable equivalents.server/src/routes/openapi.ts currently serves a 247-path operation inventory with generic responses, while doc/plans/2026-05-23-cli-api-parity-openapi-reference.ts already contains a real OpenAPIRegistry/OpenApiGeneratorV3 implementation with request bodies from shared Zod schemas, auth/security fixups, and status overrides. Positive board-claim requires an authenticated-mode instance whose only instance admin is local-board; the current disposable server is local_trusted, where no challenge is generated. Interactive connect intentionally exits in non-TTY mode before any prompts; its network/token/context side effects are covered by scriptable command paths, but the prompt flow itself has not been PTY-tested.connect can be checked with a PTY/script harness if a local board-login challenge can be approved non-interactively.pnpm add @asteasolutions/[email protected] --filter @paperclipai/server; replaced server/src/routes/openapi.ts inventory stub with the schema-backed generator from doc/plans/2026-05-23-cli-api-parity-openapi-reference.ts; added route wrapper exports; tightened server/src/__tests__/openapi-routes.test.ts; pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts; pnpm --dir server typecheck; restarted isolated server with the scratch env; pnpm paperclipai openapi --json.127.0.0.1:3197; DATABASE_URL and DATABASE_MIGRATION_URL unset; PAPERCLIP_HOME, PAPERCLIP_CONFIG, PAPERCLIP_CONTEXT, PAPERCLIP_AUTH_STORE, CODEX_HOME, and CLAUDE_HOME all under tmp/cli-api-parity./api/openapi.json and paperclipai openapi --json return OpenAPI 3.0 with schema-backed request bodies, security schemes, public-operation security overrides, and create-operation 201 responses.BoardSessionAuth, BoardApiKeyAuth, AgentBearerAuth, public /api/health security [], POST /api/companies request body schema, POST /api/companies 201 response, and POST /api/agents/{id}/keys request body schema. Server typecheck passed. Live CLI returned {openapi:"3.0.0", pathCount:259, security:["BoardSessionAuth","BoardApiKeyAuth","AgentBearerAuth"], companyCreateRequest:{type:"string",minLength:1}, companyCreateStatus:["201","400","401","403"], agentKeyRequest:{type:"string",minLength:1,default:"default"}}.tmp/cli-api-parity/artifacts/caveat-followup/openapi-live-schema-backed.json.server/src/__tests__/board-claim.test.ts; ran pnpm exec vitest run server/src/__tests__/board-claim.test.ts; ran pnpm --dir server typecheck.local_trusted scratch instance.local-board as the only instance_admin; initialized board-claim challenge with deploymentMode: "authenticated".inspectBoardClaimChallenge(token, code) returns available; claiming as the signed-in user returns claimed; local-board loses instance admin; the signed-in user gains instance admin and active owner membership for the existing company; subsequent inspect returns claimed.principal_permission_grants; cleanup was fixed to delete grants before companies. The rerun passed. Server typecheck passed.local_trusted, which is correct for the main parity harness.connect can be PTY-tested or should remain classified as lower-risk because its side effects were exercised through scriptable paths.cli/src/__tests__/connect.test.ts; ran pnpm exec vitest run cli/src/__tests__/connect.test.ts; ran pnpm --dir cli typecheck.connect caveat by exercising the actual TTY-gated command path with mocked prompts and mocked board-login approval, without opening a real browser or touching real auth state.process.stdin.isTTY and process.stdout.isTTY to true; mocked loginBoardCli to return a board credential; mocked API responses for health, company list, board API key create, agent list, and agent API key create.connect tests passed. CLI typecheck passed. The test intentionally does not launch a browser; browser approval itself is already covered by CLI auth challenge route tests and mocked here as the boundary before profile selection/token creation.connect no longer has an untested command-flow caveat. Remaining real-browser/device approval behavior is covered by lower-level CLI auth challenge route tests and scriptable auth commands, not by manually approving in this terminal.pnpm paperclipai health --json; pnpm paperclipai openapi --json; lsof -nP -iTCP:3197 -sTCP:LISTEN; git status --short --branch, all with the scratch PAPERCLIP_*, CODEX_HOME, and CLAUDE_HOME environment and with DATABASE_URL/DATABASE_MIGRATION_URL unset.127.0.0.1:3197; PID 84908; same tmp/cli-api-parity home/config/context/auth paths.status:"ok", version 0.3.1, deployment mode local_trusted, exposure private, auth ready, bootstrap ready. OpenAPI returned {openapi:"3.0.0", pathCount:259, security:["BoardSessionAuth","BoardApiKeyAuth","AgentBearerAuth"], companyCreateStatus:["201","400","401","403"]}. node PID 84908 is listening on 127.0.0.1:3197. Git status was clean before this final log update.1ab85cb5; positive board-claim caveat covered in commit 678fd3a8; interactive connect caveat covered in commit 40480f38.paperclip-cli-parity; verified pnpm paperclipai health --json; checked lsof -nP -iTCP:3197 -sTCP:LISTEN; checked screen -ls.91568.paperclip-cli-parity.3197 with the same isolated home/config/context/auth paths.status:"ok" with deployment mode local_trusted; node PID 91583 is listening on 127.0.0.1:3197; screen -ls shows detached session 91568.paperclip-cli-parity.tmp/cli-api-parity/artifacts/caveat-followup/server-screen.log.screen -r paperclip-cli-parity to inspect the server session.git mv doc/bugs doc/logs; appended this entry in doc/logs/2026-05-24-cli-api-parity-e2e-log.md; git status --short --branch; git diff --check.doc/bugs to doc/logs while preserving the existing audit trail.improvement/cli-api-parity; single log file 2026-05-24-cli-api-parity-e2e-log.md.doc/bugs/ to doc/logs/; historical command strings inside the log remain unchanged because they record what was run at the time.doc/logs/2026-05-24-cli-api-parity-e2e-log.md.routine trigger:create <routine-id> --payload-json '{"kind":"webhook","signingMode":"bearer"}' --json; routine trigger:delete <trigger-id> --json; secrets list --company-id <company-id> --json.referenceCount: 1 and description Webhook auth for routine ....deleteTrigger() deleted only the routine_triggers row and appended a revision; it did not remove existing.secretId.server/src/services/routines.ts, server/src/__tests__/routines-service.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.secretsSvc.remove(existing.secretId) for webhook triggers with managed secrets. Added assertions that deleting a webhook trigger removes both company_secrets and company_secret_bindings rows.pnpm exec vitest run server/src/__tests__/routines-service.test.ts; pnpm --dir server typecheck; live isolated webhook trigger create/delete; live secrets list --company-id <company-id> --json.packages/plugins/examples/plugin-kitchen-sink-example, then run pnpm paperclipai plugin tool:execute --payload-json '{"tool":"paperclip-kitchen-sink-example:echo","parameters":{"message":"CLI parity tool"},"runContext":{"companyId":"<company-id>","projectId":"<project-id>","agentId":"<agent-id>","runId":"<run-id>"}}' --json.ToolResult.plugin tools listed paperclip-kitchen-sink-example:echo, and bridge data/action calls to the same plugin worker succeeded, but tool:execute returned 502: Cannot execute tool ... worker for plugin "paperclip-kitchen-sink-example" is not running.plugin-loader registered tools with only the plugin key, so RegisteredTool.pluginDbId defaulted to the plugin key. plugin-worker-manager tracks running workers by database plugin UUID, so the dispatcher looked up the wrong worker ID.server/src/services/plugin-tool-dispatcher.ts, server/src/services/plugin-loader.ts, server/src/__tests__/plugin-database.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.registerPluginTools to accept an optional database plugin ID, passed the database ID from the plugin loader, and added regression coverage that plugin activation registers manifest-key namespaced tools with the database ID for worker lookup.pnpm exec vitest run server/src/__tests__/plugin-database.test.ts; pnpm --dir server typecheck; restarted isolated server; live kitchen-sink plugin tools; live plugin tool:execute; cleanup plugin uninstall --force.token agent list --agent <agent-id> failed even when the agent existspnpm paperclipai token agent list --company-id 12e9db4b-f66c-459b-959e-d645002240fb --agent 1dd601a1-031a-4225-b005-419427fd059f --json.--agent accepts the documented agent ID, shortname, or unambiguous name.404: Agent not found for the ID form; the name form worked./api/agents/:ref?companyId=...; the server route did not resolve the UUID ref in that lookup mode.cli/src/commands/client/token.ts, cli/src/__tests__/token.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md./api/agents/:id directly, and verify the returned agent belongs to the requested company before listing/creating/revoking keys.pnpm exec vitest run cli/src/__tests__/token.test.ts; pnpm --dir cli typecheck; live isolated token agent list --company-id <company-id> --agent <agent-id> --json.worktree:make can recurse through pnpm shim when HOME is isolatedHOME=/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/shell-home pnpm paperclipai worktree:make cli-parity-wt --home /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/worktree-instances --from-config /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/instances/cli-api-parity/config.json --server-port 3198 --db-port 54331 --seed-mode minimal.installDependenciesBestEffort() executed bare pnpm install. With HOME redirected for isolation, the user's pnpm shim repeatedly spawned pnpm add [email protected] under the scratch home and the command did not reach worktree initialization until the runaway process tree was stopped.HOME.cli/src/commands/worktree.ts, cli/src/__tests__/worktree.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.resolvePnpmInstallInvocation() and changed worktree dependency installation to reuse npm_execpath when the CLI was launched through pnpm, falling back to bare pnpm only when no pnpm launcher is available.pnpm exec vitest run cli/src/__tests__/worktree.test.ts; pnpm --dir cli typecheck; live isolated worktree:cleanup --force for the partial worktree; live isolated worktree:make ... --seed-mode minimal; worktree:list --json; worktree env --config <scratch-worktree-config> --json; worktree:merge-history --from paperclip-cli-parity-wt --to current --company CLI --dry.configure --section <invalid> printed an error but exited 0pnpm paperclipai configure --config /Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/home/instances/cli-api-parity/config.json --section invalid-section.Unknown section: invalid-section... but exited with status 0.configure() logged and returned without setting process.exitCode.cli/src/commands/configure.ts, cli/src/__tests__/configure.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.process.exitCode = 1 for missing config and unknown section early returns; added regression coverage for both paths.pnpm exec vitest run cli/src/__tests__/configure.test.ts; pnpm --dir cli typecheck; live isolated configure --config <scratch-config> --section invalid-section returned exit code 1.context set erased existing profile fieldsapiBase can be silently removed and later commands may fall back to http://localhost:3100 if PAPERCLIP_API_URL is absent.pnpm paperclipai context set --api-base http://127.0.0.1:3197 --use --json; then pnpm paperclipai context set --company-id <company-id> --use --json; then pnpm paperclipai context show --json.apiBase while adding companyId.companyId; apiBase was removed.context set passed an object containing keys with undefined values into upsertProfile, and the merge spread those undefined values over existing properties.cli/src/commands/client/context.ts; cli/src/client/context.ts; cli/src/__tests__/context.test.ts.upsertProfile ignore undefined values while still allowing empty strings to delete fields.pnpm exec vitest run cli/src/__tests__/context.test.ts; pnpm --dir cli typecheck; pnpm paperclipai context show --json.access whoami command is not registeredpnpm paperclipai access whoami --json.unknown command 'access'.registerAccessCommands registers whoami as a top-level command, not under an access group.cli/src/commands/client/access.ts, cli/src/__tests__/access-parity.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.paperclipai access whoami as an alias for the existing top-level whoami command.pnpm exec vitest run cli/src/__tests__/access-parity.test.ts; pnpm --dir cli typecheck; pnpm paperclipai access whoami --json.issue interaction:accept rejected omitted optional selected keys--selected-client-keys optional, but omitting it made the CLI fail before calling the API.pnpm paperclipai issue interaction:accept <issue-id> <request-confirmation-interaction-id> --json.{} and the API accepts the pending request confirmation.selectedClientKeys too small because omitted input was converted to [].parseCsv(undefined) returns [], and interaction:accept always included that value in the payload.cli/src/commands/client/issue.ts; cli/src/__tests__/issue-subresources.test.ts.undefined when --selected-client-keys is omitted; keep CSV parsing for explicit values.pnpm exec vitest run cli/src/__tests__/issue-subresources.test.ts; pnpm --dir cli typecheck.pnpm paperclipai issue tree-hold:get <issue-id> null --json or pnpm paperclipai issue tree-hold:release <issue-id> null --json.API error 500: Internal server error; server log showed invalid input syntax for type uuid: "null".holdId before passing it to service/database code.server/src/routes/issue-tree-control.ts; server/src/__tests__/issue-tree-control-routes.test.ts.holdId with isUuidLike in get/release routes and return { error: "Invalid hold ID" } with status 400.pnpm exec vitest run server/src/__tests__/issue-tree-control-routes.test.ts; pnpm --dir server typecheck.issue interaction:cancel command is generic but API only cancels questionspnpm paperclipai issue interaction:cancel <issue-id> <request-confirmation-interaction-id> --reason "..." --json.ask_user_questions, or request confirmations expose a cancel/supersede flow.422: Only ask_user_questions interactions can be cancelled.cancelQuestions.cli/src/commands/client/issue.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.ask_user_questions interaction.pnpm exec vitest run cli/src/__tests__/issue-subresources.test.ts; pnpm --dir cli typecheck; pnpm paperclipai issue interaction:cancel --help.issue recovery:resolve help overstates valid restored statusespnpm paperclipai issue recovery:resolve <issue-id> --action-id <action-id> --outcome restored --source-issue-status blocked --json.restored outcomes.--source-issue-status accepts todo, done, in_review, or blocked; validator rejects blocked for --outcome restored with Restored recovery actions must move the source issue to todo, done, or in_review.cli/src/commands/client/issue.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.blocked is only valid for blocked outcomes.pnpm exec vitest run cli/src/__tests__/issue-subresources.test.ts; pnpm --dir cli typecheck; pnpm paperclipai issue recovery:resolve --help.agent instructions-path:update help does not expose process adapter requirementspnpm paperclipai agent instructions-path:update <process-agent-id> --payload-json '{"path":"docs/cli-parity.md"}' --json.adapterConfigKey, and relative paths need adapterConfig.cwd.No default instructions path key for adapter type 'process'. Provide adapterConfigKey. A second attempt with a relative path and adapterConfigKey failed with Relative instructions path requires adapterConfig.cwd to be set to an absolute path.cli/src/commands/client/agent.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.--payload-json help to call out process-adapter adapterConfigKey, relative path adapterConfig.cwd, and an example payload.pnpm exec vitest run cli/src/__tests__/agent-lifecycle.test.ts; pnpm --dir cli typecheck; pnpm paperclipai agent instructions-path:update --help.invite test-resolution omits required URL querypnpm paperclipai invite test-resolution <invite-token> --json.400: url query parameter is required.invite test-resolution <token> directly to /api/invites/:token/test-resolution without any url query option.cli/src/commands/client/access.ts, cli/src/__tests__/access-parity.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.--url <url> option and forwards it as the url query parameter.pnpm exec vitest run cli/src/__tests__/access-parity.test.ts; pnpm --dir cli typecheck; pnpm paperclipai invite test-resolution <token> --url https://example.com/invite/<token> --json.join list --status pending is rejected; API expects pending_approvalpnpm paperclipai join list --company-id <company-id> --status pending --request-type agent --json.pending is accepted.pending; valid values include pending_approval, approved, and rejected.cli/src/commands/client/access.ts, cli/src/__tests__/access-parity.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.join list --status pending now normalizes to pending_approval; help lists canonical statuses.pnpm exec vitest run cli/src/__tests__/access-parity.test.ts; pnpm --dir cli typecheck; pnpm paperclipai join list --company-id <company-id> --status pending --request-type agent --json.pnpm paperclipai openapi --json; pnpm paperclipai available-skill get cmux --json; pnpm paperclipai llm agent-configuration --json; pnpm paperclipai llm agent-icons --json; pnpm paperclipai llm agent-configuration:adapter process --json.openapi and all tested llm commands returned 404: API route not found. available-skill list returned cmux from the real Claude home, but available-skill get cmux returned 404: Skill not found./api/llms; available-skill discovery used HOME/.claude/skills instead of CLAUDE_HOME; OpenAPI generation was referenced by CLI/docs but no route was mounted.server/src/app.ts, server/src/routes/access.ts, server/src/routes/openapi.ts, server/src/__tests__/openapi-routes.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md./api; made available-skill discovery honor CLAUDE_HOME, include built-in Paperclip repo skills, and fetch safe skill markdown consistently; added /api/openapi.json, then upgraded it from the initial path inventory to the schema-backed OpenAPIRegistry/OpenApiGeneratorV3 implementation from the parity reference.pnpm exec vitest run server/src/__tests__/llms-routes.test.ts cli/src/__tests__/access-parity.test.ts; pnpm --dir server typecheck; pnpm --dir cli typecheck; live llm and available-skill commands after restart; pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts; live curl http://127.0.0.1:3197/api/openapi.json; live pnpm paperclipai openapi --json; follow-up live schema-backed paperclipai openapi --json.CLAUDE_HOMECLAUDE_HOME=/Users/aronprins/Documents/PaperclipAI/paperclip/tmp/cli-api-parity/claude-home pnpm paperclipai available-skill list --json.cmux from the real user Claude skills home, and available-skill get cmux failed because only a hardcoded Paperclip subset was fetchable.HOME/.claude/skills directly and did not add built-in Paperclip skills unless they were present in Claude's skills directory.server/src/routes/access.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.CLAUDE_HOME/skills when CLAUDE_HOME is set, include built-in Paperclip skills in catalog output, and resolve safe skill markdown from both Claude and Paperclip skills directories.available-skill list, available-skill get paperclip, and available-skill get cmux after restarting the isolated server.paperclipai health is not registeredpnpm paperclipai health --json.curl <api-url>/api/health.unknown command 'health'.cli/src/commands/client/access.ts, cli/src/__tests__/access-parity.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.health command that calls /api/health.pnpm exec vitest run cli/src/__tests__/access-parity.test.ts; pnpm --dir cli typecheck; pnpm paperclipai health --json.pnpm paperclipai environment create --company-id 12e9db4b-f66c-459b-959e-d645002240fb --payload-json '{"name":"CLI parity local env","description":"Disposable CLI parity environment","driver":"local","config":{"cwd":"/Users/aronprins/Documents/PaperclipAI/paperclip"}}' --json.409 or other user-facing validation error because a default local environment already exists for the company.500: Internal server error; server log showed duplicate key violation for environments_company_driver_idx.(company_id, driver) for driver = 'local'.server/src/routes/environments.ts, server/src/__tests__/environment-routes.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.409 when a local environment already exists for the company; added regression coverage.pnpm exec vitest run server/src/__tests__/environment-routes.test.ts; pnpm --dir server typecheck; restarted isolated server and reran the reproduction command, which now returns 409.pnpm paperclipai secrets --help did not expose commands for PATCH /api/secrets/:id, POST /api/secrets/:id/rotate, GET /api/secrets/:id/usage, GET /api/secrets/:id/access-events, or DELETE /api/secrets/:id.cli/src/commands/client/secrets.ts, cli/src/__tests__/secrets.test.ts, doc/bugs/2026-05-24-cli-api-parity-e2e-log.md.secrets update, secrets rotate, secrets usage, secrets access-events, and guarded secrets delete --yes --confirm <secret-id> commands.pnpm exec vitest run cli/src/__tests__/secrets.test.ts; pnpm --dir cli typecheck; live scratch commands for update/rotate/usage/access-events/delete.secrets link remains provider-dependent and correctly rejects local_encrypted external references.