@warlock.js/ai-workspace 5.29.0 → 5.31.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 (120) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +40 -21
  3. package/cjs/index.cjs +3295 -360
  4. package/cjs/index.cjs.map +1 -1
  5. package/esm/backends/local.d.mts +1 -1
  6. package/esm/backends/local.d.mts.map +1 -1
  7. package/esm/backends/local.mjs +199 -31
  8. package/esm/backends/local.mjs.map +1 -1
  9. package/esm/backends/mock.d.mts +12 -6
  10. package/esm/backends/mock.d.mts.map +1 -1
  11. package/esm/backends/mock.mjs +45 -3
  12. package/esm/backends/mock.mjs.map +1 -1
  13. package/esm/contracts/index.d.mts +3 -3
  14. package/esm/contracts/tool-io.type.d.mts +248 -11
  15. package/esm/contracts/tool-io.type.d.mts.map +1 -1
  16. package/esm/contracts/workspace-backend.contract.d.mts +78 -2
  17. package/esm/contracts/workspace-backend.contract.d.mts.map +1 -1
  18. package/esm/contracts/workspace-ops.contract.d.mts +41 -16
  19. package/esm/contracts/workspace-ops.contract.d.mts.map +1 -1
  20. package/esm/contracts/workspace-policy.type.d.mts +142 -14
  21. package/esm/contracts/workspace-policy.type.d.mts.map +1 -1
  22. package/esm/contracts/workspace.contract.d.mts +75 -22
  23. package/esm/contracts/workspace.contract.d.mts.map +1 -1
  24. package/esm/errors.d.mts +80 -6
  25. package/esm/errors.d.mts.map +1 -1
  26. package/esm/errors.mjs +23 -2
  27. package/esm/errors.mjs.map +1 -1
  28. package/esm/index.d.mts +13 -5
  29. package/esm/index.mjs +10 -2
  30. package/esm/ops.d.mts +22 -3
  31. package/esm/ops.d.mts.map +1 -1
  32. package/esm/ops.mjs +341 -82
  33. package/esm/ops.mjs.map +1 -1
  34. package/esm/policy/jail.mjs +73 -0
  35. package/esm/policy/jail.mjs.map +1 -0
  36. package/esm/policy/policy.d.mts +26 -16
  37. package/esm/policy/policy.d.mts.map +1 -1
  38. package/esm/policy/policy.mjs +62 -86
  39. package/esm/policy/policy.mjs.map +1 -1
  40. package/esm/policy/shell-check.d.mts +64 -0
  41. package/esm/policy/shell-check.d.mts.map +1 -0
  42. package/esm/policy/shell-check.mjs +627 -0
  43. package/esm/policy/shell-check.mjs.map +1 -0
  44. package/esm/policy/shell-parser.mjs +802 -0
  45. package/esm/policy/shell-parser.mjs.map +1 -0
  46. package/esm/policy/tokenize-command.d.mts +63 -0
  47. package/esm/policy/tokenize-command.d.mts.map +1 -0
  48. package/esm/policy/tokenize-command.mjs +76 -24
  49. package/esm/policy/tokenize-command.mjs.map +1 -1
  50. package/esm/shell-jobs.d.mts +45 -0
  51. package/esm/shell-jobs.d.mts.map +1 -0
  52. package/esm/shell-jobs.mjs +247 -0
  53. package/esm/shell-jobs.mjs.map +1 -0
  54. package/esm/todos.d.mts +22 -0
  55. package/esm/todos.d.mts.map +1 -0
  56. package/esm/todos.mjs +73 -0
  57. package/esm/todos.mjs.map +1 -0
  58. package/esm/tools/edit-file.d.mts +1 -1
  59. package/esm/tools/edit-file.d.mts.map +1 -1
  60. package/esm/tools/edit-file.mjs +3 -2
  61. package/esm/tools/edit-file.mjs.map +1 -1
  62. package/esm/tools/glob.d.mts +1 -1
  63. package/esm/tools/glob.d.mts.map +1 -1
  64. package/esm/tools/glob.mjs +3 -2
  65. package/esm/tools/glob.mjs.map +1 -1
  66. package/esm/tools/grep.d.mts +1 -1
  67. package/esm/tools/grep.d.mts.map +1 -1
  68. package/esm/tools/grep.mjs +3 -2
  69. package/esm/tools/grep.mjs.map +1 -1
  70. package/esm/tools/json-schemas.mjs +175 -0
  71. package/esm/tools/json-schemas.mjs.map +1 -0
  72. package/esm/tools/list-dir.d.mts +32 -0
  73. package/esm/tools/list-dir.d.mts.map +1 -0
  74. package/esm/tools/list-dir.mjs +50 -0
  75. package/esm/tools/list-dir.mjs.map +1 -0
  76. package/esm/tools/multi-edit.d.mts +38 -0
  77. package/esm/tools/multi-edit.d.mts.map +1 -0
  78. package/esm/tools/multi-edit.mjs +121 -0
  79. package/esm/tools/multi-edit.mjs.map +1 -0
  80. package/esm/tools/read-file.d.mts +5 -5
  81. package/esm/tools/read-file.d.mts.map +1 -1
  82. package/esm/tools/read-file.mjs +10 -20
  83. package/esm/tools/read-file.mjs.map +1 -1
  84. package/esm/tools/run-shell.d.mts +39 -13
  85. package/esm/tools/run-shell.d.mts.map +1 -1
  86. package/esm/tools/run-shell.mjs +60 -47
  87. package/esm/tools/run-shell.mjs.map +1 -1
  88. package/esm/tools/run-tests.d.mts +11 -2
  89. package/esm/tools/run-tests.d.mts.map +1 -1
  90. package/esm/tools/run-tests.mjs +15 -7
  91. package/esm/tools/run-tests.mjs.map +1 -1
  92. package/esm/tools/schema.mjs +24 -19
  93. package/esm/tools/schema.mjs.map +1 -1
  94. package/esm/tools/shell-kill.d.mts +25 -0
  95. package/esm/tools/shell-kill.d.mts.map +1 -0
  96. package/esm/tools/shell-kill.mjs +36 -0
  97. package/esm/tools/shell-kill.mjs.map +1 -0
  98. package/esm/tools/shell-output.d.mts +30 -0
  99. package/esm/tools/shell-output.d.mts.map +1 -0
  100. package/esm/tools/shell-output.mjs +49 -0
  101. package/esm/tools/shell-output.mjs.map +1 -0
  102. package/esm/tools/todo.d.mts +43 -0
  103. package/esm/tools/todo.d.mts.map +1 -0
  104. package/esm/tools/todo.mjs +126 -0
  105. package/esm/tools/todo.mjs.map +1 -0
  106. package/esm/tools/write-file.d.mts +1 -1
  107. package/esm/tools/write-file.d.mts.map +1 -1
  108. package/esm/tools/write-file.mjs +3 -2
  109. package/esm/tools/write-file.mjs.map +1 -1
  110. package/esm/workspace.d.mts +12 -9
  111. package/esm/workspace.d.mts.map +1 -1
  112. package/esm/workspace.mjs +109 -28
  113. package/esm/workspace.mjs.map +1 -1
  114. package/llms-full.txt +192 -35
  115. package/llms.txt +1 -1
  116. package/package.json +5 -4
  117. package/skills/README.md +2 -2
  118. package/skills/build-loop-agent/SKILL.md +7 -7
  119. package/skills/index.md +6 -1
  120. package/skills/use-a-workspace/SKILL.md +185 -28
