chivgent 0.19.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,75 @@
1
+ import { fitLine } from "./text.js";
2
+ /** A small transient region beneath readline, with the cursor left in the draft. */
3
+ export class InputMenu {
4
+ readline;
5
+ output;
6
+ items = [];
7
+ selected = 0;
8
+ reserved = 0;
9
+ painted = 0;
10
+ constructor(readline, output) {
11
+ this.readline = readline;
12
+ this.output = output;
13
+ }
14
+ get active() { return this.items.length > 0; }
15
+ get selection() { return this.items[this.selected]?.value; }
16
+ show(items, preserveSelection = false) {
17
+ const previous = this.selection;
18
+ this.clear();
19
+ this.items = items;
20
+ this.selected = preserveSelection ? Math.max(0, items.findIndex((item) => item.value === previous)) : 0;
21
+ if (items.length === 0)
22
+ return;
23
+ const height = Math.min(items.length, 12, Math.max(0, (this.output.rows ?? 24) - 2));
24
+ if (height === 0)
25
+ return;
26
+ if (height > this.reserved) {
27
+ const extra = height - this.reserved;
28
+ const column = this.readline.getCursorPos().cols + 1;
29
+ this.output.write("\r\n".repeat(extra) + `\u001b[${extra}A\u001b[${column}G`);
30
+ this.reserved = height;
31
+ }
32
+ const start = Math.max(0, Math.min(this.selected - height + 1, items.length - height));
33
+ const width = Math.max(1, (this.output.columns ?? 80) - 1);
34
+ this.output.write("\u001b7" + this.belowInput());
35
+ for (let index = 0; index < height; index++) {
36
+ const itemIndex = start + index;
37
+ const item = items[itemIndex];
38
+ this.output.write(`\r\u001b[2K${fitLine(`${itemIndex === this.selected ? "❯" : " "} ${item?.label ?? ""}`, width)}`);
39
+ if (index < height - 1)
40
+ this.output.write("\u001b[1B");
41
+ }
42
+ this.output.write("\u001b8");
43
+ this.painted = height;
44
+ }
45
+ move(delta) {
46
+ if (!this.active)
47
+ return;
48
+ this.selected = (this.selected + delta + this.items.length) % this.items.length;
49
+ this.show(this.items, true);
50
+ }
51
+ clear() {
52
+ if (this.painted > 0) {
53
+ this.output.write("\u001b7" + this.belowInput());
54
+ for (let index = 0; index < this.painted; index++) {
55
+ this.output.write("\r\u001b[2K");
56
+ if (index < this.painted - 1)
57
+ this.output.write("\u001b[1B");
58
+ }
59
+ this.output.write("\u001b8");
60
+ }
61
+ this.painted = 0;
62
+ this.items = [];
63
+ }
64
+ reset() {
65
+ this.clear();
66
+ this.reserved = 0;
67
+ }
68
+ belowInput() {
69
+ const columns = Math.max(1, this.output.columns ?? 80);
70
+ const endRow = Math.floor((2 + this.readline.line.length) / columns);
71
+ const distance = Math.max(1, endRow - this.readline.getCursorPos().rows + 1);
72
+ return `\u001b[${distance}B\r`;
73
+ }
74
+ }
75
+ //# sourceMappingURL=menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/tui/menu.ts"],"names":[],"mappings":"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"}
@@ -4,4 +4,6 @@ export declare function terminalText(text: string): string;
4
4
  export { stringWidth as displayWidth };
5
5
  /** Fit terminal cells, preserving whole graphemes (including joined emoji). */
6
6
  export declare function fitLine(text: string, columns: number): string;
