@wardby/cli 0.2.1 → 0.4.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 (555) hide show
  1. package/.env.example +53 -4
  2. package/README.md +52 -13
  3. package/dist/claude-coding-worker/driver.d.ts +6 -1
  4. package/dist/claude-coding-worker/driver.js +27 -1
  5. package/dist/claude-coding-worker/main.js +2 -0
  6. package/dist/claude-coding-worker/tool-socket.d.ts +9 -0
  7. package/dist/claude-coding-worker/tool-socket.js +26 -0
  8. package/dist/cli-help.d.ts +1 -1
  9. package/dist/cli-help.js +14 -4
  10. package/dist/cli.d.ts +1 -1
  11. package/dist/cli.js +284 -36
  12. package/dist/coding/base-commit.d.ts +6 -0
  13. package/dist/coding/base-commit.js +12 -0
  14. package/dist/coding/collect-exclude.d.ts +25 -0
  15. package/dist/coding/collect-exclude.js +76 -0
  16. package/dist/coding/profile.d.ts +67 -22
  17. package/dist/coding/profile.js +58 -25
  18. package/dist/coding/protected-path-wording.d.ts +24 -0
  19. package/dist/coding/protected-path-wording.js +55 -0
  20. package/dist/coding/protected-paths.d.ts +31 -0
  21. package/dist/coding/protected-paths.js +48 -0
  22. package/dist/coding/protocol.d.ts +91 -4
  23. package/dist/coding/protocol.js +123 -12
  24. package/dist/coding/provider.d.ts +6 -1
  25. package/dist/coding/provider.js +16 -9
  26. package/dist/coding/registry/adapters.d.ts +2 -0
  27. package/dist/coding/registry/adapters.js +9 -0
  28. package/dist/coding/registry/allowlist.d.ts +9 -0
  29. package/dist/coding/registry/allowlist.js +28 -0
  30. package/dist/coding/registry/json-scan.d.ts +55 -0
  31. package/dist/coding/registry/json-scan.js +191 -0
  32. package/dist/coding/registry/lockfiles.d.ts +6 -0
  33. package/dist/coding/registry/lockfiles.js +89 -0
  34. package/dist/coding/registry/npm-lockfile.d.ts +9 -0
  35. package/dist/coding/registry/npm-lockfile.js +73 -0
  36. package/dist/coding/registry/npm-plan.d.ts +29 -0
  37. package/dist/coding/registry/npm-plan.js +289 -0
  38. package/dist/coding/registry/npm.d.ts +7 -0
  39. package/dist/coding/registry/npm.js +252 -0
  40. package/dist/coding/registry/pypi.d.ts +4 -0
  41. package/dist/coding/registry/pypi.js +210 -0
  42. package/dist/coding/registry/report.d.ts +37 -0
  43. package/dist/coding/registry/report.js +31 -0
  44. package/dist/coding/registry/token.d.ts +4 -0
  45. package/dist/coding/registry/token.js +7 -0
  46. package/dist/coding/registry/types.d.ts +286 -0
  47. package/dist/coding/registry/types.js +19 -0
  48. package/dist/coding/registry/worker-config.d.ts +14 -0
  49. package/dist/coding/registry/worker-config.js +31 -0
  50. package/dist/coding/services/builtins.d.ts +22 -0
  51. package/dist/coding/services/builtins.js +85 -0
  52. package/dist/coding/services/catalog.d.ts +443 -0
  53. package/dist/coding/services/catalog.js +159 -0
  54. package/dist/coding/services/declaration.d.ts +11 -0
  55. package/dist/coding/services/declaration.js +114 -0
  56. package/dist/coding/services/note.d.ts +8 -0
  57. package/dist/coding/services/note.js +15 -0
  58. package/dist/coding/services/resolve.d.ts +25 -0
  59. package/dist/coding/services/resolve.js +50 -0
  60. package/dist/coding/services/wording.d.ts +25 -0
  61. package/dist/coding/services/wording.js +70 -0
  62. package/dist/coding-proxy/main.js +24 -4
  63. package/dist/coding-worker/artifact.d.ts +6 -0
  64. package/dist/coding-worker/debug-trace.d.ts +37 -0
  65. package/dist/coding-worker/debug-trace.js +117 -0
  66. package/dist/coding-worker/driver.d.ts +13 -1
  67. package/dist/coding-worker/driver.js +102 -13
  68. package/dist/coding-worker/errors.js +8 -0
  69. package/dist/coding-worker/main.js +10 -2
  70. package/dist/coding-worker/sdk.d.ts +2 -2
  71. package/dist/coding-worker/sdk.js +7 -2
  72. package/dist/coding-worker/types.d.ts +3 -0
  73. package/dist/config/providers.d.ts +66 -0
  74. package/dist/config/providers.js +137 -0
  75. package/dist/core/attribution.d.ts +101 -0
  76. package/dist/core/attribution.js +208 -0
  77. package/dist/core/budget-groups.d.ts +120 -10
  78. package/dist/core/budget-groups.js +133 -24
  79. package/dist/core/budget-wording.d.ts +22 -0
  80. package/dist/core/budget-wording.js +55 -0
  81. package/dist/core/coding-queue.d.ts +3 -0
  82. package/dist/core/coding-queue.js +6 -2
  83. package/dist/core/coding-service-status.d.ts +11 -0
  84. package/dist/core/coding-service-status.js +17 -0
  85. package/dist/core/cost-report.d.ts +88 -0
  86. package/dist/core/cost-report.js +248 -0
  87. package/dist/core/datastores.js +18 -2
  88. package/dist/core/db.d.ts +5 -1
  89. package/dist/core/db.js +8 -2
  90. package/dist/core/dispatch.d.ts +74 -7
  91. package/dist/core/dispatch.js +382 -47
  92. package/dist/core/engine-native.js +44 -14
  93. package/dist/core/glob.d.ts +10 -0
  94. package/dist/core/glob.js +33 -0
  95. package/dist/core/grants.d.ts +86 -0
  96. package/dist/core/grants.js +126 -0
  97. package/dist/core/host-events.d.ts +72 -0
  98. package/dist/core/host-events.js +597 -0
  99. package/dist/core/host-identity-links.d.ts +54 -0
  100. package/dist/core/host-identity-links.js +189 -0
  101. package/dist/core/host-status.d.ts +78 -0
  102. package/dist/core/host-status.js +228 -0
  103. package/dist/core/in-flight-runs.d.ts +8 -0
  104. package/dist/core/in-flight-runs.js +56 -0
  105. package/dist/core/issue-bridge.d.ts +60 -0
  106. package/dist/core/issue-bridge.js +189 -0
  107. package/dist/core/issue-dedupe.d.ts +70 -0
  108. package/dist/core/issue-dedupe.js +255 -0
  109. package/dist/core/issue-events.d.ts +42 -0
  110. package/dist/core/issue-events.js +155 -0
  111. package/dist/core/issue-status.d.ts +29 -0
  112. package/dist/core/issue-status.js +241 -0
  113. package/dist/core/issue-tracker-tools.d.ts +64 -0
  114. package/dist/core/issue-tracker-tools.js +850 -0
  115. package/dist/core/model-usage.d.ts +10 -0
  116. package/dist/core/model-usage.js +24 -0
  117. package/dist/core/provider-wording.d.ts +12 -0
  118. package/dist/core/provider-wording.js +44 -0
  119. package/dist/core/reconciler.d.ts +42 -2
  120. package/dist/core/reconciler.js +97 -2
  121. package/dist/core/repo-access.d.ts +99 -0
  122. package/dist/core/repo-access.js +136 -0
  123. package/dist/core/review-host-checks.d.ts +11 -0
  124. package/dist/core/review-host-checks.js +41 -0
  125. package/dist/core/review-host-tools.d.ts +47 -0
  126. package/dist/core/review-host-tools.js +354 -0
  127. package/dist/core/run-heartbeat.d.ts +27 -0
  128. package/dist/core/run-heartbeat.js +54 -0
  129. package/dist/core/run-pricing.d.ts +61 -0
  130. package/dist/core/run-pricing.js +56 -0
  131. package/dist/core/runner.d.ts +33 -8
  132. package/dist/core/runner.js +410 -62
  133. package/dist/core/scheduler.d.ts +4 -1
  134. package/dist/core/scheduler.js +3 -2
  135. package/dist/core/secrets.d.ts +11 -2
  136. package/dist/core/secrets.js +25 -6
  137. package/dist/core/self-defects.d.ts +80 -0
  138. package/dist/core/self-defects.js +180 -0
  139. package/dist/core/subagent-memory-tools.d.ts +1 -1
  140. package/dist/core/subagent-memory-tools.js +16 -3
  141. package/dist/core/tool-admin.d.ts +81 -0
  142. package/dist/core/tool-admin.js +129 -0
  143. package/dist/core/tool-names.d.ts +42 -0
  144. package/dist/core/tool-names.js +67 -0
  145. package/dist/core/untrusted-content.d.ts +32 -0
  146. package/dist/core/untrusted-content.js +72 -0
  147. package/dist/core/webhooks.d.ts +17 -2
  148. package/dist/core/webhooks.js +42 -3
  149. package/dist/generated/prisma/browser.d.ts +166 -0
  150. package/dist/generated/prisma/client.d.ts +166 -0
  151. package/dist/generated/prisma/commonInputTypes.d.ts +152 -52
  152. package/dist/generated/prisma/enums.d.ts +13 -0
  153. package/dist/generated/prisma/enums.js +12 -1
  154. package/dist/generated/prisma/internal/class.d.ts +242 -0
  155. package/dist/generated/prisma/internal/class.js +4 -4
  156. package/dist/generated/prisma/internal/prismaNamespace.d.ts +2571 -577
  157. package/dist/generated/prisma/internal/prismaNamespace.js +312 -6
  158. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +328 -0
  159. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +312 -6
  160. package/dist/generated/prisma/models/Agent.d.ts +682 -1
  161. package/dist/generated/prisma/models/AgentIssueProject.d.ts +1838 -0
  162. package/dist/generated/prisma/models/AgentIssueProject.js +1 -0
  163. package/dist/generated/prisma/models/AgentRepository.d.ts +1425 -0
  164. package/dist/generated/prisma/models/AgentRepository.js +1 -0
  165. package/dist/generated/prisma/models/AgentTool.d.ts +95 -1
  166. package/dist/generated/prisma/models/AuthUser.d.ts +56 -1
  167. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +258 -7
  168. package/dist/generated/prisma/models/CodingProxySession.d.ts +195 -2
  169. package/dist/generated/prisma/models/CodingRun.d.ts +1405 -95
  170. package/dist/generated/prisma/models/CodingRunServiceStatus.d.ts +1404 -0
  171. package/dist/generated/prisma/models/CodingRunServiceStatus.js +1 -0
  172. package/dist/generated/prisma/models/CodingService.d.ts +1348 -0
  173. package/dist/generated/prisma/models/CodingService.js +1 -0
  174. package/dist/generated/prisma/models/HostEventDelivery.d.ts +946 -0
  175. package/dist/generated/prisma/models/HostEventDelivery.js +1 -0
  176. package/dist/generated/prisma/models/HostIdentity.d.ts +1232 -0
  177. package/dist/generated/prisma/models/HostIdentity.js +1 -0
  178. package/dist/generated/prisma/models/HostIdentityLinkRequest.d.ts +1473 -0
  179. package/dist/generated/prisma/models/HostIdentityLinkRequest.js +1 -0
  180. package/dist/generated/prisma/models/IssueFingerprint.d.ts +1183 -0
  181. package/dist/generated/prisma/models/IssueFingerprint.js +1 -0
  182. package/dist/generated/prisma/models/IssuePullRequest.d.ts +1255 -0
  183. package/dist/generated/prisma/models/IssuePullRequest.js +1 -0
  184. package/dist/generated/prisma/models/ModelCatalogEntry.d.ts +1322 -0
  185. package/dist/generated/prisma/models/ModelCatalogEntry.js +1 -0
  186. package/dist/generated/prisma/models/Principal.d.ts +455 -0
  187. package/dist/generated/prisma/models/RegistryAllowance.d.ts +1148 -0
  188. package/dist/generated/prisma/models/RegistryAllowance.js +1 -0
  189. package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +1219 -0
  190. package/dist/generated/prisma/models/RegistryApprovedVersion.js +1 -0
  191. package/dist/generated/prisma/models/RegistryFetch.d.ts +1428 -0
  192. package/dist/generated/prisma/models/RegistryFetch.js +1 -0
  193. package/dist/generated/prisma/models/RegistryPlanRefusal.d.ts +1294 -0
  194. package/dist/generated/prisma/models/RegistryPlanRefusal.js +1 -0
  195. package/dist/generated/prisma/models/RegistryVersionFact.d.ts +1085 -0
  196. package/dist/generated/prisma/models/RegistryVersionFact.js +1 -0
  197. package/dist/generated/prisma/models/ResourceGrant.d.ts +1437 -0
  198. package/dist/generated/prisma/models/ResourceGrant.js +1 -0
  199. package/dist/generated/prisma/models/Run.d.ts +1402 -82
  200. package/dist/generated/prisma/models/RunAttribution.d.ts +1259 -0
  201. package/dist/generated/prisma/models/RunAttribution.js +1 -0
  202. package/dist/generated/prisma/models/RunHostCheck.d.ts +1239 -0
  203. package/dist/generated/prisma/models/RunHostCheck.js +1 -0
  204. package/dist/generated/prisma/models/RunHostStatus.d.ts +1315 -0
  205. package/dist/generated/prisma/models/RunHostStatus.js +1 -0
  206. package/dist/generated/prisma/models/RunIssueStatus.d.ts +1199 -0
  207. package/dist/generated/prisma/models/RunIssueStatus.js +1 -0
  208. package/dist/generated/prisma/models/RunModelUsage.d.ts +1316 -0
  209. package/dist/generated/prisma/models/RunModelUsage.js +1 -0
  210. package/dist/generated/prisma/models/Tool.d.ts +15 -3
  211. package/dist/generated/prisma/models/WorkItem.d.ts +1408 -0
  212. package/dist/generated/prisma/models/WorkItem.js +1 -0
  213. package/dist/generated/prisma/models.d.ts +22 -0
  214. package/dist/help/build.d.ts +1 -0
  215. package/dist/help/build.js +9 -0
  216. package/dist/help/catalog.d.ts +24 -0
  217. package/dist/help/catalog.js +160 -0
  218. package/dist/help/cli.d.ts +2 -0
  219. package/dist/help/cli.js +65 -0
  220. package/dist/help/runtime.d.ts +3 -0
  221. package/dist/help/runtime.js +44 -0
  222. package/dist/help/search.d.ts +9 -0
  223. package/dist/help/search.js +104 -0
  224. package/dist/help-index.json +999 -0
  225. package/dist/import/cli-args.js +3 -2
  226. package/dist/import/create.d.ts +5 -0
  227. package/dist/import/create.js +67 -13
  228. package/dist/import/index.js +19 -9
  229. package/dist/import/neutral-schema.d.ts +18 -18
  230. package/dist/knowledge/check.d.ts +13 -0
  231. package/dist/knowledge/check.js +69 -0
  232. package/dist/knowledge/cli.d.ts +14 -0
  233. package/dist/knowledge/cli.js +67 -0
  234. package/dist/knowledge/concept.d.ts +54 -0
  235. package/dist/knowledge/concept.js +78 -0
  236. package/dist/knowledge/note.d.ts +11 -0
  237. package/dist/knowledge/note.js +39 -0
  238. package/dist/knowledge/relevance.d.ts +11 -0
  239. package/dist/knowledge/relevance.js +14 -0
  240. package/dist/knowledge/span-hash.d.ts +3 -0
  241. package/dist/knowledge/span-hash.js +16 -0
  242. package/dist/mcp/auth/access.d.ts +72 -0
  243. package/dist/mcp/auth/access.js +58 -0
  244. package/dist/mcp/auth/grants-cli.d.ts +149 -0
  245. package/dist/mcp/auth/grants-cli.js +518 -0
  246. package/dist/mcp/auth/host-account-cli.d.ts +2 -0
  247. package/dist/mcp/auth/host-account-cli.js +47 -0
  248. package/dist/mcp/auth/ownership.d.ts +25 -51
  249. package/dist/mcp/auth/ownership.js +19 -14
  250. package/dist/mcp/auth/repo-authorization.d.ts +22 -0
  251. package/dist/mcp/auth/repo-authorization.js +51 -0
  252. package/dist/mcp/auth/resource-server.d.ts +33 -2
  253. package/dist/mcp/auth/resource-server.js +99 -3
  254. package/dist/mcp/auth/self-hosted/browser.js +2 -2
  255. package/dist/mcp/auth/self-hosted/cli.js +47 -13
  256. package/dist/mcp/auth/self-hosted/credentials.d.ts +23 -5
  257. package/dist/mcp/auth/self-hosted/credentials.js +62 -4
  258. package/dist/mcp/auth/self-hosted/session.d.ts +7 -6
  259. package/dist/mcp/context.d.ts +30 -1
  260. package/dist/mcp/errors.d.ts +25 -6
  261. package/dist/mcp/errors.js +98 -0
  262. package/dist/mcp/host-events/deliveries.d.ts +9 -0
  263. package/dist/mcp/host-events/deliveries.js +17 -0
  264. package/dist/mcp/host-events/github-ingress.d.ts +38 -0
  265. package/dist/mcp/host-events/github-ingress.js +83 -0
  266. package/dist/mcp/host-events/github-user-callback.d.ts +18 -0
  267. package/dist/mcp/host-events/github-user-callback.js +50 -0
  268. package/dist/mcp/host-events/jira-ingress.d.ts +29 -0
  269. package/dist/mcp/host-events/jira-ingress.js +92 -0
  270. package/dist/mcp/index.d.ts +10 -1
  271. package/dist/mcp/index.js +187 -19
  272. package/dist/mcp/server.js +32 -11
  273. package/dist/mcp/tools/agents.js +519 -50
  274. package/dist/mcp/tools/budget-groups.js +3 -3
  275. package/dist/mcp/tools/cost-report.d.ts +8 -0
  276. package/dist/mcp/tools/cost-report.js +60 -0
  277. package/dist/mcp/tools/datastore.js +22 -15
  278. package/dist/mcp/tools/grants.d.ts +2 -0
  279. package/dist/mcp/tools/grants.js +239 -0
  280. package/dist/mcp/tools/help.d.ts +5 -0
  281. package/dist/mcp/tools/help.js +67 -0
  282. package/dist/mcp/tools/host-accounts.d.ts +2 -0
  283. package/dist/mcp/tools/host-accounts.js +114 -0
  284. package/dist/mcp/tools/issue-projects.d.ts +2 -0
  285. package/dist/mcp/tools/issue-projects.js +238 -0
  286. package/dist/mcp/tools/memory.d.ts +7 -1
  287. package/dist/mcp/tools/memory.js +5 -5
  288. package/dist/mcp/tools/model-catalog.d.ts +22 -0
  289. package/dist/mcp/tools/model-catalog.js +423 -0
  290. package/dist/mcp/tools/repositories.d.ts +2 -0
  291. package/dist/mcp/tools/repositories.js +182 -0
  292. package/dist/mcp/tools/runs.d.ts +6 -0
  293. package/dist/mcp/tools/runs.js +60 -6
  294. package/dist/mcp/tools/scheduling.js +3 -6
  295. package/dist/mcp/tools/secrets.js +18 -6
  296. package/dist/mcp/tools/services.d.ts +2 -0
  297. package/dist/mcp/tools/services.js +222 -0
  298. package/dist/mcp/tools/subagents.js +52 -16
  299. package/dist/mcp/tools/tools.d.ts +41 -0
  300. package/dist/mcp/tools/tools.js +201 -40
  301. package/dist/mcp/tools/trigger.js +65 -7
  302. package/dist/mcp/tools/webhooks.js +15 -4
  303. package/dist/mcp/transport/streamable-http.d.ts +15 -0
  304. package/dist/mcp/transport/streamable-http.js +55 -3
  305. package/dist/mcp/webhooks/ingress.d.ts +2 -1
  306. package/dist/mcp/webhooks/ingress.js +9 -2
  307. package/dist/providers/auth/delegating.d.ts +19 -0
  308. package/dist/providers/auth/delegating.js +71 -0
  309. package/dist/providers/auth/index.d.ts +2 -0
  310. package/dist/providers/auth/index.js +11 -0
  311. package/dist/providers/auth/self-hosted.d.ts +10 -2
  312. package/dist/providers/auth/self-hosted.js +55 -6
  313. package/dist/providers/auth/types.d.ts +6 -0
  314. package/dist/providers/coding-proxy/memory-ledger.d.ts +4 -1
  315. package/dist/providers/coding-proxy/memory-ledger.js +31 -3
  316. package/dist/providers/coding-proxy/metering.d.ts +6 -1
  317. package/dist/providers/coding-proxy/metering.js +41 -4
  318. package/dist/providers/coding-proxy/prisma-ledger.d.ts +17 -0
  319. package/dist/providers/coding-proxy/prisma-ledger.js +106 -8
  320. package/dist/providers/coding-proxy/proxy.d.ts +25 -2
  321. package/dist/providers/coding-proxy/proxy.js +561 -38
  322. package/dist/providers/coding-proxy/registry/audit.d.ts +131 -0
  323. package/dist/providers/coding-proxy/registry/audit.js +380 -0
  324. package/dist/providers/coding-proxy/registry/bounded-fetch.d.ts +16 -0
  325. package/dist/providers/coding-proxy/registry/bounded-fetch.js +77 -0
  326. package/dist/providers/coding-proxy/registry/plan.d.ts +58 -0
  327. package/dist/providers/coding-proxy/registry/plan.js +304 -0
  328. package/dist/providers/coding-proxy/registry/prisma-store.d.ts +34 -0
  329. package/dist/providers/coding-proxy/registry/prisma-store.js +151 -0
  330. package/dist/providers/coding-proxy/registry/service.d.ts +213 -0
  331. package/dist/providers/coding-proxy/registry/service.js +1137 -0
  332. package/dist/providers/coding-proxy/registry/store.d.ts +127 -0
  333. package/dist/providers/coding-proxy/registry/store.js +70 -0
  334. package/dist/providers/coding-proxy/runtime.d.ts +17 -0
  335. package/dist/providers/coding-proxy/runtime.js +63 -0
  336. package/dist/providers/coding-proxy/secure-fetch.js +0 -1
  337. package/dist/providers/coding-proxy/server.d.ts +11 -0
  338. package/dist/providers/coding-proxy/server.js +163 -0
  339. package/dist/providers/coding-proxy/types.d.ts +33 -1
  340. package/dist/providers/coding-proxy/types.js +12 -1
  341. package/dist/providers/engine/types.d.ts +29 -0
  342. package/dist/providers/executor/build.d.ts +2 -2
  343. package/dist/providers/executor/composition.d.ts +3 -0
  344. package/dist/providers/executor/composition.js +28 -1
  345. package/dist/providers/executor/container.d.ts +134 -4
  346. package/dist/providers/executor/container.js +394 -37
  347. package/dist/providers/executor/dbos.d.ts +4 -3
  348. package/dist/providers/executor/dbos.js +7 -5
  349. package/dist/providers/executor/in-process.d.ts +2 -3
  350. package/dist/providers/executor/routing.d.ts +13 -0
  351. package/dist/providers/executor/routing.js +18 -0
  352. package/dist/providers/executor/types.d.ts +34 -0
  353. package/dist/providers/issue-tracker/adf.d.ts +31 -0
  354. package/dist/providers/issue-tracker/adf.js +181 -0
  355. package/dist/providers/issue-tracker/index.d.ts +5 -0
  356. package/dist/providers/issue-tracker/index.js +12 -0
  357. package/dist/providers/issue-tracker/jira-client.d.ts +41 -0
  358. package/dist/providers/issue-tracker/jira-client.js +151 -0
  359. package/dist/providers/issue-tracker/jira-events.d.ts +3 -0
  360. package/dist/providers/issue-tracker/jira-events.js +98 -0
  361. package/dist/providers/issue-tracker/jira.d.ts +116 -0
  362. package/dist/providers/issue-tracker/jira.js +502 -0
  363. package/dist/providers/issue-tracker/types.d.ts +269 -0
  364. package/dist/providers/issue-tracker/types.js +16 -0
  365. package/dist/providers/jobs/claude-tool-setup.d.ts +23 -0
  366. package/dist/providers/jobs/claude-tool-setup.js +50 -0
  367. package/dist/providers/jobs/collect-prune.d.ts +7 -0
  368. package/dist/providers/jobs/collect-prune.js +27 -0
  369. package/dist/providers/jobs/docker-isolation.d.ts +48 -3
  370. package/dist/providers/jobs/docker-isolation.js +213 -22
  371. package/dist/providers/jobs/docker-services.d.ts +35 -0
  372. package/dist/providers/jobs/docker-services.js +191 -0
  373. package/dist/providers/jobs/docker.d.ts +53 -2
  374. package/dist/providers/jobs/docker.js +307 -32
  375. package/dist/providers/jobs/fake-kubernetes-api.d.ts +1 -0
  376. package/dist/providers/jobs/fake-kubernetes-api.js +12 -3
  377. package/dist/providers/jobs/kubernetes-isolation.d.ts +17 -2
  378. package/dist/providers/jobs/kubernetes-isolation.js +238 -57
  379. package/dist/providers/jobs/kubernetes-platform.d.ts +10 -4
  380. package/dist/providers/jobs/kubernetes-platform.js +11 -5
  381. package/dist/providers/jobs/kubernetes-preflight.js +3 -0
  382. package/dist/providers/jobs/kubernetes.d.ts +24 -2
  383. package/dist/providers/jobs/kubernetes.js +153 -22
  384. package/dist/providers/jobs/service-state.d.ts +22 -0
  385. package/dist/providers/jobs/service-state.js +17 -0
  386. package/dist/providers/jobs/types.d.ts +18 -0
  387. package/dist/providers/llm/anthropic.d.ts +3 -3
  388. package/dist/providers/llm/anthropic.js +3 -5
  389. package/dist/providers/llm/bedrock.d.ts +3 -3
  390. package/dist/providers/llm/bedrock.js +3 -8
  391. package/dist/providers/llm/catalog-lookup.d.ts +10 -0
  392. package/dist/providers/llm/catalog-lookup.js +15 -0
  393. package/dist/providers/llm/catalog-shipped.d.ts +18 -0
  394. package/dist/providers/llm/catalog-shipped.js +197 -0
  395. package/dist/providers/llm/catalog-store.d.ts +58 -0
  396. package/dist/providers/llm/catalog-store.js +138 -0
  397. package/dist/providers/llm/catalog-types.d.ts +66 -0
  398. package/dist/providers/llm/catalog-types.js +64 -0
  399. package/dist/providers/llm/catalog.d.ts +61 -0
  400. package/dist/providers/llm/catalog.js +147 -0
  401. package/dist/providers/llm/claude-messages.d.ts +5 -1
  402. package/dist/providers/llm/claude-messages.js +1 -0
  403. package/dist/providers/llm/claude-provider.d.ts +10 -12
  404. package/dist/providers/llm/claude-provider.js +15 -6
  405. package/dist/providers/llm/index.d.ts +9 -6
  406. package/dist/providers/llm/index.js +8 -5
  407. package/dist/providers/llm/openai.d.ts +14 -5
  408. package/dist/providers/llm/openai.js +24 -14
  409. package/dist/providers/llm/pricing-core.d.ts +5 -3
  410. package/dist/providers/llm/registration.js +8 -12
  411. package/dist/providers/llm/routing.d.ts +21 -11
  412. package/dist/providers/llm/routing.js +47 -13
  413. package/dist/providers/llm/types.d.ts +12 -0
  414. package/dist/providers/llm/types.js +8 -1
  415. package/dist/providers/review-host/diff-lines.d.ts +16 -0
  416. package/dist/providers/review-host/diff-lines.js +59 -0
  417. package/dist/providers/review-host/github-events.d.ts +6 -0
  418. package/dist/providers/review-host/github-events.js +226 -0
  419. package/dist/providers/review-host/github-user-auth.d.ts +38 -0
  420. package/dist/providers/review-host/github-user-auth.js +128 -0
  421. package/dist/providers/review-host/github.d.ts +57 -0
  422. package/dist/providers/review-host/github.js +568 -0
  423. package/dist/providers/review-host/index.d.ts +12 -0
  424. package/dist/providers/review-host/index.js +30 -0
  425. package/dist/providers/review-host/review-format.d.ts +19 -0
  426. package/dist/providers/review-host/review-format.js +59 -0
  427. package/dist/providers/review-host/types.d.ts +309 -0
  428. package/dist/providers/review-host/types.js +24 -0
  429. package/dist/providers/vcs/git.d.ts +16 -6
  430. package/dist/providers/vcs/git.js +78 -34
  431. package/dist/providers/vcs/github.d.ts +94 -3
  432. package/dist/providers/vcs/github.js +223 -17
  433. package/dist/providers/vcs/types.d.ts +48 -4
  434. package/dist/quickstart/index.d.ts +2 -0
  435. package/dist/quickstart/index.js +36 -8
  436. package/dist/sandbox/fetch-policy.d.ts +20 -2
  437. package/dist/sandbox/fetch-policy.js +64 -3
  438. package/dist/sandbox/host-functions.d.ts +9 -1
  439. package/dist/sandbox/host-functions.js +12 -5
  440. package/dist/serve.js +8 -2
  441. package/dist/viewer/api-schema.d.ts +2757 -0
  442. package/dist/viewer/api-schema.js +165 -0
  443. package/dist/viewer/build-schemas.d.ts +2 -0
  444. package/dist/viewer/build-schemas.js +18 -0
  445. package/dist/viewer/event-bus.d.ts +38 -0
  446. package/dist/viewer/event-bus.js +232 -0
  447. package/dist/viewer/graph.d.ts +40 -0
  448. package/dist/viewer/graph.js +243 -0
  449. package/dist/viewer/http.d.ts +30 -0
  450. package/dist/viewer/http.js +133 -0
  451. package/dist/viewer/run-detail.d.ts +4 -0
  452. package/dist/viewer/run-detail.js +61 -0
  453. package/dist/wardby-bin.js +11 -0
  454. package/docs/README.md +40 -0
  455. package/docs/agent-recipes.md +383 -0
  456. package/docs/architecture-runtime.md +90 -0
  457. package/docs/assets/brand/wardby-icon-512.png +0 -0
  458. package/docs/assets/brand/wardby-icon.svg +16 -0
  459. package/docs/assets/brand/wardby-mascot-profile-512.png +0 -0
  460. package/docs/assets/brand/wardby-mascot.png +0 -0
  461. package/docs/assets/brand/wardby-mascot.svg +5 -0
  462. package/docs/assets/wardby-workflow.svg +106 -0
  463. package/docs/code-review-agents.md +508 -0
  464. package/docs/coding-agent-setup.md +175 -0
  465. package/docs/coding-packages.md +455 -0
  466. package/docs/coding-services.md +300 -0
  467. package/docs/coding-worker-byo-images.md +98 -0
  468. package/docs/coding-worker-isolation.md +1068 -0
  469. package/docs/getting-started-gke.md +632 -0
  470. package/docs/getting-started-identity-provider.md +319 -0
  471. package/docs/getting-started.md +147 -0
  472. package/docs/jira-agents.md +649 -0
  473. package/docs/knowledge.md +387 -0
  474. package/docs/models.md +221 -0
  475. package/docs/observability.md +53 -0
  476. package/docs/release-verification.md +66 -0
  477. package/docs/security-deployment.md +667 -0
  478. package/docs/viewer-api.md +142 -0
  479. package/help/admin-viewer.md +39 -0
  480. package/help/agent-recipes.md +173 -0
  481. package/help/architecture-agent.md +189 -0
  482. package/help/builder-agent.md +80 -0
  483. package/help/code-review-agents.md +37 -0
  484. package/help/coding-packages.md +31 -0
  485. package/help/coding-services.md +71 -0
  486. package/help/cost-attribution.md +67 -0
  487. package/help/creating-agents.md +90 -0
  488. package/help/deploy-gke.md +45 -0
  489. package/help/deployment-targets.md +39 -0
  490. package/help/errors/budget-group-exhausted.md +25 -0
  491. package/help/errors/docker-isolation-unsupported.md +26 -0
  492. package/help/errors/model-unavailable.md +63 -0
  493. package/help/errors/protected-path.md +45 -0
  494. package/help/errors/repo-access.md +27 -0
  495. package/help/errors/service-declaration-invalid.md +27 -0
  496. package/help/errors/service-declaration-unavailable.md +25 -0
  497. package/help/errors/service-launcher-unsupported.md +30 -0
  498. package/help/errors/service-not-allowed.md +27 -0
  499. package/help/errors/service-unknown.md +23 -0
  500. package/help/errors/service-unready.md +49 -0
  501. package/help/getting-started.md +32 -0
  502. package/help/github.md +48 -0
  503. package/help/identity-and-access.md +44 -0
  504. package/help/jira.md +135 -0
  505. package/help/knowledge.md +47 -0
  506. package/help/mcp.md +30 -0
  507. package/help/models.md +90 -0
  508. package/help/native-capabilities.md +30 -0
  509. package/help/observability.md +41 -0
  510. package/help/operating-agents.md +36 -0
  511. package/help/security.md +27 -0
  512. package/help/troubleshooting/budgets.md +32 -0
  513. package/help/troubleshooting/coding-workers.md +47 -0
  514. package/help/troubleshooting/repository-access.md +27 -0
  515. package/package.json +14 -3
  516. package/prisma/migrations/20260925010000_coding_collect_exclude/migration.sql +8 -0
  517. package/prisma/migrations/20260925015000_allowed_egress_default/migration.sql +8 -0
  518. package/prisma/migrations/20260925020000_coding_package_registry/migration.sql +55 -0
  519. package/prisma/migrations/20260925030000_tool_name_per_owner/migration.sql +11 -0
  520. package/prisma/migrations/20260926010000_run_trigger_host_event/migration.sql +7 -0
  521. package/prisma/migrations/20260926020000_code_review_hosts/migration.sql +53 -0
  522. package/prisma/migrations/20260926030000_auth_user_roles/migration.sql +9 -0
  523. package/prisma/migrations/20260926040000_agent_effort/migration.sql +6 -0
  524. package/prisma/migrations/20260926050000_registry_lockfile_plan/migration.sql +32 -0
  525. package/prisma/migrations/20260926050000_repo_access_authorization/migration.sql +82 -0
  526. package/prisma/migrations/20260926060000_registry_plan_refusal/migration.sql +19 -0
  527. package/prisma/migrations/20260926100000_registry_plan_refusal_published_at/migration.sql +5 -0
  528. package/prisma/migrations/20260926190000_run_host_status/migration.sql +18 -0
  529. package/prisma/migrations/20260926210000_run_host_status_at_dispatch/migration.sql +5 -0
  530. package/prisma/migrations/20260927010000_resource_grants/migration.sql +72 -0
  531. package/prisma/migrations/20260927020000_proxy_session_budget_exhausted/migration.sql +3 -0
  532. package/prisma/migrations/20260927030000_coding_debug_trace/migration.sql +4 -0
  533. package/prisma/migrations/20260927040000_proxy_session_upstream_failure/migration.sql +3 -0
  534. package/prisma/migrations/20260927050000_coding_run_services/migration.sql +74 -0
  535. package/prisma/migrations/20260928000000_coding_run_tool_image/migration.sql +5 -0
  536. package/prisma/migrations/20260930000000_jira_issue_projects/migration.sql +34 -0
  537. package/prisma/migrations/20261001000000_jira_phase2_allowlists/migration.sql +3 -0
  538. package/prisma/migrations/20261001010000_jira_link_types_allowlist/migration.sql +2 -0
  539. package/prisma/migrations/20261002000000_jira_coding_bridge/migration.sql +28 -0
  540. package/prisma/migrations/20261002010000_jira_issue_creation/migration.sql +25 -0
  541. package/prisma/migrations/20261003000000_issue_cost_attribution/migration.sql +56 -0
  542. package/prisma/migrations/20261003010000_coding_run_service_status/migration.sql +23 -0
  543. package/prisma/migrations/20261003020000_viewer_notify/migration.sql +54 -0
  544. package/prisma/migrations/20261003030000_viewer_notify_fixes/migration.sql +47 -0
  545. package/prisma/migrations/20261003040000_viewer_indexes/migration.sql +12 -0
  546. package/prisma/migrations/20261004000000_model_catalog/migration.sql +26 -0
  547. package/prisma/schema.prisma +663 -21
  548. package/dist/mcp/tools/models.d.ts +0 -8
  549. package/dist/mcp/tools/models.js +0 -15
  550. package/dist/providers/llm/pricing-anthropic.d.ts +0 -4
  551. package/dist/providers/llm/pricing-anthropic.js +0 -30
  552. package/dist/providers/llm/pricing-bedrock-claude.d.ts +0 -12
  553. package/dist/providers/llm/pricing-bedrock-claude.js +0 -37
  554. package/dist/providers/llm/pricing.d.ts +0 -30
  555. package/dist/providers/llm/pricing.js +0 -74