@@ -1,6 +1,6 @@
1
- //#region ../ai-workspace/src/contracts/tool-io.type.d.ts
1
+ //#region ../../packages/ai-workspace/src/contracts/tool-io.type.d.ts
2
2
  /**
3
- * Input/output shapes for the seven workspace tools and the direct
3
+ * Input/output shapes for the workspace tools and the direct
4
4
  * methods that back them. These are the wire contracts the agent sees
5
5
  * (via each tool's schema) and the values the policy-enforced ops layer
6
6
  * returns. Paths in every `*Input` are workspace-relative; the policy
@@ -10,7 +10,7 @@
10
10
  * The discriminating set of tool names a workspace can vend, used by
11
11
  * `tools.pick(...)` to select a least-privilege subset.
12
12
  */
13
- type WorkspaceToolName = "readFile" | "editFile" | "writeFile" | "runShell" | "runTests" | "grep" | "glob";
13
+ type WorkspaceToolName = "readFile" | "editFile" | "multiEdit" | "writeFile" | "listDir" | "runShell" | "shellOutput" | "shellKill" | "runTests" | "grep" | "glob" | "todoWrite" | "todoRead";
14
14
  /** Input to the `read_file` tool / `readFile()` direct method. */
15
15
  interface ReadFileInput {
16
16
  /** Workspace-relative path to read. */
@@ -23,20 +23,42 @@ interface ReadFileInput {
23
23
  /**
24
24
  * Result of a read — the requested line window plus the metadata an
25
25
  * agent needs to read-before-edit (the `hash` feeds `editFile`'s
26
- * `expectHash` stale-guard).
26
+ * `expectHash` stale-guard). The `read_file` tool and the `readFile()`
27
+ * direct method return the same shape for the same arguments.
28
+ *
29
+ * `content` is `cat -n` numbered and is bounded by the policy's
30
+ * `read.maxBytes`, measured in UTF-8 bytes of `content` itself (line-number
31
+ * prefixes and newlines included). When the cap cuts the window, the last
32
+ * returned line may be partial — clipped on a character boundary, never
33
+ * mid-character — and `bytesCapped` is `true`.
27
34
  */
28
35
  interface ReadFileResult {
29
- /** The returned file content for the requested window. */
36
+ /** The returned, line-numbered file content for the requested window. */
30
37
  content: string;
31
- /** 1-based first line included in `content`. */
38
+ /** 1-based first line requested. */
32
39
  startLine: number;
33
- /** 1-based last line included in `content`. */
40
+ /**
41
+ * 1-based last line included in `content` (possibly partially, when
42
+ * `bytesCapped`). Below `startLine` when the window is empty.
43
+ */
34
44
  endLine: number;
35
45
  /** Total line count of the underlying file. */
36
46
  totalLines: number;
37
- /** True when the window stopped short of the file end (policy cap or `limit`). */
47
+ /**
48
+ * True when anything after `content` was withheld: lines past `endLine`
49
+ * (line `limit`, policy default window or byte cap) or the tail of
50
+ * `endLine` itself (byte cap).
51
+ */
38
52
  truncated: boolean;
39
- /** SHA-256 of the full file content at read time (stale-edit guard). */
53
+ /** True when `read.maxBytes` cut the window short. */
54
+ bytesCapped: boolean;
55
+ /** UTF-8 byte length of the full file. */
56
+ totalBytes: number;
57
+ /**
58
+ * SHA-256 of the **full** file content at read time — not of the returned
59
+ * window — so it stays valid as an `editFile` `expectHash` whatever window
60
+ * or byte cap was applied.
61
+ */
40
62
  hash: string;
41
63
  }
42
64
  /**
@@ -64,6 +86,40 @@ interface EditFileResult {
64
86
  /** SHA-256 of the file content after the edit. */
65
87
  hash: string;
66
88
  }
89
+ /** One replacement inside a {@link MultiEditInput}. */
90
+ interface MultiEditOperation {
91
+ /** Exact substring to replace; must be unique unless `replaceAll`. */
92
+ oldString: string;
93
+ /** Replacement text. */
94
+ newString: string;
95
+ /** Replace every occurrence instead of requiring a single unique match. */
96
+ replaceAll?: boolean;
97
+ }
98
+ /**
99
+ * Input to the `multi_edit` tool / `multiEdit()` direct method — several
100
+ * exact-string replacements in one file, applied in order (each edit sees
101
+ * the result of the previous ones) and written once. All of them apply or
102
+ * none do.
103
+ */
104
+ interface MultiEditInput {
105
+ /** Workspace-relative path to edit. */
106
+ path: string;
107
+ /** The replacements, applied in order. At least one. */
108
+ edits: MultiEditOperation[];
109
+ /** Expected current SHA-256 of the file; a mismatch rejects every edit as stale. */
110
+ expectHash?: string;
111
+ }
112
+ /** Result of a successful multi-edit. */
113
+ interface MultiEditResult {
114
+ /** Workspace-relative path that was edited. */
115
+ path: string;
116
+ /** Number of edits applied (always `edits.length`). */
117
+ edits: number;
118
+ /** Total occurrences replaced across every edit. */
119
+ replacements: number;
120
+ /** SHA-256 of the file content after all edits. */
121
+ hash: string;
122
+ }
67
123
  /** Input to the `write_file` tool / `writeFile()` direct method. */
68
124
  interface WriteFileInput {
69
125
  /** Workspace-relative path to write (created if absent). */
@@ -80,12 +136,117 @@ interface WriteFileResult {
80
136
  /** SHA-256 of the written content. */
81
137
  hash: string;
82
138
  }
139
+ /** Options for the `exec()` direct method. */
140
+ interface ExecOptions {
141
+ /** Per-call wall-clock cap in ms; overrides the policy `shell.timeoutMs`. */
142
+ timeoutMs?: number;
143
+ /**
144
+ * Cancels this one command. Already aborted: the command is not started.
145
+ * Aborted mid-run: its process tree is killed. Either way the result has
146
+ * `cancelled: true`. The tools pass the agent run's signal here.
147
+ */
148
+ signal?: AbortSignal;
149
+ }
83
150
  /** Input to the `run_shell` tool / `exec()` direct method. */
84
151
  interface RunShellInput {
85
- /** The command line to run; its leading basename is policy-checked. */
152
+ /** The command line to run; every command in it is policy-checked. */
86
153
  command: string;
87
154
  /** Per-call wall-clock cap (overrides the policy default if lower). */
88
155
  timeoutMs?: number;
156
+ /**
157
+ * Start the command as a background job and return its id at once,
158
+ * instead of waiting for it. Needs `shell.background` in the policy.
159
+ */
160
+ background?: boolean;
161
+ }
162
+ /**
163
+ * Lifecycle state of a background command.
164
+ *
165
+ * - `"running"` — still running.
166
+ * - `"exited"` — finished on its own; `exitCode` holds its exit code.
167
+ * - `"killed"` — stopped by `shell_kill` / `shellKill()` or `dispose()`.
168
+ * - `"timed-out"` — killed for exceeding `shell.background.timeoutMs` (or
169
+ * the per-call `timeoutMs`).
170
+ */
171
+ type ShellJobStatus = "running" | "exited" | "killed" | "timed-out";
172
+ /** A background command owned by the workspace. */
173
+ interface ShellJobInfo {
174
+ /** Workspace-unique id (`"job-1"`, `"job-2"`, …) for `shell_output` / `shell_kill`. */
175
+ id: string;
176
+ /** The command line it runs. */
177
+ command: string;
178
+ /** Lifecycle state. */
179
+ status: ShellJobStatus;
180
+ /** Exit code once it has stopped; `null` while running. */
181
+ exitCode: number | null;
182
+ /** OS process id of the direct child, when the backend has one. */
183
+ pid?: number;
184
+ /** ISO timestamp it was started. */
185
+ startedAt: string;
186
+ /** ISO timestamp it stopped, once it has. */
187
+ endedAt?: string;
188
+ }
189
+ /** What `run_shell` returns when called with `background: true`. */
190
+ interface RunShellBackgroundResult extends ShellJobInfo {
191
+ /** Always `true` — tells this result apart from a foreground {@link RunShellResult}. */
192
+ background: true;
193
+ }
194
+ /** Options for `startShell()`. */
195
+ interface StartShellOptions {
196
+ /**
197
+ * Wall-clock cap for this background command, in ms. Lowers
198
+ * `shell.background.timeoutMs` (never raises it); absent ⇒ the policy
199
+ * value, or no cap.
200
+ */
201
+ timeoutMs?: number;
202
+ }
203
+ /** Input to the `shell_output` tool. */
204
+ interface ShellOutputInput {
205
+ /** The background command id `run_shell` returned. */
206
+ id: string;
207
+ /**
208
+ * Return only output produced after this `cursor` (from an earlier
209
+ * result). Omit to get everything since the previous read.
210
+ */
211
+ since?: number;
212
+ /**
213
+ * Wait up to this many ms (capped at 30 000) for new output or for the
214
+ * command to stop, when there is nothing new yet.
215
+ */
216
+ waitMs?: number;
217
+ }
218
+ /** Options for `shellOutput()`. */
219
+ interface ShellOutputOptions {
220
+ /** See {@link ShellOutputInput.since}. */
221
+ since?: number;
222
+ /** See {@link ShellOutputInput.waitMs}. */
223
+ waitMs?: number;
224
+ /** Stops a `waitMs` wait early. */
225
+ signal?: AbortSignal;
226
+ }
227
+ /** New output of a background command plus its current state. */
228
+ interface ShellOutputResult extends ShellJobInfo {
229
+ /** Standard output produced after `since`. */
230
+ stdout: string;
231
+ /** Standard error produced after `since`. */
232
+ stderr: string;
233
+ /**
234
+ * Total bytes the command has produced so far (both streams). Pass it as
235
+ * `since` to read only what comes next.
236
+ */
237
+ cursor: number;
238
+ /**
239
+ * Bytes produced after `since` that are no longer kept (the per-command
240
+ * buffer holds the newest `shell.maxOutputBytes`).
241
+ */
242
+ droppedBytes: number;
243
+ /** True when `droppedBytes > 0`. */
244
+ truncated: boolean;
245
+ }
246
+ /** Input to the `shell_kill` tool. */
247
+ interface ShellKillInput {
248
+ /** The background command id to stop. */
249
+ id: string;
89
250
  }
90
251
  /** Result of a shell command — captured streams plus how it terminated. */
91
252
  interface RunShellResult {
@@ -99,6 +260,12 @@ interface RunShellResult {
99
260
  truncated: boolean;
100
261
  /** True when the command was SIGKILLed for exceeding its timeout. */
101
262
  timedOut: boolean;
263
+ /**
264
+ * True when the invocation's `signal` aborted: before start (nothing ran)
265
+ * or mid-run (the process tree was killed). Never true together with
266
+ * `timedOut`.
267
+ */
268
+ cancelled: boolean;
102
269
  }
103
270
  /**
104
271
  * Input to the `run_tests` tool. Convenience over `run_shell` that runs
@@ -134,6 +301,44 @@ interface GrepResult {
134
301
  /** Total number of matches (== `matches.length` unless capped). */
135
302
  total: number;
136
303
  }
304
+ /** Input to the `list_dir` tool. */
305
+ interface ListDirInput {
306
+ /** Workspace-relative directory to list. Default `"."` (the root). */
307
+ path?: string;
308
+ /** How many levels deep to list (1 = direct children). Default `1`. */
309
+ depth?: number;
310
+ /** Extra globs to leave out, on top of `list.ignore` and `denyPaths`. */
311
+ ignore?: string[];
312
+ }
313
+ /** Options for `listDir()`. */
314
+ interface ListDirOptions {
315
+ /** See {@link ListDirInput.depth}. */
316
+ depth?: number;
317
+ /** See {@link ListDirInput.ignore}. */
318
+ ignore?: string[];
319
+ }
320
+ /** Kind of a listed entry. A symlink is reported, never followed. */
321
+ type ListDirEntryType = "file" | "directory" | "symlink" | "other";
322
+ /** One entry of a directory listing. */
323
+ interface ListDirEntry {
324
+ /** Workspace-relative path (absolute for a directory outside `cwd` in `allowPaths`). */
325
+ path: string;
326
+ /** Entry kind. */
327
+ type: ListDirEntryType;
328
+ /** Size in bytes, for files (when the backend reports it). */
329
+ size?: number;
330
+ /** 1 for a direct child of the listed directory, 2 for a grandchild, … */
331
+ depth: number;
332
+ }
333
+ /** Result of a directory listing. */
334
+ interface ListDirResult {
335
+ /** The listed directory, workspace-relative (`"."` for the root). */
336
+ path: string;
337
+ /** Entries, breadth-first, each level sorted by name. */
338
+ entries: ListDirEntry[];
339
+ /** True when `list.maxEntries` cut the listing short. */
340
+ truncated: boolean;
341
+ }
137
342
  /** Input to the `glob` tool / `glob()` direct method. */
138
343
  interface GlobInput {
139
344
  /** Glob pattern resolved relative to `cwd` (e.g. `"src/api/*.ts"`). */
@@ -144,6 +349,38 @@ interface GlobResult {
144
349
  /** Workspace-relative paths matching the pattern, sorted. */
145
350
  paths: string[];
146
351
  }
352
+ /** State of one todo item. */
353
+ type WorkspaceTodoStatus = "pending" | "in_progress" | "completed";
354
+ /** One item of the workspace's todo list. */
355
+ interface WorkspaceTodo {
356
+ /** Stable id (assigned `"1"`, `"2"`, … when the writer omits it). */
357
+ id: string;
358
+ /** What the step is. */
359
+ content: string;
360
+ /** Its state. */
361
+ status: WorkspaceTodoStatus;
362
+ }
363
+ /** One item as written by `todo_write` / `writeTodos()` — `id` is optional. */
364
+ interface WorkspaceTodoInput {
365
+ /** Stable id; omit to have one assigned from the item's position. */
366
+ id?: string;
367
+ /** What the step is (non-empty, at most 1 000 characters). */
368
+ content: string;
369
+ /** Its state. */
370
+ status: WorkspaceTodoStatus;
371
+ }
372
+ /** Input to the `todo_write` tool — the whole new list, replacing the old one. */
373
+ interface TodoWriteInput {
374
+ /** The complete list (at most 100 items). An empty list clears it. */
375
+ todos: WorkspaceTodoInput[];
376
+ }
377
+ /** The todo list plus a count per status. */
378
+ interface TodoListResult {
379
+ /** Every item, in order. */
380
+ todos: WorkspaceTodo[];
381
+ /** How many items are in each status. */
382
+ counts: Record<WorkspaceTodoStatus, number>;
383
+ }
147
384
  //#endregion
148
- export { EditFileInput, EditFileResult, GlobInput, GlobResult, GrepInput, GrepMatch, GrepResult, ReadFileInput, ReadFileResult, RunShellInput, RunShellResult, RunTestsInput, WorkspaceToolName, WriteFileInput, WriteFileResult };
385
+ export { EditFileInput, EditFileResult, ExecOptions, GlobInput, GlobResult, GrepInput, GrepMatch, GrepResult, ListDirEntry, ListDirEntryType, ListDirInput, ListDirOptions, ListDirResult, MultiEditInput, MultiEditOperation, MultiEditResult, ReadFileInput, ReadFileResult, RunShellBackgroundResult, RunShellInput, RunShellResult, RunTestsInput, ShellJobInfo, ShellJobStatus, ShellKillInput, ShellOutputInput, ShellOutputOptions, ShellOutputResult, StartShellOptions, TodoListResult, TodoWriteInput, WorkspaceTodo, WorkspaceTodoInput, WorkspaceTodoStatus, WorkspaceToolName, WriteFileInput, WriteFileResult };
149
386
  //# sourceMappingURL=tool-io.type.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-io.type.d.mts","names":[],"sources":["../../../../../../../ai-workspace/src/contracts/tool-io.type.ts"],"mappings":";;AAYA;;;;AAA6B;AAU7B;;;;;KAVY,iBAAA;;UAUK,aAAA;EAMV;EAJL,IAAA;EAY6B;EAV7B,SAAA;EAU6B;EAR7B,KAAA;AAAA;;;;;;UAQe,cAAA;EAmBA;EAjBf,OAAA;;EAEA,SAAA;EAiBA;EAfA,OAAA;EAmBA;EAjBA,UAAA;EAqBA;EAnBA,SAAA;EAmBU;EAjBV,IAAA;AAAA;;;;;UAOe,aAAA;EAoBX;EAlBJ,IAAA;EAsBe;EApBf,SAAA;;EAEA,SAAA;EAsBO;EApBP,UAAA;EAwB8B;EAtB9B,UAAA;AAAA;;UAIe,cAAA;EAwBf;EAtBA,IAAA;EAsBI;EApBJ,YAAA;EAwB4B;EAtB5B,IAAA;AAAA;AA0BS;AAAA,UAtBM,cAAA;EA0Bc;EAxB7B,IAAA;EAwB6B;EAtB7B,OAAO;AAAA;;UAIQ,eAAA;EA4Bf;EA1BA,IAAA;EA0BQ;EAxBR,YAAA;EAgC4B;EA9B5B,IAAA;AAAA;AAgCO;AAAA,UA5BQ,aAAA;EAgCS;EA9BxB,OAAA;EA8BwB;EA5BxB,SAAS;AAAA;;UAIM,cAAA;EA8BL;EA5BV,QAAA;EAgCwB;EA9BxB,MAAA;EA8BwB;EA5BxB,MAAA;EAgCA;EA9BA,SAAA;EAgCI;EA9BJ,QAAA;AAAA;;;;;;UAQe,aAAA;EA8BV;EA5BL,OAAO;AAAA;;UAIQ,SAAA;EA8BR;EA5BP,OAAA;EAgCe;EA9Bf,IAAA;;EAEA,UAAA;AAAA;;UAIe,SAAA;;EAEf,IAAA;;EAEA,IAAA;;EAEA,IAAA;AAAA;;UAIe,UAAA;;EAEf,OAAA,EAAS,SAAS;;EAElB,KAAA;AAAA;;UAIe,SAAA;;EAEf,OAAO;AAAA;;UAIQ,UAAA;;EAEf,KAAK;AAAA"}
1
+ {"version":3,"file":"tool-io.type.d.mts","names":[],"sources":["../../../../../../../../packages/ai-workspace/src/contracts/tool-io.type.ts"],"mappings":"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"}
@@ -1,4 +1,6 @@
1
- //#region ../ai-workspace/src/contracts/workspace-backend.contract.d.ts
1
+ import { WorkspaceShellInterpreter } from "./workspace-policy.type.mjs";
2
+
3
+ //#region ../../packages/ai-workspace/src/contracts/workspace-backend.contract.d.ts
2
4
  /**
3
5
  * Low-level result of a backend command execution. Mirrors the shape the
4
6
  * policy-enforced ops layer surfaces as `RunShellResult`, minus the
@@ -14,6 +16,13 @@ interface WorkspaceBackendExecResult {
14
16
  stderr: string;
15
17
  /** True when the command was killed for exceeding its timeout. */
16
18
  timedOut: boolean;
19
+ /**
20
+ * True when the invocation's `signal` aborted — either before the
21
+ * command started (nothing was spawned) or while it ran (the process
22
+ * tree was killed). Mutually exclusive with `timedOut`. Optional so
23
+ * existing custom backends keep compiling; absent reads as `false`.
24
+ */
25
+ cancelled?: boolean;
17
26
  }
18
27
  /**
19
28
  * Options threaded into a backend `exec` call. The ops layer resolves
@@ -27,6 +36,61 @@ interface WorkspaceBackendExecOptions {
27
36
  timeoutMs?: number;
28
37
  /** Exact environment for the spawned process (NOT merged with process.env). */
29
38
  env?: Record<string, string>;
39
+ /**
40
+ * Per-invocation cancellation. A backend must not start the command when
41
+ * the signal is already aborted, must tear down the whole process tree
42
+ * when it aborts mid-run, must remove its abort listener once the command
43
+ * settles, and reports either case as `cancelled: true` (never a
44
+ * rejection). The signal belongs to ONE call — never cache it on the
45
+ * backend.
46
+ */
47
+ signal?: AbortSignal;
48
+ /**
49
+ * How to run `command`: `"none"` (default) tokenizes it into an argv and
50
+ * spawns it without a shell; `"sh"` hands the whole line to `/bin/sh -c`
51
+ * (`cmd.exe /d /v:off /s /c` on Windows). The ops layer has already
52
+ * checked every command in the line against the policy; a backend that
53
+ * does not support `"sh"` must refuse the command rather than run it
54
+ * another way.
55
+ */
56
+ interpreter?: WorkspaceShellInterpreter;
57
+ }
58
+ /** Which stream a background command's output chunk came from. */
59
+ type WorkspaceOutputStream = "stdout" | "stderr";
60
+ /** Options for {@link WorkspaceBackend.start}. */
61
+ interface WorkspaceBackendStartOptions {
62
+ /** Working directory for the spawned process (already jail-resolved). */
63
+ cwd?: string;
64
+ /** Exact environment for the spawned process (NOT merged with process.env). */
65
+ env?: Record<string, string>;
66
+ /** See {@link WorkspaceBackendExecOptions.interpreter}. */
67
+ interpreter?: WorkspaceShellInterpreter;
68
+ /**
69
+ * Receives output as it arrives, decoded as UTF-8 and never split inside a
70
+ * character. Called synchronously or later — never after `done` settles.
71
+ */
72
+ onOutput(stream: WorkspaceOutputStream, chunk: string): void;
73
+ }
74
+ /** A running background command, as a backend hands it to the ops layer. */
75
+ interface WorkspaceBackendProcess {
76
+ /** OS process id of the direct child, when there is one. */
77
+ readonly pid?: number;
78
+ /**
79
+ * Settles once the process has exited and its output has been delivered.
80
+ * Never rejects: a spawn failure resolves with exit code `127`.
81
+ */
82
+ readonly done: Promise<{
83
+ exitCode: number;
84
+ }>;
85
+ /** Kill the whole process tree. Idempotent; safe after it has exited. */
86
+ kill(): void;
87
+ }
88
+ /** What {@link WorkspaceBackend.stat} reports about a path (symlinks are not followed). */
89
+ interface WorkspaceBackendStat {
90
+ /** Entry kind. */
91
+ type: "file" | "directory" | "symlink" | "other";
92
+ /** Size in bytes. */
93
+ size: number;
30
94
  }
31
95
  /**
32
96
  * The swappable executor a workspace runs on — the thin, **policy-agnostic**
@@ -63,7 +127,19 @@ interface WorkspaceBackend {
63
127
  realpath(absPath: string): Promise<string>;
64
128
  /** Run a command and capture its outcome. */
65
129
  exec(command: string, opts?: WorkspaceBackendExecOptions): Promise<WorkspaceBackendExecResult>;
130
+ /**
131
+ * Describe an absolute path without following a final symlink. Optional:
132
+ * without it, `list_dir` tells files from directories by trying to list
133
+ * them and reports no sizes.
134
+ */
135
+ stat?(absPath: string): Promise<WorkspaceBackendStat>;
136
+ /**
137
+ * Start a long-running command and return at once. Optional: without it,
138
+ * background commands are refused. The process must be its own process
139
+ * group (or equivalent) so `kill()` reaches every descendant.
140
+ */
141
+ start?(command: string, opts: WorkspaceBackendStartOptions): WorkspaceBackendProcess;
66
142
  }
