Add CEO-safe company portability flows
Expose CEO-scoped import/export preview and apply routes, keep safe imports non-destructive, add export preview-first UI behavior, and document the new portability workflows. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -241,40 +241,67 @@ PATCH /api/agents/{agentId}/instructions-path
|
||||
|
||||
## Key Endpoints (Quick Reference)
|
||||
|
||||
| Action | Endpoint |
|
||||
| ------------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| My identity | `GET /api/agents/me` |
|
||||
| My compact inbox | `GET /api/agents/me/inbox-lite` |
|
||||
| My assignments | `GET /api/companies/:companyId/issues?assigneeAgentId=:id&status=todo,in_progress,blocked` |
|
||||
| Checkout task | `POST /api/issues/:issueId/checkout` |
|
||||
| Get task + ancestors | `GET /api/issues/:issueId` |
|
||||
| List issue documents | `GET /api/issues/:issueId/documents` |
|
||||
| Get issue document | `GET /api/issues/:issueId/documents/:key` |
|
||||
| Create/update issue document | `PUT /api/issues/:issueId/documents/:key` |
|
||||
| Get issue document revisions | `GET /api/issues/:issueId/documents/:key/revisions` |
|
||||
| Get compact heartbeat context | `GET /api/issues/:issueId/heartbeat-context` |
|
||||
| Get comments | `GET /api/issues/:issueId/comments` |
|
||||
| Get comment delta | `GET /api/issues/:issueId/comments?after=:commentId&order=asc` |
|
||||
| Get specific comment | `GET /api/issues/:issueId/comments/:commentId` |
|
||||
| Update task | `PATCH /api/issues/:issueId` (optional `comment` field) |
|
||||
| Add comment | `POST /api/issues/:issueId/comments` |
|
||||
| Create subtask | `POST /api/companies/:companyId/issues` |
|
||||
| Generate OpenClaw invite prompt (CEO) | `POST /api/companies/:companyId/openclaw/invite-prompt` |
|
||||
| Create project | `POST /api/companies/:companyId/projects` |
|
||||
| Create project workspace | `POST /api/projects/:projectId/workspaces` |
|
||||
| Set instructions path | `PATCH /api/agents/:agentId/instructions-path` |
|
||||
| Release task | `POST /api/issues/:issueId/release` |
|
||||
| List agents | `GET /api/companies/:companyId/agents` |
|
||||
| List company skills | `GET /api/companies/:companyId/skills` |
|
||||
| Import company skills | `POST /api/companies/:companyId/skills/import` |
|
||||
| Scan project workspaces for skills | `POST /api/companies/:companyId/skills/scan-projects` |
|
||||
| Sync agent desired skills | `POST /api/agents/:agentId/skills/sync` |
|
||||
| Dashboard | `GET /api/companies/:companyId/dashboard` |
|
||||
| Search issues | `GET /api/companies/:companyId/issues?q=search+term` |
|
||||
| Upload attachment (multipart, field=file) | `POST /api/companies/:companyId/issues/:issueId/attachments` |
|
||||
| List issue attachments | `GET /api/issues/:issueId/attachments` |
|
||||
| Get attachment content | `GET /api/attachments/:attachmentId/content` |
|
||||
| Delete attachment | `DELETE /api/attachments/:attachmentId` |
|
||||
| Action | Endpoint |
|
||||
| ----------------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| My identity | `GET /api/agents/me` |
|
||||
| My compact inbox | `GET /api/agents/me/inbox-lite` |
|
||||
| My assignments | `GET /api/companies/:companyId/issues?assigneeAgentId=:id&status=todo,in_progress,blocked` |
|
||||
| Checkout task | `POST /api/issues/:issueId/checkout` |
|
||||
| Get task + ancestors | `GET /api/issues/:issueId` |
|
||||
| List issue documents | `GET /api/issues/:issueId/documents` |
|
||||
| Get issue document | `GET /api/issues/:issueId/documents/:key` |
|
||||
| Create/update issue document | `PUT /api/issues/:issueId/documents/:key` |
|
||||
| Get issue document revisions | `GET /api/issues/:issueId/documents/:key/revisions` |
|
||||
| Get compact heartbeat context | `GET /api/issues/:issueId/heartbeat-context` |
|
||||
| Get comments | `GET /api/issues/:issueId/comments` |
|
||||
| Get comment delta | `GET /api/issues/:issueId/comments?after=:commentId&order=asc` |
|
||||
| Get specific comment | `GET /api/issues/:issueId/comments/:commentId` |
|
||||
| Update task | `PATCH /api/issues/:issueId` (optional `comment` field) |
|
||||
| Add comment | `POST /api/issues/:issueId/comments` |
|
||||
| Create subtask | `POST /api/companies/:companyId/issues` |
|
||||
| Generate OpenClaw invite prompt (CEO) | `POST /api/companies/:companyId/openclaw/invite-prompt` |
|
||||
| Create project | `POST /api/companies/:companyId/projects` |
|
||||
| Create project workspace | `POST /api/projects/:projectId/workspaces` |
|
||||
| Set instructions path | `PATCH /api/agents/:agentId/instructions-path` |
|
||||
| Release task | `POST /api/issues/:issueId/release` |
|
||||
| List agents | `GET /api/companies/:companyId/agents` |
|
||||
| List company skills | `GET /api/companies/:companyId/skills` |
|
||||
| Import company skills | `POST /api/companies/:companyId/skills/import` |
|
||||
| Scan project workspaces for skills | `POST /api/companies/:companyId/skills/scan-projects` |
|
||||
| Sync agent desired skills | `POST /api/agents/:agentId/skills/sync` |
|
||||
| Preview CEO-safe company import | `POST /api/companies/:companyId/imports/preview` |
|
||||
| Apply CEO-safe company import | `POST /api/companies/:companyId/imports/apply` |
|
||||
| Preview company export | `POST /api/companies/:companyId/exports/preview` |
|
||||
| Build company export | `POST /api/companies/:companyId/exports` |
|
||||
| Dashboard | `GET /api/companies/:companyId/dashboard` |
|
||||
| Search issues | `GET /api/companies/:companyId/issues?q=search+term` |
|
||||
| Upload attachment (multipart, field=file) | `POST /api/companies/:companyId/issues/:issueId/attachments` |
|
||||
| List issue attachments | `GET /api/issues/:issueId/attachments` |
|
||||
| Get attachment content | `GET /api/attachments/:attachmentId/content` |
|
||||
| Delete attachment | `DELETE /api/attachments/:attachmentId` |
|
||||
|
||||
## Company Import / Export
|
||||
|
||||
Use the company-scoped routes when a CEO agent needs to inspect or move package content.
|
||||
|
||||
- CEO-safe imports:
|
||||
- `POST /api/companies/{companyId}/imports/preview`
|
||||
- `POST /api/companies/{companyId}/imports/apply`
|
||||
- Allowed callers: board users and the CEO agent of that same company.
|
||||
- Safe import rules:
|
||||
- existing-company imports are non-destructive
|
||||
- `replace` is rejected
|
||||
- collisions resolve with `rename` or `skip`
|
||||
- issues are always created as new issues
|
||||
- CEO agents may use the safe routes with `target.mode = "new_company"` to create a new company directly. Paperclip copies active user memberships from the source company so the new company is not orphaned.
|
||||
|
||||
For export, preview first and keep tasks explicit:
|
||||
|
||||
- `POST /api/companies/{companyId}/exports/preview`
|
||||
- `POST /api/companies/{companyId}/exports`
|
||||
- Export preview defaults to `issues: false`
|
||||
- Add `issues` or `projectIssues` only when you intentionally need task files
|
||||
- Use `selectedFiles` to narrow the final package to specific agents, skills, projects, or tasks after you inspect the preview inventory
|
||||
|
||||
## Searching Issues
|
||||
|
||||
|
||||
@@ -39,6 +39,72 @@ Detailed reference for the Paperclip control plane API. For the core heartbeat p
|
||||
|
||||
Use `chainOfCommand` to know who to escalate to. Use `budgetMonthlyCents` and `spentMonthlyCents` to check remaining budget.
|
||||
|
||||
### Company Portability
|
||||
|
||||
CEO-safe package routes are company-scoped:
|
||||
|
||||
- `POST /api/companies/:companyId/imports/preview`
|
||||
- `POST /api/companies/:companyId/imports/apply`
|
||||
- `POST /api/companies/:companyId/exports/preview`
|
||||
- `POST /api/companies/:companyId/exports`
|
||||
|
||||
Rules:
|
||||
|
||||
- Allowed callers: board users and the CEO agent of that same company
|
||||
- Safe import routes reject `collisionStrategy: "replace"`
|
||||
- Existing-company safe imports only create new entities or skip collisions
|
||||
- `new_company` safe imports are allowed and copy active user memberships from the source company
|
||||
- Export preview defaults to `issues: false`; add task selectors explicitly when needed
|
||||
- Use `selectedFiles` on export to narrow the final package after previewing the inventory
|
||||
|
||||
Example safe import preview:
|
||||
|
||||
```json
|
||||
POST /api/companies/company-1/imports/preview
|
||||
{
|
||||
"source": { "type": "github", "url": "https://github.com/acme/agent-company" },
|
||||
"include": { "company": true, "agents": true, "projects": true, "issues": true },
|
||||
"target": { "mode": "existing_company", "companyId": "company-1" },
|
||||
"collisionStrategy": "rename"
|
||||
}
|
||||
```
|
||||
|
||||
Example new-company safe import:
|
||||
|
||||
```json
|
||||
POST /api/companies/company-1/imports/apply
|
||||
{
|
||||
"source": { "type": "github", "url": "https://github.com/acme/agent-company" },
|
||||
"include": { "company": true, "agents": true, "projects": true, "issues": false },
|
||||
"target": { "mode": "new_company", "newCompanyName": "Imported Acme" },
|
||||
"collisionStrategy": "rename"
|
||||
}
|
||||
```
|
||||
|
||||
Example export preview without tasks:
|
||||
|
||||
```json
|
||||
POST /api/companies/company-1/exports/preview
|
||||
{
|
||||
"include": { "company": true, "agents": true, "projects": true }
|
||||
}
|
||||
```
|
||||
|
||||
Example narrowed export with explicit tasks:
|
||||
|
||||
```json
|
||||
POST /api/companies/company-1/exports
|
||||
{
|
||||
"include": { "company": true, "agents": true, "projects": true, "issues": true },
|
||||
"selectedFiles": [
|
||||
"COMPANY.md",
|
||||
"agents/ceo/AGENTS.md",
|
||||
"skills/paperclip/SKILL.md",
|
||||
"tasks/pap-42/TASK.md"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Issue with Ancestors (`GET /api/issues/:issueId`)
|
||||
|
||||
Includes the issue's `project` and `goal` (with descriptions), plus each ancestor's resolved `project` and `goal`. This gives agents full context about where the task sits in the project/goal hierarchy.
|
||||
|
||||
@@ -149,3 +149,9 @@ curl -sS -X POST "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/agents"
|
||||
- Built-in Paperclip runtime skills are still added automatically when required by the adapter.
|
||||
- If a reference is missing or ambiguous, the API returns `422`.
|
||||
- Prefer linking back to the relevant issue, approval, and agent when you comment about skill changes.
|
||||
- Use company portability routes when you need whole-package import/export, not just a skill:
|
||||
- `POST /api/companies/:companyId/imports/preview`
|
||||
- `POST /api/companies/:companyId/imports/apply`
|
||||
- `POST /api/companies/:companyId/exports/preview`
|
||||
- `POST /api/companies/:companyId/exports`
|
||||
- Use skill-only import when the task is specifically to add a skill to the company library without importing the surrounding company/team/package structure.
|
||||
|
||||
Reference in New Issue
Block a user