@gaunt-sloth/agent 2.0.0-alpha.3 → 2.0.0-alpha.30
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/README.md +73 -23
- package/dist/builtInToolsConfig.d.ts +17 -3
- package/dist/builtInToolsConfig.js +40 -41
- package/dist/builtInToolsConfig.js.map +1 -1
- package/dist/core/GthDeepAgent.d.ts +52 -32
- package/dist/core/GthDeepAgent.js +438 -198
- package/dist/core/GthDeepAgent.js.map +1 -1
- package/dist/core/debugCapture.d.ts +8 -49
- package/dist/core/debugCapture.js +1 -1
- package/dist/core/debugCapture.js.map +1 -1
- package/dist/core/deepAgentPermissions.d.ts +67 -2
- package/dist/core/deepAgentPermissions.js +151 -3
- package/dist/core/deepAgentPermissions.js.map +1 -1
- package/dist/core/gthAcpServer.js +11 -0
- package/dist/core/gthAcpServer.js.map +1 -1
- package/dist/core/gthDeepAgentFactory.d.ts +3 -0
- package/dist/core/gthDeepAgentFactory.js +9 -1
- package/dist/core/gthDeepAgentFactory.js.map +1 -1
- package/dist/core/resolveAgentFactory.d.ts +14 -0
- package/dist/core/resolveAgentFactory.js +18 -0
- package/dist/core/resolveAgentFactory.js.map +1 -0
- package/dist/core/subagentProfiles.d.ts +50 -0
- package/dist/core/subagentProfiles.js +76 -0
- package/dist/core/subagentProfiles.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/OAuthClientProviderImpl.js.map +1 -1
- package/dist/mcp/tlsTrust.d.ts +61 -0
- package/dist/mcp/tlsTrust.js +109 -0
- package/dist/mcp/tlsTrust.js.map +1 -0
- package/dist/middleware/binaryContentInjectionMiddleware.d.ts +8 -1
- package/dist/middleware/binaryContentInjectionMiddleware.js +11 -2
- package/dist/middleware/binaryContentInjectionMiddleware.js.map +1 -1
- package/dist/middleware/frontendImageInjectionMiddleware.d.ts +106 -0
- package/dist/middleware/frontendImageInjectionMiddleware.js +166 -0
- package/dist/middleware/frontendImageInjectionMiddleware.js.map +1 -0
- package/dist/middleware/registry.js +36 -1
- package/dist/middleware/registry.js.map +1 -1
- package/dist/middleware/types.d.ts +16 -2
- package/dist/modules/a2a/A2AClientWrapper.d.ts +56 -1
- package/dist/modules/a2a/A2AClientWrapper.js +131 -31
- package/dist/modules/a2a/A2AClientWrapper.js.map +1 -1
- package/dist/modules/acpModule.js +17 -1
- package/dist/modules/acpModule.js.map +1 -1
- package/dist/modules/apiAgUiModule.d.ts +87 -0
- package/dist/modules/apiAgUiModule.js +229 -28
- package/dist/modules/apiAgUiModule.js.map +1 -1
- package/dist/modules/interactiveSessionModule.js +501 -41
- package/dist/modules/interactiveSessionModule.js.map +1 -1
- package/dist/modules/slashCommands.d.ts +576 -0
- package/dist/modules/slashCommands.js +995 -0
- package/dist/modules/slashCommands.js.map +1 -0
- package/dist/resolvers.js +119 -9
- package/dist/resolvers.js.map +1 -1
- package/dist/tools/GthCustomToolkit.js +95 -11
- package/dist/tools/GthCustomToolkit.js.map +1 -1
- package/dist/tools/GthDevToolkit.d.ts +11 -3
- package/dist/tools/GthDevToolkit.js +120 -34
- package/dist/tools/GthDevToolkit.js.map +1 -1
- package/dist/tools/GthFileSystemToolkit.d.ts +63 -0
- package/dist/tools/GthFileSystemToolkit.js +506 -105
- package/dist/tools/GthFileSystemToolkit.js.map +1 -1
- package/dist/tools/McpResourceTool.d.ts +31 -0
- package/dist/tools/McpResourceTool.js +106 -0
- package/dist/tools/McpResourceTool.js.map +1 -0
- package/dist/tools/gthChecklistTool.d.ts +30 -0
- package/dist/tools/gthChecklistTool.js +81 -0
- package/dist/tools/gthChecklistTool.js.map +1 -0
- package/dist/tools/gthGrepTool.d.ts +54 -0
- package/dist/tools/gthGrepTool.js +482 -0
- package/dist/tools/gthGrepTool.js.map +1 -0
- package/dist/tools/shell/env.js +1 -1
- package/dist/tools/shell/env.js.map +1 -1
- package/dist/tools/shell/outputBuffer.js.map +1 -1
- package/dist/tools/shell/workDir.d.ts +11 -0
- package/dist/tools/shell/workDir.js +45 -0
- package/dist/tools/shell/workDir.js.map +1 -0
- package/dist/utils/mcpAuthError.d.ts +36 -0
- package/dist/utils/mcpAuthError.js +89 -0
- package/dist/utils/mcpAuthError.js.map +1 -0
- package/dist/utils/mcpUtils.js +16 -0
- package/dist/utils/mcpUtils.js.map +1 -1
- package/package.json +12 -11
- package/dist/tools/shell/allowlist.d.ts +0 -11
- package/dist/tools/shell/allowlist.js +0 -12
- package/dist/tools/shell/allowlist.js.map +0 -1
- package/dist/tools/shell/arity.d.ts +0 -11
- package/dist/tools/shell/arity.js +0 -12
- package/dist/tools/shell/arity.js.map +0 -1
- package/dist/tools/shell/hardline.d.ts +0 -15
- package/dist/tools/shell/hardline.js +0 -88
- package/dist/tools/shell/hardline.js.map +0 -1
- package/dist/tools/shell/normalize.d.ts +0 -10
- package/dist/tools/shell/normalize.js +0 -11
- package/dist/tools/shell/normalize.js.map +0 -1
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module gthGrepTool
|
|
3
|
+
* The `gth_grep` content-search tool — a structured, permission-light regex search over file
|
|
4
|
+
* CONTENTS. Complements `search_files` (which only matches file NAMES) and gives the lean agent a
|
|
5
|
+
* grep primitive without falling back to the shell-approval-gated `run_shell_command`. Being a
|
|
6
|
+
* built-in (not a dev tool) it is available in every mode, unlike `run_shell_command`.
|
|
7
|
+
*
|
|
8
|
+
* Two execution paths, ONE output shape:
|
|
9
|
+
* - shell out to ripgrep (`rg`) when it is on PATH;
|
|
10
|
+
* - fall back to an in-process JS scanner when `rg` is absent (CI machines may not have ripgrep).
|
|
11
|
+
* Both sandbox to the current work-dir boundary ({@link getCurrentWorkDir}), bound each matching
|
|
12
|
+
* line's preview, cap the total match count, and enforce the `.aiignore` privacy boundary on BOTH
|
|
13
|
+
* engines ({@link makeAiignoreFilter}) — since the tool reads file contents through its own path, it
|
|
14
|
+
* must honour `.aiignore` itself rather than rely on the filesystem toolkit.
|
|
15
|
+
*
|
|
16
|
+
* Named `gth_grep`, NOT `grep`: the experimental deep backend (deepagents) registers its own `grep`
|
|
17
|
+
* built-in and `createDeepAgent` throws on a name collision because both backends share the resolved
|
|
18
|
+
* toolset — the same reason {@link file://./gthChecklistTool.ts} is not called `write_todos`.
|
|
19
|
+
*/
|
|
20
|
+
import { tool } from '@langchain/core/tools';
|
|
21
|
+
import { z } from 'zod';
|
|
22
|
+
import { execFile } from 'node:child_process';
|
|
23
|
+
import fs from 'node:fs/promises';
|
|
24
|
+
import path from 'node:path';
|
|
25
|
+
import { normalizeBuiltInTools } from '@gaunt-sloth/core/config.js';
|
|
26
|
+
import { getCurrentWorkDir } from '@gaunt-sloth/core/utils/systemUtils.js';
|
|
27
|
+
import { shouldIgnoreFile } from '@gaunt-sloth/core/utils/aiignoreUtils.js';
|
|
28
|
+
export const GREP_TOOL_NAME = 'gth_grep';
|
|
29
|
+
/**
|
|
30
|
+
* Resolve the effective {@link GrepFileSet} from config. Reads the `gth_grep` entry of the SAME
|
|
31
|
+
* `builtInTools` registry that {@link file://../builtInToolsConfig.ts} uses to decide enablement, so
|
|
32
|
+
* the corpus selection and the tool's presence resolve from one source. Defaults to `gitignore`
|
|
33
|
+
* (the coordinator-set default, and already rg's native default — so rg-present machines see no
|
|
34
|
+
* behaviour change; only the selection becomes explicit).
|
|
35
|
+
*/
|
|
36
|
+
export function resolveGrepFileSet(config) {
|
|
37
|
+
const entry = normalizeBuiltInTools(config?.builtInTools)[GREP_TOOL_NAME];
|
|
38
|
+
if (entry && typeof entry === 'object' && entry.fileSet === 'all')
|
|
39
|
+
return 'all';
|
|
40
|
+
return 'gitignore';
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build the `.aiignore` privacy filter for a grep run.
|
|
44
|
+
*
|
|
45
|
+
* SECURITY (GS2-51): `gth_grep` reads file CONTENTS through its OWN ripgrep / `fs.readFile` path,
|
|
46
|
+
* so — unlike the gsloth filesystem toolkit — it must enforce `.aiignore` ITSELF. Otherwise, being
|
|
47
|
+
* on by default, it would be a default-on bypass of that boundary on BOTH backends: the deep backend
|
|
48
|
+
* deliberately disables its fs toolkit precisely so a model cannot read an `.aiignore`-protected file
|
|
49
|
+
* (see {@link file://../core/GthDeepAgent.ts}), and `gth_grep` would re-open exactly that hole.
|
|
50
|
+
* `.gitignore` means "don't commit" (build junk); `.aiignore` means "don't let the AI read this,
|
|
51
|
+
* even though it is a real tracked file" — so an `.aiignore`'d-but-tracked-and-not-hidden file is the
|
|
52
|
+
* PRIMARY case, and is enforced on BOTH engines and under BOTH {@link GrepFileSet} corpora (the
|
|
53
|
+
* privacy boundary is orthogonal to the gitignore/all selection).
|
|
54
|
+
*
|
|
55
|
+
* Reuses the SAME {@link shouldIgnoreFile} matcher and the SAME rootDir (the work-dir) the fs toolkit
|
|
56
|
+
* uses, so a file is treated identically here as there — no hand-rolled `.aiignore` parsing.
|
|
57
|
+
*
|
|
58
|
+
* @returns predicate that is TRUE when `absPath` is ALLOWED (not aiignored).
|
|
59
|
+
*/
|
|
60
|
+
function makeAiignoreFilter(workDir, aiignore) {
|
|
61
|
+
return (absPath) => !shouldIgnoreFile(absPath, workDir, aiignore?.patterns, aiignore?.enabled);
|
|
62
|
+
}
|
|
63
|
+
/** Default cap on the number of matches returned when the caller does not pass `limit`. */
|
|
64
|
+
const DEFAULT_LIMIT = 100;
|
|
65
|
+
/** Noise directories both paths skip: the JS fallback walk, and rg via `--glob !<dir>` excludes. */
|
|
66
|
+
const IGNORED_DIRS = new Set(['.git', 'node_modules', 'dist', '.idea']);
|
|
67
|
+
/** Longest matching-line preview kept before truncation, so one minified line can't blow context. */
|
|
68
|
+
const MAX_LINE_LENGTH = 250;
|
|
69
|
+
const TRUNCATION_MARKER = ' … (line truncated)';
|
|
70
|
+
/**
|
|
71
|
+
* JS-fallback only: cap the length of text fed to the regex per line. A single huge/minified line
|
|
72
|
+
* would otherwise let a model-supplied pattern block the event loop (large linear scans, and
|
|
73
|
+
* catastrophic backtracking grows with input length). rg (native, non-backtracking) is immune, so
|
|
74
|
+
* this bounds the fallback only. Matches beyond the cap on such a line are not found.
|
|
75
|
+
*/
|
|
76
|
+
const MAX_SCAN_LINE_LENGTH = 4096;
|
|
77
|
+
/** Ceiling on rg stdout we buffer (matches are sliced to `limit` anyway). */
|
|
78
|
+
const RG_MAX_BUFFER = 32 * 1024 * 1024;
|
|
79
|
+
const schema = z.object({
|
|
80
|
+
pattern: z.string().min(1).describe('Regular expression to search file CONTENTS for.'),
|
|
81
|
+
path: z
|
|
82
|
+
.string()
|
|
83
|
+
.optional()
|
|
84
|
+
.describe('Relative directory or file to search, within the working directory. Defaults to the ' +
|
|
85
|
+
'current working directory.'),
|
|
86
|
+
include: z
|
|
87
|
+
.string()
|
|
88
|
+
.optional()
|
|
89
|
+
.describe('Optional file glob to filter matched files, e.g. "*.ts" or "*.{ts,tsx}".'),
|
|
90
|
+
limit: z
|
|
91
|
+
.number()
|
|
92
|
+
.int()
|
|
93
|
+
.min(1)
|
|
94
|
+
.optional()
|
|
95
|
+
.describe(`Maximum number of matches to return (default ${DEFAULT_LIMIT}).`),
|
|
96
|
+
});
|
|
97
|
+
const description = [
|
|
98
|
+
'Search file CONTENTS by regular expression (ripgrep-backed, with an in-process fallback).',
|
|
99
|
+
'Use this to find WHERE a symbol, string, or pattern appears across files — unlike search_files,',
|
|
100
|
+
'which matches file NAMES only. Returns matching files with 1-based line numbers and a bounded',
|
|
101
|
+
'preview of each matching line.',
|
|
102
|
+
'',
|
|
103
|
+
'Args: pattern (regex, required); path (relative dir/file, defaults to the working directory);',
|
|
104
|
+
'include (file glob such as "*.ts" or "*.{ts,tsx}"); limit (max matches). Searches are confined',
|
|
105
|
+
'to the working directory.',
|
|
106
|
+
].join('\n');
|
|
107
|
+
/** Error whose message is safe to return to the model as the tool observation. */
|
|
108
|
+
class GrepError extends Error {
|
|
109
|
+
}
|
|
110
|
+
/** Sentinel: `rg` is not installed — the orchestrator must use the JS fallback. */
|
|
111
|
+
class RipgrepUnavailableError extends Error {
|
|
112
|
+
}
|
|
113
|
+
/** Truncate an over-long matching-line preview with a clear marker. */
|
|
114
|
+
function truncateLine(text) {
|
|
115
|
+
if (text.length <= MAX_LINE_LENGTH)
|
|
116
|
+
return text;
|
|
117
|
+
return text.slice(0, MAX_LINE_LENGTH) + TRUNCATION_MARKER;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Render matches in the concise, opencode-style grouped form. Shared by BOTH execution paths so
|
|
121
|
+
* the rg and JS-fallback outputs are provably identical.
|
|
122
|
+
*/
|
|
123
|
+
export function formatGrepOutput(matches) {
|
|
124
|
+
if (matches.length === 0)
|
|
125
|
+
return 'No matches found';
|
|
126
|
+
const lines = [`Found ${matches.length} matches`];
|
|
127
|
+
let currentPath = '';
|
|
128
|
+
for (const m of matches) {
|
|
129
|
+
if (m.path !== currentPath) {
|
|
130
|
+
if (currentPath)
|
|
131
|
+
lines.push('');
|
|
132
|
+
currentPath = m.path;
|
|
133
|
+
lines.push(`${m.path}:`);
|
|
134
|
+
}
|
|
135
|
+
lines.push(` Line ${m.line}: ${truncateLine(m.text)}`);
|
|
136
|
+
}
|
|
137
|
+
return lines.join('\n');
|
|
138
|
+
}
|
|
139
|
+
/** rg prints `./foo` for the cwd root; normalise to bare relative paths to match the JS scanner. */
|
|
140
|
+
function normalizeRelPath(p) {
|
|
141
|
+
return p.startsWith('./') ? p.slice(2) : p;
|
|
142
|
+
}
|
|
143
|
+
/** Escape the literal parts of a glob for use inside a RegExp. */
|
|
144
|
+
function escapeRegExp(s) {
|
|
145
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Compile an include glob (matched against a file's basename in the JS fallback) to a RegExp.
|
|
149
|
+
* Supports `*`, `?`, and `{a,b,c}` brace alternation, e.g. `*.ts`, `*.{ts,tsx}`.
|
|
150
|
+
*
|
|
151
|
+
* NOTE (rg-vs-JS divergence): this matches the basename only, whereas rg applies `--glob` with full
|
|
152
|
+
* gitignore-style path-glob semantics (a glob can match against the path, not just the basename).
|
|
153
|
+
* For the common `*.ext` case the two agree; more elaborate globs may differ between the two paths.
|
|
154
|
+
*/
|
|
155
|
+
export function globToRegExp(glob) {
|
|
156
|
+
let re = '';
|
|
157
|
+
let i = 0;
|
|
158
|
+
while (i < glob.length) {
|
|
159
|
+
const c = glob[i];
|
|
160
|
+
if (c === '*') {
|
|
161
|
+
re += '[^/]*';
|
|
162
|
+
}
|
|
163
|
+
else if (c === '?') {
|
|
164
|
+
re += '[^/]';
|
|
165
|
+
}
|
|
166
|
+
else if (c === '{') {
|
|
167
|
+
const end = glob.indexOf('}', i);
|
|
168
|
+
if (end === -1) {
|
|
169
|
+
re += '\\{';
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
const options = glob
|
|
173
|
+
.slice(i + 1, end)
|
|
174
|
+
.split(',')
|
|
175
|
+
.map(escapeRegExp);
|
|
176
|
+
re += '(?:' + options.join('|') + ')';
|
|
177
|
+
i = end + 1;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
re += escapeRegExp(c);
|
|
183
|
+
}
|
|
184
|
+
i++;
|
|
185
|
+
}
|
|
186
|
+
return new RegExp('^' + re + '$');
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Resolve a path to its real, symlink-free location, walking up to the nearest EXISTING ancestor
|
|
190
|
+
* when the path itself does not exist yet. Only an existing component can be (or sit behind) a
|
|
191
|
+
* symlink, so resolving the nearest real ancestor is enough to catch an intermediate symlinked
|
|
192
|
+
* directory. Terminates because `path.dirname` strictly shortens the path to the filesystem root.
|
|
193
|
+
*/
|
|
194
|
+
async function realpathNearestExisting(absPath) {
|
|
195
|
+
let current = absPath;
|
|
196
|
+
for (;;) {
|
|
197
|
+
try {
|
|
198
|
+
return await fs.realpath(current);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
const parent = path.dirname(current);
|
|
202
|
+
if (parent === current)
|
|
203
|
+
return current; // filesystem root; nothing left to resolve
|
|
204
|
+
current = parent;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/** True when `child` equals `root` or is a descendant of it. */
|
|
209
|
+
function isWithin(child, root) {
|
|
210
|
+
return child === root || child.startsWith(`${root}${path.sep}`);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Resolve `path` under the working directory and refuse anything that escapes it. The whole tool
|
|
214
|
+
* is sandboxed to this boundary.
|
|
215
|
+
*/
|
|
216
|
+
async function resolveTarget(inputPath, workDir) {
|
|
217
|
+
const absWorkDir = path.resolve(workDir);
|
|
218
|
+
const requested = path.resolve(absWorkDir, inputPath ?? '.');
|
|
219
|
+
const rel = path.relative(absWorkDir, requested);
|
|
220
|
+
if (rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
221
|
+
throw new GrepError(`Refusing to search '${inputPath}': path escapes the working directory (${absWorkDir}).`);
|
|
222
|
+
}
|
|
223
|
+
// Symlink containment: the lexical check above cannot catch a symlink INSIDE the workdir that
|
|
224
|
+
// points outside it (rel would not start with `..`, and stat/rg/the walk would then follow it out
|
|
225
|
+
// of the sandbox). Resolve real paths and re-assert containment. The workdir root is realpath'd
|
|
226
|
+
// too, since its own path may contain symlinks (e.g. /tmp -> /private/tmp). A not-yet-existing
|
|
227
|
+
// target resolves via its nearest existing ancestor, so a missing path is contained here and then
|
|
228
|
+
// reported as "not found" by the stat below, rather than crashing.
|
|
229
|
+
const realRoot = await realpathNearestExisting(absWorkDir);
|
|
230
|
+
const realTarget = await realpathNearestExisting(requested);
|
|
231
|
+
if (!isWithin(realTarget, realRoot)) {
|
|
232
|
+
throw new GrepError(`Refusing to search '${inputPath}': path escapes the working directory (${absWorkDir}).`);
|
|
233
|
+
}
|
|
234
|
+
let stat;
|
|
235
|
+
try {
|
|
236
|
+
stat = await fs.stat(requested);
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
throw new GrepError(`Path not found: ${inputPath ?? '.'}`);
|
|
240
|
+
}
|
|
241
|
+
if (stat.isDirectory()) {
|
|
242
|
+
return { searchRoot: requested };
|
|
243
|
+
}
|
|
244
|
+
return { searchRoot: path.dirname(requested), file: path.basename(requested) };
|
|
245
|
+
}
|
|
246
|
+
/** Parse ripgrep's `path:line:text` output (with `--with-filename --line-number --no-heading`). */
|
|
247
|
+
function parseRipgrepOutput(stdout) {
|
|
248
|
+
const matches = [];
|
|
249
|
+
for (const raw of stdout.split('\n')) {
|
|
250
|
+
if (!raw)
|
|
251
|
+
continue;
|
|
252
|
+
const first = raw.indexOf(':');
|
|
253
|
+
if (first < 0)
|
|
254
|
+
continue;
|
|
255
|
+
const second = raw.indexOf(':', first + 1);
|
|
256
|
+
if (second < 0)
|
|
257
|
+
continue;
|
|
258
|
+
const lineNum = Number(raw.slice(first + 1, second));
|
|
259
|
+
if (!Number.isInteger(lineNum))
|
|
260
|
+
continue;
|
|
261
|
+
matches.push({
|
|
262
|
+
path: normalizeRelPath(raw.slice(0, first)),
|
|
263
|
+
line: lineNum,
|
|
264
|
+
text: raw.slice(second + 1),
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
return matches;
|
|
268
|
+
}
|
|
269
|
+
function buildRipgrepArgs(pattern, target, include, fileSet) {
|
|
270
|
+
// GS2-51 — the searched corpus is a resolved config choice ({@link GrepFileSet}), applied
|
|
271
|
+
// consistently to both engines. `gitignore` (default) keeps rg's native behaviour: honour
|
|
272
|
+
// `.gitignore`/`.ignore` and skip hidden dot-files — so nothing is added here. `all` scans
|
|
273
|
+
// everything but the noise dirs, so pass `--no-ignore --hidden` (the IGNORED_DIRS excludes below
|
|
274
|
+
// still apply). NOTE (residual rg-vs-JS divergence): under `gitignore` the JS fallback
|
|
275
|
+
// ({@link collectFiles}) is only a best-effort approximation (skips IGNORED_DIRS + hidden
|
|
276
|
+
// dot-files); it does NOT read arbitrary `.gitignore` rules the way rg does, so the searched
|
|
277
|
+
// file-set can still differ when rg is absent. A full gitignore parser is deliberately out of
|
|
278
|
+
// scope — see the note on {@link collectFiles}.
|
|
279
|
+
const args = ['--line-number', '--no-heading', '--with-filename', '--color=never'];
|
|
280
|
+
if (fileSet === 'all') {
|
|
281
|
+
args.push('--no-ignore', '--hidden');
|
|
282
|
+
}
|
|
283
|
+
// Exclude the same noise dirs the JS fallback skips, so the two paths stay consistent. rg only
|
|
284
|
+
// auto-skips node_modules etc. when a .gitignore says so; outside a git repo (or under
|
|
285
|
+
// `--no-ignore`) it descends into them, so we exclude them explicitly here.
|
|
286
|
+
for (const dir of IGNORED_DIRS) {
|
|
287
|
+
args.push('--glob', `!${dir}`);
|
|
288
|
+
}
|
|
289
|
+
if (include) {
|
|
290
|
+
args.push('--glob', include);
|
|
291
|
+
}
|
|
292
|
+
args.push('-e', pattern, '--', target.file ?? '.');
|
|
293
|
+
return args;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Run ripgrep. Resolves to matches (empty on rg exit 1 = "no matches"). Rejects with
|
|
297
|
+
* {@link RipgrepUnavailableError} when `rg` is not on PATH, or {@link GrepError} on a real rg error
|
|
298
|
+
* (e.g. an invalid regex → rg exit 2).
|
|
299
|
+
*/
|
|
300
|
+
function runRipgrep(pattern, target, include, fileSet, isAllowed) {
|
|
301
|
+
const args = buildRipgrepArgs(pattern, target, include, fileSet);
|
|
302
|
+
return new Promise((resolve, reject) => {
|
|
303
|
+
execFile('rg', args, { cwd: target.searchRoot, maxBuffer: RG_MAX_BUFFER }, (error, stdout, stderr) => {
|
|
304
|
+
if (error) {
|
|
305
|
+
const code = error
|
|
306
|
+
.code;
|
|
307
|
+
if (code === 'ENOENT') {
|
|
308
|
+
reject(new RipgrepUnavailableError('ripgrep (rg) not found on PATH'));
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
// rg exit code 1 == no matches (execFile surfaces the non-zero exit as an error).
|
|
312
|
+
if (code === 1) {
|
|
313
|
+
resolve([]);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const detail = (stderr ?? '').toString().trim();
|
|
317
|
+
reject(new GrepError(`Search failed: ${detail || error.message}`));
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
// rg does not consult `.aiignore` — post-filter its matched paths through the SAME hook the
|
|
321
|
+
// JS fallback uses, so both engines enforce the privacy boundary identically. A match whose
|
|
322
|
+
// file is aiignored is dropped before it can reach the model.
|
|
323
|
+
resolve(parseRipgrepOutput(stdout.toString()).filter((m) => isAllowed(path.join(target.searchRoot, m.path))));
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Recursively collect regular files under `dir`, skipping {@link IGNORED_DIRS}. Symlinked entries
|
|
329
|
+
* (dirs and files) report `isDirectory()`/`isFile()` as false here, so the walk never follows them
|
|
330
|
+
* out of the sandbox — only the explicit target path needs the realpath guard in {@link resolveTarget}.
|
|
331
|
+
*
|
|
332
|
+
* GS2-51 — corpus selection ({@link GrepFileSet}), applied consistently with the rg path:
|
|
333
|
+
* - `skipHidden` true (the `gitignore` default): additionally skip hidden dot-files/dirs, moving the
|
|
334
|
+
* fallback CLOSER to rg's default of honouring `.gitignore` + hiding dot-files;
|
|
335
|
+
* - `skipHidden` false (`all`): skip only IGNORED_DIRS — everything-but-noise (the historical
|
|
336
|
+
* behaviour), matching rg's `--no-ignore --hidden`.
|
|
337
|
+
*
|
|
338
|
+
* NOTE (residual rg-vs-JS divergence — deliberate, bounded scope): even under `gitignore` this is
|
|
339
|
+
* only a best-effort approximation. It does NOT parse arbitrary `.gitignore`/`.ignore` rules the way
|
|
340
|
+
* rg does — a file gitignored by a custom pattern (but not a dot-file and not under IGNORED_DIRS) is
|
|
341
|
+
* still searched by the fallback though rg would skip it. Implementing a full gitignore engine here
|
|
342
|
+
* is out of scope; this is documented, not fixed — exactly like the regex-dialect divergence noted
|
|
343
|
+
* in {@link runJsScanner}.
|
|
344
|
+
*/
|
|
345
|
+
async function collectFiles(dir, out, skipHidden) {
|
|
346
|
+
let entries;
|
|
347
|
+
try {
|
|
348
|
+
entries = (await fs.readdir(dir, { withFileTypes: true }));
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
for (const entry of entries) {
|
|
354
|
+
// Hidden-skip is checked first so it covers BOTH hidden files and hidden dirs.
|
|
355
|
+
if (skipHidden && entry.name.startsWith('.'))
|
|
356
|
+
continue;
|
|
357
|
+
const full = path.join(dir, entry.name);
|
|
358
|
+
if (entry.isDirectory()) {
|
|
359
|
+
if (IGNORED_DIRS.has(entry.name))
|
|
360
|
+
continue;
|
|
361
|
+
await collectFiles(full, out, skipHidden);
|
|
362
|
+
}
|
|
363
|
+
else if (entry.isFile()) {
|
|
364
|
+
out.push(full);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* In-process fallback used when `rg` is absent: walk files under the target (respecting `include`
|
|
370
|
+
* and the ignore list) and apply the regex per line. Produces the identical {@link GrepMatch} shape
|
|
371
|
+
* as the ripgrep path.
|
|
372
|
+
*/
|
|
373
|
+
async function runJsScanner(pattern, target, include, limit, fileSet, isAllowed) {
|
|
374
|
+
let regex;
|
|
375
|
+
try {
|
|
376
|
+
// NOTE (rg-vs-JS divergence): the fallback uses the ECMAScript regex dialect (`new RegExp`),
|
|
377
|
+
// whereas rg uses the Rust `regex` crate. Host-specific features differ — notably lookaround
|
|
378
|
+
// and backreferences work here but are unsupported by rg — so the same pattern can behave
|
|
379
|
+
// differently depending on which path runs.
|
|
380
|
+
regex = new RegExp(pattern);
|
|
381
|
+
}
|
|
382
|
+
catch (e) {
|
|
383
|
+
throw new GrepError(`Search failed: invalid regular expression: ${e.message}`);
|
|
384
|
+
}
|
|
385
|
+
const includeRe = include ? globToRegExp(include) : undefined;
|
|
386
|
+
const files = [];
|
|
387
|
+
if (target.file) {
|
|
388
|
+
// An explicitly-named target file is searched even if it is a hidden dot-file — the corpus
|
|
389
|
+
// selection only governs directory discovery, matching rg's behaviour on an explicit arg. The
|
|
390
|
+
// one exception is `.aiignore`: an aiignored file named by hand is still blocked below (hidden ≠
|
|
391
|
+
// aiignored), so naming the file cannot be used as a bypass.
|
|
392
|
+
files.push(path.join(target.searchRoot, target.file));
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
await collectFiles(target.searchRoot, files, fileSet === 'gitignore');
|
|
396
|
+
}
|
|
397
|
+
const matches = [];
|
|
398
|
+
for (const file of files) {
|
|
399
|
+
if (matches.length >= limit)
|
|
400
|
+
break;
|
|
401
|
+
if (includeRe && !includeRe.test(path.basename(file)))
|
|
402
|
+
continue;
|
|
403
|
+
// `.aiignore` privacy boundary (GS2-51): skip BEFORE reading, so an aiignored file's contents
|
|
404
|
+
// are never even loaded — covers both the walk and an explicitly-named single-file target.
|
|
405
|
+
if (!isAllowed(file))
|
|
406
|
+
continue;
|
|
407
|
+
let content;
|
|
408
|
+
try {
|
|
409
|
+
content = await fs.readFile(file, 'utf8');
|
|
410
|
+
}
|
|
411
|
+
catch {
|
|
412
|
+
continue; // unreadable / non-text; skip
|
|
413
|
+
}
|
|
414
|
+
const rel = normalizeRelPath(path.relative(target.searchRoot, file));
|
|
415
|
+
const lines = content.split('\n');
|
|
416
|
+
for (let i = 0; i < lines.length; i++) {
|
|
417
|
+
if (matches.length >= limit)
|
|
418
|
+
break;
|
|
419
|
+
const line = lines[i];
|
|
420
|
+
// Bound the regex input per line (see MAX_SCAN_LINE_LENGTH): a huge/minified line must not
|
|
421
|
+
// block the event loop. We test a truncated view but store the original line (its preview is
|
|
422
|
+
// bounded again at format time); a match beyond the cap on such a line is not reported.
|
|
423
|
+
const scanText = line.length > MAX_SCAN_LINE_LENGTH ? line.slice(0, MAX_SCAN_LINE_LENGTH) : line;
|
|
424
|
+
if (regex.test(scanText)) {
|
|
425
|
+
matches.push({ path: rel, line: i + 1, text: line });
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return matches;
|
|
430
|
+
}
|
|
431
|
+
async function grepImpl(args, workDir, fileSet, aiignore) {
|
|
432
|
+
const limit = args.limit ?? DEFAULT_LIMIT;
|
|
433
|
+
let target;
|
|
434
|
+
try {
|
|
435
|
+
target = await resolveTarget(args.path, workDir);
|
|
436
|
+
}
|
|
437
|
+
catch (e) {
|
|
438
|
+
if (e instanceof GrepError)
|
|
439
|
+
return e.message;
|
|
440
|
+
throw e;
|
|
441
|
+
}
|
|
442
|
+
// The `.aiignore` privacy filter is resolved against the work-dir root (matching the fs toolkit)
|
|
443
|
+
// and enforced on whichever engine runs — see makeAiignoreFilter.
|
|
444
|
+
const isAllowed = makeAiignoreFilter(workDir, aiignore);
|
|
445
|
+
let matches;
|
|
446
|
+
try {
|
|
447
|
+
matches = await runRipgrep(args.pattern, target, args.include, fileSet, isAllowed);
|
|
448
|
+
}
|
|
449
|
+
catch (e) {
|
|
450
|
+
if (e instanceof RipgrepUnavailableError) {
|
|
451
|
+
try {
|
|
452
|
+
matches = await runJsScanner(args.pattern, target, args.include, limit, fileSet, isAllowed);
|
|
453
|
+
}
|
|
454
|
+
catch (inner) {
|
|
455
|
+
if (inner instanceof GrepError)
|
|
456
|
+
return inner.message;
|
|
457
|
+
throw inner;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
else if (e instanceof GrepError) {
|
|
461
|
+
return e.message;
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
throw e;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
// ripgrep has no total-match cap of its own; bound the count here so both paths agree.
|
|
468
|
+
if (matches.length > limit)
|
|
469
|
+
matches = matches.slice(0, limit);
|
|
470
|
+
return formatGrepOutput(matches);
|
|
471
|
+
}
|
|
472
|
+
export function get(config) {
|
|
473
|
+
// Resolve the corpus selection once at tool-construction time from the same config that decided
|
|
474
|
+
// this tool is enabled (GS2-51); the searched file-set is a config choice, not a per-call arg.
|
|
475
|
+
const fileSet = resolveGrepFileSet(config);
|
|
476
|
+
// The `.aiignore` privacy boundary (GS2-51) is read from the SAME config the fs toolkit reads it
|
|
477
|
+
// from, so gth_grep enforces it identically — see makeAiignoreFilter.
|
|
478
|
+
const aiignore = config?.aiignore;
|
|
479
|
+
const impl = async (args) => grepImpl(args, getCurrentWorkDir(), fileSet, aiignore);
|
|
480
|
+
return tool(impl, { name: GREP_TOOL_NAME, description, schema });
|
|
481
|
+
}
|
|
482
|
+
//# sourceMappingURL=gthGrepTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gthGrepTool.js","sourceRoot":"","sources":["../../src/tools/gthGrepTool.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/shell/env.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @module tools/shell/env
|
|
3
3
|
*
|
|
4
4
|
* Credential scrubbing for the shell tool's child environment. By default a
|
|
5
|
-
* spawned child inherits `process.env` verbatim, so an approved (or
|
|
5
|
+
* spawned child inherits `process.env` verbatim, so an approved (or bypassed)
|
|
6
6
|
* command can `echo $ANTHROPIC_API_KEY` and exfiltrate the operator's LLM/cloud
|
|
7
7
|
* credentials. {@link buildScrubbedEnv} returns a copy of the parent env with
|
|
8
8
|
* those credentials removed before spawn.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/tools/shell/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,GAAG,IAAI,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAE3E;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA0B;IACzD,gBAAgB;IAChB,mBAAmB;IACnB,sBAAsB;IACtB,yBAAyB;IACzB,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,gCAAgC;IAChC,cAAc;IACd,aAAa;IACb,kBAAkB;IAClB,iBAAiB;IACjB,oBAAoB;IACpB,gBAAgB;IAChB,kBAAkB;IAClB,oBAAoB;IACpB,mBAAmB;IACnB,eAAe;IACf,sBAAsB;IACtB,eAAe;IACf,qCAAqC;IACrC,uBAAuB;IACvB,mBAAmB;IACnB,mBAAmB;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA0B;IACzD,oEAAoE;IACpE,cAAc;IACd,UAAU;CACX,CAAC;AAEF,iFAAiF;AACjF,+EAA+E;AAC/E,wCAAwC;AACxC,MAAM,eAAe,GAAG;IACtB,YAAY;IACZ,sBAAsB;IACtB,eAAe;IACf,WAAW;IACX,UAAU;CACX,CAAC;AAEF,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY;IACvC,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/tools/shell/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,GAAG,IAAI,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAE3E;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA0B;IACzD,gBAAgB;IAChB,mBAAmB;IACnB,sBAAsB;IACtB,yBAAyB;IACzB,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,gCAAgC;IAChC,cAAc;IACd,aAAa;IACb,kBAAkB;IAClB,iBAAiB;IACjB,oBAAoB;IACpB,gBAAgB;IAChB,kBAAkB;IAClB,oBAAoB;IACpB,mBAAmB;IACnB,eAAe;IACf,sBAAsB;IACtB,eAAe;IACf,qCAAqC;IACrC,uBAAuB;IACvB,mBAAmB;IACnB,mBAAmB;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA0B;IACzD,oEAAoE;IACpE,cAAc;IACd,UAAU;CACX,CAAC;AAEF,iFAAiF;AACjF,+EAA+E;AAC/E,wCAAwC;AACxC,MAAM,eAAe,GAAG;IACtB,YAAY;IACZ,sBAAsB;IACtB,eAAe;IACf,WAAW;IACX,UAAU;CACX,CAAC;AAEF,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY;IACvC,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAM,GAAsB,UAAU;IACrE,MAAM,QAAQ,GAAsB,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,IAAI,iBAAiB,CAAC,GAAG,CAAC;YAAE,SAAS;QACrC,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACxB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outputBuffer.js","sourceRoot":"","sources":["../../../src/tools/shell/outputBuffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,IAAI,MAAM,WAAW,CAAC;AAa7B;;;;;GAKG;AACH,MAAM,OAAO,YAAY;IACf,IAAI,GAAG,EAAE,CAAC;IACV,SAAS,GAAG,CAAC,CAAC;IACL,UAAU,GAAa,EAAE,CAAC;IACnC,SAAS,GAAG,CAAC,CAAC;IACd,eAAe,GAAG,CAAC,CAAC;IAC5B,0DAA0D;IAClD,IAAI,GAAG,EAAE,CAAC;IACV,aAAa,GAAG,KAAK,CAAC;IAEb,UAAU,CAAS;IACnB,UAAU,CAAS;IACnB,WAAW,CAAS;IAErC;;;;;OAKG;IACH,YAAY,cAAsB,EAAE,WAAW,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;QAChE,iDAAiD;QACjD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAChE,uDAAuD;QACvD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC3D,CAAC;IAED,wEAAwE;IACxE,MAAM,CAAC,KAAa;QAClB,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC;QAE9B,6EAA6E;QAC7E,gEAAgE;QAChE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAClD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACrC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;gBAClB,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;oBACb,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAC7E,CAAC;gBACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,8BAA8B;QAC9B,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;YAC9C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;gBAClB,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC;gBACnB,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;gBACxB,OAAO;YACT,CAAC;YACD,6DAA6D;YAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC3E,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;YAClB,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAClD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,8EAA8E;IACtE,QAAQ,CAAC,KAAa;QAC5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtE,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAG,CAAC;YACzC,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACvD,CAAC;QACD,2EAA2E;QAC3E,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrE,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;YAClD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACtC,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACxD,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;YAC7B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAChE,CAAC;IAED,mEAAmE;IACnE,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;;;;;;OAOG;IACH,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"outputBuffer.js","sourceRoot":"","sources":["../../../src/tools/shell/outputBuffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Working directory the shell tool spawns in: the ACP session override when set (ACP transport),
|
|
3
|
+
* otherwise `getCurrentWorkDir()` (local runner + AG-UI, unchanged).
|
|
4
|
+
*/
|
|
5
|
+
export declare function getShellWorkDir(): string;
|
|
6
|
+
/**
|
|
7
|
+
* ACP-only: point the shell tool at the current ACP session's fs-backend root (the resolved
|
|
8
|
+
* `session/new.cwd`, or the startup workspace when a session carries no cwd). Pass `undefined` to
|
|
9
|
+
* clear the override and restore the `getCurrentWorkDir()` default (used by tests).
|
|
10
|
+
*/
|
|
11
|
+
export declare function setAcpShellWorkDir(cwd: string | undefined): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Resolves the working directory the shell tool (`run_shell_command`) spawns in, keeping it aligned
|
|
4
|
+
* with the deepagents filesystem-backend root so the shell and the fs tools (ls/read_file/write_file/
|
|
5
|
+
* edit_file/glob/grep) share ONE path namespace.
|
|
6
|
+
*
|
|
7
|
+
* DEFAULT (local `code`/`chat` runner + AG-UI): `getCurrentWorkDir()`. On these surfaces the fs
|
|
8
|
+
* backend is rooted at `getCurrentWorkDir()` by `GthDeepAgent.init()` (`rootDir: getCurrentWorkDir()`),
|
|
9
|
+
* so the shell already matches it — this is exactly EXT-22 S4. These surfaces NEVER call
|
|
10
|
+
* {@link setAcpShellWorkDir}, so {@link getShellWorkDir} stays `getCurrentWorkDir()` for them.
|
|
11
|
+
*
|
|
12
|
+
* ACP transport override: unlike the local runner, the ACP server does NOT call `init()`; it re-roots
|
|
13
|
+
* ITS per-session fs backend to each `session/new.cwd` (see `gthAcpServer.ts`). The shell tool
|
|
14
|
+
* instances are built ONCE at startup (`buildDeepAgentParams`), so they cannot themselves see the
|
|
15
|
+
* later session cwd. The ACP server therefore updates this module-level override on every
|
|
16
|
+
* `session/new`; the shell reads it at spawn time so it tracks the session fs root.
|
|
17
|
+
*
|
|
18
|
+
* This also removes the EXT-22 S4 `INIT_CWD` hazard on ACP: `getCurrentWorkDir()` prefers `INIT_CWD`,
|
|
19
|
+
* which is stale in the long-lived ACP subprocess (the reason `acpModule` roots the startup workspace
|
|
20
|
+
* at raw `process.cwd()`). Once the override tracks the session cwd, the ACP shell never consults
|
|
21
|
+
* `INIT_CWD`.
|
|
22
|
+
*
|
|
23
|
+
* Scope note: this mirrors the ACP design, which is ALREADY "latest-session-cwd wins" process-wide —
|
|
24
|
+
* `gthAcpServer` clobbers every backend to the newest session cwd. A single process-wide override has
|
|
25
|
+
* the same semantics. The ACP subprocess is dedicated (never co-hosts a local runner / AG-UI), so the
|
|
26
|
+
* override can never leak into a non-ACP surface.
|
|
27
|
+
*/
|
|
28
|
+
import { getCurrentWorkDir } from '@gaunt-sloth/core/utils/systemUtils.js';
|
|
29
|
+
let acpShellWorkDir;
|
|
30
|
+
/**
|
|
31
|
+
* Working directory the shell tool spawns in: the ACP session override when set (ACP transport),
|
|
32
|
+
* otherwise `getCurrentWorkDir()` (local runner + AG-UI, unchanged).
|
|
33
|
+
*/
|
|
34
|
+
export function getShellWorkDir() {
|
|
35
|
+
return acpShellWorkDir ?? getCurrentWorkDir();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* ACP-only: point the shell tool at the current ACP session's fs-backend root (the resolved
|
|
39
|
+
* `session/new.cwd`, or the startup workspace when a session carries no cwd). Pass `undefined` to
|
|
40
|
+
* clear the override and restore the `getCurrentWorkDir()` default (used by tests).
|
|
41
|
+
*/
|
|
42
|
+
export function setAcpShellWorkDir(cwd) {
|
|
43
|
+
acpShellWorkDir = cwd;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=workDir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workDir.js","sourceRoot":"","sources":["../../../src/tools/shell/workDir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAE3E,IAAI,eAAmC,CAAC;AAExC;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,eAAe,IAAI,iBAAiB,EAAE,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAuB;IACxD,eAAe,GAAG,GAAG,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* EXT-31 — classify and format MCP integration connect/tool-load failures so an expired or invalid
|
|
4
|
+
* credential is SURFACED (named + actionable) instead of silently dropping the integration's tools.
|
|
5
|
+
*
|
|
6
|
+
* The `@langchain/mcp-adapters` client only tags a bare HTTP 401 as an authentication error; a 403
|
|
7
|
+
* (forbidden / expired scope) otherwise falls through as a generic "Failed to connect". This module
|
|
8
|
+
* classifies auth failures independently (401/403 + credential keywords) so a stale token is not
|
|
9
|
+
* mistaken for "this integration was never configured" or an unrelated transient error.
|
|
10
|
+
*
|
|
11
|
+
* Pure + side-effect free: callers do the surfacing (`displayWarning`) with the returned message.
|
|
12
|
+
*/
|
|
13
|
+
/** Coarse classification of an MCP connect/tool-load failure. */
|
|
14
|
+
export type McpConnectErrorKind = 'auth' | 'other';
|
|
15
|
+
/** Options that tune the suggested fix path in the surfaced message. */
|
|
16
|
+
export interface McpConnectFailureOptions {
|
|
17
|
+
/** The server uses OAuth (`authProvider: 'OAuth'`) — suggest re-running the OAuth login. */
|
|
18
|
+
oauth?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Classify an MCP connect/tool-load failure as a credential problem (`auth`) or anything else
|
|
22
|
+
* (`other`). Detection is independent of the adapter (which only tags 401), so a 403 or an
|
|
23
|
+
* "expired token" surfaced by the upstream server is still recognised as auth.
|
|
24
|
+
*/
|
|
25
|
+
export declare function classifyMcpConnectError(error: unknown): McpConnectErrorKind;
|
|
26
|
+
/**
|
|
27
|
+
* Build the user-facing message for a failed MCP integration. For `auth` failures it names the
|
|
28
|
+
* integration, states the credential is expired/invalid, and points at the concrete fix path
|
|
29
|
+
* (OAuth login or the API token / authorization header, plus the `mcpServers` entry in gth config).
|
|
30
|
+
* For `other` failures it surfaces the failure plainly and explicitly says it is NOT an auth error,
|
|
31
|
+
* so an unrelated transient never triggers a spurious "re-authenticate" nudge.
|
|
32
|
+
*
|
|
33
|
+
* Either way the caller degrades gracefully AFTER surfacing this — the integration's tools are
|
|
34
|
+
* dropped for the session, but the user (and the log) now knows why.
|
|
35
|
+
*/
|
|
36
|
+
export declare function formatMcpConnectFailureMessage(serverName: string | undefined, error: unknown, options?: McpConnectFailureOptions): string;
|