@@ -0,0 +1,59 @@
1
+ /** Agent ids are cuids; anything else could break out of the HTML comment. */
2
+ export const SAFE_AGENT_MARKER = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
3
+ const SAFE_SHA = /^[0-9a-f]{40}$/;
4
+ const MARKER_PREFIX = "<!-- wardby:review:";
5
+ function assertMarker(agentMarker) {
6
+ if (!SAFE_AGENT_MARKER.test(agentMarker))
7
+ throw new Error("review_marker_invalid");
8
+ }
9
+ export function reviewMarker(agentMarker, headSha) {
10
+ assertMarker(agentMarker);
11
+ if (!SAFE_SHA.test(headSha))
12
+ throw new Error("review_marker_invalid");
13
+ return `${MARKER_PREFIX}${agentMarker} sha=${headSha} -->`;
14
+ }
15
+ export function hasReviewMarker(body, agentMarker) {
16
+ assertMarker(agentMarker);
17
+ return body.includes(`${MARKER_PREFIX}${agentMarker} sha=`);
18
+ }
19
+ export function parseReviewMarker(body, agentMarker) {
20
+ assertMarker(agentMarker);
21
+ const match = new RegExp(`${MARKER_PREFIX}${agentMarker} sha=([0-9a-f]{40}) -->`).exec(body);
22
+ return match ? match[1] : null;
23
+ }
24
+ export function verdictConclusion(verdict) {
25
+ if (verdict === "APPROVE")
26
+ return "success";
27
+ if (verdict === "CHANGES_REQUESTED")
28
+ return "failure";
29
+ return "neutral";
30
+ }
31
+ const BADGES = {
32
+ APPROVE: "✅ **Approved**",
33
+ CHANGES_REQUESTED: "❌ **Changes requested**",
34
+ COMMENT: "💬 **Comments**",
35
+ };
36
+ const FINDING_PREFIX = "<!-- wardby:finding:";
37
+ /** Tags an inline comment with the agent that wrote it, so only that agent resolves its thread. */
38
+ export function findingMarker(agentMarker) {
39
+ assertMarker(agentMarker);
40
+ return `${FINDING_PREFIX}${agentMarker} -->`;
41
+ }
42
+ export function hasFindingMarker(body, agentMarker) {
43
+ return body.includes(findingMarker(agentMarker));
44
+ }
45
+ export function renderInlineComment(comment, agentMarker) {
46
+ return `**[${comment.severity}]** ${comment.body}\n\n${findingMarker(agentMarker)}`;
47
+ }
48
+ export function renderSummaryComment(input) {
49
+ const sections = [
50
+ reviewMarker(input.agentMarker, input.headSha),
51
+ `${BADGES[input.verdict]} — reviewed \`${input.headSha.slice(0, 7)}\``,
52
+ input.summary,
53
+ input.body,
54
+ ];
55
+ if (input.outside.length > 0) {
56
+ sections.push(["## Outside the diff", ...input.outside.map((c) => `- **[${c.severity}] ${c.path}:${c.line}** ${c.body}`)].join("\n"));
57
+ }
58
+ return sections.join("\n\n");
59
+ }
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Host-neutral code-review surface for native agents. GitHub is the first
3
+ * implementation (./github.ts); Bitbucket Cloud is anticipated. Every method
4
+ * takes the repository and mints its own least-permission credential — no
5
+ * method accepts a token or a permission. See
6
+ * docs/private/2026-09-25-code-review-host-design.md §5.
7
+ */
8
+ export type ReviewHostProvider = "github";
9
+ export declare const REVIEW_HOST_PROVIDERS: readonly ReviewHostProvider[];
10
+ export type ReviewVerdict = "APPROVE" | "CHANGES_REQUESTED" | "COMMENT";
11
+ export type CheckConclusion = "success" | "failure" | "neutral";
12
+ export type CommentSide = "LEFT" | "RIGHT";
13
+ export interface PullRequestFileView {
14
+ filename: string;
15
+ status: string;
16
+ additions: number;
17
+ deletions: number;
18
+ previousFilename?: string;
19
+ patch: string;
20
+ patchTruncated: boolean;
21
+ }
22
+ /** One of this agent's own review threads that is still unresolved. */
23
+ export interface ReviewThreadView {
24
+ /** Opaque host id; pass it back in PublishReviewInput.resolveThreadIds. */
25
+ id: string;
26
+ path: string;
27
+ /** The line in the current head, or null when the thread is outdated (its line no longer exists). */
28
+ line: number | null;
29
+ outdated: boolean;
30
+ /** The finding as posted, without its marker, capped at 1,000 characters. */
31
+ body: string;
32
+ }
33
+ export interface PullRequestView {
34
+ number: number;
35
+ title: string;
36
+ body: string;
37
+ author: string | null;
38
+ state: string;
39
+ merged: boolean;
40
+ draft: boolean;
41
+ baseRef: string;
42
+ headRef: string;
43
+ headSha: string;
44
+ isFork: boolean;
45
+ htmlUrl: string;
46
+ /** Head sha recorded in this agent's summary comment, if it reviewed before. */
47
+ lastReviewedSha: string | null;
48
+ /** Set when `files` is the compare of `comparedFrom...headSha` rather than the whole PR. */
49
+ comparedFrom: string | null;
50
+ /**
51
+ * The base branch was merged into the PR since `comparedFrom`: `files` is
52
+ * then the PR's own diff (against its base), limited to files that changed
53
+ * since `comparedFrom`, so base-branch changes are left out.
54
+ */
55
+ baseMergedSince: boolean;
56
+ files: PullRequestFileView[];
57
+ /** This agent's own unresolved review threads on the PR (the first 100 threads are searched). */
58
+ openThreads: ReviewThreadView[];
59
+ }
60
+ export interface PullRequestHead {
61
+ headSha: string;
62
+ isFork: boolean;
63
+ state: string;
64
+ }
65
+ export type FileReadResult = {
66
+ kind: "file";
67
+ path: string;
68
+ ref: string;
69
+ totalLines: number;
70
+ startLine: number;
71
+ endLine: number;
72
+ truncated: boolean;
73
+ /** The window with `N: ` line-number prefixes: the display form shown to agents. */
74
+ content: string;
75
+ /** The same window without line-number prefixes, lines joined by "\n": for machine parsing. */
76
+ text: string;
77
+ } | {
78
+ kind: "directory";
79
+ path: string;
80
+ entries: string[];
81
+ } | {
82
+ kind: "not_found";
83
+ path: string;
84
+ };
85
+ export interface FileListView {
86
+ ref: string;
87
+ count: number;
88
+ truncated: boolean;
89
+ /** Display strings (path plus size) shown to agents. */
90
+ files: string[];
91
+ /** Bare repository paths, same order and length as `files`. */
92
+ paths: string[];
93
+ }
94
+ export interface InlineComment {
95
+ path: string;
96
+ line: number;
97
+ side: CommentSide;
98
+ severity: string;
99
+ body: string;
100
+ }
101
+ export interface PublishReviewInput {
102
+ prNumber: number;
103
+ headSha: string;
104
+ verdict: ReviewVerdict;
105
+ summary: string;
106
+ body: string;
107
+ comments: InlineComment[];
108
+ /** Identifies this agent's summary comment; the agent id. */
109
+ agentMarker: string;
110
+ /**
111
+ * Names a completed check to create when no checkId is supplied (a run not
112
+ * started by a host event). With neither, no check is created.
113
+ */
114
+ checkName?: string;
115
+ /** The run's own in-progress check, when the control plane started one. */
116
+ checkId?: string;
117
+ /**
118
+ * Threads to resolve because this head fixes them. Only this agent's own
119
+ * unresolved threads on this PR are resolved; any other id is skipped.
120
+ */
121
+ resolveThreadIds?: string[];
122
+ }
123
+ export type PublishReviewResult = {
124
+ published: true;
125
+ reviewUrl: string | null;
126
+ summaryCommentUrl: string;
127
+ /** Null when no check was completed or created (neither checkId nor checkName). */
128
+ checkId: string | null;
129
+ /** The verdict's check mapping — informational when checkId is null. */
130
+ checkConclusion: CheckConclusion;
131
+ inlineCount: number;
132
+ outsideDiffCount: number;
133
+ resolvedThreadIds: string[];
134
+ /** Requested ids that were not resolved: not this agent's open thread on this PR, or the host refused. */
135
+ skippedThreadIds: string[];
136
+ } | {
137
+ published: false;
138
+ reason: "stale_head";
139
+ currentHeadSha: string;
140
+ };
141
+ export interface CommentInput {
142
+ number: number;
143
+ body: string;
144
+ replyToReviewCommentId?: string;
145
+ }
146
+ /** A comment the App wrote, to edit later: a conversation comment or a reply in a review thread. */
147
+ export interface EditCommentInput {
148
+ kind: "conversation" | "inline";
149
+ id: string;
150
+ body: string;
151
+ }
152
+ export interface CommentRef {
153
+ /**
154
+ * "conversation" = a top-level comment on an issue/PR conversation; "inline" = a comment on a diff line (review
155
+ * thread); "subject" = the issue or PR itself (its title/description), with `id` its number.
156
+ */
157
+ kind: "conversation" | "inline" | "subject";
158
+ id: string;
159
+ }
160
+ export interface StartCheckInput {
161
+ headSha: string;
162
+ name: string;
163
+ }
164
+ export interface CompleteCheckInput {
165
+ checkId: string;
166
+ conclusion: CheckConclusion;
167
+ title: string;
168
+ summary: string;
169
+ text?: string;
170
+ detailsUrl?: string;
171
+ }
172
+ /**
173
+ * A user's effective permission on one repository, host-neutral and ranked
174
+ * none < read < triage < write < maintain < admin. GitHub maps its
175
+ * collaborator permission onto these directly; GitLab would map reporter ->
176
+ * read, developer -> write, maintainer -> maintain, owner -> admin.
177
+ */
178
+ export type HostPermission = "none" | "read" | "triage" | "write" | "maintain" | "admin";
179
+ export declare const HOST_PERMISSION_RANK: Readonly<Record<HostPermission, number>>;
180
+ /** A host user, by its immutable numeric id (as text) and its current login. */
181
+ export interface HostUser {
182
+ id: string;
183
+ login: string;
184
+ }
185
+ export interface CodeReviewHost {
186
+ readonly provider: ReviewHostProvider;
187
+ /**
188
+ * The user's effective permission on `repository`, asked with the App's own
189
+ * installation credential (never a user token). Answers only for the user
190
+ * with this id: a login that now names someone else is re-resolved by id,
191
+ * and `login` in the result is the user's current login.
192
+ */
193
+ repositoryPermission(repository: string, user: HostUser): Promise<{
194
+ level: HostPermission;
195
+ login: string;
196
+ }>;
197
+ readPullRequest(repository: string, prNumber: number, opts: {
198
+ sinceSha?: string;
199
+ maxPatchChars: number;
200
+ agentMarker: string;
201
+ }): Promise<PullRequestView>;
202
+ pullRequestHead(repository: string, prNumber: number): Promise<PullRequestHead>;
203
+ readFile(repository: string, path: string, ref: string | undefined, window: {
204
+ startLine: number;
205
+ maxLines: number;
206
+ }): Promise<FileReadResult>;
207
+ listFiles(repository: string, ref: string | undefined, pathPrefix?: string): Promise<FileListView>;
208
+ publishReview(repository: string, input: PublishReviewInput): Promise<PublishReviewResult>;
209
+ /** `id` identifies the new comment for editComment; a reply is an "inline" comment, anything else "conversation". */
210
+ comment(repository: string, input: CommentInput): Promise<{
211
+ url: string;
212
+ id: string;
213
+ }>;
214
+ /** Replaces the body of a comment the App wrote. */
215
+ editComment(repository: string, input: EditCommentInput): Promise<void>;
216
+ /** Marks a comment as picked up (GitHub: a 👀 reaction); a host without reactions may do nothing. */
217
+ acknowledge(repository: string, target: CommentRef): Promise<void>;
218
+ startCheck(repository: string, input: StartCheckInput): Promise<{
219
+ checkId: string;
220
+ }>;
221
+ completeCheck(repository: string, input: CompleteCheckInput): Promise<void>;
222
+ }
223
+ export type ReviewHostErrorCode = "host_not_installed" | "host_permission_missing" | "host_api_error" | "host_invalid_response";
224
+ export declare class ReviewHostError extends Error {
225
+ readonly code: ReviewHostErrorCode;
226
+ constructor(code: ReviewHostErrorCode, message?: string);
227
+ }
228
+ export type ReviewHostRegistry = Partial<Record<ReviewHostProvider, CodeReviewHost>>;
229
+ /**
230
+ * A host's user-authorization (OAuth web) flow, used only to learn who a
231
+ * wardby principal is on the host. Implementations never store or return the
232
+ * user token: `complete` reads the user and revokes the token at once.
233
+ */
234
+ export interface HostUserAuthorizer {
235
+ readonly provider: ReviewHostProvider;
236
+ authorizeUrl(input: {
237
+ state: string;
238
+ codeChallenge: string;
239
+ redirectUri: string;
240
+ }): string;
241
+ complete(input: {
242
+ code: string;
243
+ codeVerifier: string;
244
+ redirectUri: string;
245
+ }): Promise<{
246
+ hostUserId: string;
247
+ login: string;
248
+ }>;
249
+ }
250
+ export type HostUserAuthorizerRegistry = Partial<Record<ReviewHostProvider, HostUserAuthorizer>>;
251
+ /**
252
+ * Host-neutral shape a webhook adapter (github-events.ts) normalises its
253
+ * provider payload into, for src/core/host-events.ts to route.
254
+ */
255
+ export type HostEvent = {
256
+ kind: "push";
257
+ provider: ReviewHostProvider;
258
+ repository: string;
259
+ /** The branch pushed (without refs/heads/), always the repository's default branch. */
260
+ branch: string;
261
+ before: string;
262
+ after: string;
263
+ /** Union of added/modified/removed paths over the payload's commits, deduplicated, at most 1000. */
264
+ changedPaths: string[];
265
+ /** False when GitHub truncated the commit list (> 20 commits) or paths were capped: treat every concept as in scope. */
266
+ changedPathsComplete: boolean;
267
+ } | {
268
+ kind: "pr_updated";
269
+ provider: ReviewHostProvider;
270
+ repository: string;
271
+ prNumber: number;
272
+ headSha: string;
273
+ isFork: boolean;
274
+ } | {
275
+ /** The PR was merged or closed; only drives bookkeeping on issue/PR pairs wardby recorded. */
276
+ kind: "pr_closed";
277
+ provider: ReviewHostProvider;
278
+ repository: string;
279
+ prNumber: number;
280
+ merged: boolean;
281
+ } | {
282
+ kind: "check_rerun";
283
+ provider: ReviewHostProvider;
284
+ repository: string;
285
+ prNumber: number;
286
+ headSha: string;
287
+ checkName: string;
288
+ } | {
289
+ kind: "mention";
290
+ provider: ReviewHostProvider;
291
+ repository: string;
292
+ number: number;
293
+ isPullRequest: boolean;
294
+ comment: CommentRef;
295
+ /** Set when the mention is inside an inline review thread. */
296
+ replyToReviewCommentId?: string;
297
+ /** The comment text; for a "subject" mention, the issue/PR description. */
298
+ body: string;
299
+ author: string;
300
+ /** The author's immutable numeric host user id, as text; their permission is checked by it. */
301
+ authorId: string;
302
+ /** The issue or PR the mention is on, when the payload carries it. */
303
+ subject?: {
304
+ title: string;
305
+ body: string;
306
+ };
307
+ /** The run that opened this PR, when its description carries a valid run marker. */
308
+ priorRunId?: string;
309
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Host-neutral code-review surface for native agents. GitHub is the first
3
+ * implementation (./github.ts); Bitbucket Cloud is anticipated. Every method
4
+ * takes the repository and mints its own least-permission credential — no
5
+ * method accepts a token or a permission. See
6
+ * docs/private/2026-09-25-code-review-host-design.md §5.
7
+ */
8
+ export const REVIEW_HOST_PROVIDERS = ["github"];
9
+ export const HOST_PERMISSION_RANK = {
10
+ none: 0,
11
+ read: 1,
12
+ triage: 2,
13
+ write: 3,
14
+ maintain: 4,
15
+ admin: 5,
16
+ };
17
+ export class ReviewHostError extends Error {
18
+ code;
19
+ constructor(code, message = code) {
20
+ super(message);
21
+ this.code = code;
22
+ this.name = "ReviewHostError";
23
+ }
24
+ }
@@ -1,5 +1,5 @@
1
- import { type GitHubRepositoryAccess } from "./github.js";
2
- import type { FinalizeChangesDetails, FinalizeChangesResult, PreparedWorkspace, VcsPrepareInput, VcsProvider } from "./types.js";
1
+ import { type GitHubRepositoryAccess, type RepositoryFileInput } from "./github.js";
2
+ import type { ContinuationFinishedDetails, ContinuationOutcome, FinalizeChangesDetails, FinalizeChangesResult, PreparedWorkspace, VcsPrepareInput, VcsProvider } from "./types.js";
3
3
  export declare const DEFAULT_MAX_CHANGED_FILES = 1000;
4
4
  export declare const DEFAULT_MAX_DIFF_BYTES: number;
5
5
  export interface GitCommandOptions {
@@ -43,6 +43,18 @@ export interface GitVcsProviderOptions {
43
43
  /** Test-only transport override; production composition always uses github.com. */
44
44
  cloneUrlForRepository?: (repository: string) => string;
45
45
  }
46
+ /**
47
+ * Whether a changed path is protected, in this order: the WARDBY_PROTECTED_PATHS
48
+ * baseline's exception (.wardby/services.yaml, which a builder may propose; it
49
+ * takes effect only after merge, docs/coding-services.md) is never protected;
50
+ * anything else under the baseline (.wardby/**) always is, whatever the agent's
51
+ * exceptions say; any other path is protected when it matches one of the
52
+ * agent's `patterns` and is not one of its exceptions (entries with a leading
53
+ * "!", each a literal path, so order does not matter). The baseline is applied
54
+ * here, at enforcement, rather than stored, so every existing agent and
55
+ * in-flight run gets it.
56
+ */
57
+ export declare function protectedPathMatcher(patterns: readonly string[]): (path: string) => boolean;
46
58
  export declare class GitVcsProvider implements VcsProvider {
47
59
  private readonly options;
48
60
  private readonly rootDir;
@@ -74,10 +86,8 @@ export declare class GitVcsProvider implements VcsProvider {
74
86
  * github.ts). Safe to call more than once for the same run. Same
75
87
  * never-throw contract as notifyContinuationStarted.
76
88
  */
77
- notifyContinuationFinished(workspace: PreparedWorkspace, outcome: "succeeded" | "failed", details?: {
78
- summary?: string;
79
- agentName?: string;
80
- }): Promise<void>;
89
+ notifyContinuationFinished(workspace: PreparedWorkspace, outcome: ContinuationOutcome, details?: ContinuationFinishedDetails): Promise<void>;
90
+ readRepositoryFile(input: RepositoryFileInput): Promise<string | null>;
81
91
  private validateInput;
82
92
  private expectedPaths;
83
93
  private validatePrepared;
@@ -2,7 +2,10 @@ import { spawn } from "node:child_process";
2
2
  import { lstat, mkdir, opendir, readFile, readlink, realpath, rm } from "node:fs/promises";
3
3
  import { isAbsolute, resolve, sep } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
+ import { gitExcludePathspecs, normalizeCollectExclusions } from "../../coding/collect-exclude.js";
6
+ import { WARDBY_PROTECTED_PATHS, isProtectedPathException, isWellFormedProtectedPath, protectedPathBody, protectsSomePath, } from "../../coding/protected-paths.js";
5
7
  import { ensurePrivateDirectory } from "../../core/private-directory.js";
8
+ import { globRegex } from "../../core/glob.js";
6
9
  import { MAX_REDACTED_SPAN, redactTokenShapedValues, normalizeGitHubRepository, normalizeGitRef, } from "../../coding/protocol.js";
7
10
  import { isSafeGitHubInstallationToken } from "./github.js";
8
11
  export const DEFAULT_MAX_CHANGED_FILES = 1_000;
@@ -139,39 +142,40 @@ export class NodeGitCommandRunner {
139
142
  });
140
143
  }
141
144
  }
