@wrongstack/acp 1.0.33 → 1.0.35

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/index.js CHANGED
@@ -2238,39 +2238,6 @@ async function ensureAuthenticated(host) {
2238
2238
  );
2239
2239
  }
2240
2240
 
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
2241
  // src/client/acp-message-routing.ts
2275
2242
  function isBestEffortAckMethod(method) {
2276
2243
  return method === "mcp/connect" || method === "mcp/message" || method === "mcp/disconnect" || method === "elicitation/create" || method === "elicitation/complete";
@@ -2742,6 +2709,39 @@ function resolvePermissionDeadline(value) {
2742
2709
  return DEFAULT_PERMISSION_TIMEOUT_MS;
2743
2710
  }
2744
2711
 
2712
+ // src/client/acp-session-content.ts
2713
+ function textContent(text) {
2714
+ return { type: "text", text };
2715
+ }
2716
+ function imageContent(mimeType, data) {
2717
+ return { type: "image", mimeType, data };
2718
+ }
2719
+ function audioContent(mimeType, data) {
2720
+ return { type: "audio", mimeType, data };
2721
+ }
2722
+ function extractText(block) {
2723
+ if (typeof block !== "object" || block === null) return "";
2724
+ const b = block;
2725
+ if (b.type === "text" && typeof b.text === "string") return b.text;
2726
+ if (b.type === "resource" && b.resource && typeof b.resource === "object" && typeof b.resource.text === "string") {
2727
+ return b.resource.text;
2728
+ }
2729
+ return "";
2730
+ }
2731
+ function isRecord(v) {
2732
+ return typeof v === "object" && v !== null && !Array.isArray(v);
2733
+ }
2734
+ function emptyRunResult(stopReason) {
2735
+ return {
2736
+ text: "",
2737
+ stopReason,
2738
+ hasText: false,
2739
+ toolCalls: [],
2740
+ diffs: [],
2741
+ thoughts: ""
2742
+ };
2743
+ }
2744
+
2745
2745
  // src/client/acp-session-updates.ts
2746
2746
  function createSessionScratch() {
2747
2747
  return { text: "", thoughts: "", toolCalls: /* @__PURE__ */ new Map(), diffs: [] };
@@ -2937,6 +2937,146 @@ function emitProgress(event) {
2937
2937
  }
2938
2938
  }
2939
2939
 
2940
+ // src/client/acp-session-prompt.ts
2941
+ async function prompt(host, blocks, signal, onProgress) {
2942
+ if (host.closed) {
2943
+ throw new ACPSessionError("closed", "session is closed");
2944
+ }
2945
+ if (host.state !== "ready" && host.state !== "authenticated" && host.state !== "done") {
2946
+ throw new ACPSessionError("protocol_error", `prompt called in state=${host.state}`);
2947
+ }
2948
+ if (host.promptCallbackAbort) {
2949
+ throw new ACPSessionError("protocol_error", "prompt called while another prompt is running");
2950
+ }
2951
+ if (signal.aborted) {
2952
+ return emptyRunResult("cancelled");
2953
+ }
2954
+ const caps = host.agentCapabilities.promptCapabilities;
2955
+ for (const block of blocks) {
2956
+ const supported = block.type === "image" ? caps?.image : block.type === "audio" ? caps?.audio : block.type === "resource" ? caps?.embeddedContext : true;
2957
+ if (supported !== true) {
2958
+ throw new ACPSessionError(
2959
+ "unsupported_capability",
2960
+ `agent does not support ${block.type} prompt content`
2961
+ );
2962
+ }
2963
+ }
2964
+ let cancelled = false;
2965
+ host.promptCallbackAbort = new AbortController();
2966
+ const onAbort = () => {
2967
+ cancelled = true;
2968
+ host.promptCallbackAbort?.abort();
2969
+ if (host.sessionId) {
2970
+ host.transport.send({
2971
+ jsonrpc: "2.0",
2972
+ method: "session/cancel",
2973
+ params: { sessionId: host.sessionId }
2974
+ }).catch(() => {
2975
+ });
2976
+ }
2977
+ };
2978
+ signal.addEventListener("abort", onAbort, { once: true });
2979
+ let rejectCreate;
2980
+ const onCreateAbort = () => {
2981
+ signal.removeEventListener("abort", onAbort);
2982
+ rejectCreate?.(new ACPSessionError("aborted", "prompt was aborted by the parent"));
2983
+ };
2984
+ if (!host.sessionId) {
2985
+ let sessionId;
2986
+ const createPromise = host.createSessionWithAuth();
2987
+ try {
2988
+ sessionId = await Promise.race([
2989
+ createPromise,
2990
+ new Promise((_, reject) => {
2991
+ rejectCreate = reject;
2992
+ signal.addEventListener("abort", onCreateAbort, { once: true });
2993
+ })
2994
+ ]);
2995
+ } catch (err) {
2996
+ signal.removeEventListener("abort", onAbort);
2997
+ signal.removeEventListener("abort", onCreateAbort);
2998
+ rejectCreate = void 0;
2999
+ host.promptCallbackAbort?.abort();
3000
+ host.promptCallbackAbort = null;
3001
+ if (err instanceof ACPSessionError && err.kind === "aborted") {
3002
+ host.cancelLateSession(createPromise);
3003
+ return emptyRunResult("cancelled");
3004
+ }
3005
+ throw err;
3006
+ }
3007
+ signal.removeEventListener("abort", onCreateAbort);
3008
+ rejectCreate = void 0;
3009
+ host.sessionId = sessionId;
3010
+ }
3011
+ if (signal.aborted) {
3012
+ host.promptCallbackAbort = null;
3013
+ return emptyRunResult("cancelled");
3014
+ }
3015
+ host.resetScratch();
3016
+ host.progressHandler = onProgress ?? null;
3017
+ const promptId = host.allocId();
3018
+ let rejectTurn;
3019
+ const onTurnAbort = () => {
3020
+ rejectTurn?.(new ACPSessionError("aborted", "prompt was aborted by the parent"));
3021
+ };
3022
+ signal.addEventListener("abort", onTurnAbort, { once: true });
3023
+ const turnPromise = Promise.race([
3024
+ host.sendRequest(
3025
+ promptId,
3026
+ "session/prompt",
3027
+ {
3028
+ sessionId: host.sessionId,
3029
+ prompt: blocks
3030
+ },
3031
+ host.timeoutMs
3032
+ ),
3033
+ new Promise((_, reject) => {
3034
+ rejectTurn = reject;
3035
+ })
3036
+ ]);
3037
+ host.state = "prompting";
3038
+ let response;
3039
+ try {
3040
+ response = await turnPromise;
3041
+ } catch (err) {
3042
+ host.state = "done";
3043
+ const abortedKind = err instanceof ACPSessionError && err.kind === "aborted";
3044
+ if (cancelled || abortedKind) {
3045
+ return emptyRunResult("cancelled");
3046
+ }
3047
+ const msg = err instanceof Error ? err.message : String(err);
3048
+ if (signal.aborted) {
3049
+ throw new ACPSessionError("aborted", "prompt was aborted by the parent", err);
3050
+ }
3051
+ throw new ACPSessionError("prompt_failed", `session/prompt failed: ${msg}`, err);
3052
+ } finally {
3053
+ signal.removeEventListener("abort", onAbort);
3054
+ signal.removeEventListener("abort", onTurnAbort);
3055
+ signal.removeEventListener("abort", onCreateAbort);
3056
+ rejectTurn = void 0;
3057
+ rejectCreate = void 0;
3058
+ host.promptCallbackAbort?.abort();
3059
+ host.promptCallbackAbort = null;
3060
+ host.progressHandler = null;
3061
+ }
3062
+ host.state = "done";
3063
+ if (isJsonRpcError(response)) {
3064
+ throw new ACPSessionError("prompt_failed", `agent error: ${response.message}`, response);
3065
+ }
3066
+ const stopReason = response.stopReason ?? "end_turn";
3067
+ const finalText = host.scratch.text;
3068
+ return {
3069
+ text: finalText,
3070
+ stopReason,
3071
+ hasText: finalText.length > 0,
3072
+ usage: host.scratch.usage,
3073
+ plan: host.scratch.plan,
3074
+ toolCalls: [...host.scratch.toolCalls.values()],
3075
+ diffs: host.scratch.diffs,
3076
+ thoughts: host.scratch.thoughts
3077
+ };
3078
+ }
3079
+
2940
3080
  // src/client/permission.ts
2941
3081
  function pickAllow(options) {
2942
3082
  const ranked = [...options].sort((a, b) => {
@@ -3835,142 +3975,7 @@ var ACPSession = class _ACPSession {
3835
3975
  // Prompt
3836
3976
  // ──────────────────────────────────────────────────────────────────────
3837
3977
  async prompt(blocks, signal, onProgress) {
3838
- if (this.closed) {
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
- };
3978
+ return prompt(this.acpSessionPromptHost(), blocks, signal, onProgress);
3974
3979
  }
3975
3980
  /**
3976
3981
  * Best-effort cancel for a session the server confirmed after we already
@@ -4140,6 +4145,25 @@ var ACPSession = class _ACPSession {
4140
4145
  void this.progressHandler;
4141
4146
  return this;
4142
4147
  }
4148
+ acpSessionPromptHost() {
4149
+ void {
4150
+ closed: this.closed,
4151
+ state: this.state,
4152
+ promptCallbackAbort: this.promptCallbackAbort,
4153
+ agentCapabilities: this.agentCapabilities,
4154
+ sessionId: this.sessionId,
4155
+ transport: this.transport,
4156
+ createSessionWithAuth: this.createSessionWithAuth,
4157
+ cancelLateSession: this.cancelLateSession,
4158
+ resetScratch: this.resetScratch,
4159
+ progressHandler: this.progressHandler,
4160
+ allocId: this.allocId,
4161
+ sendRequest: this.sendRequest,
4162
+ timeoutMs: this.timeoutMs,
4163
+ scratch: this.scratch
4164
+ };
4165
+ return this;
4166
+ }
4143
4167
  };
4144
4168
 
4145
4169
  // src/client/tool-translator.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/acp",
3
- "version": "1.0.33",
3
+ "version": "1.0.35",
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.33",
56
- "@wrongstack/primitives": "1.0.33"
55
+ "@wrongstack/core": "1.0.35",
56
+ "@wrongstack/primitives": "1.0.35"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@types/node": "^26.5.1",