@pentoshi/clai 1.2.5 → 1.2.7

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 (71) hide show
  1. package/dist/agent/classic-renderer.d.ts +5 -0
  2. package/dist/agent/classic-renderer.js +124 -0
  3. package/dist/agent/classic-renderer.js.map +1 -0
  4. package/dist/agent/events.d.ts +62 -0
  5. package/dist/agent/events.js +2 -0
  6. package/dist/agent/events.js.map +1 -0
  7. package/dist/agent/runner.d.ts +12 -4
  8. package/dist/agent/runner.js +236 -83
  9. package/dist/agent/runner.js.map +1 -1
  10. package/dist/commands/update.js +1 -1
  11. package/dist/index.js +32 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/llm/capabilities.js +1 -0
  14. package/dist/llm/capabilities.js.map +1 -1
  15. package/dist/llm/http.js +19 -11
  16. package/dist/llm/http.js.map +1 -1
  17. package/dist/llm/openai.js +10 -1
  18. package/dist/llm/openai.js.map +1 -1
  19. package/dist/modes/agent.d.ts +4 -1
  20. package/dist/modes/agent.js.map +1 -1
  21. package/dist/prompts/index.d.ts +1 -1
  22. package/dist/prompts/index.js +1 -1
  23. package/dist/repl.js +57 -15
  24. package/dist/repl.js.map +1 -1
  25. package/dist/tui/App.d.ts +8 -0
  26. package/dist/tui/App.js +273 -0
  27. package/dist/tui/App.js.map +1 -0
  28. package/dist/tui/can-use-tui.d.ts +20 -0
  29. package/dist/tui/can-use-tui.js +28 -0
  30. package/dist/tui/can-use-tui.js.map +1 -0
  31. package/dist/tui/components/Composer.d.ts +6 -0
  32. package/dist/tui/components/Composer.js +122 -0
  33. package/dist/tui/components/Composer.js.map +1 -0
  34. package/dist/tui/components/ConfirmModal.d.ts +6 -0
  35. package/dist/tui/components/ConfirmModal.js +16 -0
  36. package/dist/tui/components/ConfirmModal.js.map +1 -0
  37. package/dist/tui/components/Header.d.ts +7 -0
  38. package/dist/tui/components/Header.js +6 -0
  39. package/dist/tui/components/Header.js.map +1 -0
  40. package/dist/tui/components/JobsPanel.d.ts +11 -0
  41. package/dist/tui/components/JobsPanel.js +55 -0
  42. package/dist/tui/components/JobsPanel.js.map +1 -0
  43. package/dist/tui/components/Pager.d.ts +13 -0
  44. package/dist/tui/components/Pager.js +46 -0
  45. package/dist/tui/components/Pager.js.map +1 -0
  46. package/dist/tui/components/StatusLine.d.ts +7 -0
  47. package/dist/tui/components/StatusLine.js +25 -0
  48. package/dist/tui/components/StatusLine.js.map +1 -0
  49. package/dist/tui/components/items.d.ts +5 -0
  50. package/dist/tui/components/items.js +57 -0
  51. package/dist/tui/components/items.js.map +1 -0
  52. package/dist/tui/confirm.d.ts +16 -0
  53. package/dist/tui/confirm.js +41 -0
  54. package/dist/tui/confirm.js.map +1 -0
  55. package/dist/tui/hooks/useAgentRunner.d.ts +36 -0
  56. package/dist/tui/hooks/useAgentRunner.js +90 -0
  57. package/dist/tui/hooks/useAgentRunner.js.map +1 -0
  58. package/dist/tui/hooks/useJobs.d.ts +7 -0
  59. package/dist/tui/hooks/useJobs.js +39 -0
  60. package/dist/tui/hooks/useJobs.js.map +1 -0
  61. package/dist/tui/hooks/useSpinner.d.ts +5 -0
  62. package/dist/tui/hooks/useSpinner.js +19 -0
  63. package/dist/tui/hooks/useSpinner.js.map +1 -0
  64. package/dist/tui/index.d.ts +8 -0
  65. package/dist/tui/index.js +22 -0
  66. package/dist/tui/index.js.map +1 -0
  67. package/dist/tui/state.d.ts +101 -0
  68. package/dist/tui/state.js +323 -0
  69. package/dist/tui/state.js.map +1 -0
  70. package/dist/types.d.ts +1 -1
  71. package/package.json +5 -2
