@warlock.js/ai-workspace 5.30.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.
- package/CHANGELOG.md +52 -2
- package/README.md +34 -21
- package/cjs/index.cjs +3134 -315
- package/cjs/index.cjs.map +1 -1
- package/esm/backends/local.d.mts +1 -3
- package/esm/backends/local.d.mts.map +1 -1
- package/esm/backends/local.mjs +166 -28
- package/esm/backends/local.mjs.map +1 -1
- package/esm/backends/mock.d.mts +14 -9
- package/esm/backends/mock.d.mts.map +1 -1
- package/esm/backends/mock.mjs +34 -0
- package/esm/backends/mock.mjs.map +1 -1
- package/esm/contracts/index.d.mts +5 -4
- package/esm/contracts/tool-io.type.d.mts +216 -19
- package/esm/contracts/tool-io.type.d.mts.map +1 -1
- package/esm/contracts/workspace-backend.contract.d.mts +62 -4
- package/esm/contracts/workspace-backend.contract.d.mts.map +1 -1
- package/esm/contracts/workspace-ops.contract.d.mts +33 -6
- package/esm/contracts/workspace-ops.contract.d.mts.map +1 -1
- package/esm/contracts/workspace-policy.type.d.mts +136 -16
- package/esm/contracts/workspace-policy.type.d.mts.map +1 -1
- package/esm/contracts/workspace.contract.d.mts +65 -13
- package/esm/contracts/workspace.contract.d.mts.map +1 -1
- package/esm/errors.d.mts +103 -17
- package/esm/errors.d.mts.map +1 -1
- package/esm/errors.mjs +22 -1
- package/esm/errors.mjs.map +1 -1
- package/esm/index.d.mts +14 -5
- package/esm/index.mjs +10 -2
- package/esm/ops.d.mts +21 -3
- package/esm/ops.d.mts.map +1 -1
- package/esm/ops.mjs +230 -64
- package/esm/ops.mjs.map +1 -1
- package/esm/policy/jail.mjs +73 -0
- package/esm/policy/jail.mjs.map +1 -0
- package/esm/policy/policy.d.mts +30 -20
- package/esm/policy/policy.d.mts.map +1 -1
- package/esm/policy/policy.mjs +64 -87
- package/esm/policy/policy.mjs.map +1 -1
- package/esm/policy/shell-check.d.mts +63 -0
- package/esm/policy/shell-check.d.mts.map +1 -0
- package/esm/policy/shell-check.mjs +638 -0
- package/esm/policy/shell-check.mjs.map +1 -0
- package/esm/policy/shell-parser.mjs +802 -0
- package/esm/policy/shell-parser.mjs.map +1 -0
- package/esm/policy/tokenize-command.d.mts +62 -0
- package/esm/policy/tokenize-command.d.mts.map +1 -0
- package/esm/policy/tokenize-command.mjs +76 -24
- package/esm/policy/tokenize-command.mjs.map +1 -1
- package/esm/shell-jobs.d.mts +45 -0
- package/esm/shell-jobs.d.mts.map +1 -0
- package/esm/shell-jobs.mjs +247 -0
- package/esm/shell-jobs.mjs.map +1 -0
- package/esm/todos.d.mts +22 -0
- package/esm/todos.d.mts.map +1 -0
- package/esm/todos.mjs +73 -0
- package/esm/todos.mjs.map +1 -0
- package/esm/tools/edit-file.d.mts +2 -3
- package/esm/tools/edit-file.d.mts.map +1 -1
- package/esm/tools/edit-file.mjs +2 -1
- package/esm/tools/edit-file.mjs.map +1 -1
- package/esm/tools/glob.d.mts +3 -4
- package/esm/tools/glob.d.mts.map +1 -1
- package/esm/tools/glob.mjs +2 -1
- package/esm/tools/glob.mjs.map +1 -1
- package/esm/tools/grep.d.mts +3 -4
- package/esm/tools/grep.d.mts.map +1 -1
- package/esm/tools/grep.mjs +2 -1
- package/esm/tools/grep.mjs.map +1 -1
- package/esm/tools/json-schemas.mjs +175 -0
- package/esm/tools/json-schemas.mjs.map +1 -0
- package/esm/tools/list-dir.d.mts +31 -0
- package/esm/tools/list-dir.d.mts.map +1 -0
- package/esm/tools/list-dir.mjs +50 -0
- package/esm/tools/list-dir.mjs.map +1 -0
- package/esm/tools/multi-edit.d.mts +37 -0
- package/esm/tools/multi-edit.d.mts.map +1 -0
- package/esm/tools/multi-edit.mjs +121 -0
- package/esm/tools/multi-edit.mjs.map +1 -0
- package/esm/tools/read-file.d.mts +2 -3
- package/esm/tools/read-file.d.mts.map +1 -1
- package/esm/tools/read-file.mjs +2 -1
- package/esm/tools/read-file.mjs.map +1 -1
- package/esm/tools/run-shell.d.mts +36 -15
- package/esm/tools/run-shell.d.mts.map +1 -1
- package/esm/tools/run-shell.mjs +59 -53
- package/esm/tools/run-shell.mjs.map +1 -1
- package/esm/tools/run-tests.d.mts +11 -4
- package/esm/tools/run-tests.d.mts.map +1 -1
- package/esm/tools/run-tests.mjs +10 -3
- package/esm/tools/run-tests.mjs.map +1 -1
- package/esm/tools/schema.mjs +23 -18
- package/esm/tools/schema.mjs.map +1 -1
- package/esm/tools/shell-kill.d.mts +24 -0
- package/esm/tools/shell-kill.d.mts.map +1 -0
- package/esm/tools/shell-kill.mjs +36 -0
- package/esm/tools/shell-kill.mjs.map +1 -0
- package/esm/tools/shell-output.d.mts +29 -0
- package/esm/tools/shell-output.d.mts.map +1 -0
- package/esm/tools/shell-output.mjs +49 -0
- package/esm/tools/shell-output.mjs.map +1 -0
- package/esm/tools/todo.d.mts +42 -0
- package/esm/tools/todo.d.mts.map +1 -0
- package/esm/tools/todo.mjs +126 -0
- package/esm/tools/todo.mjs.map +1 -0
- package/esm/tools/write-file.d.mts +2 -3
- package/esm/tools/write-file.d.mts.map +1 -1
- package/esm/tools/write-file.mjs +2 -1
- package/esm/tools/write-file.mjs.map +1 -1
- package/esm/workspace.d.mts +14 -11
- package/esm/workspace.d.mts.map +1 -1
- package/esm/workspace.mjs +108 -27
- package/esm/workspace.mjs.map +1 -1
- package/llms-full.txt +155 -34
- package/llms.txt +1 -1
- package/package.json +3 -3
- package/skills/README.md +2 -2
- package/skills/build-loop-agent/SKILL.md +7 -7
- package/skills/index.md +6 -1
- package/skills/use-a-workspace/SKILL.md +148 -27
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region ../../packages/ai-workspace/src/contracts/tool-io.type.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Input/output shapes for the
|
|
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,9 +10,9 @@
|
|
|
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
|
+
export 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
|
-
interface ReadFileInput {
|
|
15
|
+
export interface ReadFileInput {
|
|
16
16
|
/** Workspace-relative path to read. */
|
|
17
17
|
path: string;
|
|
18
18
|
/** 1-based line to start from. Omit to start at the top. */
|
|
@@ -32,7 +32,7 @@ interface ReadFileInput {
|
|
|
32
32
|
* returned line may be partial — clipped on a character boundary, never
|
|
33
33
|
* mid-character — and `bytesCapped` is `true`.
|
|
34
34
|
*/
|
|
35
|
-
interface ReadFileResult {
|
|
35
|
+
export interface ReadFileResult {
|
|
36
36
|
/** The returned, line-numbered file content for the requested window. */
|
|
37
37
|
content: string;
|
|
38
38
|
/** 1-based first line requested. */
|
|
@@ -65,7 +65,7 @@ interface ReadFileResult {
|
|
|
65
65
|
* Input to the `edit_file` tool / `editFile()` direct method — an
|
|
66
66
|
* exact-string replacement with a read-before-edit stale guard.
|
|
67
67
|
*/
|
|
68
|
-
interface EditFileInput {
|
|
68
|
+
export interface EditFileInput {
|
|
69
69
|
/** Workspace-relative path to edit. */
|
|
70
70
|
path: string;
|
|
71
71
|
/** Exact substring to replace; must be unique unless `replaceAll`. */
|
|
@@ -78,7 +78,7 @@ interface EditFileInput {
|
|
|
78
78
|
expectHash?: string;
|
|
79
79
|
}
|
|
80
80
|
/** Result of a successful edit. */
|
|
81
|
-
interface EditFileResult {
|
|
81
|
+
export interface EditFileResult {
|
|
82
82
|
/** Workspace-relative path that was edited. */
|
|
83
83
|
path: string;
|
|
84
84
|
/** Number of occurrences replaced. */
|
|
@@ -86,15 +86,49 @@ interface EditFileResult {
|
|
|
86
86
|
/** SHA-256 of the file content after the edit. */
|
|
87
87
|
hash: string;
|
|
88
88
|
}
|
|
89
|
+
/** One replacement inside a {@link MultiEditInput}. */
|
|
90
|
+
export 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
|
+
export 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
|
+
export 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
|
+
}
|
|
89
123
|
/** Input to the `write_file` tool / `writeFile()` direct method. */
|
|
90
|
-
interface WriteFileInput {
|
|
124
|
+
export interface WriteFileInput {
|
|
91
125
|
/** Workspace-relative path to write (created if absent). */
|
|
92
126
|
path: string;
|
|
93
127
|
/** Full file content to write atomically. */
|
|
94
128
|
content: string;
|
|
95
129
|
}
|
|
96
130
|
/** Result of a write. */
|
|
97
|
-
interface WriteFileResult {
|
|
131
|
+
export interface WriteFileResult {
|
|
98
132
|
/** Workspace-relative path that was written. */
|
|
99
133
|
path: string;
|
|
100
134
|
/** Number of bytes written. */
|
|
@@ -103,7 +137,7 @@ interface WriteFileResult {
|
|
|
103
137
|
hash: string;
|
|
104
138
|
}
|
|
105
139
|
/** Options for the `exec()` direct method. */
|
|
106
|
-
interface ExecOptions {
|
|
140
|
+
export interface ExecOptions {
|
|
107
141
|
/** Per-call wall-clock cap in ms; overrides the policy `shell.timeoutMs`. */
|
|
108
142
|
timeoutMs?: number;
|
|
109
143
|
/**
|
|
@@ -114,14 +148,108 @@ interface ExecOptions {
|
|
|
114
148
|
signal?: AbortSignal;
|
|
115
149
|
}
|
|
116
150
|
/** Input to the `run_shell` tool / `exec()` direct method. */
|
|
117
|
-
interface RunShellInput {
|
|
118
|
-
/** The command line to run;
|
|
151
|
+
export interface RunShellInput {
|
|
152
|
+
/** The command line to run; every command in it is policy-checked. */
|
|
119
153
|
command: string;
|
|
120
154
|
/** Per-call wall-clock cap (overrides the policy default if lower). */
|
|
121
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
|
+
export type ShellJobStatus = "running" | "exited" | "killed" | "timed-out";
|
|
172
|
+
/** A background command owned by the workspace. */
|
|
173
|
+
export 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
|
+
export 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
|
+
export 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
|
+
export 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
|
+
export 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
|
+
export 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
|
+
export interface ShellKillInput {
|
|
248
|
+
/** The background command id to stop. */
|
|
249
|
+
id: string;
|
|
122
250
|
}
|
|
123
251
|
/** Result of a shell command — captured streams plus how it terminated. */
|
|
124
|
-
interface RunShellResult {
|
|
252
|
+
export interface RunShellResult {
|
|
125
253
|
/** Process exit code (non-zero ⇒ the command failed, not the tool). */
|
|
126
254
|
exitCode: number;
|
|
127
255
|
/** Captured standard output (byte-capped per policy). */
|
|
@@ -144,12 +272,12 @@ interface RunShellResult {
|
|
|
144
272
|
* the workspace's configured test command, optionally narrowed to a
|
|
145
273
|
* pattern (a path/suite filter passed through to the runner).
|
|
146
274
|
*/
|
|
147
|
-
interface RunTestsInput {
|
|
275
|
+
export interface RunTestsInput {
|
|
148
276
|
/** Optional path/name filter forwarded to the test runner. */
|
|
149
277
|
pattern?: string;
|
|
150
278
|
}
|
|
151
279
|
/** Input to the `grep` tool / `grep()` direct method. */
|
|
152
|
-
interface GrepInput {
|
|
280
|
+
export interface GrepInput {
|
|
153
281
|
/** Regular-expression pattern to search file contents for. */
|
|
154
282
|
pattern: string;
|
|
155
283
|
/** Glob narrowing which files are scanned (e.g. `"src/api/*.ts"`). */
|
|
@@ -158,7 +286,7 @@ interface GrepInput {
|
|
|
158
286
|
ignoreCase?: boolean;
|
|
159
287
|
}
|
|
160
288
|
/** A single matched line within a file. */
|
|
161
|
-
interface GrepMatch {
|
|
289
|
+
export interface GrepMatch {
|
|
162
290
|
/** Workspace-relative path of the file containing the match. */
|
|
163
291
|
path: string;
|
|
164
292
|
/** 1-based line number of the match. */
|
|
@@ -167,22 +295,91 @@ interface GrepMatch {
|
|
|
167
295
|
text: string;
|
|
168
296
|
}
|
|
169
297
|
/** Result of a content search across the jailed file set. */
|
|
170
|
-
interface GrepResult {
|
|
298
|
+
export interface GrepResult {
|
|
171
299
|
/** Every matching line found, in file/line order. */
|
|
172
300
|
matches: GrepMatch[];
|
|
173
301
|
/** Total number of matches (== `matches.length` unless capped). */
|
|
174
302
|
total: number;
|
|
175
303
|
}
|
|
304
|
+
/** Input to the `list_dir` tool. */
|
|
305
|
+
export 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
|
+
export 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
|
+
export type ListDirEntryType = "file" | "directory" | "symlink" | "other";
|
|
322
|
+
/** One entry of a directory listing. */
|
|
323
|
+
export 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
|
+
export 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
|
+
}
|
|
176
342
|
/** Input to the `glob` tool / `glob()` direct method. */
|
|
177
|
-
interface GlobInput {
|
|
343
|
+
export interface GlobInput {
|
|
178
344
|
/** Glob pattern resolved relative to `cwd` (e.g. `"src/api/*.ts"`). */
|
|
179
345
|
pattern: string;
|
|
180
346
|
}
|
|
181
347
|
/** Result of a glob — the matched workspace-relative paths. */
|
|
182
|
-
interface GlobResult {
|
|
348
|
+
export interface GlobResult {
|
|
183
349
|
/** Workspace-relative paths matching the pattern, sorted. */
|
|
184
350
|
paths: string[];
|
|
185
351
|
}
|
|
352
|
+
/** State of one todo item. */
|
|
353
|
+
export type WorkspaceTodoStatus = "pending" | "in_progress" | "completed";
|
|
354
|
+
/** One item of the workspace's todo list. */
|
|
355
|
+
export 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
|
+
export 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
|
+
export 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
|
+
export interface TodoListResult {
|
|
379
|
+
/** Every item, in order. */
|
|
380
|
+
todos: WorkspaceTodo[];
|
|
381
|
+
/** How many items are in each status. */
|
|
382
|
+
counts: Record<WorkspaceTodoStatus, number>;
|
|
383
|
+
}
|
|
186
384
|
//#endregion
|
|
187
|
-
export { EditFileInput, EditFileResult, ExecOptions, GlobInput, GlobResult, GrepInput, GrepMatch, GrepResult, ReadFileInput, ReadFileResult, RunShellInput, RunShellResult, RunTestsInput, WorkspaceToolName, WriteFileInput, WriteFileResult };
|
|
188
385
|
//# sourceMappingURL=tool-io.type.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-io.type.d.mts","names":[],"sources":["../../../../../../../../packages/ai-workspace/src/contracts/tool-io.type.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"tool-io.type.d.mts","names":[],"sources":["../../../../../../../../packages/ai-workspace/src/contracts/tool-io.type.ts"],"mappings":";;;;;;;;;;;;YAYY;;iBAgBK;;EAEf;;EAEA;;EAEA;;;;;;;;;;;;;;iBAee;;EAEf;;EAEA;;;;;EAKA;;EAEA;;;;;;EAMA;;EAEA;;EAEA;;;;;;EAMA;;;;;;iBAOe;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;;iBAIe;;EAEf;;EAEA;;EAEA;;;iBAIe;;EAEf;;EAEA;;EAEA;;;;;;;;iBASe;;EAEf;;EAEA,OAAO;;EAEP;;;iBAIe;;EAEf;;EAEA;;EAEA;;EAEA;;;iBAIe;;EAEf;;EAEA;;;iBAIe;;EAEf;;EAEA;;EAEA;;;iBAIe;;EAEf;;;;;;EAMA,SAAS;;;iBAIM;;EAEf;;EAEA;;;;;EAKA;;;;;;;;;;;YAYU;;iBAGK;;EAEf;;EAEA;;EAEA,QAAQ;;EAER;;EAEA;;EAEA;;EAEA;;;iBAIe,iCAAiC;;EAEhD;;;iBAIe;;;;;;EAMf;;;iBAIe;;EAEf;;;;;EAKA;;;;;EAKA;;;iBAIe;;EAEf;;EAEA;;EAEA,SAAS;;;iBAIM,0BAA0B;;EAEzC;;EAEA;;;;;EAKA;;;;;EAKA;;EAEA;;;iBAIe;;EAEf;;;iBAIe;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;EAMA;;;;;;;iBAQe;;EAEf;;;iBAIe;;EAEf;;EAEA;;EAEA;;;iBAIe;;EAEf;;EAEA;;EAEA;;;iBAIe;;EAEf,SAAS;;EAET;;;iBAIe;;EAEf;;EAEA;;EAEA;;;iBAIe;;EAEf;;EAEA;;;YAIU;;iBAGK;;EAEf;;EAEA,MAAM;;EAEN;;EAEA;;;iBAIe;;EAEf;;EAEA,SAAS;;EAET;;;iBAIe;;EAEf;;;iBAIe;;EAEf;;;YAIU;;iBAGK;;EAEf;;EAEA;;EAEA,QAAQ;;;iBAIO;;EAEf;;EAEA;;EAEA,QAAQ;;;iBAIO;;EAEf,OAAO;;;iBAIQ;;EAEf,OAAO;;EAEP,QAAQ,OAAO"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { WorkspaceShellInterpreter } from "./workspace-policy.type.mjs";
|
|
1
2
|
//#region ../../packages/ai-workspace/src/contracts/workspace-backend.contract.d.ts
|
|
2
3
|
/**
|
|
3
4
|
* Low-level result of a backend command execution. Mirrors the shape the
|
|
@@ -5,7 +6,7 @@
|
|
|
5
6
|
* byte-cap `truncated` flag (capping is an ops-layer concern, not the
|
|
6
7
|
* raw executor's).
|
|
7
8
|
*/
|
|
8
|
-
interface WorkspaceBackendExecResult {
|
|
9
|
+
export interface WorkspaceBackendExecResult {
|
|
9
10
|
/** Process exit code. */
|
|
10
11
|
exitCode: number;
|
|
11
12
|
/** Captured standard output. */
|
|
@@ -27,7 +28,7 @@ interface WorkspaceBackendExecResult {
|
|
|
27
28
|
* the effective environment and timeout from policy before handing them
|
|
28
29
|
* down — the backend just runs what it is told.
|
|
29
30
|
*/
|
|
30
|
-
interface WorkspaceBackendExecOptions {
|
|
31
|
+
export interface WorkspaceBackendExecOptions {
|
|
31
32
|
/** Working directory for the spawned process (already jail-resolved). */
|
|
32
33
|
cwd?: string;
|
|
33
34
|
/** Wall-clock cap in ms; on expiry the process is SIGKILLed. */
|
|
@@ -43,6 +44,52 @@ interface WorkspaceBackendExecOptions {
|
|
|
43
44
|
* backend.
|
|
44
45
|
*/
|
|
45
46
|
signal?: AbortSignal;
|
|
47
|
+
/**
|
|
48
|
+
* How to run `command`: `"none"` (default) tokenizes it into an argv and
|
|
49
|
+
* spawns it without a shell; `"sh"` hands the whole line to `/bin/sh -c`
|
|
50
|
+
* (`cmd.exe /d /v:off /s /c` on Windows). The ops layer has already
|
|
51
|
+
* checked every command in the line against the policy; a backend that
|
|
52
|
+
* does not support `"sh"` must refuse the command rather than run it
|
|
53
|
+
* another way.
|
|
54
|
+
*/
|
|
55
|
+
interpreter?: WorkspaceShellInterpreter;
|
|
56
|
+
}
|
|
57
|
+
/** Which stream a background command's output chunk came from. */
|
|
58
|
+
export type WorkspaceOutputStream = "stdout" | "stderr";
|
|
59
|
+
/** Options for {@link WorkspaceBackend.start}. */
|
|
60
|
+
export interface WorkspaceBackendStartOptions {
|
|
61
|
+
/** Working directory for the spawned process (already jail-resolved). */
|
|
62
|
+
cwd?: string;
|
|
63
|
+
/** Exact environment for the spawned process (NOT merged with process.env). */
|
|
64
|
+
env?: Record<string, string>;
|
|
65
|
+
/** See {@link WorkspaceBackendExecOptions.interpreter}. */
|
|
66
|
+
interpreter?: WorkspaceShellInterpreter;
|
|
67
|
+
/**
|
|
68
|
+
* Receives output as it arrives, decoded as UTF-8 and never split inside a
|
|
69
|
+
* character. Called synchronously or later — never after `done` settles.
|
|
70
|
+
*/
|
|
71
|
+
onOutput(stream: WorkspaceOutputStream, chunk: string): void;
|
|
72
|
+
}
|
|
73
|
+
/** A running background command, as a backend hands it to the ops layer. */
|
|
74
|
+
export interface WorkspaceBackendProcess {
|
|
75
|
+
/** OS process id of the direct child, when there is one. */
|
|
76
|
+
readonly pid?: number;
|
|
77
|
+
/**
|
|
78
|
+
* Settles once the process has exited and its output has been delivered.
|
|
79
|
+
* Never rejects: a spawn failure resolves with exit code `127`.
|
|
80
|
+
*/
|
|
81
|
+
readonly done: Promise<{
|
|
82
|
+
exitCode: number;
|
|
83
|
+
}>;
|
|
84
|
+
/** Kill the whole process tree. Idempotent; safe after it has exited. */
|
|
85
|
+
kill(): void;
|
|
86
|
+
}
|
|
87
|
+
/** What {@link WorkspaceBackend.stat} reports about a path (symlinks are not followed). */
|
|
88
|
+
export interface WorkspaceBackendStat {
|
|
89
|
+
/** Entry kind. */
|
|
90
|
+
type: "file" | "directory" | "symlink" | "other";
|
|
91
|
+
/** Size in bytes. */
|
|
92
|
+
size: number;
|
|
46
93
|
}
|
|
47
94
|
/**
|
|
48
95
|
* The swappable executor a workspace runs on — the thin, **policy-agnostic**
|
|
@@ -62,7 +109,7 @@ interface WorkspaceBackendExecOptions {
|
|
|
62
109
|
* const out = await backend.readFile("/srv/acme-api/src/index.ts");
|
|
63
110
|
* const { exitCode } = await backend.exec("npm test", { cwd: "/srv/acme-api" });
|
|
64
111
|
*/
|
|
65
|
-
interface WorkspaceBackend {
|
|
112
|
+
export interface WorkspaceBackend {
|
|
66
113
|
/** Read a file's full UTF-8 content at an absolute path. */
|
|
67
114
|
readFile(absPath: string): Promise<string>;
|
|
68
115
|
/** Write full content to an absolute path (atomically where supported). */
|
|
@@ -79,7 +126,18 @@ interface WorkspaceBackend {
|
|
|
79
126
|
realpath(absPath: string): Promise<string>;
|
|
80
127
|
/** Run a command and capture its outcome. */
|
|
81
128
|
exec(command: string, opts?: WorkspaceBackendExecOptions): Promise<WorkspaceBackendExecResult>;
|
|
129
|
+
/**
|
|
130
|
+
* Describe an absolute path without following a final symlink. Optional:
|
|
131
|
+
* without it, `list_dir` tells files from directories by trying to list
|
|
132
|
+
* them and reports no sizes.
|
|
133
|
+
*/
|
|
134
|
+
stat?(absPath: string): Promise<WorkspaceBackendStat>;
|
|
135
|
+
/**
|
|
136
|
+
* Start a long-running command and return at once. Optional: without it,
|
|
137
|
+
* background commands are refused. The process must be its own process
|
|
138
|
+
* group (or equivalent) so `kill()` reaches every descendant.
|
|
139
|
+
*/
|
|
140
|
+
start?(command: string, opts: WorkspaceBackendStartOptions): WorkspaceBackendProcess;
|
|
82
141
|
}
|
|
83
142
|
//#endregion
|
|
84
|
-
export { WorkspaceBackend, WorkspaceBackendExecOptions, WorkspaceBackendExecResult };
|
|
85
143
|
//# sourceMappingURL=workspace-backend.contract.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-backend.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-workspace/src/contracts/workspace-backend.contract.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"workspace-backend.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-workspace/src/contracts/workspace-backend.contract.ts"],"mappings":";;;;;;;;iBAQiB;;EAEf;;EAEA;;EAEA;;EAEA;;;;;;;EAOA;;;;;;;iBAQe;;EAEf;;EAEA;;EAEA,MAAM;;;;;;;;;EASN,SAAS;;;;;;;;;EAST,cAAc;;;YAIJ;;iBAGK;;EAEf;;EAEA,MAAM;;EAEN,cAAc;;;;;EAKd,SAAS,QAAQ,uBAAuB;;;iBAIzB;;WAEN;;;;;WAKA,MAAM;IAAU;;;EAEzB;;;iBAIe;;EAEf;;EAEA;;;;;;;;;;;;;;;;;;;;iBAqBe;;EAEf,SAAS,kBAAkB;;EAE3B,UAAU,iBAAiB,kBAAkB;;EAE7C,OAAO,kBAAkB;;EAEzB,MAAM,kBAAkB;;EAExB,OAAO,kBAAkB;;EAEzB,KAAK,iBAAiB;;EAEtB,SAAS,kBAAkB;;EAE3B,KAAK,iBAAiB,OAAO,8BAA8B,QAAQ;;;;;;EAMnE,MAAM,kBAAkB,QAAQ;;;;;;EAMhC,OAAO,iBAAiB,MAAM,+BAA+B"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { EditFileInput, EditFileResult, ExecOptions, GrepResult, ReadFileResult, RunShellResult } from "./tool-io.type.mjs";
|
|
2
|
-
|
|
1
|
+
import { EditFileInput, EditFileResult, ExecOptions, GrepResult, ListDirOptions, ListDirResult, MultiEditInput, MultiEditResult, ReadFileResult, RunShellResult, ShellJobInfo, ShellOutputOptions, ShellOutputResult, StartShellOptions } from "./tool-io.type.mjs";
|
|
3
2
|
//#region ../../packages/ai-workspace/src/contracts/workspace-ops.contract.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* The **policy-enforced** operation layer that sits between the dumb
|
|
@@ -20,7 +19,7 @@ import { EditFileInput, EditFileResult, ExecOptions, GrepResult, ReadFileResult,
|
|
|
20
19
|
* const { content, hash } = await ops.readFile("src/index.ts");
|
|
21
20
|
* await ops.editFile({ path: "src/index.ts", oldString: "x", newString: "y", expectHash: hash });
|
|
22
21
|
*/
|
|
23
|
-
interface WorkspaceOps {
|
|
22
|
+
export interface WorkspaceOps {
|
|
24
23
|
/**
|
|
25
24
|
* Read a jailed file, returning a numbered line window, the full file's
|
|
26
25
|
* hash and the window metadata. `offset`/`limit` select a 1-based line
|
|
@@ -43,12 +42,35 @@ interface WorkspaceOps {
|
|
|
43
42
|
*/
|
|
44
43
|
editFile(input: EditFileInput): Promise<EditFileResult>;
|
|
45
44
|
/**
|
|
46
|
-
*
|
|
47
|
-
* against the
|
|
45
|
+
* Apply several exact-string edits to one file atomically: each edit runs
|
|
46
|
+
* against the result of the previous ones, under the same uniqueness rules
|
|
47
|
+
* as `editFile`, and the file is written once — or, when any edit fails,
|
|
48
|
+
* not at all (`WorkspaceEditError` with `editIndex`).
|
|
49
|
+
*/
|
|
50
|
+
multiEdit(input: MultiEditInput): Promise<MultiEditResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Run a command line after checking every command in it against the
|
|
53
|
+
* shell policy (see `WorkspaceShellPolicy`), with the policy environment,
|
|
48
54
|
* timeout, and output byte cap applied. `signal` cancels this one call
|
|
49
55
|
* (see {@link ExecOptions}).
|
|
50
56
|
*/
|
|
51
57
|
exec(command: string, opts?: ExecOptions): Promise<RunShellResult>;
|
|
58
|
+
/**
|
|
59
|
+
* Start a policy-checked command as a background job owned by the
|
|
60
|
+
* workspace and return at once. Needs `shell.background`.
|
|
61
|
+
*/
|
|
62
|
+
startShell(command: string, opts?: StartShellOptions): Promise<ShellJobInfo>;
|
|
63
|
+
/** New output of a background command since `since` (default: the last read). */
|
|
64
|
+
shellOutput(id: string, opts?: ShellOutputOptions): Promise<ShellOutputResult>;
|
|
65
|
+
/** Kill a background command's whole process tree and report its final state. */
|
|
66
|
+
shellKill(id: string): Promise<ShellJobInfo>;
|
|
67
|
+
/** Every background command this workspace knows, oldest first. */
|
|
68
|
+
listShells(): ShellJobInfo[];
|
|
69
|
+
/**
|
|
70
|
+
* List a jailed directory — bounded by depth and `list.maxEntries`, with
|
|
71
|
+
* `denyPaths` and `list.ignore` left out and symlinks never followed.
|
|
72
|
+
*/
|
|
73
|
+
listDir(path?: string, opts?: ListDirOptions): Promise<ListDirResult>;
|
|
52
74
|
/** Search jailed file contents for a regex pattern. */
|
|
53
75
|
grep(pattern: string, opts?: {
|
|
54
76
|
glob?: string;
|
|
@@ -62,7 +84,12 @@ interface WorkspaceOps {
|
|
|
62
84
|
mkdir(path: string): Promise<void>;
|
|
63
85
|
/** Remove a file or directory tree at a jailed path. */
|
|
64
86
|
remove(path: string): Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Kill every background command (whole process trees) and refuse new
|
|
89
|
+
* commands. A foreground command already running finishes on its own (or
|
|
90
|
+
* by its timeout / signal). Idempotent.
|
|
91
|
+
*/
|
|
92
|
+
dispose(): Promise<void>;
|
|
65
93
|
}
|
|
66
94
|
//#endregion
|
|
67
|
-
export { WorkspaceOps };
|
|
68
95
|
//# sourceMappingURL=workspace-ops.contract.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-ops.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-workspace/src/contracts/workspace-ops.contract.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"workspace-ops.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-workspace/src/contracts/workspace-ops.contract.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;iBAoCiB;;;;;;;EAOf,SAAS,cAAc;IAAS;IAAiB;MAAmB,QAAQ;;EAG5E,UAAU,cAAc,kBAAkB;IAAU;IAAc;;;;;;;EAOlE,SAAS,OAAO,gBAAgB,QAAQ;;;;;;;EAQxC,UAAU,OAAO,iBAAiB,QAAQ;;;;;;;EAQ1C,KAAK,iBAAiB,OAAO,cAAc,QAAQ;;;;;EAMnD,WAAW,iBAAiB,OAAO,oBAAoB,QAAQ;;EAG/D,YAAY,YAAY,OAAO,qBAAqB,QAAQ;;EAG5D,UAAU,aAAa,QAAQ;;EAG/B,cAAc;;;;;EAMd,QAAQ,eAAe,OAAO,iBAAiB,QAAQ;;EAGvD,KAAK,iBAAiB;IAAS;IAAe;MAAyB,QAAQ;;EAG/E,KAAK,kBAAkB;;EAGvB,OAAO,eAAe;;EAGtB,MAAM,eAAe;;EAGrB,OAAO,eAAe;;;;;;EAOtB,WAAW"}
|