@wrongstack/acp 1.0.35 → 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.js CHANGED
@@ -1086,6 +1086,7 @@ ${b.resource.text}` : `[embedded resource: ${b.resource.uri}]`
1086
1086
  function extractText(result) {
1087
1087
  if (typeof result !== "object" || result === null) return "";
1088
1088
  const r = result;
1089
+ if (typeof r.finalText === "string") return r.finalText;
1089
1090
  if (typeof r.text === "string") return r.text;
1090
1091
  if (Array.isArray(r.content)) {
1091
1092
  const parts = [];
@@ -1103,6 +1104,7 @@ function pickStopReason(result, signal) {
1103
1104
  if (signal.aborted) return "cancelled";
1104
1105
  if (typeof result !== "object" || result === null) return "end_turn";
1105
1106
  const r = result;
1107
+ if (r.status === "max_iterations") return "max_turn_requests";
1106
1108
  if (r.error) {
1107
1109
  return "end_turn";
1108
1110
  }
@@ -1461,7 +1463,7 @@ function replayEntryBytes(entry) {
1461
1463
  // src/agent/session-store.ts
1462
1464
  import * as fsp2 from "node:fs/promises";
1463
1465
  import * as path2 from "node:path";
1464
- import { isSafePathSegment, resolveContainedPath } from "@wrongstack/core/utils";
1466
+ import { isSafePathSegment, resolveContainedPath, withFileLock } from "@wrongstack/core/utils";
1465
1467
  var RESERVED_SESSION_IDS = /* @__PURE__ */ new Set(["index"]);
1466
1468
  var ACPSessionStore = class {
1467
1469
  dir;
@@ -1635,7 +1637,8 @@ var ACPSessionStore = class {
1635
1637
  */
1636
1638
  withIndexLock(fn) {
1637
1639
  const prev = this.indexChain;
1638
- const next = prev.then(fn, fn);
1640
+ const locked = () => withFileLock(this.indexPath(), fn);
1641
+ const next = prev.then(locked, locked);
1639
1642
  const settled = next.then(
1640
1643
  () => void 0,
1641
1644
  () => void 0
@@ -1855,7 +1858,11 @@ var StdioTransport = class {
1855
1858
  return;
1856
1859
  }
1857
1860
  try {
1858
- this.dispatch(JSON.parse(raw), raw.length);
1861
+ const parsed = JSON.parse(raw);
1862
+ if (parsed === null || typeof parsed !== "object") {
1863
+ throw new Error("frame is not a JSON-RPC object");
1864
+ }
1865
+ this.dispatch(parsed, raw.length);
1859
1866
  } catch (err) {
1860
1867
  this.stderr.write(`[wstack-acp parse error] ${err}
