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.
- package/README.md +39 -9
- package/dist/adapters/approval-context.d.ts +2 -0
- package/dist/adapters/approval-context.js +9 -0
- package/dist/adapters/approval-context.js.map +1 -0
- package/dist/adapters/approval-lifetime.d.ts +8 -0
- package/dist/adapters/approval-lifetime.js +50 -0
- package/dist/adapters/approval-lifetime.js.map +1 -0
- package/dist/adapters/claude-approvals.d.ts +4 -0
- package/dist/adapters/claude-approvals.js +32 -0
- package/dist/adapters/claude-approvals.js.map +1 -0
- package/dist/adapters/claude-permissions.js +1 -1
- package/dist/adapters/claude-permissions.js.map +1 -1
- 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 +60 -12
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/codex-approvals.d.ts +6 -0
- package/dist/adapters/codex-approvals.js +111 -0
- package/dist/adapters/codex-approvals.js.map +1 -0
- package/dist/adapters/codex.js +36 -3
- 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-approvals.d.ts +2 -0
- package/dist/adapters/fx-approvals.js +14 -0
- package/dist/adapters/fx-approvals.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 +77 -30
- 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 +7 -0
- package/dist/adapters/types.js.map +1 -1
- package/dist/approvals/schema.d.ts +4 -0
- package/dist/approvals/schema.js +70 -0
- package/dist/approvals/schema.js.map +1 -0
- package/dist/approvals/types.d.ts +47 -0
- package/dist/approvals/types.js +2 -0
- package/dist/approvals/types.js.map +1 -0
- package/dist/cli/args.d.ts +3 -2
- package/dist/cli/args.js +24 -3
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/dashboard-client.d.ts +5 -1
- package/dist/cli/dashboard-client.js +162 -15
- 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 +16 -0
- package/dist/cli/dashboard-detail-view.js +162 -0
- package/dist/cli/dashboard-detail-view.js.map +1 -0
- package/dist/cli/dashboard-history-view.d.ts +29 -0
- package/dist/cli/dashboard-history-view.js +211 -0
- package/dist/cli/dashboard-history-view.js.map +1 -0
- package/dist/cli/dashboard-input.d.ts +14 -0
- package/dist/cli/dashboard-input.js +128 -0
- package/dist/cli/dashboard-input.js.map +1 -0
- package/dist/cli/dashboard-layout.d.ts +12 -1
- package/dist/cli/dashboard-layout.js +32 -30
- package/dist/cli/dashboard-layout.js.map +1 -1
- package/dist/cli/dashboard-renderer.d.ts +30 -2
- package/dist/cli/dashboard-renderer.js +125 -7
- package/dist/cli/dashboard-renderer.js.map +1 -1
- package/dist/cli/dashboard-style.d.ts +9 -0
- package/dist/cli/dashboard-style.js +36 -0
- package/dist/cli/dashboard-style.js.map +1 -0
- package/dist/cli/dashboard.d.ts +5 -3
- package/dist/cli/dashboard.js +102 -12
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +37 -12
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/input.d.ts +1 -0
- package/dist/cli/input.js +23 -17
- package/dist/cli/input.js.map +1 -1
- package/dist/cli/main.js +6 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/output.js +17 -1
- package/dist/cli/output.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.d.ts +27 -0
- package/dist/runtime/approval-registry.js +126 -0
- package/dist/runtime/approval-registry.js.map +1 -0
- package/dist/runtime/client.js +54 -14
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/coordinator.d.ts +17 -1
- package/dist/runtime/coordinator.js +124 -6
- package/dist/runtime/coordinator.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 +43 -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.d.ts +2 -1
- package/dist/runtime/select-native.js +28 -10
- package/dist/runtime/select-native.js.map +1 -1
- package/dist/runtime/service.js +24 -1
- package/dist/runtime/service.js.map +1 -1
- package/dist/runtime/types.d.ts +9 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/runtime/worker-approvals.d.ts +21 -0
- package/dist/runtime/worker-approvals.js +51 -0
- package/dist/runtime/worker-approvals.js.map +1 -0
- package/dist/runtime/worker-client.js +73 -20
- package/dist/runtime/worker-client.js.map +1 -1
- package/dist/runtime/worker-server.d.ts +2 -0
- package/dist/runtime/worker-server.js +39 -10
- package/dist/runtime/worker-server.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 +86 -4
- package/sdk/adapter-contract.md +7 -13
- package/sdk/additional-harnesses.md +43 -0
- package/sdk/agent-skill.md +7 -4
- package/sdk/agent.md +5 -3
- package/sdk/approvals.md +120 -0
- package/sdk/authentication.md +1 -1
- package/sdk/cli/dashboard-design.md +44 -4
- package/sdk/cli/dashboard-inspection.md +25 -0
- package/sdk/cli/index.md +20 -11
- package/sdk/cli/output.md +10 -4
- package/sdk/completion-notifications.md +2 -0
- 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 +53 -1
- package/sdk/evals.md +10 -4
- package/sdk/fx.md +51 -6
- package/sdk/harnesses.md +13 -13
- package/sdk/index.md +4 -2
- package/sdk/message-delivery.md +1 -1
- package/sdk/opencode.md +57 -0
- package/sdk/permissions.md +7 -5
- package/sdk/pr-integration.md +1 -1
- package/sdk/project-team.md +2 -0
- package/sdk/sessions.md +4 -1
- package/sdk/tools.md +1 -1
- package/sdk/v1-runtime.md +6 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-errors.js","sourceRoot":"","sources":["../../src/runtime/access-errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,UAAU,iBAAiB,CAAC,KAAiB,EAAE,OAAe;IAClE,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,KAAK,UAAU,WAAW,CAAI,SAA2B,EAAE,OAAe;IACxE,IAAI,CAAC;QAAC,OAAO,MAAM,SAAS,EAAE,CAAC;IAAC,CAAC;IACjC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,KAAK,YAAY,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YACnE,MAAM,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAAqB,EAAE,OAAe;IAC7E,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAC/D,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QACjE,SAAS,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC;QAC/D,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,CAAC;QACzD,KAAK,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC;KACxD,CAAC;AACJ,CAAC","sourcesContent":["import type { NativeSession } from \"../adapters/types.js\";\nimport { AgentError } from \"../errors.js\";\n\nexport function withAccessContext(error: AgentError, context: string): AgentError {\n return new AgentError(error.code, `${error.message}\\n${context}`);\n}\n\nasync function sessionCall<T>(operation: () => Promise<T>, context: string): Promise<T> {\n try { return await operation(); }\n catch (error) {\n if (error instanceof AgentError && error.code === \"INVALID_CONFIG\") {\n throw withAccessContext(error, context);\n }\n throw error;\n }\n}\n\nexport function withSessionAccessContext(native: NativeSession, context: string): NativeSession {\n return {\n turn: prompt => sessionCall(() => native.turn(prompt), context),\n steer: prompt => sessionCall(() => native.steer(prompt), context),\n interrupt: () => sessionCall(() => native.interrupt(), context),\n resume: () => sessionCall(() => native.resume(), context),\n close: () => sessionCall(() => native.close(), context),\n };\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ApprovalContent, NativeApprovalRequest } from '../approvals/types.js';
|
|
2
|
+
import type { ApprovalRequest } from './types.js';
|
|
3
|
+
type RequestIdentity = Pick<ApprovalRequest, 'requestId' | 'taskId' | 'sessionId'>;
|
|
4
|
+
/** Retains pending requests and a bounded settlement-ordered outcome history. */
|
|
5
|
+
export declare class ApprovalRegistry {
|
|
6
|
+
private readonly changed;
|
|
7
|
+
private pending;
|
|
8
|
+
private settled;
|
|
9
|
+
constructor(changed: (taskId: string) => void);
|
|
10
|
+
register(taskId: string, sessionId: string, request: NativeApprovalRequest, signal: AbortSignal): Promise<ApprovalContent>;
|
|
11
|
+
request(id: string): RequestIdentity;
|
|
12
|
+
respond(id: string, content: unknown): {
|
|
13
|
+
version: 1;
|
|
14
|
+
type: 'approval_answered';
|
|
15
|
+
requestId: string;
|
|
16
|
+
taskId: string;
|
|
17
|
+
sessionId: string;
|
|
18
|
+
};
|
|
19
|
+
pendingFor(taskId: string): ApprovalRequest[];
|
|
20
|
+
retireTask(taskId: string): void;
|
|
21
|
+
close(): void;
|
|
22
|
+
private retire;
|
|
23
|
+
private retain;
|
|
24
|
+
private validateBoundedContent;
|
|
25
|
+
private receipt;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
3
|
+
import { AgentError } from '../errors.js';
|
|
4
|
+
import { validateApprovalContent, validateApprovalSchema } from '../approvals/schema.js';
|
|
5
|
+
const MAX_SETTLED_REQUESTS = 1_024;
|
|
6
|
+
const expired = () => new AgentError('REQUEST_EXPIRED', 'The native permission request is no longer pending.');
|
|
7
|
+
const unknown = () => new AgentError('UNKNOWN_REQUEST', 'Permission request is unavailable in this coordinator.');
|
|
8
|
+
const identity = (request) => ({
|
|
9
|
+
requestId: request.requestId, taskId: request.taskId, sessionId: request.sessionId,
|
|
10
|
+
});
|
|
11
|
+
/** Retains pending requests and a bounded settlement-ordered outcome history. */
|
|
12
|
+
export class ApprovalRegistry {
|
|
13
|
+
changed;
|
|
14
|
+
pending = new Map();
|
|
15
|
+
settled = new Map();
|
|
16
|
+
constructor(changed) {
|
|
17
|
+
this.changed = changed;
|
|
18
|
+
}
|
|
19
|
+
async register(taskId, sessionId, request, signal) {
|
|
20
|
+
if (signal.aborted)
|
|
21
|
+
throw expired();
|
|
22
|
+
if (this.pendingFor(taskId).length >= 32)
|
|
23
|
+
throw new AgentError('INPUT_REQUIRED', 'A task cannot wait on more than 32 permission requests.');
|
|
24
|
+
let copy;
|
|
25
|
+
try {
|
|
26
|
+
const serialized = JSON.stringify(request);
|
|
27
|
+
if (Buffer.byteLength(serialized) > 64 * 1024)
|
|
28
|
+
throw new Error();
|
|
29
|
+
copy = JSON.parse(serialized);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
throw new AgentError('INPUT_REQUIRED', 'The native permission request cannot be represented within 64 KiB.');
|
|
33
|
+
}
|
|
34
|
+
if (copy.kind !== 'permission' || !['codex', 'claudeCode', 'fx', 'opencode', 'copilot', 'cursor'].includes(copy.harness) || typeof copy.message !== 'string')
|
|
35
|
+
throw new AgentError('INPUT_REQUIRED', 'The native permission request cannot be represented.');
|
|
36
|
+
validateApprovalSchema(copy.requestedSchema);
|
|
37
|
+
const requestId = `req_${randomUUID()}`;
|
|
38
|
+
const snapshot = { ...copy, requestId, taskId, sessionId };
|
|
39
|
+
if (Buffer.byteLength(JSON.stringify(snapshot)) > 64 * 1024)
|
|
40
|
+
throw new AgentError('INPUT_REQUIRED', 'The native permission request cannot be represented within 64 KiB.');
|
|
41
|
+
const answer = new Promise((resolve, reject) => {
|
|
42
|
+
const abort = () => this.retire(requestId);
|
|
43
|
+
this.pending.set(requestId, { outcome: 'pending', request: snapshot,
|
|
44
|
+
continuation: { resolve, reject, cleanup: () => signal.removeEventListener('abort', abort) } });
|
|
45
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
46
|
+
});
|
|
47
|
+
this.changed(taskId);
|
|
48
|
+
return answer;
|
|
49
|
+
}
|
|
50
|
+
request(id) {
|
|
51
|
+
const pending = this.pending.get(id);
|
|
52
|
+
if (pending)
|
|
53
|
+
return identity(pending.request);
|
|
54
|
+
const settled = this.settled.get(id);
|
|
55
|
+
if (!settled)
|
|
56
|
+
throw unknown();
|
|
57
|
+
return { ...settled.identity };
|
|
58
|
+
}
|
|
59
|
+
respond(id, content) {
|
|
60
|
+
const pending = this.pending.get(id);
|
|
61
|
+
if (!pending) {
|
|
62
|
+
const settled = this.settled.get(id);
|
|
63
|
+
if (!settled)
|
|
64
|
+
throw unknown();
|
|
65
|
+
if (settled.outcome === 'withdrawn')
|
|
66
|
+
throw expired();
|
|
67
|
+
this.validateBoundedContent(content);
|
|
68
|
+
if (!isDeepStrictEqual(settled.answer, content))
|
|
69
|
+
throw new AgentError('INVALID_APPROVAL_RESPONSE', 'This permission request already has a different answer.');
|
|
70
|
+
return this.receipt(settled.identity);
|
|
71
|
+
}
|
|
72
|
+
this.validateBoundedContent(content);
|
|
73
|
+
const answer = validateApprovalContent(pending.request.requestedSchema, content);
|
|
74
|
+
const requestIdentity = identity(pending.request);
|
|
75
|
+
this.pending.delete(id);
|
|
76
|
+
pending.continuation.cleanup();
|
|
77
|
+
this.retain({ outcome: 'answered', identity: requestIdentity, answer: structuredClone(answer) });
|
|
78
|
+
pending.continuation.resolve(answer);
|
|
79
|
+
this.changed(requestIdentity.taskId);
|
|
80
|
+
return this.receipt(requestIdentity);
|
|
81
|
+
}
|
|
82
|
+
pendingFor(taskId) {
|
|
83
|
+
return [...this.pending.values()].filter(entry => entry.request.taskId === taskId)
|
|
84
|
+
.map(entry => structuredClone(entry.request));
|
|
85
|
+
}
|
|
86
|
+
retireTask(taskId) {
|
|
87
|
+
for (const [id, entry] of this.pending)
|
|
88
|
+
if (entry.request.taskId === taskId)
|
|
89
|
+
this.retire(id);
|
|
90
|
+
}
|
|
91
|
+
close() { for (const id of [...this.pending.keys()])
|
|
92
|
+
this.retire(id); }
|
|
93
|
+
retire(id) {
|
|
94
|
+
const entry = this.pending.get(id);
|
|
95
|
+
if (!entry)
|
|
96
|
+
return;
|
|
97
|
+
const requestIdentity = identity(entry.request);
|
|
98
|
+
this.pending.delete(id);
|
|
99
|
+
entry.continuation.cleanup();
|
|
100
|
+
this.retain({ outcome: 'withdrawn', identity: requestIdentity });
|
|
101
|
+
entry.continuation.reject(expired());
|
|
102
|
+
this.changed(requestIdentity.taskId);
|
|
103
|
+
}
|
|
104
|
+
retain(entry) {
|
|
105
|
+
this.settled.set(entry.identity.requestId, entry);
|
|
106
|
+
while (this.settled.size > MAX_SETTLED_REQUESTS) {
|
|
107
|
+
const oldest = this.settled.keys().next().value;
|
|
108
|
+
if (oldest !== undefined)
|
|
109
|
+
this.settled.delete(oldest);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
validateBoundedContent(content) {
|
|
113
|
+
let serialized;
|
|
114
|
+
try {
|
|
115
|
+
serialized = JSON.stringify(content);
|
|
116
|
+
}
|
|
117
|
+
catch { /* Report no submitted data. */ }
|
|
118
|
+
if (!serialized || Buffer.byteLength(serialized) > 16 * 1024)
|
|
119
|
+
throw new AgentError('INVALID_APPROVAL_RESPONSE', 'Approval content must be a JSON object within 16 KiB.');
|
|
120
|
+
}
|
|
121
|
+
receipt(request) {
|
|
122
|
+
return { version: 1, type: 'approval_answered', requestId: request.requestId,
|
|
123
|
+
taskId: request.taskId, sessionId: request.sessionId };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=approval-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-registry.js","sourceRoot":"","sources":["../../src/runtime/approval-registry.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { isDeepStrictEqual } from 'node:util';\nimport { AgentError } from '../errors.js';\nimport { validateApprovalContent, validateApprovalSchema } from '../approvals/schema.js';\nimport type { ApprovalContent, NativeApprovalRequest } from '../approvals/types.js';\nimport type { ApprovalRequest } from './types.js';\n\ntype RequestIdentity = Pick<ApprovalRequest,'requestId'|'taskId'|'sessionId'>;\ninterface Continuation {\n resolve(content: ApprovalContent): void;\n reject(error: AgentError): void;\n cleanup(): void;\n}\ninterface PendingEntry {\n outcome: 'pending';\n request: ApprovalRequest;\n continuation: Continuation;\n}\ninterface AnsweredEntry { outcome: 'answered'; identity: RequestIdentity; answer: ApprovalContent }\ninterface WithdrawnEntry { outcome: 'withdrawn'; identity: RequestIdentity }\ntype SettledEntry = AnsweredEntry | WithdrawnEntry;\n\nconst MAX_SETTLED_REQUESTS = 1_024;\nconst expired = () => new AgentError('REQUEST_EXPIRED','The native permission request is no longer pending.');\nconst unknown = () => new AgentError('UNKNOWN_REQUEST','Permission request is unavailable in this coordinator.');\nconst identity = (request: ApprovalRequest): RequestIdentity => ({\n requestId:request.requestId,taskId:request.taskId,sessionId:request.sessionId,\n});\n\n/** Retains pending requests and a bounded settlement-ordered outcome history. */\nexport class ApprovalRegistry {\n private pending = new Map<string,PendingEntry>();\n private settled = new Map<string,SettledEntry>();\n constructor(private readonly changed: (taskId: string) => void) {}\n\n async register(taskId: string, sessionId: string, request: NativeApprovalRequest, signal: AbortSignal): Promise<ApprovalContent> {\n if (signal.aborted) throw expired();\n if (this.pendingFor(taskId).length >= 32)\n throw new AgentError('INPUT_REQUIRED','A task cannot wait on more than 32 permission requests.');\n let copy: NativeApprovalRequest;\n try {\n const serialized = JSON.stringify(request);\n if (Buffer.byteLength(serialized) > 64 * 1024) throw new Error();\n copy = JSON.parse(serialized) as NativeApprovalRequest;\n } catch { throw new AgentError('INPUT_REQUIRED','The native permission request cannot be represented within 64 KiB.'); }\n if (copy.kind !== 'permission' || !['codex','claudeCode','fx','opencode','copilot','cursor'].includes(copy.harness) || typeof copy.message !== 'string')\n throw new AgentError('INPUT_REQUIRED','The native permission request cannot be represented.');\n validateApprovalSchema(copy.requestedSchema);\n const requestId = `req_${randomUUID()}`;\n const snapshot: ApprovalRequest = {...copy,requestId,taskId,sessionId};\n if (Buffer.byteLength(JSON.stringify(snapshot)) > 64 * 1024)\n throw new AgentError('INPUT_REQUIRED','The native permission request cannot be represented within 64 KiB.');\n const answer = new Promise<ApprovalContent>((resolve,reject) => {\n const abort = () => this.retire(requestId);\n this.pending.set(requestId,{outcome:'pending',request:snapshot,\n continuation:{resolve,reject,cleanup:() => signal.removeEventListener('abort',abort)}});\n signal.addEventListener('abort',abort,{once:true});\n });\n this.changed(taskId);\n return answer;\n }\n\n request(id: string): RequestIdentity {\n const pending = this.pending.get(id);\n if (pending) return identity(pending.request);\n const settled = this.settled.get(id);\n if (!settled) throw unknown();\n return {...settled.identity};\n }\n\n respond(id: string, content: unknown) {\n const pending = this.pending.get(id);\n if (!pending) {\n const settled = this.settled.get(id);\n if (!settled) throw unknown();\n if (settled.outcome === 'withdrawn') throw expired();\n this.validateBoundedContent(content);\n if (!isDeepStrictEqual(settled.answer,content))\n throw new AgentError('INVALID_APPROVAL_RESPONSE','This permission request already has a different answer.');\n return this.receipt(settled.identity);\n }\n this.validateBoundedContent(content);\n const answer = validateApprovalContent(pending.request.requestedSchema,content);\n const requestIdentity = identity(pending.request);\n this.pending.delete(id);\n pending.continuation.cleanup();\n this.retain({outcome:'answered',identity:requestIdentity,answer:structuredClone(answer)});\n pending.continuation.resolve(answer);\n this.changed(requestIdentity.taskId);\n return this.receipt(requestIdentity);\n }\n\n pendingFor(taskId: string): ApprovalRequest[] {\n return [...this.pending.values()].filter(entry => entry.request.taskId === taskId)\n .map(entry => structuredClone(entry.request));\n }\n\n retireTask(taskId: string) {\n for (const [id,entry] of this.pending) if (entry.request.taskId === taskId) this.retire(id);\n }\n\n close() { for (const id of [...this.pending.keys()]) this.retire(id); }\n\n private retire(id: string) {\n const entry = this.pending.get(id);\n if (!entry) return;\n const requestIdentity = identity(entry.request);\n this.pending.delete(id);\n entry.continuation.cleanup();\n this.retain({outcome:'withdrawn',identity:requestIdentity});\n entry.continuation.reject(expired());\n this.changed(requestIdentity.taskId);\n }\n\n private retain(entry: SettledEntry) {\n this.settled.set(entry.identity.requestId,entry);\n while (this.settled.size > MAX_SETTLED_REQUESTS) {\n const oldest = this.settled.keys().next().value;\n if (oldest !== undefined) this.settled.delete(oldest);\n }\n }\n\n private validateBoundedContent(content: unknown) {\n let serialized: string | undefined;\n try { serialized = JSON.stringify(content); } catch { /* Report no submitted data. */ }\n if (!serialized || Buffer.byteLength(serialized) > 16 * 1024)\n throw new AgentError('INVALID_APPROVAL_RESPONSE','Approval content must be a JSON object within 16 KiB.');\n }\n\n private receipt(request: RequestIdentity) {\n return {version:1 as const,type:'approval_answered' as const,requestId:request.requestId,\n taskId:request.taskId,sessionId:request.sessionId};\n }\n}\n"]}
|
package/dist/runtime/client.js
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
3
3
|
import { AgentError } from '../errors.js';
|
|
4
|
+
import { processExitDescription } from '../process-diagnostics.js';
|
|
4
5
|
import { localProgram, privateDirectory, readEndpoint, stateDirectory } from './state.js';
|
|
5
6
|
import { startupOutcome, startupRetirementRequest } from './startup-protocol.js';
|
|
6
7
|
const retirementConfirmationMs = 1_000;
|
|
8
|
+
const coordinatorOperations = new Set([
|
|
9
|
+
'dashboard', 'dashboard-session', 'dashboard-detail', 'parent', 'run', 'send', 'resume', 'wait',
|
|
10
|
+
'status', 'queue', 'cancel', 'respond',
|
|
11
|
+
]);
|
|
12
|
+
function coordinatorOperation(body) {
|
|
13
|
+
if (!body || typeof body !== 'object' || Array.isArray(body))
|
|
14
|
+
return;
|
|
15
|
+
const command = body.command;
|
|
16
|
+
return typeof command === 'string' && coordinatorOperations.has(command) ? command : undefined;
|
|
17
|
+
}
|
|
7
18
|
export async function connect(start, options = {}) {
|
|
8
19
|
const directory = options.directory ?? stateDirectory();
|
|
9
20
|
const available = await readEndpoint(directory);
|
|
@@ -19,9 +30,14 @@ export async function connect(start, options = {}) {
|
|
|
19
30
|
if (Date.now() >= deadline)
|
|
20
31
|
throw new AgentError('STARTUP_FAILED', 'Another command did not finish coordinator startup.');
|
|
21
32
|
const program = options.program ?? localProgram('daemon');
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
33
|
+
try {
|
|
34
|
+
child = spawn(process.execPath, [...program.execArgv, program.file, String(Math.max(1, deadline - Date.now()))], {
|
|
35
|
+
detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'], env: { ...process.env, AGENT_STATE_DIR: directory },
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
throw new AgentError('STARTUP_FAILED', 'The local coordinator could not be spawned.');
|
|
40
|
+
}
|
|
25
41
|
candidate = observeCandidate(child);
|
|
26
42
|
options.afterSpawn?.(child);
|
|
27
43
|
child.unref();
|
|
@@ -44,7 +60,15 @@ export async function connect(start, options = {}) {
|
|
|
44
60
|
const replacement = await readEndpoint(directory);
|
|
45
61
|
if (replacement)
|
|
46
62
|
return replacement;
|
|
47
|
-
if (
|
|
63
|
+
if (!observed && outcome)
|
|
64
|
+
throw new AgentError('STARTUP_FAILED', 'The local coordinator timed out before publishing an endpoint.');
|
|
65
|
+
if (observed?.state === 'spawn-failed')
|
|
66
|
+
throw new AgentError('STARTUP_FAILED', 'The local coordinator could not be spawned.');
|
|
67
|
+
if (observed?.state === 'exited')
|
|
68
|
+
throw new AgentError('STARTUP_FAILED', `The local coordinator exited before startup completed${processExitDescription(observed.code, observed.signal)}.`);
|
|
69
|
+
if (observed?.state === 'retired')
|
|
70
|
+
throw new AgentError('STARTUP_FAILED', 'The local coordinator retired before startup completed.');
|
|
71
|
+
if (outcome?.state === 'retired' || outcome?.state === 'exited' || outcome?.state === 'spawn-failed')
|
|
48
72
|
throw new AgentError('STARTUP_FAILED', 'The local coordinator could not start.');
|
|
49
73
|
throw new AgentError('STARTUP_FAILED', 'The local coordinator timed out, and its retirement could not be confirmed. It was left untouched because it may have published.');
|
|
50
74
|
}
|
|
@@ -73,16 +97,17 @@ function observeCandidate(child) {
|
|
|
73
97
|
if (value)
|
|
74
98
|
finish(value);
|
|
75
99
|
};
|
|
76
|
-
const
|
|
100
|
+
const onError = () => finish({ state: 'spawn-failed' });
|
|
101
|
+
const onExit = (code, signal) => finish({ state: 'exited', code, signal });
|
|
77
102
|
child.on('message', onMessage);
|
|
78
|
-
child.once('error',
|
|
103
|
+
child.once('error', onError);
|
|
79
104
|
child.once('exit', onExit);
|
|
80
105
|
return {
|
|
81
106
|
outcome,
|
|
82
107
|
current: () => current,
|
|
83
108
|
close() {
|
|
84
109
|
child.off('message', onMessage);
|
|
85
|
-
child.off('error',
|
|
110
|
+
child.off('error', onError);
|
|
86
111
|
child.off('exit', onExit);
|
|
87
112
|
},
|
|
88
113
|
};
|
|
@@ -109,6 +134,7 @@ async function within(promise, timeoutMs) {
|
|
|
109
134
|
}
|
|
110
135
|
}
|
|
111
136
|
export async function* request(endpoint, body) {
|
|
137
|
+
const operation = coordinatorOperation(body);
|
|
112
138
|
let response;
|
|
113
139
|
try {
|
|
114
140
|
response = await fetch(endpoint.url, { method: 'POST', headers: { authorization: `Bearer ${endpoint.token}`, 'content-type': 'application/json' }, body: JSON.stringify(body) });
|
|
@@ -116,8 +142,12 @@ export async function* request(endpoint, body) {
|
|
|
116
142
|
catch {
|
|
117
143
|
throw new AgentError('COORDINATOR_UNAVAILABLE', 'Connection to the local coordinator failed. The task was not automatically retried.');
|
|
118
144
|
}
|
|
119
|
-
if (!response.ok
|
|
120
|
-
|
|
145
|
+
if (!response.ok) {
|
|
146
|
+
void response.body?.cancel().catch(() => { });
|
|
147
|
+
throw new AgentError('COORDINATOR_UNAVAILABLE', `The coordinator rejected ${operation ? `the ${operation} operation` : 'the request'} with HTTP status ${response.status}.`);
|
|
148
|
+
}
|
|
149
|
+
if (!response.body)
|
|
150
|
+
throw new AgentError('COORDINATOR_UNAVAILABLE', `The coordinator returned a successful response with no body${operation ? ` for the ${operation} operation` : ''}.`);
|
|
121
151
|
let buffer = '';
|
|
122
152
|
const decoder = new TextDecoder();
|
|
123
153
|
try {
|
|
@@ -127,16 +157,26 @@ export async function* request(endpoint, body) {
|
|
|
127
157
|
while ((newline = buffer.indexOf('\n')) >= 0) {
|
|
128
158
|
const line = buffer.slice(0, newline);
|
|
129
159
|
buffer = buffer.slice(newline + 1);
|
|
130
|
-
if (line)
|
|
131
|
-
|
|
160
|
+
if (line) {
|
|
161
|
+
let record;
|
|
162
|
+
try {
|
|
163
|
+
record = JSON.parse(line);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
throw new AgentError('COORDINATOR_UNAVAILABLE', `The coordinator returned a malformed JSON record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);
|
|
167
|
+
}
|
|
168
|
+
yield record;
|
|
169
|
+
}
|
|
132
170
|
}
|
|
133
171
|
}
|
|
134
172
|
buffer += decoder.decode();
|
|
135
173
|
if (buffer.trim())
|
|
136
|
-
throw new
|
|
174
|
+
throw new AgentError('COORDINATOR_UNAVAILABLE', `The coordinator response ended with an incomplete final record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);
|
|
137
175
|
}
|
|
138
|
-
catch {
|
|
139
|
-
|
|
176
|
+
catch (error) {
|
|
177
|
+
if (error instanceof AgentError)
|
|
178
|
+
throw error;
|
|
179
|
+
throw new AgentError('COORDINATOR_UNAVAILABLE', 'The coordinator response stream was interrupted. The task was not automatically retried.');
|
|
140
180
|
}
|
|
141
181
|
}
|
|
142
182
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/runtime/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, type ChildProcess } from 'node:child_process';\nimport { setTimeout as delay } from 'node:timers/promises';\nimport { AgentError } from '../errors.js';\nimport type { OutputRecord } from '../cli/output.js';\nimport { type Endpoint, localProgram, privateDirectory, readEndpoint, stateDirectory } from './state.js';\nimport { startupOutcome, startupRetirementRequest, type StartupOutcome } from './startup-protocol.js';\n\ninterface ConnectionOptions {\n directory?: string;\n timeoutMs?: number;\n afterSpawn?: (child: ChildProcess) => void;\n beforeRetirement?: (child: ChildProcess) => void | Promise<void>;\n program?: ReturnType<typeof localProgram>;\n}\n\ntype CandidateOutcome = StartupOutcome | {state:'exited'};\nconst retirementConfirmationMs = 1_000;\n\nexport async function connect(start: boolean, options: ConnectionOptions = {}): Promise<Endpoint> {\n const directory = options.directory ?? stateDirectory();\n const available = await readEndpoint(directory);\n if (available) return available;\n if (!start) throw new AgentError('UNKNOWN_SESSION','No coordinator is reachable from this environment. Its sessions may have ended, or native permissions may block access to its local endpoint.');\n await privateDirectory(directory);\n const deadline = Date.now() + (options.timeoutMs ?? 15_000);\n let child: ChildProcess | undefined;\n let candidate: ReturnType<typeof observeCandidate> | undefined;\n try {\n if (Date.now() >= deadline) throw new AgentError('STARTUP_FAILED','Another command did not finish coordinator startup.');\n const program = options.program ?? localProgram('daemon');\n child = spawn(process.execPath,[...program.execArgv,program.file,String(Math.max(1,deadline-Date.now()))],{\n detached:true,stdio:['ignore','ignore','ignore','ipc'],env:{...process.env,AGENT_STATE_DIR:directory},\n });\n candidate = observeCandidate(child);\n options.afterSpawn?.(child);\n child.unref();\n while (Date.now() < deadline && !candidate.current()) {\n await delay(50);\n const endpoint = await readEndpoint(directory);\n if (endpoint) return endpoint;\n }\n const observed = candidate.current();\n if (observed?.state === 'published') return observed.endpoint;\n if (!observed) {\n await options.beforeRetirement?.(child);\n requestRetirement(child);\n }\n const outcome = observed ?? await within(candidate.outcome,retirementConfirmationMs);\n if (outcome?.state === 'published') return outcome.endpoint;\n const replacement = await readEndpoint(directory);\n if (replacement) return replacement;\n if (outcome?.state === 'retired' || outcome?.state === 'exited')\n throw new AgentError('STARTUP_FAILED','The local coordinator could not start.');\n throw new AgentError('STARTUP_FAILED','The local coordinator timed out, and its retirement could not be confirmed. It was left untouched because it may have published.');\n } finally {\n candidate?.close();\n if (child?.connected) {\n try { child.disconnect(); } catch { /* The candidate may have disconnected after retirement. */ }\n }\n }\n}\n\nfunction observeCandidate(child: ChildProcess) {\n let current: CandidateOutcome | undefined;\n let settle!: (outcome: CandidateOutcome) => void;\n const outcome = new Promise<CandidateOutcome>(resolve => { settle = resolve; });\n const finish = (value: CandidateOutcome) => {\n if (current) return;\n current = value;\n settle(value);\n };\n const onMessage = (message: unknown) => {\n const value = startupOutcome(message);\n if (value) finish(value);\n };\n const onExit = () => finish({state:'exited'});\n child.on('message',onMessage);\n child.once('error',onExit);\n child.once('exit',onExit);\n return {\n outcome,\n current:() => current,\n close() {\n child.off('message',onMessage);\n child.off('error',onExit);\n child.off('exit',onExit);\n },\n };\n}\n\nfunction requestRetirement(child: ChildProcess) {\n if (!child.connected) return;\n try { child.send(startupRetirementRequest,()=>{}); }\n catch { /* The bounded outcome wait reports an unconfirmed retirement. */ }\n}\n\nasync function within<T>(promise: Promise<T>, timeoutMs: number): Promise<T | undefined> {\n let timer: number | NodeJS.Timeout | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<undefined>(resolve => { timer = setTimeout(resolve,timeoutMs); }),\n ]);\n } finally { if (timer) clearTimeout(timer); }\n}\n\nexport async function* request(endpoint: Endpoint, body: unknown): AsyncGenerator<OutputRecord> {\n let response: globalThis.Response;\n try {\n response = await fetch(endpoint.url,{method:'POST',headers:{authorization:`Bearer ${endpoint.token}`,'content-type':'application/json'},body:JSON.stringify(body)});\n } catch { throw new AgentError('COORDINATOR_UNAVAILABLE','Connection to the local coordinator failed. The task was not automatically retried.'); }\n if (!response.ok || !response.body) throw new AgentError('COORDINATOR_UNAVAILABLE','The coordinator rejected the request.');\n let buffer = '';\n const decoder = new TextDecoder();\n try {\n for await (const chunk of response.body) {\n buffer += decoder.decode(chunk,{stream:true});\n let newline;\n while ((newline = buffer.indexOf('\\n')) >= 0) {\n const line = buffer.slice(0,newline); buffer = buffer.slice(newline + 1);\n if (line) yield JSON.parse(line) as OutputRecord;\n }\n }\n buffer += decoder.decode();\n if (buffer.trim()) throw new Error('Incomplete response record');\n } catch {\n throw new AgentError('COORDINATOR_UNAVAILABLE','The coordinator response was interrupted or invalid. The task was not automatically retried.');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/runtime/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, type ChildProcess } from 'node:child_process';\nimport { setTimeout as delay } from 'node:timers/promises';\nimport { AgentError } from '../errors.js';\nimport { processExitDescription } from '../process-diagnostics.js';\nimport type { OutputRecord } from '../cli/output.js';\nimport { type Endpoint, localProgram, privateDirectory, readEndpoint, stateDirectory } from './state.js';\nimport { startupOutcome, startupRetirementRequest, type StartupOutcome } from './startup-protocol.js';\n\ninterface ConnectionOptions {\n directory?: string;\n timeoutMs?: number;\n afterSpawn?: (child: ChildProcess) => void;\n beforeRetirement?: (child: ChildProcess) => void | Promise<void>;\n program?: ReturnType<typeof localProgram>;\n}\n\ntype CandidateOutcome = StartupOutcome\n | {state:'spawn-failed'}\n | {state:'exited';code:unknown;signal:unknown};\nconst retirementConfirmationMs = 1_000;\nconst coordinatorOperations = new Set([\n 'dashboard', 'dashboard-session', 'dashboard-detail', 'parent', 'run', 'send', 'resume', 'wait',\n 'status', 'queue', 'cancel', 'respond',\n]);\n\nfunction coordinatorOperation(body: unknown): string | undefined {\n if (!body || typeof body !== 'object' || Array.isArray(body)) return;\n const command = (body as {command?:unknown}).command;\n return typeof command === 'string' && coordinatorOperations.has(command) ? command : undefined;\n}\n\nexport async function connect(start: boolean, options: ConnectionOptions = {}): Promise<Endpoint> {\n const directory = options.directory ?? stateDirectory();\n const available = await readEndpoint(directory);\n if (available) return available;\n if (!start) throw new AgentError('UNKNOWN_SESSION','No coordinator is reachable from this environment. Its sessions may have ended, or native permissions may block access to its local endpoint.');\n await privateDirectory(directory);\n const deadline = Date.now() + (options.timeoutMs ?? 15_000);\n let child: ChildProcess | undefined;\n let candidate: ReturnType<typeof observeCandidate> | undefined;\n try {\n if (Date.now() >= deadline) throw new AgentError('STARTUP_FAILED','Another command did not finish coordinator startup.');\n const program = options.program ?? localProgram('daemon');\n try {\n child = spawn(process.execPath,[...program.execArgv,program.file,String(Math.max(1,deadline-Date.now()))],{\n detached:true,stdio:['ignore','ignore','ignore','ipc'],env:{...process.env,AGENT_STATE_DIR:directory},\n });\n } catch {\n throw new AgentError('STARTUP_FAILED','The local coordinator could not be spawned.');\n }\n candidate = observeCandidate(child);\n options.afterSpawn?.(child);\n child.unref();\n while (Date.now() < deadline && !candidate.current()) {\n await delay(50);\n const endpoint = await readEndpoint(directory);\n if (endpoint) return endpoint;\n }\n const observed = candidate.current();\n if (observed?.state === 'published') return observed.endpoint;\n if (!observed) {\n await options.beforeRetirement?.(child);\n requestRetirement(child);\n }\n const outcome = observed ?? await within(candidate.outcome,retirementConfirmationMs);\n if (outcome?.state === 'published') return outcome.endpoint;\n const replacement = await readEndpoint(directory);\n if (replacement) return replacement;\n if (!observed && outcome)\n throw new AgentError('STARTUP_FAILED','The local coordinator timed out before publishing an endpoint.');\n if (observed?.state === 'spawn-failed')\n throw new AgentError('STARTUP_FAILED','The local coordinator could not be spawned.');\n if (observed?.state === 'exited')\n throw new AgentError('STARTUP_FAILED',\n `The local coordinator exited before startup completed${processExitDescription(observed.code, observed.signal)}.`);\n if (observed?.state === 'retired')\n throw new AgentError('STARTUP_FAILED','The local coordinator retired before startup completed.');\n if (outcome?.state === 'retired' || outcome?.state === 'exited' || outcome?.state === 'spawn-failed')\n throw new AgentError('STARTUP_FAILED','The local coordinator could not start.');\n throw new AgentError('STARTUP_FAILED','The local coordinator timed out, and its retirement could not be confirmed. It was left untouched because it may have published.');\n } finally {\n candidate?.close();\n if (child?.connected) {\n try { child.disconnect(); } catch { /* The candidate may have disconnected after retirement. */ }\n }\n }\n}\n\nfunction observeCandidate(child: ChildProcess) {\n let current: CandidateOutcome | undefined;\n let settle!: (outcome: CandidateOutcome) => void;\n const outcome = new Promise<CandidateOutcome>(resolve => { settle = resolve; });\n const finish = (value: CandidateOutcome) => {\n if (current) return;\n current = value;\n settle(value);\n };\n const onMessage = (message: unknown) => {\n const value = startupOutcome(message);\n if (value) finish(value);\n };\n const onError = () => finish({state:'spawn-failed'});\n const onExit = (code: unknown, signal: unknown) => finish({state:'exited',code,signal});\n child.on('message',onMessage);\n child.once('error',onError);\n child.once('exit',onExit);\n return {\n outcome,\n current:() => current,\n close() {\n child.off('message',onMessage);\n child.off('error',onError);\n child.off('exit',onExit);\n },\n };\n}\n\nfunction requestRetirement(child: ChildProcess) {\n if (!child.connected) return;\n try { child.send(startupRetirementRequest,()=>{}); }\n catch { /* The bounded outcome wait reports an unconfirmed retirement. */ }\n}\n\nasync function within<T>(promise: Promise<T>, timeoutMs: number): Promise<T | undefined> {\n let timer: number | NodeJS.Timeout | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<undefined>(resolve => { timer = setTimeout(resolve,timeoutMs); }),\n ]);\n } finally { if (timer) clearTimeout(timer); }\n}\n\nexport async function* request(endpoint: Endpoint, body: unknown): AsyncGenerator<OutputRecord> {\n const operation = coordinatorOperation(body);\n let response: globalThis.Response;\n try {\n response = await fetch(endpoint.url,{method:'POST',headers:{authorization:`Bearer ${endpoint.token}`,'content-type':'application/json'},body:JSON.stringify(body)});\n } catch { throw new AgentError('COORDINATOR_UNAVAILABLE','Connection to the local coordinator failed. The task was not automatically retried.'); }\n if (!response.ok) {\n void response.body?.cancel().catch(() => {});\n throw new AgentError('COORDINATOR_UNAVAILABLE',\n `The coordinator rejected ${operation ? `the ${operation} operation` : 'the request'} with HTTP status ${response.status}.`);\n }\n if (!response.body) throw new AgentError('COORDINATOR_UNAVAILABLE',\n `The coordinator returned a successful response with no body${operation ? ` for the ${operation} operation` : ''}.`);\n let buffer = '';\n const decoder = new TextDecoder();\n try {\n for await (const chunk of response.body) {\n buffer += decoder.decode(chunk,{stream:true});\n let newline;\n while ((newline = buffer.indexOf('\\n')) >= 0) {\n const line = buffer.slice(0,newline); buffer = buffer.slice(newline + 1);\n if (line) {\n let record: OutputRecord;\n try { record = JSON.parse(line) as OutputRecord; }\n catch {\n throw new AgentError('COORDINATOR_UNAVAILABLE',\n `The coordinator returned a malformed JSON record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);\n }\n yield record;\n }\n }\n }\n buffer += decoder.decode();\n if (buffer.trim()) throw new AgentError('COORDINATOR_UNAVAILABLE',\n `The coordinator response ended with an incomplete final record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);\n } catch (error) {\n if (error instanceof AgentError) throw error;\n throw new AgentError('COORDINATOR_UNAVAILABLE','The coordinator response stream was interrupted. The task was not automatically retried.');\n }\n}\n"]}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { type DriverFactory, type Observation, type Receipt, type SessionInput, type Delivery } from './types.js';
|
|
2
|
-
import { type DashboardSnapshot } from './dashboard.js';
|
|
2
|
+
import { type DashboardDetail, type DashboardSession, type DashboardSnapshot } from './dashboard.js';
|
|
3
3
|
export declare class Coordinator {
|
|
4
4
|
private readonly factory;
|
|
5
5
|
private readonly now;
|
|
6
6
|
private sessions;
|
|
7
7
|
private tasks;
|
|
8
8
|
private dashboardHistory?;
|
|
9
|
+
private closed;
|
|
10
|
+
private approvals;
|
|
9
11
|
constructor(factory: DriverFactory, now?: () => number);
|
|
10
12
|
parentContext(token: string): {
|
|
11
13
|
taskId: string;
|
|
@@ -22,6 +24,7 @@ export declare class Coordinator {
|
|
|
22
24
|
taskId: string;
|
|
23
25
|
sessionId: string;
|
|
24
26
|
state: import("./types.js").TaskState;
|
|
27
|
+
requests?: import("./types.js").ApprovalRequest[] | undefined;
|
|
25
28
|
error?: import("../errors.js").ErrorInfo | undefined;
|
|
26
29
|
response?: {
|
|
27
30
|
responseId: string;
|
|
@@ -29,7 +32,18 @@ export declare class Coordinator {
|
|
|
29
32
|
truncated: boolean;
|
|
30
33
|
} | undefined;
|
|
31
34
|
};
|
|
35
|
+
respond(id: string, content: unknown, parentToken?: string): {
|
|
36
|
+
version: 1;
|
|
37
|
+
type: 'approval_answered';
|
|
38
|
+
requestId: string;
|
|
39
|
+
taskId: string;
|
|
40
|
+
sessionId: string;
|
|
41
|
+
};
|
|
32
42
|
dashboard(): Promise<DashboardSnapshot>;
|
|
43
|
+
dashboardDetail(id: string, includePrompt?: boolean, knownResponseId?: string): Promise<DashboardDetail>;
|
|
44
|
+
dashboardSession(id: string): Promise<DashboardSession>;
|
|
45
|
+
private dashboardRow;
|
|
46
|
+
private dashboardRelatedTask;
|
|
33
47
|
private finish;
|
|
34
48
|
queue(id: string): {
|
|
35
49
|
version: number;
|
|
@@ -61,6 +75,8 @@ export declare class Coordinator {
|
|
|
61
75
|
private deliver;
|
|
62
76
|
private continueParent;
|
|
63
77
|
private touch;
|
|
78
|
+
private pendingApprovals;
|
|
79
|
+
private approvalChanged;
|
|
64
80
|
private notify;
|
|
65
81
|
private task;
|
|
66
82
|
private session;
|