@sofer_agent/cli 0.3.20 → 0.4.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.
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"AAsCA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAmCjD"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"AAsCA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAkCjD"}
package/dist/chat.js CHANGED
@@ -77,7 +77,6 @@ export async function chatCommand() {
77
77
  agent.getBalance().then((b) => tui.setInfo({ balance: (Number(b) / 1e9).toFixed(4) })).catch(() => { });
78
78
  if (sp)
79
79
  saveSession(sp, agent.getHistory());
80
- tui.render();
81
80
  });
82
81
  }
83
82
  //# 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,47 +1,38 @@
1
1
  import type { SoferAgent, SoferConfig } from "@sofer_agent/core";
2
- export interface ChatLine {
3
- role: "you" | "agent" | "system" | "error";
4
- text: string;
5
- }
6
- export interface TuiInfo {
7
- lastTurnIn: number;
8
- lastTurnOut: number;
9
- balance?: string;
10
- }
11
2
  export declare class SoferTui {
12
3
  private readonly agent;
13
4
  private readonly config;
14
- private state;
15
- private inputBuf;
16
- private columns;
17
- private rows;
18
- private chatW;
19
- private sideW;
20
- private bodyH;
21
- private scrollOff;
5
+ private screen;
6
+ private chat;
7
+ private input;
8
+ private sidebar;
9
+ private spinnerBox;
10
+ private footer;
22
11
  private status;
12
+ private abortCtrl;
23
13
  private spinnerFrame;
24
14
  private spinnerTimer;
25
15
  private turnStartedAt;
26
- private abortCtrl;
27
- private info;
16
+ private lastTurnIn;
17
+ private lastTurnOut;
18
+ private balance?;
28
19
  private resolve;
29
20
  private onLine;
21
+ private agentName;
30
22
  constructor(agent: SoferAgent, config: SoferConfig);
31
- private measure;
32
- addMessage(role: ChatLine["role"], text: string): void;
33
- setInfo(info: Partial<TuiInfo>): void;
23
+ private submit;
24
+ addMessage(role: string, text: string): void;
25
+ setInfo(info: {
26
+ lastTurnIn?: number;
27
+ lastTurnOut?: number;
28
+ balance?: string;
29
+ }): void;
34
30
  private startSpinner;
35
31
  private stopSpinner;
32
+ private renderSpinner;
33
+ private buildSidebarContent;
34
+ private renderFooter;
36
35
  run(onLine: (line: string, signal?: AbortSignal) => Promise<void>): Promise<void>;
37
36
  private shutdown;
38
- private handleInput;
39
- private submit;
40
- private handleResize;
41
- render(): void;
42
- private buildFrame;
43
- private wrapMessage;
44
- private roleLabel;
45
- private buildSidebar;
46
37
  }
47
38
  //# 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;IAmBjB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAnBzB,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,QAAQ,CAAM;IACtB,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,CAoBjB;YAEY,MAAM;IAepB,OAAO,CAAC,YAAY,CAAkD;IAEtE,MAAM,IAAI,IAAI;IAKd,OAAO,CAAC,UAAU;IA0DlB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,YAAY;CAyBrB"}
