@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.
Files changed (268) hide show
  1. package/LICENSE +22 -0
  2. package/dist/cli/format-event.d.ts +2 -0
  3. package/dist/cli/format-event.d.ts.map +1 -0
  4. package/dist/cli/format-event.js +218 -0
  5. package/dist/cli/format-event.js.map +1 -0
  6. package/dist/cli/index.d.ts +2 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/cli/index.js +2 -0
  9. package/dist/cli/index.js.map +1 -0
  10. package/dist/cli/quota-probe.d.ts +3 -0
  11. package/dist/cli/quota-probe.d.ts.map +1 -0
  12. package/dist/cli/quota-probe.js +104 -0
  13. package/dist/cli/quota-probe.js.map +1 -0
  14. package/dist/index.d.ts +21 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +155 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/index.test.d.ts +2 -0
  19. package/dist/index.test.d.ts.map +1 -0
  20. package/dist/index.test.js +58 -0
  21. package/dist/index.test.js.map +1 -0
  22. package/dist/server/acp.d.ts +30 -0
  23. package/dist/server/acp.d.ts.map +1 -0
  24. package/dist/server/acp.js +532 -0
  25. package/dist/server/acp.js.map +1 -0
  26. package/dist/server/acp.test.d.ts +2 -0
  27. package/dist/server/acp.test.d.ts.map +1 -0
  28. package/dist/server/acp.test.js +1087 -0
  29. package/dist/server/acp.test.js.map +1 -0
  30. package/dist/server/adapter-auth-promotion.d.ts +102 -0
  31. package/dist/server/adapter-auth-promotion.d.ts.map +1 -0
  32. package/dist/server/adapter-auth-promotion.js +210 -0
  33. package/dist/server/adapter-auth-promotion.js.map +1 -0
  34. package/dist/server/adapter-auth-promotion.test.d.ts +2 -0
  35. package/dist/server/adapter-auth-promotion.test.d.ts.map +1 -0
  36. package/dist/server/adapter-auth-promotion.test.js +658 -0
  37. package/dist/server/adapter-auth-promotion.test.js.map +1 -0
  38. package/dist/server/auth-check.d.ts +8 -0
  39. package/dist/server/auth-check.d.ts.map +1 -0
  40. package/dist/server/auth-check.js +8 -0
  41. package/dist/server/auth-check.js.map +1 -0
  42. package/dist/server/auth-precedence.d.ts +16 -0
  43. package/dist/server/auth-precedence.d.ts.map +1 -0
  44. package/dist/server/auth-precedence.js +20 -0
  45. package/dist/server/auth-precedence.js.map +1 -0
  46. package/dist/server/auth-precedence.test.d.ts +2 -0
  47. package/dist/server/auth-precedence.test.d.ts.map +1 -0
  48. package/dist/server/auth-precedence.test.js +100 -0
  49. package/dist/server/auth-precedence.test.js.map +1 -0
  50. package/dist/server/codex-args.d.ts +13 -0
  51. package/dist/server/codex-args.d.ts.map +1 -0
  52. package/dist/server/codex-args.js +76 -0
  53. package/dist/server/codex-args.js.map +1 -0
  54. package/dist/server/codex-args.test.d.ts +2 -0
  55. package/dist/server/codex-args.test.d.ts.map +1 -0
  56. package/dist/server/codex-args.test.js +243 -0
  57. package/dist/server/codex-args.test.js.map +1 -0
  58. package/dist/server/codex-auth-cache.d.ts +206 -0
  59. package/dist/server/codex-auth-cache.d.ts.map +1 -0
  60. package/dist/server/codex-auth-cache.js +501 -0
  61. package/dist/server/codex-auth-cache.js.map +1 -0
  62. package/dist/server/codex-auth-cache.test.d.ts +2 -0
  63. package/dist/server/codex-auth-cache.test.d.ts.map +1 -0
  64. package/dist/server/codex-auth-cache.test.js +497 -0
  65. package/dist/server/codex-auth-cache.test.js.map +1 -0
  66. package/dist/server/codex-auth-copyback.d.ts +53 -0
  67. package/dist/server/codex-auth-copyback.d.ts.map +1 -0
  68. package/dist/server/codex-auth-copyback.js +123 -0
  69. package/dist/server/codex-auth-copyback.js.map +1 -0
  70. package/dist/server/codex-auth-copyback.test.d.ts +2 -0
  71. package/dist/server/codex-auth-copyback.test.d.ts.map +1 -0
  72. package/dist/server/codex-auth-copyback.test.js +507 -0
  73. package/dist/server/codex-auth-copyback.test.js.map +1 -0
  74. package/dist/server/codex-auth-merge-decision.cjs +170 -0
  75. package/dist/server/codex-auth-merge-decision.d.ts +22 -0
  76. package/dist/server/codex-auth-merge-decision.d.ts.map +1 -0
  77. package/dist/server/codex-auth-merge-decision.js +58 -0
  78. package/dist/server/codex-auth-merge-decision.js.map +1 -0
  79. package/dist/server/codex-auth-merge-decision.test.d.ts +2 -0
  80. package/dist/server/codex-auth-merge-decision.test.d.ts.map +1 -0
  81. package/dist/server/codex-auth-merge-decision.test.js +230 -0
  82. package/dist/server/codex-auth-merge-decision.test.js.map +1 -0
  83. package/dist/server/codex-auth-merge-extract.sh +73 -0
  84. package/dist/server/codex-auth-merge-scripts.d.ts +21 -0
  85. package/dist/server/codex-auth-merge-scripts.d.ts.map +1 -0
  86. package/dist/server/codex-auth-merge-scripts.js +40 -0
  87. package/dist/server/codex-auth-merge-scripts.js.map +1 -0
  88. package/dist/server/codex-auth-merge.test.d.ts +2 -0
  89. package/dist/server/codex-auth-merge.test.d.ts.map +1 -0
  90. package/dist/server/codex-auth-merge.test.js +714 -0
  91. package/dist/server/codex-auth-merge.test.js.map +1 -0
  92. package/dist/server/codex-auth-seed-write.d.ts +30 -0
  93. package/dist/server/codex-auth-seed-write.d.ts.map +1 -0
  94. package/dist/server/codex-auth-seed-write.js +41 -0
  95. package/dist/server/codex-auth-seed-write.js.map +1 -0
  96. package/dist/server/codex-home.d.ts +162 -0
  97. package/dist/server/codex-home.d.ts.map +1 -0
  98. package/dist/server/codex-home.js +771 -0
  99. package/dist/server/codex-home.js.map +1 -0
  100. package/dist/server/codex-home.test.d.ts +2 -0
  101. package/dist/server/codex-home.test.d.ts.map +1 -0
  102. package/dist/server/codex-home.test.js +1183 -0
  103. package/dist/server/codex-home.test.js.map +1 -0
  104. package/dist/server/config-schema.d.ts +3 -0
  105. package/dist/server/config-schema.d.ts.map +1 -0
  106. package/dist/server/config-schema.js +67 -0
  107. package/dist/server/config-schema.js.map +1 -0
  108. package/dist/server/device-login-export.d.ts +56 -0
  109. package/dist/server/device-login-export.d.ts.map +1 -0
  110. package/dist/server/device-login-export.js +230 -0
  111. package/dist/server/device-login-export.js.map +1 -0
  112. package/dist/server/device-login-export.test.d.ts +2 -0
  113. package/dist/server/device-login-export.test.d.ts.map +1 -0
  114. package/dist/server/device-login-export.test.js +245 -0
  115. package/dist/server/device-login-export.test.js.map +1 -0
  116. package/dist/server/device-login-parse.d.ts +20 -0
  117. package/dist/server/device-login-parse.d.ts.map +1 -0
  118. package/dist/server/device-login-parse.js +155 -0
  119. package/dist/server/device-login-parse.js.map +1 -0
  120. package/dist/server/device-login-parse.test.d.ts +2 -0
  121. package/dist/server/device-login-parse.test.d.ts.map +1 -0
  122. package/dist/server/device-login-parse.test.js +269 -0
  123. package/dist/server/device-login-parse.test.js.map +1 -0
  124. package/dist/server/device-login-runner.d.ts +69 -0
  125. package/dist/server/device-login-runner.d.ts.map +1 -0
  126. package/dist/server/device-login-runner.js +109 -0
  127. package/dist/server/device-login-runner.js.map +1 -0
  128. package/dist/server/device-login-runner.test.d.ts +2 -0
  129. package/dist/server/device-login-runner.test.d.ts.map +1 -0
  130. package/dist/server/device-login-runner.test.js +201 -0
  131. package/dist/server/device-login-runner.test.js.map +1 -0
  132. package/dist/server/engine-availability.test.d.ts +2 -0
  133. package/dist/server/engine-availability.test.d.ts.map +1 -0
  134. package/dist/server/engine-availability.test.js +41 -0
  135. package/dist/server/engine-availability.test.js.map +1 -0
  136. package/dist/server/execute.acp-fallback.test.d.ts +2 -0
  137. package/dist/server/execute.acp-fallback.test.d.ts.map +1 -0
  138. package/dist/server/execute.acp-fallback.test.js +123 -0
  139. package/dist/server/execute.acp-fallback.test.js.map +1 -0
  140. package/dist/server/execute.auth-precedence.test.d.ts +2 -0
  141. package/dist/server/execute.auth-precedence.test.d.ts.map +1 -0
  142. package/dist/server/execute.auth-precedence.test.js +137 -0
  143. package/dist/server/execute.auth-precedence.test.js.map +1 -0
  144. package/dist/server/execute.auth.test.d.ts +2 -0
  145. package/dist/server/execute.auth.test.d.ts.map +1 -0
  146. package/dist/server/execute.auth.test.js +197 -0
  147. package/dist/server/execute.auth.test.js.map +1 -0
  148. package/dist/server/execute.d.ts +40 -0
  149. package/dist/server/execute.d.ts.map +1 -0
  150. package/dist/server/execute.js +1290 -0
  151. package/dist/server/execute.js.map +1 -0
  152. package/dist/server/execute.remote.test.d.ts +2 -0
  153. package/dist/server/execute.remote.test.d.ts.map +1 -0
  154. package/dist/server/execute.remote.test.js +556 -0
  155. package/dist/server/execute.remote.test.js.map +1 -0
  156. package/dist/server/execute.stderr-error.test.d.ts +2 -0
  157. package/dist/server/execute.stderr-error.test.d.ts.map +1 -0
  158. package/dist/server/execute.stderr-error.test.js +142 -0
  159. package/dist/server/execute.stderr-error.test.js.map +1 -0
  160. package/dist/server/execute.test.d.ts +2 -0
  161. package/dist/server/execute.test.d.ts.map +1 -0
  162. package/dist/server/execute.test.js +240 -0
  163. package/dist/server/execute.test.js.map +1 -0
  164. package/dist/server/index.d.ts +18 -0
  165. package/dist/server/index.d.ts.map +1 -0
  166. package/dist/server/index.js +71 -0
  167. package/dist/server/index.js.map +1 -0
  168. package/dist/server/output-inactivity-monitor.d.ts +62 -0
  169. package/dist/server/output-inactivity-monitor.d.ts.map +1 -0
  170. package/dist/server/output-inactivity-monitor.integration.test.d.ts +2 -0
  171. package/dist/server/output-inactivity-monitor.integration.test.d.ts.map +1 -0
  172. package/dist/server/output-inactivity-monitor.integration.test.js +136 -0
  173. package/dist/server/output-inactivity-monitor.integration.test.js.map +1 -0
  174. package/dist/server/output-inactivity-monitor.js +112 -0
  175. package/dist/server/output-inactivity-monitor.js.map +1 -0
  176. package/dist/server/output-inactivity-monitor.test.d.ts +2 -0
  177. package/dist/server/output-inactivity-monitor.test.d.ts.map +1 -0
  178. package/dist/server/output-inactivity-monitor.test.js +284 -0
  179. package/dist/server/output-inactivity-monitor.test.js.map +1 -0
  180. package/dist/server/parse.d.ts +51 -0
  181. package/dist/server/parse.d.ts.map +1 -0
  182. package/dist/server/parse.js +261 -0
  183. package/dist/server/parse.js.map +1 -0
  184. package/dist/server/parse.test.d.ts +2 -0
  185. package/dist/server/parse.test.d.ts.map +1 -0
  186. package/dist/server/parse.test.js +186 -0
  187. package/dist/server/parse.test.js.map +1 -0
  188. package/dist/server/process-activity-monitor.d.ts +21 -0
  189. package/dist/server/process-activity-monitor.d.ts.map +1 -0
  190. package/dist/server/process-activity-monitor.js +103 -0
  191. package/dist/server/process-activity-monitor.js.map +1 -0
  192. package/dist/server/process-activity-monitor.test.d.ts +2 -0
  193. package/dist/server/process-activity-monitor.test.d.ts.map +1 -0
  194. package/dist/server/process-activity-monitor.test.js +82 -0
  195. package/dist/server/process-activity-monitor.test.js.map +1 -0
  196. package/dist/server/quota-spawn-error.test.d.ts +2 -0
  197. package/dist/server/quota-spawn-error.test.d.ts.map +1 -0
  198. package/dist/server/quota-spawn-error.test.js +174 -0
  199. package/dist/server/quota-spawn-error.test.js.map +1 -0
  200. package/dist/server/quota.d.ts +66 -0
  201. package/dist/server/quota.d.ts.map +1 -0
  202. package/dist/server/quota.js +511 -0
  203. package/dist/server/quota.js.map +1 -0
  204. package/dist/server/runtime-config.d.ts +11 -0
  205. package/dist/server/runtime-config.d.ts.map +1 -0
  206. package/dist/server/runtime-config.js +380 -0
  207. package/dist/server/runtime-config.js.map +1 -0
  208. package/dist/server/runtime-config.test.d.ts +2 -0
  209. package/dist/server/runtime-config.test.d.ts.map +1 -0
  210. package/dist/server/runtime-config.test.js +367 -0
  211. package/dist/server/runtime-config.test.js.map +1 -0
  212. package/dist/server/skills.d.ts +8 -0
  213. package/dist/server/skills.d.ts.map +1 -0
  214. package/dist/server/skills.js +26 -0
  215. package/dist/server/skills.js.map +1 -0
  216. package/dist/server/test.d.ts +3 -0
  217. package/dist/server/test.d.ts.map +1 -0
  218. package/dist/server/test.js +458 -0
  219. package/dist/server/test.js.map +1 -0
  220. package/dist/server/test.remote.test.d.ts +2 -0
  221. package/dist/server/test.remote.test.d.ts.map +1 -0
  222. package/dist/server/test.remote.test.js +396 -0
  223. package/dist/server/test.remote.test.js.map +1 -0
  224. package/dist/ui/build-config.d.ts +5 -0
  225. package/dist/ui/build-config.d.ts.map +1 -0
  226. package/dist/ui/build-config.js +229 -0
  227. package/dist/ui/build-config.js.map +1 -0
  228. package/dist/ui/build-config.test.d.ts +2 -0
  229. package/dist/ui/build-config.test.d.ts.map +1 -0
  230. package/dist/ui/build-config.test.js +272 -0
  231. package/dist/ui/build-config.test.js.map +1 -0
  232. package/dist/ui/index.d.ts +4 -0
  233. package/dist/ui/index.d.ts.map +1 -0
  234. package/dist/ui/index.js +8 -0
  235. package/dist/ui/index.js.map +1 -0
  236. package/dist/ui/parse-stdout.d.ts +3 -0
  237. package/dist/ui/parse-stdout.d.ts.map +1 -0
  238. package/dist/ui/parse-stdout.js +265 -0
  239. package/dist/ui/parse-stdout.js.map +1 -0
  240. package/dist/ui/parse-stdout.test.d.ts +2 -0
  241. package/dist/ui/parse-stdout.test.d.ts.map +1 -0
  242. package/dist/ui/parse-stdout.test.js +77 -0
  243. package/dist/ui/parse-stdout.test.js.map +1 -0
  244. package/package.json +61 -0
  245. package/skills/agentmail/SKILL.md +70 -0
  246. package/skills/paperclip/SKILL.md +712 -0
  247. package/skills/paperclip/references/api-reference.md +1675 -0
  248. package/skills/paperclip/references/artifacts.md +158 -0
  249. package/skills/paperclip/references/cases.md +295 -0
  250. package/skills/paperclip/references/company-skills.md +266 -0
  251. package/skills/paperclip/references/issue-workspaces.md +80 -0
  252. package/skills/paperclip/references/routines.md +231 -0
  253. package/skills/paperclip/references/workflows.md +141 -0
  254. package/skills/paperclip/scripts/paperclip-upload-artifact.sh +592 -0
  255. package/skills/paperclip-board/SKILL.md +619 -0
  256. package/skills/paperclip-converting-plans-to-tasks/SKILL.md +60 -0
  257. package/skills/paperclip-create-agent/SKILL.md +179 -0
  258. package/skills/paperclip-create-agent/references/agent-instruction-templates.md +123 -0
  259. package/skills/paperclip-create-agent/references/agents/coder.md +64 -0
  260. package/skills/paperclip-create-agent/references/agents/qa.md +88 -0
  261. package/skills/paperclip-create-agent/references/agents/securityengineer.md +135 -0
  262. package/skills/paperclip-create-agent/references/agents/uxdesigner.md +115 -0
  263. package/skills/paperclip-create-agent/references/api-reference.md +110 -0
  264. package/skills/paperclip-create-agent/references/baseline-role-guide.md +168 -0
  265. package/skills/paperclip-create-agent/references/draft-review-checklist.md +95 -0
  266. package/skills/para-memory-files/SKILL.md +100 -0
  267. package/skills/para-memory-files/references/schemas.md +35 -0
  268. 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.