67
143
  //#endregion
68
- export { WorkspaceBackend, WorkspaceBackendExecOptions, WorkspaceBackendExecResult };
144
+ export { WorkspaceBackend, WorkspaceBackendExecOptions, WorkspaceBackendExecResult, WorkspaceBackendProcess, WorkspaceBackendStartOptions, WorkspaceBackendStat, WorkspaceOutputStream };
69
145
  //# sourceMappingURL=workspace-backend.contract.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-backend.contract.d.mts","names":[],"sources":["../../../../../../../ai-workspace/src/contracts/workspace-backend.contract.ts"],"mappings":";;AAMA;;;;;UAAiB,0BAAA;EAMf;EAJA,QAAA;EAMQ;EAJR,MAAA;EAYe;EAVf,MAAA;;EAEA,QAAA;AAAA;;;;;AAcY;UANG,2BAAA;EA2BgB;EAzB/B,GAAA;EA2B2B;EAzB3B,SAAA;EA6ByB;EA3BzB,GAAA,GAAM,MAAM;AAAA;;;;;;;;;;;;;;;;;;;UAqBG,gBAAA;EAQS;EANxB,QAAA,CAAS,OAAA,WAAkB,OAAA;EAQpB;EANP,SAAA,CAAU,OAAA,UAAiB,OAAA,WAAkB,OAAA;EAQ7C;EANA,MAAA,CAAO,OAAA,WAAkB,OAAA;EAMH;EAJtB,KAAA,CAAM,OAAA,WAAkB,OAAA;EAMf;EAJT,MAAA,CAAO,OAAA,WAAkB,OAAA;EAMzB;EAJA,IAAA,CAAK,MAAA,WAAiB,OAAA;EAMb;EAJT,QAAA,CAAS,OAAA,WAAkB,OAAA;EAKxB;EAHH,IAAA,CACE,OAAA,UACA,IAAA,GAAO,2BAAA,GACN,OAAA,CAAQ,0BAAA;AAAA"}
