stitchkit 0.94.0 → 0.94.1

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 (346) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/dist/agent-runtime/coding-shell-process.d.ts.map +1 -1
  3. package/dist/agent-runtime/coding-tool-listing.d.ts.map +1 -1
  4. package/dist/agent-runtime/coding-tool-search-patch.d.ts.map +1 -1
  5. package/dist/agent-runtime/contained-darwin.d.ts +38 -0
  6. package/dist/agent-runtime/contained-darwin.d.ts.map +1 -0
  7. package/dist/agent-runtime/contained-files.d.ts +11 -26
  8. package/dist/agent-runtime/contained-files.d.ts.map +1 -1
  9. package/dist/agent-runtime/contained-scan.d.ts +21 -0
  10. package/dist/agent-runtime/contained-scan.d.ts.map +1 -0
  11. package/dist/agent-runtime/contained-write.d.ts +9 -0
  12. package/dist/agent-runtime/contained-write.d.ts.map +1 -0
  13. package/dist/agent-runtime/deferred-tool-types.d.ts +3 -2
  14. package/dist/agent-runtime/deferred-tool-types.d.ts.map +1 -1
  15. package/dist/agent-runtime/harness-control.d.ts +0 -1
  16. package/dist/agent-runtime/harness-control.d.ts.map +1 -1
  17. package/dist/agent-runtime/harness.d.ts +0 -5
  18. package/dist/agent-runtime/harness.d.ts.map +1 -1
  19. package/dist/agent-runtime/managed-tools.d.ts +3 -2
  20. package/dist/agent-runtime/managed-tools.d.ts.map +1 -1
  21. package/dist/agent-runtime/runtime.d.ts +1 -1
  22. package/dist/agent-runtime/runtime.d.ts.map +1 -1
  23. package/dist/agent-runtime/schedule-records.d.ts +34 -0
  24. package/dist/agent-runtime/schedule-records.d.ts.map +1 -0
  25. package/dist/agent-runtime/schedules.d.ts +34 -0
  26. package/dist/agent-runtime/schedules.d.ts.map +1 -1
  27. package/dist/agent-runtime/store-conformance-lifecycle.d.ts +434 -0
  28. package/dist/agent-runtime/store-conformance-lifecycle.d.ts.map +1 -0
  29. package/dist/agent-runtime/store-conformance-ordering.d.ts +18 -0
  30. package/dist/agent-runtime/store-conformance-ordering.d.ts.map +1 -0
  31. package/dist/agent-runtime/store-conformance-support.d.ts +130 -0
  32. package/dist/agent-runtime/store-conformance-support.d.ts.map +1 -0
  33. package/dist/agent-runtime/store-conformance-terminal.d.ts +12 -0
  34. package/dist/agent-runtime/store-conformance-terminal.d.ts.map +1 -0
  35. package/dist/agent-runtime/store-conformance.d.ts.map +1 -1
  36. package/dist/application/admission-rate.d.ts +21 -0
  37. package/dist/application/admission-rate.d.ts.map +1 -0
  38. package/dist/application/admission-run.d.ts +8 -0
  39. package/dist/application/admission-run.d.ts.map +1 -0
  40. package/dist/application/admission.d.ts.map +1 -1
  41. package/dist/application/diagnostic-journal-lock.d.ts +9 -34
  42. package/dist/application/diagnostic-journal-lock.d.ts.map +1 -1
  43. package/dist/application/diagnostic-journal-manager.d.ts.map +1 -1
  44. package/dist/application/diagnostic-journal-storage.d.ts.map +1 -1
  45. package/dist/application/kernel-resource-context.d.ts.map +1 -1
  46. package/dist/application/notification-outbox.d.ts.map +1 -1
  47. package/dist/application/schedule.d.ts +0 -1
  48. package/dist/application/schedule.d.ts.map +1 -1
  49. package/dist/application/watch-hub-core.d.ts +122 -0
  50. package/dist/application/watch-hub-core.d.ts.map +1 -0
  51. package/dist/application/watch-hub.d.ts +2 -2
  52. package/dist/application/watch-hub.d.ts.map +1 -1
  53. package/dist/browser/client-executors.d.ts +14 -0
  54. package/dist/browser/client-executors.d.ts.map +1 -0
  55. package/dist/browser/client-multipart.d.ts +1 -1
  56. package/dist/browser/client-multipart.d.ts.map +1 -1
  57. package/dist/browser/client.d.ts +3 -2
  58. package/dist/browser/client.d.ts.map +1 -1
  59. package/dist/browser/http-fetch.d.ts +22 -0
  60. package/dist/browser/http-fetch.d.ts.map +1 -0
  61. package/dist/browser/http.d.ts +1 -3
  62. package/dist/browser/http.d.ts.map +1 -1
  63. package/dist/browser/live-state-core.d.ts +63 -0
  64. package/dist/browser/live-state-core.d.ts.map +1 -0
  65. package/dist/browser/live-state.d.ts.map +1 -1
  66. package/dist/browser/realtime-client.d.ts +26 -0
  67. package/dist/browser/realtime-client.d.ts.map +1 -0
  68. package/dist/browser/socket-io-connection.d.ts +82 -0
  69. package/dist/browser/socket-io-connection.d.ts.map +1 -0
  70. package/dist/browser/socket-io-peer.d.ts +20 -0
  71. package/dist/browser/socket-io-peer.d.ts.map +1 -0
  72. package/dist/browser/socket-io-trace.d.ts +31 -0
  73. package/dist/browser/socket-io-trace.d.ts.map +1 -0
  74. package/dist/browser/socket-io.d.ts +2 -18
  75. package/dist/browser/socket-io.d.ts.map +1 -1
  76. package/dist/contract/client-types.d.ts +134 -0
  77. package/dist/contract/client-types.d.ts.map +1 -0
  78. package/dist/contract/define-validation.d.ts +30 -0
  79. package/dist/contract/define-validation.d.ts.map +1 -0
  80. package/dist/contract/define.d.ts +3 -357
  81. package/dist/contract/define.d.ts.map +1 -1
  82. package/dist/contract/runtime-context.d.ts +131 -0
  83. package/dist/contract/runtime-context.d.ts.map +1 -0
  84. package/dist/contract/tool-options.d.ts +105 -0
  85. package/dist/contract/tool-options.d.ts.map +1 -0
  86. package/dist/contract/tool-view.d.ts +15 -2
  87. package/dist/contract/tool-view.d.ts.map +1 -1
  88. package/dist/durability/contract.d.ts +83 -0
  89. package/dist/durability/contract.d.ts.map +1 -1
  90. package/dist/durability/effect.d.ts +24 -0
  91. package/dist/durability/effect.d.ts.map +1 -0
  92. package/dist/durability/engine.d.ts +2 -2
  93. package/dist/durability/engine.d.ts.map +1 -1
  94. package/dist/durability/events.d.ts +2 -0
  95. package/dist/durability/events.d.ts.map +1 -1
  96. package/dist/durability/ledger.d.ts +11 -0
  97. package/dist/durability/ledger.d.ts.map +1 -1
  98. package/dist/durability/parks.d.ts +22 -0
  99. package/dist/durability/parks.d.ts.map +1 -0
  100. package/dist/durability/scheduler.d.ts +1 -0
  101. package/dist/durability/scheduler.d.ts.map +1 -1
  102. package/dist/entrypoints/agent-runtime/coding-tools.js +4 -4
  103. package/dist/entrypoints/agent-runtime/harness.js +127 -116
  104. package/dist/entrypoints/agent-runtime/sandbox.js +4 -4
  105. package/dist/entrypoints/agent-runtime/sqlite/bun.js +3 -3
  106. package/dist/entrypoints/agent-runtime/sqlite/node.js +3 -3
  107. package/dist/entrypoints/agent-runtime/testing.js +246 -214
  108. package/dist/entrypoints/agent-runtime.js +224 -203
  109. package/dist/entrypoints/application/diagnostic-journal.js +63 -203
  110. package/dist/entrypoints/application/opentelemetry.js +1 -1
  111. package/dist/entrypoints/application.js +361 -324
  112. package/dist/entrypoints/cli.d.ts +4 -1
  113. package/dist/entrypoints/cli.d.ts.map +1 -1
  114. package/dist/entrypoints/cli.js +57 -35
  115. package/dist/entrypoints/contract.d.ts +5 -2
  116. package/dist/entrypoints/contract.d.ts.map +1 -1
  117. package/dist/entrypoints/contract.js +3 -2
  118. package/dist/entrypoints/files.d.ts +2 -0
  119. package/dist/entrypoints/files.d.ts.map +1 -1
  120. package/dist/entrypoints/files.js +98 -2
  121. package/dist/entrypoints/index.d.ts +4 -2
  122. package/dist/entrypoints/index.d.ts.map +1 -1
  123. package/dist/entrypoints/index.js +348 -282
  124. package/dist/entrypoints/live.js +89 -71
  125. package/dist/entrypoints/node.d.ts +2 -1
  126. package/dist/entrypoints/node.d.ts.map +1 -1
  127. package/dist/entrypoints/node.js +13 -12
  128. package/dist/entrypoints/react.js +1 -1
  129. package/dist/entrypoints/remote.js +4 -4
  130. package/dist/entrypoints/server.d.ts +4 -2
  131. package/dist/entrypoints/server.d.ts.map +1 -1
  132. package/dist/entrypoints/server.js +293 -79
  133. package/dist/entrypoints/testing.d.ts +2 -1
  134. package/dist/entrypoints/testing.d.ts.map +1 -1
  135. package/dist/entrypoints/testing.js +288 -281
  136. package/dist/entrypoints/tools/connections.js +2 -2
  137. package/dist/entrypoints/tools/invoker.js +4 -4
  138. package/dist/entrypoints/tools.d.ts +6 -3
  139. package/dist/entrypoints/tools.d.ts.map +1 -1
  140. package/dist/entrypoints/tools.js +245 -202
  141. package/dist/entrypoints/tracking.js +325 -274
  142. package/dist/files/boundary.d.ts.map +1 -1
  143. package/dist/files/file-io.d.ts +14 -0
  144. package/dist/files/file-io.d.ts.map +1 -0
  145. package/dist/index-1j8pm5t0.js +412 -0
  146. package/dist/{index-kvj7f4hq.js → index-2bxbyab0.js} +10 -2
  147. package/dist/{index-xnj9bgxe.js → index-2gxzjvyr.js} +2 -162
  148. package/dist/index-4gcnakhx.js +82 -0
  149. package/dist/{index-j05z5gn4.js → index-55hkhm67.js} +136 -119
  150. package/dist/{index-cq4qfycf.js → index-79z7m7dt.js} +227 -59
  151. package/dist/{index-97ac4gph.js → index-7f68ghdn.js} +3 -3
  152. package/dist/{index-r7nmqpsg.js → index-7p1f0vp2.js} +1 -1
  153. package/dist/{index-dcpdvjsc.js → index-863ea9jb.js} +4 -4
  154. package/dist/index-8p52kd5p.js +242 -0
  155. package/dist/{index-2qzskm8h.js → index-dce5wxcq.js} +1 -1
  156. package/dist/index-e01r054k.js +105 -0
  157. package/dist/{index-sees8yf8.js → index-ensd0r74.js} +118 -111
  158. package/dist/{index-1nd48tm9.js → index-gxrt5h6v.js} +2 -1
  159. package/dist/{index-e87kakm4.js → index-ham5sz8m.js} +112 -110
  160. package/dist/{index-kj2wbeta.js → index-het2he5g.js} +280 -196
  161. package/dist/{index-vcvkq30w.js → index-hmp4800j.js} +3 -3
  162. package/dist/{index-gyr48nzg.js → index-k30h66yd.js} +71 -151
  163. package/dist/{index-2cr1cqhn.js → index-khtgb21r.js} +2 -2
  164. package/dist/{index-x4799c19.js → index-ndddxtyx.js} +11 -11
  165. package/dist/{index-dydjcp8z.js → index-np4m8hd3.js} +38 -36
  166. package/dist/{index-p81267c2.js → index-p3vsv1fb.js} +621 -357
  167. package/dist/{index-mp5sn43f.js → index-p9e0w8hs.js} +2 -2
  168. package/dist/{index-rewkc2hj.js → index-p9sh0xx4.js} +3 -3
  169. package/dist/{index-70yj2ebz.js → index-paz6sgdp.js} +107 -103
  170. package/dist/{index-bn2cjajt.js → index-px2gm2jp.js} +26 -102
  171. package/dist/index-s812ycat.js +65 -0
  172. package/dist/{index-xsqjkha9.js → index-sp1tzwnb.js} +2 -2
  173. package/dist/{index-n6hxg8as.js → index-t9rhjr9f.js} +615 -566
  174. package/dist/{index-zeemqhqx.js → index-v260df89.js} +88 -80
  175. package/dist/{index-fdp6hdxn.js → index-w906953s.js} +5 -1
  176. package/dist/{index-mdzh02yc.js → index-wdkt63w3.js} +1 -1
  177. package/dist/{index-58k4fp34.js → index-wsm5w4ee.js} +1 -1
  178. package/dist/{index-v38qyerb.js → index-xw3s75nj.js} +1 -1
  179. package/dist/internal/atomic-file.d.ts +23 -2
  180. package/dist/internal/atomic-file.d.ts.map +1 -1
  181. package/dist/internal/exclusive-lock.d.ts +51 -0
  182. package/dist/internal/exclusive-lock.d.ts.map +1 -0
  183. package/dist/internal/process-identity.d.ts +47 -0
  184. package/dist/internal/process-identity.d.ts.map +1 -0
  185. package/dist/internal/with-exclusive-lock.d.ts +67 -0
  186. package/dist/internal/with-exclusive-lock.d.ts.map +1 -0
  187. package/dist/live/watch-client.d.ts.map +1 -1
  188. package/dist/observability/audit.d.ts +2 -2
  189. package/dist/observability/audit.d.ts.map +1 -1
  190. package/dist/observability/event.d.ts +2 -1
  191. package/dist/observability/event.d.ts.map +1 -1
  192. package/dist/primitives/export-operation.d.ts +1 -1
  193. package/dist/primitives/export-operation.d.ts.map +1 -1
  194. package/dist/realtime/registry.d.ts +0 -5
  195. package/dist/realtime/registry.d.ts.map +1 -1
  196. package/dist/server/bun.d.ts +0 -1
  197. package/dist/server/bun.d.ts.map +1 -1
  198. package/dist/server/context-contribution.d.ts +1 -1
  199. package/dist/server/context-contribution.d.ts.map +1 -1
  200. package/dist/server/context.d.ts +1 -1
  201. package/dist/server/context.d.ts.map +1 -1
  202. package/dist/server/endpoint-response.d.ts +2 -1
  203. package/dist/server/endpoint-response.d.ts.map +1 -1
  204. package/dist/server/error-dispatch.d.ts +1 -1
  205. package/dist/server/error-dispatch.d.ts.map +1 -1
  206. package/dist/server/error-hook.d.ts +1 -1
  207. package/dist/server/error-hook.d.ts.map +1 -1
  208. package/dist/server/handler-state.d.ts +1 -1
  209. package/dist/server/handler-state.d.ts.map +1 -1
  210. package/dist/server/implement-registry.d.ts +54 -0
  211. package/dist/server/implement-registry.d.ts.map +1 -0
  212. package/dist/server/implement.d.ts +9 -55
  213. package/dist/server/implement.d.ts.map +1 -1
  214. package/dist/server/middleware/auth.d.ts +1 -31
  215. package/dist/server/middleware/auth.d.ts.map +1 -1
  216. package/dist/server/middleware/jwt.d.ts +31 -0
  217. package/dist/server/middleware/jwt.d.ts.map +1 -0
  218. package/dist/server/multipart-reader.d.ts +22 -0
  219. package/dist/server/multipart-reader.d.ts.map +1 -0
  220. package/dist/server/multipart.d.ts +1 -1
  221. package/dist/server/multipart.d.ts.map +1 -1
  222. package/dist/server/oauth/cimd.d.ts +88 -0
  223. package/dist/server/oauth/cimd.d.ts.map +1 -0
  224. package/dist/server/oauth/endpoints.d.ts +39 -0
  225. package/dist/server/oauth/endpoints.d.ts.map +1 -0
  226. package/dist/server/oauth/provider.d.ts +1 -68
  227. package/dist/server/oauth/provider.d.ts.map +1 -1
  228. package/dist/server/streaming-pump.d.ts +66 -0
  229. package/dist/server/streaming-pump.d.ts.map +1 -0
  230. package/dist/server/streaming-route.d.ts +12 -5
  231. package/dist/server/streaming-route.d.ts.map +1 -1
  232. package/dist/server/types.d.ts +4 -1
  233. package/dist/server/types.d.ts.map +1 -1
  234. package/dist/server/unix-client-bun.d.ts.map +1 -1
  235. package/dist/server/unix-client-http1.d.ts +76 -0
  236. package/dist/server/unix-client-http1.d.ts.map +1 -0
  237. package/dist/server/unix-client.d.ts.map +1 -1
  238. package/dist/testing/handler-clients.d.ts +2 -1
  239. package/dist/testing/handler-clients.d.ts.map +1 -1
  240. package/dist/testing/realtime-probe.d.ts +33 -0
  241. package/dist/testing/realtime-probe.d.ts.map +1 -0
  242. package/dist/testing/surface-conformance.d.ts +0 -31
  243. package/dist/testing/surface-conformance.d.ts.map +1 -1
  244. package/dist/testing/surface-manifest-digest.d.ts +44 -0
  245. package/dist/testing/surface-manifest-digest.d.ts.map +1 -0
  246. package/dist/testing/surface-manifest.d.ts.map +1 -1
  247. package/dist/tools/agent.d.ts +1 -1
  248. package/dist/tools/agent.d.ts.map +1 -1
  249. package/dist/tools/cli/args-fields.d.ts +31 -0
  250. package/dist/tools/cli/args-fields.d.ts.map +1 -0
  251. package/dist/tools/cli/args-route.d.ts +42 -0
  252. package/dist/tools/cli/args-route.d.ts.map +1 -0
  253. package/dist/tools/cli/args-view.d.ts +32 -0
  254. package/dist/tools/cli/args-view.d.ts.map +1 -0
  255. package/dist/tools/cli/args.d.ts +2 -65
  256. package/dist/tools/cli/args.d.ts.map +1 -1
  257. package/dist/tools/cli/argument-error.d.ts +5 -0
  258. package/dist/tools/cli/argument-error.d.ts.map +1 -0
  259. package/dist/tools/cli/checkpoint.d.ts.map +1 -1
  260. package/dist/tools/cli/command.d.ts +1 -1
  261. package/dist/tools/cli/command.d.ts.map +1 -1
  262. package/dist/tools/cli/config.d.ts +1 -1
  263. package/dist/tools/cli/config.d.ts.map +1 -1
  264. package/dist/tools/cli/format.d.ts +2 -1
  265. package/dist/tools/cli/format.d.ts.map +1 -1
  266. package/dist/tools/cli/invoke.d.ts +2 -1
  267. package/dist/tools/cli/invoke.d.ts.map +1 -1
  268. package/dist/tools/cli/managed-surface.d.ts +1 -1
  269. package/dist/tools/cli/managed-surface.d.ts.map +1 -1
  270. package/dist/tools/cli/policy.d.ts +1 -1
  271. package/dist/tools/cli/policy.d.ts.map +1 -1
  272. package/dist/tools/cli/prepare.d.ts.map +1 -1
  273. package/dist/tools/cli/run-managed.d.ts.map +1 -1
  274. package/dist/tools/cli/session.d.ts +1 -1
  275. package/dist/tools/cli/session.d.ts.map +1 -1
  276. package/dist/tools/cli/update.d.ts +19 -0
  277. package/dist/tools/cli/update.d.ts.map +1 -1
  278. package/dist/tools/cli/view.d.ts +1 -1
  279. package/dist/tools/cli/view.d.ts.map +1 -1
  280. package/dist/tools/cli/wait.d.ts +1 -1
  281. package/dist/tools/cli/wait.d.ts.map +1 -1
  282. package/dist/tools/connections/runtime.d.ts +1 -1
  283. package/dist/tools/connections/runtime.d.ts.map +1 -1
  284. package/dist/tools/execute-args.d.ts +23 -0
  285. package/dist/tools/execute-args.d.ts.map +1 -0
  286. package/dist/tools/execute-hooks.d.ts +146 -0
  287. package/dist/tools/execute-hooks.d.ts.map +1 -0
  288. package/dist/tools/execute-result.d.ts +40 -0
  289. package/dist/tools/execute-result.d.ts.map +1 -0
  290. package/dist/tools/execute.d.ts +4 -193
  291. package/dist/tools/execute.d.ts.map +1 -1
  292. package/dist/tools/internal/surface-projector.d.ts +2 -1
  293. package/dist/tools/internal/surface-projector.d.ts.map +1 -1
  294. package/dist/tools/invoker.d.ts +2 -1
  295. package/dist/tools/invoker.d.ts.map +1 -1
  296. package/dist/tools/lifecycle.d.ts +1 -1
  297. package/dist/tools/lifecycle.d.ts.map +1 -1
  298. package/dist/tools/mcp/mount.d.ts +1 -1
  299. package/dist/tools/mcp/mount.d.ts.map +1 -1
  300. package/dist/tools/mcp/prepare.d.ts +2 -1
  301. package/dist/tools/mcp/prepare.d.ts.map +1 -1
  302. package/dist/tools/mcp/progress.d.ts +1 -1
  303. package/dist/tools/mcp/progress.d.ts.map +1 -1
  304. package/dist/tools/mcp/register.d.ts +3 -2
  305. package/dist/tools/mcp/register.d.ts.map +1 -1
  306. package/dist/tools/mcp/round-context.d.ts +38 -0
  307. package/dist/tools/mcp/round-context.d.ts.map +1 -0
  308. package/dist/tools/mcp/round-policy.d.ts +1 -1
  309. package/dist/tools/mcp/round-policy.d.ts.map +1 -1
  310. package/dist/tools/mcp/round.d.ts +3 -11
  311. package/dist/tools/mcp/round.d.ts.map +1 -1
  312. package/dist/tools/mcp/runtime-tools.d.ts +2 -1
  313. package/dist/tools/mcp/runtime-tools.d.ts.map +1 -1
  314. package/dist/tools/mount.d.ts +3 -1
  315. package/dist/tools/mount.d.ts.map +1 -1
  316. package/dist/tools/native-definition.d.ts +2 -1
  317. package/dist/tools/native-definition.d.ts.map +1 -1
  318. package/dist/tools/operations/async-operation-runtime-tools.d.ts +2 -1
  319. package/dist/tools/operations/async-operation-runtime-tools.d.ts.map +1 -1
  320. package/dist/tools/operations/async-operation-runtime-types.d.ts +2 -1
  321. package/dist/tools/operations/async-operation-runtime-types.d.ts.map +1 -1
  322. package/dist/tools/remote.d.ts.map +1 -1
  323. package/dist/tools/runtime-tool.d.ts +3 -1
  324. package/dist/tools/runtime-tool.d.ts.map +1 -1
  325. package/dist/tools/tool-logger.d.ts +1 -1
  326. package/dist/tools/tool-logger.d.ts.map +1 -1
  327. package/dist/tracking/client-listeners.d.ts +30 -0
  328. package/dist/tracking/client-listeners.d.ts.map +1 -0
  329. package/dist/tracking/client-visit.d.ts +61 -0
  330. package/dist/tracking/client-visit.d.ts.map +1 -0
  331. package/dist/tracking/client.d.ts +3 -2
  332. package/dist/tracking/client.d.ts.map +1 -1
  333. package/llms/application.2.txt +266 -2
  334. package/llms/application.txt +8 -266
  335. package/llms/cli.2.txt +80 -0
  336. package/llms/cli.txt +45 -74
  337. package/llms/contract.txt +3 -3
  338. package/llms/files.txt +3 -0
  339. package/llms/tools.2.txt +88 -279
  340. package/llms/tools.3.txt +288 -0
  341. package/llms/tools.txt +27 -65
  342. package/llms-full.txt +108 -12
  343. package/llms.txt +5 -5
  344. package/package.json +1 -1
  345. package/dist/index-e2z3ahw9.js +0 -325
  346. package/dist/index-mkm15s49.js +0 -394