1861
1868
  `, "utf8");
package/dist/client.js CHANGED
@@ -1158,7 +1158,9 @@ function isAbortLikeError(err) {
1158
1158
  }
1159
1159
  function resolvePermissionDeadline(value) {
1160
1160
  if (value === Number.POSITIVE_INFINITY) return null;
1161
- if (value !== void 0 && Number.isFinite(value) && value > 0) return Math.trunc(value);
1161
+ if (value !== void 0 && Number.isFinite(value) && value > 0) {
1162
+ return Math.min(Math.trunc(value), 2147483647);
1163
+ }
1162
1164
  return DEFAULT_PERMISSION_TIMEOUT_MS;
1163
1165
  }
1164
1166
 
@@ -1585,7 +1587,8 @@ function win32BatchTarget(command) {
1585
1587
  if (/\.(?:cmd|bat)$/i.test(command)) return command;
1586
1588
  if (/[\\/]/.test(command) || path2.extname(command)) return void 0;
1587
1589
  const exts = (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").toLowerCase().split(";");
1588
- for (const dir of (process.env["PATH"] ?? "").split(path2.delimiter)) {
1590
+ for (const rawDir of (process.env["PATH"] ?? "").split(path2.delimiter)) {
1591
+ const dir = rawDir.trim().replace(/^"|"$/g, "");
1589
1592
  if (!dir) continue;
1590
1593
  for (const ext of exts) {
1591
1594
  if (!ext) continue;
@@ -1849,15 +1852,13 @@ var TerminalServer = class {
1849
1852
  resolveCwd(cwd) {
1850
1853
  if (!cwd) return this.projectRoot;
1851
1854
  const resolved = path2.resolve(cwd);
1852
- const rootWithSep = this.projectRoot.endsWith(path2.sep) ? this.projectRoot : this.projectRoot + path2.sep;
1853
- if (resolved !== this.projectRoot && !resolved.startsWith(rootWithSep)) {
1855
+ if (!isInsideRoot(resolved, this.projectRoot)) {
1854
1856
  return this.projectRoot;
1855
1857
  }
1856
1858
  try {
1857
1859
  const realRoot = realpathSync2(this.projectRoot);
1858
1860
  const realCwd = realpathSync2(resolved);
1859
- const realRootWithSep = realRoot.endsWith(path2.sep) ? realRoot : realRoot + path2.sep;
1860
- if (realCwd !== realRoot && !realCwd.startsWith(realRootWithSep)) {
1861
+ if (!isInsideRoot(realCwd, realRoot)) {
1861
1862
  return realRoot;
1862
1863
  }
1863
1864
  return realCwd;
@@ -1889,6 +1890,12 @@ var TerminalServer = class {
1889
1890
  return Math.trunc(value);
1890
1891
  }
1891
1892
  };
1893
+ function isInsideRoot(child, root) {
1894
+ const fold = (p) => process.platform === "win32" ? p.toLowerCase() : p;
1895
+ const c = fold(child);
1896
+ const r = fold(root);
1897
+ return c === r || c.startsWith(r.endsWith(path2.sep) ? r : r + path2.sep);
1898
+ }
1892
1899
  var DENIED_AGENT_ENV_KEYS = /* @__PURE__ */ new Set([
1893
1900
  "NODE_OPTIONS",
1894
1901
  "LD_PRELOAD",
@@ -2152,6 +2159,7 @@ var WebSocketClientTransport = class {
2152
2159
  }
2153
2160
  dispatch(msg) {
2154
2161
  for (const handler of [...this.handlers]) {
2162
+ if (this.closed) break;
2155
2163
  try {
2156
2164
  handler(msg);
2157
2165
  } catch {
package/dist/index.js CHANGED
@@ -1135,7 +1135,11 @@ var StdioTransport = class {
1135
1135
  return;
1136
1136
  }
1137
1137
  try {
1138
- this.dispatch(JSON.parse(raw), raw.length);
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");
@@ -2705,7 +2709,9 @@ function isAbortLikeError(err) {
2705
2709
  }
2706
2710
  function resolvePermissionDeadline(value) {
2707
2711
  if (value === Number.POSITIVE_INFINITY) return null;
2708
- if (value !== void 0 && Number.isFinite(value) && value > 0) return Math.trunc(value);
2712
+ if (value !== void 0 && Number.isFinite(value) && value > 0) {
2713
+ return Math.min(Math.trunc(value), 2147483647);
2714
+ }
2709
2715
  return DEFAULT_PERMISSION_TIMEOUT_MS;
2710
2716
  }
2711
2717
 
@@ -3132,7 +3138,8 @@ function win32BatchTarget(command) {
3132
3138
  if (/\.(?:cmd|bat)$/i.test(command)) return command;
3133
3139
  if (/[\\/]/.test(command) || path3.extname(command)) return void 0;
3134
3140
  const exts = (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").toLowerCase().split(";");
3135
- for (const dir of (process.env["PATH"] ?? "").split(path3.delimiter)) {
3141
+ for (const rawDir of (process.env["PATH"] ?? "").split(path3.delimiter)) {
3142
+ const dir = rawDir.trim().replace(/^"|"$/g, "");
3136
3143
  if (!dir) continue;
3137
3144
  for (const ext of exts) {
3138
3145
  if (!ext) continue;
@@ -3396,15 +3403,13 @@ var TerminalServer = class {
3396
3403
  resolveCwd(cwd) {
3397
3404
  if (!cwd) return this.projectRoot;
3398
3405
  const resolved = path3.resolve(cwd);
3399
- const rootWithSep = this.projectRoot.endsWith(path3.sep) ? this.projectRoot : this.projectRoot + path3.sep;
3400
- if (resolved !== this.projectRoot && !resolved.startsWith(rootWithSep)) {
3406
+ if (!isInsideRoot(resolved, this.projectRoot)) {
3401
3407
  return this.projectRoot;
3402
3408
  }
3403
3409
  try {
3404
3410
  const realRoot = realpathSync2(this.projectRoot);
3405
3411
  const realCwd = realpathSync2(resolved);
3406
- const realRootWithSep = realRoot.endsWith(path3.sep) ? realRoot : realRoot + path3.sep;
3407
- if (realCwd !== realRoot && !realCwd.startsWith(realRootWithSep)) {
3412
+ if (!isInsideRoot(realCwd, realRoot)) {
3408
3413
  return realRoot;
3409
3414
  }
3410
3415
  return realCwd;
@@ -3436,6 +3441,12 @@ var TerminalServer = class {
3436
3441
  return Math.trunc(value);
3437
3442
  }
3438
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
+ }
3439
3450
  var DENIED_AGENT_ENV_KEYS = /* @__PURE__ */ new Set([
3440
3451
  "NODE_OPTIONS",
3441
3452
  "LD_PRELOAD",
@@ -3699,6 +3710,7 @@ var WebSocketClientTransport = class {
3699
3710
  }
3700
3711
  dispatch(msg) {
3701
3712
  for (const handler of [...this.handlers]) {
3713
+ if (this.closed) break;
3702
3714
  try {
3703
3715
  handler(msg);
3704
3716
  } catch {
@@ -1132,7 +1132,11 @@ var StdioTransport = class {
1132
1132
  return;
1133
1133
  }
1134
1134
  try {
1135
- this.dispatch(JSON.parse(raw), raw.length);
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.35",
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.35",
56
- "@wrongstack/primitives": "1.0.35"
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": "tsc --noEmit",
69
- "typecheck:tests": "tsc --noEmit -p tsconfig.test.json",
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"