1
+ {"version":3,"file":"workspace-backend.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-workspace/src/contracts/workspace-backend.contract.ts"],"mappings":";;;;;AAQA;;;;UAAiB,0BAAA;EAIf;EAFA,QAAA;EAMA;EAJA,MAAA;EAWS;EATT,MAAA;EAiBe;EAff,QAAA;;;;;;;EAOA,SAAA;AAAA;;;;;;UAQe,2BAAA;EAwBwB;EAtBvC,GAAA;EA0BU;EAxBV,SAAA;;EAEA,GAAA,GAAM,MAAA;EAsByB;AAGjC;;;;;;;EAhBE,MAAA,GAAS,WAAA;EAkBT;;;;;;;;EATA,WAAA,GAAc,yBAAA;AAAA;AAkBuC;AAAA,KAd3C,qBAAA;;UAGK,4BAAA;EAsBO;EApBtB,GAAA;EAoBS;EAlBT,GAAA,GAAM,MAAA;EAkBmB;EAhBzB,WAAA,GAAc,yBAAA;EAkBV;AAAA;AAIN;;EAjBE,QAAA,CAAS,MAAA,EAAQ,qBAAA,EAAuB,KAAA;AAAA;AAqBpC;AAAA,UAjBW,uBAAA;EAsCgB;EAAA,SApCtB,GAAA;EAsCkB;;;;EAAA,SAjClB,IAAA,EAAM,OAAO;IAAG,QAAA;EAAA;EA+CI;EA7C7B,IAAA;AAAA;;UAIe,oBAAA;EAqDe;EAnD9B,IAAA;EAmDoF;EAjDpF,IAAI;AAAA;;;;;;;;;;;;;;;;;;;UAqBW,gBAAA;EAcN;EAZT,QAAA,CAAS,OAAA,WAAkB,OAAA;EAc3B;EAZA,SAAA,CAAU,OAAA,UAAiB,OAAA,WAAkB,OAAA;EAYhB;EAV7B,MAAA,CAAO,OAAA,WAAkB,OAAA;EAUkC;EAR3D,KAAA,CAAM,OAAA,WAAkB,OAAA;EAcxB;EAZA,MAAA,CAAO,OAAA,WAAkB,OAAA;EAYD;EAVxB,IAAA,CAAK,MAAA,WAAiB,OAAA;EAgBtB;EAdA,QAAA,CAAS,OAAA,WAAkB,OAAA;EAcG;EAZ9B,IAAA,CAAK,OAAA,UAAiB,IAAA,GAAO,2BAAA,GAA8B,OAAA,CAAQ,0BAAA;EAYN;;AAAuB;;;EANpF,IAAA,EAAM,OAAA,WAAkB,OAAA,CAAQ,oBAAA;;;;;;EAMhC,KAAA,EAAO,OAAA,UAAiB,IAAA,EAAM,4BAAA,GAA+B,uBAAA;AAAA"}
@@ -1,6 +1,6 @@
1
- import { EditFileInput, EditFileResult, GrepResult, RunShellResult } from "./tool-io.type.mjs";
1
+ import { EditFileInput, EditFileResult, ExecOptions, GrepResult, ListDirOptions, ListDirResult, MultiEditInput, MultiEditResult, ReadFileResult, RunShellResult, ShellJobInfo, ShellOutputOptions, ShellOutputResult, StartShellOptions } from "./tool-io.type.mjs";
2
2
 
