@pentoshi/clai 0.6.0 → 0.7.1
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 +9 -17
- package/dist/agent/context-manager.d.ts +27 -0
- package/dist/agent/context-manager.js +75 -0
- package/dist/agent/context-manager.js.map +1 -0
- package/dist/agent/runner.d.ts +21 -1
- package/dist/agent/runner.js +176 -73
- package/dist/agent/runner.js.map +1 -1
- package/dist/commands/doctor.js +20 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/update.js +11 -2
- package/dist/commands/update.js.map +1 -1
- package/dist/index.js +156 -5
- package/dist/index.js.map +1 -1
- package/dist/llm/anthropic.js +29 -38
- package/dist/llm/anthropic.js.map +1 -1
- package/dist/llm/gemini.js +31 -40
- package/dist/llm/gemini.js.map +1 -1
- package/dist/llm/http.d.ts +21 -0
- package/dist/llm/http.js +140 -1
- package/dist/llm/http.js.map +1 -1
- package/dist/llm/ollama.js +18 -27
- package/dist/llm/ollama.js.map +1 -1
- package/dist/llm/router.d.ts +7 -0
- package/dist/llm/router.js +14 -23
- package/dist/llm/router.js.map +1 -1
- package/dist/modes/agent.d.ts +4 -2
- package/dist/modes/agent.js +2 -2
- package/dist/modes/agent.js.map +1 -1
- package/dist/modes/ask.js +3 -4
- package/dist/modes/ask.js.map +1 -1
- package/dist/os/pkgmgr.d.ts +7 -1
- package/dist/os/pkgmgr.js +97 -18
- package/dist/os/pkgmgr.js.map +1 -1
- package/dist/prompts/index.d.ts +7 -0
- package/dist/prompts/index.js +12 -4
- package/dist/prompts/index.js.map +1 -1
- package/dist/repl.d.ts +1 -0
- package/dist/repl.js +283 -43
- package/dist/repl.js.map +1 -1
- package/dist/safety/classifier.d.ts +5 -1
- package/dist/safety/classifier.js +244 -88
- package/dist/safety/classifier.js.map +1 -1
- package/dist/safety/patterns.d.ts +48 -1
- package/dist/safety/patterns.js +140 -7
- package/dist/safety/patterns.js.map +1 -1
- package/dist/store/config.d.ts +21 -3
- package/dist/store/config.js +28 -9
- package/dist/store/config.js.map +1 -1
- package/dist/store/history.d.ts +9 -0
- package/dist/store/history.js +58 -1
- package/dist/store/history.js.map +1 -1
- package/dist/store/keys.d.ts +2 -1
- package/dist/store/keys.js +7 -3
- package/dist/store/keys.js.map +1 -1
- package/dist/store/logs.d.ts +7 -0
- package/dist/store/logs.js +39 -1
- package/dist/store/logs.js.map +1 -1
- package/dist/store/project.d.ts +1 -0
- package/dist/store/project.js +34 -9
- package/dist/store/project.js.map +1 -1
- package/dist/store/scope.d.ts +29 -0
- package/dist/store/scope.js +113 -0
- package/dist/store/scope.js.map +1 -0
- package/dist/tools/fs.d.ts +6 -2
- package/dist/tools/fs.js +99 -87
- package/dist/tools/fs.js.map +1 -1
- package/dist/tools/http.d.ts +5 -3
- package/dist/tools/http.js +170 -31
- package/dist/tools/http.js.map +1 -1
- package/dist/tools/policies/output-policy.d.ts +13 -0
- package/dist/tools/policies/output-policy.js +56 -0
- package/dist/tools/policies/output-policy.js.map +1 -0
- package/dist/tools/reducers/ffuf.d.ts +6 -0
- package/dist/tools/reducers/ffuf.js +74 -0
- package/dist/tools/reducers/ffuf.js.map +1 -0
- package/dist/tools/reducers/generic.d.ts +2 -0
- package/dist/tools/reducers/generic.js +60 -0
- package/dist/tools/reducers/generic.js.map +1 -0
- package/dist/tools/reducers/gobuster.d.ts +2 -0
- package/dist/tools/reducers/gobuster.js +36 -0
- package/dist/tools/reducers/gobuster.js.map +1 -0
- package/dist/tools/reducers/httpx.d.ts +2 -0
- package/dist/tools/reducers/httpx.js +38 -0
- package/dist/tools/reducers/httpx.js.map +1 -0
- package/dist/tools/reducers/nmap.d.ts +7 -0
- package/dist/tools/reducers/nmap.js +82 -0
- package/dist/tools/reducers/nmap.js.map +1 -0
- package/dist/tools/reducers/nuclei.d.ts +2 -0
- package/dist/tools/reducers/nuclei.js +51 -0
- package/dist/tools/reducers/nuclei.js.map +1 -0
- package/dist/tools/reducers/sqlmap.d.ts +2 -0
- package/dist/tools/reducers/sqlmap.js +39 -0
- package/dist/tools/reducers/sqlmap.js.map +1 -0
- package/dist/tools/reducers/subdomains.d.ts +6 -0
- package/dist/tools/reducers/subdomains.js +31 -0
- package/dist/tools/reducers/subdomains.js.map +1 -0
- package/dist/tools/reducers/types.d.ts +14 -0
- package/dist/tools/reducers/types.js +2 -0
- package/dist/tools/reducers/types.js.map +1 -0
- package/dist/tools/registry.d.ts +1 -1
- package/dist/tools/registry.js +223 -79
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/shell.d.ts +45 -4
- package/dist/tools/shell.js +419 -88
- package/dist/tools/shell.js.map +1 -1
- package/dist/tools/validate.d.ts +37 -0
- package/dist/tools/validate.js +144 -0
- package/dist/tools/validate.js.map +1 -0
- package/dist/types.d.ts +7 -15
- package/dist/ui/keys.d.ts +21 -0
- package/dist/ui/keys.js +13 -0
- package/dist/ui/keys.js.map +1 -0
- package/dist/ui/output-pane.d.ts +31 -0
- package/dist/ui/output-pane.js +81 -0
- package/dist/ui/output-pane.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface EngagementScope {
|
|
2
|
+
name?: string | undefined;
|
|
3
|
+
authorizedTargets: string[];
|
|
4
|
+
excludedTargets?: string[] | undefined;
|
|
5
|
+
allowedPhases?: Array<"recon" | "enumeration" | "exploitation" | "post-exploitation"> | undefined;
|
|
6
|
+
maxRate?: number | undefined;
|
|
7
|
+
maxConcurrency?: number | undefined;
|
|
8
|
+
authorizationNote?: string | undefined;
|
|
9
|
+
createdAt?: string | undefined;
|
|
10
|
+
expiresAt?: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare function loadScope(): Promise<EngagementScope | undefined>;
|
|
13
|
+
export declare function saveScope(scope: EngagementScope): Promise<void>;
|
|
14
|
+
export declare function clearScope(): Promise<void>;
|
|
15
|
+
export declare function getScopePath(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Reset the cache. Used by tests so a fresh load picks up the new file.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resetScopeCache(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Returns true if `target` (hostname / IP / CIDR string) is covered by any
|
|
22
|
+
* authorized entry in scope. A target is in-scope if:
|
|
23
|
+
* - it appears literally in authorizedTargets
|
|
24
|
+
* - it is a subdomain of an authorized hostname
|
|
25
|
+
* - it is an IPv4 inside an authorized CIDR
|
|
26
|
+
* - the CIDR target is exactly an authorized CIDR
|
|
27
|
+
*/
|
|
28
|
+
export declare function targetInScope(target: string, scope: EngagementScope): boolean;
|
|
29
|
+
export declare function isScopeActive(scope: EngagementScope | undefined): scope is EngagementScope;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import net from "node:net";
|
|
6
|
+
const scopeFile = join(homedir(), ".clai", "scope.json");
|
|
7
|
+
let cached;
|
|
8
|
+
let cacheLoaded = false;
|
|
9
|
+
export async function loadScope() {
|
|
10
|
+
if (cacheLoaded)
|
|
11
|
+
return cached;
|
|
12
|
+
cacheLoaded = true;
|
|
13
|
+
if (!existsSync(scopeFile))
|
|
14
|
+
return undefined;
|
|
15
|
+
try {
|
|
16
|
+
const raw = await readFile(scopeFile, "utf8");
|
|
17
|
+
cached = JSON.parse(raw);
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export async function saveScope(scope) {
|
|
25
|
+
await mkdir(join(homedir(), ".clai"), { recursive: true });
|
|
26
|
+
await writeFile(scopeFile, `${JSON.stringify(scope, null, 2)}\n`, { mode: 0o600 });
|
|
27
|
+
cached = scope;
|
|
28
|
+
cacheLoaded = true;
|
|
29
|
+
}
|
|
30
|
+
export async function clearScope() {
|
|
31
|
+
cached = undefined;
|
|
32
|
+
cacheLoaded = true;
|
|
33
|
+
if (existsSync(scopeFile)) {
|
|
34
|
+
await writeFile(scopeFile, "", "utf8");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function getScopePath() {
|
|
38
|
+
return scopeFile;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Reset the cache. Used by tests so a fresh load picks up the new file.
|
|
42
|
+
*/
|
|
43
|
+
export function resetScopeCache() {
|
|
44
|
+
cached = undefined;
|
|
45
|
+
cacheLoaded = false;
|
|
46
|
+
}
|
|
47
|
+
function ipToNumber(ip) {
|
|
48
|
+
const parts = ip.split(".").map((p) => Number(p));
|
|
49
|
+
if (parts.length !== 4 || parts.some((p) => !Number.isInteger(p) || p < 0 || p > 255)) {
|
|
50
|
+
return NaN;
|
|
51
|
+
}
|
|
52
|
+
return parts.reduce((acc, octet) => acc * 256 + octet, 0);
|
|
53
|
+
}
|
|
54
|
+
function ipInCidr(ip, cidr) {
|
|
55
|
+
const [base, maskRaw] = cidr.split("/");
|
|
56
|
+
if (!base || !maskRaw)
|
|
57
|
+
return false;
|
|
58
|
+
const mask = Number(maskRaw);
|
|
59
|
+
if (!Number.isInteger(mask) || mask < 0 || mask > 32)
|
|
60
|
+
return false;
|
|
61
|
+
const ipNum = ipToNumber(ip);
|
|
62
|
+
const baseNum = ipToNumber(base);
|
|
63
|
+
if (Number.isNaN(ipNum) || Number.isNaN(baseNum))
|
|
64
|
+
return false;
|
|
65
|
+
if (mask === 0)
|
|
66
|
+
return true;
|
|
67
|
+
const shift = 32 - mask;
|
|
68
|
+
// eslint-disable-next-line no-bitwise
|
|
69
|
+
return (ipNum >>> shift) === (baseNum >>> shift);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Returns true if `target` (hostname / IP / CIDR string) is covered by any
|
|
73
|
+
* authorized entry in scope. A target is in-scope if:
|
|
74
|
+
* - it appears literally in authorizedTargets
|
|
75
|
+
* - it is a subdomain of an authorized hostname
|
|
76
|
+
* - it is an IPv4 inside an authorized CIDR
|
|
77
|
+
* - the CIDR target is exactly an authorized CIDR
|
|
78
|
+
*/
|
|
79
|
+
export function targetInScope(target, scope) {
|
|
80
|
+
const trimmed = target.trim().toLowerCase();
|
|
81
|
+
if (!trimmed)
|
|
82
|
+
return false;
|
|
83
|
+
const excluded = (scope.excludedTargets ?? []).map((t) => t.toLowerCase());
|
|
84
|
+
if (excluded.some((entry) => matchEntry(trimmed, entry)))
|
|
85
|
+
return false;
|
|
86
|
+
return scope.authorizedTargets.some((entry) => matchEntry(trimmed, entry.toLowerCase()));
|
|
87
|
+
}
|
|
88
|
+
function matchEntry(target, entry) {
|
|
89
|
+
if (entry === target)
|
|
90
|
+
return true;
|
|
91
|
+
// CIDR membership for IPv4 targets
|
|
92
|
+
if (entry.includes("/") && net.isIPv4(target)) {
|
|
93
|
+
return ipInCidr(target, entry);
|
|
94
|
+
}
|
|
95
|
+
// Hostname suffix match (entry "example.com" covers "api.example.com")
|
|
96
|
+
if (!net.isIP(target) && !entry.includes("/")) {
|
|
97
|
+
return target === entry || target.endsWith(`.${entry}`);
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
export function isScopeActive(scope) {
|
|
102
|
+
if (!scope)
|
|
103
|
+
return false;
|
|
104
|
+
if (!scope.authorizedTargets || scope.authorizedTargets.length === 0)
|
|
105
|
+
return false;
|
|
106
|
+
if (scope.expiresAt) {
|
|
107
|
+
const expires = Date.parse(scope.expiresAt);
|
|
108
|
+
if (!Number.isNaN(expires) && Date.now() > expires)
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/store/scope.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/fs.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { ToolResult } from "../types.js";
|
|
2
|
-
export declare function fsRead(path: string
|
|
2
|
+
export declare function fsRead(path: string, options?: {
|
|
3
|
+
maxBytes?: number | undefined;
|
|
4
|
+
}): Promise<ToolResult>;
|
|
3
5
|
export declare function fsWrite(path: string, content: string): Promise<ToolResult>;
|
|
4
|
-
export declare function fsList(path: string
|
|
6
|
+
export declare function fsList(path: string, options?: {
|
|
7
|
+
maxEntries?: number | undefined;
|
|
8
|
+
}): Promise<ToolResult>;
|
|
5
9
|
export declare function fsSearch(pattern: string, path?: string): Promise<ToolResult>;
|
package/dist/tools/fs.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { open,
|
|
2
|
-
import {
|
|
3
|
-
import { homedir } from "node:os";
|
|
1
|
+
import { open, readdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { relative, resolve } from "node:path";
|
|
3
|
+
import { homedir, tmpdir } from "node:os";
|
|
4
4
|
import { execa } from "execa";
|
|
5
5
|
import { getConfig } from "../store/config.js";
|
|
6
|
-
import {
|
|
6
|
+
import { isSecretPath } from "../safety/patterns.js";
|
|
7
|
+
const DEFAULT_READ_MAX_BYTES = 256 * 1024;
|
|
8
|
+
const DEFAULT_LIST_MAX_ENTRIES = 500;
|
|
7
9
|
function expandHome(path) {
|
|
8
10
|
if (path === "~")
|
|
9
11
|
return homedir();
|
|
@@ -12,81 +14,96 @@ function expandHome(path) {
|
|
|
12
14
|
}
|
|
13
15
|
return path;
|
|
14
16
|
}
|
|
17
|
+
/** Resolve path with tilde expansion. */
|
|
15
18
|
function resolvePath(path) {
|
|
16
19
|
return resolve(expandHome(path));
|
|
17
20
|
}
|
|
18
|
-
function
|
|
19
|
-
|
|
21
|
+
function ensureNotSecret(resolved) {
|
|
22
|
+
if (isSecretPath(resolved)) {
|
|
23
|
+
throw new Error(`Refusing to access secret path: ${resolved}. Block list covers ~/.ssh, ~/.gnupg, ~/.aws, ~/.kube, ~/.docker, ~/.npmrc, ~/.pypirc, .env, ~/.clai/keys.json, id_rsa, *.pem, *.key, /etc/shadow.`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Decide whether a given absolute path falls inside any approved sandbox
|
|
28
|
+
* root. Roots are the configured `sandboxRoots`, the current working
|
|
29
|
+
* directory, and (for read operations only) optionally the user's home
|
|
30
|
+
* directory.
|
|
31
|
+
*
|
|
32
|
+
* `mode` flips two things:
|
|
33
|
+
* - "read" → home directory is included as an implicit root (so the
|
|
34
|
+
* agent can still inspect dotfiles by name without each one
|
|
35
|
+
* needing to be added to sandboxRoots), but the secret-path
|
|
36
|
+
* blocklist still applies on top.
|
|
37
|
+
* - "write" → home directory is NOT included unless explicitly added to
|
|
38
|
+
* sandboxRoots, so a runaway agent can't drop files all over
|
|
39
|
+
* $HOME.
|
|
40
|
+
*/
|
|
41
|
+
function pathInsideSandbox(resolvedPath, mode) {
|
|
42
|
+
const roots = [
|
|
20
43
|
...getConfig().sandboxRoots.map((root) => resolve(expandHome(root))),
|
|
21
|
-
|
|
44
|
+
process.cwd(),
|
|
22
45
|
];
|
|
23
|
-
|
|
24
|
-
|
|
46
|
+
if (mode === "read") {
|
|
47
|
+
// For reads we also accept the user's home (so dotfiles are inspectable
|
|
48
|
+
// by name, modulo the secret-path blocklist) and the OS temp dir
|
|
49
|
+
// (where shellExec stores its artifacts at ~/.clai/outputs and where
|
|
50
|
+
// tests mkdtemp into).
|
|
51
|
+
roots.push(homedir(), tmpdir());
|
|
52
|
+
}
|
|
25
53
|
return roots.some((root) => {
|
|
26
|
-
const rel = relative(root,
|
|
27
|
-
return rel === "" || (!rel.startsWith("..") && !
|
|
54
|
+
const rel = relative(root, resolvedPath);
|
|
55
|
+
return (rel === "" || (!rel.startsWith("..") && !resolve(rel).startsWith("..")));
|
|
28
56
|
});
|
|
29
57
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
"/.kube/",
|
|
39
|
-
"/.docker/",
|
|
40
|
-
"/.config/gcloud/",
|
|
41
|
-
"/.clai/keys.json",
|
|
42
|
-
];
|
|
43
|
-
if (secretSegments.some((segment) => relativeHome.includes(segment)))
|
|
44
|
-
return true;
|
|
45
|
-
return /(^|\/)(\.env(?:\..*)?|\.npmrc|\.pypirc|id_rsa|id_dsa|id_ecdsa|id_ed25519|.*\.pem|.*\.key)$/i.test(lower);
|
|
46
|
-
}
|
|
47
|
-
function ensureReadAllowed(path) {
|
|
48
|
-
const resolved = resolvePath(path);
|
|
49
|
-
if (isForbiddenSecretPath(resolved)) {
|
|
50
|
-
throw new Error(`Read blocked — path looks like a secret: ${path}`);
|
|
51
|
-
}
|
|
52
|
-
if (!isWithinRoots(resolved, configuredRoots())) {
|
|
53
|
-
throw new Error(`Read blocked — path is outside approved roots: ${path}`);
|
|
58
|
+
/** Throw with a useful message when a read/list/search escapes the sandbox. */
|
|
59
|
+
function ensureReadAllowed(resolved, original) {
|
|
60
|
+
ensureNotSecret(resolved);
|
|
61
|
+
// Allow opt-out for users who deliberately want unrestricted reads.
|
|
62
|
+
if (getConfig().sandboxReads === false)
|
|
63
|
+
return;
|
|
64
|
+
if (!pathInsideSandbox(resolved, "read")) {
|
|
65
|
+
throw new Error(`Read blocked — "${original}" resolves outside the approved sandbox roots. Add the path with /cwd or sandboxRoots, or set sandboxReads=false.`);
|
|
54
66
|
}
|
|
55
|
-
return resolved;
|
|
56
67
|
}
|
|
68
|
+
/** Resolve + sandbox check for write operations. */
|
|
57
69
|
function ensureWriteAllowed(path) {
|
|
58
70
|
const resolved = resolvePath(path);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
resolve(homedir()),
|
|
62
|
-
];
|
|
63
|
-
if (!isWithinRoots(resolved, roots)) {
|
|
71
|
+
ensureNotSecret(resolved);
|
|
72
|
+
if (!pathInsideSandbox(resolved, "write")) {
|
|
64
73
|
throw new Error(`Write blocked — path is outside approved roots: ${path}`);
|
|
65
74
|
}
|
|
66
75
|
return resolved;
|
|
67
76
|
}
|
|
68
|
-
export async function fsRead(path) {
|
|
69
|
-
const resolved =
|
|
70
|
-
|
|
71
|
-
const maxBytes =
|
|
72
|
-
if (info.size <= maxBytes) {
|
|
73
|
-
const content = redactSecrets(await readFile(resolved, "utf8"));
|
|
74
|
-
return { ok: true, output: content, stats: { bytesRead: info.size, bytesShown: Buffer.byteLength(content) } };
|
|
75
|
-
}
|
|
77
|
+
export async function fsRead(path, options = {}) {
|
|
78
|
+
const resolved = resolvePath(path);
|
|
79
|
+
ensureReadAllowed(resolved, path);
|
|
80
|
+
const maxBytes = options.maxBytes ?? DEFAULT_READ_MAX_BYTES;
|
|
76
81
|
const handle = await open(resolved, "r");
|
|
77
82
|
try {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
83
|
+
const stat = await handle.stat();
|
|
84
|
+
if (!stat.isFile()) {
|
|
85
|
+
return {
|
|
86
|
+
ok: false,
|
|
87
|
+
output: `Not a regular file: ${resolved}`,
|
|
88
|
+
exitCode: 1,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const cap = Math.min(stat.size, maxBytes);
|
|
92
|
+
const buffer = Buffer.alloc(cap);
|
|
93
|
+
const { bytesRead } = await handle.read(buffer, 0, cap, 0);
|
|
94
|
+
const truncated = stat.size > maxBytes;
|
|
95
|
+
const text = buffer.slice(0, bytesRead).toString("utf8");
|
|
96
|
+
const suffix = truncated
|
|
97
|
+
? `\n... (truncated at ${maxBytes.toLocaleString()} bytes of ${stat.size.toLocaleString()})`
|
|
98
|
+
: "";
|
|
81
99
|
return {
|
|
82
100
|
ok: true,
|
|
83
|
-
output: `${
|
|
84
|
-
truncated
|
|
85
|
-
stats: { bytesRead: info.size, bytesShown: bytesRead, bytesDropped: Math.max(0, info.size - bytesRead) },
|
|
101
|
+
output: `${text}${suffix}`,
|
|
102
|
+
truncated,
|
|
86
103
|
};
|
|
87
104
|
}
|
|
88
105
|
finally {
|
|
89
|
-
await handle.close();
|
|
106
|
+
await handle.close().catch(() => undefined);
|
|
90
107
|
}
|
|
91
108
|
}
|
|
92
109
|
export async function fsWrite(path, content) {
|
|
@@ -94,47 +111,38 @@ export async function fsWrite(path, content) {
|
|
|
94
111
|
await writeFile(resolved, content, "utf8");
|
|
95
112
|
return { ok: true, output: `Wrote ${resolved}` };
|
|
96
113
|
}
|
|
97
|
-
export async function fsList(path) {
|
|
98
|
-
const resolved =
|
|
114
|
+
export async function fsList(path, options = {}) {
|
|
115
|
+
const resolved = resolvePath(path);
|
|
116
|
+
ensureReadAllowed(resolved, path);
|
|
117
|
+
const maxEntries = options.maxEntries ?? DEFAULT_LIST_MAX_ENTRIES;
|
|
99
118
|
const entries = await readdir(resolved, { withFileTypes: true });
|
|
100
|
-
const
|
|
101
|
-
const
|
|
119
|
+
const truncated = entries.length > maxEntries;
|
|
120
|
+
const visible = truncated ? entries.slice(0, maxEntries) : entries;
|
|
121
|
+
const lines = visible.map((entry) => `${entry.isDirectory() ? "dir " : "file"} ${entry.name}`);
|
|
122
|
+
if (truncated) {
|
|
123
|
+
lines.push(`... (${(entries.length - maxEntries).toLocaleString()} entries omitted of ${entries.length.toLocaleString()})`);
|
|
124
|
+
}
|
|
102
125
|
return {
|
|
103
126
|
ok: true,
|
|
104
|
-
output:
|
|
105
|
-
|
|
106
|
-
.join("\n") +
|
|
107
|
-
(entries.length > maxEntries
|
|
108
|
-
? `\n... ${entries.length - maxEntries} entries omitted ...`
|
|
109
|
-
: ""),
|
|
110
|
-
truncated: entries.length > maxEntries,
|
|
111
|
-
stats: { linesRead: entries.length },
|
|
127
|
+
output: lines.join("\n"),
|
|
128
|
+
truncated,
|
|
112
129
|
};
|
|
113
130
|
}
|
|
114
131
|
export async function fsSearch(pattern, path = process.cwd()) {
|
|
115
|
-
const resolved =
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
const lines = redactSecrets(all ?? "")
|
|
119
|
-
.split(/\r?\n/)
|
|
120
|
-
.filter(Boolean);
|
|
121
|
-
const shown = lines.slice(0, maxLines);
|
|
122
|
-
return {
|
|
123
|
-
ok: exitCode === 0,
|
|
124
|
-
output: shown.join("\n") +
|
|
125
|
-
(lines.length > maxLines ? `\n... ${lines.length - maxLines} matches omitted ...` : ""),
|
|
126
|
-
exitCode,
|
|
127
|
-
truncated: lines.length > maxLines,
|
|
128
|
-
stats: { linesRead: lines.length },
|
|
129
|
-
};
|
|
130
|
-
};
|
|
132
|
+
const resolved = resolvePath(path);
|
|
133
|
+
ensureReadAllowed(resolved, path);
|
|
134
|
+
const maxLines = 50;
|
|
131
135
|
try {
|
|
132
|
-
const result = await execa("rg", ["--max-count", "5", "--max-filesize", "1M", "
|
|
136
|
+
const result = await execa("rg", ["--max-count", "5", "--max-filesize", "1M", "-l", pattern, resolved], {
|
|
133
137
|
reject: false,
|
|
134
138
|
all: true,
|
|
135
139
|
timeout: 15_000,
|
|
136
140
|
});
|
|
137
|
-
return
|
|
141
|
+
return {
|
|
142
|
+
ok: result.exitCode === 0,
|
|
143
|
+
output: result.all ?? "",
|
|
144
|
+
exitCode: result.exitCode,
|
|
145
|
+
};
|
|
138
146
|
}
|
|
139
147
|
catch {
|
|
140
148
|
const result = await execa("grep", ["-R", "-l", "-m", String(maxLines), pattern, resolved], {
|
|
@@ -142,7 +150,11 @@ export async function fsSearch(pattern, path = process.cwd()) {
|
|
|
142
150
|
all: true,
|
|
143
151
|
timeout: 15_000,
|
|
144
152
|
});
|
|
145
|
-
return
|
|
153
|
+
return {
|
|
154
|
+
ok: result.exitCode === 0,
|
|
155
|
+
output: result.all ?? "",
|
|
156
|
+
exitCode: result.exitCode,
|
|
157
|
+
};
|
|
146
158
|
}
|
|
147
159
|
}
|
|
148
160
|
//# sourceMappingURL=fs.js.map
|
package/dist/tools/fs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/tools/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/tools/fs.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/http.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ToolResult } from "../types.js";
|
|
2
|
-
|
|
2
|
+
interface FetchOptions {
|
|
3
3
|
method?: string | undefined;
|
|
4
4
|
body?: string | undefined;
|
|
5
5
|
headers?: Record<string, string> | undefined;
|
|
6
6
|
maxBytes?: number | undefined;
|
|
7
|
-
|
|
8
|
-
}
|
|
7
|
+
iOwnThis?: boolean | undefined;
|
|
8
|
+
}
|
|
9
|
+
export declare function httpFetch(url: string, options?: FetchOptions): Promise<ToolResult>;
|
|
10
|
+
export {};
|