@@ -3,15 +3,15 @@ import {
3
3
  } from "./index-sbdmyz75.js";
4
4
  import {
5
5
  collectToolSurface
6
- } from "./index-vcvkq30w.js";
6
+ } from "./index-hmp4800j.js";
7
7
  import {
8
8
  createToolRunner,
9
9
  formatToolError
10
- } from "./index-2cr1cqhn.js";
10
+ } from "./index-khtgb21r.js";
11
11
  import {
12
12
  toolErrorFromResult,
13
13
  toolResultFromError
14
- } from "./index-j05z5gn4.js";
14
+ } from "./index-55hkhm67.js";
15
15
  import {
16
16
  coerceJsonArgs
17
17
  } from "./index-1zbbzgfh.js";
@@ -19,7 +19,7 @@ import {
19
19
  assertUniqueToolName,
20
20
  buildToolPresentationSchema,
21
21
  objectShapeKeys
22
- } from "./index-dydjcp8z.js";
22
+ } from "./index-np4m8hd3.js";
23
23
  import {
24
24
  jsonSchemaFields
25
25
  } from "./index-eqqvgdb3.js";
@@ -145,149 +145,13 @@ function emitResult(result, writers, opts) {
145
145
  return cliExitCode(result, opts.exitCodes);
146
146
  }
