subharness 0.0.3 → 0.0.5

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 (241) hide show
  1. package/README.md +39 -9
  2. package/dist/adapters/approval-context.d.ts +2 -0
  3. package/dist/adapters/approval-context.js +9 -0
  4. package/dist/adapters/approval-context.js.map +1 -0
  5. package/dist/adapters/approval-lifetime.d.ts +8 -0
  6. package/dist/adapters/approval-lifetime.js +50 -0
  7. package/dist/adapters/approval-lifetime.js.map +1 -0
  8. package/dist/adapters/claude-approvals.d.ts +4 -0
  9. package/dist/adapters/claude-approvals.js +32 -0
  10. package/dist/adapters/claude-approvals.js.map +1 -0
  11. package/dist/adapters/claude-permissions.js +1 -1
  12. package/dist/adapters/claude-permissions.js.map +1 -1
  13. package/dist/adapters/claude-process.d.ts +3 -0
  14. package/dist/adapters/claude-process.js +11 -1
  15. package/dist/adapters/claude-process.js.map +1 -1
  16. package/dist/adapters/claude-result.d.ts +2 -0
  17. package/dist/adapters/claude-result.js +22 -0
  18. package/dist/adapters/claude-result.js.map +1 -0
  19. package/dist/adapters/claude.js +60 -12
  20. package/dist/adapters/claude.js.map +1 -1
  21. package/dist/adapters/codex-approvals.d.ts +6 -0
  22. package/dist/adapters/codex-approvals.js +111 -0
  23. package/dist/adapters/codex-approvals.js.map +1 -0
  24. package/dist/adapters/codex.js +36 -3
  25. package/dist/adapters/codex.js.map +1 -1
  26. package/dist/adapters/copilot-permissions.d.ts +26 -0
  27. package/dist/adapters/copilot-permissions.js +121 -0
  28. package/dist/adapters/copilot-permissions.js.map +1 -0
  29. package/dist/adapters/copilot-tools.d.ts +12 -0
  30. package/dist/adapters/copilot-tools.js +61 -0
  31. package/dist/adapters/copilot-tools.js.map +1 -0
  32. package/dist/adapters/copilot.d.ts +108 -0
  33. package/dist/adapters/copilot.js +819 -0
  34. package/dist/adapters/copilot.js.map +1 -0
  35. package/dist/adapters/cursor-cli-approvals.d.ts +2 -0
  36. package/dist/adapters/cursor-cli-approvals.js +83 -0
  37. package/dist/adapters/cursor-cli-approvals.js.map +1 -0
  38. package/dist/adapters/cursor-cli-model.d.ts +4 -0
  39. package/dist/adapters/cursor-cli-model.js +64 -0
  40. package/dist/adapters/cursor-cli-model.js.map +1 -0
  41. package/dist/adapters/cursor-cli-session.d.ts +32 -0
  42. package/dist/adapters/cursor-cli-session.js +316 -0
  43. package/dist/adapters/cursor-cli-session.js.map +1 -0
  44. package/dist/adapters/cursor-cli-tools.d.ts +20 -0
  45. package/dist/adapters/cursor-cli-tools.js +181 -0
  46. package/dist/adapters/cursor-cli-tools.js.map +1 -0
  47. package/dist/adapters/cursor-cli.d.ts +2 -0
  48. package/dist/adapters/cursor-cli.js +306 -0
  49. package/dist/adapters/cursor-cli.js.map +1 -0
  50. package/dist/adapters/cursor-model.d.ts +7 -0
  51. package/dist/adapters/cursor-model.js +67 -0
  52. package/dist/adapters/cursor-model.js.map +1 -0
  53. package/dist/adapters/cursor-rpc.d.ts +42 -0
  54. package/dist/adapters/cursor-rpc.js +271 -0
  55. package/dist/adapters/cursor-rpc.js.map +1 -0
  56. package/dist/adapters/cursor-session.d.ts +4 -0
  57. package/dist/adapters/cursor-session.js +327 -0
  58. package/dist/adapters/cursor-session.js.map +1 -0
  59. package/dist/adapters/cursor-startup.d.ts +16 -0
  60. package/dist/adapters/cursor-startup.js +74 -0
  61. package/dist/adapters/cursor-startup.js.map +1 -0
  62. package/dist/adapters/cursor-tools.d.ts +11 -0
  63. package/dist/adapters/cursor-tools.js +49 -0
  64. package/dist/adapters/cursor-tools.js.map +1 -0
  65. package/dist/adapters/cursor.d.ts +6 -0
  66. package/dist/adapters/cursor.js +17 -0
  67. package/dist/adapters/cursor.js.map +1 -0
  68. package/dist/adapters/fx-approvals.d.ts +2 -0
  69. package/dist/adapters/fx-approvals.js +14 -0
  70. package/dist/adapters/fx-approvals.js.map +1 -0
  71. package/dist/adapters/fx-auth.d.ts +12 -2
  72. package/dist/adapters/fx-auth.js +51 -61
  73. package/dist/adapters/fx-auth.js.map +1 -1
  74. package/dist/adapters/fx-profile.d.ts +8 -0
  75. package/dist/adapters/fx-profile.js +101 -0
  76. package/dist/adapters/fx-profile.js.map +1 -0
  77. package/dist/adapters/fx-rpc.d.ts +2 -0
  78. package/dist/adapters/fx-rpc.js +30 -4
  79. package/dist/adapters/fx-rpc.js.map +1 -1
  80. package/dist/adapters/fx-status.d.ts +2 -0
  81. package/dist/adapters/fx-status.js +96 -0
  82. package/dist/adapters/fx-status.js.map +1 -0
  83. package/dist/adapters/fx.js +77 -30
  84. package/dist/adapters/fx.js.map +1 -1
  85. package/dist/adapters/opencode-access.d.ts +13 -0
  86. package/dist/adapters/opencode-access.js +76 -0
  87. package/dist/adapters/opencode-access.js.map +1 -0
  88. package/dist/adapters/opencode-config.d.ts +11 -0
  89. package/dist/adapters/opencode-config.js +238 -0
  90. package/dist/adapters/opencode-config.js.map +1 -0
  91. package/dist/adapters/opencode-http.d.ts +28 -0
  92. package/dist/adapters/opencode-http.js +297 -0
  93. package/dist/adapters/opencode-http.js.map +1 -0
  94. package/dist/adapters/opencode-tools.d.ts +19 -0
  95. package/dist/adapters/opencode-tools.js +127 -0
  96. package/dist/adapters/opencode-tools.js.map +1 -0
  97. package/dist/adapters/opencode.d.ts +2 -0
  98. package/dist/adapters/opencode.js +569 -0
  99. package/dist/adapters/opencode.js.map +1 -0
  100. package/dist/adapters/rpc.d.ts +3 -0
  101. package/dist/adapters/rpc.js +45 -4
  102. package/dist/adapters/rpc.js.map +1 -1
  103. package/dist/adapters/types.d.ts +7 -0
  104. package/dist/adapters/types.js.map +1 -1
  105. package/dist/approvals/schema.d.ts +4 -0
  106. package/dist/approvals/schema.js +70 -0
  107. package/dist/approvals/schema.js.map +1 -0
  108. package/dist/approvals/types.d.ts +47 -0
  109. package/dist/approvals/types.js +2 -0
  110. package/dist/approvals/types.js.map +1 -0
  111. package/dist/cli/args.d.ts +3 -2
  112. package/dist/cli/args.js +24 -3
  113. package/dist/cli/args.js.map +1 -1
  114. package/dist/cli/dashboard-client.d.ts +5 -1
  115. package/dist/cli/dashboard-client.js +162 -15
  116. package/dist/cli/dashboard-client.js.map +1 -1
  117. package/dist/cli/dashboard-controller.d.ts +7 -0
  118. package/dist/cli/dashboard-controller.js +27 -0
  119. package/dist/cli/dashboard-controller.js.map +1 -0
  120. package/dist/cli/dashboard-detail-view.d.ts +16 -0
  121. package/dist/cli/dashboard-detail-view.js +162 -0
  122. package/dist/cli/dashboard-detail-view.js.map +1 -0
  123. package/dist/cli/dashboard-history-view.d.ts +29 -0
  124. package/dist/cli/dashboard-history-view.js +211 -0
  125. package/dist/cli/dashboard-history-view.js.map +1 -0
  126. package/dist/cli/dashboard-input.d.ts +14 -0
  127. package/dist/cli/dashboard-input.js +128 -0
  128. package/dist/cli/dashboard-input.js.map +1 -0
  129. package/dist/cli/dashboard-layout.d.ts +12 -1
  130. package/dist/cli/dashboard-layout.js +32 -30
  131. package/dist/cli/dashboard-layout.js.map +1 -1
  132. package/dist/cli/dashboard-renderer.d.ts +30 -2
  133. package/dist/cli/dashboard-renderer.js +125 -7
  134. package/dist/cli/dashboard-renderer.js.map +1 -1
  135. package/dist/cli/dashboard-style.d.ts +9 -0
  136. package/dist/cli/dashboard-style.js +36 -0
  137. package/dist/cli/dashboard-style.js.map +1 -0
  138. package/dist/cli/dashboard.d.ts +5 -3
  139. package/dist/cli/dashboard.js +102 -12
  140. package/dist/cli/dashboard.js.map +1 -1
  141. package/dist/cli/help.d.ts +1 -1
  142. package/dist/cli/help.js +37 -12
  143. package/dist/cli/help.js.map +1 -1
  144. package/dist/cli/input.d.ts +1 -0
  145. package/dist/cli/input.js +23 -17
  146. package/dist/cli/input.js.map +1 -1
  147. package/dist/cli/main.js +6 -2
  148. package/dist/cli/main.js.map +1 -1
  149. package/dist/cli/output.js +17 -1
  150. package/dist/cli/output.js.map +1 -1
  151. package/dist/config/access-provenance.d.ts +10 -0
  152. package/dist/config/access-provenance.js +31 -0
  153. package/dist/config/access-provenance.js.map +1 -0
  154. package/dist/config/access.d.ts +12 -2
  155. package/dist/config/access.js +125 -27
  156. package/dist/config/access.js.map +1 -1
  157. package/dist/config/loader.js +1 -0
  158. package/dist/config/loader.js.map +1 -1
  159. package/dist/config/oidc.js +4 -2
  160. package/dist/config/oidc.js.map +1 -1
  161. package/dist/config/project.js +2 -1
  162. package/dist/config/project.js.map +1 -1
  163. package/dist/config/resolve-access.js +24 -10
  164. package/dist/config/resolve-access.js.map +1 -1
  165. package/dist/index.d.ts +2 -2
  166. package/dist/index.js +1 -1
  167. package/dist/index.js.map +1 -1
  168. package/dist/process-diagnostics.d.ts +2 -0
  169. package/dist/process-diagnostics.js +11 -0
  170. package/dist/process-diagnostics.js.map +1 -0
  171. package/dist/runtime/access-errors.d.ts +4 -0
  172. package/dist/runtime/access-errors.js +25 -0
  173. package/dist/runtime/access-errors.js.map +1 -0
  174. package/dist/runtime/approval-registry.d.ts +27 -0
  175. package/dist/runtime/approval-registry.js +126 -0
  176. package/dist/runtime/approval-registry.js.map +1 -0
  177. package/dist/runtime/client.js +54 -14
  178. package/dist/runtime/client.js.map +1 -1
  179. package/dist/runtime/coordinator.d.ts +17 -1
  180. package/dist/runtime/coordinator.js +124 -6
  181. package/dist/runtime/coordinator.js.map +1 -1
  182. package/dist/runtime/dashboard-sanitize.d.ts +2 -0
  183. package/dist/runtime/dashboard-sanitize.js +7 -0
  184. package/dist/runtime/dashboard-sanitize.js.map +1 -0
  185. package/dist/runtime/dashboard.d.ts +43 -1
  186. package/dist/runtime/dashboard.js +2 -3
  187. package/dist/runtime/dashboard.js.map +1 -1
  188. package/dist/runtime/definition.js +11 -1
  189. package/dist/runtime/definition.js.map +1 -1
  190. package/dist/runtime/select-native.d.ts +2 -1
  191. package/dist/runtime/select-native.js +28 -10
  192. package/dist/runtime/select-native.js.map +1 -1
  193. package/dist/runtime/service.js +24 -1
  194. package/dist/runtime/service.js.map +1 -1
  195. package/dist/runtime/types.d.ts +9 -1
  196. package/dist/runtime/types.js.map +1 -1
  197. package/dist/runtime/worker-approvals.d.ts +21 -0
  198. package/dist/runtime/worker-approvals.js +51 -0
  199. package/dist/runtime/worker-approvals.js.map +1 -0
  200. package/dist/runtime/worker-client.js +73 -20
  201. package/dist/runtime/worker-client.js.map +1 -1
  202. package/dist/runtime/worker-server.d.ts +2 -0
  203. package/dist/runtime/worker-server.js +39 -10
  204. package/dist/runtime/worker-server.js.map +1 -1
  205. package/dist/sdk/definitions.d.ts +4 -1
  206. package/dist/sdk/definitions.js +16 -2
  207. package/dist/sdk/definitions.js.map +1 -1
  208. package/dist/sdk/permission-validation.js +10 -1
  209. package/dist/sdk/permission-validation.js.map +1 -1
  210. package/dist/sdk/types.d.ts +29 -1
  211. package/dist/sdk/types.js.map +1 -1
  212. package/package.json +4 -1
  213. package/sdk/access-config.md +86 -4
  214. package/sdk/adapter-contract.md +7 -13
  215. package/sdk/additional-harnesses.md +43 -0
  216. package/sdk/agent-skill.md +7 -4
  217. package/sdk/agent.md +5 -3
  218. package/sdk/approvals.md +120 -0
  219. package/sdk/authentication.md +1 -1
  220. package/sdk/cli/dashboard-design.md +44 -4
  221. package/sdk/cli/dashboard-inspection.md +25 -0
  222. package/sdk/cli/index.md +20 -11
  223. package/sdk/cli/output.md +10 -4
  224. package/sdk/completion-notifications.md +2 -0
  225. package/sdk/config.md +1 -1
  226. package/sdk/copilot.md +53 -0
  227. package/sdk/cursor.md +68 -0
  228. package/sdk/diagnostics.md +29 -0
  229. package/sdk/distribution.md +53 -1
  230. package/sdk/evals.md +10 -4
  231. package/sdk/fx.md +51 -6
  232. package/sdk/harnesses.md +13 -13
  233. package/sdk/index.md +4 -2
  234. package/sdk/message-delivery.md +1 -1
  235. package/sdk/opencode.md +57 -0
  236. package/sdk/permissions.md +7 -5
  237. package/sdk/pr-integration.md +1 -1
  238. package/sdk/project-team.md +2 -0
  239. package/sdk/sessions.md +4 -1
  240. package/sdk/tools.md +1 -1
  241. package/sdk/v1-runtime.md +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/cli/dashboard.ts"],"names":[],"mappings":"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","sourcesContent":["import type { EventEmitter } from 'node:events';\nimport { setTimeout as delay } from 'node:timers/promises';\nimport { AgentError } from '../errors.js';\nimport type { DashboardRow, DashboardSnapshot } from '../runtime/dashboard.js';\nimport { resolveDashboardWorkspace } from '../runtime/dashboard-workspace.js';\nimport { readEndpoint, stateDirectory, type Endpoint } from '../runtime/state.js';\nimport { fetchDashboardSnapshot } from './dashboard-client.js';\nimport { DashboardRenderer, type DashboardOutput } from './dashboard-renderer.js';\n\ninterface Terminal extends DashboardOutput {\n isTTY?: boolean;\n on(event: 'drain' | 'resize' | 'error', listener: (...args: any[]) => void): unknown;\n off(event: 'drain' | 'resize' | 'error', listener: (...args: any[]) => void): unknown;\n}\ninterface Keyboard {\n isTTY?: boolean;\n isRaw?: boolean;\n readableFlowing: boolean | null;\n setRawMode(enabled: boolean): unknown;\n resume(): unknown;\n pause(): unknown;\n on(event: 'data', listener: (chunk: Buffer | string) => void): unknown;\n off(event: 'data', listener: (chunk: Buffer | string) => void): unknown;\n}\ninterface DashboardOptions {\n cwd?: string;\n output?: Terminal;\n input?: Keyboard;\n signals?: Pick<EventEmitter, 'on' | 'off'>;\n term?: string;\n intervalMs?: number;\n discover?: () => Promise<Endpoint | undefined>;\n snapshot?: (endpoint: Endpoint, signal: AbortSignal) => Promise<DashboardSnapshot>;\n}\n\nexport async function runDashboard(options: DashboardOptions = {}): Promise<number> {\n const output = options.output ?? process.stdout;\n if (!output.isTTY || (options.term ?? process.env.TERM) === 'dumb') {\n throw new AgentError('INVALID_ARGUMENT', 'The dashboard requires terminal stdout with cursor control.');\n }\n const input = options.input ?? process.stdin;\n const wasRaw = input.isRaw ?? false;\n const wasFlowing = input.readableFlowing === true;\n let inputEnabled = false;\n const signals = options.signals ?? process;\n const discover = options.discover ?? (() => readEndpoint(stateDirectory()));\n const snapshot = options.snapshot ?? fetchDashboardSnapshot;\n const interval = options.intervalMs ?? 1_000;\n const abort = new AbortController();\n const renderer = new DashboardRenderer(output, await resolveDashboardWorkspace(options.cwd ?? process.cwd()));\n let rows: DashboardRow[] = [];\n let endpoint: Endpoint | undefined;\n let exitCode = 0;\n let outputError: unknown;\n const interrupt = () => { exitCode = 130; abort.abort(); };\n const terminate = () => { exitCode = 143; abort.abort(); };\n const keys = (chunk: Buffer | string) => {\n if (typeof chunk === 'string' ? chunk.includes('\\u0003') : chunk.includes(3)) interrupt();\n };\n const resize = () => renderer.render(rows, Date.now());\n const failedOutput = (error: unknown) => { outputError = error; abort.abort(); };\n signals.on('SIGINT', interrupt);\n signals.on('SIGTERM', terminate);\n output.on('resize', resize);\n output.on('error', failedOutput);\n try {\n if (input.isTTY) {\n input.setRawMode(true);\n inputEnabled = true;\n input.on('data', keys);\n input.resume();\n }\n renderer.start();\n while (!abort.signal.aborted) {\n const next = Date.now() + interval;\n endpoint ??= await discover();\n if (abort.signal.aborted) break;\n if (endpoint) rows = (await snapshot(endpoint, abort.signal)).sessions;\n if (abort.signal.aborted) break;\n renderer.render(rows, Date.now());\n await delay(Math.max(0, next - Date.now()), undefined, {signal: abort.signal});\n }\n } catch (error) {\n if (!abort.signal.aborted) throw error;\n } finally {\n abort.abort();\n renderer.close();\n if (inputEnabled) {\n input.off('data', keys);\n input.setRawMode(wasRaw);\n if (!wasFlowing) input.pause();\n }\n signals.off('SIGINT', interrupt);\n signals.off('SIGTERM', terminate);\n output.off('resize', resize);\n output.off('error', failedOutput);\n }\n if (outputError) throw new AgentError('INTERNAL', 'The dashboard terminal output failed.');\n return exitCode;\n}\n"]}
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/cli/dashboard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAiB,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC5G,OAAO,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAwB,MAAM,yBAAyB,CAAC;AAoClF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAO,GAAqB,EAAE;IAC/D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC;QACnE,MAAM,IAAI,UAAU,CAAC,kBAAkB,EAAE,6DAA6D,CAAC,CAAC;IAC1G,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC;IAC7C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC;IACpC,MAAM,UAAU,GAAG,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC;IAClD,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;IAC5E,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,sBAAsB,CAAC;IAC5D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,oBAAoB,CAAC;IACtD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,qBAAqB,CAAC;IACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,MAAM,yBAAyB,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAChF,IAAI,IAAI,GAAmB,EAAE,CAAC;IAC9B,IAAI,QAA8B,CAAC;IACnC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,WAAoB,CAAC;IACzB,IAAI,WAAwC,CAAC;IAC7C,IAAI,IAA8B,CAAC;IACnC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE;QAC5B,QAAQ,GAAG,IAAI,CAAC;QAChB,WAAW,EAAE,KAAK,EAAE,CAAC;QACrB,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,IAAI,EAAE,EAAE,CAAC;IACX,CAAC,CAAC;IACF,MAAM,YAAY,GAAG,CAAC,KAAc,EAAE,EAAE;QACtC,WAAW,KAAK,KAAK,CAAC;QACtB,WAAW,EAAE,KAAK,EAAE,CAAC;QACrB,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,IAAI,EAAE,EAAE,CAAC;IACX,CAAC,CAAC;IACF,sFAAsF;IACtF,MAAM,OAAO,GAAG,CAA8B,QAAsC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAe,EAAE,EAAE;QAC9G,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO;QACjC,IAAI,CAAC;YAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;IACnE,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC/F,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,CAAC,OAAmD,EAAE,EAAE;QAClE,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACvD,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YAAC,SAAS,EAAE,CAAC;YAAC,OAAO;QAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAC7B,WAAW,EAAE,KAAK,EAAE,CAAC;YACrB,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YACtE,IAAI,EAAE,EAAE,CAAC;QACX,CAAC;IACH,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,KAA0B,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAChE,MAAM,cAAc,GAAG,CAAC,YAAoB,EAAiB,EAAE;QAC7D,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QACnD,OAAO,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;YACjC,IAAI,KAAiC,CAAC;YACtC,MAAM,IAAI,GAAG,GAAG,EAAE;gBAChB,IAAI,KAAK;oBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC/B,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAChD,IAAI,IAAI,KAAK,IAAI;oBAAE,IAAI,GAAG,SAAS,CAAC;gBACpC,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC;YACF,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC;YAC3D,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAAC,IAAI,EAAE,CAAC;gBAAC,OAAO;YAAC,CAAC;YAC7C,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;YACvC,IAAI,GAAG,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5B,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACjC,IAAI,CAAC;QACH,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACvB,YAAY,GAAG,IAAI,CAAC;YACpB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACvB,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,CAAC;QACD,QAAQ,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC;YACnC,QAAQ,KAAK,MAAM,QAAQ,EAAE,CAAC;YAC9B,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO;gBAAE,MAAM;YAChC,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU;gBAAE,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC/F,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO;gBAAE,MAAM;YAChC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAClC,MAAM,YAAY,GAAG,QAAQ,CAAC,eAAe,CAAC;YAC9C,MAAM,eAAe,GAAG,WAAW,CAAC;YACpC,IAAI,QAAQ,IAAI,YAAY,IAAI,eAAe,EAAE,CAAC;gBAChD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;oBACvE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;oBAC9D,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,WAAW,KAAK,eAAe,IAAI,QAAQ,CAAC,eAAe,KAAK,YAAY;wBAAE,SAAS;oBACnH,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;oBAChC,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC;oBAC3C,IAAI,UAAU,EAAE,CAAC;wBACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;wBAC5G,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,WAAW,KAAK,eAAe,IAAI,QAAQ,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;4BACvG,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;wBAChC,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,WAAW,KAAK,eAAe,IAAI,QAAQ,CAAC,eAAe,KAAK,YAAY;wBAAE,SAAS;oBAC3F,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;YACD,MAAM,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,KAAK,CAAC;IACzC,CAAC;YAAS,CAAC;QACT,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,WAAW,EAAE,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,IAAI,CAAC;YAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAAC,WAAW,KAAK,KAAK,CAAC;QAAC,CAAC;QAClE,IAAI,YAAY,EAAE,CAAC;YACjB,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACxB,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACzB,IAAI,CAAC,UAAU;gBAAE,KAAK,CAAC,KAAK,EAAE,CAAC;QACjC,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,WAAW;QAAE,MAAM,IAAI,UAAU,CAAC,UAAU,EAAE,uCAAuC,CAAC,CAAC;IAC3F,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import type { EventEmitter } from 'node:events';\nimport { AgentError } from '../errors.js';\nimport type { DashboardDetail, DashboardRow, DashboardSession, DashboardSnapshot } from '../runtime/dashboard.js';\nimport { resolveDashboardWorkspace } from '../runtime/dashboard-workspace.js';\nimport { readEndpoint, stateDirectory, type Endpoint } from '../runtime/state.js';\nimport { fetchDashboardDetail, fetchDashboardSession, fetchDashboardSnapshot } from './dashboard-client.js';\nimport {dispatchDashboardKey} from './dashboard-controller.js';\nimport { DashboardKeyDecoder } from './dashboard-input.js';\nimport { DashboardRenderer, type DashboardOutput } from './dashboard-renderer.js';\n\ninterface Terminal extends DashboardOutput {\n isTTY?: boolean;\n on(event: 'drain' | 'resize' | 'error', listener: (...args: any[]) => void): unknown;\n off(event: 'drain' | 'resize' | 'error', listener: (...args: any[]) => void): unknown;\n}\ninterface Keyboard {\n isTTY?: boolean;\n isRaw?: boolean;\n readableFlowing: boolean | null;\n setRawMode(enabled: boolean): unknown;\n resume(): unknown;\n pause(): unknown;\n on(event: 'data', listener: (chunk: Uint8Array | string) => void): unknown;\n off(event: 'data', listener: (chunk: Uint8Array | string) => void): unknown;\n}\ninterface DashboardOptions {\n cwd?: string;\n output?: Terminal;\n input?: Keyboard;\n signals?: Pick<EventEmitter, 'on' | 'off'>;\n term?: string;\n intervalMs?: number;\n discover?: () => Promise<Endpoint | undefined>;\n snapshot?: (endpoint: Endpoint, signal: AbortSignal) => Promise<DashboardSnapshot>;\n session?: (endpoint: Endpoint, id: string, signal: AbortSignal) => Promise<DashboardSession>;\n detail?: (\n endpoint: Endpoint,\n id: string,\n signal: AbortSignal,\n includePrompt?: boolean,\n knownResponseId?: string,\n ) => Promise<DashboardDetail>;\n}\n\nexport async function runDashboard(options: DashboardOptions = {}): Promise<number> {\n const output = options.output ?? process.stdout;\n if (!output.isTTY || (options.term ?? process.env.TERM) === 'dumb') {\n throw new AgentError('INVALID_ARGUMENT', 'The dashboard requires terminal stdout with cursor control.');\n }\n const input = options.input ?? process.stdin;\n const wasRaw = input.isRaw ?? false;\n const wasFlowing = input.readableFlowing === true;\n let inputEnabled = false;\n const signals = options.signals ?? process;\n const discover = options.discover ?? (() => readEndpoint(stateDirectory()));\n const snapshot = options.snapshot ?? fetchDashboardSnapshot;\n const detail = options.detail ?? fetchDashboardDetail;\n const session = options.session ?? fetchDashboardSession;\n const interval = options.intervalMs ?? 1_000;\n const abort = new AbortController();\n const workspace = await resolveDashboardWorkspace(options.cwd ?? process.cwd());\n let rows: DashboardRow[] = [];\n let endpoint: Endpoint | undefined;\n let exitCode = 0;\n let outputError: unknown;\n let detailAbort: AbortController | undefined;\n let wake: (() => void) | undefined;\n const stop = (code: number) => {\n exitCode = code;\n detailAbort?.abort();\n abort.abort();\n wake?.();\n };\n const failedOutput = (error: unknown) => {\n outputError ??= error;\n detailAbort?.abort();\n abort.abort();\n wake?.();\n };\n // Event listeners and the decoder's Escape timer run outside the polling try/finally.\n const guarded = <Arguments extends unknown[]>(callback: (...args: Arguments) => void) => (...args: Arguments) => {\n if (abort.signal.aborted) return;\n try { callback(...args); } catch (error) { failedOutput(error); }\n };\n const renderer = new DashboardRenderer(output, workspace, !process.env.NO_COLOR, failedOutput);\n const interrupt = () => stop(130);\n const terminate = () => stop(143);\n const key = (pressed: Parameters<typeof dispatchDashboardKey>[1]) => {\n const action = dispatchDashboardKey(renderer, pressed);\n if (action.interrupt) { interrupt(); return; }\n if (action.refreshInspection) {\n detailAbort?.abort();\n detailAbort = renderer.inspecting ? new AbortController() : undefined;\n wake?.();\n }\n };\n const decoder = new DashboardKeyDecoder(guarded(key));\n const keys = guarded((chunk: Uint8Array | string) => decoder.push(chunk));\n const resize = guarded(() => renderer.render(rows, Date.now()));\n const waitForRefresh = (milliseconds: number): Promise<void> => {\n if (abort.signal.aborted) return Promise.resolve();\n return new Promise<void>(resolve => {\n let timer: NodeJS.Timeout | undefined;\n const done = () => {\n if (timer) clearTimeout(timer);\n abort.signal.removeEventListener('abort', done);\n if (wake === done) wake = undefined;\n resolve();\n };\n abort.signal.addEventListener('abort', done, {once: true});\n if (abort.signal.aborted) { done(); return; }\n timer = setTimeout(done, milliseconds);\n wake = done;\n });\n };\n signals.on('SIGINT', interrupt);\n signals.on('SIGTERM', terminate);\n output.on('resize', resize);\n output.on('error', failedOutput);\n try {\n if (input.isTTY) {\n input.setRawMode(true);\n inputEnabled = true;\n input.on('data', keys);\n input.resume();\n }\n renderer.start();\n while (!abort.signal.aborted) {\n const next = Date.now() + interval;\n endpoint ??= await discover();\n if (abort.signal.aborted) break;\n if (endpoint && !renderer.inspecting) rows = (await snapshot(endpoint, abort.signal)).sessions;\n if (abort.signal.aborted) break;\n renderer.render(rows, Date.now());\n const inspectionId = renderer.inspectedTaskId;\n const inspectionAbort = detailAbort;\n if (endpoint && inspectionId && inspectionAbort) {\n try {\n const signal = AbortSignal.any([abort.signal, inspectionAbort.signal]);\n const history = await session(endpoint, inspectionId, signal);\n if (abort.signal.aborted || detailAbort !== inspectionAbort || renderer.inspectedTaskId !== inspectionId) continue;\n renderer.updateSession(history);\n const expandedId = renderer.expandedTaskId;\n if (expandedId) {\n const record = await detail(endpoint, expandedId, signal, !renderer.detailLoaded, renderer.knownResponseId);\n if (!abort.signal.aborted && detailAbort === inspectionAbort && renderer.expandedTaskId === expandedId) {\n renderer.updateDetail(record);\n }\n }\n } catch (error) {\n if (detailAbort !== inspectionAbort || renderer.inspectedTaskId !== inspectionId) continue;\n throw error;\n }\n }\n await waitForRefresh(Math.max(0, next - Date.now()));\n }\n } catch (error) {\n if (!abort.signal.aborted) throw error;\n } finally {\n abort.abort();\n detailAbort?.abort();\n decoder.close();\n try { renderer.close(); } catch (error) { outputError ??= error; }\n if (inputEnabled) {\n input.off('data', keys);\n input.setRawMode(wasRaw);\n if (!wasFlowing) input.pause();\n }\n signals.off('SIGINT', interrupt);\n signals.off('SIGTERM', terminate);\n output.off('resize', resize);\n output.off('error', failedOutput);\n }\n if (outputError) throw new AgentError('INTERNAL', 'The dashboard terminal output failed.');\n return exitCode;\n}\n"]}
@@ -1,3 +1,3 @@
1
- type DirectHarness = 'codex' | 'claudeCode' | 'fx';
1
+ type DirectHarness = 'codex' | 'claudeCode' | 'fx' | 'opencode' | 'copilot' | 'cursor';
2
2
  export declare function renderHelp(harness?: DirectHarness, command?: 'run' | 'check'): string;
3
3
  export {};
package/dist/cli/help.js CHANGED
@@ -16,14 +16,21 @@ Usage:
16
16
  subharness queue <session-id>
17
17
  subharness cancel <task-id>
18
18
  subharness resume <session-id>
19
+ subharness respond <request-id> --content <json>
20
+ subharness respond <request-id> --content-file <path|->
19
21
 
20
- Direct harness targets: codex, claude, fx. These bare names are reserved; same-named specialists require repo: or global:.
22
+ Direct harness targets: codex, claude, fx, opencode, copilot, cursor. These bare names are reserved; same-named specialists require repo: or global:.
21
23
  Specialist targets: repo:<name>, global:<name>, or an unambiguous bare name.
22
24
  Declared child targets: subagent:<name>, resolved only from the active managed parent's declarations.
23
25
  Run "subharness run <harness> --help" or "subharness check <harness> --help" for harness-specific options.
24
26
  Execution commands accept --format text|jsonl; text is the default.
25
27
  Omit --after to wait for the first retained response; supply it to wait for the next response.
26
28
  Detach after admission with --detach, then use wait or status; steering cannot be detached.
29
+ Permission requests return approval_required with a request-specific schema. Inspect the action and scope,
30
+ respond with one JSON object matching that schema (at most 16 KiB), then wait on the same task.
31
+ Each request offers its own choices; never invent a universal allow/deny value or assume "always" is permanent.
32
+ Denial uses an offered rejection choice. Use cancel to stop the task; resume does not answer permissions.
33
+ Approval content files resolve from the caller's working directory; - reads standard input.
27
34
  Dashboard is a terminal-only read-only view and accepts no options.
28
35
  --help and --version do not start a coordinator or native harness.
29
36
  Use -- to pass a positional prompt beginning with a dash.
@@ -42,51 +49,69 @@ const details = {
42
49
  },
43
50
  fx: {
44
51
  name: 'fx',
45
- access: 'Requires an installed fx executable and configured Gateway access.',
52
+ access: 'Requires an installed fx executable and explicit native login, API-key, or Gateway access.',
46
53
  effort: 'fx accepts a nonempty native effort identifier; model compatibility is checked by the adapter.',
47
54
  },
55
+ opencode: {
56
+ name: 'opencode',
57
+ access: 'Requires an installed OpenCode executable and explicit native login, API-key, or Gateway access.',
58
+ modelRequired: true,
59
+ },
60
+ copilot: {
61
+ name: 'copilot',
62
+ access: 'Requires the GitHub Copilot SDK runtime and explicit native login, API-key, or Gateway access.',
63
+ modelRequired: true,
64
+ },
65
+ cursor: {
66
+ name: 'cursor',
67
+ access: 'Requires configured native Cursor CLI subscription access or Cursor SDK API-key access.',
68
+ modelRequired: true,
69
+ },
48
70
  };
