@wrongstack/acp 0.293.0 → 0.295.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.
Files changed (63) hide show
  1. package/README.md +22 -2
  2. package/dist/agent/protocol-contract.d.ts +210 -0
  3. package/dist/agent/protocol-contract.d.ts.map +1 -0
  4. package/dist/agent/protocol-handler.d.ts +15 -189
  5. package/dist/agent/protocol-handler.d.ts.map +1 -1
  6. package/dist/agent/server-agent-turn.d.ts +89 -1
  7. package/dist/agent/server-agent-turn.d.ts.map +1 -1
  8. package/dist/agent/session-store.d.ts.map +1 -1
  9. package/dist/agent/stdio-transport.d.ts +30 -1
  10. package/dist/agent/stdio-transport.d.ts.map +1 -1
  11. package/dist/agent/tools-registry.d.ts +1 -1
  12. package/dist/agent/tools-registry.d.ts.map +1 -1
  13. package/dist/agent/wrongstack-acp-agent.d.ts +37 -0
  14. package/dist/agent/wrongstack-acp-agent.d.ts.map +1 -1
  15. package/dist/agent.js +189 -32
  16. package/dist/agent.js.map +4 -4
  17. package/dist/client/acp-session.d.ts +13 -1
  18. package/dist/client/acp-session.d.ts.map +1 -1
  19. package/dist/client/file-server.d.ts +19 -0
  20. package/dist/client/file-server.d.ts.map +1 -1
  21. package/dist/client/index.d.ts +11 -9
  22. package/dist/client/index.d.ts.map +1 -1
  23. package/dist/client/terminal-server.d.ts +5 -0
  24. package/dist/client/terminal-server.d.ts.map +1 -1
  25. package/dist/client/tool-translator.d.ts +1 -1
  26. package/dist/client/tool-translator.d.ts.map +1 -1
  27. package/dist/client/trust-boundary-permission.d.ts +31 -0
  28. package/dist/client/trust-boundary-permission.d.ts.map +1 -0
  29. package/dist/client/websocket-transport.d.ts +6 -0
  30. package/dist/client/websocket-transport.d.ts.map +1 -1
  31. package/dist/client.js +459 -243
  32. package/dist/client.js.map +4 -4
  33. package/dist/index.d.ts +29 -29
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +2116 -1802
  36. package/dist/index.js.map +4 -4
  37. package/dist/integration/acp-bench.d.ts +32 -0
  38. package/dist/integration/acp-bench.d.ts.map +1 -1
  39. package/dist/integration/acp-subagent-runner.d.ts +3 -3
  40. package/dist/integration/acp-subagent-runner.d.ts.map +1 -1
  41. package/dist/integration/ensemble-runner.d.ts +22 -1
  42. package/dist/integration/ensemble-runner.d.ts.map +1 -1
  43. package/dist/legacy.d.ts +8 -0
  44. package/dist/legacy.d.ts.map +1 -0
  45. package/dist/legacy.js +6 -0
  46. package/dist/legacy.js.map +7 -0
  47. package/dist/registry/acp-registry-fetch.d.ts +1 -1
  48. package/dist/registry/acp-registry-fetch.d.ts.map +1 -1
  49. package/dist/registry/ensemble-registry.d.ts +22 -0
  50. package/dist/registry/ensemble-registry.d.ts.map +1 -1
  51. package/dist/sdk.d.ts +10 -8
  52. package/dist/sdk.d.ts.map +1 -1
  53. package/dist/sdk.js +22 -0
  54. package/dist/sdk.js.map +3 -3
  55. package/dist/v1.d.ts +3 -0
  56. package/dist/v1.d.ts.map +1 -0
  57. package/dist/v1.js +12 -0
  58. package/dist/v1.js.map +7 -0
  59. package/dist/version.d.ts +10 -0
  60. package/dist/version.d.ts.map +1 -0
  61. package/dist/wrongstack-acp-agent.js +121 -24
  62. package/dist/wrongstack-acp-agent.js.map +4 -4
  63. package/package.json +10 -2
@@ -1,4 +1,5 @@
1
1
  import type { ACPMessage } from '../types/acp-messages.js';
