@warlock.js/ai-workspace 5.39.1 → 5.40.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 +14 -0
- package/README.md +2 -2
- package/cjs/index.cjs +691 -114
- package/cjs/index.cjs.map +1 -1
- package/esm/contracts/index.d.mts +2 -2
- package/esm/contracts/tool-io.type.d.mts +32 -1
- package/esm/contracts/tool-io.type.d.mts.map +1 -1
- package/esm/contracts/workspace-ops.contract.d.mts +10 -1
- package/esm/contracts/workspace-ops.contract.d.mts.map +1 -1
- package/esm/contracts/workspace.contract.d.mts +7 -1
- package/esm/contracts/workspace.contract.d.mts.map +1 -1
- package/esm/errors.d.mts +17 -1
- package/esm/errors.d.mts.map +1 -1
- package/esm/errors.mjs +1 -0
- package/esm/errors.mjs.map +1 -1
- package/esm/index.d.mts +6 -2
- package/esm/index.mjs +5 -1
- package/esm/ops.d.mts.map +1 -1
- package/esm/ops.mjs +16 -0
- package/esm/ops.mjs.map +1 -1
- package/esm/patch/apply-hunks.d.mts +14 -0
- package/esm/patch/apply-hunks.d.mts.map +1 -0
- package/esm/patch/apply-hunks.mjs +89 -0
- package/esm/patch/apply-hunks.mjs.map +1 -0
- package/esm/patch/apply-patch-generic.d.mts +14 -0
- package/esm/patch/apply-patch-generic.d.mts.map +1 -0
- package/esm/patch/apply-patch-generic.mjs +68 -0
- package/esm/patch/apply-patch-generic.mjs.map +1 -0
- package/esm/patch/execute-patch.mjs +151 -0
- package/esm/patch/execute-patch.mjs.map +1 -0
- package/esm/patch/parse-patch.d.mts +45 -0
- package/esm/patch/parse-patch.d.mts.map +1 -0
- package/esm/patch/parse-patch.mjs +201 -0
- package/esm/patch/parse-patch.mjs.map +1 -0
- package/esm/tools/apply-patch.d.mts +27 -0
- package/esm/tools/apply-patch.d.mts.map +1 -0
- package/esm/tools/apply-patch.mjs +61 -0
- package/esm/tools/apply-patch.mjs.map +1 -0
- package/esm/tools/edit-file.mjs +1 -1
- package/esm/tools/glob.mjs +1 -1
- package/esm/tools/grep.mjs +1 -1
- package/esm/tools/json-schemas.mjs +10 -1
- package/esm/tools/json-schemas.mjs.map +1 -1
- package/esm/tools/list-dir.mjs +1 -1
- package/esm/tools/multi-edit.mjs +1 -1
- package/esm/tools/read-file.mjs +1 -1
- package/esm/tools/run-shell.mjs +1 -1
- package/esm/tools/run-tests.mjs +1 -1
- package/esm/tools/shell-kill.mjs +1 -1
- package/esm/tools/shell-output.mjs +1 -1
- package/esm/tools/todo.mjs +1 -1
- package/esm/tools/write-file.mjs +1 -1
- package/esm/workspace.d.mts.map +1 -1
- package/esm/workspace.mjs +9 -0
- package/esm/workspace.mjs.map +1 -1
- package/llms-full.txt +7 -6
- package/llms.txt +2 -2
- package/package.json +3 -3
- package/skills/build-loop-agent/SKILL.md +1 -1
- package/skills/index.md +1 -1
- package/skills/use-a-workspace/SKILL.md +5 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: use-a-workspace
|
|
3
|
-
description: 'Build and operate a policy-jailed filesystem + shell workspace with @warlock.js/ai-workspace. Triggers: `ai.workspace`, `workspace(`, `WorkspacePolicy`, `WorkspaceShellPolicy`, `WorkspaceToolName`, `ws.tools.all`, `ws.tools.pick`, `ws.readFile`, `ws.writeFile`, `ws.editFile`, `ws.exec`, `ws.grep`, `ws.glob`, `ws.readonly`, `ws.scope`, `ws.multiEdit`, `ws.listDir`, `ws.startShell`, `ws.shellOutput`, `ws.shellKill`, `ws.dispose`, `ws.readTodos`, `ws.writeTodos`, `WorkspacePolicyError`, `WorkspaceEditError`, `WorkspaceJobError`, `WorkspaceShellRefusalReason`, `checkShellCommand`, `denyPaths`, `denyPatterns`, `allowCommand`, `interpreter`, `shell.background`, `list.ignore`, `inheritEnv`, `expectHash`, `read.maxBytes`, `bytesCapped`, `cancelled`, `ExecOptions`, `tokenizeCommand`, `read_file`/`edit_file`/`multi_edit`/`write_file`/`list_dir`/`run_shell`/`shell_output`/`shell_kill`/`run_tests`/`grep`/`todo_write`/`todo_read`; ''give an agent file tools'', ''jail an agent to a directory'', ''let an agent read/write/grep a repo'', ''read-only workspace for a reviewer'', ''scope an agent to a subdirectory'', ''run a shell command under policy'', ''edit a file with a stale-hash guard'', ''command injection guard for an agent shell tool'', ''ReDoS-safe grep for an agent'', ''cap how many bytes a read returns'', ''cancel a running workspace command'', ''let the agent use pipes and &&'', ''why was my shell command refused'', ''deny git push --force'', ''run a dev server in the background'', ''atomic multi-edit'', ''list a directory for an agent'', ''todo list tool for an agent''; typical import `import "@warlock.js/ai-workspace"; import { ai } from "@warlock.js/ai"`. Skip: building the agent loop that consumes the tools — the `build-loop-agent` topic; defining a non-filesystem custom tool — the `define-ai-tool` topic of the `warlock-js-ai` skill.'
|
|
3
|
+
description: 'Build and operate a policy-jailed filesystem + shell workspace with @warlock.js/ai-workspace. Triggers: `ai.workspace`, `workspace(`, `WorkspacePolicy`, `WorkspaceShellPolicy`, `WorkspaceToolName`, `ws.tools.all`, `ws.tools.pick`, `ws.readFile`, `ws.writeFile`, `ws.editFile`, `ws.exec`, `ws.grep`, `ws.glob`, `ws.readonly`, `ws.scope`, `ws.multiEdit`, `ws.applyPatch`, `ws.listDir`, `ws.startShell`, `ws.shellOutput`, `ws.shellKill`, `ws.dispose`, `ws.readTodos`, `ws.writeTodos`, `WorkspacePolicyError`, `WorkspaceEditError`, `WorkspaceJobError`, `WorkspaceShellRefusalReason`, `checkShellCommand`, `denyPaths`, `denyPatterns`, `allowCommand`, `interpreter`, `shell.background`, `list.ignore`, `inheritEnv`, `expectHash`, `read.maxBytes`, `bytesCapped`, `cancelled`, `ExecOptions`, `tokenizeCommand`, `read_file`/`edit_file`/`multi_edit`/`apply_patch`/`write_file`/`list_dir`/`run_shell`/`shell_output`/`shell_kill`/`run_tests`/`grep`/`todo_write`/`todo_read`; ''give an agent file tools'', ''jail an agent to a directory'', ''let an agent read/write/grep a repo'', ''read-only workspace for a reviewer'', ''scope an agent to a subdirectory'', ''run a shell command under policy'', ''edit a file with a stale-hash guard'', ''command injection guard for an agent shell tool'', ''ReDoS-safe grep for an agent'', ''cap how many bytes a read returns'', ''cancel a running workspace command'', ''let the agent use pipes and &&'', ''why was my shell command refused'', ''deny git push --force'', ''run a dev server in the background'', ''atomic multi-edit'', ''list a directory for an agent'', ''todo list tool for an agent''; typical import `import "@warlock.js/ai-workspace"; import { ai } from "@warlock.js/ai"`. Skip: building the agent loop that consumes the tools — the `build-loop-agent` topic; defining a non-filesystem custom tool — the `define-ai-tool` topic of the `warlock-js-ai` skill.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Use a workspace — a policy jail for an agent's filesystem + shell
|
|
@@ -104,7 +104,7 @@ export async function commitWork(cwd: string) {
|
|
|
104
104
|
|
|
105
105
|
### Agent-facing — `ws.tools.*`
|
|
106
106
|
|
|
107
|
-
Each tool is a `ToolContract` (with a JSON Schema of its input) ready for `ai.agent({ tools })`. The LLM-visible tool names are `read_file`, `edit_file`, `multi_edit`, `write_file`, `list_dir`, `run_shell`, `shell_output`, `shell_kill`, `run_tests`, `grep`, `glob`, `todo_write`, `todo_read` — `shell_output` / `shell_kill` only in `all()` when `shell.background` is set.
|
|
107
|
+
Each tool is a `ToolContract` (with a JSON Schema of its input) ready for `ai.agent({ tools })`. The LLM-visible tool names are `read_file`, `edit_file`, `multi_edit`, `apply_patch`, `write_file`, `list_dir`, `run_shell`, `shell_output`, `shell_kill`, `run_tests`, `grep`, `glob`, `todo_write`, `todo_read` — `shell_output` / `shell_kill` only in `all()` when `shell.background` is set.
|
|
108
108
|
|
|
109
109
|
```ts
|
|
110
110
|
ws.tools.all(); // every tool, canonical order
|
|
@@ -172,6 +172,7 @@ export async function devLoop(cwd: string) {
|
|
|
172
172
|
```
|
|
173
173
|
|
|
174
174
|
- `list_dir({ path?, depth?, ignore? })` → `{ path, entries: [{ path, type, size?, depth }], truncated }`; `denyPaths` always hidden, `list.ignore` (default `node_modules`, `.git`) hidden from listings, symlinks reported but never followed.
|
|
175
|
+
- `apply_patch({ patch, dryRun? })` → `{ files: [{ path, action, oldPath?, hunks, hash? }], dryRun }`; a unified diff that modifies, creates, deletes and renames files, all or none; paths jailed, hunks matched by context, line endings kept, binary files refused (`binary-file`); `dryRun` checks only. Not in `readonly()`.
|
|
175
176
|
- `multi_edit({ path, edits, expectHash? })` → `{ path, edits, replacements, hash }`; same uniqueness rules as `edit_file`, at most 100 edits.
|
|
176
177
|
- Background: `shell_output({ id, since?, waitMs? })` → `{ stdout, stderr, cursor, droppedBytes, truncated, status, exitCode }`; only the newest `shell.maxOutputBytes` per command are kept. States `"running"`, `"exited"`, `"killed"`, `"timed-out"`. Unknown id → `WorkspaceJobError`. Background commands outlive the agent run; `dispose()` (or process exit) kills them. Only processes the workspace spawned are ever signalled.
|
|
177
178
|
- Todos: one in-memory list per workspace, shared with `readonly()` / `scope()`; `todo_write` replaces the whole list (≤ 100 items, status `pending` / `in_progress` / `completed`).
|
|
@@ -238,7 +239,7 @@ try {
|
|
|
238
239
|
```
|
|
239
240
|
|
|
240
241
|
- `WorkspacePolicyError.type`: `"path-escape"` (jail escape / deny glob) | `"denied-command"` (the shell policy refused the line — `reason` says why) | `"unsafe-pattern"` (`grep` pattern too long or nested-quantifier ReDoS shape).
|
|
241
|
-
- `WorkspaceEditError.type`: `"not-found"` | `"not-unique"` | `"stale-hash"` (+ `editIndex` for `multiEdit`).
|
|
242
|
+
- `WorkspaceEditError.type`: `"not-found"` | `"not-unique"` | `"stale-hash"` | `"patch-invalid"` | `"hunk-failed"` | `"binary-file"` | `"file-exists"` | `"file-missing"` (+ `editIndex` for `multiEdit`, `hunkIndex` for `applyPatch`).
|
|
242
243
|
- `WorkspaceJobError.type`: `"not-found"` (unknown background command id).
|
|
243
244
|
|
|
244
245
|
## Composition — `readonly()` and `scope()`
|
|
@@ -248,7 +249,7 @@ const ro = ws.readonly(); // vends only read/grep/glob; mutating direct methods
|
|
|
248
249
|
const api = ws.scope("packages/api"); // a sub-jailed workspace rooted at the subdir
|
|
249
250
|
```
|
|
250
251
|
|
|
251
|
-
`readonly()` is the least-privilege reviewer projection — `tools.all()` on it returns `read_file`, `list_dir`, `grep`, `glob` and the todo tools only, and `writeFile` / `editFile` / `multiEdit` / `exec` / `startShell` / `shellKill` / `mkdir` / `remove` throw a `WorkspacePolicyError`. Projections share the workspace's background commands and todo list. `scope(subdir)` narrows `cwd` to `join(cwd, subdir)` (same sub-policies, same backend), so a per-package agent gets a tighter blast radius.
|
|
252
|
+
`readonly()` is the least-privilege reviewer projection — `tools.all()` on it returns `read_file`, `list_dir`, `grep`, `glob` and the todo tools only, and `writeFile` / `editFile` / `multiEdit` / `applyPatch` / `exec` / `startShell` / `shellKill` / `mkdir` / `remove` throw a `WorkspacePolicyError`. Projections share the workspace's background commands and todo list. `scope(subdir)` narrows `cwd` to `join(cwd, subdir)` (same sub-policies, same backend), so a per-package agent gets a tighter blast radius.
|
|
252
253
|
|
|
253
254
|
## Hermetic tests with the mock backend
|
|
254
255
|
|