49
71
  export function renderHelp(harness, command = 'run') {
50
72
  if (!harness)
51
73
  return GLOBAL_HELP;
52
74
  const target = details[harness];
75
+ const effortUsage = target.effort ? ' [--effort <effort>]' : '';
76
+ const effortOption = target.effort ? ' --effort <effort> Native effort identifier\n' : '';
77
+ const modelNote = target.modelRequired
78
+ ? 'This harness requires an explicit --model; it has no verifiable implicit model.'
79
+ : 'Omitting --model or --effort uses the verifiable native default for the selected access route.';
53
80
  if (command === 'check')
54
81
  return `subharness check ${target.name} — check direct ${target.name} startup readiness
55
82
 
56
83
  Usage:
57
- subharness check ${target.name} [--cwd <directory>] [--model <model>] [--effort <effort>] [--format text|jsonl]
84
+ subharness check ${target.name} [--cwd <directory>] ${target.modelRequired ? '--model <model>' : '[--model <model>]'}${effortUsage} [--format text|jsonl]
58
85
 
59
86
  Options:
60
87
  --cwd <directory> Execution directory for the startup check
61
88
  --model <model> Native model identifier
62
- --effort <effort> Native effort identifier
63
- --format text|jsonl Output format (text by default)
89
+ ${effortOption} --format text|jsonl Output format (text by default)
64
90
 
65
91
  The check opens and closes an isolated native session without submitting a turn.
66
92
  Readiness covers startup at that moment, not quota, task success, native permissions, or continued availability.
67
- Omitting --model or --effort uses the verifiable native default for the selected access route.
68
- ${target.effort}
93
+ ${modelNote}
94
+ ${target.effort ?? ''}
69
95
  ${target.access}
70
96
  Native harness flags are not forwarded; unsupported options are errors.
71
97
  `;
72
98
  return `subharness run ${target.name} — start a direct ${target.name} session
73
99
 
74
100
  Usage:
75
- subharness run ${target.name} [--cwd <directory>] [--model <model>] [--effort <effort>] <prompt>
101
+ subharness run ${target.name} [--cwd <directory>] ${target.modelRequired ? '--model <model>' : '[--model <model>]'}${effortUsage} <prompt>
76
102
  subharness run ${target.name} [options] --prompt <text>
77
103
  subharness run ${target.name} [options] --prompt-file <path|->
78
104
 
79
105
  Options:
80
106
  --cwd <directory> Execution directory for the new session
81
107
  --model <model> Native model identifier
82
- --effort <effort> Native effort identifier
83
- --prompt <text> Prompt text
108
+ ${target.effort ? ' --effort <effort> Native effort identifier\n' : ''} --prompt <text> Prompt text
84
109
  --prompt-file <path|-> Read the prompt from a UTF-8 file or stdin
85
110
  --detach Return after admission without observing a response
86
111
  --format text|jsonl Output format (text by default)
87
112
 
88
- Omitting --model or --effort uses the verifiable native default for the selected access route.
89
- ${target.effort}
113
+ ${modelNote}
114
+ ${target.effort ?? ''}
90
115
  ${target.access}
91
116
  Native harness flags are not forwarded; unsupported options are errors.
92
117
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BnB,CAAC;AAEF,MAAM,OAAO,GAA0E;IACrF,KAAK,EAAE;QACL,IAAI,EAAE,OAAO;QACb,MAAM,EAAE,wEAAwE;QAChF,MAAM,EAAE,mGAAmG;KAC5G;IACD,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,8EAA8E;QACtF,MAAM,EAAE,yDAAyD;KAClE;IACD,EAAE,EAAE;QACF,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,oEAAoE;QAC5E,MAAM,EAAE,gGAAgG;KACzG;CACF,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,OAAuB,EAAE,OAAO,GAAoB,KAAK;IAClF,IAAI,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC;IACjC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,oBAAoB,MAAM,CAAC,IAAI,mBAAmB,MAAM,CAAC,IAAI;;;qBAG1E,MAAM,CAAC,IAAI;;;;;;;;;;;EAW9B,MAAM,CAAC,MAAM;EACb,MAAM,CAAC,MAAM;;CAEd,CAAC;IACA,OAAO,kBAAkB,MAAM,CAAC,IAAI,qBAAqB,MAAM,CAAC,IAAI;;;mBAGnD,MAAM,CAAC,IAAI;mBACX,MAAM,CAAC,IAAI;mBACX,MAAM,CAAC,IAAI;;;;;;;;;;;;EAY5B,MAAM,CAAC,MAAM;EACb,MAAM,CAAC,MAAM;;CAEd,CAAC;AACF,CAAC","sourcesContent":["type DirectHarness = 'codex' | 'claudeCode' | 'fx';\n\nconst GLOBAL_HELP = `subharness — coordinate external coding agents\n\nUsage:\n subharness list [--cwd <directory>]\n subharness dashboard\n subharness check <target> [--cwd <directory>] [--format text|jsonl]\n subharness check <harness> [--cwd <directory>] [--model <model>] [--effort <effort>] [--format text|jsonl]\n subharness run <target> [options] [--detach] <prompt>\n subharness run <target> [options] [--detach] --prompt <text>\n subharness run <target> [options] [--detach] --prompt-file <path|->\n subharness send <session-id> [--delivery queue|steer|interrupt] [--detach] <prompt>\n subharness send <session-id> [--delivery queue|steer|interrupt] [--detach] --prompt <text>\n subharness send <session-id> [--delivery queue|steer|interrupt] [--detach] --prompt-file <path|->\n subharness wait <task-id> [--after <response-id>]\n subharness status <task-id> [--full]\n subharness queue <session-id>\n subharness cancel <task-id>\n subharness resume <session-id>\n\nDirect harness targets: codex, claude, fx. These bare names are reserved; same-named specialists require repo: or global:.\nSpecialist targets: repo:<name>, global:<name>, or an unambiguous bare name.\nDeclared child targets: subagent:<name>, resolved only from the active managed parent's declarations.\nRun \"subharness run <harness> --help\" or \"subharness check <harness> --help\" for harness-specific options.\nExecution commands accept --format text|jsonl; text is the default.\nOmit --after to wait for the first retained response; supply it to wait for the next response.\nDetach after admission with --detach, then use wait or status; steering cannot be detached.\nDashboard is a terminal-only read-only view and accepts no options.\n--help and --version do not start a coordinator or native harness.\nUse -- to pass a positional prompt beginning with a dash.\nagent is an identical compatibility alias for subharness.\n`;\n\nconst details: Record<DirectHarness, {name: string; access: string; effort: string}> = {\n codex: {\n name: 'codex',\n access: 'Requires an installed Codex executable and eligible configured access.',\n effort: 'Codex accepts a nonempty native effort identifier; model compatibility is checked by the adapter.',\n },\n claudeCode: {\n name: 'claude',\n access: 'Requires an installed Claude Code executable and eligible configured access.',\n effort: 'Claude effort must be low, medium, high, xhigh, or max.',\n },\n fx: {\n name: 'fx',\n access: 'Requires an installed fx executable and configured Gateway access.',\n effort: 'fx accepts a nonempty native effort identifier; model compatibility is checked by the adapter.',\n },\n};\n\nexport function renderHelp(harness?: DirectHarness, command: 'run' | 'check' = 'run'): string {\n if (!harness) return GLOBAL_HELP;\n const target = details[harness];\n if (command === 'check') return `subharness check ${target.name} — check direct ${target.name} startup readiness\n\nUsage:\n subharness check ${target.name} [--cwd <directory>] [--model <model>] [--effort <effort>] [--format text|jsonl]\n\nOptions:\n --cwd <directory> Execution directory for the startup check\n --model <model> Native model identifier\n --effort <effort> Native effort identifier\n --format text|jsonl Output format (text by default)\n\nThe check opens and closes an isolated native session without submitting a turn.\nReadiness covers startup at that moment, not quota, task success, native permissions, or continued availability.\nOmitting --model or --effort uses the verifiable native default for the selected access route.\n${target.effort}\n${target.access}\nNative harness flags are not forwarded; unsupported options are errors.\n`;\n return `subharness run ${target.name} — start a direct ${target.name} session\n\nUsage:\n subharness run ${target.name} [--cwd <directory>] [--model <model>] [--effort <effort>] <prompt>\n subharness run ${target.name} [options] --prompt <text>\n subharness run ${target.name} [options] --prompt-file <path|->\n\nOptions:\n --cwd <directory> Execution directory for the new session\n --model <model> Native model identifier\n --effort <effort> Native effort identifier\n --prompt <text> Prompt text\n --prompt-file <path|-> Read the prompt from a UTF-8 file or stdin\n --detach Return after admission without observing a response\n --format text|jsonl Output format (text by default)\n\nOmitting --model or --effort uses the verifiable native default for the selected access route.\n${target.effort}\n${target.access}\nNative harness flags are not forwarded; unsupported options are errors.\n`;\n}\n"]}
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCnB,CAAC;AAEF,MAAM,OAAO,GAAiG;IAC5G,KAAK,EAAE;QACL,IAAI,EAAE,OAAO;QACb,MAAM,EAAE,wEAAwE;QAChF,MAAM,EAAE,mGAAmG;KAC5G;IACD,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,8EAA8E;QACtF,MAAM,EAAE,yDAAyD;KAClE;IACD,EAAE,EAAE;QACF,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,4FAA4F;QACpG,MAAM,EAAE,gGAAgG;KACzG;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,kGAAkG;QAC1G,aAAa,EAAE,IAAI;KACpB;IACD,OAAO,EAAE;QACP,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,gGAAgG;QACxG,aAAa,EAAE,IAAI;KACpB;IACD,MAAM,EAAE;QACN,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,yFAAyF;QACjG,aAAa,EAAE,IAAI;KACpB;CACF,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,OAAuB,EAAE,OAAO,GAAoB,KAAK;IAClF,IAAI,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC;IACjC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,mDAAmD,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa;QACpC,CAAC,CAAC,iFAAiF;QACnF,CAAC,CAAC,gGAAgG,CAAC;IACrG,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,oBAAoB,MAAM,CAAC,IAAI,mBAAmB,MAAM,CAAC,IAAI;;;qBAG1E,MAAM,CAAC,IAAI,wBAAwB,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,GAAG,WAAW;;;;;EAKlI,YAAY;;;;EAIZ,SAAS;EACT,MAAM,CAAC,MAAM,IAAI,EAAE;EACnB,MAAM,CAAC,MAAM;;CAEd,CAAC;IACA,OAAO,kBAAkB,MAAM,CAAC,IAAI,qBAAqB,MAAM,CAAC,IAAI;;;mBAGnD,MAAM,CAAC,IAAI,wBAAwB,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,GAAG,WAAW;mBAC/G,MAAM,CAAC,IAAI;mBACX,MAAM,CAAC,IAAI;;;;;EAK5B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC,CAAC,EAAE;;;;;EAK3E,SAAS;EACT,MAAM,CAAC,MAAM,IAAI,EAAE;EACnB,MAAM,CAAC,MAAM;;CAEd,CAAC;AACF,CAAC","sourcesContent":["type DirectHarness = 'codex' | 'claudeCode' | 'fx' | 'opencode' | 'copilot' | 'cursor';\n\nconst GLOBAL_HELP = `subharness — coordinate external coding agents\n\nUsage:\n subharness list [--cwd <directory>]\n subharness dashboard\n subharness check <target> [--cwd <directory>] [--format text|jsonl]\n subharness check <harness> [--cwd <directory>] [--model <model>] [--effort <effort>] [--format text|jsonl]\n subharness run <target> [options] [--detach] <prompt>\n subharness run <target> [options] [--detach] --prompt <text>\n subharness run <target> [options] [--detach] --prompt-file <path|->\n subharness send <session-id> [--delivery queue|steer|interrupt] [--detach] <prompt>\n subharness send <session-id> [--delivery queue|steer|interrupt] [--detach] --prompt <text>\n subharness send <session-id> [--delivery queue|steer|interrupt] [--detach] --prompt-file <path|->\n subharness wait <task-id> [--after <response-id>]\n subharness status <task-id> [--full]\n subharness queue <session-id>\n subharness cancel <task-id>\n subharness resume <session-id>\n subharness respond <request-id> --content <json>\n subharness respond <request-id> --content-file <path|->\n\nDirect harness targets: codex, claude, fx, opencode, copilot, cursor. These bare names are reserved; same-named specialists require repo: or global:.\nSpecialist targets: repo:<name>, global:<name>, or an unambiguous bare name.\nDeclared child targets: subagent:<name>, resolved only from the active managed parent's declarations.\nRun \"subharness run <harness> --help\" or \"subharness check <harness> --help\" for harness-specific options.\nExecution commands accept --format text|jsonl; text is the default.\nOmit --after to wait for the first retained response; supply it to wait for the next response.\nDetach after admission with --detach, then use wait or status; steering cannot be detached.\nPermission requests return approval_required with a request-specific schema. Inspect the action and scope,\nrespond with one JSON object matching that schema (at most 16 KiB), then wait on the same task.\nEach request offers its own choices; never invent a universal allow/deny value or assume \"always\" is permanent.\nDenial uses an offered rejection choice. Use cancel to stop the task; resume does not answer permissions.\nApproval content files resolve from the caller's working directory; - reads standard input.\nDashboard is a terminal-only read-only view and accepts no options.\n--help and --version do not start a coordinator or native harness.\nUse -- to pass a positional prompt beginning with a dash.\nagent is an identical compatibility alias for subharness.\n`;\n\nconst details: Record<DirectHarness, {name: string; access: string; effort?: string; modelRequired?: true}> = {\n codex: {\n name: 'codex',\n access: 'Requires an installed Codex executable and eligible configured access.',\n effort: 'Codex accepts a nonempty native effort identifier; model compatibility is checked by the adapter.',\n },\n claudeCode: {\n name: 'claude',\n access: 'Requires an installed Claude Code executable and eligible configured access.',\n effort: 'Claude effort must be low, medium, high, xhigh, or max.',\n },\n fx: {\n name: 'fx',\n access: 'Requires an installed fx executable and explicit native login, API-key, or Gateway access.',\n effort: 'fx accepts a nonempty native effort identifier; model compatibility is checked by the adapter.',\n },\n opencode: {\n name: 'opencode',\n access: 'Requires an installed OpenCode executable and explicit native login, API-key, or Gateway access.',\n modelRequired: true,\n },\n copilot: {\n name: 'copilot',\n access: 'Requires the GitHub Copilot SDK runtime and explicit native login, API-key, or Gateway access.',\n modelRequired: true,\n },\n cursor: {\n name: 'cursor',\n access: 'Requires configured native Cursor CLI subscription access or Cursor SDK API-key access.',\n modelRequired: true,\n },\n};\n\nexport function renderHelp(harness?: DirectHarness, command: 'run' | 'check' = 'run'): string {\n if (!harness) return GLOBAL_HELP;\n const target = details[harness];\n const effortUsage = target.effort ? ' [--effort <effort>]' : '';\n const effortOption = target.effort ? ' --effort <effort> Native effort identifier\\n' : '';\n const modelNote = target.modelRequired\n ? 'This harness requires an explicit --model; it has no verifiable implicit model.'\n : 'Omitting --model or --effort uses the verifiable native default for the selected access route.';\n if (command === 'check') return `subharness check ${target.name} — check direct ${target.name} startup readiness\n\nUsage:\n subharness check ${target.name} [--cwd <directory>] ${target.modelRequired ? '--model <model>' : '[--model <model>]'}${effortUsage} [--format text|jsonl]\n\nOptions:\n --cwd <directory> Execution directory for the startup check\n --model <model> Native model identifier\n${effortOption} --format text|jsonl Output format (text by default)\n\nThe check opens and closes an isolated native session without submitting a turn.\nReadiness covers startup at that moment, not quota, task success, native permissions, or continued availability.\n${modelNote}\n${target.effort ?? ''}\n${target.access}\nNative harness flags are not forwarded; unsupported options are errors.\n`;\n return `subharness run ${target.name} — start a direct ${target.name} session\n\nUsage:\n subharness run ${target.name} [--cwd <directory>] ${target.modelRequired ? '--model <model>' : '[--model <model>]'}${effortUsage} <prompt>\n subharness run ${target.name} [options] --prompt <text>\n subharness run ${target.name} [options] --prompt-file <path|->\n\nOptions:\n --cwd <directory> Execution directory for the new session\n --model <model> Native model identifier\n${target.effort ? ' --effort <effort> Native effort identifier\\n' : ''} --prompt <text> Prompt text\n --prompt-file <path|-> Read the prompt from a UTF-8 file or stdin\n --detach Return after admission without observing a response\n --format text|jsonl Output format (text by default)\n\n${modelNote}\n${target.effort ?? ''}\n${target.access}\nNative harness flags are not forwarded; unsupported options are errors.\n`;\n}\n"]}
@@ -3,3 +3,4 @@ export type PromptStream = AsyncIterable<Uint8Array | string> & {
3
3
  isTTY?: boolean;
4
4
  };
5
5
  export declare function readPromptInput(source: string, cwd: string, stdin?: PromptStream): Promise<string>;
6
+ export declare function readApprovalInput(source: string, cwd: string, stdin?: PromptStream): Promise<string>;
package/dist/cli/input.js CHANGED
@@ -3,58 +3,59 @@ import { resolve } from 'node:path';
3
3
  import { AgentError } from '../errors.js';
4
4
  export const MAX_PROMPT_BYTES = 1024 * 1024;
5
5
  const invalid = (message) => { throw new AgentError('INVALID_ARGUMENT', message); };
6
- function decode(chunks, bytes, source) {
7
- if (bytes > MAX_PROMPT_BYTES)
8
- invalid('Prompt exceeds 1 MiB.');
6
+ const tooLarge = (limit) => invalid(`${limit.noun[0].toUpperCase()}${limit.noun.slice(1)} exceeds ${limit.size}.`);
7
+ function decode(chunks, bytes, source, limit) {
8
+ if (bytes > limit.bytes)
9
+ tooLarge(limit);
9
10
  try {
10
11
  return new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks, bytes));
11
12
  }
12
13
  catch {
13
- return invalid(`Cannot read UTF-8 prompt ${source}.`);
14
+ return invalid(`Cannot read UTF-8 ${limit.noun} ${source}.`);
14
15
  }
15
16
  }
