@warlock.js/ai-workspace 5.30.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.
- package/CHANGELOG.md +46 -2
- package/README.md +34 -21
- package/cjs/index.cjs +3116 -309
- package/cjs/index.cjs.map +1 -1
- package/esm/backends/local.d.mts.map +1 -1
- package/esm/backends/local.mjs +165 -27
- package/esm/backends/local.mjs.map +1 -1
- package/esm/backends/mock.d.mts +11 -5
- 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 +3 -3
- package/esm/contracts/tool-io.type.d.mts +202 -4
- package/esm/contracts/tool-io.type.d.mts.map +1 -1
- package/esm/contracts/workspace-backend.contract.d.mts +61 -1
- package/esm/contracts/workspace-backend.contract.d.mts.map +1 -1
- package/esm/contracts/workspace-ops.contract.d.mts +32 -3
- package/esm/contracts/workspace-ops.contract.d.mts.map +1 -1
- package/esm/contracts/workspace-policy.type.d.mts +133 -12
- package/esm/contracts/workspace-policy.type.d.mts.map +1 -1
- package/esm/contracts/workspace.contract.d.mts +63 -9
- package/esm/contracts/workspace.contract.d.mts.map +1 -1
- package/esm/errors.d.mts +79 -5
- 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 +13 -5
- package/esm/index.mjs +10 -2
- package/esm/ops.d.mts +21 -2
- 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 +25 -15
- package/esm/policy/policy.d.mts.map +1 -1
- package/esm/policy/policy.mjs +61 -85
- package/esm/policy/policy.mjs.map +1 -1
- package/esm/policy/shell-check.d.mts +64 -0
- package/esm/policy/shell-check.d.mts.map +1 -0
- package/esm/policy/shell-check.mjs +627 -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 +63 -0
- package/esm/policy/tokenize-command.d.mts.map +1 -0
- package/esm/policy/tokenize-command.mjs +75 -23
- 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.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.map +1 -1
- package/esm/tools/glob.mjs +2 -1
- package/esm/tools/glob.mjs.map +1 -1
- 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 +32 -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 +38 -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.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 +34 -12
- 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 +8 -0
- 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 +25 -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 +30 -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 +43 -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.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 +11 -8
- 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,4 +1,4 @@
|
|
|
1
|
-
import { EditFileInput, EditFileResult, ExecOptions, GrepResult, ReadFileResult, RunShellResult, WorkspaceToolName } from "./tool-io.type.mjs";
|
|
1
|
+
import { EditFileInput, EditFileResult, ExecOptions, GrepResult, ListDirOptions, ListDirResult, MultiEditInput, MultiEditResult, ReadFileResult, RunShellResult, ShellJobInfo, ShellOutputOptions, ShellOutputResult, StartShellOptions, TodoListResult, WorkspaceTodoInput, WorkspaceToolName } from "./tool-io.type.mjs";
|
|
2
2
|
import { WorkspacePolicy } from "./workspace-policy.type.mjs";
|
|
3
3
|
import { ToolContract } from "@warlock.js/ai";
|
|
4
4
|
|
|
@@ -14,7 +14,11 @@ import { ToolContract } from "@warlock.js/ai";
|
|
|
14
14
|
* multiple agents.
|
|
15
15
|
*/
|
|
16
16
|
interface WorkspaceTools {
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Every tool this workspace vends, as `ToolContract[]`, ready for
|
|
19
|
+
* `ai.agent({ tools })`. `shell_output` / `shell_kill` are included only
|
|
20
|
+
* when the policy enables background commands (`shell.background`).
|
|
21
|
+
*/
|
|
18
22
|
all(): ToolContract[];
|
|
19
23
|
/** A named subset, e.g. `pick("readFile", "grep")` for least privilege. */
|
|
20
24
|
pick(...names: WorkspaceToolName[]): ToolContract[];
|
|
@@ -26,14 +30,30 @@ interface WorkspaceTools {
|
|
|
26
30
|
editFile(opts?: {
|
|
27
31
|
name?: string;
|
|
28
32
|
}): ToolContract;
|
|
33
|
+
/** The `multi_edit` tool (several replacements in one file, all or none). */
|
|
34
|
+
multiEdit(opts?: {
|
|
35
|
+
name?: string;
|
|
36
|
+
}): ToolContract;
|
|
29
37
|
/** The `write_file` tool (atomic full-content write). */
|
|
30
38
|
writeFile(opts?: {
|
|
31
39
|
name?: string;
|
|
32
40
|
}): ToolContract;
|
|
33
|
-
/** The `
|
|
41
|
+
/** The `list_dir` tool (bounded, jailed directory listing). */
|
|
42
|
+
listDir(opts?: {
|
|
43
|
+
name?: string;
|
|
44
|
+
}): ToolContract;
|
|
45
|
+
/** The `run_shell` tool (policy-gated command execution, optionally in the background). */
|
|
34
46
|
runShell(opts?: {
|
|
35
47
|
name?: string;
|
|
36
48
|
}): ToolContract;
|
|
49
|
+
/** The `shell_output` tool (read a background command's new output). */
|
|
50
|
+
shellOutput(opts?: {
|
|
51
|
+
name?: string;
|
|
52
|
+
}): ToolContract;
|
|
53
|
+
/** The `shell_kill` tool (stop a background command). */
|
|
54
|
+
shellKill(opts?: {
|
|
55
|
+
name?: string;
|
|
56
|
+
}): ToolContract;
|
|
37
57
|
/** The `run_tests` tool (runs the configured test command). */
|
|
38
58
|
runTests(opts?: {
|
|
39
59
|
name?: string;
|
|
@@ -47,6 +67,14 @@ interface WorkspaceTools {
|
|
|
47
67
|
glob(opts?: {
|
|
48
68
|
name?: string;
|
|
49
69
|
}): ToolContract;
|
|
70
|
+
/** The `todo_write` tool (replace the workspace's todo list). */
|
|
71
|
+
todoWrite(opts?: {
|
|
72
|
+
name?: string;
|
|
73
|
+
}): ToolContract;
|
|
74
|
+
/** The `todo_read` tool (read the workspace's todo list). */
|
|
75
|
+
todoRead(opts?: {
|
|
76
|
+
name?: string;
|
|
77
|
+
}): ToolContract;
|
|
50
78
|
}
|
|
51
79
|
/**
|
|
52
80
|
* The bounded place an agent reads, writes, and runs commands — a
|
|
@@ -54,12 +82,11 @@ interface WorkspaceTools {
|
|
|
54
82
|
* ops layer, two ways to touch it: the agent uses `.tools.*`; you use the
|
|
55
83
|
* direct methods.
|
|
56
84
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* deferred to later phases and intentionally absent here.
|
|
85
|
+
* The surface: the policy jail, the tools, the direct methods,
|
|
86
|
+
* `tools.all()` / `tools.pick()`, the two composition projections
|
|
87
|
+
* `readonly()` and `scope()`, background commands, a todo list, and
|
|
88
|
+
* `dispose()`. Projections share their parent's background commands and
|
|
89
|
+
* todo list; disposing any of them disposes the whole workspace.
|
|
63
90
|
*
|
|
64
91
|
* @example
|
|
65
92
|
* const ws = ai.workspace({ cwd: "/srv/acme-api", shell: { allow: ["npm"], inheritEnv: ["PATH"] } });
|
|
@@ -93,12 +120,39 @@ interface Workspace {
|
|
|
93
120
|
}>;
|
|
94
121
|
/** Apply an exact-string edit under the read-before-edit stale guard. */
|
|
95
122
|
editFile(input: EditFileInput): Promise<EditFileResult>;
|
|
123
|
+
/** Apply several exact-string edits to one file — all of them or none. */
|
|
124
|
+
multiEdit(input: MultiEditInput): Promise<MultiEditResult>;
|
|
125
|
+
/** List a jailed directory (bounded, ignores applied, symlinks not followed). */
|
|
126
|
+
listDir(path?: string, opts?: ListDirOptions): Promise<ListDirResult>;
|
|
96
127
|
/**
|
|
97
128
|
* Run a policy-gated shell command and capture its outcome. `signal`
|
|
98
129
|
* cancels this one call: not started when already aborted, process tree
|
|
99
130
|
* killed when it aborts mid-run, `cancelled: true` either way.
|
|
100
131
|
*/
|
|
101
132
|
exec(command: string, opts?: ExecOptions): Promise<RunShellResult>;
|
|
133
|
+
/**
|
|
134
|
+
* Start a policy-checked background command owned by this workspace
|
|
135
|
+
* (needs `shell.background`). It runs until it exits, `shellKill(id)`,
|
|
136
|
+
* its timeout, or `dispose()`.
|
|
137
|
+
*/
|
|
138
|
+
startShell(command: string, opts?: StartShellOptions): Promise<ShellJobInfo>;
|
|
139
|
+
/** New output of a background command since `since` (default: the last read). */
|
|
140
|
+
shellOutput(id: string, opts?: ShellOutputOptions): Promise<ShellOutputResult>;
|
|
141
|
+
/** Kill a background command's whole process tree. */
|
|
142
|
+
shellKill(id: string): Promise<ShellJobInfo>;
|
|
143
|
+
/** Every background command this workspace knows, oldest first. */
|
|
144
|
+
listShells(): ShellJobInfo[];
|
|
145
|
+
/** The workspace's todo list (what `todo_read` returns). */
|
|
146
|
+
readTodos(): TodoListResult;
|
|
147
|
+
/** Replace the workspace's todo list (what `todo_write` does). */
|
|
148
|
+
writeTodos(todos: WorkspaceTodoInput[]): TodoListResult;
|
|
149
|
+
/**
|
|
150
|
+
* Close the workspace: kill every background command's process tree and
|
|
151
|
+
* refuse new commands (a foreground command already running finishes on
|
|
152
|
+
* its own, or by its timeout / signal). Idempotent; resolves once the
|
|
153
|
+
* background processes are gone.
|
|
154
|
+
*/
|
|
155
|
+
dispose(): Promise<void>;
|
|
102
156
|
/** Search jailed file contents for a regex pattern. */
|
|
103
157
|
grep(pattern: string, opts?: {
|
|
104
158
|
glob?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-workspace/src/contracts/workspace.contract.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"workspace.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-workspace/src/contracts/workspace.contract.ts"],"mappings":";;;;;;;AAgCA;;;;;;;;UAAiB,cAAA;EAgBsB;;;;;EAVrC,GAAA,IAAO,YAAA;EAsByB;EApBhC,IAAA,IAAQ,KAAA,EAAO,iBAAA,KAAsB,YAAA;EAwBA;EAtBrC,QAAA,CAAS,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;EAJpC;EAMA,QAAA,CAAS,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;EAJrB;EAMf,SAAA,CAAU,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;EAJ5B;EAMT,SAAA,CAAU,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;EAJ5B;EAMT,OAAA,CAAQ,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;EAJzB;EAMV,QAAA,CAAS,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;EAJ1B;EAMV,WAAA,CAAY,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;EAJ/B;EAMR,SAAA,CAAU,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;EAJ5B;EAMT,QAAA,CAAS,IAAA;IAAS,IAAA;IAAe,OAAA;EAAA,IAAqB,YAAA;EAJf;EAMvC,IAAA,CAAK,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;EAJK;EAMrC,IAAA,CAAK,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;EAJvB;EAMT,SAAA,CAAU,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;EAJhC;EAML,QAAA,CAAS,IAAA;IAAS,IAAA;EAAA,IAAkB,YAAA;AAAA;;;;;;;;;;;AAAY;AAyBlD;;;;;;;;;;;UAAiB,SAAA;EAsB2B;EAAA,SApBjC,MAAA,EAAQ,eAAA;EAuBa;EAAA,SApBrB,KAAA,EAAO,cAAA;EAoB+B;;;;;;EAZ/C,QAAA,CAAS,IAAA,UAAc,IAAA;IAAS,MAAA;IAAiB,KAAA;EAAA,IAAmB,OAAA,CAAQ,cAAA;EAgC7C;EA7B/B,SAAA,CAAU,IAAA,UAAc,OAAA,WAAkB,OAAA;IAAU,IAAA;IAAc,YAAA;EAAA;EAsCzB;EAnCzC,QAAA,CAAS,KAAA,EAAO,aAAA,GAAgB,OAAA,CAAQ,cAAA;EA8CuC;EA3C/E,SAAA,CAAU,KAAA,EAAO,cAAA,GAAiB,OAAA,CAAQ,eAAA;EA8CnB;EA3CvB,OAAA,CAAQ,IAAA,WAAe,IAAA,GAAO,cAAA,GAAiB,OAAA,CAAQ,aAAA;EAiDlC;;;;;EA1CrB,IAAA,CAAK,OAAA,UAAiB,IAAA,GAAO,WAAA,GAAc,OAAA,CAAQ,cAAA;EA9B1C;;;;;EAqCT,UAAA,CAAW,OAAA,UAAiB,IAAA,GAAO,iBAAA,GAAoB,OAAA,CAAQ,YAAA;EA1B/B;EA6BhC,WAAA,CAAY,EAAA,UAAY,IAAA,GAAO,kBAAA,GAAqB,OAAA,CAAQ,iBAAA;EA7BrC;EAgCvB,SAAA,CAAU,EAAA,WAAa,OAAA,CAAQ,YAAA;EAhC6C;EAmC5E,UAAA,IAAc,YAAA;EAhCJ;EAmCV,SAAA,IAAa,cAAA;EAnC6B;EAsC1C,UAAA,CAAW,KAAA,EAAO,kBAAA,KAAuB,cAAA;EAtCyB;;;;;;EA8ClE,OAAA,IAAW,OAAA;EAxCM;EA2CjB,IAAA,CAAK,OAAA,UAAiB,IAAA;IAAS,IAAA;IAAe,UAAA;EAAA,IAAyB,OAAA,CAAQ,UAAA;EAxCvE;EA2CR,IAAA,CAAK,OAAA,WAAkB,OAAA;EA3CA;EA8CvB,MAAA,CAAO,IAAA,WAAe,OAAA;EA9CiC;EAiDvD,KAAA,CAAM,IAAA,WAAe,OAAA;EA1ChB;EA6CL,MAAA,CAAO,IAAA,WAAe,OAAA;EA7CA;;;;;EAoDtB,QAAA,IAAY,SAAA;EA7CgB;;;;;EAoD5B,KAAA,CAAM,MAAA,WAAiB,SAAA;AAAA"}
|
package/esm/errors.d.mts
CHANGED
|
@@ -6,13 +6,41 @@ import { AIError, AIErrorOptions } from "@warlock.js/ai";
|
|
|
6
6
|
*
|
|
7
7
|
* - `"path-escape"` — a resolved path fell outside the `cwd` jail (or an
|
|
8
8
|
* `allowPaths` root), or matched a `denyPaths` glob.
|
|
9
|
-
* - `"denied-command"` —
|
|
10
|
-
*
|
|
9
|
+
* - `"denied-command"` — the shell policy refused a command line (`reason`
|
|
10
|
+
* says why: an executable outside `shell.allow` or inside `shell.deny`, a
|
|
11
|
+
* metacharacter in argv mode, a redirection outside the jail in shell
|
|
12
|
+
* mode, …), or a mutating method was called on a read-only projection.
|
|
11
13
|
* - `"unsafe-pattern"` — a `grep` pattern was too long or matched a
|
|
12
14
|
* catastrophic-backtracking shape (nested quantifiers) that could hang
|
|
13
15
|
* the process (ReDoS).
|
|
14
16
|
*/
|
|
15
17
|
type WorkspacePolicyViolation = "path-escape" | "denied-command" | "unsafe-pattern";
|
|
18
|
+
/**
|
|
19
|
+
* Why the shell policy refused a command. Set on every
|
|
20
|
+
* {@link WorkspacePolicyError} of type `"denied-command"` raised for a
|
|
21
|
+
* command line, so a host can phrase the refusal itself instead of parsing
|
|
22
|
+
* the message.
|
|
23
|
+
*
|
|
24
|
+
* - `"metacharacter"` — argv mode (the default `interpreter: "none"`) met an
|
|
25
|
+
* unquoted shell operator (`&&`, `;`, `|`, `>`, `$`, backticks, …). The
|
|
26
|
+
* message suggests how to split the line into separate commands.
|
|
27
|
+
* - `"unbalanced-quotes"` — a quote is never closed.
|
|
28
|
+
* - `"denied-executable"` — a command's executable is listed in `shell.deny`.
|
|
29
|
+
* - `"not-allowed"` — a command's executable is not in `shell.allow`, the
|
|
30
|
+
* `shell.allowCommand` hook refused it, the workspace has no shell policy,
|
|
31
|
+
* the line is empty, or background commands are not enabled.
|
|
32
|
+
* - `"denied-pattern"` — a command matched one of `shell.denyPatterns`.
|
|
33
|
+
* - `"nested-command"` — a command runs another command the policy cannot
|
|
34
|
+
* inspect (`bash -c …`, `eval`, `xargs`, `sudo`, a wrapper with options the
|
|
35
|
+
* policy cannot read), while the policy has deny rules it would bypass.
|
|
36
|
+
* - `"unsupported-syntax"` — shell mode (`interpreter: "sh"`) met syntax the
|
|
37
|
+
* policy does not parse with confidence (compound commands, arithmetic,
|
|
38
|
+
* brace expansion, background `&`, a command name decided at run time, …),
|
|
39
|
+
* so the line is refused rather than guessed at.
|
|
40
|
+
* - `"path-escape"` — shell mode: a redirection target or `cd` directory
|
|
41
|
+
* resolves outside the workspace jail or hits `denyPaths`.
|
|
42
|
+
*/
|
|
43
|
+
type WorkspaceShellRefusalReason = "metacharacter" | "unbalanced-quotes" | "denied-executable" | "not-allowed" | "denied-pattern" | "nested-command" | "unsupported-syntax" | "path-escape";
|
|
16
44
|
/**
|
|
17
45
|
* Options for {@link WorkspacePolicyError} — the structured `type`
|
|
18
46
|
* discriminator plus, where relevant, the offending path or command for
|
|
@@ -22,7 +50,9 @@ type WorkspacePolicyErrorOptions = AIErrorOptions & {
|
|
|
22
50
|
/** Which policy rule was violated. */type: WorkspacePolicyViolation; /** The offending workspace-relative path (for `"path-escape"`). */
|
|
23
51
|
path?: string; /** The offending command line (for `"denied-command"`). */
|
|
24
52
|
command?: string; /** The offending regex pattern (for `"unsafe-pattern"`). */
|
|
25
|
-
pattern?: string;
|
|
53
|
+
pattern?: string; /** Why the shell policy refused the command (for `"denied-command"`). */
|
|
54
|
+
reason?: WorkspaceShellRefusalReason; /** The executable the refusal is about, when there is one. */
|
|
55
|
+
executable?: string;
|
|
26
56
|
};
|
|
27
57
|
/**
|
|
28
58
|
* The workspace policy engine refused an operation — a path escaped the
|
|
@@ -50,6 +80,14 @@ declare class WorkspacePolicyError extends AIError {
|
|
|
50
80
|
readonly command?: string;
|
|
51
81
|
/** The offending regex pattern, when the violation was `"unsafe-pattern"`. */
|
|
52
82
|
readonly pattern?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Why the shell policy refused a command line — set on every
|
|
85
|
+
* `"denied-command"` refusal of a command (see
|
|
86
|
+
* {@link WorkspaceShellRefusalReason}).
|
|
87
|
+
*/
|
|
88
|
+
readonly reason?: WorkspaceShellRefusalReason;
|
|
89
|
+
/** The executable the shell refusal is about, when there is one. */
|
|
90
|
+
readonly executable?: string;
|
|
53
91
|
constructor(message: string, options: WorkspacePolicyErrorOptions);
|
|
54
92
|
}
|
|
55
93
|
/**
|
|
@@ -72,7 +110,8 @@ type WorkspaceEditErrorOptions = AIErrorOptions & {
|
|
|
72
110
|
path: string; /** How many times `oldString` matched (for `"not-unique"`). */
|
|
73
111
|
matches?: number; /** The hash the caller expected (for `"stale-hash"`). */
|
|
74
112
|
expectedHash?: string; /** The file's actual current hash (for `"stale-hash"`). */
|
|
75
|
-
actualHash?: string;
|
|
113
|
+
actualHash?: string; /** 0-based index of the failing edit, for a `multiEdit` rejection. */
|
|
114
|
+
editIndex?: number;
|
|
76
115
|
};
|
|
77
116
|
/**
|
|
78
117
|
* An `editFile` operation was rejected by the read-before-edit guard:
|
|
@@ -99,8 +138,43 @@ declare class WorkspaceEditError extends AIError {
|
|
|
99
138
|
readonly expectedHash?: string;
|
|
100
139
|
/** The file's actual current hash, for the `"stale-hash"` case. */
|
|
101
140
|
readonly actualHash?: string;
|
|
141
|
+
/**
|
|
142
|
+
* For a `multiEdit` rejection, the 0-based index of the edit that failed.
|
|
143
|
+
* Nothing was written: a multi-edit applies all of its edits or none.
|
|
144
|
+
*/
|
|
145
|
+
readonly editIndex?: number;
|
|
102
146
|
constructor(message: string, options: WorkspaceEditErrorOptions);
|
|
103
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Why a background-command operation failed.
|
|
150
|
+
*
|
|
151
|
+
* - `"not-found"` — no background command with that id exists in this
|
|
152
|
+
* workspace (it never existed, or it finished long enough ago to be
|
|
153
|
+
* pruned).
|
|
154
|
+
*/
|
|
155
|
+
type WorkspaceJobFailure = "not-found";
|
|
156
|
+
/** Options for {@link WorkspaceJobError}. */
|
|
157
|
+
type WorkspaceJobErrorOptions = AIErrorOptions & {
|
|
158
|
+
/** Why the operation failed. */type: WorkspaceJobFailure; /** The background command id the caller asked for. */
|
|
159
|
+
jobId: string;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* A `shell_output` / `shell_kill` call (or `shellOutput()` / `shellKill()`)
|
|
163
|
+
* named a background command this workspace does not know. Returned to the
|
|
164
|
+
* agent as tool-error data like the other workspace errors.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* if (error instanceof WorkspaceJobError && error.type === "not-found") {
|
|
168
|
+
* console.warn(`No background command ${error.jobId}`);
|
|
169
|
+
* }
|
|
170
|
+
*/
|
|
171
|
+
declare class WorkspaceJobError extends AIError {
|
|
172
|
+
/** Why the operation failed. */
|
|
173
|
+
readonly type: WorkspaceJobFailure;
|
|
174
|
+
/** The background command id the caller asked for. */
|
|
175
|
+
readonly jobId: string;
|
|
176
|
+
constructor(message: string, options: WorkspaceJobErrorOptions);
|
|
177
|
+
}
|
|
104
178
|
//#endregion
|
|
105
|
-
export { WorkspaceEditError, WorkspaceEditErrorOptions, WorkspaceEditFailure, WorkspacePolicyError, WorkspacePolicyErrorOptions, WorkspacePolicyViolation };
|
|
179
|
+
export { WorkspaceEditError, WorkspaceEditErrorOptions, WorkspaceEditFailure, WorkspaceJobError, WorkspaceJobErrorOptions, WorkspaceJobFailure, WorkspacePolicyError, WorkspacePolicyErrorOptions, WorkspacePolicyViolation, WorkspaceShellRefusalReason };
|
|
106
180
|
//# sourceMappingURL=errors.d.mts.map
|
package/esm/errors.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.mts","names":[],"sources":["../../../../../../../packages/ai-workspace/src/errors.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"errors.d.mts","names":[],"sources":["../../../../../../../packages/ai-workspace/src/errors.ts"],"mappings":";;;;;AAeA;;;;AAAoC;AA2BpC;;;;AAAuC;AAevC;KA1CY,wBAAA;;;;;;;;;;;;;;;;;AAsDA;AAoBZ;;;;;;;;KA/CY,2BAAA;;;;;;KAeA,2BAAA,GAA8B,cAAA;EA8CxB,sCA5ChB,IAAA,EAAM,wBAAA,EA8CU;EA5ChB,IAAA,WA8CmB;EA5CnB,OAAA,WA4CoC;EA1CpC,OAAA,WA0CwE;EAxCxE,MAAA,GAAS,2BAAA,EA8DqB;EA5D9B,UAAA;AAAA;AA4D8B;AAOhC;;;;;;;;;;;;;AAYW;AAiBX;;AApCgC,cAxCnB,oBAAA,SAA6B,OAAA;EA8ElB;EAAA,SA5EN,IAAA,EAAM,wBAAA;EA0EgB;EAAA,SAxEtB,IAAA;EAwE6B;EAAA,SAtE7B,OAAA;EAwEA;EAAA,SAtEA,OAAA;EAwEA;;;;;EAAA,SAlEA,MAAA,GAAS,2BAAA;EA+EN;EAAA,SA7EH,UAAA;cAEG,OAAA,UAAiB,OAAA,EAAS,2BAAA;AAAA;AA2EyB;AAoBxE;;;;AAA+B;AAG/B;;;AAvBwE,KArD5D,oBAAA;;;;;;KAOA,yBAAA,GAA4B,cAAA;EAsF3B,iCApFX,IAAA,EAAM,oBAAoB;EAE1B,IAAA,UAwF6C;EAtF7C,OAAA,WAgF4C;EA9E5C,YAAA,WA8EqC;EA5ErC,UAAA,WA8EsB;EA5EtB,SAAA;AAAA;;;;;AAgFqE;;;;;;;;;;cA/D1D,kBAAA,SAA2B,OAAA;;WAEtB,IAAA,EAAM,oBAAA;;WAEN,IAAA;;WAEA,OAAA;;WAEA,YAAA;;WAEA,UAAA;;;;;WAKA,SAAA;cAEG,OAAA,UAAiB,OAAA,EAAS,yBAAA;AAAA;;;;;;;;KAoBnC,mBAAA;;KAGA,wBAAA,GAA2B,cAAA;kCAErC,IAAA,EAAM,mBAAmB;EAEzB,KAAA;AAAA;;;;;;;;;;;cAaW,iBAAA,SAA0B,OAAA;;WAErB,IAAA,EAAM,mBAAA;;WAEN,KAAA;cAEG,OAAA,UAAiB,OAAA,EAAS,wBAAA;AAAA"}
|
package/esm/errors.mjs
CHANGED
|
@@ -26,6 +26,8 @@ var WorkspacePolicyError = class extends AIError {
|
|
|
26
26
|
this.path = options.path;
|
|
27
27
|
this.command = options.command;
|
|
28
28
|
this.pattern = options.pattern;
|
|
29
|
+
this.reason = options.reason;
|
|
30
|
+
this.executable = options.executable;
|
|
29
31
|
}
|
|
30
32
|
};
|
|
31
33
|
/**
|
|
@@ -51,9 +53,28 @@ var WorkspaceEditError = class extends AIError {
|
|
|
51
53
|
this.matches = options.matches;
|
|
52
54
|
this.expectedHash = options.expectedHash;
|
|
53
55
|
this.actualHash = options.actualHash;
|
|
56
|
+
this.editIndex = options.editIndex;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* A `shell_output` / `shell_kill` call (or `shellOutput()` / `shellKill()`)
|
|
61
|
+
* named a background command this workspace does not know. Returned to the
|
|
62
|
+
* agent as tool-error data like the other workspace errors.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* if (error instanceof WorkspaceJobError && error.type === "not-found") {
|
|
66
|
+
* console.warn(`No background command ${error.jobId}`);
|
|
67
|
+
* }
|
|
68
|
+
*/
|
|
69
|
+
var WorkspaceJobError = class extends AIError {
|
|
70
|
+
constructor(message, options) {
|
|
71
|
+
super("TOOL_EXEC_FAILED", message, options);
|
|
72
|
+
this.name = "WorkspaceJobError";
|
|
73
|
+
this.type = options.type;
|
|
74
|
+
this.jobId = options.jobId;
|
|
54
75
|
}
|
|
55
76
|
};
|
|
56
77
|
|
|
57
78
|
//#endregion
|
|
58
|
-
export { WorkspaceEditError, WorkspacePolicyError };
|
|
79
|
+
export { WorkspaceEditError, WorkspaceJobError, WorkspacePolicyError };
|
|
59
80
|
//# sourceMappingURL=errors.mjs.map
|
package/esm/errors.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.mjs","names":[],"sources":["../../../../../../../packages/ai-workspace/src/errors.ts"],"sourcesContent":["import { AIError, type AIErrorOptions } from \"@warlock.js/ai\";\n\n/**\n * Why a workspace policy check rejected an operation.\n *\n * - `\"path-escape\"` — a resolved path fell outside the `cwd` jail (or an\n * `allowPaths` root), or matched a `denyPaths` glob.\n * - `\"denied-command\"` — a shell command's leading executable basename\n * was not in `shell.allow`, or was explicitly in `shell.deny`.\n * - `\"unsafe-pattern\"` — a `grep` pattern was too long or matched a\n * catastrophic-backtracking shape (nested quantifiers) that could hang\n * the process (ReDoS).\n */\nexport type WorkspacePolicyViolation = \"path-escape\" | \"denied-command\" | \"unsafe-pattern\";\n\n/**\n * Options for {@link WorkspacePolicyError} — the structured `type`\n * discriminator plus, where relevant, the offending path or command for\n * branchable diagnostics without parsing the message.\n */\nexport type WorkspacePolicyErrorOptions = AIErrorOptions & {\n /** Which policy rule was violated. */\n type: WorkspacePolicyViolation;\n /** The offending workspace-relative path (for `\"path-escape\"`). */\n path?: string;\n /** The offending command line (for `\"denied-command\"`). */\n command?: string;\n /** The offending regex pattern (for `\"unsafe-pattern\"`). */\n pattern?: string;\n};\n\n/**\n * The workspace policy engine refused an operation — a path escaped the\n * jail (or hit a deny glob), or a shell command's executable was not\n * allowed.\n *\n * **Surface.** This is returned to the agent as tool-error *data*, never\n * a thrown run-killer — the agent reads the failure and self-corrects.\n * Extends the framework `AIError` (category `\"tool\"`, code\n * `TOOL_EXEC_FAILED`) so it flows through the same typed error contract\n * as every other AI error; branch on `error.type` for the specific\n * violation.\n *\n * @example\n * if (error instanceof WorkspacePolicyError && error.type === \"denied-command\") {\n * console.warn(`Blocked command: ${error.command}`);\n * }\n */\nexport class WorkspacePolicyError extends AIError {\n /** Which policy rule was violated. */\n public readonly type: WorkspacePolicyViolation;\n /** The offending path, when the violation was a path escape. */\n public readonly path?: string;\n /** The offending command, when the violation was a denied command. */\n public readonly command?: string;\n /** The offending regex pattern, when the violation was `\"unsafe-pattern\"`. */\n public readonly pattern?: string;\n\n public constructor(message: string, options: WorkspacePolicyErrorOptions) {\n super(\"TOOL_EXEC_FAILED\", message, options);\n\n this.name = \"WorkspacePolicyError\";\n this.type = options.type;\n this.path = options.path;\n this.command = options.command;\n this.pattern = options.pattern;\n }\n}\n\n/**\n * Why an edit was rejected.\n *\n * - `\"not-found\"` — the `oldString` did not appear in the file.\n * - `\"not-unique\"` — `oldString` matched more than once and `replaceAll`\n * was not set, so the edit is ambiguous.\n * - `\"stale-hash\"` — the file's current hash did not match the supplied\n * `expectHash`; the file changed since it was read.\n */\nexport type WorkspaceEditFailure = \"not-found\" | \"not-unique\" | \"stale-hash\";\n\n/**\n * Options for {@link WorkspaceEditError} — the structured `type`\n * discriminator plus optional match-count / hash context for the\n * `\"not-unique\"` and `\"stale-hash\"` cases.\n */\nexport type WorkspaceEditErrorOptions = AIErrorOptions & {\n /** Why the edit was rejected. */\n type: WorkspaceEditFailure;\n /** The edited file's workspace-relative path. */\n path: string;\n /** How many times `oldString` matched (for `\"not-unique\"`). */\n matches?: number;\n /** The hash the caller expected (for `\"stale-hash\"`). */\n expectedHash?: string;\n /** The file's actual current hash (for `\"stale-hash\"`). */\n actualHash?: string;\n};\n\n/**\n * An `editFile` operation was rejected by the read-before-edit guard:\n * the `oldString` was absent, matched non-uniquely without `replaceAll`,\n * or the file's hash no longer matched the supplied `expectHash`.\n *\n * **Surface.** Like {@link WorkspacePolicyError}, returned to the agent\n * as tool-error *data* so it can re-read and retry. Extends `AIError`\n * (category `\"tool\"`, code `TOOL_EXEC_FAILED`); branch on `error.type`.\n *\n * @example\n * if (error instanceof WorkspaceEditError && error.type === \"stale-hash\") {\n * // re-read the file and retry the edit with the fresh hash\n * }\n */\nexport class WorkspaceEditError extends AIError {\n /** Why the edit was rejected. */\n public readonly type: WorkspaceEditFailure;\n /** The edited file's workspace-relative path. */\n public readonly path: string;\n /** How many times `oldString` matched, for the `\"not-unique\"` case. */\n public readonly matches?: number;\n /** The hash the caller expected, for the `\"stale-hash\"` case. */\n public readonly expectedHash?: string;\n /** The file's actual current hash, for the `\"stale-hash\"` case. */\n public readonly actualHash?: string;\n\n public constructor(message: string, options: WorkspaceEditErrorOptions) {\n super(\"TOOL_EXEC_FAILED\", message, options);\n\n this.name = \"WorkspaceEditError\";\n this.type = options.type;\n this.path = options.path;\n this.matches = options.matches;\n this.expectedHash = options.expectedHash;\n this.actualHash = options.actualHash;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgDA,IAAa,uBAAb,cAA0C,QAAQ;CAUhD,AAAO,YAAY,SAAiB,SAAsC;EACxE,MAAM,oBAAoB,SAAS,OAAO;EAE1C,KAAK,OAAO;EACZ,KAAK,OAAO,QAAQ;EACpB,KAAK,OAAO,QAAQ;EACpB,KAAK,UAAU,QAAQ;EACvB,KAAK,UAAU,QAAQ;CACzB;AACF;;;;;;;;;;;;;;;AA6CA,IAAa,qBAAb,cAAwC,QAAQ;CAY9C,AAAO,YAAY,SAAiB,SAAoC;EACtE,MAAM,oBAAoB,SAAS,OAAO;EAE1C,KAAK,OAAO;EACZ,KAAK,OAAO,QAAQ;EACpB,KAAK,OAAO,QAAQ;EACpB,KAAK,UAAU,QAAQ;EACvB,KAAK,eAAe,QAAQ;EAC5B,KAAK,aAAa,QAAQ;CAC5B;AACF"}
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":[],"sources":["../../../../../../../packages/ai-workspace/src/errors.ts"],"sourcesContent":["import { AIError, type AIErrorOptions } from \"@warlock.js/ai\";\n\n/**\n * Why a workspace policy check rejected an operation.\n *\n * - `\"path-escape\"` — a resolved path fell outside the `cwd` jail (or an\n * `allowPaths` root), or matched a `denyPaths` glob.\n * - `\"denied-command\"` — the shell policy refused a command line (`reason`\n * says why: an executable outside `shell.allow` or inside `shell.deny`, a\n * metacharacter in argv mode, a redirection outside the jail in shell\n * mode, …), or a mutating method was called on a read-only projection.\n * - `\"unsafe-pattern\"` — a `grep` pattern was too long or matched a\n * catastrophic-backtracking shape (nested quantifiers) that could hang\n * the process (ReDoS).\n */\nexport type WorkspacePolicyViolation = \"path-escape\" | \"denied-command\" | \"unsafe-pattern\";\n\n/**\n * Why the shell policy refused a command. Set on every\n * {@link WorkspacePolicyError} of type `\"denied-command\"` raised for a\n * command line, so a host can phrase the refusal itself instead of parsing\n * the message.\n *\n * - `\"metacharacter\"` — argv mode (the default `interpreter: \"none\"`) met an\n * unquoted shell operator (`&&`, `;`, `|`, `>`, `$`, backticks, …). The\n * message suggests how to split the line into separate commands.\n * - `\"unbalanced-quotes\"` — a quote is never closed.\n * - `\"denied-executable\"` — a command's executable is listed in `shell.deny`.\n * - `\"not-allowed\"` — a command's executable is not in `shell.allow`, the\n * `shell.allowCommand` hook refused it, the workspace has no shell policy,\n * the line is empty, or background commands are not enabled.\n * - `\"denied-pattern\"` — a command matched one of `shell.denyPatterns`.\n * - `\"nested-command\"` — a command runs another command the policy cannot\n * inspect (`bash -c …`, `eval`, `xargs`, `sudo`, a wrapper with options the\n * policy cannot read), while the policy has deny rules it would bypass.\n * - `\"unsupported-syntax\"` — shell mode (`interpreter: \"sh\"`) met syntax the\n * policy does not parse with confidence (compound commands, arithmetic,\n * brace expansion, background `&`, a command name decided at run time, …),\n * so the line is refused rather than guessed at.\n * - `\"path-escape\"` — shell mode: a redirection target or `cd` directory\n * resolves outside the workspace jail or hits `denyPaths`.\n */\nexport type WorkspaceShellRefusalReason =\n | \"metacharacter\"\n | \"unbalanced-quotes\"\n | \"denied-executable\"\n | \"not-allowed\"\n | \"denied-pattern\"\n | \"nested-command\"\n | \"unsupported-syntax\"\n | \"path-escape\";\n\n/**\n * Options for {@link WorkspacePolicyError} — the structured `type`\n * discriminator plus, where relevant, the offending path or command for\n * branchable diagnostics without parsing the message.\n */\nexport type WorkspacePolicyErrorOptions = AIErrorOptions & {\n /** Which policy rule was violated. */\n type: WorkspacePolicyViolation;\n /** The offending workspace-relative path (for `\"path-escape\"`). */\n path?: string;\n /** The offending command line (for `\"denied-command\"`). */\n command?: string;\n /** The offending regex pattern (for `\"unsafe-pattern\"`). */\n pattern?: string;\n /** Why the shell policy refused the command (for `\"denied-command\"`). */\n reason?: WorkspaceShellRefusalReason;\n /** The executable the refusal is about, when there is one. */\n executable?: string;\n};\n\n/**\n * The workspace policy engine refused an operation — a path escaped the\n * jail (or hit a deny glob), or a shell command's executable was not\n * allowed.\n *\n * **Surface.** This is returned to the agent as tool-error *data*, never\n * a thrown run-killer — the agent reads the failure and self-corrects.\n * Extends the framework `AIError` (category `\"tool\"`, code\n * `TOOL_EXEC_FAILED`) so it flows through the same typed error contract\n * as every other AI error; branch on `error.type` for the specific\n * violation.\n *\n * @example\n * if (error instanceof WorkspacePolicyError && error.type === \"denied-command\") {\n * console.warn(`Blocked command: ${error.command}`);\n * }\n */\nexport class WorkspacePolicyError extends AIError {\n /** Which policy rule was violated. */\n public readonly type: WorkspacePolicyViolation;\n /** The offending path, when the violation was a path escape. */\n public readonly path?: string;\n /** The offending command, when the violation was a denied command. */\n public readonly command?: string;\n /** The offending regex pattern, when the violation was `\"unsafe-pattern\"`. */\n public readonly pattern?: string;\n /**\n * Why the shell policy refused a command line — set on every\n * `\"denied-command\"` refusal of a command (see\n * {@link WorkspaceShellRefusalReason}).\n */\n public readonly reason?: WorkspaceShellRefusalReason;\n /** The executable the shell refusal is about, when there is one. */\n public readonly executable?: string;\n\n public constructor(message: string, options: WorkspacePolicyErrorOptions) {\n super(\"TOOL_EXEC_FAILED\", message, options);\n\n this.name = \"WorkspacePolicyError\";\n this.type = options.type;\n this.path = options.path;\n this.command = options.command;\n this.pattern = options.pattern;\n this.reason = options.reason;\n this.executable = options.executable;\n }\n}\n\n/**\n * Why an edit was rejected.\n *\n * - `\"not-found\"` — the `oldString` did not appear in the file.\n * - `\"not-unique\"` — `oldString` matched more than once and `replaceAll`\n * was not set, so the edit is ambiguous.\n * - `\"stale-hash\"` — the file's current hash did not match the supplied\n * `expectHash`; the file changed since it was read.\n */\nexport type WorkspaceEditFailure = \"not-found\" | \"not-unique\" | \"stale-hash\";\n\n/**\n * Options for {@link WorkspaceEditError} — the structured `type`\n * discriminator plus optional match-count / hash context for the\n * `\"not-unique\"` and `\"stale-hash\"` cases.\n */\nexport type WorkspaceEditErrorOptions = AIErrorOptions & {\n /** Why the edit was rejected. */\n type: WorkspaceEditFailure;\n /** The edited file's workspace-relative path. */\n path: string;\n /** How many times `oldString` matched (for `\"not-unique\"`). */\n matches?: number;\n /** The hash the caller expected (for `\"stale-hash\"`). */\n expectedHash?: string;\n /** The file's actual current hash (for `\"stale-hash\"`). */\n actualHash?: string;\n /** 0-based index of the failing edit, for a `multiEdit` rejection. */\n editIndex?: number;\n};\n\n/**\n * An `editFile` operation was rejected by the read-before-edit guard:\n * the `oldString` was absent, matched non-uniquely without `replaceAll`,\n * or the file's hash no longer matched the supplied `expectHash`.\n *\n * **Surface.** Like {@link WorkspacePolicyError}, returned to the agent\n * as tool-error *data* so it can re-read and retry. Extends `AIError`\n * (category `\"tool\"`, code `TOOL_EXEC_FAILED`); branch on `error.type`.\n *\n * @example\n * if (error instanceof WorkspaceEditError && error.type === \"stale-hash\") {\n * // re-read the file and retry the edit with the fresh hash\n * }\n */\nexport class WorkspaceEditError extends AIError {\n /** Why the edit was rejected. */\n public readonly type: WorkspaceEditFailure;\n /** The edited file's workspace-relative path. */\n public readonly path: string;\n /** How many times `oldString` matched, for the `\"not-unique\"` case. */\n public readonly matches?: number;\n /** The hash the caller expected, for the `\"stale-hash\"` case. */\n public readonly expectedHash?: string;\n /** The file's actual current hash, for the `\"stale-hash\"` case. */\n public readonly actualHash?: string;\n /**\n * For a `multiEdit` rejection, the 0-based index of the edit that failed.\n * Nothing was written: a multi-edit applies all of its edits or none.\n */\n public readonly editIndex?: number;\n\n public constructor(message: string, options: WorkspaceEditErrorOptions) {\n super(\"TOOL_EXEC_FAILED\", message, options);\n\n this.name = \"WorkspaceEditError\";\n this.type = options.type;\n this.path = options.path;\n this.matches = options.matches;\n this.expectedHash = options.expectedHash;\n this.actualHash = options.actualHash;\n this.editIndex = options.editIndex;\n }\n}\n\n/**\n * Why a background-command operation failed.\n *\n * - `\"not-found\"` — no background command with that id exists in this\n * workspace (it never existed, or it finished long enough ago to be\n * pruned).\n */\nexport type WorkspaceJobFailure = \"not-found\";\n\n/** Options for {@link WorkspaceJobError}. */\nexport type WorkspaceJobErrorOptions = AIErrorOptions & {\n /** Why the operation failed. */\n type: WorkspaceJobFailure;\n /** The background command id the caller asked for. */\n jobId: string;\n};\n\n/**\n * A `shell_output` / `shell_kill` call (or `shellOutput()` / `shellKill()`)\n * named a background command this workspace does not know. Returned to the\n * agent as tool-error data like the other workspace errors.\n *\n * @example\n * if (error instanceof WorkspaceJobError && error.type === \"not-found\") {\n * console.warn(`No background command ${error.jobId}`);\n * }\n */\nexport class WorkspaceJobError extends AIError {\n /** Why the operation failed. */\n public readonly type: WorkspaceJobFailure;\n /** The background command id the caller asked for. */\n public readonly jobId: string;\n\n public constructor(message: string, options: WorkspaceJobErrorOptions) {\n super(\"TOOL_EXEC_FAILED\", message, options);\n\n this.name = \"WorkspaceJobError\";\n this.type = options.type;\n this.jobId = options.jobId;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAyFA,IAAa,uBAAb,cAA0C,QAAQ;CAkBhD,AAAO,YAAY,SAAiB,SAAsC;EACxE,MAAM,oBAAoB,SAAS,OAAO;EAE1C,KAAK,OAAO;EACZ,KAAK,OAAO,QAAQ;EACpB,KAAK,OAAO,QAAQ;EACpB,KAAK,UAAU,QAAQ;EACvB,KAAK,UAAU,QAAQ;EACvB,KAAK,SAAS,QAAQ;EACtB,KAAK,aAAa,QAAQ;CAC5B;AACF;;;;;;;;;;;;;;;AA+CA,IAAa,qBAAb,cAAwC,QAAQ;CAiB9C,AAAO,YAAY,SAAiB,SAAoC;EACtE,MAAM,oBAAoB,SAAS,OAAO;EAE1C,KAAK,OAAO;EACZ,KAAK,OAAO,QAAQ;EACpB,KAAK,OAAO,QAAQ;EACpB,KAAK,UAAU,QAAQ;EACvB,KAAK,eAAe,QAAQ;EAC5B,KAAK,aAAa,QAAQ;EAC1B,KAAK,YAAY,QAAQ;CAC3B;AACF;;;;;;;;;;;AA6BA,IAAa,oBAAb,cAAuC,QAAQ;CAM7C,AAAO,YAAY,SAAiB,SAAmC;EACrE,MAAM,oBAAoB,SAAS,OAAO;EAE1C,KAAK,OAAO;EACZ,KAAK,OAAO,QAAQ;EACpB,KAAK,QAAQ,QAAQ;CACvB;AACF"}
|
package/esm/index.d.mts
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
|
-
import { EditFileInput, EditFileResult, ExecOptions, GlobInput, GlobResult, GrepInput, GrepMatch, GrepResult, ReadFileInput, ReadFileResult, RunShellInput, RunShellResult, RunTestsInput, WorkspaceToolName, WriteFileInput, WriteFileResult } from "./contracts/tool-io.type.mjs";
|
|
2
|
-
import {
|
|
1
|
+
import { 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 } from "./contracts/tool-io.type.mjs";
|
|
2
|
+
import { WorkspaceAllowCommand, WorkspaceBackendType, WorkspaceBackgroundPolicy, WorkspaceCommandCheckContext, WorkspaceCommandPattern, WorkspaceListPolicy, WorkspacePolicy, WorkspaceReadPolicy, WorkspaceShellInterpreter, WorkspaceShellPolicy } from "./contracts/workspace-policy.type.mjs";
|
|
3
|
+
import { WorkspaceBackend, WorkspaceBackendExecOptions, WorkspaceBackendExecResult, WorkspaceBackendProcess, WorkspaceBackendStartOptions, WorkspaceBackendStat, WorkspaceOutputStream } from "./contracts/workspace-backend.contract.mjs";
|
|
3
4
|
import { WorkspaceOps } from "./contracts/workspace-ops.contract.mjs";
|
|
4
|
-
import { WorkspaceBackendType, WorkspacePolicy, WorkspaceReadPolicy, WorkspaceShellPolicy } from "./contracts/workspace-policy.type.mjs";
|
|
5
5
|
import { Workspace, WorkspaceTools } from "./contracts/workspace.contract.mjs";
|
|
6
|
-
import { WorkspaceEditError, WorkspaceEditErrorOptions, WorkspaceEditFailure, WorkspacePolicyError, WorkspacePolicyErrorOptions, WorkspacePolicyViolation } from "./errors.mjs";
|
|
6
|
+
import { WorkspaceEditError, WorkspaceEditErrorOptions, WorkspaceEditFailure, WorkspaceJobError, WorkspaceJobErrorOptions, WorkspaceJobFailure, WorkspacePolicyError, WorkspacePolicyErrorOptions, WorkspacePolicyViolation, WorkspaceShellRefusalReason } from "./errors.mjs";
|
|
7
7
|
import { ResolvedPath, buildEnv, isCommandAllowed, resolveInJail } from "./policy/policy.mjs";
|
|
8
|
+
import { WorkspaceShellCheck, WorkspaceShellPath, WorkspaceShellPathAccess, checkShellCommand } from "./policy/shell-check.mjs";
|
|
9
|
+
import { ArgvAnalysis, analyzeArgvCommand, tokenizeCommand } from "./policy/tokenize-command.mjs";
|
|
8
10
|
import { createOps } from "./ops.mjs";
|
|
9
11
|
import { createLocalBackend } from "./backends/local.mjs";
|
|
10
12
|
import { MockBackendSeed, MockExecResult, createMockBackend } from "./backends/mock.mjs";
|
|
11
13
|
import { makeEditFileTool } from "./tools/edit-file.mjs";
|
|
12
14
|
import { MakeGlobToolOptions, makeGlobTool } from "./tools/glob.mjs";
|
|
13
15
|
import { MakeGrepToolOptions, makeGrepTool } from "./tools/grep.mjs";
|
|
16
|
+
import { makeListDirTool } from "./tools/list-dir.mjs";
|
|
17
|
+
import { makeMultiEditTool } from "./tools/multi-edit.mjs";
|
|
14
18
|
import { makeReadFileTool } from "./tools/read-file.mjs";
|
|
15
19
|
import { MakeRunShellToolOptions, makeRunShellTool } from "./tools/run-shell.mjs";
|
|
16
20
|
import { MakeRunTestsToolOptions, makeRunTestsTool } from "./tools/run-tests.mjs";
|
|
21
|
+
import { makeShellKillTool } from "./tools/shell-kill.mjs";
|
|
22
|
+
import { makeShellOutputTool } from "./tools/shell-output.mjs";
|
|
23
|
+
import { TodoStore } from "./todos.mjs";
|
|
24
|
+
import { makeTodoReadTool, makeTodoWriteTool } from "./tools/todo.mjs";
|
|
17
25
|
import { makeWriteFileTool } from "./tools/write-file.mjs";
|
|
18
26
|
import { workspace } from "./workspace.mjs";
|
|
19
|
-
export { type EditFileInput, type EditFileResult, type ExecOptions, type GlobInput, type GlobResult, type GrepInput, type GrepMatch, type GrepResult, type MakeGlobToolOptions, type MakeGrepToolOptions, type MakeRunShellToolOptions, type MakeRunTestsToolOptions, type MockBackendSeed, type MockExecResult, type ReadFileInput, type ReadFileResult, type ResolvedPath, type RunShellInput, type RunShellResult, type RunTestsInput, type Workspace, type WorkspaceBackend, type WorkspaceBackendExecOptions, type WorkspaceBackendExecResult, type WorkspaceBackendType, WorkspaceEditError, type WorkspaceEditErrorOptions, type WorkspaceEditFailure, type WorkspaceOps, type WorkspacePolicy, WorkspacePolicyError, type WorkspacePolicyErrorOptions, type WorkspacePolicyViolation, type WorkspaceReadPolicy, type WorkspaceShellPolicy, type WorkspaceToolName, type WorkspaceTools, type WriteFileInput, type WriteFileResult, buildEnv, createLocalBackend, createMockBackend, createOps, isCommandAllowed, makeEditFileTool, makeGlobTool, makeGrepTool, makeReadFileTool, makeRunShellTool, makeRunTestsTool, makeWriteFileTool, resolveInJail, workspace };
|
|
27
|
+
export { type ArgvAnalysis, type EditFileInput, type EditFileResult, type ExecOptions, type GlobInput, type GlobResult, type GrepInput, type GrepMatch, type GrepResult, type ListDirEntry, type ListDirEntryType, type ListDirInput, type ListDirOptions, type ListDirResult, type MakeGlobToolOptions, type MakeGrepToolOptions, type MakeRunShellToolOptions, type MakeRunTestsToolOptions, type MockBackendSeed, type MockExecResult, type MultiEditInput, type MultiEditOperation, type MultiEditResult, type ReadFileInput, type ReadFileResult, type ResolvedPath, type RunShellBackgroundResult, type RunShellInput, type RunShellResult, type RunTestsInput, type ShellJobInfo, type ShellJobStatus, type ShellKillInput, type ShellOutputInput, type ShellOutputOptions, type ShellOutputResult, type StartShellOptions, type TodoListResult, TodoStore, type TodoWriteInput, type Workspace, type WorkspaceAllowCommand, type WorkspaceBackend, type WorkspaceBackendExecOptions, type WorkspaceBackendExecResult, type WorkspaceBackendProcess, type WorkspaceBackendStartOptions, type WorkspaceBackendStat, type WorkspaceBackendType, type WorkspaceBackgroundPolicy, type WorkspaceCommandCheckContext, type WorkspaceCommandPattern, WorkspaceEditError, type WorkspaceEditErrorOptions, type WorkspaceEditFailure, WorkspaceJobError, type WorkspaceJobErrorOptions, type WorkspaceJobFailure, type WorkspaceListPolicy, type WorkspaceOps, type WorkspaceOutputStream, type WorkspacePolicy, WorkspacePolicyError, type WorkspacePolicyErrorOptions, type WorkspacePolicyViolation, type WorkspaceReadPolicy, type WorkspaceShellCheck, type WorkspaceShellInterpreter, type WorkspaceShellPath, type WorkspaceShellPathAccess, type WorkspaceShellPolicy, type WorkspaceShellRefusalReason, type WorkspaceTodo, type WorkspaceTodoInput, type WorkspaceTodoStatus, type WorkspaceToolName, type WorkspaceTools, type WriteFileInput, type WriteFileResult, analyzeArgvCommand, buildEnv, checkShellCommand, createLocalBackend, createMockBackend, createOps, isCommandAllowed, makeEditFileTool, makeGlobTool, makeGrepTool, makeListDirTool, makeMultiEditTool, makeReadFileTool, makeRunShellTool, makeRunTestsTool, makeShellKillTool, makeShellOutputTool, makeTodoReadTool, makeTodoWriteTool, makeWriteFileTool, resolveInJail, tokenizeCommand, workspace };
|
|
20
28
|
import "./workspace.mjs";
|
package/esm/index.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { WorkspaceEditError, WorkspacePolicyError } from "./errors.mjs";
|
|
1
|
+
import { WorkspaceEditError, WorkspaceJobError, WorkspacePolicyError } from "./errors.mjs";
|
|
2
|
+
import { analyzeArgvCommand, tokenizeCommand } from "./policy/tokenize-command.mjs";
|
|
3
|
+
import { checkShellCommand } from "./policy/shell-check.mjs";
|
|
2
4
|
import { buildEnv, isCommandAllowed, resolveInJail } from "./policy/policy.mjs";
|
|
3
5
|
import { createOps } from "./ops.mjs";
|
|
4
6
|
import { createLocalBackend } from "./backends/local.mjs";
|
|
@@ -6,10 +8,16 @@ import { createMockBackend } from "./backends/mock.mjs";
|
|
|
6
8
|
import { makeEditFileTool } from "./tools/edit-file.mjs";
|
|
7
9
|
import { makeGlobTool } from "./tools/glob.mjs";
|
|
8
10
|
import { makeGrepTool } from "./tools/grep.mjs";
|
|
11
|
+
import { makeListDirTool } from "./tools/list-dir.mjs";
|
|
12
|
+
import { makeMultiEditTool } from "./tools/multi-edit.mjs";
|
|
9
13
|
import { makeReadFileTool } from "./tools/read-file.mjs";
|
|
10
14
|
import { makeRunShellTool } from "./tools/run-shell.mjs";
|
|
11
15
|
import { makeRunTestsTool } from "./tools/run-tests.mjs";
|
|
16
|
+
import { makeShellKillTool } from "./tools/shell-kill.mjs";
|
|
17
|
+
import { makeShellOutputTool } from "./tools/shell-output.mjs";
|
|
18
|
+
import { TodoStore } from "./todos.mjs";
|
|
19
|
+
import { makeTodoReadTool, makeTodoWriteTool } from "./tools/todo.mjs";
|
|
12
20
|
import { makeWriteFileTool } from "./tools/write-file.mjs";
|
|
13
21
|
import { workspace } from "./workspace.mjs";
|
|
14
22
|
|
|
15
|
-
export { WorkspaceEditError, WorkspacePolicyError, buildEnv, createLocalBackend, createMockBackend, createOps, isCommandAllowed, makeEditFileTool, makeGlobTool, makeGrepTool, makeReadFileTool, makeRunShellTool, makeRunTestsTool, makeWriteFileTool, resolveInJail, workspace };
|
|
23
|
+
export { TodoStore, WorkspaceEditError, WorkspaceJobError, WorkspacePolicyError, analyzeArgvCommand, buildEnv, checkShellCommand, createLocalBackend, createMockBackend, createOps, isCommandAllowed, makeEditFileTool, makeGlobTool, makeGrepTool, makeListDirTool, makeMultiEditTool, makeReadFileTool, makeRunShellTool, makeRunTestsTool, makeShellKillTool, makeShellOutputTool, makeTodoReadTool, makeTodoWriteTool, makeWriteFileTool, resolveInJail, tokenizeCommand, workspace };
|
package/esm/ops.d.mts
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
|
+
import { WorkspacePolicy } from "./contracts/workspace-policy.type.mjs";
|
|
1
2
|
import { WorkspaceBackend } from "./contracts/workspace-backend.contract.mjs";
|
|
2
3
|
import { WorkspaceOps } from "./contracts/workspace-ops.contract.mjs";
|
|
3
|
-
import {
|
|
4
|
+
import { ShellJobs } from "./shell-jobs.mjs";
|
|
5
|
+
|
|
4
6
|
//#region ../../packages/ai-workspace/src/ops.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* The internal, single-instance implementation of {@link WorkspaceOps}.
|
|
9
|
+
* Holds the backend + policy and is the one place the jail, command
|
|
10
|
+
* gating, read caps, and the read-before-edit guard are enforced — both
|
|
11
|
+
* the agent-facing tools and the human-facing direct methods funnel
|
|
12
|
+
* through this object, so there is exactly one set of rules.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* State an ops layer shares with the other projections of the same
|
|
16
|
+
* workspace (`readonly()`, `scope()`): the background commands it owns.
|
|
17
|
+
*/
|
|
18
|
+
interface OpsRuntime {
|
|
19
|
+
/** The workspace's background commands. */
|
|
20
|
+
jobs: ShellJobs;
|
|
21
|
+
}
|
|
5
22
|
/**
|
|
6
23
|
* Create the policy-enforced operation layer over a backend.
|
|
7
24
|
*
|
|
@@ -14,12 +31,14 @@ import { WorkspacePolicy } from "./contracts/workspace-policy.type.mjs";
|
|
|
14
31
|
*
|
|
15
32
|
* @param backend - The dumb IO executor (local disk or in-memory mock).
|
|
16
33
|
* @param policy - The policy that bounds every operation.
|
|
34
|
+
* @param runtime - State shared with other views of the same workspace
|
|
35
|
+
* (its background commands); a fresh one when omitted.
|
|
17
36
|
*
|
|
18
37
|
* @example
|
|
19
38
|
* const ops = createOps(localBackend, { cwd: "/srv/api", shell: { allow: ["npm"] } });
|
|
20
39
|
* const { content, hash } = await ops.readFile("src/index.ts");
|
|
21
40
|
*/
|
|
22
|
-
declare function createOps(backend: WorkspaceBackend, policy: WorkspacePolicy): WorkspaceOps;
|
|
41
|
+
declare function createOps(backend: WorkspaceBackend, policy: WorkspacePolicy, runtime?: OpsRuntime): WorkspaceOps;
|
|
23
42
|
//#endregion
|
|
24
43
|
export { createOps };
|
|
25
44
|
//# sourceMappingURL=ops.d.mts.map
|
package/esm/ops.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ops.d.mts","names":[],"sources":["../../../../../../../packages/ai-workspace/src/ops.ts"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"ops.d.mts","names":[],"sources":["../../../../../../../packages/ai-workspace/src/ops.ts"],"mappings":";;;;;;;;;AA8LA;;;;AAEiB;AAitBjB;;;AAjtBiB,UAFA,UAAA;EAqtBP;EAntBR,IAAA,EAAM,SAAS;AAAA;;;;;;;;;;;AAqtBF;;;;;;;;;iBAJC,SAAA,CACd,OAAA,EAAS,gBAAA,EACT,MAAA,EAAQ,eAAA,EACR,OAAA,GAAU,UAAA,GACT,YAAA"}
|