147
147
 
148
- // src/tools/cli/args.ts
149
- import { z } from "zod";
150
- var NUMERIC_VALUE = /^-(\d+\.?\d*|\.\d+)$/;
151
- var BOOL_OPTIONS = new Set(["json", "wait", "quiet", "dry-run", "help", "ascending"]);
152
- var VIEW_OPTIONS = new Set(["count-by", "sum", "by", "top", "table", "sort"]);
153
- var VALUE_OPTIONS = new Set(["wait-timeout", "output-dir", ...VIEW_OPTIONS]);
154
- var RESERVED_CLI_OPTIONS = new Set([...BOOL_OPTIONS, ...VALUE_OPTIONS]);
155
- function classifyLongOptionToken(token) {
156
- if (!token.startsWith("--") || token === "--")
157
- return;
158
- const equals = token.indexOf("=");
159
- const name = equals >= 0 ? token.slice(2, equals) : token.slice(2);
160
- return {
161
- name,
162
- value: equals >= 0 ? token.slice(equals + 1) : undefined,
163
- inline: equals >= 0,
164
- globalKind: BOOL_OPTIONS.has(name) ? "boolean" : VALUE_OPTIONS.has(name) ? "value" : undefined
165
- };
166
- }
167
- var HELP_TOKENS = new Set(["--help", "-h", "help"]);
168
- function helpFilterFrom(token, rest) {
169
- if (token?.startsWith("--help=")) {
170
- const value = token.slice("--help=".length).trim();
171
- if (value.length === 0 || isReservedBoolWord(value))
172
- return;
173
- return value;
174
- }
175
- if (token === undefined || !HELP_TOKENS.has(token))
176
- return;
177
- const next = rest[0];
178
- return next !== undefined && !next.startsWith("-") ? next : undefined;
179
- }
180
- function routeCliArgv(argv, defaultCommand) {
181
- if (defaultCommand === undefined) {
182
- const [command, ...commandArgv] = argv;
183
- const helpFilter = helpFilterFrom(command, commandArgv);
184
- return {
185
- command,
186
- commandArgv,
187
- topLevelHelp: false,
188
- version: false,
189
- ...helpFilter !== undefined && { helpFilter }
190
- };
191
- }
192
- const globals = [];
193
- let index = 0;
194
- while (index < argv.length) {
195
- const token = argv[index];
196
- if (token === undefined)
197
- break;
198
- if (token === "--") {
199
- return {
200
- commandArgv: [],
201
- topLevelHelp: false,
202
- version: false,
203
- error: 'A command is required before "--"'
204
- };
205
- }
206
- const inlineHelpFilter = token.startsWith("--help=") && !isReservedBoolWord(token.slice("--help=".length));
207
- if (token === "--help" || token === "-h" || inlineHelpFilter) {
208
- const helpFilter = helpFilterFrom(token, argv.slice(index + 1));
209
- return {
210
- commandArgv: [],
211
- topLevelHelp: true,
212
- version: false,
213
- ...helpFilter !== undefined && { helpFilter }
214
- };
215
- }
216
- if (token === "--version" || token === "version") {
217
- return { commandArgv: [], topLevelHelp: false, version: true };
218
- }
219
- if (!token.startsWith("-") || token === "-") {
220
- return {
221
- command: token,
222
- commandArgv: [...globals, ...argv.slice(index + 1)],
223
- topLevelHelp: false,
224
- version: false
225
- };
226
- }
227
- if (!token.startsWith("--")) {
228
- return {
229
- command: defaultCommand,
230
- commandArgv: [...globals, ...argv.slice(index)],
231
- topLevelHelp: false,
232
- version: false
233
- };
234
- }
235
- const option = classifyLongOptionToken(token);
236
- if (!option) {
237
- return {
238
- command: defaultCommand,
239
- commandArgv: [...globals, ...argv.slice(index)],
240
- topLevelHelp: false,
241
- version: false
242
- };
243
- }
244
- if (option.globalKind === "boolean") {
245
- globals.push(token);
246
- index += 1;
247
- continue;
248
- }
249
- if (option.globalKind === "value") {
250
- globals.push(token);
251
- if (!option.inline) {
252
- const value = argv[index + 1];
253
- if (value === "--help" || value === "-h") {
254
- const helpFilter = helpFilterFrom(value, argv.slice(index + 2));
255
- return {
256
- commandArgv: [],
257
- topLevelHelp: true,
258
- version: false,
259
- ...helpFilter !== undefined && { helpFilter }
260
- };
261
- }
262
- if (value === "--version" || value === "version") {
263
- return { commandArgv: [], topLevelHelp: false, version: true };
264
- }
265
- if (value !== undefined)
266
- globals.push(value);
267
- index += value === undefined ? 1 : 2;
268
- } else {
269
- index += 1;
270
- }
271
- continue;
272
- }
273
- return {
274
- command: defaultCommand,
275
- commandArgv: [...globals, ...argv.slice(index)],
276
- topLevelHelp: false,
277
- version: false
278
- };
279
- }
280
- return {
281
- command: defaultCommand,
282
- commandArgv: globals,
283
- topLevelHelp: false,
284
- version: false
285
- };
286
- }
287
-
148
+ // src/tools/cli/argument-error.ts
288
149
  class CliArgumentError extends Error {
289
150
  name = "CliArgumentError";
290
151
  }
