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
@@ -0,0 +1,320 @@
1
+ import { fork } from 'node:child_process';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { randomUUID } from 'node:crypto';
4
+ import { AgentError, errorInfo } from '../errors.js';
5
+ import { createSessionLauncher } from './session-launcher.js';
6
+ import { processExitDescription } from '../process-diagnostics.js';
7
+ const shutdownTimeoutMs = 1_000;
8
+ class GraphConnection {
9
+ child;
10
+ timeout;
11
+ nextId = 1;
12
+ pending = new Map();
13
+ approvals = new Map();
14
+ handlers = new Map();
15
+ exited = false;
16
+ leases = new Set();
17
+ abandonedLeases = new Set();
18
+ observedExit = '';
19
+ processExit;
20
+ markExited;
21
+ constructor(child, timeout) {
22
+ this.child = child;
23
+ this.timeout = timeout;
24
+ this.processExit = new Promise(resolve => { this.markExited = resolve; });
25
+ child.once('error', () => this.exit(undefined, undefined, true));
26
+ child.once('exit', (code, signal) => this.exit(code, signal));
27
+ child.on('message', (message) => this.message(message));
28
+ }
29
+ setApprovalHandler(leaseId, handler) { this.handlers.set(leaseId, handler); }
30
+ deleteApprovalHandler(leaseId) { this.handlers.delete(leaseId); }
31
+ retainLease(leaseId) { this.leases.add(leaseId); }
32
+ async releaseLease(leaseId) {
33
+ this.leases.delete(leaseId);
34
+ await this.retryAbandonedLeases();
35
+ const retained = [...this.leases].filter(id => !this.abandonedLeases.has(id));
36
+ if (retained.length !== 0)
37
+ return;
38
+ if (this.abandonedLeases.size) {
39
+ this.abandonedLeases.clear();
40
+ this.leases.clear();
41
+ await this.stop();
42
+ return;
43
+ }
44
+ if (await this.waitWithin(this.timeout))
45
+ return;
46
+ await this.stop();
47
+ }
48
+ async abandonLease(leaseId) {
49
+ if (!this.leases.has(leaseId))
50
+ return;
51
+ const siblings = [...this.leases].filter(id => id !== leaseId && !this.abandonedLeases.has(id));
52
+ if (siblings.length) {
53
+ this.abandonedLeases.add(leaseId);
54
+ return;
55
+ }
56
+ this.leases.delete(leaseId);
57
+ await this.stop();
58
+ }
59
+ async retryAbandonedLeases() {
60
+ for (const leaseId of [...this.abandonedLeases]) {
61
+ try {
62
+ await this.request('lease.close', { leaseId });
63
+ this.abandonedLeases.delete(leaseId);
64
+ this.leases.delete(leaseId);
65
+ }
66
+ catch { /* Retain ownership until the remaining graph leases close. */ }
67
+ }
68
+ }
69
+ request(method, extra = {}) {
70
+ return new Promise((resolve, reject) => {
71
+ if (this.exited) {
72
+ reject(new AgentError('HARNESS_FAILED', `The captured definition worker is unavailable while ${method} was pending${this.observedExit}.`));
73
+ return;
74
+ }
75
+ const id = this.nextId++;
76
+ this.pending.set(id, { operation: method, resolve, reject });
77
+ this.child.send({ id, method, ...extra }, error => {
78
+ if (!error)
79
+ return;
80
+ setImmediate(() => {
81
+ const waiting = this.pending.get(id);
82
+ if (!waiting || this.exited)
83
+ return;
84
+ this.pending.delete(id);
85
+ waiting.reject(new AgentError('HARNESS_FAILED', `Cannot reach the captured definition worker while ${method} was pending.`));
86
+ });
87
+ });
88
+ });
89
+ }
90
+ message(message) {
91
+ if ('event' in message) {
92
+ const key = `${message.leaseId}:${message.requestId}`;
93
+ if (message.event === 'approval.withdraw') {
94
+ this.approvals.get(key)?.abort();
95
+ this.approvals.delete(key);
96
+ return;
97
+ }
98
+ const controller = new AbortController();
99
+ this.approvals.set(key, controller);
100
+ void Promise.resolve().then(() => {
101
+ const handler = this.handlers.get(message.leaseId);
102
+ if (!handler)
103
+ throw new AgentError('INPUT_REQUIRED', 'Native tool approval requires an observing caller.');
104
+ return handler(message.request, controller.signal);
105
+ }).then(content => { if (!controller.signal.aborted && !this.exited)
106
+ return this.request('approval.respond', { leaseId: message.leaseId, requestId: message.requestId, content }); }, error => { if (!controller.signal.aborted && !this.exited)
107
+ return this.request('approval.respond', { leaseId: message.leaseId, requestId: message.requestId, error: errorInfo(error) }); }).catch(error => {
108
+ if (!controller.signal.aborted && !this.exited)
109
+ return this.request('approval.respond', { leaseId: message.leaseId, requestId: message.requestId, error: errorInfo(error) }).catch(() => { });
110
+ }).finally(() => this.approvals.delete(key));
111
+ return;
112
+ }
113
+ const waiting = this.pending.get(message.id);
114
+ if (!waiting)
115
+ return;
116
+ this.pending.delete(message.id);
117
+ if (message.error)
118
+ waiting.reject(new AgentError(message.error.code, message.error.message));
119
+ else
120
+ waiting.resolve(message.result);
121
+ }
122
+ exit(code, signal, spawnFailure = false) {
123
+ if (this.exited)
124
+ return;
125
+ this.exited = true;
126
+ this.observedExit = spawnFailure ? '' : processExitDescription(code, signal);
127
+ for (const controller of this.approvals.values())
128
+ controller.abort();
129
+ this.approvals.clear();
130
+ this.markExited();
131
+ for (const waiting of this.pending.values())
132
+ waiting.reject(new AgentError('HARNESS_FAILED', spawnFailure
133
+ ? `The captured definition worker process failed while ${waiting.operation} was pending.`
134
+ : `The captured definition worker exited while ${waiting.operation} was pending${this.observedExit}.`));
135
+ this.pending.clear();
136
+ }
137
+ async stop() {
138
+ if (this.exited)
139
+ return;
140
+ if (this.child.connected)
141
+ try {
142
+ this.child.disconnect();
143
+ }
144
+ catch { }
145
+ if (await this.waitWithin(this.timeout))
146
+ return;
147
+ this.child.kill('SIGTERM');
148
+ if (await this.waitWithin(this.timeout))
149
+ return;
150
+ this.child.kill('SIGKILL');
151
+ if (!await this.waitWithin(this.timeout))
152
+ throw new AgentError('HARNESS_FAILED', 'The captured definition worker did not confirm termination.');
153
+ }
154
+ waitWithin(timeout) {
155
+ return new Promise(resolve => {
156
+ const timer = setTimeout(() => resolve(false), timeout);
157
+ this.processExit.then(() => { clearTimeout(timer); resolve(true); });
158
+ });
159
+ }
160
+ }
161
+ class CaptureLease {
162
+ graph;
163
+ leaseId;
164
+ reference;
165
+ prepared;
166
+ children;
167
+ launcher;
168
+ nativeClosed = false;
169
+ released = false;
170
+ closing = false;
171
+ opening;
172
+ constructor(graph, leaseId, reference, children) {
173
+ this.graph = graph;
174
+ this.leaseId = leaseId;
175
+ this.reference = reference;
176
+ this.graph.retainLease(leaseId);
177
+ this.children = Object.freeze(children.map(child => Object.freeze({ ...child })));
178
+ this.prepared = { open: input => this.open(input), close: () => this.close() };
179
+ }
180
+ async child(name) {
181
+ if (this.released)
182
+ throw new AgentError('INVALID_PARENT', 'The captured parent context is closed.');
183
+ const result = await this.graph.request('child', { leaseId: this.leaseId, name });
184
+ return new CaptureLease(this.graph, result.leaseId, result.reference, result.children);
185
+ }
186
+ async open(input) {
187
+ if (this.released || this.closing || this.opening)
188
+ throw new AgentError('HARNESS_FAILED', 'Native session startup is unavailable.');
189
+ const opening = this.startOpen(input);
190
+ this.opening = opening;
191
+ return opening;
192
+ }
193
+ async startOpen(input) {
194
+ const state = input.env.AGENT_STATE_DIR;
195
+ if (typeof state !== 'string' || !state)
196
+ throw new AgentError('INVALID_CONFIG', 'AGENT_STATE_DIR must select the coordinator state directory.');
197
+ const launcher = await createSessionLauncher(state, input.token);
198
+ this.launcher = launcher;
199
+ if (this.closing) {
200
+ await launcher.close();
201
+ this.launcher = undefined;
202
+ throw new AgentError('COORDINATOR_UNAVAILABLE', 'The captured session closed during startup.');
203
+ }
204
+ const { onApproval, ...serializedInput } = input;
205
+ let selectedHarness;
206
+ try {
207
+ this.graph.setApprovalHandler(this.leaseId, onApproval);
208
+ selectedHarness = await this.graph.request('open', { leaseId: this.leaseId, input: serializedInput,
209
+ handlesApprovals: !!onApproval, launcherPath: launcher.path });
210
+ }
211
+ catch (error) {
212
+ this.graph.deleteApprovalHandler(this.leaseId);
213
+ this.launcher = undefined;
214
+ await launcher.close();
215
+ throw error;
216
+ }
217
+ const request = (method, extra = {}) => this.graph.request(method, { leaseId: this.leaseId, ...extra });
218
+ return {
219
+ selectedHarness,
220
+ turn: prompt => request('turn', { prompt }),
221
+ steer: async (prompt) => { await request('steer', { prompt }); },
222
+ interrupt: async () => { await request('interrupt'); },
223
+ resume: () => request('resume'),
224
+ close: async () => {
225
+ if (this.nativeClosed)
226
+ return;
227
+ await request('native.close');
228
+ this.nativeClosed = true;
229
+ this.graph.deleteApprovalHandler(this.leaseId);
230
+ },
231
+ };
232
+ }
233
+ async close() {
234
+ this.closing = true;
235
+ if (!this.released) {
236
+ await this.graph.request('lease.close', { leaseId: this.leaseId });
237
+ this.released = true;
238
+ this.nativeClosed = true;
239
+ this.graph.deleteApprovalHandler(this.leaseId);
240
+ }
241
+ await this.opening?.catch(() => undefined);
242
+ if (this.launcher) {
243
+ await this.launcher.close();
244
+ this.launcher = undefined;
245
+ }
246
+ await this.graph.releaseLease(this.leaseId);
247
+ }
248
+ async abandonFailedCheck() {
249
+ this.closing = true;
250
+ this.released = true;
251
+ this.nativeClosed = true;
252
+ this.graph.deleteApprovalHandler(this.leaseId);
253
+ await this.opening?.catch(() => undefined);
254
+ if (this.launcher) {
255
+ await this.launcher.close().catch(() => { });
256
+ this.launcher = undefined;
257
+ }
258
+ await this.graph.abandonLease(this.leaseId);
259
+ }
260
+ }
261
+ export async function captureExecution(agent, input, options = {}) {
262
+ return captureRequest(input, options, { method: 'capture', agent });
263
+ }
264
+ /** Captures an already resolved private CLI reference without applying public connected validation. */
265
+ export async function captureReference(reference, input, options = {}) {
266
+ if ('kind' in reference && reference.kind === 'inline')
267
+ throw new AgentError('INVALID_DEFINITION', 'Inline agent definitions cannot be loaded by native CLI workers.');
268
+ return captureRequest(input, options, { method: 'capture.reference', reference });
269
+ }
270
+ async function captureRequest(input, options, request) {
271
+ const { AGENT_PARENT_TOKEN: _parent, AGENT_CLI_PATH: _launcher, ...environment } = input.env;
272
+ const workerModule = options.workerModule ?? new URL(`./worker.${import.meta.url.endsWith('.ts') ? 'ts' : 'js'}`, import.meta.url);
273
+ const extension = workerModule.pathname.endsWith('.ts') ? 'ts' : 'js';
274
+ let child;
275
+ try {
276
+ child = fork(fileURLToPath(workerModule), [], { cwd: input.cwd, env: environment, stdio: ['ignore', 'ignore', 'ignore', 'ipc'],
277
+ execArgv: extension === 'ts' ? ['--import', import.meta.resolve('tsx')] : [] });
278
+ }
279
+ catch {
280
+ throw new AgentError('INVALID_DEFINITION', 'The captured definition worker could not be spawned.');
281
+ }
282
+ const graph = new GraphConnection(child, options.shutdownTimeoutMs ?? shutdownTimeoutMs);
283
+ try {
284
+ const { method, ...data } = request;
285
+ const result = await graph.request(method, data);
286
+ return new CaptureLease(graph, result.leaseId, result.reference, result.children);
287
+ }
288
+ catch (error) {
289
+ await graph.stop().catch(() => { });
290
+ throw error;
291
+ }
292
+ }
293
+ export async function checkCapturedExecution(captured, input) {
294
+ let native;
295
+ let failure;
296
+ try {
297
+ native = await captured.prepared.open({ reference: captured.reference, cwd: input.cwd, env: input.env,
298
+ token: randomUUID(), sessionId: `check_${randomUUID()}` });
299
+ await native.close();
300
+ }
301
+ catch (error) {
302
+ failure = error;
303
+ }
304
+ try {
305
+ await captured.prepared.close();
306
+ }
307
+ catch (error) {
308
+ failure ??= error;
309
+ try {
310
+ await captured.prepared.close();
311
+ }
312
+ catch {
313
+ if (captured instanceof CaptureLease)
314
+ await captured.abandonFailedCheck();
315
+ }
316
+ }
317
+ if (failure)
318
+ throw failure;
319
+ }
320
+ //# sourceMappingURL=capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/runtime/capture.ts"],"names":[],"mappings":"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","sourcesContent":["import { fork, type ChildProcess } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport { randomUUID } from 'node:crypto';\nimport { AgentError, errorInfo, type ErrorInfo } from '../errors.js';\nimport type { ApprovalHandler } from '../approvals/types.js';\nimport type { HarnessConfig, HarnessKind } from '../sdk/types.js';\nimport type { CatalogEnvironment } from './catalog.js';\nimport type { DriverInput, ExecutionReference, ManagedNativeSession, PreparedExecution } from './types.js';\nimport type { ApprovalEvent } from './worker-approvals.js';\nimport { createSessionLauncher } from './session-launcher.js';\nimport { processExitDescription } from '../process-diagnostics.js';\n\nexport interface CapturedChild {\n readonly name: string;\n readonly description: string;\n}\n\nexport interface CapturedExecution {\n readonly reference: ExecutionReference;\n readonly prepared: PreparedExecution;\n readonly children: readonly CapturedChild[];\n child(name: string): Promise<CapturedExecution>;\n}\n\ninterface CaptureOptions { workerModule?: URL; shutdownTimeoutMs?: number }\ninterface CaptureResult {leaseId:number;reference:ExecutionReference;children:CapturedChild[]}\ntype WorkerReply = ApprovalEvent & {leaseId:number} | {id:number;result?:unknown;error?:ErrorInfo};\n\nconst shutdownTimeoutMs = 1_000;\n\nclass GraphConnection {\n private nextId=1;\n private pending=new Map<number,{operation:string;resolve(value:unknown):void;reject(error:Error):void}>();\n private approvals=new Map<string,AbortController>();\n private handlers=new Map<number,ApprovalHandler|undefined>();\n private exited=false;\n private leases=new Set<number>();\n private abandonedLeases=new Set<number>();\n private observedExit='';\n private readonly processExit:Promise<void>;\n private markExited!:()=>void;\n\n constructor(private readonly child:ChildProcess,private readonly timeout:number) {\n this.processExit=new Promise(resolve=>{this.markExited=resolve;});\n child.once('error',()=>this.exit(undefined,undefined,true));\n child.once('exit',(code,signal)=>this.exit(code,signal));\n child.on('message',(message:WorkerReply)=>this.message(message));\n }\n\n setApprovalHandler(leaseId:number,handler:ApprovalHandler|undefined) { this.handlers.set(leaseId,handler); }\n deleteApprovalHandler(leaseId:number) { this.handlers.delete(leaseId); }\n retainLease(leaseId:number) { this.leases.add(leaseId); }\n async releaseLease(leaseId:number) {\n this.leases.delete(leaseId);\n await this.retryAbandonedLeases();\n const retained=[...this.leases].filter(id=>!this.abandonedLeases.has(id));\n if(retained.length!==0)return;\n if(this.abandonedLeases.size){this.abandonedLeases.clear();this.leases.clear();await this.stop();return;}\n if(await this.waitWithin(this.timeout))return;\n await this.stop();\n }\n async abandonLease(leaseId:number) {\n if(!this.leases.has(leaseId))return;\n const siblings=[...this.leases].filter(id=>id!==leaseId&&!this.abandonedLeases.has(id));\n if(siblings.length){this.abandonedLeases.add(leaseId);return;}\n this.leases.delete(leaseId);\n await this.stop();\n }\n\n private async retryAbandonedLeases() {\n for(const leaseId of [...this.abandonedLeases]){\n try{\n await this.request('lease.close',{leaseId});\n this.abandonedLeases.delete(leaseId);this.leases.delete(leaseId);\n }catch{/* Retain ownership until the remaining graph leases close. */}\n }\n }\n\n request(method:string,extra:Record<string,unknown>={}):Promise<unknown> {\n return new Promise((resolve,reject)=>{\n if(this.exited){reject(new AgentError('HARNESS_FAILED',`The captured definition worker is unavailable while ${method} was pending${this.observedExit}.`));return;}\n const id=this.nextId++;\n this.pending.set(id,{operation:method,resolve,reject});\n this.child.send({id,method,...extra},error=>{\n if(!error)return;\n setImmediate(()=>{\n const waiting=this.pending.get(id);\n if(!waiting||this.exited)return;\n this.pending.delete(id);\n waiting.reject(new AgentError('HARNESS_FAILED',`Cannot reach the captured definition worker while ${method} was pending.`));\n });\n });\n });\n }\n\n private message(message:WorkerReply) {\n if('event' in message){\n const key=`${message.leaseId}:${message.requestId}`;\n if(message.event==='approval.withdraw'){\n this.approvals.get(key)?.abort();this.approvals.delete(key);return;\n }\n const controller=new AbortController();\n this.approvals.set(key,controller);\n void Promise.resolve().then(()=>{\n const handler=this.handlers.get(message.leaseId);\n if(!handler)throw new AgentError('INPUT_REQUIRED','Native tool approval requires an observing caller.');\n return handler(message.request,controller.signal);\n }).then(\n content=>{if(!controller.signal.aborted&&!this.exited)return this.request('approval.respond',{leaseId:message.leaseId,requestId:message.requestId,content});},\n error=>{if(!controller.signal.aborted&&!this.exited)return this.request('approval.respond',{leaseId:message.leaseId,requestId:message.requestId,error:errorInfo(error)});},\n ).catch(error=>{\n if(!controller.signal.aborted&&!this.exited)\n return this.request('approval.respond',{leaseId:message.leaseId,requestId:message.requestId,error:errorInfo(error)}).catch(()=>{});\n }).finally(()=>this.approvals.delete(key));\n return;\n }\n const waiting=this.pending.get(message.id);\n if(!waiting)return;\n this.pending.delete(message.id);\n if(message.error)waiting.reject(new AgentError(message.error.code,message.error.message));\n else waiting.resolve(message.result);\n }\n\n private exit(code:unknown,signal:unknown,spawnFailure=false) {\n if(this.exited)return;\n this.exited=true;\n this.observedExit=spawnFailure?'':processExitDescription(code,signal);\n for(const controller of this.approvals.values())controller.abort();\n this.approvals.clear();this.markExited();\n for(const waiting of this.pending.values())waiting.reject(new AgentError('HARNESS_FAILED',spawnFailure\n ?`The captured definition worker process failed while ${waiting.operation} was pending.`\n :`The captured definition worker exited while ${waiting.operation} was pending${this.observedExit}.`));\n this.pending.clear();\n }\n\n async stop() {\n if(this.exited)return;\n if(this.child.connected)try{this.child.disconnect();}catch{}\n if(await this.waitWithin(this.timeout))return;\n this.child.kill('SIGTERM');\n if(await this.waitWithin(this.timeout))return;\n this.child.kill('SIGKILL');\n if(!await this.waitWithin(this.timeout))throw new AgentError('HARNESS_FAILED','The captured definition worker did not confirm termination.');\n }\n\n private waitWithin(timeout:number):Promise<boolean>{\n return new Promise(resolve=>{\n const timer=setTimeout(()=>resolve(false),timeout);\n this.processExit.then(()=>{clearTimeout(timer);resolve(true);});\n });\n }\n}\n\nclass CaptureLease implements CapturedExecution {\n readonly prepared:PreparedExecution;\n readonly children:readonly CapturedChild[];\n private launcher?:Awaited<ReturnType<typeof createSessionLauncher>>;\n private nativeClosed=false;\n private released=false;\n private closing=false;\n private opening?:Promise<ManagedNativeSession>;\n\n constructor(\n private readonly graph:GraphConnection,\n private readonly leaseId:number,\n readonly reference:ExecutionReference,\n children:readonly CapturedChild[],\n ) {\n this.graph.retainLease(leaseId);\n this.children=Object.freeze(children.map(child=>Object.freeze({...child})));\n this.prepared={open:input=>this.open(input),close:()=>this.close()};\n }\n\n async child(name:string):Promise<CapturedExecution>{\n if(this.released)throw new AgentError('INVALID_PARENT','The captured parent context is closed.');\n const result=await this.graph.request('child',{leaseId:this.leaseId,name}) as CaptureResult;\n return new CaptureLease(this.graph,result.leaseId,result.reference,result.children);\n }\n\n private async open(input:DriverInput):Promise<ManagedNativeSession>{\n if(this.released||this.closing||this.opening)throw new AgentError('HARNESS_FAILED','Native session startup is unavailable.');\n const opening=this.startOpen(input);\n this.opening=opening;\n return opening;\n }\n\n private async startOpen(input:DriverInput):Promise<ManagedNativeSession>{\n const state=input.env.AGENT_STATE_DIR;\n if(typeof state!=='string'||!state)throw new AgentError('INVALID_CONFIG','AGENT_STATE_DIR must select the coordinator state directory.');\n const launcher=await createSessionLauncher(state,input.token);\n this.launcher=launcher;\n if(this.closing){\n await launcher.close();this.launcher=undefined;\n throw new AgentError('COORDINATOR_UNAVAILABLE','The captured session closed during startup.');\n }\n const {onApproval,...serializedInput}=input;\n let selectedHarness:HarnessKind|undefined;\n try{\n this.graph.setApprovalHandler(this.leaseId,onApproval);\n selectedHarness=await this.graph.request('open',{leaseId:this.leaseId,input:serializedInput,\n handlesApprovals:!!onApproval,launcherPath:launcher.path}) as HarnessKind;\n }catch(error){\n this.graph.deleteApprovalHandler(this.leaseId);\n this.launcher=undefined;\n await launcher.close();\n throw error;\n }\n const request=(method:string,extra:Record<string,unknown>={})=>this.graph.request(method,{leaseId:this.leaseId,...extra});\n return {\n selectedHarness,\n turn:prompt=>request('turn',{prompt}) as Promise<string>,\n steer:async prompt=>{await request('steer',{prompt});},\n interrupt:async()=>{await request('interrupt');},\n resume:()=>request('resume') as Promise<string>,\n close:async()=>{\n if(this.nativeClosed)return;\n await request('native.close');\n this.nativeClosed=true;\n this.graph.deleteApprovalHandler(this.leaseId);\n },\n };\n }\n\n private async close():Promise<void>{\n this.closing=true;\n if(!this.released){\n await this.graph.request('lease.close',{leaseId:this.leaseId});\n this.released=true;\n this.nativeClosed=true;\n this.graph.deleteApprovalHandler(this.leaseId);\n }\n await this.opening?.catch(()=>undefined);\n if(this.launcher){await this.launcher.close();this.launcher=undefined;}\n await this.graph.releaseLease(this.leaseId);\n }\n\n async abandonFailedCheck():Promise<void>{\n this.closing=true;this.released=true;this.nativeClosed=true;\n this.graph.deleteApprovalHandler(this.leaseId);\n await this.opening?.catch(()=>undefined);\n if(this.launcher){await this.launcher.close().catch(()=>{});this.launcher=undefined;}\n await this.graph.abandonLease(this.leaseId);\n }\n}\n\nexport async function captureExecution(\n agent:string|HarnessConfig,\n input:CatalogEnvironment,\n options:CaptureOptions={},\n):Promise<CapturedExecution>{\n return captureRequest(input,options,{method:'capture',agent});\n}\n\n/** Captures an already resolved private CLI reference without applying public connected validation. */\nexport async function captureReference(\n reference:ExecutionReference,\n input:CatalogEnvironment,\n options:CaptureOptions={},\n):Promise<CapturedExecution>{\n if('kind' in reference&&reference.kind==='inline')\n throw new AgentError('INVALID_DEFINITION','Inline agent definitions cannot be loaded by native CLI workers.');\n return captureRequest(input,options,{method:'capture.reference',reference});\n}\n\nasync function captureRequest(\n input:CatalogEnvironment,\n options:CaptureOptions,\n request:{method:'capture';agent:string|HarnessConfig}|{method:'capture.reference';reference:ExecutionReference},\n):Promise<CapturedExecution>{\n const {AGENT_PARENT_TOKEN:_parent,AGENT_CLI_PATH:_launcher,...environment}=input.env;\n const workerModule=options.workerModule??new URL(`./worker.${import.meta.url.endsWith('.ts')?'ts':'js'}`,import.meta.url);\n const extension=workerModule.pathname.endsWith('.ts')?'ts':'js';\n let child:ChildProcess;\n try{\n child=fork(fileURLToPath(workerModule),[],{cwd:input.cwd,env:environment,stdio:['ignore','ignore','ignore','ipc'],\n execArgv:extension==='ts'?['--import',import.meta.resolve('tsx')]:[]});\n }catch{throw new AgentError('INVALID_DEFINITION','The captured definition worker could not be spawned.');}\n const graph=new GraphConnection(child,options.shutdownTimeoutMs??shutdownTimeoutMs);\n try{\n const {method,...data}=request;\n const result=await graph.request(method,data) as CaptureResult;\n return new CaptureLease(graph,result.leaseId,result.reference,result.children);\n }catch(error){await graph.stop().catch(()=>{});throw error;}\n}\n\nexport async function checkCapturedExecution(captured:CapturedExecution,input:CatalogEnvironment):Promise<void>{\n let native:ManagedNativeSession|undefined;\n let failure:unknown;\n try{\n native=await captured.prepared.open({reference:captured.reference,cwd:input.cwd,env:input.env,\n token:randomUUID(),sessionId:`check_${randomUUID()}`});\n await native.close();\n }catch(error){failure=error;}\n try{await captured.prepared.close();}catch(error){\n failure??=error;\n try{await captured.prepared.close();}\n catch{if(captured instanceof CaptureLease)await captured.abandonFailedCheck();}\n }\n if(failure)throw failure;\n}\n"]}
@@ -0,0 +1,39 @@
1
+ import { type ErrorInfo } from '../errors.js';
2
+ import type { HarnessConfig } from '../sdk/types.js';
3
+ import type { ExecutionReference } from './types.js';
4
+ export interface CatalogEnvironment {
5
+ readonly cwd: string;
6
+ readonly env: NodeJS.ProcessEnv;
7
+ }
8
+ export interface CatalogAgent {
9
+ readonly id: string;
10
+ readonly name: string;
11
+ readonly description: string;
12
+ readonly scope: 'harness' | 'repo' | 'global';
13
+ }
14
+ export interface CatalogSnapshot {
15
+ entries: {
16
+ id: string;
17
+ name: string;
18
+ description: string;
19
+ scope: 'repo' | 'global';
20
+ file: string;
21
+ }[];
22
+ children: {
23
+ name: string;
24
+ description: string;
25
+ }[];
26
+ }
27
+ export type CatalogReply = {
28
+ result: CatalogSnapshot;
29
+ error?: never;
30
+ } | {
31
+ result?: never;
32
+ error: ErrorInfo;
33
+ };
34
+ export declare function listAgents(input: CatalogEnvironment): Promise<{
35
+ readonly items: readonly CatalogAgent[];
36
+ }>;
37
+ export declare function resolveAgent(agent: string | HarnessConfig, input: CatalogEnvironment): Promise<ExecutionReference>;
38
+ export declare function checkAgent(agent: string | HarnessConfig, input: CatalogEnvironment): Promise<void>;
39
+ export declare function loadCatalogSnapshot(input: CatalogEnvironment, parent?: ExecutionReference, discover?: boolean): Promise<CatalogSnapshot>;
@@ -0,0 +1,84 @@
1
+ import { fork } from 'node:child_process';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { AgentError } from '../errors.js';
4
+ import { validateAgent } from '../sdk/definitions.js';
5
+ import { harnessReference } from './definition.js';
6
+ const nativeAgents = [
7
+ { id: 'codex', name: 'codex', description: 'Run the native Codex harness.', scope: 'harness' },
8
+ { id: 'claude', name: 'claude', description: 'Run the native Claude Code harness.', scope: 'harness' },
9
+ { id: 'fx', name: 'fx', description: 'Run the native fx harness through AI Gateway.', scope: 'harness' },
10
+ { id: 'opencode', name: 'opencode', description: 'Run the native OpenCode harness through AI Gateway.', scope: 'harness' },
11
+ { id: 'copilot', name: 'copilot', description: 'Run the native GitHub Copilot harness through AI Gateway.', scope: 'harness' },
12
+ { id: 'cursor', name: 'cursor', description: 'Run the native Cursor harness.', scope: 'harness' },
13
+ ];
14
+ export async function listAgents(input) {
15
+ const snapshot = await loadCatalogSnapshot(input);
16
+ return { items: [...nativeAgents, ...snapshot.entries.map(({ id, name, description, scope }) => ({ id, name, description, scope }))] };
17
+ }
18
+ export async function resolveAgent(agent, input) {
19
+ if (typeof agent !== 'string') {
20
+ validateAgent({ name: 'direct', description: 'Direct native harness.', instructions: 'Run.', harness: agent });
21
+ return { kind: 'harness', harness: agent };
22
+ }
23
+ if (agent === 'codex')
24
+ return harnessReference('codex');
25
+ if (agent === 'claude')
26
+ return harnessReference('claudeCode');
27
+ if (agent === 'fx')
28
+ return harnessReference('fx');
29
+ if (agent === 'opencode' || agent === 'copilot' || agent === 'cursor')
30
+ throw new AgentError('INVALID_CONFIG', `${agent} requires an explicit model configuration.`);
31
+ if (agent.startsWith('subagent:'))
32
+ throw new AgentError('UNKNOWN_AGENT', 'Managed subagents require an active parent context.');
33
+ const { entries } = await loadCatalogSnapshot(input);
34
+ const matches = entries.filter(entry => entry.id === agent || entry.name === agent);
35
+ if (matches.length !== 1)
36
+ throw new AgentError(matches.length ? 'AMBIGUOUS_AGENT' : 'UNKNOWN_AGENT', matches.length ? `Choose ${matches.map(entry => entry.id).join(' or ')}.` : 'Agent not found.');
37
+ return { file: matches[0].file, subagents: [] };
38
+ }
39
+ export async function checkAgent(agent, input) {
40
+ const { captureExecution, checkCapturedExecution } = await import('./capture.js');
41
+ const captured = await captureExecution(agent, input);
42
+ await checkCapturedExecution(captured, input);
43
+ }
44
+ export function loadCatalogSnapshot(input, parent, discover = true) {
45
+ if (parent && 'kind' in parent && parent.kind === 'inline')
46
+ return Promise.reject(new AgentError('INVALID_PARENT', 'Inline SDK definitions are unavailable to the CLI catalog.'));
47
+ return new Promise((resolve, reject) => {
48
+ const extension = import.meta.url.endsWith('.ts') ? 'ts' : 'js';
49
+ const child = fork(fileURLToPath(new URL(`../cli/catalog-worker.${extension}`, import.meta.url)), [], {
50
+ cwd: input.cwd, env: input.env, stdio: ['ignore', 'ignore', 'ignore', 'ipc'],
51
+ execArgv: extension === 'ts' ? ['--import', import.meta.resolve('tsx')] : [],
52
+ });
53
+ let reply;
54
+ let settled = false;
55
+ const fail = () => {
56
+ if (settled)
57
+ return;
58
+ settled = true;
59
+ reject(new AgentError('INVALID_DEFINITION', 'The agent catalog worker exited before returning its catalog.'));
60
+ };
61
+ child.once('error', fail);
62
+ child.once('exit', () => {
63
+ if (!reply)
64
+ fail();
65
+ else if (!settled) {
66
+ settled = true;
67
+ if (reply.error)
68
+ reject(new AgentError(reply.error.code, reply.error.message));
69
+ else
70
+ resolve(reply.result);
71
+ }
72
+ });
73
+ child.once('message', (message) => {
74
+ reply = message;
75
+ child.send({ received: true }, error => { if (error)
76
+ child.kill(); });
77
+ });
78
+ child.send({ cwd: input.cwd, parent, discover }, error => { if (error) {
79
+ child.kill();
80
+ fail();
81
+ } });
82
+ });
83
+ }
84
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/runtime/catalog.ts"],"names":[],"mappings":"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","sourcesContent":["import { fork } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport { AgentError, type ErrorInfo } from '../errors.js';\nimport { validateAgent } from '../sdk/definitions.js';\nimport type { HarnessConfig } from '../sdk/types.js';\nimport { harnessReference } from './definition.js';\nimport type { ExecutionReference } from './types.js';\n\nexport interface CatalogEnvironment {\n readonly cwd: string;\n readonly env: NodeJS.ProcessEnv;\n}\n\nexport interface CatalogAgent {\n readonly id: string;\n readonly name: string;\n readonly description: string;\n readonly scope: 'harness' | 'repo' | 'global';\n}\n\nexport interface CatalogSnapshot {\n entries: {id:string;name:string;description:string;scope:'repo'|'global';file:string}[];\n children: {name:string;description:string}[];\n}\n\nexport type CatalogReply = {result:CatalogSnapshot;error?:never}|{result?:never;error:ErrorInfo};\n\nconst nativeAgents: readonly CatalogAgent[] = [\n {id:'codex',name:'codex',description:'Run the native Codex harness.',scope:'harness'},\n {id:'claude',name:'claude',description:'Run the native Claude Code harness.',scope:'harness'},\n {id:'fx',name:'fx',description:'Run the native fx harness through AI Gateway.',scope:'harness'},\n {id:'opencode',name:'opencode',description:'Run the native OpenCode harness through AI Gateway.',scope:'harness'},\n {id:'copilot',name:'copilot',description:'Run the native GitHub Copilot harness through AI Gateway.',scope:'harness'},\n {id:'cursor',name:'cursor',description:'Run the native Cursor harness.',scope:'harness'},\n];\n\nexport async function listAgents(input: CatalogEnvironment): Promise<{readonly items:readonly CatalogAgent[]}> {\n const snapshot = await loadCatalogSnapshot(input);\n return {items:[...nativeAgents,...snapshot.entries.map(({id,name,description,scope})=>({id,name,description,scope}))]};\n}\n\nexport async function resolveAgent(agent: string | HarnessConfig, input: CatalogEnvironment): Promise<ExecutionReference> {\n if (typeof agent !== 'string') {\n validateAgent({name:'direct',description:'Direct native harness.',instructions:'Run.',harness:agent});\n return {kind:'harness',harness:agent};\n }\n if (agent === 'codex') return harnessReference('codex');\n if (agent === 'claude') return harnessReference('claudeCode');\n if (agent === 'fx') return harnessReference('fx');\n if (agent === 'opencode' || agent === 'copilot' || agent === 'cursor')\n throw new AgentError('INVALID_CONFIG', `${agent} requires an explicit model configuration.`);\n if (agent.startsWith('subagent:'))\n throw new AgentError('UNKNOWN_AGENT', 'Managed subagents require an active parent context.');\n const {entries} = await loadCatalogSnapshot(input);\n const matches = entries.filter(entry => entry.id === agent || entry.name === agent);\n if (matches.length !== 1) throw new AgentError(matches.length ? 'AMBIGUOUS_AGENT' : 'UNKNOWN_AGENT',\n matches.length ? `Choose ${matches.map(entry=>entry.id).join(' or ')}.` : 'Agent not found.');\n return {file:matches[0]!.file,subagents:[]};\n}\n\nexport async function checkAgent(agent:string|HarnessConfig,input:CatalogEnvironment):Promise<void>{\n const {captureExecution,checkCapturedExecution}=await import('./capture.js');\n const captured=await captureExecution(agent,input);\n await checkCapturedExecution(captured,input);\n}\n\nexport function loadCatalogSnapshot(\n input: CatalogEnvironment,\n parent?: ExecutionReference,\n discover = true,\n): Promise<CatalogSnapshot> {\n if (parent && 'kind' in parent && parent.kind === 'inline')\n return Promise.reject(new AgentError('INVALID_PARENT','Inline SDK definitions are unavailable to the CLI catalog.'));\n return new Promise((resolve,reject) => {\n const extension = import.meta.url.endsWith('.ts') ? 'ts' : 'js';\n const child = fork(fileURLToPath(new URL(`../cli/catalog-worker.${extension}`,import.meta.url)),[],{\n cwd:input.cwd,env:input.env,stdio:['ignore','ignore','ignore','ipc'],\n execArgv:extension === 'ts' ? ['--import',import.meta.resolve('tsx')] : [],\n });\n let reply: CatalogReply | undefined;\n let settled = false;\n const fail = () => {\n if (settled) return;\n settled = true;\n reject(new AgentError('INVALID_DEFINITION','The agent catalog worker exited before returning its catalog.'));\n };\n child.once('error',fail);\n child.once('exit',()=>{\n if (!reply) fail();\n else if (!settled) {\n settled = true;\n if (reply.error) reject(new AgentError(reply.error.code,reply.error.message));\n else resolve(reply.result);\n }\n });\n child.once('message',(message:CatalogReply)=>{\n reply=message;\n child.send({received:true},error=>{if(error)child.kill();});\n });\n child.send({cwd:input.cwd,parent,discover},error=>{if(error){child.kill();fail();}});\n });\n}\n"]}
@@ -1,9 +1,10 @@
1
1
  import { type ChildProcess } from 'node:child_process';
2
2
  import type { OutputRecord } from '../cli/output.js';
3
- import { type Endpoint, localProgram } from './state.js';
3
+ import { type Endpoint, type EndpointCapability, localProgram } from './state.js';
4
4
  interface ConnectionOptions {
5
5
  directory?: string;
6
6
  timeoutMs?: number;
7
+ capability?: EndpointCapability;
7
8
  afterSpawn?: (child: ChildProcess) => void;
8
9
  beforeRetirement?: (child: ChildProcess) => void | Promise<void>;
9
10
  program?: ReturnType<typeof localProgram>;