1
+ {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIjE,qBAAa,QAAQ;IAoBjB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IApBzB,OAAO,CAAC,MAAM,CAAoC;IAClD,OAAO,CAAC,IAAI,CAAiC;IAC7C,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,MAAM,CAAwE;IACtF,OAAO,CAAC,SAAS,CAAS;gBAGP,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,WAAW;IAwFtC,OAAO,CAAC,MAAM;IAsBd,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAY5C,OAAO,CAAC,IAAI,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAMpF,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,mBAAmB;IAyB3B,OAAO,CAAC,YAAY;IAUd,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvF,OAAO,CAAC,QAAQ;CAKjB"}
package/dist/tui.js CHANGED
@@ -1,62 +1,159 @@
1
- const SIDEBAR_W = 28;
2
- const MIN_CHAT_W = 34;
3
- const GUTTER = " ";
4
- const LABEL_W = 6;
5
- const INDENT = `${GUTTER}${" ".repeat(LABEL_W + 1)}`;
1
+ import blessed from "blessed";
6
2
  const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
7
- const SPINNER_MS = 80;
8
- const B = {
9
- tl: "╭", tr: "╮", bl: "╰", br: "╯",
10
- h: "─", v: "│",
11
- lt: "├", rt: "┤", tt: "┬", bt: "┴",
12
- };
13
3
  export class SoferTui {
14
4
  agent;
15
5
  config;
16
- state = [];
17
- inputBuf = "";
18
- columns = 90;
19
- rows = 28;
20
- chatW = 58;
21
- sideW = 26;
22
- bodyH = 22;
23
- scrollOff = Number.MAX_SAFE_INTEGER;
6
+ screen;
7
+ chat;
8
+ input;
9
+ sidebar;
10
+ spinnerBox;
11
+ footer;
24
12
  status = "idle";
13
+ abortCtrl = null;
25
14
  spinnerFrame = 0;
26
15
  spinnerTimer = null;
27
16
  turnStartedAt = 0;
28
- abortCtrl = null;
29
- info = { lastTurnIn: 0, lastTurnOut: 0 };
17
+ lastTurnIn = 0;
18
+ lastTurnOut = 0;
19
+ balance;
30
20
  resolve = null;
31
21
  onLine = null;
22
+ agentName;
32
23
  constructor(agent, config) {
33
24
  this.agent = agent;
34
25
  this.config = config;
35
- }
36
- measure() {
37
- this.columns = Math.max(80, process.stdout.columns ?? 80);
38
- this.rows = Math.max(24, process.stdout.rows ?? 24);
39
- this.chatW = Math.min(120, Math.max(MIN_CHAT_W, this.columns - SIDEBAR_W - 3));
40
- this.sideW = this.columns - this.chatW - 3;
41
- this.bodyH = this.rows - 5;
26
+ this.agentName = agent.name.toLowerCase();
27
+ this.screen = blessed.screen({ smartCSR: true, title: "sofer" });
28
+ this.chat = blessed.log({
29
+ parent: this.screen,
30
+ top: 0,
31
+ left: 0,
32
+ width: "75%",
33
+ height: "100%-5",
34
+ border: { type: "line" },
35
+ label: ` ${this.agentName} `,
36
+ scrollable: true,
37
+ alwaysScroll: true,
38
+ scrollOnInput: true,
39
+ keys: true,
40
+ vi: true,
41
+ mouse: true,
42
+ tags: true,
43
+ });
44
+ this.sidebar = blessed.box({
45
+ parent: this.screen,
46
+ top: 0,
47
+ left: "75%",
48
+ width: "25%",
49
+ height: "100%-5",
50
+ border: { type: "line" },
51
+ label: " stats ",
52
+ content: this.buildSidebarContent(),
53
+ tags: true,
54
+ });
55
+ this.spinnerBox = blessed.box({
56
+ parent: this.screen,
57
+ bottom: 4,
58
+ left: 0,
59
+ width: "100%",
60
+ height: 1,
61
+ content: "",
62
+ tags: true,
63
+ });
64
+ this.input = blessed.textbox({
65
+ parent: this.screen,
66
+ bottom: 1,
67
+ left: 0,
68
+ width: "100%",
69
+ height: 3,
70
+ inputOnFocus: true,
71
+ border: { type: "line" },
72
+ label: " you ",
73
+ keys: true,
74
+ vi: true,
75
+ style: { focus: { border: { fg: "cyan" } } },
76
+ });
77
+ this.footer = blessed.box({
78
+ parent: this.screen,
79
+ bottom: 0,
80
+ left: 0,
81
+ width: "100%",
82
+ height: 1,
83
+ content: "",
84
+ tags: true,
85
+ });
86
+ this.renderFooter();
87
+ this.input.key(["enter"], () => this.submit());
88
+ this.input.key(["escape"], () => {
89
+ if (this.status === "thinking" && this.abortCtrl) {
90
+ this.abortCtrl.abort();
91
+ }
92
+ else {
93
+ this.input.clearValue();
94
+ this.screen.render();
95
+ }
96
+ });
97
+ this.input.on("cancel", () => this.input.clearValue());
98
+ this.screen.key(["C-c"], () => this.shutdown());
99
+ this.screen.key(["C-d"], () => {
100
+ if (this.input.getValue() === "")
101
+ this.shutdown();
102
+ });
103
+ }
104
+ submit() {
105
+ const text = this.input.getValue().trim();
106
+ this.input.clearValue();
107
+ this.screen.render();
108
+ if (!text) {
109
+ this.input.focus();
110
+ return;
111
+ }
112
+ if (text === "/exit" || text === "/quit") {
113
+ this.shutdown();
114
+ return;
115
+ }
116
+ this.chat.log(`{cyan-fg} you {/cyan-fg} ${text}`);
117
+ this.abortCtrl = new AbortController();
118
+ this.startSpinner();
119
+ this.screen.render();
120
+ this.onLine?.(text, this.abortCtrl.signal).finally(() => {
121
+ this.abortCtrl = null;
122
+ this.stopSpinner();
123
+ this.sidebar.setContent(this.buildSidebarContent());
124
+ this.renderFooter();
125
+ this.input.focus();
126
+ this.screen.render();
127
+ });
42
128
  }
43
129
  addMessage(role, text) {
44
- this.state.push({ role, text });
45
- this.scrollOff = Number.MAX_SAFE_INTEGER;
130
+ const color = role === "agent" ? "green-fg"
131
+ : role === "error" ? "red-fg"
132
+ : role === "system" ? "gray-fg"
133
+ : "cyan-fg";
134
+ const label = role === "agent" ? this.agentName
135
+ : role === "error" ? "err"
136
+ : role === "system" ? "sys"
137
+ : "you";
138
+ this.chat.log(`{${color}} ${label.padEnd(5)} {/${color}} ${text}`);
46
139
  }
47
140
  setInfo(info) {
48
- Object.assign(this.info, info);
141
+ if (info.lastTurnIn !== undefined)
142
+ this.lastTurnIn = info.lastTurnIn;
143
+ if (info.lastTurnOut !== undefined)
144
+ this.lastTurnOut = info.lastTurnOut;
145
+ if (info.balance !== undefined)
146
+ this.balance = info.balance;
49
147
  }
50
148
  startSpinner() {
51
- if (this.spinnerTimer)
52
- return;
53
149
  this.status = "thinking";
54
150
  this.turnStartedAt = Date.now();
55
151
  this.spinnerFrame = 0;
56
152
  this.spinnerTimer = setInterval(() => {
57
153
  this.spinnerFrame = (this.spinnerFrame + 1) % SPINNER_FRAMES.length;
58
- this.render();
59
- }, SPINNER_MS);
154
+ this.renderSpinner();
155
+ this.screen.render();
156
+ }, 80);
60
157
  }
61
158
  stopSpinner() {
62
159
  this.status = "idle";
@@ -65,248 +162,49 @@ export class SoferTui {
65
162
  clearInterval(this.spinnerTimer);
66
163
  this.spinnerTimer = null;
67
164
  }
165
+ this.spinnerBox.setContent("");
68
166
  }