2
+ declare function positiveLimit(value: number | undefined, fallback: number): number;
2
3
  export interface AgentServerTransport {
3
4
  send(msg: ACPMessage): Promise<void>;
4
5
  sendRaw(chunk: string): void;
@@ -26,7 +27,12 @@ export declare class StdioTransport implements AgentServerTransport {
26
27
  private closed;
27
28
  private resolveRead;
28
29
  private messageQueue;
29
- constructor();
30
+ private readonly maxFrameChars;
31
+ private readonly maxQueuedMessages;
32
+ constructor(opts?: {
33
+ maxFrameChars?: number;
34
+ maxQueuedMessages?: number;
35
+ });
30
36
  sendStartupMarker(): void;
31
37
  send(msg: ACPMessage): Promise<void>;
32
38
  sendRaw(chunk: string): void;
@@ -52,6 +58,10 @@ export interface ClientTransportOptions {
52
58
  * server-side transport (the default) keeps the marker check.
53
59
  */
54
60
  skipHandshakeMarker?: boolean | undefined;
61
+ /** Maximum pending newline-delimited JSON frame size. Default 20 MiB. */
62
+ maxFrameChars?: number | undefined;
63
+ /** Maximum messages retained for the optional read() API. Default 1000. */
64
+ maxQueuedMessages?: number | undefined;
55
65
  }
56
66
  export interface ACPChildProcess extends EventEmitter {
57
67
  stdout: NodeJS.ReadableStream;
@@ -68,6 +78,8 @@ export declare class ClientTransport implements ACPClientTransport {
68
78
  private resolveRead;
69
79
  private messageQueue;
70
80
  private readonly opts;
81
+ private readonly maxFrameChars;
82
+ private readonly maxQueuedMessages;
71
83
  constructor(options: ClientTransportOptions);
72
84
  start(): Promise<void>;
73
85
  send(msg: ACPMessage): Promise<void>;
@@ -79,4 +91,21 @@ export declare class ClientTransport implements ACPClientTransport {
79
91
  private onChildClose;
80
92
  private dispatch;
81
93
  }
94
+ declare function spawnInvocation(command: string, args: string[], platform: NodeJS.Platform): {
95
+ command: string;
96
+ args: string[];
97
+ windowsVerbatimArguments?: true;
98
+ };
99
+ declare function verbatimOptions(invocation: {
100
+ windowsVerbatimArguments?: true;
101
+ }): {
102
+ windowsVerbatimArguments?: true;
103
+ };
104
+ /** Direct-module test seam; not re-exported by the package barrel. */
105
+ export declare const stdioTransportCoverage: {
106
+ positiveLimit: typeof positiveLimit;
107
+ spawnInvocation: typeof spawnInvocation;
108
+ verbatimOptions: typeof verbatimOptions;
109
+ };
110
+ export {};
82
111
  //# sourceMappingURL=stdio-transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stdio-transport.d.ts","sourceRoot":"","sources":["../../src/agent/stdio-transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stdio-transport.d.ts","sourceRoot":"","sources":["../../src/agent/stdio-transport.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  * Translates WrongStack Tool definitions → ACP ACPToolDefinition format.
5
5
  * Provides tool lookup and result assembly for the ACP protocol handler.
6
6
  */
7
- import type { Tool } from '@wrongstack/core';
7
+ import type { Tool } from '@wrongstack/core/types';
8
8
  import type { ACPToolList, ACPToolResult } from '../types/acp-messages.js';
9
9
  export declare class ACPToolsRegistry {
10
10
  private tools;
@@ -1 +1 @@
1
- {"version":3,"file":"tools-registry.d.ts","sourceRoot":"","sources":["../../src/agent/tools-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,EAEV,WAAW,EAEX,aAAa,EAEd,MAAM,0BAA0B,CAAC;AAElC,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,YAAY,KAAK,SAAe,EAE/B;IAED;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAI5B;IAED;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAG5B;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAElC;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzB;IAED,IAAI,IAAI,IAAI,EAAE,CAEb;IAED,8DAA8D;IAC9D,aAAa,IAAI,WAAW,CAM3B;IAED;;;OAGG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAa/B;CACF"}
1
+ {"version":3,"file":"tools-registry.d.ts","sourceRoot":"","sources":["../../src/agent/tools-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,EAEV,WAAW,EAEX,aAAa,EAEd,MAAM,0BAA0B,CAAC;AAElC,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,YAAY,KAAK,SAAe,EAE/B;IAED;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAI5B;IAED;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAG5B;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAElC;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzB;IAED,IAAI,IAAI,IAAI,EAAE,CAEb;IAED,8DAA8D;IAC9D,aAAa,IAAI,WAAW,CAM3B;IAED;;;OAGG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAa/B;CACF"}
@@ -1,3 +1,29 @@
1
+ /**
2
+ * WrongStackACPServer — ACP v1 server-side entry point.
3
+ *
4
+ * Exposes WrongStack as an ACP-compatible agent. ACP clients (Zed, JetBrains
5
+ * Junie, VS Code ACP extension) spawn this as a subprocess, send JSON-RPC
6
+ * messages over stdio, and receive v1-protocol responses.
7
+ *
8
+ * Usage:
9
+ * node dist/agent/wrongstack-acp-agent.js
10
+ *
11
+ * Or via the CLI:
12
+ * wstack acp-server
13
+ *
14
+ * Wiring a real agent: this class is the surface; the bootstrap
15
+ * binary uses a no-op echo by default so the binary is a useful
16
+ * connectivity smoke test. For a real server, instantiate
17
+ * `WrongStackACPServer` programmatically and pass a `runTurn`
18
+ * produced by `makeACPServerAgentTurn({ agentFor: ... })` from
19
+ * `./server-agent-turn.js`. The factory is responsible for building
20
+ * a real core `Agent` (with the right provider, model, system prompt,
21
+ * etc.) per session.
22
+ *
23
+ * Startup: stdout is JSON-RPC only by default. The legacy `[wstack-acp]\n`
24
+ * marker can be enabled for older internal harnesses with
25
+ * `legacyStartupMarker`, but ACP clients should rely on v1 initialize.
26
+ */
1
27
  import { type RunTurn, type SessionPersistence } from './protocol-handler.js';
2
28
  export interface WrongStackACPServerOptions {
3
29
  runTurn?: RunTurn | undefined;
@@ -37,6 +63,8 @@ export interface WrongStackACPServerOptions {
37
63
  sessionUpdate: string;
38
64
  content: unknown;
39
65
  }>) => void) | undefined;
66
+ /** Per-session cleanup hook, normally `makeACPServerAgentTurn(...).dispose`. */
67
+ disposeFor?: ((sessionId: string) => void) | undefined;
40
68
  /**
41
69
  * Durable session store. When set, sessions + history are persisted and
42
70
  * restored across restarts for `session/load`. Pass an `ACPSessionStore`.
@@ -62,4 +90,13 @@ export declare class WrongStackACPServer {
62
90
  /** Stop the server. */
63
91
  stop(): void;
64
92
  }
93
+ declare function headerValue(value: string | string[] | undefined): string | undefined;
94
+ declare function requestPath(value: string | undefined): string;
95
+ /** Direct-module test seam; not re-exported by the package barrel. */
96
+ export declare const wrongStackACPServerCoverage: {
97
+ defaultEchoRunTurn: RunTurn;
98
+ headerValue: typeof headerValue;
99
+ requestPath: typeof requestPath;
100
+ };
101
+ export {};
65
102
  //# sourceMappingURL=wrongstack-acp-agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrongstack-acp-agent.d.ts","sourceRoot":"","sources":["../../src/agent/wrongstack-acp-agent.ts"],"names":[],"mappings":"AA8BA,OAAO,EAEL,KAAK,OAAO,EAEZ,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,0BAA0B;IACzC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACzC,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,kEAAkE;IAClE,mBAAmB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,KAAK,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAC;IACpG;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACjH;;;OAGG;IACH,KAAK,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;CACxC;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,+CAA+C;IAC/C,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,OAAO,CAAS;IAExB,YAAY,IAAI,GAAE,0BAA+B,EAahD;IAED;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAO3B;YAEa,UAAU;YAcV,SAAS;IAmKvB,uBAAuB;IACvB,IAAI,IAAI,IAAI,CAOX;CACF"}
1
+ {"version":3,"file":"wrongstack-acp-agent.d.ts","sourceRoot":"","sources":["../../src/agent/wrongstack-acp-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH,OAAO,EAEL,KAAK,OAAO,EAEZ,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,0BAA0B;IACzC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACzC,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,kEAAkE;IAClE,mBAAmB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C;;;;OAIG;IACH,SAAS,CAAC,EACN,CAAC,CAAC,SAAS,EAAE,MAAM,KAAK,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,GAC3E,SAAS,CAAC;IACd;;;OAGG;IACH,OAAO,CAAC,EACJ,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,KAAK,IAAI,CAAC,GAC1F,SAAS,CAAC;IACd,gFAAgF;IAChF,UAAU,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACvD;;;OAGG;IACH,KAAK,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;CACxC;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,+CAA+C;IAC/C,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,OAAO,CAAS;IAExB,YAAY,IAAI,GAAE,0BAA+B,EAchD;IAED;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAO3B;YAEa,UAAU;YAkBV,SAAS;IA4JvB,uBAAuB;IACvB,IAAI,IAAI,IAAI,CAQX;CACF;AAaD,iBAAS,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAE7E;AAED,iBAAS,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEtD;AAED,sEAAsE;AACtE,eAAO,MAAM,2BAA2B;;;;CAAmD,CAAC"}
package/dist/agent.js CHANGED
@@ -1,5 +1,11 @@
1
1
  // src/agent/stdio-transport.ts
2
- import { expectDefined, writeErr } from "@wrongstack/core";
2
+ import { expectDefined, writeErr } from "@wrongstack/core/utils";
3
+ import { treeKill } from "@wrongstack/core/utils/tree-kill";
4
+ var DEFAULT_MAX_FRAME_CHARS = 20 * 1024 * 1024;
5
+ var DEFAULT_MAX_QUEUED_MESSAGES = 1e3;
6
+ function positiveLimit(value, fallback) {
7
+ return value !== void 0 && Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;
8
+ }
3
9
  var StdioTransport = class {
4
10
  stdin = process.stdin;
5
11
  stdout = process.stdout;
@@ -9,7 +15,11 @@ var StdioTransport = class {
9
15
  closed = false;
10
16
  resolveRead = null;
11
17
  messageQueue = [];
12
- constructor() {
18
+ maxFrameChars;
19
+ maxQueuedMessages;
20
+ constructor(opts = {}) {
21
+ this.maxFrameChars = positiveLimit(opts.maxFrameChars, DEFAULT_MAX_FRAME_CHARS);
22
+ this.maxQueuedMessages = positiveLimit(opts.maxQueuedMessages, DEFAULT_MAX_QUEUED_MESSAGES);
13
23
  this.stdin.resume();
14
24
  this.stdin.setEncoding("utf8");
15
25
  this.stdin.on("data", (chunk) => this.onData(chunk));
@@ -30,7 +40,8 @@ var StdioTransport = class {
30
40
  this.stdout.write(chunk, "utf8");
31
41
  }
32
42
  read() {
33
- if (this.messageQueue.length > 0) return Promise.resolve(expectDefined(this.messageQueue.shift()));
43
+ if (this.messageQueue.length > 0)
44
+ return Promise.resolve(expectDefined(this.messageQueue.shift()));
34
45
  if (this.closed) return Promise.resolve(null);
35
46
  return new Promise((resolve) => {
36
47
  this.resolveRead = resolve;
@@ -45,13 +56,34 @@ var StdioTransport = class {
45
56
  this.stdin.pause();
46
57
  this.resolveRead?.(null);
47
58
  this.resolveRead = null;
59
+ this.buffer = "";
60
+ this.messageQueue.length = 0;
61
+ this.handlers.clear();
48
62
  }
49
63
  onData(chunk) {
50
64
  this.buffer += chunk;
51
65
  const lines = this.buffer.split("\n");
52
66
  this.buffer = lines.pop() ?? "";
67
+ if (this.buffer.length > this.maxFrameChars) {
68
+ this.stderr.write(
69
+ `[wstack-acp frame error] pending frame exceeds ${this.maxFrameChars} characters
70
+ `,
71
+ "utf8"
72
+ );
73
+ this.close();
74
+ return;
75
+ }
53
76
  for (const raw of lines) {
54
77
  if (!raw.trim()) continue;
78
+ if (raw.length > this.maxFrameChars) {
79
+ this.stderr.write(
80
+ `[wstack-acp frame error] frame exceeds ${this.maxFrameChars} characters
81
+ `,
82
+ "utf8"
83
+ );
84
+ this.close();
85
+ return;
86
+ }
55
87
  try {
56
88
  this.dispatch(JSON.parse(raw));
57
89
  } catch (err) {
@@ -66,6 +98,15 @@ var StdioTransport = class {
66
98
  this.resolveRead = null;
67
99
  resolve(msg);
68
100
  } else {
101
+ if (this.messageQueue.length >= this.maxQueuedMessages) {
102
+ this.stderr.write(
103
+ `[wstack-acp queue error] pending message queue exceeds ${this.maxQueuedMessages} entries
104
+ `,
105
+ "utf8"
106
+ );
107
+ this.close();
108
+ return;
109
+ }
69
110
  this.messageQueue.push(msg);
70
111
  }
71
112
  for (const handler of this.handlers) {
@@ -78,9 +119,7 @@ var StdioTransport = class {
78
119
  }
79
120
  }
80
121
  handleClose() {
81
- this.closed = true;
82
- this.resolveRead?.(null);
83
- this.resolveRead = null;
122
+ this.close();
84
123
  }
85
124
  failAll(err) {
86
125
  this.stderr.write(`[wstack-acp stdin error] ${err.message}
@@ -206,11 +245,28 @@ function toolToPriority(tool) {
206
245
  // src/types/acp-v1.ts
207
246
  var ACP_PROTOCOL_VERSION = 1;
208
247
 
209
- // src/agent/protocol-handler.ts
248
+ // src/version.ts
249
+ import { createRequire } from "node:module";
250
+ var require2 = createRequire(import.meta.url);
251
+ function readPackageVersion(load = () => require2("../package.json")) {
252
+ try {
253
+ const packageJson = load();
254
+ if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
255
+ return packageJson.version;
256
+ }
257
+ } catch {
258
+ }
259
+ return "dev";
260
+ }
261
+ var ACP_PACKAGE_VERSION = readPackageVersion();
262
+
263
+ // src/agent/protocol-contract.ts
210
264
  function toWire(msg) {
211
265
  return msg;
212
266
  }
213
- var WRONGSTACK_VERSION = "0.274.1";
267
+ var WRONGSTACK_VERSION = ACP_PACKAGE_VERSION;
268
+
269
+ // src/agent/protocol-handler.ts
214
270
  var WRONGSTACK_AUTH_METHODS = [
215
271
  {
216
272
  id: "wrongstack-auth",
@@ -221,6 +277,7 @@ var WRONGSTACK_AUTH_METHODS = [
221
277
  }
222
278
  ];
223
279
  var DEFAULT_MODE_ID = "code";
280
+ var DEFAULT_MAX_SESSIONS = 64;
224
281
  var DEFAULT_MODES = [
225
282
  {
226
283
  id: DEFAULT_MODE_ID,
@@ -238,6 +295,8 @@ var ACPProtocolHandler = class {
238
295
  agentName;
239
296
  replayFor;
240
297
  seedFor;
298
+ disposeFor;
299
+ maxSessions;
241
300
  store;
242
301
  initialized = false;
243
302
  clientCapabilities = {};
@@ -258,6 +317,8 @@ var ACPProtocolHandler = class {
258
317
  this.agentName = opts.agentName ?? "wrongstack";
259
318
  this.replayFor = opts.replayFor;
260
319
  this.seedFor = opts.seedFor;
320
+ this.disposeFor = opts.disposeFor;
321
+ this.maxSessions = Number.isFinite(opts.maxSessions) && opts.maxSessions > 0 ? Math.floor(opts.maxSessions) : DEFAULT_MAX_SESSIONS;
261
322
  this.store = opts.store;
262
323
  if (typeof this.transport.onMessage === "function") {
263
324
  this.transport.onMessage((m) => this.maybeResolvePending(m));
@@ -315,8 +376,9 @@ var ACPProtocolHandler = class {
315
376
  }
316
377
  /** Abort all active turns and drop session state. */
317
378
  close() {
318
- for (const [, session] of this.sessions) {
379
+ for (const [sessionId, session] of this.sessions) {
319
380
  session.abort.abort();
381
+ this.disposeSession(sessionId);
320
382
  }
321
383
  this.sessions.clear();
322
384
  for (const [, p] of this.pendingOut) {
@@ -325,6 +387,12 @@ var ACPProtocolHandler = class {
325
387
  }
326
388
  this.pendingOut.clear();
327
389
  }
390
+ disposeSession(sessionId) {
391
+ try {
392
+ this.disposeFor?.(sessionId);
393
+ } catch {
394
+ }
395
+ }
328
396
  // ────────────────────────────────────────────────────────────────────
329
397
  // Requests
330
398
  // ────────────────────────────────────────────────────────────────────
@@ -444,6 +512,10 @@ var ACPProtocolHandler = class {
444
512
  return false;
445
513
  }
446
514
  async handleSessionNew(id, params) {
515
+ if (this.sessions.size >= this.maxSessions) {
516
+ await this.sendError(id, -32e3, `active session limit reached (${this.maxSessions})`);
517
+ return false;
518
+ }
447
519
  const p = params ?? {};
448
520
  const cwd = typeof p.cwd === "string" ? p.cwd : this.defaultCwd;
449
521
  const sessionId = `sess_${this.allocId()}`;
@@ -494,6 +566,10 @@ var ACPProtocolHandler = class {
494
566
  if (!existing && sessionId && this.store) {
495
567
  const persisted = await this.store.load(sessionId);
496
568
  if (persisted) {
569
+ if (this.sessions.size >= this.maxSessions) {
570
+ await this.sendError(id, -32e3, `active session limit reached (${this.maxSessions})`);
571
+ return false;
572
+ }
497
573
  const restored = {
498
574
  id: sessionId,
499
575
  cwd: persisted.cwd ?? loadCwd ?? this.defaultCwd,
@@ -524,7 +600,7 @@ var ACPProtocolHandler = class {
524
600
  }
525
601
  if (existing) {
526
602
  existing.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
527
- const replay = sessionId ? this.replayFor?.(sessionId) : void 0;
603
+ const replay = this.replayFor?.(sessionId);
528
604
  if (replay) {
529
605
  for (const update of replay) {
530
606
  await this.sendNotification({ sessionId, update });
@@ -589,7 +665,8 @@ var ACPProtocolHandler = class {
589
665
  return false;
590
666
  }
591
667
  session.abort.abort();
592
- if (sessionId) this.sessions.delete(sessionId);
668
+ this.sessions.delete(sessionId);
669
+ this.disposeSession(sessionId);
593
670
  await this.transport.send(toWire({
594
671
  jsonrpc: "2.0",
595
672
  id,
@@ -611,6 +688,7 @@ var ACPProtocolHandler = class {
611
688
  const session = this.sessions.get(sessionId);
612
689
  session.abort.abort();
613
690
  this.sessions.delete(sessionId);
691
+ this.disposeSession(sessionId);
614
692
  await this.transport.send(toWire({
615
693
  jsonrpc: "2.0",
616
694
  id,
@@ -626,6 +704,10 @@ var ACPProtocolHandler = class {
626
704
  await this.sendError(id, -32e3, `session not found: ${sourceId}`);
627
705
  return false;
628
706
  }
707
+ if (this.sessions.size >= this.maxSessions) {
708
+ await this.sendError(id, -32e3, `active session limit reached (${this.maxSessions})`);
709
+ return false;
710
+ }
629
711
  const now = (/* @__PURE__ */ new Date()).toISOString();
630
712
  const sessionId = `sess_${this.allocId()}`;
631
713
  const forked = {
@@ -919,8 +1001,10 @@ var ACPSessionStore = class {
919
1001
  */
920
1002
  async save(state, history) {
921
1003
  await this.init();
1004
+ const target = path.join(this.dir, `${state.id}.json`);
1005
+ const tmp = `${target}.${process.pid}.${Date.now()}.tmp`;
922
1006
  await fsp.writeFile(
923
- path.join(this.dir, `${state.id}.json`),
1007
+ tmp,
924
1008
  JSON.stringify({
925
1009
  id: state.id,
926
1010
  cwd: state.cwd,
@@ -932,6 +1016,7 @@ var ACPSessionStore = class {
932
1016
  }),
933
1017
  "utf8"
934
1018
  );
1019
+ await fsp.rename(tmp, target);
935
1020
  await this.updateIndex(state.id, state.updatedAt);
936
1021
  return state.id;
937
1022
  }
@@ -1092,9 +1177,9 @@ var WsBridgeTransport = class {
1092
1177
  };
1093
1178
 
1094
1179
  // src/agent/wrongstack-acp-agent.ts
1095
- import { fileURLToPath } from "node:url";
1096
1180
  import { createServer } from "node:http";
1097
- import { writeErr as writeErr2 } from "@wrongstack/core";
1181
+ import { fileURLToPath } from "node:url";
1182
+ import { writeErr as writeErr2 } from "@wrongstack/core/utils";
1098
1183
  var WrongStackACPServer = class {
1099
1184
  transport;
1100
1185
  handler;
@@ -1113,6 +1198,7 @@ var WrongStackACPServer = class {
1113
1198
  agentName: opts.agentName,
1114
1199
  ...opts.replayFor ? { replayFor: opts.replayFor } : {},
1115
1200
  ...opts.seedFor ? { seedFor: opts.seedFor } : {},
1201
+ ...opts.disposeFor ? { disposeFor: opts.disposeFor } : {},
1116
1202
  ...opts.store ? { store: opts.store } : {}
1117
1203
  });
1118
1204
  }
@@ -1134,13 +1220,17 @@ var WrongStackACPServer = class {
1134
1220
  this.transport.sendStartupMarker();
1135
1221
  }
1136
1222
  this.running = true;
1137
- while (this.running) {
1138
- const msg = await this.transport.read();
1139
- if (!msg) break;
1140
- const terminal = await this.handler.handleMessage(msg);
1141
- if (terminal) break;
1223
+ try {
1224
+ while (this.running) {
1225
+ const msg = await this.transport.read();
1226
+ if (!msg) break;
1227
+ const terminal = await this.handler.handleMessage(msg);
1228
+ if (terminal) break;
1229
+ }
1230
+ } finally {
1231
+ this.handler.close();
1232
+ this.transport.close();
1142
1233
  }
1143
- this.transport.close();
1144
1234
  }
1145
1235
  async startHttp(port) {
1146
1236
  const host = this.options.host ?? "127.0.0.1";
@@ -1149,10 +1239,9 @@ var WrongStackACPServer = class {
1149
1239
  let httpChain = Promise.resolve();
1150
1240
  this.httpServer = createServer(async (req, res) => {
1151
1241
  if (authToken) {
1152
- const url = new URL(req.url ?? "/", `http://${host}:${port}`);
1242
+ const url = new URL(requestPath(req.url), `http://${host}:${port}`);
1153
1243
  const queryToken = url.searchParams.get("token");
1154
- const authHeader = req.headers["authorization"];
1155
- const bearerToken = Array.isArray(authHeader) ? authHeader[0]?.replace(/^Bearer\s+/i, "") : authHeader?.replace(/^Bearer\s+/i, "");
1244
+ const bearerToken = headerValue(req.headers.authorization)?.replace(/^Bearer\s+/i, "");
1156
1245
  const supplied = queryToken ?? bearerToken ?? "";
1157
1246
  if (supplied !== authToken) {
1158
1247
  res.writeHead(401, { "Content-Type": "application/json" });
@@ -1161,7 +1250,7 @@ var WrongStackACPServer = class {
1161
1250
  }
1162
1251
  }
1163
1252
  const selfOrigin = `http://${host}:${port}`;
1164
- const reqOrigin = Array.isArray(req.headers.origin) ? req.headers.origin[0] : req.headers.origin;
1253
+ const reqOrigin = headerValue(req.headers.origin);
1165
1254
  if (reqOrigin && reqOrigin !== selfOrigin) {
1166
1255
  res.writeHead(403);
1167
1256
  res.end(JSON.stringify({ error: "cross-origin request forbidden" }));
@@ -1241,6 +1330,8 @@ var WrongStackACPServer = class {
1241
1330
  try {
1242
1331
  await requestPromise;
1243
1332
  } catch {
1333
+ res.writeHead(500, { "Content-Type": "application/json" });
1334
+ res.end(JSON.stringify({ error: { code: -32603, message: "Internal error" } }));
1244
1335
  }
1245
1336
  });
1246
1337
  return new Promise((resolve) => {
@@ -1255,6 +1346,7 @@ var WrongStackACPServer = class {
1255
1346
  /** Stop the server. */
1256
1347
  stop() {
1257
1348
  this.running = false;
1349
+ this.handler.close();
1258
1350
  this.transport.close();
1259
1351
  if (this.httpServer) {
1260
1352
  this.httpServer.close();
@@ -1265,6 +1357,12 @@ var WrongStackACPServer = class {
1265
1357
  var defaultEchoRunTurn = async (_input, _emit) => {
1266
1358
  return { stopReason: "end_turn" };
1267
1359
  };
1360
+ function headerValue(value) {
1361
+ return Array.isArray(value) ? value[0] : value;
1362
+ }
1363
+ function requestPath(value) {
1364
+ return value ?? "/";
1365
+ }
1268
1366
  async function main() {
1269
1367
  const server = new WrongStackACPServer();
1270
1368
  await server.start();
@@ -1283,8 +1381,11 @@ function makeACPServerAgentTurn(opts) {
1283
1381
  const agents = /* @__PURE__ */ new Map();
1284
1382
  const timeouts = /* @__PURE__ */ new Map();
1285
1383
  const history = /* @__PURE__ */ new Map();
1384
+ const historyBytes = /* @__PURE__ */ new Map();
1286
1385
  const pendingSeed = /* @__PURE__ */ new Set();
1287
1386
  const timeoutMs = opts.timeoutMs ?? 5 * 6e4;
1387
+ const maxHistoryEntries = finitePositiveLimit(opts.maxHistoryEntries, 1e3);
1388
+ const maxHistoryBytes = finitePositiveLimit(opts.maxHistoryBytes, 8 * 1024 * 1024);
1288
1389
  const turn = async (input, emit, api) => {
1289
1390
  let agent = agents.get(input.sessionId);
1290
1391
  if (!agent) {
@@ -1292,7 +1393,7 @@ function makeACPServerAgentTurn(opts) {
1292
1393
  agents.set(input.sessionId, agent);
1293
1394
  if (pendingSeed.has(input.sessionId)) {
1294
1395
  pendingSeed.delete(input.sessionId);
1295
- seedAgentContext(agent, history.get(input.sessionId) ?? []);
1396
+ seedAgentContext(agent, history.get(input.sessionId));
1296
1397
  }
1297
1398
  }
1298
1399
  const turnAbort = new AbortController();
@@ -1348,13 +1449,36 @@ function makeACPServerAgentTurn(opts) {
1348
1449
  }
1349
1450
  const userText = promptToText(input.prompt);
1350
1451
  const hist = history.get(input.sessionId) ?? [];
1452
+ let retainedHistoryBytes = historyBytes.get(input.sessionId) ?? 0;
1351
1453
  if (userText) {
1352
- hist.push({ sessionUpdate: "user_message_chunk", content: { type: "text", text: userText } });
1454
+ const update = {
1455
+ sessionUpdate: "user_message_chunk",
1456
+ content: { type: "text", text: userText }
1457
+ };
1458
+ hist.push(update);
1459
+ retainedHistoryBytes += replayEntryBytes(update);
1353
1460
  }
1354
1461
  if (text) {
1355
- hist.push({ sessionUpdate: "agent_message_chunk", content: { type: "text", text } });
1462
+ const update = {
1463
+ sessionUpdate: "agent_message_chunk",
1464
+ content: { type: "text", text }
1465
+ };
1466
+ hist.push(update);
1467
+ retainedHistoryBytes += replayEntryBytes(update);
1468
+ }
1469
+ retainedHistoryBytes = trimHistory(
1470
+ hist,
1471
+ retainedHistoryBytes,
1472
+ maxHistoryEntries,
1473
+ maxHistoryBytes
1474
+ );
1475
+ if (hist.length > 0) {
1476
+ history.set(input.sessionId, hist);
1477
+ historyBytes.set(input.sessionId, retainedHistoryBytes);
1478
+ } else {
1479
+ history.delete(input.sessionId);
1480
+ historyBytes.delete(input.sessionId);
1356
1481
  }
1357
- if (hist.length > 0) history.set(input.sessionId, hist);
1358
1482
  const plan = extractPlan(result);
1359
1483
  if (plan.length > 0) {
1360
1484
  emit({
@@ -1388,13 +1512,46 @@ function makeACPServerAgentTurn(opts) {
1388
1512
  for (const u of unsub) u();
1389
1513
  }
1390
1514
  };
1391
- const replay = (sessionId) => history.get(sessionId) ?? [];
1515
+ const replay = (sessionId) => [
1516
+ ...history.get(sessionId) ?? []
1517
+ ];
1392
1518
  const seed = (sessionId, incoming) => {
1393
1519
  if (incoming.length === 0) return;
1394
- history.set(sessionId, [...incoming]);
1520
+ const seeded = [...incoming];
1521
+ const retainedBytes = trimHistory(
1522
+ seeded,
1523
+ seeded.reduce((total, entry) => total + replayEntryBytes(entry), 0),
1524
+ maxHistoryEntries,
1525
+ maxHistoryBytes
1526
+ );
1527
+ history.set(sessionId, seeded);
1528
+ historyBytes.set(sessionId, retainedBytes);
1395
1529
  pendingSeed.add(sessionId);
1396
1530
  };
1397
- return Object.assign(turn, { replay, seed });
1531
+ const dispose = (sessionId) => {
1532
+ const timer = timeouts.get(sessionId);
1533
+ if (timer) clearTimeout(timer);
1534
+ timeouts.delete(sessionId);
1535
+ agents.delete(sessionId);
1536
+ history.delete(sessionId);
1537
+ historyBytes.delete(sessionId);
1538
+ pendingSeed.delete(sessionId);
1539
+ };
1540
+ return Object.assign(turn, { replay, seed, dispose });
1541
+ }
1542
+ function finitePositiveLimit(value, fallback) {
1543
+ return Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;
1544
+ }
1545
+ function trimHistory(entries, retainedBytes, maxEntries, maxBytes) {
1546
+ while (entries.length > maxEntries || retainedBytes > maxBytes) {
1547
+ const removed = entries.shift();
1548
+ if (!removed) break;
1549
+ retainedBytes -= replayEntryBytes(removed);
1550
+ }
1551
+ return Math.max(0, retainedBytes);
1552
+ }
1553
+ function replayEntryBytes(entry) {
1554
+ return Buffer.byteLength(JSON.stringify(entry), "utf8");
1398
1555
  }
1399
1556
  function seedAgentContext(agent, history) {
1400
1557
  const state = agent.ctx?.state;
@@ -1410,7 +1567,7 @@ function toolNameToKind(name) {
1410
1567
  const n = name.toLowerCase();
1411
1568
  if (n.includes("read") || n.includes("cat")) return "read";
1412
1569
  if (n.includes("write") || n.includes("edit") || n.includes("apply") || n.includes("patch")) return "edit";
1413
- if (n.includes("delete") || n.includes("rm")) return "delete";
1570
+ if (n.includes("delete") || n === "rm" || n.startsWith("rm_") || n.endsWith("_rm")) return "delete";
1414
1571
  if (n.includes("move") || n.includes("rename") || n.includes("mv")) return "move";
1415
1572
  if (n.includes("grep") || n.includes("glob") || n.includes("search") || n.includes("find")) return "search";
1416
1573
  if (n.includes("bash") || n.includes("shell") || n.includes("exec") || n.includes("run") || n.includes("terminal")) return "execute";