@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
package/dist/modes/ask.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../src/modes/ask.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../src/modes/ask.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AASzD,KAAK,UAAU,gBAAgB,CAC7B,MAAc,EACd,OAAmB;IAEnB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC,eAAe,CAAC;IAC5D,MAAM,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,cAAc,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAClD,MAAM,YAAY,GAAG,cAAc;QACjC,CAAC,CAAC,GAAG,qBAAqB,EAAE,+CAA+C,cAAc,EAAE;QAC3F,CAAC,CAAC,qBAAqB,EAAE,CAAC;IAC5B,OAAO;QACL,QAAQ;QACR,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,YAAY;QAC3C,QAAQ,EAAE;YACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;YACzC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;YAC1B,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;SAClC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,MAAc,EACd,UAAsB,EAAE;IAExB,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC;QACxC,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,WAAW,EAAE,GAAG;QAChB,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;QACnD,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAc,EACd,OAAgC,EAChC,UAAsB,EAAE;IAExB,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,MAAM,kBAAkB,CACrC;QACE,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,WAAW,EAAE,GAAG;QAChB,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;QACnD,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,EACD,OAAO,CACR,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
|
package/dist/os/pkgmgr.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
export interface PackageManager {
|
|
2
|
-
id:
|
|
2
|
+
id: "brew" | "apt" | "dnf" | "pacman" | "winget" | "choco" | "unknown";
|
|
3
3
|
installCommand(tool: string): string;
|
|
4
|
+
installArgv(tool: string): {
|
|
5
|
+
command: string;
|
|
6
|
+
argv: string[];
|
|
7
|
+
needsSudo: boolean;
|
|
8
|
+
} | undefined;
|
|
4
9
|
}
|
|
10
|
+
export declare function assertSafePackageName(tool: string): string;
|
|
5
11
|
export declare function detectPackageManager(): Promise<PackageManager>;
|
|
6
12
|
export declare function commandAvailable(command: string): Promise<boolean>;
|
package/dist/os/pkgmgr.js
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
|
-
import { execa } from
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
/**
|
|
3
|
+
* Strict allowlist for package names. Lets common upstream identifiers
|
|
4
|
+
* through (alphanum, dot, dash, underscore, slash for cask paths, colon for
|
|
5
|
+
* winget IDs and apt versioned packages, plus @ for npm-style scopes), but
|
|
6
|
+
* blocks shell metacharacters.
|
|
7
|
+
*/
|
|
8
|
+
const PACKAGE_NAME_RE = /^[A-Za-z0-9_.@:/+-]+$/;
|
|
9
|
+
export function assertSafePackageName(tool) {
|
|
10
|
+
const value = tool.trim();
|
|
11
|
+
if (!value)
|
|
12
|
+
throw new Error("Package name is empty");
|
|
13
|
+
if (!PACKAGE_NAME_RE.test(value)) {
|
|
14
|
+
throw new Error(`Invalid package name: ${tool}`);
|
|
15
|
+
}
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
2
18
|
async function commandExists(command) {
|
|
3
19
|
try {
|
|
4
|
-
await execa(process.platform ===
|
|
20
|
+
await execa(process.platform === "win32" ? "where" : "which", [command]);
|
|
5
21
|
return true;
|
|
6
22
|
}
|
|
7
23
|
catch {
|
|
@@ -9,22 +25,85 @@ async function commandExists(command) {
|
|
|
9
25
|
}
|
|
10
26
|
}
|
|
11
27
|
export async function detectPackageManager() {
|
|
12
|
-
if (process.platform ===
|
|
13
|
-
return {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
if (process.platform === "darwin" && (await commandExists("brew"))) {
|
|
29
|
+
return {
|
|
30
|
+
id: "brew",
|
|
31
|
+
installCommand: (tool) => `brew install ${tool}`,
|
|
32
|
+
installArgv: (tool) => ({
|
|
33
|
+
command: "brew",
|
|
34
|
+
argv: ["install", assertSafePackageName(tool)],
|
|
35
|
+
needsSudo: false,
|
|
36
|
+
}),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (process.platform === "win32") {
|
|
40
|
+
if (await commandExists("winget")) {
|
|
41
|
+
return {
|
|
42
|
+
id: "winget",
|
|
43
|
+
installCommand: (tool) => `winget install ${tool}`,
|
|
44
|
+
installArgv: (tool) => ({
|
|
45
|
+
command: "winget",
|
|
46
|
+
argv: ["install", assertSafePackageName(tool)],
|
|
47
|
+
needsSudo: false,
|
|
48
|
+
}),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (await commandExists("choco")) {
|
|
52
|
+
return {
|
|
53
|
+
id: "choco",
|
|
54
|
+
installCommand: (tool) => `choco install ${tool}`,
|
|
55
|
+
installArgv: (tool) => ({
|
|
56
|
+
command: "choco",
|
|
57
|
+
argv: ["install", "-y", assertSafePackageName(tool)],
|
|
58
|
+
needsSudo: false,
|
|
59
|
+
}),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (await commandExists("apt")) {
|
|
64
|
+
return {
|
|
65
|
+
id: "apt",
|
|
66
|
+
installCommand: (tool) => `sudo apt update && sudo apt install -y ${tool}`,
|
|
67
|
+
installArgv: (tool) => ({
|
|
68
|
+
command: "sudo",
|
|
69
|
+
argv: ["apt", "install", "-y", assertSafePackageName(tool)],
|
|
70
|
+
needsSudo: true,
|
|
71
|
+
}),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (await commandExists("dnf")) {
|
|
75
|
+
return {
|
|
76
|
+
id: "dnf",
|
|
77
|
+
installCommand: (tool) => `sudo dnf install -y ${tool}`,
|
|
78
|
+
installArgv: (tool) => ({
|
|
79
|
+
command: "sudo",
|
|
80
|
+
argv: ["dnf", "install", "-y", assertSafePackageName(tool)],
|
|
81
|
+
needsSudo: true,
|
|
82
|
+
}),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (await commandExists("pacman")) {
|
|
86
|
+
return {
|
|
87
|
+
id: "pacman",
|
|
88
|
+
installCommand: (tool) => `sudo pacman -S --needed ${tool}`,
|
|
89
|
+
installArgv: (tool) => ({
|
|
90
|
+
command: "sudo",
|
|
91
|
+
argv: [
|
|
92
|
+
"pacman",
|
|
93
|
+
"-S",
|
|
94
|
+
"--needed",
|
|
95
|
+
"--noconfirm",
|
|
96
|
+
assertSafePackageName(tool),
|
|
97
|
+
],
|
|
98
|
+
needsSudo: true,
|
|
99
|
+
}),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
id: "unknown",
|
|
104
|
+
installCommand: (tool) => `Install ${tool} with your OS package manager`,
|
|
105
|
+
installArgv: () => undefined,
|
|
106
|
+
};
|
|
28
107
|
}
|
|
29
108
|
export async function commandAvailable(command) {
|
|
30
109
|
return commandExists(command);
|
package/dist/os/pkgmgr.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pkgmgr.js","sourceRoot":"","sources":["../../src/os/pkgmgr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"pkgmgr.js","sourceRoot":"","sources":["../../src/os/pkgmgr.ts"],"names":[],"mappings":"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"}
|
package/dist/prompts/index.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal exports for tests that verify the canonical inline templates
|
|
3
|
+
* have not drifted from the markdown copies in src/prompts/. These are
|
|
4
|
+
* not part of the public API.
|
|
5
|
+
*/
|
|
6
|
+
export declare const _ASK_TEMPLATE = "You are clai in /ask mode \u2014 a cybersecurity and pentesting assistant. Do NOT execute anything.\nOS: {{os}} | Shell: {{shell}} | CWD: {{cwd}}\n\nFor every user request, respond with:\n1. One-line summary of what the user is trying to achieve\n2. Exact commands for their OS with the recommended tool flags\n3. What each command does and expected output\n4. Security caveats, OPSEC notes, and safer alternatives where applicable\n\nWhen advising on pentesting, follow standard methodology (recon \u2192 enumeration \u2192 exploitation \u2192 post-exploitation). Always note which phase the user is in and suggest logical next steps.";
|
|
7
|
+
export declare const _AGENT_TEMPLATE = "You are clai, a terminal AI agent specialized in cybersecurity, pentesting, and sysadmin.\nOS: {{os}} | Shell: {{shell}} | CWD: {{cwd}}\n\nTOOLS (use EXACT arg names \u2014 wrong names = failure):\n- shell.exec: {\"command\":\"<cmd>\"} \u2014 run any shell command. Optional: {\"command\":\"...\",\"cwd\":\"/path\",\"timeoutMs\":300000}\n- fs.read: {\"path\":\"<file>\"} \u2014 read a file\n- fs.write: {\"path\":\"<file>\",\"content\":\"<data>\"} \u2014 write a file\n- fs.list: {\"path\":\"<dir>\"} \u2014 list directory\n- fs.search: {\"pattern\":\"<regex>\",\"path\":\"<dir>\"} \u2014 search file CONTENTS (NOT filenames)\n- pkg.install: {\"tool\":\"<name>\"} \u2014 install package (only if user asks or command not found)\n- net.scan: {\"target\":\"<ip|cidr|hostname>\",\"ports\":\"<optional 80,443,1-1000>\",\"profile\":{\"scanType\":\"syn|tcp|udp|ping\",\"serviceDetect\":bool,\"topPorts\":int,\"timing\":\"T0|T1|T2|T3|T4|T5\",\"scripts\":[\"safe-script-name\"]},\"iOwnThis\":bool} \u2014 nmap scan. Target/ports/flags are strictly validated (no shell injection). Prefer the structured profile field; the legacy flags string still works but every token must be safe.\n- http.fetch: {\"url\":\"<url>\",\"method\":\"<optional GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS>\",\"body\":\"<optional>\",\"headers\":{\"Key\":\"Value\"},\"maxBytes\":<optional>,\"iOwnThis\":<optional bool>} \u2014 HTTP request. GET/HEAD auto-execute against public URLs; non-GET/HEAD and private/loopback/metadata addresses require confirmation; pass iOwnThis=true to allow private targets you own.\n- sysinfo: {} \u2014 OS info\n- pentest.recon: {\"target\":\"<ip/host>\"} \u2014 whois + dig + nmap top-100\n- tool.batch: {\"calls\":[{\"name\":\"<tool>\",\"args\":{...}}, ...],\"concurrency\":<optional 1-4>} \u2014 run up to 8 read-only tools (fs.read/list/search, http.fetch GET/HEAD, sysinfo) in parallel and aggregate their outputs. Use this for independent recon lookups (e.g. resolve a hostname AND read robots.txt) instead of a chain of single calls.\n\nFORMAT \u2014 one tool per response:\n```tool\n{\"name\":\"shell.exec\",\"args\":{\"command\":\"curl -s ifconfig.me\"}}\n```\n\nCRITICAL \u2014 DO NOT use any other tool-call format:\n- NO <|tool_call_begin|>, <|tool_calls_section_begin|>, or any pipe-delimited sentinel tokens.\n- NO <tool_call> XML, NO ### tool headings, NO trailing JSON outside a fence.\n- The \"functions.\" prefix is NOT allowed \u2014 use the bare tool name (e.g. \"shell.exec\", not \"functions.shell.exec\").\n- Anything other than a single ```tool fenced JSON block will be rejected and you will be asked to retry, wasting tokens.\n\nRULES:\n1. ANSWER THEN STOP. Once you have the answer, give it and STOP. Do NOT run extra tools.\n2. STAY ON TASK. Do EXACTLY what the user asked \u2014 nothing more, nothing less.\n3. One tool per response. 1-2 lines of reasoning MAX before the tool block.\n4. To find files/dirs by name: shell.exec find /path -maxdepth 3 -name '*pattern*'\n5. CONTINUE only if the original task is NOT yet done. Resolve sub-problems then proceed.\n6. Use conversation history for follow-ups. \"it\", \"that\", \"such\" = context from previous messages.\n7. Suppress noise: curl -s, wget -q. Always use full absolute paths.\n8. Never run cd, pwd, or re-list directories you already listed.\n9. Only pentest systems the user owns or has permission to test.\n10. Do not invent volatile live data (IPs, scan results, dates). Re-run commands for current data.\n11. After a tool returns output, summarize concrete findings. Never say only \"check the output\".\n12. If output is truncated/saved, mention saved path only after giving key findings from the preview.\n13. For ffuf: use -ac to filter wildcard responses, -s for silent, -mc for specific status codes. Never use -q.\n14. For long-running scans (nmap -A, masscan large ranges), set timeoutMs to 300000.\n15. When a command fails with \"not found\", use pkg.install to install it, then retry.\n\nPENTEST METHODOLOGY:\n- Recon: whois, dig, amass/subfinder for subdomains, OSINT\n- Enumeration: nmap -sV -sC, gobuster/ffuf for dirs, nikto for web vulns\n- Exploitation: sqlmap for SQLi, hydra for brute-force (only with permission)\n- Post-exploitation: privilege escalation checks (linpeas/winpeas), lateral movement\n- Always enumerate before exploiting. Suggest logical next steps after each finding.\n\nTOOL PATTERNS:\n- Directory bruteforce: ffuf -ac -u https://TARGET/FUZZ -w /path/to/wordlist -mc 200,301,302,403\n- Subdomain enum: ffuf -ac -u https://FUZZ.target.com -w /path/to/subdomains.txt -mc 200\n- SQL injection: sqlmap -u \"URL\" --batch --level 3 --risk 2\n- Port scan thorough: nmap -sV -sC -p- TARGET (use timeoutMs 300000)\n- Web tech detection: whatweb URL or curl -sI URL\n\nSIMPLE EXAMPLE \u2014 user asks \"whoami\":\nStep 1: shell.exec whoami \u2192 \"aniket\". Answer: \"You are aniket.\" DONE.\n\nCOMPLEX EXAMPLE \u2014 user asks \"directory scan on example.com\":\nStep 1: Find wordlist \u2192 shell.exec find /usr -maxdepth 4 -name 'common.txt' -path '*/Discovery/*'\nStep 2: Run scan \u2192 shell.exec ffuf -ac -u https://example.com/FUZZ -w /path/common.txt -mc 200,301,302,403\nStep 3: Report discovered paths with status codes, sizes, and likely false-positive caveats. DONE.\n\nDo NOT: run sysinfo after answering, list home dirs, scan localhost unprompted, fetch random ports, install tools without reason, or do ANYTHING the user did not ask for.";
|
|
1
8
|
export declare function renderAskSystemPrompt(): string;
|
|
2
9
|
export declare function renderAgentSystemPrompt(toolList: string): string;
|
package/dist/prompts/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { detectSystem } from
|
|
1
|
+
import { detectSystem } from "../os/detect.js";
|
|
2
2
|
const askPrompt = `You are clai in /ask mode — a cybersecurity and pentesting assistant. Do NOT execute anything.
|
|
3
3
|
OS: {{os}} | Shell: {{shell}} | CWD: {{cwd}}
|
|
4
4
|
|
|
@@ -19,10 +19,11 @@ TOOLS (use EXACT arg names — wrong names = failure):
|
|
|
19
19
|
- fs.list: {"path":"<dir>"} — list directory
|
|
20
20
|
- fs.search: {"pattern":"<regex>","path":"<dir>"} — search file CONTENTS (NOT filenames)
|
|
21
21
|
- pkg.install: {"tool":"<name>"} — install package (only if user asks or command not found)
|
|
22
|
-
- net.scan: {"target":"<ip
|
|
23
|
-
- http.fetch: {"url":"<url>","method":"<optional>","body":"<optional>","headers":{"Key":"Value"}} — HTTP request
|
|
22
|
+
- net.scan: {"target":"<ip|cidr|hostname>","ports":"<optional 80,443,1-1000>","profile":{"scanType":"syn|tcp|udp|ping","serviceDetect":bool,"topPorts":int,"timing":"T0|T1|T2|T3|T4|T5","scripts":["safe-script-name"]},"iOwnThis":bool} — nmap scan. Target/ports/flags are strictly validated (no shell injection). Prefer the structured profile field; the legacy flags string still works but every token must be safe.
|
|
23
|
+
- http.fetch: {"url":"<url>","method":"<optional GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS>","body":"<optional>","headers":{"Key":"Value"},"maxBytes":<optional>,"iOwnThis":<optional bool>} — HTTP request. GET/HEAD auto-execute against public URLs; non-GET/HEAD and private/loopback/metadata addresses require confirmation; pass iOwnThis=true to allow private targets you own.
|
|
24
24
|
- sysinfo: {} — OS info
|
|
25
25
|
- pentest.recon: {"target":"<ip/host>"} — whois + dig + nmap top-100
|
|
26
|
+
- tool.batch: {"calls":[{"name":"<tool>","args":{...}}, ...],"concurrency":<optional 1-4>} — run up to 8 read-only tools (fs.read/list/search, http.fetch GET/HEAD, sysinfo) in parallel and aggregate their outputs. Use this for independent recon lookups (e.g. resolve a hostname AND read robots.txt) instead of a chain of single calls.
|
|
26
27
|
|
|
27
28
|
FORMAT — one tool per response:
|
|
28
29
|
\`\`\`tool
|
|
@@ -78,13 +79,20 @@ Do NOT: run sysinfo after answering, list home dirs, scan localhost unprompted,
|
|
|
78
79
|
function render(template, values) {
|
|
79
80
|
return Object.entries(values).reduce((current, [key, value]) => current.replaceAll(`{{${key}}}`, value), template);
|
|
80
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Internal exports for tests that verify the canonical inline templates
|
|
84
|
+
* have not drifted from the markdown copies in src/prompts/. These are
|
|
85
|
+
* not part of the public API.
|
|
86
|
+
*/
|
|
87
|
+
export const _ASK_TEMPLATE = askPrompt;
|
|
88
|
+
export const _AGENT_TEMPLATE = agentPrompt;
|
|
81
89
|
export function renderAskSystemPrompt() {
|
|
82
90
|
const system = detectSystem();
|
|
83
91
|
return render(askPrompt, {
|
|
84
92
|
os: `${system.osName} ${system.release} ${system.arch}`,
|
|
85
93
|
shell: system.shell,
|
|
86
94
|
cwd: system.cwd,
|
|
87
|
-
tool_list:
|
|
95
|
+
tool_list: "none",
|
|
88
96
|
});
|
|
89
97
|
}
|
|
90
98
|
export function renderAgentSystemPrompt(toolList) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,SAAS,GAAG;;;;;;;;;0LASwK,CAAC;AAE3L,MAAM,WAAW,GAAG
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,SAAS,GAAG;;;;;;;;;0LASwK,CAAC;AAE3L,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2KAkEuJ,CAAC;AAE5K,SAAS,MAAM,CAAC,QAAgB,EAAE,MAA8B;IAC9D,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAClC,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC,EAClE,QAAQ,CACT,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC;AACvC,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC;AAE3C,MAAM,UAAU,qBAAqB;IACnC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,OAAO,MAAM,CAAC,SAAS,EAAE;QACvB,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,EAAE;QACvD,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,SAAS,EAAE,MAAM;KAClB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,OAAO,MAAM,CAAC,WAAW,EAAE;QACzB,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,EAAE;QACvD,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,SAAS,EAAE,QAAQ;KACpB,CAAC,CAAC;AACL,CAAC"}
|