@paperclipai/adapter-codex-local 0.2.7 → 0.3.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/skills/paperclip/SKILL.md +77 -10
- package/skills/paperclip/references/api-reference.md +24 -3
- package/skills/release/SKILL.md +247 -0
- package/skills/release-changelog/SKILL.md +140 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Paperclip AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,gBAAgB,CAAC;AAClC,eAAO,MAAM,KAAK,kBAAkB,CAAC;AACrC,eAAO,MAAM,yBAAyB,kBAAkB,CAAC;AACzD,eAAO,MAAM,gDAAgD,OAAO,CAAC;AAErE,eAAO,MAAM,MAAM;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,gBAAgB,CAAC;AAClC,eAAO,MAAM,KAAK,kBAAkB,CAAC;AACrC,eAAO,MAAM,yBAAyB,kBAAkB,CAAC;AACzD,eAAO,MAAM,gDAAgD,OAAO,CAAC;AAErE,eAAO,MAAM,MAAM;;;GAWlB,CAAC;AAEF,eAAO,MAAM,qBAAqB,w3CAwBjC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export const label = "Codex (local)";
|
|
|
3
3
|
export const DEFAULT_CODEX_LOCAL_MODEL = "gpt-5.3-codex";
|
|
4
4
|
export const DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX = true;
|
|
5
5
|
export const models = [
|
|
6
|
+
{ id: "gpt-5.4", label: "gpt-5.4" },
|
|
6
7
|
{ id: DEFAULT_CODEX_LOCAL_MODEL, label: DEFAULT_CODEX_LOCAL_MODEL },
|
|
7
8
|
{ id: "gpt-5.3-codex-spark", label: "gpt-5.3-codex-spark" },
|
|
8
9
|
{ id: "gpt-5", label: "gpt-5" },
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG,aAAa,CAAC;AAClC,MAAM,CAAC,MAAM,KAAK,GAAG,eAAe,CAAC;AACrC,MAAM,CAAC,MAAM,yBAAyB,GAAG,eAAe,CAAC;AACzD,MAAM,CAAC,MAAM,gDAAgD,GAAG,IAAI,CAAC;AAErE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,EAAE,EAAE,EAAE,yBAAyB,EAAE,KAAK,EAAE,yBAAyB,EAAE;IACnE,EAAE,EAAE,EAAE,qBAAqB,EAAE,KAAK,EAAE,qBAAqB,EAAE;IAC3D,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;IAC/B,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;IACzB,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;IACnC,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;IACzC,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;IACzC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;IACnC,EAAE,EAAE,EAAE,mBAAmB,EAAE,KAAK,EAAE,YAAY,EAAE;CACjD,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwBpC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG,aAAa,CAAC;AAClC,MAAM,CAAC,MAAM,KAAK,GAAG,eAAe,CAAC;AACrC,MAAM,CAAC,MAAM,yBAAyB,GAAG,eAAe,CAAC;AACzD,MAAM,CAAC,MAAM,gDAAgD,GAAG,IAAI,CAAC;AAErE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;IACnC,EAAE,EAAE,EAAE,yBAAyB,EAAE,KAAK,EAAE,yBAAyB,EAAE;IACnE,EAAE,EAAE,EAAE,qBAAqB,EAAE,KAAK,EAAE,qBAAqB,EAAE;IAC3D,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;IAC/B,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;IACzB,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;IACnC,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;IACzC,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;IACzC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;IACnC,EAAE,EAAE,EAAE,mBAAmB,EAAE,KAAK,EAAE,YAAY,EAAE;CACjD,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwBpC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paperclipai/adapter-codex-local",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-canary.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -29,9 +29,10 @@
|
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"picocolors": "^1.1.1",
|
|
32
|
-
"@paperclipai/adapter-utils": "0.
|
|
32
|
+
"@paperclipai/adapter-utils": "0.3.0-canary.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
+
"@types/node": "^24.6.0",
|
|
35
36
|
"typescript": "^5.7.3"
|
|
36
37
|
},
|
|
37
38
|
"scripts": {
|
|
@@ -16,6 +16,8 @@ You run in **heartbeats** — short execution windows triggered by Paperclip. Ea
|
|
|
16
16
|
|
|
17
17
|
Env vars auto-injected: `PAPERCLIP_AGENT_ID`, `PAPERCLIP_COMPANY_ID`, `PAPERCLIP_API_URL`, `PAPERCLIP_RUN_ID`. Optional wake-context vars may also be present: `PAPERCLIP_TASK_ID` (issue/task that triggered this wake), `PAPERCLIP_WAKE_REASON` (why this run was triggered), `PAPERCLIP_WAKE_COMMENT_ID` (specific comment that triggered this wake), `PAPERCLIP_APPROVAL_ID`, `PAPERCLIP_APPROVAL_STATUS`, and `PAPERCLIP_LINKED_ISSUE_IDS` (comma-separated). For local adapters, `PAPERCLIP_API_KEY` is auto-injected as a short-lived run JWT. For non-local adapters, your operator should set `PAPERCLIP_API_KEY` in adapter config. All requests use `Authorization: Bearer $PAPERCLIP_API_KEY`. All endpoints under `/api`, all JSON. Never hard-code the API URL.
|
|
18
18
|
|
|
19
|
+
Manual local CLI mode (outside heartbeat runs): use `paperclipai agent local-cli <agent-id-or-shortname> --company-id <company-id>` to install Paperclip skills for Claude/Codex and print/export the required `PAPERCLIP_*` environment variables for that agent identity.
|
|
20
|
+
|
|
19
21
|
**Run audit trail:** You MUST include `-H 'X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID'` on ALL API requests that modify issues (checkout, update, comment, create subtask, release). This links your actions to the current heartbeat run for traceability.
|
|
20
22
|
|
|
21
23
|
## The Heartbeat Procedure
|
|
@@ -89,6 +91,30 @@ Workspace rules:
|
|
|
89
91
|
- For repo-only setup, omit `cwd` and provide `repoUrl`.
|
|
90
92
|
- Include both `cwd` + `repoUrl` when local and remote references should both be tracked.
|
|
91
93
|
|
|
94
|
+
## OpenClaw Invite Workflow (CEO)
|
|
95
|
+
|
|
96
|
+
Use this when asked to invite a new OpenClaw employee.
|
|
97
|
+
|
|
98
|
+
1. Generate a fresh OpenClaw invite prompt:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
POST /api/companies/{companyId}/openclaw/invite-prompt
|
|
102
|
+
{ "agentMessage": "optional onboarding note for OpenClaw" }
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Access control:
|
|
106
|
+
- Board users with invite permission can call it.
|
|
107
|
+
- Agent callers: only the company CEO agent can call it.
|
|
108
|
+
|
|
109
|
+
2. Build the copy-ready OpenClaw prompt for the board:
|
|
110
|
+
- Use `onboardingTextUrl` from the response.
|
|
111
|
+
- Ask the board to paste that prompt into OpenClaw.
|
|
112
|
+
- If the issue includes an OpenClaw URL (for example `ws://127.0.0.1:18789`), include that URL in your comment so the board/OpenClaw uses it in `agentDefaultsPayload.url`.
|
|
113
|
+
|
|
114
|
+
3. Post the prompt in the issue comment so the human can paste it into OpenClaw.
|
|
115
|
+
|
|
116
|
+
4. After OpenClaw submits the join request, monitor approvals and continue onboarding (approval + API key claim + skill install).
|
|
117
|
+
|
|
92
118
|
## Critical Rules
|
|
93
119
|
|
|
94
120
|
- **Always checkout** before working. Never PATCH to `in_progress` manually.
|
|
@@ -112,16 +138,18 @@ When posting issue comments, use concise markdown with:
|
|
|
112
138
|
|
|
113
139
|
- a short status line
|
|
114
140
|
- bullets for what changed / what is blocked
|
|
115
|
-
- links to related entities when available
|
|
141
|
+
- links to related entities when available
|
|
116
142
|
|
|
117
|
-
|
|
143
|
+
**Company-prefixed URLs (required):** All internal links MUST include the company prefix. Derive the prefix from any issue identifier you have (e.g., `PAP-315` → prefix is `PAP`). Use this prefix in all UI links:
|
|
118
144
|
|
|
119
|
-
- Issues:
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
-
|
|
145
|
+
- Issues: `/<prefix>/issues/<issue-identifier>` (e.g., `/PAP/issues/PAP-224`)
|
|
146
|
+
- Issue comments: `/<prefix>/issues/<issue-identifier>#comment-<comment-id>` (deep link to a specific comment)
|
|
147
|
+
- Agents: `/<prefix>/agents/<agent-url-key>` (e.g., `/PAP/agents/claudecoder`)
|
|
148
|
+
- Projects: `/<prefix>/projects/<project-url-key>` (id fallback allowed)
|
|
149
|
+
- Approvals: `/<prefix>/approvals/<approval-id>`
|
|
150
|
+
- Runs: `/<prefix>/agents/<agent-url-key-or-id>/runs/<run-id>`
|
|
123
151
|
|
|
124
|
-
|
|
152
|
+
Do NOT use unprefixed paths like `/issues/PAP-123` or `/agents/cto` — always include the company prefix.
|
|
125
153
|
|
|
126
154
|
Example:
|
|
127
155
|
|
|
@@ -130,9 +158,9 @@ Example:
|
|
|
130
158
|
|
|
131
159
|
Submitted CTO hire request and linked it for board review.
|
|
132
160
|
|
|
133
|
-
- Approval: [ca6ba09d](/approvals/ca6ba09d-b558-4a53-a552-e7ef87e54a1b)
|
|
134
|
-
- Pending agent: [CTO draft](/agents/cto)
|
|
135
|
-
- Source issue: [PC-142](/issues/PC-142)
|
|
161
|
+
- Approval: [ca6ba09d](/PAP/approvals/ca6ba09d-b558-4a53-a552-e7ef87e54a1b)
|
|
162
|
+
- Pending agent: [CTO draft](/PAP/agents/cto)
|
|
163
|
+
- Source issue: [PC-142](/PAP/issues/PC-142)
|
|
136
164
|
```
|
|
137
165
|
|
|
138
166
|
## Planning (Required when planning requested)
|
|
@@ -198,9 +226,11 @@ PATCH /api/agents/{agentId}/instructions-path
|
|
|
198
226
|
| Checkout task | `POST /api/issues/:issueId/checkout` |
|
|
199
227
|
| Get task + ancestors | `GET /api/issues/:issueId` |
|
|
200
228
|
| Get comments | `GET /api/issues/:issueId/comments` |
|
|
229
|
+
| Get specific comment | `GET /api/issues/:issueId/comments/:commentId` |
|
|
201
230
|
| Update task | `PATCH /api/issues/:issueId` (optional `comment` field) |
|
|
202
231
|
| Add comment | `POST /api/issues/:issueId/comments` |
|
|
203
232
|
| Create subtask | `POST /api/companies/:companyId/issues` |
|
|
233
|
+
| Generate OpenClaw invite prompt (CEO) | `POST /api/companies/:companyId/openclaw/invite-prompt` |
|
|
204
234
|
| Create project | `POST /api/companies/:companyId/projects` |
|
|
205
235
|
| Create project workspace | `POST /api/projects/:projectId/workspaces` |
|
|
206
236
|
| Set instructions path | `PATCH /api/agents/:agentId/instructions-path` |
|
|
@@ -219,6 +249,43 @@ GET /api/companies/{companyId}/issues?q=dockerfile
|
|
|
219
249
|
|
|
220
250
|
Results are ranked by relevance: title matches first, then identifier, description, and comments. You can combine `q` with other filters (`status`, `assigneeAgentId`, `projectId`, `labelId`).
|
|
221
251
|
|
|
252
|
+
## Self-Test Playbook (App-Level)
|
|
253
|
+
|
|
254
|
+
Use this when validating Paperclip itself (assignment flow, checkouts, run visibility, and status transitions).
|
|
255
|
+
|
|
256
|
+
1. Create a throwaway issue assigned to a known local agent (`claudecoder` or `codexcoder`):
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
pnpm paperclipai issue create \
|
|
260
|
+
--company-id "$PAPERCLIP_COMPANY_ID" \
|
|
261
|
+
--title "Self-test: assignment/watch flow" \
|
|
262
|
+
--description "Temporary validation issue" \
|
|
263
|
+
--status todo \
|
|
264
|
+
--assignee-agent-id "$PAPERCLIP_AGENT_ID"
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
2. Trigger and watch a heartbeat for that assignee:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
pnpm paperclipai heartbeat run --agent-id "$PAPERCLIP_AGENT_ID"
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
3. Verify the issue transitions (`todo -> in_progress -> done` or `blocked`) and that comments are posted:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
pnpm paperclipai issue get <issue-id-or-identifier>
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
4. Reassignment test (optional): move the same issue between `claudecoder` and `codexcoder` and confirm wake/run behavior:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
pnpm paperclipai issue update <issue-id> --assignee-agent-id <other-agent-id> --status todo
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
5. Cleanup: mark temporary issues done/cancelled with a clear note.
|
|
286
|
+
|
|
287
|
+
If you use direct `curl` during these tests, include `X-Paperclip-Run-Id` on all mutating issue requests whenever running inside a heartbeat.
|
|
288
|
+
|
|
222
289
|
## Full Reference
|
|
223
290
|
|
|
224
291
|
For detailed API tables, JSON response schemas, worked examples (IC and Manager heartbeats), governance/approvals, cross-team delegation rules, error codes, issue lifecycle diagram, and the common mistakes table, read: `skills/paperclip/references/api-reference.md`
|
|
@@ -216,11 +216,13 @@ Use markdown formatting and include links to related entities when they exist:
|
|
|
216
216
|
```md
|
|
217
217
|
## Update
|
|
218
218
|
|
|
219
|
-
- Approval: [APPROVAL_ID](
|
|
220
|
-
- Pending agent: [AGENT_NAME](
|
|
221
|
-
- Source issue: [ISSUE_ID](
|
|
219
|
+
- Approval: [APPROVAL_ID](/<prefix>/approvals/<approval-id>)
|
|
220
|
+
- Pending agent: [AGENT_NAME](/<prefix>/agents/<agent-url-key-or-id>)
|
|
221
|
+
- Source issue: [ISSUE_ID](/<prefix>/issues/<issue-identifier-or-id>)
|
|
222
222
|
```
|
|
223
223
|
|
|
224
|
+
Where `<prefix>` is the company prefix derived from the issue identifier (e.g., `PAP-123` → prefix is `PAP`).
|
|
225
|
+
|
|
224
226
|
**@-mentions:** Mention another agent by name using `@AgentName` to automatically wake them:
|
|
225
227
|
|
|
226
228
|
```
|
|
@@ -278,6 +280,23 @@ GET /api/companies/{companyId}/dashboard — health summary: agent/task counts,
|
|
|
278
280
|
|
|
279
281
|
Use the dashboard for situational awareness, especially if you're a manager or CEO.
|
|
280
282
|
|
|
283
|
+
## OpenClaw Invite Prompt (CEO)
|
|
284
|
+
|
|
285
|
+
Use this endpoint to generate a short-lived OpenClaw onboarding invite prompt:
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
POST /api/companies/{companyId}/openclaw/invite-prompt
|
|
289
|
+
{
|
|
290
|
+
"agentMessage": "optional note for the joining OpenClaw agent"
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Response includes invite token, onboarding text URL, and expiry metadata.
|
|
295
|
+
|
|
296
|
+
Access is intentionally constrained:
|
|
297
|
+
- board users with invite permission
|
|
298
|
+
- CEO agent only (non-CEO agents are rejected)
|
|
299
|
+
|
|
281
300
|
---
|
|
282
301
|
|
|
283
302
|
## Setting Agent Instructions Path
|
|
@@ -479,6 +498,7 @@ Terminal states: `done`, `cancelled`
|
|
|
479
498
|
| POST | `/api/issues/:issueId/checkout` | Atomic checkout (claim + start). Idempotent if you already own it. |
|
|
480
499
|
| POST | `/api/issues/:issueId/release` | Release task ownership |
|
|
481
500
|
| GET | `/api/issues/:issueId/comments` | List comments |
|
|
501
|
+
| GET | `/api/issues/:issueId/comments/:commentId` | Get a specific comment by ID |
|
|
482
502
|
| POST | `/api/issues/:issueId/comments` | Add comment (@-mentions trigger wakeups) |
|
|
483
503
|
| GET | `/api/issues/:issueId/approvals` | List approvals linked to issue |
|
|
484
504
|
| POST | `/api/issues/:issueId/approvals` | Link approval to issue |
|
|
@@ -502,6 +522,7 @@ Terminal states: `done`, `cancelled`
|
|
|
502
522
|
| GET | `/api/goals/:goalId` | Goal details |
|
|
503
523
|
| POST | `/api/companies/:companyId/goals` | Create goal |
|
|
504
524
|
| PATCH | `/api/goals/:goalId` | Update goal |
|
|
525
|
+
| POST | `/api/companies/:companyId/openclaw/invite-prompt` | Generate OpenClaw invite prompt (CEO/board only) |
|
|
505
526
|
|
|
506
527
|
### Approvals, Costs, Activity, Dashboard
|
|
507
528
|
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release
|
|
3
|
+
description: >
|
|
4
|
+
Coordinate a full Paperclip release across engineering verification, npm,
|
|
5
|
+
GitHub, website publishing, and announcement follow-up. Use when leadership
|
|
6
|
+
asks to ship a release, not merely to discuss version bumps.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Release Coordination Skill
|
|
10
|
+
|
|
11
|
+
Run the full Paperclip release as a maintainer workflow, not just an npm publish.
|
|
12
|
+
|
|
13
|
+
This skill coordinates:
|
|
14
|
+
|
|
15
|
+
- stable changelog drafting via `release-changelog`
|
|
16
|
+
- prerelease canary publishing via `scripts/release.sh --canary`
|
|
17
|
+
- Docker smoke testing via `scripts/docker-onboard-smoke.sh`
|
|
18
|
+
- stable publishing via `scripts/release.sh`
|
|
19
|
+
- pushing the release commit and tag
|
|
20
|
+
- GitHub Release creation via `scripts/create-github-release.sh`
|
|
21
|
+
- website / announcement follow-up tasks
|
|
22
|
+
|
|
23
|
+
## Trigger
|
|
24
|
+
|
|
25
|
+
Use this skill when leadership asks for:
|
|
26
|
+
|
|
27
|
+
- "do a release"
|
|
28
|
+
- "ship the next patch/minor/major"
|
|
29
|
+
- "release vX.Y.Z"
|
|
30
|
+
|
|
31
|
+
## Preconditions
|
|
32
|
+
|
|
33
|
+
Before proceeding, verify all of the following:
|
|
34
|
+
|
|
35
|
+
1. `skills/release-changelog/SKILL.md` exists and is usable.
|
|
36
|
+
2. The repo working tree is clean, including untracked files.
|
|
37
|
+
3. There are commits since the last stable tag.
|
|
38
|
+
4. The release SHA has passed the verification gate or is about to.
|
|
39
|
+
5. npm publish rights are available locally, or the GitHub release workflow is being used with trusted publishing.
|
|
40
|
+
6. If running through Paperclip, you have issue context for status updates and follow-up task creation.
|
|
41
|
+
|
|
42
|
+
If any precondition fails, stop and report the blocker.
|
|
43
|
+
|
|
44
|
+
## Inputs
|
|
45
|
+
|
|
46
|
+
Collect these inputs up front:
|
|
47
|
+
|
|
48
|
+
- requested bump: `patch`, `minor`, or `major`
|
|
49
|
+
- whether this run is a dry run or live release
|
|
50
|
+
- whether the release is being run locally or from GitHub Actions
|
|
51
|
+
- release issue / company context for website and announcement follow-up
|
|
52
|
+
|
|
53
|
+
## Step 0 — Release Model
|
|
54
|
+
|
|
55
|
+
Paperclip now uses this release model:
|
|
56
|
+
|
|
57
|
+
1. Draft the **stable** changelog as `releases/vX.Y.Z.md`
|
|
58
|
+
2. Publish one or more **prerelease canaries** such as `X.Y.Z-canary.0`
|
|
59
|
+
3. Smoke test the canary via Docker
|
|
60
|
+
4. Publish the stable version `X.Y.Z`
|
|
61
|
+
5. Push the release commit and tag
|
|
62
|
+
6. Create the GitHub Release
|
|
63
|
+
7. Complete website and announcement surfaces
|
|
64
|
+
|
|
65
|
+
Critical consequence:
|
|
66
|
+
|
|
67
|
+
- Canaries do **not** use promote-by-dist-tag anymore.
|
|
68
|
+
- The changelog remains stable-only. Do not create `releases/vX.Y.Z-canary.N.md`.
|
|
69
|
+
|
|
70
|
+
## Step 1 — Decide the Stable Version
|
|
71
|
+
|
|
72
|
+
Run release preflight first:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
./scripts/release-preflight.sh canary {patch|minor|major}
|
|
76
|
+
# or
|
|
77
|
+
./scripts/release-preflight.sh stable {patch|minor|major}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Then use the last stable tag as the base:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
LAST_TAG=$(git tag --list 'v*' --sort=-version:refname | head -1)
|
|
84
|
+
git log "${LAST_TAG}..HEAD" --oneline --no-merges
|
|
85
|
+
git diff --name-only "${LAST_TAG}..HEAD" -- packages/db/src/migrations/
|
|
86
|
+
git diff "${LAST_TAG}..HEAD" -- packages/db/src/schema/
|
|
87
|
+
git log "${LAST_TAG}..HEAD" --format="%s" | rg -n 'BREAKING CHANGE|BREAKING:|^[a-z]+!:' || true
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Bump policy:
|
|
91
|
+
|
|
92
|
+
- destructive migrations, removed APIs, breaking config changes -> `major`
|
|
93
|
+
- additive migrations or clearly user-visible features -> at least `minor`
|
|
94
|
+
- fixes only -> `patch`
|
|
95
|
+
|
|
96
|
+
If the requested bump is too low, escalate it and explain why.
|
|
97
|
+
|
|
98
|
+
## Step 2 — Draft the Stable Changelog
|
|
99
|
+
|
|
100
|
+
Invoke `release-changelog` and generate:
|
|
101
|
+
|
|
102
|
+
- `releases/vX.Y.Z.md`
|
|
103
|
+
|
|
104
|
+
Rules:
|
|
105
|
+
|
|
106
|
+
- review the draft with a human before publish
|
|
107
|
+
- preserve manual edits if the file already exists
|
|
108
|
+
- keep the heading and filename stable-only, for example `v1.2.3`
|
|
109
|
+
- do not create a separate canary changelog file
|
|
110
|
+
|
|
111
|
+
## Step 3 — Verify the Release SHA
|
|
112
|
+
|
|
113
|
+
Run the standard gate:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
pnpm -r typecheck
|
|
117
|
+
pnpm test:run
|
|
118
|
+
pnpm build
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
If the release will be run through GitHub Actions, the workflow can rerun this gate. Still report whether the local tree currently passes.
|
|
122
|
+
|
|
123
|
+
## Step 4 — Publish a Canary
|
|
124
|
+
|
|
125
|
+
Run:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
./scripts/release.sh {patch|minor|major} --canary --dry-run
|
|
129
|
+
./scripts/release.sh {patch|minor|major} --canary
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
What this means:
|
|
133
|
+
|
|
134
|
+
- npm receives `X.Y.Z-canary.N` under dist-tag `canary`
|
|
135
|
+
- `latest` remains unchanged
|
|
136
|
+
- no git tag is created
|
|
137
|
+
- the script cleans the working tree afterward
|
|
138
|
+
|
|
139
|
+
Guard:
|
|
140
|
+
|
|
141
|
+
- if the current stable is `0.2.7`, the next patch canary is `0.2.8-canary.0`
|
|
142
|
+
- the tooling must never publish `0.2.7-canary.N` after `0.2.7` is already stable
|
|
143
|
+
|
|
144
|
+
After publish, verify:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm view paperclipai@canary version
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
The user install path is:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
npx paperclipai@canary onboard
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Step 5 — Smoke Test the Canary
|
|
157
|
+
|
|
158
|
+
Run:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
PAPERCLIPAI_VERSION=canary ./scripts/docker-onboard-smoke.sh
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Confirm:
|
|
165
|
+
|
|
166
|
+
1. install succeeds
|
|
167
|
+
2. onboarding completes
|
|
168
|
+
3. server boots
|
|
169
|
+
4. UI loads
|
|
170
|
+
5. basic company/dashboard flow works
|
|
171
|
+
|
|
172
|
+
If smoke testing fails:
|
|
173
|
+
|
|
174
|
+
- stop the stable release
|
|
175
|
+
- fix the issue
|
|
176
|
+
- publish another canary
|
|
177
|
+
- repeat the smoke test
|
|
178
|
+
|
|
179
|
+
Each retry should create a higher canary ordinal, while the stable target version can stay the same.
|
|
180
|
+
|
|
181
|
+
## Step 6 — Publish Stable
|
|
182
|
+
|
|
183
|
+
Once the SHA is vetted, run:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
./scripts/release.sh {patch|minor|major} --dry-run
|
|
187
|
+
./scripts/release.sh {patch|minor|major}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Stable publish does this:
|
|
191
|
+
|
|
192
|
+
- publishes `X.Y.Z` to npm under `latest`
|
|
193
|
+
- creates the local release commit
|
|
194
|
+
- creates the local git tag `vX.Y.Z`
|
|
195
|
+
|
|
196
|
+
Stable publish does **not** push the release for you.
|
|
197
|
+
|
|
198
|
+
## Step 7 — Push and Create GitHub Release
|
|
199
|
+
|
|
200
|
+
After stable publish succeeds:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
git push origin HEAD:master --follow-tags
|
|
204
|
+
./scripts/create-github-release.sh X.Y.Z
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Use the stable changelog file as the GitHub Release notes source.
|
|
208
|
+
|
|
209
|
+
## Step 8 — Finish the Other Surfaces
|
|
210
|
+
|
|
211
|
+
Create or verify follow-up work for:
|
|
212
|
+
|
|
213
|
+
- website changelog publishing
|
|
214
|
+
- launch post / social announcement
|
|
215
|
+
- any release summary in Paperclip issue context
|
|
216
|
+
|
|
217
|
+
These should reference the stable release, not the canary.
|
|
218
|
+
|
|
219
|
+
## Failure Handling
|
|
220
|
+
|
|
221
|
+
If the canary is bad:
|
|
222
|
+
|
|
223
|
+
- publish another canary, do not ship stable
|
|
224
|
+
|
|
225
|
+
If stable npm publish succeeds but push or GitHub release creation fails:
|
|
226
|
+
|
|
227
|
+
- fix the git/GitHub issue immediately from the same checkout
|
|
228
|
+
- do not republish the same version
|
|
229
|
+
|
|
230
|
+
If `latest` is bad after stable publish:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
./scripts/rollback-latest.sh <last-good-version>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Then fix forward with a new patch release.
|
|
237
|
+
|
|
238
|
+
## Output
|
|
239
|
+
|
|
240
|
+
When the skill completes, provide:
|
|
241
|
+
|
|
242
|
+
- stable version and, if relevant, the final canary version tested
|
|
243
|
+
- verification status
|
|
244
|
+
- npm status
|
|
245
|
+
- git tag / GitHub Release status
|
|
246
|
+
- website / announcement follow-up status
|
|
247
|
+
- rollback recommendation if anything is still partially complete
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release-changelog
|
|
3
|
+
description: >
|
|
4
|
+
Generate the stable Paperclip release changelog at releases/v{version}.md by
|
|
5
|
+
reading commits, changesets, and merged PR context since the last stable tag.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Release Changelog Skill
|
|
9
|
+
|
|
10
|
+
Generate the user-facing changelog for the **stable** Paperclip release.
|
|
11
|
+
|
|
12
|
+
Output:
|
|
13
|
+
|
|
14
|
+
- `releases/v{version}.md`
|
|
15
|
+
|
|
16
|
+
Important rule:
|
|
17
|
+
|
|
18
|
+
- even if there are canary releases such as `1.2.3-canary.0`, the changelog file stays `releases/v1.2.3.md`
|
|
19
|
+
|
|
20
|
+
## Step 0 — Idempotency Check
|
|
21
|
+
|
|
22
|
+
Before generating anything, check whether the file already exists:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
ls releases/v{version}.md 2>/dev/null
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
If it exists:
|
|
29
|
+
|
|
30
|
+
1. read it first
|
|
31
|
+
2. present it to the reviewer
|
|
32
|
+
3. ask whether to keep it, regenerate it, or update specific sections
|
|
33
|
+
4. never overwrite it silently
|
|
34
|
+
|
|
35
|
+
## Step 1 — Determine the Stable Range
|
|
36
|
+
|
|
37
|
+
Find the last stable tag:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
git tag --list 'v*' --sort=-version:refname | head -1
|
|
41
|
+
git log v{last}..HEAD --oneline --no-merges
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The planned stable version comes from one of:
|
|
45
|
+
|
|
46
|
+
- an explicit maintainer request
|
|
47
|
+
- the chosen bump type applied to the last stable tag
|
|
48
|
+
- the release plan already agreed in `doc/RELEASING.md`
|
|
49
|
+
|
|
50
|
+
Do not derive the changelog version from a canary tag or prerelease suffix.
|
|
51
|
+
|
|
52
|
+
## Step 2 — Gather the Raw Inputs
|
|
53
|
+
|
|
54
|
+
Collect release data from:
|
|
55
|
+
|
|
56
|
+
1. git commits since the last stable tag
|
|
57
|
+
2. `.changeset/*.md` files
|
|
58
|
+
3. merged PRs via `gh` when available
|
|
59
|
+
|
|
60
|
+
Useful commands:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
git log v{last}..HEAD --oneline --no-merges
|
|
64
|
+
git log v{last}..HEAD --format="%H %s" --no-merges
|
|
65
|
+
ls .changeset/*.md | grep -v README.md
|
|
66
|
+
gh pr list --state merged --search "merged:>={last-tag-date}" --json number,title,body,labels
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Step 3 — Detect Breaking Changes
|
|
70
|
+
|
|
71
|
+
Look for:
|
|
72
|
+
|
|
73
|
+
- destructive migrations
|
|
74
|
+
- removed or changed API fields/endpoints
|
|
75
|
+
- renamed or removed config keys
|
|
76
|
+
- `major` changesets
|
|
77
|
+
- `BREAKING:` or `BREAKING CHANGE:` commit signals
|
|
78
|
+
|
|
79
|
+
Key commands:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
git diff --name-only v{last}..HEAD -- packages/db/src/migrations/
|
|
83
|
+
git diff v{last}..HEAD -- packages/db/src/schema/
|
|
84
|
+
git diff v{last}..HEAD -- server/src/routes/ server/src/api/
|
|
85
|
+
git log v{last}..HEAD --format="%s" | rg -n 'BREAKING CHANGE|BREAKING:|^[a-z]+!:' || true
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
If the requested bump is lower than the minimum required bump, flag that before the release proceeds.
|
|
89
|
+
|
|
90
|
+
## Step 4 — Categorize for Users
|
|
91
|
+
|
|
92
|
+
Use these stable changelog sections:
|
|
93
|
+
|
|
94
|
+
- `Breaking Changes`
|
|
95
|
+
- `Highlights`
|
|
96
|
+
- `Improvements`
|
|
97
|
+
- `Fixes`
|
|
98
|
+
- `Upgrade Guide` when needed
|
|
99
|
+
|
|
100
|
+
Exclude purely internal refactors, CI changes, and docs-only work unless they materially affect users.
|
|
101
|
+
|
|
102
|
+
Guidelines:
|
|
103
|
+
|
|
104
|
+
- group related commits into one user-facing entry
|
|
105
|
+
- write from the user perspective
|
|
106
|
+
- keep highlights short and concrete
|
|
107
|
+
- spell out upgrade actions for breaking changes
|
|
108
|
+
|
|
109
|
+
## Step 5 — Write the File
|
|
110
|
+
|
|
111
|
+
Template:
|
|
112
|
+
|
|
113
|
+
```markdown
|
|
114
|
+
# v{version}
|
|
115
|
+
|
|
116
|
+
> Released: {YYYY-MM-DD}
|
|
117
|
+
|
|
118
|
+
## Breaking Changes
|
|
119
|
+
|
|
120
|
+
## Highlights
|
|
121
|
+
|
|
122
|
+
## Improvements
|
|
123
|
+
|
|
124
|
+
## Fixes
|
|
125
|
+
|
|
126
|
+
## Upgrade Guide
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Omit empty sections except `Highlights`, `Improvements`, and `Fixes`, which should usually exist.
|
|
130
|
+
|
|
131
|
+
## Step 6 — Review Before Release
|
|
132
|
+
|
|
133
|
+
Before handing it off:
|
|
134
|
+
|
|
135
|
+
1. confirm the heading is the stable version only
|
|
136
|
+
2. confirm there is no `-canary` language in the title or filename
|
|
137
|
+
3. confirm any breaking changes have an upgrade path
|
|
138
|
+
4. present the draft for human sign-off
|
|
139
|
+
|
|
140
|
+
This skill never publishes anything. It only prepares the stable changelog artifact.
|