@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
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Minimal CLI.
4
4
  *
5
- * wardby agent create --name <n> --model <m> --prompt <p> --budget <usd> [--schedule "<cron>"] [--timezone <tz>] [--memory-enabled]
5
+ * wardby agent create --name <n> --model <m> --prompt <p> --budget <usd> [--schedule "<cron>"] [--timezone <tz>] [--memory-enabled] [--effort <level>]
6
6
  * wardby agent list
7
7
  * wardby agent schedule <name> --cron "<expr>" [--timezone <tz>] [--disable]
8
8
  * wardby run <name>
@@ -20,31 +20,43 @@ import { readFileSync } from "node:fs";
20
20
  import { execFile as execFileCallback } from "node:child_process";
21
21
  import { parseArgs } from "node:util";
22
22
  import { promisify } from "node:util";
23
- import { loadCodingConcurrencyConfig, loadContainerExecutorConfig, loadKubernetesJobConfig, loadProviderConfig, } from "./config/providers.js";
23
+ import { loadCodingConcurrencyConfig, loadContainerExecutorConfig, loadKubernetesJobConfig, loadMcpConfig, loadProviderConfig, } from "./config/providers.js";
24
24
  import { drainCodingQueue } from "./core/coding-queue.js";
25
25
  import { isImmutableDockerImage } from "./providers/jobs/docker-isolation.js";
26
26
  import { ClientNodeKubernetesApi } from "./providers/jobs/kubernetes-client.js";
27
27
  import { describePreflightFailure, kubernetesPreflight } from "./providers/jobs/kubernetes-preflight.js";
28
- import { RoutingLlmProvider, resolveLlmRegistrations } from "./providers/llm/index.js";
28
+ import { RoutingLlmProvider, isLlmEffort, modelSupportedEfforts, resolveLlmRegistrations, } from "./providers/llm/index.js";
29
+ import { startModelCatalog } from "./providers/llm/catalog-store.js";
29
30
  import { buildConfiguredExecutor, buildExecutor } from "./providers/executor/index.js";
30
31
  import { PostgresDatastore } from "./providers/datastore/index.js";
31
32
  import { PostgresAgentMemory } from "./providers/memory/index.js";
32
33
  import { buildSecretCipher } from "./providers/secrets/index.js";
33
34
  import { prisma } from "./core/db.js";
34
35
  import { runAgent } from "./core/runner.js";
36
+ import { cancelRunOnSignal } from "./core/run-heartbeat.js";
37
+ import { buildIssueTrackers } from "./providers/issue-tracker/index.js";
38
+ import { buildReviewHosts } from "./providers/review-host/index.js";
39
+ import { createRepoAccessGate } from "./core/repo-access.js";
35
40
  import { validateCronExpression } from "./core/cron.js";
41
+ import { assertAgentModelAvailable } from "./core/run-pricing.js";
36
42
  import { startScheduler } from "./core/scheduler.js";
37
43
  import { startReconciler } from "./core/reconciler.js";
38
44
  import { NativeEngine } from "./core/engine-native.js";
39
45
  import { logger } from "./core/logger.js";
40
46
  import { deriveJsonSchema } from "./sandbox/zod-params.js";
47
+ import { findSameNamedAttachedTool, reservedToolNameReason, resolveToolRef } from "./core/tool-names.js";
48
+ import { ToolAttachedError, deleteToolGuarded, formatAttachedAgents, formatToolLine, hasToolChanges, prepareToolUpdate, updateToolGuarded, } from "./core/tool-admin.js";
41
49
  import { ToolCapabilitiesPatchSchema } from "./sandbox/tool-capabilities.js";
42
50
  import { startMcp } from "./mcp/index.js";
43
51
  import { startServe } from "./serve.js";
44
52
  import { authCommand } from "./mcp/auth/self-hosted/cli.js";
53
+ import { hostAccountCommand } from "./mcp/auth/host-account-cli.js";
54
+ import { grantsCommand, resolveCliAgentOwner } from "./mcp/auth/grants-cli.js";
55
+ import { everyoneGrantData } from "./core/grants.js";
45
56
  import { parseImportArgs } from "./import/cli-args.js";
