subharness 0.0.4 → 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.
- package/README.md +36 -6
- package/dist/adapters/claude-process.d.ts +3 -0
- package/dist/adapters/claude-process.js +11 -1
- package/dist/adapters/claude-process.js.map +1 -1
- package/dist/adapters/claude-result.d.ts +2 -0
- package/dist/adapters/claude-result.js +22 -0
- package/dist/adapters/claude-result.js.map +1 -0
- package/dist/adapters/claude.js +30 -11
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/codex.js +4 -1
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/copilot-permissions.d.ts +26 -0
- package/dist/adapters/copilot-permissions.js +121 -0
- package/dist/adapters/copilot-permissions.js.map +1 -0
- package/dist/adapters/copilot-tools.d.ts +12 -0
- package/dist/adapters/copilot-tools.js +61 -0
- package/dist/adapters/copilot-tools.js.map +1 -0
- package/dist/adapters/copilot.d.ts +108 -0
- package/dist/adapters/copilot.js +819 -0
- package/dist/adapters/copilot.js.map +1 -0
- package/dist/adapters/cursor-cli-approvals.d.ts +2 -0
- package/dist/adapters/cursor-cli-approvals.js +83 -0
- package/dist/adapters/cursor-cli-approvals.js.map +1 -0
- package/dist/adapters/cursor-cli-model.d.ts +4 -0
- package/dist/adapters/cursor-cli-model.js +64 -0
- package/dist/adapters/cursor-cli-model.js.map +1 -0
- package/dist/adapters/cursor-cli-session.d.ts +32 -0
- package/dist/adapters/cursor-cli-session.js +316 -0
- package/dist/adapters/cursor-cli-session.js.map +1 -0
- package/dist/adapters/cursor-cli-tools.d.ts +20 -0
- package/dist/adapters/cursor-cli-tools.js +181 -0
- package/dist/adapters/cursor-cli-tools.js.map +1 -0
- package/dist/adapters/cursor-cli.d.ts +2 -0
- package/dist/adapters/cursor-cli.js +306 -0
- package/dist/adapters/cursor-cli.js.map +1 -0
- package/dist/adapters/cursor-model.d.ts +7 -0
- package/dist/adapters/cursor-model.js +67 -0
- package/dist/adapters/cursor-model.js.map +1 -0
- package/dist/adapters/cursor-rpc.d.ts +42 -0
- package/dist/adapters/cursor-rpc.js +271 -0
- package/dist/adapters/cursor-rpc.js.map +1 -0
- package/dist/adapters/cursor-session.d.ts +4 -0
- package/dist/adapters/cursor-session.js +327 -0
- package/dist/adapters/cursor-session.js.map +1 -0
- package/dist/adapters/cursor-startup.d.ts +16 -0
- package/dist/adapters/cursor-startup.js +74 -0
- package/dist/adapters/cursor-startup.js.map +1 -0
- package/dist/adapters/cursor-tools.d.ts +11 -0
- package/dist/adapters/cursor-tools.js +49 -0
- package/dist/adapters/cursor-tools.js.map +1 -0
- package/dist/adapters/cursor.d.ts +6 -0
- package/dist/adapters/cursor.js +17 -0
- package/dist/adapters/cursor.js.map +1 -0
- package/dist/adapters/fx-auth.d.ts +12 -2
- package/dist/adapters/fx-auth.js +51 -61
- package/dist/adapters/fx-auth.js.map +1 -1
- package/dist/adapters/fx-profile.d.ts +8 -0
- package/dist/adapters/fx-profile.js +101 -0
- package/dist/adapters/fx-profile.js.map +1 -0
- package/dist/adapters/fx-rpc.d.ts +2 -0
- package/dist/adapters/fx-rpc.js +30 -4
- package/dist/adapters/fx-rpc.js.map +1 -1
- package/dist/adapters/fx-status.d.ts +2 -0
- package/dist/adapters/fx-status.js +96 -0
- package/dist/adapters/fx-status.js.map +1 -0
- package/dist/adapters/fx.js +28 -12
- package/dist/adapters/fx.js.map +1 -1
- package/dist/adapters/opencode-access.d.ts +13 -0
- package/dist/adapters/opencode-access.js +76 -0
- package/dist/adapters/opencode-access.js.map +1 -0
- package/dist/adapters/opencode-config.d.ts +11 -0
- package/dist/adapters/opencode-config.js +238 -0
- package/dist/adapters/opencode-config.js.map +1 -0
- package/dist/adapters/opencode-http.d.ts +28 -0
- package/dist/adapters/opencode-http.js +297 -0
- package/dist/adapters/opencode-http.js.map +1 -0
- package/dist/adapters/opencode-tools.d.ts +19 -0
- package/dist/adapters/opencode-tools.js +127 -0
- package/dist/adapters/opencode-tools.js.map +1 -0
- package/dist/adapters/opencode.d.ts +2 -0
- package/dist/adapters/opencode.js +569 -0
- package/dist/adapters/opencode.js.map +1 -0
- package/dist/adapters/rpc.d.ts +3 -0
- package/dist/adapters/rpc.js +45 -4
- package/dist/adapters/rpc.js.map +1 -1
- package/dist/adapters/types.d.ts +5 -0
- package/dist/adapters/types.js.map +1 -1
- package/dist/approvals/types.d.ts +1 -1
- package/dist/approvals/types.js.map +1 -1
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.js +4 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/dashboard-client.js +1 -1
- package/dist/cli/dashboard-client.js.map +1 -1
- package/dist/cli/dashboard-controller.d.ts +7 -0
- package/dist/cli/dashboard-controller.js +27 -0
- package/dist/cli/dashboard-controller.js.map +1 -0
- package/dist/cli/dashboard-detail-view.d.ts +1 -1
- package/dist/cli/dashboard-detail-view.js +3 -4
- package/dist/cli/dashboard-detail-view.js.map +1 -1
- package/dist/cli/dashboard-history-view.js.map +1 -1
- package/dist/cli/dashboard-input.d.ts +1 -1
- package/dist/cli/dashboard-input.js +11 -1
- package/dist/cli/dashboard-input.js.map +1 -1
- package/dist/cli/dashboard-layout.js +3 -3
- package/dist/cli/dashboard-layout.js.map +1 -1
- package/dist/cli/dashboard-renderer.js.map +1 -1
- package/dist/cli/dashboard-style.js +2 -2
- package/dist/cli/dashboard-style.js.map +1 -1
- package/dist/cli/dashboard.d.ts +2 -2
- package/dist/cli/dashboard.js +7 -32
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +30 -12
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/main.js +5 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/config/access-provenance.d.ts +10 -0
- package/dist/config/access-provenance.js +31 -0
- package/dist/config/access-provenance.js.map +1 -0
- package/dist/config/access.d.ts +12 -2
- package/dist/config/access.js +125 -27
- package/dist/config/access.js.map +1 -1
- package/dist/config/loader.js +1 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/oidc.js +4 -2
- package/dist/config/oidc.js.map +1 -1
- package/dist/config/project.js +2 -1
- package/dist/config/project.js.map +1 -1
- package/dist/config/resolve-access.js +24 -10
- package/dist/config/resolve-access.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/process-diagnostics.d.ts +2 -0
- package/dist/process-diagnostics.js +11 -0
- package/dist/process-diagnostics.js.map +1 -0
- package/dist/runtime/access-errors.d.ts +4 -0
- package/dist/runtime/access-errors.js +25 -0
- package/dist/runtime/access-errors.js.map +1 -0
- package/dist/runtime/approval-registry.js +1 -1
- package/dist/runtime/approval-registry.js.map +1 -1
- package/dist/runtime/client.js +54 -14
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/dashboard-sanitize.d.ts +2 -0
- package/dist/runtime/dashboard-sanitize.js +7 -0
- package/dist/runtime/dashboard-sanitize.js.map +1 -0
- package/dist/runtime/dashboard.d.ts +1 -1
- package/dist/runtime/dashboard.js +2 -3
- package/dist/runtime/dashboard.js.map +1 -1
- package/dist/runtime/definition.js +11 -1
- package/dist/runtime/definition.js.map +1 -1
- package/dist/runtime/select-native.js +26 -8
- package/dist/runtime/select-native.js.map +1 -1
- package/dist/runtime/worker-client.js +38 -13
- package/dist/runtime/worker-client.js.map +1 -1
- package/dist/sdk/definitions.d.ts +4 -1
- package/dist/sdk/definitions.js +16 -2
- package/dist/sdk/definitions.js.map +1 -1
- package/dist/sdk/permission-validation.js +10 -1
- package/dist/sdk/permission-validation.js.map +1 -1
- package/dist/sdk/types.d.ts +29 -1
- package/dist/sdk/types.js.map +1 -1
- package/package.json +4 -1
- package/sdk/access-config.md +58 -4
- package/sdk/adapter-contract.md +5 -3
- package/sdk/additional-harnesses.md +43 -0
- package/sdk/agent-skill.md +2 -2
- package/sdk/agent.md +5 -3
- package/sdk/approvals.md +3 -1
- package/sdk/authentication.md +1 -1
- package/sdk/cli/dashboard-design.md +6 -0
- package/sdk/cli/index.md +9 -6
- package/sdk/cli/output.md +3 -1
- package/sdk/config.md +1 -1
- package/sdk/copilot.md +53 -0
- package/sdk/cursor.md +68 -0
- package/sdk/diagnostics.md +29 -0
- package/sdk/distribution.md +1 -1
- package/sdk/evals.md +1 -1
- package/sdk/fx.md +50 -5
- package/sdk/harnesses.md +13 -13
- package/sdk/index.md +3 -2
- package/sdk/opencode.md +57 -0
- package/sdk/permissions.md +4 -2
- package/sdk/project-team.md +2 -0
- package/sdk/tools.md +1 -1
- package/sdk/v1-runtime.md +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-client.js","sourceRoot":"","sources":["../../src/runtime/worker-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { fork, type ChildProcess } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport { delimiter } from 'node:path';\nimport { AgentError, errorInfo, type ErrorInfo } from '../errors.js';\nimport type { DriverInput } from './types.js';\nimport type { ManagedNativeSession } from './types.js';\nimport type { HarnessKind } from '../sdk/types.js';\nimport { createSessionLauncher } from './session-launcher.js';\nimport type { ApprovalEvent } from './worker-approvals.js';\n\ninterface WorkerClientOptions {\n workerModule?: URL;\n shutdownTimeoutMs?: number;\n}\n\nconst closeResponseTimeoutMs = 15_000;\nconst shutdownTimeoutMs = 1_000;\n\nfunction waitWithin(promise: Promise<unknown>, timeout: number): Promise<boolean> {\n return new Promise(resolve => {\n const timer = setTimeout(() => resolve(false),timeout);\n promise.then(\n () => { clearTimeout(timer); resolve(true); },\n () => { clearTimeout(timer); resolve(true); },\n );\n });\n}\n\nfunction withTimeout<T>(promise: Promise<T>, timeout: number): Promise<T> {\n return new Promise((resolve,reject) => {\n const timer = setTimeout(() => reject(new AgentError('HARNESS_FAILED','The session worker did not complete cleanup.')),timeout);\n promise.then(\n value => { clearTimeout(timer); resolve(value); },\n error => { clearTimeout(timer); reject(error); },\n );\n });\n}\n\nexport async function createWorker(input: DriverInput, options: WorkerClientOptions = {}): Promise<ManagedNativeSession> {\n const launcher = await createSessionLauncher(input.env.AGENT_STATE_DIR!,input.token);\n const workerModule = options.workerModule ?? new URL(`./worker.${import.meta.url.endsWith('.ts') ? 'ts' : 'js'}`, import.meta.url);\n const extension = workerModule.pathname.endsWith('.ts') ? 'ts' : 'js';\n let child: ChildProcess;\n try {\n child = fork(fileURLToPath(workerModule), [], {\n cwd: input.cwd, env: {...input.env,AGENT_PARENT_TOKEN:input.token,AGENT_CLI_PATH:launcher.path,\n PATH:launcher.directory + delimiter + (input.env.PATH ?? '')},\n execArgv: extension === 'ts' ? ['--import', import.meta.resolve('tsx')] : [],\n stdio: ['ignore','ignore','ignore','ipc'],\n });\n } catch (error) { await launcher.close(); throw error; }\n let nextId = 1;\n const pending = new Map<number, {resolve(value:unknown):void;reject(error:Error):void}>();\n const approvals = new Map<number,AbortController>();\n const withdrawApprovals = () => { for (const controller of approvals.values()) controller.abort(); approvals.clear(); };\n let exited = false;\n let markExited!: () => void;\n const processExit = new Promise<void>(resolve => { markExited = resolve; });\n const exit = () => {\n if (exited) return;\n exited = true;\n withdrawApprovals();\n markExited();\n void launcher.close().catch(() => {}).finally(() => {\n for (const waiting of pending.values()) waiting.reject(new AgentError('HARNESS_FAILED','The session worker exited.'));\n pending.clear();\n });\n };\n child.once('error', exit); child.once('exit', exit);\n child.on('message', (message: ApprovalEvent | {id:number;result?:unknown;error?:ErrorInfo}) => {\n if ('event' in message) {\n if (message.event === 'approval.withdraw') {\n approvals.get(message.requestId)?.abort(); approvals.delete(message.requestId);\n } else if (message.event === 'approval.request') {\n const controller = new AbortController();\n approvals.set(message.requestId,controller);\n void Promise.resolve().then(() => {\n if (!input.onApproval) throw new AgentError('INPUT_REQUIRED','Native tool approval requires an observing caller.');\n return input.onApproval(message.request,controller.signal);\n }).then(\n content => { if (!controller.signal.aborted && !exited) return request('approval.respond',{requestId:message.requestId,content}); },\n error => { if (!controller.signal.aborted && !exited) return request('approval.respond',{requestId:message.requestId,error:errorInfo(error)}); },\n ).catch(error => {\n // A rejected control cannot leave an already-settled caller callback parked forever.\n if (!controller.signal.aborted && !exited)\n return request('approval.respond',{requestId:message.requestId,error:errorInfo(error)}).catch(() => {});\n }).finally(() => { approvals.delete(message.requestId); });\n }\n return;\n }\n const waiting = pending.get(message.id);\n if (!waiting) return;\n pending.delete(message.id);\n if (message.error) waiting.reject(new AgentError(message.error.code, message.error.message));\n else waiting.resolve(message.result);\n });\n const request = (method:string, extra:Record<string,unknown> = {}) => new Promise<unknown>((resolve,reject) => {\n if (exited) { reject(new AgentError('HARNESS_FAILED','The session worker is unavailable.')); return; }\n const id = nextId++;\n pending.set(id,{resolve,reject});\n child.send({id,method,...extra}, error => { if (error) { pending.delete(id); reject(new AgentError('HARNESS_FAILED','Cannot reach the session worker.')); } });\n });\n let selectedHarness: HarnessKind;\n const {onApproval,...serializedInput} = input;\n try { selectedHarness = await request('open',{input:serializedInput,handlesApprovals:!!onApproval}) as HarnessKind; } catch (error) { child.kill(); await launcher.close(); throw error; }\n const stopWorker = async () => {\n if (exited) return;\n if (child.connected) try { child.disconnect(); } catch { /* Continue to termination escalation. */ }\n const timeout = options.shutdownTimeoutMs ?? shutdownTimeoutMs;\n if (await waitWithin(processExit,timeout)) return;\n child.kill('SIGTERM');\n if (await waitWithin(processExit,timeout)) return;\n child.kill('SIGKILL');\n if (await waitWithin(processExit,timeout)) return;\n throw new AgentError('HARNESS_FAILED','The session worker did not confirm termination.');\n };\n return {\n selectedHarness,\n turn: prompt => request('turn',{prompt}) as Promise<string>,\n steer: async prompt => { await request('steer',{prompt}); },\n interrupt: async () => { withdrawApprovals(); await request('interrupt'); },\n resume: () => request('resume') as Promise<string>,\n close: async () => {\n withdrawApprovals();\n let failure: unknown;\n if (!exited) {\n try { await withTimeout(request('close'),closeResponseTimeoutMs); }\n catch (error) { failure = error; }\n }\n try { await stopWorker(); } catch (error) { failure ??= error; }\n try { await launcher.close(); } catch (error) { failure ??= error; }\n if (failure) throw failure;\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"worker-client.js","sourceRoot":"","sources":["../../src/runtime/worker-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { fork, type ChildProcess } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport { delimiter } from 'node:path';\nimport { AgentError, errorInfo, type ErrorInfo } from '../errors.js';\nimport type { DriverInput } from './types.js';\nimport type { ManagedNativeSession } from './types.js';\nimport type { HarnessKind } from '../sdk/types.js';\nimport { createSessionLauncher } from './session-launcher.js';\nimport type { ApprovalEvent } from './worker-approvals.js';\nimport { processExitDescription } from '../process-diagnostics.js';\n\ninterface WorkerClientOptions {\n workerModule?: URL;\n shutdownTimeoutMs?: number;\n}\n\nconst closeResponseTimeoutMs = 15_000;\nconst shutdownTimeoutMs = 1_000;\n\nconst workerOperationLabels: Record<string,string> = {\n open:'startup',\n turn:'turn submission',\n steer:'steering',\n interrupt:'interruption',\n resume:'recovery',\n close:'closing',\n 'approval.respond':'approval response',\n};\n\nfunction waitWithin(promise: Promise<unknown>, timeout: number): Promise<boolean> {\n return new Promise(resolve => {\n const timer = setTimeout(() => resolve(false),timeout);\n promise.then(\n () => { clearTimeout(timer); resolve(true); },\n () => { clearTimeout(timer); resolve(true); },\n );\n });\n}\n\nfunction withTimeout<T>(promise: Promise<T>, timeout: number): Promise<T> {\n return new Promise((resolve,reject) => {\n const timer = setTimeout(() => reject(new AgentError('HARNESS_FAILED','The session worker did not complete cleanup.')),timeout);\n promise.then(\n value => { clearTimeout(timer); resolve(value); },\n error => { clearTimeout(timer); reject(error); },\n );\n });\n}\n\nexport async function createWorker(input: DriverInput, options: WorkerClientOptions = {}): Promise<ManagedNativeSession> {\n const launcher = await createSessionLauncher(input.env.AGENT_STATE_DIR!,input.token);\n const workerModule = options.workerModule ?? new URL(`./worker.${import.meta.url.endsWith('.ts') ? 'ts' : 'js'}`, import.meta.url);\n const extension = workerModule.pathname.endsWith('.ts') ? 'ts' : 'js';\n let child: ChildProcess;\n try {\n child = fork(fileURLToPath(workerModule), [], {\n cwd: input.cwd, env: {...input.env,AGENT_PARENT_TOKEN:input.token,AGENT_CLI_PATH:launcher.path,\n PATH:launcher.directory + delimiter + (input.env.PATH ?? '')},\n execArgv: extension === 'ts' ? ['--import', import.meta.resolve('tsx')] : [],\n stdio: ['ignore','ignore','ignore','ipc'],\n });\n } catch { await launcher.close(); throw new AgentError('HARNESS_FAILED','The session worker could not be spawned during startup.'); }\n let nextId = 1;\n const pending = new Map<number, {operation:string;resolve(value:unknown):void;reject(error:Error):void}>();\n const approvals = new Map<number,AbortController>();\n const withdrawApprovals = () => { for (const controller of approvals.values()) controller.abort(); approvals.clear(); };\n let exited = false;\n let closing = false;\n let observedExit = '';\n let markExited!: () => void;\n const processExit = new Promise<void>(resolve => { markExited = resolve; });\n const exit = (code: unknown, signal: unknown, spawnFailure = false) => {\n if (exited) return;\n exited = true;\n observedExit = spawnFailure || closing ? '' : processExitDescription(code,signal);\n withdrawApprovals();\n markExited();\n void launcher.close().catch(() => {}).finally(() => {\n for (const waiting of pending.values()) {\n waiting.reject(new AgentError('HARNESS_FAILED', spawnFailure\n ? `The session worker process failed while ${waiting.operation} was pending.`\n : `The session worker exited while ${waiting.operation} was pending${observedExit}.`));\n }\n pending.clear();\n });\n };\n child.once('error', () => exit(undefined,undefined,true));\n child.once('exit', (code,signal) => exit(code,signal));\n child.on('message', (message: ApprovalEvent | {id:number;result?:unknown;error?:ErrorInfo}) => {\n if ('event' in message) {\n if (message.event === 'approval.withdraw') {\n approvals.get(message.requestId)?.abort(); approvals.delete(message.requestId);\n } else if (message.event === 'approval.request') {\n const controller = new AbortController();\n approvals.set(message.requestId,controller);\n void Promise.resolve().then(() => {\n if (!input.onApproval) throw new AgentError('INPUT_REQUIRED','Native tool approval requires an observing caller.');\n return input.onApproval(message.request,controller.signal);\n }).then(\n content => { if (!controller.signal.aborted && !exited) return request('approval.respond',{requestId:message.requestId,content}); },\n error => { if (!controller.signal.aborted && !exited) return request('approval.respond',{requestId:message.requestId,error:errorInfo(error)}); },\n ).catch(error => {\n // A rejected control cannot leave an already-settled caller callback parked forever.\n if (!controller.signal.aborted && !exited)\n return request('approval.respond',{requestId:message.requestId,error:errorInfo(error)}).catch(() => {});\n }).finally(() => { approvals.delete(message.requestId); });\n }\n return;\n }\n const waiting = pending.get(message.id);\n if (!waiting) return;\n pending.delete(message.id);\n if (message.error) waiting.reject(new AgentError(message.error.code, message.error.message));\n else waiting.resolve(message.result);\n });\n const request = (method:string, extra:Record<string,unknown> = {}) => new Promise<unknown>((resolve,reject) => {\n const operation = workerOperationLabels[method] ?? 'native operation';\n if (exited) {\n reject(new AgentError('HARNESS_FAILED',`The session worker is unavailable while ${operation} was pending${observedExit}.`));\n return;\n }\n const id = nextId++;\n pending.set(id,{operation,resolve,reject});\n child.send({id,method,...extra}, error => {\n if (!error) return;\n setImmediate(() => {\n const waiting = pending.get(id);\n if (!waiting || exited) return;\n pending.delete(id);\n waiting.reject(new AgentError('HARNESS_FAILED',`Cannot reach the session worker while ${operation} was pending.`));\n });\n });\n });\n let selectedHarness: HarnessKind;\n const {onApproval,...serializedInput} = input;\n try { selectedHarness = await request('open',{input:serializedInput,handlesApprovals:!!onApproval}) as HarnessKind; } catch (error) { child.kill(); await launcher.close(); throw error; }\n const stopWorker = async () => {\n if (exited) return;\n if (child.connected) try { child.disconnect(); } catch { /* Continue to termination escalation. */ }\n const timeout = options.shutdownTimeoutMs ?? shutdownTimeoutMs;\n if (await waitWithin(processExit,timeout)) return;\n child.kill('SIGTERM');\n if (await waitWithin(processExit,timeout)) return;\n child.kill('SIGKILL');\n if (await waitWithin(processExit,timeout)) return;\n throw new AgentError('HARNESS_FAILED','The session worker did not confirm termination.');\n };\n return {\n selectedHarness,\n turn: prompt => request('turn',{prompt}) as Promise<string>,\n steer: async prompt => { await request('steer',{prompt}); },\n interrupt: async () => { withdrawApprovals(); await request('interrupt'); },\n resume: () => request('resume') as Promise<string>,\n close: async () => {\n closing = true;\n withdrawApprovals();\n let failure: unknown;\n if (!exited) {\n try { await withTimeout(request('close'),closeResponseTimeoutMs); }\n catch (error) { failure = error; }\n }\n try { await stopWorker(); } catch (error) { failure ??= error; }\n try { await launcher.close(); } catch (error) { failure ??= error; }\n if (failure) throw failure;\n },\n };\n}\n"]}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type { AgentDefinition, ClaudeCodeConfig, ClaudeCodeOptions, CodexConfig, CodexOptions, FxConfig, FxOptions } from "./types.js";
|
|
1
|
+
import type { AgentDefinition, ClaudeCodeConfig, ClaudeCodeOptions, CodexConfig, CodexOptions, FxConfig, FxOptions, OpencodeConfig, OpencodeOptions, CopilotConfig, CopilotOptions, CursorConfig, CursorOptions } from "./types.js";
|
|
2
2
|
export declare function codex(options: CodexOptions): CodexConfig;
|
|
3
3
|
export declare function claudeCode(options: ClaudeCodeOptions): ClaudeCodeConfig;
|
|
4
4
|
export declare function fx(options: FxOptions): FxConfig;
|
|
5
|
+
export declare function opencode(options: OpencodeOptions): OpencodeConfig;
|
|
6
|
+
export declare function copilot(options: CopilotOptions): CopilotConfig;
|
|
7
|
+
export declare function cursor(options: CursorOptions): CursorConfig;
|
|
5
8
|
export declare function agent(definition: AgentDefinition): AgentDefinition;
|
|
6
9
|
export declare function validateAgent(value: unknown, ancestors?: Set<unknown>): asserts value is AgentDefinition;
|
package/dist/sdk/definitions.js
CHANGED
|
@@ -4,10 +4,12 @@ import { validateTool } from "./tools.js";
|
|
|
4
4
|
function validateHarness(value, configured = false, expectedKind) {
|
|
5
5
|
object(value);
|
|
6
6
|
const candidate = configured ? value.kind : expectedKind;
|
|
7
|
-
if (
|
|
7
|
+
if (!["codex", "claudeCode", "fx", "opencode", "copilot", "cursor"].includes(candidate))
|
|
8
8
|
invalid("Unsupported harness kind.");
|
|
9
9
|
const kind = candidate;
|
|
10
|
-
const fields = ["model"
|
|
10
|
+
const fields = ["model"];
|
|
11
|
+
if (kind === "codex" || kind === "claudeCode" || kind === "fx")
|
|
12
|
+
fields.push("effort");
|
|
11
13
|
if (kind === "codex" || kind === "claudeCode")
|
|
12
14
|
fields.push("fast");
|
|
13
15
|
fields.push(...permissionOptionFields(kind));
|
|
@@ -45,6 +47,18 @@ export function fx(options) {
|
|
|
45
47
|
validateHarness(options, false, "fx");
|
|
46
48
|
return Object.freeze({ ...options, kind: "fx" });
|
|
47
49
|
}
|
|
50
|
+
export function opencode(options) {
|
|
51
|
+
validateHarness(options, false, "opencode");
|
|
52
|
+
return Object.freeze({ ...options, kind: "opencode" });
|
|
53
|
+
}
|
|
54
|
+
export function copilot(options) {
|
|
55
|
+
validateHarness(options, false, "copilot");
|
|
56
|
+
return Object.freeze({ ...options, kind: "copilot" });
|
|
57
|
+
}
|
|
58
|
+
export function cursor(options) {
|
|
59
|
+
validateHarness(options, false, "cursor");
|
|
60
|
+
return Object.freeze({ ...options, kind: "cursor" });
|
|
61
|
+
}
|
|
48
62
|
export function agent(definition) {
|
|
49
63
|
validateAgent(definition);
|
|
50
64
|
return Object.freeze({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/sdk/definitions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/sdk/definitions.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,SAAS,eAAe,CAAC,KAAc,EAAE,UAAU,GAAG,KAAK,EAAE,YAAoC;IAC/F,MAAM,CAAC,KAAK,CAAC,CAAC;IACd,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC;IACzD,IAAI,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,SAAmB,CAAC;QAAE,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACxI,MAAM,IAAI,GAAG,SAAkC,CAAC;IAChD,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC;IACzB,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,IAAI;QAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtF,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,YAAY;QAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnE,MAAM,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7C,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACzD,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjE,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACpG,IAAI,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;QAAE,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClF,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,oBAAoB,CAAC,MAAe;IAC3C,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAgB,CAAC,EAAE,CAAC;QAClG,OAAO,CAAC,yDAAyD,CAAC,CAAC;IACrE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,OAAqB;IACzC,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAA0B;IACnD,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAC9C,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,GAAG,OAAO;QACV,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3F,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpG,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK;KAC5B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,EAAE,CAAC,OAAkB;IACnC,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAwB;IAC/C,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAC5C,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAuB;IAC7C,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAC3C,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,OAAsB;IAC3C,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,UAA2B;IAC/C,aAAa,CAAC,UAAU,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,GAAG,UAAU;QACb,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjG,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3F,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,SAAS,GAAG,IAAI,GAAG,EAAW;IAC1E,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;IACxF,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,2DAA2D,CAAC,CAAC;IAC/F,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC3C,QAAQ,CAAC,KAAK,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjF,IAAI,CAAC,SAAS,CAAC,MAAM;QAAE,OAAO,CAAC,mCAAmC,CAAC,CAAC;IACpE,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/D,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5D,SAAS,CAAC,IAAI,CAAC,CAAC;YAChB,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import type {\n AgentDefinition,\n ClaudeCodeConfig,\n ClaudeCodeOptions,\n CodexConfig,\n CodexOptions,\n FxConfig,\n FxOptions,\n HarnessConfig,\n OpencodeConfig,\n OpencodeOptions,\n CopilotConfig,\n CopilotOptions,\n CursorConfig,\n CursorOptions,\n} from \"./types.js\";\nimport { invalid, nonempty, object, validName } from \"./validation.js\";\nimport { permissionOptionFields, validateHarnessPermissions } from \"./permission-validation.js\";\nimport { validateTool } from \"./tools.js\";\n\nfunction validateHarness(value: unknown, configured = false, expectedKind?: HarnessConfig[\"kind\"]): void {\n object(value);\n const candidate = configured ? value.kind : expectedKind;\n if (![\"codex\", \"claudeCode\", \"fx\", \"opencode\", \"copilot\", \"cursor\"].includes(candidate as string)) invalid(\"Unsupported harness kind.\");\n const kind = candidate as HarnessConfig[\"kind\"];\n const fields = [\"model\"];\n if (kind === \"codex\" || kind === \"claudeCode\" || kind === \"fx\") fields.push(\"effort\");\n if (kind === \"codex\" || kind === \"claudeCode\") fields.push(\"fast\");\n fields.push(...permissionOptionFields(kind));\n object(value, configured ? [\"kind\", ...fields] : fields);\n nonempty(value.model, \"Model\");\n if (value.effort !== undefined) nonempty(value.effort, \"Effort\");\n if (value.fast !== undefined && typeof value.fast !== \"boolean\") invalid(\"fast must be a boolean.\");\n if (configured && value.kind === \"claudeCode\") validateClaudeEffort(value.effort);\n validateHarnessPermissions(kind, value);\n}\n\nfunction validateClaudeEffort(effort: unknown): void {\n if (effort !== undefined && ![\"low\", \"medium\", \"high\", \"xhigh\", \"max\"].includes(effort as string)) {\n invalid(\"Claude effort must be low, medium, high, xhigh, or max.\");\n }\n}\n\nexport function codex(options: CodexOptions): CodexConfig {\n validateHarness(options, false, \"codex\");\n return Object.freeze({ ...options, kind: \"codex\", fast: options.fast ?? false });\n}\n\nexport function claudeCode(options: ClaudeCodeOptions): ClaudeCodeConfig {\n validateHarness(options, false, \"claudeCode\");\n validateClaudeEffort(options.effort);\n return Object.freeze({\n ...options,\n ...(options.allowedTools ? { allowedTools: Object.freeze([...options.allowedTools]) } : {}),\n ...(options.disallowedTools ? { disallowedTools: Object.freeze([...options.disallowedTools]) } : {}),\n kind: \"claudeCode\",\n fast: options.fast ?? false,\n });\n}\n\nexport function fx(options: FxOptions): FxConfig {\n validateHarness(options, false, \"fx\");\n return Object.freeze({ ...options, kind: \"fx\" });\n}\n\nexport function opencode(options: OpencodeOptions): OpencodeConfig {\n validateHarness(options, false, \"opencode\");\n return Object.freeze({ ...options, kind: \"opencode\" });\n}\n\nexport function copilot(options: CopilotOptions): CopilotConfig {\n validateHarness(options, false, \"copilot\");\n return Object.freeze({ ...options, kind: \"copilot\" });\n}\n\nexport function cursor(options: CursorOptions): CursorConfig {\n validateHarness(options, false, \"cursor\");\n return Object.freeze({ ...options, kind: \"cursor\" });\n}\n\nexport function agent(definition: AgentDefinition): AgentDefinition {\n validateAgent(definition);\n return Object.freeze({\n ...definition,\n ...(Array.isArray(definition.harness) ? { harness: Object.freeze([...definition.harness]) } : {}),\n ...(definition.tools ? { tools: Object.freeze({ ...definition.tools }) } : {}),\n ...(definition.subagents ? { subagents: Object.freeze({ ...definition.subagents }) } : {}),\n });\n}\n\nexport function validateAgent(value: unknown, ancestors = new Set<unknown>()): asserts value is AgentDefinition {\n object(value, [\"name\", \"description\", \"instructions\", \"harness\", \"tools\", \"subagents\"]);\n if (ancestors.has(value)) invalid(\"Subagent definitions cannot contain recursive references.\");\n validName(value.name);\n nonempty(value.description, \"Description\");\n nonempty(value.instructions, \"Instructions\");\n const harnesses = Array.isArray(value.harness) ? value.harness : [value.harness];\n if (!harnesses.length) invalid(\"At least one harness is required.\");\n harnesses.forEach((harness) => validateHarness(harness, true));\n if (value.tools !== undefined) {\n object(value.tools);\n Object.keys(value.tools).forEach(validName);\n Object.values(value.tools).forEach(validateTool);\n }\n if (value.subagents !== undefined) {\n object(value.subagents);\n const next = new Set(ancestors).add(value);\n for (const [name, child] of Object.entries(value.subagents)) {\n validName(name);\n validateAgent(child, next);\n }\n }\n}\n"]}
|
|
@@ -3,6 +3,9 @@ const fields = {
|
|
|
3
3
|
codex: Object.freeze(["approvalPolicy", "sandboxMode", "networkAccessEnabled"]),
|
|
4
4
|
claudeCode: Object.freeze(["permissionMode", "allowedTools", "disallowedTools"]),
|
|
5
5
|
fx: Object.freeze(["permissionMode"]),
|
|
6
|
+
opencode: Object.freeze([]),
|
|
7
|
+
copilot: Object.freeze([]),
|
|
8
|
+
cursor: Object.freeze(["sandboxMode"]),
|
|
6
9
|
};
|
|
7
10
|
const allFields = new Set(Object.values(fields).flat());
|
|
8
11
|
export function permissionOptionFields(kind) {
|
|
@@ -48,7 +51,13 @@ export function validateHarnessPermissions(kind, value) {
|
|
|
48
51
|
}
|
|
49
52
|
return;
|
|
50
53
|
}
|
|
51
|
-
if (
|
|
54
|
+
if (kind === "cursor") {
|
|
55
|
+
if (value.sandboxMode !== undefined && !["enabled", "disabled"].includes(value.sandboxMode)) {
|
|
56
|
+
invalid("Cursor sandboxMode must be enabled or disabled.");
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (kind === "fx" && value.permissionMode !== undefined && !["ask", "auto", "full-access"].includes(value.permissionMode)) {
|
|
52
61
|
invalid("fx permissionMode must be ask, auto, or full-access.");
|
|
53
62
|
}
|
|
54
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-validation.js","sourceRoot":"","sources":["../../src/sdk/permission-validation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,MAAM,GAAG;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,EAAE,aAAa,EAAE,sBAAsB,CAAC,CAAC;IAC/E,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,CAAC,CAAC;IAChF,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"permission-validation.js","sourceRoot":"","sources":["../../src/sdk/permission-validation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { HarnessKind } from \"./types.js\";\nimport { invalid } from \"./validation.js\";\n\nconst fields = {\n codex: Object.freeze([\"approvalPolicy\", \"sandboxMode\", \"networkAccessEnabled\"]),\n claudeCode: Object.freeze([\"permissionMode\", \"allowedTools\", \"disallowedTools\"]),\n fx: Object.freeze([\"permissionMode\"]),\n opencode: Object.freeze([]),\n copilot: Object.freeze([]),\n cursor: Object.freeze([\"sandboxMode\"]),\n} as const satisfies Record<HarnessKind, readonly string[]>;\n\nconst allFields = new Set(Object.values(fields).flat());\n\nexport function permissionOptionFields(kind: HarnessKind): readonly string[] {\n return fields[kind];\n}\n\n/** Validates only native permission fields, ignoring unrelated caller-owned fields. */\nexport function validateHarnessPermissions(kind: HarnessKind, value: Readonly<Record<string, unknown>>): void {\n const supported = new Set<string>(fields[kind]);\n if ([...allFields].some(field => Object.hasOwn(value, field) && !supported.has(field))) {\n invalid(\"Unknown configuration field.\");\n }\n\n if (kind === \"codex\") {\n if (value.approvalPolicy !== undefined && ![\"never\", \"on-request\", \"untrusted\"].includes(value.approvalPolicy as string)) {\n invalid(\"Codex approvalPolicy must be never, on-request, or untrusted.\");\n }\n if (value.sandboxMode !== undefined && ![\"read-only\", \"workspace-write\", \"danger-full-access\"].includes(value.sandboxMode as string)) {\n invalid(\"Codex sandboxMode must be read-only, workspace-write, or danger-full-access.\");\n }\n if (value.networkAccessEnabled !== undefined && typeof value.networkAccessEnabled !== \"boolean\") {\n invalid(\"Codex networkAccessEnabled must be a boolean.\");\n }\n if (value.networkAccessEnabled !== undefined && value.sandboxMode !== \"workspace-write\") {\n invalid(\"Codex networkAccessEnabled requires sandboxMode workspace-write.\");\n }\n return;\n }\n\n if (kind === \"claudeCode\") {\n if (value.permissionMode !== undefined && ![\"default\", \"acceptEdits\", \"bypassPermissions\", \"plan\", \"dontAsk\", \"auto\"].includes(value.permissionMode as string)) {\n invalid(\"Claude permissionMode is unsupported.\");\n }\n for (const field of [\"allowedTools\", \"disallowedTools\"] as const) {\n const rules = value[field];\n if (rules === undefined) continue;\n if (!Array.isArray(rules)) invalid(`Claude ${field} must be an array of nonempty strings.`);\n for (let index = 0; index < rules.length; index++) {\n const rule = rules[index];\n if (typeof rule !== \"string\" || !rule.trim()) {\n invalid(`Claude ${field} must be an array of nonempty strings.`);\n }\n }\n }\n return;\n }\n\n if (kind === \"cursor\") {\n if (value.sandboxMode !== undefined && ![\"enabled\", \"disabled\"].includes(value.sandboxMode as string)) {\n invalid(\"Cursor sandboxMode must be enabled or disabled.\");\n }\n return;\n }\n\n if (kind === \"fx\" && value.permissionMode !== undefined && ![\"ask\", \"auto\", \"full-access\"].includes(value.permissionMode as string)) {\n invalid(\"fx permissionMode must be ask, auto, or full-access.\");\n }\n}\n"]}
|
package/dist/sdk/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { z } from "zod";
|
|
2
|
-
export type HarnessKind = "codex" | "claudeCode" | "fx";
|
|
2
|
+
export type HarnessKind = "codex" | "claudeCode" | "fx" | "opencode" | "copilot" | "cursor";
|
|
3
3
|
export interface CodexConfig {
|
|
4
4
|
readonly kind: "codex";
|
|
5
5
|
readonly model: string;
|
|
@@ -24,8 +24,36 @@ export interface FxConfig {
|
|
|
24
24
|
readonly effort?: string;
|
|
25
25
|
readonly permissionMode?: "ask" | "auto" | "full-access";
|
|
26
26
|
}
|
|
27
|
+
export interface OpencodeOptions {
|
|
28
|
+
readonly model: string;
|
|
29
|
+
}
|
|
30
|
+
export interface OpencodeConfig extends OpencodeOptions {
|
|
31
|
+
readonly kind: "opencode";
|
|
32
|
+
}
|
|
33
|
+
export interface CopilotOptions {
|
|
34
|
+
readonly model: string;
|
|
35
|
+
}
|
|
36
|
+
export interface CopilotConfig extends CopilotOptions {
|
|
37
|
+
readonly kind: "copilot";
|
|
38
|
+
}
|
|
39
|
+
export interface CursorOptions {
|
|
40
|
+
readonly model: string;
|
|
41
|
+
readonly sandboxMode?: "enabled" | "disabled";
|
|
42
|
+
}
|
|
43
|
+
export interface CursorConfig extends CursorOptions {
|
|
44
|
+
readonly kind: "cursor";
|
|
45
|
+
}
|
|
27
46
|
export type HarnessConfig = CodexConfig | ClaudeCodeConfig | (FxConfig & {
|
|
28
47
|
readonly fast?: never;
|
|
48
|
+
}) | (OpencodeConfig & {
|
|
49
|
+
readonly effort?: never;
|
|
50
|
+
readonly fast?: never;
|
|
51
|
+
}) | (CopilotConfig & {
|
|
52
|
+
readonly effort?: never;
|
|
53
|
+
readonly fast?: never;
|
|
54
|
+
}) | (CursorConfig & {
|
|
55
|
+
readonly effort?: never;
|
|
56
|
+
readonly fast?: never;
|
|
29
57
|
});
|
|
30
58
|
export interface CodexOptions {
|
|
31
59
|
readonly model: string;
|
package/dist/sdk/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sdk/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { z } from \"zod\";\n\nexport type HarnessKind = \"codex\" | \"claudeCode\" | \"fx\";\n\nexport interface CodexConfig {\n readonly kind: \"codex\";\n readonly model: string;\n readonly effort?: string;\n readonly fast: boolean;\n readonly approvalPolicy?: \"never\" | \"on-request\" | \"untrusted\";\n readonly sandboxMode?: \"read-only\" | \"workspace-write\" | \"danger-full-access\";\n readonly networkAccessEnabled?: boolean;\n}\n\nexport interface ClaudeCodeConfig {\n readonly kind: \"claudeCode\";\n readonly model: string;\n readonly effort?: \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n readonly fast: boolean;\n readonly permissionMode?: \"default\" | \"acceptEdits\" | \"bypassPermissions\" | \"plan\" | \"dontAsk\" | \"auto\";\n readonly allowedTools?: readonly string[];\n readonly disallowedTools?: readonly string[];\n}\n\nexport interface FxConfig {\n readonly kind: \"fx\";\n readonly model: string;\n readonly effort?: string;\n readonly permissionMode?: \"ask\" | \"auto\" | \"full-access\";\n}\n\nexport type HarnessConfig
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sdk/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { z } from \"zod\";\n\nexport type HarnessKind = \"codex\" | \"claudeCode\" | \"fx\" | \"opencode\" | \"copilot\" | \"cursor\";\n\nexport interface CodexConfig {\n readonly kind: \"codex\";\n readonly model: string;\n readonly effort?: string;\n readonly fast: boolean;\n readonly approvalPolicy?: \"never\" | \"on-request\" | \"untrusted\";\n readonly sandboxMode?: \"read-only\" | \"workspace-write\" | \"danger-full-access\";\n readonly networkAccessEnabled?: boolean;\n}\n\nexport interface ClaudeCodeConfig {\n readonly kind: \"claudeCode\";\n readonly model: string;\n readonly effort?: \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n readonly fast: boolean;\n readonly permissionMode?: \"default\" | \"acceptEdits\" | \"bypassPermissions\" | \"plan\" | \"dontAsk\" | \"auto\";\n readonly allowedTools?: readonly string[];\n readonly disallowedTools?: readonly string[];\n}\n\nexport interface FxConfig {\n readonly kind: \"fx\";\n readonly model: string;\n readonly effort?: string;\n readonly permissionMode?: \"ask\" | \"auto\" | \"full-access\";\n}\n\nexport interface OpencodeOptions {\n readonly model: string;\n}\n\nexport interface OpencodeConfig extends OpencodeOptions {\n readonly kind: \"opencode\";\n}\n\nexport interface CopilotOptions {\n readonly model: string;\n}\n\nexport interface CopilotConfig extends CopilotOptions {\n readonly kind: \"copilot\";\n}\n\nexport interface CursorOptions {\n readonly model: string;\n readonly sandboxMode?: \"enabled\" | \"disabled\";\n}\n\nexport interface CursorConfig extends CursorOptions {\n readonly kind: \"cursor\";\n}\n\nexport type HarnessConfig =\n | CodexConfig\n | ClaudeCodeConfig\n | (FxConfig & { readonly fast?: never })\n | (OpencodeConfig & { readonly effort?: never; readonly fast?: never })\n | (CopilotConfig & { readonly effort?: never; readonly fast?: never })\n | (CursorConfig & { readonly effort?: never; readonly fast?: never });\n\nexport interface CodexOptions {\n readonly model: string;\n readonly effort?: string;\n readonly fast?: boolean;\n readonly approvalPolicy?: \"never\" | \"on-request\" | \"untrusted\";\n readonly sandboxMode?: \"read-only\" | \"workspace-write\" | \"danger-full-access\";\n readonly networkAccessEnabled?: boolean;\n}\n\nexport interface ClaudeCodeOptions {\n readonly model: string;\n readonly effort?: \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n readonly fast?: boolean;\n readonly permissionMode?: \"default\" | \"acceptEdits\" | \"bypassPermissions\" | \"plan\" | \"dontAsk\" | \"auto\";\n readonly allowedTools?: readonly string[];\n readonly disallowedTools?: readonly string[];\n}\n\nexport interface FxOptions {\n readonly model: string;\n readonly effort?: string;\n readonly permissionMode?: \"ask\" | \"auto\" | \"full-access\";\n}\n\nexport interface ToolDefinition<S extends z.ZodObject = z.ZodObject> {\n readonly description: string;\n readonly inputSchema: S;\n readonly execute: (input: z.output<S>) => unknown | Promise<unknown>;\n}\n\nexport interface AgentDefinition {\n readonly name: string;\n readonly description: string;\n readonly instructions: string;\n readonly harness: HarnessConfig | readonly HarnessConfig[];\n readonly tools?: Readonly<Record<string, ToolDefinition<any>>>;\n readonly subagents?: Readonly<Record<string, AgentDefinition>>;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subharness",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.18.0"
|
|
@@ -22,8 +22,11 @@
|
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@anthropic-ai/claude-agent-sdk": "0.3.278",
|
|
25
|
+
"@cursor/sdk": "1.0.32",
|
|
26
|
+
"@github/copilot-sdk": "1.0.14",
|
|
25
27
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
26
28
|
"string-width": "8.2.1",
|
|
29
|
+
"strip-ansi": "7.2.0",
|
|
27
30
|
"tsx": "4.23.15",
|
|
28
31
|
"zod": "4.6.5"
|
|
29
32
|
},
|
package/sdk/access-config.md
CHANGED
|
@@ -26,19 +26,73 @@ This example explicitly enables subscription-to-Gateway fallback for Codex befor
|
|
|
26
26
|
|
|
27
27
|
| `type` | Credential source | Default `env` |
|
|
28
28
|
| --- | --- | --- |
|
|
29
|
-
| `subscription` | The harness's
|
|
30
|
-
| `api-key` | Direct native provider API key | `OPENAI_API_KEY` for Codex, `ANTHROPIC_API_KEY` for Claude Code |
|
|
29
|
+
| `subscription` | The harness's saved native login for the selected route | Not applicable |
|
|
30
|
+
| `api-key` | Direct native provider API key | `OPENAI_API_KEY` for Codex, `ANTHROPIC_API_KEY` for Claude Code, `CURSOR_API_KEY` for Cursor |
|
|
31
31
|
| `vercel-api-key` | AI Gateway API key | `AI_GATEWAY_API_KEY` |
|
|
32
32
|
| `vercel-oidc` | Project OIDC token | `VERCEL_OIDC_TOKEN` |
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
The connection shapes are:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
type AccessConnection =
|
|
38
|
+
| { type: "subscription"; provider?: string }
|
|
39
|
+
| {
|
|
40
|
+
type: "api-key";
|
|
41
|
+
provider?: string;
|
|
42
|
+
env?: string;
|
|
43
|
+
envFile?: string;
|
|
44
|
+
baseUrl?: string;
|
|
45
|
+
wireApi?: "completions" | "responses";
|
|
46
|
+
apiVersion?: string;
|
|
47
|
+
wireModel?: string;
|
|
48
|
+
}
|
|
49
|
+
| { type: "vercel-api-key"; env?: string; envFile?: string }
|
|
50
|
+
| { type: "vercel-oidc"; env?: string; envFile?: string; project?: string };
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`provider` selects a native authentication or inference provider; it does not change the agent definition. Its meaning is harness-specific:
|
|
54
|
+
|
|
55
|
+
| Harness | `subscription` | Direct `api-key` |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| Codex | Native Codex login; no `provider` field | OpenAI; defaults to `OPENAI_API_KEY`; no provider options |
|
|
58
|
+
| Claude Code | Native Claude Code login; no `provider` field | Anthropic; defaults to `ANTHROPIC_API_KEY`; no provider options |
|
|
59
|
+
| Cursor | Native Cursor CLI login; no `provider` field | Cursor; defaults to `CURSOR_API_KEY`; no provider options |
|
|
60
|
+
| OpenCode | Required `provider`: `openai`, `github-copilot`, or `xai` | Required `provider` and explicit `env`; supported providers are defined in [OpenCode](opencode.md) |
|
|
61
|
+
| Copilot | Native Copilot or GitHub CLI login; no `provider` field | Required `provider`: `github`, `openai`, `anthropic`, or `azure` |
|
|
62
|
+
| fx | Required `provider`: `gateway`, `codex`, or `grok` | Required `provider` naming an existing native custom connection and explicit `env` |
|
|
63
|
+
|
|
64
|
+
For Copilot API keys, default variables are respectively `COPILOT_GITHUB_TOKEN`, `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, and `AZURE_OPENAI_API_KEY`. A GitHub token selects GitHub Copilot billing; the other three providers select direct provider billing. An explicit `env` replaces the default rather than adding credential discovery.
|
|
65
|
+
|
|
66
|
+
`baseUrl` is supported only for OpenCode direct API keys and Copilot BYOK providers. It must be an absolute HTTP or HTTPS URL without user information, query, or fragment; credentials belong in environment references. OpenCode preserves the selected provider's native endpoint when it is omitted. Copilot defaults OpenAI to `https://api.openai.com/v1` and Anthropic to `https://api.anthropic.com`; Azure requires an explicit `baseUrl`. OpenAI-compatible endpoints use Copilot `provider: "openai"` with an explicit URL. This does not define custom OpenCode provider or model metadata.
|
|
67
|
+
|
|
68
|
+
`wireApi` is supported only for Copilot OpenAI/Azure routes, defaulting to `completions`. `apiVersion` is supported only for Copilot Azure and maps to the native Azure API version; omission preserves its native versionless route. `wireModel` is supported only for Copilot BYOK and supplies the provider model or deployment name when it differs from the agent's native behavior model. Omission uses the agent's model for both. These fields are not accepted for GitHub-token, subscription, or Gateway routes. No arbitrary headers, token callbacks, or native configuration objects are accepted.
|
|
69
|
+
|
|
70
|
+
Gateway connection shapes and billing behavior are unchanged; they do not accept provider overrides. `vercel-oidc` accepts `project`, defaulting to `.`. Unknown or inapplicable fields and missing required provider/source selections fail before native startup. Variable names match `[A-Za-z_][A-Za-z0-9_]*`. Tokens and API keys must never appear directly in this file. Native logins are completed through each harness's own login command, outside Subharness.
|
|
35
71
|
|
|
36
72
|
Without `envFile`, the named variable is read from the invoking environment. With `envFile`, only that variable is read from that explicit UTF-8 dotenv file; its other values are not imported, and the process environment does not override the selected file. File and project paths resolve relative to the main checkout, or project root outside Git. Shell expansion and command execution in dotenv values are not supported. Sources are read at native session startup; changing a file does not refresh a token already supplied to a running harness.
|
|
37
73
|
|
|
38
|
-
Omitting `codex` or `claudeCode` retains native subscription discovery. A nonempty array replaces discovery with the listed connections in order. An empty array disables that harness. Supported keys are `codex`, `claudeCode`,
|
|
74
|
+
Omitting `codex` or `claudeCode` retains native subscription discovery. A nonempty array replaces discovery with the listed connections in order. An empty array disables that harness. Supported keys are `codex`, `claudeCode`, `fx`, `opencode`, `copilot`, and `cursor`. The last four require an explicit connection; omission enables no access, even when a native login or ambient key exists. fx, OpenCode, and Copilot accept their documented native login, direct-key, and Gateway routes. Cursor accepts native CLI login or Cursor SDK API-key access and rejects Gateway connections. Each connection selects one billing route without implicit substitution. See [fx](fx.md), [OpenCode](opencode.md), [Copilot](copilot.md), and [Cursor](cursor.md).
|
|
75
|
+
|
|
76
|
+
Missing credentials make a connection unavailable before submission; malformed settings, malformed tokens, expired OIDC tokens, and project mismatches are errors. Only known unavailability permits advancing to another explicitly enabled connection or harness. Native status and configuration checks do not prove remote credential validity, quota, or plan eligibility. Failures after submission never automatically migrate or replay the task.
|
|
39
77
|
|
|
40
78
|
`subharness check` resolves these settings and tries eligible connections and declared harness alternatives exactly as `run` does before submission. It does not infer readiness from environment variables or duplicate adapter authentication checks. A successful check applies only to the connection and harness selected by that fallback process at that moment.
|
|
41
79
|
|
|
80
|
+
## Access context in errors
|
|
81
|
+
|
|
82
|
+
Schema validation locations and distinct OIDC temporal errors are defined in [error diagnostics](diagnostics.md). A settings validation failure identifies the file and structural location before native access selection begins.
|
|
83
|
+
|
|
84
|
+
When a connection fails during native startup, `check` and `run` include the harness and attempted connection type in the diagnostic. They retain the original error code and fallback rules. A model configuration failure reported by an already opened session also includes its selected connection context. This context describes the connection attempted by Subharness; it does not claim that the native harness authenticated successfully through that connection.
|
|
85
|
+
|
|
86
|
+
Diagnostics distinguish explicitly configured connections from default native subscription discovery. For settings loaded from disk, they identify the absolute personal settings path in the main checkout, or the execution project outside Git. If the file is absent, the diagnostic says that native subscription discovery was used because no personal access settings were found there. If the file exists but omits the harness's access entry, the diagnostic says that the entry is omitted. An explicit connection identifies its type and its position in the configured list, so multiple connections of the same type remain distinguishable.
|
|
87
|
+
|
|
88
|
+
When the current personal settings file is absent and an entry exists at the former `.agents/agents.local.json` location, the diagnostic also identifies that legacy path and explains that it is not read. Detecting the legacy entry does not read its contents, migrate it, or change connection selection. Failure to inspect the legacy location does not replace the original startup error. Settings presence and selection context are captured when access settings are loaded, so a later file change does not rewrite the explanation for an existing session.
|
|
89
|
+
|
|
90
|
+
Claude model mismatch diagnostics identify whether the mismatch was observed during startup settings validation, native initialization, or retained-session validation before submission. They do not infer that a mismatch is transient or that missing access settings caused it. A mismatch still fails without automatic retry, model substitution, or task replay.
|
|
91
|
+
|
|
92
|
+
For example, a startup mismatch with a missing access file reports the model validation failure together with `claudeCode`, the attempted `subscription` connection, and `No personal access settings were found at "/project/.subharness/agents.local.json"; using native subscription discovery.` Explicit Gateway access instead reports the configured `vercel-oidc` or `vercel-api-key` connection and its list position.
|
|
93
|
+
|
|
94
|
+
Added diagnostic context contains only connection-selection metadata and settings paths. It never includes credential values, environment contents, settings-file contents, or raw native output. Paths are quoted with C0 and C1 control characters, DEL, and Unicode line separators escaped so one path cannot inject terminal controls or extra diagnostic lines. Successful command output and the public error record shape remain unchanged.
|
|
95
|
+
|
|
42
96
|
## OIDC project selection
|
|
43
97
|
|
|
44
98
|
The selected project directory must contain `.vercel/project.json` with `projectId` and `orgId`. In a deployment without local linkage, `VERCEL_PROJECT_ID` and `VERCEL_ORG_ID` identify the expected project and organization when `project` is omitted. A supplied `project` always requires its explicit linkage. Token claims must match the expected project and organization and be within their validity interval. Local claim checks prevent accidental selection errors; the Gateway authenticates the token.
|
package/sdk/adapter-contract.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Native Adapter Contract
|
|
2
2
|
|
|
3
|
-
Adapters create native Codex, Claude Code, or
|
|
3
|
+
Adapters create native Codex, Claude Code, fx, OpenCode, GitHub Copilot, or Cursor conversations in the caller-supplied directory. Their implementation interface is internal and is not an SDK extension API. A session supplies `turn(prompt)`, `steer(prompt)`, `interrupt()`, `resume()`, and `close()`. A turn resolves with its complete text; machine-reported execution failures reject with a stable error code. The Cursor subscription ACP route has the documented limitation that some native backend failures arrive only as assistant text. Interrupt resolves only when active execution has stopped. Unsupported operations return explicit capability errors. Harness-specific contracts are defined for [fx](fx.md), [OpenCode](opencode.md), [Copilot](copilot.md), and [Cursor](cursor.md).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[Error diagnostics](diagnostics.md) defines startup failure classification, safe native failure categories, and process termination context. Unexpected Claude account-inspection or model-catalog exceptions are harness failures, not evidence that another access route should be tried.
|
|
6
|
+
|
|
7
|
+
Adapter startup receives the selected harness configuration, loaded agent definition, execution directory, environment, and resolved personal access. Startup verifies compatibility and access before submitting any task. A direct CLI harness target supplies no specialist instructions, custom tools, or declared children. Codex, Claude Code, and fx may request a verifiable native default model internally; OpenCode, Copilot, and Cursor require an explicit CLI model. Public SDK constructors always require a model. Default resolution happens before the first prompt, within the authorized access route, and the resolved model is retained for follow-ups. An unavailable or unverifiable default fails with guidance to supply `--model`, without probing it through a paid generation. Explicit model and effort validation remains effective. `HARNESS_UNAVAILABLE` and `ACCESS_UNAVAILABLE` permit trying another declared alternative before submission. Invalid configuration and unsupported explicit options do not. No adapter performs automatic fallback after turn submission.
|
|
6
8
|
|
|
7
9
|
The CLI readiness check uses this same startup and pre-submission fallback path in an isolated worker, then closes the native session without calling `turn`. It therefore verifies only capabilities observable during startup. It does not probe quota with generation, exercise native tools, or establish shell and child-launch permissions. Startup may create an empty native conversation and private temporary files; normal close removes library-owned temporary files under the adapter lifecycle rules.
|
|
8
10
|
|
|
@@ -22,7 +24,7 @@ Claude accelerated mode with subscription access is rejected in v1 because it re
|
|
|
22
24
|
|
|
23
25
|
## Native default selection
|
|
24
26
|
|
|
25
|
-
Direct CLI targets resolve omitted models through the native session's effective configuration before submitting user input. Codex uses the model returned by App Server `thread/start`, verifies the selected provider and subscription catalog when applicable, and retains that model in subsequent turns. fx uses the
|
|
27
|
+
Direct CLI targets resolve omitted models through the native session's effective configuration before submitting user input. Codex uses the model returned by App Server `thread/start`, verifies the selected provider and subscription catalog when applicable, and retains that model in subsequent turns. fx uses the selected native provider and model reported by ACP `session/new`, then verifies any explicit effort through the existing configuration control.
|
|
26
28
|
|
|
27
29
|
Claude Code resolves its effective model through a capability-checked native settings control. Only applied model and effort fields are retained; merged settings and credential-bearing source details are never logged or included in output. The adapter pins the resolved model for the session through the native model control and verifies the applied result before input is admitted. If the installed SDK or executable cannot expose a verifiable applied model before submission, omitted-model startup fails with `INVALID_CONFIG` and guidance to supply `--model`. Explicit models retain compatibility with native versions that lack that introspection, along with the existing catalog and initialization checks.
|
|
28
30
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Additional native harnesses
|
|
2
|
+
|
|
3
|
+
OpenCode, GitHub Copilot, and Cursor are native harness targets. The SDK exports `opencode`, `copilot`, and `cursor`. Their configuration discriminators, personal access keys, and reserved CLI targets are respectively `opencode`, `copilot`, and `cursor`.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { opencode, copilot, cursor } from "subharness";
|
|
7
|
+
|
|
8
|
+
opencode({ model: "anthropic/claude-sonnet-5" });
|
|
9
|
+
copilot({ model: "openai/gpt-6-astra" });
|
|
10
|
+
cursor({ model: "CURSOR_MODEL_ID", sandboxMode: "enabled" });
|
|
11
|
+
|
|
12
|
+
interface OpencodeOptions { readonly model: string }
|
|
13
|
+
interface CopilotOptions { readonly model: string }
|
|
14
|
+
interface OpencodeConfig extends OpencodeOptions { readonly kind: "opencode" }
|
|
15
|
+
interface CopilotConfig extends CopilotOptions { readonly kind: "copilot" }
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Constructors return immutable configurations. Models must be nonempty. These options deliberately expose only verified capabilities. `fast`, `effort`, unknown fields, and permission options for other harnesses are rejected. Cursor's additional sandbox option and native lifecycle are specified in [Cursor](cursor.md).
|
|
19
|
+
|
|
20
|
+
All three direct CLI targets require an explicit `--model` and reject `--effort`. An omitted or unverifiable model fails with `INVALID_CONFIG` and guidance to supply `--model`, without a generation to discover it. SDK constructors always require the model. OpenCode and Copilot Gateway models use the Gateway's `creator/model` identifier; adapters translate native provider prefixes internally and never silently select a different model.
|
|
21
|
+
|
|
22
|
+
## Access routes
|
|
23
|
+
|
|
24
|
+
OpenCode and Copilot accept explicit native saved-login, direct API-key, and Vercel AI Gateway connections. Each route is selected independently; Gateway is optional. The provider selectors, credential variables, endpoint options, and route-specific model IDs are defined in [personal access](access-config.md), [OpenCode](opencode.md), and [Copilot](copilot.md). Cursor accepts native CLI `subscription` or Cursor SDK `api-key` access and does not support Gateway connections. Omitting any of the three access keys enables no connections. Empty arrays disable them. No ambient credential enables spending.
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"access": {
|
|
28
|
+
"opencode": [{ "type": "vercel-oidc", "project": ".", "envFile": ".env.local" }],
|
|
29
|
+
"copilot": [{ "type": "vercel-oidc", "project": ".", "envFile": ".env.local" }],
|
|
30
|
+
"cursor": [{ "type": "api-key", "env": "CURSOR_API_KEY" }]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Existing credential reference, main-checkout path, OIDC identity/expiry, fallback, and credential redaction rules apply. Gateway API keys default to `AI_GATEWAY_API_KEY`, OIDC defaults to `VERCEL_OIDC_TOKEN`, and Cursor API keys default to `CURSOR_API_KEY`. Unsupported explicit connections fail before native startup, without choosing another billing route.
|
|
36
|
+
|
|
37
|
+
## CLI and coordination
|
|
38
|
+
|
|
39
|
+
The built-in catalog lists `codex`, `claude`, `fx`, `opencode`, `copilot`, and `cursor` in that order before specialists. Same-named specialists require a scope qualifier. Direct targets bypass catalog evaluation. These labels are accepted by the dashboard and execution records. Readiness checks use the same selection and cleanup path as runs and never submit a prompt.
|
|
40
|
+
|
|
41
|
+
The existing queue, declared-child launcher, task/result, interruption, and fallback contracts apply. These adapters do not expose verified active steering or prompt-free recovery. Steering uses the coordinator's documented interrupt behavior; `resume` returns `RECOVERY_UNSUPPORTED`. Unsupported interactive input fails with `INPUT_REQUIRED` without automatically granting permission. An adapter reports interruption only after native execution has stopped and admitted custom tool callbacks have settled. Native processes and resources must be closed before readiness can succeed.
|
|
42
|
+
|
|
43
|
+
The eval runner's named scenarios remain limited to the existing Codex, Claude Code, and fx matrix. Adding runtime harnesses does not implicitly add paid eval scenarios or native credentials.
|
package/sdk/agent-skill.md
CHANGED
|
@@ -14,7 +14,7 @@ The installer reads the source repository, so installation requires access to [v
|
|
|
14
14
|
|
|
15
15
|
## Location and discovery
|
|
16
16
|
|
|
17
|
-
The skill's entry point is `skills/subharness/SKILL.md` at the repository root, with its credential helper in `skills/subharness/scripts/refresh-vercel-oidc.mjs`. Its frontmatter `name` is `subharness`, and its `description` states that the skill applies when the human asks the agent to delegate, parallelize, or hand off work to Codex, Claude Code, or
|
|
17
|
+
The skill's entry point is `skills/subharness/SKILL.md` at the repository root, with its credential helper in `skills/subharness/scripts/refresh-vercel-oidc.mjs`. Its frontmatter `name` is `subharness`, and its `description` states that the skill applies when the human asks the agent to delegate, parallelize, or hand off work to Codex, Claude Code, fx, OpenCode, GitHub Copilot, or Cursor, or to follow up on, check, or cancel delegated work.
|
|
18
18
|
|
|
19
19
|
`npx skills add vercel-labs/subharness` offers only this skill. The repository's development skills under `.agents/skills/` set `metadata.internal: true` in their frontmatter, which the installer hides by default. That field does not change how native harnesses read those skills.
|
|
20
20
|
|
|
@@ -25,7 +25,7 @@ The skill is not part of the npm package. [Package Distribution](distribution.md
|
|
|
25
25
|
The skill is concise, task-oriented guidance for the main agent. It agrees with the [CLI](cli/index.md), [Output](cli/output.md), [Message delivery](message-delivery.md), and [Sessions](sessions.md), and [Responding to Native Permission Requests](approvals.md) references and introduces no commands, flags, defaults, or behavior they do not document. It covers:
|
|
26
26
|
|
|
27
27
|
- When to delegate: independent, well-scoped work that can run while the conversation continues, and when the human names a harness.
|
|
28
|
-
- Choosing a target: the reserved `claude`, `
|
|
28
|
+
- Choosing a target: the reserved `codex`, `claude`, `fx`, `opencode`, `copilot`, and `cursor` direct targets, and `subharness list` for discovered specialists.
|
|
29
29
|
- Starting work with `subharness run <target> [--cwd <directory>] <prompt>`, `--prompt`, or `--prompt-file`, including quoting a positional prompt and giving the child explicit task context, because children do not receive the main conversation's transcript or loaded skills.
|
|
30
30
|
- Preferring a single `subharness run <target> <prompt>` through the host's background-task controls when that capability is known to be available. The caller collects that hosted command's output later; a separate `--detach` and `wait` sequence is unnecessary for its first response.
|
|
31
31
|
- Using `subharness run <target> --detach <prompt>` when background-command support is unavailable or uncertain, returning after admission and retaining the task identifier. `wait` returns or awaits the first response and runs only after useful independent work, when the caller is ready to wait. The minimal example contains only `run --detach` and `wait`; `status` is a separate optional nonblocking snapshot, not an unconditional step before or after `wait`.
|
package/sdk/agent.md
CHANGED
|
@@ -45,12 +45,14 @@ Children do not inherit loaded skill contents or the parent's transcript. Includ
|
|
|
45
45
|
|
|
46
46
|
`codex(options)` and `claudeCode(options)` return configurations. Both require `model`, accept native `effort`, and accept `fast?: boolean`, defaulting to `false`. Options are typed independently to preserve each harness's capabilities. Codex effort values depend on the native model catalog; Claude effort accepts `low`, `medium`, `high`, `xhigh`, and `max`, subject to native model restrictions.
|
|
47
47
|
|
|
48
|
-
`fx(options)` requires `model` and accepts optional native `effort`. It has no `fast` option. Its readonly configuration has `kind: "fx"`; see the [fx contract](fx.md) for
|
|
48
|
+
`fx(options)` requires `model` and accepts optional native `effort`. It has no `fast` option. Its readonly configuration has `kind: "fx"`; see the [fx contract](fx.md) for supported access routes, native capabilities, and permission limits. `HarnessConfig` is the union of the native harness configurations, so narrowing by `kind` exposes the options supported by that harness.
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
`opencode(options)` and `copilot(options)` require only `model`. Their readonly configurations use `kind: "opencode"` and `kind: "copilot"`. `cursor(options)` requires `model` and accepts `sandboxMode?: "enabled" | "disabled"`; omission preserves Cursor's native default. These constructors reject `effort`, `fast`, and permission fields belonging to other harnesses. See [Additional native harnesses](additional-harnesses.md), [OpenCode](opencode.md), [Copilot](copilot.md), and [Cursor](cursor.md).
|
|
51
|
+
|
|
52
|
+
The package exports the corresponding `Options` and readonly `Config` types for all six constructors. Runtime validation also enforces Claude's listed effort values and Cursor's sandbox values when TypeScript checking is absent; unsupported values fail with `INVALID_DEFINITION` before native execution.
|
|
51
53
|
|
|
52
54
|
The `harness` property always uses that name, even for an array. Alternatives are considered in declaration order; an array does not mean parallel execution. [Personal access settings](access-config.md) determine which connections are eligible without editing a shared agent.
|
|
53
55
|
|
|
54
56
|
## Native permission options
|
|
55
57
|
|
|
56
|
-
|
|
58
|
+
The Codex, Claude Code, and fx constructors also accept the native permission options defined in [Native Permissions](permissions.md). Options are typed and validated independently for each harness. Omitted values preserve native settings; explicit values configure only the new native session and remain fixed for follow-ups. Cursor's `sandboxMode` selects the SDK sandbox for API-key access; subscription ACP access rejects explicit sandbox settings. OpenCode and Copilot expose no public permission option. There is no permission profile registry.
|
package/sdk/approvals.md
CHANGED
|
@@ -70,6 +70,8 @@ Claude tool approvals expose allow-once and denial. Session-scoped reuse is offe
|
|
|
70
70
|
|
|
71
71
|
fx retains the actual ACP option identifiers and descriptive labels. In the supported fx integration, `allow_always` means the session, not a permanent grant. The adapter accepts only offered options and translates the selected ID to the original ACP response. Native cancellation remains distinct from a chosen denial.
|
|
72
72
|
|
|
73
|
+
OpenCode exposes only its native once and rejection decisions for supported active permission requests. Copilot exposes only the specific offered approve-once and rejection decisions. Neither adapter exposes or invents a reusable grant. Their bounded action context and withdrawal behavior are defined in [OpenCode](opencode.md) and [Copilot](copilot.md). Cursor subscription sessions expose offered ACP allow-once and reject-once options, retaining native IDs and bounded tool context; persistent choices are excluded. Its API-key SDK route has no interactive approval bridge. Other Cursor interactive requests fail with `INPUT_REQUIRED` as defined in [Cursor](cursor.md).
|
|
74
|
+
|
|
73
75
|
Requests which cannot be represented faithfully, unsupported interactive input, and startup-time interactions fail explicitly with `INPUT_REQUIRED`. Policies such as `never` or `dontAsk` may suppress native requests entirely; hard sandbox denials cannot be approved through this mechanism. Omitted native settings remain unchanged.
|
|
74
76
|
|
|
75
77
|
These answer objects illustrate different schemas; submit one only when its fields and values are offered by the actual request:
|
|
@@ -102,7 +104,7 @@ These signatures describe an internal implementation boundary, not new package e
|
|
|
102
104
|
type ApprovalContent = Record<string, string | number | boolean | string[]>;
|
|
103
105
|
interface NativeApprovalRequest {
|
|
104
106
|
kind: "permission";
|
|
105
|
-
harness: "codex" | "claudeCode" | "fx";
|
|
107
|
+
harness: "codex" | "claudeCode" | "fx" | "opencode" | "copilot" | "cursor";
|
|
106
108
|
message: string;
|
|
107
109
|
requestedSchema: ApprovalSchema;
|
|
108
110
|
context?: Record<string, unknown>;
|
package/sdk/authentication.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Login belongs to the selected native harness or access provider. The library selects compatible access at startup and does not create a separate subscription account or transfer subscription tokens between harnesses.
|
|
4
4
|
|
|
5
|
-
Without personal settings,
|
|
5
|
+
Without personal settings, Codex and Claude Code retain native subscription discovery. Other harnesses require an explicit connection. An API credential in the environment does not enable API billing. Saved-login routes verify the native credential source according to each adapter contract; they do not infer plan eligibility, free usage, or a spending cap from OAuth alone. The fx saved Vercel login is a native-login route that still bills AI Gateway.
|
|
6
6
|
|
|
7
7
|
Users can mix subscription, direct API, Gateway API-key, and Gateway OIDC access in one project. Preferences belong to the user, separately from versioned agent definitions. Two contributors can run the same definition through different declared harness alternatives and compatible connections.
|
|
8
8
|
|
|
@@ -72,3 +72,9 @@ The overview remains a small snapshot. An open history requests only metadata fo
|
|
|
72
72
|
Inspection never sends prompts, steers, cancels, resumes or acknowledges work, starts execution, or restarts the coordinator. The private transport is defined in [Inspection transport](dashboard-inspection.md).
|
|
73
73
|
|
|
74
74
|
Snapshots require finished-history and grouped-context capabilities. A missing capability or the exact legacy unknown-operation response reports `COORDINATOR_OUTDATED` with restart guidance. Opening history against a coordinator without the history operation reports the same error rather than presenting incomplete history. Other malformed or failed reads report `COORDINATOR_UNAVAILABLE` after terminal cleanup. Restarting a coordinator discards retained history and is never performed automatically.
|
|
75
|
+
|
|
76
|
+
## Shared presentation boundary
|
|
77
|
+
|
|
78
|
+
The terminal command and website demonstration reuse the internal ANSI renderer, layout, history/detail formatting, text sanitization, input decoding and key-action dispatch. Presentation code accepts explicit dimensions, data and time; it does not discover workspaces, access credentials, read files or contact the coordinator. This boundary adds no public SDK method. The terminal command preserves its existing process lifecycle, serialized reads and backpressure behavior. The website supplies fictional read-only projections and owns its browser terminal lifecycle.
|
|
79
|
+
|
|
80
|
+
The internal `dispatchDashboardKey(renderer, key)` function in `src/cli/dashboard-controller.ts` applies a `DashboardKey` to a `DashboardRenderer` and returns `{ interrupt: boolean; refreshInspection: boolean }`. Interrupt requests process exit only in the CLI host; the browser host instead releases focus. `refreshInspection` is true when a successful open, toggle, leave or selected-request change invalidates the previous inspection read, including collapsing an expanded request by changing selection. Hosts cancel obsolete reads or load their local sample projection after that signal. Overview movement and scrolling an unchanged expansion do not request new detail reads. The dispatcher never fetches data or schedules timers.
|