@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,304 @@
1
+ /**
2
+ * Package audit mode (docs/coding-packages.md#package-audit-mode): a timed,
3
+ * owner-set mode in which a coding run's registry serves packages outside the
4
+ * agent's allowlist (`audit`) and, in `full`, versions withheld only by
5
+ * non-malware blocking advisories, recording each one for approval
6
+ * afterwards. Pure (no provider imports): the MCP tools, dispatch, the proxy,
7
+ * the PR body, the status comment and Slack all read this one model.
8
+ */
9
+ import { ACCEPTED_ADVISORY_ID } from "./allowlist.js";
10
+ import { codeSpan } from "./refusal-wording.js";
11
+ export const PACKAGE_AUDIT_MODES = ["audit", "full"];
12
+ /** The window `packageAuditMode` opens when `packageAuditMinutes` is omitted: 24 hours. */
13
+ export const DEFAULT_PACKAGE_AUDIT_MINUTES = 24 * 60;
14
+ /** The longest window one update may open: 7 days. */
15
+ export const MAX_PACKAGE_AUDIT_MINUTES = 7 * 24 * 60;
16
+ const RELATIONS = ["top-level", "unknown", "transitive", "allowed"];
17
+ export class PackageAuditPatchError extends Error {
18
+ }
19
+ export function isPackageAuditMode(value) {
20
+ return typeof value === "string" && PACKAGE_AUDIT_MODES.includes(value);
21
+ }
22
+ /** Whether a stored mode is in force: set, and its window has not ended. */
23
+ export function isPackageAuditActive(mode, until, now) {
24
+ return isPackageAuditMode(mode) && !!until && until.getTime() > now.getTime();
25
+ }
26
+ /** The get_agent / update_agent warning while a mode is in force. */
27
+ export function packageAuditActiveWarning(mode, until) {
28
+ return `Package audit mode (\`${mode}\`) is on until ${until.toISOString()}: this agent's coding runs install packages outside the allowlist.`;
29
+ }
30
+ /**
31
+ * update_agent's packageAuditMode / packageAuditMinutes semantics: a mode
32
+ * opens a window of the given minutes (24 hours by default), minutes alone
33
+ * re-arm the stored mode, and null clears both. Returns undefined when the
34
+ * patch names neither field; throws PackageAuditPatchError for a 400.
35
+ */
36
+ export function resolvePackageAuditPatch(stored, patch, now) {
37
+ const { packageAuditMode: mode, packageAuditMinutes: minutes } = patch;
38
+ if (mode === undefined && minutes === undefined)
39
+ return undefined;
40
+ if (minutes !== undefined && (!Number.isInteger(minutes) || minutes < 1 || minutes > MAX_PACKAGE_AUDIT_MINUTES)) {
41
+ throw new PackageAuditPatchError(`packageAuditMinutes must be a whole number from 1 to ${MAX_PACKAGE_AUDIT_MINUTES} (7 days).`);
42
+ }
43
+ if (mode === null) {
44
+ if (minutes !== undefined) {
45
+ throw new PackageAuditPatchError("packageAuditMinutes cannot be set while turning packageAuditMode off (null).");
46
+ }
47
+ return { mode: null, until: null };
48
+ }
49
+ const effective = mode ?? stored.mode;
50
+ if (!effective) {
51
+ throw new PackageAuditPatchError('packageAuditMinutes needs a package audit mode: set packageAuditMode to "audit" or "full" as well.');
52
+ }
53
+ return { mode: effective, until: new Date(now.getTime() + (minutes ?? DEFAULT_PACKAGE_AUDIT_MINUTES) * 60_000) };
54
+ }
55
+ const SEVERITIES = new Set(["CRITICAL", "HIGH", "MODERATE", "LOW", "UNKNOWN"]);
56
+ const MAX_AUDIT_ADVISORIES = 16;
57
+ export const MAX_AUDIT_SUMMARY_CHARS = 200;
58
+ /** An advisory summary (OSV free text) as plain, single-line, bounded text. */
59
+ export function sanitizeAuditSummary(value) {
60
+ if (typeof value !== "string")
61
+ return "";
62
+ return (value
63
+ // eslint-disable-next-line no-control-regex -- stripping untrusted control characters.
64
+ .replace(/[`\u0000-\u001f\u007f<>]/g, " ")
65
+ .replace(/\s+/g, " ")
66
+ .trim()
67
+ .slice(0, MAX_AUDIT_SUMMARY_CHARS));
68
+ }
69
+ /** Untrusted advisory JSON reduced to well-formed, non-malware entries (at most 16, distinct ids). */
70
+ export function sanitizeAuditAdvisories(value) {
71
+ if (!Array.isArray(value))
72
+ return [];
73
+ const out = new Map();
74
+ for (const item of value) {
75
+ if (out.size >= MAX_AUDIT_ADVISORIES)
76
+ break;
77
+ if (!item || typeof item !== "object")
78
+ continue;
79
+ const { id, severity, summary } = item;
80
+ // Malware is never served in any mode, so a MAL- id here is malformed data.
81
+ if (typeof id !== "string" || id.startsWith("MAL-") || !ACCEPTED_ADVISORY_ID.test(id) || out.has(id))
82
+ continue;
83
+ const level = typeof severity === "string" ? severity.toUpperCase() : "";
84
+ out.set(id, { id, severity: SEVERITIES.has(level) ? level : "UNKNOWN", summary: sanitizeAuditSummary(summary) });
85
+ }
86
+ return [...out.values()];
87
+ }
88
+ /** A stored verdict (RegistryApprovedVersion.audit, untrusted JSON) read back; null when absent or malformed. */
89
+ export function parsePackageAuditVerdict(value) {
90
+ if (!value || typeof value !== "object" || Array.isArray(value))
91
+ return null;
92
+ const { relation, via, advisories } = value;
93
+ if (typeof relation !== "string" || !RELATIONS.includes(relation))
94
+ return null;
95
+ const list = sanitizeAuditAdvisories(advisories);
96
+ return {
97
+ relation: relation,
98
+ ...(relation === "transitive" && typeof via === "string" && via !== "" ? { via } : {}),
99
+ ...(list.length > 0 ? { advisories: list } : {}),
100
+ };
101
+ }
102
+ /**
103
+ * A run's (or a PR's runs') audit rows deduplicated on ecosystem + name +
104
+ * version (advisories unioned) and ordered top-level, unknown, transitive,
105
+ * allowed. An unrecognised relation reads as `unknown`, so it is listed to
106
+ * approve rather than hidden.
107
+ */
108
+ export function summarizePackageAudit(rows) {
109
+ const byKey = new Map();
110
+ for (const row of rows) {
111
+ const key = `${row.ecosystem}\0${row.name}\0${row.version}`;
112
+ const advisories = sanitizeAuditAdvisories(row.advisories);
113
+ const existing = byKey.get(key);
114
+ if (existing) {
115
+ if (advisories.length > 0) {
116
+ const merged = new Map((existing.advisories ?? []).map((a) => [a.id, a]));
117
+ for (const advisory of advisories)
118
+ if (!merged.has(advisory.id))
119
+ merged.set(advisory.id, advisory);
120
+ existing.advisories = [...merged.values()].slice(0, MAX_AUDIT_ADVISORIES);
121
+ }
122
+ continue;
123
+ }
124
+ const relation = RELATIONS.includes(row.relation)
125
+ ? row.relation
126
+ : "unknown";
127
+ byKey.set(key, {
128
+ ecosystem: row.ecosystem,
129
+ name: row.name,
130
+ version: row.version,
131
+ size: row.sizeBytes,
132
+ relation,
133
+ ...(relation === "transitive" && row.via ? { via: row.via } : {}),
134
+ ...(advisories.length > 0 ? { advisories } : {}),
135
+ });
136
+ }
137
+ const entries = [...byKey.values()].sort((a, b) => RELATIONS.indexOf(a.relation) - RELATIONS.indexOf(b.relation));
138
+ const toApprove = new Map();
139
+ const unknown = new Map();
140
+ // Entries are ordered top-level first, so a name recorded both ways is listed to approve.
141
+ for (const entry of entries) {
142
+ if (entry.relation !== "top-level" && entry.relation !== "unknown")
143
+ continue;
144
+ const key = `${entry.ecosystem}\0${entry.name}`;
145
+ if (toApprove.has(key) || unknown.has(key))
146
+ continue;
147
+ (entry.relation === "top-level" ? toApprove : unknown).set(key, {
148
+ ecosystem: entry.ecosystem,
149
+ name: entry.name,
150
+ dependencies: 0,
151
+ });
152
+ }
153
+ const counted = new Set();
154
+ for (const entry of entries) {
155
+ if (entry.relation !== "transitive" || !entry.via)
156
+ continue;
157
+ const parentKey = `${entry.ecosystem}\0${entry.via}`;
158
+ const parent = toApprove.get(parentKey) ?? unknown.get(parentKey);
159
+ const key = `${entry.ecosystem}\0${entry.via}\0${entry.name}`;
160
+ if (!parent || counted.has(key))
161
+ continue;
162
+ counted.add(key);
163
+ parent.dependencies += 1;
164
+ }
165
+ const advisoryRows = entries.flatMap((entry) => (entry.advisories ?? []).map((advisory) => ({
166
+ ecosystem: entry.ecosystem,
167
+ name: entry.name,
168
+ version: entry.version,
169
+ advisory,
170
+ })));
171
+ return { entries, toApprove: [...toApprove.values()], unknown: [...unknown.values()], advisoryRows };
172
+ }
173
+ /** How a name recorded with relation `unknown` is labelled wherever it is listed. */
174
+ export const UNKNOWN_RELATION_LABEL = "Relation unknown — may be a dependency; approve only if needed directly";
175
+ /** At most this many names in a status comment or Slack message, and table rows in a PR body. */
176
+ const MAX_STATUS_NAMES = 10;
177
+ const MAX_PR_AUDIT_LINES = 50;
178
+ function dependencies(count) {
179
+ return count === 0 ? "" : ` (and ${count} ${count === 1 ? "dependency" : "dependencies"})`;
180
+ }
181
+ /**
182
+ * The package audit block for a PR body (`format: "pr"`, a `[!CAUTION]`
183
+ * banner plus the names to approve and, in full mode, the advisories served
184
+ * past), a status comment (`format: "status"`, short), or Slack mrkdwn
185
+ * (`slack`, already escaped). Control-plane text only: names, versions and
186
+ * ids pass through codeSpan.
187
+ */
188
+ export function packageAuditWording(mode, summary, opts = {}) {
189
+ return opts.format === "pr" && !opts.slack ? prWording(mode, summary) : statusWording(mode, summary, !!opts.slack);
190
+ }
191
+ function prWording(mode, summary) {
192
+ const nothing = summary.entries.length === 0;
193
+ const banner = [
194
+ "> [!CAUTION]",
195
+ nothing
196
+ ? `> **Package audit mode (\`${mode}\`) was on for this run:** nothing outside the allowlist was installed${mode === "full" ? " and no advisory was served past" : ""}.`
197
+ : `> **Package audit mode (\`${mode}\`) was on for this run.** Wardby's registry installed packages outside this agent's allowlist${mode === "full" ? " and, in `full` mode, versions with high or critical advisories" : ""}. Review them before merging. Malware and the release-age limit were still enforced.`,
198
+ ];
199
+ const sections = [banner.join("\n")];
200
+ if (summary.toApprove.length > 0) {
201
+ const lines = summary.toApprove.map((pkg) => `- ${codeSpan(pkg.ecosystem).slice(1, -1)} ${codeSpan(pkg.name)}${dependencies(pkg.dependencies)}`);
202
+ sections.push([
203
+ "**Packages outside the allowlist** (add to `codingProfile.packageAllowlist` to keep using them):",
204
+ ...capped(lines),
205
+ ].join("\n"));
206
+ }
207
+ if (summary.unknown.length > 0) {
208
+ const lines = summary.unknown.map((pkg) => `- ${codeSpan(pkg.ecosystem).slice(1, -1)} ${codeSpan(pkg.name)}${dependencies(pkg.dependencies)}`);
209
+ sections.push([`**Relation unknown** — may be a dependency; approve only if needed directly:`, ...capped(lines)].join("\n"));
210
+ }
211
+ if (!nothing &&
212
+ summary.toApprove.length === 0 &&
213
+ summary.unknown.length === 0 &&
214
+ summary.entries.some((e) => e.relation === "transitive")) {
215
+ // Every audited package came in as a dependency whose parent was not itself recorded.
216
+ sections.push(`**Packages outside the allowlist:** ${summary.entries.filter((e) => e.relation === "transitive").length} dependencies of audited packages.`);
217
+ }
218
+ if (mode === "full" && summary.advisoryRows.length > 0) {
219
+ const rows = summary.advisoryRows.map((row) => `| ${codeSpan(row.ecosystem).slice(1, -1)} ${codeSpan(row.name)} | ${codeSpan(row.version)} | ${codeSpan(row.advisory.id)} | ${row.advisory.severity} |`);
220
+ sections.push(["**Served despite advisories:**", "| Package | Version | Advisory | Severity |", "| --- | --- | --- | --- |"]
221
+ .concat(rows.slice(0, MAX_PR_AUDIT_LINES))
222
+ .concat(rows.length > MAX_PR_AUDIT_LINES
223
+ ? [`\n…and ${rows.length - MAX_PR_AUDIT_LINES} more — see get_run for the full list`]
224
+ : [])
225
+ .join("\n"));
226
+ }
227
+ return sections.join("\n\n");
228
+ }
229
+ function capped(lines) {
230
+ return lines.length > MAX_PR_AUDIT_LINES
231
+ ? [
232
+ ...lines.slice(0, MAX_PR_AUDIT_LINES),
233
+ `- …and ${lines.length - MAX_PR_AUDIT_LINES} more — see get_run for the full list`,
234
+ ]
235
+ : [...lines];
236
+ }
237
+ function statusWording(mode, summary, slack) {
238
+ return packageAuditStatusText(mode, packageAuditDigest(mode, summary), slack);
239
+ }
240
+ export function packageAuditDigest(mode, summary) {
241
+ const listed = summary.toApprove.slice(0, MAX_STATUS_NAMES);
242
+ return {
243
+ toApprove: listed.map(({ ecosystem, name }) => ({ ecosystem, name })),
244
+ moreToApprove: summary.toApprove.length - listed.length,
245
+ unknown: summary.unknown.slice(0, MAX_STATUS_NAMES).map(({ ecosystem, name }) => ({ ecosystem, name })),
246
+ moreUnknown: Math.max(0, summary.unknown.length - MAX_STATUS_NAMES),
247
+ transitive: summary.entries.filter((e) => e.relation === "transitive").length,
248
+ advisories: mode === "full" ? summary.advisoryRows.length : 0,
249
+ };
250
+ }
251
+ /** The short audit notice as GitHub/Jira Markdown or, with `slack`, Slack mrkdwn (already escaped). */
252
+ export function packageAuditStatusText(mode, digest, slack) {
253
+ const bold = (text) => (slack ? `*${text}*` : `**${text}**`);
254
+ const head = `🔎 ${bold(`Package audit mode (\`${mode}\`) was on:`)}`;
255
+ const advisoryText = digest.advisories > 0 ? ` ${digest.advisories} served despite advisories.` : "";
256
+ let text;
257
+ // Older stored payloads (before unknown names were listed apart) have no `unknown`.
258
+ const unknown = digest.unknown ?? [];
259
+ const nameList = (list, more) => list
260
+ .slice(0, MAX_STATUS_NAMES)
261
+ .map((pkg) => `${codeSpan(pkg.name)} (${codeSpan(pkg.ecosystem).slice(1, -1)})`)
262
+ .join(", ") + (more > 0 ? ` and ${more} more` : "");
263
+ if (digest.toApprove.length === 0 && unknown.length === 0 && digest.transitive === 0) {
264
+ text = `${head} nothing outside the allowlist was installed.${advisoryText}`;
265
+ }
266
+ else {
267
+ const listed = digest.toApprove.length > 0 ? nameList(digest.toApprove, digest.moreToApprove) : "no top-level names";
268
+ const transitive = digest.transitive;
269
+ const unknownText = unknown.length > 0 ? ` ${UNKNOWN_RELATION_LABEL}: ${nameList(unknown, digest.moreUnknown ?? 0)}.` : "";
270
+ text =
271
+ `${head} installed outside the allowlist: ${listed}` +
272
+ `${transitive > 0 ? ` (plus ${transitive} ${transitive === 1 ? "dependency" : "dependencies"})` : ""}.` +
273
+ `${unknownText}${advisoryText} Keep them with \`approve_audited_packages\` (adds them to codingProfile.packageAllowlist).`;
274
+ }
275
+ // Slack's three control characters; codeSpan already removed < and > from names.
276
+ return slack ? text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") : text;
277
+ }
278
+ /** Entries back as rows, so several runs' entries summarize (dedup, order) like one run's. */
279
+ export function packageAuditRows(entries) {
280
+ return entries.map((entry) => ({
281
+ ecosystem: entry.ecosystem,
282
+ name: entry.name,
283
+ version: entry.version,
284
+ relation: entry.relation,
285
+ via: entry.via ?? null,
286
+ sizeBytes: entry.size,
287
+ advisories: entry.advisories ?? [],
288
+ }));
289
+ }
290
+ /**
291
+ * Several runs' audit reports as one (a pull request's runs): entries merged
292
+ * on ecosystem + name + version with advisories unioned, and the strongest
293
+ * mode seen (`full` over `audit`). Undefined when no run had the mode.
294
+ */
295
+ export function mergePackageAuditReports(reports) {
296
+ const present = reports.filter((report) => !!report && isPackageAuditMode(report.mode));
297
+ if (present.length === 0)
298
+ return undefined;
299
+ const mode = present.some((report) => report.mode === "full") ? "full" : "audit";
300
+ return {
301
+ mode,
302
+ entries: summarizePackageAudit(present.flatMap((report) => packageAuditRows(report.entries))).entries,
303
+ };
304
+ }
@@ -0,0 +1,36 @@
1
+ import { RegistryError, type LockfileEntry, type ParsedLockfile } from "./types.js";
2
+ /** yarn classic's default registry host, which it writes into `resolved`. */
3
+ export declare const YARN_CLASSIC_REGISTRY = "https://registry.yarnpkg.com/";
4
+ export declare function badRequest(message: string): RegistryError;
5
+ export declare function tooLarge(count: number, maxEntries: number): RegistryError;
6
+ /** `name@range` split at the `@` that ends the name (a scope's `@` is the
7
+ * first character). */
8
+ export declare function splitDescriptor(descriptor: string): {
9
+ name: string;
10
+ range: string;
11
+ };
12
+ export declare function isLocal(range: string): boolean;
13
+ export declare function fromRegistry(url: string, proxyRegistryUrl: string): boolean;
14
+ export declare function entryOf(path: string, name: string, version: string, integrity: string | null, source: "registry" | "elsewhere"): LockfileEntry;
15
+ /** What a descriptor names: an entry, or a local package (null). */
16
+ export type Target = LockfileEntry | null;
17
+ /** The client's resolution rule (`resolve`) and, for each entry, the
18
+ * dependency keys the lockfile lists for it (`dependencyKeys`): `resolve`
19
+ * answers only for those keys, which is what lets a parse made in a
20
+ * worker thread be shipped back as a plain edge table. */
21
+ export declare function buildResolve(byPath: ReadonlyMap<string, {
22
+ dependencies: ReadonlyMap<string, string>;
23
+ }>, byDescriptor: ReadonlyMap<string, Target>, candidates: (key: string, range: string) => string[]): Required<Pick<ParsedLockfile, "resolve" | "dependencyKeys">>;
24
+ /** A rough upper bound on a YAML lockfile's entries, read without parsing
25
+ * it: the number of lines that open a two-space-indented mapping key
26
+ * (each package, snapshot and importer is one). Lets a lockfile far over
27
+ * the entry bound be refused before the parser builds its whole tree. */
28
+ export declare function yamlEntryLines(body: string): number;
29
+ /** The lockfile as plain objects and strings. Throws a 400
30
+ * `wardby_bad_request` RegistryError for anything that is not a single
31
+ * valid YAML mapping without aliases. */
32
+ export declare function parseLockfileYaml(body: string): Record<string, unknown>;
33
+ /** `value` as a string-keyed object, or an empty one. */
34
+ export declare function mapOf(value: unknown): Record<string, unknown>;
35
+ /** `value` when it is a string, else undefined. */
36
+ export declare function stringOf(value: unknown): string | undefined;
@@ -0,0 +1,128 @@
1
+ /**
2
+ * What the pnpm and yarn lockfile parsers (pnpm-lockfile.ts,
3
+ * yarn-lockfile.ts) share: entry classification, descriptor-based
4
+ * resolution, and bounded YAML reading for the lockfiles pnpm and yarn
5
+ * Berry write (`pnpm-lock.yaml`, a Berry `yarn.lock`). Every scalar is read as a string
6
+ * (the failsafe schema: no type coercion, no custom or language tags), merge
7
+ * keys are off, and any alias or anchor is refused: no lockfile those
8
+ * clients write uses one, and refusing them rules out alias expansion
9
+ * ("billion laughs"). Nothing in a lockfile is ever executed.
10
+ */
11
+ import semver from "semver";
12
+ import { parseDocument } from "yaml";
13
+ import { PACKAGE_NAME } from "./npm-lockfile.js";
14
+ import { RegistryError } from "./types.js";
15
+ /** yarn classic's default registry host, which it writes into `resolved`. */
16
+ export const YARN_CLASSIC_REGISTRY = "https://registry.yarnpkg.com/";
17
+ /** Where a registry entry may say it was downloaded from (besides the proxy). */
18
+ const PUBLIC_REGISTRIES = [YARN_CLASSIC_REGISTRY, "https://registry.npmjs.org/"];
19
+ /** Specs and resolutions that are never fetched from the registry. */
20
+ const LOCAL_PROTOCOLS = ["file:", "link:", "portal:", "workspace:", "exec:", "patch:"];
21
+ export function badRequest(message) {
22
+ return new RegistryError(400, "wardby_bad_request", message);
23
+ }
24
+ export function tooLarge(count, maxEntries) {
25
+ return new RegistryError(413, "wardby_lockfile_too_large", `the lockfile has ${count} entries; at most ${maxEntries} are verified (REGISTRY_PLAN_MAX_ENTRIES)`);
26
+ }
27
+ /** `name@range` split at the `@` that ends the name (a scope's `@` is the
28
+ * first character). */
29
+ export function splitDescriptor(descriptor) {
30
+ const at = descriptor.indexOf("@", 1);
31
+ return at < 0 ? { name: descriptor, range: "" } : { name: descriptor.slice(0, at), range: descriptor.slice(at + 1) };
32
+ }
33
+ export function isLocal(range) {
34
+ return LOCAL_PROTOCOLS.some((protocol) => range.startsWith(protocol));
35
+ }
36
+ export function fromRegistry(url, proxyRegistryUrl) {
37
+ return [...PUBLIC_REGISTRIES, proxyRegistryUrl].some((base) => url.startsWith(base));
38
+ }
39
+ export function entryOf(path, name, version, integrity, source) {
40
+ if (!PACKAGE_NAME.test(name) || semver.valid(version) !== version)
41
+ return {
42
+ path,
43
+ name,
44
+ version,
45
+ integrity,
46
+ kind: "unsupported",
47
+ unsupportedReason: "not a registry package name and exact version",
48
+ };
49
+ if (source !== "registry")
50
+ return {
51
+ path,
52
+ name,
53
+ version,
54
+ integrity,
55
+ kind: "unsupported",
56
+ unsupportedReason: "installed from outside the npm registry",
57
+ };
58
+ return { path, name, version, integrity, kind: "registry" };
59
+ }
60
+ /** The client's resolution rule (`resolve`) and, for each entry, the
61
+ * dependency keys the lockfile lists for it (`dependencyKeys`): `resolve`
62
+ * answers only for those keys, which is what lets a parse made in a
63
+ * worker thread be shipped back as a plain edge table. */
64
+ export function buildResolve(byPath, byDescriptor, candidates) {
65
+ return {
66
+ resolve: (fromPath, key) => {
67
+ const range = byPath.get(fromPath)?.dependencies.get(key);
68
+ if (range === undefined)
69
+ return undefined;
70
+ for (const descriptor of candidates(key, range)) {
71
+ const target = byDescriptor.get(descriptor);
72
+ if (target !== undefined)
73
+ return target ?? undefined;
74
+ }
75
+ return undefined;
76
+ },
77
+ dependencyKeys: (path) => [...(byPath.get(path)?.dependencies.keys() ?? [])],
78
+ };
79
+ }
80
+ /** A rough upper bound on a YAML lockfile's entries, read without parsing
81
+ * it: the number of lines that open a two-space-indented mapping key
82
+ * (each package, snapshot and importer is one). Lets a lockfile far over
83
+ * the entry bound be refused before the parser builds its whole tree. */
84
+ export function yamlEntryLines(body) {
85
+ let count = 0;
86
+ let at = body.indexOf("\n ");
87
+ while (at >= 0) {
88
+ const next = body[at + 3];
89
+ if (next !== " " && next !== "\n" && next !== "\r" && next !== undefined)
90
+ count += 1;
91
+ at = body.indexOf("\n ", at + 3);
92
+ }
93
+ return count;
94
+ }
95
+ /** The lockfile as plain objects and strings. Throws a 400
96
+ * `wardby_bad_request` RegistryError for anything that is not a single
97
+ * valid YAML mapping without aliases. */
98
+ export function parseLockfileYaml(body) {
99
+ const document = parseDocument(body, {
100
+ schema: "failsafe",
101
+ merge: false,
102
+ // The duplicate-key check is quadratic in a mapping's size (seconds for
103
+ // a large lockfile); a duplicate only means the later value is read,
104
+ // and nothing parsed here is trusted anyway.
105
+ uniqueKeys: false,
106
+ logLevel: "silent",
107
+ });
108
+ if (document.errors.length > 0)
109
+ throw badRequest("the lockfile is not valid YAML");
110
+ let value;
111
+ try {
112
+ value = document.toJS({ maxAliasCount: 0 });
113
+ }
114
+ catch {
115
+ throw badRequest("the lockfile uses YAML aliases, which no supported client writes");
116
+ }
117
+ if (!value || typeof value !== "object" || Array.isArray(value))
118
+ throw badRequest("the lockfile is not a YAML mapping");
119
+ return value;
120
+ }
121
+ /** `value` as a string-keyed object, or an empty one. */
122
+ export function mapOf(value) {
123
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
124
+ }
125
+ /** `value` when it is a string, else undefined. */
126
+ export function stringOf(value) {
127
+ return typeof value === "string" ? value : undefined;
128
+ }
@@ -58,7 +58,7 @@ export async function normalizeRegistryLockfiles(input) {
58
58
  continue;
59
59
  const registryUrl = registryUrlFor(input.proxyBaseUrl, adapter.id);
60
60
  for (const name of lockfiles.names)
61
- byName.set(name, (content) => lockfiles.normalize(content, registryUrl));
61
+ byName.set(name, (content) => lockfiles.normalize(content, registryUrl, name));
62
62
  }
63
63
  const rewritten = [];
64
64
  const walk = async (relative, depth) => {
@@ -0,0 +1,11 @@
1
+ import { type LockfilePlanSupport, type ParsedLockfile } from "./types.js";
2
+ /** Parses whichever supported lockfile `body` is. */
3
+ export declare function parseNpmClientLockfile(body: string, options: {
4
+ maxEntries: number;
5
+ proxyRegistryUrl: string;
6
+ }): ParsedLockfile;
7
+ export declare const npmClientLockfilePlan: LockfilePlanSupport;
8
+ export declare const npmClientLockfiles: {
9
+ readonly names: readonly ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock"];
10
+ readonly normalize: (content: string, registryUrl: string, name: string) => string;
11
+ };
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Every lockfile the npm registry route verifies and rewrites: npm's own
3
+ * (package-lock.json, npm-shrinkwrap.json), pnpm's (pnpm-lock.yaml) and
4
+ * yarn's (yarn.lock, classic and Berry). They all install from the same
5
+ * registry, so they share one plan route (`POST /registry/npm/-/plan`),
6
+ * which tells them apart by content, and one set of registry reads.
7
+ *
8
+ * Kept free of imports from npm.ts, which imports this module.
9
+ */
10
+ import { normalizeNpmLockfile } from "./npm-lockfile.js";
11
+ import { npmLockfilePlan, parseNpmLockfile } from "./npm-plan.js";
12
+ import { isPnpmLockfile, normalizePnpmLockfile, parsePnpmLockfile } from "./pnpm-lockfile.js";
13
+ import { RegistryError } from "./types.js";
14
+ import { isYarnBerryLockfile, isYarnClassicLockfile, normalizeYarnLockfile, parseYarnLockfile, } from "./yarn-lockfile.js";
15
+ /** Parses whichever supported lockfile `body` is. */
16
+ export function parseNpmClientLockfile(body, options) {
17
+ if (body.trimStart().startsWith("{"))
18
+ return parseNpmLockfile(body, options);
19
+ if (isYarnClassicLockfile(body) || isYarnBerryLockfile(body))
20
+ return parseYarnLockfile(body, options);
21
+ if (isPnpmLockfile(body))
22
+ return parsePnpmLockfile(body, options);
23
+ throw new RegistryError(400, "wardby_lockfile_unsupported", "not a lockfile this registry verifies: send a package-lock.json, npm-shrinkwrap.json, pnpm-lock.yaml or yarn.lock");
24
+ }
25
+ export const npmClientLockfilePlan = {
26
+ ...npmLockfilePlan,
27
+ parse: parseNpmClientLockfile,
28
+ // npm's JSON parses in milliseconds on the event loop; pnpm's and yarn's
29
+ // formats go to a worker thread (registry/lockfile-parse.ts).
30
+ parsesOffThread: (body) => !body.trimStart().startsWith("{"),
31
+ };
32
+ export const npmClientLockfiles = {
33
+ names: ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock"],
34
+ normalize(content, registryUrl, name) {
35
+ if (name === "pnpm-lock.yaml")
36
+ return normalizePnpmLockfile(content, registryUrl);
37
+ if (name === "yarn.lock")
38
+ return normalizeYarnLockfile(content, registryUrl);
39
+ return normalizeNpmLockfile(content, registryUrl);
40
+ },
41
+ };
@@ -1,9 +1,13 @@
1
1
  /** Same shape as the adapter's allowlist name check (scoped names are lower case). */
2
2
  export declare const PACKAGE_NAME: RegExp;
3
+ /** The package and version a path under the proxy's npm base downloads:
4
+ * `-/tarball/<encoded name>/<version>` (the proxy's own route) or the
5
+ * standard `<name>/-/<unscoped>-<version>.tgz`, with the scope separator
6
+ * literal or percent-encoded. Null for anything else. */
7
+ export declare function parseProxyPath(path: string): {
8
+ name: string;
9
+ version: string;
10
+ } | null;
3
11
  /** `https://registry.npmjs.org/@scope/pkg/-/pkg-1.0.0.tgz` */
4
12
  export declare function publicNpmTarballUrl(name: string, version: string): string;
5
13
  export declare function normalizeNpmLockfile(content: string, registryUrl: string): string;
6
- export declare const npmLockfiles: {
7
- readonly names: readonly ["package-lock.json", "npm-shrinkwrap.json"];
8
- readonly normalize: typeof normalizeNpmLockfile;
9
- };
@@ -31,7 +31,7 @@ function unscoped(name) {
31
31
  * `-/tarball/<encoded name>/<version>` (the proxy's own route) or the
32
32
  * standard `<name>/-/<unscoped>-<version>.tgz`, with the scope separator
33
33
  * literal or percent-encoded. Null for anything else. */
34
- function parseProxyPath(path) {
34
+ export function parseProxyPath(path) {
35
35
  let name;
36
36
  let version;
37
37
  const own = path.match(/^-\/tarball\/([^/]+)\/([^/]+)$/);
@@ -50,7 +50,9 @@ function parseProxyPath(path) {
50
50
  const prefix = `${unscoped(name)}-`;
51
51
  version = file.startsWith(prefix) ? file.slice(prefix.length) : null;
52
52
  }
53
- if (!name || !version || !PACKAGE_NAME.test(name) || semver.valid(version) !== version)
53
+ // A valid semver version, build metadata allowed (the proxy serves such a
54
+ // version on its own route), made only of version characters.
55
+ if (!name || !version || !PACKAGE_NAME.test(name) || !semver.valid(version) || !/^[0-9A-Za-z.+-]+$/.test(version))
54
56
  return null;
55
57
  return { name, version };
56
58
  }
@@ -67,7 +69,3 @@ export function normalizeNpmLockfile(content, registryUrl) {
67
69
  return target ? `${open}${publicNpmTarballUrl(target.name, target.version)}${close}` : match;
68
70
  });
69
71
  }
70
- export const npmLockfiles = {
71
- names: ["package-lock.json", "npm-shrinkwrap.json"],
72
- normalize: normalizeNpmLockfile,
73
- };