46
57
  import { runImport } from "./import/index.js";
47
58
  import { CLI_USAGE } from "./cli-help.js";
59
+ import { helpCommand } from "./help/cli.js";
48
60
  const cliLog = logger.child({ module: "cli" });
49
61
  const RUN_STATUSES = [
50
62
  "pending",
@@ -106,6 +118,9 @@ async function agentCreate(args) {
106
118
  timezone: { type: "string" },
107
119
  "max-turns": { type: "string" },
108
120
  "memory-enabled": { type: "boolean" },
121
+ effort: { type: "string" },
122
+ owner: { type: "string" },
123
+ public: { type: "boolean" },
109
124
  },
110
125
  });
111
126
  if (!values.name || !values.model || !values.prompt || !values.budget) {
@@ -128,17 +143,58 @@ async function agentCreate(args) {
128
143
  fail(`invalid --schedule/--timezone: ${err instanceof Error ? err.message : String(err)}`);
129
144
  }
130
145
  }
131
- const agent = await prisma.agent.create({
132
- data: {
133
- name: values.name,
134
- model: values.model,
135
- systemPrompt: values.prompt,
136
- budgetUsd,
137
- schedule: values.schedule ?? null,
138
- timezone,
139
- maxTurns,
140
- memoryEnabled: values["memory-enabled"] ?? false,
141
- },
146
+ // Started before validating the model so an admin override recorded in
147
+ // ModelCatalogEntry (a disabled model, a narrowed effort list) is
148
+ // respected here too, not just at run time.
149
+ let modelCatalog;
150
+ try {
151
+ modelCatalog = await startModelCatalog(prisma);
152
+ }
153
+ catch (err) {
154
+ fail(err instanceof Error ? err.message : String(err));
155
+ }
156
+ try {
157
+ assertAgentModelAvailable(values.model);
158
+ }
159
+ catch (err) {
160
+ fail(err instanceof Error ? err.message : String(err));
161
+ }
162
+ if (values.effort !== undefined) {
163
+ const accepted = modelSupportedEfforts(values.model);
164
+ if (!isLlmEffort(values.effort) || !accepted.includes(values.effort)) {
165
+ fail(`model "${values.model}" does not accept --effort "${values.effort}"` +
166
+ (accepted.length > 0 ? ` (accepted: ${accepted.join(", ")}).` : " (it accepts no effort setting)."));
167
+ }
168
+ }
169
+ modelCatalog.close();
170
+ // Owned by --owner or the local operator; never owner-less (resource-
171
+ // sharing grants spec §3.8). --public shares it with everyone at execute.
172
+ let ownerId;
173
+ try {
174
+ ownerId = await resolveCliAgentOwner(prisma, values.owner, loadMcpConfig().localPrincipal);
175
+ }
176
+ catch (err) {
177
+ fail(err instanceof Error ? err.message : String(err));
178
+ }
179
+ const agent = await prisma.$transaction(async (tx) => {
180
+ const created = await tx.agent.create({
181
+ data: {
182
+ name: values.name,
183
+ model: values.model,
184
+ systemPrompt: values.prompt,
185
+ budgetUsd,
186
+ schedule: values.schedule ?? null,
187
+ timezone,
188
+ maxTurns,
189
+ memoryEnabled: values["memory-enabled"] ?? false,
190
+ effort: values.effort ?? null,
191
+ ownerId: ownerId,
192
+ },
193
+ });
194
+ if (values.public) {
195
+ await tx.resourceGrant.create({ data: everyoneGrantData("agent", created.id, "execute", "operator") });
196
+ }
197
+ return created;
142
198
  });
143
199
  console.log(agent.id);
144
200
  }
@@ -155,6 +211,9 @@ async function toolCreate(args) {
155
211
  if (!values.name || !values.description || !values.params || !values.code) {
156
212
  fail("tool create requires --name, --description, --params <file>, and --code <file>.");
157
213
  }
214
+ const reserved = reservedToolNameReason(values.name);
215
+ if (reserved)
216
+ fail(reserved);
158
217
  let paramsZod;
159
218
  let code;
160
219
  try {
@@ -170,12 +229,19 @@ async function toolCreate(args) {
170
229
  fail(`could not read --code file "${values.code}": ${err instanceof Error ? err.message : String(err)}`);
171
230
  }
172
231
  // Fails at registration, not at call time: a malformed schema never gets
173
- // persisted. The derived schema is cached on the row (no "update tool"
174
- // path exists, so it can never go stale) rather than re-derived per run.
232
+ // persisted. The derived schema is cached on the row rather than
233
+ // re-derived per run; MCP update_tool re-derives it whenever paramsZod
234
+ // changes, so it never goes stale.
175
235
  const schemaResult = await deriveJsonSchema(paramsZod);
176
236
  if (!schemaResult.ok) {
177
237
  fail(`invalid --params schema: ${schemaResult.errorMessage}`);
178
238
  }
239
+ // CLI tools are public (no owner), and the (ownerId, name) unique index
240
+ // treats NULL owners as distinct, so it can't stop a second public tool
241
+ // with this name -- check here instead.
242
+ if (await prisma.tool.findFirst({ where: { ownerId: null, name: values.name } })) {
243
+ fail(`a public tool named "${values.name}" already exists.`);
244
+ }
179
245
  const tool = await prisma.tool.create({
180
246
  data: {
181
247
  name: values.name,
@@ -203,11 +269,14 @@ async function toolAttach(args, detach) {
203
269
  });
204
270
  const [toolName, agentName] = positionals;
205
271
  if (!toolName || !agentName) {
206
- fail(`tool ${detach ? "detach" : "attach"} requires <tool-name> <agent-name>.`);
207
- }
208
- const tool = await prisma.tool.findUnique({ where: { name: toolName } });
209
- if (!tool)
210
- fail(`unknown tool "${toolName}".`);
272
+ fail(`tool ${detach ? "detach" : "attach"} requires <tool-name|tool-id> <agent-name>.`);
273
+ }
274
+ // Tool names are unique per owner, not globally: an ambiguous name fails
275
+ // with the candidate ids, and an id is accepted in its place.
276
+ const resolved = await resolveToolRef(prisma, toolName);
277
+ if (!resolved.ok)
278
+ fail(resolved.error);
279
+ const tool = resolved.tool;
211
280
  const agent = await prisma.agent.findUnique({ where: { name: agentName } });
212
281
  if (!agent)
213
282
  fail(`unknown agent "${agentName}".`);
@@ -229,6 +298,14 @@ async function toolAttach(args, detach) {
229
298
  (allowedSharedDatastorePrefixes[boundName] ??= []).push(prefix);
230
299
  }
231
300
  }
301
+ // Same guard as MCP attach_tool: one agent never holds two tools with the
302
+ // same name, since the runtime dispatches by name. Operator-only, so unlike
303
+ // attach_tool this check-then-upsert is not one Serializable transaction
304
+ // (the runner's load-time duplicate check still catches a race).
305
+ const clash = await findSameNamedAttachedTool(prisma, agent.id, tool);
306
+ if (clash) {
307
+ fail(`agent "${agentName}" already has a different tool named "${tool.name}" attached (${clash.id}); detach it first.`);
308
+ }
232
309
  const patch = ToolCapabilitiesPatchSchema.safeParse({
233
310
  allowedSecrets: values["allow-secret"],
234
311
  allowedDatastorePrefixes: values["allow-datastore-prefix"],
@@ -238,6 +315,10 @@ async function toolAttach(args, detach) {
238
315
  if (!patch.success) {
239
316
  fail(`invalid tool capabilities: ${patch.error.issues.map((i) => i.message).join("; ")}`);
240
317
  }
318
+ // The operator is trusted with the database, so it grants these
319
+ // capabilities in the agent owner's name: the runner honours them only
320
+ // with the owner's consent stamp (resource-sharing grants spec §3.4.2).
321
+ // An owner-less agent has no owner to stamp: its capabilities stay inert.
241
322
  await prisma.agentTool.upsert({
242
323
  where: { agentId_toolId: { agentId: agent.id, toolId: tool.id } },
243
324
  create: {
@@ -247,8 +328,10 @@ async function toolAttach(args, detach) {
247
328
  allowedDatastorePrefixes: patch.data.allowedDatastorePrefixes ?? [],
248
329
  allowedHosts: patch.data.allowedHosts ?? [],
249
330
  allowedSharedDatastorePrefixes: patch.data.allowedSharedDatastorePrefixes ?? {},
331
+ capabilitiesGrantedById: agent.ownerId,
250
332
  },
251
333
  update: {
334
+ capabilitiesGrantedById: agent.ownerId,
252
335
  ...(patch.data.allowedSecrets !== undefined ? { allowedSecrets: patch.data.allowedSecrets } : {}),
253
336
  ...(patch.data.allowedDatastorePrefixes !== undefined
254
337
  ? { allowedDatastorePrefixes: patch.data.allowedDatastorePrefixes }
@@ -273,16 +356,116 @@ async function toolList(args) {
273
356
  return;
274
357
  }
275
358
  for (const a of attached)
276
- console.log(`${a.tool.name} ${a.tool.description}`);
359
+ console.log(formatToolLine(a.tool));
277
360
  return;
278
361
  }
279
- const tools = await prisma.tool.findMany({ orderBy: { name: "asc" } });
362
+ const tools = await prisma.tool.findMany({ orderBy: [{ name: "asc" }, { id: "asc" }] });
280
363
  if (tools.length === 0) {
281
364
  console.log("no tools registered.");
282
365
  return;
283
366
  }
284
367
  for (const t of tools)
285
- console.log(`${t.name} ${t.description}`);
368
+ console.log(formatToolLine(t));
369
+ }
370
+ /**
371
+ * The operator may change any tool, public ones included; only a row that
372
+ * vanished since it was resolved is refused. Thrown rather than fail()ed:
373
+ * it runs inside the transaction, which must roll back, not exit mid-way.
374
+ */
375
+ function operatorAuthorize(ref) {
376
+ return (tool) => {
377
+ if (!tool)
378
+ throw new Error(`unknown tool "${ref}".`);
379
+ };
380
+ }
381
+ /**
382
+ * `wardby tool update <tool-name|tool-id>` -- the operator's counterpart of
383
+ * MCP update_tool, and the only way to change a public tool. Same
384
+ * validation (jsonSchema re-derived from --params) and the same attachment
385
+ * rule, judged against the tool's owner (core/tool-admin.ts).
386
+ */
387
+ async function toolUpdate(args) {
388
+ const { values, positionals } = parseArgs({
389
+ args,
390
+ allowPositionals: true,
391
+ options: {
392
+ description: { type: "string" },
393
+ params: { type: "string" },
394
+ code: { type: "string" },
395
+ },
396
+ });
397
+ const [ref] = positionals;
398
+ if (!ref)
399
+ fail("tool update requires <tool-name|tool-id>.");
400
+ const readFile = (flag, path) => {
401
+ if (path === undefined)
402
+ return undefined;
403
+ try {
404
+ return readFileSync(path, "utf8");
405
+ }
406
+ catch (err) {
407
+ fail(`could not read ${flag} file "${path}": ${err instanceof Error ? err.message : String(err)}`);
408
+ }
409
+ };
410
+ const changes = {
411
+ description: values.description,
412
+ paramsZod: readFile("--params", values.params),
413
+ code: readFile("--code", values.code),
414
+ };
415
+ if (!hasToolChanges(changes)) {
416
+ fail("tool update requires at least one of --description, --params <file>, --code <file>.");
417
+ }
418
+ const resolved = await resolveToolRef(prisma, ref);
419
+ if (!resolved.ok)
420
+ fail(resolved.error);
421
+ const prepared = await prepareToolUpdate(changes);
422
+ if (!prepared.ok)
423
+ fail(`invalid --params schema: ${prepared.errorMessage}`);
424
+ try {
425
+ await updateToolGuarded(prisma, resolved.tool.id, prepared.data, operatorAuthorize(ref));
426
+ }
427
+ catch (err) {
428
+ if (err instanceof ToolAttachedError) {
429
+ fail(`tool "${ref}" is attached to agents with a different owner: ${formatAttachedAgents(err.agents)}. Detach it from those agents first, or create a new tool.`);
430
+ }
431
+ throw err;
432
+ }
433
+ console.log(`updated tool ${resolved.tool.id}.`);
434
+ }
435
+ /** `wardby tool delete <tool-name|tool-id> [--detach]` -- MCP delete_tool's rules, public tools included. */
436
+ async function toolDelete(args) {
437
+ const { values, positionals } = parseArgs({
438
+ args,
439
+ allowPositionals: true,
440
+ options: { detach: { type: "boolean" } },
441
+ });
442
+ const [ref] = positionals;
443
+ if (!ref)
444
+ fail("tool delete requires <tool-name|tool-id>.");
445
+ const resolved = await resolveToolRef(prisma, ref);
446
+ if (!resolved.ok)
447
+ fail(resolved.error);
448
+ let detachedFrom;
449
+ try {
450
+ detachedFrom = await deleteToolGuarded(prisma, resolved.tool.id, {
451
+ detach: values.detach ?? false,
452
+ authorize: operatorAuthorize(ref),
453
+ });
454
+ }
455
+ catch (err) {
456
+ if (!(err instanceof ToolAttachedError))
457
+ throw err;
458
+ if (err.reason === "other_owners") {
459
+ fail(`tool "${ref}" is attached to agents with a different owner: ${formatAttachedAgents(err.agents)}. Detach it from those agents first (wardby tool detach).`);
460
+ }
461
+ if (err.reason === "needs_detach") {
462
+ fail(`tool "${ref}" is still attached to ${formatAttachedAgents(err.agents)}. Pass --detach to detach it and delete it.`);
463
+ }
464
+ fail(`tool "${ref}" is still attached to an agent; nothing was deleted.`);
465
+ }
466
+ console.log(detachedFrom.length > 0
467
+ ? `deleted tool ${resolved.tool.id} (detached from ${detachedFrom.join(", ")}).`
468
+ : `deleted tool ${resolved.tool.id}.`);
286
469
  }
287
470
  async function agentSchedule(args) {
288
471
  const [name, ...rest] = args;
@@ -347,20 +530,36 @@ async function run(name) {
347
530
  if (agent.kind === "coding") {
348
531
  fail("Coding agents are MCP-first: use trigger_agent so task input and ownership are recorded safely.");
349
532
  }
533
+ let modelCatalog;
534
+ try {
535
+ modelCatalog = await startModelCatalog(prisma);
536
+ }
537
+ catch (err) {
538
+ fail(err instanceof Error ? err.message : String(err));
539
+ }
350
540
  const llm = buildLlmProvider();
351
541
  const engine = buildEngine();
352
542
  const secrets = buildSecrets();
353
543
  const datastore = buildDatastore(secrets);
354
544
  const memory = buildMemory();
355
545
  let run;
546
+ // Ctrl-C (or a SIGTERM) records the run as cancelled rather than leaving a
547
+ // `running` row behind.
548
+ let removeSignalHandlers;
356
549
  try {
357
- run = await runAgent(name, { llm, engine, datastore, secrets, memory }, prisma, (delta) => {
550
+ run = await runAgent(name, { llm, engine, datastore, secrets, memory, reviewHosts: buildReviewHosts(), issueTrackers: buildIssueTrackers() }, prisma, (delta) => {
358
551
  process.stdout.write(delta);
552
+ }, (created) => {
553
+ removeSignalHandlers = cancelRunOnSignal(prisma, created.id);
359
554
  });
360
555
  }
361
556
  catch (err) {
362
557
  fail(err instanceof Error ? err.message : String(err));
363
558
  }
559
+ finally {
560
+ removeSignalHandlers?.();
561
+ modelCatalog.close();
562
+ }
364
563
  process.stdout.write("\n");
365
564
  const completedAgent = await prisma.agent.findUnique({ where: { id: run.agentId } });
366
565
  const budgetUsd = completedAgent ? Number(completedAgent.budgetUsd) : NaN;
@@ -486,22 +685,35 @@ async function scheduler(args) {
486
685
  // Parsed before anything starts, so a malformed CODING_MAX_CONCURRENT or
487
686
  // CODING_QUEUE_TIMEOUT_SEC fails fast.
488
687
  const concurrency = loadCodingConcurrencyConfig();
688
+ let modelCatalog;
689
+ try {
690
+ modelCatalog = await startModelCatalog(prisma);
691
+ }
692
+ catch (err) {
693
+ fail(err instanceof Error ? err.message : String(err));
694
+ }
489
695
  const config = loadProviderConfig();
490
696
  const llm = buildLlmProvider();
491
697
  const engine = buildEngine();
492
698
  const secrets = buildSecrets();
493
699
  const datastore = buildDatastore(secrets);
494
700
  const memory = buildMemory();
495
- const nativeExecutor = buildExecutor(config, { llm, engine, datastore, secrets, memory }, prisma);
496
- const executor = buildConfiguredExecutor({ native: nativeExecutor, db: prisma, providerConfig: config });
701
+ const reviewHosts = buildReviewHosts();
702
+ const issueTrackers = buildIssueTrackers();
703
+ // One repository-access gate (and cache) for native repo_* calls and coding runs.
704
+ const repoAccess = createRepoAccessGate({ db: prisma, hosts: reviewHosts });
705
+ const nativeExecutor = buildExecutor(config, { llm, engine, datastore, secrets, memory, reviewHosts, issueTrackers, repoAccess }, prisma);
706
+ const executor = buildConfiguredExecutor({ native: nativeExecutor, db: prisma, providerConfig: config, repoAccess });
497
707
  await executor.launch?.();
498
- const reconciler = startReconciler({ db: prisma, executor });
708
+ const reconciler = startReconciler({ db: prisma, executor, reviewHosts, issueTrackers });
709
+ const selfDefects = { db: prisma, issueTrackers };
499
710
  const sched = startScheduler({
500
711
  executor,
501
712
  db: prisma,
502
713
  scope,
714
+ selfDefects,
503
715
  onLeaderTick: async () => {
504
- await drainCodingQueue({ db: prisma, executor, ...concurrency });
716
+ await drainCodingQueue({ db: prisma, executor, ...concurrency, selfDefects });
505
717
  },
506
718
  });
507
719
  console.log(`wardby scheduler started (scope "${scope}"). Press Ctrl+C to stop.`);
@@ -512,7 +724,10 @@ async function scheduler(args) {
512
724
  reconciler.stop();
513
725
  void Promise.resolve(executor.close?.())
514
726
  .catch((err) => cliLog.warn({ err }, "executor close failed during scheduler shutdown"))
515
- .finally(resolve);
727
+ .finally(() => {
728
+ modelCatalog.close();
729
+ resolve();
730
+ });
516
731
  };
517
732
  process.once("SIGINT", shutdown);
518
733
  process.once("SIGTERM", shutdown);
@@ -560,19 +775,46 @@ async function serve(args) {
560
775
  }
561
776
  async function importCommand(rest) {
562
777
  const opts = parseImportArgs(rest);
563
- const { report, result } = await runImport({ ...opts, db: prisma, env: process.env });
564
- console.log(report);
565
- if (result) {
566
- for (const w of result.webhookSecrets)
567
- console.log(`webhook secret (${w.agentName}): ${w.secret}`);
778
+ // runImport builds an LLM provider and classifies each agent's model as
779
+ // routable/unroutable from currentModelCatalog() — without a store
780
+ // started here first, that falls back to the shipped catalog, so an
781
+ // admin-disabled model would be (wrongly) imported as routable and a
782
+ // DB-only custom model would be (wrongly) imported as disabled.
783
+ let modelCatalog;
784
+ try {
785
+ modelCatalog = await startModelCatalog(prisma);
786
+ }
787
+ catch (err) {
788
+ fail(err instanceof Error ? err.message : String(err));
789
+ }
790
+ try {
791
+ const { report, result } = await runImport({ ...opts, db: prisma, env: process.env });
792
+ console.log(report);
793
+ if (result) {
794
+ for (const w of result.webhookSecrets)
795
+ console.log(`webhook secret (${w.agentName}): ${w.secret}`);
796
+ }
797
+ }
798
+ finally {
799
+ modelCatalog.close();
568
800
  }
569
801
  }
570
802
  async function main() {
571
803
  const [command, ...rest] = process.argv.slice(2);
572
804
  try {
573
- if (command === "auth") {
805
+ if (command === "auth" && rest[0] === "host-account") {
806
+ // Both auth modes: keyed on Principal, not the self-hosted AuthUser.
807
+ await hostAccountCommand(rest.slice(1), prisma);
808
+ }
809
+ else if (command === "grants") {
810
+ await grantsCommand(rest, prisma);
811
+ }
812
+ else if (command === "auth") {
574
813
  await authCommand(rest, prisma, process.env.AUTH_CREDENTIAL_HASH_KEY ?? "");
575
814
  }
815
+ else if (command === "help") {
816
+ await helpCommand(rest);
817
+ }
576
818
  else if (command === "agent" && rest[0] === "create") {
577
819
  await agentCreate(rest.slice(1));
578
820
  }
@@ -591,6 +833,12 @@ async function main() {
591
833
  else if (command === "tool" && rest[0] === "detach") {
592
834
  await toolAttach(rest.slice(1), true);
593
835
  }
836
+ else if (command === "tool" && rest[0] === "update") {
837
+ await toolUpdate(rest.slice(1));
838
+ }
839
+ else if (command === "tool" && rest[0] === "delete") {
840
+ await toolDelete(rest.slice(1));
841
+ }
594
842
  else if (command === "tool" && rest[0] === "list") {
595
843
  await toolList(rest.slice(1));
596
844
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The coding workspace has no git metadata, so the worker cannot learn which
3
+ * commit it is looking at. The executor appends it to the task when it writes
4
+ * the worker input (after cloning). Never grows a task past the limit.
5
+ */
6
+ export declare function withBaseCommit(task: string, baseCommit: string): string;
@@ -0,0 +1,12 @@
1
+ import { byteLength, MAX_CODING_TASK_BYTES } from "./protocol.js";
2
+ /**
3
+ * The coding workspace has no git metadata, so the worker cannot learn which
4
+ * commit it is looking at. The executor appends it to the task when it writes
5
+ * the worker input (after cloning). Never grows a task past the limit.
6
+ */
7
+ export function withBaseCommit(task, baseCommit) {
8
+ if (!/^[0-9a-f]{40}$/.test(baseCommit))
9
+ return task;
10
+ const withLine = `${task}\n\nBase commit: ${baseCommit} (the commit this workspace was checked out at; the workspace has no git metadata).`;
11
+ return byteLength(withLine) <= MAX_CODING_TASK_BYTES ? withLine : task;
12
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Paths a coding run's workspace never sends back: dependency and cache folders
3
+ * (matched by name at any depth) plus per-agent repository-relative paths. The
4
+ * same set is rendered three ways so the Kubernetes keeper's tar, the Docker
5
+ * staging prune, and Git staging all agree on what "excluded" means.
6
+ */
7
+ export declare const BUILTIN_COLLECT_EXCLUDE_NAMES: readonly ["node_modules", ".venv", "venv", "__pycache__", ".pytest_cache", ".ruff_cache", ".mypy_cache", ".tox", ".vite", ".cache"];
8
+ export declare const MAX_COLLECT_EXCLUDE_PATHS = 64;
9
+ export interface CollectExclusions {
10
+ names: readonly string[];
11
+ paths: readonly string[];
12
+ }
13
+ export declare function validateCollectExcludePath(value: string): string;
14
+ export declare function collectExclusions(paths: readonly string[]): CollectExclusions;
15
+ /** For values read back from the database or a job record, which are untrusted shapes. */
16
+ export declare function normalizeCollectExclusions(value: unknown): CollectExclusions;
17
+ export declare function isCollectExcluded(relativePath: string, exclusions: CollectExclusions): boolean;
18
+ /**
19
+ * GNU tar options for `tar -C <workspace> -cf - .`, whose member names start with
20
+ * "./". Names are unanchored (they match any path component); paths are anchored
21
+ * to the archive root. An excluded directory's contents are skipped with it.
22
+ */
23
+ export declare function tarExcludeArgs(exclusions: CollectExclusions): string[];
24
+ /** Git exclude pathspecs, appended after ":/" when staging. */
25
+ export declare function gitExcludePathspecs(exclusions: CollectExclusions): string[];
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Paths a coding run's workspace never sends back: dependency and cache folders
3
+ * (matched by name at any depth) plus per-agent repository-relative paths. The
4
+ * same set is rendered three ways so the Kubernetes keeper's tar, the Docker
5
+ * staging prune, and Git staging all agree on what "excluded" means.
6
+ */
7
+ export const BUILTIN_COLLECT_EXCLUDE_NAMES = [
8
+ "node_modules",
9
+ ".venv",
10
+ "venv",
11
+ "__pycache__",
12
+ ".pytest_cache",
13
+ ".ruff_cache",
14
+ ".mypy_cache",
15
+ ".tox",
16
+ ".vite",
17
+ ".cache",
18
+ ];
19
+ export const MAX_COLLECT_EXCLUDE_PATHS = 64;
20
+ const MAX_PATH_BYTES = 512;
21
+ const CONTROL = /[\u0000-\u001F\u007F]/;
22
+ const GLOB = /[*?[\]]/;
23
+ export function validateCollectExcludePath(value) {
24
+ const path = value.trim();
25
+ const valid = path.length > 0 &&
26
+ Buffer.byteLength(path, "utf8") <= MAX_PATH_BYTES &&
27
+ !CONTROL.test(path) &&
28
+ !GLOB.test(path) &&
29
+ !path.includes("\\") &&
30
+ !path.startsWith("/") &&
31
+ !path.startsWith("./") &&
32
+ !path.split("/").some((part) => part === "" || part === "." || part === "..");
33
+ if (!valid)
34
+ throw new Error("collect_exclude_path_invalid");
35
+ return path;
36
+ }
37
+ export function collectExclusions(paths) {
38
+ if (paths.length > MAX_COLLECT_EXCLUDE_PATHS)
39
+ throw new Error("collect_exclude_path_invalid");
40
+ return { names: [...BUILTIN_COLLECT_EXCLUDE_NAMES], paths: [...new Set(paths.map(validateCollectExcludePath))] };
41
+ }
42
+ /** For values read back from the database or a job record, which are untrusted shapes. */
43
+ export function normalizeCollectExclusions(value) {
44
+ if (value === undefined || value === null)
45
+ return collectExclusions([]);
46
+ if (!Array.isArray(value) || !value.every((entry) => typeof entry === "string")) {
47
+ throw new Error("collect_exclude_invalid");
48
+ }
49
+ return collectExclusions(value);
50
+ }
51
+ export function isCollectExcluded(relativePath, exclusions) {
52
+ const segments = relativePath.split("/");
53
+ if (segments.some((segment) => exclusions.names.includes(segment)))
54
+ return true;
55
+ return exclusions.paths.some((path) => relativePath === path || relativePath.startsWith(`${path}/`));
56
+ }
57
+ /**
58
+ * GNU tar options for `tar -C <workspace> -cf - .`, whose member names start with
59
+ * "./". Names are unanchored (they match any path component); paths are anchored
60
+ * to the archive root. An excluded directory's contents are skipped with it.
61
+ */
62
+ export function tarExcludeArgs(exclusions) {
63
+ return [
64
+ "--no-anchored",
65
+ ...exclusions.names.map((name) => `--exclude=${name}`),
66
+ "--anchored",
67
+ ...exclusions.paths.map((path) => `--exclude=./${path}`),
68
+ ];
69
+ }
70
+ /** Git exclude pathspecs, appended after ":/" when staging. */
71
+ export function gitExcludePathspecs(exclusions) {
72
+ return [
73
+ ...exclusions.names.flatMap((name) => [`:(exclude,glob)**/${name}`, `:(exclude,glob)**/${name}/**`]),
74
+ ...exclusions.paths.map((path) => `:(exclude,literal)${path}`),
75
+ ];
76
+ }