3
- //#region ../ai-workspace/src/contracts/workspace-ops.contract.d.ts
3
+ //#region ../../packages/ai-workspace/src/contracts/workspace-ops.contract.d.ts
4
4
  /**
5
5
  * The **policy-enforced** operation layer that sits between the dumb
6
6
  * {@link WorkspaceBackend} and the two public callers — the agent-facing
@@ -22,18 +22,15 @@ import { EditFileInput, EditFileResult, GrepResult, RunShellResult } from "./too
22
22
  */
23
23
  interface WorkspaceOps {
24
24
  /**
25
- * Read a jailed file, returning its content, content hash, and total
26
- * line count. `offset`/`limit` select a 1-based line window; the
27
- * policy `read` caps still apply.
25
+ * Read a jailed file, returning a numbered line window, the full file's
26
+ * hash and the window metadata. `offset`/`limit` select a 1-based line
27
+ * window; `read.maxBytes` bounds the UTF-8 bytes of the returned
28
+ * `content` (see {@link ReadFileResult}).
28
29
  */
29
30
  readFile(path: string, opts?: {
30
31
  offset?: number;
31
32
  limit?: number;
32
- }): Promise<{
33
- content: string;
34
- hash: string;
35
- totalLines: number;
36
- }>;
33
+ }): Promise<ReadFileResult>;
37
34
  /** Atomically write full content to a jailed path, returning size + hash. */