152
+
153
+ // src/tools/cli/args-fields.ts
154
+ import { z } from "zod";
291
155
  function unwrap(field) {
292
156
  if (field instanceof z.ZodOptional || field instanceof z.ZodNullable || field instanceof z.ZodDefault) {
293
157
  return unwrap(field.unwrap());
@@ -334,9 +198,15 @@ function collectSchemaFields(schema, fields) {
334
198
  const fieldBase = unwrap(raw);
335
199
  const kind = classify(fieldBase);
336
200
  if (kind === "array" && fieldBase instanceof z.ZodArray) {
337
- mergeField(fields, name, { kind, elementKind: classify(unwrap(fieldBase.element)) });
201
+ mergeField(fields, name, {
202
+ kind,
203
+ elementKind: classify(unwrap(fieldBase.element))
204
+ });
338
205
  } else {
339
- mergeField(fields, name, { kind });
206
+ mergeField(fields, name, {
207
+ kind,
208
+ ...fieldBase instanceof z.ZodNumber && fieldBase.isInt && { integer: true }
209
+ });
340
210
  }
341
211
  }
342
212
  return;
@@ -412,18 +282,38 @@ function looksLikeJson(value) {
412
282
  const t = value.trim();
413
283
  return t.startsWith("[") || t.startsWith("{");
414
284
  }
415
- function coerceField(info, values) {
285
+ function expectedValue(kind, integer) {
286
+ if (kind === "number")
287
+ return integer ? "a whole number" : "a number";
288
+ if (kind === "bigint")
289
+ return "a whole number";
290
+ if (kind === "date")
291
+ return "a date";
292
+ return;
293
+ }
294
+ function coerceNamed(label, kind, integer, value) {
295
+ const coerced = coerceScalar(kind, value);
296
+ const expected = expectedValue(kind, integer);
297
+ if (expected !== undefined && typeof coerced === "string") {
298
+ throw new CliArgumentError(`${label} expects ${expected}, got "${value}"`);
299
+ }
300
+ if (integer && typeof coerced === "number" && !Number.isInteger(coerced)) {
301
+ throw new CliArgumentError(`${label} expects ${expected}, got "${value}"`);
302
+ }
303
+ return coerced;
304
+ }
305
+ function coerceField(info, values, label) {
416
306
  const last = values[values.length - 1] ?? "";
417
307
  if (!info)
418
308
  return values.length > 1 ? values : last;
419
309
  if (info.kind === "array") {
420
310
  if (values.length === 1 && looksLikeJson(last))
421
311
  return last;
422
- return values.map((v) => coerceScalar(info.elementKind ?? "string", v));
312
+ return values.map((v) => coerceNamed(label, info.elementKind ?? "string", false, v));
423
313
  }
424
314
  if (info.kind === "object")
425
315
  return last;
426
- return coerceScalar(info.kind, last);
316
+ return coerceNamed(label, info.kind, info.integer, last);
427
317
  }
428
318
  function setNested(target, path, value) {
429
319
  const unsafe = path.find(isUnsafeKey);
@@ -448,253 +338,365 @@ function setNested(target, path, value) {
448
338
  if (leaf !== undefined)
449
339
  node[leaf] = value;
450
340
  }
451
- function parseCliArgs(argv, schema, config = {}) {
452
- const options = {
453
- json: false,
454
- wait: false,
455
- quiet: false,
456
- dryRun: false,
457
- help: false
458
- };
459
- const fields = describeSchemaFields(schema);
460
- for (const name of config.knownFields ?? []) {
461
- if (!fields.has(name))
462
- fields.set(name, { kind: "other" });
341
+
342
+ // src/tools/cli/policy.ts
343
+ var SHORT_ALIAS = /^[A-Za-z]$/;
344
+ var RESERVED_SHORT_OPTIONS = new Set(["h"]);
345
+ function fieldMap(descriptor) {
346
+ return new Map(jsonSchemaFields(descriptor.presentationSchema).map((field) => [field.name, field]));
347
+ }
348
+ function resolveAliases(command, descriptor, configured) {
349
+ if (!configured)
350
+ return new Map;
351
+ const fields = fieldMap(descriptor);
352
+ const aliases = new Map;
353
+ for (const [alias, target] of Object.entries(configured)) {
354
+ if (!SHORT_ALIAS.test(alias)) {
355
+ throw new Error(`[stitchkit] CLI command "${command}" alias "${alias}" must be one ASCII letter`);
356
+ }
357
+ if (RESERVED_SHORT_OPTIONS.has(alias)) {
358
+ throw new Error(`[stitchkit] CLI command "${command}" alias "-${alias}" is reserved`);
359
+ }
360
+ if (isUnsafeKey(target) || !fields.has(target)) {
361
+ throw new Error(`[stitchkit] CLI command "${command}" alias "-${alias}" targets unknown field "${target}"`);
362
+ }
363
+ const existing = aliases.get(target);
364
+ if (existing !== undefined) {
365
+ throw new Error(`[stitchkit] CLI command "${command}" field "${target}" has multiple aliases: -${existing}, -${alias}`);
366
+ }
367
+ aliases.set(target, alias);
463
368
  }
464
- const flags = new Map;
465
- const boolFlags = new Map;
466
- const viewFlags = new Map;
467
- let ascending = false;
468
- const positionals = [];
469
- const pushFlag = (name, value) => {
470
- const existing = flags.get(name);
471
- if (existing)
472
- existing.push(value);
473
- else
474
- flags.set(name, [value]);
475
- };
476
- let optionsEnded = false;
477
- for (let i = 0;i < argv.length; i++) {
478
- const tok = argv[i];
479
- if (tok === undefined)
480
- continue;
481
- if (!optionsEnded && tok === "--") {
482
- optionsEnded = true;
483
- continue;
369
+ return aliases;
370
+ }
371
+ function resolvePositionals(command, descriptor, configured) {
372
+ if (configured === undefined)
373
+ return;
374
+ const fields = fieldMap(descriptor);
375
+ const kinds = describeSchemaFields(descriptor.argumentSchema);
376
+ const seen = new Set;
377
+ let optionalSeen = false;
378
+ for (const name of configured) {
379
+ const field = fields.get(name);
380
+ if (isUnsafeKey(name) || !field || !kinds.has(name)) {
381
+ throw new Error(`[stitchkit] CLI command "${command}" positional targets unknown field "${name}"`);
484
382
  }
485
- if (optionsEnded || !tok.startsWith("-") || tok === "-") {
486
- positionals.push(tok);
487
- continue;
383
+ if (seen.has(name)) {
384
+ throw new Error(`[stitchkit] CLI command "${command}" repeats positional field "${name}"`);
488
385
  }
489
- if (tok === "-h") {
490
- options.help = true;
491
- continue;
386
+ if (kinds.get(name)?.kind === "boolean") {
387
+ throw new Error(`[stitchkit] CLI command "${command}" boolean field "${name}" cannot be positional`);
492
388
  }
493
- if (!tok.startsWith("--")) {
494
- const match = /^-([A-Za-z])(?:=(.*))?$/.exec(tok);
495
- const alias = match?.[1];
496
- const field = alias === undefined ? undefined : config.optionAliases?.get(alias);
497
- if (!alias || !field)
498
- throw new CliArgumentError(`Unknown option "${tok}"`);
499
- const inline = match?.[2];
500
- const info2 = fields.get(field);
501
- if (info2?.kind === "boolean") {
502
- boolFlags.set(field, inline === undefined ? true : parseReservedBool(field, inline));
503
- continue;
504
- }
505
- let value2 = inline;
506
- if (value2 === undefined) {
507
- const next = argv[i + 1];
508
- if (next !== undefined && (!next.startsWith("-") || NUMERIC_VALUE.test(next))) {
509
- value2 = next;
510
- i++;
511
- } else {
512
- throw new CliArgumentError(`--${field} requires a value`);
513
- }
514
- }
515
- pushFlag(field, value2);
516
- continue;
389
+ if (optionalSeen && field.required) {
390
+ throw new Error(`[stitchkit] CLI command "${command}" required positional "${name}" cannot follow an optional positional`);
517
391
  }
518
- const option = classifyLongOptionToken(tok);
519
- if (!option)
520
- throw new CliArgumentError(`Unknown option "${tok}"`);
521
- const { name } = option;
522
- let { value } = option;
523
- if (name.length === 0)
524
- throw new CliArgumentError("Invalid empty option name");
525
- if (option.globalKind === "boolean") {
526
- const enabled = value === undefined ? true : parseReservedBool(name, value);
527
- if (name === "dry-run")
528
- options.dryRun = enabled;
529
- else if (name === "json")
530
- options.json = enabled;
531
- else if (name === "wait")
532
- options.wait = enabled;
533
- else if (name === "quiet")
534
- options.quiet = enabled;
535
- else if (name === "ascending")
536
- ascending = enabled;
537
- else
538
- options.help = enabled;
539
- continue;
540
- }
541
- if (option.globalKind === "value") {
542
- const next = argv[i + 1];
543
- value = value ?? next;
544
- if (value === undefined || value.startsWith("-") && !NUMERIC_VALUE.test(value)) {
545
- throw new CliArgumentError(`--${name} requires a value`);
546
- }
547
- if (!option.inline)
548
- i++;
549
- if (name === "wait-timeout") {
550
- const timeout = Number(value);
551
- if (!Number.isFinite(timeout) || timeout <= 0) {
552
- throw new CliArgumentError("--wait-timeout must be a positive number");
553
- }
554
- options.waitTimeout = timeout;
555
- } else if (VIEW_OPTIONS.has(name)) {
556
- if (viewFlags.has(name))
557
- throw new CliArgumentError(`--${name} was given twice`);
558
- viewFlags.set(name, value);
559
- } else {
560
- options.outputDir = value;
561
- }
562
- continue;
563
- }
564
- if (value === undefined && name.startsWith("no-") && fields.get(name.slice(3))?.kind === "boolean") {
565
- boolFlags.set(name.slice(3), false);
566
- continue;
567
- }
568
- const unsafeSegment = name.split(".").find(isUnsafeKey);
569
- if (unsafeSegment !== undefined) {
570
- throw new CliArgumentError(`Unsafe option name "--${name}"`);
392
+ if (!field.required)
393
+ optionalSeen = true;
394
+ seen.add(name);
395
+ }
396
+ return [...configured];
397
+ }
398
+ function applyCliPresentationPolicy(command, descriptor, config) {
399
+ const base = { ...descriptor, aliases: new Map };
400
+ const configuredAliases = config.optionAliases && Object.hasOwn(config.optionAliases, command) ? config.optionAliases[command] : undefined;
401
+ const configuredPositionals = config.positionals && Object.hasOwn(config.positionals, command) ? config.positionals[command] : undefined;
402
+ return {
403
+ ...base,
404
+ aliases: resolveAliases(command, base, configuredAliases),
405
+ positionals: resolvePositionals(command, base, configuredPositionals)
406
+ };
407
+ }
408
+ function assertCliPoliciesResolved(commands, config) {
409
+ const configuredNames = new Set([
410
+ ...Object.keys(config.optionAliases ?? {}),
411
+ ...Object.keys(config.positionals ?? {})
412
+ ]);
413
+ if (config.defaultCommand !== undefined)
414
+ configuredNames.add(config.defaultCommand);
415
+ for (const name of configuredNames) {
416
+ if (!commands.has(name)) {
417
+ throw new Error(`[stitchkit] CLI policy targets unavailable command "${name}"`);
571
418
  }
572
- const info = fields.get(name);
573
- const rootName = name.split(".")[0] ?? name;
574
- if (!fields.has(rootName) && !config.allowUnknown) {
575
- throw new CliArgumentError(`Unknown option "--${name}"`);
419
+ }
420
+ }
421
+
422
+ // src/tools/cli/invoke.ts
423
+ function parseCliGlobals(schema, globals) {
424
+ if (!schema)
425
+ return globals ?? {};
426
+ return schema.parse(globals ?? {});
427
+ }
428
+ function cliInvocationResult(result, toolName, config) {
429
+ if (result.ok)
430
+ return { ok: true, exitCode: 0, data: result.data };
431
+ const normalized = toolErrorFromResult(result);
432
+ const hints = [];
433
+ if (result.hint)
434
+ hints.push(result.hint);
435
+ const global = config.errorHint?.(toolName, result.code);
436
+ if (global)
437
+ hints.push(global);
438
+ return {
439
+ ok: false,
440
+ exitCode: cliExitCode(result, config.exitCodes),
441
+ error: {
442
+ code: result.code,
443
+ message: normalized.message,
444
+ ...result.details !== undefined && { details: result.details },
445
+ ...hints.length > 0 && { hint: hints.join(" ") },
446
+ ...result.retryable !== undefined && { retryable: result.retryable }
576
447
  }
577
- if (value === undefined) {
578
- if (info?.kind === "boolean") {
579
- boolFlags.set(name, true);
580
- continue;
448
+ };
449
+ }
450
+ async function createCliInvoker(config, globals) {
451
+ const typedGlobals = parseCliGlobals(config.globalOptions, globals);
452
+ const auth = await (config.resolveAuth ? config.resolveAuth(typedGlobals) : config.auth);
453
+ const natives = new Map((config.commands ?? []).filter(cliCommandReturnsResult).map((definition) => [definition.name, definition]));
454
+ const nativeHelp = new Map([...natives].map(([name, definition]) => [
455
+ name,
456
+ { description: definition.description, argumentSchema: {}, presentationSchema: {} }
457
+ ]));
458
+ const { tools, help } = buildCliSurface(config, auth, new Map, new Set);
459
+ const runTool = createToolRunner({
460
+ source: "cli",
461
+ toolSurface: true,
462
+ context: { ...config.context?.(auth, typedGlobals), signal: config.signal },
463
+ hooks: config.hooks,
464
+ lifecycle: config.lifecycle,
465
+ coerceJsonArgs: config.coerceJsonArgs
466
+ });
467
+ return {
468
+ commands: [...nativeHelp, ...help].map(([name, presentation]) => ({
469
+ name,
470
+ description: presentation.description
471
+ })),
472
+ invoke: async (command, args) => {
473
+ const native = natives.get(command);
474
+ if (native)
475
+ return runNativeCommand(native, args, config, typedGlobals);
476
+ const tool = tools.get(command);
477
+ if (!tool) {
478
+ return cliInvocationResult({
479
+ ok: false,
480
+ code: "NOT_FOUND",
481
+ details: { message: `Unknown command "${command}"` }
482
+ }, command, config);
581
483
  }
582
- const next = argv[i + 1];
583
- if (next !== undefined && (!next.startsWith("-") || NUMERIC_VALUE.test(next))) {
584
- value = next;
585
- i++;
586
- } else {
587
- throw new CliArgumentError(`--${name} requires a value`);
484
+ let result;
485
+ try {
486
+ result = await runTool(tool, args);
487
+ } catch (error) {
488
+ result = toolResultFromError(error);
588
489
  }
490
+ return cliInvocationResult(result, command, config);
589
491
  }
590
- pushFlag(name, value);
591
- }
592
- const view = resolveCliView(viewFlags, ascending);
593
- if (view)
594
- options.view = view;
595
- const toolArgs = {};
596
- const fillable = config.positionals === undefined ? [...fields.entries()].filter(([, info]) => info.kind !== "boolean").map(([name]) => name) : [...config.positionals];
597
- const variadicTail = config.positionals !== undefined && fields.get(fillable[fillable.length - 1] ?? "")?.kind === "array" ? fillable[fillable.length - 1] : undefined;
598
- let pi = 0;
599
- for (const key of fillable) {
600
- if (pi >= positionals.length)
601
- break;
602
- if (key === variadicTail) {
603
- if (flags.has(key)) {
604
- throw new CliArgumentError(`--${key} conflicts with the positional values for "${key}" — pass one form, not both`);
605
- }
606
- toolArgs[key] = coerceField(fields.get(key), positionals.slice(pi));
607
- pi = positionals.length;
608
- break;
492
+ };
493
+ }
494
+ var IN_PROCESS_RUN_OPTIONS = Object.freeze({
495
+ json: false,
496
+ wait: false,
497
+ quiet: true,
498
+ dryRun: false,
499
+ help: false
500
+ });
501
+ async function runNativeCommand(definition, args, config, globals) {
502
+ let out = "";
503
+ let err = "";
504
+ const result = await executeCliCommand(definition, args, IN_PROCESS_RUN_OPTIONS, {
505
+ stdout: (text) => {
506
+ out += text;
507
+ },
508
+ stderr: (text) => {
509
+ err += text;
510
+ }
511
+ }, config.coerceJsonArgs ?? true, globals);
512
+ let invocation = cliInvocationResult(result, definition.name, config);
513
+ if (invocation.ok) {
514
+ try {
515
+ invocation = {
516
+ ...invocation,
517
+ exitCode: cliCommandSuccessExitCode(definition, result.ok ? result.data : undefined)
518
+ };
519
+ } catch (error) {
520
+ invocation = cliInvocationResult(toolResultFromError(error), definition.name, config);
609
521
  }
610
- if (flags.has(key))
611
- continue;
612
- const value = positionals[pi++];
613
- if (value !== undefined)
614
- toolArgs[key] = coerceField(fields.get(key), [value]);
615
522
  }
616
- if (pi < positionals.length) {
617
- throw new CliArgumentError(`Unexpected positional argument "${positionals[pi]}"`);
523
+ if (out === "" && err === "")
524
+ return invocation;
525
+ return {
526
+ ...invocation,
527
+ written: { ...out !== "" && { stdout: out }, ...err !== "" && { stderr: err } }
528
+ };
529
+ }
530
+ function buildCliSurface(config, auth, nativeHelp, applicationGlobalNames, assertShape) {
531
+ const services = typeof config.services === "function" ? config.services(auth) : config.services ?? [];
532
+ const runtimeTools = typeof config.runtimeTools === "function" ? config.runtimeTools(auth) : config.runtimeTools ?? [];
533
+ const tools = new Map;
534
+ const help = new Map(nativeHelp);
535
+ for (const { mountable } of collectToolSurface({
536
+ surface: { services, runtimeTools },
537
+ transport: "CLI"
538
+ })) {
539
+ const descriptor = applyCliPresentationPolicy(mountable.name, managedCliDescriptor(mountable), config);
540
+ assertShape?.(mountable.name, descriptor, help.has(mountable.name), config.passthrough?.[mountable.name], applicationGlobalNames);
541
+ tools.set(mountable.name, mountable);
542
+ help.set(mountable.name, descriptor);
618
543
  }
619
- for (const [key, value] of boolFlags) {
620
- toolArgs[key] = value;
544
+ assertCliPoliciesResolved(help, config);
545
+ return { tools, help };
546
+ }
547
+ function managedCliDescriptor(tool) {
548
+ return {
549
+ description: tool.method.desc,
550
+ argumentSchema: tool.argumentSchema,
551
+ presentationSchema: tool.presentationSchema
552
+ };
553
+ }
554
+
555
+ // src/tools/cli/args-route.ts
556
+ function isOptionToken(token) {
557
+ return token.startsWith("--") || /^-[A-Za-z](?:=|$)/.test(token);
558
+ }
559
+ function looksLikeOption(token) {
560
+ return token.startsWith("--") || /^-[A-Za-z]/.test(token);
561
+ }
562
+ var BOOL_OPTIONS = new Set(["json", "wait", "quiet", "dry-run", "help", "ascending"]);
563
+ var VIEW_OPTIONS = new Set(["count-by", "sum", "by", "top", "table", "sort"]);
564
+ var VALUE_OPTIONS = new Set(["wait-timeout", "output-dir", ...VIEW_OPTIONS]);
565
+ var RESERVED_CLI_OPTIONS = new Set([...BOOL_OPTIONS, ...VALUE_OPTIONS]);
566
+ function classifyLongOptionToken(token) {
567
+ if (!token.startsWith("--") || token === "--")
568
+ return;
569
+ const equals = token.indexOf("=");
570
+ const name = equals >= 0 ? token.slice(2, equals) : token.slice(2);
571
+ return {
572
+ name,
573
+ value: equals >= 0 ? token.slice(equals + 1) : undefined,
574
+ inline: equals >= 0,
575
+ globalKind: BOOL_OPTIONS.has(name) ? "boolean" : VALUE_OPTIONS.has(name) ? "value" : undefined
576
+ };
577
+ }
578
+ var HELP_TOKENS = new Set(["--help", "-h", "help"]);
579
+ function helpFilterFrom(token, rest) {
580
+ if (token?.startsWith("--help=")) {
581
+ const value = token.slice("--help=".length).trim();
582
+ if (value.length === 0 || isReservedBoolWord(value))
583
+ return;
584
+ return value;
621
585
  }
622
- const dottedRoots = new Map;
623
- for (const key of flags.keys()) {
624
- const dot = key.indexOf(".");
625
- if (dot > 0)
626
- dottedRoots.set(key.slice(0, dot), key);
586
+ if (token === undefined || !HELP_TOKENS.has(token))
587
+ return;
588
+ const next = rest[0];
589
+ return next !== undefined && !next.startsWith("-") ? next : undefined;
590
+ }
591
+ function routeCliArgv(argv, defaultCommand) {
592
+ if (defaultCommand === undefined) {
593
+ const [command, ...commandArgv] = argv;
594
+ const helpFilter = helpFilterFrom(command, commandArgv);
595
+ return {
596
+ command,
597
+ commandArgv,
598
+ topLevelHelp: false,
599
+ version: false,
600
+ ...helpFilter !== undefined && { helpFilter }
601
+ };
627
602
  }
628
- for (const [root, dotted] of dottedRoots) {
629
- if (flags.has(root)) {
630
- throw new CliArgumentError(`--${root} conflicts with --${dotted} — pass one form, not both`);
603
+ const globals = [];
604
+ let index = 0;
605
+ while (index < argv.length) {
606
+ const token = argv[index];
607
+ if (token === undefined)
608
+ break;
609
+ if (token === "--") {
610
+ return {
611
+ commandArgv: [],
612
+ topLevelHelp: false,
613
+ version: false,
614
+ error: 'A command is required before "--"'
615
+ };
631
616
  }
632
- }
633
- for (const [key, values] of flags) {
634
- if (key.includes(".")) {
635
- if (values.length > 1) {
636
- throw new CliArgumentError(`--${key} was passed ${values.length} times`);
637
- }
638
- setNested(toolArgs, key.split("."), looseCoerce(values[0] ?? ""));
639
- continue;
617
+ const inlineHelpFilter = token.startsWith("--help=") && !isReservedBoolWord(token.slice("--help=".length));
618
+ if (token === "--help" || token === "-h" || inlineHelpFilter) {
619
+ const helpFilter = helpFilterFrom(token, argv.slice(index + 1));
620
+ return {
621
+ commandArgv: [],
622
+ topLevelHelp: true,
623
+ version: false,
624
+ ...helpFilter !== undefined && { helpFilter }
625
+ };
626
+ }
627
+ if (token === "--version" || token === "version") {
628
+ return { commandArgv: [], topLevelHelp: false, version: true };
629
+ }
630
+ if (!token.startsWith("-") || token === "-") {
631
+ return {
632
+ command: token,
633
+ commandArgv: [...globals, ...argv.slice(index + 1)],
634
+ topLevelHelp: false,
635
+ version: false
636
+ };
640
637
  }
641
- const info = fields.get(key);
642
- if (values.length > 1 && info !== undefined && info.kind !== "array" && info.kind !== "other") {
643
- throw new CliArgumentError(`--${key} was passed ${values.length} times`);
638
+ if (!token.startsWith("--")) {
639
+ return {
640
+ command: defaultCommand,
641
+ commandArgv: [...globals, ...argv.slice(index)],
642
+ topLevelHelp: false,
643
+ version: false
644
+ };
644
645
  }
645
- toolArgs[key] = coerceField(info, values);
646
- }
647
- return { toolArgs, options };
648
- }
649
- function extractCliGlobalOptions(argv, schema) {
650
- if (schema === undefined)
651
- return { argv: [...argv], globals: {} };
652
- const fields = describeSchemaFields(schema);
653
- const rest = [];
654
- const raw = new Map;
655
- let ended = false;
656
- for (let i = 0;i < argv.length; i++) {
657
- const token = argv[i];
658
- if (token === undefined)
659
- continue;
660
- if (!ended && token === "--")
661
- ended = true;
662
- const option = ended ? undefined : classifyLongOptionToken(token);
663
- const info = option && option.globalKind === undefined ? fields.get(option.name) : undefined;
664
- if (!option || !info) {
665
- rest.push(token);
646
+ const option = classifyLongOptionToken(token);
647
+ if (!option) {
648
+ return {
649
+ command: defaultCommand,
650
+ commandArgv: [...globals, ...argv.slice(index)],
651
+ topLevelHelp: false,
652
+ version: false
653
+ };
654
+ }
655
+ if (option.globalKind === "boolean") {
656
+ globals.push(token);
657
+ index += 1;
666
658
  continue;
667
659
  }
668
- let { value } = option;
669
- if (value === undefined && info.kind === "boolean") {
670
- value = "true";
671
- } else if (value === undefined) {
672
- const next = argv[i + 1];
673
- if (next !== undefined && (!next.startsWith("-") || NUMERIC_VALUE.test(next))) {
674
- value = next;
675
- i++;
660
+ if (option.globalKind === "value") {
661
+ globals.push(token);
662
+ if (!option.inline) {
663
+ const value = argv[index + 1];
664
+ if (value === "--help" || value === "-h") {
665
+ const helpFilter = helpFilterFrom(value, argv.slice(index + 2));
666
+ return {
667
+ commandArgv: [],
668
+ topLevelHelp: true,
669
+ version: false,
670
+ ...helpFilter !== undefined && { helpFilter }
671
+ };
672
+ }
673
+ if (value === "--version" || value === "version") {
674
+ return { commandArgv: [], topLevelHelp: false, version: true };
675
+ }
676
+ if (value !== undefined)
677
+ globals.push(value);
678
+ index += value === undefined ? 1 : 2;
676
679
  } else {
677
- throw new CliArgumentError(`--${option.name} requires a value`);
680
+ index += 1;
678
681
  }
682
+ continue;
679
683
  }
680
- const existing = raw.get(option.name);
681
- if (existing)
682
- existing.push(value);
683
- else
684
- raw.set(option.name, [value]);
685
- }
686
- const args = {};
687
- for (const [name, values] of raw)
688
- args[name] = coerceField(fields.get(name), values);
689
- const parsed = schema.safeParse(coerceJsonArgs(args, schema));
690
- if (!parsed.success) {
691
- const issue = parsed.error.issues[0];
692
- const field = issue?.path[0];
693
- const where = typeof field === "string" ? `--${field}` : "application option";
694
- throw new CliArgumentError(`${where}: ${issue?.message ?? "invalid value"}`);
684
+ return {
685
+ command: defaultCommand,
686
+ commandArgv: [...globals, ...argv.slice(index)],
687
+ topLevelHelp: false,
688
+ version: false
689
+ };
695
690
  }
696
- return { argv: rest, globals: parsed.data };
691
+ return {
692
+ command: defaultCommand,
693
+ commandArgv: globals,
694
+ topLevelHelp: false,
695
+ version: false
696
+ };
697
697
  }
698
+
699
+ // src/tools/cli/args-view.ts
698
700
  function resolveCliView(flags, ascending) {
699
701
  if (flags.size === 0) {
700
702
  if (ascending) {
@@ -775,217 +777,264 @@ function resolveCliView(flags, ascending) {
775
777
  throw new CliArgumentError("--top needs --sort, --by, --count-by or --sum to rank");
776
778
  }
777
779
 
778
- // src/tools/cli/policy.ts
779
- var SHORT_ALIAS = /^[A-Za-z]$/;
780
- var RESERVED_SHORT_OPTIONS = new Set(["h"]);
781
- function fieldMap(descriptor) {
782
- return new Map(jsonSchemaFields(descriptor.presentationSchema).map((field) => [field.name, field]));
783
- }
784
- function resolveAliases(command, descriptor, configured) {
785
- if (!configured)
786
- return new Map;
787
- const fields = fieldMap(descriptor);
788
- const aliases = new Map;
789
- for (const [alias, target] of Object.entries(configured)) {
790
- if (!SHORT_ALIAS.test(alias)) {
791
- throw new Error(`[stitchkit] CLI command "${command}" alias "${alias}" must be one ASCII letter`);
780
+ // src/tools/cli/args.ts
781
+ function readCliTokens(argv, fields, config) {
782
+ const options = {
783
+ json: false,
784
+ wait: false,
785
+ quiet: false,
786
+ dryRun: false,
787
+ help: false
788
+ };
789
+ const flags = new Map;
790
+ const boolFlags = new Map;
791
+ const viewFlags = new Map;
792
+ let ascending = false;
793
+ const positionals = [];
794
+ const pushFlag = (name, value) => {
795
+ const existing = flags.get(name);
796
+ if (existing)
797
+ existing.push(value);
798
+ else
799
+ flags.set(name, [value]);
800
+ };
801
+ let optionsEnded = false;
802
+ for (let i = 0;i < argv.length; i++) {
803
+ const tok = argv[i];
804
+ if (tok === undefined)
805
+ continue;
806
+ if (!optionsEnded && tok === "--") {
807
+ optionsEnded = true;
808
+ continue;
792
809
  }
793
- if (RESERVED_SHORT_OPTIONS.has(alias)) {
794
- throw new Error(`[stitchkit] CLI command "${command}" alias "-${alias}" is reserved`);
810
+ if (optionsEnded || !looksLikeOption(tok)) {
811
+ positionals.push(tok);
812
+ continue;
795
813
  }
796
- if (isUnsafeKey(target) || !fields.has(target)) {
797
- throw new Error(`[stitchkit] CLI command "${command}" alias "-${alias}" targets unknown field "${target}"`);
814
+ if (tok === "-h") {
815
+ options.help = true;
816
+ continue;
817
+ }
818
+ if (!tok.startsWith("--")) {
819
+ const match = /^-([A-Za-z])(?:=(.*))?$/.exec(tok);
820
+ const alias = match?.[1];
821
+ const field = alias === undefined ? undefined : config.optionAliases?.get(alias);
822
+ if (!alias || !field)
823
+ throw new CliArgumentError(`Unknown option "${tok}"`);
824
+ const inline = match?.[2];
825
+ const info2 = fields.get(field);
826
+ if (info2?.kind === "boolean") {
827
+ boolFlags.set(field, inline === undefined ? true : parseReservedBool(field, inline));
828
+ continue;
829
+ }
830
+ let value2 = inline;
831
+ if (value2 === undefined) {
832
+ const next = argv[i + 1];
833
+ if (next !== undefined && !isOptionToken(next)) {
834
+ value2 = next;
835
+ i++;
836
+ } else {
837
+ throw new CliArgumentError(`--${field} requires a value`);
838
+ }
839
+ }
840
+ pushFlag(field, value2);
841
+ continue;
842
+ }
843
+ const option = classifyLongOptionToken(tok);
844
+ if (!option)
845
+ throw new CliArgumentError(`Unknown option "${tok}"`);
846
+ const { name } = option;
847
+ let { value } = option;
848
+ if (name.length === 0)
849
+ throw new CliArgumentError("Invalid empty option name");
850
+ if (option.globalKind === "boolean") {
851
+ const enabled = value === undefined ? true : parseReservedBool(name, value);
852
+ if (name === "dry-run")
853
+ options.dryRun = enabled;
854
+ else if (name === "json")
855
+ options.json = enabled;
856
+ else if (name === "wait")
857
+ options.wait = enabled;
858
+ else if (name === "quiet")
859
+ options.quiet = enabled;
860
+ else if (name === "ascending")
861
+ ascending = enabled;
862
+ else
863
+ options.help = enabled;
864
+ continue;
865
+ }
866
+ if (option.globalKind === "value") {
867
+ const next = argv[i + 1];
868
+ value = value ?? next;
869
+ if (value === undefined || !option.inline && isOptionToken(value)) {
870
+ throw new CliArgumentError(`--${name} requires a value`);
871
+ }
872
+ if (!option.inline)
873
+ i++;
874
+ if (name === "wait-timeout") {
875
+ const timeout = Number(value);
876
+ if (!Number.isFinite(timeout) || timeout <= 0) {
877
+ throw new CliArgumentError("--wait-timeout must be a positive number");
878
+ }
879
+ options.waitTimeout = timeout;
880
+ } else if (VIEW_OPTIONS.has(name)) {
881
+ if (viewFlags.has(name))
882
+ throw new CliArgumentError(`--${name} was given twice`);
883
+ viewFlags.set(name, value);
884
+ } else {
885
+ options.outputDir = value;
886
+ }
887
+ continue;
888
+ }
889
+ if (value === undefined && name.startsWith("no-") && fields.get(name.slice(3))?.kind === "boolean") {
890
+ boolFlags.set(name.slice(3), false);
891
+ continue;
892
+ }
893
+ const unsafeSegment = name.split(".").find(isUnsafeKey);
894
+ if (unsafeSegment !== undefined) {
895
+ throw new CliArgumentError(`Unsafe option name "--${name}"`);
896
+ }
897
+ const info = fields.get(name);
898
+ const rootName = name.split(".")[0] ?? name;
899
+ if (!fields.has(rootName) && !config.allowUnknown) {
900
+ throw new CliArgumentError(`Unknown option "--${name}"`);
901
+ }
902
+ if (value === undefined) {
903
+ if (info?.kind === "boolean") {
904
+ boolFlags.set(name, true);
905
+ continue;
906
+ }
907
+ const next = argv[i + 1];
908
+ if (next !== undefined && !isOptionToken(next)) {
909
+ value = next;
910
+ i++;
911
+ } else {
912
+ throw new CliArgumentError(`--${name} requires a value`);
913
+ }
914
+ }
915
+ pushFlag(name, value);
916
+ }
917
+ return { options, flags, boolFlags, viewFlags, ascending, positionals };
918
+ }
919
+ function buildToolArgs(tokens, fields, declaredPositionals) {
920
+ const { flags, boolFlags, positionals } = tokens;
921
+ const toolArgs = {};
922
+ const fillable = declaredPositionals === undefined ? [...fields.entries()].filter(([, info]) => info.kind !== "boolean").map(([name]) => name) : [...declaredPositionals];
923
+ const variadicTail = declaredPositionals !== undefined && fields.get(fillable[fillable.length - 1] ?? "")?.kind === "array" ? fillable[fillable.length - 1] : undefined;
924
+ let pi = 0;
925
+ for (const key of fillable) {
926
+ if (pi >= positionals.length)
927
+ break;
928
+ if (key === variadicTail) {
929
+ if (flags.has(key)) {
930
+ throw new CliArgumentError(`--${key} conflicts with the positional values for "${key}" — pass one form, not both`);
931
+ }
932
+ toolArgs[key] = coerceField(fields.get(key), positionals.slice(pi), `<${key}>`);
933
+ pi = positionals.length;
934
+ break;
798
935
  }
799
- const existing = aliases.get(target);
800
- if (existing !== undefined) {
801
- throw new Error(`[stitchkit] CLI command "${command}" field "${target}" has multiple aliases: -${existing}, -${alias}`);
936
+ if (flags.has(key))
937
+ continue;
938
+ const value = positionals[pi++];
939
+ if (value !== undefined) {
940
+ toolArgs[key] = coerceField(fields.get(key), [value], `<${key}>`);
802
941
  }
803
- aliases.set(target, alias);
804
942
  }
805
- return aliases;
806
- }
807
- function resolvePositionals(command, descriptor, configured) {
808
- if (configured === undefined)
809
- return;
810
- const fields = fieldMap(descriptor);
811
- const kinds = describeSchemaFields(descriptor.argumentSchema);
812
- const seen = new Set;
813
- let optionalSeen = false;
814
- for (const name of configured) {
815
- const field = fields.get(name);
816
- if (isUnsafeKey(name) || !field || !kinds.has(name)) {
817
- throw new Error(`[stitchkit] CLI command "${command}" positional targets unknown field "${name}"`);
818
- }
819
- if (seen.has(name)) {
820
- throw new Error(`[stitchkit] CLI command "${command}" repeats positional field "${name}"`);
943
+ if (pi < positionals.length) {
944
+ throw new CliArgumentError(`Unexpected positional argument "${positionals[pi]}"`);
945
+ }
946
+ for (const [key, value] of boolFlags) {
947
+ toolArgs[key] = value;
948
+ }
949
+ const dottedRoots = new Map;
950
+ for (const key of flags.keys()) {
951
+ const dot = key.indexOf(".");
952
+ if (dot > 0)
953
+ dottedRoots.set(key.slice(0, dot), key);
954
+ }
955
+ for (const [root, dotted] of dottedRoots) {
956
+ if (flags.has(root)) {
957
+ throw new CliArgumentError(`--${root} conflicts with --${dotted} — pass one form, not both`);
821
958
  }
822
- if (kinds.get(name)?.kind === "boolean") {
823
- throw new Error(`[stitchkit] CLI command "${command}" boolean field "${name}" cannot be positional`);
959
+ }
960
+ for (const [key, values] of flags) {
961
+ if (key.includes(".")) {
962
+ if (values.length > 1) {
963
+ throw new CliArgumentError(`--${key} was passed ${values.length} times`);
964
+ }
965
+ setNested(toolArgs, key.split("."), looseCoerce(values[0] ?? ""));
966
+ continue;
824
967
  }
825
- if (optionalSeen && field.required) {
826
- throw new Error(`[stitchkit] CLI command "${command}" required positional "${name}" cannot follow an optional positional`);
968
+ const info = fields.get(key);
969
+ if (values.length > 1 && info !== undefined && info.kind !== "array" && info.kind !== "other") {
970
+ throw new CliArgumentError(`--${key} was passed ${values.length} times`);
827
971
  }
828
- if (!field.required)
829
- optionalSeen = true;
830
- seen.add(name);
972
+ toolArgs[key] = coerceField(info, values, `--${key}`);
831
973
  }
832
- return [...configured];
833
- }
834
- function applyCliPresentationPolicy(command, descriptor, config) {
835
- const base = { ...descriptor, aliases: new Map };
836
- const configuredAliases = config.optionAliases && Object.hasOwn(config.optionAliases, command) ? config.optionAliases[command] : undefined;
837
- const configuredPositionals = config.positionals && Object.hasOwn(config.positionals, command) ? config.positionals[command] : undefined;
838
- return {
839
- ...base,
840
- aliases: resolveAliases(command, base, configuredAliases),
841
- positionals: resolvePositionals(command, base, configuredPositionals)
842
- };
974
+ return toolArgs;
843
975
  }
844
- function assertCliPoliciesResolved(commands, config) {
845
- const configuredNames = new Set([
846
- ...Object.keys(config.optionAliases ?? {}),
847
- ...Object.keys(config.positionals ?? {})
848
- ]);
849
- if (config.defaultCommand !== undefined)
850
- configuredNames.add(config.defaultCommand);
851
- for (const name of configuredNames) {
852
- if (!commands.has(name)) {
853
- throw new Error(`[stitchkit] CLI policy targets unavailable command "${name}"`);
854
- }
976
+ function parseCliArgs(argv, schema, config = {}) {
977
+ const fields = describeSchemaFields(schema);
978
+ for (const name of config.knownFields ?? []) {
979
+ if (!fields.has(name))
980
+ fields.set(name, { kind: "other" });
855
981
  }
982
+ const tokens = readCliTokens(argv, fields, config);
983
+ const { options } = tokens;
984
+ const view = resolveCliView(tokens.viewFlags, tokens.ascending);
985
+ if (view)
986
+ options.view = view;
987
+ return { toolArgs: buildToolArgs(tokens, fields, config.positionals), options };
856
988
  }
857
-
858
- // src/tools/cli/invoke.ts
859
- function parseCliGlobals(schema, globals) {
860
- if (!schema)
861
- return globals ?? {};
862
- return schema.parse(globals ?? {});
863
- }
864
- function cliInvocationResult(result, toolName, config) {
865
- if (result.ok)
866
- return { ok: true, exitCode: 0, data: result.data };
867
- const normalized = toolErrorFromResult(result);
868
- const hints = [];
869
- if (result.hint)
870
- hints.push(result.hint);
871
- const global = config.errorHint?.(toolName, result.code);
872
- if (global)
873
- hints.push(global);
874
- return {
875
- ok: false,
876
- exitCode: cliExitCode(result, config.exitCodes),
877
- error: {
878
- code: result.code,
879
- message: normalized.message,
880
- ...result.details !== undefined && { details: result.details },
881
- ...hints.length > 0 && { hint: hints.join(" ") },
882
- ...result.retryable !== undefined && { retryable: result.retryable }
989
+ function extractCliGlobalOptions(argv, schema) {
990
+ if (schema === undefined)
991
+ return { argv: [...argv], globals: {} };
992
+ const fields = describeSchemaFields(schema);
993
+ const rest = [];
994
+ const raw = new Map;
995
+ let ended = false;
996
+ for (let i = 0;i < argv.length; i++) {
997
+ const token = argv[i];
998
+ if (token === undefined)
999
+ continue;
1000
+ if (!ended && token === "--")
1001
+ ended = true;
1002
+ const option = ended ? undefined : classifyLongOptionToken(token);
1003
+ const info = option && option.globalKind === undefined ? fields.get(option.name) : undefined;
1004
+ if (!option || !info) {
1005
+ rest.push(token);
1006
+ continue;
883
1007
  }
884
- };
885
- }
886
- async function createCliInvoker(config, globals) {
887
- const typedGlobals = parseCliGlobals(config.globalOptions, globals);
888
- const auth = await (config.resolveAuth ? config.resolveAuth(typedGlobals) : config.auth);
889
- const natives = new Map((config.commands ?? []).filter(cliCommandReturnsResult).map((definition) => [definition.name, definition]));
890
- const nativeHelp = new Map([...natives].map(([name, definition]) => [
891
- name,
892
- { description: definition.description, argumentSchema: {}, presentationSchema: {} }
893
- ]));
894
- const { tools, help } = buildCliSurface(config, auth, new Map, new Set);
895
- const runTool = createToolRunner({
896
- source: "cli",
897
- toolSurface: true,
898
- context: { ...config.context?.(auth, typedGlobals), signal: config.signal },
899
- hooks: config.hooks,
900
- lifecycle: config.lifecycle,
901
- coerceJsonArgs: config.coerceJsonArgs
902
- });
903
- return {
904
- commands: [...nativeHelp, ...help].map(([name, presentation]) => ({
905
- name,
906
- description: presentation.description
907
- })),
908
- invoke: async (command, args) => {
909
- const native = natives.get(command);
910
- if (native)
911
- return runNativeCommand(native, args, config, typedGlobals);
912
- const tool = tools.get(command);
913
- if (!tool) {
914
- return cliInvocationResult({
915
- ok: false,
916
- code: "NOT_FOUND",
917
- details: { message: `Unknown command "${command}"` }
918
- }, command, config);
919
- }
920
- let result;
921
- try {
922
- result = await runTool(tool, args);
923
- } catch (error) {
924
- result = toolResultFromError(error);
1008
+ let { value } = option;
1009
+ if (value === undefined && info.kind === "boolean") {
1010
+ value = "true";
1011
+ } else if (value === undefined) {
1012
+ const next = argv[i + 1];
1013
+ if (next !== undefined && !isOptionToken(next)) {
1014
+ value = next;
1015
+ i++;
1016
+ } else {
1017
+ throw new CliArgumentError(`--${option.name} requires a value`);
925
1018
  }
926
- return cliInvocationResult(result, command, config);
927
- }
928
- };
929
- }
930
- var IN_PROCESS_RUN_OPTIONS = Object.freeze({
931
- json: false,
932
- wait: false,
933
- quiet: true,
934
- dryRun: false,
935
- help: false
936
- });
937
- async function runNativeCommand(definition, args, config, globals) {
938
- let out = "";
939
- let err = "";
940
- const result = await executeCliCommand(definition, args, IN_PROCESS_RUN_OPTIONS, {
941
- stdout: (text) => {
942
- out += text;
943
- },
944
- stderr: (text) => {
945
- err += text;
946
- }
947
- }, config.coerceJsonArgs ?? true, globals);
948
- let invocation = cliInvocationResult(result, definition.name, config);
949
- if (invocation.ok) {
950
- try {
951
- invocation = {
952
- ...invocation,
953
- exitCode: cliCommandSuccessExitCode(definition, result.ok ? result.data : undefined)
954
- };
955
- } catch (error) {
956
- invocation = cliInvocationResult(toolResultFromError(error), definition.name, config);
957
1019
  }
1020
+ const existing = raw.get(option.name);
1021
+ if (existing)
1022
+ existing.push(value);
1023
+ else
1024
+ raw.set(option.name, [value]);
958
1025
  }
959
- if (out === "" && err === "")
960
- return invocation;
961
- return {
962
- ...invocation,
963
- written: { ...out !== "" && { stdout: out }, ...err !== "" && { stderr: err } }
964
- };
965
- }
966
- function buildCliSurface(config, auth, nativeHelp, applicationGlobalNames, assertShape) {
967
- const services = typeof config.services === "function" ? config.services(auth) : config.services ?? [];
968
- const runtimeTools = typeof config.runtimeTools === "function" ? config.runtimeTools(auth) : config.runtimeTools ?? [];
969
- const tools = new Map;
970
- const help = new Map(nativeHelp);
971
- for (const { mountable } of collectToolSurface({
972
- surface: { services, runtimeTools },
973
- transport: "CLI"
974
- })) {
975
- const descriptor = applyCliPresentationPolicy(mountable.name, managedCliDescriptor(mountable), config);
976
- assertShape?.(mountable.name, descriptor, help.has(mountable.name), config.passthrough?.[mountable.name], applicationGlobalNames);
977
- tools.set(mountable.name, mountable);
978
- help.set(mountable.name, descriptor);
1026
+ const args = {};
1027
+ for (const [name, values] of raw) {
1028
+ args[name] = coerceField(fields.get(name), values, `--${name}`);
979
1029
  }
980
- assertCliPoliciesResolved(help, config);
981
- return { tools, help };
982
- }
983
- function managedCliDescriptor(tool) {
984
- return {
985
- description: tool.method.desc,
986
- argumentSchema: tool.argumentSchema,
987
- presentationSchema: tool.presentationSchema
988
- };
1030
+ const parsed = schema.safeParse(coerceJsonArgs(args, schema));
1031
+ if (!parsed.success) {
1032
+ const issue = parsed.error.issues[0];
1033
+ const field = issue?.path[0];
1034
+ const where = typeof field === "string" ? `--${field}` : "application option";
1035
+ throw new CliArgumentError(`${where}: ${issue?.message ?? "invalid value"}`);
1036
+ }
1037
+ return { argv: rest, globals: parsed.data };
989
1038
  }
990
1039
 
991
1040
  // src/tools/cli/view.ts
@@ -2254,4 +2303,4 @@ async function createCli(config) {
2254
2303
  return runManagedInvocation(session, route);
2255
2304
  }
2256
2305
 
2257
- export { fetchGuarded, PrivateAddressRefusal, fetchPinnedDocument, readCapped, WaitTimeoutError, runWaitOperation, defineCliCommand, DEFAULT_EXIT_CODES, cliExitCode, emitResult, routeCliArgv, CliArgumentError, parseCliArgs, extractCliGlobalOptions, cliInvocationResult, createCliInvoker, renderCliView, pollUntilDone, createCli };
2306
+ export { fetchGuarded, PrivateAddressRefusal, fetchPinnedDocument, readCapped, WaitTimeoutError, runWaitOperation, defineCliCommand, DEFAULT_EXIT_CODES, cliExitCode, emitResult, CliArgumentError, cliInvocationResult, createCliInvoker, routeCliArgv, parseCliArgs, extractCliGlobalOptions, renderCliView, pollUntilDone, createCli };