@pentoshi/clai 0.12.0 → 1.0.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/bin/clai.mjs +25 -0
- package/dist/agent/loop-guard.js +10 -2
- package/dist/agent/loop-guard.js.map +1 -1
- package/dist/agent/runner.d.ts +38 -1
- package/dist/agent/runner.js +516 -36
- package/dist/agent/runner.js.map +1 -1
- package/dist/commands/update.js +1 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/llm/anthropic.js +31 -12
- package/dist/llm/anthropic.js.map +1 -1
- package/dist/llm/capabilities.d.ts +13 -0
- package/dist/llm/capabilities.js +107 -24
- package/dist/llm/capabilities.js.map +1 -1
- package/dist/llm/gemini.js +17 -4
- package/dist/llm/gemini.js.map +1 -1
- package/dist/llm/http.d.ts +12 -1
- package/dist/llm/http.js +50 -25
- package/dist/llm/http.js.map +1 -1
- package/dist/llm/ollama.js +16 -8
- package/dist/llm/ollama.js.map +1 -1
- package/dist/modes/agent.d.ts +2 -1
- package/dist/modes/agent.js.map +1 -1
- package/dist/modes/ask.d.ts +2 -1
- package/dist/modes/ask.js +5 -1
- package/dist/modes/ask.js.map +1 -1
- package/dist/os/cwd.d.ts +30 -0
- package/dist/os/cwd.js +76 -0
- package/dist/os/cwd.js.map +1 -0
- package/dist/os/detect.js +2 -1
- package/dist/os/detect.js.map +1 -1
- package/dist/prompts/index.d.ts +1 -1
- package/dist/prompts/index.js +95 -22
- package/dist/prompts/index.js.map +1 -1
- package/dist/repl.d.ts +10 -0
- package/dist/repl.js +258 -28
- package/dist/repl.js.map +1 -1
- package/dist/safety/classifier.js +147 -26
- package/dist/safety/classifier.js.map +1 -1
- package/dist/safety/patterns.d.ts +26 -0
- package/dist/safety/patterns.js +167 -0
- package/dist/safety/patterns.js.map +1 -1
- package/dist/store/config.js +2 -1
- package/dist/store/config.js.map +1 -1
- package/dist/store/history.js +19 -5
- package/dist/store/history.js.map +1 -1
- package/dist/store/plan.d.ts +43 -0
- package/dist/store/plan.js +201 -0
- package/dist/store/plan.js.map +1 -0
- package/dist/store/project.js +3 -2
- package/dist/store/project.js.map +1 -1
- package/dist/tools/capabilities.js +6 -1
- package/dist/tools/capabilities.js.map +1 -1
- package/dist/tools/fs.d.ts +15 -0
- package/dist/tools/fs.js +69 -3
- package/dist/tools/fs.js.map +1 -1
- package/dist/tools/image.d.ts +13 -0
- package/dist/tools/image.js +81 -0
- package/dist/tools/image.js.map +1 -0
- package/dist/tools/jobs.js +2 -1
- package/dist/tools/jobs.js.map +1 -1
- package/dist/tools/pdf.d.ts +18 -0
- package/dist/tools/pdf.js +200 -0
- package/dist/tools/pdf.js.map +1 -0
- package/dist/tools/registry.js +87 -7
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/shell.js +3 -2
- package/dist/tools/shell.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/ui/keys.d.ts +1 -0
- package/dist/ui/keys.js +4 -0
- package/dist/ui/keys.js.map +1 -1
- package/dist/ui/mentions.d.ts +32 -1
- package/dist/ui/mentions.js +304 -27
- package/dist/ui/mentions.js.map +1 -1
- package/dist/ui/plan-pane.d.ts +19 -0
- package/dist/ui/plan-pane.js +101 -0
- package/dist/ui/plan-pane.js.map +1 -0
- package/package.json +6 -5
package/bin/clai.mjs
CHANGED
|
@@ -1,2 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// Guard against a deleted / inaccessible working directory BEFORE importing
|
|
3
|
+
// anything from dist. If clai was launched (or elevated via `sudo`) from a
|
|
4
|
+
// folder that no longer exists, process.cwd() throws ENOENT (uv_cwd) and the
|
|
5
|
+
// whole CLI used to crash at module-load. Relocate to a directory that
|
|
6
|
+
// definitely exists so startup — and every later spawn — works.
|
|
7
|
+
try {
|
|
8
|
+
process.cwd();
|
|
9
|
+
} catch {
|
|
10
|
+
const candidates = [
|
|
11
|
+
process.env.HOME,
|
|
12
|
+
process.env.USERPROFILE,
|
|
13
|
+
process.env.TMPDIR,
|
|
14
|
+
"/tmp",
|
|
15
|
+
"/",
|
|
16
|
+
].filter(Boolean);
|
|
17
|
+
for (const dir of candidates) {
|
|
18
|
+
try {
|
|
19
|
+
process.chdir(dir);
|
|
20
|
+
break;
|
|
21
|
+
} catch {
|
|
22
|
+
// try the next candidate
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
2
27
|
await import('../dist/index.js');
|
package/dist/agent/loop-guard.js
CHANGED
|
@@ -56,16 +56,24 @@ export class LoopGuard {
|
|
|
56
56
|
// Prior attempts all failed → allow the retry, no warning.
|
|
57
57
|
if (this.signatureSuccess.get(sig) === false)
|
|
58
58
|
return { block: false };
|
|
59
|
+
// Mutating file tools deserve tool-appropriate wording. Telling a model
|
|
60
|
+
// that just wrote a file to "use the results you already have" is
|
|
61
|
+
// nonsensical and has caused models to assume the whole task is done.
|
|
62
|
+
const isWrite = name === "fs.write" || name === "fs.writeMany" || name === "fs.edit";
|
|
59
63
|
if (count === 1) {
|
|
60
64
|
return {
|
|
61
65
|
block: false,
|
|
62
|
-
reason:
|
|
66
|
+
reason: isWrite
|
|
67
|
+
? `${name} already wrote this exact path/content once. If that file is finished, move on to the NEXT file or step — do NOT rewrite it.`
|
|
68
|
+
: `${name} has already been called with these arguments once and succeeded. Consider using the results you already have.`,
|
|
63
69
|
};
|
|
64
70
|
}
|
|
65
71
|
// count >= 2 and at least one success: block
|
|
66
72
|
return {
|
|
67
73
|
block: true,
|
|
68
|
-
reason:
|
|
74
|
+
reason: isWrite
|
|
75
|
+
? `${name} was already called ${count} time(s) with the identical path and content. That file is already written. Continue with the remaining files/steps or give your final answer.`
|
|
76
|
+
: `${name} was already called ${count} time(s) with the same arguments. Summarize existing results instead.`,
|
|
69
77
|
};
|
|
70
78
|
}
|
|
71
79
|
getAttemptCount(name, args) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop-guard.js","sourceRoot":"","sources":["../../src/agent/loop-guard.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,MAAM,OAAO,SAAS;IACZ,QAAQ,GAAkB,EAAE,CAAC;IAC7B,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,gBAAgB,GAAG,IAAI,GAAG,EAAmB,CAAC;IAEtD;;;;OAIG;IACH,YAAY,CAAC,IAAY,EAAE,IAA6B;QACtD,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3C,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACtB,8CAA8C;YAC9C,IAAI,IAAI,KAAK,YAAY,IAAI,GAAG,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC5E,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC5C,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;QACD,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IAC9C,CAAC;IAED,aAAa,CACX,IAAY,EACZ,IAAY,EACZ,IAA6B,EAC7B,EAAW,EACX,QAA6B;QAE7B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,kBAAkB,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpF,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,wEAAwE;QACxE,yEAAyE;QACzE,qEAAqE;QACrE,kBAAkB;QAClB,IAAI,EAAE;YAAE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;aACxC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;;;;;OAWG;IACH,WAAW,CACT,IAAY,EACZ,IAA6B;QAE7B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEhD,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAEzC,2DAA2D;QAC3D,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK;YAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAEtE,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,GAAG,IAAI,gHAAgH;
|
|
1
|
+
{"version":3,"file":"loop-guard.js","sourceRoot":"","sources":["../../src/agent/loop-guard.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,MAAM,OAAO,SAAS;IACZ,QAAQ,GAAkB,EAAE,CAAC;IAC7B,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,gBAAgB,GAAG,IAAI,GAAG,EAAmB,CAAC;IAEtD;;;;OAIG;IACH,YAAY,CAAC,IAAY,EAAE,IAA6B;QACtD,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3C,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACtB,8CAA8C;YAC9C,IAAI,IAAI,KAAK,YAAY,IAAI,GAAG,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC5E,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC5C,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;QACD,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IAC9C,CAAC;IAED,aAAa,CACX,IAAY,EACZ,IAAY,EACZ,IAA6B,EAC7B,EAAW,EACX,QAA6B;QAE7B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,kBAAkB,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpF,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,wEAAwE;QACxE,yEAAyE;QACzE,qEAAqE;QACrE,kBAAkB;QAClB,IAAI,EAAE;YAAE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;aACxC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;;;;;OAWG;IACH,WAAW,CACT,IAAY,EACZ,IAA6B;QAE7B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEhD,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAEzC,2DAA2D;QAC3D,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK;YAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAEtE,wEAAwE;QACxE,kEAAkE;QAClE,sEAAsE;QACtE,MAAM,OAAO,GACX,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,SAAS,CAAC;QAEvE,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,OAAO;oBACb,CAAC,CAAC,GAAG,IAAI,8HAA8H;oBACvI,CAAC,CAAC,GAAG,IAAI,gHAAgH;aAC5H,CAAC;QACJ,CAAC;QAED,6CAA6C;QAC7C,OAAO;YACL,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,OAAO;gBACb,CAAC,CAAC,GAAG,IAAI,uBAAuB,KAAK,gJAAgJ;gBACrL,CAAC,CAAC,GAAG,IAAI,uBAAuB,KAAK,uEAAuE;SAC/G,CAAC;IACJ,CAAC;IAED,eAAe,CAAC,IAAY,EAAE,IAA6B;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED;;;OAGG;IACH,mBAAmB,CAAC,SAAS,GAAG,CAAC;QAC/B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,SAAS;YAAE,OAAO,KAAK,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/C,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC9B,CAAC;CACF"}
|
package/dist/agent/runner.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChatMessage, ProviderId, ToolCall, ToolResult } from "../types.js";
|
|
1
|
+
import type { ChatMessage, ChatImage, ProviderId, ToolCall, ToolResult } from "../types.js";
|
|
2
2
|
export interface SessionPolicy {
|
|
3
3
|
/** Tools the user authorized once during this REPL session. Not persisted. */
|
|
4
4
|
allow: Set<string>;
|
|
@@ -6,6 +6,12 @@ export interface SessionPolicy {
|
|
|
6
6
|
pentestAuthorized: {
|
|
7
7
|
value: boolean;
|
|
8
8
|
};
|
|
9
|
+
/** Stable id used to scope the session's plan/tasks in the plan store. */
|
|
10
|
+
sessionId: string;
|
|
11
|
+
/** When true, the agent must follow its approved plan (set by /implement). */
|
|
12
|
+
planApproved: {
|
|
13
|
+
value: boolean;
|
|
14
|
+
};
|
|
9
15
|
}
|
|
10
16
|
export declare function createSessionPolicy(): SessionPolicy;
|
|
11
17
|
export interface AgentRunOptions {
|
|
@@ -15,6 +21,7 @@ export interface AgentRunOptions {
|
|
|
15
21
|
autoConfirm?: boolean | undefined;
|
|
16
22
|
maxSteps?: number | undefined;
|
|
17
23
|
signal?: AbortSignal | undefined;
|
|
24
|
+
images?: ChatImage[] | undefined;
|
|
18
25
|
onToolStart?: ((call: ToolCall) => void) | undefined;
|
|
19
26
|
onToolResult?: ((call: ToolCall, result: ToolResult) => void) | undefined;
|
|
20
27
|
session?: SessionPolicy | undefined;
|
|
@@ -30,6 +37,36 @@ export interface ParseToolCallOptions {
|
|
|
30
37
|
strict?: boolean | undefined;
|
|
31
38
|
}
|
|
32
39
|
export declare function parseToolCall(text: string, options?: ParseToolCallOptions): ToolCall | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* When a model means to call a tool but emits ONLY a bare JSON object —
|
|
42
|
+
* either a proper {"name","args"} that the strict matchers missed, or a bare
|
|
43
|
+
* args object like {"path":"file.pdf"} with the wrapper/fence dropped — this
|
|
44
|
+
* recognizes it. Returns:
|
|
45
|
+
* - { call } when the object is a complete {name, args} tool call, or
|
|
46
|
+
* - { argsOnly: true } when it looks like a bare args object (so the caller
|
|
47
|
+
* can nudge the model to re-emit a properly named, fenced tool call).
|
|
48
|
+
* Returns undefined for anything that is plainly a normal prose/JSON answer.
|
|
49
|
+
*/
|
|
50
|
+
export declare function recognizeBareToolJson(text: string): {
|
|
51
|
+
call?: ToolCall;
|
|
52
|
+
argsOnly?: boolean;
|
|
53
|
+
} | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Detect an opened-but-unparseable tool call. This happens when the model's
|
|
56
|
+
* output is truncated by the token limit mid-JSON: we see the ```tool fence
|
|
57
|
+
* (or a bare {"name":"...","args" prefix) open, but parseToolCall returns
|
|
58
|
+
* undefined because the JSON never closed. Without this, the broken block
|
|
59
|
+
* leaks to the screen as a "final answer" and the requested action (e.g. a
|
|
60
|
+
* multi-file fs.writeMany scaffold) silently never runs.
|
|
61
|
+
*/
|
|
62
|
+
export declare function looksLikeTruncatedToolCall(text: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Decide whether this turn should get a generous step budget because it is
|
|
65
|
+
* a multi-file build, a continuation of one, or a "it's not done yet" nudge.
|
|
66
|
+
* Looks at the current prompt first, then falls back to the most recent
|
|
67
|
+
* user/assistant turns so a terse follow-up inherits the build context.
|
|
68
|
+
*/
|
|
69
|
+
export declare function looksLikeBuildTask(prompt: string, history?: ChatMessage[] | undefined): boolean;
|
|
33
70
|
export declare function requiresFreshWebSearch(prompt: string): boolean;
|
|
34
71
|
export declare function shouldDimToolChatter(call: ToolCall): boolean;
|
|
35
72
|
export declare function runAgentLoop(prompt: string, options?: AgentRunOptions): Promise<string>;
|