7
+ /** Show the newest part of a changing line, keeping whole terminal cells. */
8
+ export declare function fitLineTail(text: string, columns: number): string;
7
9
  //# sourceMappingURL=text.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/tui/text.ts"],"names":[],"mappings":"AACA,OAAO,WAAW,MAAM,cAAc,CAAC;AAIvC,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,CAAC;AAEvC,+EAA+E;AAC/E,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAc7D"}
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/tui/text.ts"],"names":[],"mappings":"AACA,OAAO,WAAW,MAAM,cAAc,CAAC;AAIvC,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,CAAC;AAEvC,+EAA+E;AAC/E,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAc7D;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAcjE"}
package/dist/tui/text.js CHANGED
@@ -28,4 +28,23 @@ export function fitLine(text, columns) {
28
28
  }
29
29
  return `${result}…`;
30
30
  }
31
+ /** Show the newest part of a changing line, keeping whole terminal cells. */
32
+ export function fitLineTail(text, columns) {
33
+ const width = Math.max(0, Math.floor(columns));
34
+ const clean = terminalText(text).replace(/\n/g, " ");
35
+ if (width === 0)
36
+ return "";
37
+ if (stringWidth(clean) <= width)
38
+ return clean;
39
+ let result = "";
40
+ let used = 0;
41
+ for (const { segment } of [...graphemes.segment(clean)].reverse()) {
42
+ const size = stringWidth(segment);
43
+ if (used + size > width - 1)
44
+ break;
45
+ result = segment + result;
46
+ used += size;
47
+ }
48
+ return `…${result}`;
49
+ }
31
50
  //# sourceMappingURL=text.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/tui/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,WAAW,MAAM,cAAc,CAAC;AAEvC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;AAE7E,iFAAiF;AACjF,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,wBAAwB,CAAC,IAAI,CAAC;SAClC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC;SACtB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC;SACpB,OAAO,CAAC,4CAA4C,EAAE,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,CAAC;AAEvC,+EAA+E;AAC/E,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,OAAe;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3B,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC;YAAE,MAAM;QACnC,MAAM,IAAI,OAAO,CAAC;QAClB,IAAI,IAAI,IAAI,CAAC;IACf,CAAC;IACD,OAAO,GAAG,MAAM,GAAG,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/tui/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,WAAW,MAAM,cAAc,CAAC;AAEvC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;AAE7E,iFAAiF;AACjF,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,wBAAwB,CAAC,IAAI,CAAC;SAClC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC;SACtB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC;SACpB,OAAO,CAAC,4CAA4C,EAAE,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,CAAC;AAEvC,+EAA+E;AAC/E,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,OAAe;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3B,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC;YAAE,MAAM;QACnC,MAAM,IAAI,OAAO,CAAC;QAClB,IAAI,IAAI,IAAI,CAAC;IACf,CAAC;IACD,OAAO,GAAG,MAAM,GAAG,CAAC;AACtB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,OAAe;IACvD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3B,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAClE,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC;YAAE,MAAM;QACnC,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;QAC1B,IAAI,IAAI,IAAI,CAAC;IACf,CAAC;IACD,OAAO,IAAI,MAAM,EAAE,CAAC;AACtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/tui/view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAIjD,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,YAAY,CAAC;AAQzD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAmBD;;;;;;GAMG;AACH,wBAAgB,IAAI,CAClB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,WAAW,GACnB,SAAS,MAAM,EAAE,CAqCnB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,MAAM,EAAE,CActE"}
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/tui/view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAIjD,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,YAAY,CAAC;AAQzD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AA2DD;;;;;;GAMG;AACH,wBAAgB,IAAI,CAClB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,WAAW,GACnB,SAAS,MAAM,EAAE,CAwBnB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,MAAM,EAAE,CActE"}
package/dist/tui/view.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { formatTokens } from "../providers/usage.js";
2
2
  import { callTarget } from "../tools/target.js";
3
- import { fitLine } from "./text.js";
3
+ import { displayWidth, fitLine, fitLineTail, terminalText } from "./text.js";
4
4
  /** Tools listed individually before the rest are summarised as a count. */
5
5
  const MAX_LISTED_TOOLS = 3;
6
6
  /** Lines of the answer kept visible while it streams. */
@@ -12,13 +12,58 @@ function elapsed(from, now) {
12
12
  }
