@wardby/cli 0.6.0 → 0.8.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 (740) hide show
  1. package/.env.example +5 -5
  2. package/README.md +6 -1
  3. package/deploy/local/docker-compose.quickstart-coding.yml +19 -0
  4. package/dist/claude-coding-worker/driver.d.ts +33 -3
  5. package/dist/claude-coding-worker/driver.js +151 -21
  6. package/dist/claude-coding-worker/main.js +38 -6
  7. package/dist/claude-coding-worker/sdk.js +29 -2
  8. package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
  9. package/dist/claude-coding-worker/tool-socket.js +111 -0
  10. package/dist/claude-coding-worker/transcript.d.ts +18 -0
  11. package/dist/claude-coding-worker/transcript.js +77 -0
  12. package/dist/claude-plugin/command.d.ts +61 -0
  13. package/dist/claude-plugin/command.js +376 -0
  14. package/dist/cli-help.d.ts +1 -1
  15. package/dist/cli-help.js +3 -1
  16. package/dist/cli.js +71 -13
  17. package/dist/coding/code-host.d.ts +16 -0
  18. package/dist/coding/code-host.js +60 -0
  19. package/dist/coding/continuation-wording.d.ts +35 -0
  20. package/dist/coding/continuation-wording.js +73 -0
  21. package/dist/coding/linked-issue-note.d.ts +23 -0
  22. package/dist/coding/linked-issue-note.js +47 -0
  23. package/dist/coding/mcp-token.d.ts +12 -0
  24. package/dist/coding/mcp-token.js +26 -0
  25. package/dist/coding/merge-wording.d.ts +28 -0
  26. package/dist/coding/merge-wording.js +78 -0
  27. package/dist/coding/pr-description-note.d.ts +9 -0
  28. package/dist/coding/pr-description-note.js +32 -0
  29. package/dist/coding/profile.d.ts +46 -126
  30. package/dist/coding/profile.js +45 -4
  31. package/dist/coding/protected-path-wording.d.ts +8 -0
  32. package/dist/coding/protected-path-wording.js +1 -1
  33. package/dist/coding/protocol.d.ts +264 -346
  34. package/dist/coding/protocol.js +237 -12
  35. package/dist/coding/redact.d.ts +3 -0
  36. package/dist/coding/redact.js +17 -0
  37. package/dist/coding/registry/allowlist.d.ts +12 -0
  38. package/dist/coding/registry/allowlist.js +14 -1
  39. package/dist/coding/registry/audit-mode.d.ts +153 -0
  40. package/dist/coding/registry/audit-mode.js +304 -0
  41. package/dist/coding/registry/lockfile-shared.d.ts +36 -0
  42. package/dist/coding/registry/lockfile-shared.js +128 -0
  43. package/dist/coding/registry/lockfiles.js +1 -1
  44. package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
  45. package/dist/coding/registry/npm-lockfile-formats.js +41 -0
  46. package/dist/coding/registry/npm-lockfile.d.ts +8 -4
  47. package/dist/coding/registry/npm-lockfile.js +4 -6
  48. package/dist/coding/registry/npm.js +78 -8
  49. package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
  50. package/dist/coding/registry/pnpm-lockfile.js +189 -0
  51. package/dist/coding/registry/pypi-plan.d.ts +50 -0
  52. package/dist/coding/registry/pypi-plan.js +406 -0
  53. package/dist/coding/registry/pypi-requirements.d.ts +58 -0
  54. package/dist/coding/registry/pypi-requirements.js +155 -0
  55. package/dist/coding/registry/pypi.d.ts +3 -27
  56. package/dist/coding/registry/pypi.js +40 -154
  57. package/dist/coding/registry/refusal-hints.d.ts +20 -0
  58. package/dist/coding/registry/refusal-hints.js +61 -0
  59. package/dist/coding/registry/refusal-wording.d.ts +11 -0
  60. package/dist/coding/registry/refusal-wording.js +56 -0
  61. package/dist/coding/registry/report.d.ts +70 -8
  62. package/dist/coding/registry/report.js +112 -5
  63. package/dist/coding/registry/types.d.ts +58 -8
  64. package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
  65. package/dist/coding/registry/yarn-lockfile.js +367 -0
  66. package/dist/coding/services/catalog.d.ts +37 -351
  67. package/dist/coding/transcript/claude-code.d.ts +13 -0
  68. package/dist/coding/transcript/claude-code.js +273 -0
  69. package/dist/coding/transcript/download-protocol.d.ts +30 -0
  70. package/dist/coding/transcript/download-protocol.js +18 -0
  71. package/dist/coding/transcript/format.d.ts +20 -0
  72. package/dist/coding/transcript/format.js +32 -0
  73. package/dist/coding/transcript/recorder.d.ts +52 -0
  74. package/dist/coding/transcript/recorder.js +225 -0
  75. package/dist/coding/transcript/resume/checkout.d.ts +31 -0
  76. package/dist/coding/transcript/resume/checkout.js +203 -0
  77. package/dist/coding/transcript/resume/command.d.ts +17 -0
  78. package/dist/coding/transcript/resume/command.js +176 -0
  79. package/dist/coding/transcript/resume/download.d.ts +20 -0
  80. package/dist/coding/transcript/resume/download.js +153 -0
  81. package/dist/coding/transcript/resume/launch.d.ts +38 -0
  82. package/dist/coding/transcript/resume/launch.js +128 -0
  83. package/dist/coding/transcript/resume/session-file.d.ts +13 -0
  84. package/dist/coding/transcript/resume/session-file.js +79 -0
  85. package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
  86. package/dist/coding/transcript/resume/stand-in.js +49 -0
  87. package/dist/coding-worker/artifact.d.ts +8 -3
  88. package/dist/coding-worker/artifact.js +3 -1
  89. package/dist/coding-worker/debug-trace.d.ts +9 -6
  90. package/dist/coding-worker/debug-trace.js +16 -19
  91. package/dist/coding-worker/dependency-cache.d.mts +229 -0
  92. package/dist/coding-worker/dependency-cache.mjs +2123 -0
  93. package/dist/coding-worker/driver.d.ts +4 -3
  94. package/dist/coding-worker/driver.js +124 -39
  95. package/dist/coding-worker/errors.d.ts +1 -0
  96. package/dist/coding-worker/errors.js +32 -0
  97. package/dist/coding-worker/main.js +5 -1
  98. package/dist/coding-worker/mcp-config.d.ts +27 -0
  99. package/dist/coding-worker/mcp-config.js +32 -0
  100. package/dist/coding-worker/sdk.d.ts +36 -0
  101. package/dist/coding-worker/sdk.js +28 -1
  102. package/dist/coding-worker/task-note.d.ts +11 -0
  103. package/dist/coding-worker/task-note.js +13 -0
  104. package/dist/coding-worker/types.d.ts +15 -0
  105. package/dist/config/dependency-cache.d.ts +23 -0
  106. package/dist/config/dependency-cache.js +32 -0
  107. package/dist/config/mcp-call-limit.d.ts +8 -0
  108. package/dist/config/mcp-call-limit.js +18 -0
  109. package/dist/config/mcp-servers.d.ts +8 -0
  110. package/dist/config/mcp-servers.js +12 -0
  111. package/dist/config/providers.d.ts +12 -3
  112. package/dist/config/providers.js +55 -5
  113. package/dist/config/test-simulators.d.ts +92 -0
  114. package/dist/config/test-simulators.js +333 -0
  115. package/dist/config/tool-timeout.d.ts +1 -0
  116. package/dist/config/tool-timeout.js +18 -0
  117. package/dist/core/async-context.d.ts +2 -0
  118. package/dist/core/async-context.js +12 -0
  119. package/dist/core/budget-events.d.ts +108 -0
  120. package/dist/core/budget-events.js +346 -0
  121. package/dist/core/budget-groups.d.ts +50 -1
  122. package/dist/core/budget-groups.js +236 -27
  123. package/dist/core/budget-stopped-head.d.ts +46 -0
  124. package/dist/core/budget-stopped-head.js +81 -0
  125. package/dist/core/budget-topup.d.ts +51 -0
  126. package/dist/core/budget-topup.js +156 -0
  127. package/dist/core/budget-wording.d.ts +16 -2
  128. package/dist/core/budget-wording.js +40 -2
  129. package/dist/core/coding-mcp.d.ts +36 -0
  130. package/dist/core/coding-mcp.js +253 -0
  131. package/dist/core/coding-queue.d.ts +2 -1
  132. package/dist/core/coding-queue.js +7 -0
  133. package/dist/core/coding-repository.d.ts +46 -0
  134. package/dist/core/coding-repository.js +92 -0
  135. package/dist/core/cron.d.ts +19 -1
  136. package/dist/core/cron.js +17 -0
  137. package/dist/core/datastores.js +1 -1
  138. package/dist/core/deferred-coding.d.ts +14 -0
  139. package/dist/core/deferred-coding.js +62 -0
  140. package/dist/core/delegation-child.d.ts +25 -0
  141. package/dist/core/delegation-child.js +37 -0
  142. package/dist/core/delegation-slots.d.ts +27 -0
  143. package/dist/core/delegation-slots.js +44 -0
  144. package/dist/core/dispatch.d.ts +48 -2
  145. package/dist/core/dispatch.js +166 -66
  146. package/dist/core/engine-native.js +1 -1
  147. package/dist/core/error-code.d.ts +38 -0
  148. package/dist/core/error-code.js +169 -0
  149. package/dist/core/grants.d.ts +46 -8
  150. package/dist/core/grants.js +99 -8
  151. package/dist/core/host-events.d.ts +18 -2
  152. package/dist/core/host-events.js +291 -27
  153. package/dist/core/host-status.d.ts +85 -3
  154. package/dist/core/host-status.js +300 -22
  155. package/dist/core/issue-bridge.d.ts +50 -6
  156. package/dist/core/issue-bridge.js +124 -33
  157. package/dist/core/issue-events.d.ts +1 -1
  158. package/dist/core/issue-events.js +4 -10
  159. package/dist/core/issue-status.d.ts +1 -1
  160. package/dist/core/issue-status.js +58 -29
  161. package/dist/core/logger.d.ts +5 -0
  162. package/dist/core/logger.js +14 -1
  163. package/dist/core/lost-run-children.d.ts +6 -0
  164. package/dist/core/lost-run-children.js +32 -0
  165. package/dist/core/mark-ready.d.ts +34 -0
  166. package/dist/core/mark-ready.js +152 -0
  167. package/dist/core/markdown-code.d.ts +8 -0
  168. package/dist/core/markdown-code.js +107 -0
  169. package/dist/core/mcp-client/client.d.ts +47 -0
  170. package/dist/core/mcp-client/client.js +141 -0
  171. package/dist/core/mcp-client/jsonrpc.d.ts +15 -0
  172. package/dist/core/mcp-client/jsonrpc.js +54 -0
  173. package/dist/core/mcp-client/results.d.ts +13 -0
  174. package/dist/core/mcp-client/results.js +42 -0
  175. package/dist/core/mcp-servers.d.ts +90 -0
  176. package/dist/core/mcp-servers.js +230 -0
  177. package/dist/core/mcp-tools.d.ts +108 -0
  178. package/dist/core/mcp-tools.js +287 -0
  179. package/dist/core/memory-tools.js +7 -0
  180. package/dist/core/merge-order-check.d.ts +2 -1
  181. package/dist/core/merge-order-check.js +44 -18
  182. package/dist/core/notification-dispatcher.js +2 -1
  183. package/dist/core/notification-templates.d.ts +1 -7
  184. package/dist/core/notification-templates.js +36 -2
  185. package/dist/core/pull-request-state-sync.js +2 -2
  186. package/dist/core/reconciler.d.ts +4 -3
  187. package/dist/core/reconciler.js +8 -1
  188. package/dist/core/related-pull-requests.d.ts +11 -3
  189. package/dist/core/related-pull-requests.js +49 -20
  190. package/dist/core/reply-parts.d.ts +21 -0
  191. package/dist/core/reply-parts.js +73 -0
  192. package/dist/core/review-fix.d.ts +1 -1
  193. package/dist/core/review-fix.js +4 -3
  194. package/dist/core/review-host-checks.d.ts +1 -1
  195. package/dist/core/review-host-tools.d.ts +3 -0
  196. package/dist/core/review-host-tools.js +102 -14
  197. package/dist/core/review-reads.d.ts +55 -0
  198. package/dist/core/review-reads.js +233 -0
  199. package/dist/core/run-status.d.ts +12 -0
  200. package/dist/core/run-status.js +12 -0
  201. package/dist/core/runner.d.ts +145 -49
  202. package/dist/core/runner.js +719 -216
  203. package/dist/core/schedule-start.d.ts +12 -0
  204. package/dist/core/schedule-start.js +14 -0
  205. package/dist/core/secret-broker-config.d.ts +12 -74
  206. package/dist/core/secret-broker-config.js +1 -1
  207. package/dist/core/secret-guard.d.ts +49 -0
  208. package/dist/core/secret-guard.js +119 -0
  209. package/dist/core/secret-guarded-stores.d.ts +12 -0
  210. package/dist/core/secret-guarded-stores.js +41 -0
  211. package/dist/core/secret-spans.d.ts +50 -0
  212. package/dist/core/secret-spans.js +94 -0
  213. package/dist/core/secrets.d.ts +11 -1
  214. package/dist/core/secrets.js +27 -1
  215. package/dist/core/serializable-retry.d.ts +18 -0
  216. package/dist/core/serializable-retry.js +43 -0
  217. package/dist/core/stop-run.d.ts +46 -0
  218. package/dist/core/stop-run.js +61 -0
  219. package/dist/core/tool-admin.d.ts +5 -1
  220. package/dist/core/tool-admin.js +7 -2
  221. package/dist/core/tool-names.d.ts +13 -0
  222. package/dist/core/tool-names.js +20 -0
  223. package/dist/core/webhooks.d.ts +4 -0
  224. package/dist/core/webhooks.js +68 -49
  225. package/dist/core/workflow-events.d.ts +14 -2
  226. package/dist/core/workflow-events.js +4 -0
  227. package/dist/core/workflow-run-events.d.ts +5 -3
  228. package/dist/core/workflow-run-events.js +45 -9
  229. package/dist/core/zod-json-schema.d.ts +4 -0
  230. package/dist/core/zod-json-schema.js +39 -0
  231. package/dist/core/zod3-window.d.ts +35 -0
  232. package/dist/core/zod3-window.js +124 -0
  233. package/dist/generated/prisma/browser.d.ts +65 -3
  234. package/dist/generated/prisma/client.d.ts +65 -3
  235. package/dist/generated/prisma/commonInputTypes.d.ts +266 -106
  236. package/dist/generated/prisma/enums.d.ts +10 -0
  237. package/dist/generated/prisma/enums.js +8 -0
  238. package/dist/generated/prisma/internal/class.d.ts +110 -0
  239. package/dist/generated/prisma/internal/class.js +4 -4
  240. package/dist/generated/prisma/internal/prismaNamespace.d.ts +957 -9
  241. package/dist/generated/prisma/internal/prismaNamespace.js +166 -2
  242. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +174 -0
  243. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +166 -2
  244. package/dist/generated/prisma/models/Agent.d.ts +377 -8
  245. package/dist/generated/prisma/models/AgentMcpServer.d.ts +1412 -0
  246. package/dist/generated/prisma/models/AgentMcpServer.js +1 -0
  247. package/dist/generated/prisma/models/AgentRepository.d.ts +81 -1
  248. package/dist/generated/prisma/models/AuthUser.d.ts +1 -1
  249. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +228 -7
  250. package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
  251. package/dist/generated/prisma/models/CodingProxySession.d.ts +232 -2
  252. package/dist/generated/prisma/models/CodingRun.d.ts +1712 -1
  253. package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
  254. package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
  255. package/dist/generated/prisma/models/HostProvider.d.ts +2176 -0
  256. package/dist/generated/prisma/models/HostProvider.js +1 -0
  257. package/dist/generated/prisma/models/HostProviderCredential.d.ts +1285 -0
  258. package/dist/generated/prisma/models/HostProviderCredential.js +1 -0
  259. package/dist/generated/prisma/models/HostProviderOperation.d.ts +1470 -0
  260. package/dist/generated/prisma/models/HostProviderOperation.js +1 -0
  261. package/dist/generated/prisma/models/HostProviderTrustedAccount.d.ts +1145 -0
  262. package/dist/generated/prisma/models/HostProviderTrustedAccount.js +1 -0
  263. package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
  264. package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
  265. package/dist/generated/prisma/models/McpServer.d.ts +1500 -0
  266. package/dist/generated/prisma/models/McpServer.js +1 -0
  267. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +77 -1
  268. package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
  269. package/dist/generated/prisma/models/Principal.d.ts +167 -0
  270. package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
  271. package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
  272. package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
  273. package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
  274. package/dist/generated/prisma/models/ResourceGrant.d.ts +1 -1
  275. package/dist/generated/prisma/models/Run.d.ts +738 -2
  276. package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
  277. package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
  278. package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
  279. package/dist/generated/prisma/models/RunTranscript.js +1 -0
  280. package/dist/generated/prisma/models/Secret.d.ts +387 -0
  281. package/dist/generated/prisma/models/Tool.d.ts +223 -1
  282. package/dist/generated/prisma/models.d.ts +10 -0
  283. package/dist/help/search.js +12 -3
  284. package/dist/help-index.json +2033 -110
  285. package/dist/import/create.js +48 -4
  286. package/dist/import/neutral-schema.d.ts +51 -281
  287. package/dist/import/neutral-schema.js +7 -4
  288. package/dist/knowledge/check.d.ts +1 -1
  289. package/dist/knowledge/cli.d.ts +11 -1
  290. package/dist/knowledge/cli.js +37 -4
  291. package/dist/knowledge/concept.d.ts +3 -19
  292. package/dist/knowledge/location.d.ts +31 -0
  293. package/dist/knowledge/location.js +78 -0
  294. package/dist/mcp/auth/access.d.ts +10 -2
  295. package/dist/mcp/auth/access.js +15 -1
  296. package/dist/mcp/auth/grants-cli.d.ts +6 -4
  297. package/dist/mcp/auth/grants-cli.js +42 -3
  298. package/dist/mcp/auth/ownership.d.ts +7 -7
  299. package/dist/mcp/auth/resource-server.d.ts +3 -1
  300. package/dist/mcp/auth/resource-server.js +17 -2
  301. package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
  302. package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
  303. package/dist/mcp/context.d.ts +3 -0
  304. package/dist/mcp/host-events/github-ingress.d.ts +2 -0
  305. package/dist/mcp/host-events/github-ingress.js +2 -1
  306. package/dist/mcp/index.d.ts +6 -0
  307. package/dist/mcp/index.js +69 -10
  308. package/dist/mcp/server.d.ts +13 -0
  309. package/dist/mcp/server.js +33 -14
  310. package/dist/mcp/tools/agents.d.ts +4 -0
  311. package/dist/mcp/tools/agents.js +295 -28
  312. package/dist/mcp/tools/datastore.js +17 -8
  313. package/dist/mcp/tools/grants.js +73 -29
  314. package/dist/mcp/tools/host-providers.d.ts +2 -0
  315. package/dist/mcp/tools/host-providers.js +215 -0
  316. package/dist/mcp/tools/mcp-servers.d.ts +26 -0
  317. package/dist/mcp/tools/mcp-servers.js +481 -0
  318. package/dist/mcp/tools/memory.js +11 -1
  319. package/dist/mcp/tools/notification-channels.js +2 -2
  320. package/dist/mcp/tools/packages.d.ts +2 -0
  321. package/dist/mcp/tools/packages.js +195 -0
  322. package/dist/mcp/tools/repositories.js +65 -12
  323. package/dist/mcp/tools/run-access.d.ts +16 -0
  324. package/dist/mcp/tools/run-access.js +25 -0
  325. package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
  326. package/dist/mcp/tools/run-transcript-download.js +129 -0
  327. package/dist/mcp/tools/run-transcript.d.ts +19 -0
  328. package/dist/mcp/tools/run-transcript.js +70 -0
  329. package/dist/mcp/tools/runs.js +209 -27
  330. package/dist/mcp/tools/scheduling.js +3 -1
  331. package/dist/mcp/tools/secret-elicitation-form.js +5 -0
  332. package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
  333. package/dist/mcp/tools/secret-elicitation-server.js +10 -61
  334. package/dist/mcp/tools/secret-elicitation.d.ts +2 -0
  335. package/dist/mcp/tools/secret-elicitation.js +25 -2
  336. package/dist/mcp/tools/secrets.js +40 -6
  337. package/dist/mcp/tools/stop-run.d.ts +2 -0
  338. package/dist/mcp/tools/stop-run.js +82 -0
  339. package/dist/mcp/tools/subagents.js +2 -2
  340. package/dist/mcp/tools/tools.d.ts +7 -5
  341. package/dist/mcp/tools/tools.js +64 -16
  342. package/dist/mcp/tools/trigger.js +28 -6
  343. package/dist/mcp/transport/http-limits.d.ts +2 -0
  344. package/dist/mcp/transport/http-limits.js +6 -2
  345. package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
  346. package/dist/mcp/transport/stdio-link-host.js +67 -0
  347. package/dist/mcp/transport/streamable-http.d.ts +13 -0
  348. package/dist/mcp/transport/streamable-http.js +41 -1
  349. package/dist/mcp/webhooks/ingress.js +10 -0
  350. package/dist/native-worker/docker-launcher.d.ts +38 -2
  351. package/dist/native-worker/docker-launcher.js +65 -5
  352. package/dist/native-worker/gateway-server.d.ts +55 -3
  353. package/dist/native-worker/gateway-server.js +152 -34
  354. package/dist/native-worker/gateway.d.ts +29 -1
  355. package/dist/native-worker/gateway.js +74 -4
  356. package/dist/native-worker/http-server.d.ts +7 -1
  357. package/dist/native-worker/http-server.js +62 -7
  358. package/dist/native-worker/http-transport.js +1 -1
  359. package/dist/native-worker/kubernetes-launcher.d.ts +7 -3
  360. package/dist/native-worker/kubernetes-launcher.js +43 -3
  361. package/dist/native-worker/launch.d.ts +18 -1
  362. package/dist/native-worker/launch.js +6 -1
  363. package/dist/native-worker/ledger.d.ts +24 -4
  364. package/dist/native-worker/ledger.js +62 -8
  365. package/dist/native-worker/loopback.js +3 -8
  366. package/dist/native-worker/main.d.ts +2 -1
  367. package/dist/native-worker/main.js +14 -3
  368. package/dist/native-worker/protocol.d.ts +130 -577
  369. package/dist/native-worker/protocol.js +51 -2
  370. package/dist/native-worker/sandbox-executor.d.ts +17 -2
  371. package/dist/native-worker/sandbox-executor.js +78 -4
  372. package/dist/native-worker/stderr-redaction.d.ts +77 -0
  373. package/dist/native-worker/stderr-redaction.js +237 -0
  374. package/dist/native-worker/stdio.d.ts +1 -1
  375. package/dist/native-worker/stdio.js +6 -5
  376. package/dist/native-worker/warm-pool.d.ts +2 -2
  377. package/dist/native-worker/warm-pool.js +4 -4
  378. package/dist/native-worker/worker.js +28 -2
  379. package/dist/observability/metrics.js +6 -1
  380. package/dist/providers/auth/self-hosted.d.ts +1 -1
  381. package/dist/providers/coding-proxy/capability-hash.d.ts +2 -0
  382. package/dist/providers/coding-proxy/capability-hash.js +5 -0
  383. package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
  384. package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
  385. package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
  386. package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
  387. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
  388. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
  389. package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
  390. package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
  391. package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
  392. package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
  393. package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
  394. package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
  395. package/dist/providers/coding-proxy/hold.d.ts +32 -0
  396. package/dist/providers/coding-proxy/hold.js +86 -0
  397. package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
  398. package/dist/providers/coding-proxy/interrupted.js +104 -0
  399. package/dist/providers/coding-proxy/mcp-route.d.ts +34 -0
  400. package/dist/providers/coding-proxy/mcp-route.js +166 -0
  401. package/dist/providers/coding-proxy/memory-ledger.d.ts +17 -2
  402. package/dist/providers/coding-proxy/memory-ledger.js +99 -8
  403. package/dist/providers/coding-proxy/metering.d.ts +16 -0
  404. package/dist/providers/coding-proxy/metering.js +27 -4
  405. package/dist/providers/coding-proxy/prisma-ledger.d.ts +16 -2
  406. package/dist/providers/coding-proxy/prisma-ledger.js +209 -69
  407. package/dist/providers/coding-proxy/proxy.d.ts +21 -2
  408. package/dist/providers/coding-proxy/proxy.js +300 -48
  409. package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
  410. package/dist/providers/coding-proxy/registry/audit.js +94 -17
  411. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
  412. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
  413. package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
  414. package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
  415. package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
  416. package/dist/providers/coding-proxy/registry/plan.js +201 -48
  417. package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
  418. package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
  419. package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
  420. package/dist/providers/coding-proxy/registry/service.js +579 -112
  421. package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
  422. package/dist/providers/coding-proxy/registry/store.js +54 -1
  423. package/dist/providers/coding-proxy/runtime.d.ts +10 -0
  424. package/dist/providers/coding-proxy/runtime.js +109 -16
  425. package/dist/providers/coding-proxy/server.d.ts +9 -1
  426. package/dist/providers/coding-proxy/server.js +55 -1
  427. package/dist/providers/coding-proxy/types.d.ts +78 -1
  428. package/dist/providers/datastore/types.d.ts +5 -0
  429. package/dist/providers/engine/types.d.ts +17 -2
  430. package/dist/providers/engine/types.js +17 -0
  431. package/dist/providers/executor/composition.d.ts +10 -3
  432. package/dist/providers/executor/composition.js +52 -7
  433. package/dist/providers/executor/container.d.ts +394 -9
  434. package/dist/providers/executor/container.js +1210 -96
  435. package/dist/providers/executor/dbos-status.d.ts +31 -0
  436. package/dist/providers/executor/dbos-status.js +64 -0
  437. package/dist/providers/executor/dbos.d.ts +50 -1
  438. package/dist/providers/executor/dbos.js +207 -20
  439. package/dist/providers/executor/deferred.d.ts +12 -24
  440. package/dist/providers/executor/deferred.js +10 -29
  441. package/dist/providers/executor/in-process.d.ts +9 -1
  442. package/dist/providers/executor/in-process.js +14 -4
  443. package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
  444. package/dist/providers/executor/linked-issue-reader.js +30 -0
  445. package/dist/providers/executor/routing.d.ts +2 -0
  446. package/dist/providers/executor/routing.js +4 -0
  447. package/dist/providers/executor/types.d.ts +13 -0
  448. package/dist/providers/host-tools/invoke.d.ts +37 -0
  449. package/dist/providers/host-tools/invoke.js +117 -0
  450. package/dist/providers/host-tools/operations.d.ts +65 -0
  451. package/dist/providers/host-tools/operations.js +149 -0
  452. package/dist/providers/host-tools/registry.d.ts +79 -0
  453. package/dist/providers/host-tools/registry.js +362 -0
  454. package/dist/providers/host-tools/request-guard.d.ts +17 -0
  455. package/dist/providers/host-tools/request-guard.js +99 -0
  456. package/dist/providers/host-tools/self-test.d.ts +64 -0
  457. package/dist/providers/host-tools/self-test.js +142 -0
  458. package/dist/providers/index.d.ts +2 -1
  459. package/dist/providers/issue-tracker/types.d.ts +17 -0
  460. package/dist/providers/issue-tracker/types.js +39 -1
  461. package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
  462. package/dist/providers/jobs/claude-tool-setup.js +5 -2
  463. package/dist/providers/jobs/docker-isolation.d.ts +10 -2
  464. package/dist/providers/jobs/docker-isolation.js +47 -8
  465. package/dist/providers/jobs/docker.d.ts +9 -0
  466. package/dist/providers/jobs/docker.js +60 -11
  467. package/dist/providers/jobs/fake-kubernetes-api.d.ts +2 -0
  468. package/dist/providers/jobs/fake-kubernetes-api.js +3 -0
  469. package/dist/providers/jobs/kubernetes-api.d.ts +8 -0
  470. package/dist/providers/jobs/kubernetes-api.js +10 -0
  471. package/dist/providers/jobs/kubernetes-client.js +10 -1
  472. package/dist/providers/jobs/kubernetes-isolation.d.ts +5 -1
  473. package/dist/providers/jobs/kubernetes-isolation.js +32 -3
  474. package/dist/providers/jobs/kubernetes.d.ts +11 -1
  475. package/dist/providers/jobs/kubernetes.js +111 -17
  476. package/dist/providers/jobs/types.d.ts +39 -0
  477. package/dist/providers/jobs/types.js +13 -1
  478. package/dist/providers/llm/anthropic.js +5 -1
  479. package/dist/providers/llm/bedrock.d.ts +0 -12
  480. package/dist/providers/llm/bedrock.js +4 -0
  481. package/dist/providers/llm/claude-messages.d.ts +3 -1
  482. package/dist/providers/llm/claude-messages.js +4 -1
  483. package/dist/providers/llm/claude-provider.d.ts +2 -2
  484. package/dist/providers/llm/claude-provider.js +2 -2
  485. package/dist/providers/llm/openai.d.ts +2 -2
  486. package/dist/providers/llm/openai.js +6 -2
  487. package/dist/providers/llm/routing.d.ts +2 -2
  488. package/dist/providers/llm/routing.js +2 -2
  489. package/dist/providers/llm/types.d.ts +12 -2
  490. package/dist/providers/review-host/github-events.d.ts +9 -1
  491. package/dist/providers/review-host/github-events.js +34 -12
  492. package/dist/providers/review-host/github.d.ts +29 -2
  493. package/dist/providers/review-host/github.js +224 -29
  494. package/dist/providers/review-host/local.d.ts +8 -4
  495. package/dist/providers/review-host/local.js +49 -31
  496. package/dist/providers/review-host/patch-pages.d.ts +41 -0
  497. package/dist/providers/review-host/patch-pages.js +176 -0
  498. package/dist/providers/review-host/review-format.d.ts +19 -1
  499. package/dist/providers/review-host/review-format.js +38 -7
  500. package/dist/providers/review-host/types.d.ts +140 -6
  501. package/dist/providers/review-host/types.js +9 -1
  502. package/dist/providers/storage/gcs.d.ts +63 -0
  503. package/dist/providers/storage/gcs.js +69 -0
  504. package/dist/providers/storage/index.d.ts +15 -0
  505. package/dist/providers/storage/index.js +14 -0
  506. package/dist/providers/storage/local.d.ts +24 -0
  507. package/dist/providers/storage/local.js +92 -0
  508. package/dist/providers/storage/meter.d.ts +14 -0
  509. package/dist/providers/storage/meter.js +34 -0
  510. package/dist/providers/storage/s3.d.ts +41 -0
  511. package/dist/providers/storage/s3.js +107 -0
  512. package/dist/providers/storage/types.d.ts +37 -3
  513. package/dist/providers/storage/types.js +21 -4
  514. package/dist/providers/vcs/git.d.ts +39 -4
  515. package/dist/providers/vcs/git.js +339 -26
  516. package/dist/providers/vcs/github-remote.d.ts +26 -3
  517. package/dist/providers/vcs/github-remote.js +124 -14
  518. package/dist/providers/vcs/github.d.ts +183 -44
  519. package/dist/providers/vcs/github.js +455 -56
  520. package/dist/providers/vcs/index.d.ts +1 -1
  521. package/dist/providers/vcs/index.js +9 -2
  522. package/dist/providers/vcs/pr-description.d.ts +127 -0
  523. package/dist/providers/vcs/pr-description.js +270 -0
  524. package/dist/providers/vcs/remote.d.ts +37 -1
  525. package/dist/providers/vcs/remote.js +7 -1
  526. package/dist/providers/vcs/routing.d.ts +16 -8
  527. package/dist/providers/vcs/routing.js +27 -6
  528. package/dist/providers/vcs/types.d.ts +150 -5
  529. package/dist/quickstart/coding-seed.d.ts +14 -3
  530. package/dist/quickstart/coding-seed.js +213 -4
  531. package/dist/quickstart/index.d.ts +5 -0
  532. package/dist/quickstart/index.js +21 -0
  533. package/dist/quickstart/reviewer-prompt.d.ts +1 -1
  534. package/dist/quickstart/reviewer-prompt.js +6 -6
  535. package/dist/quickstart-images.json +1 -1
  536. package/dist/sandbox/eval-core.d.ts +12 -2
  537. package/dist/sandbox/eval-core.js +20 -4
  538. package/dist/sandbox/generated/zod.bundle.js +62 -1
  539. package/dist/sandbox/generated/zod3.bundle.js +5 -0
  540. package/dist/sandbox/host-functions.d.ts +5 -0
  541. package/dist/sandbox/host-functions.js +13 -13
  542. package/dist/sandbox/limits.d.ts +4 -1
  543. package/dist/sandbox/limits.js +4 -1
  544. package/dist/sandbox/run-in-sandbox.d.ts +6 -0
  545. package/dist/sandbox/run-in-sandbox.js +14 -2
  546. package/dist/sandbox/safe-fetch.d.ts +2 -0
  547. package/dist/sandbox/safe-fetch.js +1 -1
  548. package/dist/sandbox/secret-broker.d.ts +1 -0
  549. package/dist/sandbox/secret-broker.js +4 -5
  550. package/dist/sandbox/tool-capabilities.d.ts +10 -30
  551. package/dist/sandbox/tool-timeout.d.ts +32 -0
  552. package/dist/sandbox/tool-timeout.js +52 -0
  553. package/dist/sandbox/user-tool.d.ts +8 -1
  554. package/dist/sandbox/user-tool.js +9 -3
  555. package/dist/sandbox/zod-params.d.ts +37 -5
  556. package/dist/sandbox/zod-params.js +181 -26
  557. package/dist/serve.js +8 -1
  558. package/dist/viewer/api-schema.d.ts +349 -2627
  559. package/dist/viewer/api-schema.js +7 -0
  560. package/dist/viewer/build-schemas.js +6 -2
  561. package/dist/viewer/graph.js +2 -1
  562. package/dist/viewer/openapi.js +2 -4
  563. package/dist/wardby-bin.js +15 -0
  564. package/docs/README.md +11 -1
  565. package/docs/agent-recipes.md +95 -24
  566. package/docs/architecture-runtime.md +1 -1
  567. package/docs/claude-code-plugin.md +164 -0
  568. package/docs/code-review-agents.md +557 -41
  569. package/docs/coding-agent-setup.md +566 -8
  570. package/docs/coding-packages.md +1033 -90
  571. package/docs/coding-services.md +27 -12
  572. package/docs/coding-worker-byo-images.md +24 -2
  573. package/docs/coding-worker-isolation.md +183 -37
  574. package/docs/debugging-agent-runs.md +242 -0
  575. package/docs/getting-started-gke.md +129 -141
  576. package/docs/getting-started-identity-provider.md +53 -38
  577. package/docs/getting-started.md +17 -0
  578. package/docs/host-providers.md +294 -0
  579. package/docs/jira-agents.md +17 -8
  580. package/docs/knowledge/blob-not-found-semantics.md +41 -0
  581. package/docs/knowledge/bounded-file-descriptor.md +52 -0
  582. package/docs/knowledge/delegation-admission-slots.md +52 -0
  583. package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
  584. package/docs/knowledge/import-rename-target.md +52 -0
  585. package/docs/knowledge/index.md +57 -0
  586. package/docs/knowledge/log.md +9 -0
  587. package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
  588. package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
  589. package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
  590. package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
  591. package/docs/knowledge/overview-cli.md +74 -0
  592. package/docs/knowledge/overview-coding-proxy.md +72 -0
  593. package/docs/knowledge/overview-coding.md +72 -0
  594. package/docs/knowledge/overview-config.md +60 -0
  595. package/docs/knowledge/overview-core.md +72 -0
  596. package/docs/knowledge/overview-deploy.md +83 -0
  597. package/docs/knowledge/overview-mcp.md +61 -0
  598. package/docs/knowledge/overview-prisma.md +72 -0
  599. package/docs/knowledge/overview-providers.md +89 -0
  600. package/docs/knowledge/overview-sandbox.md +83 -0
  601. package/docs/knowledge/overview-surfaces.md +83 -0
  602. package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
  603. package/docs/knowledge/proxy-settlement-projections.md +41 -0
  604. package/docs/knowledge/run-pricing-first-writer.md +43 -0
  605. package/docs/knowledge/schedule-claim-transaction.md +41 -0
  606. package/docs/knowledge/secret-entry-replica-contract.md +52 -0
  607. package/docs/knowledge/terminal-run-first-writer.md +41 -0
  608. package/docs/knowledge/transactional-agent-authorization.md +52 -0
  609. package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
  610. package/docs/knowledge/warm-input-publication.md +30 -0
  611. package/docs/knowledge/workspace-staging-failure.md +54 -0
  612. package/docs/knowledge.md +54 -14
  613. package/docs/mcp-servers.md +254 -0
  614. package/docs/native-sandbox.md +143 -31
  615. package/docs/observability.md +4 -0
  616. package/docs/security-deployment.md +139 -29
  617. package/docs/slack-notifications.md +35 -19
  618. package/docs/tool-secrets.md +45 -10
  619. package/docs/viewer-api.md +6 -0
  620. package/docs/viewer-api.openapi.yml +1 -1
  621. package/help/admin-viewer.md +28 -2
  622. package/help/agent-recipes.md +33 -2
  623. package/help/architecture-agent.md +11 -6
  624. package/help/brokered-secrets.md +3 -0
  625. package/help/build-claude-code-image.md +1 -1
  626. package/help/build-worker-image.md +3 -1
  627. package/help/builder-agent.md +19 -6
  628. package/help/claude-code-run-pane.md +40 -0
  629. package/help/code-review-agents.md +177 -6
  630. package/help/coding-packages.md +156 -6
  631. package/help/cost-attribution.md +9 -5
  632. package/help/creating-agents.md +14 -1
  633. package/help/dependency-cache.md +143 -0
  634. package/help/deploy-gke.md +15 -8
  635. package/help/errors/budget-exhausted.md +187 -0
  636. package/help/errors/budget-group-exhausted.md +5 -1
  637. package/help/errors/coding-mcp-pins-unavailable.md +35 -0
  638. package/help/errors/coding-stream-quota-exceeded.md +33 -0
  639. package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
  640. package/help/errors/continuation-closed.md +9 -12
  641. package/help/errors/database-auth-invalid.md +1 -1
  642. package/help/errors/delegation-conflict.md +24 -0
  643. package/help/errors/file-list-truncated.md +45 -0
  644. package/help/errors/full-read-required.md +49 -0
  645. package/help/errors/github-account-not-allowed.md +4 -0
  646. package/help/errors/graph-incomplete.md +43 -0
  647. package/help/errors/graph-limit.md +43 -0
  648. package/help/errors/host-provider-error.md +40 -0
  649. package/help/errors/host-tool-failed.md +36 -0
  650. package/help/errors/mcp-call-limit.md +22 -0
  651. package/help/errors/mcp-call-timeout.md +22 -0
  652. package/help/errors/mcp-server-auth-failed.md +22 -0
  653. package/help/errors/mcp-server-credentials-unavailable.md +45 -0
  654. package/help/errors/mcp-server-error.md +28 -0
  655. package/help/errors/mcp-server-unreachable.md +22 -0
  656. package/help/errors/mcp-servers-off.md +21 -0
  657. package/help/errors/mcp-tool-not-allowed.md +26 -0
  658. package/help/errors/mcp-tool-removed.md +22 -0
  659. package/help/errors/mcp-unavailable.md +25 -0
  660. package/help/errors/merge-conflict.md +49 -0
  661. package/help/errors/native-sandbox-capacity.md +1 -1
  662. package/help/errors/native-sandbox-deadline-exceeded.md +1 -1
  663. package/help/errors/native-sandbox-docker-failed.md +1 -1
  664. package/help/errors/native-sandbox-gateway-error.md +20 -0
  665. package/help/errors/native-sandbox-gateway-unavailable.md +1 -1
  666. package/help/errors/native-sandbox-image-not-pinned.md +1 -1
  667. package/help/errors/native-sandbox-isolation-mismatch.md +1 -1
  668. package/help/errors/native-sandbox-launch-abandoned.md +21 -0
  669. package/help/errors/native-sandbox-network-unenforced.md +1 -1
  670. package/help/errors/native-sandbox-requires-catalog.md +1 -1
  671. package/help/errors/native-sandbox-unavailable.md +1 -1
  672. package/help/errors/native-sandbox-warm-delivery-failed.md +1 -1
  673. package/help/errors/native-sandbox-worker-exited.md +4 -3
  674. package/help/errors/native-sandbox-worker-lost.md +1 -1
  675. package/help/errors/native-sandbox-worker-unready.md +1 -1
  676. package/help/errors/package-not-allowed-pending.md +52 -0
  677. package/help/errors/package-not-allowed.md +51 -0
  678. package/help/errors/package-refusals.md +43 -0
  679. package/help/errors/patch-cursor-malformed.md +31 -0
  680. package/help/errors/repository-not-listed.md +36 -0
  681. package/help/errors/repository-required.md +36 -0
  682. package/help/errors/run-lost.md +39 -0
  683. package/help/errors/run-transcript-download.md +44 -0
  684. package/help/errors/secret-in-value.md +69 -0
  685. package/help/errors/target-merge.md +40 -0
  686. package/help/errors/tool-timeout.md +38 -0
  687. package/help/fix-merge-conflicts.md +73 -0
  688. package/help/github-app-setup.md +132 -0
  689. package/help/github.md +22 -0
  690. package/help/host-providers.md +40 -0
  691. package/help/identity-and-access.md +6 -1
  692. package/help/jira.md +23 -6
  693. package/help/knowledge.md +16 -7
  694. package/help/local-repositories.md +1 -1
  695. package/help/low-power-mode.md +7 -1
  696. package/help/mcp-servers.md +73 -0
  697. package/help/mcp.md +7 -2
  698. package/help/merge-order-check.md +5 -0
  699. package/help/native-capabilities.md +55 -1
  700. package/help/native-sandbox.md +16 -2
  701. package/help/operating-agents.md +21 -0
  702. package/help/package-audit-mode.md +91 -0
  703. package/help/related-pull-requests.md +17 -10
  704. package/help/repo-instructions-and-skills.md +3 -1
  705. package/help/resume-runs-locally.md +134 -0
  706. package/help/review-fix-rounds.md +33 -1
  707. package/help/sharing-agents.md +59 -0
  708. package/help/slack-notifications.md +19 -5
  709. package/help/status-comments.md +31 -0
  710. package/help/stop-run.md +58 -0
  711. package/help/troubleshooting/budgets.md +28 -0
  712. package/help/troubleshooting/coding-workers.md +86 -7
  713. package/help/troubleshooting/debugging-agent-runs.md +29 -0
  714. package/package.json +18 -10
  715. package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
  716. package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
  717. package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
  718. package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
  719. package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
  720. package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
  721. package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
  722. package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
  723. package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
  724. package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
  725. package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
  726. package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
  727. package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
  728. package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
  729. package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
  730. package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
  731. package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
  732. package/prisma/migrations/20261102000000_host_providers/migration.sql +56 -0
  733. package/prisma/migrations/20261104000000_coding_agent_repository_list/migration.sql +5 -0
  734. package/prisma/migrations/20261106000000_tool_timeout/migration.sql +4 -0
  735. package/prisma/migrations/20261107000000_mcp_servers/migration.sql +33 -0
  736. package/prisma/migrations/20261108000000_coding_mcp/migration.sql +5 -0
  737. package/prisma/migrations/20261109000000_task_run_index/migration.sql +3 -0
  738. package/prisma/schema.prisma +468 -109
  739. package/scripts/git-askpass.sh +1 -1
  740. package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