69
- async run(onLine) {
70
- this.onLine = onLine;
71
- this.measure();
72
- if (process.stdin.isTTY)
73
- process.stdin.setRawMode?.(true);
74
- process.stdin.on("data", this.handleInput);
75
- process.stdout.on("resize", this.handleResize);
76
- process.on("SIGWINCH", this.handleResize);
77
- this.render();
78
- return new Promise((resolve) => { this.resolve = resolve; });
79
- }
80
- shutdown() {
81
- this.stopSpinner();
82
- process.stdin.setRawMode?.(false);
83
- process.stdin.removeAllListeners("data");
84
- process.stdout.removeAllListeners("resize");
85
- process.removeAllListeners("SIGWINCH");
86
- this.render();
87
- process.stdout.write("\n");
88
- this.resolve?.();
89
- }
90
- handleInput = (data) => {
91
- for (const ch of data.toString()) {
92
- const code = ch.charCodeAt(0);
93
- if (code === 3) {
94
- this.shutdown();
95
- return;
96
- }
97
- if (code === 4 && this.inputBuf.length === 0) {
98
- this.shutdown();
99
- return;
100
- }
101
- if (code === 27) {
102
- if (this.status === "thinking" && this.abortCtrl) {
103
- this.abortCtrl.abort();
104
- return;
105
- }
106
- this.inputBuf = "";
107
- this.render();
108
- return;
109
- }
110
- if (this.status === "thinking")
111
- continue;
112
- if (code === 13) {
113
- this.submit();
114
- return;
115
- }
116
- if (code === 127) {
117
- this.inputBuf = this.inputBuf.slice(0, -1);
118
- this.render();
119
- return;
120
- }
121
- if (ch >= " ") {
122
- this.inputBuf += ch;
123
- this.render();
124
- }
125
- }
126
- };
127
- async submit() {
128
- const line = this.inputBuf.trim();
129
- this.inputBuf = "";
130
- if (!line) {
131
- this.render();
132
- return;
133
- }
134
- if (line === "/exit" || line === "/quit") {
135
- this.shutdown();
136
- return;
137
- }
138
- this.addMessage("you", line);
139
- this.abortCtrl = new AbortController();
140
- this.startSpinner();
141
- this.render();
142
- await this.onLine?.(line, this.abortCtrl.signal);
143
- this.abortCtrl = null;
144
- this.stopSpinner();
145
- this.render();
146
- }
147
- handleResize = () => { this.measure(); this.render(); };
148
- render() {
149
- this.measure();
150
- process.stdout.write("\x1b[?25l\x1b[2J\x1b[H" + this.buildFrame() + "\x1b[?25h");
151
- }
152
- buildFrame() {
153
- const { columns, chatW, sideW, bodyH } = this;
154
- const innerSideW = sideW - 2;
155
- const sep = `${B.lt}${B.h.repeat(chatW)}${B.bt}${B.h.repeat(sideW)}${B.rt}`;
156
- const inputW = columns - 2;
157
- let buf = `${B.tl}${B.h.repeat(chatW)}${B.tt}${B.h.repeat(sideW)}${B.tr}\n`;
158
- const wrapped = this.state.flatMap((m) => this.wrapMessage(m, chatW));
159
- const maxScroll = Math.max(0, wrapped.length - bodyH);
160
- if (this.scrollOff > maxScroll)
161
- this.scrollOff = maxScroll;
162
- if (this.scrollOff < 0)
163
- this.scrollOff = 0;
164
- const visible = wrapped.slice(this.scrollOff, this.scrollOff + bodyH);
165
- const sidebarLines = this.buildSidebar(innerSideW);
166
- const sbTop = Math.max(0, Math.floor((bodyH - sidebarLines.length) / 2));
167
- for (let r = 0; r < bodyH; r++) {
168
- buf += B.v;
169
- const line = visible[r];
170
- if (line)
171
- buf += padTrunc(line, chatW);
172
- else
173
- buf += " ".repeat(chatW);
174
- buf += B.v;
175
- const sbIdx = r - sbTop;
176
- const sbLine = (sbIdx >= 0 && sbIdx < sidebarLines.length) ? sidebarLines[sbIdx] : "";
177
- buf += ` ${padRight(sbLine, innerSideW)} `;
178
- buf += `${B.v}\n`;
179
- }
180
- buf += `${sep}\n`;
181
- if (this.status === "thinking") {
182
- const frame = SPINNER_FRAMES[this.spinnerFrame];
183
- const elapsed = this.turnStartedAt ? formatElapsed(Date.now() - this.turnStartedAt) : "";
184
- const st = ` ${frame} thinking…${elapsed ? ` ${elapsed}` : ""} (esc to interrupt)`;
185
- buf += `${B.v}\x1b[36m${st}\x1b[0m${" ".repeat(Math.max(0, columns - 2 - st.length - 2))}${B.v}\n`;
186
- }
187
- buf += `${B.tl}${B.h.repeat(inputW)}${B.tr}\n`;
188
- const cursorCh = this.status === "idle" ? "\x1b[5m▋\x1b[25m" : "";
189
- const inputMaxW = inputW - 4;
190
- const vi = this.inputBuf.slice(Math.max(0, this.inputBuf.length - inputMaxW));
191
- buf += `${B.v} \x1b[36m>\x1b[0m ${vi}${cursorCh}${" ".repeat(Math.max(0, inputMaxW - vi.length))} ${B.v}\n`;
192
- buf += `${B.bl}${B.h.repeat(inputW)}${B.br}\n`;
193
- const totalIn = this.agent.usage.tokens.inputTokens;
194
- const totalOut = this.agent.usage.tokens.outputTokens;
195
- const cost = this.agent.usage.costUsd.toFixed(4);
196
- const ft = `\x1b[90m${this.agent.address.slice(0, 10)}… · in ${totalIn} out ${totalOut} $${cost} /exit\x1b[0m`;
197
- buf += `${padTrunc(ft, columns)}\n`;
198
- const cursorRow = bodyH + 4 + (this.status === "thinking" ? 1 : 0);
199
- const cursorCol = 4 + Math.min(vi.length + (cursorCh ? 0 : 0), inputMaxW);
200
- buf += `\x1b[${cursorRow};${cursorCol}H`;
201
- return buf;
202
- }
203
- wrapMessage(msg, width) {
204
- const label = this.roleLabel(msg.role);
205
- const bodyWidth = Math.max(10, width - GUTTER.length - LABEL_W - 1);
206
- const lines = wrapText(msg.text, bodyWidth);
207
- return lines.map((l, i) => i === 0 ? `${GUTTER}${label} ${l}` : `${INDENT}${l}`);
208
- }
209
- roleLabel(role) {
210
- switch (role) {
211
- case "you": return "\x1b[36myou \x1b[0m";
212
- case "agent": return `\x1b[32m${this.agent.name.toLowerCase().padEnd(LABEL_W)}\x1b[0m`;
213
- case "system": return "\x1b[90msys \x1b[0m";
214
- case "error": return "\x1b[31merr \x1b[0m";
215
- }
167
+ renderSpinner() {
168
+ const frame = SPINNER_FRAMES[this.spinnerFrame];
169
+ const elapsed = this.turnStartedAt ? formatElapsed(Date.now() - this.turnStartedAt) : "";
170
+ this.spinnerBox.setContent(`{cyan-fg}${frame} thinking…${elapsed ? ` ${elapsed}` : ""} (esc to interrupt){/cyan-fg}`);
216
171
  }
217
- buildSidebar(width) {
218
- const { agent, config, info } = this;
172
+ buildSidebarContent() {
173
+ const { agent, config } = this;
219
174
  const addr = `${agent.address.slice(0, 6)}…${agent.address.slice(-4)}`;
175
+ const cost = agent.usage.costUsd.toFixed(6);
220
176
  const totalIn = agent.usage.tokens.inputTokens;
221
177
  const totalOut = agent.usage.tokens.outputTokens;
222
- const cost = agent.usage.costUsd.toFixed(6);
223
- const rows = [
224
- `\x1b[1;36m${agent.name}\x1b[0m`,
225
- `\x1b[90m${addr}\x1b[0m`,
178
+ const lines = [
179
+ `{bold}{green-fg}${agent.name}{/green-fg}{/bold}`,
180
+ `{gray-fg}${addr}{/gray-fg}`,
226
181
  "",
227
- `${B.h.repeat(width)}`,
228
- `\x1b[90mnetwork\x1b[0m ${config.network}`,
229
- `\x1b[90mmodel\x1b[0m ${shortModel(config.brain.model)}`,
182
+ `{gray-fg}network ${config.network}{/gray-fg}`,
183
+ `{gray-fg}model ${shortModel(config.brain.model)}{/gray-fg}`,
230
184
  ];
231
- if (info.balance)
232
- rows.push("", `\x1b[90mbalance\x1b[0m \x1b[33m${info.balance} SUI\x1b[0m`);
233
- rows.push("", `\x1b[90mlast\x1b[0m in ${info.lastTurnIn} out ${info.lastTurnOut}`, "", `\x1b[90mtotal\x1b[0m in ${totalIn} out ${totalOut}`, ` \x1b[33m$${cost}\x1b[0m`);
234
- return rows;
185
+ if (this.balance)
186
+ lines.push("", `{gray-fg}balance {/gray-fg}{yellow-fg}${this.balance} SUI{/yellow-fg}`);
187
+ lines.push("", `{gray-fg}last{/gray-fg} in ${this.lastTurnIn} out ${this.lastTurnOut}`, "", `{gray-fg}total{/gray-fg} in ${totalIn} out ${totalOut}`, ` {yellow-fg}$${cost}{/yellow-fg}`);
188
+ return lines.join("\n");
235
189
  }
236
- }
237
- function wrapText(text, width) {
238
- if (!text)
239
- return [""];
240
- const lines = [];
241
- for (const para of text.split("\n")) {
242
- const words = para.split(" ");
243
- let cur = "";
244
- for (const w of words) {
245
- if (w.length > width) {
246
- if (cur) {
247
- lines.push(cur);
248
- cur = "";
249
- }
250
- for (let i = 0; i < w.length; i += width)
251
- lines.push(w.slice(i, i + width));
252
- }
253
- else if (cur && cur.length + 1 + w.length > width) {
254
- lines.push(cur);
255
- cur = w;
256
- }
257
- else
258
- cur = cur ? `${cur} ${w}` : w;
259
- }
260
- if (cur)
261
- lines.push(cur);
190
+ renderFooter() {
191
+ const { agent } = this;
192
+ const totalIn = agent.usage.tokens.inputTokens;
193
+ const totalOut = agent.usage.tokens.outputTokens;
194
+ const cost = agent.usage.costUsd.toFixed(4);
195
+ this.footer.setContent(`{gray-fg}${agent.address.slice(0, 12)}… · in ${totalIn} out ${totalOut} $${cost} /exit{/gray-fg}`);
262
196
  }
263
- return lines.length > 0 ? lines : [""];
264
- }
265
- function stripAnsi(s) {
266
- // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape stripping
267
- return s.replace(/\x1b\[\d*;?\d*m/g, "");
268
- }
269
- function visibleLen(s) {
270
- // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape stripping
271
- const re = /\x1b\[\d*;?\d*m/g;
272
- let len = 0, last = 0, m = re.exec(s);
273
- while (m !== null) {
274
- len += m.index - last;
275
- last = m.index + m[0].length;
276
- m = re.exec(s);
197
+ async run(onLine) {
198
+ this.onLine = onLine;
199
+ this.input.focus();
200
+ this.screen.render();
201
+ return new Promise((resolve) => { this.resolve = resolve; });
277
202
  }
278
- return len + s.length - last;
279
- }
280
- function padRight(s, w) {
281
- const vl = visibleLen(s);
282
- return vl >= w ? s : s + " ".repeat(w - vl);
283
- }
284
- function padTrunc(s, w) {
285
- const vl = visibleLen(s);
286
- if (vl < w)
287
- return s + " ".repeat(w - vl);
288
- if (vl === w)
289
- return s;
290
- let out = "", visible = 0, i = 0;
291
- while (i < s.length && visible < w) {
292
- if (s[i] === "\x1b" && s[i + 1] === "[") {
293
- const end = s.indexOf("m", i);
294
- if (end !== -1) {
295
- out += s.slice(i, end + 1);
296
- i = end + 1;
297
- }
298
- else {
299
- out += s[i];
300
- i++;
301
- }
302
- }
303
- else {
304
- out += s[i];
305
- visible++;
306
- i++;
307
- }
203
+ shutdown() {
204
+ this.stopSpinner();
205
+ this.screen.destroy();
206
+ this.resolve?.();
308
207
  }
309
- return out;
310
208
  }
311
209
  function formatElapsed(ms) {
312
210
  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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sofer_agent/cli",
3
- "version": "0.3.20",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "sofer": "./bin/sofer"
@@ -27,7 +27,9 @@
27
27
  ],
28
28
  "dependencies": {
29
29
  "@clack/prompts": "^1.5.1",
30
- "@sofer_agent/core": "0.3.3"
30
+ "@sofer_agent/core": "0.3.3",
31
+ "@types/blessed": "^0.1.27",
32
+ "blessed": "^0.1.81"
31
33
  },
32
34
  "devDependencies": {
33
35
  "@types/node": "^22.10.2",
package/src/chat.ts CHANGED
@@ -69,6 +69,5 @@ export async function chatCommand(): Promise<void> {
69
69
  }
70
70
  agent.getBalance().then((b) => tui.setInfo({ balance: (Number(b) / 1e9).toFixed(4) })).catch(() => {});
71
71
  if (sp) saveSession(sp, agent.getHistory());
72
- tui.render();
73
72
  });
74
73
  }
package/src/tui.ts CHANGED
@@ -1,306 +1,230 @@
1
+ import blessed from "blessed";
1
2
  import type { SoferAgent, SoferConfig } from "@sofer_agent/core";
2
3
 
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
4
  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
5
 
28
6
  export class SoferTui {
29
- private state: ChatLine[] = [];
30
- private inputBuf = "";
31
- private columns = 90;
32
- private rows = 28;
33
- private chatW = 58;
34
- private sideW = 26;
35
- private bodyH = 22;
36
- private scrollOff = Number.MAX_SAFE_INTEGER;
7
+ private screen: ReturnType<typeof blessed.screen>;
8
+ private chat: ReturnType<typeof blessed.log>;
9
+ private input: ReturnType<typeof blessed.textbox>;
10
+ private sidebar: ReturnType<typeof blessed.box>;
11
+ private spinnerBox: ReturnType<typeof blessed.box>;
12
+ private footer: ReturnType<typeof blessed.box>;
37
13
  private status: "idle" | "thinking" = "idle";
14
+ private abortCtrl: AbortController | null = null;
38
15
  private spinnerFrame = 0;
39
16
  private spinnerTimer: ReturnType<typeof setInterval> | null = null;
40
17
  private turnStartedAt = 0;
41
- private abortCtrl: AbortController | null = null;
42
- private info: TuiInfo = { lastTurnIn: 0, lastTurnOut: 0 };
18
+ private lastTurnIn = 0;
19
+ private lastTurnOut = 0;
20
+ private balance?: string;
43
21
  private resolve: (() => void) | null = null;
44
22
  private onLine: ((line: string, signal?: AbortSignal) => Promise<void>) | null = null;
23
+ private agentName: string;
45
24
 
46
25
  constructor(
47
26
  private readonly agent: SoferAgent,
48
27
  private readonly config: SoferConfig,
49
- ) {}
28
+ ) {
29
+ this.agentName = agent.name.toLowerCase();
30
+
31
+ this.screen = blessed.screen({ smartCSR: true, title: "sofer" });
32
+
33
+ this.chat = blessed.log({
34
+ parent: this.screen,
35
+ top: 0,
36
+ left: 0,
37
+ width: "75%",
38
+ height: "100%-5",
39
+ border: { type: "line" },
40
+ label: ` ${this.agentName} `,
41
+ scrollable: true,
42
+ alwaysScroll: true,
43
+ scrollOnInput: true,
44
+ keys: true,
45
+ vi: true,
46
+ mouse: true,
47
+ tags: true,
48
+ });
49
+
50
+ this.sidebar = blessed.box({
51
+ parent: this.screen,
52
+ top: 0,
53
+ left: "75%",
54
+ width: "25%",
55
+ height: "100%-5",
56
+ border: { type: "line" },
57
+ label: " stats ",
58
+ content: this.buildSidebarContent(),
59
+ tags: true,
60
+ });
61
+
62
+ this.spinnerBox = blessed.box({
63
+ parent: this.screen,
64
+ bottom: 4,
65
+ left: 0,
66
+ width: "100%",
67
+ height: 1,
68
+ content: "",
69
+ tags: true,
70
+ });
71
+
72
+ this.input = blessed.textbox({
73
+ parent: this.screen,
74
+ bottom: 1,
75
+ left: 0,
76
+ width: "100%",
77
+ height: 3,
78
+ inputOnFocus: true,
79
+ border: { type: "line" },
80
+ label: " you ",
81
+ keys: true,
82
+ vi: true,
83
+ style: { focus: { border: { fg: "cyan" } } },
84
+ });
85
+
86
+ this.footer = blessed.box({
87
+ parent: this.screen,
88
+ bottom: 0,
89
+ left: 0,
90
+ width: "100%",
91
+ height: 1,
92
+ content: "",
93
+ tags: true,
94
+ });
95
+
96
+ this.renderFooter();
97
+
98
+ this.input.key(["enter"], () => this.submit());
99
+ this.input.key(["escape"], () => {
100
+ if (this.status === "thinking" && this.abortCtrl) {
101
+ this.abortCtrl.abort();
102
+ } else {
103
+ this.input.clearValue();
104
+ this.screen.render();
105
+ }
106
+ });
107
+ this.input.on("cancel", () => this.input.clearValue());
50
108
 
51
- private measure(): void {
52
- this.columns = Math.max(80, process.stdout.columns ?? 80);
53
- this.rows = Math.max(24, process.stdout.rows ?? 24);
54
- this.chatW = Math.min(120, Math.max(MIN_CHAT_W, this.columns - SIDEBAR_W - 3));
55
- this.sideW = this.columns - this.chatW - 3;
56
- this.bodyH = this.rows - 5;
109
+ this.screen.key(["C-c"], () => this.shutdown());
110
+ this.screen.key(["C-d"], () => {
111
+ if (this.input.getValue() === "") this.shutdown();
112
+ });
57
113
  }
58
114
 
59
- addMessage(role: ChatLine["role"], text: string): void {
60
- this.state.push({ role, text });
61
- this.scrollOff = Number.MAX_SAFE_INTEGER;
115
+ private submit(): void {
116
+ const text = this.input.getValue().trim();
117
+ this.input.clearValue();
118
+ this.screen.render();
119
+ if (!text) { this.input.focus(); return; }
120
+ if (text === "/exit" || text === "/quit") { this.shutdown(); return; }
121
+
122
+ this.chat.log(`{cyan-fg} you {/cyan-fg} ${text}`);
123
+ this.abortCtrl = new AbortController();
124
+ this.startSpinner();
125
+ this.screen.render();
126
+
127
+ this.onLine?.(text, this.abortCtrl.signal).finally(() => {
128
+ this.abortCtrl = null;
129
+ this.stopSpinner();
130
+ this.sidebar.setContent(this.buildSidebarContent());
131
+ this.renderFooter();
132
+ this.input.focus();
133
+ this.screen.render();
134
+ });
135
+ }
136
+
137
+ addMessage(role: string, text: string): void {
138
+ const color = role === "agent" ? "green-fg"
139
+ : role === "error" ? "red-fg"
140
+ : role === "system" ? "gray-fg"
141
+ : "cyan-fg";
142
+ const label = role === "agent" ? this.agentName
143
+ : role === "error" ? "err"
144
+ : role === "system" ? "sys"
145
+ : "you";
146
+ this.chat.log(`{${color}} ${label.padEnd(5)} {/${color}} ${text}`);
62
147
  }
63
148
 
64
- setInfo(info: Partial<TuiInfo>): void {
65
- Object.assign(this.info, info);
149
+ setInfo(info: { lastTurnIn?: number; lastTurnOut?: number; balance?: string }): void {
150
+ if (info.lastTurnIn !== undefined) this.lastTurnIn = info.lastTurnIn;
151
+ if (info.lastTurnOut !== undefined) this.lastTurnOut = info.lastTurnOut;
152
+ if (info.balance !== undefined) this.balance = info.balance;
66
153
  }
67
154
 
68
155
  private startSpinner(): void {
69
- if (this.spinnerTimer) return;
70
156
  this.status = "thinking";
71
157
  this.turnStartedAt = Date.now();
72
158
  this.spinnerFrame = 0;
73
159
  this.spinnerTimer = setInterval(() => {
74
160
  this.spinnerFrame = (this.spinnerFrame + 1) % SPINNER_FRAMES.length;
75
- this.render();
76
- }, SPINNER_MS);
161
+ this.renderSpinner();
162
+ this.screen.render();
163
+ }, 80);
77
164
  }
78
165
 
79
166
  private stopSpinner(): void {
80
167
  this.status = "idle";
81
168
  this.turnStartedAt = 0;
82
- if (this.spinnerTimer) {
83
- clearInterval(this.spinnerTimer);
84
- this.spinnerTimer = null;
85
- }
86
- }
87
-
88
- async run(onLine: (line: string, signal?: AbortSignal) => Promise<void>): Promise<void> {
89
- this.onLine = onLine;
90
- this.measure();
91
- if (process.stdin.isTTY) process.stdin.setRawMode?.(true);
92
- process.stdin.on("data", this.handleInput);
93
- process.stdout.on("resize", this.handleResize);
94
- process.on("SIGWINCH", this.handleResize);
95
- this.render();
96
- return new Promise<void>((resolve) => { this.resolve = resolve; });
97
- }
98
-
99
- private shutdown(): void {
100
- this.stopSpinner();
101
- process.stdin.setRawMode?.(false);
102
- process.stdin.removeAllListeners("data");
103
- process.stdout.removeAllListeners("resize");
104
- process.removeAllListeners("SIGWINCH");
105
- this.render();
106
- process.stdout.write("\n");
107
- this.resolve?.();
108
- }
109
-
110
- private handleInput = (data: Buffer): void => {
111
- for (const ch of data.toString()) {
112
- const code = ch.charCodeAt(0);
113
- if (code === 3) { this.shutdown(); return; }
114
- if (code === 4 && this.inputBuf.length === 0) { this.shutdown(); return; }
115
- if (code === 27) {
116
- if (this.status === "thinking" && this.abortCtrl) { this.abortCtrl.abort(); return; }
117
- this.inputBuf = "";
118
- this.render();
119
- return;
120
- }
121
- if (this.status === "thinking") continue;
122
- if (code === 13) { this.submit(); return; }
123
- if (code === 127) {
124
- this.inputBuf = this.inputBuf.slice(0, -1);
125
- this.render();
126
- return;
127
- }
128
- if (ch >= " ") { this.inputBuf += ch; this.render(); }
129
- }
130
- };
131
-
132
- private async submit(): Promise<void> {
133
- const line = this.inputBuf.trim();
134
- this.inputBuf = "";
135
- if (!line) { this.render(); return; }
136
- if (line === "/exit" || line === "/quit") { this.shutdown(); return; }
137
- this.addMessage("you", line);
138
- this.abortCtrl = new AbortController();
139
- this.startSpinner();
140
- this.render();
141
- await this.onLine?.(line, this.abortCtrl.signal);
142
- this.abortCtrl = null;
143
- this.stopSpinner();
144
- this.render();
145
- }
146
-
147
- private handleResize = (): void => { this.measure(); this.render(); };
148
-
149
- render(): void {
150
- this.measure();
151
- process.stdout.write("\x1b[?25l\x1b[2J\x1b[H" + this.buildFrame() + "\x1b[?25h");
169
+ if (this.spinnerTimer) { clearInterval(this.spinnerTimer); this.spinnerTimer = null; }
170
+ this.spinnerBox.setContent("");
152
171
  }
153
172
 
154
- private buildFrame(): string {
155
- const { columns, chatW, sideW, bodyH } = this;
156
- const innerSideW = sideW - 2;
157
- const sep = `${B.lt}${B.h.repeat(chatW)}${B.bt}${B.h.repeat(sideW)}${B.rt}`;
158
- const inputW = columns - 2;
159
-
160
- let buf = `${B.tl}${B.h.repeat(chatW)}${B.tt}${B.h.repeat(sideW)}${B.tr}\n`;
161
-
162
- const wrapped = this.state.flatMap((m) => this.wrapMessage(m, chatW));
163
- const maxScroll = Math.max(0, wrapped.length - bodyH);
164
- if (this.scrollOff > maxScroll) this.scrollOff = maxScroll;
165
- if (this.scrollOff < 0) this.scrollOff = 0;
166
- const visible = wrapped.slice(this.scrollOff, this.scrollOff + bodyH);
167
-
168
- const sidebarLines = this.buildSidebar(innerSideW);
169
- const sbTop = Math.max(0, Math.floor((bodyH - sidebarLines.length) / 2));
170
-
171
- for (let r = 0; r < bodyH; r++) {
172
- buf += B.v;
173
- const line = visible[r];
174
- if (line) buf += padTrunc(line, chatW);
175
- else buf += " ".repeat(chatW);
176
- buf += B.v;
177
- const sbIdx = r - sbTop;
178
- const sbLine = (sbIdx >= 0 && sbIdx < sidebarLines.length) ? sidebarLines[sbIdx]! : "";
179
- buf += ` ${padRight(sbLine, innerSideW)} `;
180
- buf += `${B.v}\n`;
181
- }
182
-
183
- buf += `${sep}\n`;
184
-
185
- if (this.status === "thinking") {
186
- const frame = SPINNER_FRAMES[this.spinnerFrame]!;
187
- const elapsed = this.turnStartedAt ? formatElapsed(Date.now() - this.turnStartedAt) : "";
188
- const st = ` ${frame} thinking…${elapsed ? ` ${elapsed}` : ""} (esc to interrupt)`;
189
- buf += `${B.v}\x1b[36m${st}\x1b[0m${" ".repeat(Math.max(0, columns - 2 - st.length - 2))}${B.v}\n`;
190
- }
191
-
192
- buf += `${B.tl}${B.h.repeat(inputW)}${B.tr}\n`;
193
- const cursorCh = this.status === "idle" ? "\x1b[5m▋\x1b[25m" : "";
194
- const inputMaxW = inputW - 4;
195
- const vi = this.inputBuf.slice(Math.max(0, this.inputBuf.length - inputMaxW));
196
- buf += `${B.v} \x1b[36m>\x1b[0m ${vi}${cursorCh}${" ".repeat(Math.max(0, inputMaxW - vi.length))} ${B.v}\n`;
197
- buf += `${B.bl}${B.h.repeat(inputW)}${B.br}\n`;
198
-
199
- const totalIn = this.agent.usage.tokens.inputTokens;
200
- const totalOut = this.agent.usage.tokens.outputTokens;
201
- const cost = this.agent.usage.costUsd.toFixed(4);
202
- const ft = `\x1b[90m${this.agent.address.slice(0, 10)}… · in ${totalIn} out ${totalOut} $${cost} /exit\x1b[0m`;
203
- buf += `${padTrunc(ft, columns)}\n`;
204
-
205
- const cursorRow = bodyH + 4 + (this.status === "thinking" ? 1 : 0);
206
- const cursorCol = 4 + Math.min(vi.length + (cursorCh ? 0 : 0), inputMaxW);
207
- buf += `\x1b[${cursorRow};${cursorCol}H`;
208
-
209
- return buf;
210
- }
211
-
212
- private wrapMessage(msg: ChatLine, width: number): string[] {
213
- const label = this.roleLabel(msg.role);
214
- const bodyWidth = Math.max(10, width - GUTTER.length - LABEL_W - 1);
215
- const lines = wrapText(msg.text, bodyWidth);
216
- return lines.map((l, i) => i === 0 ? `${GUTTER}${label} ${l}` : `${INDENT}${l}`);
217
- }
218
-
219
- private roleLabel(role: ChatLine["role"]): string {
220
- switch (role) {
221
- case "you": return "\x1b[36myou \x1b[0m";
222
- case "agent": return `\x1b[32m${this.agent.name.toLowerCase().padEnd(LABEL_W)}\x1b[0m`;
223
- case "system": return "\x1b[90msys \x1b[0m";
224
- case "error": return "\x1b[31merr \x1b[0m";
225
- }
173
+ private renderSpinner(): void {
174
+ const frame = SPINNER_FRAMES[this.spinnerFrame]!;
175
+ const elapsed = this.turnStartedAt ? formatElapsed(Date.now() - this.turnStartedAt) : "";
176
+ this.spinnerBox.setContent(
177
+ `{cyan-fg}${frame} thinking…${elapsed ? ` ${elapsed}` : ""} (esc to interrupt){/cyan-fg}`,
178
+ );
226
179
  }
227
180
 
228
- private buildSidebar(width: number): string[] {
229
- const { agent, config, info } = this;
181
+ private buildSidebarContent(): string {
182
+ const { agent, config } = this;
230
183
  const addr = `${agent.address.slice(0, 6)}…${agent.address.slice(-4)}`;
184
+ const cost = agent.usage.costUsd.toFixed(6);
231
185
  const totalIn = agent.usage.tokens.inputTokens;
232
186
  const totalOut = agent.usage.tokens.outputTokens;
233
- const cost = agent.usage.costUsd.toFixed(6);
234
187
 
235
- const rows = [
236
- `\x1b[1;36m${agent.name}\x1b[0m`,
237
- `\x1b[90m${addr}\x1b[0m`,
188
+ const lines = [
189
+ `{bold}{green-fg}${agent.name}{/green-fg}{/bold}`,
190
+ `{gray-fg}${addr}{/gray-fg}`,
238
191
  "",
239
- `${B.h.repeat(width)}`,
240
- `\x1b[90mnetwork\x1b[0m ${config.network}`,
241
- `\x1b[90mmodel\x1b[0m ${shortModel(config.brain.model)}`,
192
+ `{gray-fg}network ${config.network}{/gray-fg}`,
193
+ `{gray-fg}model ${shortModel(config.brain.model)}{/gray-fg}`,
242
194
  ];
243
- if (info.balance) rows.push("", `\x1b[90mbalance\x1b[0m \x1b[33m${info.balance} SUI\x1b[0m`);
244
- rows.push(
195
+ if (this.balance) lines.push("", `{gray-fg}balance {/gray-fg}{yellow-fg}${this.balance} SUI{/yellow-fg}`);
196
+ lines.push(
245
197
  "",
246
- `\x1b[90mlast\x1b[0m in ${info.lastTurnIn} out ${info.lastTurnOut}`,
198
+ `{gray-fg}last{/gray-fg} in ${this.lastTurnIn} out ${this.lastTurnOut}`,
247
199
  "",
248
- `\x1b[90mtotal\x1b[0m in ${totalIn} out ${totalOut}`,
249
- ` \x1b[33m$${cost}\x1b[0m`,
200
+ `{gray-fg}total{/gray-fg} in ${totalIn} out ${totalOut}`,
201
+ ` {yellow-fg}$${cost}{/yellow-fg}`,
250
202
  );
251
- return rows;
203
+ return lines.join("\n");
252
204
  }
253
- }
254
205
 
255
- function wrapText(text: string, width: number): string[] {
256
- if (!text) return [""];
257
- const lines: string[] = [];
258
- for (const para of text.split("\n")) {
259
- const words = para.split(" ");
260
- let cur = "";
261
- for (const w of words) {
262
- if (w.length > width) {
263
- if (cur) { lines.push(cur); cur = ""; }
264
- for (let i = 0; i < w.length; i += width) lines.push(w.slice(i, i + width));
265
- } else if (cur && cur.length + 1 + w.length > width) { lines.push(cur); cur = w; }
266
- else cur = cur ? `${cur} ${w}` : w;
267
- }
268
- if (cur) lines.push(cur);
206
+ private renderFooter(): void {
207
+ const { agent } = this;
208
+ const totalIn = agent.usage.tokens.inputTokens;
209
+ const totalOut = agent.usage.tokens.outputTokens;
210
+ const cost = agent.usage.costUsd.toFixed(4);
211
+ this.footer.setContent(
212
+ `{gray-fg}${agent.address.slice(0, 12)}… · in ${totalIn} out ${totalOut} $${cost} /exit{/gray-fg}`,
213
+ );
269
214
  }
270
- return lines.length > 0 ? lines : [""];
271
- }
272
-
273
- function stripAnsi(s: string): string {
274
- // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape stripping
275
- return s.replace(/\x1b\[\d*;?\d*m/g, "");
276
- }
277
-
278
- function visibleLen(s: string): number {
279
- // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape stripping
280
- const re = /\x1b\[\d*;?\d*m/g;
281
- let len = 0, last = 0, m = re.exec(s);
282
- while (m !== null) { len += m.index - last; last = m.index + m[0].length; m = re.exec(s); }
283
- return len + s.length - last;
284
- }
285
215
 
286
- function padRight(s: string, w: number): string {
287
- const vl = visibleLen(s);
288
- return vl >= w ? s : s + " ".repeat(w - vl);
289
- }
216
+ async run(onLine: (line: string, signal?: AbortSignal) => Promise<void>): Promise<void> {
217
+ this.onLine = onLine;
218
+ this.input.focus();
219
+ this.screen.render();
220
+ return new Promise<void>((resolve) => { this.resolve = resolve; });
221
+ }
290
222
 
291
- function padTrunc(s: string, w: number): string {
292
- const vl = visibleLen(s);
293
- if (vl < w) return s + " ".repeat(w - vl);
294
- if (vl === w) return s;
295
- let out = "", visible = 0, i = 0;
296
- while (i < s.length && visible < w) {
297
- if (s[i] === "\x1b" && s[i + 1] === "[") {
298
- const end = s.indexOf("m", i);
299
- if (end !== -1) { out += s.slice(i, end + 1); i = end + 1; }
300
- else { out += s[i]; i++; }
301
- } else { out += s[i]; visible++; i++; }
223
+ private shutdown(): void {
224
+ this.stopSpinner();
225
+ this.screen.destroy();
226
+ this.resolve?.();
302
227
  }
303
- return out;
304
228
  }
305
229
 
306
230
  function formatElapsed(ms: number): string {