@clarvis/agent-tools 0.1.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 +40 -0
- package/CODE_OF_CONDUCT.md +117 -0
- package/CONTRIBUTING.md +78 -0
- package/LICENSE +21 -0
- package/README.md +203 -0
- package/SECURITY.md +58 -0
- package/SPEC.md +266 -0
- package/dist/config.d.ts +29 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +145 -0
- package/dist/config.js.map +1 -0
- package/dist/core.d.ts +13 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +43 -0
- package/dist/core.js.map +1 -0
- package/dist/errors.d.ts +9 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +29 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/atomic.d.ts +11 -0
- package/dist/lib/atomic.d.ts.map +1 -0
- package/dist/lib/atomic.js +307 -0
- package/dist/lib/atomic.js.map +1 -0
- package/dist/lib/binary.d.ts +3 -0
- package/dist/lib/binary.d.ts.map +1 -0
- package/dist/lib/binary.js +20 -0
- package/dist/lib/binary.js.map +1 -0
- package/dist/lib/files.d.ts +9 -0
- package/dist/lib/files.d.ts.map +1 -0
- package/dist/lib/files.js +49 -0
- package/dist/lib/files.js.map +1 -0
- package/dist/lib/ignore.d.ts +5 -0
- package/dist/lib/ignore.d.ts.map +1 -0
- package/dist/lib/ignore.js +106 -0
- package/dist/lib/ignore.js.map +1 -0
- package/dist/lib/log.d.ts +4 -0
- package/dist/lib/log.d.ts.map +1 -0
- package/dist/lib/log.js +11 -0
- package/dist/lib/log.js.map +1 -0
- package/dist/lib/match-cascade.d.ts +10 -0
- package/dist/lib/match-cascade.d.ts.map +1 -0
- package/dist/lib/match-cascade.js +153 -0
- package/dist/lib/match-cascade.js.map +1 -0
- package/dist/lib/output.d.ts +8 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +77 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/paths.d.ts +3 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +46 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/rg.d.ts +22 -0
- package/dist/lib/rg.d.ts.map +1 -0
- package/dist/lib/rg.js +285 -0
- package/dist/lib/rg.js.map +1 -0
- package/dist/lib/text.d.ts +18 -0
- package/dist/lib/text.d.ts.map +1 -0
- package/dist/lib/text.js +129 -0
- package/dist/lib/text.js.map +1 -0
- package/dist/lib/textfile.d.ts +4 -0
- package/dist/lib/textfile.d.ts.map +1 -0
- package/dist/lib/textfile.js +55 -0
- package/dist/lib/textfile.js.map +1 -0
- package/dist/lib/token.d.ts +2 -0
- package/dist/lib/token.d.ts.map +1 -0
- package/dist/lib/token.js +6 -0
- package/dist/lib/token.js.map +1 -0
- package/dist/tools/apply-patch.d.ts +3 -0
- package/dist/tools/apply-patch.d.ts.map +1 -0
- package/dist/tools/apply-patch.js +221 -0
- package/dist/tools/apply-patch.js.map +1 -0
- package/dist/tools/bash.d.ts +3 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/bash.js +179 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/edit-file.d.ts +15 -0
- package/dist/tools/edit-file.d.ts.map +1 -0
- package/dist/tools/edit-file.js +163 -0
- package/dist/tools/edit-file.js.map +1 -0
- package/dist/tools/glob.d.ts +3 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +64 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.d.ts +3 -0
- package/dist/tools/grep.d.ts.map +1 -0
- package/dist/tools/grep.js +201 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/list-dir.d.ts +3 -0
- package/dist/tools/list-dir.d.ts.map +1 -0
- package/dist/tools/list-dir.js +59 -0
- package/dist/tools/list-dir.js.map +1 -0
- package/dist/tools/multi-edit.d.ts +3 -0
- package/dist/tools/multi-edit.d.ts.map +1 -0
- package/dist/tools/multi-edit.js +86 -0
- package/dist/tools/multi-edit.js.map +1 -0
- package/dist/tools/read-file.d.ts +3 -0
- package/dist/tools/read-file.d.ts.map +1 -0
- package/dist/tools/read-file.js +102 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/registry.d.ts +6 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +28 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/types.d.ts +9 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/write-file.d.ts +3 -0
- package/dist/tools/write-file.d.ts.map +1 -0
- package/dist/tools/write-file.js +61 -0
- package/dist/tools/write-file.js.map +1 -0
- package/package.json +70 -0
package/SPEC.md
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# @clarvis/agent-tools — Specification
|
|
2
|
+
|
|
3
|
+
This document specifies the behavior of each tool exposed by
|
|
4
|
+
`@clarvis/agent-tools`. For installation, configuration, and the
|
|
5
|
+
security model, see [README.md](./README.md).
|
|
6
|
+
|
|
7
|
+
## Conventions
|
|
8
|
+
|
|
9
|
+
- **Return value.** Each tool call returns `{ isError, text }`. On success
|
|
10
|
+
`text` is the tool's output; on failure `isError` is set and `text` is a JSON
|
|
11
|
+
error object (see [Errors](#errors)).
|
|
12
|
+
- **Result format.** On success every tool returns plain text **except `bash`**,
|
|
13
|
+
whose success result is a JSON object (`exit_code`, `stdout`, `stderr`,
|
|
14
|
+
`signal`, `timed_out`); a non-zero exit is a success (`isError` false), not an
|
|
15
|
+
error. Only spawn/timeout/output-limit failures of `bash` flag `isError`. All
|
|
16
|
+
failures, for every tool, are the JSON error object above.
|
|
17
|
+
- **Paths.** A path is resolved verbatim if absolute, otherwise against the
|
|
18
|
+
workspace root. By default the result is **confined to the workspace root**:
|
|
19
|
+
`../` traversal, absolute paths outside the root, and symlinks that resolve
|
|
20
|
+
outside it are rejected with `path_escape` (the existing portion of the path is
|
|
21
|
+
canonicalized with `realpath`, so symlink hops are caught). Confinement is
|
|
22
|
+
disabled by `ALLOW_OUTSIDE_WORKSPACE=1` / `--allow-outside-workspace`, which
|
|
23
|
+
restores unrestricted resolution (see README → Security).
|
|
24
|
+
- **Input size.** The file-reading tools (`read_file`, `edit_file`, `multi_edit`,
|
|
25
|
+
`apply_patch`, and the in-process `grep` backend) refuse a file larger than
|
|
26
|
+
`MAX_FILE_BYTES` (default 20000000): the read/edit tools fail with `too_large`,
|
|
27
|
+
and `grep` skips the oversized file.
|
|
28
|
+
- **Text & encoding.** Text tools operate on UTF-8. A UTF-16 file with a BOM (LE/BE)
|
|
29
|
+
is decoded by `read_file`, but the editing tools refuse it (`is_binary`) rather than
|
|
30
|
+
rewrite it as UTF-8. Other binary files (NUL byte in the first/last 8 KB, no UTF-16
|
|
31
|
+
BOM) are rejected by the text tools with `is_binary`.
|
|
32
|
+
- **Line endings & BOM.** On read, content is normalized to `\n` for matching.
|
|
33
|
+
On write, the editing tools (`edit_file`, `multi_edit`, `apply_patch` modify)
|
|
34
|
+
**preserve each untouched line's original terminator** (`\r\n`, `\n`, or lone
|
|
35
|
+
`\r`); newly inserted or edited lines use the file's dominant terminator. A
|
|
36
|
+
leading UTF-8 BOM is preserved.
|
|
37
|
+
- **Output bounding.** Every result is capped to `MAX_OUTPUT_BYTES` (default
|
|
38
|
+
131072), truncated on a UTF-8 boundary with a trailing marker.
|
|
39
|
+
- **Atomicity.** All mutations write to a temp file and `rename` into place;
|
|
40
|
+
multi-file operations (`apply_patch`) are staged and committed transactionally
|
|
41
|
+
with rollback (a rename/move participates with both its source and destination). Writes to the same path are serialized by an in-process lock —
|
|
42
|
+
this is the single-process contract; concurrent processes or external
|
|
43
|
+
editors are **not** coordinated. A symlink target is refused (the link is not
|
|
44
|
+
followed and not replaced).
|
|
45
|
+
- **BOM.** A leading U+FEFF is treated as a byte-order mark: stripped from the
|
|
46
|
+
content returned by `read_file`/used for matching, and re-emitted on write.
|
|
47
|
+
|
|
48
|
+
## Read-only surface
|
|
49
|
+
|
|
50
|
+
In `--read-only` mode only `read_file`, `list_dir`, `glob`, and `grep` are
|
|
51
|
+
exposed; the mutating tools are not registered.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## read_file
|
|
56
|
+
|
|
57
|
+
Read a text file. UTF-8 by default; a UTF-16 file with a byte-order mark (LE/BE) is
|
|
58
|
+
detected and decoded.
|
|
59
|
+
|
|
60
|
+
**Input:** `path` (string, required); `offset` (integer, 1-based start line,
|
|
61
|
+
default 1; a negative value counts from the end — `-N` reads the last N lines; 0 is
|
|
62
|
+
invalid); `limit` (integer, max lines, default tool-defined).
|
|
63
|
+
|
|
64
|
+
**Behavior:** Returns lines prefixed with right-aligned line numbers and a tab.
|
|
65
|
+
Empty file returns `(empty file)`. Over-long lines are truncated with a marker, and no
|
|
66
|
+
single emitted line exceeds `MAX_OUTPUT_BYTES` (a longer line is byte-truncated on a UTF-8
|
|
67
|
+
boundary). At least one line is always shown. When more lines remain, a continuation hint
|
|
68
|
+
with the next `offset` is appended.
|
|
69
|
+
|
|
70
|
+
**Errors:** `not_found`, `not_a_file` (directory), `is_binary`, `too_large`,
|
|
71
|
+
`path_escape`, `invalid_input` (offset 0, or a positive offset past EOF).
|
|
72
|
+
|
|
73
|
+
## list_dir
|
|
74
|
+
|
|
75
|
+
List the entries of a directory.
|
|
76
|
+
|
|
77
|
+
**Input:** `path` (string, default workspace root).
|
|
78
|
+
|
|
79
|
+
**Behavior:** One entry per line; directories are marked. An empty directory
|
|
80
|
+
returns a sentinel line rather than an empty result.
|
|
81
|
+
|
|
82
|
+
**Errors:** `not_found`, `not_a_file` (path is a file), `path_escape`, `io_error`.
|
|
83
|
+
|
|
84
|
+
## glob
|
|
85
|
+
|
|
86
|
+
Find files (not directories) by glob pattern.
|
|
87
|
+
|
|
88
|
+
**Input:** `pattern` (string, required, e.g. `**/*.ts`); `path` (base dir,
|
|
89
|
+
default workspace root); `respect_gitignore` (boolean, default true).
|
|
90
|
+
|
|
91
|
+
**Behavior:** Returns matching file paths, most-recently-modified first. Hidden
|
|
92
|
+
files are included; when `respect_gitignore` is true, files ignored by the git
|
|
93
|
+
ignore stack and the `.git/` directory are skipped. No matches returns
|
|
94
|
+
`(no matches)`.
|
|
95
|
+
|
|
96
|
+
**Errors:** `not_found`, `path_escape`, `invalid_input` (bad glob).
|
|
97
|
+
|
|
98
|
+
## grep
|
|
99
|
+
|
|
100
|
+
Search file contents by regular expression, recursively.
|
|
101
|
+
|
|
102
|
+
**Input:** `pattern` (string, required, Rust/ripgrep regex syntax); `path` (file
|
|
103
|
+
or dir, default workspace root); `glob` (restrict to matching files);
|
|
104
|
+
`output_mode` (`files_with_matches` | `content` | `count`, default
|
|
105
|
+
`files_with_matches`); `ignore_case` (boolean, default false); `context`
|
|
106
|
+
(integer, both sides, content mode only, default 0); `before_context` /
|
|
107
|
+
`after_context` (integers, content mode only — `ripgrep` `-B`/`-A`; each overrides
|
|
108
|
+
`context` for that side); `head_limit` (integer ≥ 1, max results to return — files in
|
|
109
|
+
`files_with_matches`/`count`, matches in `content`; omit for unlimited, still
|
|
110
|
+
byte-bounded); `offset` (integer ≥ 0, 0-based number of leading results to skip —
|
|
111
|
+
**a result offset, not `read_file`'s line offset**); `multiline` (boolean, default
|
|
112
|
+
false — match across line boundaries, ripgrep `--multiline --multiline-dotall`).
|
|
113
|
+
|
|
114
|
+
**Behavior:** Uses ripgrep when available, otherwise an equivalent in-process
|
|
115
|
+
fallback. Both backends apply one consistent policy: **hidden files are
|
|
116
|
+
searched, the `.git/` directory is skipped, and the full git ignore stack is
|
|
117
|
+
respected** (nested `.gitignore`, parent directories up to the repository root,
|
|
118
|
+
`.git/info/exclude`, and the global excludes file). Binary files are skipped, as
|
|
119
|
+
are files larger than `MAX_FILE_BYTES` in the in-process backend. No matches
|
|
120
|
+
returns `(no matches)` (a success). Output is deterministic (sorted by path, then
|
|
121
|
+
line number). The pattern is validated by the active backend: ripgrep reports its
|
|
122
|
+
own syntax errors, and the in-process fallback compiles the pattern as a
|
|
123
|
+
JavaScript `RegExp`; a pattern valid for one engine but not the other is accepted
|
|
124
|
+
or rejected by whichever backend runs.
|
|
125
|
+
|
|
126
|
+
**Multiline.** With `multiline` true, `.` also matches newlines and `^`/`$` anchor at
|
|
127
|
+
line boundaries, so a single match may span several lines; in `content` mode it renders
|
|
128
|
+
as the spanned lines under the start line's `path:line:` prefix, and it still counts as
|
|
129
|
+
one match for `count` and as one unit for `head_limit`/`offset` paging. A match that
|
|
130
|
+
spans `\n` may differ between the two backends on CRLF files (the in-process backend
|
|
131
|
+
matches against `\n`-normalized text).
|
|
132
|
+
|
|
133
|
+
**Pagination.** `head_limit`/`offset` page over the result units (files, or matches in
|
|
134
|
+
content mode) **within the collected result window** — re-run with `offset` advanced to
|
|
135
|
+
get the next page. A footer reports state honestly: when the underlying scan was
|
|
136
|
+
truncated by the output cap it warns the result is **incomplete** and to narrow the
|
|
137
|
+
query (and does **not** suggest paging, since unscanned files cannot be reached);
|
|
138
|
+
otherwise, when more units remain it prints `showing A..B of N; call again with
|
|
139
|
+
offset=B for more`; an `offset` past the end on a complete scan returns
|
|
140
|
+
`(no results at offset N; M total)`.
|
|
141
|
+
|
|
142
|
+
**Errors:** `not_found`, `path_escape`, `invalid_input` (bad regex).
|
|
143
|
+
|
|
144
|
+
## write_file
|
|
145
|
+
|
|
146
|
+
Create or overwrite a file with the given content (atomic).
|
|
147
|
+
|
|
148
|
+
**Input:** `path` (string, required); `content` (string, required).
|
|
149
|
+
|
|
150
|
+
**Behavior:** Writes `content` exactly. Missing parent directories are created.
|
|
151
|
+
|
|
152
|
+
**Errors:** `not_a_file`, `path_escape`, `io_error`.
|
|
153
|
+
|
|
154
|
+
## edit_file
|
|
155
|
+
|
|
156
|
+
Replace one exact occurrence of `old_string` with `new_string`.
|
|
157
|
+
|
|
158
|
+
**Input:** `path` (required); `old_string` (required, matched literally, without
|
|
159
|
+
read_file's line-number prefixes); `new_string` (required, must differ);
|
|
160
|
+
`replace_all` (boolean, default false).
|
|
161
|
+
|
|
162
|
+
**Behavior:** `old_string` is first matched **literally and exactly**, and must be
|
|
163
|
+
unique unless `replace_all` is set. When an exact match is **not** found (single-
|
|
164
|
+
replacement path only — `replace_all` stays exact-only), a **whitespace-tolerant
|
|
165
|
+
cascade** runs: it tries, strictest→loosest, an indentation-flexible, a per-line-
|
|
166
|
+
trimmed, an all-whitespace-collapsed, and finally a trimmed-substring match. It applies
|
|
167
|
+
**only when it resolves to exactly one region** (otherwise `ambiguous_match`, never a
|
|
168
|
+
guess); `new_string` is substituted verbatim (no re-indentation), and the result message
|
|
169
|
+
discloses that a tolerant match was used. Line endings/BOM are preserved per the
|
|
170
|
+
conventions above.
|
|
171
|
+
|
|
172
|
+
Note the verbatim substitution replaces the **whole matched region, including its original
|
|
173
|
+
leading indentation**, with `new_string` exactly as given. So a tolerant match can change a
|
|
174
|
+
line's indentation if `new_string` does not itself carry it — the disclosed result message
|
|
175
|
+
flags this and re-reading the file is recommended. (This is a deliberate trade-off: the tool
|
|
176
|
+
never guesses re-indentation.)
|
|
177
|
+
|
|
178
|
+
**Errors:** `no_match`, `ambiguous_match` (multiple exact or multiple tolerant
|
|
179
|
+
matches without `replace_all`), `invalid_input` (identical strings), `not_found`,
|
|
180
|
+
`is_binary`, `too_large`, `path_escape`.
|
|
181
|
+
|
|
182
|
+
## multi_edit
|
|
183
|
+
|
|
184
|
+
Apply several `edit_file`-style edits to ONE file in a single atomic call.
|
|
185
|
+
|
|
186
|
+
**Input:** `path` (required); `edits` (array of `{ old_string, new_string,
|
|
187
|
+
replace_all? }`, required).
|
|
188
|
+
|
|
189
|
+
**Behavior:** Edits run in order, each operating on the result of the previous, and
|
|
190
|
+
each inherits `edit_file`'s exact-then-whitespace-tolerant matching. The whole batch is
|
|
191
|
+
applied atomically; any failing edit aborts the call with its index and nothing is
|
|
192
|
+
written.
|
|
193
|
+
|
|
194
|
+
**Errors:** as `edit_file`, prefixed with the failing edit index.
|
|
195
|
+
|
|
196
|
+
## apply_patch
|
|
197
|
+
|
|
198
|
+
Apply a unified diff across one or more files atomically.
|
|
199
|
+
|
|
200
|
+
**Input:** `patch` (string, required, unified diff). A `/dev/null` source (`---`)
|
|
201
|
+
denotes a create and a `/dev/null` target (`+++`) a delete. A block whose old and new
|
|
202
|
+
paths differ is a **rename/move**: with hunks it moves and edits in one step, without
|
|
203
|
+
hunks (or with a content-reproducing hunk) it is a pure rename that preserves the file's
|
|
204
|
+
exact bytes.
|
|
205
|
+
|
|
206
|
+
**Behavior:** Each file block is validated and applied; all changes commit
|
|
207
|
+
together or roll back together (a rename participates with both its endpoints). Creating
|
|
208
|
+
an existing path, a rename whose destination already exists, or multiple blocks naming
|
|
209
|
+
the same path (including either endpoint of a rename), is rejected. Modified and
|
|
210
|
+
moved-and-edited files preserve line endings/BOM per the conventions; created files use
|
|
211
|
+
LF; a pure rename leaves the bytes and mode untouched. The file tools operate on UTF-8:
|
|
212
|
+
a UTF-16 file is **read** by `read_file` but the editing tools (`edit_file`,
|
|
213
|
+
`multi_edit`, `apply_patch`) refuse it (`is_binary`) rather than silently rewrite it as
|
|
214
|
+
UTF-8.
|
|
215
|
+
|
|
216
|
+
**Errors:** `patch_failed` (hunk did not apply; reports the file), `invalid_input`,
|
|
217
|
+
`not_found`, `not_a_file`, `is_binary`, `too_large`, `path_escape`, `io_error`.
|
|
218
|
+
|
|
219
|
+
## bash
|
|
220
|
+
|
|
221
|
+
Run a shell command via `sh -c` and return stdout, stderr, and exit code.
|
|
222
|
+
|
|
223
|
+
**Input:** `command` (string, required); `cwd` (string, default workspace root);
|
|
224
|
+
`timeout_ms` (integer, default `BASH_TIMEOUT_MS` = 120000; may be raised up to
|
|
225
|
+
`BASH_TIMEOUT_MAX_MS` = 600000 for a long build/test/install — a larger request is
|
|
226
|
+
clamped to the ceiling, not rejected).
|
|
227
|
+
|
|
228
|
+
**Behavior:** The command runs to completion and **blocks** until it exits;
|
|
229
|
+
stdin is closed. A long-lived process (dev server, watcher) must be backgrounded
|
|
230
|
+
with its output redirected, e.g. `npm start > /tmp/out.log 2>&1 &`. On success
|
|
231
|
+
the result is a JSON object `{ exit_code, stdout, stderr, signal, timed_out }`.
|
|
232
|
+
A non-zero exit is a normal result, not an error.
|
|
233
|
+
|
|
234
|
+
stdout and stderr are budgeted against a shared `MAX_OUTPUT_BYTES`; overflow is
|
|
235
|
+
written to a `.clarvis/` spill file referenced in the result. There is a hard
|
|
236
|
+
per-stream in-memory ceiling: a command producing unbounded output is killed
|
|
237
|
+
(process group) and the call fails with `output_limit`.
|
|
238
|
+
|
|
239
|
+
On timeout the process group is killed and `timeout` is returned (with the
|
|
240
|
+
partial stdout/stderr).
|
|
241
|
+
|
|
242
|
+
**Errors:** `timeout`, `output_limit`, `not_found`/`not_a_file` (bad `cwd`),
|
|
243
|
+
`path_escape` (`cwd` outside the workspace), `io_error` (spawn failure).
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Errors
|
|
248
|
+
|
|
249
|
+
Errors are returned as a JSON object `{ "error": <code>, "message": <string>, ...fields }`.
|
|
250
|
+
The codes are:
|
|
251
|
+
|
|
252
|
+
| Code | Meaning |
|
|
253
|
+
| ----------------- | --------------------------------------------------------- |
|
|
254
|
+
| `invalid_input` | Arguments failed schema or semantic validation. |
|
|
255
|
+
| `not_found` | Path does not exist. |
|
|
256
|
+
| `not_a_file` | Path was a directory where a file was expected (or vice). |
|
|
257
|
+
| `is_binary` | File appears to be binary; text tools refuse it. |
|
|
258
|
+
| `no_match` | `edit_file`/`multi_edit` could not find `old_string`. |
|
|
259
|
+
| `ambiguous_match` | `old_string` matched more than once without `replace_all`.|
|
|
260
|
+
| `patch_failed` | A patch hunk did not apply cleanly. |
|
|
261
|
+
| `timeout` | `bash` command exceeded its timeout. |
|
|
262
|
+
| `output_limit` | `bash` output exceeded the hard capture ceiling. |
|
|
263
|
+
| `too_large` | Input file exceeded `MAX_FILE_BYTES`. |
|
|
264
|
+
| `path_escape` | Path resolved outside the confined workspace root. |
|
|
265
|
+
| `io_error` | An underlying filesystem/process error. |
|
|
266
|
+
| `internal` | Unexpected internal error. |
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface ServerConfig {
|
|
2
|
+
workspaceRoot: string;
|
|
3
|
+
maxOutputBytes: number;
|
|
4
|
+
maxFileBytes: number;
|
|
5
|
+
bashTimeoutMs: number;
|
|
6
|
+
bashTimeoutMaxMs: number;
|
|
7
|
+
ripgrepAvailable: boolean;
|
|
8
|
+
readOnly: boolean;
|
|
9
|
+
confineToWorkspace: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const DEFAULT_MAX_OUTPUT_BYTES = 131072;
|
|
12
|
+
export declare const DEFAULT_MAX_FILE_BYTES = 20000000;
|
|
13
|
+
export declare const DEFAULT_BASH_TIMEOUT_MS = 120000;
|
|
14
|
+
export declare const DEFAULT_BASH_TIMEOUT_MAX_MS = 600000;
|
|
15
|
+
export declare class StartupError extends Error {
|
|
16
|
+
}
|
|
17
|
+
export interface AgentToolsOptions {
|
|
18
|
+
workspaceRoot: string;
|
|
19
|
+
readOnly?: boolean;
|
|
20
|
+
confineToWorkspace?: boolean;
|
|
21
|
+
maxOutputBytes?: number;
|
|
22
|
+
maxFileBytes?: number;
|
|
23
|
+
bashTimeoutMs?: number;
|
|
24
|
+
bashTimeoutMaxMs?: number;
|
|
25
|
+
probeRipgrep?: () => boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function resolveConfig(options: AgentToolsOptions): ServerConfig;
|
|
28
|
+
export declare function buildConfig(argv: string[], env: NodeJS.ProcessEnv, probe?: () => boolean): ServerConfig;
|
|
29
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IAEtB,cAAc,EAAE,MAAM,CAAC;IAEvB,YAAY,EAAE,MAAM,CAAC;IAErB,aAAa,EAAE,MAAM,CAAC;IAEtB,gBAAgB,EAAE,MAAM,CAAC;IAEzB,gBAAgB,EAAE,OAAO,CAAC;IAE1B,QAAQ,EAAE,OAAO,CAAC;IAElB,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,eAAO,MAAM,wBAAwB,SAAS,CAAC;AAC/C,eAAO,MAAM,sBAAsB,WAAa,CAAC;AACjD,eAAO,MAAM,uBAAuB,SAAS,CAAC;AAC9C,eAAO,MAAM,2BAA2B,SAAS,CAAC;AAIlD,qBAAa,YAAa,SAAQ,KAAK;CAAG;AAoG1C,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;CAC9B;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,YAAY,CAoCtE;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,KAAK,GAAE,MAAM,OAAsB,GAClC,YAAY,CAsCd"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { statSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
export const DEFAULT_MAX_OUTPUT_BYTES = 131072;
|
|
5
|
+
export const DEFAULT_MAX_FILE_BYTES = 20_000_000;
|
|
6
|
+
export const DEFAULT_BASH_TIMEOUT_MS = 120000;
|
|
7
|
+
export const DEFAULT_BASH_TIMEOUT_MAX_MS = 600000;
|
|
8
|
+
const MIN_OUTPUT_BYTES = 1024;
|
|
9
|
+
const MIN_FILE_BYTES = 1024;
|
|
10
|
+
export class StartupError extends Error {
|
|
11
|
+
}
|
|
12
|
+
function parseWorkspaceArg(argv) {
|
|
13
|
+
for (let i = 0; i < argv.length; i++) {
|
|
14
|
+
const arg = argv[i];
|
|
15
|
+
if (arg === undefined)
|
|
16
|
+
continue;
|
|
17
|
+
if (arg === "--workspace") {
|
|
18
|
+
const value = argv[i + 1];
|
|
19
|
+
if (value === undefined || value.startsWith("--")) {
|
|
20
|
+
throw new StartupError("--workspace requires a path argument");
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
if (arg.startsWith("--workspace=")) {
|
|
25
|
+
const value = arg.slice("--workspace=".length);
|
|
26
|
+
if (value === "")
|
|
27
|
+
throw new StartupError("--workspace requires a path argument");
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const BOOL_TRUE = new Set(["1", "true", "yes", "on"]);
|
|
34
|
+
const BOOL_FALSE = new Set(["0", "false", "no", "off", ""]);
|
|
35
|
+
function resolveReadOnly(argv, env) {
|
|
36
|
+
if (argv.includes("--read-only"))
|
|
37
|
+
return true;
|
|
38
|
+
const raw = env.READ_ONLY;
|
|
39
|
+
if (raw === undefined)
|
|
40
|
+
return false;
|
|
41
|
+
const norm = raw.trim().toLowerCase();
|
|
42
|
+
if (BOOL_TRUE.has(norm))
|
|
43
|
+
return true;
|
|
44
|
+
if (BOOL_FALSE.has(norm))
|
|
45
|
+
return false;
|
|
46
|
+
throw new StartupError(`READ_ONLY must be one of 1/true/yes/on or 0/false/no/off, got: ${raw}`);
|
|
47
|
+
}
|
|
48
|
+
function resolveConfine(argv, env) {
|
|
49
|
+
if (argv.includes("--allow-outside-workspace"))
|
|
50
|
+
return false;
|
|
51
|
+
const raw = env.ALLOW_OUTSIDE_WORKSPACE;
|
|
52
|
+
if (raw === undefined)
|
|
53
|
+
return true;
|
|
54
|
+
const norm = raw.trim().toLowerCase();
|
|
55
|
+
if (BOOL_TRUE.has(norm))
|
|
56
|
+
return false;
|
|
57
|
+
if (BOOL_FALSE.has(norm))
|
|
58
|
+
return true;
|
|
59
|
+
throw new StartupError(`ALLOW_OUTSIDE_WORKSPACE must be one of 1/true/yes/on or 0/false/no/off, got: ${raw}`);
|
|
60
|
+
}
|
|
61
|
+
function parsePositiveInt(value, fallback, name, min = 1) {
|
|
62
|
+
if (value === undefined || value === "")
|
|
63
|
+
return fallback;
|
|
64
|
+
if (!/^\d+$/.test(value)) {
|
|
65
|
+
throw new StartupError(`${name} must be a positive integer, got: ${value}`);
|
|
66
|
+
}
|
|
67
|
+
const n = Number(value);
|
|
68
|
+
if (!Number.isSafeInteger(n) || n < min) {
|
|
69
|
+
throw new StartupError(`${name} must be an integer >= ${min}, got: ${value}`);
|
|
70
|
+
}
|
|
71
|
+
return n;
|
|
72
|
+
}
|
|
73
|
+
function probeRipgrep() {
|
|
74
|
+
try {
|
|
75
|
+
const res = spawnSync("rg", ["--version"], { stdio: "ignore" });
|
|
76
|
+
return res.status === 0;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function validateWorkspace(rawRoot) {
|
|
83
|
+
const workspaceRoot = path.resolve(rawRoot);
|
|
84
|
+
let stat;
|
|
85
|
+
try {
|
|
86
|
+
stat = statSync(workspaceRoot);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
throw new StartupError(`Workspace root does not exist: ${workspaceRoot}`);
|
|
90
|
+
}
|
|
91
|
+
if (!stat.isDirectory()) {
|
|
92
|
+
throw new StartupError(`Workspace root is not a directory: ${workspaceRoot}`);
|
|
93
|
+
}
|
|
94
|
+
return workspaceRoot;
|
|
95
|
+
}
|
|
96
|
+
function requireMin(n, min, name) {
|
|
97
|
+
if (!Number.isSafeInteger(n) || n < min) {
|
|
98
|
+
throw new StartupError(`${name} must be an integer >= ${min}, got: ${String(n)}`);
|
|
99
|
+
}
|
|
100
|
+
return n;
|
|
101
|
+
}
|
|
102
|
+
function assertTimeoutOrder(min, max, minLabel, maxLabel) {
|
|
103
|
+
if (max < min) {
|
|
104
|
+
throw new StartupError(`${maxLabel} (${max}) must be >= ${minLabel} (${min}).`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export function resolveConfig(options) {
|
|
108
|
+
if (!options.workspaceRoot) {
|
|
109
|
+
throw new StartupError("No workspace root: options.workspaceRoot is required.");
|
|
110
|
+
}
|
|
111
|
+
const workspaceRoot = validateWorkspace(options.workspaceRoot);
|
|
112
|
+
const bashTimeoutMs = requireMin(options.bashTimeoutMs ?? DEFAULT_BASH_TIMEOUT_MS, 1, "bashTimeoutMs");
|
|
113
|
+
const bashTimeoutMaxMs = requireMin(options.bashTimeoutMaxMs ?? DEFAULT_BASH_TIMEOUT_MAX_MS, 1, "bashTimeoutMaxMs");
|
|
114
|
+
assertTimeoutOrder(bashTimeoutMs, bashTimeoutMaxMs, "bashTimeoutMs", "bashTimeoutMaxMs");
|
|
115
|
+
return {
|
|
116
|
+
workspaceRoot,
|
|
117
|
+
maxOutputBytes: requireMin(options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES, MIN_OUTPUT_BYTES, "maxOutputBytes"),
|
|
118
|
+
maxFileBytes: requireMin(options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES, MIN_FILE_BYTES, "maxFileBytes"),
|
|
119
|
+
bashTimeoutMs,
|
|
120
|
+
bashTimeoutMaxMs,
|
|
121
|
+
ripgrepAvailable: (options.probeRipgrep ?? probeRipgrep)(),
|
|
122
|
+
readOnly: options.readOnly ?? false,
|
|
123
|
+
confineToWorkspace: options.confineToWorkspace ?? true,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export function buildConfig(argv, env, probe = probeRipgrep) {
|
|
127
|
+
const rawRoot = parseWorkspaceArg(argv) ?? env.WORKSPACE_ROOT;
|
|
128
|
+
if (!rawRoot) {
|
|
129
|
+
throw new StartupError("No workspace root: pass --workspace <path> or set WORKSPACE_ROOT.");
|
|
130
|
+
}
|
|
131
|
+
const bashTimeoutMs = parsePositiveInt(env.BASH_TIMEOUT_MS, DEFAULT_BASH_TIMEOUT_MS, "BASH_TIMEOUT_MS");
|
|
132
|
+
const bashTimeoutMaxMs = parsePositiveInt(env.BASH_TIMEOUT_MAX_MS, DEFAULT_BASH_TIMEOUT_MAX_MS, "BASH_TIMEOUT_MAX_MS");
|
|
133
|
+
assertTimeoutOrder(bashTimeoutMs, bashTimeoutMaxMs, "BASH_TIMEOUT_MS", "BASH_TIMEOUT_MAX_MS");
|
|
134
|
+
return resolveConfig({
|
|
135
|
+
workspaceRoot: rawRoot,
|
|
136
|
+
maxOutputBytes: parsePositiveInt(env.MAX_OUTPUT_BYTES, DEFAULT_MAX_OUTPUT_BYTES, "MAX_OUTPUT_BYTES", MIN_OUTPUT_BYTES),
|
|
137
|
+
maxFileBytes: parsePositiveInt(env.MAX_FILE_BYTES, DEFAULT_MAX_FILE_BYTES, "MAX_FILE_BYTES", MIN_FILE_BYTES),
|
|
138
|
+
bashTimeoutMs,
|
|
139
|
+
bashTimeoutMaxMs,
|
|
140
|
+
readOnly: resolveReadOnly(argv, env),
|
|
141
|
+
confineToWorkspace: resolveConfine(argv, env),
|
|
142
|
+
probeRipgrep: probe,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ServerConfig } from "./config.js";
|
|
2
|
+
export interface DispatchResult {
|
|
3
|
+
isError: boolean;
|
|
4
|
+
text: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ToolInfo {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
inputSchema: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export declare function listTools(config: ServerConfig): ToolInfo[];
|
|
12
|
+
export declare function dispatch(name: string, args: Record<string, unknown>, config: ServerConfig): Promise<DispatchResult>;
|
|
13
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAmBhD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,QAAQ,EAAE,CAM1D;AAED,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,cAAc,CAAC,CAyBzB"}
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { ToolError, serializeError } from "./errors.js";
|
|
3
|
+
import { bound } from "./lib/output.js";
|
|
4
|
+
import { tools, getTool, selectSurface } from "./tools/registry.js";
|
|
5
|
+
const Ajv = createRequire(import.meta.url)("ajv").default;
|
|
6
|
+
const ajv = new Ajv({ allErrors: true, useDefaults: true });
|
|
7
|
+
const validators = new Map();
|
|
8
|
+
for (const tool of tools) {
|
|
9
|
+
validators.set(tool.name, ajv.compile(tool.inputSchema));
|
|
10
|
+
}
|
|
11
|
+
export function listTools(config) {
|
|
12
|
+
return selectSurface(config.readOnly).map((t) => ({
|
|
13
|
+
name: t.name,
|
|
14
|
+
description: t.description,
|
|
15
|
+
inputSchema: t.inputSchema,
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
export async function dispatch(name, args, config) {
|
|
19
|
+
const tool = getTool(name, selectSurface(config.readOnly));
|
|
20
|
+
if (!tool) {
|
|
21
|
+
return {
|
|
22
|
+
isError: true,
|
|
23
|
+
text: serializeError(new ToolError("not_found", `Unknown tool: ${name}`)),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const validate = validators.get(name);
|
|
27
|
+
const filled = structuredClone(args);
|
|
28
|
+
if (!validate(filled)) {
|
|
29
|
+
const detail = ajv.errorsText(validate.errors, { separator: "; " });
|
|
30
|
+
return {
|
|
31
|
+
isError: true,
|
|
32
|
+
text: serializeError(new ToolError("invalid_input", detail || "invalid arguments")),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const text = await tool.handler(filled, config);
|
|
37
|
+
return { isError: false, text: tool.bounded ? text : bound(text, config.maxOutputBytes) };
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
return { isError: true, text: serializeError(err) };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAYpE,MAAM,GAAG,GAAI,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAe,CAAC,OAAO,CAAC;AAEzE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;AAC5D,MAAM,UAAU,GAAG,IAAI,GAAG,EAA4B,CAAC;AACvD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;IACzB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;AAC3D,CAAC;AAaD,MAAM,UAAU,SAAS,CAAC,MAAoB;IAC5C,OAAO,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChD,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;KAC3B,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAY,EACZ,IAA6B,EAC7B,MAAoB;IAEpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,cAAc,CAAC,IAAI,SAAS,CAAC,WAAW,EAAE,iBAAiB,IAAI,EAAE,CAAC,CAAC;SAC1E,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;IACvC,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,cAAc,CAAC,IAAI,SAAS,CAAC,eAAe,EAAE,MAAM,IAAI,mBAAmB,CAAC,CAAC;SACpF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;IAC5F,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;IACtD,CAAC;AACH,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type ErrorCode = "invalid_input" | "not_found" | "not_a_file" | "is_binary" | "no_match" | "ambiguous_match" | "patch_failed" | "io_error" | "timeout" | "output_limit" | "too_large" | "path_escape" | "internal";
|
|
2
|
+
export declare class ToolError extends Error {
|
|
3
|
+
readonly code: ErrorCode;
|
|
4
|
+
readonly fields: Record<string, unknown>;
|
|
5
|
+
constructor(code: ErrorCode, message: string, fields?: Record<string, unknown>);
|
|
6
|
+
}
|
|
7
|
+
export declare function serializeError(err: unknown): string;
|
|
8
|
+
export declare function fsError(err: NodeJS.ErrnoException, path: string): ToolError;
|
|
9
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GACjB,eAAe,GACf,WAAW,GACX,YAAY,GACZ,WAAW,GACX,UAAU,GACV,iBAAiB,GACjB,cAAc,GACd,UAAU,GACV,SAAS,GACT,cAAc,GACd,WAAW,GACX,aAAa,GACb,UAAU,CAAC;AAEf,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAE7B,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;CAMnF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAOnD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAO3E"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { warn } from "./lib/log.js";
|
|
2
|
+
export class ToolError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
fields;
|
|
5
|
+
constructor(code, message, fields = {}) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "ToolError";
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.fields = fields;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function serializeError(err) {
|
|
13
|
+
if (err instanceof ToolError) {
|
|
14
|
+
return JSON.stringify({ error: err.code, message: err.message, ...err.fields });
|
|
15
|
+
}
|
|
16
|
+
const detail = err instanceof Error ? (err.stack ?? err.message) : String(err);
|
|
17
|
+
warn(`clarvis-agent-tools: internal error: ${detail}\n`);
|
|
18
|
+
return JSON.stringify({ error: "internal", message: "internal error" });
|
|
19
|
+
}
|
|
20
|
+
export function fsError(err, path) {
|
|
21
|
+
if (err.code === "ENOENT")
|
|
22
|
+
return new ToolError("not_found", `No such file: ${path}`, { path });
|
|
23
|
+
if (err.code === "EISDIR")
|
|
24
|
+
return new ToolError("not_a_file", `Path is a directory: ${path}`, { path });
|
|
25
|
+
if (err.code === "ENOTDIR")
|
|
26
|
+
return new ToolError("not_a_file", `Not a directory: ${path}`, { path });
|
|
27
|
+
return new ToolError("io_error", `${err.code ?? "EIO"}: ${err.message}`, { path });
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAiBpC,MAAM,OAAO,SAAU,SAAQ,KAAK;IACzB,IAAI,CAAY;IAChB,MAAM,CAA0B;IAEzC,YAAY,IAAe,EAAE,OAAe,EAAE,SAAkC,EAAE;QAChF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,GAAG,YAAY,SAAS,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/E,IAAI,CAAC,wCAAwC,MAAM,IAAI,CAAC,CAAC;IACzD,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAA0B,EAAE,IAAY;IAC9D,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,SAAS,CAAC,WAAW,EAAE,iBAAiB,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAChG,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;QACvB,OAAO,IAAI,SAAS,CAAC,YAAY,EAAE,wBAAwB,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;QACxB,OAAO,IAAI,SAAS,CAAC,YAAY,EAAE,oBAAoB,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,OAAO,IAAI,SAAS,CAAC,UAAU,EAAE,GAAG,GAAG,CAAC,IAAI,IAAI,KAAK,KAAK,GAAG,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AACrF,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AgentToolsOptions, ServerConfig } from "./config.js";
|
|
2
|
+
import type { DispatchResult, ToolInfo } from "./core.js";
|
|
3
|
+
export interface AgentTools {
|
|
4
|
+
readonly config: ServerConfig;
|
|
5
|
+
listTools(): ToolInfo[];
|
|
6
|
+
callTool(name: string, args?: Record<string, unknown>): Promise<DispatchResult>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createAgentTools(options: AgentToolsOptions): AgentTools;
|
|
9
|
+
export { dispatch, listTools } from "./core.js";
|
|
10
|
+
export type { DispatchResult, ToolInfo } from "./core.js";
|
|
11
|
+
export { resolveConfig, buildConfig, StartupError, DEFAULT_MAX_OUTPUT_BYTES, DEFAULT_MAX_FILE_BYTES, DEFAULT_BASH_TIMEOUT_MS, DEFAULT_BASH_TIMEOUT_MAX_MS, } from "./config.js";
|
|
12
|
+
export type { ServerConfig, AgentToolsOptions } from "./config.js";
|
|
13
|
+
export { tools, readOnlyTools, getTool, selectSurface } from "./tools/registry.js";
|
|
14
|
+
export type { ToolDef } from "./tools/types.js";
|
|
15
|
+
export { ToolError, serializeError, fsError } from "./errors.js";
|
|
16
|
+
export type { ErrorCode } from "./errors.js";
|
|
17
|
+
export { sweepSpillDir } from "./lib/output.js";
|
|
18
|
+
export { setWarnSink } from "./lib/log.js";
|
|
19
|
+
export type { WarnSink } from "./lib/log.js";
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAE9B,SAAS,IAAI,QAAQ,EAAE,CAAC;IAExB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACjF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAOvE;AAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1D,OAAO,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACnF,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { resolveConfig } from "./config.js";
|
|
2
|
+
import { dispatch, listTools } from "./core.js";
|
|
3
|
+
export function createAgentTools(options) {
|
|
4
|
+
const config = resolveConfig(options);
|
|
5
|
+
return {
|
|
6
|
+
config,
|
|
7
|
+
listTools: () => listTools(config),
|
|
8
|
+
callTool: (name, args = {}) => dispatch(name, args, config),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export { dispatch, listTools } from "./core.js";
|
|
12
|
+
export { resolveConfig, buildConfig, StartupError, DEFAULT_MAX_OUTPUT_BYTES, DEFAULT_MAX_FILE_BYTES, DEFAULT_BASH_TIMEOUT_MS, DEFAULT_BASH_TIMEOUT_MAX_MS, } from "./config.js";
|
|
13
|
+
export { tools, readOnlyTools, getTool, selectSurface } from "./tools/registry.js";
|
|
14
|
+
export { ToolError, serializeError, fsError } from "./errors.js";
|
|
15
|
+
export { sweepSpillDir } from "./lib/output.js";
|
|
16
|
+
export { setWarnSink } from "./lib/log.js";
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAYhD,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,OAAO;QACL,MAAM;QACN,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC;QAClC,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGhD,OAAO,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGnF,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function withFileLock<T>(absPath: string, fn: () => Promise<T>): Promise<T>;
|
|
2
|
+
export declare function withFileLocks<T>(paths: string[], fn: () => Promise<T>): Promise<T>;
|
|
3
|
+
export declare function writeAtomic(target: string, content: string): Promise<void>;
|
|
4
|
+
export interface FileOp {
|
|
5
|
+
type: "create" | "modify" | "delete" | "rename";
|
|
6
|
+
path: string;
|
|
7
|
+
from?: string;
|
|
8
|
+
content?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function applyOpsAtomic(ops: FileOp[]): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=atomic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic.d.ts","sourceRoot":"","sources":["../../src/lib/atomic.ts"],"names":[],"mappings":"AAOA,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAYjF;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAGlF;AAiED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAahF;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAoLD,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCjE"}
|