@pentoshi/clai 0.13.0 → 1.0.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.
Files changed (77) hide show
  1. package/bin/clai.mjs +25 -0
  2. package/dist/agent/runner.d.ts +38 -1
  3. package/dist/agent/runner.js +472 -31
  4. package/dist/agent/runner.js.map +1 -1
  5. package/dist/commands/update.js +1 -1
  6. package/dist/commands/update.js.map +1 -1
  7. package/dist/llm/anthropic.js +31 -12
  8. package/dist/llm/anthropic.js.map +1 -1
  9. package/dist/llm/capabilities.d.ts +13 -0
  10. package/dist/llm/capabilities.js +107 -24
  11. package/dist/llm/capabilities.js.map +1 -1
  12. package/dist/llm/gemini.js +17 -4
  13. package/dist/llm/gemini.js.map +1 -1
  14. package/dist/llm/http.d.ts +12 -1
  15. package/dist/llm/http.js +50 -25
  16. package/dist/llm/http.js.map +1 -1
  17. package/dist/llm/ollama.js +16 -8
  18. package/dist/llm/ollama.js.map +1 -1
  19. package/dist/modes/agent.d.ts +2 -1
  20. package/dist/modes/agent.js.map +1 -1
  21. package/dist/modes/ask.d.ts +2 -1
  22. package/dist/modes/ask.js +5 -1
  23. package/dist/modes/ask.js.map +1 -1
  24. package/dist/os/cwd.d.ts +30 -0
  25. package/dist/os/cwd.js +76 -0
  26. package/dist/os/cwd.js.map +1 -0
  27. package/dist/os/detect.js +2 -1
  28. package/dist/os/detect.js.map +1 -1
  29. package/dist/prompts/index.d.ts +1 -1
  30. package/dist/prompts/index.js +66 -21
  31. package/dist/prompts/index.js.map +1 -1
  32. package/dist/repl.d.ts +10 -0
  33. package/dist/repl.js +260 -28
  34. package/dist/repl.js.map +1 -1
  35. package/dist/safety/classifier.js +121 -26
  36. package/dist/safety/classifier.js.map +1 -1
  37. package/dist/safety/patterns.d.ts +26 -0
  38. package/dist/safety/patterns.js +167 -0
  39. package/dist/safety/patterns.js.map +1 -1
  40. package/dist/store/config.js +2 -1
  41. package/dist/store/config.js.map +1 -1
  42. package/dist/store/history.js +19 -5
  43. package/dist/store/history.js.map +1 -1
  44. package/dist/store/plan.d.ts +43 -0
  45. package/dist/store/plan.js +201 -0
  46. package/dist/store/plan.js.map +1 -0
  47. package/dist/store/project.js +3 -2
  48. package/dist/store/project.js.map +1 -1
  49. package/dist/tools/capabilities.js +6 -1
  50. package/dist/tools/capabilities.js.map +1 -1
  51. package/dist/tools/fs.js +3 -2
  52. package/dist/tools/fs.js.map +1 -1
  53. package/dist/tools/image.d.ts +13 -0
  54. package/dist/tools/image.js +81 -0
  55. package/dist/tools/image.js.map +1 -0
  56. package/dist/tools/jobs.js +2 -1
  57. package/dist/tools/jobs.js.map +1 -1
  58. package/dist/tools/pdf.d.ts +18 -0
  59. package/dist/tools/pdf.js +200 -0
  60. package/dist/tools/pdf.js.map +1 -0
  61. package/dist/tools/registry.js +79 -7
  62. package/dist/tools/registry.js.map +1 -1
  63. package/dist/tools/shell.js +3 -2
  64. package/dist/tools/shell.js.map +1 -1
  65. package/dist/types.d.ts +16 -0
  66. package/dist/ui/keys.d.ts +1 -0
  67. package/dist/ui/keys.js +4 -0
  68. package/dist/ui/keys.js.map +1 -1
  69. package/dist/ui/mentions.d.ts +32 -1
  70. package/dist/ui/mentions.js +304 -27
  71. package/dist/ui/mentions.js.map +1 -1
  72. package/dist/ui/output-pane.js +11 -2
  73. package/dist/ui/output-pane.js.map +1 -1
  74. package/dist/ui/plan-pane.d.ts +19 -0
  75. package/dist/ui/plan-pane.js +101 -0
  76. package/dist/ui/plan-pane.js.map +1 -0
  77. package/package.json +4 -1
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');
@@ -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,29 @@ 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;
33
63
  /**
34
64
  * Decide whether this turn should get a generous step budget because it is
35
65
  * a multi-file build, a continuation of one, or a "it's not done yet" nudge.
@@ -38,5 +68,12 @@ export declare function parseToolCall(text: string, options?: ParseToolCallOptio
38
68
  */
39
69
  export declare function looksLikeBuildTask(prompt: string, history?: ChatMessage[] | undefined): boolean;
40
70
  export declare function requiresFreshWebSearch(prompt: string): boolean;
71
+ /**
72
+ * Detect a low-quality "everything in one step" plan task. A single task that
73
+ * itself enumerates many files/actions (multiple commas, an "and", several
74
+ * slashes, or an overlong title) means the model lumped the whole build into
75
+ * one checkbox instead of producing a real ordered checklist.
76
+ */
77
+ export declare function isLumpedSingleTask(taskTitles: string[]): boolean;
41
78
  export declare function shouldDimToolChatter(call: ToolCall): boolean;
42
79
  export declare function runAgentLoop(prompt: string, options?: AgentRunOptions): Promise<string>;