38
35
  writeFile(path: string, content: string): Promise<{
39
36
  hash: string;
@@ -46,13 +43,35 @@ interface WorkspaceOps {
46
43
  */
47
44
  editFile(input: EditFileInput): Promise<EditFileResult>;
48
45
  /**
49
- * Run a shell command after gating its leading executable basename
50
- * against the shell allow/deny policy, with the policy environment,
51
- * timeout, and output byte cap applied.
46
+ * Apply several exact-string edits to one file atomically: each edit runs
47
+ * against the result of the previous ones, under the same uniqueness rules
48
+ * as `editFile`, and the file is written once — or, when any edit fails,
49
+ * not at all (`WorkspaceEditError` with `editIndex`).
50
+ */
51
+ multiEdit(input: MultiEditInput): Promise<MultiEditResult>;
52
+ /**
53
+ * Run a command line after checking every command in it against the
54
+ * shell policy (see `WorkspaceShellPolicy`), with the policy environment,
55
+ * timeout, and output byte cap applied. `signal` cancels this one call
56
+ * (see {@link ExecOptions}).
57
+ */
58
+ exec(command: string, opts?: ExecOptions): Promise<RunShellResult>;
59
+ /**
60
+ * Start a policy-checked command as a background job owned by the
61
+ * workspace and return at once. Needs `shell.background`.
62
+ */
63
+ startShell(command: string, opts?: StartShellOptions): Promise<ShellJobInfo>;
64
+ /** New output of a background command since `since` (default: the last read). */
65
+ shellOutput(id: string, opts?: ShellOutputOptions): Promise<ShellOutputResult>;
66
+ /** Kill a background command's whole process tree and report its final state. */
67
+ shellKill(id: string): Promise<ShellJobInfo>;
68
+ /** Every background command this workspace knows, oldest first. */
69
+ listShells(): ShellJobInfo[];
70
+ /**
71
+ * List a jailed directory — bounded by depth and `list.maxEntries`, with
72
+ * `denyPaths` and `list.ignore` left out and symlinks never followed.
52
73
  */
53
- exec(command: string, opts?: {
54
- timeoutMs?: number;
55
- }): Promise<RunShellResult>;
74
+ listDir(path?: string, opts?: ListDirOptions): Promise<ListDirResult>;
56
75
  /** Search jailed file contents for a regex pattern. */
57
76
  grep(pattern: string, opts?: {
58
77
  glob?: string;
@@ -66,6 +85,12 @@ interface WorkspaceOps {
66
85
  mkdir(path: string): Promise<void>;
67
86
  /** Remove a file or directory tree at a jailed path. */
68
87
  remove(path: string): Promise<void>;
88
+ /**
89
+ * Kill every background command (whole process trees) and refuse new
90
+ * commands. A foreground command already running finishes on its own (or
91
+ * by its timeout / signal). Idempotent.
92
+ */
93
+ dispose(): Promise<void>;
69
94
  }
70
95
  //#endregion
71
96
  export { WorkspaceOps };
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-ops.contract.d.mts","names":[],"sources":["../../../../../../../ai-workspace/src/contracts/workspace-ops.contract.ts"],"mappings":";;;;;AA0BA;;;;;;;;;;;;;;;;;UAAiB,YAAA;EAMf;;;;;EAAA,QAAA,CACE,IAAA,UACA,IAAA;IAAS,MAAA;IAAiB,KAAA;EAAA,IACzB,OAAA;IAAU,OAAA;IAAiB,IAAA;IAAc,UAAA;EAAA;EAM/B;EAHb,SAAA,CACE,IAAA,UACA,OAAA,WACC,OAAA;IAAU,IAAA;IAAc,YAAA;EAAA;EAOK;;;;;EAAhC,QAAA,CAAS,KAAA,EAAO,aAAA,GAAgB,OAAA,CAAQ,cAAA;EAUrC;;;;;EAHH,IAAA,CACE,OAAA,UACA,IAAA;IAAS,SAAA;EAAA,IACR,OAAA,CAAQ,cAAA;EAMA;EAHX,IAAA,CACE,OAAA,UACA,IAAA;IAAS,IAAA;IAAe,UAAA;EAAA,IACvB,OAAA,CAAQ,UAAA;EAMJ;EAHP,IAAA,CAAK,OAAA,WAAkB,OAAA;EAMvB;EAHA,MAAA,CAAO,IAAA,WAAe,OAAA;EAGD;EAArB,KAAA,CAAM,IAAA,WAAe,OAAA;EAGd;EAAP,MAAA,CAAO,IAAA,WAAe,OAAA;AAAA"}
1
+ {"version":3,"file":"workspace-ops.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-workspace/src/contracts/workspace-ops.contract.ts"],"mappings":";;;;;AAoCA;;;;;;;;;;;;;;;;;UAAiB,YAAA;EA0CgB;;;;;;EAnC/B,QAAA,CAAS,IAAA,UAAc,IAAA;IAAS,MAAA;IAAiB,KAAA;EAAA,IAAmB,OAAA,CAAQ,cAAA;EAkDL;EA/CvE,SAAA,CAAU,IAAA,UAAc,OAAA,WAAkB,OAAA;IAAU,IAAA;IAAc,YAAA;EAAA;EAkEvD;;;;;EA3DX,QAAA,CAAS,KAAA,EAAO,aAAA,GAAgB,OAAA,CAAQ,cAAA;EAVS;;;;;;EAkBjD,SAAA,CAAU,KAAA,EAAO,cAAA,GAAiB,OAAA,CAAQ,eAAA;EAfA;;;;;;EAuB1C,IAAA,CAAK,OAAA,UAAiB,IAAA,GAAO,WAAA,GAAc,OAAA,CAAQ,cAAA;EAhBX;;;;EAsBxC,UAAA,CAAW,OAAA,UAAiB,IAAA,GAAO,iBAAA,GAAoB,OAAA,CAAQ,YAAA;EAdrB;EAiB1C,WAAA,CAAY,EAAA,UAAY,IAAA,GAAO,kBAAA,GAAqB,OAAA,CAAQ,iBAAA;EATvD;EAYL,SAAA,CAAU,EAAA,WAAa,OAAA,CAAQ,YAAA;EAZT;EAetB,UAAA,IAAc,YAAA;EAfqC;;;;EAqBnD,OAAA,CAAQ,IAAA,WAAe,IAAA,GAAO,cAAA,GAAiB,OAAA,CAAQ,aAAA;EAfA;EAkBvD,IAAA,CAAK,OAAA,UAAiB,IAAA;IAAS,IAAA;IAAe,UAAA;EAAA,IAAyB,OAAA,CAAQ,UAAA;EAfvD;EAkBxB,IAAA,CAAK,OAAA,WAAkB,OAAA;EAlBqC;EAqB5D,MAAA,CAAO,IAAA,WAAe,OAAA;EAlBZ;EAqBV,KAAA,CAAM,IAAA,WAAe,OAAA;EArBU;EAwB/B,MAAA,CAAO,IAAA,WAAe,OAAA;EArBR;;;;;EA4Bd,OAAA,IAAW,OAAA;AAAA"}