diff --git a/skills/paperclip/SKILL.md b/skills/paperclip/SKILL.md index 5335dcbe..ee5ac2ae 100644 --- a/skills/paperclip/SKILL.md +++ b/skills/paperclip/SKILL.md @@ -126,6 +126,17 @@ Access control: 4. After OpenClaw submits the join request, monitor approvals and continue onboarding (approval + API key claim + skill install). +## Company Skills Workflow + +Authorized managers can install company skills independently of hiring, then assign or remove those skills on agents. + +- Install and inspect company skills with the company skills API. +- Assign skills to existing agents with `POST /api/agents/{agentId}/skills/sync`. +- When hiring or creating an agent, include optional `desiredSkills` so the same assignment model is applied on day one. + +If you are asked to install a skill for the company or an agent you MUST read: +`skills/paperclip/references/company-skills.md` + ## Critical Rules - **Always checkout** before working. Never PATCH to `in_progress` manually. @@ -240,60 +251,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` | -| Dashboard | `GET /api/companies/:companyId/dashboard` | -| Search issues | `GET /api/companies/:companyId/issues?q=search+term` | -| Get company details (CEO/board) | `GET /api/companies/:companyId` | -| Update company branding (CEO/board) | `PATCH /api/companies/:companyId` | -| Upload company logo | `POST /api/companies/:companyId/logo` (multipart file upload) | +| 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 Branding (CEO) +## Company Import / Export -CEO agents can read and update their company's branding. Board users have full access to all company fields. +Use the company-scoped routes when a CEO agent needs to inspect or move package content. -**Readable fields** (via `GET /api/companies/:companyId`): +- 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. -All company fields including `name`, `description`, `brandColor`, `logoUrl`, `issuePrefix`. +For export, preview first and keep tasks explicit: -**Updatable fields** (CEO agents, via `PATCH /api/companies/:companyId`): - -| Field | Type | Notes | -| ------------- | ------------------------ | ----------------------------------------- | -| `name` | string | Company display name | -| `description` | string \| null | Company description | -| `brandColor` | string \| null | Hex color, e.g. `#FF5733` | -| `logoAssetId` | UUID string \| null | Set after uploading via the logo endpoint | - -**Protected fields** (board-only): `status`, `budgetMonthlyCents`, `spentMonthlyCents`, `requireBoardApprovalForNewAgents`. The `issuePrefix` (company slug) cannot be changed via API. - -**Logo upload flow:** - -1. Upload: `POST /api/companies/:companyId/logo` with `Content-Type: multipart/form-data`, field name `file`. Accepts PNG, JPEG, WebP, GIF, SVG (max 10 MB). -2. Set: `PATCH /api/companies/:companyId` with `{ "logoAssetId": "" }`. -3. Clear: `PATCH /api/companies/:companyId` with `{ "logoAssetId": null }`. +- `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 diff --git a/skills/paperclip/references/company-skills.md b/skills/paperclip/references/company-skills.md new file mode 100644 index 00000000..a0ddd064 --- /dev/null +++ b/skills/paperclip/references/company-skills.md @@ -0,0 +1,187 @@ +# Company Skills Workflow + +Use this reference when a board user, CEO, or manager asks you to find a skill, install it into the company library, or assign it to an agent. + +## What Exists + +- Company skill library: install, inspect, update, and read imported skills for the whole company. +- Agent skill assignment: add or remove company skills on an existing agent. +- Hire/create composition: pass `desiredSkills` when creating or hiring an agent so the same assignment model applies immediately. + +The canonical model is: + +1. install the skill into the company +2. assign the company skill to the agent +3. optionally do step 2 during hire/create with `desiredSkills` + +## Permission Model + +- Company skill reads: any same-company actor +- Company skill mutations: board, CEO, or an agent with the effective `agents:create` capability +- Agent skill assignment: same permission model as updating that agent + +## Core Endpoints + +- `GET /api/companies/:companyId/skills` +- `GET /api/companies/:companyId/skills/:skillId` +- `POST /api/companies/:companyId/skills/import` +- `POST /api/companies/:companyId/skills/scan-projects` +- `POST /api/companies/:companyId/skills/:skillId/install-update` +- `GET /api/agents/:agentId/skills` +- `POST /api/agents/:agentId/skills/sync` +- `POST /api/companies/:companyId/agent-hires` +- `POST /api/companies/:companyId/agents` + +## Install A Skill Into The Company + +Import using a **skills.sh URL**, a key-style source string, a GitHub URL, or a local path. + +### Source types (in order of preference) + +| Source format | Example | When to use | +|---|---|---| +| **skills.sh URL** | `https://skills.sh/google-labs-code/stitch-skills/design-md` | When a user gives you a `skills.sh` link. This is the managed skill registry — **always prefer it when available**. | +| **Key-style string** | `google-labs-code/stitch-skills/design-md` | Shorthand for the same skill — `org/repo/skill-name` format. Equivalent to the skills.sh URL. | +| **GitHub URL** | `https://github.com/vercel-labs/agent-browser` | When the skill is in a GitHub repo but not on skills.sh. | +| **Local path** | `/abs/path/to/skill-dir` | When the skill is on disk (dev/testing only). | + +**Critical:** If a user gives you a `https://skills.sh/...` URL, use that URL or its key-style equivalent (`org/repo/skill-name`) as the `source`. Do **not** convert it to a GitHub URL — skills.sh is the managed registry and the source of truth for versioning, discovery, and updates. + +### Example: skills.sh import (preferred) + +```sh +curl -sS -X POST "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/skills/import" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "source": "https://skills.sh/google-labs-code/stitch-skills/design-md" + }' +``` + +Or equivalently using the key-style string: + +```sh +curl -sS -X POST "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/skills/import" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "source": "google-labs-code/stitch-skills/design-md" + }' +``` + +### Example: GitHub import + +```sh +curl -sS -X POST "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/skills/import" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "source": "https://github.com/vercel-labs/agent-browser" + }' +``` + +If the task is to discover skills from the company project workspaces first: + +```sh +curl -sS -X POST "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/skills/scan-projects" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{}' +``` + +## Inspect What Was Installed + +```sh +curl -sS "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/skills" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" +``` + +Read the skill entry and its `SKILL.md`: + +```sh +curl -sS "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/skills/" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" + +curl -sS "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/skills//files?path=SKILL.md" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" +``` + +## Assign Skills To An Existing Agent + +`desiredSkills` accepts: + +- exact company skill key +- exact company skill id +- exact slug when it is unique in the company + +The server persists canonical company skill keys. + +```sh +curl -sS -X POST "$PAPERCLIP_API_URL/api/agents//skills/sync" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "desiredSkills": [ + "vercel-labs/agent-browser/agent-browser" + ] + }' +``` + +If you need the current state first: + +```sh +curl -sS "$PAPERCLIP_API_URL/api/agents//skills" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" +``` + +## Include Skills During Hire Or Create + +Use the same company skill keys or references in `desiredSkills` when hiring or creating an agent: + +```sh +curl -sS -X POST "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/agent-hires" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "QA Browser Agent", + "role": "qa", + "adapterType": "codex_local", + "adapterConfig": { + "cwd": "/abs/path/to/repo" + }, + "desiredSkills": [ + "agent-browser" + ] + }' +``` + +For direct create without approval: + +```sh +curl -sS -X POST "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/agents" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "QA Browser Agent", + "role": "qa", + "adapterType": "codex_local", + "adapterConfig": { + "cwd": "/abs/path/to/repo" + }, + "desiredSkills": [ + "agent-browser" + ] + }' +``` + +## Notes + +- 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.