mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-14 01:50:39 +09:00
## Thinking Path > - Paperclip is a control plane for AI-agent companies, with the CLI acting as a scriptable operator and agent interface to that control plane. > - The REST API surface has grown across companies, agents, issues, routines, plugins, auth, workspaces, secrets, and operational inspection commands. > - The CLI had drifted from that API surface: some commands were missing, some command shapes differed from docs/reference material, and several edge cases only failed during end-to-end local-source testing. > - The local development runbook requires these tests to be disposable and isolated from a real `~/.paperclip`, `~/.codex`, or `~/.claude` installation. > - This pull request adds broad CLI/API parity coverage, fixes the actionable bugs found during that pass, and records the reproducible test log under `doc/logs`. > - The benefit is a more complete, scriptable CLI surface with regression coverage for the command families exercised by the parity run. ## What Changed - Added or expanded CLI command coverage for access/auth, companies, agents, projects, goals, issues and subresources, routines, plugins, workspaces, activity/run/cost/dashboard inspection, assets, skills, secrets, tokens, prompt/wake flows, and local setup helpers. - Fixed CLI/API parity bugs found during the run, including context profile patching, issue interaction optional payloads, malformed tree-hold errors, environment duplicate handling, configure invalid-section exit codes, worktree pnpm invocation, token agent ID resolution, plugin tool worker lookup, and routine webhook secret cleanup. - Added missing CLI wrappers and route coverage for health/access, invite resolution URL forwarding, join status normalization, secret lifecycle commands, LLM docs routes, available-skill isolation, positive board-claim coverage, and interactive `connect` prompt-flow tests. - Added a schema-backed `/api/openapi.json` route sufficient for CLI parity and `paperclipai openapi --json` smoke coverage. - Added `doc/logs/2026-05-24-cli-api-parity-e2e-log.md` with the detailed living test/bug log and renamed the log directory from `doc/bugs` to `doc/logs`. - Added `doc/plans/2026-05-23-cli-api-parity.md` and the OpenAPI parity reference used during the pass. OpenAPI note: this PR intentionally does not try to subsume `feature/openapi-spec`. The OpenAPI implementation here is schema-backed and better than the earlier route-inventory stub, but `feature/openapi-spec` is the fuller/better OpenAPI branch because it includes exact mounted-route coverage tests and additional current route coverage. That branch should stay as its own PR and can supersede this OpenAPI route implementation. ## Verification Targeted automated checks run: - `pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts` - `pnpm exec vitest run server/src/__tests__/board-claim.test.ts` - `pnpm exec vitest run cli/src/__tests__/connect.test.ts` - `pnpm exec vitest run cli/src/__tests__/agent-lifecycle.test.ts` - `pnpm exec vitest run server/src/__tests__/plugin-database.test.ts` - `pnpm exec vitest run server/src/__tests__/routines-service.test.ts` - `pnpm --dir cli typecheck` - `pnpm --dir server typecheck` Manual/local E2E verification: - Ran the full disposable local-source CLI/API parity pass with isolated `PAPERCLIP_HOME`, `PAPERCLIP_CONFIG`, `PAPERCLIP_CONTEXT`, `PAPERCLIP_AUTH_STORE`, `CODEX_HOME`, and `CLAUDE_HOME` under `tmp/cli-api-parity`. - Verified `DATABASE_URL` and `DATABASE_MIGRATION_URL` stayed unset for the scratch server. - Verified live health and schema-backed OpenAPI responses on non-default port `3197`. - Revoked created board/agent tokens and cleaned up temporary plugins, secrets, non-default environments, and project workspaces. - See `doc/logs/2026-05-24-cli-api-parity-e2e-log.md` for the full command-by-command reproduction log. Not run: - Full `pnpm test`, `pnpm test:run`, or `pnpm build` were not run after the entire branch because the branch is broad and the parity pass used focused test/typecheck verification plus live isolated CLI reruns. ## Risks - This is a broad PR and touches many CLI command modules, so review surface is high. The changes are grouped around one theme, but a split may be easier if maintainers prefer narrower PRs. - The OpenAPI route in this PR is not the final/best OpenAPI implementation. `feature/openapi-spec` has stronger exact-route coverage and should remain the source for the dedicated OpenAPI PR. - The living log is intentionally detailed and large. It is useful for reproducibility but adds documentation weight. - No UI changes are intended; screenshots are not applicable. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex, GPT-5-based coding agent in Codex desktop. Exact served model/context-window identifier was not exposed in the local app. Work used shell/Git/GitHub CLI tooling, local source inspection, targeted test execution, and live isolated Paperclip CLI/API smoke testing. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Devin Foley <devin@devinfoley.com>
623 lines
25 KiB
Markdown
623 lines
25 KiB
Markdown
# CLI API Parity PRD
|
|
|
|
Date: 2026-05-23
|
|
Branch: `improvement/cli-api-parity`
|
|
Status: PRD
|
|
|
|
## Summary
|
|
|
|
Paperclip already exposes a broad REST API, but the CLI only covers a narrow operator slice: setup/configuration, context profiles, board auth, companies import/export/delete, issues basic CRUD/comments/checkout/release, approvals, agents list/get/local CLI key export, activity, dashboard, secrets basics, plugin lifecycle basics, feedback export, and cloud sync.
|
|
|
|
The next CLI product slice should make the CLI a real external API entry point:
|
|
|
|
1. Connect interactively as a board operator or as one agent in one company.
|
|
2. Mint, list, revoke, and use board and agent tokens intentionally.
|
|
3. Provide single-command agent execution and prompt handoff for scripts.
|
|
4. Add CLI coverage for API surfaces that are currently UI-only or curl-only.
|
|
|
|
The most important requirement is credential ergonomics. External integrations need a reliable "way in" to Paperclip:
|
|
|
|
- full board access via a board token approved by a user
|
|
- individual agent access via an agent API key scoped to a specific company and agent
|
|
- saved CLI profiles that know whether they are board or agent personas
|
|
- non-interactive commands that can run from shell scripts without a prior wizard
|
|
|
|
## Existing CLI Coverage
|
|
|
|
Current top-level command families:
|
|
|
|
- Setup/runtime: `onboard`, `doctor`, `configure`, `env`, `run`, `db:backup`, `allowed-hostname`, `env-lab`, `worktree`
|
|
- Context/auth: `context`, `auth login`, `auth logout`, `auth whoami`, `auth bootstrap-ceo`
|
|
- Companies: `company list`, `company get`, `company export`, `company import`, `company delete`, company feedback export
|
|
- Issues: `issue list`, `issue get`, `issue create`, `issue update`, `issue comment`, `issue checkout`, `issue release`, issue feedback export
|
|
- Agents: `agent list`, `agent get`, `agent local-cli`
|
|
- Approvals: `approval list/get/create/approve/reject/request-revision/resubmit/comment`
|
|
- Activity/dashboard: `activity list`, `dashboard get`
|
|
- Secrets: `secrets list/declarations/create/link/doctor/providers/migrate-inline-env`
|
|
- Plugins/cloud/feedback: basic lifecycle and transfer workflows
|
|
|
|
Current auth behavior:
|
|
|
|
- `auth login` creates a CLI auth challenge, opens the board approval URL, and stores the approved board token locally.
|
|
- `agent local-cli` creates an agent API key through board access, installs local skills, and prints `PAPERCLIP_API_URL`, `PAPERCLIP_COMPANY_ID`, `PAPERCLIP_AGENT_ID`, and `PAPERCLIP_API_KEY`.
|
|
- Every client command can accept `--api-base`, `--api-key`, `--context`, `--profile`, `--company-id`, and `--json`.
|
|
|
|
Main limitation:
|
|
|
|
- The CLI has no explicit concept of "I am connected as board" versus "I am connected as this agent in this company". It only has a raw bearer token plus optional company context.
|
|
|
|
## Product Goals
|
|
|
|
1. Make the CLI the canonical external connection surface for scripts, local agents, and human operators.
|
|
2. Reach near-parity with first-class REST API domains, starting with company-scoped control-plane operations.
|
|
3. Make token creation safe and auditable: keys are named, scoped, shown once, and easy to revoke.
|
|
4. Support both interactive and single-command flows.
|
|
5. Preserve existing API authorization boundaries: board has operator control; agent keys remain company and agent scoped.
|
|
|
|
## Non-Goals
|
|
|
|
- Do not turn the CLI into a full TUI replacement for the board UI.
|
|
- Do not weaken agent authorization to make script flows easier.
|
|
- Do not store plaintext tokens in repo files.
|
|
- Do not add project/issue privacy semantics; V1 visibility remains company-scoped.
|
|
- Do not make a generic `curl` passthrough the primary parity story.
|
|
|
|
## API Location Requirements
|
|
|
|
The CLI must always know which Paperclip API it is operating against. This is especially important for fork/local development, where Paperclip may run on `3101+` rather than the upstream default `3100`.
|
|
|
|
Resolution order:
|
|
|
|
1. Explicit `--api-base <url>`.
|
|
2. `PAPERCLIP_API_URL`.
|
|
3. Selected context profile `apiBase`.
|
|
4. Repo-local or instance config port, when available.
|
|
5. Default `http://localhost:3100`.
|
|
|
|
Behavior requirements:
|
|
|
|
- `paperclipai connect` must show the resolved API base before any auth or mutation and allow the user to override it.
|
|
- Non-interactive commands must accept `--api-base` and produce a clear connection error that includes the attempted URL and a health-check hint.
|
|
- Profiles must persist `apiBase` so a board/agent persona is always tied to the API instance it was created for.
|
|
- Commands that mint or use tokens must not silently fall back to a different API base if a stored credential is missing. They should ask interactively or fail with instructions in non-interactive mode.
|
|
- The quick verification after `connect` should call `GET /api/health` against the selected API base.
|
|
|
|
## Target User Flows
|
|
|
|
### Interactive Connection Wizard
|
|
|
|
Command:
|
|
|
|
```sh
|
|
paperclipai connect
|
|
```
|
|
|
|
Flow:
|
|
|
|
1. Resolve or ask for API base.
|
|
2. Fetch accessible companies with current board auth, or trigger `auth login`.
|
|
3. Ask whether the user wants to connect as:
|
|
- Board operator
|
|
- Agent in a company
|
|
4. If board:
|
|
- Mint or reuse a named board token.
|
|
- Save profile with `persona=board`, `apiBase`, `companyId`, and token env-var preference.
|
|
5. If agent:
|
|
- Ask for company.
|
|
- List agents in that company.
|
|
- Create a named agent API key for the selected agent.
|
|
- Save profile with `persona=agent`, `companyId`, `agentId`, `agentName`, and token env-var preference.
|
|
6. Print shell exports and a verification command.
|
|
|
|
Expected profile shape should evolve from today's context:
|
|
|
|
```json
|
|
{
|
|
"version": 2,
|
|
"currentProfile": "default",
|
|
"profiles": {
|
|
"default": {
|
|
"apiBase": "http://localhost:3100",
|
|
"companyId": "company-id",
|
|
"persona": "agent",
|
|
"agentId": "agent-id",
|
|
"apiKeyEnvVarName": "PAPERCLIP_API_KEY"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Board Token Flow
|
|
|
|
Commands:
|
|
|
|
```sh
|
|
paperclipai token board create --company-id <company-id> --name "external-admin"
|
|
paperclipai token board list
|
|
paperclipai token board revoke <key-id>
|
|
```
|
|
|
|
Requirements:
|
|
|
|
- Board token creation must require an authenticated board approval or an existing board token with sufficient authority.
|
|
- Token output shows plaintext once.
|
|
- Tokens should have names, creation time, last-used time, expiration, and revoked status.
|
|
- A company ID in the profile selects the operating company, but full board tokens retain the server's board authorization model.
|
|
- If product wants company-limited board keys, add that as an explicit server-side scope rather than relying on client context.
|
|
|
|
Current API support:
|
|
|
|
- Existing challenge flow supports browser-approved board token minting via `/api/cli-auth/challenges`.
|
|
- Existing revocation only covers the current CLI key via `/api/cli-auth/revoke-current`.
|
|
|
|
API gap:
|
|
|
|
- There is no first-class board API key list/create/revoke endpoint for named external tokens. Add endpoints such as:
|
|
- `GET /api/board-api-keys`
|
|
- `POST /api/board-api-keys`
|
|
- `DELETE /api/board-api-keys/:keyId`
|
|
|
|
### Agent Token Flow
|
|
|
|
Commands:
|
|
|
|
```sh
|
|
paperclipai token agent create --company-id <company-id> --agent <agent-id-or-name> --name "external-worker"
|
|
paperclipai token agent list --company-id <company-id> --agent <agent-id-or-name>
|
|
paperclipai token agent revoke --agent <agent-id-or-name> <key-id>
|
|
```
|
|
|
|
Requirements:
|
|
|
|
- Requires board access to create/list/revoke long-lived agent keys.
|
|
- Agent selector accepts UUID, url key, or unambiguous name within company.
|
|
- Output includes `agentId`, `companyId`, key id, key name, and plaintext token once.
|
|
- Agent keys remain scoped to one agent and one company, matching `agent_api_keys`.
|
|
|
|
Current API support:
|
|
|
|
- `GET /api/agents/:id/keys`
|
|
- `POST /api/agents/:id/keys`
|
|
- `DELETE /api/agents/:id/keys/:keyId`
|
|
|
|
CLI gap:
|
|
|
|
- `agent local-cli` can create a key, but it is bundled with skill installation and local CLI setup.
|
|
- There is no generic token command for list/revoke/create.
|
|
|
|
### Single-Command Prompt Handoff
|
|
|
|
Required user-facing shape:
|
|
|
|
```sh
|
|
paperclipai agent-prompt <agent-name-or-id> <agent-api-key> "Prompt here"
|
|
```
|
|
|
|
Recommended safer variants:
|
|
|
|
```sh
|
|
paperclipai agent prompt --agent <agent-name-or-id> --api-key-env PAPERCLIP_API_KEY "Prompt here"
|
|
paperclipai agent prompt --profile my-agent "Prompt here"
|
|
paperclipai board prompt --agent <agent-name-or-id> "Prompt here"
|
|
```
|
|
|
|
Behavior:
|
|
|
|
- With an agent key:
|
|
- Verify identity with `GET /api/agents/me`.
|
|
- Resolve the provided agent name/id against the authenticated agent. If they do not match, fail clearly.
|
|
- Create a new issue assigned to that agent, or append to a specified issue when `--issue` is passed.
|
|
- Optionally invoke/wake the agent when the authenticated agent is allowed to do so.
|
|
- With board auth:
|
|
- Resolve company and target agent.
|
|
- Create a board-authored issue assigned to that agent.
|
|
- Wake/invoke the agent when requested.
|
|
|
|
Open decision:
|
|
|
|
- Default prompt target should be `issue create + assign + wake`, because Paperclip's communication model is tasks/comments, not chat.
|
|
- A direct "send message" mode can be `--issue <id>` and should add an issue comment plus optional wake.
|
|
|
|
## Missing CLI Coverage By API Domain
|
|
|
|
Priority is based on external API usefulness, not raw endpoint count.
|
|
|
|
OpenAPI source audit:
|
|
|
|
- Source branch: `feature/openapi-spec`
|
|
- Source file: `server/src/openapi.ts`
|
|
- Local snapshot for this PRD: `doc/plans/2026-05-23-cli-api-parity-openapi-reference.ts`
|
|
- Extracted operations: 307
|
|
- Validation context: that branch includes `server/src/__tests__/openapi-spec.test.ts`, which asserts the OpenAPI document covers mounted server routes exactly.
|
|
- Snapshot purpose: keep the full operation registrations, request schemas, auth annotations, response status overrides, and tag/summary values next to the CLI parity plan even before the OpenAPI branch is merged.
|
|
|
|
Additional gaps made explicit by the OpenAPI branch:
|
|
|
|
- Public/bootstrap surfaces need CLI decisions, not just board UI paths: `GET /api/openapi.json`, board-claim get/claim, invite onboarding docs, skill docs, join key claim, and CLI auth challenge status/approve/cancel.
|
|
- User/profile and admin surfaces were under-specified in the first PRD: auth session/profile, company user profile lookup, admin user list/promote/demote/company access.
|
|
- Legacy compatibility routes still exist and need an explicit stance: `/api/companies/:companyId/export`, `/api/companies/import/preview`, `/api/companies/import`, `/api/companies/issues`, and bare `GET /api/issues`.
|
|
- Agent operations need several extra CLI items: skills list/sync, `claude-login`, scheduler heartbeat visibility, org SVG/PNG export, adapter UI parser, and agent approval.
|
|
- Cost/budget coverage must reconcile the OpenAPI branch and current main. The OpenAPI branch lists `GET /api/companies/:companyId/cost-events`; current main exposes `POST /api/companies/:companyId/cost-events` plus additional summary and finance read endpoints. Treat this as a spec/code drift item before implementation.
|
|
- The current main branch includes secrets provider-config and remote-import routes beyond the OpenAPI branch list. Keep them in scope for CLI parity even though they are absent from that branch's generated spec.
|
|
|
|
### P0: Connection, Tokens, and Identity
|
|
|
|
Missing or incomplete CLI surfaces:
|
|
|
|
- Board token lifecycle:
|
|
- `GET /api/cli-auth/me` is covered by `auth whoami`.
|
|
- `POST /api/cli-auth/revoke-current` is covered by `auth logout`.
|
|
- Missing named board key list/create/revoke API and CLI.
|
|
- Agent identity:
|
|
- Missing `agent me` for `GET /api/agents/me`.
|
|
- Missing `agent inbox` for `GET /api/agents/me/inbox-lite` and `GET /api/agents/me/inbox/mine`.
|
|
- Agent token lifecycle:
|
|
- Missing generic CLI for `GET/POST/DELETE /api/agents/:id/keys`.
|
|
- Connect wizard:
|
|
- No CLI command combines company selection, persona selection, token minting, profile saving, and verification.
|
|
- Public/bootstrap auth helpers:
|
|
- `GET /api/board-claim/:token`
|
|
- `POST /api/board-claim/:token/claim`
|
|
- `POST /api/cli-auth/challenges`
|
|
- `GET /api/cli-auth/challenges/:id`
|
|
- `POST /api/cli-auth/challenges/:id/approve`
|
|
- `POST /api/cli-auth/challenges/:id/cancel`
|
|
- `POST /api/join-requests/:requestId/claim-api-key`
|
|
|
|
### P0: Prompt, Wake, and Run Control
|
|
|
|
Missing CLI surfaces:
|
|
|
|
- `POST /api/agents/:id/wakeup`
|
|
- `POST /api/agents/:id/heartbeat/invoke` is partially covered by `heartbeat run`, but not integrated with prompt handoff.
|
|
- `GET /api/companies/:companyId/heartbeat-runs`
|
|
- `GET /api/companies/:companyId/live-runs`
|
|
- `GET /api/heartbeat-runs/:runId`
|
|
- `POST /api/heartbeat-runs/:runId/cancel`
|
|
- `GET /api/heartbeat-runs/:runId/events`
|
|
- `GET /api/heartbeat-runs/:runId/log`
|
|
- `GET /api/issues/:issueId/live-runs`
|
|
- `GET /api/issues/:issueId/active-run`
|
|
- `GET /api/issues/:id/runs`
|
|
- `GET /api/heartbeat-runs/:runId/issues`
|
|
- `POST /api/heartbeat-runs/:runId/watchdog-decisions`
|
|
- `GET /api/heartbeat-runs/:runId/workspace-operations`
|
|
- `GET /api/workspace-operations/:operationId/log`
|
|
|
|
CLI commands to add:
|
|
|
|
```sh
|
|
paperclipai agent wake <agent>
|
|
paperclipai run list --company-id <company-id>
|
|
paperclipai run get <run-id>
|
|
paperclipai run log <run-id>
|
|
paperclipai run cancel <run-id>
|
|
paperclipai issue runs <issue-id>
|
|
```
|
|
|
|
### P1: Projects and Goals
|
|
|
|
Missing CLI surfaces:
|
|
|
|
- `GET /api/companies/:companyId/projects`
|
|
- `POST /api/companies/:companyId/projects`
|
|
- `GET /api/projects/:id`
|
|
- `PATCH /api/projects/:id`
|
|
- `DELETE /api/projects/:id`
|
|
- `GET /api/companies/:companyId/goals`
|
|
- `POST /api/companies/:companyId/goals`
|
|
- `GET /api/goals/:id`
|
|
- `PATCH /api/goals/:id`
|
|
- `DELETE /api/goals/:id`
|
|
|
|
Commands:
|
|
|
|
```sh
|
|
paperclipai project list|get|create|update|delete
|
|
paperclipai goal list|get|create|update|delete
|
|
```
|
|
|
|
### P1: Issue Parity Beyond Basic CRUD
|
|
|
|
Missing CLI surfaces:
|
|
|
|
- Issue counts/search/labels:
|
|
- `GET /api/issues`
|
|
- `GET /api/companies/:companyId/search`
|
|
- `GET /api/companies/:companyId/issues/count`
|
|
- `GET /api/companies/issues`
|
|
- `GET/POST /api/companies/:companyId/labels`
|
|
- `DELETE /api/labels/:labelId`
|
|
- Child issues:
|
|
- `POST /api/issues/:id/children`
|
|
- Force-release/admin recovery:
|
|
- `POST /api/issues/:id/admin/force-release`
|
|
- Documents:
|
|
- `GET /api/issues/:id/documents`
|
|
- `GET/PUT/DELETE /api/issues/:id/documents/:key`
|
|
- lock/unlock/revisions/restore endpoints
|
|
- Work products:
|
|
- `GET/POST /api/issues/:id/work-products`
|
|
- `PATCH/DELETE /api/work-products/:id`
|
|
- Interactions:
|
|
- `GET/POST /api/issues/:id/interactions`
|
|
- accept/reject/respond/cancel endpoints
|
|
- Read/archive state:
|
|
- `POST/DELETE /api/issues/:id/read`
|
|
- `POST/DELETE /api/issues/:id/inbox-archive`
|
|
- Attachments:
|
|
- `GET /api/issues/:id/attachments`
|
|
- `POST /api/companies/:companyId/issues/:issueId/attachments`
|
|
- `GET /api/attachments/:attachmentId/content`
|
|
- `DELETE /api/attachments/:attachmentId`
|
|
- Comment-specific access:
|
|
- `GET /api/issues/:id/comments/:commentId`
|
|
- `DELETE /api/issues/:id/comments/:commentId`
|
|
- Recovery/tree control:
|
|
- `GET /api/issues/:id/recovery-actions`
|
|
- `POST /api/issues/:id/recovery-actions/resolve`
|
|
- tree hold and preview endpoints
|
|
|
|
Commands:
|
|
|
|
```sh
|
|
paperclipai issue child create <issue-id>
|
|
paperclipai issue document list|get|put|delete|lock|unlock|revisions|restore
|
|
paperclipai issue work-product list|create|update|delete
|
|
paperclipai issue interaction list|create|accept|reject|respond|cancel
|
|
paperclipai issue attachment list|upload|download|delete
|
|
paperclipai issue force-release <issue-id>
|
|
paperclipai issue label list|create|delete
|
|
paperclipai issue read|unread|archive|unarchive
|
|
```
|
|
|
|
### P1: Agent Lifecycle and Configuration
|
|
|
|
Missing CLI surfaces:
|
|
|
|
- Create/update/pause/resume/approve/terminate/delete:
|
|
- `POST /api/companies/:companyId/agents`
|
|
- `PATCH /api/agents/:id`
|
|
- `POST /api/agents/:id/pause`
|
|
- `POST /api/agents/:id/resume`
|
|
- `POST /api/agents/:id/approve`
|
|
- `POST /api/agents/:id/terminate`
|
|
- `DELETE /api/agents/:id`
|
|
- Org and config:
|
|
- `GET /api/companies/:companyId/org`
|
|
- `GET /api/companies/:companyId/org.svg`
|
|
- `GET /api/companies/:companyId/org.png`
|
|
- `GET /api/companies/:companyId/agent-configurations`
|
|
- `GET /api/agents/:id/configuration`
|
|
- config revision list/get/rollback
|
|
- runtime state and task sessions
|
|
- Instructions:
|
|
- instructions bundle, path, and file endpoints
|
|
- Adapter support:
|
|
- models, model profiles, detect model, test environment
|
|
- Skills and local-auth helpers:
|
|
- `GET /api/agents/:id/skills`
|
|
- `POST /api/agents/:id/skills/sync`
|
|
- `POST /api/agents/:id/claude-login`
|
|
- Scheduler visibility:
|
|
- `GET /api/instance/scheduler-heartbeats`
|
|
|
|
Commands:
|
|
|
|
```sh
|
|
paperclipai agent create|update|pause|resume|approve|terminate|delete
|
|
paperclipai agent org
|
|
paperclipai agent config get|revisions|rollback
|
|
paperclipai agent instructions get|set|file
|
|
paperclipai adapter list|models|profiles|detect|test|install|enable|disable|reload
|
|
```
|
|
|
|
### P1: Costs, Budgets, and Finance
|
|
|
|
Missing CLI surfaces:
|
|
|
|
- `POST /api/companies/:companyId/cost-events`
|
|
- `GET /api/companies/:companyId/cost-events` from the OpenAPI branch needs reconciliation with main before implementation.
|
|
- `POST /api/companies/:companyId/finance-events`
|
|
- cost summaries by agent/model/provider/biller/project
|
|
- finance summaries by biller/kind and finance events
|
|
- quota windows and window spend
|
|
- budget overview, budget policies, budget incident resolution
|
|
- `PATCH /api/companies/:companyId/budgets`
|
|
- `PATCH /api/agents/:agentId/budgets`
|
|
- `GET /api/issues/:id/cost-summary`
|
|
|
|
Commands:
|
|
|
|
```sh
|
|
paperclipai cost summary|by-agent|by-project|by-provider|issue
|
|
paperclipai cost event create
|
|
paperclipai finance event create|list|summary
|
|
paperclipai budget overview|set-company|set-agent|policy-create|incident-resolve
|
|
```
|
|
|
|
### P1: Access, Invites, and Memberships
|
|
|
|
Missing CLI surfaces:
|
|
|
|
- Invite creation/list/revoke and onboarding manifests
|
|
- Join request list/approve/reject/claim API key
|
|
- Company members and user directory
|
|
- Member role/grant/permission updates
|
|
- Admin users and company access management
|
|
- Board claim endpoints
|
|
- Skills index/invite onboarding docs
|
|
- Auth/profile endpoints:
|
|
- `GET /api/auth/get-session`
|
|
- `GET /api/auth/profile`
|
|
- `PATCH /api/auth/profile`
|
|
- `GET /api/companies/:companyId/users/:userSlug/profile`
|
|
|
|
Commands:
|
|
|
|
```sh
|
|
paperclipai invite create|list|revoke|show|onboarding
|
|
paperclipai join list|approve|reject|claim-key
|
|
paperclipai member list|update|archive|permissions
|
|
paperclipai admin user list|promote|demote|company-access
|
|
```
|
|
|
|
### P2: Routines, Workspaces, Environments
|
|
|
|
Missing CLI surfaces:
|
|
|
|
- Routines API:
|
|
- list/create/get/update/revisions/restore/runs/run/triggers/rotate-secret/public fire
|
|
- Environments API:
|
|
- list/capabilities/create/get/update/delete/probe/leases
|
|
- Execution and project workspaces:
|
|
- execution workspace list/get/patch/close readiness/operations/runtime actions
|
|
- project workspace list/create/update/delete/runtime actions
|
|
|
|
Commands:
|
|
|
|
```sh
|
|
paperclipai routine list|create|get|update|run|runs|trigger|revision
|
|
paperclipai environment list|create|get|update|delete|probe|leases
|
|
paperclipai workspace list|get|update|operations|runtime
|
|
paperclipai project workspace list|create|update|delete|runtime
|
|
```
|
|
|
|
### P2: Instance, Sidebar, Assets, Profile, and Miscellaneous
|
|
|
|
Missing CLI surfaces:
|
|
|
|
- Instance settings general/experimental and database backups API
|
|
- Sidebar preferences and sidebar badges
|
|
- Asset image/logo upload and asset content download
|
|
- User profile read/update and company user profile lookup
|
|
- LLM prompt docs endpoints
|
|
- Public API documentation endpoint:
|
|
- `GET /api/openapi.json`
|
|
- Plugin deeper surfaces:
|
|
- tools list/execute
|
|
- UI contributions
|
|
- plugin config/test
|
|
- plugin health/logs/jobs/webhooks/local folders/dashboard
|
|
- Company create/update/archive/branding/stats are missing or partial in CLI.
|
|
- Company portability compatibility routes:
|
|
- `POST /api/companies/:companyId/export`
|
|
- `POST /api/companies/import/preview`
|
|
- `POST /api/companies/import`
|
|
- `POST /api/companies/:companyId/exports`
|
|
- `POST /api/companies/:companyId/exports/preview`
|
|
- `POST /api/companies/:companyId/imports/preview`
|
|
- `POST /api/companies/:companyId/imports/apply`
|
|
|
|
## Command Taxonomy
|
|
|
|
Recommended command hierarchy:
|
|
|
|
```text
|
|
paperclipai connect
|
|
paperclipai token board|agent create|list|revoke
|
|
paperclipai whoami
|
|
paperclipai prompt ...
|
|
paperclipai board ...
|
|
paperclipai agent ...
|
|
paperclipai issue ...
|
|
paperclipai project ...
|
|
paperclipai goal ...
|
|
paperclipai run ...
|
|
paperclipai cost ...
|
|
paperclipai budget ...
|
|
paperclipai routine ...
|
|
paperclipai environment ...
|
|
paperclipai workspace ...
|
|
paperclipai invite ...
|
|
paperclipai member ...
|
|
paperclipai plugin ...
|
|
paperclipai instance ...
|
|
```
|
|
|
|
Alias policy:
|
|
|
|
- Keep existing commands working.
|
|
- Add aliases only for high-frequency flows, for example `paperclipai ask` as an alias for `paperclipai prompt`.
|
|
|
|
## Authorization Rules
|
|
|
|
- Board commands should use board tokens and fail clearly when an agent key is supplied.
|
|
- Agent commands should prefer `GET /api/agents/me` to establish identity instead of trusting CLI flags.
|
|
- `--company-id` is a context selector, not an authorization bypass.
|
|
- Token creation and revocation must log activity through existing server routes.
|
|
- Commands that mutate company state should print the actor type and target company in `--json` output when practical.
|
|
|
|
## Testing Rules
|
|
|
|
Automated tests should prefer mocked HTTP/server fixtures where possible. Live/API verification is allowed, but it must be isolated:
|
|
|
|
- Live tests must create a new disposable company specifically for that test run.
|
|
- Live tests must never use an existing company from the operator's profile, local instance, or shared environment.
|
|
- The disposable company name should include a clear prefix such as `CLI Parity Test` plus a timestamp or random suffix.
|
|
- All agents, projects, issues, tokens, budgets, secrets, routines, workspaces, and other test data must be created inside the disposable company.
|
|
- Agent API keys used in tests must be minted only for agents created inside the disposable company.
|
|
- Board token tests must use a test-specific key name and revoke the key during cleanup when the API supports it.
|
|
- Cleanup should archive or delete the disposable company when the server permits it. If deletion is disabled, the test must leave the company clearly named as disposable and report its ID.
|
|
- Commands must provide a `--yes` or non-interactive path for test setup so CI and local verification do not depend on manual prompts.
|
|
- Destructive tests must require an explicit test opt-in such as an env var or a dedicated test command; normal unit tests must not mutate a real running Paperclip instance.
|
|
|
|
## Implementation Plan
|
|
|
|
### Phase 1: Credential and Persona Foundation
|
|
|
|
- Extend CLI context to version 2 with `persona`, `agentId`, and token metadata.
|
|
- Add `connect` wizard.
|
|
- Add `token agent create/list/revoke`.
|
|
- Add `agent me`.
|
|
- Add `agent prompt` and `prompt` using issue create/comment plus optional wake.
|
|
- Harden API base resolution and connection diagnostics.
|
|
- Add tests around context migration, explicit token precedence, and persona mismatch failures.
|
|
- Add live-test helpers that always create a disposable company before exercising real API mutations.
|
|
|
|
### Phase 2: Board Token Management
|
|
|
|
- Add server endpoints for named board API key lifecycle if product approves direct token management.
|
|
- Add CLI `token board create/list/revoke`.
|
|
- Keep browser approval as the default interactive path.
|
|
- Add expiration and naming options.
|
|
|
|
### Phase 3: Core API Parity
|
|
|
|
- Add projects/goals.
|
|
- Add agent lifecycle/config/instructions.
|
|
- Add run/heartbeat inspection and cancellation.
|
|
- Add issue documents/work products/interactions/attachments/labels.
|
|
|
|
### Phase 4: Operations Parity
|
|
|
|
- Add costs/budgets/finance.
|
|
- Add access/invites/members/admin users.
|
|
- Add routines/environments/workspaces.
|
|
- Expand plugin and instance settings surfaces.
|
|
|
|
## Acceptance Criteria
|
|
|
|
- A new user can run `paperclipai connect`, confirm or override the API base, select board or agent, and get a saved working profile tied to that API base.
|
|
- A board operator can mint an agent key for a selected agent in a selected company without using `agent local-cli`.
|
|
- A script can run a one-liner equivalent to:
|
|
|
|
```sh
|
|
paperclipai agent-prompt AgentName "$AGENT_API_KEY" "Prompt here"
|
|
```
|
|
|
|
- The one-liner creates or updates Paperclip work, does not require a browser, and fails with a clear company/agent mismatch error when the token does not belong to the requested agent.
|
|
- Live/API verification creates and uses a disposable company only; no existing company is used for testing.
|
|
- CLI docs list which API route families are covered and which remain UI-only.
|
|
- Token creation, revocation, and prompt handoff have tests for board and agent auth paths.
|
|
|
|
## Risks
|
|
|
|
- Board token lifecycle endpoints may create a broader security surface if expiration, revocation, and audit logging are incomplete.
|
|
- A raw prompt command can look like chat; the implementation must keep prompts attached to issues/comments.
|
|
- Agent name selectors can be ambiguous; require exact UUID/urlKey or fail on duplicate names.
|
|
- CLI parity can sprawl. Ship by user workflow, not by endpoint count alone.
|
|
|
|
## OpenAPI Reference
|
|
|
|
The full OpenAPI source snapshot is kept next to this PRD at `doc/plans/2026-05-23-cli-api-parity-openapi-reference.ts`. Use that file when request body schemas, auth levels, response statuses, tags, operation summaries, or the complete endpoint inventory are needed.
|