@@ -0,0 +1,273 @@
1
+ const KEPT_TYPES = new Set(["user", "assistant", "attachment", "system", "ai-title", "custom-title", "summary"]);
2
+ /** System records kept: a compaction boundary decides which history a resume loads. */
3
+ const KEPT_SYSTEM = new Set(["compact_boundary"]);
4
+ /** Attachments that are part of the conversation the model saw and still applies on a laptop. */
5
+ export const KEPT_ATTACHMENTS = new Set([
6
+ "agent_listing_delta",
7
+ "compact_file_reference",
8
+ "deferred_tools_delta",
9
+ "deferred_tools_record",
10
+ "dynamic_skill",
11
+ "edited_text_file",
12
+ "file",
13
+ "hook_additional_context",
14
+ "hook_success",
15
+ "instructions",
16
+ "invoked_skills",
17
+ "mcp_instructions_delta",
18
+ "nested_memory",
19
+ "queued_command",
20
+ "read_truncation_notice",
21
+ "skill_listing",
22
+ // A copy of the run's final StructuredOutput answer, tied to that call (not shown to the model).
23
+ "structured_output",
24
+ "task_reminder",
25
+ "task_status",
26
+ ]);
27
+ /**
28
+ * Attachments dropped on purpose: the run's system prompt, account, organisation, pod and budget
29
+ * state. Listed so the compatibility test can tell a reviewed kind from a new one.
30
+ */
31
+ export const DROPPED_ATTACHMENTS = new Set([
32
+ "auto_mode",
33
+ "budget_usd",
34
+ "command_permissions",
35
+ "credential_org",
36
+ "date",
37
+ "environment",
38
+ "model",
39
+ "prompt_snapshot",
40
+ "remote_session_change",
41
+ "session_context",
42
+ "session_cron_carry",
43
+ "silent_turn_reminder",
44
+ "thinking_drop",
45
+ "total_tokens_reminder",
46
+ ]);
47
+ const THINKING = new Set(["thinking", "redacted_thinking"]);
48
+ /** Fields removed from any kept record: the account's plan and rate-limit state. */
49
+ const DROPPED_FIELDS = ["quotaLimits", "usageLimitNote"];
50
+ /** `fallbackTitle` is used when the session has no title of its own. */
51
+ export function sanitizeClaudeTranscript(jsonl, fallbackTitle) {
52
+ const kept = [];
53
+ const titles = [];
54
+ // A dropped record's uuid -> its parent, so kept children can be relinked past it.
55
+ const droppedParent = new Map();
56
+ // Every record's parent as written, for walking a compaction's preserved segment.
57
+ const rawParent = new Map();
58
+ let sessionId;
59
+ for (const line of jsonl.split("\n")) {
60
+ const record = parseRecord(line);
61
+ if (!record)
62
+ continue;
63
+ if (typeof record.uuid === "string")
64
+ rawParent.set(record.uuid, parentOf(record));
65
+ if (record.type === "ai-title" || record.type === "custom-title" || record.type === "summary") {
66
+ titles.push(record);
67
+ continue;
68
+ }
69
+ const copy = keptRecord(record);
70
+ if (!copy) {
71
+ if (typeof record.uuid === "string")
72
+ droppedParent.set(record.uuid, parentOf(record));
73
+ continue;
74
+ }
75
+ if (typeof record.sessionId === "string" && record.isSidechain !== true)
76
+ sessionId ??= record.sessionId;
77
+ kept.push(copy);
78
+ }
79
+ for (const record of kept)
80
+ record.parentUuid = resolveParent(parentOf(record), droppedParent);
81
+ const end = lastSettled(kept);
82
+ if (end < 0 || !sessionId)
83
+ return null;
84
+ let records = kept.slice(0, end + 1);
85
+ let present = new Set(records.map((record) => record.uuid));
86
+ for (const record of records) {
87
+ if (record.type === "system")
88
+ repointCompaction(record, present, rawParent, droppedParent);
89
+ }
90
+ records = fromLastCompaction(records);
91
+ present = new Set(records.map((record) => record.uuid));
92
+ for (const record of records) {
93
+ // A compaction boundary starts a new chain on purpose (its link back is logicalParentUuid).
94
+ if (record.parentUuid !== null && !present.has(record.parentUuid))
95
+ record.parentUuid = null;
96
+ }
97
+ for (const title of titles) {
98
+ if (title.type === "summary" && !present.has(title.leafUuid))
99
+ continue;
100
+ records.push(title.type === "summary" ? title : { ...title, sessionId });
101
+ }
102
+ if (!titles.some((title) => title.type !== "summary") && fallbackTitle) {
103
+ records.push({ type: "ai-title", aiTitle: fallbackTitle, sessionId });
104
+ }
105
+ return { sessionId, lines: records.map((record) => JSON.stringify(record)) };
106
+ }
107
+ /** The record as stored, or null when it is dropped. Only thinking and account fields are edited out. */
108
+ function keptRecord(record) {
109
+ const copy = keptRecordWithFields(record);
110
+ if (copy)
111
+ for (const field of DROPPED_FIELDS)
112
+ delete copy[field];
113
+ return copy;
114
+ }
115
+ function keptRecordWithFields(record) {
116
+ const type = record.type;
117
+ if (typeof type !== "string" || !KEPT_TYPES.has(type))
118
+ return null;
119
+ if (type === "system")
120
+ return KEPT_SYSTEM.has(record.subtype) ? { ...record } : null;
121
+ if (type === "attachment") {
122
+ const kind = record.attachment?.type;
123
+ return typeof kind === "string" && KEPT_ATTACHMENTS.has(kind) ? { ...record } : null;
124
+ }
125
+ const message = withoutThinking(record.message);
126
+ return message ? { ...record, message } : null;
127
+ }
128
+ function parseRecord(line) {
129
+ if (!line.trim())
130
+ return null;
131
+ try {
132
+ const value = JSON.parse(line);
133
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
134
+ }
135
+ catch {
136
+ // A torn last line (the writer was cut off mid-record).
137
+ return null;
138
+ }
139
+ }
140
+ function parentOf(record) {
141
+ return typeof record.parentUuid === "string" ? record.parentUuid : null;
142
+ }
143
+ function resolveParent(parent, dropped) {
144
+ const seen = new Set();
145
+ while (parent !== null && dropped.has(parent) && !seen.has(parent)) {
146
+ seen.add(parent);
147
+ parent = dropped.get(parent) ?? null;
148
+ }
149
+ return parent;
150
+ }
151
+ /**
152
+ * Only what a resume loads: the last compaction boundary, everything after it, and the messages it
153
+ * kept word for word. Resume never loads what that compaction summarised (Claude Code continues
154
+ * "with the last compaction's summary, the messages that compaction left unsummarized, and every
155
+ * message since"), so the earlier history is not stored. Without a compaction, everything is kept.
156
+ */
157
+ function fromLastCompaction(records) {
158
+ let last = -1;
159
+ records.forEach((record, index) => {
160
+ if (record.type === "system" && record.subtype === "compact_boundary")
161
+ last = index;
162
+ });
163
+ if (last <= 0)
164
+ return records;
165
+ const metadata = (records[last].compactMetadata ?? {});
166
+ const keep = new Set();
167
+ const segment = metadata.preservedSegment;
168
+ if (segment && typeof segment === "object") {
169
+ const byId = new Map(records.map((record) => [record.uuid, record]));
170
+ let id = segment.tailUuid;
171
+ while (typeof id === "string" && byId.has(id) && !keep.has(id)) {
172
+ keep.add(id);
173
+ if (id === segment.headUuid)
174
+ break;
175
+ id = byId.get(id)?.parentUuid;
176
+ }
177
+ }
178
+ const messages = metadata.preservedMessages;
179
+ for (const list of [messages?.uuids, messages?.allUuids]) {
180
+ if (Array.isArray(list))
181
+ for (const id of list)
182
+ keep.add(id);
183
+ }
184
+ return records.filter((record, index) => index >= last || keep.has(record.uuid));
185
+ }
186
+ /**
187
+ * A compaction boundary names the messages it kept word for word (`preservedSegment`, from head to
188
+ * tail, and `preservedMessages`). Resume splices that segment back in after the summary, so ids of
189
+ * dropped records are moved to the nearest kept record inside the segment, or the segment is removed
190
+ * when nothing in it is kept.
191
+ */
192
+ function repointCompaction(boundary, present, rawParent, droppedParent) {
193
+ if (typeof boundary.logicalParentUuid === "string") {
194
+ boundary.logicalParentUuid = resolveParent(boundary.logicalParentUuid, droppedParent);
195
+ }
196
+ const metadata = boundary.compactMetadata;
197
+ if (!metadata || typeof metadata !== "object")
198
+ return;
199
+ const copy = { ...metadata };
200
+ boundary.compactMetadata = copy;
201
+ const segment = copy.preservedSegment;
202
+ if (segment && typeof segment === "object") {
203
+ // Walk tail -> head along the links as written; the kept records on that path are the segment.
204
+ const path = [];
205
+ let id = typeof segment.tailUuid === "string" ? segment.tailUuid : null;
206
+ while (id !== null && !path.includes(id)) {
207
+ path.push(id);
208
+ if (id === segment.headUuid)
209
+ break;
210
+ id = rawParent.get(id) ?? null;
211
+ }
212
+ const kept = path.filter((uuid) => present.has(uuid));
213
+ if (path.at(-1) !== segment.headUuid || kept.length === 0) {
214
+ delete copy.preservedSegment;
215
+ }
216
+ else {
217
+ copy.preservedSegment = { ...segment, tailUuid: kept[0], headUuid: kept.at(-1) };
218
+ }
219
+ }
220
+ const messages = copy.preservedMessages;
221
+ if (messages && typeof messages === "object") {
222
+ const keep = (list) => (Array.isArray(list) ? list.filter((uuid) => present.has(uuid)) : list);
223
+ copy.preservedMessages = { ...messages, uuids: keep(messages.uuids), allUuids: keep(messages.allUuids) };
224
+ }
225
+ }
226
+ /** The message without thinking blocks, or null when nothing is left. */
227
+ function withoutThinking(message) {
228
+ if (!message || typeof message !== "object")
229
+ return null;
230
+ const m = message;
231
+ if (typeof m.content === "string")
232
+ return m.content ? m : null;
233
+ if (!Array.isArray(m.content))
234
+ return null;
235
+ const content = m.content.filter((block) => !THINKING.has(block?.type));
236
+ if (content.length === 0)
237
+ return null;
238
+ return content.length === m.content.length ? m : { ...m, content };
239
+ }
240
+ /**
241
+ * The index the history can end at and be continued: the last main-chain record after which no tool
242
+ * call is waiting for its result. That is a reply that asks for no tool, or a tool result that answers
243
+ * the last open call (a run's final StructuredOutput call and its result end this way). A call left
244
+ * without a result (the run was cut off mid-command) is cut, with everything after the last such point.
245
+ * -1 when the history never settles.
246
+ */
247
+ function lastSettled(records) {
248
+ let end = -1;
249
+ const waiting = new Set();
250
+ records.forEach((record, index) => {
251
+ if (record.isSidechain === true || (record.type !== "user" && record.type !== "assistant"))
252
+ return;
253
+ const content = record.message.content;
254
+ const blocks = Array.isArray(content) ? content : [];
255
+ if (record.type === "assistant") {
256
+ const calls = blocks.filter((block) => block?.type === "tool_use");
257
+ // A reply that asks for no tool settles everything before it.
258
+ if (calls.length === 0) {
259
+ waiting.clear();
260
+ end = index;
261
+ }
262
+ for (const call of calls)
263
+ waiting.add(call?.id);
264
+ return;
265
+ }
266
+ const results = blocks.filter((block) => block?.type === "tool_result");
267
+ for (const result of results)
268
+ waiting.delete(result?.tool_use_id);
269
+ if (results.length > 0 && waiting.size === 0)
270
+ end = index;
271
+ });
272
+ return end;
273
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The run transcript download, as the server (mcp/tools/run-transcript-download.ts)
3
+ * serves it and `wardby resume` reads it. Import-free, so the CLI side loads
4
+ * nothing of the server.
5
+ *
6
+ * GET <origin>/run-transcripts/download?t=<signed token>
7
+ * 200: body = the stored gzip object; headers:
8
+ * x-wardby-sha256 sha256 (hex) of the body
9
+ * x-wardby-session-id the Claude Code session id
10
+ * x-wardby-transcript-meta base64url JSON TranscriptDownloadMeta
11
+ * otherwise: JSON { "error": <DownloadRefusal> }
12
+ */
13
+ export declare const RUN_TRANSCRIPT_DOWNLOAD_PATH = "/run-transcripts/download";
14
+ /** How long a download link works. */
15
+ export declare const RUN_TRANSCRIPT_LINK_TTL_MS: number;
16
+ export declare const TRANSCRIPT_SHA256_HEADER = "x-wardby-sha256";
17
+ export declare const TRANSCRIPT_SESSION_HEADER = "x-wardby-session-id";
18
+ export declare const TRANSCRIPT_META_HEADER = "x-wardby-transcript-meta";
19
+ /** What the importer needs besides the bytes: where to check the run out. Ids and refs only, never content. */
20
+ export interface TranscriptDownloadMeta {
21
+ runId: string;
22
+ sessionId: string;
23
+ provider: string;
24
+ repository: string;
25
+ headRef: string;
26
+ resultBranch: string | null;
27
+ baseSha: string | null;
28
+ sha256: string;
29
+ }
30
+ export type DownloadRefusal = "link_invalid" | "not_found" | "transcript_expired" | "transcript_unavailable" | "transcript_corrupt";
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The run transcript download, as the server (mcp/tools/run-transcript-download.ts)
3
+ * serves it and `wardby resume` reads it. Import-free, so the CLI side loads
4
+ * nothing of the server.
5
+ *
6
+ * GET <origin>/run-transcripts/download?t=<signed token>
7
+ * 200: body = the stored gzip object; headers:
8
+ * x-wardby-sha256 sha256 (hex) of the body
9
+ * x-wardby-session-id the Claude Code session id
10
+ * x-wardby-transcript-meta base64url JSON TranscriptDownloadMeta
11
+ * otherwise: JSON { "error": <DownloadRefusal> }
12
+ */
13
+ export const RUN_TRANSCRIPT_DOWNLOAD_PATH = "/run-transcripts/download";
14
+ /** How long a download link works. */
15
+ export const RUN_TRANSCRIPT_LINK_TTL_MS = 10 * 60_000;
16
+ export const TRANSCRIPT_SHA256_HEADER = "x-wardby-sha256";
17
+ export const TRANSCRIPT_SESSION_HEADER = "x-wardby-session-id";
18
+ export const TRANSCRIPT_META_HEADER = "x-wardby-transcript-meta";
@@ -0,0 +1,20 @@
1
+ export declare const TRANSCRIPT_FORMAT_VERSION = 1;
2
+ /** The largest sanitised transcript file the worker writes (uncompressed). */
3
+ export declare const MAX_TRANSCRIPT_BYTES: number;
4
+ /** The default cap on a stored transcript before compression (RUN_TRANSCRIPT_MAX_BYTES). */
5
+ export declare const DEFAULT_TRANSCRIPT_MAX_BYTES: number;
6
+ export declare const MAX_RAW_TRANSCRIPT_BYTES: number;
7
+ export type TranscriptProvider = "claude-code";
8
+ export type TranscriptHeaderStatus = "ok" | "too_large" | "no_complete_turn";
9
+ export interface TranscriptHeader {
10
+ type: "wardby-transcript";
11
+ version: 1;
12
+ provider: TranscriptProvider;
13
+ sessionId: string;
14
+ status: TranscriptHeaderStatus;
15
+ }
16
+ export declare function formatTranscriptFile(header: TranscriptHeader, lines: readonly string[]): string;
17
+ export declare function parseTranscriptFile(text: string): {
18
+ header: TranscriptHeader;
19
+ body: string;
20
+ } | null;
@@ -0,0 +1,32 @@
1
+ export const TRANSCRIPT_FORMAT_VERSION = 1;
2
+ /** The largest sanitised transcript file the worker writes (uncompressed). */
3
+ export const MAX_TRANSCRIPT_BYTES = 64 * 1024 * 1024;
4
+ /** The default cap on a stored transcript before compression (RUN_TRANSCRIPT_MAX_BYTES). */
5
+ export const DEFAULT_TRANSCRIPT_MAX_BYTES = 10 * 1024 * 1024;
6
+ export const MAX_RAW_TRANSCRIPT_BYTES = 64 * 1024 * 1024;
7
+ export function formatTranscriptFile(header, lines) {
8
+ return [JSON.stringify(header), ...lines].join("\n") + "\n";
9
+ }
10
+ export function parseTranscriptFile(text) {
11
+ const newline = text.indexOf("\n");
12
+ const first = newline < 0 ? text : text.slice(0, newline);
13
+ let header;
14
+ try {
15
+ header = JSON.parse(first);
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ if (!isHeader(header))
21
+ return null;
22
+ return { header, body: newline < 0 ? "" : text.slice(newline + 1) };
23
+ }
24
+ function isHeader(value) {
25
+ const v = value;
26
+ return (!!v &&
27
+ v.type === "wardby-transcript" &&
28
+ v.version === TRANSCRIPT_FORMAT_VERSION &&
29
+ v.provider === "claude-code" &&
30
+ typeof v.sessionId === "string" &&
31
+ (v.status === "ok" || v.status === "too_large" || v.status === "no_complete_turn"));
32
+ }
@@ -0,0 +1,52 @@
1
+ import type { PrismaClient } from "#prisma";
2
+ import { type BlobStore } from "../../providers/storage/types.js";
3
+ export type TranscriptStatus = "stored" | "too_large" | "not_captured" | "failed";
4
+ /** What `record` reports to its caller: the row's status, or that the row itself was lost. */
5
+ export type RecordResult = TranscriptStatus | "row_write_failed";
6
+ /** The stored object: the transcript file, gzip-compressed. */
7
+ export declare function transcriptBlobKey(runId: string): string;
8
+ /** RUN_TRANSCRIPT_MAX_BYTES: the largest transcript stored, measured before compression. */
9
+ export declare function loadTranscriptMaxBytes(env?: NodeJS.ProcessEnv): number;
10
+ export declare function loadTranscriptRetentionDays(env?: NodeJS.ProcessEnv): number;
11
+ export interface RunTranscriptRecorderDeps {
12
+ db: {
13
+ runTranscript: Pick<PrismaClient["runTranscript"], "upsert" | "findMany" | "deleteMany">;
14
+ };
15
+ blobs: BlobStore | undefined;
16
+ /**
17
+ * The agent's attached secret values; rejects when any can't be loaded. The run capability (rrp_), the
18
+ * registry token derived from it (rrg_) and the run's MCP token (rmt_) are not listed: they have fixed
19
+ * token shapes that redactSecrets (redact.ts) removes whatever their value, and the vault no longer holds
20
+ * the capability or the MCP token by now.
21
+ */
22
+ secretValues: (agentId: string) => Promise<string[]>;
23
+ retentionDays: number;
24
+ /** The largest transcript stored, before compression (loadTranscriptMaxBytes). */
25
+ maxBytes: number;
26
+ now?: () => Date;
27
+ }
28
+ export interface RecordTranscriptInput {
29
+ runId: string;
30
+ agentId: string;
31
+ provider: string;
32
+ read: (maxBytes: number) => Promise<string | undefined>;
33
+ }
34
+ /**
35
+ * Stores a coding run's session transcript for local resume. The worker's file is not trusted: it is
36
+ * sanitised again here, then every string in each record (values and object keys) is redacted by exact
37
+ * value against the agent's attached secret values (and their JSON-escaped forms); the run capability
38
+ * (rrp_), the registry token (rrg_) and the MCP token (rmt_) are removed by their fixed token shape. Only that copy is stored.
39
+ * Rows carry fixed codes, never content. Never throws.
40
+ */
41
+ export declare class RunTranscriptRecorder {
42
+ private readonly deps;
43
+ constructor(deps: RunTranscriptRecorderDeps);
44
+ /**
45
+ * Returns the stored status, or `row_write_failed` when the row could not be written (the caller logs
46
+ * that code with the run id; the error itself is never surfaced, as it may quote content).
47
+ */
48
+ record(input: RecordTranscriptInput): Promise<RecordResult>;
49
+ private capture;
50
+ private writeRow;
51
+ pruneExpired(limit?: number): Promise<number>;
52
+ }
@@ -0,0 +1,225 @@
1
+ import { createHash } from "node:crypto";
2
+ import { promisify } from "node:util";
3
+ import { gzip } from "node:zlib";
4
+ import { BlobStoreError } from "../../providers/storage/types.js";
5
+ import { withEscapedForms } from "../../core/secret-spans.js";
6
+ import { REDACTED, redactSecrets } from "../redact.js";
7
+ import { sanitizeClaudeTranscript } from "./claude-code.js";
8
+ import { DEFAULT_TRANSCRIPT_MAX_BYTES, formatTranscriptFile, MAX_TRANSCRIPT_BYTES, parseTranscriptFile, } from "./format.js";
9
+ const gzipAsync = promisify(gzip);
10
+ const SESSION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
11
+ const DAY_MS = 24 * 60 * 60 * 1000;
12
+ /** The stored object: the transcript file, gzip-compressed. */
13
+ export function transcriptBlobKey(runId) {
14
+ return `run-transcripts/${runId}.jsonl.gz`;
15
+ }
16
+ const MIN_TRANSCRIPT_MAX_BYTES = 1024 * 1024;
17
+ /** RUN_TRANSCRIPT_MAX_BYTES: the largest transcript stored, measured before compression. */
18
+ export function loadTranscriptMaxBytes(env = process.env) {
19
+ const raw = env.RUN_TRANSCRIPT_MAX_BYTES?.trim();
20
+ if (!raw)
21
+ return DEFAULT_TRANSCRIPT_MAX_BYTES;
22
+ const bytes = Number(raw);
23
+ if (!Number.isInteger(bytes) || bytes < MIN_TRANSCRIPT_MAX_BYTES || bytes > MAX_TRANSCRIPT_BYTES) {
24
+ throw new Error(`RUN_TRANSCRIPT_MAX_BYTES must be a whole number of bytes from ${MIN_TRANSCRIPT_MAX_BYTES} to ${MAX_TRANSCRIPT_BYTES}.`);
25
+ }
26
+ return bytes;
27
+ }
28
+ export function loadTranscriptRetentionDays(env = process.env) {
29
+ const raw = env.RUN_TRANSCRIPT_RETENTION_DAYS?.trim();
30
+ if (!raw)
31
+ return 30;
32
+ const days = Number(raw);
33
+ if (!Number.isInteger(days) || days < 1 || days > 3650) {
34
+ throw new Error("RUN_TRANSCRIPT_RETENTION_DAYS must be a whole number of days from 1 to 3650.");
35
+ }
36
+ return days;
37
+ }
38
+ /**
39
+ * Stores a coding run's session transcript for local resume. The worker's file is not trusted: it is
40
+ * sanitised again here, then every string in each record (values and object keys) is redacted by exact
41
+ * value against the agent's attached secret values (and their JSON-escaped forms); the run capability
42
+ * (rrp_), the registry token (rrg_) and the MCP token (rmt_) are removed by their fixed token shape. Only that copy is stored.
43
+ * Rows carry fixed codes, never content. Never throws.
44
+ */
45
+ export class RunTranscriptRecorder {
46
+ deps;
47
+ constructor(deps) {
48
+ this.deps = deps;
49
+ }
50
+ /**
51
+ * Returns the stored status, or `row_write_failed` when the row could not be written (the caller logs
52
+ * that code with the run id; the error itself is never surfaced, as it may quote content).
53
+ */
54
+ async record(input) {
55
+ const outcome = await this.capture(input).catch(() => ({ status: "failed", reason: "unexpected" }));
56
+ const rowWritten = await this.writeRow(input, outcome).then(() => true, () => false);
57
+ if (outcome.status === "stored")
58
+ await this.pruneExpired().catch(() => 0);
59
+ return rowWritten ? outcome.status : "row_write_failed";
60
+ }
61
+ async capture(input) {
62
+ const { blobs } = this.deps;
63
+ if (!blobs)
64
+ return { status: "not_captured", reason: "no_blob_store" };
65
+ if (input.provider !== "claude-code")
66
+ return { status: "not_captured", reason: "provider_unsupported" };
67
+ let text;
68
+ try {
69
+ text = await input.read(this.deps.maxBytes);
70
+ }
71
+ catch (error) {
72
+ const tooLarge = error instanceof Error && error.message === "transcript_too_large";
73
+ return tooLarge ? { status: "too_large" } : { status: "not_captured", reason: "unreadable" };
74
+ }
75
+ if (text === undefined)
76
+ return { status: "not_captured", reason: "missing" };
77
+ const file = parseTranscriptFile(text);
78
+ if (!file)
79
+ return { status: "failed", reason: "invalid_file" };
80
+ if (!SESSION_ID.test(file.header.sessionId))
81
+ return { status: "failed", reason: "invalid_file" };
82
+ if (file.header.status === "too_large")
83
+ return { status: "too_large", sessionId: file.header.sessionId };
84
+ if (file.header.status === "no_complete_turn") {
85
+ return { status: "not_captured", reason: "no_complete_turn", sessionId: file.header.sessionId };
86
+ }
87
+ const sanitized = sanitizeClaudeTranscript(file.body);
88
+ if (!sanitized)
89
+ return { status: "not_captured", reason: "no_complete_turn", sessionId: file.header.sessionId };
90
+ if (!SESSION_ID.test(sanitized.sessionId))
91
+ return { status: "failed", reason: "invalid_file" };
92
+ let secrets;
93
+ try {
94
+ secrets = await this.deps.secretValues(input.agentId);
95
+ }
96
+ catch {
97
+ return { status: "failed", reason: "secrets_unavailable" };
98
+ }
99
+ const escaped = withEscapedForms(secrets);
100
+ let lines;
101
+ try {
102
+ lines = sanitized.lines.map((line) => redactJsonLine(line, escaped));
103
+ }
104
+ catch {
105
+ return { status: "failed", reason: "redaction_broke_record" };
106
+ }
107
+ // Guard: every stored line must still be one JSON record.
108
+ for (const line of lines) {
109
+ try {
110
+ JSON.parse(line);
111
+ }
112
+ catch {
113
+ return { status: "failed", reason: "redaction_broke_record" };
114
+ }
115
+ }
116
+ const body = Buffer.from(formatTranscriptFile({
117
+ type: "wardby-transcript",
118
+ version: 1,
119
+ provider: "claude-code",
120
+ sessionId: sanitized.sessionId,
121
+ status: "ok",
122
+ }, lines));
123
+ if (body.byteLength > this.deps.maxBytes)
124
+ return { status: "too_large", sessionId: sanitized.sessionId };
125
+ // Async, so compressing a large transcript does not block the server's event loop.
126
+ const stored = await gzipAsync(body);
127
+ const blobKey = transcriptBlobKey(input.runId);
128
+ try {
129
+ await blobs.put(blobKey, stored, { contentType: "application/gzip" });
130
+ }
131
+ catch {
132
+ return { status: "failed", reason: "store_failed", sessionId: sanitized.sessionId };
133
+ }
134
+ // Size and hash are of the stored (compressed) bytes, for the importer to verify its download.
135
+ return {
136
+ status: "stored",
137
+ sessionId: sanitized.sessionId,
138
+ blobKey,
139
+ sizeBytes: stored.byteLength,
140
+ sha256: createHash("sha256").update(stored).digest("hex"),
141
+ };
142
+ }
143
+ async writeRow(input, outcome) {
144
+ const now = (this.deps.now ?? (() => new Date()))();
145
+ const data = {
146
+ provider: input.provider,
147
+ status: outcome.status,
148
+ reason: outcome.reason ?? null,
149
+ sessionId: outcome.sessionId ?? null,
150
+ blobKey: outcome.blobKey ?? null,
151
+ sizeBytes: outcome.sizeBytes ?? null,
152
+ sha256: outcome.sha256 ?? null,
153
+ expiresAt: new Date(now.getTime() + this.deps.retentionDays * DAY_MS),
154
+ };
155
+ await this.deps.db.runTranscript.upsert({
156
+ where: { runId: input.runId },
157
+ create: { runId: input.runId, ...data },
158
+ update: data,
159
+ });
160
+ }
161
+ async pruneExpired(limit = 20) {
162
+ const now = (this.deps.now ?? (() => new Date()))();
163
+ const expired = await this.deps.db.runTranscript.findMany({
164
+ where: { expiresAt: { lt: now } },
165
+ select: { runId: true, blobKey: true },
166
+ orderBy: { expiresAt: "asc" },
167
+ take: limit,
168
+ });
169
+ const deletable = [];
170
+ for (const row of expired) {
171
+ try {
172
+ if (row.blobKey && this.deps.blobs)
173
+ await this.deps.blobs.delete(row.blobKey);
174
+ deletable.push(row.runId);
175
+ }
176
+ catch (error) {
177
+ if (error instanceof BlobStoreError && error.code === "not_found")
178
+ deletable.push(row.runId);
179
+ }
180
+ }
181
+ if (deletable.length === 0)
182
+ return 0;
183
+ const { count } = await this.deps.db.runTranscript.deleteMany({ where: { runId: { in: deletable } } });
184
+ return count;
185
+ }
186
+ }
187
+ /**
188
+ * Redacts every string leaf of one JSON record, then re-serialises it. Redacting the serialised line
189
+ * instead lets token patterns consume JSON escapes (the Bearer pattern eats the backslash of `\"`).
190
+ */
191
+ function redactJsonLine(line, secrets) {
192
+ return JSON.stringify(redactJsonValue(parseNumbersAsSource(line, secrets), secrets));
193
+ }
194
+ const NUMERIC = /^-?\d+(\.\d+)?([eE][+-]?\d+)?$/;
195
+ /**
196
+ * Parses one record, replacing any number that holds a secret (a digits-only value written as a
197
+ * JSON number) with the marker. Checks the source text and the numeric value: the sanitiser has
198
+ * already re-serialised the record, so a number too long for a double arrives rounded.
199
+ */
200
+ function parseNumbersAsSource(line, secrets) {
201
+ const numericSecrets = secrets.filter((secret) => NUMERIC.test(secret)).map(Number);
202
+ const reviver = (_key, value, context) => {
203
+ if (typeof value !== "number")
204
+ return value;
205
+ const source = context.source ?? String(value);
206
+ if (redactSecrets(source, secrets) !== source || numericSecrets.includes(value))
207
+ return REDACTED;
208
+ return value;
209
+ };
210
+ return JSON.parse(line, reviver);
211
+ }
212
+ function redactJsonValue(value, secrets) {
213
+ if (typeof value === "string")
214
+ return redactSecrets(value, secrets);
215
+ if (Array.isArray(value))
216
+ return value.map((item) => redactJsonValue(item, secrets));
217
+ if (value !== null && typeof value === "object") {
218
+ // A null-prototype object keeps a "__proto__" key as data.
219
+ const out = Object.create(null);
220
+ for (const [key, item] of Object.entries(value))
221
+ out[redactSecrets(key, secrets)] = redactJsonValue(item, secrets);
222
+ return out;
223
+ }
224
+ return value;
225
+ }