@pentoshi/clai 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +287 -0
- package/bin/clai.mjs +2 -0
- package/dist/agent/runner.d.ts +12 -0
- package/dist/agent/runner.js +249 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +29 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/providers.d.ts +13 -0
- package/dist/commands/providers.js +137 -0
- package/dist/commands/providers.js.map +1 -0
- package/dist/commands/update.d.ts +5 -0
- package/dist/commands/update.js +123 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +172 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/anthropic.d.ts +2 -0
- package/dist/llm/anthropic.js +127 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/gemini.d.ts +2 -0
- package/dist/llm/gemini.js +109 -0
- package/dist/llm/gemini.js.map +1 -0
- package/dist/llm/groq.d.ts +2 -0
- package/dist/llm/groq.js +49 -0
- package/dist/llm/groq.js.map +1 -0
- package/dist/llm/http.d.ts +35 -0
- package/dist/llm/http.js +112 -0
- package/dist/llm/http.js.map +1 -0
- package/dist/llm/ollama.d.ts +2 -0
- package/dist/llm/ollama.js +95 -0
- package/dist/llm/ollama.js.map +1 -0
- package/dist/llm/openai.d.ts +2 -0
- package/dist/llm/openai.js +49 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/llm/openrouter.d.ts +2 -0
- package/dist/llm/openrouter.js +55 -0
- package/dist/llm/openrouter.js.map +1 -0
- package/dist/llm/provider.d.ts +23 -0
- package/dist/llm/provider.js +58 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/router.d.ts +8 -0
- package/dist/llm/router.js +103 -0
- package/dist/llm/router.js.map +1 -0
- package/dist/modes/agent.d.ts +17 -0
- package/dist/modes/agent.js +6 -0
- package/dist/modes/agent.js.map +1 -0
- package/dist/modes/ask.d.ts +8 -0
- package/dist/modes/ask.js +46 -0
- package/dist/modes/ask.js.map +1 -0
- package/dist/os/detect.d.ts +10 -0
- package/dist/os/detect.js +17 -0
- package/dist/os/detect.js.map +1 -0
- package/dist/os/pkgmgr.d.ts +6 -0
- package/dist/os/pkgmgr.js +32 -0
- package/dist/os/pkgmgr.js.map +1 -0
- package/dist/prompts/index.d.ts +2 -0
- package/dist/prompts/index.js +60 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/repl.d.ts +7 -0
- package/dist/repl.js +216 -0
- package/dist/repl.js.map +1 -0
- package/dist/safety/classifier.d.ts +8 -0
- package/dist/safety/classifier.js +118 -0
- package/dist/safety/classifier.js.map +1 -0
- package/dist/safety/patterns.d.ts +5 -0
- package/dist/safety/patterns.js +45 -0
- package/dist/safety/patterns.js.map +1 -0
- package/dist/store/config.d.ts +20 -0
- package/dist/store/config.js +46 -0
- package/dist/store/config.js.map +1 -0
- package/dist/store/history.d.ts +24 -0
- package/dist/store/history.js +145 -0
- package/dist/store/history.js.map +1 -0
- package/dist/store/keys.d.ts +10 -0
- package/dist/store/keys.js +115 -0
- package/dist/store/keys.js.map +1 -0
- package/dist/store/logs.d.ts +2 -0
- package/dist/store/logs.js +31 -0
- package/dist/store/logs.js.map +1 -0
- package/dist/store/project.d.ts +2 -0
- package/dist/store/project.js +14 -0
- package/dist/store/project.js.map +1 -0
- package/dist/tools/fs.d.ts +5 -0
- package/dist/tools/fs.js +82 -0
- package/dist/tools/fs.js.map +1 -0
- package/dist/tools/http.d.ts +6 -0
- package/dist/tools/http.js +14 -0
- package/dist/tools/http.js.map +1 -0
- package/dist/tools/registry.d.ts +5 -0
- package/dist/tools/registry.js +79 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/shell.d.ts +7 -0
- package/dist/tools/shell.js +16 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/banner.d.ts +12 -0
- package/dist/ui/banner.js +55 -0
- package/dist/ui/banner.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CompletionRequest, CompletionResult, ProviderId } from "../types.js";
|
|
2
|
+
import type { LlmProvider, ProviderAuth } from "./provider.js";
|
|
3
|
+
export declare const providers: Record<ProviderId, LlmProvider>;
|
|
4
|
+
export declare function getProvider(provider: ProviderId): LlmProvider;
|
|
5
|
+
export declare function providerAuth(provider: ProviderId): Promise<ProviderAuth>;
|
|
6
|
+
export declare function completeWithProvider(request: CompletionRequest): Promise<CompletionResult>;
|
|
7
|
+
export declare function streamWithProvider(request: CompletionRequest, onToken: (token: string) => void): Promise<CompletionResult>;
|
|
8
|
+
export declare function pingProvider(providerId: ProviderId, secretOverride?: string): Promise<void>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { getConfig } from "../store/config.js";
|
|
2
|
+
import { getProviderSecret } from "../store/keys.js";
|
|
3
|
+
import { anthropicProvider } from "./anthropic.js";
|
|
4
|
+
import { geminiProvider } from "./gemini.js";
|
|
5
|
+
import { groqProvider } from "./groq.js";
|
|
6
|
+
import { ollamaProvider } from "./ollama.js";
|
|
7
|
+
import { openaiProvider } from "./openai.js";
|
|
8
|
+
import { openrouterProvider } from "./openrouter.js";
|
|
9
|
+
export const providers = {
|
|
10
|
+
groq: groqProvider,
|
|
11
|
+
gemini: geminiProvider,
|
|
12
|
+
openrouter: openrouterProvider,
|
|
13
|
+
openai: openaiProvider,
|
|
14
|
+
anthropic: anthropicProvider,
|
|
15
|
+
ollama: ollamaProvider,
|
|
16
|
+
};
|
|
17
|
+
const fallbackOrder = [
|
|
18
|
+
"groq",
|
|
19
|
+
"gemini",
|
|
20
|
+
"openrouter",
|
|
21
|
+
"openai",
|
|
22
|
+
"anthropic",
|
|
23
|
+
"ollama",
|
|
24
|
+
];
|
|
25
|
+
export function getProvider(provider) {
|
|
26
|
+
return providers[provider];
|
|
27
|
+
}
|
|
28
|
+
export async function providerAuth(provider) {
|
|
29
|
+
const secret = await getProviderSecret(provider);
|
|
30
|
+
if (provider === "ollama") {
|
|
31
|
+
return { baseUrl: secret.value };
|
|
32
|
+
}
|
|
33
|
+
return { apiKey: secret.value };
|
|
34
|
+
}
|
|
35
|
+
export async function completeWithProvider(request) {
|
|
36
|
+
const config = getConfig();
|
|
37
|
+
const requested = request.provider ?? config.defaultProvider;
|
|
38
|
+
const order = [
|
|
39
|
+
requested,
|
|
40
|
+
...fallbackOrder.filter((provider) => provider !== requested),
|
|
41
|
+
];
|
|
42
|
+
const failures = [];
|
|
43
|
+
for (const providerId of order) {
|
|
44
|
+
const provider = providers[providerId];
|
|
45
|
+
const auth = await providerAuth(providerId);
|
|
46
|
+
const hasAuth = providerId === "ollama" ? Boolean(auth.baseUrl) : Boolean(auth.apiKey);
|
|
47
|
+
if (!hasAuth) {
|
|
48
|
+
failures.push(`${providerId}: no API key configured`);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const model = providerId === requested
|
|
53
|
+
? (request.model ?? provider.defaultModel)
|
|
54
|
+
: provider.defaultModel;
|
|
55
|
+
return await provider.complete({ ...request, provider: providerId, model }, auth);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
failures.push(`${providerId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`No provider could complete the request. ${failures.join(" | ")}`);
|
|
62
|
+
}
|
|
63
|
+
export async function streamWithProvider(request, onToken) {
|
|
64
|
+
const config = getConfig();
|
|
65
|
+
const requested = request.provider ?? config.defaultProvider;
|
|
66
|
+
const order = [
|
|
67
|
+
requested,
|
|
68
|
+
...fallbackOrder.filter((provider) => provider !== requested),
|
|
69
|
+
];
|
|
70
|
+
const failures = [];
|
|
71
|
+
for (const providerId of order) {
|
|
72
|
+
const provider = providers[providerId];
|
|
73
|
+
const auth = await providerAuth(providerId);
|
|
74
|
+
const hasAuth = providerId === "ollama" ? Boolean(auth.baseUrl) : Boolean(auth.apiKey);
|
|
75
|
+
if (!hasAuth) {
|
|
76
|
+
failures.push(`${providerId}: no API key configured`);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const model = providerId === requested
|
|
81
|
+
? (request.model ?? provider.defaultModel)
|
|
82
|
+
: provider.defaultModel;
|
|
83
|
+
if (provider.stream) {
|
|
84
|
+
return await provider.stream({ ...request, provider: providerId, model }, auth, onToken);
|
|
85
|
+
}
|
|
86
|
+
const result = await provider.complete({ ...request, provider: providerId, model }, auth);
|
|
87
|
+
onToken(result.text);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
failures.push(`${providerId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
throw new Error(`No provider could stream the request. ${failures.join(" | ")}`);
|
|
95
|
+
}
|
|
96
|
+
export async function pingProvider(providerId, secretOverride) {
|
|
97
|
+
const provider = providers[providerId];
|
|
98
|
+
const auth = providerId === "ollama"
|
|
99
|
+
? { baseUrl: secretOverride ?? (await providerAuth(providerId)).baseUrl }
|
|
100
|
+
: { apiKey: secretOverride ?? (await providerAuth(providerId)).apiKey };
|
|
101
|
+
await provider.ping(auth);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/llm/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ChatMessage, ProviderId, ToolCall } from "../types.js";
|
|
2
|
+
import { parseToolCall } from "../agent/runner.js";
|
|
3
|
+
export interface AgentOptions {
|
|
4
|
+
provider?: ProviderId | undefined;
|
|
5
|
+
model?: string | undefined;
|
|
6
|
+
history?: ChatMessage[] | undefined;
|
|
7
|
+
autoConfirm?: boolean | undefined;
|
|
8
|
+
maxSteps?: number | undefined;
|
|
9
|
+
onToolStart?: ((call: ToolCall) => void) | undefined;
|
|
10
|
+
onToolResult?: ((call: ToolCall, result: {
|
|
11
|
+
ok: boolean;
|
|
12
|
+
output: string;
|
|
13
|
+
exitCode?: number | undefined;
|
|
14
|
+
}) => void) | undefined;
|
|
15
|
+
}
|
|
16
|
+
export { parseToolCall };
|
|
17
|
+
export declare function runAgent(prompt: string, options?: AgentOptions): Promise<string>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/modes/agent.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAiBjE,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAc,EACd,UAAwB,EAAE;IAE1B,OAAO,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ChatMessage, ProviderId } from "../types.js";
|
|
2
|
+
export interface AskOptions {
|
|
3
|
+
provider?: ProviderId | undefined;
|
|
4
|
+
model?: string | undefined;
|
|
5
|
+
history?: ChatMessage[] | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare function runAsk(prompt: string, options?: AskOptions): Promise<string>;
|
|
8
|
+
export declare function runAskStream(prompt: string, onToken: (token: string) => void, options?: AskOptions): Promise<string>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { completeWithProvider, streamWithProvider } from "../llm/router.js";
|
|
2
|
+
import { renderAskSystemPrompt } from "../prompts/index.js";
|
|
3
|
+
import { getConfig } from "../store/config.js";
|
|
4
|
+
import { ensureProviderConfigured } from "../commands/providers.js";
|
|
5
|
+
import { loadProjectContext } from "../store/project.js";
|
|
6
|
+
async function buildAskMessages(prompt, options) {
|
|
7
|
+
const config = getConfig();
|
|
8
|
+
const provider = options.provider ?? config.defaultProvider;
|
|
9
|
+
await ensureProviderConfigured(provider);
|
|
10
|
+
const projectContext = await loadProjectContext();
|
|
11
|
+
const systemPrompt = projectContext
|
|
12
|
+
? `${renderAskSystemPrompt()}\n\nProject context from .clai/context.md:\n${projectContext}`
|
|
13
|
+
: renderAskSystemPrompt();
|
|
14
|
+
return {
|
|
15
|
+
provider,
|
|
16
|
+
model: options.model ?? config.defaultModel,
|
|
17
|
+
messages: [
|
|
18
|
+
{ role: "system", content: systemPrompt },
|
|
19
|
+
...(options.history ?? []),
|
|
20
|
+
{ role: "user", content: prompt },
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export async function runAsk(prompt, options = {}) {
|
|
25
|
+
const request = await buildAskMessages(prompt, options);
|
|
26
|
+
const result = await completeWithProvider({
|
|
27
|
+
provider: request.provider,
|
|
28
|
+
model: request.model,
|
|
29
|
+
messages: request.messages,
|
|
30
|
+
temperature: 0.2,
|
|
31
|
+
maxTokens: 1_500,
|
|
32
|
+
});
|
|
33
|
+
return result.text;
|
|
34
|
+
}
|
|
35
|
+
export async function runAskStream(prompt, onToken, options = {}) {
|
|
36
|
+
const request = await buildAskMessages(prompt, options);
|
|
37
|
+
const result = await streamWithProvider({
|
|
38
|
+
provider: request.provider,
|
|
39
|
+
model: request.model,
|
|
40
|
+
messages: request.messages,
|
|
41
|
+
temperature: 0.2,
|
|
42
|
+
maxTokens: 1_500,
|
|
43
|
+
}, onToken);
|
|
44
|
+
return result.text;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=ask.js.map
|
|
@@ -0,0 +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;AAQzD,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,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,KAAK;KACjB,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,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,KAAK;KACjB,EACD,OAAO,CACR,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { arch, platform, release, type } from 'node:os';
|
|
2
|
+
export function detectSystem() {
|
|
3
|
+
const currentPlatform = platform();
|
|
4
|
+
const osName = currentPlatform === 'darwin' ? 'macOS' : currentPlatform === 'win32' ? 'Windows' : type();
|
|
5
|
+
return {
|
|
6
|
+
platform: currentPlatform,
|
|
7
|
+
osName,
|
|
8
|
+
arch: arch(),
|
|
9
|
+
release: release(),
|
|
10
|
+
shell: process.env.SHELL ?? process.env.ComSpec ?? 'unknown',
|
|
11
|
+
cwd: process.cwd(),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function isWindows() {
|
|
15
|
+
return process.platform === 'win32';
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/os/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAWxD,MAAM,UAAU,YAAY;IAC1B,MAAM,eAAe,GAAG,QAAQ,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACzG,OAAO;QACL,QAAQ,EAAE,eAAe;QACzB,MAAM;QACN,IAAI,EAAE,IAAI,EAAE;QACZ,OAAO,EAAE,OAAO,EAAE;QAClB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,SAAS;QAC5D,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;KACnB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface PackageManager {
|
|
2
|
+
id: 'brew' | 'apt' | 'dnf' | 'pacman' | 'winget' | 'choco' | 'unknown';
|
|
3
|
+
installCommand(tool: string): string;
|
|
4
|
+
}
|
|
5
|
+
export declare function detectPackageManager(): Promise<PackageManager>;
|
|
6
|
+
export declare function commandAvailable(command: string): Promise<boolean>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
async function commandExists(command) {
|
|
3
|
+
try {
|
|
4
|
+
await execa(process.platform === 'win32' ? 'where' : 'which', [command]);
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export async function detectPackageManager() {
|
|
12
|
+
if (process.platform === 'darwin' && (await commandExists('brew'))) {
|
|
13
|
+
return { id: 'brew', installCommand: (tool) => `brew install ${tool}` };
|
|
14
|
+
}
|
|
15
|
+
if (process.platform === 'win32') {
|
|
16
|
+
if (await commandExists('winget'))
|
|
17
|
+
return { id: 'winget', installCommand: (tool) => `winget install ${tool}` };
|
|
18
|
+
if (await commandExists('choco'))
|
|
19
|
+
return { id: 'choco', installCommand: (tool) => `choco install ${tool}` };
|
|
20
|
+
}
|
|
21
|
+
if (await commandExists('apt'))
|
|
22
|
+
return { id: 'apt', installCommand: (tool) => `sudo apt update && sudo apt install -y ${tool}` };
|
|
23
|
+
if (await commandExists('dnf'))
|
|
24
|
+
return { id: 'dnf', installCommand: (tool) => `sudo dnf install -y ${tool}` };
|
|
25
|
+
if (await commandExists('pacman'))
|
|
26
|
+
return { id: 'pacman', installCommand: (tool) => `sudo pacman -S --needed ${tool}` };
|
|
27
|
+
return { id: 'unknown', installCommand: (tool) => `Install ${tool} with your OS package manager` };
|
|
28
|
+
}
|
|
29
|
+
export async function commandAvailable(command) {
|
|
30
|
+
return commandExists(command);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=pkgmgr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkgmgr.js","sourceRoot":"","sources":["../../src/os/pkgmgr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAO9B,KAAK,UAAU,aAAa,CAAC,OAAe;IAC1C,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACzE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACnE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,IAAI,EAAE,EAAE,CAAC;IAC1E,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,MAAM,aAAa,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,IAAI,EAAE,EAAE,CAAC;QAC/G,IAAI,MAAM,aAAa,CAAC,OAAO,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,IAAI,EAAE,EAAE,CAAC;IAC9G,CAAC;IAED,IAAI,MAAM,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,0CAA0C,IAAI,EAAE,EAAE,CAAC;IACjI,IAAI,MAAM,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,uBAAuB,IAAI,EAAE,EAAE,CAAC;IAC9G,IAAI,MAAM,aAAa,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,2BAA2B,IAAI,EAAE,EAAE,CAAC;IAExH,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,IAAI,+BAA+B,EAAE,CAAC;AACrG,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAe;IACpD,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { detectSystem } from '../os/detect.js';
|
|
2
|
+
const askPrompt = 'You are clai in /ask mode. Do NOT execute anything. For every user request, respond with: (1) one-line summary, (2) exact commands for their OS ({{os}}, shell={{shell}}), (3) what each command does, (4) caveats / safer alternatives.';
|
|
3
|
+
const agentPrompt = `You are clai, a terminal AI agent for cybersecurity, pentesting, and sysadmin.
|
|
4
|
+
OS: {{os}} | Shell: {{shell}} | CWD: {{cwd}}
|
|
5
|
+
|
|
6
|
+
TOOLS (use EXACT arg names — wrong names = failure):
|
|
7
|
+
- shell.exec: {"command":"<cmd>"} — run any shell command. Use full paths. cd does NOT work.
|
|
8
|
+
- fs.read: {"path":"<file>"} — read a file
|
|
9
|
+
- fs.write: {"path":"<file>","content":"<data>"} — write a file
|
|
10
|
+
- fs.list: {"path":"<dir>"} — list directory
|
|
11
|
+
- fs.search: {"pattern":"<regex>","path":"<dir>"} — search file CONTENTS (NOT filenames)
|
|
12
|
+
- pkg.install: {"tool":"<name>"} — install package (only if user asks or command not found)
|
|
13
|
+
- net.scan: {"target":"<ip/host>","ports":"<optional>"} — nmap scan
|
|
14
|
+
- http.fetch: {"url":"<url>","method":"<optional>","body":"<optional>"} — HTTP request
|
|
15
|
+
- sysinfo: {} — OS info
|
|
16
|
+
- pentest.recon: {"target":"<ip/host>"} — whois + dig + nmap
|
|
17
|
+
|
|
18
|
+
FORMAT — one tool per response:
|
|
19
|
+
\`\`\`tool
|
|
20
|
+
{"name":"shell.exec","args":{"command":"curl -s ifconfig.me"}}
|
|
21
|
+
\`\`\`
|
|
22
|
+
|
|
23
|
+
RULES:
|
|
24
|
+
1. STAY ON TASK. Do EXACTLY what the user asked. Do NOT add extra scans, installs, or exploration.
|
|
25
|
+
2. One tool per response. 1-2 lines of thinking MAX before the tool block.
|
|
26
|
+
3. To find files/dirs by name: shell.exec find /path -maxdepth 3 -name '*pattern*'
|
|
27
|
+
4. CONTINUE until the original task is done. Resolve sub-problems then proceed.
|
|
28
|
+
5. Use conversation history for follow-ups. "it", "that", "such" = context from previous messages.
|
|
29
|
+
6. Suppress noise: curl -s, wget -q. Always use full absolute paths.
|
|
30
|
+
7. Never run cd, pwd, or re-list directories you already listed.
|
|
31
|
+
8. Only pentest systems the user owns or has permission to test.
|
|
32
|
+
|
|
33
|
+
EXAMPLE — user asks "directory scan on example.com, seclists in /opt":
|
|
34
|
+
Step 1: Find the wordlist → shell.exec find /opt -maxdepth 3 -type d -name 'Discovery'
|
|
35
|
+
Step 2: List wordlists → fs.list /opt/wordlist/SecLists/Discovery/Web-Content
|
|
36
|
+
Step 3: Run scan → shell.exec gobuster dir -u https://example.com -w /opt/wordlist/SecLists/Discovery/Web-Content/common.txt -q
|
|
37
|
+
Step 4: Report findings. DONE.
|
|
38
|
+
Do NOT: scan localhost, fetch random ports, search file contents, install tools, or do anything else.`;
|
|
39
|
+
function render(template, values) {
|
|
40
|
+
return Object.entries(values).reduce((current, [key, value]) => current.replaceAll(`{{${key}}}`, value), template);
|
|
41
|
+
}
|
|
42
|
+
export function renderAskSystemPrompt() {
|
|
43
|
+
const system = detectSystem();
|
|
44
|
+
return render(askPrompt, {
|
|
45
|
+
os: `${system.osName} ${system.release} ${system.arch}`,
|
|
46
|
+
shell: system.shell,
|
|
47
|
+
cwd: system.cwd,
|
|
48
|
+
tool_list: 'none',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
export function renderAgentSystemPrompt(toolList) {
|
|
52
|
+
const system = detectSystem();
|
|
53
|
+
return render(agentPrompt, {
|
|
54
|
+
os: `${system.osName} ${system.release} ${system.arch}`,
|
|
55
|
+
shell: system.shell,
|
|
56
|
+
cwd: system.cwd,
|
|
57
|
+
tool_list: toolList,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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,0OAA0O,CAAC;AAE7P,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sGAmCkF,CAAC;AAGvG,SAAS,MAAM,CAAC,QAAgB,EAAE,MAA8B;IAC9D,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC;AACrH,CAAC;AAED,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"}
|
package/dist/repl.d.ts
ADDED
package/dist/repl.js
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import readline from "node:readline/promises";
|
|
2
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { runAskStream } from "./modes/ask.js";
|
|
5
|
+
import { runAgent } from "./modes/agent.js";
|
|
6
|
+
import { providerSwitcher, printProviderKeys, setProviderKey, unsetProviderKey, } from "./commands/providers.js";
|
|
7
|
+
import { getConfig, getProviderModel, setDefaultMode, setProviderModel, updateConfig, } from "./store/config.js";
|
|
8
|
+
import { listSessions, saveSession } from "./store/history.js";
|
|
9
|
+
import { assertProvider } from "./llm/provider.js";
|
|
10
|
+
import { runUpdate, checkForUpdateSilent, getCurrentVersion } from "./commands/update.js";
|
|
11
|
+
import { renderBanner, renderSessionInfo, renderSuggestions, renderModeSwitch, renderProviderSwitch, PROMPT, } from "./ui/banner.js";
|
|
12
|
+
function splitCommand(line) {
|
|
13
|
+
return (line
|
|
14
|
+
.match(/(?:[^\s"]+|"[^"]*")+/g)
|
|
15
|
+
?.map((part) => part.replace(/^"|"$/g, "")) ?? []);
|
|
16
|
+
}
|
|
17
|
+
function help() {
|
|
18
|
+
const cmds = [
|
|
19
|
+
["/ask", "switch to ask mode"],
|
|
20
|
+
["/agent", "switch to agent mode"],
|
|
21
|
+
["/model <name>", "switch model"],
|
|
22
|
+
["/provider [name]", "switch provider or open picker"],
|
|
23
|
+
["/use <provider>", "alias for /provider <name>"],
|
|
24
|
+
["/set <provider> [key]", "store API key"],
|
|
25
|
+
["/unset <provider>", "remove key"],
|
|
26
|
+
["/keys", "list configured providers"],
|
|
27
|
+
["/clear", "clear context"],
|
|
28
|
+
["/history", "show past sessions"],
|
|
29
|
+
["/save <name>", "save session"],
|
|
30
|
+
["/cwd <path>", "change working directory"],
|
|
31
|
+
["/allow <tool>", "allow a tool for session"],
|
|
32
|
+
["/update", "check for updates"],
|
|
33
|
+
["/exit", "quit"],
|
|
34
|
+
["/help", "list commands"],
|
|
35
|
+
];
|
|
36
|
+
const maxCmd = Math.max(...cmds.map((c) => c[0].length));
|
|
37
|
+
return cmds
|
|
38
|
+
.map((c) => ` ${chalk.cyan(c[0].padEnd(maxCmd + 2))}${chalk.dim(c[1])}`)
|
|
39
|
+
.join("\n");
|
|
40
|
+
}
|
|
41
|
+
async function handleSlash(line, state) {
|
|
42
|
+
const [command, ...args] = splitCommand(line);
|
|
43
|
+
switch (command) {
|
|
44
|
+
case "/ask":
|
|
45
|
+
state.mode = "ask";
|
|
46
|
+
setDefaultMode("ask");
|
|
47
|
+
console.log(renderModeSwitch("ask"));
|
|
48
|
+
return true;
|
|
49
|
+
case "/agent":
|
|
50
|
+
state.mode = "agent";
|
|
51
|
+
setDefaultMode("agent");
|
|
52
|
+
console.log(renderModeSwitch("agent"));
|
|
53
|
+
return true;
|
|
54
|
+
case "/model": {
|
|
55
|
+
const model = args.join(" ");
|
|
56
|
+
if (!model)
|
|
57
|
+
console.log(chalk.dim("usage: /model <name>"));
|
|
58
|
+
else {
|
|
59
|
+
state.model = model;
|
|
60
|
+
setProviderModel(state.provider, model);
|
|
61
|
+
console.log(renderProviderSwitch(state.provider, model));
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
case "/provider":
|
|
66
|
+
case "/use": {
|
|
67
|
+
await providerSwitcher(args[0]);
|
|
68
|
+
const config = getConfig();
|
|
69
|
+
state.provider = config.defaultProvider;
|
|
70
|
+
state.model = getProviderModel(state.provider);
|
|
71
|
+
console.log(renderProviderSwitch(state.provider, state.model));
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
case "/set": {
|
|
75
|
+
if (!args[0])
|
|
76
|
+
console.log(chalk.dim("usage: /set <provider> [key]"));
|
|
77
|
+
else
|
|
78
|
+
await setProviderKey(args[0], args[1], {});
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
case "/unset": {
|
|
82
|
+
if (!args[0])
|
|
83
|
+
console.log(chalk.dim("usage: /unset <provider>"));
|
|
84
|
+
else
|
|
85
|
+
await unsetProviderKey(args[0]);
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
case "/keys":
|
|
89
|
+
await printProviderKeys();
|
|
90
|
+
return true;
|
|
91
|
+
case "/clear":
|
|
92
|
+
state.messages.length = 0;
|
|
93
|
+
console.log(chalk.dim(" context cleared"));
|
|
94
|
+
return true;
|
|
95
|
+
case "/history": {
|
|
96
|
+
const sessions = await listSessions();
|
|
97
|
+
if (sessions.length === 0)
|
|
98
|
+
console.log(chalk.dim(" no saved sessions"));
|
|
99
|
+
for (const session of sessions) {
|
|
100
|
+
console.log(chalk.dim(" ") +
|
|
101
|
+
`${session.createdAt} ${session.name ?? session.id} ${chalk.dim(`(${session.messages.length} msgs)`)}`);
|
|
102
|
+
}
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
case "/save": {
|
|
106
|
+
const record = await saveSession(state.messages, args.join(" ") || undefined);
|
|
107
|
+
console.log(chalk.dim(` saved session ${record.id}`));
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
case "/cwd": {
|
|
111
|
+
const dir = args.join(" ");
|
|
112
|
+
if (!dir)
|
|
113
|
+
console.log(chalk.dim(` ${process.cwd()}`));
|
|
114
|
+
else {
|
|
115
|
+
process.chdir(dir);
|
|
116
|
+
const config = getConfig();
|
|
117
|
+
updateConfig({
|
|
118
|
+
sandboxRoots: Array.from(new Set([...config.sandboxRoots, process.cwd()])),
|
|
119
|
+
});
|
|
120
|
+
console.log(chalk.dim(` cwd → ${process.cwd()}`));
|
|
121
|
+
}
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
case "/allow": {
|
|
125
|
+
const tool = args[0];
|
|
126
|
+
if (!tool)
|
|
127
|
+
console.log(chalk.dim("usage: /allow <tool>"));
|
|
128
|
+
else {
|
|
129
|
+
const config = getConfig();
|
|
130
|
+
updateConfig({
|
|
131
|
+
allowAlwaysTools: Array.from(new Set([...config.allowAlwaysTools, tool])),
|
|
132
|
+
});
|
|
133
|
+
console.log(chalk.dim(` allowed ${tool} ✓`));
|
|
134
|
+
}
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
case "/exit":
|
|
138
|
+
case "/quit":
|
|
139
|
+
return false;
|
|
140
|
+
case "/update":
|
|
141
|
+
await runUpdate();
|
|
142
|
+
return true;
|
|
143
|
+
case "/help":
|
|
144
|
+
console.log(help());
|
|
145
|
+
return true;
|
|
146
|
+
default:
|
|
147
|
+
console.log(chalk.dim(` unknown command: ${command}. Try /help`));
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export async function startRepl(options = {}) {
|
|
152
|
+
const config = getConfig();
|
|
153
|
+
const state = {
|
|
154
|
+
mode: options.mode ?? config.defaultMode,
|
|
155
|
+
provider: options.provider ?? config.defaultProvider,
|
|
156
|
+
model: options.model ?? config.defaultModel,
|
|
157
|
+
messages: [],
|
|
158
|
+
};
|
|
159
|
+
if (options.provider) {
|
|
160
|
+
state.provider = assertProvider(options.provider);
|
|
161
|
+
}
|
|
162
|
+
const rl = readline.createInterface({ input, output });
|
|
163
|
+
// ── Startup banner ──────────────────────────────────────────────────────
|
|
164
|
+
console.log(renderBanner(getCurrentVersion()));
|
|
165
|
+
console.log(renderSessionInfo({
|
|
166
|
+
workdir: process.cwd(),
|
|
167
|
+
model: state.model,
|
|
168
|
+
provider: state.provider,
|
|
169
|
+
mode: state.mode,
|
|
170
|
+
}));
|
|
171
|
+
console.log(renderSuggestions());
|
|
172
|
+
console.log();
|
|
173
|
+
// Non-blocking update check
|
|
174
|
+
checkForUpdateSilent();
|
|
175
|
+
try {
|
|
176
|
+
while (true) {
|
|
177
|
+
const line = (await rl.question(PROMPT)).trim();
|
|
178
|
+
if (!line)
|
|
179
|
+
continue;
|
|
180
|
+
if (line.startsWith("/")) {
|
|
181
|
+
const shouldContinue = await handleSlash(line, state);
|
|
182
|
+
if (!shouldContinue)
|
|
183
|
+
break;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
const answer = state.mode === "ask"
|
|
188
|
+
? await runAskStream(line, (token) => process.stdout.write(token), {
|
|
189
|
+
provider: state.provider,
|
|
190
|
+
model: state.model,
|
|
191
|
+
history: state.messages,
|
|
192
|
+
})
|
|
193
|
+
: await runAgent(line, {
|
|
194
|
+
provider: state.provider,
|
|
195
|
+
model: state.model,
|
|
196
|
+
history: state.messages,
|
|
197
|
+
});
|
|
198
|
+
if (state.mode === "ask") {
|
|
199
|
+
process.stdout.write("\n");
|
|
200
|
+
}
|
|
201
|
+
console.log(); // breathing room between exchanges
|
|
202
|
+
state.messages.push({ role: "user", content: line }, { role: "assistant", content: answer });
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
if (state.messages.length > 0) {
|
|
211
|
+
await saveSession(state.messages, `repl-${new Date().toISOString()}`);
|
|
212
|
+
}
|
|
213
|
+
rl.close();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=repl.js.map
|
package/dist/repl.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repl.js","sourceRoot":"","sources":["../src/repl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RiskLevel, ToolCall } from "../types.js";
|
|
2
|
+
export interface RiskDecision {
|
|
3
|
+
level: RiskLevel;
|
|
4
|
+
reason: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function isPrivateIpv4(value: string): boolean;
|
|
7
|
+
export declare function isPentestToolCall(call: ToolCall): boolean;
|
|
8
|
+
export declare function classifyToolCall(call: ToolCall): RiskDecision;
|