subharness 0.0.4 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -9
- package/dist/adapters/claude-process.d.ts +3 -0
- package/dist/adapters/claude-process.js +19 -2
- 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-tools.d.ts +6 -2
- package/dist/adapters/claude-tools.js +14 -12
- package/dist/adapters/claude-tools.js.map +1 -1
- package/dist/adapters/claude-worker-client.d.ts +49 -0
- package/dist/adapters/claude-worker-client.js +359 -0
- package/dist/adapters/claude-worker-client.js.map +1 -0
- package/dist/adapters/claude-worker-process.d.ts +20 -0
- package/dist/adapters/claude-worker-process.js +76 -0
- package/dist/adapters/claude-worker-process.js.map +1 -0
- package/dist/adapters/claude-worker-protocol.d.ts +38 -0
- package/dist/adapters/claude-worker-protocol.js +2 -0
- package/dist/adapters/claude-worker-protocol.js.map +1 -0
- package/dist/adapters/claude-worker.d.ts +1 -0
- package/dist/adapters/claude-worker.js +126 -0
- package/dist/adapters/claude-worker.js.map +1 -0
- package/dist/adapters/claude.d.ts +16 -6
- package/dist/adapters/claude.js +164 -75
- 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/catalog-worker.js.map +1 -1
- package/dist/cli/dashboard-client.js +20 -31
- 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 +55 -43
- 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/errors.d.ts +2 -2
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.js +4 -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 +9 -0
- package/dist/runtime/approval-registry.js +144 -5
- package/dist/runtime/approval-registry.js.map +1 -1
- package/dist/runtime/capture.d.ts +22 -0
- package/dist/runtime/capture.js +320 -0
- package/dist/runtime/capture.js.map +1 -0
- package/dist/runtime/catalog.d.ts +39 -0
- package/dist/runtime/catalog.js +84 -0
- package/dist/runtime/catalog.js.map +1 -0
- package/dist/runtime/client.d.ts +2 -1
- package/dist/runtime/client.js +74 -47
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/coordinator.d.ts +44 -7
- package/dist/runtime/coordinator.js +265 -31
- package/dist/runtime/coordinator.js.map +1 -1
- package/dist/runtime/daemon.js +12 -6
- package/dist/runtime/daemon.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-workspace.js +5 -1
- package/dist/runtime/dashboard-workspace.js.map +1 -1
- 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.d.ts +6 -1
- package/dist/runtime/definition.js +42 -2
- package/dist/runtime/definition.js.map +1 -1
- package/dist/runtime/native-owner.js +7 -1
- package/dist/runtime/native-owner.js.map +1 -1
- package/dist/runtime/pagination.d.ts +9 -0
- package/dist/runtime/pagination.js +36 -0
- package/dist/runtime/pagination.js.map +1 -0
- package/dist/runtime/sdk-observation.d.ts +8 -0
- package/dist/runtime/sdk-observation.js +75 -0
- package/dist/runtime/sdk-observation.js.map +1 -0
- package/dist/runtime/sdk-projection.d.ts +8 -0
- package/dist/runtime/sdk-projection.js +19 -0
- package/dist/runtime/sdk-projection.js.map +1 -0
- package/dist/runtime/sdk-service.d.ts +11 -0
- package/dist/runtime/sdk-service.js +109 -0
- package/dist/runtime/sdk-service.js.map +1 -0
- package/dist/runtime/select-native.d.ts +4 -1
- package/dist/runtime/select-native.js +28 -13
- package/dist/runtime/select-native.js.map +1 -1
- package/dist/runtime/service.d.ts +11 -1
- package/dist/runtime/service.js +178 -3
- package/dist/runtime/service.js.map +1 -1
- package/dist/runtime/session-launcher.js +1 -1
- package/dist/runtime/session-launcher.js.map +1 -1
- package/dist/runtime/snapshots.d.ts +103 -0
- package/dist/runtime/snapshots.js +124 -0
- package/dist/runtime/snapshots.js.map +1 -0
- package/dist/runtime/state.d.ts +26 -0
- package/dist/runtime/state.js +86 -17
- package/dist/runtime/state.js.map +1 -1
- package/dist/runtime/task-data.d.ts +38 -0
- package/dist/runtime/task-data.js +2 -0
- package/dist/runtime/task-data.js.map +1 -0
- package/dist/runtime/transport.d.ts +13 -0
- package/dist/runtime/transport.js +166 -0
- package/dist/runtime/transport.js.map +1 -0
- package/dist/runtime/types.d.ts +28 -9
- package/dist/runtime/types.js.map +1 -1
- package/dist/runtime/worker-client.js +40 -13
- package/dist/runtime/worker-client.js.map +1 -1
- package/dist/runtime/worker-server.js +105 -24
- package/dist/runtime/worker-server.js.map +1 -1
- package/dist/sdk/connected-types.d.ts +42 -0
- package/dist/sdk/connected-types.js +2 -0
- package/dist/sdk/connected-types.js.map +1 -0
- package/dist/sdk/connected.d.ts +3 -0
- package/dist/sdk/connected.js +232 -0
- package/dist/sdk/connected.js.map +1 -0
- 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/execution-definition.d.ts +3 -0
- package/dist/sdk/execution-definition.js +59 -0
- package/dist/sdk/execution-definition.js.map +1 -0
- package/dist/sdk/execution-driver.d.ts +6 -0
- package/dist/sdk/execution-driver.js +86 -0
- package/dist/sdk/execution-driver.js.map +1 -0
- package/dist/sdk/execution-observation.d.ts +3 -0
- package/dist/sdk/execution-observation.js +35 -0
- package/dist/sdk/execution-observation.js.map +1 -0
- package/dist/sdk/execution-options.d.ts +17 -0
- package/dist/sdk/execution-options.js +115 -0
- package/dist/sdk/execution-options.js.map +1 -0
- package/dist/sdk/execution-types.d.ts +72 -0
- package/dist/sdk/execution-types.js +2 -0
- package/dist/sdk/execution-types.js.map +1 -0
- package/dist/sdk/execution.d.ts +3 -0
- package/dist/sdk/execution.js +3 -0
- package/dist/sdk/execution.js.map +1 -0
- package/dist/sdk/hosted-error.d.ts +3 -0
- package/dist/sdk/hosted-error.js +14 -0
- package/dist/sdk/hosted-error.js.map +1 -0
- package/dist/sdk/hosted.d.ts +23 -0
- package/dist/sdk/hosted.js +204 -0
- package/dist/sdk/hosted.js.map +1 -0
- package/dist/sdk/permission-validation.js +10 -1
- package/dist/sdk/permission-validation.js.map +1 -1
- package/dist/sdk/runner.d.ts +5 -0
- package/dist/sdk/runner.js +107 -0
- package/dist/sdk/runner.js.map +1 -0
- package/dist/sdk/tools.js +4 -1
- package/dist/sdk/tools.js.map +1 -1
- package/dist/sdk/types.d.ts +29 -1
- package/dist/sdk/types.js.map +1 -1
- package/package.json +6 -3
- package/sdk/access-config.md +60 -4
- package/sdk/adapter-contract.md +13 -3
- package/sdk/additional-harnesses.md +43 -0
- package/sdk/agent-skill.md +2 -2
- package/sdk/agent.md +6 -4
- package/sdk/approvals.md +5 -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/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 +5 -3
- package/sdk/evals.md +1 -1
- package/sdk/examples/chat-tool.ts +126 -0
- package/sdk/execution.md +743 -0
- package/sdk/fx.md +50 -5
- package/sdk/harnesses.md +13 -13
- package/sdk/index.md +45 -20
- package/sdk/message-delivery.md +2 -0
- package/sdk/opencode.md +57 -0
- package/sdk/permissions.md +6 -2
- package/sdk/plugins/sub-agents.md +4 -2
- package/sdk/project-team.md +25 -1
- package/sdk/sessions.md +2 -0
- package/sdk/tools.md +4 -2
- package/sdk/v1-runtime.md +8 -6
- package/dist/cli/catalog.d.ts +0 -26
- package/dist/cli/catalog.js +0 -41
- package/dist/cli/catalog.js.map +0 -1
package/dist/runtime/state.js
CHANGED
|
@@ -1,30 +1,99 @@
|
|
|
1
1
|
import { homedir } from 'node:os';
|
|
2
|
-
import { join,
|
|
2
|
+
import { isAbsolute, join, normalize } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { createHash } from 'node:crypto';
|
|
5
4
|
import { mkdir, readFile, chmod } from 'node:fs/promises';
|
|
5
|
+
import { AgentError } from '../errors.js';
|
|
6
|
+
export function resolveStateDirectory(explicit, env = process.env) {
|
|
7
|
+
const selected = explicit ?? env.AGENT_STATE_DIR ?? join(homedir(), '.subharness', 'state', 'shared');
|
|
8
|
+
if (!selected || !isAbsolute(selected)) {
|
|
9
|
+
throw new AgentError('INVALID_CONFIG', 'Coordinator state directory must be a nonempty absolute local path.');
|
|
10
|
+
}
|
|
11
|
+
return normalize(selected);
|
|
12
|
+
}
|
|
6
13
|
export function stateDirectory() {
|
|
7
|
-
|
|
8
|
-
return process.env.AGENT_STATE_DIR ?? join(homedir(), '.subharness', 'state', installation);
|
|
14
|
+
return resolveStateDirectory();
|
|
9
15
|
}
|
|
10
16
|
export async function privateDirectory(directory) {
|
|
11
17
|
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
12
18
|
await chmod(directory, 0o700);
|
|
13
19
|
}
|
|
14
|
-
export async function
|
|
20
|
+
export async function probeEndpoint(directory, options = {}) {
|
|
21
|
+
let source;
|
|
22
|
+
try {
|
|
23
|
+
source = await readFile(join(directory, 'coordinator.json'), 'utf8');
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error.code === 'ENOENT')
|
|
27
|
+
return { kind: 'absent' };
|
|
28
|
+
return { kind: 'malformed' };
|
|
29
|
+
}
|
|
30
|
+
let candidate;
|
|
15
31
|
try {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
candidate = JSON.parse(source);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return { kind: 'malformed' };
|
|
36
|
+
}
|
|
37
|
+
if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate))
|
|
38
|
+
return { kind: 'malformed' };
|
|
39
|
+
const endpoint = candidate;
|
|
40
|
+
if (!/^http:\/\/127\.0\.0\.1:\d+\/$/.test(String(endpoint.url))
|
|
41
|
+
|| typeof endpoint.token !== 'string' || !endpoint.token
|
|
42
|
+
|| !Number.isSafeInteger(endpoint.pid) || endpoint.pid <= 0
|
|
43
|
+
|| typeof endpoint.instanceId !== 'string' || !endpoint.instanceId)
|
|
44
|
+
return { kind: 'malformed' };
|
|
45
|
+
const parsed = endpoint;
|
|
46
|
+
let response;
|
|
47
|
+
try {
|
|
48
|
+
const timeout = AbortSignal.timeout(Math.max(1, options.timeoutMs ?? 500));
|
|
49
|
+
response = await fetch(parsed.url + 'health', {
|
|
50
|
+
headers: { authorization: `Bearer ${parsed.token}` },
|
|
51
|
+
signal: options.signal ? AbortSignal.any([options.signal, timeout]) : timeout,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return { kind: 'unresponsive', endpoint: parsed, owner: (options.checkPid ?? processOwnerState)(parsed.pid) };
|
|
56
|
+
}
|
|
57
|
+
if (response.status === 401 || response.status === 403) {
|
|
58
|
+
void response.body?.cancel().catch(() => { });
|
|
59
|
+
return { kind: 'authentication-failed', endpoint: parsed };
|
|
60
|
+
}
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
void response.body?.cancel().catch(() => { });
|
|
63
|
+
return { kind: 'incompatible', endpoint: parsed };
|
|
64
|
+
}
|
|
65
|
+
let health;
|
|
66
|
+
try {
|
|
67
|
+
health = await response.json();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return { kind: 'incompatible', endpoint: parsed };
|
|
71
|
+
}
|
|
72
|
+
if (!health || typeof health !== 'object' || Array.isArray(health))
|
|
73
|
+
return { kind: 'incompatible', endpoint: parsed };
|
|
74
|
+
const record = health;
|
|
75
|
+
if (record.instanceId !== parsed.instanceId)
|
|
76
|
+
return { kind: 'instance-mismatch', endpoint: parsed };
|
|
77
|
+
if (record.version !== 1 || record.type !== 'coordinator-health' || record.protocolVersion !== 1
|
|
78
|
+
|| !Array.isArray(record.capabilities) || !record.capabilities.every(item => typeof item === 'string')
|
|
79
|
+
|| (options.capability && !record.capabilities.includes(options.capability))) {
|
|
80
|
+
return { kind: 'incompatible', endpoint: parsed };
|
|
81
|
+
}
|
|
82
|
+
return { kind: 'reachable', endpoint: parsed };
|
|
83
|
+
}
|
|
84
|
+
export function processOwnerState(pid) {
|
|
85
|
+
try {
|
|
86
|
+
process.kill(pid, 0);
|
|
87
|
+
return 'alive';
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
const code = error.code;
|
|
91
|
+
return code === 'ESRCH' ? 'dead' : 'unknown';
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export async function readEndpoint(directory) {
|
|
95
|
+
const probe = await probeEndpoint(directory, { capability: 'cli-v1' });
|
|
96
|
+
return probe.kind === 'reachable' ? probe.endpoint : undefined;
|
|
28
97
|
}
|
|
29
98
|
export function localProgram(name) {
|
|
30
99
|
const extension = import.meta.url.endsWith('.ts') ? 'ts' : 'js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/runtime/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/runtime/state.ts"],"names":[],"mappings":"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","sourcesContent":["import { homedir } from 'node:os';\nimport { isAbsolute, join, normalize } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { mkdir, readFile, chmod } from 'node:fs/promises';\nimport { AgentError } from '../errors.js';\n\nexport interface Endpoint { url: string; token: string; pid: number; instanceId: string }\nexport type EndpointCapability = 'sdk-v1' | 'cli-v1';\nexport type OwnerState = 'alive' | 'dead' | 'unknown';\nexport type EndpointProbe =\n | { readonly kind: 'absent' }\n | { readonly kind: 'malformed' }\n | { readonly kind: 'reachable'; readonly endpoint: Endpoint }\n | { readonly kind: 'authentication-failed' | 'incompatible' | 'instance-mismatch'; readonly endpoint: Endpoint }\n | { readonly kind: 'unresponsive'; readonly endpoint: Endpoint; readonly owner: OwnerState };\nexport interface EndpointProbeOptions {\n readonly capability?: EndpointCapability;\n readonly timeoutMs?: number;\n readonly signal?: AbortSignal;\n readonly checkPid?: (pid: number) => OwnerState;\n}\nexport function resolveStateDirectory(\n explicit?: string,\n env: Readonly<Record<string, string | undefined>> = process.env,\n): string {\n const selected = explicit ?? env.AGENT_STATE_DIR ?? join(homedir(),'.subharness','state','shared');\n if (!selected || !isAbsolute(selected)) {\n throw new AgentError('INVALID_CONFIG','Coordinator state directory must be a nonempty absolute local path.');\n }\n return normalize(selected);\n}\nexport function stateDirectory() {\n return resolveStateDirectory();\n}\nexport async function privateDirectory(directory: string) {\n await mkdir(directory,{recursive:true,mode:0o700});\n await chmod(directory,0o700);\n}\nexport async function probeEndpoint(directory: string, options: EndpointProbeOptions = {}): Promise<EndpointProbe> {\n let source: string;\n try { source = await readFile(join(directory,'coordinator.json'),'utf8'); }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return {kind:'absent'};\n return {kind:'malformed'};\n }\n let candidate: unknown;\n try { candidate = JSON.parse(source); }\n catch { return {kind:'malformed'}; }\n if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) return {kind:'malformed'};\n const endpoint = candidate as Partial<Endpoint>;\n if (!/^http:\\/\\/127\\.0\\.0\\.1:\\d+\\/$/.test(String(endpoint.url))\n || typeof endpoint.token !== 'string' || !endpoint.token\n || !Number.isSafeInteger(endpoint.pid) || endpoint.pid! <= 0\n || typeof endpoint.instanceId !== 'string' || !endpoint.instanceId) return {kind:'malformed'};\n const parsed = endpoint as Endpoint;\n let response: Response;\n try {\n const timeout = AbortSignal.timeout(Math.max(1,options.timeoutMs ?? 500));\n response = await fetch(parsed.url + 'health', {\n headers:{authorization:`Bearer ${parsed.token}`},\n signal:options.signal ? AbortSignal.any([options.signal,timeout]) : timeout,\n });\n } catch {\n return {kind:'unresponsive',endpoint:parsed,owner:(options.checkPid ?? processOwnerState)(parsed.pid)};\n }\n if (response.status === 401 || response.status === 403) {\n void response.body?.cancel().catch(()=>{});\n return {kind:'authentication-failed',endpoint:parsed};\n }\n if (!response.ok) {\n void response.body?.cancel().catch(()=>{});\n return {kind:'incompatible',endpoint:parsed};\n }\n let health: unknown;\n try { health = await response.json(); }\n catch { return {kind:'incompatible',endpoint:parsed}; }\n if (!health || typeof health !== 'object' || Array.isArray(health)) return {kind:'incompatible',endpoint:parsed};\n const record = health as Record<string,unknown>;\n if (record.instanceId !== parsed.instanceId) return {kind:'instance-mismatch',endpoint:parsed};\n if (record.version !== 1 || record.type !== 'coordinator-health' || record.protocolVersion !== 1\n || !Array.isArray(record.capabilities) || !record.capabilities.every(item => typeof item === 'string')\n || (options.capability && !record.capabilities.includes(options.capability))) {\n return {kind:'incompatible',endpoint:parsed};\n }\n return {kind:'reachable',endpoint:parsed};\n}\n\nexport function processOwnerState(pid: number): OwnerState {\n try { process.kill(pid,0); return 'alive'; }\n catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n return code === 'ESRCH' ? 'dead' : 'unknown';\n }\n}\nexport async function readEndpoint(directory: string): Promise<Endpoint | undefined> {\n const probe = await probeEndpoint(directory,{capability:'cli-v1'});\n return probe.kind === 'reachable' ? probe.endpoint : undefined;\n}\nexport function localProgram(name: string) {\n const extension = import.meta.url.endsWith('.ts') ? 'ts' : 'js';\n return { file:fileURLToPath(new URL(`./${name}.${extension}`, import.meta.url)),\n execArgv:extension === 'ts' ? ['--import',import.meta.resolve('tsx')] : [] };\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { NativeApprovalRequest } from '../approvals/types.js';
|
|
2
|
+
export type TaskState = 'queued' | 'running' | 'waiting' | 'awaiting_approval' | 'completed' | 'failed' | 'cancelled' | 'interrupted';
|
|
3
|
+
export interface ApprovalRequest extends NativeApprovalRequest {
|
|
4
|
+
requestId: string;
|
|
5
|
+
taskId: string;
|
|
6
|
+
sessionId: string;
|
|
7
|
+
}
|
|
8
|
+
export type ApprovalScope = 'once' | 'turn' | 'session';
|
|
9
|
+
export type ApprovalAction = {
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly label: string;
|
|
12
|
+
readonly description?: string;
|
|
13
|
+
} & ({
|
|
14
|
+
readonly decision: 'allow' | 'deny';
|
|
15
|
+
readonly scope: ApprovalScope;
|
|
16
|
+
} | {
|
|
17
|
+
readonly decision: 'cancel';
|
|
18
|
+
readonly scope?: never;
|
|
19
|
+
});
|
|
20
|
+
export interface ApprovalGrant {
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly label: string;
|
|
23
|
+
readonly description?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface SdkApprovalRequest {
|
|
26
|
+
readonly id: string;
|
|
27
|
+
readonly taskId: string;
|
|
28
|
+
readonly sessionId: string;
|
|
29
|
+
readonly harness: import('../sdk/types.js').HarnessKind;
|
|
30
|
+
readonly message: string;
|
|
31
|
+
readonly actions: readonly ApprovalAction[];
|
|
32
|
+
readonly grants?: readonly ApprovalGrant[];
|
|
33
|
+
readonly context?: Readonly<Record<string, unknown>>;
|
|
34
|
+
}
|
|
35
|
+
export interface ApprovalResponse {
|
|
36
|
+
readonly actionId: string;
|
|
37
|
+
readonly grants?: readonly string[];
|
|
38
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-data.js","sourceRoot":"","sources":["../../src/runtime/task-data.ts"],"names":[],"mappings":"","sourcesContent":["import type { NativeApprovalRequest } from '../approvals/types.js';\n\nexport type TaskState = 'queued' | 'running' | 'waiting' | 'awaiting_approval' |\n 'completed' | 'failed' | 'cancelled' | 'interrupted';\n\nexport interface ApprovalRequest extends NativeApprovalRequest {\n requestId: string;\n taskId: string;\n sessionId: string;\n}\n\nexport type ApprovalScope = 'once' | 'turn' | 'session';\nexport type ApprovalAction = {\n readonly id: string;\n readonly label: string;\n readonly description?: string;\n} & (\n | { readonly decision: 'allow' | 'deny'; readonly scope: ApprovalScope }\n | { readonly decision: 'cancel'; readonly scope?: never }\n);\nexport interface ApprovalGrant { readonly id: string; readonly label: string; readonly description?: string }\nexport interface SdkApprovalRequest {\n readonly id: string;\n readonly taskId: string;\n readonly sessionId: string;\n readonly harness: import('../sdk/types.js').HarnessKind;\n readonly message: string;\n readonly actions: readonly ApprovalAction[];\n readonly grants?: readonly ApprovalGrant[];\n readonly context?: Readonly<Record<string, unknown>>;\n}\nexport interface ApprovalResponse { readonly actionId: string; readonly grants?: readonly string[] }\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Endpoint } from './state.js';
|
|
2
|
+
export declare class CoordinatorTransport {
|
|
3
|
+
readonly endpoint: Endpoint;
|
|
4
|
+
private readonly closed;
|
|
5
|
+
constructor(endpoint: Endpoint);
|
|
6
|
+
disconnect(): void;
|
|
7
|
+
one<T>(body: unknown, signal?: AbortSignal): Promise<T>;
|
|
8
|
+
stream<T>(body: unknown, signal?: AbortSignal): AsyncIterable<T>;
|
|
9
|
+
records(body: unknown, signal?: AbortSignal, options?: {
|
|
10
|
+
allowFinalRecord?: boolean;
|
|
11
|
+
}): AsyncGenerator<unknown>;
|
|
12
|
+
private assertOpen;
|
|
13
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { AgentError } from '../errors.js';
|
|
2
|
+
export class CoordinatorTransport {
|
|
3
|
+
endpoint;
|
|
4
|
+
closed = new AbortController();
|
|
5
|
+
constructor(endpoint) {
|
|
6
|
+
this.endpoint = endpoint;
|
|
7
|
+
}
|
|
8
|
+
disconnect() { this.closed.abort(); }
|
|
9
|
+
async one(body, signal) {
|
|
10
|
+
let value;
|
|
11
|
+
let count = 0;
|
|
12
|
+
for await (const record of this.records(body, signal)) {
|
|
13
|
+
throwRemote(record);
|
|
14
|
+
value = record;
|
|
15
|
+
count++;
|
|
16
|
+
if (count > 1)
|
|
17
|
+
throw unavailable('The coordinator returned too many records for one operation.');
|
|
18
|
+
}
|
|
19
|
+
if (count !== 1)
|
|
20
|
+
throw unavailable('The coordinator returned no record for the operation.');
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
stream(body, signal) {
|
|
24
|
+
const transport = this;
|
|
25
|
+
return { [Symbol.asyncIterator]() {
|
|
26
|
+
const lifetime = new AbortController();
|
|
27
|
+
const observerSignal = signal ? AbortSignal.any([signal, lifetime.signal]) : lifetime.signal;
|
|
28
|
+
const source = transport.records(body, observerSignal)[Symbol.asyncIterator]();
|
|
29
|
+
return {
|
|
30
|
+
async next() {
|
|
31
|
+
const result = await source.next();
|
|
32
|
+
if (result.done)
|
|
33
|
+
return { done: true, value: undefined };
|
|
34
|
+
throwRemote(result.value);
|
|
35
|
+
return { done: false, value: result.value };
|
|
36
|
+
},
|
|
37
|
+
async return() {
|
|
38
|
+
lifetime.abort();
|
|
39
|
+
try {
|
|
40
|
+
await source.return?.(undefined);
|
|
41
|
+
}
|
|
42
|
+
catch { }
|
|
43
|
+
return { done: true, value: undefined };
|
|
44
|
+
},
|
|
45
|
+
async throw(error) {
|
|
46
|
+
lifetime.abort();
|
|
47
|
+
if (source.throw)
|
|
48
|
+
return source.throw(error);
|
|
49
|
+
throw error;
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
} };
|
|
53
|
+
}
|
|
54
|
+
async *records(body, signal, options = {}) {
|
|
55
|
+
this.assertOpen();
|
|
56
|
+
const operation = operationName(body);
|
|
57
|
+
const combined = signal
|
|
58
|
+
? AbortSignal.any([this.closed.signal, signal])
|
|
59
|
+
: this.closed.signal;
|
|
60
|
+
let response;
|
|
61
|
+
try {
|
|
62
|
+
response = await fetch(this.endpoint.url, {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
headers: { authorization: `Bearer ${this.endpoint.token}`, 'content-type': 'application/json',
|
|
65
|
+
'x-subharness-instance': this.endpoint.instanceId },
|
|
66
|
+
body: JSON.stringify(body),
|
|
67
|
+
signal: combined,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
if (signal?.aborted)
|
|
72
|
+
throw new AgentError('OBSERVATION_CLOSED', 'The observer disconnected.');
|
|
73
|
+
throw unavailable('Connection to the local coordinator failed. The task was not automatically retried.');
|
|
74
|
+
}
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
void response.body?.cancel().catch(() => { });
|
|
77
|
+
if (response.status === 401)
|
|
78
|
+
throw new AgentError('COORDINATOR_AUTH_FAILED', 'The local coordinator rejected its private authentication token.');
|
|
79
|
+
throw unavailable(`The coordinator rejected ${operation ? `the ${operation} operation` : 'the request'} with HTTP status ${response.status}.`);
|
|
80
|
+
}
|
|
81
|
+
if (!response.body)
|
|
82
|
+
throw unavailable(`The coordinator returned a successful response with no body${operation ? ` for the ${operation} operation` : ''}.`);
|
|
83
|
+
let buffer = '';
|
|
84
|
+
const decoder = new TextDecoder();
|
|
85
|
+
const reader = response.body.getReader();
|
|
86
|
+
let complete = false;
|
|
87
|
+
try {
|
|
88
|
+
for (;;) {
|
|
89
|
+
const result = await reader.read();
|
|
90
|
+
if (result.done) {
|
|
91
|
+
complete = true;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
const chunk = result.value;
|
|
95
|
+
buffer += decoder.decode(chunk, { stream: true });
|
|
96
|
+
let newline;
|
|
97
|
+
while ((newline = buffer.indexOf('\n')) >= 0) {
|
|
98
|
+
const line = buffer.slice(0, newline);
|
|
99
|
+
buffer = buffer.slice(newline + 1);
|
|
100
|
+
if (!line)
|
|
101
|
+
continue;
|
|
102
|
+
try {
|
|
103
|
+
yield JSON.parse(line);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
throw unavailable(`The coordinator returned a malformed JSON record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
buffer += decoder.decode();
|
|
111
|
+
if (buffer.trim()) {
|
|
112
|
+
if (options.allowFinalRecord) {
|
|
113
|
+
try {
|
|
114
|
+
yield JSON.parse(buffer);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
throw unavailable(`The coordinator returned a malformed JSON record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else
|
|
121
|
+
throw unavailable(`The coordinator response ended with an incomplete final record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
if (error instanceof AgentError)
|
|
126
|
+
throw error;
|
|
127
|
+
if (signal?.aborted)
|
|
128
|
+
throw new AgentError('OBSERVATION_CLOSED', 'The observer disconnected.');
|
|
129
|
+
throw unavailable('The coordinator response stream was interrupted. The task was not automatically retried.');
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
if (!complete)
|
|
133
|
+
await reader.cancel().catch(() => { });
|
|
134
|
+
reader.releaseLock();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
assertOpen() {
|
|
138
|
+
if (this.closed.signal.aborted)
|
|
139
|
+
throw unavailable('The coordinator client is disconnected.');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function throwRemote(value) {
|
|
143
|
+
if (!value || typeof value !== 'object' || value.type !== 'error')
|
|
144
|
+
return;
|
|
145
|
+
const record = value;
|
|
146
|
+
if (!record.error || typeof record.error.code !== 'string' || typeof record.error.message !== 'string')
|
|
147
|
+
throw unavailable('The coordinator returned a malformed error record.');
|
|
148
|
+
throw new AgentError(record.error.code, record.error.message);
|
|
149
|
+
}
|
|
150
|
+
function operationName(body) {
|
|
151
|
+
if (!body || typeof body !== 'object' || Array.isArray(body))
|
|
152
|
+
return;
|
|
153
|
+
const command = body.command;
|
|
154
|
+
return typeof command === 'string' && operations.has(command) ? command : undefined;
|
|
155
|
+
}
|
|
156
|
+
const operations = new Set([
|
|
157
|
+
'dashboard', 'dashboard-session', 'dashboard-detail', 'parent', 'run', 'send', 'resume', 'wait', 'status', 'queue', 'cancel', 'respond',
|
|
158
|
+
'sdk-agent-list', 'sdk-agent-check',
|
|
159
|
+
'sdk-session-create', 'sdk-session-get', 'sdk-session-list', 'sdk-session-prompt', 'sdk-session-close',
|
|
160
|
+
'sdk-task-get', 'sdk-task-list', 'sdk-task-snapshot', 'sdk-task-inspect', 'sdk-task-result', 'sdk-task-watch',
|
|
161
|
+
'sdk-task-responses', 'sdk-task-cancel', 'sdk-approval-respond',
|
|
162
|
+
]);
|
|
163
|
+
function unavailable(message) {
|
|
164
|
+
return new AgentError('COORDINATOR_UNAVAILABLE', message);
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/runtime/transport.ts"],"names":[],"mappings":"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","sourcesContent":["import { AgentError } from '../errors.js';\nimport type { Endpoint } from './state.js';\n\ninterface ErrorRecord {\n readonly version: 1;\n readonly type: 'error';\n readonly error: {readonly code:string;readonly message:string};\n}\n\nexport class CoordinatorTransport {\n private readonly closed = new AbortController();\n constructor(readonly endpoint:Endpoint) {}\n\n disconnect(): void { this.closed.abort(); }\n\n async one<T>(body:unknown,signal?:AbortSignal):Promise<T> {\n let value:T|undefined;\n let count=0;\n for await (const record of this.records(body,signal)) {\n throwRemote(record);\n value=record as T;\n count++;\n if (count > 1) throw unavailable('The coordinator returned too many records for one operation.');\n }\n if (count !== 1) throw unavailable('The coordinator returned no record for the operation.');\n return value!;\n }\n\n stream<T>(body:unknown,signal?:AbortSignal):AsyncIterable<T> {\n const transport=this;\n return {[Symbol.asyncIterator]():AsyncIterator<T> {\n const lifetime=new AbortController();\n const observerSignal=signal ? AbortSignal.any([signal,lifetime.signal]) : lifetime.signal;\n const source=transport.records(body,observerSignal)[Symbol.asyncIterator]();\n return {\n async next() {\n const result=await source.next();\n if(result.done)return {done:true,value:undefined};\n throwRemote(result.value);\n return {done:false,value:result.value as T};\n },\n async return() {\n lifetime.abort();\n try{await source.return?.(undefined);}catch{}\n return {done:true,value:undefined};\n },\n async throw(error?:unknown) {\n lifetime.abort();\n if(source.throw)return source.throw(error) as Promise<IteratorResult<T>>;\n throw error;\n },\n };\n }};\n }\n\n async *records(body:unknown,signal?:AbortSignal,options:{allowFinalRecord?:boolean}={}):AsyncGenerator<unknown> {\n this.assertOpen();\n const operation=operationName(body);\n const combined=signal\n ? AbortSignal.any([this.closed.signal,signal])\n : this.closed.signal;\n let response:Response;\n try {\n response=await fetch(this.endpoint.url,{\n method:'POST',\n headers:{authorization:`Bearer ${this.endpoint.token}`,'content-type':'application/json',\n 'x-subharness-instance':this.endpoint.instanceId},\n body:JSON.stringify(body),\n signal:combined,\n });\n } catch {\n if (signal?.aborted) throw new AgentError('OBSERVATION_CLOSED','The observer disconnected.');\n throw unavailable('Connection to the local coordinator failed. The task was not automatically retried.');\n }\n if (!response.ok) {\n void response.body?.cancel().catch(()=>{});\n if (response.status === 401)\n throw new AgentError('COORDINATOR_AUTH_FAILED','The local coordinator rejected its private authentication token.');\n throw unavailable(`The coordinator rejected ${operation ? `the ${operation} operation` : 'the request'} with HTTP status ${response.status}.`);\n }\n if (!response.body) throw 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 const reader=response.body.getReader();\n let complete=false;\n try {\n for (;;) {\n const result=await reader.read();\n if (result.done) { complete=true; break; }\n const chunk=result.value;\n buffer+=decoder.decode(chunk,{stream:true});\n let newline:number;\n while ((newline=buffer.indexOf('\\n')) >= 0) {\n const line=buffer.slice(0,newline); buffer=buffer.slice(newline+1);\n if (!line) continue;\n try { yield JSON.parse(line) as unknown; }\n catch { throw unavailable(`The coordinator returned a malformed JSON record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`); }\n }\n }\n buffer+=decoder.decode();\n if (buffer.trim()) {\n if (options.allowFinalRecord) {\n try { yield JSON.parse(buffer) as unknown; }\n catch { throw unavailable(`The coordinator returned a malformed JSON record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`); }\n } else throw unavailable(\n `The coordinator response ended with an incomplete final record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);\n }\n } catch (error) {\n if (error instanceof AgentError) throw error;\n if (signal?.aborted) throw new AgentError('OBSERVATION_CLOSED','The observer disconnected.');\n throw unavailable('The coordinator response stream was interrupted. The task was not automatically retried.');\n } finally {\n if (!complete) await reader.cancel().catch(()=>{});\n reader.releaseLock();\n }\n }\n\n private assertOpen():void {\n if (this.closed.signal.aborted) throw unavailable('The coordinator client is disconnected.');\n }\n}\n\nfunction throwRemote(value:unknown):void {\n if (!value || typeof value !== 'object' || (value as {type?:unknown}).type !== 'error') return;\n const record=value as Partial<ErrorRecord>;\n if (!record.error || typeof record.error.code !== 'string' || typeof record.error.message !== 'string')\n throw unavailable('The coordinator returned a malformed error record.');\n throw new AgentError(record.error.code,record.error.message);\n}\n\nfunction operationName(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' && operations.has(command) ? command : undefined;\n}\n\nconst operations=new Set([\n 'dashboard','dashboard-session','dashboard-detail','parent','run','send','resume','wait','status','queue','cancel','respond',\n 'sdk-agent-list','sdk-agent-check',\n 'sdk-session-create','sdk-session-get','sdk-session-list','sdk-session-prompt','sdk-session-close',\n 'sdk-task-get','sdk-task-list','sdk-task-snapshot','sdk-task-inspect','sdk-task-result','sdk-task-watch',\n 'sdk-task-responses','sdk-task-cancel','sdk-approval-respond',\n]);\n\nfunction unavailable(message:string):AgentError {\n return new AgentError('COORDINATOR_UNAVAILABLE',message);\n}\n"]}
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -2,8 +2,10 @@ import type { ErrorInfo } from '../errors.js';
|
|
|
2
2
|
import type { HarnessRequest, NativeSession } from '../adapters/types.js';
|
|
3
3
|
import type { HarnessKind } from '../sdk/types.js';
|
|
4
4
|
import type { DashboardHarness, DashboardWorkspace } from './dashboard.js';
|
|
5
|
-
import type { ApprovalHandler
|
|
6
|
-
|
|
5
|
+
import type { ApprovalHandler } from '../approvals/types.js';
|
|
6
|
+
import type { AgentDefinition } from '../sdk/types.js';
|
|
7
|
+
import type { ApprovalRequest, TaskState } from './task-data.js';
|
|
8
|
+
export type { ApprovalRequest, TaskState } from './task-data.js';
|
|
7
9
|
export type Delivery = 'queue' | 'steer' | 'interrupt';
|
|
8
10
|
export interface AgentReference {
|
|
9
11
|
file: string;
|
|
@@ -13,7 +15,11 @@ export interface HarnessReference {
|
|
|
13
15
|
kind: 'harness';
|
|
14
16
|
harness: HarnessRequest;
|
|
15
17
|
}
|
|
16
|
-
export
|
|
18
|
+
export interface InlineReference {
|
|
19
|
+
kind: 'inline';
|
|
20
|
+
definition: AgentDefinition;
|
|
21
|
+
}
|
|
22
|
+
export type ExecutionReference = AgentReference | HarnessReference | InlineReference;
|
|
17
23
|
export interface SessionInput {
|
|
18
24
|
reference: ExecutionReference;
|
|
19
25
|
cwd: string;
|
|
@@ -21,6 +27,7 @@ export interface SessionInput {
|
|
|
21
27
|
prompt: string;
|
|
22
28
|
parentToken?: string;
|
|
23
29
|
}
|
|
30
|
+
export type SessionCreateInput = Omit<SessionInput, 'prompt' | 'parentToken'>;
|
|
24
31
|
export interface DriverInput extends Omit<SessionInput, 'prompt' | 'parentToken'> {
|
|
25
32
|
token: string;
|
|
26
33
|
sessionId: string;
|
|
@@ -30,6 +37,10 @@ export type ManagedNativeSession = NativeSession & {
|
|
|
30
37
|
selectedHarness?: HarnessKind;
|
|
31
38
|
};
|
|
32
39
|
export type DriverFactory = (input: DriverInput) => Promise<ManagedNativeSession>;
|
|
40
|
+
export interface PreparedExecution {
|
|
41
|
+
open(input: DriverInput): Promise<ManagedNativeSession>;
|
|
42
|
+
close(): Promise<void>;
|
|
43
|
+
}
|
|
33
44
|
export interface RecordBase {
|
|
34
45
|
version: 1;
|
|
35
46
|
type: string;
|
|
@@ -37,17 +48,13 @@ export interface RecordBase {
|
|
|
37
48
|
taskId: string;
|
|
38
49
|
state?: TaskState;
|
|
39
50
|
}
|
|
40
|
-
export interface ApprovalRequest extends NativeApprovalRequest {
|
|
41
|
-
requestId: string;
|
|
42
|
-
taskId: string;
|
|
43
|
-
sessionId: string;
|
|
44
|
-
}
|
|
45
51
|
export interface Observation extends RecordBase {
|
|
46
52
|
state: TaskState;
|
|
47
53
|
responseId?: string;
|
|
48
54
|
text?: string;
|
|
49
55
|
error?: ErrorInfo;
|
|
50
56
|
requests?: ApprovalRequest[];
|
|
57
|
+
stopUnconfirmed?: boolean;
|
|
51
58
|
}
|
|
52
59
|
export interface Receipt extends RecordBase {
|
|
53
60
|
delivery?: Delivery;
|
|
@@ -85,19 +92,31 @@ export interface Task {
|
|
|
85
92
|
failedAt?: number;
|
|
86
93
|
finishedAt?: number;
|
|
87
94
|
updatedAt: number;
|
|
95
|
+
revision: number;
|
|
96
|
+
ordinal: number;
|
|
97
|
+
membership: number;
|
|
88
98
|
changed: Set<() => void>;
|
|
99
|
+
watchers: Set<() => void>;
|
|
89
100
|
}
|
|
90
101
|
export interface Session {
|
|
91
102
|
id: string;
|
|
92
103
|
token: string;
|
|
93
|
-
input:
|
|
104
|
+
input: SessionCreateInput;
|
|
94
105
|
driver?: Promise<ManagedNativeSession>;
|
|
106
|
+
prepared?: PreparedExecution;
|
|
107
|
+
preparedClosed?: boolean;
|
|
95
108
|
tasks: string[];
|
|
96
109
|
active?: string;
|
|
97
110
|
paused: boolean;
|
|
98
111
|
commands: Promise<unknown>;
|
|
99
112
|
controls: number;
|
|
113
|
+
nextOrdinal: number;
|
|
114
|
+
membership: number;
|
|
100
115
|
harness: DashboardHarness;
|
|
116
|
+
selectedHarness?: HarnessKind;
|
|
101
117
|
workspace: Promise<DashboardWorkspace>;
|
|
118
|
+
state: 'open' | 'closing' | 'closed';
|
|
119
|
+
closePromise?: Promise<void>;
|
|
120
|
+
driverClosed?: boolean;
|
|
102
121
|
}
|
|
103
122
|
export declare const terminal: (state: TaskState) => boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"AAmDA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAgB,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC","sourcesContent":["import type { ErrorInfo } from '../errors.js';\nimport type { HarnessRequest, NativeSession } from '../adapters/types.js';\nimport type { HarnessKind } from '../sdk/types.js';\nimport type { DashboardHarness, DashboardWorkspace } from './dashboard.js';\nimport type { ApprovalHandler } from '../approvals/types.js';\nimport type { AgentDefinition } from '../sdk/types.js';\nimport type { ApprovalRequest, TaskState } from './task-data.js';\n\nexport type { ApprovalRequest, TaskState } from './task-data.js';\n\nexport type Delivery = 'queue' | 'steer' | 'interrupt';\nexport interface AgentReference { file: string; subagents: string[] }\nexport interface HarnessReference { kind: 'harness'; harness: HarnessRequest }\nexport interface InlineReference { kind: 'inline'; definition: AgentDefinition }\nexport type ExecutionReference = AgentReference | HarnessReference | InlineReference;\nexport interface SessionInput { reference: ExecutionReference; cwd: string; env: NodeJS.ProcessEnv; prompt: string; parentToken?: string }\nexport type SessionCreateInput = Omit<SessionInput, 'prompt' | 'parentToken'>;\nexport interface DriverInput extends Omit<SessionInput, 'prompt' | 'parentToken'> { token: string; sessionId: string; onApproval?: ApprovalHandler }\nexport type ManagedNativeSession = NativeSession & { selectedHarness?: HarnessKind };\nexport type DriverFactory = (input: DriverInput) => Promise<ManagedNativeSession>;\nexport interface PreparedExecution {\n open(input: DriverInput): Promise<ManagedNativeSession>;\n close(): Promise<void>;\n}\nexport interface RecordBase { version: 1; type: string; sessionId: string; taskId: string; state?: TaskState }\nexport interface Observation extends RecordBase {\n state: TaskState; responseId?: string; text?: string; error?: ErrorInfo; requests?: ApprovalRequest[];\n stopUnconfirmed?: boolean;\n}\nexport interface Receipt extends RecordBase {\n delivery?: Delivery; requestedDelivery?: Delivery; resumed?: boolean;\n paused?: true; blockedByTaskId?: string;\n}\nexport interface Response extends Observation { type: 'response'; responseId: string; text: string }\nexport interface ChildResult { taskId: string; state: TaskState; text: string }\nexport interface Task {\n id: string; sessionId: string; prompt: string; title: string; parentId?: string; state: TaskState;\n responses: Response[]; children: Set<string>; inbox: ChildResult[]; nativeActive: boolean;\n stopping: boolean; stopPromise?: Promise<void>; stopUnconfirmed?: boolean; error?: ErrorInfo;\n dispatchedAt?: number; failedAt?: number; finishedAt?: number; updatedAt: number; revision: number;\n ordinal: number; membership: number;\n changed: Set<() => void>; watchers: Set<() => void>;\n}\nexport interface Session {\n id: string; token: string; input: SessionCreateInput; driver?: Promise<ManagedNativeSession>;\n prepared?: PreparedExecution; preparedClosed?: boolean;\n tasks: string[]; active?: string; paused: boolean; commands: Promise<unknown>; controls: number;\n nextOrdinal: number; membership: number;\n harness: DashboardHarness; selectedHarness?: HarnessKind; workspace: Promise<DashboardWorkspace>;\n state: 'open' | 'closing' | 'closed'; closePromise?: Promise<void>; driverClosed?: boolean;\n}\nexport const terminal = (state: TaskState) => ['completed', 'failed', 'cancelled', 'interrupted'].includes(state);\n"]}
|