16
- async function readStdin(stdin) {
17
+ async function readStdin(stdin, limit) {
17
18
  if (stdin.isTTY)
18
- invalid('Cannot read a prompt from interactive terminal stdin.');
19
+ invalid(`Cannot read ${limit.noun} from interactive terminal stdin.`);
19
20
  const chunks = [];
20
21
  let bytes = 0;
21
22
  try {
22
23
  for await (const value of stdin) {
23
24
  const chunk = Buffer.from(value);
24
25
  bytes += chunk.byteLength;
25
- if (bytes > MAX_PROMPT_BYTES)
26
- invalid('Prompt exceeds 1 MiB.');
26
+ if (bytes > limit.bytes)
27
+ tooLarge(limit);
27
28
  chunks.push(chunk);
28
29
  }
29
30
  }
30
31
  catch (error) {
31
32
  if (error instanceof AgentError)
32
33
  throw error;
33
- invalid('Cannot read prompt from stdin.');
34
+ invalid(`Cannot read ${limit.noun} from stdin.`);
34
35
  }
35
- return decode(chunks, bytes, 'from stdin');
36
+ return decode(chunks, bytes, 'from stdin', limit);
36
37
  }
37
- async function readFileBounded(path) {
38
+ async function readFileBounded(path, limit) {
38
39
  let file;
39
40
  try {
40
41
  file = await open(path, 'r');
41
42
  const chunks = [];
42
43
  let bytes = 0;
43
44
  while (true) {
44
- const buffer = Buffer.allocUnsafe(Math.min(64 * 1024, MAX_PROMPT_BYTES + 1 - bytes));
45
+ const buffer = Buffer.allocUnsafe(Math.min(64 * 1024, limit.bytes + 1 - bytes));
45
46
  const { bytesRead } = await file.read(buffer, 0, buffer.byteLength, null);
46
47
  if (!bytesRead)
47
- return decode(chunks, bytes, `file: ${path}`);
48
+ return decode(chunks, bytes, `file: ${path}`, limit);
48
49
  bytes += bytesRead;
49
- if (bytes > MAX_PROMPT_BYTES)
50
- invalid('Prompt exceeds 1 MiB.');
50
+ if (bytes > limit.bytes)
51
+ tooLarge(limit);
51
52
  chunks.push(buffer.subarray(0, bytesRead));
52
53
  }
53
54
  }
54
55
  catch (error) {
55
56
  if (error instanceof AgentError)
56
57
  throw error;
57
- return invalid(`Cannot read prompt file: ${path}`);
58
+ return invalid(`Cannot read ${limit.noun} file: ${path}`);
58
59
  }
59
60
  finally {
60
61
  try {
@@ -64,6 +65,11 @@ async function readFileBounded(path) {
64
65
  }
65
66
  }
66
67
  export function readPromptInput(source, cwd, stdin = process.stdin) {
67
- return source === '-' ? readStdin(stdin) : readFileBounded(resolve(cwd, source));
68
+ const limit = { bytes: MAX_PROMPT_BYTES, noun: 'prompt', size: '1 MiB' };
69
+ return source === '-' ? readStdin(stdin, limit) : readFileBounded(resolve(cwd, source), limit);
70
+ }
71
+ export function readApprovalInput(source, cwd, stdin = process.stdin) {
72
+ const limit = { bytes: 16 * 1024, noun: 'approval content', size: '16 KiB' };
73
+ return source === '-' ? readStdin(stdin, limit) : readFileBounded(resolve(cwd, source), limit);
68
74
  }
69
75
  //# sourceMappingURL=input.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/cli/input.ts"],"names":[],"mappings":"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","sourcesContent":["import { open } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { AgentError } from '../errors.js';\n\nexport const MAX_PROMPT_BYTES = 1024 * 1024;\n\nexport type PromptStream = AsyncIterable<Uint8Array | string> & {isTTY?: boolean};\n\nconst invalid = (message: string): never => { throw new AgentError('INVALID_ARGUMENT', message); };\n\nfunction decode(chunks: Uint8Array[], bytes: number, source: string): string {\n if (bytes > MAX_PROMPT_BYTES) invalid('Prompt exceeds 1 MiB.');\n try {\n return new TextDecoder('utf-8', {fatal: true}).decode(Buffer.concat(chunks, bytes));\n } catch {\n return invalid(`Cannot read UTF-8 prompt ${source}.`);\n }\n}\n\nasync function readStdin(stdin: PromptStream): Promise<string> {\n if (stdin.isTTY) invalid('Cannot read a prompt from interactive terminal stdin.');\n const chunks: Uint8Array[] = [];\n let bytes = 0;\n try {\n for await (const value of stdin) {\n const chunk = Buffer.from(value);\n bytes += chunk.byteLength;\n if (bytes > MAX_PROMPT_BYTES) invalid('Prompt exceeds 1 MiB.');\n chunks.push(chunk);\n }\n } catch (error) {\n if (error instanceof AgentError) throw error;\n invalid('Cannot read prompt from stdin.');\n }\n return decode(chunks, bytes, 'from stdin');\n}\n\nasync function readFileBounded(path: string): Promise<string> {\n let file;\n try {\n file = await open(path, 'r');\n const chunks: Uint8Array[] = [];\n let bytes = 0;\n while (true) {\n const buffer = Buffer.allocUnsafe(Math.min(64 * 1024, MAX_PROMPT_BYTES + 1 - bytes));\n const {bytesRead} = await file.read(buffer, 0, buffer.byteLength, null);\n if (!bytesRead) return decode(chunks, bytes, `file: ${path}`);\n bytes += bytesRead;\n if (bytes > MAX_PROMPT_BYTES) invalid('Prompt exceeds 1 MiB.');\n chunks.push(buffer.subarray(0, bytesRead));\n }\n } catch (error) {\n if (error instanceof AgentError) throw error;\n return invalid(`Cannot read prompt file: ${path}`);\n } finally {\n try { await file?.close(); } catch {}\n }\n}\n\nexport function readPromptInput(source: string, cwd: string, stdin: PromptStream = process.stdin): Promise<string> {\n return source === '-' ? readStdin(stdin) : readFileBounded(resolve(cwd, source));\n}\n"]}
1
+ {"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/cli/input.ts"],"names":[],"mappings":"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","sourcesContent":["import { open } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { AgentError } from '../errors.js';\n\nexport const MAX_PROMPT_BYTES = 1024 * 1024;\n\nexport type PromptStream = AsyncIterable<Uint8Array | string> & {isTTY?: boolean};\n\nconst invalid = (message: string): never => { throw new AgentError('INVALID_ARGUMENT', message); };\n\ninterface InputLimit { bytes: number; noun: string; size: string }\nconst tooLarge = (limit: InputLimit): never => invalid(`${limit.noun[0]!.toUpperCase()}${limit.noun.slice(1)} exceeds ${limit.size}.`);\n\nfunction decode(chunks: Uint8Array[], bytes: number, source: string, limit: InputLimit): string {\n if (bytes > limit.bytes) tooLarge(limit);\n try {\n return new TextDecoder('utf-8', {fatal: true}).decode(Buffer.concat(chunks, bytes));\n } catch {\n return invalid(`Cannot read UTF-8 ${limit.noun} ${source}.`);\n }\n}\n\nasync function readStdin(stdin: PromptStream, limit: InputLimit): Promise<string> {\n if (stdin.isTTY) invalid(`Cannot read ${limit.noun} from interactive terminal stdin.`);\n const chunks: Uint8Array[] = [];\n let bytes = 0;\n try {\n for await (const value of stdin) {\n const chunk = Buffer.from(value);\n bytes += chunk.byteLength;\n if (bytes > limit.bytes) tooLarge(limit);\n chunks.push(chunk);\n }\n } catch (error) {\n if (error instanceof AgentError) throw error;\n invalid(`Cannot read ${limit.noun} from stdin.`);\n }\n return decode(chunks, bytes, 'from stdin',limit);\n}\n\nasync function readFileBounded(path: string, limit: InputLimit): Promise<string> {\n let file;\n try {\n file = await open(path, 'r');\n const chunks: Uint8Array[] = [];\n let bytes = 0;\n while (true) {\n const buffer = Buffer.allocUnsafe(Math.min(64 * 1024, limit.bytes + 1 - bytes));\n const {bytesRead} = await file.read(buffer, 0, buffer.byteLength, null);\n if (!bytesRead) return decode(chunks, bytes, `file: ${path}`,limit);\n bytes += bytesRead;\n if (bytes > limit.bytes) tooLarge(limit);\n chunks.push(buffer.subarray(0, bytesRead));\n }\n } catch (error) {\n if (error instanceof AgentError) throw error;\n return invalid(`Cannot read ${limit.noun} file: ${path}`);\n } finally {\n try { await file?.close(); } catch {}\n }\n}\n\nexport function readPromptInput(source: string, cwd: string, stdin: PromptStream = process.stdin): Promise<string> {\n const limit = {bytes:MAX_PROMPT_BYTES,noun:'prompt',size:'1 MiB'};\n return source === '-' ? readStdin(stdin,limit) : readFileBounded(resolve(cwd, source),limit);\n}\n\nexport function readApprovalInput(source: string, cwd: string, stdin: PromptStream = process.stdin): Promise<string> {\n const limit = {bytes:16 * 1024,noun:'approval content',size:'16 KiB'};\n return source === '-' ? readStdin(stdin,limit) : readFileBounded(resolve(cwd,source),limit);\n}\n"]}
package/dist/cli/main.js CHANGED
@@ -8,7 +8,8 @@ import { AgentError, errorInfo } from '../errors.js';
8
8
  import { connect, request } from '../runtime/client.js';
9
9
  import { harnessReference } from '../runtime/definition.js';
10
10
  import { checkReadiness } from '../runtime/readiness.js';
11
- const valueOptions = new Set(['cwd', 'prompt', 'prompt-file', 'model', 'effort', 'delivery', 'after']);
11
+ import { quoteDiagnosticPath } from '../config/access-provenance.js';
12
+ const valueOptions = new Set(['cwd', 'prompt', 'prompt-file', 'content', 'content-file', 'model', 'effort', 'delivery', 'after']);
12
13
  function parseErrorFormat(argv) {
13
14
  for (let index = 1; index < argv.length; index++) {
14
15
  const argument = argv[index];
@@ -55,7 +56,7 @@ async function main() {
55
56
  throw new Error();
56
57
  }
57
58
  catch {
58
- throw new AgentError('INVALID_CONFIG', `Execution directory is not accessible: ${requestedCwd}`);
59
+ throw new AgentError('INVALID_CONFIG', `Execution directory is not accessible: ${quoteDiagnosticPath(requestedCwd)}`);
59
60
  }
60
61
  if ((args.command === 'run' || args.command === 'check') && args.harness) {
61
62
  reference = harnessReference(args.harness, args.model, args.effort);
@@ -86,6 +87,9 @@ async function main() {
86
87
  { id: 'codex', name: 'codex', description: 'Run the native Codex harness.', scope: 'harness' },
87
88
  { id: 'claude', name: 'claude', description: 'Run the native Claude Code harness.', scope: 'harness' },
88
89
  { id: 'fx', name: 'fx', description: 'Run the native fx harness through AI Gateway.', scope: 'harness' },
90
+ { id: 'opencode', name: 'opencode', description: 'Run the native OpenCode harness through AI Gateway.', scope: 'harness' },
91
+ { id: 'copilot', name: 'copilot', description: 'Run the native GitHub Copilot harness through AI Gateway.', scope: 'harness' },
92
+ { id: 'cursor', name: 'cursor', description: 'Run the native Cursor harness.', scope: 'harness' },
89
93
  ...entries.map(({ id, name, description, scope }) => ({ id, name, description, scope })),
90
94
  ...children.map(({ name, description }) => ({ id: `subagent:${name}`, name, description, scope: 'subagent' })),
91
95
  ] });
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { readFile, realpath, stat } from 'node:fs/promises';\nimport { parseArgs } from './args.js';\nimport { renderHelp } from './help.js';\nimport { renderText, exitCode, type OutputRecord } from './output.js';\nimport { loadCatalog, loadDeclaredChildren } from './catalog.js';\nimport { AgentError, errorInfo } from '../errors.js';\nimport { connect, request } from '../runtime/client.js';\nimport type { ExecutionReference } from '../runtime/types.js';\nimport { harnessReference } from '../runtime/definition.js';\nimport { checkReadiness } from '../runtime/readiness.js';\n\nconst valueOptions = new Set(['cwd', 'prompt', 'prompt-file', 'model', 'effort', 'delivery', 'after']);\n\nfunction parseErrorFormat(argv: string[]): 'text' | 'jsonl' {\n for (let index = 1; index < argv.length; index++) {\n const argument = argv[index]!;\n if (argument === '--') break;\n if (argument === '--format') return argv[index + 1] === 'jsonl' ? 'jsonl' : 'text';\n if (argument.startsWith('--') && valueOptions.has(argument.slice(2))) index++;\n }\n return 'text';\n}\n\nasync function main() {\n let format = process.argv[2] === 'dashboard' ? 'text' : parseErrorFormat(process.argv.slice(2));\n const emit = (record: OutputRecord) => {\n const text = format === 'jsonl' ? JSON.stringify(record) : renderText(record);\n (record.type === 'error' && format === 'text' ? process.stderr : process.stdout).write(text + '\\n');\n process.exitCode = exitCode(record);\n };\n try {\n const args = await parseArgs(process.argv.slice(2)); format = args.format;\n if (args.command === 'help') { process.stdout.write(renderHelp(args.harness, args.helpCommand)); return; }\n if (args.command === 'version') {\n const manifest = JSON.parse(await readFile(new URL('../../package.json', import.meta.url), 'utf8')) as { version: string };\n process.stdout.write(`${manifest.version}\\n`);\n return;\n }\n if (args.command === 'dashboard') {\n const { runDashboard } = await import('./dashboard.js');\n process.exitCode = await runDashboard();\n return;\n }\n const parentToken = process.env.AGENT_PARENT_TOKEN;\n let reference: ExecutionReference | undefined;\n if (args.command === 'list' || args.command === 'run' || args.command === 'check') {\n const requestedCwd = args.cwd;\n try {\n args.cwd = await realpath(requestedCwd);\n if (!(await stat(args.cwd)).isDirectory()) throw new Error();\n } catch {\n throw new AgentError('INVALID_CONFIG', `Execution directory is not accessible: ${requestedCwd}`);\n }\n if ((args.command === 'run' || args.command === 'check') && args.harness) {\n reference = harnessReference(args.harness, args.model, args.effort);\n } else {\n let parent: {reference:ExecutionReference}|undefined;\n if (parentToken) {\n const endpoint = await connect(false);\n for await (const record of request(endpoint,{command:'parent',parentToken})) {\n if (record.type === 'error') throw new AgentError((record.error as any).code,(record.error as any).message);\n parent = record as unknown as {reference:ExecutionReference};\n }\n }\n if ((args.command === 'run' || args.command === 'check') && args.id!.startsWith('subagent:')) {\n const name = args.id!.slice(9);\n if (!parent || !('file' in parent.reference)) throw new AgentError('INVALID_PARENT','This subagent is not available in the active parent context.');\n const children = await loadDeclaredChildren(args.cwd, parent.reference);\n if (!children.some(child => child.name === name)) throw new AgentError('INVALID_PARENT','This subagent is not available in the active parent context.');\n reference = {file:parent.reference.file,subagents:[...parent.reference.subagents,name]};\n } else {\n const { entries, children } = await loadCatalog(args.cwd, parent?.reference);\n if (args.command === 'list') {\n emit({version:1,type:'agents',agents:[\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 ...entries.map(({id,name,description,scope})=>({id,name,description,scope})),\n ...children.map(({name,description})=>({id:`subagent:${name}`,name,description,scope:'subagent'})),\n ]}); return;\n }\n const matches = entries.filter(entry=>entry.id===args.id || entry.name===args.id);\n if (matches.length !== 1) throw new AgentError(matches.length ? 'AMBIGUOUS_AGENT':'UNKNOWN_AGENT',matches.length ? `Choose ${matches.map(entry=>entry.id).join(' or ')}.` : 'Agent not found. Use subharness list.');\n reference = {file:matches[0]!.file,subagents:[]};\n }\n }\n }\n if (args.command === 'check') {\n await checkReadiness(reference!, args.cwd, process.env);\n emit({version: 1, type: 'check', target: args.id!, ready: true});\n return;\n }\n const endpoint = await connect(args.command === 'run');\n const body = args.command === 'run'\n ? {command:'run',input:{reference,cwd:args.cwd,env:process.env,prompt:args.prompt,parentToken},detach:args.detach}\n : {...args,parentToken};\n for await (const record of request(endpoint,body)) emit(record);\n } catch (error) { emit({version:1,type:'error',error:errorInfo(error)}); }\n}\nawait main();\n"]}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { readFile, realpath, stat } from 'node:fs/promises';\nimport { parseArgs } from './args.js';\nimport { renderHelp } from './help.js';\nimport { renderText, exitCode, type OutputRecord } from './output.js';\nimport { loadCatalog, loadDeclaredChildren } from './catalog.js';\nimport { AgentError, errorInfo } from '../errors.js';\nimport { connect, request } from '../runtime/client.js';\nimport type { ExecutionReference } from '../runtime/types.js';\nimport { harnessReference } from '../runtime/definition.js';\nimport { checkReadiness } from '../runtime/readiness.js';\nimport { quoteDiagnosticPath } from '../config/access-provenance.js';\n\nconst valueOptions = new Set(['cwd', 'prompt', 'prompt-file', 'content', 'content-file', 'model', 'effort', 'delivery', 'after']);\n\nfunction parseErrorFormat(argv: string[]): 'text' | 'jsonl' {\n for (let index = 1; index < argv.length; index++) {\n const argument = argv[index]!;\n if (argument === '--') break;\n if (argument === '--format') return argv[index + 1] === 'jsonl' ? 'jsonl' : 'text';\n if (argument.startsWith('--') && valueOptions.has(argument.slice(2))) index++;\n }\n return 'text';\n}\n\nasync function main() {\n let format = process.argv[2] === 'dashboard' ? 'text' : parseErrorFormat(process.argv.slice(2));\n const emit = (record: OutputRecord) => {\n const text = format === 'jsonl' ? JSON.stringify(record) : renderText(record);\n (record.type === 'error' && format === 'text' ? process.stderr : process.stdout).write(text + '\\n');\n process.exitCode = exitCode(record);\n };\n try {\n const args = await parseArgs(process.argv.slice(2)); format = args.format;\n if (args.command === 'help') { process.stdout.write(renderHelp(args.harness, args.helpCommand)); return; }\n if (args.command === 'version') {\n const manifest = JSON.parse(await readFile(new URL('../../package.json', import.meta.url), 'utf8')) as { version: string };\n process.stdout.write(`${manifest.version}\\n`);\n return;\n }\n if (args.command === 'dashboard') {\n const { runDashboard } = await import('./dashboard.js');\n process.exitCode = await runDashboard();\n return;\n }\n const parentToken = process.env.AGENT_PARENT_TOKEN;\n let reference: ExecutionReference | undefined;\n if (args.command === 'list' || args.command === 'run' || args.command === 'check') {\n const requestedCwd = args.cwd;\n try {\n args.cwd = await realpath(requestedCwd);\n if (!(await stat(args.cwd)).isDirectory()) throw new Error();\n } catch {\n throw new AgentError('INVALID_CONFIG', `Execution directory is not accessible: ${quoteDiagnosticPath(requestedCwd)}`);\n }\n if ((args.command === 'run' || args.command === 'check') && args.harness) {\n reference = harnessReference(args.harness, args.model, args.effort);\n } else {\n let parent: {reference:ExecutionReference}|undefined;\n if (parentToken) {\n const endpoint = await connect(false);\n for await (const record of request(endpoint,{command:'parent',parentToken})) {\n if (record.type === 'error') throw new AgentError((record.error as any).code,(record.error as any).message);\n parent = record as unknown as {reference:ExecutionReference};\n }\n }\n if ((args.command === 'run' || args.command === 'check') && args.id!.startsWith('subagent:')) {\n const name = args.id!.slice(9);\n if (!parent || !('file' in parent.reference)) throw new AgentError('INVALID_PARENT','This subagent is not available in the active parent context.');\n const children = await loadDeclaredChildren(args.cwd, parent.reference);\n if (!children.some(child => child.name === name)) throw new AgentError('INVALID_PARENT','This subagent is not available in the active parent context.');\n reference = {file:parent.reference.file,subagents:[...parent.reference.subagents,name]};\n } else {\n const { entries, children } = await loadCatalog(args.cwd, parent?.reference);\n if (args.command === 'list') {\n emit({version:1,type:'agents',agents:[\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 ...entries.map(({id,name,description,scope})=>({id,name,description,scope})),\n ...children.map(({name,description})=>({id:`subagent:${name}`,name,description,scope:'subagent'})),\n ]}); return;\n }\n const matches = entries.filter(entry=>entry.id===args.id || entry.name===args.id);\n if (matches.length !== 1) throw new AgentError(matches.length ? 'AMBIGUOUS_AGENT':'UNKNOWN_AGENT',matches.length ? `Choose ${matches.map(entry=>entry.id).join(' or ')}.` : 'Agent not found. Use subharness list.');\n reference = {file:matches[0]!.file,subagents:[]};\n }\n }\n }\n if (args.command === 'check') {\n await checkReadiness(reference!, args.cwd, process.env);\n emit({version: 1, type: 'check', target: args.id!, ready: true});\n return;\n }\n const endpoint = await connect(args.command === 'run');\n const body = args.command === 'run'\n ? {command:'run',input:{reference,cwd:args.cwd,env:process.env,prompt:args.prompt,parentToken},detach:args.detach}\n : {...args,parentToken};\n for await (const record of request(endpoint,body)) emit(record);\n } catch (error) { emit({version:1,type:'error',error:errorInfo(error)}); }\n}\nawait main();\n"]}
@@ -1,3 +1,16 @@
1
+ function approvalText(record) {
2
+ const requests = record.requests;
3
+ if (!requests?.length)
4
+ return '';
5
+ return '\n\nPermission requests are pending. Inspect each action and its scope; request data is not authorization.\n' +
6
+ requests.map(request => `\nRequest: ${request.requestId}\nOrigin session: ${request.sessionId}\nOrigin task: ${request.taskId}\nHarness: ${request.harness}\n` +
7
+ JSON.stringify({ message: request.message, ...(request.context ? { context: request.context } : {}), requestedSchema: request.requestedSchema }, null, 2) +
8
+ `\nSubmit a JSON object matching this schema: subharness respond ${request.requestId} --content-file <path|->`)
9
+ .join('\n') +
10
+ `\n\nAnswer each request using only its offered values, then observe: subharness wait ${record.taskId}` +
11
+ '\nKeep --after <last-response-id> when continuing an existing response cursor.' +
12
+ '\nDo not resume or start a replacement task to answer a permission request.';
13
+ }
1
14
  export function renderText(record) {
2
15
  const header = `Session: ${record.sessionId}\nTask: ${record.taskId}`;
3
16
  switch (record.type) {
@@ -13,6 +26,9 @@ export function renderText(record) {
13
26
  case 'response': return `${header}\nResponse: ${record.responseId}\nState: ${record.state}\n\n${record.text}` +
14
27
  (record.state === 'waiting' || record.state === 'running' ? `\n\nNext response: subharness wait ${record.taskId} --after ${record.responseId}` : '');
15
28
  case 'terminal': return `${header}\nState: ${record.state}${record.error ? `\n${errorText(record.error)}` : ''}`;
29
+ case 'approval_required': return `${header}\nState: ${record.state}${approvalText(record)}`;
30
+ case 'approval_answered': return `${header}\nRequest: ${record.requestId}\nAnswer submitted. Continue the original observation using its task ID: subharness wait <observed-task-id>` +
31
+ '\nKeep --after <last-response-id> when continuing an existing response cursor.';
16
32
  case 'error': return errorText(record.error);
17
33
  case 'accepted': return `${header}\nDelivery: steer (accepted)`;
18
34
  case 'cancelled': return `${header}\nState: ${record.state}`;
@@ -24,7 +40,7 @@ export function renderText(record) {
24
40
  case 'status': {
25
41
  const response = record.response;
26
42
  return `${header}\nState: ${record.state}${record.error ? `\n${errorText(record.error)}` : ''}` +
27
- (response ? `\nResponse: ${response.responseId}\n\n${response.text}${response.truncated ? '\n[Preview truncated; use status --full.]' : ''}` : '');
43
+ (response ? `\nResponse: ${response.responseId}\n\n${response.text}${response.truncated ? '\n[Preview truncated; use status --full.]' : ''}` : '') + approvalText(record);
28
44
  }
29
45
  case 'queue': {
30
46
  const active = record.active;
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"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","sourcesContent":["export type OutputRecord = {version: number; type: string; [key: string]: unknown};\n\nexport function renderText(record: OutputRecord): string {\n const header = `Session: ${record.sessionId}\\nTask: ${record.taskId}`;\n switch (record.type) {\n case 'started': {\n const started = `${header}\\nState: ${record.state}${record.delivery ? `\\nDelivery: ${record.delivery}` : ''}`;\n if (record.paused !== true || typeof record.blockedByTaskId !== 'string') return started;\n return `${started}\\n\\nTask accepted, but it cannot dispatch while the session queue is paused by failed task ${record.blockedByTaskId}.` +\n `\\nInspect the failure: subharness status ${record.blockedByTaskId} --full` +\n `\\nCancel the failed task: subharness cancel ${record.blockedByTaskId}` +\n '\\nCancellation must succeed before queue dispatch resumes.';\n }\n case 'response': return `${header}\\nResponse: ${record.responseId}\\nState: ${record.state}\\n\\n${record.text}` +\n (record.state === 'waiting' || record.state === 'running' ? `\\n\\nNext response: subharness wait ${record.taskId} --after ${record.responseId}` : '');\n case 'terminal': return `${header}\\nState: ${record.state}${record.error ? `\\n${errorText(record.error)}` : ''}`;\n case 'error': return errorText(record.error);\n case 'accepted': return `${header}\\nDelivery: steer (accepted)`;\n case 'cancelled': return `${header}\\nState: ${record.state}`;\n case 'check': return `${record.target} is ready.`;\n case 'agents': {\n const entries = record.agents as {id:string;description:string}[];\n return entries.length ? entries.map(entry => `${entry.id} — ${entry.description}`).join('\\n') : 'No agents found.';\n }\n case 'status': {\n const response = record.response as {responseId:string;text:string;truncated:boolean}|undefined;\n return `${header}\\nState: ${record.state}${record.error ? `\\n${errorText(record.error)}` : ''}` +\n (response ? `\\nResponse: ${response.responseId}\\n\\n${response.text}${response.truncated ? '\\n[Preview truncated; use status --full.]' : ''}` : '');\n }\n case 'queue': {\n const active = record.active as {taskId:string;state:string}|undefined;\n const tasks = record.tasks as {taskId:string;description:string}[];\n return `Session: ${record.sessionId}\\nPaused: ${record.paused}\\nActive: ${active ? `${active.taskId} (${active.state})` : 'none'}\\n` +\n (tasks.length ? tasks.map(task => `${task.taskId} — ${task.description}`).join('\\n') : 'Queue empty.');\n }\n default: return JSON.stringify(record);\n }\n}\nfunction errorText(error: unknown) {\n const value = error as {code:string;message:string};\n return `${value.code}: ${value.message}`;\n}\nexport function exitCode(record: OutputRecord): number {\n if (record.type === 'cancelled') return 0;\n if (record.state === 'cancelled' || record.state === 'interrupted') return 130;\n const error = record.error as {code?:string}|undefined;\n if (!error && record.state !== 'failed') return 0;\n return /^(INVALID_|UNKNOWN_|AMBIGUOUS_|NOT_FAILED|NO_ACTIVE_TASK)/.test(error?.code ?? '') ? 2 : 1;\n}\n"]}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"AAIA,SAAS,YAAY,CAAC,MAAoB;IACxC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAyC,CAAC;IAClE,IAAI,CAAC,QAAQ,EAAE,MAAM;QAAE,OAAO,EAAE,CAAC;IACjC,OAAO,8GAA8G;QACnH,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,cAAc,OAAO,CAAC,SAAS,qBAAqB,OAAO,CAAC,SAAS,kBAAkB,OAAO,CAAC,MAAM,cAAc,OAAO,CAAC,OAAO,IAAI;YAC5J,IAAI,CAAC,SAAS,CAAC,EAAC,OAAO,EAAC,OAAO,CAAC,OAAO,EAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAC,OAAO,EAAC,OAAO,CAAC,OAAO,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,eAAe,EAAC,OAAO,CAAC,eAAe,EAAC,EAAC,IAAI,EAAC,CAAC,CAAC;YAC9I,mEAAmE,OAAO,CAAC,SAAS,0BAA0B,CAAC;aAC9G,IAAI,CAAC,IAAI,CAAC;QACb,wFAAwF,MAAM,CAAC,MAAM,EAAE;QACvG,gFAAgF;QAChF,6EAA6E,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAoB;IAC7C,MAAM,MAAM,GAAG,YAAY,MAAM,CAAC,SAAS,WAAW,MAAM,CAAC,MAAM,EAAE,CAAC;IACtE,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,SAAS,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,GAAG,MAAM,YAAY,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC9G,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,CAAC,eAAe,KAAK,QAAQ;gBAAE,OAAO,OAAO,CAAC;YACzF,OAAO,GAAG,OAAO,8FAA8F,MAAM,CAAC,eAAe,GAAG;gBACtI,4CAA4C,MAAM,CAAC,eAAe,SAAS;gBAC3E,+CAA+C,MAAM,CAAC,eAAe,EAAE;gBACvE,4DAA4D,CAAC;QACjE,CAAC;QACD,KAAK,UAAU,EAAE,OAAO,GAAG,MAAM,eAAe,MAAM,CAAC,UAAU,YAAY,MAAM,CAAC,KAAK,OAAO,MAAM,CAAC,IAAI,EAAE;YAC3G,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,sCAAsC,MAAM,CAAC,MAAM,YAAY,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACvJ,KAAK,UAAU,EAAE,OAAO,GAAG,MAAM,YAAY,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACjH,KAAK,mBAAmB,EAAE,OAAO,GAAG,MAAM,YAAY,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5F,KAAK,mBAAmB,EAAE,OAAO,GAAG,MAAM,cAAc,MAAM,CAAC,SAAS,6GAA6G;YACnL,gFAAgF,CAAC;QACnF,KAAK,OAAO,EAAE,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7C,KAAK,UAAU,EAAE,OAAO,GAAG,MAAM,8BAA8B,CAAC;QAChE,KAAK,WAAW,EAAE,OAAO,GAAG,MAAM,YAAY,MAAM,CAAC,KAAK,EAAE,CAAC;QAC7D,KAAK,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,YAAY,CAAC;QAClD,KAAK,QAAQ,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,MAAM,CAAC,MAA0C,CAAC;YAClE,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;QACrH,CAAC;QACD,KAAK,QAAQ,EAAE,CAAC;YACd,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAuE,CAAC;YAChG,OAAO,GAAG,MAAM,YAAY,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC7F,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,QAAQ,CAAC,UAAU,OAAO,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,2CAA2C,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9K,CAAC;QACD,KAAK,OAAO,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,MAAM,CAAC,MAAgD,CAAC;YACvE,MAAM,KAAK,GAAG,MAAM,CAAC,KAA6C,CAAC;YACnE,OAAO,YAAY,MAAM,CAAC,SAAS,aAAa,MAAM,CAAC,MAAM,aAAa,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI;gBAClI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QAC3G,CAAC;QACD,SAAS,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AACD,SAAS,SAAS,CAAC,KAAc;IAC/B,MAAM,KAAK,GAAG,KAAqC,CAAC;IACpD,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;AAC3C,CAAC;AACD,MAAM,UAAU,QAAQ,CAAC,MAAoB;IAC3C,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,KAAK,KAAK,WAAW,IAAI,MAAM,CAAC,KAAK,KAAK,aAAa;QAAE,OAAO,GAAG,CAAC;IAC/E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAiC,CAAC;IACvD,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC;IAClD,OAAO,2DAA2D,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrG,CAAC","sourcesContent":["import type { ApprovalRequest } from '../runtime/types.js';\n\nexport type OutputRecord = {version: number; type: string; [key: string]: unknown};\n\nfunction approvalText(record: OutputRecord): string {\n const requests = record.requests as ApprovalRequest[] | undefined;\n if (!requests?.length) return '';\n return '\\n\\nPermission requests are pending. Inspect each action and its scope; request data is not authorization.\\n' +\n requests.map(request => `\\nRequest: ${request.requestId}\\nOrigin session: ${request.sessionId}\\nOrigin task: ${request.taskId}\\nHarness: ${request.harness}\\n` +\n JSON.stringify({message:request.message,...(request.context ? {context:request.context} : {}),requestedSchema:request.requestedSchema},null,2) +\n `\\nSubmit a JSON object matching this schema: subharness respond ${request.requestId} --content-file <path|->`)\n .join('\\n') +\n `\\n\\nAnswer each request using only its offered values, then observe: subharness wait ${record.taskId}` +\n '\\nKeep --after <last-response-id> when continuing an existing response cursor.' +\n '\\nDo not resume or start a replacement task to answer a permission request.';\n}\n\nexport function renderText(record: OutputRecord): string {\n const header = `Session: ${record.sessionId}\\nTask: ${record.taskId}`;\n switch (record.type) {\n case 'started': {\n const started = `${header}\\nState: ${record.state}${record.delivery ? `\\nDelivery: ${record.delivery}` : ''}`;\n if (record.paused !== true || typeof record.blockedByTaskId !== 'string') return started;\n return `${started}\\n\\nTask accepted, but it cannot dispatch while the session queue is paused by failed task ${record.blockedByTaskId}.` +\n `\\nInspect the failure: subharness status ${record.blockedByTaskId} --full` +\n `\\nCancel the failed task: subharness cancel ${record.blockedByTaskId}` +\n '\\nCancellation must succeed before queue dispatch resumes.';\n }\n case 'response': return `${header}\\nResponse: ${record.responseId}\\nState: ${record.state}\\n\\n${record.text}` +\n (record.state === 'waiting' || record.state === 'running' ? `\\n\\nNext response: subharness wait ${record.taskId} --after ${record.responseId}` : '');\n case 'terminal': return `${header}\\nState: ${record.state}${record.error ? `\\n${errorText(record.error)}` : ''}`;\n case 'approval_required': return `${header}\\nState: ${record.state}${approvalText(record)}`;\n case 'approval_answered': return `${header}\\nRequest: ${record.requestId}\\nAnswer submitted. Continue the original observation using its task ID: subharness wait <observed-task-id>` +\n '\\nKeep --after <last-response-id> when continuing an existing response cursor.';\n case 'error': return errorText(record.error);\n case 'accepted': return `${header}\\nDelivery: steer (accepted)`;\n case 'cancelled': return `${header}\\nState: ${record.state}`;\n case 'check': return `${record.target} is ready.`;\n case 'agents': {\n const entries = record.agents as {id:string;description:string}[];\n return entries.length ? entries.map(entry => `${entry.id} — ${entry.description}`).join('\\n') : 'No agents found.';\n }\n case 'status': {\n const response = record.response as {responseId:string;text:string;truncated:boolean}|undefined;\n return `${header}\\nState: ${record.state}${record.error ? `\\n${errorText(record.error)}` : ''}` +\n (response ? `\\nResponse: ${response.responseId}\\n\\n${response.text}${response.truncated ? '\\n[Preview truncated; use status --full.]' : ''}` : '') + approvalText(record);\n }\n case 'queue': {\n const active = record.active as {taskId:string;state:string}|undefined;\n const tasks = record.tasks as {taskId:string;description:string}[];\n return `Session: ${record.sessionId}\\nPaused: ${record.paused}\\nActive: ${active ? `${active.taskId} (${active.state})` : 'none'}\\n` +\n (tasks.length ? tasks.map(task => `${task.taskId} — ${task.description}`).join('\\n') : 'Queue empty.');\n }\n default: return JSON.stringify(record);\n }\n}\nfunction errorText(error: unknown) {\n const value = error as {code:string;message:string};\n return `${value.code}: ${value.message}`;\n}\nexport function exitCode(record: OutputRecord): number {\n if (record.type === 'cancelled') return 0;\n if (record.state === 'cancelled' || record.state === 'interrupted') return 130;\n const error = record.error as {code?:string}|undefined;\n if (!error && record.state !== 'failed') return 0;\n return /^(INVALID_|UNKNOWN_|AMBIGUOUS_|NOT_FAILED|NO_ACTIVE_TASK)/.test(error?.code ?? '') ? 2 : 1;\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import type { HarnessKind } from "../sdk/types.js";
2
+ import type { AccessConfig, AccessConnection } from "./access.js";
3
+ export interface AccessProvenance {
4
+ file: string;
5
+ present: boolean;
6
+ legacyFile?: string;
7
+ }
8
+ export declare function recordAccessProvenance(settings: AccessConfig, value: AccessProvenance): void;
9
+ export declare function quoteDiagnosticPath(path: string): string;
10
+ export declare function accessAttemptContext(settings: AccessConfig, harness: HarnessKind, connection: AccessConnection, index: number, total: number): string;
@@ -0,0 +1,31 @@
1
+ const provenance = new WeakMap();
2
+ export function recordAccessProvenance(settings, value) {
3
+ provenance.set(settings, value);
4
+ }
5
+ export function quoteDiagnosticPath(path) {
6
+ return JSON.stringify(path).replace(/[\u007f-\u009f\u2028\u2029]/gu, character => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`);
7
+ }
8
+ export function accessAttemptContext(settings, harness, connection, index, total) {
9
+ const configured = settings.access?.[harness] !== undefined;
10
+ const detail = configured
11
+ ? `configured entry ${index + 1} of ${total}`
12
+ : "native subscription discovery";
13
+ const lines = [`Access context: harness ${harness}; attempted connection type ${connection.type}; ${detail}.`];
14
+ const source = provenance.get(settings);
15
+ if (!source)
16
+ return lines[0];
17
+ if (!source.present) {
18
+ lines.push(`No personal access settings were found at ${quoteDiagnosticPath(source.file)}; using native subscription discovery.`);
19
+ if (source.legacyFile) {
20
+ lines.push(`A legacy personal access entry exists at ${quoteDiagnosticPath(source.legacyFile)}; it is not read.`);
21
+ }
22
+ }
23
+ else if (!configured) {
24
+ lines.push(`Personal access settings at ${quoteDiagnosticPath(source.file)} omit the ${harness} access entry; using native subscription discovery.`);
25
+ }
26
+ else {
27
+ lines.push(`Personal access settings were loaded from ${quoteDiagnosticPath(source.file)}.`);
28
+ }
29
+ return lines.join("\n");
30
+ }
31
+ //# sourceMappingURL=access-provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-provenance.js","sourceRoot":"","sources":["../../src/config/access-provenance.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,GAAG,IAAI,OAAO,EAAkC,CAAC;AAEjE,MAAM,UAAU,sBAAsB,CAAC,QAAsB,EAAE,KAAuB;IACpF,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,+BAA+B,EAAE,SAAS,CAAC,EAAE,CAC/E,MAAM,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,QAAsB,EACtB,OAAoB,EACpB,UAA4B,EAC5B,KAAa,EACb,KAAa;IAEb,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC;IAC5D,MAAM,MAAM,GAAG,UAAU;QACvB,CAAC,CAAC,oBAAoB,KAAK,GAAG,CAAC,OAAO,KAAK,EAAE;QAC7C,CAAC,CAAC,+BAA+B,CAAC;IACpC,MAAM,KAAK,GAAG,CAAC,2BAA2B,OAAO,+BAA+B,UAAU,CAAC,IAAI,KAAK,MAAM,GAAG,CAAC,CAAC;IAC/G,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC,CAAC,CAAE,CAAC;IAC9B,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,6CAA6C,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QAClI,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,4CAA4C,mBAAmB,CAAC,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;QACpH,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,+BAA+B,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,OAAO,qDAAqD,CAAC,CAAC;IACvJ,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,6CAA6C,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC","sourcesContent":["import type { HarnessKind } from \"../sdk/types.js\";\nimport type { AccessConfig, AccessConnection } from \"./access.js\";\n\nexport interface AccessProvenance {\n file: string;\n present: boolean;\n legacyFile?: string;\n}\n\nconst provenance = new WeakMap<AccessConfig, AccessProvenance>();\n\nexport function recordAccessProvenance(settings: AccessConfig, value: AccessProvenance): void {\n provenance.set(settings, value);\n}\n\nexport function quoteDiagnosticPath(path: string): string {\n return JSON.stringify(path).replace(/[\\u007f-\\u009f\\u2028\\u2029]/gu, character =>\n `\\\\u${character.charCodeAt(0).toString(16).padStart(4, \"0\")}`);\n}\n\nexport function accessAttemptContext(\n settings: AccessConfig,\n harness: HarnessKind,\n connection: AccessConnection,\n index: number,\n total: number,\n): string {\n const configured = settings.access?.[harness] !== undefined;\n const detail = configured\n ? `configured entry ${index + 1} of ${total}`\n : \"native subscription discovery\";\n const lines = [`Access context: harness ${harness}; attempted connection type ${connection.type}; ${detail}.`];\n const source = provenance.get(settings);\n if (!source) return lines[0]!;\n if (!source.present) {\n lines.push(`No personal access settings were found at ${quoteDiagnosticPath(source.file)}; using native subscription discovery.`);\n if (source.legacyFile) {\n lines.push(`A legacy personal access entry exists at ${quoteDiagnosticPath(source.legacyFile)}; it is not read.`);\n }\n } else if (!configured) {\n lines.push(`Personal access settings at ${quoteDiagnosticPath(source.file)} omit the ${harness} access entry; using native subscription discovery.`);\n } else {\n lines.push(`Personal access settings were loaded from ${quoteDiagnosticPath(source.file)}.`);\n }\n return lines.join(\"\\n\");\n}\n"]}
@@ -2,8 +2,18 @@ import type { HarnessKind } from "../sdk/types.js";
2
2
  export { resolveAccess } from "./resolve-access.js";
3
3
  export type AccessConnection = {
4
4
  type: "subscription";
5
+ provider?: string;
5
6
  } | {
6
- type: "api-key" | "vercel-api-key";
7
+ type: "api-key";
8
+ provider?: string;
9
+ env?: string;
10
+ envFile?: string;
11
+ baseUrl?: string;
12
+ wireApi?: "completions" | "responses";
13
+ apiVersion?: string;
14
+ wireModel?: string;
15
+ } | {
16
+ type: "vercel-api-key";
7
17
  env?: string;
8
18
  envFile?: string;
9
19
  } | {
@@ -16,6 +26,6 @@ export interface AccessConfig {
16
26
  access?: Partial<Record<HarnessKind, AccessConnection[]>>;
17
27
  }
18
28
  export declare function configError(message: string): never;
19
- export declare function parseConnection(value: unknown): AccessConnection;
29
+ export declare function parseConnection(value: unknown, harness?: HarnessKind): AccessConnection;
20
30
  export declare function parseAccess(value: unknown): AccessConfig;
21
31
  export declare function loadAccess(cwd: string): Promise<AccessConfig>;