13
13
  return `${Math.floor(seconds / 60)}m${String(seconds % 60).padStart(2, "0")}s`;
14
14
  }
15
- function describeTool(tool, now) {
16
- const head = tool.target === undefined ? tool.name : `${tool.name} ${tool.target}`;
17
- // The newest line of a tool's output says more than its first, and a running
18
- // command's interesting output is at the end.
19
- const latest = tool.progress.split("\n").filter((line) => line.length > 0).at(-1);
20
- const suffix = latest === undefined ? "" : ` ${latest}`;
21
- return ` ${head} (${elapsed(tool.startedAt, now)})${suffix}`;
15
+ function toolHead(tool, now, width) {
16
+ const prefix = ` ${terminalText(tool.name)}`;
17
+ const duration = ` (${elapsed(tool.startedAt, now)})`;
18
+ if (displayWidth(prefix) + displayWidth(duration) > width)
19
+ return fitLine(prefix, width);
20
+ if (tool.target === undefined)
21
+ return fitLine(`${prefix}${duration}`, width);
22
+ const targetWidth = width - displayWidth(prefix) - displayWidth(duration) - 1;
23
+ if (targetWidth < 2)
24
+ return fitLine(`${prefix}${duration}`, width);
25
+ return `${prefix} ${fitLineTail(tool.target, targetWidth)}${duration}`;
26
+ }
27
+ function describeTool(tool, now, width) {
28
+ // Preserve the tool name, the end of a long path, and the latest progress.
29
+ const latest = terminalText(tool.progress.split("\n").filter((line) => line.length > 0).at(-1) ?? "");
30
+ if (latest.length === 0)
31
+ return toolHead(tool, now, width);
32
+ const fullHead = toolHead(tool, now, width);
33
+ if (displayWidth(fullHead) + 2 + displayWidth(latest) <= width) {
34
+ return `${fullHead} ${latest}`;
35
+ }
36
+ const progressWidth = Math.max(6, Math.floor(width * 0.35));
37
+ if (width - progressWidth < 14)
38
+ return fullHead;
39
+ return `${toolHead(tool, now, width - progressWidth - 2)} ${fitLineTail(latest, progressWidth)}`;
40
+ }
41
+ function statusLine(run, now, width) {
42
+ const status = run.status === "thinking" ? "thinking" : "running tools";
43
+ const shortStatus = run.status === "thinking" ? "thinking" : "tools";
44
+ const duration = elapsed(run.startedAt, now);
45
+ const usage = run.usage;
46
+ const tokens = usage !== undefined && usage.usage.totalTokens > 0
47
+ ? `${formatTokens(usage.usage.totalTokens)} tokens${usage.complete ? "" : "+"}`
48
+ : undefined;
49
+ const candidates = [
50
+ [status, `turn ${run.turn}/${run.maxTurns}`, duration, ...(tokens === undefined ? [] : [tokens]), "ctrl+c to stop"],
51
+ [status, `turn ${run.turn}/${run.maxTurns}`, duration, "ctrl+c to stop"],
52
+ [status, `${run.turn}/${run.maxTurns}`, duration, "^C stop"],
53
+ [status, duration, "^C stop"],
54
+ [shortStatus, duration, "^C stop"],
55
+ [shortStatus, "^C stop"],
56
+ ];
57
+ for (const parts of candidates) {
58
+ const line = parts.join(" · ");
59
+ if (displayWidth(line) <= width)
60
+ return line;
61
+ }
62
+ for (const line of [`${shortStatus} ^C stop`, `${shortStatus} ^C`]) {
63
+ if (displayWidth(line) <= width)
64
+ return line;
65
+ }
66
+ return fitLine("^C stop", width);
22
67
  }
23
68
  /**
24
69
  * Renders the live region. Pure: no terminal, no clock, no colour.
@@ -33,29 +78,18 @@ export function view(state, options) {
33
78
  return [];
34
79
  }
35
80
  const lines = [];
36
- const tail = run.text.split("\n").slice(-MAX_TEXT_LINES);
81
+ const tail = run.text.split("\n").filter((line) => line.length > 0).slice(-MAX_TEXT_LINES);
37
82
  for (const line of tail) {
38
- if (line.length > 0) {
39
- lines.push(fitLine(line, options.width));
40
- }
83
+ lines.push(fitLineTail(line, options.width));
41
84
  }
42
85
  for (const tool of run.running.slice(0, MAX_LISTED_TOOLS)) {
43
- lines.push(fitLine(describeTool(tool, options.now), options.width));
86
+ lines.push(describeTool(tool, options.now, options.width));
44
87
  }
45
88
  const hidden = run.running.length - MAX_LISTED_TOOLS;
46
89
  if (hidden > 0) {
47
90
  lines.push(fitLine(` and ${hidden} more`, options.width));
48
91
  }
49
- const status = [
50
- run.status === "thinking" ? "thinking" : "running tools",
51
- `turn ${run.turn}/${run.maxTurns}`,
52
- elapsed(run.startedAt, options.now),
53
- ];
54
- if (run.usage !== undefined && run.usage.usage.totalTokens > 0) {
55
- status.push(`${formatTokens(run.usage.usage.totalTokens)} tokens${run.usage.complete ? "" : "+"}`);
56
- }
57
- status.push("ctrl+c to stop");
58
- lines.push(fitLine(status.join(" · "), options.width));
92
+ lines.push(statusLine(run, options.now, options.width));
59
93
  return lines.slice(-Math.max(1, options.height ?? lines.length));
60
94
  }
61
95
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/tui/view.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/tui/view.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,11 @@ export interface WelcomeOptions {
3
3
  readonly provider: string;
4
4
  readonly model: string;
5
5
  readonly cwd: string;
6
- readonly sessionId: string;
7
6
  readonly resumed: boolean;
8
7
  readonly signedOut: boolean;
8
+ readonly setupIssue?: "model" | "base-url";
9
9
  readonly width: number;
10
+ readonly color?: boolean;
10
11
  }
11
12
  export declare function welcome(options: WelcomeOptions): string;
12
13
  //# sourceMappingURL=welcome.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"welcome.d.ts","sourceRoot":"","sources":["../../src/tui/welcome.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAyBvD"}
1
+ {"version":3,"file":"welcome.d.ts","sourceRoot":"","sources":["../../src/tui/welcome.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AASD,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAqBvD"}
@@ -1,28 +1,30 @@
1
- import { displayWidth, fitLine } from "./text.js";
1
+ import { fitLine, fitLineTail } from "./text.js";
2
+ const glyphs = {
3
+ C: ["█▀▀", "█ ", "█▄▄"], H: ["█ █", "█▀█", "█ █"], I: ["█", "█", "█"],
4
+ V: ["█ █", "█ █", " ▀ "], G: ["█▀▀", "█ ▄", "█▄█"], E: ["█▀▀", "█▀ ", "█▄▄"],
5
+ N: ["█▄█", "█▀█", "█ █"], T: ["▀█▀", " █ ", " █ "],
6
+ };
7
+ const wordmark = [0, 1, 2].map((row) => [..."CHIVGENT"].map((letter) => glyphs[letter]?.[row] ?? "").join(" "));
2
8
  export function welcome(options) {
3
- const width = Math.max(1, Math.min(88, options.width - 1));
4
- const content = [
5
- `chivgent ${options.version} · coding assistant`,
6
- `${options.provider} / ${options.model}`,
7
- `Workspace ${options.cwd}`,
8
- `${options.resumed ? "Resumed" : "Session"} ${options.sessionId}`,
9
- "",
10
- options.signedOut ? "Run /login to add your API key." : "Ready. Describe what you want to build.",
11
- "Tab commands · ↑ history · Ctrl+C stop · Ctrl+D exit",
9
+ const width = Math.max(1, options.width - 1);
10
+ const brand = width >= 38 ? wordmark.map((row) => ` ${row}`) : [" ◆ chivgent"];
11
+ const lines = [
12
+ ...brand,
13
+ ` v${options.version}${options.resumed ? " · continued session" : ""}`,
14
+ ` ${options.provider} / ${options.model}`,
15
+ ` ${fitLineTail(options.cwd, width - 2)}`,
16
+ options.setupIssue === "model"
17
+ ? " Set a model with /model MODEL"
18
+ : options.setupIssue === "base-url"
19
+ ? " Set the API URL with /endpoint URL"
20
+ : options.signedOut
21
+ ? " Start with /provider → choose a Provider"
22
+ : " Ready. Type a task or use /provider to switch.",
23
+ " / commands · ↑↓ select · Ctrl+C exit",
12
24
  ];
13
- if (width < 12) {
14
- return `${content.map((line) => fitLine(line, width)).join("\n")}\n`;
15
- }
16
- const inner = width - 4;
17
- const lines = content.map((line) => {
18
- const fitted = fitLine(line, inner);
19
- return `│ ${fitted}${" ".repeat(inner - displayWidth(fitted))} │`;
20
- });
21
- return [
22
- `╭${"─".repeat(width - 2)}╮`,
23
- ...lines,
24
- `╰${"─".repeat(width - 2)}╯`,
25
- "",
26
- ].join("\n");
25
+ return `\n${lines.map((line, index) => {
26
+ const fitted = fitLine(line, width);
27
+ return options.color && index < brand.length ? `\u001b[1;36m${fitted}\u001b[0m` : fitted;
28
+ }).join("\n")}\n\n`;
27
29
  }
28
30
  //# sourceMappingURL=welcome.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"welcome.js","sourceRoot":"","sources":["../../src/tui/welcome.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAalD,MAAM,UAAU,OAAO,CAAC,OAAuB;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG;QACd,YAAY,OAAO,CAAC,OAAO,uBAAuB;QAClD,GAAG,OAAO,CAAC,QAAQ,MAAM,OAAO,CAAC,KAAK,EAAE;QACxC,cAAc,OAAO,CAAC,GAAG,EAAE;QAC3B,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,OAAO,OAAO,CAAC,SAAS,EAAE;QACpE,EAAE;QACF,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,yCAAyC;QACjG,sDAAsD;KACvD,CAAC;IACF,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;QACf,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACvE,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC;IACxB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACjC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACpC,OAAO,KAAK,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;IACpE,CAAC,CAAC,CAAC;IACH,OAAO;QACL,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG;QAC5B,GAAG,KAAK;QACR,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG;QAC5B,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"welcome.js","sourceRoot":"","sources":["../../src/tui/welcome.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAcjD,MAAM,MAAM,GAAsC;IAChD,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACtE,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAC5E,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;CACnD,CAAC;AACF,MAAM,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEhH,MAAM,UAAU,OAAO,CAAC,OAAuB;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IACjF,MAAM,KAAK,GAAG;QACZ,GAAG,KAAK;QACR,MAAM,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,EAAE;QACzE,KAAK,OAAO,CAAC,QAAQ,MAAM,OAAO,CAAC,KAAK,EAAE;QAC1C,KAAK,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE;QAC1C,OAAO,CAAC,UAAU,KAAK,OAAO;YAC5B,CAAC,CAAC,iCAAiC;YACnC,CAAC,CAAC,OAAO,CAAC,UAAU,KAAK,UAAU;gBACjC,CAAC,CAAC,sCAAsC;gBACxC,CAAC,CAAC,OAAO,CAAC,SAAS;oBACjB,CAAC,CAAC,4CAA4C;oBAC9C,CAAC,CAAC,kDAAkD;QAC1D,4CAA4C;KAC7C,CAAC;IACF,OAAO,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACpC,OAAO,OAAO,CAAC,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,MAAM,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3F,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;AACtB,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "chivgent",
3
- "version": "0.19.0",
4
- "description": "A minimal coding agent CLI built to learn agent harness architecture.",
3
+ "version": "1.0.0",
4
+ "description": "A terminal coding agent with a streaming TUI and configurable AI providers.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",