@@ -0,0 +1,5 @@
1
+ import type { AgentEvent } from "./events.js";
2
+ export interface ClassicRenderer {
3
+ onEvent: (event: AgentEvent) => void;
4
+ }
5
+ export declare function attachClassicRenderer(write?: (chunk: string) => void): ClassicRenderer;
@@ -0,0 +1,124 @@
1
+ import chalk from "chalk";
2
+ import { styleToolChatter } from "./runner.js";
3
+ import { indentAndWrapText, renderMarkdown } from "../ui/markdown.js";
4
+ import { renderPlanChecklist } from "../ui/plan-pane.js";
5
+ import { startThinkingSpinner } from "../ui/spinner.js";
6
+ import { renderThinkingSummary } from "../ui/thinking.js";
7
+ export function attachClassicRenderer(write = (chunk) => {
8
+ process.stdout.write(chunk);
9
+ }) {
10
+ const toolCalls = new Map();
11
+ let spinner;
12
+ const callFor = (id) => toolCalls.get(id) ?? { name: "tool", args: {} };
13
+ const stopSpinner = () => {
14
+ spinner?.stop();
15
+ spinner = undefined;
16
+ };
17
+ const setSpinnerLabel = (label) => {
18
+ if (!spinner) {
19
+ spinner = startThinkingSpinner(label);
20
+ }
21
+ else {
22
+ spinner.setLabel(label);
23
+ }
24
+ };
25
+ const onEvent = (event) => {
26
+ switch (event.type) {
27
+ case "turn-start":
28
+ case "assistant-delta":
29
+ case "confirm-request":
30
+ return;
31
+ case "thinking-delta":
32
+ setSpinnerLabel("thinking");
33
+ spinner?.pushPreview(event.text);
34
+ return;
35
+ case "status":
36
+ if (event.text === "waiting for model" ||
37
+ event.text === "thinking" ||
38
+ /^step \d+$/.test(event.text)) {
39
+ setSpinnerLabel(event.text);
40
+ return;
41
+ }
42
+ stopSpinner();
43
+ write(chalk.dim(event.text));
44
+ return;
45
+ case "notice": {
46
+ stopSpinner();
47
+ const prefix = event.level === "warn" ? " ⚠ " : " ℹ ";
48
+ const color = event.level === "warn" ? chalk.yellow : chalk.dim;
49
+ write(color(`${prefix}${event.text}\n`));
50
+ return;
51
+ }
52
+ case "thinking-block":
53
+ stopSpinner();
54
+ write(`${renderThinkingSummary(event.content)}\n`);
55
+ return;
56
+ case "assistant-message": {
57
+ stopSpinner();
58
+ write(renderMarkdown(event.text));
59
+ if (!event.text.endsWith("\n"))
60
+ write("\n");
61
+ return;
62
+ }
63
+ case "tool-call": {
64
+ stopSpinner();
65
+ const call = { name: event.name, args: {} };
66
+ toolCalls.set(event.id, call);
67
+ const line = chalk.cyan(` ▶ ${event.name}`) + chalk.gray(` ${event.argsDisplay}`);
68
+ write(styleToolChatter(call, line) + "\n");
69
+ return;
70
+ }
71
+ case "tool-output": {
72
+ stopSpinner();
73
+ if (!event.chunk)
74
+ return;
75
+ if (event.chunk === "ok\n") {
76
+ write(chalk.green(" ✓") + "\n");
77
+ return;
78
+ }
79
+ if (event.chunk === "failed\n") {
80
+ write(chalk.red(" ✗") + "\n");
81
+ return;
82
+ }
83
+ const call = callFor(event.id);
84
+ const body = event.chunk.startsWith("\n")
85
+ ? event.chunk
86
+ : indentAndWrapText(event.chunk);
87
+ write(styleToolChatter(call, body.endsWith("\n") ? body : `${body}\n`));
88
+ return;
89
+ }
90
+ case "tool-result":
91
+ return;
92
+ case "tool-blocked":
93
+ stopSpinner();
94
+ write(chalk.red(` ✗ blocked: ${event.reason}`) + "\n");
95
+ return;
96
+ case "plan-update":
97
+ stopSpinner();
98
+ if (event.plan.status === "draft") {
99
+ write(chalk.cyan(" ● planning\n") +
100
+ renderPlanChecklist(event.plan) +
101
+ "\n" +
102
+ chalk.dim(" ✦ plan created — press Ctrl+P to view it, /implement to approve and run it,\n" +
103
+ " or /discard to cancel it. Any other message refines this plan.\n"));
104
+ }
105
+ else {
106
+ write(renderPlanChecklist(event.plan) + "\n");
107
+ }
108
+ return;
109
+ case "turn-end":
110
+ stopSpinner();
111
+ return;
112
+ case "turn-aborted":
113
+ stopSpinner();
114
+ write(chalk.yellow(" ⏹ Aborted.\n"));
115
+ return;
116
+ case "turn-error":
117
+ stopSpinner();
118
+ write(chalk.red(` ✗ ${event.message}\n`));
119
+ return;
120
+ }
121
+ };
122
+ return { onEvent };
123
+ }
124
+ //# sourceMappingURL=classic-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classic-renderer.js","sourceRoot":"","sources":["../../src/agent/classic-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAwB,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAM1D,MAAM,UAAU,qBAAqB,CACnC,QAAiC,CAAC,KAAK,EAAE,EAAE;IACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC9C,IAAI,OAAoC,CAAC;IAEzC,MAAM,OAAO,GAAG,CAAC,EAAU,EAAY,EAAE,CACvC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IAElD,MAAM,WAAW,GAAG,GAAS,EAAE;QAC7B,OAAO,EAAE,IAAI,EAAE,CAAC;QAChB,OAAO,GAAG,SAAS,CAAC;IACtB,CAAC,CAAC;IAEF,MAAM,eAAe,GAAG,CAAC,KAAa,EAAQ,EAAE;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,KAAiB,EAAQ,EAAE;QAC1C,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,YAAY,CAAC;YAClB,KAAK,iBAAiB,CAAC;YACvB,KAAK,iBAAiB;gBACpB,OAAO;YACT,KAAK,gBAAgB;gBACnB,eAAe,CAAC,UAAU,CAAC,CAAC;gBAC5B,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjC,OAAO;YACT,KAAK,QAAQ;gBACX,IACE,KAAK,CAAC,IAAI,KAAK,mBAAmB;oBAClC,KAAK,CAAC,IAAI,KAAK,UAAU;oBACzB,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAC7B,CAAC;oBACD,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC5B,OAAO;gBACT,CAAC;gBACD,WAAW,EAAE,CAAC;gBACd,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC7B,OAAO;YACT,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,WAAW,EAAE,CAAC;gBACd,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;gBACxD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;gBAChE,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;gBACzC,OAAO;YACT,CAAC;YACD,KAAK,gBAAgB;gBACnB,WAAW,EAAE,CAAC;gBACd,KAAK,CAAC,GAAG,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACnD,OAAO;YACT,KAAK,mBAAmB,CAAC,CAAC,CAAC;gBACzB,WAAW,EAAE,CAAC;gBACd,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBAClC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC5C,OAAO;YACT,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,WAAW,EAAE,CAAC;gBACd,MAAM,IAAI,GAAa,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;gBACtD,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBAC9B,MAAM,IAAI,GACR,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;gBACxE,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;gBAC3C,OAAO;YACT,CAAC;YACD,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,WAAW,EAAE,CAAC;gBACd,IAAI,CAAC,KAAK,CAAC,KAAK;oBAAE,OAAO;gBACzB,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;oBAC3B,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;oBACjC,OAAO;gBACT,CAAC;gBACD,IAAI,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;oBAC/B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;oBAC/B,OAAO;gBACT,CAAC;gBACD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;oBACvC,CAAC,CAAC,KAAK,CAAC,KAAK;oBACb,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACnC,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC;gBACxE,OAAO;YACT,CAAC;YACD,KAAK,aAAa;gBAChB,OAAO;YACT,KAAK,cAAc;gBACjB,WAAW,EAAE,CAAC;gBACd,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;gBACxD,OAAO;YACT,KAAK,aAAa;gBAChB,WAAW,EAAE,CAAC;gBACd,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;oBAClC,KAAK,CACH,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC;wBAC1B,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC;wBAC/B,IAAI;wBACJ,KAAK,CAAC,GAAG,CACP,iFAAiF;4BAC/E,sEAAsE,CACzE,CACJ,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;gBAChD,CAAC;gBACD,OAAO;YACT,KAAK,UAAU;gBACb,WAAW,EAAE,CAAC;gBACd,OAAO;YACT,KAAK,cAAc;gBACjB,WAAW,EAAE,CAAC;gBACd,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBACtC,OAAO;YACT,KAAK,YAAY;gBACf,WAAW,EAAE,CAAC;gBACd,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;gBAC3C,OAAO;QACX,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}
@@ -0,0 +1,62 @@
1
+ import type { SessionPlan } from "../store/plan.js";
2
+ export type AgentEvent = {
3
+ type: "turn-start";
4
+ prompt: string;
5
+ } | {
6
+ type: "status";
7
+ text: string;
8
+ } | {
9
+ type: "thinking-delta";
10
+ text: string;
11
+ } | {
12
+ type: "thinking-block";
13
+ content: string;
14
+ } | {
15
+ type: "assistant-delta";
16
+ text: string;
17
+ } | {
18
+ type: "assistant-message";
19
+ text: string;
20
+ } | {
21
+ type: "notice";
22
+ level: "info" | "warn";
23
+ text: string;
24
+ } | {
25
+ type: "tool-call";
26
+ id: string;
27
+ name: string;
28
+ argsDisplay: string;
29
+ } | {
30
+ type: "tool-output";
31
+ id: string;
32
+ chunk: string;
33
+ } | {
34
+ type: "tool-result";
35
+ id: string;
36
+ ok: boolean;
37
+ exitCode?: number;
38
+ summary: string;
39
+ artifactPath?: string;
40
+ } | {
41
+ type: "tool-blocked";
42
+ id: string;
43
+ name: string;
44
+ reason: string;
45
+ } | {
46
+ type: "plan-update";
47
+ plan: SessionPlan;
48
+ } | {
49
+ type: "confirm-request";
50
+ id: string;
51
+ kind: "tool" | "pentest";
52
+ prompt: string;
53
+ } | {
54
+ type: "turn-end";
55
+ finalAnswer: string;
56
+ steps: number;
57
+ } | {
58
+ type: "turn-aborted";
59
+ } | {
60
+ type: "turn-error";
61
+ message: string;
62
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/agent/events.ts"],"names":[],"mappings":""}
@@ -1,4 +1,5 @@
1
1
  import type { ChatMessage, ChatImage, ProviderId, ToolCall, ToolResult } from "../types.js";
2
+ import type { AgentEvent } from "./events.js";
2
3
  export interface SessionPolicy {
3
4
  /** Tools the user authorized once during this REPL session. Not persisted. */
4
5
  allow: Set<string>;
@@ -14,6 +15,10 @@ export interface SessionPolicy {
14
15
  };
15
16
  }
16
17
  export declare function createSessionPolicy(): SessionPolicy;
18
+ export interface ConfirmPort {
19
+ confirmTool(call: ToolCall): Promise<boolean>;
20
+ confirmPentest(): Promise<boolean>;
21
+ }
17
22
  export interface AgentRunOptions {
18
23
  provider?: ProviderId | undefined;
19
24
  model?: string | undefined;
@@ -24,6 +29,8 @@ export interface AgentRunOptions {
24
29
  images?: ChatImage[] | undefined;
25
30
  onToolStart?: ((call: ToolCall) => void) | undefined;
26
31
  onToolResult?: ((call: ToolCall, result: ToolResult) => void) | undefined;
32
+ onEvent?: ((event: AgentEvent) => void) | undefined;
33
+ confirm?: ConfirmPort | undefined;
27
34
  session?: SessionPolicy | undefined;
28
35
  }
29
36
  export interface ParseToolCallOptions {
@@ -106,10 +113,10 @@ export declare function sameToolCall(a: ToolCall, b: ToolCall): boolean;
106
113
  */
107
114
  export declare function collapseRepeatedText(text: string): string;
108
115
  /**
109
- * Decide whether this turn should get a generous step budget because it is
110
- * a multi-file build, a continuation of one, or a "it's not done yet" nudge.
111
- * Looks at the current prompt first, then falls back to the most recent
112
- * user/assistant turns so a terse follow-up inherits the build context.
116
+ * Decide whether this turn should get the build workflow (explore plan
117
+ * implement) and a generous step budget. Looks at the current prompt first,
118
+ * then falls back to recent USER turns so a terse follow-up inherits an
119
+ * ongoing build but NOT the agent's own (possibly mistaken) plan narration.
113
120
  */
114
121
  export declare function looksLikeBuildTask(prompt: string, history?: ChatMessage[] | undefined): boolean;
115
122
  /**
@@ -137,4 +144,5 @@ export declare function requiresFreshWebSearch(prompt: string): boolean;
137
144
  export declare function isLumpedSingleTask(taskTitles: string[]): boolean;
138
145
  export declare function shouldDimToolChatter(call: ToolCall): boolean;
139
146
  export declare function isPreApprovalAllowedTool(name: string): boolean;
147
+ export declare function styleToolChatter(call: ToolCall, text: string): string;
140
148
  export declare function runAgentLoop(prompt: string, options?: AgentRunOptions): Promise<string>;