@sofer_agent/cli 0.3.15 → 0.3.17

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/sofer ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+ import "@opentui/solid/preload";
3
+ import "../src/bin.ts";
package/dist/bin.js CHANGED
File without changes
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"AAsCA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAsCjD"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"AAsCA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAwCjD"}
package/dist/chat.js CHANGED
@@ -2,7 +2,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { dirname } from "node:path";
3
3
  import { agentPaths, loadConfig, shortAgentId, SoferAgent, } from "@sofer_agent/core";
4
4
  import { loadSecrets } from "./env.js";
5
- import { SoferTui } from "./tui.js";
5
+ import { createTuiState, runTui } from "./tui.jsx";
6
6
  function sessionPath(config) {
7
7
  if (config.agentObjectId)
8
8
  return agentPaths.agent(shortAgentId(config.agentObjectId)).activityLog;
@@ -45,26 +45,39 @@ export async function chatCommand() {
45
45
  if (history.length > 0)
46
46
  agent.loadHistory(history);
47
47
  }
48
- const tui = new SoferTui(agent, config);
49
- agent.getBalance().then((bal) => tui.setInfo({ balance: (Number(bal) / 1e9).toFixed(4) })).catch(() => { });
50
- await tui.run(async (line, signal) => {
48
+ const tuiState = createTuiState();
49
+ const [, setRows] = tuiState.rows;
50
+ const [, setInfo] = tuiState.info;
51
+ agent.getBalance().then((bal) => setInfo((prev) => ({ ...prev, balance: (Number(bal) / 1e9).toFixed(4) }))).catch(() => { });
52
+ await runTui(tuiState, agent, config, async (line, signal) => {
51
53
  try {
52
54
  const { text, turnUsage } = await agent.chat(line, signal);
53
- tui.addMessage("agent", text);
54
- tui.setInfo({ lastTurnIn: turnUsage.inputTokens, lastTurnOut: turnUsage.outputTokens });
55
+ setRows((prev) => [...prev, { role: "agent", text }]);
56
+ setInfo((prev) => ({ ...prev, lastTurnIn: turnUsage.inputTokens, lastTurnOut: turnUsage.outputTokens }));
55
57
  }
56
58
  catch (e) {
57
- if (signal?.aborted) {
58
- tui.addMessage("system", "turn interrupted (esc).");
59
+ if (signal.aborted) {
60
+ setRows((prev) => [...prev, { role: "system", text: "turn interrupted." }]);
59
61
  }
60
62
  else {
61
- tui.addMessage("error", e instanceof Error ? e.message : String(e));
63
+ const raw = e instanceof Error ? e.message : String(e);
64
+ setRows((prev) => [...prev, { role: "error", text: cleanError(raw) }]);
62
65
  }
63
66
  }
64
- agent.getBalance().then((bal) => tui.setInfo({ balance: (Number(bal) / 1e9).toFixed(4) })).catch(() => { });
67
+ agent.getBalance().then((bal) => setInfo((prev) => ({ ...prev, balance: (Number(bal) / 1e9).toFixed(4) }))).catch(() => { });
65
68
  if (sp)
66
69
  saveSession(sp, agent.getHistory());
67
- tui.render();
68
70
  });
69
71
  }
72
+ function cleanError(raw) {
73
+ try {
74
+ const obj = JSON.parse(raw);
75
+ if (obj?.error?.type === "overloaded_error")
76
+ return "Claude is overloaded — try again in a moment.";
77
+ if (obj?.error?.message)
78
+ return obj.error.message;
79
+ }
80
+ catch { /* not JSON */ }
81
+ return raw;
82
+ }
70
83
  //# sourceMappingURL=chat.js.map
package/dist/chat.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"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"}
package/dist/tui.d.ts CHANGED
@@ -1,4 +1,14 @@
1
1
  import type { SoferAgent, SoferConfig } from "@sofer_agent/core";
2
+ import { createSignal } from "solid-js";
3
+ export interface TuiState {
4
+ rows: ReturnType<typeof createSignal<ChatLine[]>>;
5
+ status: ReturnType<typeof createSignal<"idle" | "thinking">>;
6
+ input: ReturnType<typeof createSignal<string>>;
7
+ info: ReturnType<typeof createSignal<TuiInfo>>;
8
+ spinnerFrame: ReturnType<typeof createSignal<number>>;
9
+ turnStartedAt: ReturnType<typeof createSignal<number | null>>;
10
+ activeAbort: ReturnType<typeof createSignal<AbortController | null>>;
11
+ }
2
12
  export interface ChatLine {
3
13
  role: "you" | "agent" | "system" | "error";
4
14
  text: string;
@@ -8,41 +18,6 @@ export interface TuiInfo {
8
18
  lastTurnOut: number;
9
19
  balance?: string;
10
20
  }
11
- export declare class SoferTui {
12
- private readonly agent;
13
- private readonly config;
14
- private state;
15
- private inputBuf;
16
- private cursor;
17
- private columns;
18
- private rows;
19
- private chatW;
20
- private sideW;
21
- private bodyH;
22
- private scrollOff;
23
- private status;
24
- private spinnerFrame;
25
- private spinnerTimer;
26
- private turnStartedAt;
27
- private abortCtrl;
28
- private info;
29
- private resolve;
30
- private onLine;
31
- constructor(agent: SoferAgent, config: SoferConfig);
32
- private measure;
33
- addMessage(role: ChatLine["role"], text: string): void;
34
- setInfo(info: Partial<TuiInfo>): void;
35
- private startSpinner;
36
- private stopSpinner;
37
- run(onLine: (line: string, signal?: AbortSignal) => Promise<void>): Promise<void>;
38
- private shutdown;
39
- private handleInput;
40
- private submit;
41
- private handleResize;
42
- render(): void;
43
- private buildFrame;
44
- private wrapMessage;
45
- private roleLabel;
46
- private buildSidebar;
47
- }
21
+ export declare function createTuiState(): TuiState;
22
+ export declare function runTui(state: TuiState, agent: SoferAgent, config: SoferConfig, onSubmit: (line: string, signal: AbortSignal) => Promise<void>): Promise<void>;
48
23
  //# sourceMappingURL=tui.d.ts.map
package/dist/tui.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAgBjE,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,QAAQ;IAoBjB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IApBzB,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,IAAI,CAA8C;IAC1D,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,MAAM,CAAwE;gBAGnE,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,WAAW;IAGtC,OAAO,CAAC,OAAO;IAQf,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKtD,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAIrC,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,WAAW;IASb,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvF,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,WAAW,CA6BjB;YAEY,MAAM;IAgBpB,OAAO,CAAC,YAAY,CAAkD;IAEtE,MAAM,IAAI,IAAI;IAKd,OAAO,CAAC,UAAU;IA8DlB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,YAAY;CA8BrB"}
1
+ {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAqB,YAAY,EAAa,MAAM,UAAU,CAAC;AAKtE,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAClD,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;IAC7D,KAAK,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/C,IAAI,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,YAAY,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,aAAa,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9D,WAAW,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA+LD,wBAAgB,cAAc,IAAI,QAAQ,CAUzC;AAED,wBAAsB,MAAM,CAC1B,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAC7D,OAAO,CAAC,IAAI,CAAC,CAYf"}
package/dist/tui.js CHANGED
@@ -37,7 +37,7 @@ export class SoferTui {
37
37
  measure() {
38
38
  this.columns = Math.max(80, process.stdout.columns ?? 80);
39
39
  this.rows = Math.max(24, process.stdout.rows ?? 24);
40
- this.chatW = Math.max(MIN_CHAT_W, this.columns - SIDEBAR_W - 3);
40
+ this.chatW = Math.min(120, Math.max(MIN_CHAT_W, this.columns - SIDEBAR_W - 3));
41
41
  this.sideW = this.columns - this.chatW - 3;
42
42
  this.bodyH = this.rows - 5;
43
43
  }
@@ -155,7 +155,7 @@ export class SoferTui {
155
155
  handleResize = () => { this.measure(); this.render(); };
156
156
  render() {
157
157
  this.measure();
158
- process.stdout.write("\x1b[?25l\x1b[H" + this.buildFrame() + "\x1b[?25h");
158
+ process.stdout.write("\x1b[?25l\x1b[2J\x1b[H" + this.buildFrame() + "\x1b[?25h");
159
159
  }
160
160
  buildFrame() {
161
161
  const { columns, chatW, sideW, bodyH } = this;
@@ -298,10 +298,35 @@ function padRight(s, w) {
298
298
  return vl >= w ? s : s + " ".repeat(w - vl);
299
299
  }
300
300
  function padTrunc(s, w) {
301
- const stripped = stripAnsi(s);
302
- if (stripped.length <= w)
303
- return s + " ".repeat(w - stripped.length);
304
- return stripped.slice(0, w);
301
+ const vl = visibleLen(s);
302
+ if (vl < w)
303
+ return s + " ".repeat(w - vl);
304
+ if (vl === w)
305
+ return s;
306
+ // Truncate preserving ANSI codes — walk through character by character
307
+ let out = "";
308
+ let visible = 0;
309
+ let i = 0;
310
+ while (i < s.length && visible < w) {
311
+ if (s[i] === "\x1b" && s[i + 1] === "[") {
312
+ // ANSI escape sequence — copy until 'm'
313
+ const end = s.indexOf("m", i);
314
+ if (end !== -1) {
315
+ out += s.slice(i, end + 1);
316
+ i = end + 1;
317
+ }
318
+ else {
319
+ out += s[i];
320
+ i++;
321
+ }
322
+ }
323
+ else {
324
+ out += s[i];
325
+ visible++;
326
+ i++;
327
+ }
328
+ }
329
+ return out;
305
330
  }
306
331
  function formatElapsed(ms) {
307
332
  const sec = Math.floor(ms / 1000);
package/dist/tui.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tui.js","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tui.js","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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"}
package/dist/tui.jsx ADDED
@@ -0,0 +1,182 @@
1
+ import { render, useKeyboard, useTerminalDimensions } from "@opentui/solid";
2
+ import { For, createEffect, createSignal, onCleanup } from "solid-js";
3
+ const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
4
+ const SPINNER_MS = 80;
5
+ function formatElapsed(startedAt) {
6
+ if (!startedAt)
7
+ return "";
8
+ const sec = Math.floor((Date.now() - startedAt) / 1000);
9
+ if (sec < 60)
10
+ return `${sec}s`;
11
+ const m = Math.floor(sec / 60);
12
+ return `${m}m${String(sec % 60).padStart(2, "0")}s`;
13
+ }
14
+ function shortModel(model) {
15
+ const m = model.toLowerCase();
16
+ if (m.includes("sonnet"))
17
+ return "sonnet-4";
18
+ if (m.includes("haiku"))
19
+ return "haiku";
20
+ if (m.includes("opus"))
21
+ return "opus-4";
22
+ return model.length > 14 ? `${model.slice(0, 13)}…` : model;
23
+ }
24
+ function App(props) {
25
+ const { state, agent, config } = props;
26
+ const dims = useTerminalDimensions();
27
+ const [rows] = state.rows;
28
+ const [status] = state.status;
29
+ const [input, setInput] = state.input;
30
+ const [info] = state.info;
31
+ const [spinnerFrame, setSpinnerFrame] = state.spinnerFrame;
32
+ const [turnStartedAt] = state.turnStartedAt;
33
+ const [, setActiveAbort] = state.activeAbort;
34
+ const [activeAbort] = state.activeAbort;
35
+ createEffect(() => {
36
+ if (status() !== "thinking") {
37
+ setSpinnerFrame(0);
38
+ return;
39
+ }
40
+ const id = setInterval(() => setSpinnerFrame((f) => (f + 1) % SPINNER_FRAMES.length), SPINNER_MS);
41
+ onCleanup(() => clearInterval(id));
42
+ });
43
+ useKeyboard((evt) => {
44
+ if (evt.ctrl && evt.name === "c") {
45
+ evt.preventDefault();
46
+ props.onExit();
47
+ return;
48
+ }
49
+ if (evt.name === "escape") {
50
+ const ab = activeAbort();
51
+ if (ab && !ab.signal.aborted)
52
+ ab.abort();
53
+ return;
54
+ }
55
+ if (status() === "thinking")
56
+ return;
57
+ if (evt.name === "return") {
58
+ const text = input().trim();
59
+ if (!text)
60
+ return;
61
+ if (text === "/exit" || text === "/quit") {
62
+ props.onExit();
63
+ return;
64
+ }
65
+ const ctrl = new AbortController();
66
+ setActiveAbort(ctrl);
67
+ state.rows[1](prev => [...prev, { role: "you", text }]);
68
+ setInput("");
69
+ state.status[1]("thinking");
70
+ state.turnStartedAt[1](Date.now());
71
+ props.onSubmit(text, ctrl.signal).finally(() => {
72
+ state.status[1]("idle");
73
+ state.turnStartedAt[1](null);
74
+ setActiveAbort(null);
75
+ });
76
+ return;
77
+ }
78
+ if (evt.name === "backspace" || evt.name === "delete") {
79
+ setInput((p) => p.slice(0, -1));
80
+ return;
81
+ }
82
+ if (evt.sequence && !evt.ctrl && !evt.meta && !evt.option) {
83
+ setInput((p) => p + evt.sequence);
84
+ }
85
+ });
86
+ const sidebarW = Math.min(30, Math.floor(dims().width * 0.22));
87
+ const chatW = dims().width - sidebarW;
88
+ const addr = () => `${agent.address.slice(0, 6)}…${agent.address.slice(-4)}`;
89
+ return (<box flexDirection="row" width={dims().width} height={dims().height}>
90
+ {/* Chat area */}
91
+ <box flexDirection="column" width={chatW} height={dims().height}>
92
+ <scrollbox flexGrow={1} flexShrink={1} stickyScroll stickyStart="bottom" contentOptions={{ flexDirection: "column", paddingLeft: 1, paddingRight: 1, paddingTop: 1, paddingBottom: 1 }}>
93
+ <For each={rows()}>
94
+ {(line) => {
95
+ const color = line.role === "you" ? "#67e8f9"
96
+ : line.role === "agent" ? "#86efac"
97
+ : line.role === "error" ? "#fca5a5"
98
+ : "#9ca3af";
99
+ const label = line.role === "you" ? "you"
100
+ : line.role === "agent" ? agent.name.toLowerCase().slice(0, 5)
101
+ : line.role === "error" ? "err"
102
+ : "sys";
103
+ return (<box flexDirection="row">
104
+ <text fg={color} flexShrink={0}>{` ${label.padEnd(5)} `}</text>
105
+ <text wrapMode="word" flexGrow={1} fg="#e5e7eb">
106
+ {line.text}
107
+ </text>
108
+ </box>);
109
+ }}
110
+ </For>
111
+ </scrollbox>
112
+
113
+ <box flexDirection="row" flexShrink={0} paddingLeft={3} paddingRight={2} marginTop={1}>
114
+ <text fg="#67e8f9" flexGrow={1}>
115
+ {(() => {
116
+ if (status() !== "thinking")
117
+ return " ";
118
+ const frame = SPINNER_FRAMES[spinnerFrame()];
119
+ const elapsed = formatElapsed(turnStartedAt());
120
+ return elapsed
121
+ ? `${frame} thinking… ${elapsed} (esc to interrupt)`
122
+ : `${frame} thinking… (esc to interrupt)`;
123
+ })()}
124
+ </text>
125
+ </box>
126
+
127
+ <box flexDirection="row" flexShrink={0} minHeight={3} maxHeight={8} borderStyle="rounded" borderColor="#374151" paddingLeft={1} paddingRight={1} marginLeft={2} marginRight={2}>
128
+ <text fg="#67e8f9" flexShrink={0}>{"› "}</text>
129
+ <text wrapMode="word" flexGrow={1} fg="#e5e7eb">
130
+ {`${input()}${status() === "idle" ? "▋" : ""}`}
131
+ </text>
132
+ </box>
133
+
134
+ <box flexDirection="row" flexShrink={0} paddingLeft={2} paddingRight={2}>
135
+ <text fg="#9ca3af">
136
+ {[
137
+ addr(),
138
+ config.network,
139
+ shortModel(config.brain.model),
140
+ info().balance ? `${info().balance} SUI` : null,
141
+ `in ${agent.usage.tokens.inputTokens} out ${agent.usage.tokens.outputTokens} $${agent.usage.costUsd.toFixed(4)}`,
142
+ "/exit",
143
+ ].filter(Boolean).join(" · ")}
144
+ </text>
145
+ </box>
146
+ </box>
147
+
148
+ {/* Sidebar */}
149
+ <box flexDirection="column" width={sidebarW} borderStyle="single" borderColor="#374151" paddingLeft={2} paddingRight={1}>
150
+ <text fg="#86efac">{agent.name}</text>
151
+ <text fg="#9ca3af">{addr()}</text>
152
+ <text>{" "}</text>
153
+ <text fg="#6b7280">{"─".repeat(sidebarW - 4)}</text>
154
+ <text fg="#9ca3af">{`network ${config.network}`}</text>
155
+ <text fg="#9ca3af">{`model ${shortModel(config.brain.model)}`}</text>
156
+ {info().balance ? <text fg="#fbbf24">{`balance ${info().balance} SUI`}</text> : null}
157
+ <text>{" "}</text>
158
+ <text fg="#6b7280">{"─".repeat(sidebarW - 4)}</text>
159
+ <text fg="#9ca3af">{`last in ${info().lastTurnIn} out ${info().lastTurnOut}`}</text>
160
+ <text fg="#9ca3af">{`total in ${agent.usage.tokens.inputTokens}`}</text>
161
+ <text fg="#9ca3af">{` out ${agent.usage.tokens.outputTokens}`}</text>
162
+ <text fg="#fbbf24">{` $${agent.usage.costUsd.toFixed(6)}`}</text>
163
+ </box>
164
+ </box>);
165
+ }
166
+ export function createTuiState() {
167
+ return {
168
+ rows: createSignal([]),
169
+ status: createSignal("idle"),
170
+ input: createSignal(""),
171
+ info: createSignal({ lastTurnIn: 0, lastTurnOut: 0 }),
172
+ spinnerFrame: createSignal(0),
173
+ turnStartedAt: createSignal(null),
174
+ activeAbort: createSignal(null),
175
+ };
176
+ }
177
+ export async function runTui(state, agent, config, onSubmit) {
178
+ return new Promise((resolve) => {
179
+ render(() => (<App state={state} agent={agent} config={config} onSubmit={onSubmit} onExit={resolve}/>));
180
+ });
181
+ }
182
+ //# sourceMappingURL=tui.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui.jsx","sourceRoot":"","sources":["../src/tui.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@sofer_agent/cli",
3
- "version": "0.3.15",
3
+ "version": "0.3.17",
4
4
  "type": "module",
5
5
  "bin": {
6
- "sofer": "./dist/bin.js"
6
+ "sofer": "./bin/sofer"
7
7
  },
8
8
  "files": [
9
+ "bin",
9
10
  "dist",
10
11
  "src"
11
12
  ],
@@ -26,14 +27,17 @@
26
27
  ],
27
28
  "dependencies": {
28
29
  "@clack/prompts": "^1.5.1",
29
- "@sofer_agent/core": "0.3.3"
30
+ "@opentui/core": "^0.1.97",
31
+ "@opentui/solid": "^0.1.97",
32
+ "@sofer_agent/core": "0.3.3",
33
+ "solid-js": "^1.9.12"
30
34
  },
31
35
  "devDependencies": {
32
36
  "@types/node": "^22.10.2",
33
37
  "typescript": "^5.7.2"
34
38
  },
35
39
  "scripts": {
36
- "build": "tsc -b && chmod +x dist/bin.js",
40
+ "build": "tsc -b && chmod +x bin/sofer",
37
41
  "typecheck": "tsc --noEmit"
38
42
  }
39
43
  }
package/src/chat.ts CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  SoferAgent,
9
9
  } from "@sofer_agent/core";
10
10
  import { loadSecrets } from "./env.js";
11
- import { SoferTui } from "./tui.js";
11
+ import { createTuiState, runTui } from "./tui.jsx";
12
12
 
13
13
  interface SessionMessage {
14
14
  role: string;
@@ -54,24 +54,35 @@ export async function chatCommand(): Promise<void> {
54
54
  if (history.length > 0) agent.loadHistory(history);
55
55
  }
56
56
 
57
- const tui = new SoferTui(agent, config);
57
+ const tuiState = createTuiState();
58
+ const [, setRows] = tuiState.rows;
59
+ const [, setInfo] = tuiState.info;
58
60
 
59
- agent.getBalance().then((bal) => tui.setInfo({ balance: (Number(bal) / 1e9).toFixed(4) })).catch(() => {});
61
+ agent.getBalance().then((bal) => setInfo((prev) => ({ ...prev, balance: (Number(bal) / 1e9).toFixed(4) }))).catch(() => {});
60
62
 
61
- await tui.run(async (line, signal) => {
63
+ await runTui(tuiState, agent, config, async (line, signal) => {
62
64
  try {
63
65
  const { text, turnUsage } = await agent.chat(line, signal);
64
- tui.addMessage("agent", text);
65
- tui.setInfo({ lastTurnIn: turnUsage.inputTokens, lastTurnOut: turnUsage.outputTokens });
66
+ setRows((prev) => [...prev, { role: "agent", text }]);
67
+ setInfo((prev) => ({ ...prev, lastTurnIn: turnUsage.inputTokens, lastTurnOut: turnUsage.outputTokens }));
66
68
  } catch (e) {
67
- if (signal?.aborted) {
68
- tui.addMessage("system", "turn interrupted (esc).");
69
+ if (signal.aborted) {
70
+ setRows((prev) => [...prev, { role: "system", text: "turn interrupted." }]);
69
71
  } else {
70
- tui.addMessage("error", e instanceof Error ? e.message : String(e));
72
+ const raw = e instanceof Error ? e.message : String(e);
73
+ setRows((prev) => [...prev, { role: "error", text: cleanError(raw) }]);
71
74
  }
72
75
  }
73
- agent.getBalance().then((bal) => tui.setInfo({ balance: (Number(bal) / 1e9).toFixed(4) })).catch(() => {});
76
+ agent.getBalance().then((bal) => setInfo((prev) => ({ ...prev, balance: (Number(bal) / 1e9).toFixed(4) }))).catch(() => {});
74
77
  if (sp) saveSession(sp, agent.getHistory());
75
- tui.render();
76
78
  });
77
79
  }
80
+
81
+ function cleanError(raw: string): string {
82
+ try {
83
+ const obj = JSON.parse(raw);
84
+ if (obj?.error?.type === "overloaded_error") return "Claude is overloaded — try again in a moment.";
85
+ if (obj?.error?.message) return obj.error.message;
86
+ } catch { /* not JSON */ }
87
+ return raw;
88
+ }
package/src/tui.tsx ADDED
@@ -0,0 +1,247 @@
1
+ import { render, useKeyboard, useTerminalDimensions } from "@opentui/solid";
2
+ import type { SoferAgent, SoferConfig } from "@sofer_agent/core";
3
+ import { For, createEffect, createSignal, onCleanup } from "solid-js";
4
+
5
+ const SPINNER_FRAMES = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"] as const;
6
+ const SPINNER_MS = 80;
7
+
8
+ export interface TuiState {
9
+ rows: ReturnType<typeof createSignal<ChatLine[]>>;
10
+ status: ReturnType<typeof createSignal<"idle" | "thinking">>;
11
+ input: ReturnType<typeof createSignal<string>>;
12
+ info: ReturnType<typeof createSignal<TuiInfo>>;
13
+ spinnerFrame: ReturnType<typeof createSignal<number>>;
14
+ turnStartedAt: ReturnType<typeof createSignal<number | null>>;
15
+ activeAbort: ReturnType<typeof createSignal<AbortController | null>>;
16
+ }
17
+
18
+ export interface ChatLine {
19
+ role: "you" | "agent" | "system" | "error";
20
+ text: string;
21
+ }
22
+
23
+ export interface TuiInfo {
24
+ lastTurnIn: number;
25
+ lastTurnOut: number;
26
+ balance?: string;
27
+ }
28
+
29
+ function formatElapsed(startedAt: number | null): string {
30
+ if (!startedAt) return "";
31
+ const sec = Math.floor((Date.now() - startedAt) / 1000);
32
+ if (sec < 60) return `${sec}s`;
33
+ const m = Math.floor(sec / 60);
34
+ return `${m}m${String(sec % 60).padStart(2, "0")}s`;
35
+ }
36
+
37
+ function shortModel(model: string): string {
38
+ const m = model.toLowerCase();
39
+ if (m.includes("sonnet")) return "sonnet-4";
40
+ if (m.includes("haiku")) return "haiku";
41
+ if (m.includes("opus")) return "opus-4";
42
+ return model.length > 14 ? `${model.slice(0, 13)}…` : model;
43
+ }
44
+
45
+ function App(props: {
46
+ state: TuiState;
47
+ agent: SoferAgent;
48
+ config: SoferConfig;
49
+ onSubmit: (line: string, signal: AbortSignal) => Promise<void>;
50
+ onExit: () => void;
51
+ }) {
52
+ const { state, agent, config } = props;
53
+ const dims = useTerminalDimensions();
54
+
55
+ const [rows] = state.rows;
56
+ const [status] = state.status;
57
+ const [input, setInput] = state.input;
58
+ const [info] = state.info;
59
+ const [spinnerFrame, setSpinnerFrame] = state.spinnerFrame;
60
+ const [turnStartedAt] = state.turnStartedAt;
61
+ const [, setActiveAbort] = state.activeAbort;
62
+ const [activeAbort] = state.activeAbort;
63
+
64
+ createEffect(() => {
65
+ if (status() !== "thinking") { setSpinnerFrame(0); return; }
66
+ const id = setInterval(
67
+ () => setSpinnerFrame((f) => (f + 1) % SPINNER_FRAMES.length),
68
+ SPINNER_MS,
69
+ );
70
+ onCleanup(() => clearInterval(id));
71
+ });
72
+
73
+ useKeyboard((evt) => {
74
+ if (evt.ctrl && evt.name === "c") { evt.preventDefault(); props.onExit(); return; }
75
+
76
+ if (evt.name === "escape") {
77
+ const ab = activeAbort();
78
+ if (ab && !ab.signal.aborted) ab.abort();
79
+ return;
80
+ }
81
+
82
+ if (status() === "thinking") return;
83
+
84
+ if (evt.name === "return") {
85
+ const text = input().trim();
86
+ if (!text) return;
87
+ if (text === "/exit" || text === "/quit") { props.onExit(); return; }
88
+ const ctrl = new AbortController();
89
+ setActiveAbort(ctrl);
90
+ state.rows[1](prev => [...prev, { role: "you", text }]);
91
+ setInput("");
92
+ state.status[1]("thinking");
93
+ state.turnStartedAt[1](Date.now());
94
+ props.onSubmit(text, ctrl.signal).finally(() => {
95
+ state.status[1]("idle");
96
+ state.turnStartedAt[1](null);
97
+ setActiveAbort(null);
98
+ });
99
+ return;
100
+ }
101
+
102
+ if (evt.name === "backspace" || evt.name === "delete") {
103
+ setInput((p) => p.slice(0, -1));
104
+ return;
105
+ }
106
+
107
+ if (evt.sequence && !evt.ctrl && !evt.meta && !evt.option) {
108
+ setInput((p) => p + evt.sequence);
109
+ }
110
+ });
111
+
112
+ const sidebarW = Math.min(30, Math.floor(dims().width * 0.22));
113
+ const chatW = dims().width - sidebarW;
114
+ const addr = () => `${agent.address.slice(0, 6)}…${agent.address.slice(-4)}`;
115
+
116
+ return (
117
+ <box flexDirection="row" width={dims().width} height={dims().height}>
118
+ {/* Chat area */}
119
+ <box flexDirection="column" width={chatW} height={dims().height}>
120
+ <scrollbox
121
+ flexGrow={1}
122
+ flexShrink={1}
123
+ stickyScroll
124
+ stickyStart="bottom"
125
+ contentOptions={{ flexDirection: "column", paddingLeft: 1, paddingRight: 1, paddingTop: 1, paddingBottom: 1 }}
126
+ >
127
+ <For each={rows()}>
128
+ {(line) => {
129
+ const color = line.role === "you" ? "#67e8f9"
130
+ : line.role === "agent" ? "#86efac"
131
+ : line.role === "error" ? "#fca5a5"
132
+ : "#9ca3af";
133
+ const label = line.role === "you" ? "you"
134
+ : line.role === "agent" ? agent.name.toLowerCase().slice(0, 5)
135
+ : line.role === "error" ? "err"
136
+ : "sys";
137
+ return (
138
+ <box flexDirection="row">
139
+ <text fg={color} flexShrink={0}>{` ${label.padEnd(5)} `}</text>
140
+ <text wrapMode="word" flexGrow={1} fg="#e5e7eb">
141
+ {line.text}
142
+ </text>
143
+ </box>
144
+ );
145
+ }}
146
+ </For>
147
+ </scrollbox>
148
+
149
+ <box flexDirection="row" flexShrink={0} paddingLeft={3} paddingRight={2} marginTop={1}>
150
+ <text fg="#67e8f9" flexGrow={1}>
151
+ {(() => {
152
+ if (status() !== "thinking") return " ";
153
+ const frame = SPINNER_FRAMES[spinnerFrame()];
154
+ const elapsed = formatElapsed(turnStartedAt());
155
+ return elapsed
156
+ ? `${frame} thinking… ${elapsed} (esc to interrupt)`
157
+ : `${frame} thinking… (esc to interrupt)`;
158
+ })()}
159
+ </text>
160
+ </box>
161
+
162
+ <box
163
+ flexDirection="row"
164
+ flexShrink={0}
165
+ minHeight={3}
166
+ maxHeight={8}
167
+ borderStyle="rounded"
168
+ borderColor="#374151"
169
+ paddingLeft={1} paddingRight={1}
170
+ marginLeft={2} marginRight={2}
171
+ >
172
+ <text fg="#67e8f9" flexShrink={0}>{"› "}</text>
173
+ <text wrapMode="word" flexGrow={1} fg="#e5e7eb">
174
+ {`${input()}${status() === "idle" ? "▋" : ""}`}
175
+ </text>
176
+ </box>
177
+
178
+ <box flexDirection="row" flexShrink={0} paddingLeft={2} paddingRight={2}>
179
+ <text fg="#9ca3af">
180
+ {[
181
+ addr(),
182
+ config.network,
183
+ shortModel(config.brain.model),
184
+ info().balance ? `${info().balance} SUI` : null,
185
+ `in ${agent.usage.tokens.inputTokens} out ${agent.usage.tokens.outputTokens} $${agent.usage.costUsd.toFixed(4)}`,
186
+ "/exit",
187
+ ].filter(Boolean).join(" · ")}
188
+ </text>
189
+ </box>
190
+ </box>
191
+
192
+ {/* Sidebar */}
193
+ <box
194
+ flexDirection="column"
195
+ width={sidebarW}
196
+ borderStyle="single"
197
+ borderColor="#374151"
198
+ paddingLeft={2} paddingRight={1}
199
+ >
200
+ <text fg="#86efac">{agent.name}</text>
201
+ <text fg="#9ca3af">{addr()}</text>
202
+ <text>{" "}</text>
203
+ <text fg="#6b7280">{"─".repeat(sidebarW - 4)}</text>
204
+ <text fg="#9ca3af">{`network ${config.network}`}</text>
205
+ <text fg="#9ca3af">{`model ${shortModel(config.brain.model)}`}</text>
206
+ {info().balance ? <text fg="#fbbf24">{`balance ${info().balance} SUI`}</text> : null}
207
+ <text>{" "}</text>
208
+ <text fg="#6b7280">{"─".repeat(sidebarW - 4)}</text>
209
+ <text fg="#9ca3af">{`last in ${info().lastTurnIn} out ${info().lastTurnOut}`}</text>
210
+ <text fg="#9ca3af">{`total in ${agent.usage.tokens.inputTokens}`}</text>
211
+ <text fg="#9ca3af">{` out ${agent.usage.tokens.outputTokens}`}</text>
212
+ <text fg="#fbbf24">{` $${agent.usage.costUsd.toFixed(6)}`}</text>
213
+ </box>
214
+ </box>
215
+ );
216
+ }
217
+
218
+ export function createTuiState(): TuiState {
219
+ return {
220
+ rows: createSignal<ChatLine[]>([]),
221
+ status: createSignal<"idle" | "thinking">("idle"),
222
+ input: createSignal(""),
223
+ info: createSignal<TuiInfo>({ lastTurnIn: 0, lastTurnOut: 0 }),
224
+ spinnerFrame: createSignal(0),
225
+ turnStartedAt: createSignal<number | null>(null),
226
+ activeAbort: createSignal<AbortController | null>(null),
227
+ };
228
+ }
229
+
230
+ export async function runTui(
231
+ state: TuiState,
232
+ agent: SoferAgent,
233
+ config: SoferConfig,
234
+ onSubmit: (line: string, signal: AbortSignal) => Promise<void>,
235
+ ): Promise<void> {
236
+ return new Promise<void>((resolve) => {
237
+ render(() => (
238
+ <App
239
+ state={state}
240
+ agent={agent}
241
+ config={config}
242
+ onSubmit={onSubmit}
243
+ onExit={resolve}
244
+ />
245
+ ));
246
+ });
247
+ }
package/src/tui.ts DELETED
@@ -1,341 +0,0 @@
1
- import type { SoferAgent, SoferConfig } from "@sofer_agent/core";
2
-
3
- const SIDEBAR_W = 28;
4
- const MIN_CHAT_W = 34;
5
- const GUTTER = " ";
6
- const LABEL_W = 6;
7
- const INDENT = `${GUTTER}${" ".repeat(LABEL_W + 1)}`;
8
- const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
9
- const SPINNER_MS = 80;
10
-
11
- const B = {
12
- tl: "╭", tr: "╮", bl: "╰", br: "╯",
13
- h: "─", v: "│",
14
- lt: "├", rt: "┤", tt: "┬", bt: "┴",
15
- };
16
-
17
- export interface ChatLine {
18
- role: "you" | "agent" | "system" | "error";
19
- text: string;
20
- }
21
-
22
- export interface TuiInfo {
23
- lastTurnIn: number;
24
- lastTurnOut: number;
25
- balance?: string;
26
- }
27
-
28
- export class SoferTui {
29
- private state: ChatLine[] = [];
30
- private inputBuf = "";
31
- private cursor = 0;
32
- private columns = 90;
33
- private rows = 28;
34
- private chatW = 58;
35
- private sideW = 26;
36
- private bodyH = 22;
37
- private scrollOff = Number.MAX_SAFE_INTEGER;
38
- private status: "idle" | "thinking" = "idle";
39
- private spinnerFrame = 0;
40
- private spinnerTimer: ReturnType<typeof setInterval> | null = null;
41
- private turnStartedAt = 0;
42
- private abortCtrl: AbortController | null = null;
43
- private info: TuiInfo = { lastTurnIn: 0, lastTurnOut: 0 };
44
- private resolve: (() => void) | null = null;
45
- private onLine: ((line: string, signal?: AbortSignal) => Promise<void>) | null = null;
46
-
47
- constructor(
48
- private readonly agent: SoferAgent,
49
- private readonly config: SoferConfig,
50
- ) {}
51
-
52
- private measure(): void {
53
- this.columns = Math.max(80, process.stdout.columns ?? 80);
54
- this.rows = Math.max(24, process.stdout.rows ?? 24);
55
- this.chatW = Math.max(MIN_CHAT_W, this.columns - SIDEBAR_W - 3);
56
- this.sideW = this.columns - this.chatW - 3;
57
- this.bodyH = this.rows - 5;
58
- }
59
-
60
- addMessage(role: ChatLine["role"], text: string): void {
61
- this.state.push({ role, text });
62
- this.scrollOff = Number.MAX_SAFE_INTEGER;
63
- }
64
-
65
- setInfo(info: Partial<TuiInfo>): void {
66
- Object.assign(this.info, info);
67
- }
68
-
69
- private startSpinner(): void {
70
- if (this.spinnerTimer) return;
71
- this.status = "thinking";
72
- this.turnStartedAt = Date.now();
73
- this.spinnerFrame = 0;
74
- this.spinnerTimer = setInterval(() => {
75
- this.spinnerFrame = (this.spinnerFrame + 1) % SPINNER_FRAMES.length;
76
- this.render();
77
- }, SPINNER_MS);
78
- }
79
-
80
- private stopSpinner(): void {
81
- this.status = "idle";
82
- this.turnStartedAt = 0;
83
- if (this.spinnerTimer) {
84
- clearInterval(this.spinnerTimer);
85
- this.spinnerTimer = null;
86
- }
87
- }
88
-
89
- async run(onLine: (line: string, signal?: AbortSignal) => Promise<void>): Promise<void> {
90
- this.onLine = onLine;
91
- this.measure();
92
- if (process.stdin.isTTY) process.stdin.setRawMode?.(true);
93
- process.stdin.on("data", this.handleInput);
94
- process.stdout.on("resize", this.handleResize);
95
- process.on("SIGWINCH", this.handleResize);
96
- this.render();
97
- return new Promise<void>((resolve) => { this.resolve = resolve; });
98
- }
99
-
100
- private shutdown(): void {
101
- this.stopSpinner();
102
- process.stdin.setRawMode?.(false);
103
- process.stdin.removeAllListeners("data");
104
- process.stdout.removeAllListeners("resize");
105
- process.removeAllListeners("SIGWINCH");
106
- this.render();
107
- process.stdout.write("\n");
108
- this.resolve?.();
109
- }
110
-
111
- private handleInput = (data: Buffer): void => {
112
- const str = data.toString();
113
- for (const ch of str) {
114
- const code = ch.charCodeAt(0);
115
- if (code === 3) { this.shutdown(); return; }
116
- if (code === 4 && this.inputBuf.length === 0) { this.shutdown(); return; }
117
- if (code === 27) {
118
- if (this.status === "thinking" && this.abortCtrl) { this.abortCtrl.abort(); return; }
119
- this.inputBuf = "";
120
- this.cursor = 0;
121
- this.render();
122
- return;
123
- }
124
- if (this.status === "thinking") continue;
125
- if (code === 13) { this.submit(); return; }
126
- if (code === 127) {
127
- if (this.cursor > 0) {
128
- this.inputBuf = this.inputBuf.slice(0, this.cursor - 1) + this.inputBuf.slice(this.cursor);
129
- this.cursor--;
130
- }
131
- this.render();
132
- return;
133
- }
134
- if (ch >= " ") {
135
- this.inputBuf = this.inputBuf.slice(0, this.cursor) + ch + this.inputBuf.slice(this.cursor);
136
- this.cursor++;
137
- this.render();
138
- }
139
- }
140
- };
141
-
142
- private async submit(): Promise<void> {
143
- const line = this.inputBuf.trim();
144
- this.inputBuf = "";
145
- this.cursor = 0;
146
- if (!line) { this.render(); return; }
147
- if (line === "/exit" || line === "/quit") { this.shutdown(); return; }
148
- this.addMessage("you", line);
149
- this.abortCtrl = new AbortController();
150
- this.startSpinner();
151
- this.render();
152
- await this.onLine?.(line, this.abortCtrl.signal);
153
- this.abortCtrl = null;
154
- this.stopSpinner();
155
- this.render();
156
- }
157
-
158
- private handleResize = (): void => { this.measure(); this.render(); };
159
-
160
- render(): void {
161
- this.measure();
162
- process.stdout.write("\x1b[?25l\x1b[H" + this.buildFrame() + "\x1b[?25h");
163
- }
164
-
165
- private buildFrame(): string {
166
- const { columns, chatW, sideW, bodyH } = this;
167
- const innerSideW = sideW - 2;
168
- const sep = `${B.lt}${B.h.repeat(chatW)}${B.bt}${B.h.repeat(sideW)}${B.rt}`;
169
- const inputW = columns - 2;
170
-
171
- let buf = `${B.tl}${B.h.repeat(chatW)}${B.tt}${B.h.repeat(sideW)}${B.tr}\n`;
172
-
173
- const wrapped = this.state.flatMap((m) => this.wrapMessage(m, chatW));
174
- const maxScroll = Math.max(0, wrapped.length - bodyH);
175
- if (this.scrollOff > maxScroll) this.scrollOff = maxScroll;
176
- if (this.scrollOff < 0) this.scrollOff = 0;
177
- const visible = wrapped.slice(this.scrollOff, this.scrollOff + bodyH);
178
-
179
- const sidebarLines = this.buildSidebar(innerSideW);
180
- const sbTop = Math.max(0, Math.floor((bodyH - sidebarLines.length) / 2));
181
-
182
- for (let r = 0; r < bodyH; r++) {
183
- buf += B.v;
184
- const line = visible[r];
185
- if (line) buf += padTrunc(line, chatW);
186
- else buf += " ".repeat(chatW);
187
- buf += B.v;
188
- const sbIdx = r - sbTop;
189
- const sbLine = (sbIdx >= 0 && sbIdx < sidebarLines.length) ? sidebarLines[sbIdx]! : "";
190
- buf += ` ${padRight(sbLine, innerSideW)} `;
191
- buf += `${B.v}\n`;
192
- }
193
-
194
- buf += `${sep}\n`;
195
-
196
- if (this.status === "thinking") {
197
- const frame = SPINNER_FRAMES[this.spinnerFrame]!;
198
- const elapsed = this.turnStartedAt ? formatElapsed(Date.now() - this.turnStartedAt) : "";
199
- const spinnerText = `${frame} thinking…${elapsed ? ` ${elapsed}` : ""} (esc to interrupt)`;
200
- const padLen = Math.max(0, inputW - 1 - spinnerText.length);
201
- buf += `${B.v} \x1b[36m${spinnerText}\x1b[0m${" ".repeat(padLen)}${B.v}\n`;
202
- }
203
-
204
- buf += `${B.tl}${B.h.repeat(inputW)}${B.tr}\n`;
205
- const cursorCh = this.status === "idle" ? "\x1b[5m▋\x1b[25m" : "";
206
- const inputMaxW = inputW - 3;
207
- const visibleInput = this.inputBuf.length > inputMaxW
208
- ? this.inputBuf.slice(this.inputBuf.length - inputMaxW)
209
- : this.inputBuf;
210
- const inputPad = inputMaxW - visibleInput.length;
211
- buf += `${B.v} \x1b[36m>\x1b[0m ${visibleInput}${cursorCh}${" ".repeat(Math.max(0, inputPad))} ${B.v}\n`;
212
- buf += `${B.bl}${B.h.repeat(inputW)}${B.br}\n`;
213
-
214
- const totalIn = this.agent.usage.tokens.inputTokens;
215
- const totalOut = this.agent.usage.tokens.outputTokens;
216
- const cost = this.agent.usage.costUsd.toFixed(4);
217
- const ft = `\x1b[90m${this.agent.address.slice(0, 10)}… · in ${totalIn} out ${totalOut} $${cost} /exit\x1b[0m`;
218
- buf += `${padTrunc(ft, columns)}\n`;
219
-
220
- const cursorRow = bodyH + 4 + (this.status === "thinking" ? 1 : 0);
221
- const cursorCol = 4 + Math.min(this.cursor, inputMaxW);
222
- buf += `\x1b[${cursorRow};${cursorCol}H`;
223
-
224
- return buf;
225
- }
226
-
227
- private wrapMessage(msg: ChatLine, width: number): string[] {
228
- const label = this.roleLabel(msg.role);
229
- const bodyWidth = Math.max(10, width - GUTTER.length - LABEL_W - 1);
230
- const lines = wrapText(msg.text, bodyWidth);
231
- return lines.map((l, i) => i === 0 ? `${GUTTER}${label} ${l}` : `${INDENT}${l}`);
232
- }
233
-
234
- private roleLabel(role: ChatLine["role"]): string {
235
- switch (role) {
236
- case "you": return "\x1b[36myou \x1b[0m";
237
- case "agent": return `\x1b[32m${this.agent.name.toLowerCase().padEnd(LABEL_W)}\x1b[0m`;
238
- case "system": return "\x1b[90msys \x1b[0m";
239
- case "error": return "\x1b[31merr \x1b[0m";
240
- }
241
- }
242
-
243
- private buildSidebar(width: number): string[] {
244
- const { agent, config, info } = this;
245
- const addr = `${agent.address.slice(0, 6)}…${agent.address.slice(-4)}`;
246
- const totalIn = agent.usage.tokens.inputTokens;
247
- const totalOut = agent.usage.tokens.outputTokens;
248
- const cost = agent.usage.costUsd.toFixed(6);
249
-
250
- const rows = [
251
- `\x1b[1;36m${agent.name}\x1b[0m`,
252
- `\x1b[90m${addr}\x1b[0m`,
253
- "",
254
- `${B.h.repeat(width)}`,
255
- `\x1b[90mnetwork\x1b[0m ${config.network}`,
256
- `\x1b[90mmodel\x1b[0m ${shortModel(config.brain.model)}`,
257
- ];
258
-
259
- if (info.balance) {
260
- rows.push("", `\x1b[90mbalance\x1b[0m \x1b[33m${info.balance} SUI\x1b[0m`);
261
- }
262
-
263
- rows.push(
264
- "",
265
- `\x1b[90mlast\x1b[0m in ${info.lastTurnIn} out ${info.lastTurnOut}`,
266
- "",
267
- `\x1b[90mtotal\x1b[0m in ${totalIn} out ${totalOut}`,
268
- ` \x1b[33m$${cost}\x1b[0m`,
269
- );
270
-
271
- return rows;
272
- }
273
- }
274
-
275
- function wrapText(text: string, width: number): string[] {
276
- if (!text) return [""];
277
- const lines: string[] = [];
278
- for (const para of text.split("\n")) {
279
- const words = para.split(" ");
280
- let cur = "";
281
- for (const w of words) {
282
- if (w.length > width) {
283
- if (cur) { lines.push(cur); cur = ""; }
284
- for (let i = 0; i < w.length; i += width) lines.push(w.slice(i, i + width));
285
- } else if (cur && cur.length + 1 + w.length > width) {
286
- lines.push(cur);
287
- cur = w;
288
- } else {
289
- cur = cur ? `${cur} ${w}` : w;
290
- }
291
- }
292
- if (cur) lines.push(cur);
293
- }
294
- return lines.length > 0 ? lines : [""];
295
- }
296
-
297
- function stripAnsi(s: string): string {
298
- // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape stripping
299
- return s.replace(/\x1b\[\d*;?\d*m/g, "");
300
- }
301
-
302
- function visibleLen(s: string): number {
303
- // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape stripping
304
- const re = /\x1b\[\d*;?\d*m/g;
305
- let len = 0;
306
- let last = 0;
307
- let m = re.exec(s);
308
- while (m !== null) {
309
- len += m.index - last;
310
- last = m.index + m[0].length;
311
- m = re.exec(s);
312
- }
313
- return len + s.length - last;
314
- }
315
-
316
- function padRight(s: string, w: number): string {
317
- const vl = visibleLen(s);
318
- return vl >= w ? s : s + " ".repeat(w - vl);
319
- }
320
-
321
- function padTrunc(s: string, w: number): string {
322
- const stripped = stripAnsi(s);
323
- if (stripped.length <= w) return s + " ".repeat(w - stripped.length);
324
- return stripped.slice(0, w);
325
- }
326
-
327
- function formatElapsed(ms: number): string {
328
- const sec = Math.floor(ms / 1000);
329
- if (sec < 60) return `${sec}s`;
330
- const m = Math.floor(sec / 60);
331
- return `${m}m${String(sec % 60).padStart(2, "0")}s`;
332
- }
333
-
334
- function shortModel(model: string): string {
335
- const m = model.toLowerCase();
336
- if (m.includes("sonnet")) return "Sonnet 4";
337
- if (m.includes("haiku")) return "Haiku";
338
- if (m.includes("opus")) return "Opus 4";
339
- if (m.includes("fable")) return "Fable 5";
340
- return model.length > 14 ? `${model.slice(0, 13)}…` : model;
341
- }