@warlock.js/ai-workspace 5.31.0 → 5.32.0

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 (74) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/cjs/index.cjs +34 -22
  3. package/cjs/index.cjs.map +1 -1
  4. package/esm/backends/local.d.mts +1 -3
  5. package/esm/backends/local.d.mts.map +1 -1
  6. package/esm/backends/local.mjs +1 -1
  7. package/esm/backends/local.mjs.map +1 -1
  8. package/esm/backends/mock.d.mts +5 -6
  9. package/esm/backends/mock.d.mts.map +1 -1
  10. package/esm/contracts/index.d.mts +2 -1
  11. package/esm/contracts/tool-io.type.d.mts +37 -38
  12. package/esm/contracts/tool-io.type.d.mts.map +1 -1
  13. package/esm/contracts/workspace-backend.contract.d.mts +7 -9
  14. package/esm/contracts/workspace-backend.contract.d.mts.map +1 -1
  15. package/esm/contracts/workspace-ops.contract.d.mts +1 -3
  16. package/esm/contracts/workspace-ops.contract.d.mts.map +1 -1
  17. package/esm/contracts/workspace-policy.type.d.mts +10 -11
  18. package/esm/contracts/workspace-policy.type.d.mts.map +1 -1
  19. package/esm/contracts/workspace.contract.d.mts +2 -4
  20. package/esm/contracts/workspace.contract.d.mts.map +1 -1
  21. package/esm/errors.d.mts +35 -23
  22. package/esm/errors.d.mts.map +1 -1
  23. package/esm/index.d.mts +1 -0
  24. package/esm/ops.d.mts +3 -4
  25. package/esm/ops.d.mts.map +1 -1
  26. package/esm/policy/policy.d.mts +5 -5
  27. package/esm/policy/policy.d.mts.map +1 -1
  28. package/esm/policy/policy.mjs +4 -3
  29. package/esm/policy/policy.mjs.map +1 -1
  30. package/esm/policy/shell-check.d.mts +5 -6
  31. package/esm/policy/shell-check.d.mts.map +1 -1
  32. package/esm/policy/shell-check.mjs +24 -13
  33. package/esm/policy/shell-check.mjs.map +1 -1
  34. package/esm/policy/shell-parser.mjs +2 -2
  35. package/esm/policy/shell-parser.mjs.map +1 -1
  36. package/esm/policy/tokenize-command.d.mts +3 -4
  37. package/esm/policy/tokenize-command.d.mts.map +1 -1
  38. package/esm/policy/tokenize-command.mjs +2 -2
  39. package/esm/policy/tokenize-command.mjs.map +1 -1
  40. package/esm/shell-jobs.d.mts +3 -3
  41. package/esm/shell-jobs.d.mts.map +1 -1
  42. package/esm/shell-jobs.mjs +1 -1
  43. package/esm/todos.d.mts +2 -2
  44. package/esm/todos.d.mts.map +1 -1
  45. package/esm/todos.mjs +1 -1
  46. package/esm/tools/edit-file.d.mts +2 -3
  47. package/esm/tools/edit-file.d.mts.map +1 -1
  48. package/esm/tools/glob.d.mts +3 -4
  49. package/esm/tools/glob.d.mts.map +1 -1
  50. package/esm/tools/grep.d.mts +3 -4
  51. package/esm/tools/grep.d.mts.map +1 -1
  52. package/esm/tools/list-dir.d.mts +2 -3
  53. package/esm/tools/list-dir.d.mts.map +1 -1
  54. package/esm/tools/multi-edit.d.mts +2 -3
  55. package/esm/tools/multi-edit.d.mts.map +1 -1
  56. package/esm/tools/read-file.d.mts +2 -3
  57. package/esm/tools/read-file.d.mts.map +1 -1
  58. package/esm/tools/run-shell.d.mts +5 -6
  59. package/esm/tools/run-shell.d.mts.map +1 -1
  60. package/esm/tools/run-tests.d.mts +3 -4
  61. package/esm/tools/run-tests.d.mts.map +1 -1
  62. package/esm/tools/shell-kill.d.mts +2 -3
  63. package/esm/tools/shell-kill.d.mts.map +1 -1
  64. package/esm/tools/shell-output.d.mts +2 -3
  65. package/esm/tools/shell-output.d.mts.map +1 -1
  66. package/esm/tools/todo.d.mts +3 -4
  67. package/esm/tools/todo.d.mts.map +1 -1
  68. package/esm/tools/write-file.d.mts +2 -3
  69. package/esm/tools/write-file.d.mts.map +1 -1
  70. package/esm/workspace.d.mts +3 -3
  71. package/esm/workspace.d.mts.map +1 -1
  72. package/esm/workspace.mjs +1 -1
  73. package/esm/workspace.mjs.map +1 -1
  74. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to `@warlock.js/ai-workspace` are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
