@wrongstack/acp 1.0.33 → 1.0.36
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/agent/protocol-contract.d.ts +0 -10
- package/dist/agent/protocol-handler.d.ts +1 -6
- package/dist/agent/server-agent-turn-content.d.ts +117 -0
- package/dist/agent/server-agent-turn.d.ts +4 -67
- package/dist/agent.js +148 -139
- package/dist/client/acp-session-prompt.d.ts +23 -0
- package/dist/client/acp-session.d.ts +1 -0
- package/dist/client.js +207 -175
- package/dist/index.js +212 -176
- package/dist/wrongstack-acp-agent.js +5 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1135,7 +1135,11 @@ var StdioTransport = class {
|
|
|
1135
1135
|
return;
|
|
1136
1136
|
}
|
|
1137
1137
|
try {
|
|
1138
|
-
|
|
1138
|
+
const parsed = JSON.parse(raw);
|
|
1139
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
1140
|
+
throw new Error("frame is not a JSON-RPC object");
|
|
1141
|
+
}
|
|
1142
|
+
this.dispatch(parsed, raw.length);
|
|
1139
1143
|
} catch (err) {
|
|
1140
1144
|
this.stderr.write(`[wstack-acp parse error] ${err}
|
|
1141
1145
|
`, "utf8");
|
|
@@ -2238,39 +2242,6 @@ async function ensureAuthenticated(host) {
|
|
|
2238
2242
|
);
|
|
2239
2243
|
}
|
|
2240
2244
|
|
|
2241
|
-
// src/client/acp-session-content.ts
|
|
2242
|
-
function textContent(text) {
|
|
2243
|
-
return { type: "text", text };
|
|
2244
|
-
}
|
|
2245
|
-
function imageContent(mimeType, data) {
|
|
2246
|
-
return { type: "image", mimeType, data };
|
|
2247
|
-
}
|
|
2248
|
-
function audioContent(mimeType, data) {
|
|
2249
|
-
return { type: "audio", mimeType, data };
|
|
2250
|
-
}
|
|
2251
|
-
function extractText(block) {
|
|
2252
|
-
if (typeof block !== "object" || block === null) return "";
|
|
2253
|
-
const b = block;
|
|
2254
|
-
if (b.type === "text" && typeof b.text === "string") return b.text;
|
|
2255
|
-
if (b.type === "resource" && b.resource && typeof b.resource === "object" && typeof b.resource.text === "string") {
|
|
2256
|
-
return b.resource.text;
|
|
2257
|
-
}
|
|
2258
|
-
return "";
|
|
2259
|
-
}
|
|
2260
|
-
function isRecord(v) {
|
|
2261
|
-
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2262
|
-
}
|
|
2263
|
-
function emptyRunResult(stopReason) {
|
|
2264
|
-
return {
|
|
2265
|
-
text: "",
|
|
2266
|
-
stopReason,
|
|
2267
|
-
hasText: false,
|
|
2268
|
-
toolCalls: [],
|
|
2269
|
-
diffs: [],
|
|
2270
|
-
thoughts: ""
|
|
2271
|
-
};
|
|
2272
|
-
}
|
|
2273
|
-
|
|
2274
2245
|
// src/client/acp-message-routing.ts
|
|
2275
2246
|
function isBestEffortAckMethod(method) {
|
|
2276
2247
|
return method === "mcp/connect" || method === "mcp/message" || method === "mcp/disconnect" || method === "elicitation/create" || method === "elicitation/complete";
|
|
@@ -2738,10 +2709,45 @@ function isAbortLikeError(err) {
|
|
|
2738
2709
|
}
|
|
2739
2710
|
function resolvePermissionDeadline(value) {
|
|
2740
2711
|
if (value === Number.POSITIVE_INFINITY) return null;
|
|
2741
|
-
if (value !== void 0 && Number.isFinite(value) && value > 0)
|
|
2712
|
+
if (value !== void 0 && Number.isFinite(value) && value > 0) {
|
|
2713
|
+
return Math.min(Math.trunc(value), 2147483647);
|
|
2714
|
+
}
|
|
2742
2715
|
return DEFAULT_PERMISSION_TIMEOUT_MS;
|
|
2743
2716
|
}
|
|
2744
2717
|
|
|
2718
|
+
// src/client/acp-session-content.ts
|
|
2719
|
+
function textContent(text) {
|
|
2720
|
+
return { type: "text", text };
|
|
2721
|
+
}
|
|
2722
|
+
function imageContent(mimeType, data) {
|
|
2723
|
+
return { type: "image", mimeType, data };
|
|
2724
|
+
}
|
|
2725
|
+
function audioContent(mimeType, data) {
|
|
2726
|
+
return { type: "audio", mimeType, data };
|
|
2727
|
+
}
|
|
2728
|
+
function extractText(block) {
|
|
2729
|
+
if (typeof block !== "object" || block === null) return "";
|
|
2730
|
+
const b = block;
|
|
2731
|
+
if (b.type === "text" && typeof b.text === "string") return b.text;
|
|
2732
|
+
if (b.type === "resource" && b.resource && typeof b.resource === "object" && typeof b.resource.text === "string") {
|
|
2733
|
+
return b.resource.text;
|
|
2734
|
+
}
|
|
2735
|
+
return "";
|
|
2736
|
+
}
|
|
2737
|
+
function isRecord(v) {
|
|
2738
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2739
|
+
}
|
|
2740
|
+
function emptyRunResult(stopReason) {
|
|
2741
|
+
return {
|
|
2742
|
+
text: "",
|
|
2743
|
+
stopReason,
|
|
2744
|
+
hasText: false,
|
|
2745
|
+
toolCalls: [],
|
|
2746
|
+
diffs: [],
|
|
2747
|
+
thoughts: ""
|
|
2748
|
+
};
|
|
2749
|
+
}
|
|
2750
|
+
|
|
2745
2751
|
// src/client/acp-session-updates.ts
|
|
2746
2752
|
function createSessionScratch() {
|
|
2747
2753
|
return { text: "", thoughts: "", toolCalls: /* @__PURE__ */ new Map(), diffs: [] };
|
|
@@ -2937,6 +2943,146 @@ function emitProgress(event) {
|
|
|
2937
2943
|
}
|
|
2938
2944
|
}
|
|
2939
2945
|
|
|
2946
|
+
// src/client/acp-session-prompt.ts
|
|
2947
|
+
async function prompt(host, blocks, signal, onProgress) {
|
|
2948
|
+
if (host.closed) {
|
|
2949
|
+
throw new ACPSessionError("closed", "session is closed");
|
|
2950
|
+
}
|
|
2951
|
+
if (host.state !== "ready" && host.state !== "authenticated" && host.state !== "done") {
|
|
2952
|
+
throw new ACPSessionError("protocol_error", `prompt called in state=${host.state}`);
|
|
2953
|
+
}
|
|
2954
|
+
if (host.promptCallbackAbort) {
|
|
2955
|
+
throw new ACPSessionError("protocol_error", "prompt called while another prompt is running");
|
|
2956
|
+
}
|
|
2957
|
+
if (signal.aborted) {
|
|
2958
|
+
return emptyRunResult("cancelled");
|
|
2959
|
+
}
|
|
2960
|
+
const caps = host.agentCapabilities.promptCapabilities;
|
|
2961
|
+
for (const block of blocks) {
|
|
2962
|
+
const supported = block.type === "image" ? caps?.image : block.type === "audio" ? caps?.audio : block.type === "resource" ? caps?.embeddedContext : true;
|
|
2963
|
+
if (supported !== true) {
|
|
2964
|
+
throw new ACPSessionError(
|
|
2965
|
+
"unsupported_capability",
|
|
2966
|
+
`agent does not support ${block.type} prompt content`
|
|
2967
|
+
);
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2970
|
+
let cancelled = false;
|
|
2971
|
+
host.promptCallbackAbort = new AbortController();
|
|
2972
|
+
const onAbort = () => {
|
|
2973
|
+
cancelled = true;
|
|
2974
|
+
host.promptCallbackAbort?.abort();
|
|
2975
|
+
if (host.sessionId) {
|
|
2976
|
+
host.transport.send({
|
|
2977
|
+
jsonrpc: "2.0",
|
|
2978
|
+
method: "session/cancel",
|
|
2979
|
+
params: { sessionId: host.sessionId }
|
|
2980
|
+
}).catch(() => {
|
|
2981
|
+
});
|
|
2982
|
+
}
|
|
2983
|
+
};
|
|
2984
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
2985
|
+
let rejectCreate;
|
|
2986
|
+
const onCreateAbort = () => {
|
|
2987
|
+
signal.removeEventListener("abort", onAbort);
|
|
2988
|
+
rejectCreate?.(new ACPSessionError("aborted", "prompt was aborted by the parent"));
|
|
2989
|
+
};
|
|
2990
|
+
if (!host.sessionId) {
|
|
2991
|
+
let sessionId;
|
|
2992
|
+
const createPromise = host.createSessionWithAuth();
|
|
2993
|
+
try {
|
|
2994
|
+
sessionId = await Promise.race([
|
|
2995
|
+
createPromise,
|
|
2996
|
+
new Promise((_, reject) => {
|
|
2997
|
+
rejectCreate = reject;
|
|
2998
|
+
signal.addEventListener("abort", onCreateAbort, { once: true });
|
|
2999
|
+
})
|
|
3000
|
+
]);
|
|
3001
|
+
} catch (err) {
|
|
3002
|
+
signal.removeEventListener("abort", onAbort);
|
|
3003
|
+
signal.removeEventListener("abort", onCreateAbort);
|
|
3004
|
+
rejectCreate = void 0;
|
|
3005
|
+
host.promptCallbackAbort?.abort();
|
|
3006
|
+
host.promptCallbackAbort = null;
|
|
3007
|
+
if (err instanceof ACPSessionError && err.kind === "aborted") {
|
|
3008
|
+
host.cancelLateSession(createPromise);
|
|
3009
|
+
return emptyRunResult("cancelled");
|
|
3010
|
+
}
|
|
3011
|
+
throw err;
|
|
3012
|
+
}
|
|
3013
|
+
signal.removeEventListener("abort", onCreateAbort);
|
|
3014
|
+
rejectCreate = void 0;
|
|
3015
|
+
host.sessionId = sessionId;
|
|
3016
|
+
}
|
|
3017
|
+
if (signal.aborted) {
|
|
3018
|
+
host.promptCallbackAbort = null;
|
|
3019
|
+
return emptyRunResult("cancelled");
|
|
3020
|
+
}
|
|
3021
|
+
host.resetScratch();
|
|
3022
|
+
host.progressHandler = onProgress ?? null;
|
|
3023
|
+
const promptId = host.allocId();
|
|
3024
|
+
let rejectTurn;
|
|
3025
|
+
const onTurnAbort = () => {
|
|
3026
|
+
rejectTurn?.(new ACPSessionError("aborted", "prompt was aborted by the parent"));
|
|
3027
|
+
};
|
|
3028
|
+
signal.addEventListener("abort", onTurnAbort, { once: true });
|
|
3029
|
+
const turnPromise = Promise.race([
|
|
3030
|
+
host.sendRequest(
|
|
3031
|
+
promptId,
|
|
3032
|
+
"session/prompt",
|
|
3033
|
+
{
|
|
3034
|
+
sessionId: host.sessionId,
|
|
3035
|
+
prompt: blocks
|
|
3036
|
+
},
|
|
3037
|
+
host.timeoutMs
|
|
3038
|
+
),
|
|
3039
|
+
new Promise((_, reject) => {
|
|
3040
|
+
rejectTurn = reject;
|
|
3041
|
+
})
|
|
3042
|
+
]);
|
|
3043
|
+
host.state = "prompting";
|
|
3044
|
+
let response;
|
|
3045
|
+
try {
|
|
3046
|
+
response = await turnPromise;
|
|
3047
|
+
} catch (err) {
|
|
3048
|
+
host.state = "done";
|
|
3049
|
+
const abortedKind = err instanceof ACPSessionError && err.kind === "aborted";
|
|
3050
|
+
if (cancelled || abortedKind) {
|
|
3051
|
+
return emptyRunResult("cancelled");
|
|
3052
|
+
}
|
|
3053
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3054
|
+
if (signal.aborted) {
|
|
3055
|
+
throw new ACPSessionError("aborted", "prompt was aborted by the parent", err);
|
|
3056
|
+
}
|
|
3057
|
+
throw new ACPSessionError("prompt_failed", `session/prompt failed: ${msg}`, err);
|
|
3058
|
+
} finally {
|
|
3059
|
+
signal.removeEventListener("abort", onAbort);
|
|
3060
|
+
signal.removeEventListener("abort", onTurnAbort);
|
|
3061
|
+
signal.removeEventListener("abort", onCreateAbort);
|
|
3062
|
+
rejectTurn = void 0;
|
|
3063
|
+
rejectCreate = void 0;
|
|
3064
|
+
host.promptCallbackAbort?.abort();
|
|
3065
|
+
host.promptCallbackAbort = null;
|
|
3066
|
+
host.progressHandler = null;
|
|
3067
|
+
}
|
|
3068
|
+
host.state = "done";
|
|
3069
|
+
if (isJsonRpcError(response)) {
|
|
3070
|
+
throw new ACPSessionError("prompt_failed", `agent error: ${response.message}`, response);
|
|
3071
|
+
}
|
|
3072
|
+
const stopReason = response.stopReason ?? "end_turn";
|
|
3073
|
+
const finalText = host.scratch.text;
|
|
3074
|
+
return {
|
|
3075
|
+
text: finalText,
|
|
3076
|
+
stopReason,
|
|
3077
|
+
hasText: finalText.length > 0,
|
|
3078
|
+
usage: host.scratch.usage,
|
|
3079
|
+
plan: host.scratch.plan,
|
|
3080
|
+
toolCalls: [...host.scratch.toolCalls.values()],
|
|
3081
|
+
diffs: host.scratch.diffs,
|
|
3082
|
+
thoughts: host.scratch.thoughts
|
|
3083
|
+
};
|
|
3084
|
+
}
|
|
3085
|
+
|
|
2940
3086
|
// src/client/permission.ts
|
|
2941
3087
|
function pickAllow(options) {
|
|
2942
3088
|
const ranked = [...options].sort((a, b) => {
|
|
@@ -2992,7 +3138,8 @@ function win32BatchTarget(command) {
|
|
|
2992
3138
|
if (/\.(?:cmd|bat)$/i.test(command)) return command;
|
|
2993
3139
|
if (/[\\/]/.test(command) || path3.extname(command)) return void 0;
|
|
2994
3140
|
const exts = (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").toLowerCase().split(";");
|
|
2995
|
-
for (const
|
|
3141
|
+
for (const rawDir of (process.env["PATH"] ?? "").split(path3.delimiter)) {
|
|
3142
|
+
const dir = rawDir.trim().replace(/^"|"$/g, "");
|
|
2996
3143
|
if (!dir) continue;
|
|
2997
3144
|
for (const ext of exts) {
|
|
2998
3145
|
if (!ext) continue;
|
|
@@ -3256,15 +3403,13 @@ var TerminalServer = class {
|
|
|
3256
3403
|
resolveCwd(cwd) {
|
|
3257
3404
|
if (!cwd) return this.projectRoot;
|
|
3258
3405
|
const resolved = path3.resolve(cwd);
|
|
3259
|
-
|
|
3260
|
-
if (resolved !== this.projectRoot && !resolved.startsWith(rootWithSep)) {
|
|
3406
|
+
if (!isInsideRoot(resolved, this.projectRoot)) {
|
|
3261
3407
|
return this.projectRoot;
|
|
3262
3408
|
}
|
|
3263
3409
|
try {
|
|
3264
3410
|
const realRoot = realpathSync2(this.projectRoot);
|
|
3265
3411
|
const realCwd = realpathSync2(resolved);
|
|
3266
|
-
|
|
3267
|
-
if (realCwd !== realRoot && !realCwd.startsWith(realRootWithSep)) {
|
|
3412
|
+
if (!isInsideRoot(realCwd, realRoot)) {
|
|
3268
3413
|
return realRoot;
|
|
3269
3414
|
}
|
|
3270
3415
|
return realCwd;
|
|
@@ -3296,6 +3441,12 @@ var TerminalServer = class {
|
|
|
3296
3441
|
return Math.trunc(value);
|
|
3297
3442
|
}
|
|
3298
3443
|
};
|
|
3444
|
+
function isInsideRoot(child, root) {
|
|
3445
|
+
const fold = (p) => process.platform === "win32" ? p.toLowerCase() : p;
|
|
3446
|
+
const c = fold(child);
|
|
3447
|
+
const r = fold(root);
|
|
3448
|
+
return c === r || c.startsWith(r.endsWith(path3.sep) ? r : r + path3.sep);
|
|
3449
|
+
}
|
|
3299
3450
|
var DENIED_AGENT_ENV_KEYS = /* @__PURE__ */ new Set([
|
|
3300
3451
|
"NODE_OPTIONS",
|
|
3301
3452
|
"LD_PRELOAD",
|
|
@@ -3559,6 +3710,7 @@ var WebSocketClientTransport = class {
|
|
|
3559
3710
|
}
|
|
3560
3711
|
dispatch(msg) {
|
|
3561
3712
|
for (const handler of [...this.handlers]) {
|
|
3713
|
+
if (this.closed) break;
|
|
3562
3714
|
try {
|
|
3563
3715
|
handler(msg);
|
|
3564
3716
|
} catch {
|
|
@@ -3835,142 +3987,7 @@ var ACPSession = class _ACPSession {
|
|
|
3835
3987
|
// Prompt
|
|
3836
3988
|
// ──────────────────────────────────────────────────────────────────────
|
|
3837
3989
|
async prompt(blocks, signal, onProgress) {
|
|
3838
|
-
|
|
3839
|
-
throw new ACPSessionError("closed", "session is closed");
|
|
3840
|
-
}
|
|
3841
|
-
if (this.state !== "ready" && this.state !== "authenticated" && this.state !== "done") {
|
|
3842
|
-
throw new ACPSessionError("protocol_error", `prompt called in state=${this.state}`);
|
|
3843
|
-
}
|
|
3844
|
-
if (this.promptCallbackAbort) {
|
|
3845
|
-
throw new ACPSessionError("protocol_error", "prompt called while another prompt is running");
|
|
3846
|
-
}
|
|
3847
|
-
if (signal.aborted) {
|
|
3848
|
-
return emptyRunResult("cancelled");
|
|
3849
|
-
}
|
|
3850
|
-
const caps = this.agentCapabilities.promptCapabilities;
|
|
3851
|
-
for (const block of blocks) {
|
|
3852
|
-
const supported = block.type === "image" ? caps?.image : block.type === "audio" ? caps?.audio : block.type === "resource" ? caps?.embeddedContext : true;
|
|
3853
|
-
if (supported !== true) {
|
|
3854
|
-
throw new ACPSessionError(
|
|
3855
|
-
"unsupported_capability",
|
|
3856
|
-
`agent does not support ${block.type} prompt content`
|
|
3857
|
-
);
|
|
3858
|
-
}
|
|
3859
|
-
}
|
|
3860
|
-
let cancelled = false;
|
|
3861
|
-
this.promptCallbackAbort = new AbortController();
|
|
3862
|
-
const onAbort = () => {
|
|
3863
|
-
cancelled = true;
|
|
3864
|
-
this.promptCallbackAbort?.abort();
|
|
3865
|
-
if (this.sessionId) {
|
|
3866
|
-
this.transport.send({
|
|
3867
|
-
jsonrpc: "2.0",
|
|
3868
|
-
method: "session/cancel",
|
|
3869
|
-
params: { sessionId: this.sessionId }
|
|
3870
|
-
}).catch(() => {
|
|
3871
|
-
});
|
|
3872
|
-
}
|
|
3873
|
-
};
|
|
3874
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
3875
|
-
let rejectCreate;
|
|
3876
|
-
const onCreateAbort = () => {
|
|
3877
|
-
signal.removeEventListener("abort", onAbort);
|
|
3878
|
-
rejectCreate?.(new ACPSessionError("aborted", "prompt was aborted by the parent"));
|
|
3879
|
-
};
|
|
3880
|
-
if (!this.sessionId) {
|
|
3881
|
-
let sessionId;
|
|
3882
|
-
const createPromise = this.createSessionWithAuth();
|
|
3883
|
-
try {
|
|
3884
|
-
sessionId = await Promise.race([
|
|
3885
|
-
createPromise,
|
|
3886
|
-
new Promise((_, reject) => {
|
|
3887
|
-
rejectCreate = reject;
|
|
3888
|
-
signal.addEventListener("abort", onCreateAbort, { once: true });
|
|
3889
|
-
})
|
|
3890
|
-
]);
|
|
3891
|
-
} catch (err) {
|
|
3892
|
-
signal.removeEventListener("abort", onAbort);
|
|
3893
|
-
signal.removeEventListener("abort", onCreateAbort);
|
|
3894
|
-
rejectCreate = void 0;
|
|
3895
|
-
this.promptCallbackAbort?.abort();
|
|
3896
|
-
this.promptCallbackAbort = null;
|
|
3897
|
-
if (err instanceof ACPSessionError && err.kind === "aborted") {
|
|
3898
|
-
this.cancelLateSession(createPromise);
|
|
3899
|
-
return emptyRunResult("cancelled");
|
|
3900
|
-
}
|
|
3901
|
-
throw err;
|
|
3902
|
-
}
|
|
3903
|
-
signal.removeEventListener("abort", onCreateAbort);
|
|
3904
|
-
rejectCreate = void 0;
|
|
3905
|
-
this.sessionId = sessionId;
|
|
3906
|
-
}
|
|
3907
|
-
if (signal.aborted) {
|
|
3908
|
-
this.promptCallbackAbort = null;
|
|
3909
|
-
return emptyRunResult("cancelled");
|
|
3910
|
-
}
|
|
3911
|
-
this.resetScratch();
|
|
3912
|
-
this.progressHandler = onProgress ?? null;
|
|
3913
|
-
const promptId = this.allocId();
|
|
3914
|
-
let rejectTurn;
|
|
3915
|
-
const onTurnAbort = () => {
|
|
3916
|
-
rejectTurn?.(new ACPSessionError("aborted", "prompt was aborted by the parent"));
|
|
3917
|
-
};
|
|
3918
|
-
signal.addEventListener("abort", onTurnAbort, { once: true });
|
|
3919
|
-
const turnPromise = Promise.race([
|
|
3920
|
-
this.sendRequest(
|
|
3921
|
-
promptId,
|
|
3922
|
-
"session/prompt",
|
|
3923
|
-
{
|
|
3924
|
-
sessionId: this.sessionId,
|
|
3925
|
-
prompt: blocks
|
|
3926
|
-
},
|
|
3927
|
-
this.timeoutMs
|
|
3928
|
-
),
|
|
3929
|
-
new Promise((_, reject) => {
|
|
3930
|
-
rejectTurn = reject;
|
|
3931
|
-
})
|
|
3932
|
-
]);
|
|
3933
|
-
this.state = "prompting";
|
|
3934
|
-
let response;
|
|
3935
|
-
try {
|
|
3936
|
-
response = await turnPromise;
|
|
3937
|
-
} catch (err) {
|
|
3938
|
-
this.state = "done";
|
|
3939
|
-
const abortedKind = err instanceof ACPSessionError && err.kind === "aborted";
|
|
3940
|
-
if (cancelled || abortedKind) {
|
|
3941
|
-
return emptyRunResult("cancelled");
|
|
3942
|
-
}
|
|
3943
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
3944
|
-
if (signal.aborted) {
|
|
3945
|
-
throw new ACPSessionError("aborted", "prompt was aborted by the parent", err);
|
|
3946
|
-
}
|
|
3947
|
-
throw new ACPSessionError("prompt_failed", `session/prompt failed: ${msg}`, err);
|
|
3948
|
-
} finally {
|
|
3949
|
-
signal.removeEventListener("abort", onAbort);
|
|
3950
|
-
signal.removeEventListener("abort", onTurnAbort);
|
|
3951
|
-
signal.removeEventListener("abort", onCreateAbort);
|
|
3952
|
-
rejectTurn = void 0;
|
|
3953
|
-
rejectCreate = void 0;
|
|
3954
|
-
this.promptCallbackAbort?.abort();
|
|
3955
|
-
this.promptCallbackAbort = null;
|
|
3956
|
-
this.progressHandler = null;
|
|
3957
|
-
}
|
|
3958
|
-
this.state = "done";
|
|
3959
|
-
if (isJsonRpcError(response)) {
|
|
3960
|
-
throw new ACPSessionError("prompt_failed", `agent error: ${response.message}`, response);
|
|
3961
|
-
}
|
|
3962
|
-
const stopReason = response.stopReason ?? "end_turn";
|
|
3963
|
-
const finalText = this.scratch.text;
|
|
3964
|
-
return {
|
|
3965
|
-
text: finalText,
|
|
3966
|
-
stopReason,
|
|
3967
|
-
hasText: finalText.length > 0,
|
|
3968
|
-
usage: this.scratch.usage,
|
|
3969
|
-
plan: this.scratch.plan,
|
|
3970
|
-
toolCalls: [...this.scratch.toolCalls.values()],
|
|
3971
|
-
diffs: this.scratch.diffs,
|
|
3972
|
-
thoughts: this.scratch.thoughts
|
|
3973
|
-
};
|
|
3990
|
+
return prompt(this.acpSessionPromptHost(), blocks, signal, onProgress);
|
|
3974
3991
|
}
|
|
3975
3992
|
/**
|
|
3976
3993
|
* Best-effort cancel for a session the server confirmed after we already
|
|
@@ -4140,6 +4157,25 @@ var ACPSession = class _ACPSession {
|
|
|
4140
4157
|
void this.progressHandler;
|
|
4141
4158
|
return this;
|
|
4142
4159
|
}
|
|
4160
|
+
acpSessionPromptHost() {
|
|
4161
|
+
void {
|
|
4162
|
+
closed: this.closed,
|
|
4163
|
+
state: this.state,
|
|
4164
|
+
promptCallbackAbort: this.promptCallbackAbort,
|
|
4165
|
+
agentCapabilities: this.agentCapabilities,
|
|
4166
|
+
sessionId: this.sessionId,
|
|
4167
|
+
transport: this.transport,
|
|
4168
|
+
createSessionWithAuth: this.createSessionWithAuth,
|
|
4169
|
+
cancelLateSession: this.cancelLateSession,
|
|
4170
|
+
resetScratch: this.resetScratch,
|
|
4171
|
+
progressHandler: this.progressHandler,
|
|
4172
|
+
allocId: this.allocId,
|
|
4173
|
+
sendRequest: this.sendRequest,
|
|
4174
|
+
timeoutMs: this.timeoutMs,
|
|
4175
|
+
scratch: this.scratch
|
|
4176
|
+
};
|
|
4177
|
+
return this;
|
|
4178
|
+
}
|
|
4143
4179
|
};
|
|
4144
4180
|
|
|
4145
4181
|
// src/client/tool-translator.ts
|
|
@@ -1132,7 +1132,11 @@ var StdioTransport = class {
|
|
|
1132
1132
|
return;
|
|
1133
1133
|
}
|
|
1134
1134
|
try {
|
|
1135
|
-
|
|
1135
|
+
const parsed = JSON.parse(raw);
|
|
1136
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
1137
|
+
throw new Error("frame is not a JSON-RPC object");
|
|
1138
|
+
}
|
|
1139
|
+
this.dispatch(parsed, raw.length);
|
|
1136
1140
|
} catch (err) {
|
|
1137
1141
|
this.stderr.write(`[wstack-acp parse error] ${err}
|
|
1138
1142
|
`, "utf8");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/acp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.36",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "ACP (Agent Client Protocol) integration for WrongStack — client + agent support",
|
|
6
6
|
"keywords": [
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
],
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@agentclientprotocol/sdk": "^1.4.0",
|
|
55
|
-
"@wrongstack/core": "1.0.
|
|
56
|
-
"@wrongstack/primitives": "1.0.
|
|
55
|
+
"@wrongstack/core": "1.0.36",
|
|
56
|
+
"@wrongstack/primitives": "1.0.36"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@types/node": "^26.5.1",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
},
|
|
66
66
|
"scripts": {
|
|
67
67
|
"build": "node ../../scripts/build-package.mjs",
|
|
68
|
-
"typecheck": "
|
|
69
|
-
"typecheck:tests": "
|
|
68
|
+
"typecheck": "node ../../scripts/bun-typecheck.mjs --noEmit",
|
|
69
|
+
"typecheck:tests": "node ../../scripts/bun-typecheck.mjs --noEmit -p tsconfig.test.json",
|
|
70
70
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
71
71
|
"test": "vitest run",
|
|
72
72
|
"smoke": "pnpm build && node --experimental-strip-types ../../scripts/acp-smoke-test.mts"
|