145
+ /** Validates one protectedPaths entry; a leading "!" makes it an exception (see protectedPathMatcher). */
142
146
  function validateProtectedPath(value) {
143
147
  const path = value.trim();
144
- if (!path ||
145
- Buffer.byteLength(path, "utf8") > 512 ||
146
- path.startsWith("/") ||
147
- path.startsWith("./") ||
148
- path.includes("\\") ||
149
- path.split("/").some((part) => !part || part === "." || part === "..")) {
148
+ if (Buffer.byteLength(path, "utf8") > 512 || !isWellFormedProtectedPath(path)) {
150
149
  throw new Error("vcs_protected_path_invalid");
151
150
  }
152
151
  return path;
153
152
  }
154
- function globRegex(pattern) {
155
- let source = "^";
156
- for (let index = 0; index < pattern.length; index += 1) {
157
- const character = pattern[index];
158
- if (character === "*") {
159
- if (pattern[index + 1] === "*") {
160
- source += ".*";
161
- index += 1;
162
- }
163
- else {
164
- source += "[^/]*";
165
- }
166
- }
167
- else if (character === "?") {
168
- source += "[^/]";
169
- }
170
- else {
171
- source += character.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
172
- }
173
- }
174
- return new RegExp(`${source}$`);
153
+ /** The fixed baseline, split once: its literal exceptions and its protected globs. */
154
+ const WARDBY_UNPROTECTED = new Set(WARDBY_PROTECTED_PATHS.filter(isProtectedPathException).map(protectedPathBody));
155
+ const WARDBY_PROTECTED = WARDBY_PROTECTED_PATHS.filter((pattern) => !isProtectedPathException(pattern)).map((pattern) => globRegex(pattern));
156
+ /**
157
+ * Whether a changed path is protected, in this order: the WARDBY_PROTECTED_PATHS
158
+ * baseline's exception (.wardby/services.yaml, which a builder may propose; it
159
+ * takes effect only after merge, docs/coding-services.md) is never protected;
160
+ * anything else under the baseline (.wardby/**) always is, whatever the agent's
161
+ * exceptions say; any other path is protected when it matches one of the
162
+ * agent's `patterns` and is not one of its exceptions (entries with a leading
163
+ * "!", each a literal path, so order does not matter). The baseline is applied
164
+ * here, at enforcement, rather than stored, so every existing agent and
165
+ * in-flight run gets it.
166
+ */
167
+ export function protectedPathMatcher(patterns) {
168
+ const exceptions = new Set(patterns.filter(isProtectedPathException).map(protectedPathBody));
169
+ const protectedPatterns = patterns
170
+ .filter((pattern) => !isProtectedPathException(pattern))
171
+ .map((pattern) => globRegex(pattern));
172
+ return (path) => {
173
+ if (WARDBY_UNPROTECTED.has(path))
174
+ return false;
175
+ if (WARDBY_PROTECTED.some((matcher) => matcher.test(path)))
176
+ return true;
177
+ return protectedPatterns.some((matcher) => matcher.test(path)) && !exceptions.has(path);
178
+ };
175
179
  }
176
180
  function validateChangedPath(path) {
177
181
  if (!path ||
@@ -352,7 +356,15 @@ export class GitVcsProvider {
352
356
  await this.inspectWorkspace(prepared.workspacePath);
353
357
  await this.assertRemote(prepared);
354
358
  await this.assertSafeLocalConfig(prepared.gitMetadataPath);
355
- await this.gitFor(prepared, ["add", "--all", "--", ":/"]);
359
+ // Excluded paths (src/coding/collect-exclude.ts) are never collected from the worker, so
360
+ // they are also neither added nor deleted here: tracked files under them stay untouched.
361
+ await this.gitFor(prepared, [
362
+ "add",
363
+ "--all",
364
+ "--",
365
+ ":/",
366
+ ...gitExcludePathspecs(normalizeCollectExclusions(prepared.collectExclude)),
367
+ ]);
356
368
  const changed = nullSeparated((await this.gitFor(prepared, [
357
369
  "diff",
358
370
  "--cached",
@@ -364,8 +376,7 @@ export class GitVcsProvider {
364
376
  ])).stdout);
365
377
  if (changed.length > this.maxChangedFiles)
366
378
  throw new Error("vcs_changed_file_limit");
367
- const protectedMatchers = prepared.protectedPaths.map((path) => ({ path, matcher: globRegex(path) }));
368
- const protectedChange = changed.find((path) => protectedMatchers.some(({ matcher }) => matcher.test(path)));
379
+ const protectedChange = changed.find(protectedPathMatcher(prepared.protectedPaths));
369
380
  if (protectedChange)
370
381
  throw new Error(`vcs_protected_path:${protectedChange}`);
371
382
  let diff;
@@ -412,15 +423,21 @@ export class GitVcsProvider {
412
423
  // run's id), not this run's own -- this finds the existing open PR and
413
424
  // returns it rather than creating a new one, since headRef/baseRef
414
425
  // already match it exactly. No other change needed here: pushing a new
415
- // commit onto that branch already updates the PR natively.
426
+ // commit onto that branch already updates the PR natively -- which is
427
+ // also why a PR a person has since marked ready for review is accepted
428
+ // (acceptReadyForReview) rather than failing an already-pushed run.
416
429
  const pullRequest = await this.options.github.createOrFindDraftPullRequest({
417
430
  runId: prepared.continuation?.rootRunId ?? prepared.runId,
431
+ ...(prepared.continuation ? { acceptReadyForReview: true } : {}),
418
432
  repository: prepared.repository,
419
433
  baseRef: prepared.baseRef,
420
434
  headRef: prepared.headRef,
421
435
  summary: details?.summary,
422
436
  tests: details?.tests,
423
437
  tag: details?.tag,
438
+ packages: details?.packages,
439
+ packageRefusals: details?.packageRefusals,
440
+ ...(details?.issue ? { issue: details.issue } : {}),
424
441
  });
425
442
  return {
426
443
  outcome: prepared.continuation ? "pull_request_updated" : "pull_request_opened",
@@ -498,14 +515,25 @@ export class GitVcsProvider {
498
515
  };
499
516
  const label = runLabel(details?.agentName, workspace.runId);
500
517
  const summarySuffix = details?.summary ? `\n\n${details.summary}` : "";
501
- const body = outcome === "succeeded" ? `✅ ${label} finished.${summarySuffix}` : `❌ ${label} failed.${summarySuffix}`;
518
+ const budgetSuffix = details?.budgetSentence ? ` ${details.budgetSentence}` : "";
519
+ const body = outcome === "succeeded"
520
+ ? `✅ ${label} finished.${summarySuffix}`
521
+ : outcome === "budget_exhausted"
522
+ ? `❌ ${label} ran out of budget.${budgetSuffix}${summarySuffix}`
523
+ : details?.serviceSentence
524
+ ? `❌ ${label} could not start: ${details.serviceSentence}${summarySuffix}`
525
+ : details?.providerSentence
526
+ ? `❌ ${label} could not run: ${details.providerSentence}${summarySuffix}`
527
+ : details?.protectedPathSentence
528
+ ? `❌ ${label} could not open its changes: ${details.protectedPathSentence}${summarySuffix}`
529
+ : `❌ ${label} failed.${summarySuffix}`;
502
530
  await Promise.allSettled([
503
531
  this.options.github.updateContinuationStatusComment({ ...identity, body }),
504
532
  this.options.github.completeContinuationCheckRun({
505
533
  repository: workspace.repository,
506
534
  headSha: workspace.baseCommit,
507
535
  runId: workspace.runId,
508
- outcome,
536
+ outcome: outcome === "succeeded" ? "succeeded" : "failed",
509
537
  }),
510
538
  ]);
511
539
  }
@@ -513,6 +541,17 @@ export class GitVcsProvider {
513
541
  // Best-effort observability only -- must never affect the real run.
514
542
  }
515
543
  }
544
+ async readRepositoryFile(input) {
545
+ const github = this.options.github;
546
+ if (!github.readFileAtRef)
547
+ throw new Error("vcs_read_file_unsupported");
548
+ return github.readFileAtRef({
549
+ repository: normalizeGitHubRepository(input.repository),
550
+ ref: normalizeGitRef(input.ref),
551
+ path: validateChangedPath(input.path),
552
+ maxBytes: input.maxBytes,
553
+ });
554
+ }
516
555
  validateInput(input) {
517
556
  if (!SAFE_RUN_ID.test(input.runId))
518
557
  throw new Error("vcs_run_id_invalid");
@@ -540,7 +579,10 @@ export class GitVcsProvider {
540
579
  const protectedPaths = [...new Set(input.protectedPaths.map(validateProtectedPath))];
541
580
  if (protectedPaths.length === 0 || protectedPaths.length > 128)
542
581
  throw new Error("vcs_protected_paths_invalid");
543
- return { runId: input.runId, repository, baseRef, headRef, protectedPaths, continuation };
582
+ if (!protectsSomePath(protectedPaths))
583
+ throw new Error("vcs_protected_paths_invalid");
584
+ const collectExclude = [...normalizeCollectExclusions(input.collectExclude ?? []).paths];
585
+ return { runId: input.runId, repository, baseRef, headRef, protectedPaths, collectExclude, continuation };
544
586
  }
545
587
  expectedPaths(runId) {
546
588
  if (!SAFE_RUN_ID.test(runId))
@@ -566,6 +608,8 @@ export class GitVcsProvider {
566
608
  workspace.gitMetadataPath !== expected.gitMetadataPath ||
567
609
  workspace.protectedPaths.length !== normalized.protectedPaths.length ||
568
610
  workspace.protectedPaths.some((path, index) => path !== normalized.protectedPaths[index]) ||
611
+ workspace.collectExclude.length !== normalized.collectExclude.length ||
612
+ workspace.collectExclude.some((path, index) => path !== normalized.collectExclude[index]) ||
569
613
  workspace.continuation?.rootRunId !== normalized.continuation?.rootRunId) {
570
614
  throw new Error("vcs_workspace_handle_invalid");
571
615
  }