subharness 0.0.4 → 0.0.7

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 (303) hide show
  1. package/README.md +95 -9
  2. package/dist/adapters/claude-process.d.ts +3 -0
  3. package/dist/adapters/claude-process.js +19 -2
  4. package/dist/adapters/claude-process.js.map +1 -1
  5. package/dist/adapters/claude-result.d.ts +2 -0
  6. package/dist/adapters/claude-result.js +22 -0
  7. package/dist/adapters/claude-result.js.map +1 -0
  8. package/dist/adapters/claude-tools.d.ts +6 -2
  9. package/dist/adapters/claude-tools.js +14 -12
  10. package/dist/adapters/claude-tools.js.map +1 -1
  11. package/dist/adapters/claude-worker-client.d.ts +49 -0
  12. package/dist/adapters/claude-worker-client.js +359 -0
  13. package/dist/adapters/claude-worker-client.js.map +1 -0
  14. package/dist/adapters/claude-worker-process.d.ts +20 -0
  15. package/dist/adapters/claude-worker-process.js +76 -0
  16. package/dist/adapters/claude-worker-process.js.map +1 -0
  17. package/dist/adapters/claude-worker-protocol.d.ts +38 -0
  18. package/dist/adapters/claude-worker-protocol.js +2 -0
  19. package/dist/adapters/claude-worker-protocol.js.map +1 -0
  20. package/dist/adapters/claude-worker.d.ts +1 -0
  21. package/dist/adapters/claude-worker.js +126 -0
  22. package/dist/adapters/claude-worker.js.map +1 -0
  23. package/dist/adapters/claude.d.ts +16 -6
  24. package/dist/adapters/claude.js +164 -75
  25. package/dist/adapters/claude.js.map +1 -1
  26. package/dist/adapters/codex.js +4 -1
  27. package/dist/adapters/codex.js.map +1 -1
  28. package/dist/adapters/copilot-permissions.d.ts +26 -0
  29. package/dist/adapters/copilot-permissions.js +121 -0
  30. package/dist/adapters/copilot-permissions.js.map +1 -0
  31. package/dist/adapters/copilot-tools.d.ts +12 -0
  32. package/dist/adapters/copilot-tools.js +61 -0
  33. package/dist/adapters/copilot-tools.js.map +1 -0
  34. package/dist/adapters/copilot.d.ts +108 -0
  35. package/dist/adapters/copilot.js +819 -0
  36. package/dist/adapters/copilot.js.map +1 -0
  37. package/dist/adapters/cursor-cli-approvals.d.ts +2 -0
  38. package/dist/adapters/cursor-cli-approvals.js +83 -0
  39. package/dist/adapters/cursor-cli-approvals.js.map +1 -0
  40. package/dist/adapters/cursor-cli-model.d.ts +4 -0
  41. package/dist/adapters/cursor-cli-model.js +64 -0
  42. package/dist/adapters/cursor-cli-model.js.map +1 -0
  43. package/dist/adapters/cursor-cli-session.d.ts +32 -0
  44. package/dist/adapters/cursor-cli-session.js +316 -0
  45. package/dist/adapters/cursor-cli-session.js.map +1 -0
  46. package/dist/adapters/cursor-cli-tools.d.ts +20 -0
  47. package/dist/adapters/cursor-cli-tools.js +181 -0
  48. package/dist/adapters/cursor-cli-tools.js.map +1 -0
  49. package/dist/adapters/cursor-cli.d.ts +2 -0
  50. package/dist/adapters/cursor-cli.js +306 -0
  51. package/dist/adapters/cursor-cli.js.map +1 -0
  52. package/dist/adapters/cursor-model.d.ts +7 -0
  53. package/dist/adapters/cursor-model.js +67 -0
  54. package/dist/adapters/cursor-model.js.map +1 -0
  55. package/dist/adapters/cursor-rpc.d.ts +42 -0
  56. package/dist/adapters/cursor-rpc.js +271 -0
  57. package/dist/adapters/cursor-rpc.js.map +1 -0
  58. package/dist/adapters/cursor-session.d.ts +4 -0
  59. package/dist/adapters/cursor-session.js +327 -0
  60. package/dist/adapters/cursor-session.js.map +1 -0
  61. package/dist/adapters/cursor-startup.d.ts +16 -0
  62. package/dist/adapters/cursor-startup.js +74 -0
  63. package/dist/adapters/cursor-startup.js.map +1 -0
  64. package/dist/adapters/cursor-tools.d.ts +11 -0
  65. package/dist/adapters/cursor-tools.js +49 -0
  66. package/dist/adapters/cursor-tools.js.map +1 -0
  67. package/dist/adapters/cursor.d.ts +6 -0
  68. package/dist/adapters/cursor.js +17 -0
  69. package/dist/adapters/cursor.js.map +1 -0
  70. package/dist/adapters/fx-auth.d.ts +12 -2
  71. package/dist/adapters/fx-auth.js +51 -61
  72. package/dist/adapters/fx-auth.js.map +1 -1
  73. package/dist/adapters/fx-profile.d.ts +8 -0
  74. package/dist/adapters/fx-profile.js +101 -0
  75. package/dist/adapters/fx-profile.js.map +1 -0
  76. package/dist/adapters/fx-rpc.d.ts +2 -0
  77. package/dist/adapters/fx-rpc.js +30 -4
  78. package/dist/adapters/fx-rpc.js.map +1 -1
  79. package/dist/adapters/fx-status.d.ts +2 -0
  80. package/dist/adapters/fx-status.js +96 -0
  81. package/dist/adapters/fx-status.js.map +1 -0
  82. package/dist/adapters/fx.js +28 -12
  83. package/dist/adapters/fx.js.map +1 -1
  84. package/dist/adapters/opencode-access.d.ts +13 -0
  85. package/dist/adapters/opencode-access.js +76 -0
  86. package/dist/adapters/opencode-access.js.map +1 -0
  87. package/dist/adapters/opencode-config.d.ts +11 -0
  88. package/dist/adapters/opencode-config.js +238 -0
  89. package/dist/adapters/opencode-config.js.map +1 -0
  90. package/dist/adapters/opencode-http.d.ts +28 -0
  91. package/dist/adapters/opencode-http.js +297 -0
  92. package/dist/adapters/opencode-http.js.map +1 -0
  93. package/dist/adapters/opencode-tools.d.ts +19 -0
  94. package/dist/adapters/opencode-tools.js +127 -0
  95. package/dist/adapters/opencode-tools.js.map +1 -0
  96. package/dist/adapters/opencode.d.ts +2 -0
  97. package/dist/adapters/opencode.js +569 -0
  98. package/dist/adapters/opencode.js.map +1 -0
  99. package/dist/adapters/rpc.d.ts +3 -0
  100. package/dist/adapters/rpc.js +45 -4
  101. package/dist/adapters/rpc.js.map +1 -1
  102. package/dist/adapters/types.d.ts +5 -0
  103. package/dist/adapters/types.js.map +1 -1
  104. package/dist/approvals/types.d.ts +1 -1
  105. package/dist/approvals/types.js.map +1 -1
  106. package/dist/cli/args.d.ts +1 -1
  107. package/dist/cli/args.js +4 -1
  108. package/dist/cli/args.js.map +1 -1
  109. package/dist/cli/catalog-worker.js.map +1 -1
  110. package/dist/cli/dashboard-client.js +20 -31
  111. package/dist/cli/dashboard-client.js.map +1 -1
  112. package/dist/cli/dashboard-controller.d.ts +7 -0
  113. package/dist/cli/dashboard-controller.js +27 -0
  114. package/dist/cli/dashboard-controller.js.map +1 -0
  115. package/dist/cli/dashboard-detail-view.d.ts +1 -1
  116. package/dist/cli/dashboard-detail-view.js +3 -4
  117. package/dist/cli/dashboard-detail-view.js.map +1 -1
  118. package/dist/cli/dashboard-history-view.js.map +1 -1
  119. package/dist/cli/dashboard-input.d.ts +1 -1
  120. package/dist/cli/dashboard-input.js +11 -1
  121. package/dist/cli/dashboard-input.js.map +1 -1
  122. package/dist/cli/dashboard-layout.js +3 -3
  123. package/dist/cli/dashboard-layout.js.map +1 -1
  124. package/dist/cli/dashboard-renderer.js.map +1 -1
  125. package/dist/cli/dashboard-style.js +2 -2
  126. package/dist/cli/dashboard-style.js.map +1 -1
  127. package/dist/cli/dashboard.d.ts +2 -2
  128. package/dist/cli/dashboard.js +7 -32
  129. package/dist/cli/dashboard.js.map +1 -1
  130. package/dist/cli/help.d.ts +1 -1
  131. package/dist/cli/help.js +30 -12
  132. package/dist/cli/help.js.map +1 -1
  133. package/dist/cli/main.js +55 -43
  134. package/dist/cli/main.js.map +1 -1
  135. package/dist/config/access-provenance.d.ts +10 -0
  136. package/dist/config/access-provenance.js +31 -0
  137. package/dist/config/access-provenance.js.map +1 -0
  138. package/dist/config/access.d.ts +12 -2
  139. package/dist/config/access.js +125 -27
  140. package/dist/config/access.js.map +1 -1
  141. package/dist/config/loader.js +1 -0
  142. package/dist/config/loader.js.map +1 -1
  143. package/dist/config/oidc.js +4 -2
  144. package/dist/config/oidc.js.map +1 -1
  145. package/dist/config/project.js +2 -1
  146. package/dist/config/project.js.map +1 -1
  147. package/dist/config/resolve-access.js +24 -10
  148. package/dist/config/resolve-access.js.map +1 -1
  149. package/dist/errors.d.ts +2 -2
  150. package/dist/errors.js.map +1 -1
  151. package/dist/index.d.ts +8 -2
  152. package/dist/index.js +4 -1
  153. package/dist/index.js.map +1 -1
  154. package/dist/process-diagnostics.d.ts +2 -0
  155. package/dist/process-diagnostics.js +11 -0
  156. package/dist/process-diagnostics.js.map +1 -0
  157. package/dist/runtime/access-errors.d.ts +4 -0
  158. package/dist/runtime/access-errors.js +25 -0
  159. package/dist/runtime/access-errors.js.map +1 -0
  160. package/dist/runtime/approval-registry.d.ts +9 -0
  161. package/dist/runtime/approval-registry.js +144 -5
  162. package/dist/runtime/approval-registry.js.map +1 -1
  163. package/dist/runtime/capture.d.ts +22 -0
  164. package/dist/runtime/capture.js +320 -0
  165. package/dist/runtime/capture.js.map +1 -0
  166. package/dist/runtime/catalog.d.ts +39 -0
  167. package/dist/runtime/catalog.js +84 -0
  168. package/dist/runtime/catalog.js.map +1 -0
  169. package/dist/runtime/client.d.ts +2 -1
  170. package/dist/runtime/client.js +74 -47
  171. package/dist/runtime/client.js.map +1 -1
  172. package/dist/runtime/coordinator.d.ts +44 -7
  173. package/dist/runtime/coordinator.js +265 -31
  174. package/dist/runtime/coordinator.js.map +1 -1
  175. package/dist/runtime/daemon.js +12 -6
  176. package/dist/runtime/daemon.js.map +1 -1
  177. package/dist/runtime/dashboard-sanitize.d.ts +2 -0
  178. package/dist/runtime/dashboard-sanitize.js +7 -0
  179. package/dist/runtime/dashboard-sanitize.js.map +1 -0
  180. package/dist/runtime/dashboard-workspace.js +5 -1
  181. package/dist/runtime/dashboard-workspace.js.map +1 -1
  182. package/dist/runtime/dashboard.d.ts +1 -1
  183. package/dist/runtime/dashboard.js +2 -3
  184. package/dist/runtime/dashboard.js.map +1 -1
  185. package/dist/runtime/definition.d.ts +6 -1
  186. package/dist/runtime/definition.js +42 -2
  187. package/dist/runtime/definition.js.map +1 -1
  188. package/dist/runtime/native-owner.js +7 -1
  189. package/dist/runtime/native-owner.js.map +1 -1
  190. package/dist/runtime/pagination.d.ts +9 -0
  191. package/dist/runtime/pagination.js +36 -0
  192. package/dist/runtime/pagination.js.map +1 -0
  193. package/dist/runtime/sdk-observation.d.ts +8 -0
  194. package/dist/runtime/sdk-observation.js +75 -0
  195. package/dist/runtime/sdk-observation.js.map +1 -0
  196. package/dist/runtime/sdk-projection.d.ts +8 -0
  197. package/dist/runtime/sdk-projection.js +19 -0
  198. package/dist/runtime/sdk-projection.js.map +1 -0
  199. package/dist/runtime/sdk-service.d.ts +11 -0
  200. package/dist/runtime/sdk-service.js +109 -0
  201. package/dist/runtime/sdk-service.js.map +1 -0
  202. package/dist/runtime/select-native.d.ts +4 -1
  203. package/dist/runtime/select-native.js +28 -13
  204. package/dist/runtime/select-native.js.map +1 -1
  205. package/dist/runtime/service.d.ts +11 -1
  206. package/dist/runtime/service.js +178 -3
  207. package/dist/runtime/service.js.map +1 -1
  208. package/dist/runtime/session-launcher.js +1 -1
  209. package/dist/runtime/session-launcher.js.map +1 -1
  210. package/dist/runtime/snapshots.d.ts +103 -0
  211. package/dist/runtime/snapshots.js +124 -0
  212. package/dist/runtime/snapshots.js.map +1 -0
  213. package/dist/runtime/state.d.ts +26 -0
  214. package/dist/runtime/state.js +86 -17
  215. package/dist/runtime/state.js.map +1 -1
  216. package/dist/runtime/task-data.d.ts +38 -0
  217. package/dist/runtime/task-data.js +2 -0
  218. package/dist/runtime/task-data.js.map +1 -0
  219. package/dist/runtime/transport.d.ts +13 -0
  220. package/dist/runtime/transport.js +166 -0
  221. package/dist/runtime/transport.js.map +1 -0
  222. package/dist/runtime/types.d.ts +28 -9
  223. package/dist/runtime/types.js.map +1 -1
  224. package/dist/runtime/worker-client.js +40 -13
  225. package/dist/runtime/worker-client.js.map +1 -1
  226. package/dist/runtime/worker-server.js +105 -24
  227. package/dist/runtime/worker-server.js.map +1 -1
  228. package/dist/sdk/connected-types.d.ts +42 -0
  229. package/dist/sdk/connected-types.js +2 -0
  230. package/dist/sdk/connected-types.js.map +1 -0
  231. package/dist/sdk/connected.d.ts +3 -0
  232. package/dist/sdk/connected.js +232 -0
  233. package/dist/sdk/connected.js.map +1 -0
  234. package/dist/sdk/definitions.d.ts +4 -1
  235. package/dist/sdk/definitions.js +16 -2
  236. package/dist/sdk/definitions.js.map +1 -1
  237. package/dist/sdk/execution-definition.d.ts +3 -0
  238. package/dist/sdk/execution-definition.js +59 -0
  239. package/dist/sdk/execution-definition.js.map +1 -0
  240. package/dist/sdk/execution-driver.d.ts +6 -0
  241. package/dist/sdk/execution-driver.js +86 -0
  242. package/dist/sdk/execution-driver.js.map +1 -0
  243. package/dist/sdk/execution-observation.d.ts +3 -0
  244. package/dist/sdk/execution-observation.js +35 -0
  245. package/dist/sdk/execution-observation.js.map +1 -0
  246. package/dist/sdk/execution-options.d.ts +17 -0
  247. package/dist/sdk/execution-options.js +115 -0
  248. package/dist/sdk/execution-options.js.map +1 -0
  249. package/dist/sdk/execution-types.d.ts +72 -0
  250. package/dist/sdk/execution-types.js +2 -0
  251. package/dist/sdk/execution-types.js.map +1 -0
  252. package/dist/sdk/execution.d.ts +3 -0
  253. package/dist/sdk/execution.js +3 -0
  254. package/dist/sdk/execution.js.map +1 -0
  255. package/dist/sdk/hosted-error.d.ts +3 -0
  256. package/dist/sdk/hosted-error.js +14 -0
  257. package/dist/sdk/hosted-error.js.map +1 -0
  258. package/dist/sdk/hosted.d.ts +23 -0
  259. package/dist/sdk/hosted.js +204 -0
  260. package/dist/sdk/hosted.js.map +1 -0
  261. package/dist/sdk/permission-validation.js +10 -1
  262. package/dist/sdk/permission-validation.js.map +1 -1
  263. package/dist/sdk/runner.d.ts +5 -0
  264. package/dist/sdk/runner.js +107 -0
  265. package/dist/sdk/runner.js.map +1 -0
  266. package/dist/sdk/tools.js +4 -1
  267. package/dist/sdk/tools.js.map +1 -1
  268. package/dist/sdk/types.d.ts +29 -1
  269. package/dist/sdk/types.js.map +1 -1
  270. package/package.json +6 -3
  271. package/sdk/access-config.md +60 -4
  272. package/sdk/adapter-contract.md +13 -3
  273. package/sdk/additional-harnesses.md +43 -0
  274. package/sdk/agent-skill.md +2 -2
  275. package/sdk/agent.md +6 -4
  276. package/sdk/approvals.md +5 -1
  277. package/sdk/authentication.md +1 -1
  278. package/sdk/cli/dashboard-design.md +6 -0
  279. package/sdk/cli/index.md +9 -6
  280. package/sdk/cli/output.md +3 -1
  281. package/sdk/completion-notifications.md +2 -0
  282. package/sdk/config.md +1 -1
  283. package/sdk/copilot.md +53 -0
  284. package/sdk/cursor.md +68 -0
  285. package/sdk/diagnostics.md +29 -0
  286. package/sdk/distribution.md +5 -3
  287. package/sdk/evals.md +1 -1
  288. package/sdk/examples/chat-tool.ts +126 -0
  289. package/sdk/execution.md +743 -0
  290. package/sdk/fx.md +50 -5
  291. package/sdk/harnesses.md +13 -13
  292. package/sdk/index.md +45 -20
  293. package/sdk/message-delivery.md +2 -0
  294. package/sdk/opencode.md +57 -0
  295. package/sdk/permissions.md +6 -2
  296. package/sdk/plugins/sub-agents.md +4 -2
  297. package/sdk/project-team.md +25 -1
  298. package/sdk/sessions.md +2 -0
  299. package/sdk/tools.md +4 -2
  300. package/sdk/v1-runtime.md +8 -6
  301. package/dist/cli/catalog.d.ts +0 -26
  302. package/dist/cli/catalog.js +0 -41
  303. package/dist/cli/catalog.js.map +0 -1
