@claudexor/harness-acp 3.20.1

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/dist/probes.js ADDED
@@ -0,0 +1,185 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { mkdtempSync, rmSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { resolveHarnessBinary, runCapture, HarnessUnavailableError, } from "@claudexor/core";
6
+ import { ConformanceReport, HarnessModel, HarnessRunSpec, } from "@claudexor/schema";
7
+ import { AcpFailure } from "./events.js";
8
+ import { acpToken, prepareAcpEnv } from "./env.js";
9
+ import { acpManifest } from "./manifest.js";
10
+ import { ACP_DISCLOSURE } from "./run.js";
11
+ const INTENTS = [
12
+ "plan",
13
+ "spec",
14
+ "implement",
15
+ "repair",
16
+ "create_from_scratch",
17
+ "review",
18
+ "verify",
19
+ "synthesize",
20
+ "explain",
21
+ "audit",
22
+ ];
23
+ export function acpProbes(entry, profile, runner) {
24
+ let version;
25
+ const binary = () => {
26
+ const bin = process.env[entry.binaryEnv] ?? entry.binary;
27
+ if (!resolveHarnessBinary(bin))
28
+ throw new HarnessUnavailableError(`${entry.displayName} binary is not installed`);
29
+ return bin;
30
+ };
31
+ const probe = async (spec, paid = false) => {
32
+ binary();
33
+ acpToken(entry, spec.credentialProfile ?? null);
34
+ const temporary = paid ? mkdtempSync(join(tmpdir(), "acp-conformance-")) : null;
35
+ const abort = new AbortController();
36
+ const onAbort = () => abort.abort();
37
+ spec.abortSignal?.addEventListener("abort", onAbort, { once: true });
38
+ if (spec.abortSignal?.aborted)
39
+ abort.abort();
40
+ const timer = setTimeout(onAbort, 45_000);
41
+ const observation = { writePermission: false, promptDispatched: false };
42
+ try {
43
+ let problem;
44
+ for await (const event of runner.run(HarnessRunSpec.parse({
45
+ session_id: randomUUID(),
46
+ intent: "implement",
47
+ cwd: temporary ?? spec.cwd,
48
+ access: paid ? "workspace_write" : "readonly",
49
+ env: spec.env,
50
+ auth_preference: spec.authPreference ?? "api_key",
51
+ credential_profile: spec.credentialProfile ?? null,
52
+ prompt: paid
53
+ ? "Create claudexor-acp-conformance.txt in the current directory containing only ok. Then say done."
54
+ : "",
55
+ extra: { abortSignal: abort.signal },
56
+ }), { probe: !paid, observation })) {
57
+ if (event.type === "error")
58
+ problem = new AcpFailure(String(event.payload?.["code"] ?? "acp_error"), event.error ?? event.text ?? "ACP probe failed");
59
+ if (event.type === "completed" && event.payload?.["aborted"])
60
+ problem ??= new AcpFailure("probe_cancelled", "ACP probe cancelled");
61
+ }
62
+ if (problem)
63
+ throw problem;
64
+ version = observation.version ?? version;
65
+ return observation;
66
+ }
67
+ finally {
68
+ clearTimeout(timer);
69
+ spec.abortSignal?.removeEventListener("abort", onAbort);
70
+ if (temporary)
71
+ rmSync(temporary, { recursive: true, force: true });
72
+ }
73
+ };
74
+ return {
75
+ async discover() {
76
+ const bin = binary();
77
+ if (!version) {
78
+ const prepared = prepareAcpEnv(entry, "");
79
+ try {
80
+ const result = await runCapture(bin, ["--version"], {
81
+ env: prepared.env,
82
+ inheritEnv: "clean",
83
+ timeoutMs: 10_000,
84
+ });
85
+ if (result.code !== 0)
86
+ throw new HarnessUnavailableError(`${entry.displayName} --version failed`);
87
+ version = result.stdout.trim() || "unknown";
88
+ }
89
+ finally {
90
+ prepared.dispose();
91
+ }
92
+ }
93
+ return acpManifest(entry, version, profile);
94
+ },
95
+ async doctor(spec) {
96
+ // Check ids follow the shared readiness table: `installed` is the binary
97
+ // check remote install reads, `api_key` the managed token. A passed check
98
+ // stays in the report when a later step fails.
99
+ const passed = [];
100
+ let step = "acp_session";
101
+ try {
102
+ if (spec.authSource && spec.authSource !== "api_key_env")
103
+ throw new HarnessUnavailableError("ACP supports only api_key_env authentication");
104
+ step = "installed";
105
+ binary();
106
+ passed.push({ id: "installed", status: "pass" });
107
+ step = "api_key";
108
+ acpToken(entry);
109
+ passed.push({ id: "api_key", status: "pass" });
110
+ step = "acp_session";
111
+ if (spec.conformance)
112
+ profile.access_control.write_mechanism = "none";
113
+ const observation = await probe(spec, spec.conformance === true);
114
+ if (spec.conformance && observation.writePermission)
115
+ profile.access_control.write_mechanism = "tool_policy";
116
+ return ConformanceReport.parse({
117
+ harness_id: entry.id,
118
+ status: "degraded",
119
+ enabled_intents: INTENTS,
120
+ reasons: [ACP_DISCLOSURE],
121
+ checks: [
122
+ ...passed,
123
+ {
124
+ id: "acp_session",
125
+ status: "pass",
126
+ detail: "initialize and session/new accepted; default probe sends no prompt",
127
+ },
128
+ {
129
+ id: "write_conformance",
130
+ status: spec.conformance ? (observation.writePermission ? "pass" : "fail") : "skip",
131
+ detail: `write_mechanism=${profile.access_control.write_mechanism}; ${observation.writePermission ? "typed write permission callback observed; shell is not sandboxed" : "write permission callback unproven or absent (#4537); writes are unfenced"}`,
132
+ },
133
+ ],
134
+ auth_sources: [
135
+ {
136
+ source: "api_key_env",
137
+ availability: "available",
138
+ verification: spec.conformance ? "passed" : "not_run",
139
+ detail: spec.conformance
140
+ ? "explicit prompt completed"
141
+ : "session creation accepted; paid capability smoke not run",
142
+ },
143
+ ],
144
+ });
145
+ }
146
+ catch (error) {
147
+ const code = error instanceof AcpFailure ? error.code : step;
148
+ const message = error instanceof Error ? error.message : String(error);
149
+ const detail = error instanceof Error ? `${code}: ${message}` : message;
150
+ return ConformanceReport.parse({
151
+ harness_id: entry.id,
152
+ status: "unavailable",
153
+ disabled_intents: INTENTS,
154
+ reasons: [detail],
155
+ checks: [...passed, { id: code, status: "fail", detail: message }],
156
+ auth_sources: [
157
+ { source: "api_key_env", availability: "unavailable", verification: "not_run", detail },
158
+ ],
159
+ });
160
+ }
161
+ },
162
+ async models(spec) {
163
+ const hints = () => entry.modelHints.map((id) => HarnessModel.parse({ id, origin: "hint" }));
164
+ if (!spec)
165
+ return hints();
166
+ try {
167
+ const observation = await probe(spec);
168
+ const models = [];
169
+ for (const config of observation.session?.configOptions ?? []) {
170
+ if (config.category !== "model" || config.type !== "select")
171
+ continue;
172
+ for (const option of config.options) {
173
+ for (const item of "options" in option ? option.options : [option])
174
+ models.push(HarnessModel.parse({ id: item.value, label: item.name, origin: "live" }));
175
+ }
176
+ }
177
+ return models.length ? models : hints();
178
+ }
179
+ catch {
180
+ return hints();
181
+ }
182
+ },
183
+ };
184
+ }
185
+ //# sourceMappingURL=probes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probes.js","sourceRoot":"","sources":["../src/probes.ts"],"names":[],"mappings":"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"}
package/dist/run.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import type { HarnessEvent, HarnessRunSpec } from "@claudexor/schema";
2
+ import type { AcpEntry } from "./entry.js";
3
+ import { type AcpObservation } from "./transport.js";
4
+ export declare const ACP_DISCLOSURE = "ACP preview: readonly uses a CLI tool allowlist; workspace writes and shell commands are not sandboxed. Permission callbacks may be absent (github/copilot-cli#4537); write containment is unproven. Network is uncontrolled; cost may be unknown; live input and MCP injection are unavailable.";
5
+ export interface AcpRunOptions {
6
+ probe?: boolean;
7
+ observation?: AcpObservation;
8
+ }
9
+ export declare function acpRunner(entry: AcpEntry): {
10
+ cancel(sessionId: string): Promise<void>;
11
+ run(spec: HarnessRunSpec, options?: AcpRunOptions): AsyncGenerator<HarnessEvent>;
12
+ };
13
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEjE,eAAO,MAAM,cAAc,qSACyQ,CAAC;AAErS,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ;IAG/B,MAAM,YAAY,MAAM;IAGvB,GAAG,OAAO,cAAc,YAAW,aAAa,GAAQ,cAAc,CAAC,YAAY,CAAC;EA+K9F"}
package/dist/run.js ADDED
@@ -0,0 +1,189 @@
1
+ import * as acp from "@agentclientprotocol/sdk";
2
+ import { abortSignalFromSpec, HarnessUnavailableError, promptWithInstructions, } from "@claudexor/core";
3
+ import { CLAUDEXOR_VERSION, redactSecrets } from "@claudexor/util";
4
+ import { Channel } from "./channel.js";
5
+ import { acpToken, prepareAcpEnv } from "./env.js";
6
+ import { AcpEvents, AcpFailure } from "./events.js";
7
+ import { acpArgs } from "./policy.js";
8
+ import { connectAcp } from "./transport.js";
9
+ export const ACP_DISCLOSURE = "ACP preview: readonly uses a CLI tool allowlist; workspace writes and shell commands are not sandboxed. Permission callbacks may be absent (github/copilot-cli#4537); write containment is unproven. Network is uncontrolled; cost may be unknown; live input and MCP injection are unavailable.";
10
+ export function acpRunner(entry) {
11
+ const active = new Map();
12
+ return {
13
+ async cancel(sessionId) {
14
+ await active.get(sessionId)?.();
15
+ },
16
+ async *run(spec, options = {}) {
17
+ const events = new AcpEvents(spec.session_id, entry.disabledToolsNotice);
18
+ const queue = new Channel();
19
+ const abort = new AbortController();
20
+ const observation = options.observation ?? {
21
+ writePermission: false,
22
+ promptDispatched: false,
23
+ };
24
+ let transport;
25
+ let prepared;
26
+ let cancelled = false;
27
+ let failure;
28
+ let timer;
29
+ const emit = (event) => queue.push(event, abort.signal);
30
+ const external = abortSignalFromSpec(spec);
31
+ const cancel = async () => {
32
+ cancelled = true;
33
+ if (transport)
34
+ await transport.cancel();
35
+ else
36
+ abort.abort();
37
+ };
38
+ const onAbort = () => {
39
+ void cancel().catch((error) => {
40
+ failure = error;
41
+ });
42
+ };
43
+ if (active.has(spec.session_id))
44
+ throw new HarnessUnavailableError("ACP session is already active");
45
+ // Typed pre-spawn refusals throw like the check above, so the engine keeps
46
+ // their failure class instead of a generic acp_error event.
47
+ const args = acpArgs(entry, spec);
48
+ const token = acpToken(entry, spec.credential_profile);
49
+ active.set(spec.session_id, cancel);
50
+ external?.addEventListener("abort", onAbort, { once: true });
51
+ const work = (async () => {
52
+ try {
53
+ if (external?.aborted) {
54
+ cancelled = true;
55
+ return;
56
+ }
57
+ if (spec.resume_session_id)
58
+ throw new AcpFailure("resume_unsupported", "ACP session/load is not supported in stage 1");
59
+ if (spec.auth_preference === "subscription")
60
+ throw new AcpFailure("auth_profile_incompatible", "ACP requires a managed API token");
61
+ if (spec.external_context_policy === "off" || spec.tool_permission_policy.web === "off")
62
+ throw new AcpFailure("web_policy_incompatible", "ACP cannot enforce web policy off");
63
+ if (spec.extra_mcp_servers.length)
64
+ throw new AcpFailure("mcp_unsupported", "ACP MCP injection is not supported in stage 1");
65
+ prepared = prepareAcpEnv(entry, token, spec.env);
66
+ await emit(events.event("started", {
67
+ credential_route: "managed_api_key",
68
+ credential_source: "api_key_env",
69
+ ...(spec.credential_profile
70
+ ? { credential_profile_id: spec.credential_profile.profile_id }
71
+ : {}),
72
+ }));
73
+ await emit(events.event("status", { text: ACP_DISCLOSURE }));
74
+ transport = connectAcp({
75
+ binary: process.env[entry.binaryEnv] ?? entry.binary,
76
+ args,
77
+ env: prepared.env,
78
+ spec,
79
+ abort,
80
+ events,
81
+ observation,
82
+ emit,
83
+ });
84
+ timer = setTimeout(() => {
85
+ failure = new AcpFailure("startup_timeout", "ACP initialize/session/new timed out");
86
+ void transport?.close().catch((error) => {
87
+ failure = error;
88
+ });
89
+ }, 15_000);
90
+ const agent = transport.connection.agent;
91
+ const initialized = await agent.request(acp.methods.agent.initialize, {
92
+ protocolVersion: acp.PROTOCOL_VERSION,
93
+ clientCapabilities: {},
94
+ clientInfo: { name: "claudexor", version: CLAUDEXOR_VERSION },
95
+ });
96
+ if (initialized.protocolVersion !== acp.PROTOCOL_VERSION)
97
+ throw new AcpFailure("protocol_version", "ACP v1 negotiation failed");
98
+ observation.version = initialized.agentInfo?.version;
99
+ observation.session = await agent.request(acp.methods.agent.session.new, {
100
+ cwd: spec.cwd,
101
+ mcpServers: [],
102
+ });
103
+ clearTimeout(timer);
104
+ timer = undefined;
105
+ if (options.probe)
106
+ return;
107
+ observation.promptDispatched = true;
108
+ const result = await agent.request(acp.methods.agent.session.prompt, {
109
+ sessionId: observation.session.sessionId,
110
+ prompt: [{ type: "text", text: promptWithInstructions(spec) }],
111
+ });
112
+ cancelled ||= result.stopReason === "cancelled";
113
+ for (const event of events.finish(result.stopReason))
114
+ await emit(event);
115
+ }
116
+ catch (error) {
117
+ failure ??= error;
118
+ }
119
+ finally {
120
+ if (timer)
121
+ clearTimeout(timer);
122
+ try {
123
+ await transport?.close();
124
+ }
125
+ catch (error) {
126
+ failure = error;
127
+ }
128
+ try {
129
+ prepared?.dispose();
130
+ }
131
+ catch (error) {
132
+ failure ??= error;
133
+ }
134
+ external?.removeEventListener("abort", onAbort);
135
+ active.delete(spec.session_id);
136
+ if (!queue.closed) {
137
+ if (failure &&
138
+ (!cancelled ||
139
+ (failure instanceof AcpFailure && failure.code === "termination_unconfirmed"))) {
140
+ const auth = failure instanceof acp.RequestError && failure.code === -32000;
141
+ const code = auth
142
+ ? "not_logged_in"
143
+ : failure instanceof AcpFailure
144
+ ? failure.code
145
+ : "acp_error";
146
+ const message = auth
147
+ ? "ACP agent requires authentication (not logged in)"
148
+ : failure instanceof Error
149
+ ? failure.message
150
+ : String(failure);
151
+ await queue.push(events.event("error", {
152
+ text: message,
153
+ error: message,
154
+ payload: {
155
+ code,
156
+ retryable: false,
157
+ prompt_delivery: observation.promptDispatched
158
+ ? "possibly_delivered"
159
+ : "not_sent",
160
+ },
161
+ }));
162
+ }
163
+ await queue.push(events.event("completed", { payload: { aborted: cancelled } }));
164
+ queue.close();
165
+ }
166
+ }
167
+ })();
168
+ try {
169
+ for await (const event of queue.read()) {
170
+ // Redact before storage, including unknown wire fields and error diagnostics.
171
+ const json = JSON.stringify(event, (_key, value) => typeof value === "string"
172
+ ? redactSecrets(token ? value.split(token).join("[REDACTED]") : value)
173
+ : value);
174
+ yield JSON.parse(json);
175
+ }
176
+ }
177
+ finally {
178
+ queue.close();
179
+ try {
180
+ await cancel();
181
+ }
182
+ finally {
183
+ await work;
184
+ }
185
+ }
186
+ },
187
+ };
188
+ }
189
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import * as acp from "@agentclientprotocol/sdk";
2
+ import type { HarnessEvent, HarnessRunSpec } from "@claudexor/schema";
3
+ import { AcpEvents } from "./events.js";
4
+ export interface AcpObservation {
5
+ session?: acp.NewSessionResponse;
6
+ version?: string;
7
+ writePermission: boolean;
8
+ promptDispatched: boolean;
9
+ }
10
+ /** SDK owns RPC correlation/validation; our byte-bounded stream owns transcript order. */
11
+ export declare function connectAcp(input: {
12
+ binary: string;
13
+ args: string[];
14
+ env: Record<string, string | null>;
15
+ spec: HarnessRunSpec;
16
+ abort: AbortController;
17
+ events: AcpEvents;
18
+ observation: AcpObservation;
19
+ emit: (event: HarnessEvent) => Promise<void>;
20
+ }): {
21
+ connection: acp.ClientConnection;
22
+ cancel(): Promise<void>;
23
+ close(): Promise<void>;
24
+ };
25
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAsB,MAAM,aAAa,CAAC;AAG5D,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,GAAG,CAAC,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,eAAe,CAAC;IACvB,MAAM,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,cAAc,CAAC;IAC5B,IAAI,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;;;aAqIY,OAAO,CAAC,IAAI,CAAC;EAazB"}
@@ -0,0 +1,154 @@
1
+ import * as acp from "@agentclientprotocol/sdk";
2
+ import { spawnProcess } from "@claudexor/core";
3
+ import { AcpFailure, record } from "./events.js";
4
+ import { decidePermission, denyPermission } from "./policy.js";
5
+ /** SDK owns RPC correlation/validation; our byte-bounded stream owns transcript order. */
6
+ export function connectAcp(input) {
7
+ const { spec, abort, events, observation, emit } = input;
8
+ let stdin;
9
+ let receive;
10
+ const spawned = new Promise((resolve) => {
11
+ receive = resolve;
12
+ });
13
+ let termination;
14
+ let closing = false;
15
+ let replyId;
16
+ let replyReady;
17
+ let replied;
18
+ const process = spawnProcess(input.binary, input.args, {
19
+ cwd: spec.cwd,
20
+ env: input.env,
21
+ inheritEnv: "clean",
22
+ keepStdinOpen: true,
23
+ abortSignal: abort.signal,
24
+ streamLimits: { stdoutFrameBytes: 8 * 1024 * 1024, queuedFrames: 16, stderrBytes: 64 * 1024 },
25
+ onSpawn: (io) => {
26
+ stdin = io;
27
+ receive(io);
28
+ },
29
+ onTerminationUnconfirmed: () => {
30
+ termination = "ACP process tree death could not be confirmed";
31
+ },
32
+ });
33
+ const wire = (direction, line) => emit(events.event("status", { payload: { acp_frame: { direction, line } } }));
34
+ const stream = {
35
+ writable: new WritableStream({
36
+ async write(message) {
37
+ const line = `${JSON.stringify(message)}\n`;
38
+ if (Buffer.byteLength(line) > 8 * 1024 * 1024)
39
+ throw new AcpFailure("frame_too_large", "ACP outgoing frame exceeds 8 MiB");
40
+ const io = await spawned;
41
+ if (closing)
42
+ throw new Error("ACP transport closed");
43
+ // Delivery can be ambiguous after this write. No reconnection/replay exists.
44
+ io.write(line);
45
+ // Cancellation must reach the pipe even when the transcript is backpressured.
46
+ if (!abort.signal.aborted)
47
+ await wire("client", line);
48
+ if ("id" in message && !("method" in message) && message.id === replyId)
49
+ replied?.();
50
+ },
51
+ }),
52
+ readable: new ReadableStream({
53
+ async pull(controller) {
54
+ try {
55
+ // SDK handlers are concurrent. Wait for each inbound request's
56
+ // response before reading another, so its writer queue stays bounded.
57
+ await replyReady;
58
+ if (closing)
59
+ return;
60
+ for (;;) {
61
+ const next = await process.next();
62
+ if (closing)
63
+ return;
64
+ if (next.done) {
65
+ controller.close();
66
+ return;
67
+ }
68
+ const event = next.value;
69
+ if (event.type === "termination_unconfirmed") {
70
+ termination = "ACP process tree death could not be confirmed";
71
+ }
72
+ else if (event.type === "stderr") {
73
+ await emit(events.event("status", { payload: { stderr: event.line } }));
74
+ }
75
+ else if (event.type === "stdout") {
76
+ await wire("agent", event.wire ?? `${event.line}\n`);
77
+ const message = JSON.parse(event.line);
78
+ const envelope = record(message);
79
+ if (envelope["jsonrpc"] !== "2.0")
80
+ throw new AcpFailure("invalid_frame", "ACP frame is not JSON-RPC 2.0");
81
+ if (typeof envelope["method"] === "string" && !("id" in envelope)) {
82
+ if (envelope["method"] === acp.methods.client.session.update) {
83
+ const params = record(envelope["params"]);
84
+ if (!observation.session ||
85
+ params["sessionId"] !== observation.session.sessionId)
86
+ throw new AcpFailure("wrong_session", "ACP update is outside the active session");
87
+ for (const translated of events.update(params["update"]))
88
+ await emit(translated);
89
+ }
90
+ // Preserve unknown updates/notifications without SDK filtering or console logging.
91
+ continue;
92
+ }
93
+ if (typeof envelope["method"] === "string") {
94
+ replyId = envelope["id"];
95
+ replyReady = new Promise((resolve) => {
96
+ replied = resolve;
97
+ });
98
+ }
99
+ controller.enqueue(message);
100
+ return;
101
+ }
102
+ }
103
+ }
104
+ catch (error) {
105
+ if (!closing)
106
+ controller.error(error);
107
+ }
108
+ },
109
+ cancel() {
110
+ /* The lifetime owner closes and reaps the process below. */
111
+ },
112
+ }, { highWaterMark: 0 }),
113
+ };
114
+ const connection = acp
115
+ .client()
116
+ .onRequest(acp.methods.client.session.requestPermission, ({ params }) => {
117
+ if (abort.signal.aborted || params.sessionId !== observation.session?.sessionId)
118
+ return denyPermission();
119
+ if (params.toolCall.kind === "edit" || params.toolCall.kind === "execute")
120
+ observation.writePermission = true;
121
+ return decidePermission(spec.access, spec.cwd, params);
122
+ })
123
+ .connect(stream);
124
+ let cleanup;
125
+ return {
126
+ connection,
127
+ async cancel() {
128
+ // Queue the protocol notification before abort; don't wait on a blocked stream writer.
129
+ if (observation.session && !closing) {
130
+ const frame = {
131
+ jsonrpc: "2.0",
132
+ method: acp.methods.agent.session.cancel,
133
+ params: { sessionId: observation.session.sessionId },
134
+ };
135
+ stdin?.write(`${JSON.stringify(frame)}\n`);
136
+ }
137
+ await this.close();
138
+ },
139
+ close() {
140
+ cleanup ??= (async () => {
141
+ closing = true;
142
+ replied?.();
143
+ abort.abort();
144
+ connection.close();
145
+ stdin?.end();
146
+ await process.return(undefined);
147
+ if (termination)
148
+ throw new AcpFailure("termination_unconfirmed", termination);
149
+ })();
150
+ return cleanup;
151
+ },
152
+ };
153
+ }
154
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,YAAY,EAAmB,MAAM,iBAAiB,CAAC;AAEhE,OAAO,EAAa,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAS/D,0FAA0F;AAC1F,MAAM,UAAU,UAAU,CAAC,KAS1B;IACC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACzD,IAAI,KAAkB,CAAC;IACvB,IAAI,OAAkC,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,EAAE;QAClD,OAAO,GAAG,OAAO,CAAC;IACpB,CAAC,CAAC,CAAC;IACH,IAAI,WAA+B,CAAC;IACpC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,OAAkC,CAAC;IACvC,IAAI,UAAqC,CAAC;IAC1C,IAAI,OAAiC,CAAC;IACtC,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE;QACrD,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,UAAU,EAAE,OAAO;QACnB,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,KAAK,CAAC,MAAM;QACzB,YAAY,EAAE,EAAE,gBAAgB,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,GAAG,IAAI,EAAE;QAC7F,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;YACd,KAAK,GAAG,EAAE,CAAC;YACX,OAAO,CAAC,EAAE,CAAC,CAAC;QACd,CAAC;QACD,wBAAwB,EAAE,GAAG,EAAE;YAC7B,WAAW,GAAG,+CAA+C,CAAC;QAChE,CAAC;KACF,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,SAA6B,EAAE,IAAY,EAAE,EAAE,CAC3D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAChF,MAAM,MAAM,GAAe;QACzB,QAAQ,EAAE,IAAI,cAAc,CAAiB;YAC3C,KAAK,CAAC,KAAK,CAAC,OAAO;gBACjB,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;gBAC5C,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI;oBAC3C,MAAM,IAAI,UAAU,CAAC,iBAAiB,EAAE,kCAAkC,CAAC,CAAC;gBAC9E,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC;gBACzB,IAAI,OAAO;oBAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;gBACrD,6EAA6E;gBAC7E,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACf,8EAA8E;gBAC9E,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO;oBAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBACtD,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC,EAAE,KAAK,OAAO;oBAAE,OAAO,EAAE,EAAE,CAAC;YACvF,CAAC;SACF,CAAC;QACF,QAAQ,EAAE,IAAI,cAAc,CAC1B;YACE,KAAK,CAAC,IAAI,CAAC,UAAU;gBACnB,IAAI,CAAC;oBACH,+DAA+D;oBAC/D,sEAAsE;oBACtE,MAAM,UAAU,CAAC;oBACjB,IAAI,OAAO;wBAAE,OAAO;oBACpB,SAAS,CAAC;wBACR,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;wBAClC,IAAI,OAAO;4BAAE,OAAO;wBACpB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;4BACd,UAAU,CAAC,KAAK,EAAE,CAAC;4BACnB,OAAO;wBACT,CAAC;wBACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;wBACzB,IAAI,KAAK,CAAC,IAAI,KAAK,yBAAyB,EAAE,CAAC;4BAC7C,WAAW,GAAG,+CAA+C,CAAC;wBAChE,CAAC;6BAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;4BACnC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;wBAC1E,CAAC;6BAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;4BACnC,MAAM,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;4BACrD,MAAM,OAAO,GAAY,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;4BACjC,IAAI,QAAQ,CAAC,SAAS,CAAC,KAAK,KAAK;gCAC/B,MAAM,IAAI,UAAU,CAAC,eAAe,EAAE,+BAA+B,CAAC,CAAC;4BACzE,IAAI,OAAO,QAAQ,CAAC,QAAQ,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,EAAE,CAAC;gCAClE,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;oCAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;oCAC1C,IACE,CAAC,WAAW,CAAC,OAAO;wCACpB,MAAM,CAAC,WAAW,CAAC,KAAK,WAAW,CAAC,OAAO,CAAC,SAAS;wCAErD,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,0CAA0C,CAC3C,CAAC;oCACJ,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;wCACtD,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC;gCAC3B,CAAC;gCACD,mFAAmF;gCACnF,SAAS;4BACX,CAAC;4BACD,IAAI,OAAO,QAAQ,CAAC,QAAQ,CAAC,KAAK,QAAQ,EAAE,CAAC;gCAC3C,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAkB,CAAC;gCAC1C,UAAU,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;oCACzC,OAAO,GAAG,OAAO,CAAC;gCACpB,CAAC,CAAC,CAAC;4BACL,CAAC;4BACD,UAAU,CAAC,OAAO,CAAC,OAAyB,CAAC,CAAC;4BAC9C,OAAO;wBACT,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,OAAO;wBAAE,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YACD,MAAM;gBACJ,4DAA4D;YAC9D,CAAC;SACF,EACD,EAAE,aAAa,EAAE,CAAC,EAAE,CACrB;KACF,CAAC;IACF,MAAM,UAAU,GAAG,GAAG;SACnB,MAAM,EAAE;SACR,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;QACtE,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,SAAS,KAAK,WAAW,CAAC,OAAO,EAAE,SAAS;YAC7E,OAAO,cAAc,EAAE,CAAC;QAC1B,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS;YACvE,WAAW,CAAC,eAAe,GAAG,IAAI,CAAC;QACrC,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACzD,CAAC,CAAC;SACD,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,IAAI,OAAkC,CAAC;IACvC,OAAO;QACL,UAAU;QACV,KAAK,CAAC,MAAM;YACV,uFAAuF;YACvF,IAAI,WAAW,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;gBACpC,MAAM,KAAK,GAAG;oBACZ,OAAO,EAAE,KAAK;oBACd,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM;oBACxC,MAAM,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE;iBACrD,CAAC;gBACF,KAAK,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7C,CAAC;YACD,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;QACD,KAAK;YACH,OAAO,KAAK,CAAC,KAAK,IAAI,EAAE;gBACtB,OAAO,GAAG,IAAI,CAAC;gBACf,OAAO,EAAE,EAAE,CAAC;gBACZ,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,UAAU,CAAC,KAAK,EAAE,CAAC;gBACnB,KAAK,EAAE,GAAG,EAAE,CAAC;gBACb,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBAChC,IAAI,WAAW;oBAAE,MAAM,IAAI,UAAU,CAAC,yBAAyB,EAAE,WAAW,CAAC,CAAC;YAChF,CAAC,CAAC,EAAE,CAAC;YACL,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}