@pentoshi/clai 2.0.38 → 2.0.43
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 +43 -34
- package/dist/agent/context-manager.d.ts +5 -5
- package/dist/agent/context-manager.js +34 -10
- package/dist/agent/context-manager.js.map +1 -1
- package/dist/agent/plan-tool.js +7 -1
- package/dist/agent/plan-tool.js.map +1 -1
- package/dist/agent/runner.js +122 -33
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/tool-call-parser.d.ts +16 -0
- package/dist/agent/tool-call-parser.js +100 -4
- package/dist/agent/tool-call-parser.js.map +1 -1
- package/dist/commands/update.js +1 -1
- package/dist/prompts/index.d.ts +2 -2
- package/dist/prompts/index.js +12 -5
- package/dist/prompts/index.js.map +1 -1
- package/dist/repl.js +19 -2
- package/dist/repl.js.map +1 -1
- package/dist/tools/registry.js +2 -2
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/wordlists.d.ts +0 -1
- package/dist/tools/wordlists.js +149 -67
- package/dist/tools/wordlists.js.map +1 -1
- package/dist/tui/App.js +7 -2
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/render-lines.js +20 -5
- package/dist/tui/render-lines.js.map +1 -1
- package/dist/ui/intro-card.js +47 -8
- package/dist/ui/intro-card.js.map +1 -1
- package/package.json +1 -1
package/dist/tools/wordlists.js
CHANGED
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Locate
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* which only exists on Kali — then ffuf fails with "no such file" on macOS
|
|
6
|
-
* or Windows. This tool checks the well-known install locations for each OS
|
|
7
|
-
* first, then falls back to a bounded filesystem search (capped depth,
|
|
8
|
-
* capped time, permission errors suppressed) instead of scanning the whole
|
|
9
|
-
* disk or letting stderr noise flood the model's context.
|
|
2
|
+
* Locate wordlist files for fuzzing tools. Searches known paths first, then
|
|
3
|
+
* broadens to locate DB, full filesystem, and sudo-elevated search so
|
|
4
|
+
* wordlists are found regardless of install location or OS.
|
|
10
5
|
*/
|
|
11
6
|
import { execFileSync } from "node:child_process";
|
|
12
7
|
import { existsSync } from "node:fs";
|
|
13
8
|
import { homedir, platform } from "node:os";
|
|
14
9
|
import { join } from "node:path";
|
|
15
|
-
|
|
10
|
+
const IS_WIN = platform() === "win32";
|
|
11
|
+
const IS_MAC = platform() === "darwin";
|
|
12
|
+
function getHome() {
|
|
13
|
+
return process.env.HOME || process.env.USERPROFILE || homedir();
|
|
14
|
+
}
|
|
15
|
+
// --- Known roots per OS ---
|
|
16
16
|
function knownRoots() {
|
|
17
|
-
const home =
|
|
17
|
+
const home = getHome();
|
|
18
18
|
const common = [
|
|
19
19
|
join(home, "wordlists"),
|
|
20
20
|
join(home, "SecLists"),
|
|
21
21
|
join(home, "seclists"),
|
|
22
22
|
join(home, ".wordlists"),
|
|
23
|
+
join(home, "Documents", "wordlists"),
|
|
24
|
+
join(home, "Documents", "SecLists"),
|
|
25
|
+
join(home, "projects"),
|
|
26
|
+
join(home, "github"),
|
|
27
|
+
join(home, "repos"),
|
|
28
|
+
join(home, "pentesting"),
|
|
29
|
+
join(home, "pentest"),
|
|
23
30
|
];
|
|
24
|
-
if (
|
|
31
|
+
if (IS_WIN) {
|
|
25
32
|
return [
|
|
26
33
|
...common,
|
|
27
34
|
"C:\\SecLists",
|
|
@@ -30,28 +37,33 @@ function knownRoots() {
|
|
|
30
37
|
join(home, "Tools", "SecLists"),
|
|
31
38
|
];
|
|
32
39
|
}
|
|
33
|
-
if (
|
|
40
|
+
if (IS_MAC) {
|
|
34
41
|
return [
|
|
35
42
|
...common,
|
|
36
43
|
"/opt/homebrew/share/seclists",
|
|
37
44
|
"/opt/homebrew/share/wordlists",
|
|
38
45
|
"/usr/local/share/seclists",
|
|
39
46
|
"/usr/local/share/wordlists",
|
|
40
|
-
"/
|
|
47
|
+
"/opt/local/share/seclists",
|
|
48
|
+
"/opt/local/share/wordlists",
|
|
49
|
+
"/usr/share/wordlists",
|
|
41
50
|
"/usr/share/seclists",
|
|
42
51
|
];
|
|
43
52
|
}
|
|
44
|
-
// Linux (Kali ships these by default; other distros vary)
|
|
45
53
|
return [
|
|
46
54
|
...common,
|
|
47
55
|
"/usr/share/wordlists",
|
|
48
56
|
"/usr/share/seclists",
|
|
49
57
|
"/usr/share/dirb/wordlists",
|
|
50
58
|
"/usr/share/dirbuster/wordlists",
|
|
59
|
+
"/usr/share/wfuzz/wordlist",
|
|
51
60
|
"/opt/SecLists",
|
|
61
|
+
"/opt/wordlists",
|
|
62
|
+
"/var/wordlists",
|
|
63
|
+
"/pentest",
|
|
52
64
|
];
|
|
53
65
|
}
|
|
54
|
-
|
|
66
|
+
// --- Aliases ---
|
|
55
67
|
const NAME_ALIASES = {
|
|
56
68
|
common: ["common.txt", "common.txt.gz"],
|
|
57
69
|
"common.txt": ["common.txt"],
|
|
@@ -65,50 +77,119 @@ const NAME_ALIASES = {
|
|
|
65
77
|
};
|
|
66
78
|
function candidateFilenames(query) {
|
|
67
79
|
const lower = query.toLowerCase().trim();
|
|
68
|
-
|
|
69
|
-
return NAME_ALIASES[lower];
|
|
70
|
-
// Bare filename already (has an extension) — search for it verbatim too.
|
|
71
|
-
return [query];
|
|
80
|
+
return NAME_ALIASES[lower] ?? [query];
|
|
72
81
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
// --- Search helpers ---
|
|
83
|
+
function parseLines(raw) {
|
|
84
|
+
return raw.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
|
|
85
|
+
}
|
|
86
|
+
function buildFindNameExpr(filenames) {
|
|
87
|
+
return filenames.flatMap((f, i) => (i === 0 ? ["-name", f] : ["-o", "-name", f]));
|
|
88
|
+
}
|
|
89
|
+
// Quiet directory search: capped depth, timeout, stderr suppressed.
|
|
79
90
|
function searchRoot(root, filenames, maxDepth) {
|
|
80
91
|
if (!existsSync(root))
|
|
81
92
|
return [];
|
|
82
|
-
const hits = [];
|
|
83
|
-
const isWindows = platform() === "win32";
|
|
84
93
|
try {
|
|
85
|
-
if (
|
|
86
|
-
// PowerShell Get-ChildItem with -ErrorAction SilentlyContinue mirrors
|
|
87
|
-
// the 2>/dev/null suppression used on POSIX below.
|
|
94
|
+
if (IS_WIN) {
|
|
88
95
|
const namePattern = filenames.map((f) => `'${f.replace(/'/g, "''")}'`).join(",");
|
|
89
96
|
const script = `Get-ChildItem -Path '${root.replace(/'/g, "''")}' -Recurse -File ` +
|
|
90
97
|
`-Depth ${maxDepth} -ErrorAction SilentlyContinue ` +
|
|
91
98
|
`| Where-Object { @(${namePattern}) -contains $_.Name } ` +
|
|
92
99
|
`| Select-Object -First 20 -ExpandProperty FullName`;
|
|
93
100
|
const out = execFileSync("powershell.exe", ["-NoProfile", "-Command", script], {
|
|
94
|
-
timeout: 8_000,
|
|
95
|
-
encoding: "utf8",
|
|
96
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
101
|
+
timeout: 8_000, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"],
|
|
97
102
|
});
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
const nameExpr = filenames.flatMap((f, i) => (i === 0 ? ["-name", f] : ["-o", "-name", f]));
|
|
102
|
-
const out = execFileSync("find", [root, "-maxdepth", String(maxDepth), "-type", "f", "(", ...nameExpr, ")"], { timeout: 8_000, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
103
|
-
hits.push(...out.split("\n").map((l) => l.trim()).filter(Boolean));
|
|
103
|
+
return parseLines(out);
|
|
104
104
|
}
|
|
105
|
+
const nameExpr = buildFindNameExpr(filenames);
|
|
106
|
+
const out = execFileSync("find", [root, "-maxdepth", String(maxDepth), "-type", "f", "(", ...nameExpr, ")"], { timeout: 8_000, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
107
|
+
return parseLines(out);
|
|
105
108
|
}
|
|
106
109
|
catch {
|
|
107
|
-
|
|
108
|
-
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Query the locate/mlocate DB — fast, no root needed. POSIX only.
|
|
114
|
+
function searchLocate(filenames) {
|
|
115
|
+
if (IS_WIN)
|
|
116
|
+
return [];
|
|
117
|
+
const hits = [];
|
|
118
|
+
for (const f of filenames) {
|
|
119
|
+
try {
|
|
120
|
+
const out = execFileSync("locate", ["-i", "-l", "20", f], {
|
|
121
|
+
timeout: 5_000, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"],
|
|
122
|
+
});
|
|
123
|
+
hits.push(...parseLines(out));
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// locate not installed or DB not built — skip silently.
|
|
127
|
+
}
|
|
128
|
+
if (hits.length > 0)
|
|
129
|
+
break;
|
|
109
130
|
}
|
|
110
131
|
return hits;
|
|
111
132
|
}
|
|
133
|
+
// Full filesystem search. POSIX: find /, Windows: all drive letters.
|
|
134
|
+
function searchFullFilesystem(filenames) {
|
|
135
|
+
try {
|
|
136
|
+
if (IS_WIN) {
|
|
137
|
+
const namePattern = filenames.map((f) => `'${f.replace(/'/g, "''")}'`).join(",");
|
|
138
|
+
// Discover available drive letters
|
|
139
|
+
const drivesRaw = execFileSync("powershell.exe", ["-NoProfile", "-Command", "(Get-PSDrive -PSProvider FileSystem).Root -join ','"], { timeout: 3_000, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
140
|
+
const drives = parseLines(drivesRaw.replace(/,/g, "\n"));
|
|
141
|
+
if (drives.length === 0)
|
|
142
|
+
return [];
|
|
143
|
+
const paths = drives.map((d) => `'${d.replace(/'/g, "''")}'`).join(",");
|
|
144
|
+
const script = `Get-ChildItem -Path ${paths} -Recurse -File ` +
|
|
145
|
+
`-Depth 6 -ErrorAction SilentlyContinue ` +
|
|
146
|
+
`| Where-Object { @(${namePattern}) -contains $_.Name } ` +
|
|
147
|
+
`| Select-Object -First 20 -ExpandProperty FullName`;
|
|
148
|
+
const out = execFileSync("powershell.exe", ["-NoProfile", "-Command", script], {
|
|
149
|
+
timeout: 15_000, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"],
|
|
150
|
+
});
|
|
151
|
+
return parseLines(out);
|
|
152
|
+
}
|
|
153
|
+
const nameExpr = buildFindNameExpr(filenames);
|
|
154
|
+
const out = execFileSync("find", ["/", "-maxdepth", "8", "-type", "f", "(", ...nameExpr, ")"], { timeout: 15_000, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
155
|
+
return parseLines(out);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Sudo-elevated find /. Tries non-interactive first (cached creds), then
|
|
162
|
+
// interactive (prompts for password via terminal). POSIX only.
|
|
163
|
+
function searchSudo(filenames) {
|
|
164
|
+
if (IS_WIN)
|
|
165
|
+
return [];
|
|
166
|
+
const nameExpr = buildFindNameExpr(filenames);
|
|
167
|
+
const findArgs = ["/", "-maxdepth", "8", "-type", "f", "(", ...nameExpr, ")"];
|
|
168
|
+
// Try non-interactive sudo first (succeeds if creds are cached).
|
|
169
|
+
try {
|
|
170
|
+
const out = execFileSync("sudo", ["-n", "find", ...findArgs], {
|
|
171
|
+
timeout: 15_000, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"],
|
|
172
|
+
});
|
|
173
|
+
const hits = parseLines(out);
|
|
174
|
+
if (hits.length > 0)
|
|
175
|
+
return hits;
|
|
176
|
+
}
|
|
177
|
+
catch { /* creds not cached — fall through to interactive */ }
|
|
178
|
+
// Interactive sudo: inherit stdin so the terminal can prompt for password.
|
|
179
|
+
try {
|
|
180
|
+
const out = execFileSync("sudo", ["find", ...findArgs], {
|
|
181
|
+
timeout: 30_000, encoding: "utf8", stdio: ["inherit", "pipe", "ignore"],
|
|
182
|
+
});
|
|
183
|
+
return parseLines(out);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// --- Result builder ---
|
|
190
|
+
function found(hits, source) {
|
|
191
|
+
return { ok: true, output: `${source}:\n${hits.join("\n")}`, exitCode: 0 };
|
|
192
|
+
}
|
|
112
193
|
export async function wordlistFind(args) {
|
|
113
194
|
const query = args.query?.trim();
|
|
114
195
|
if (!query) {
|
|
@@ -116,17 +197,11 @@ export async function wordlistFind(args) {
|
|
|
116
197
|
}
|
|
117
198
|
const filenames = candidateFilenames(query);
|
|
118
199
|
const roots = knownRoots();
|
|
119
|
-
// Pass 1: well-known install locations
|
|
120
|
-
// already wordlist directories, so a shallow walk is enough and fast).
|
|
200
|
+
// Pass 1: well-known install locations (shallow, fast).
|
|
121
201
|
for (const root of roots) {
|
|
122
202
|
const hits = searchRoot(root, filenames, 6);
|
|
123
|
-
if (hits.length > 0)
|
|
124
|
-
return
|
|
125
|
-
ok: true,
|
|
126
|
-
output: `Found in a known wordlist location:\n${hits.join("\n")}`,
|
|
127
|
-
exitCode: 0,
|
|
128
|
-
};
|
|
129
|
-
}
|
|
203
|
+
if (hits.length > 0)
|
|
204
|
+
return found(hits, "Found in a known wordlist location");
|
|
130
205
|
}
|
|
131
206
|
if (args.expand === false) {
|
|
132
207
|
return {
|
|
@@ -137,31 +212,38 @@ export async function wordlistFind(args) {
|
|
|
137
212
|
exitCode: 1,
|
|
138
213
|
};
|
|
139
214
|
}
|
|
140
|
-
// Pass 2:
|
|
141
|
-
|
|
142
|
-
const home = homedir();
|
|
215
|
+
// Pass 2: broader user directories.
|
|
216
|
+
const home = getHome();
|
|
143
217
|
const broaderRoots = [
|
|
144
|
-
join(home, "Downloads"),
|
|
145
|
-
join(home, "
|
|
146
|
-
join(home, "tools"),
|
|
147
|
-
join(home, "
|
|
218
|
+
join(home, "Downloads"), join(home, "Desktop"),
|
|
219
|
+
join(home, "Documents"), join(home, "Projects"),
|
|
220
|
+
join(home, "tools"), join(home, "Tools"),
|
|
221
|
+
join(home, "github"), join(home, "repos"),
|
|
222
|
+
join(home, "pentesting"), join(home, "pentest"),
|
|
148
223
|
"/opt",
|
|
149
224
|
].filter((r) => !roots.includes(r));
|
|
150
225
|
for (const root of broaderRoots) {
|
|
151
226
|
const hits = searchRoot(root, filenames, 4);
|
|
152
|
-
if (hits.length > 0)
|
|
153
|
-
return
|
|
154
|
-
ok: true,
|
|
155
|
-
output: `Found outside the standard wordlist locations:\n${hits.join("\n")}`,
|
|
156
|
-
exitCode: 0,
|
|
157
|
-
};
|
|
158
|
-
}
|
|
227
|
+
if (hits.length > 0)
|
|
228
|
+
return found(hits, "Found in user directory");
|
|
159
229
|
}
|
|
230
|
+
// Pass 3: locate database (fast indexed search, POSIX only).
|
|
231
|
+
const locateHits = searchLocate(filenames);
|
|
232
|
+
if (locateHits.length > 0)
|
|
233
|
+
return found(locateHits, "Found via locate database");
|
|
234
|
+
// Pass 4: full filesystem search (find / or all Windows drives).
|
|
235
|
+
const fsHits = searchFullFilesystem(filenames);
|
|
236
|
+
if (fsHits.length > 0)
|
|
237
|
+
return found(fsHits, "Found via full filesystem search");
|
|
238
|
+
// Pass 5: sudo-elevated search (POSIX only, non-interactive).
|
|
239
|
+
const sudoHits = searchSudo(filenames);
|
|
240
|
+
if (sudoHits.length > 0)
|
|
241
|
+
return found(sudoHits, "Found via elevated filesystem search");
|
|
160
242
|
return {
|
|
161
243
|
ok: false,
|
|
162
|
-
output: `No wordlist matching "${query}" found
|
|
163
|
-
`
|
|
164
|
-
`
|
|
244
|
+
output: `No wordlist matching "${query}" found after searching the entire filesystem.\n` +
|
|
245
|
+
`Install one: pkg.install seclists (Linux/macOS) or clone https://github.com/danielmiessler/SecLists.\n` +
|
|
246
|
+
`If running without root, try: sudo clai`,
|
|
165
247
|
exitCode: 1,
|
|
166
248
|
};
|
|
167
249
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wordlists.js","sourceRoot":"","sources":["../../src/tools/wordlists.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"wordlists.js","sourceRoot":"","sources":["../../src/tools/wordlists.ts"],"names":[],"mappings":"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"}
|
package/dist/tui/App.js
CHANGED
|
@@ -1718,7 +1718,8 @@ export function App({ version, initialMode, provider: initialProvider, initialMo
|
|
|
1718
1718
|
};
|
|
1719
1719
|
}, [stdin, modalActive, maxOffset, mouseMode, viewportH, state.pendingConfirm, secretRequest, overlayOpen]);
|
|
1720
1720
|
// Key handling
|
|
1721
|
-
|
|
1721
|
+
const onInputRef = useRef(undefined);
|
|
1722
|
+
onInputRef.current = (ch, key) => {
|
|
1722
1723
|
if (key.backspace && isCtrlHPressed.current) {
|
|
1723
1724
|
isCtrlHPressed.current = false;
|
|
1724
1725
|
return;
|
|
@@ -1995,7 +1996,11 @@ export function App({ version, initialMode, provider: initialProvider, initialMo
|
|
|
1995
1996
|
historyIdx.current = -1;
|
|
1996
1997
|
historyDraft.current = "";
|
|
1997
1998
|
}
|
|
1998
|
-
}
|
|
1999
|
+
};
|
|
2000
|
+
const handleInputStable = useCallback((ch, key) => {
|
|
2001
|
+
onInputRef.current?.(ch, key);
|
|
2002
|
+
}, []);
|
|
2003
|
+
useInput(handleInputStable);
|
|
1999
2004
|
const closeOverlay = useCallback(() => setOverlay({ kind: "none" }), []);
|
|
2000
2005
|
// Render
|
|
2001
2006
|
const elapsed = state.status.startedAt
|