6
 
7
+ ## 5.32.0 - 2026-10-18
8
+
9
+ ### Changed
10
+
11
+ - Pin the package development compiler to TypeScript 7.0.2 and use explicit Node types and source roots with supported module resolution.
12
+
7
13
  ## 5.31.0 - 2026-10-18
8
14
 
9
15
  ### Upgrading
package/cjs/index.cjs CHANGED
@@ -20,7 +20,7 @@ var __copyProps = (to, from, except, desc) => {
20
20
  }
21
21
  return to;
22
22
  };
23
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
24
24
  value: mod,
25
25
  enumerable: true
26
26
  }) : target, mod));
@@ -188,7 +188,7 @@ const MAX_NESTING = 16;
188
188
  * appear unquoted in command position. The parser does not read compound
189
189
  * commands, so a line using one is refused.
190
190
  */
191
- const RESERVED_WORDS = new Set([
191
+ const RESERVED_WORDS = /* @__PURE__ */ new Set([
192
192
  "!",
193
193
  "{",
194
194
  "}",
@@ -212,7 +212,7 @@ const RESERVED_WORDS = new Set([
212
212
  "while"
213
213
  ]);
214
214
  /** cmd.exe keywords the `"cmd"` dialect refuses in command position. */
215
- const CMD_RESERVED_WORDS = new Set([
215
+ const CMD_RESERVED_WORDS = /* @__PURE__ */ new Set([
216
216
  "if",
217
217
  "for",
218
218
  "goto",
@@ -990,7 +990,7 @@ function parseShellLine(line, dialect) {
990
990
  * rejected instead of silently running commands past the allowlist. Inside
991
991
  * quotes they are ordinary literal bytes and pass through as argument data.
992
992
  */
993
- const UNQUOTED_METACHARACTERS = new Set([
993
+ const UNQUOTED_METACHARACTERS = /* @__PURE__ */ new Set([
994
994
  ";",
995
995
  "&",
996
996
  "|",
@@ -1002,7 +1002,7 @@ const UNQUOTED_METACHARACTERS = new Set([
1002
1002
  ")"
1003
1003
  ]);
1004
1004
  /** Two-character operators reported as one token in a refusal. */
1005
- const TWO_CHARACTER_OPERATORS = new Set([
1005
+ const TWO_CHARACTER_OPERATORS = /* @__PURE__ */ new Set([
1006
1006
  "&&",
1007
1007
  "||",
1008
1008
  ">>",
@@ -1115,7 +1115,7 @@ function tokenizeCommand(command) {
1115
1115
  * With deny rules in force they would hide a denied command, so they are
1116
1116
  * refused unless the policy names them in `allow`.
1117
1117
  */
1118
- const OPAQUE_RUNNERS = new Set([
1118
+ const OPAQUE_RUNNERS = /* @__PURE__ */ new Set([
1119
1119
  "sh",
1120
1120
  "bash",
1121
1121
  "dash",
@@ -1159,7 +1159,7 @@ const OPAQUE_RUNNERS = new Set([
1159
1159
  "flock"
1160
1160
  ]);
1161
1161
  /** POSIX shell builtins that evaluate code or change how later names resolve. */
1162
- const SHELL_OPAQUE_BUILTINS = new Set([
1162
+ const SHELL_OPAQUE_BUILTINS = /* @__PURE__ */ new Set([
1163
1163
  "eval",
1164
1164
  ".",
1165
1165
  "source",
@@ -1183,7 +1183,7 @@ const SHELL_OPAQUE_BUILTINS = new Set([
1183
1183
  "readarray"
1184
1184
  ]);
1185
1185
  /** cmd.exe builtins that run commands or change the environment. */
1186
- const CMD_OPAQUE_BUILTINS = new Set([
1186
+ const CMD_OPAQUE_BUILTINS = /* @__PURE__ */ new Set([
1187
1187
  "call",
1188
1188
  "start",
1189
1189
  "set",
@@ -1195,7 +1195,7 @@ const CMD_OPAQUE_BUILTINS = new Set([
1195
1195
  * subscripts such as `a[$(cmd)]`): their arguments must be literal and free
1196
1196
  * of `[`.
1197
1197
  */
1198
- const ARITHMETIC_SENSITIVE_BUILTINS = new Set([
1198
+ const ARITHMETIC_SENSITIVE_BUILTINS = /* @__PURE__ */ new Set([
1199
1199
  "test",
1200
1200
  "[",
1201
1201
  "printf",
@@ -1219,7 +1219,7 @@ const ARITHMETIC_SENSITIVE_BUILTINS = new Set([
1219
1219
  * the jail's sight, `PS4` is expanded — command substitutions included —
1220
1220
  * on every traced line, `IFS` re-splits expansions).
1221
1221
  */
1222
- const SENSITIVE_VARIABLES = new Set([
1222
+ const SENSITIVE_VARIABLES = /* @__PURE__ */ new Set([
1223
1223
  "CDPATH",
1224
1224
  "ENV",
1225
1225
  "BASH_ENV",
@@ -1237,13 +1237,13 @@ const SENSITIVE_VARIABLES = new Set([
1237
1237
  "BASH_LOADABLES_PATH"
1238
1238
  ]);
1239
1239
  /** Redirection targets that are always fine even though they sit outside the jail. */
1240
- const DEVICE_TARGETS = new Set([
1240
+ const DEVICE_TARGETS = /* @__PURE__ */ new Set([
1241
1241
  "/dev/null",
1242
1242
  "/dev/stdout",
1243
1243
  "/dev/stderr"
1244
1244
  ]);
1245
1245
  /** cmd.exe's null device. */
1246
- const CMD_DEVICE_TARGETS = new Set(["nul"]);
1246
+ const CMD_DEVICE_TARGETS = /* @__PURE__ */ new Set(["nul"]);
1247
1247
  /** Deepest chain of wrappers (`env time nice …`) the policy unwraps. */
1248
1248
  const MAX_WRAPPER_DEPTH = 8;
1249
1249
  /** Most distinct directories a line may `cd` between. */
@@ -1342,7 +1342,8 @@ var LineChecker = class {
1342
1342
  verdict = false;
1343
1343
  }
1344
1344
  if (verdict === true) return;
1345
- throw new Refusal("not-allowed", `${shown} was refused by the workspace shell policy.${typeof verdict === "string" && verdict.trim() !== "" ? ` ${verdict.trim()}` : ""}`, executableBasename(argv[0] ?? "", this.dialect));
1345
+ const explanation = typeof verdict === "string" && verdict.trim() !== "" ? ` ${verdict.trim()}` : "";
1346
+ throw new Refusal("not-allowed", `${shown} was refused by the workspace shell policy.${explanation}`, executableBasename(argv[0] ?? "", this.dialect));
1346
1347
  }
1347
1348
  /** Whether the policy names `executable` in a non-empty `allow` list. */
1348
1349
  explicitlyAllowed(executable) {
@@ -1365,7 +1366,10 @@ var LineChecker = class {
1365
1366
  if (executable === "") throw new Refusal("not-allowed", "The command has no executable name.");
1366
1367
  if (dynamic[0] === true) throw new Refusal("unsupported-syntax", `The command name \`${first}\` is decided when the line runs, so the workspace shell policy cannot check it. Write the command name literally.`);
1367
1368
  if (this.deny.has(key)) throw new Refusal("denied-executable", `\`${executable}\` is denied by the workspace shell policy (in ${show(argv.join(" "))}).`, executable);
1368
- if (this.allow.length > 0 && !this.allow.includes(executable)) throw new Refusal("not-allowed", `\`${executable}\` is not in the workspace shell allowlist. Allowed commands: ${this.allow.slice(0, 20).join(", ")}${this.allow.length > 20 ? ", …" : ""}.`, executable);
1369
+ if (this.allow.length > 0 && !this.allow.includes(executable)) {
1370
+ const listed = this.allow.slice(0, 20).join(", ");
1371
+ throw new Refusal("not-allowed", `\`${executable}\` is not in the workspace shell allowlist. Allowed commands: ${listed}${this.allow.length > 20 ? ", …" : ""}.`, executable);
1372
+ }
1369
1373
  this.checkHooks(argv, depth > 0);
1370
1374
  this.commands.push([...argv]);
1371
1375
  if (OPAQUE_RUNNERS.has(key) || this.shellMode && this.dialect === "posix" && SHELL_OPAQUE_BUILTINS.has(key) || this.shellMode && this.dialect === "cmd" && CMD_OPAQUE_BUILTINS.has(key)) {
@@ -1609,16 +1613,23 @@ function argvModeRefusal(command) {
1609
1613
  const segments = parsed.ok ? parsed.segments : [];
1610
1614
  if ((token === "&&" || token === "||" || token === ";" || token === "\n") && segments.length >= 2) {
1611
1615
  const shownOperator = token === "\n" ? "A line break" : `\`${token}\``;
1612
- if ((segments[0]?.source ?? "").trim().split(/\s+/)[0] === "cd") return new Refusal("metacharacter", `${shownOperator} is not supported in argv mode, and \`cd\` does not carry over: every command starts in the workspace root. Run ${segments.slice(1).map((segment) => show(segment.source)).join(", then ")} on its own, with paths relative to the root.${suffix}`);
1616
+ if ((segments[0]?.source ?? "").trim().split(/\s+/)[0] === "cd") {
1617
+ const rest = segments.slice(1).map((segment) => show(segment.source));
1618
+ return new Refusal("metacharacter", `${shownOperator} is not supported in argv mode, and \`cd\` does not carry over: every command starts in the workspace root. Run ${rest.join(", then ")} on its own, with paths relative to the root.${suffix}`);
1619
+ }
1613
1620
  const steps = segments.map((segment) => show(segment.source));
1614
1621
  const joiner = token === "||" ? ", and if it fails, " : ", then ";
1615
1622
  return new Refusal("metacharacter", `${shownOperator} is not supported in argv mode: run ${steps.join(joiner)}, as separate commands.${suffix}`);
1616
1623
  }
1617
1624
  if (token === "&" && segments.length >= 1) {
1618
1625
  const steps = segments.map((segment) => show(segment.source));
1619
- return new Refusal("metacharacter", `\`&\` is not supported in argv mode: ${steps.length === 1 ? `run ${steps[0] ?? ""} without it` : `run ${steps.join(", then ")} as separate commands`}; start a long-running command with background: true.${suffix}`);
1626
+ const run = steps.length === 1 ? `run ${steps[0] ?? ""} without it` : `run ${steps.join(", then ")} as separate commands`;
1627
+ return new Refusal("metacharacter", `\`&\` is not supported in argv mode: ${run}; start a long-running command with background: true.${suffix}`);
1628
+ }
1629
+ if (token === "|") {
1630
+ const pipeline = command.split("|").map((part) => part.trim()).filter(Boolean);
1631
+ return new Refusal("metacharacter", `\`|\` (a pipe) is not supported in argv mode: run ${show(pipeline[0] ?? command)} on its own and read its output yourself.${suffix}`);
1620
1632
  }
1621
- if (token === "|") return new Refusal("metacharacter", `\`|\` (a pipe) is not supported in argv mode: run ${show(command.split("|").map((part) => part.trim()).filter(Boolean)[0] ?? command)} on its own and read its output yourself.${suffix}`);
1622
1633
  if (token === ">" || token === ">>" || token === ">&") return new Refusal("metacharacter", `\`${token}\` (redirection) is not supported in argv mode: run the command without it and save the output with write_file if you need it.${suffix}`);
1623
1634
  if (token === "<" || token === "<<" || token === "<&") return new Refusal("metacharacter", `\`${token}\` (input redirection) is not supported in argv mode: pass the file path to the command as an argument.${suffix}`);
1624
1635
  if (token === "$(" || token === "`") return new Refusal("metacharacter", `Command substitution (${token === "$(" ? "`$(…)`" : "backticks"}) is not supported in argv mode: run the inner command first, then pass its output literally.${suffix}`);
@@ -1785,8 +1796,9 @@ async function resolveInJail(policy, inputPath) {
1785
1796
  const insideCwd = isInside(absolutePath, jailRoot);
1786
1797
  const allowRoots = policy.allowPaths ?? [];
1787
1798
  let insideAllow = false;
1788
- if (!insideCwd) {
1789
- for (const root of allowRoots) if (isInside(absolutePath, await canonicalize$1(root))) {
1799
+ if (!insideCwd) for (const root of allowRoots) {
1800
+ const canonicalRoot = await canonicalize$1(root);
1801
+ if (isInside(absolutePath, canonicalRoot)) {
1790
1802
  insideAllow = true;
1791
1803
  break;
1792
1804
  }
@@ -1863,7 +1875,7 @@ function buildEnv(policy) {
1863
1875
  * `PS4` can run command substitutions, `BASH_FUNC_*` imports functions that
1864
1876
  * shadow commands, `CDPATH` moves `cd`, `IFS` re-splits words).
1865
1877
  */
1866
- const SHELL_STARTUP_VARIABLES = new Set([
1878
+ const SHELL_STARTUP_VARIABLES = /* @__PURE__ */ new Set([
1867
1879
  "ENV",
1868
1880
  "BASH_ENV",
1869
1881
  "SHELLOPTS",
@@ -2727,7 +2739,7 @@ function createOps(backend, policy, runtime) {
2727
2739
  * policy-driven cap (and the `truncated` flag) on top. Generous enough that
2728
2740
  * ordinary command output is never clipped here.
2729
2741
  */
2730
- const MAX_STREAM_BYTES = 10 * 1024 * 1024;
2742
+ const MAX_STREAM_BYTES = 10485760;
2731
2743
  /**
2732
2744
  * Append a chunk to a capped list of buffers, tracking the running byte
2733
2745
  * total and stopping once {@link MAX_STREAM_BYTES} is reached. Trailing bytes
@@ -4485,7 +4497,7 @@ const READONLY_TOOL_NAMES = [
4485
4497
  "todoRead"
4486
4498
  ];
4487
4499
  /** Tools vended only when the policy enables background commands. */
4488
- const BACKGROUND_TOOL_NAMES = new Set(["shellOutput", "shellKill"]);
4500
+ const BACKGROUND_TOOL_NAMES = /* @__PURE__ */ new Set(["shellOutput", "shellKill"]);
4489
4501
  /**
4490
4502
  * Choose the dumb IO executor for a policy. `"mock"` selects the
4491
4503
  * in-memory backend (hermetic tests); anything else — including the