@tickernelz/paperclip-pro-adapter-codex-local 2026.925.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 +22 -0
- package/dist/cli/format-event.d.ts +2 -0
- package/dist/cli/format-event.d.ts.map +1 -0
- package/dist/cli/format-event.js +218 -0
- package/dist/cli/format-event.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/quota-probe.d.ts +3 -0
- package/dist/cli/quota-probe.d.ts.map +1 -0
- package/dist/cli/quota-probe.js +104 -0
- package/dist/cli/quota-probe.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +155 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +58 -0
- package/dist/index.test.js.map +1 -0
- package/dist/server/acp.d.ts +30 -0
- package/dist/server/acp.d.ts.map +1 -0
- package/dist/server/acp.js +532 -0
- package/dist/server/acp.js.map +1 -0
- package/dist/server/acp.test.d.ts +2 -0
- package/dist/server/acp.test.d.ts.map +1 -0
- package/dist/server/acp.test.js +1087 -0
- package/dist/server/acp.test.js.map +1 -0
- package/dist/server/adapter-auth-promotion.d.ts +102 -0
- package/dist/server/adapter-auth-promotion.d.ts.map +1 -0
- package/dist/server/adapter-auth-promotion.js +210 -0
- package/dist/server/adapter-auth-promotion.js.map +1 -0
- package/dist/server/adapter-auth-promotion.test.d.ts +2 -0
- package/dist/server/adapter-auth-promotion.test.d.ts.map +1 -0
- package/dist/server/adapter-auth-promotion.test.js +658 -0
- package/dist/server/adapter-auth-promotion.test.js.map +1 -0
- package/dist/server/auth-check.d.ts +8 -0
- package/dist/server/auth-check.d.ts.map +1 -0
- package/dist/server/auth-check.js +8 -0
- package/dist/server/auth-check.js.map +1 -0
- package/dist/server/auth-precedence.d.ts +16 -0
- package/dist/server/auth-precedence.d.ts.map +1 -0
- package/dist/server/auth-precedence.js +20 -0
- package/dist/server/auth-precedence.js.map +1 -0
- package/dist/server/auth-precedence.test.d.ts +2 -0
- package/dist/server/auth-precedence.test.d.ts.map +1 -0
- package/dist/server/auth-precedence.test.js +100 -0
- package/dist/server/auth-precedence.test.js.map +1 -0
- package/dist/server/codex-args.d.ts +13 -0
- package/dist/server/codex-args.d.ts.map +1 -0
- package/dist/server/codex-args.js +76 -0
- package/dist/server/codex-args.js.map +1 -0
- package/dist/server/codex-args.test.d.ts +2 -0
- package/dist/server/codex-args.test.d.ts.map +1 -0
- package/dist/server/codex-args.test.js +243 -0
- package/dist/server/codex-args.test.js.map +1 -0
- package/dist/server/codex-auth-cache.d.ts +206 -0
- package/dist/server/codex-auth-cache.d.ts.map +1 -0
- package/dist/server/codex-auth-cache.js +501 -0
- package/dist/server/codex-auth-cache.js.map +1 -0
- package/dist/server/codex-auth-cache.test.d.ts +2 -0
- package/dist/server/codex-auth-cache.test.d.ts.map +1 -0
- package/dist/server/codex-auth-cache.test.js +497 -0
- package/dist/server/codex-auth-cache.test.js.map +1 -0
- package/dist/server/codex-auth-copyback.d.ts +53 -0
- package/dist/server/codex-auth-copyback.d.ts.map +1 -0
- package/dist/server/codex-auth-copyback.js +123 -0
- package/dist/server/codex-auth-copyback.js.map +1 -0
- package/dist/server/codex-auth-copyback.test.d.ts +2 -0
- package/dist/server/codex-auth-copyback.test.d.ts.map +1 -0
- package/dist/server/codex-auth-copyback.test.js +507 -0
- package/dist/server/codex-auth-copyback.test.js.map +1 -0
- package/dist/server/codex-auth-merge-decision.cjs +170 -0
- package/dist/server/codex-auth-merge-decision.d.ts +22 -0
- package/dist/server/codex-auth-merge-decision.d.ts.map +1 -0
- package/dist/server/codex-auth-merge-decision.js +58 -0
- package/dist/server/codex-auth-merge-decision.js.map +1 -0
- package/dist/server/codex-auth-merge-decision.test.d.ts +2 -0
- package/dist/server/codex-auth-merge-decision.test.d.ts.map +1 -0
- package/dist/server/codex-auth-merge-decision.test.js +230 -0
- package/dist/server/codex-auth-merge-decision.test.js.map +1 -0
- package/dist/server/codex-auth-merge-extract.sh +73 -0
- package/dist/server/codex-auth-merge-scripts.d.ts +21 -0
- package/dist/server/codex-auth-merge-scripts.d.ts.map +1 -0
- package/dist/server/codex-auth-merge-scripts.js +40 -0
- package/dist/server/codex-auth-merge-scripts.js.map +1 -0
- package/dist/server/codex-auth-merge.test.d.ts +2 -0
- package/dist/server/codex-auth-merge.test.d.ts.map +1 -0
- package/dist/server/codex-auth-merge.test.js +714 -0
- package/dist/server/codex-auth-merge.test.js.map +1 -0
- package/dist/server/codex-auth-seed-write.d.ts +30 -0
- package/dist/server/codex-auth-seed-write.d.ts.map +1 -0
- package/dist/server/codex-auth-seed-write.js +41 -0
- package/dist/server/codex-auth-seed-write.js.map +1 -0
- package/dist/server/codex-home.d.ts +162 -0
- package/dist/server/codex-home.d.ts.map +1 -0
- package/dist/server/codex-home.js +771 -0
- package/dist/server/codex-home.js.map +1 -0
- package/dist/server/codex-home.test.d.ts +2 -0
- package/dist/server/codex-home.test.d.ts.map +1 -0
- package/dist/server/codex-home.test.js +1183 -0
- package/dist/server/codex-home.test.js.map +1 -0
- package/dist/server/config-schema.d.ts +3 -0
- package/dist/server/config-schema.d.ts.map +1 -0
- package/dist/server/config-schema.js +67 -0
- package/dist/server/config-schema.js.map +1 -0
- package/dist/server/device-login-export.d.ts +56 -0
- package/dist/server/device-login-export.d.ts.map +1 -0
- package/dist/server/device-login-export.js +230 -0
- package/dist/server/device-login-export.js.map +1 -0
- package/dist/server/device-login-export.test.d.ts +2 -0
- package/dist/server/device-login-export.test.d.ts.map +1 -0
- package/dist/server/device-login-export.test.js +245 -0
- package/dist/server/device-login-export.test.js.map +1 -0
- package/dist/server/device-login-parse.d.ts +20 -0
- package/dist/server/device-login-parse.d.ts.map +1 -0
- package/dist/server/device-login-parse.js +155 -0
- package/dist/server/device-login-parse.js.map +1 -0
- package/dist/server/device-login-parse.test.d.ts +2 -0
- package/dist/server/device-login-parse.test.d.ts.map +1 -0
- package/dist/server/device-login-parse.test.js +269 -0
- package/dist/server/device-login-parse.test.js.map +1 -0
- package/dist/server/device-login-runner.d.ts +69 -0
- package/dist/server/device-login-runner.d.ts.map +1 -0
- package/dist/server/device-login-runner.js +109 -0
- package/dist/server/device-login-runner.js.map +1 -0
- package/dist/server/device-login-runner.test.d.ts +2 -0
- package/dist/server/device-login-runner.test.d.ts.map +1 -0
- package/dist/server/device-login-runner.test.js +201 -0
- package/dist/server/device-login-runner.test.js.map +1 -0
- package/dist/server/engine-availability.test.d.ts +2 -0
- package/dist/server/engine-availability.test.d.ts.map +1 -0
- package/dist/server/engine-availability.test.js +41 -0
- package/dist/server/engine-availability.test.js.map +1 -0
- package/dist/server/execute.acp-fallback.test.d.ts +2 -0
- package/dist/server/execute.acp-fallback.test.d.ts.map +1 -0
- package/dist/server/execute.acp-fallback.test.js +123 -0
- package/dist/server/execute.acp-fallback.test.js.map +1 -0
- package/dist/server/execute.auth-precedence.test.d.ts +2 -0
- package/dist/server/execute.auth-precedence.test.d.ts.map +1 -0
- package/dist/server/execute.auth-precedence.test.js +137 -0
- package/dist/server/execute.auth-precedence.test.js.map +1 -0
- package/dist/server/execute.auth.test.d.ts +2 -0
- package/dist/server/execute.auth.test.d.ts.map +1 -0
- package/dist/server/execute.auth.test.js +197 -0
- package/dist/server/execute.auth.test.js.map +1 -0
- package/dist/server/execute.d.ts +40 -0
- package/dist/server/execute.d.ts.map +1 -0
- package/dist/server/execute.js +1290 -0
- package/dist/server/execute.js.map +1 -0
- package/dist/server/execute.remote.test.d.ts +2 -0
- package/dist/server/execute.remote.test.d.ts.map +1 -0
- package/dist/server/execute.remote.test.js +556 -0
- package/dist/server/execute.remote.test.js.map +1 -0
- package/dist/server/execute.stderr-error.test.d.ts +2 -0
- package/dist/server/execute.stderr-error.test.d.ts.map +1 -0
- package/dist/server/execute.stderr-error.test.js +142 -0
- package/dist/server/execute.stderr-error.test.js.map +1 -0
- package/dist/server/execute.test.d.ts +2 -0
- package/dist/server/execute.test.d.ts.map +1 -0
- package/dist/server/execute.test.js +240 -0
- package/dist/server/execute.test.js.map +1 -0
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +71 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/output-inactivity-monitor.d.ts +62 -0
- package/dist/server/output-inactivity-monitor.d.ts.map +1 -0
- package/dist/server/output-inactivity-monitor.integration.test.d.ts +2 -0
- package/dist/server/output-inactivity-monitor.integration.test.d.ts.map +1 -0
- package/dist/server/output-inactivity-monitor.integration.test.js +136 -0
- package/dist/server/output-inactivity-monitor.integration.test.js.map +1 -0
- package/dist/server/output-inactivity-monitor.js +112 -0
- package/dist/server/output-inactivity-monitor.js.map +1 -0
- package/dist/server/output-inactivity-monitor.test.d.ts +2 -0
- package/dist/server/output-inactivity-monitor.test.d.ts.map +1 -0
- package/dist/server/output-inactivity-monitor.test.js +284 -0
- package/dist/server/output-inactivity-monitor.test.js.map +1 -0
- package/dist/server/parse.d.ts +51 -0
- package/dist/server/parse.d.ts.map +1 -0
- package/dist/server/parse.js +261 -0
- package/dist/server/parse.js.map +1 -0
- package/dist/server/parse.test.d.ts +2 -0
- package/dist/server/parse.test.d.ts.map +1 -0
- package/dist/server/parse.test.js +186 -0
- package/dist/server/parse.test.js.map +1 -0
- package/dist/server/process-activity-monitor.d.ts +21 -0
- package/dist/server/process-activity-monitor.d.ts.map +1 -0
- package/dist/server/process-activity-monitor.js +103 -0
- package/dist/server/process-activity-monitor.js.map +1 -0
- package/dist/server/process-activity-monitor.test.d.ts +2 -0
- package/dist/server/process-activity-monitor.test.d.ts.map +1 -0
- package/dist/server/process-activity-monitor.test.js +82 -0
- package/dist/server/process-activity-monitor.test.js.map +1 -0
- package/dist/server/quota-spawn-error.test.d.ts +2 -0
- package/dist/server/quota-spawn-error.test.d.ts.map +1 -0
- package/dist/server/quota-spawn-error.test.js +174 -0
- package/dist/server/quota-spawn-error.test.js.map +1 -0
- package/dist/server/quota.d.ts +66 -0
- package/dist/server/quota.d.ts.map +1 -0
- package/dist/server/quota.js +511 -0
- package/dist/server/quota.js.map +1 -0
- package/dist/server/runtime-config.d.ts +11 -0
- package/dist/server/runtime-config.d.ts.map +1 -0
- package/dist/server/runtime-config.js +380 -0
- package/dist/server/runtime-config.js.map +1 -0
- package/dist/server/runtime-config.test.d.ts +2 -0
- package/dist/server/runtime-config.test.d.ts.map +1 -0
- package/dist/server/runtime-config.test.js +367 -0
- package/dist/server/runtime-config.test.js.map +1 -0
- package/dist/server/skills.d.ts +8 -0
- package/dist/server/skills.d.ts.map +1 -0
- package/dist/server/skills.js +26 -0
- package/dist/server/skills.js.map +1 -0
- package/dist/server/test.d.ts +3 -0
- package/dist/server/test.d.ts.map +1 -0
- package/dist/server/test.js +458 -0
- package/dist/server/test.js.map +1 -0
- package/dist/server/test.remote.test.d.ts +2 -0
- package/dist/server/test.remote.test.d.ts.map +1 -0
- package/dist/server/test.remote.test.js +396 -0
- package/dist/server/test.remote.test.js.map +1 -0
- package/dist/ui/build-config.d.ts +5 -0
- package/dist/ui/build-config.d.ts.map +1 -0
- package/dist/ui/build-config.js +229 -0
- package/dist/ui/build-config.js.map +1 -0
- package/dist/ui/build-config.test.d.ts +2 -0
- package/dist/ui/build-config.test.d.ts.map +1 -0
- package/dist/ui/build-config.test.js +272 -0
- package/dist/ui/build-config.test.js.map +1 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +8 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/parse-stdout.d.ts +3 -0
- package/dist/ui/parse-stdout.d.ts.map +1 -0
- package/dist/ui/parse-stdout.js +265 -0
- package/dist/ui/parse-stdout.js.map +1 -0
- package/dist/ui/parse-stdout.test.d.ts +2 -0
- package/dist/ui/parse-stdout.test.d.ts.map +1 -0
- package/dist/ui/parse-stdout.test.js +77 -0
- package/dist/ui/parse-stdout.test.js.map +1 -0
- package/package.json +61 -0
- package/skills/agentmail/SKILL.md +70 -0
- package/skills/paperclip/SKILL.md +712 -0
- package/skills/paperclip/references/api-reference.md +1675 -0
- package/skills/paperclip/references/artifacts.md +158 -0
- package/skills/paperclip/references/cases.md +295 -0
- package/skills/paperclip/references/company-skills.md +266 -0
- package/skills/paperclip/references/issue-workspaces.md +80 -0
- package/skills/paperclip/references/routines.md +231 -0
- package/skills/paperclip/references/workflows.md +141 -0
- package/skills/paperclip/scripts/paperclip-upload-artifact.sh +592 -0
- package/skills/paperclip-board/SKILL.md +619 -0
- package/skills/paperclip-converting-plans-to-tasks/SKILL.md +60 -0
- package/skills/paperclip-create-agent/SKILL.md +179 -0
- package/skills/paperclip-create-agent/references/agent-instruction-templates.md +123 -0
- package/skills/paperclip-create-agent/references/agents/coder.md +64 -0
- package/skills/paperclip-create-agent/references/agents/qa.md +88 -0
- package/skills/paperclip-create-agent/references/agents/securityengineer.md +135 -0
- package/skills/paperclip-create-agent/references/agents/uxdesigner.md +115 -0
- package/skills/paperclip-create-agent/references/api-reference.md +110 -0
- package/skills/paperclip-create-agent/references/baseline-role-guide.md +168 -0
- package/skills/paperclip-create-agent/references/draft-review-checklist.md +95 -0
- package/skills/para-memory-files/SKILL.md +100 -0
- package/skills/para-memory-files/references/schemas.md +35 -0
- package/skills/slack/SKILL.md +65 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Generated Artifacts and Work Products
|
|
2
|
+
|
|
3
|
+
When work produces a user-inspectable file, upload true deliverables to the current issue before final disposition. Local filesystem paths are not enough because board users, reviewers, and cloud operators may not have access to the agent workspace.
|
|
4
|
+
|
|
5
|
+
Use Bash to run the helper bundled with this skill; installed skill files may not retain executable permissions. From an installed `paperclip` skill directory, the helper lives at `scripts/paperclip-upload-artifact.sh`:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bash scripts/paperclip-upload-artifact.sh path/to/output.webm \
|
|
9
|
+
--title "Walkthrough render" \
|
|
10
|
+
--summary "Rendered walkthrough for review"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The helper uses `PAPERCLIP_API_URL`, `PAPERCLIP_API_KEY`, `PAPERCLIP_COMPANY_ID`, `PAPERCLIP_TASK_ID`, and `PAPERCLIP_RUN_ID`. It uploads the file as an issue attachment, creates an attachment-backed artifact work product by default, and prints issue-safe markdown links for your final comment.
|
|
14
|
+
|
|
15
|
+
## Workspace-Only File References
|
|
16
|
+
|
|
17
|
+
Use a workspace-only reference only when the file should stay in the project or
|
|
18
|
+
execution workspace, such as a source file, committed report, generated index,
|
|
19
|
+
or other file whose value is tied to the checkout. This is not a substitute for
|
|
20
|
+
uploading a deliverable file that a board user should be able to inspect outside
|
|
21
|
+
the workspace.
|
|
22
|
+
|
|
23
|
+
Annotate the work product with `metadata.resourceRef`:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"type": "document",
|
|
28
|
+
"provider": "workspace",
|
|
29
|
+
"title": "Regression test plan",
|
|
30
|
+
"status": "ready_for_review",
|
|
31
|
+
"reviewState": "needs_board_review",
|
|
32
|
+
"summary": "Markdown plan committed in the execution workspace.",
|
|
33
|
+
"metadata": {
|
|
34
|
+
"resourceRef": {
|
|
35
|
+
"kind": "workspace_file",
|
|
36
|
+
"issueId": "<issue-id>",
|
|
37
|
+
"workspaceKind": "execution_workspace",
|
|
38
|
+
"workspaceId": "<execution-workspace-id>",
|
|
39
|
+
"relativePath": "doc/plans/regression-test-plan.md",
|
|
40
|
+
"line": 1,
|
|
41
|
+
"displayPath": "doc/plans/regression-test-plan.md"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`workspaceKind` is `execution_workspace` for the current issue checkout or
|
|
48
|
+
`project_workspace` for a shared project workspace. `line` and `column` are
|
|
49
|
+
optional positive integers. `relativePath` must be relative to the selected
|
|
50
|
+
workspace root; do not use host-local absolute paths in `resourceRef`.
|
|
51
|
+
|
|
52
|
+
Create the work product with:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl -sS -X POST \
|
|
56
|
+
"$PAPERCLIP_API_URL/api/issues/$PAPERCLIP_TASK_ID/work-products" \
|
|
57
|
+
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
|
|
58
|
+
-H "X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID" \
|
|
59
|
+
-H "Content-Type: application/json" \
|
|
60
|
+
--data-binary @workspace-file-work-product.json
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If the helper is unavailable, use the Paperclip API directly:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
curl -sS -X POST \
|
|
67
|
+
"$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/issues/$PAPERCLIP_TASK_ID/attachments" \
|
|
68
|
+
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
|
|
69
|
+
-H "X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID" \
|
|
70
|
+
-F 'file=@"path/to/output.webm";type=video/webm'
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Then create a work product when the file is the deliverable. The server canonicalizes attachment-backed artifact metadata from the `attachmentId`:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
curl -sS -X POST \
|
|
77
|
+
"$PAPERCLIP_API_URL/api/issues/$PAPERCLIP_TASK_ID/work-products" \
|
|
78
|
+
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
|
|
79
|
+
-H "X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID" \
|
|
80
|
+
-H "Content-Type: application/json" \
|
|
81
|
+
--data-binary '{
|
|
82
|
+
"type": "artifact",
|
|
83
|
+
"provider": "paperclip",
|
|
84
|
+
"title": "Walkthrough render",
|
|
85
|
+
"status": "ready_for_review",
|
|
86
|
+
"reviewState": "needs_board_review",
|
|
87
|
+
"isPrimary": true,
|
|
88
|
+
"metadata": { "attachmentId": "<uploaded-attachment-id>" }
|
|
89
|
+
}'
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
In your final issue comment, link the uploaded attachment or work product and
|
|
93
|
+
describe what it contains. If the output is workspace-only, name the work
|
|
94
|
+
product and the relative path that was recorded in `metadata.resourceRef`.
|
|
95
|
+
Browse/search is the fallback for recovering a workspace file when the issue
|
|
96
|
+
chip or link cannot open it; it is not the preferred deliverable path. Do not
|
|
97
|
+
leave artifact-producing work `in_progress` with only a local path or a
|
|
98
|
+
`Remaining` note.
|
|
99
|
+
|
|
100
|
+
When the current run was started by an external chat request and the file is
|
|
101
|
+
part of the response intended for that external conversation, have the upload
|
|
102
|
+
helper bind that specific file to an explicit response comment:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
bash scripts/paperclip-upload-artifact.sh path/to/result.png \
|
|
106
|
+
--title "Requested image" \
|
|
107
|
+
--chat-comment "Here is the requested image."
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`--chat-comment` uses the current run-scoped API directly, so it does not depend
|
|
111
|
+
on a separately installed CLI version. It first uploads the file and creates
|
|
112
|
+
the same-run artifact work product, then binds that exact attachment to the
|
|
113
|
+
comment. Concurrent matching invocations on one host serialize by API, company,
|
|
114
|
+
task, run, filename, content hash, and media type. On retry, the helper reuses
|
|
115
|
+
the server's immutable same-run attachment record instead of uploading a second
|
|
116
|
+
copy. A retry from a different host is still subject to server-side attachment
|
|
117
|
+
admission and should not be run concurrently.
|
|
118
|
+
|
|
119
|
+
If the upload connection ends without an HTTP response, the helper records that
|
|
120
|
+
ambiguous outcome locally. The same command polls briefly for Paperclip's
|
|
121
|
+
immutable attachment record and otherwise stops instead of blindly creating a
|
|
122
|
+
duplicate. Retry later. Use `--retry-unknown-upload` only after establishing
|
|
123
|
+
that the first upload did not commit; this explicit override accepts the risk of
|
|
124
|
+
creating a duplicate file.
|
|
125
|
+
|
|
126
|
+
The binding is durable Paperclip state, but it is not proof of external
|
|
127
|
+
delivery—or even proof that the current run has an active external-chat origin.
|
|
128
|
+
For an authorized active chat-origin run, Paperclip keeps this selection
|
|
129
|
+
internal until it selects the run's final response, then attempts the provider
|
|
130
|
+
publication. The final assistant response may use different prose from
|
|
131
|
+
`--chat-comment`.
|
|
132
|
+
|
|
133
|
+
Treat the helper's exit status as confirmation that the Paperclip attachment,
|
|
134
|
+
work product, and requested comment binding were saved. Use neutral final prose
|
|
135
|
+
such as “I prepared the requested image.” Do not claim the file is shown above,
|
|
136
|
+
attached, queued, or delivered. If the bind step fails after upload, say that
|
|
137
|
+
the artifact was saved to the Paperclip task but was **not** bound to the
|
|
138
|
+
response comment; never also claim that it appears above or is attached.
|
|
139
|
+
|
|
140
|
+
Do not infer sharing intent from other files on the task or bind every
|
|
141
|
+
attachment from a run. Only the file passed with `--chat-comment` is eligible
|
|
142
|
+
for external publication; unbound artifacts remain Paperclip-only.
|
|
143
|
+
|
|
144
|
+
**Native runner**
|
|
145
|
+
|
|
146
|
+
When `register_deliverable` is available, use it for files in the bound local or
|
|
147
|
+
remote workspace. Supply a workspace-relative `contentRef`, basename `filename`,
|
|
148
|
+
`contentType`, exact `byteSize` and SHA-256, `title`, and a stable `idempotencyKey`.
|
|
149
|
+
The tool verifies the file, stores an attachment and artifact work product, and
|
|
150
|
+
binds it to the response. Generic API tools and a legacy API key are unnecessary.
|
|
151
|
+
|
|
152
|
+
Wait for the receipt. It includes `attachmentId`, `contentPath`, and
|
|
153
|
+
`downloadPath`, along with the existing command, revision, entity references,
|
|
154
|
+
and disposition. Reuse the original key after an ambiguous result. A receipt
|
|
155
|
+
confirms storage and response binding in Paperclip; it does not confirm delivery
|
|
156
|
+
to an external chat provider. If registration fails, use the returned error to
|
|
157
|
+
resolve the failure or explain the limitation; do not describe a workspace path
|
|
158
|
+
as an uploaded file.
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# Cases
|
|
2
|
+
|
|
3
|
+
Cases are agent-owned work records for durable outputs such as blog posts,
|
|
4
|
+
research packets, release notes, incidents, QA runs, or generated asset sets.
|
|
5
|
+
They are company-scoped and live beside issues: issues coordinate work, while
|
|
6
|
+
cases preserve the structured object an agent is producing.
|
|
7
|
+
|
|
8
|
+
Cases are experimental and must be enabled with `experimental.enableCases`.
|
|
9
|
+
If a route returns `403 Cases are disabled`, stop and report that the operator
|
|
10
|
+
must enable cases before the skill can use this surface.
|
|
11
|
+
|
|
12
|
+
## Core Model
|
|
13
|
+
|
|
14
|
+
A case has:
|
|
15
|
+
|
|
16
|
+
- `identifier`: server-assigned display id such as `PAP-C42`
|
|
17
|
+
- `caseType`: skill-owned type such as `blog_post`, `image_assets`, or `incident`
|
|
18
|
+
- `key`: optional deterministic upsert key inside `(companyId, caseType)`
|
|
19
|
+
- `title` and optional `summary`
|
|
20
|
+
- `status`: `draft`, `in_progress`, `in_review`, `approved`, `done`, or `cancelled`
|
|
21
|
+
- `fields`: JSON object owned by the skill using the case
|
|
22
|
+
- `parentCaseId`: optional parent case for child work
|
|
23
|
+
- documents, attachments, issue links, labels, and events
|
|
24
|
+
|
|
25
|
+
Use deterministic `caseType` + `key` when a skill may be retried. Repeating
|
|
26
|
+
`POST /api/companies/:companyId/cases` with the same `caseType` and `key`
|
|
27
|
+
upserts the same case instead of creating a duplicate.
|
|
28
|
+
|
|
29
|
+
## Upsert Semantics
|
|
30
|
+
|
|
31
|
+
`POST /api/companies/:companyId/cases` creates or upserts a case.
|
|
32
|
+
|
|
33
|
+
Request:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"caseType": "blog_post",
|
|
38
|
+
"key": "launch-announcement",
|
|
39
|
+
"title": "Launch announcement",
|
|
40
|
+
"summary": "Draft launch post for operators.",
|
|
41
|
+
"status": "draft",
|
|
42
|
+
"fields": {
|
|
43
|
+
"slug": "launch-announcement",
|
|
44
|
+
"target_audience": "operators"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Response:
|
|
50
|
+
|
|
51
|
+
- `201` when a new case was created
|
|
52
|
+
- `200` when an existing `(caseType, key)` case was updated
|
|
53
|
+
|
|
54
|
+
Field behavior on upsert:
|
|
55
|
+
|
|
56
|
+
- `title` is required and replaces the previous title.
|
|
57
|
+
- `projectId`, `summary`, `status`, `fields`, and `parentCaseId` replace the
|
|
58
|
+
previous value when present.
|
|
59
|
+
- Omitted optional values preserve the previous value during upsert.
|
|
60
|
+
- `fields` is replaced as a whole object when provided. It is not deep-merged.
|
|
61
|
+
Send the complete desired JSON object each time.
|
|
62
|
+
- Concurrent retries with the same `(caseType, key)` converge to one case.
|
|
63
|
+
|
|
64
|
+
Do not use a random `key` for retryable skills. Use a stable content slug,
|
|
65
|
+
external id, source URL hash, or parent-derived request key.
|
|
66
|
+
|
|
67
|
+
## Read And Search
|
|
68
|
+
|
|
69
|
+
Get a case by UUID or identifier:
|
|
70
|
+
|
|
71
|
+
```http
|
|
72
|
+
GET /api/cases/PAP-C42
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
List cases for a company:
|
|
76
|
+
|
|
77
|
+
```http
|
|
78
|
+
GET /api/companies/:companyId/cases?type=blog_post&status=active&q=launch
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Useful filters:
|
|
82
|
+
|
|
83
|
+
- `type`: exact `caseType`
|
|
84
|
+
- `status`: exact lifecycle status, or `active` for non-terminal cases
|
|
85
|
+
- `projectId` / `project`: project UUID
|
|
86
|
+
- `labelId` / `label`: label UUID
|
|
87
|
+
- `q`: identifier, title, summary, or key search
|
|
88
|
+
- `limit`: 1-200, default 100
|
|
89
|
+
|
|
90
|
+
## Documents
|
|
91
|
+
|
|
92
|
+
Use case documents for rich bodies such as drafts, briefs, reports, or plans.
|
|
93
|
+
|
|
94
|
+
```http
|
|
95
|
+
PUT /api/cases/:caseIdOrIdentifier/documents/body
|
|
96
|
+
Content-Type: application/json
|
|
97
|
+
|
|
98
|
+
{
|
|
99
|
+
"title": "Launch announcement body",
|
|
100
|
+
"format": "markdown",
|
|
101
|
+
"body": "# Launch announcement\n\nDraft copy...",
|
|
102
|
+
"changeSummary": "Initial draft"
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Updating an existing case document requires `baseRevisionId`:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"baseRevisionId": "latest-revision-uuid",
|
|
111
|
+
"body": "Updated body"
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
If you get `409 stale_base_revision`, refetch the case detail, read the latest
|
|
116
|
+
document revision id, merge intentionally, and retry with that `baseRevisionId`.
|
|
117
|
+
|
|
118
|
+
## Fields
|
|
119
|
+
|
|
120
|
+
Each skill owns the schema of `fields` for the `caseType` it creates. Keep fields
|
|
121
|
+
small, typed, and stable enough for other agents to inspect.
|
|
122
|
+
|
|
123
|
+
Examples:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"slug": "launch-announcement",
|
|
128
|
+
"target_audience": "operators",
|
|
129
|
+
"publish_url": "https://example.com/blog/launch-announcement"
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Patch fields or status with:
|
|
134
|
+
|
|
135
|
+
```http
|
|
136
|
+
PATCH /api/cases/:caseIdOrIdentifier
|
|
137
|
+
Content-Type: application/json
|
|
138
|
+
|
|
139
|
+
{
|
|
140
|
+
"status": "in_review",
|
|
141
|
+
"fields": {
|
|
142
|
+
"slug": "launch-announcement",
|
|
143
|
+
"target_audience": "operators",
|
|
144
|
+
"publish_url": "https://example.com/blog/launch-announcement"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Remember: `fields` replaces the whole object when present.
|
|
150
|
+
|
|
151
|
+
## Issue Links
|
|
152
|
+
|
|
153
|
+
Link cases to issues explicitly when needed:
|
|
154
|
+
|
|
155
|
+
```http
|
|
156
|
+
POST /api/cases/:caseIdOrIdentifier/links
|
|
157
|
+
Content-Type: application/json
|
|
158
|
+
|
|
159
|
+
{
|
|
160
|
+
"issueId": "issue-uuid",
|
|
161
|
+
"role": "reference"
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Roles:
|
|
166
|
+
|
|
167
|
+
- `origin`: the issue/run that created the case
|
|
168
|
+
- `work`: an issue/run that changed the case
|
|
169
|
+
- `reference`: related issue context
|
|
170
|
+
|
|
171
|
+
Agent run writes auto-link the run's issue when Paperclip can resolve it from
|
|
172
|
+
the run JWT or `X-Paperclip-Run-Id`. Creation/upsert writes use `origin`; later
|
|
173
|
+
document, patch, and attachment writes use `work` when no link already exists.
|
|
174
|
+
You do not need to manually link the current issue before writing the case.
|
|
175
|
+
|
|
176
|
+
## Child Cases
|
|
177
|
+
|
|
178
|
+
Create child cases by setting `parentCaseId` to the parent case UUID.
|
|
179
|
+
|
|
180
|
+
```json
|
|
181
|
+
{
|
|
182
|
+
"caseType": "image_assets",
|
|
183
|
+
"key": "launch-announcement:hero-images",
|
|
184
|
+
"title": "Hero images for launch announcement",
|
|
185
|
+
"parentCaseId": "parent-case-uuid",
|
|
186
|
+
"fields": {
|
|
187
|
+
"required_assets": ["hero", "social-card"]
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Use child cases when the output has independently inspectable pieces or when
|
|
193
|
+
another agent can work on a bounded part without editing the parent case body.
|
|
194
|
+
|
|
195
|
+
## Attachments
|
|
196
|
+
|
|
197
|
+
Attach generated files with multipart form data:
|
|
198
|
+
|
|
199
|
+
```http
|
|
200
|
+
POST /api/cases/:caseIdOrIdentifier/attachments
|
|
201
|
+
Content-Type: multipart/form-data
|
|
202
|
+
|
|
203
|
+
file=@hero.png
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The server records an asset and adds an `attachment_added` case event.
|
|
207
|
+
|
|
208
|
+
## Lifecycle
|
|
209
|
+
|
|
210
|
+
Use the lifecycle consistently:
|
|
211
|
+
|
|
212
|
+
- `draft`: case exists but useful work has not started
|
|
213
|
+
- `in_progress`: an agent is actively producing or revising it
|
|
214
|
+
- `in_review`: ready for reviewer, board, or downstream approval
|
|
215
|
+
- `approved`: accepted but not finally shipped or archived
|
|
216
|
+
- `done`: complete and no further action remains
|
|
217
|
+
- `cancelled`: intentionally abandoned
|
|
218
|
+
|
|
219
|
+
Terminal statuses are `done` and `cancelled`; setting either records
|
|
220
|
+
`completedAt`. Moving back to a non-terminal status clears `completedAt`.
|
|
221
|
+
|
|
222
|
+
## Worked Blog Post Example
|
|
223
|
+
|
|
224
|
+
Create or upsert the parent blog post:
|
|
225
|
+
|
|
226
|
+
```http
|
|
227
|
+
POST /api/companies/:companyId/cases
|
|
228
|
+
Content-Type: application/json
|
|
229
|
+
|
|
230
|
+
{
|
|
231
|
+
"caseType": "blog_post",
|
|
232
|
+
"key": "paperclip-cases-launch",
|
|
233
|
+
"title": "Introducing Paperclip Cases",
|
|
234
|
+
"summary": "Blog post explaining the cases surface for agent outputs.",
|
|
235
|
+
"status": "in_progress",
|
|
236
|
+
"fields": {
|
|
237
|
+
"slug": "paperclip-cases-launch",
|
|
238
|
+
"target_audience": "AI company operators",
|
|
239
|
+
"publish_url": null
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Write the body:
|
|
245
|
+
|
|
246
|
+
```http
|
|
247
|
+
PUT /api/cases/PAP-C42/documents/body
|
|
248
|
+
Content-Type: application/json
|
|
249
|
+
|
|
250
|
+
{
|
|
251
|
+
"title": "Introducing Paperclip Cases",
|
|
252
|
+
"format": "markdown",
|
|
253
|
+
"body": "# Introducing Paperclip Cases\n\n..."
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Create the child image-assets case:
|
|
258
|
+
|
|
259
|
+
```http
|
|
260
|
+
POST /api/companies/:companyId/cases
|
|
261
|
+
Content-Type: application/json
|
|
262
|
+
|
|
263
|
+
{
|
|
264
|
+
"caseType": "image_assets",
|
|
265
|
+
"key": "paperclip-cases-launch:image-assets",
|
|
266
|
+
"title": "Image assets for Introducing Paperclip Cases",
|
|
267
|
+
"parentCaseId": "parent-case-uuid",
|
|
268
|
+
"status": "in_progress",
|
|
269
|
+
"fields": {
|
|
270
|
+
"slug": "paperclip-cases-launch",
|
|
271
|
+
"required_assets": ["hero", "social-card"],
|
|
272
|
+
"publish_url": null
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Attach generated assets to the child, then patch both cases as they move through
|
|
278
|
+
review:
|
|
279
|
+
|
|
280
|
+
```http
|
|
281
|
+
PATCH /api/cases/PAP-C42
|
|
282
|
+
Content-Type: application/json
|
|
283
|
+
|
|
284
|
+
{
|
|
285
|
+
"status": "in_review",
|
|
286
|
+
"fields": {
|
|
287
|
+
"slug": "paperclip-cases-launch",
|
|
288
|
+
"target_audience": "AI company operators",
|
|
289
|
+
"publish_url": "https://example.com/blog/paperclip-cases-launch"
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
If the same skill retries the example with the same keys, it updates the parent
|
|
295
|
+
and child cases rather than creating duplicates.
|