@@ -15,10 +15,16 @@ export class NativeOwner {
15
15
  return native;
16
16
  }
17
17
  close() {
18
- this.closing ??= (async () => {
18
+ if (this.closing)
19
+ return this.closing;
20
+ const attempt = (async () => {
19
21
  const native = await this.opening?.catch(() => undefined);
20
22
  await native?.close();
21
23
  })();
24
+ this.closing = attempt.catch(error => {
25
+ this.closing = undefined;
26
+ throw error;
27
+ });
22
28
  return this.closing;
23
29
  }
24
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"native-owner.js","sourceRoot":"","sources":["../../src/runtime/native-owner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,oFAAoF;AACpF,MAAM,OAAO,WAAW;IACd,OAAO,CAA0B;IACjC,OAAO,CAAiB;IAEhC,KAAK,CAAC,IAAI,CAAC,OAAqC;QAC9C,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAC,wCAAwC,CAAC,CAAC;QAClH,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;QAClC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,OAAO,CAAC;YACnB,MAAM,IAAI,UAAU,CAAC,yBAAyB,EAAC,8CAA8C,CAAC,CAAC;QACjG,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,KAAK,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAC1D,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC;QACxB,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF","sourcesContent":["import type { NativeSession } from '../adapters/types.js';\nimport { AgentError } from '../errors.js';\n\n/** Ensures startup cannot publish a session after its process owner disconnects. */\nexport class NativeOwner {\n private opening?: Promise<NativeSession>;\n private closing?: Promise<void>;\n\n async open(factory: () => Promise<NativeSession>) {\n if (this.closing || this.opening) throw new AgentError('HARNESS_FAILED','Native session startup is unavailable.');\n this.opening = factory();\n const native = await this.opening;\n if (this.closing) {\n await this.closing;\n throw new AgentError('COORDINATOR_UNAVAILABLE','The coordinator disconnected during startup.');\n }\n return native;\n }\n\n close(): Promise<void> {\n this.closing ??= (async () => {\n const native = await this.opening?.catch(() => undefined);\n await native?.close();\n })();\n return this.closing;\n }\n}\n"]}
1
+ {"version":3,"file":"native-owner.js","sourceRoot":"","sources":["../../src/runtime/native-owner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,oFAAoF;AACpF,MAAM,OAAO,WAAW;IACd,OAAO,CAA0B;IACjC,OAAO,CAAiB;IAEhC,KAAK,CAAC,IAAI,CAAC,OAAqC;QAC9C,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAC,wCAAwC,CAAC,CAAC;QAClH,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;QAClC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,OAAO,CAAC;YACnB,MAAM,IAAI,UAAU,CAAC,yBAAyB,EAAC,8CAA8C,CAAC,CAAC;QACjG,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC;QACtC,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;YAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAC1D,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC;QACxB,CAAC,CAAC,EAAE,CAAC;QACL,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;YACnC,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;YACzB,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF","sourcesContent":["import type { NativeSession } from '../adapters/types.js';\nimport { AgentError } from '../errors.js';\n\n/** Ensures startup cannot publish a session after its process owner disconnects. */\nexport class NativeOwner {\n private opening?: Promise<NativeSession>;\n private closing?: Promise<void>;\n\n async open(factory: () => Promise<NativeSession>) {\n if (this.closing || this.opening) throw new AgentError('HARNESS_FAILED','Native session startup is unavailable.');\n this.opening = factory();\n const native = await this.opening;\n if (this.closing) {\n await this.closing;\n throw new AgentError('COORDINATOR_UNAVAILABLE','The coordinator disconnected during startup.');\n }\n return native;\n }\n\n close(): Promise<void> {\n if (this.closing) return this.closing;\n const attempt = (async () => {\n const native = await this.opening?.catch(() => undefined);\n await native?.close();\n })();\n this.closing = attempt.catch(error => {\n this.closing = undefined;\n throw error;\n });\n return this.closing;\n }\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import type { PageOptions } from './snapshots.js';
2
+ export declare function paginate<T>(values: T[], options: PageOptions | undefined, binding: {
3
+ instance: string;
4
+ collection: string;
5
+ filter: string;
6
+ }, membership: (value: T) => number): {
7
+ items: T[];
8
+ nextCursor?: string;
9
+ };
@@ -0,0 +1,36 @@
1
+ import { AgentError } from '../errors.js';
2
+ export function paginate(values, options, binding, membership) {
3
+ const limit = options?.limit ?? 100;
4
+ if (!Number.isInteger(limit) || limit < 1 || limit > 1_000)
5
+ throw new AgentError('INVALID_ARGUMENT', 'Page limit must be an integer from 1 through 1000.');
6
+ const current = values.reduce((max, value) => Math.max(max, membership(value)), 0);
7
+ let watermark = current, after = 0;
8
+ if (options?.cursor !== undefined) {
9
+ if (typeof options.cursor !== 'string' || !options.cursor)
10
+ invalid();
11
+ let cursor;
12
+ try {
13
+ cursor = JSON.parse(Buffer.from(options.cursor, 'base64url').toString('utf8'));
14
+ }
15
+ catch {
16
+ invalid();
17
+ }
18
+ if (!cursor || typeof cursor !== 'object' || Array.isArray(cursor)
19
+ || Object.keys(cursor).sort().join(',') !== 'after,collection,filter,instance,v,watermark'
20
+ || cursor.v !== 1 || cursor.instance !== binding.instance || cursor.collection !== binding.collection
21
+ || cursor.filter !== binding.filter || !Number.isSafeInteger(cursor.watermark) || cursor.watermark < 0
22
+ || cursor.watermark > current || !Number.isSafeInteger(cursor.after) || cursor.after < 0
23
+ || cursor.after > cursor.watermark)
24
+ invalid();
25
+ watermark = cursor.watermark;
26
+ after = cursor.after;
27
+ }
28
+ const eligible = values.filter(value => membership(value) <= watermark && membership(value) > after);
29
+ const items = eligible.slice(0, limit);
30
+ if (eligible.length <= items.length)
31
+ return { items };
32
+ const cursor = { v: 1, ...binding, watermark, after: membership(items.at(-1)) };
33
+ return { items, nextCursor: Buffer.from(JSON.stringify(cursor)).toString('base64url') };
34
+ }
35
+ function invalid() { throw new AgentError('INVALID_CURSOR', 'The page cursor is invalid for this collection.'); }
36
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/runtime/pagination.ts"],"names":[],"mappings":"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","sourcesContent":["import { AgentError } from '../errors.js';\nimport type { PageOptions } from './snapshots.js';\n\nexport function paginate<T>(values:T[], options:PageOptions|undefined, binding:{instance:string;collection:string;filter:string},\n membership:(value:T)=>number): {items:T[];nextCursor?:string} {\n const limit=options?.limit ?? 100;\n if (!Number.isInteger(limit) || limit < 1 || limit > 1_000)\n throw new AgentError('INVALID_ARGUMENT','Page limit must be an integer from 1 through 1000.');\n const current=values.reduce((max,value)=>Math.max(max,membership(value)),0);\n let watermark=current, after=0;\n if (options?.cursor !== undefined) {\n if (typeof options.cursor !== 'string' || !options.cursor) invalid();\n let cursor: any;\n try { cursor=JSON.parse(Buffer.from(options.cursor,'base64url').toString('utf8')); } catch { invalid(); }\n if (!cursor || typeof cursor !== 'object' || Array.isArray(cursor)\n || Object.keys(cursor).sort().join(',') !== 'after,collection,filter,instance,v,watermark'\n || cursor.v !== 1 || cursor.instance !== binding.instance || cursor.collection !== binding.collection\n || cursor.filter !== binding.filter || !Number.isSafeInteger(cursor.watermark) || cursor.watermark < 0\n || cursor.watermark > current || !Number.isSafeInteger(cursor.after) || cursor.after < 0\n || cursor.after > cursor.watermark) invalid();\n watermark=cursor.watermark; after=cursor.after;\n }\n const eligible=values.filter(value=>membership(value)<=watermark && membership(value)>after);\n const items=eligible.slice(0,limit);\n if (eligible.length <= items.length) return {items};\n const cursor={v:1,...binding,watermark,after:membership(items.at(-1)!)};\n return {items,nextCursor:Buffer.from(JSON.stringify(cursor)).toString('base64url')};\n}\n\nfunction invalid():never { throw new AgentError('INVALID_CURSOR','The page cursor is invalid for this collection.'); }\n"]}
@@ -0,0 +1,8 @@
1
+ import type { CompleteResponse, SdkTaskSnapshot } from './snapshots.js';
2
+ import { type Task } from './types.js';
3
+ export interface TerminalCapture {
4
+ readonly snapshot: SdkTaskSnapshot;
5
+ readonly response?: CompleteResponse;
6
+ }
7
+ export declare function terminalInterval(task: Task, read: () => SdkTaskSnapshot, signal?: AbortSignal): Promise<TerminalCapture>;
8
+ export declare function responseReplay(task: Task, start: number, signal?: AbortSignal): AsyncIterable<CompleteResponse>;
@@ -0,0 +1,75 @@
1
+ import { AgentError } from '../errors.js';
2
+ import { detached } from './snapshots.js';
3
+ import { terminal } from './types.js';
4
+ export function terminalInterval(task, read, signal) {
5
+ if (signal?.aborted)
6
+ return Promise.reject(closed());
7
+ return new Promise((resolve, reject) => {
8
+ let settled = false;
9
+ const cleanup = () => { task.watchers.delete(change); signal?.removeEventListener('abort', abort); };
10
+ const change = () => {
11
+ if (settled || !terminal(task.state))
12
+ return;
13
+ settled = true;
14
+ cleanup();
15
+ const response = task.responses.at(-1);
16
+ resolve({ snapshot: read(), ...(response ? { response: detached(response) } : {}) });
17
+ };
18
+ const abort = () => { if (!settled) {
19
+ settled = true;
20
+ cleanup();
21
+ reject(closed());
22
+ } };
23
+ task.watchers.add(change);
24
+ signal?.addEventListener('abort', abort, { once: true });
25
+ change();
26
+ });
27
+ }
28
+ export function responseReplay(task, start, signal) {
29
+ return {
30
+ [Symbol.asyncIterator]() {
31
+ let position = start, boundary, ended = false;
32
+ const wakes = new Set();
33
+ const wakeAll = () => { for (const wake of wakes)
34
+ wake(); wakes.clear(); };
35
+ const detach = () => { task.watchers.delete(changed); signal?.removeEventListener('abort', aborted); };
36
+ const changed = () => {
37
+ if (terminal(task.state) && boundary === undefined) {
38
+ boundary = task.responses.length;
39
+ detach();
40
+ }
41
+ wakeAll();
42
+ };
43
+ const cleanup = () => { ended = true; detach(); wakeAll(); };
44
+ const aborted = () => cleanup();
45
+ if (!signal?.aborted) {
46
+ task.watchers.add(changed);
47
+ signal?.addEventListener('abort', aborted, { once: true });
48
+ changed();
49
+ }
50
+ return {
51
+ async next() {
52
+ for (;;) {
53
+ if (signal?.aborted) {
54
+ cleanup();
55
+ throw closed();
56
+ }
57
+ if (ended)
58
+ return { done: true, value: undefined };
59
+ const limit = boundary ?? task.responses.length;
60
+ if (position < limit)
61
+ return { done: false, value: detached(task.responses[position++]) };
62
+ if (boundary !== undefined || ended) {
63
+ cleanup();
64
+ return { done: true, value: undefined };
65
+ }
66
+ await new Promise(resolve => { wakes.add(resolve); });
67
+ }
68
+ },
69
+ async return() { cleanup(); return { done: true, value: undefined }; },
70
+ };
71
+ },
72
+ };
73
+ }
74
+ const closed = () => new AgentError('OBSERVATION_CLOSED', 'The observer disconnected.');
75
+ //# sourceMappingURL=sdk-observation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-observation.js","sourceRoot":"","sources":["../../src/runtime/sdk-observation.ts"],"names":[],"mappings":"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","sourcesContent":["import { AgentError } from '../errors.js';\nimport type { CompleteResponse, SdkTaskSnapshot } from './snapshots.js';\nimport { detached } from './snapshots.js';\nimport { terminal, type Task } from './types.js';\n\nexport interface TerminalCapture {\n readonly snapshot: SdkTaskSnapshot;\n readonly response?: CompleteResponse;\n}\n\nexport function terminalInterval(task: Task, read: () => SdkTaskSnapshot, signal?: AbortSignal): Promise<TerminalCapture> {\n if (signal?.aborted) return Promise.reject(closed());\n return new Promise((resolve,reject) => {\n let settled = false;\n const cleanup = () => { task.watchers.delete(change); signal?.removeEventListener('abort',abort); };\n const change = () => {\n if (settled || !terminal(task.state)) return;\n settled=true; cleanup();\n const response=task.responses.at(-1);\n resolve({snapshot:read(),...(response ? {response:detached(response)} : {})});\n };\n const abort = () => { if (!settled) { settled=true; cleanup(); reject(closed()); } };\n task.watchers.add(change);\n signal?.addEventListener('abort',abort,{once:true});\n change();\n });\n}\n\nexport function responseReplay(task: Task, start: number, signal?: AbortSignal): AsyncIterable<CompleteResponse> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<CompleteResponse> {\n let position=start, boundary:number|undefined, ended=false;\n const wakes=new Set<()=>void>();\n const wakeAll=()=>{ for (const wake of wakes) wake(); wakes.clear(); };\n const detach=()=>{ task.watchers.delete(changed); signal?.removeEventListener('abort',aborted); };\n const changed=()=>{\n if (terminal(task.state) && boundary === undefined) { boundary=task.responses.length; detach(); }\n wakeAll();\n };\n const cleanup=()=>{ ended=true; detach(); wakeAll(); };\n const aborted=()=>cleanup();\n if (!signal?.aborted) {\n task.watchers.add(changed);\n signal?.addEventListener('abort',aborted,{once:true});\n changed();\n }\n return {\n async next() {\n for (;;) {\n if (signal?.aborted) { cleanup(); throw closed(); }\n if (ended) return {done:true,value:undefined};\n const limit=boundary ?? task.responses.length;\n if (position < limit) return {done:false,value:detached(task.responses[position++]!)};\n if (boundary !== undefined || ended) { cleanup(); return {done:true,value:undefined}; }\n await new Promise<void>(resolve=>{ wakes.add(resolve); });\n }\n },\n async return() { cleanup(); return {done:true,value:undefined}; },\n };\n },\n };\n}\n\nconst closed=()=>new AgentError('OBSERVATION_CLOSED','The observer disconnected.');\n"]}
@@ -0,0 +1,8 @@
1
+ import type { HarnessKind } from '../sdk/types.js';
2
+ import type { DashboardWorkspace } from './dashboard.js';
3
+ import type { SdkApprovalRequest } from './task-data.js';
4
+ import type { SdkSessionSummary, SdkTaskSnapshot, SdkTaskSummary } from './snapshots.js';
5
+ import type { Session, Task } from './types.js';
6
+ export declare function sdkTaskSummary(task: Task, selectedHarness?: HarnessKind): SdkTaskSummary;
7
+ export declare function sdkTaskSnapshot(task: Task, summary: (task: Task) => SdkTaskSummary, lookup: (id: string) => Task, requests: readonly SdkApprovalRequest[]): SdkTaskSnapshot;
8
+ export declare function sdkSessionSummary(session: Session, workspace: DashboardWorkspace, summary: (task: Task) => SdkTaskSummary, lookup: (id: string) => Task): SdkSessionSummary;
@@ -0,0 +1,19 @@
1
+ export function sdkTaskSummary(task, selectedHarness) {
2
+ return { taskId: task.id, sessionId: task.sessionId, state: task.state,
3
+ ...(selectedHarness ? { selectedHarness } : {}), title: task.title, ordinal: task.ordinal, updatedAt: task.updatedAt,
4
+ ...(task.dispatchedAt === undefined ? {} : { dispatchedAt: task.dispatchedAt }),
5
+ ...(task.failedAt === undefined ? {} : { failedAt: task.failedAt }),
6
+ ...(task.finishedAt === undefined ? {} : { finishedAt: task.finishedAt }) };
7
+ }
8
+ export function sdkTaskSnapshot(task, summary, lookup, requests) {
9
+ const response = task.responses.at(-1);
10
+ return { ...summary(task), revision: task.revision, ...(task.parentId ? { parentTaskId: task.parentId } : {}),
11
+ children: [...task.children].map(id => summary(lookup(id))), requests,
12
+ ...(response ? { latestResponse: { responseId: response.responseId, text: response.text, state: response.state } } : {}),
13
+ ...(task.error ? { error: task.error } : {}), stopUnconfirmed: task.stopUnconfirmed ?? false };
14
+ }
15
+ export function sdkSessionSummary(session, workspace, summary, lookup) {
16
+ return { sessionId: session.id, state: session.state, paused: session.paused, cwd: session.input.cwd, workspace,
17
+ ...(session.active ? { active: summary(lookup(session.active)) } : {}) };
18
+ }
19
+ //# sourceMappingURL=sdk-projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-projection.js","sourceRoot":"","sources":["../../src/runtime/sdk-projection.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,cAAc,CAAC,IAAS,EAAC,eAA4B;IACnE,OAAO,EAAC,MAAM,EAAC,IAAI,CAAC,EAAE,EAAC,SAAS,EAAC,IAAI,CAAC,SAAS,EAAC,KAAK,EAAC,IAAI,CAAC,KAAK;QAC9D,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAC,eAAe,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,KAAK,EAAC,IAAI,CAAC,KAAK,EAAC,OAAO,EAAC,IAAI,CAAC,OAAO,EAAC,SAAS,EAAC,IAAI,CAAC,SAAS;QAC5G,GAAG,CAAC,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,YAAY,EAAC,IAAI,CAAC,YAAY,EAAC,CAAC;QAC5E,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,QAAQ,EAAC,IAAI,CAAC,QAAQ,EAAC,CAAC;QAChE,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,UAAU,EAAC,IAAI,CAAC,UAAU,EAAC,CAAC,EAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAS,EAAC,OAAmC,EAC3E,MAAwB,EAAC,QAAsC;IAC/D,MAAM,QAAQ,GAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,OAAO,EAAC,GAAG,OAAO,CAAC,IAAI,CAAC,EAAC,QAAQ,EAAC,IAAI,CAAC,QAAQ,EAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAC,YAAY,EAAC,IAAI,CAAC,QAAQ,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpG,QAAQ,EAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,CAAA,EAAE,CAAA,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,QAAQ;QACjE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAC,cAAc,EAAC,EAAC,UAAU,EAAC,QAAQ,CAAC,UAAU,EAAC,IAAI,EAAC,QAAQ,CAAC,IAAI,EAAC,KAAK,EAAC,QAAQ,CAAC,KAAK,EAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9G,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAC,KAAK,EAAC,IAAI,CAAC,KAAK,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,eAAe,EAAC,IAAI,CAAC,eAAe,IAAI,KAAK,EAAC,CAAC;AAC7F,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAC,SAA4B,EAC5E,OAAmC,EAAC,MAAwB;IAC5D,OAAO,EAAC,SAAS,EAAC,OAAO,CAAC,EAAE,EAAC,KAAK,EAAC,OAAO,CAAC,KAAK,EAAC,MAAM,EAAC,OAAO,CAAC,MAAM,EAAC,GAAG,EAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAC,SAAS;QACpG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAC,MAAM,EAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC;AACzE,CAAC","sourcesContent":["import type { HarnessKind } from '../sdk/types.js';\nimport type { DashboardWorkspace } from './dashboard.js';\nimport type { SdkApprovalRequest } from './task-data.js';\nimport type { SdkSessionSummary, SdkTaskSnapshot, SdkTaskSummary } from './snapshots.js';\nimport type { Session, Task } from './types.js';\n\nexport function sdkTaskSummary(task:Task,selectedHarness?:HarnessKind):SdkTaskSummary {\n return {taskId:task.id,sessionId:task.sessionId,state:task.state,\n ...(selectedHarness ? {selectedHarness} : {}),title:task.title,ordinal:task.ordinal,updatedAt:task.updatedAt,\n ...(task.dispatchedAt === undefined ? {} : {dispatchedAt:task.dispatchedAt}),\n ...(task.failedAt === undefined ? {} : {failedAt:task.failedAt}),\n ...(task.finishedAt === undefined ? {} : {finishedAt:task.finishedAt})};\n}\n\nexport function sdkTaskSnapshot(task:Task,summary:(task:Task)=>SdkTaskSummary,\n lookup:(id:string)=>Task,requests:readonly SdkApprovalRequest[]):SdkTaskSnapshot {\n const response=task.responses.at(-1);\n return {...summary(task),revision:task.revision,...(task.parentId ? {parentTaskId:task.parentId} : {}),\n children:[...task.children].map(id=>summary(lookup(id))),requests,\n ...(response ? {latestResponse:{responseId:response.responseId,text:response.text,state:response.state}} : {}),\n ...(task.error ? {error:task.error} : {}),stopUnconfirmed:task.stopUnconfirmed ?? false};\n}\n\nexport function sdkSessionSummary(session:Session,workspace:DashboardWorkspace,\n summary:(task:Task)=>SdkTaskSummary,lookup:(id:string)=>Task):SdkSessionSummary {\n return {sessionId:session.id,state:session.state,paused:session.paused,cwd:session.input.cwd,workspace,\n ...(session.active ? {active:summary(lookup(session.active))} : {})};\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { Coordinator } from './coordinator.js';
2
+ type Request = Record<string, unknown>;
3
+ export interface SdkServiceOperations {
4
+ listAgents(data: Request): Promise<unknown>;
5
+ checkAgent(data: Request): Promise<void>;
6
+ createSession(data: Request): Promise<string>;
7
+ closeSession(id: string): Promise<void>;
8
+ }
9
+ export declare function isSdkCommand(value: unknown): boolean;
10
+ export declare function dispatchSdkRequest(engine: Coordinator, data: Request, signal: AbortSignal, operations?: SdkServiceOperations): AsyncGenerator<unknown>;
11
+ export {};
@@ -0,0 +1,109 @@
1
+ import { AgentError } from '../errors.js';
2
+ export function isSdkCommand(value) {
3
+ return typeof value === 'string' && value.startsWith('sdk-');
4
+ }
5
+ export async function* dispatchSdkRequest(engine, data, signal, operations) {
6
+ const command = text(data.command, 'SDK command');
7
+ switch (command) {
8
+ case 'sdk-agent-list':
9
+ if (!operations)
10
+ throw new AgentError('COORDINATOR_UNAVAILABLE', 'Connected agent discovery is unavailable.');
11
+ yield await operations.listAgents(data);
12
+ return;
13
+ case 'sdk-agent-check':
14
+ if (!operations)
15
+ throw new AgentError('COORDINATOR_UNAVAILABLE', 'Connected agent checks are unavailable.');
16
+ await operations.checkAgent(data);
17
+ yield { version: 1, type: 'ack' };
18
+ return;
19
+ case 'sdk-session-create': {
20
+ if (!operations)
21
+ throw new AgentError('COORDINATOR_UNAVAILABLE', 'Connected session creation is unavailable.');
22
+ const sessionId = await operations.createSession(data);
23
+ yield { version: 1, type: 'session-created', sessionId };
24
+ return;
25
+ }
26
+ case 'sdk-session-list':
27
+ yield await engine.listSessions(page(data));
28
+ return;
29
+ case 'sdk-session-get':
30
+ yield await engine.sdkSessionSnapshot(text(data.id, 'Session ID'));
31
+ return;
32
+ case 'sdk-session-prompt': {
33
+ const selected = delivery(data.delivery);
34
+ yield await engine.send(text(data.id, 'Session ID'), text(data.prompt, 'Prompt'), selected);
35
+ return;
36
+ }
37
+ case 'sdk-session-close':
38
+ if (operations)
39
+ await operations.closeSession(text(data.id, 'Session ID'));
40
+ else
41
+ await engine.closeSession(text(data.id, 'Session ID'));
42
+ yield { version: 1, type: 'ack' };
43
+ return;
44
+ case 'sdk-task-list':
45
+ yield engine.listTasks({ ...page(data), ...(data.sessionId === undefined ? {} : { sessionId: text(data.sessionId, 'Session ID') }) });
46
+ return;
47
+ case 'sdk-task-get':
48
+ case 'sdk-task-snapshot':
49
+ yield engine.sdkTaskSnapshot(text(data.id, 'Task ID'));
50
+ return;
51
+ case 'sdk-task-inspect':
52
+ yield engine.taskDetails(text(data.id, 'Task ID'));
53
+ return;
54
+ case 'sdk-task-result':
55
+ yield await engine.taskResult(text(data.id, 'Task ID'), signal);
56
+ return;
57
+ case 'sdk-task-watch':
58
+ for await (const snapshot of engine.watchTask(text(data.id, 'Task ID'), signal))
59
+ yield snapshot;
60
+ return;
61
+ case 'sdk-task-responses':
62
+ for await (const response of engine.taskResponses(text(data.id, 'Task ID'), optionalString(data.after, 'Response cursor'), signal))
63
+ yield response;
64
+ return;
65
+ case 'sdk-task-cancel': {
66
+ const id = text(data.id, 'Task ID');
67
+ await engine.cancel(id);
68
+ yield engine.sdkTaskSnapshot(id);
69
+ return;
70
+ }
71
+ case 'sdk-approval-respond':
72
+ engine.respondSdk(text(data.id, 'Approval ID'), data.response);
73
+ yield { version: 1, type: 'ack' };
74
+ return;
75
+ default: throw new AgentError('INVALID_ARGUMENT', 'Unknown SDK coordinator operation.');
76
+ }
77
+ }
78
+ function page(data) {
79
+ const result = {};
80
+ if (data.limit !== undefined) {
81
+ if (!Number.isSafeInteger(data.limit) || data.limit <= 0)
82
+ throw new AgentError('INVALID_ARGUMENT', 'Page limit must be a positive integer.');
83
+ result.limit = data.limit;
84
+ }
85
+ if (data.cursor !== undefined)
86
+ result.cursor = string(data.cursor, 'Page cursor');
87
+ return result;
88
+ }
89
+ function delivery(value) {
90
+ if (value === undefined)
91
+ return 'queue';
92
+ if (value !== 'queue' && value !== 'steer' && value !== 'interrupt')
93
+ throw new AgentError('INVALID_ARGUMENT', 'Unknown delivery mode.');
94
+ return value;
95
+ }
96
+ function text(value, label) {
97
+ if (typeof value !== 'string' || !value)
98
+ throw new AgentError('INVALID_ARGUMENT', `${label} must be a nonempty string.`);
99
+ return value;
100
+ }
101
+ function string(value, label) {
102
+ if (typeof value !== 'string')
103
+ throw new AgentError('INVALID_ARGUMENT', `${label} must be a string.`);
104
+ return value;
105
+ }
106
+ function optionalString(value, label) {
107
+ return value === undefined ? undefined : string(value, label);
108
+ }
109
+ //# sourceMappingURL=sdk-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-service.js","sourceRoot":"","sources":["../../src/runtime/sdk-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { AgentError } from '../errors.js';\nimport type { Coordinator } from './coordinator.js';\nimport type { Delivery } from './types.js';\n\ntype Request=Record<string,unknown>;\nexport interface SdkServiceOperations {\n listAgents(data:Request):Promise<unknown>;\n checkAgent(data:Request):Promise<void>;\n createSession(data:Request):Promise<string>;\n closeSession(id:string):Promise<void>;\n}\n\nexport function isSdkCommand(value:unknown):boolean {\n return typeof value === 'string' && value.startsWith('sdk-');\n}\n\nexport async function* dispatchSdkRequest(\n engine:Coordinator,\n data:Request,\n signal:AbortSignal,\n operations?:SdkServiceOperations,\n):AsyncGenerator<unknown> {\n const command=text(data.command,'SDK command');\n switch(command) {\n case 'sdk-agent-list':\n if (!operations) throw new AgentError('COORDINATOR_UNAVAILABLE','Connected agent discovery is unavailable.');\n yield await operations.listAgents(data); return;\n case 'sdk-agent-check':\n if (!operations) throw new AgentError('COORDINATOR_UNAVAILABLE','Connected agent checks are unavailable.');\n await operations.checkAgent(data); yield {version:1,type:'ack'}; return;\n case 'sdk-session-create': {\n if (!operations) throw new AgentError('COORDINATOR_UNAVAILABLE','Connected session creation is unavailable.');\n const sessionId=await operations.createSession(data);\n yield {version:1,type:'session-created',sessionId}; return;\n }\n case 'sdk-session-list':\n yield await engine.listSessions(page(data)); return;\n case 'sdk-session-get':\n yield await engine.sdkSessionSnapshot(text(data.id,'Session ID')); return;\n case 'sdk-session-prompt': {\n const selected=delivery(data.delivery);\n yield await engine.send(text(data.id,'Session ID'),text(data.prompt,'Prompt'),selected); return;\n }\n case 'sdk-session-close':\n if (operations) await operations.closeSession(text(data.id,'Session ID'));\n else await engine.closeSession(text(data.id,'Session ID'));\n yield {version:1,type:'ack'}; return;\n case 'sdk-task-list':\n yield engine.listTasks({...page(data),...(data.sessionId === undefined ? {} : {sessionId:text(data.sessionId,'Session ID')})}); return;\n case 'sdk-task-get':\n case 'sdk-task-snapshot':\n yield engine.sdkTaskSnapshot(text(data.id,'Task ID')); return;\n case 'sdk-task-inspect':\n yield engine.taskDetails(text(data.id,'Task ID')); return;\n case 'sdk-task-result':\n yield await engine.taskResult(text(data.id,'Task ID'),signal); return;\n case 'sdk-task-watch':\n for await (const snapshot of engine.watchTask(text(data.id,'Task ID'),signal)) yield snapshot;\n return;\n case 'sdk-task-responses':\n for await (const response of engine.taskResponses(text(data.id,'Task ID'),optionalString(data.after,'Response cursor'),signal)) yield response;\n return;\n case 'sdk-task-cancel': {\n const id=text(data.id,'Task ID');\n await engine.cancel(id); yield engine.sdkTaskSnapshot(id); return;\n }\n case 'sdk-approval-respond':\n engine.respondSdk(text(data.id,'Approval ID'),data.response as never);\n yield {version:1,type:'ack'}; return;\n default: throw new AgentError('INVALID_ARGUMENT','Unknown SDK coordinator operation.');\n }\n}\n\nfunction page(data:Request):{limit?:number;cursor?:string} {\n const result:{limit?:number;cursor?:string}={};\n if (data.limit !== undefined) {\n if (!Number.isSafeInteger(data.limit) || (data.limit as number) <= 0)\n throw new AgentError('INVALID_ARGUMENT','Page limit must be a positive integer.');\n result.limit=data.limit as number;\n }\n if (data.cursor !== undefined) result.cursor=string(data.cursor,'Page cursor');\n return result;\n}\n\nfunction delivery(value:unknown):Delivery {\n if (value === undefined) return 'queue';\n if (value !== 'queue' && value !== 'steer' && value !== 'interrupt')\n throw new AgentError('INVALID_ARGUMENT','Unknown delivery mode.');\n return value;\n}\n\nfunction text(value:unknown,label:string):string {\n if (typeof value !== 'string' || !value) throw new AgentError('INVALID_ARGUMENT',`${label} must be a nonempty string.`);\n return value;\n}\nfunction string(value:unknown,label:string):string {\n if (typeof value !== 'string') throw new AgentError('INVALID_ARGUMENT',`${label} must be a string.`);\n return value;\n}\nfunction optionalString(value:unknown,label:string):string|undefined {\n return value === undefined ? undefined : string(value,label);\n}\n"]}
@@ -2,4 +2,7 @@ import type { HarnessKind } from '../sdk/types.js';
2
2
  import type { AdapterOptions, ExecutionDefinition, NativeSession } from '../adapters/types.js';
3
3
  import { type AccessConfig } from '../config/access.js';
4
4
  import type { ApprovalHandler } from '../approvals/types.js';
5
- export declare function selectNative(agent: ExecutionDefinition, cwd: string, env: NodeJS.ProcessEnv, settings: AccessConfig, open?: (options: AdapterOptions) => Promise<NativeSession>, selected?: (kind: HarnessKind) => void, onApproval?: ApprovalHandler): Promise<NativeSession>;
5
+ export interface NativeSelectionDiagnosticContext {
6
+ readonly origin: 'cli' | 'sdk';
7
+ }
8
+ export declare function selectNative(agent: ExecutionDefinition, cwd: string, env: NodeJS.ProcessEnv, settings: AccessConfig, open?: (options: AdapterOptions) => Promise<NativeSession>, selected?: (kind: HarnessKind) => void, onApproval?: ApprovalHandler, diagnosticContext?: NativeSelectionDiagnosticContext): Promise<NativeSession>;
@@ -1,33 +1,48 @@
1
- import { openCodex } from '../adapters/codex.js';
2
- import { openClaude } from '../adapters/claude.js';
3
- import { openFx } from '../adapters/fx.js';
4
1
  import { resolveAccess } from '../config/access.js';
2
+ import { accessAttemptContext } from '../config/access-provenance.js';
5
3
  import { AgentError } from '../errors.js';
6
- const openers = { codex: openCodex, claudeCode: openClaude, fx: openFx };
7
- export async function selectNative(agent, cwd, env, settings, open = (options) => openers[options.harness.kind](options), selected = () => { }, onApproval) {
4
+ import { withAccessContext, withSessionAccessContext } from './access-errors.js';
5
+ const openers = {
6
+ codex: async (options) => (await import('../adapters/codex.js')).openCodex(options),
7
+ claudeCode: async (options) => (await import('../adapters/claude.js')).openClaude(options),
8
+ fx: async (options) => (await import('../adapters/fx.js')).openFx(options),
9
+ opencode: async (options) => (await import('../adapters/opencode.js')).openOpencode(options),
10
+ copilot: async (options) => (await import('../adapters/copilot.js')).openCopilot(options),
11
+ cursor: async (options) => (await import('../adapters/cursor.js')).openCursor(options),
12
+ };
13
+ export async function selectNative(agent, cwd, env, settings, open = (options) => openers[options.harness.kind](options), selected = () => { }, onApproval, diagnosticContext = { origin: 'cli' }) {
8
14
  const alternatives = Array.isArray(agent.harness) ? agent.harness : [agent.harness];
9
15
  const unavailable = [];
10
16
  for (const harness of alternatives) {
11
17
  const configuredConnections = settings.access?.[harness.kind];
18
+ const explicitAccessRequired = ['fx', 'opencode', 'copilot', 'cursor'].includes(harness.kind);
12
19
  const connections = configuredConnections ??
13
- (harness.kind === 'fx' ? [] : [{ type: 'subscription' }]);
20
+ (explicitAccessRequired ? [] : [{ type: 'subscription' }]);
14
21
  if (configuredConnections?.length === 0) {
15
- unavailable.push(`${harness.kind}: Access is disabled in the main checkout's .subharness/agents.local.json.`);
22
+ unavailable.push(diagnosticContext.origin === 'sdk'
23
+ ? `${harness.kind}: Access is disabled by the empty connection list in RunnerOptions.access.`
24
+ : `${harness.kind}: Access is disabled in the main checkout's .subharness/agents.local.json.`);
16
25
  }
17
- else if (harness.kind === 'fx' && !connections.length) {
18
- unavailable.push('fx: Enable an explicit AI Gateway connection in personal access settings.');
26
+ else if (!connections.length && explicitAccessRequired) {
27
+ const setting = diagnosticContext.origin === 'sdk' ? 'RunnerOptions.access' : 'personal access settings';
28
+ const guidance = harness.kind === 'cursor' ? 'Cursor subscription or API-key'
29
+ : 'native login, API-key, or Gateway';
30
+ unavailable.push(`${harness.kind}: Enable an explicit ${guidance} connection in ${setting}.`);
19
31
  }
20
- for (const connection of connections) {
32
+ for (const [index, connection] of connections.entries()) {
33
+ const context = accessAttemptContext(settings, harness.kind, connection, index, connections.length);
21
34
  try {
22
35
  const access = await resolveAccess(connection, harness.kind, cwd, env);
23
36
  const native = await open({ agent, harness, cwd, env, access, ...(onApproval ? { onApproval } : {}) });
24
37
  selected(harness.kind);
25
- return native;
38
+ return withSessionAccessContext(native, context);
26
39
  }
27
40
  catch (error) {
28
- if (!(error instanceof AgentError) || !['HARNESS_UNAVAILABLE', 'ACCESS_UNAVAILABLE'].includes(error.code))
41
+ if (!(error instanceof AgentError))
29
42
  throw error;
30
- unavailable.push(`${harness.kind}: ${error.message}`);
43
+ if (!['HARNESS_UNAVAILABLE', 'ACCESS_UNAVAILABLE'].includes(error.code))
44
+ throw withAccessContext(error, context);
45
+ unavailable.push(`${harness.kind}: ${withAccessContext(error, context).message}`);
31
46
  }
32
47
  }
33
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"select-native.js","sourceRoot":"","sources":["../../src/runtime/select-native.ts"],"names":[],"mappings":"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","sourcesContent":["import type { HarnessKind } from '../sdk/types.js';\nimport type { AdapterOptions, ExecutionDefinition, NativeSession } from '../adapters/types.js';\nimport { openCodex } from '../adapters/codex.js';\nimport { openClaude } from '../adapters/claude.js';\nimport { openFx } from '../adapters/fx.js';\nimport { resolveAccess, type AccessConfig } from '../config/access.js';\nimport { AgentError } from '../errors.js';\nimport type { ApprovalHandler } from '../approvals/types.js';\n\nconst openers = {codex:openCodex,claudeCode:openClaude,fx:openFx};\n\nexport async function selectNative(\n agent: ExecutionDefinition, cwd: string, env: NodeJS.ProcessEnv, settings: AccessConfig,\n open = (options: AdapterOptions): Promise<NativeSession> => openers[options.harness.kind](options),\n selected: (kind: HarnessKind) => void = () => {},\n onApproval?: ApprovalHandler,\n): Promise<NativeSession> {\n const alternatives = Array.isArray(agent.harness) ? agent.harness : [agent.harness];\n const unavailable: string[] = [];\n for (const harness of alternatives) {\n const configuredConnections = settings.access?.[harness.kind as HarnessKind];\n const connections = configuredConnections ??\n (harness.kind === 'fx' ? [] : [{type:'subscription' as const}]);\n if (configuredConnections?.length === 0) {\n unavailable.push(`${harness.kind}: Access is disabled in the main checkout's .subharness/agents.local.json.`);\n } else if (harness.kind === 'fx' && !connections.length) {\n unavailable.push('fx: Enable an explicit AI Gateway connection in personal access settings.');\n }\n for (const connection of connections) {\n try {\n const access = await resolveAccess(connection, harness.kind, cwd, env);\n const native = await open({agent,harness,cwd,env,access,...(onApproval ? {onApproval} : {})});\n selected(harness.kind);\n return native;\n } catch (error) {\n if (!(error instanceof AgentError) || !['HARNESS_UNAVAILABLE','ACCESS_UNAVAILABLE'].includes(error.code)) throw error;\n unavailable.push(`${harness.kind}: ${error.message}`);\n }\n }\n }\n throw new AgentError('ACCESS_UNAVAILABLE', unavailable.length ? unavailable.join('\\n') : 'No declared harness has enabled access.');\n}\n"]}
1
+ {"version":3,"file":"select-native.js","sourceRoot":"","sources":["../../src/runtime/select-native.ts"],"names":[],"mappings":"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","sourcesContent":["import type { HarnessKind } from '../sdk/types.js';\nimport type { AdapterOptions, ExecutionDefinition, NativeSession } from '../adapters/types.js';\nimport { resolveAccess, type AccessConfig } from '../config/access.js';\nimport { accessAttemptContext } from '../config/access-provenance.js';\nimport { AgentError } from '../errors.js';\nimport type { ApprovalHandler } from '../approvals/types.js';\nimport { withAccessContext, withSessionAccessContext } from './access-errors.js';\n\nconst openers = {\n codex: async (options: AdapterOptions) => (await import('../adapters/codex.js')).openCodex(options),\n claudeCode: async (options: AdapterOptions) => (await import('../adapters/claude.js')).openClaude(options),\n fx: async (options: AdapterOptions) => (await import('../adapters/fx.js')).openFx(options),\n opencode: async (options: AdapterOptions) => (await import('../adapters/opencode.js')).openOpencode(options),\n copilot: async (options: AdapterOptions) => (await import('../adapters/copilot.js')).openCopilot(options),\n cursor: async (options: AdapterOptions) => (await import('../adapters/cursor.js')).openCursor(options),\n} satisfies Record<HarnessKind, (options: AdapterOptions) => Promise<NativeSession>>;\n\nexport interface NativeSelectionDiagnosticContext {\n readonly origin: 'cli' | 'sdk';\n}\n\nexport async function selectNative(\n agent: ExecutionDefinition, cwd: string, env: NodeJS.ProcessEnv, settings: AccessConfig,\n open = (options: AdapterOptions): Promise<NativeSession> => openers[options.harness.kind](options),\n selected: (kind: HarnessKind) => void = () => {},\n onApproval?: ApprovalHandler,\n diagnosticContext: NativeSelectionDiagnosticContext = {origin: 'cli'},\n): Promise<NativeSession> {\n const alternatives = Array.isArray(agent.harness) ? agent.harness : [agent.harness];\n const unavailable: string[] = [];\n for (const harness of alternatives) {\n const configuredConnections = settings.access?.[harness.kind as HarnessKind];\n const explicitAccessRequired = ['fx','opencode','copilot','cursor'].includes(harness.kind);\n const connections = configuredConnections ??\n (explicitAccessRequired ? [] : [{type:'subscription' as const}]);\n if (configuredConnections?.length === 0) {\n unavailable.push(diagnosticContext.origin === 'sdk'\n ? `${harness.kind}: Access is disabled by the empty connection list in RunnerOptions.access.`\n : `${harness.kind}: Access is disabled in the main checkout's .subharness/agents.local.json.`);\n } else if (!connections.length && explicitAccessRequired) {\n const setting = diagnosticContext.origin === 'sdk' ? 'RunnerOptions.access' : 'personal access settings';\n const guidance = harness.kind === 'cursor' ? 'Cursor subscription or API-key'\n : 'native login, API-key, or Gateway';\n unavailable.push(`${harness.kind}: Enable an explicit ${guidance} connection in ${setting}.`);\n }\n for (const [index, connection] of connections.entries()) {\n const context = accessAttemptContext(settings, harness.kind, connection, index, connections.length);\n try {\n const access = await resolveAccess(connection, harness.kind, cwd, env);\n const native = await open({agent,harness,cwd,env,access,...(onApproval ? {onApproval} : {})});\n selected(harness.kind);\n return withSessionAccessContext(native, context);\n } catch (error) {\n if (!(error instanceof AgentError)) throw error;\n if (!['HARNESS_UNAVAILABLE','ACCESS_UNAVAILABLE'].includes(error.code)) throw withAccessContext(error, context);\n unavailable.push(`${harness.kind}: ${withAccessContext(error, context).message}`);\n }\n }\n }\n throw new AgentError('ACCESS_UNAVAILABLE', unavailable.length ? unavailable.join('\\n') : 'No declared harness has enabled access.');\n}\n"]}
@@ -1,5 +1,15 @@
1
1
  import { Coordinator } from './coordinator.js';
2
- export declare function startService(engine: Coordinator, token: string, instanceId: string): Promise<{
2
+ import { captureExecution, captureReference, checkCapturedExecution, type CapturedExecution } from './capture.js';
3
+ export interface ServiceCaptureOperations {
4
+ captureExecution: typeof captureExecution;
5
+ captureReference: typeof captureReference;
6
+ checkCapturedExecution: typeof checkCapturedExecution;
7
+ }
8
+ export interface ServiceOptions {
9
+ readonly initialCaptures?: ReadonlyMap<string, CapturedExecution>;
10
+ readonly capture?: Partial<ServiceCaptureOperations>;
11
+ }
12
+ export declare function startService(engine: Coordinator, token: string, instanceId: string, state?: string, options?: ServiceOptions): Promise<{
3
13
  url: string;
4
14
  close(): Promise<void>;
5
15
  }>;