moderado 0.4.34 → 0.4.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/commands/chat.d.ts +7 -70
  2. package/dist/commands/chat.d.ts.map +1 -1
  3. package/dist/commands/chat.js +279 -453
  4. package/dist/commands/chat.js.map +1 -1
  5. package/dist/commands/chat_meta.d.ts +36 -0
  6. package/dist/commands/chat_meta.d.ts.map +1 -0
  7. package/dist/commands/chat_meta.js +102 -0
  8. package/dist/commands/chat_meta.js.map +1 -0
  9. package/dist/commands/chat_outcome.d.ts +31 -0
  10. package/dist/commands/chat_outcome.d.ts.map +1 -0
  11. package/dist/commands/chat_outcome.js +70 -0
  12. package/dist/commands/chat_outcome.js.map +1 -0
  13. package/dist/commands/chat_search.d.ts +24 -0
  14. package/dist/commands/chat_search.d.ts.map +1 -0
  15. package/dist/commands/chat_search.js +61 -0
  16. package/dist/commands/chat_search.js.map +1 -0
  17. package/dist/commands/chat_slash.d.ts +17 -0
  18. package/dist/commands/chat_slash.d.ts.map +1 -0
  19. package/dist/commands/chat_slash.js +109 -0
  20. package/dist/commands/chat_slash.js.map +1 -0
  21. package/dist/commands/run.d.ts.map +1 -1
  22. package/dist/commands/run.js +25 -1
  23. package/dist/commands/run.js.map +1 -1
  24. package/dist/config.d.ts +1 -1
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/config.js +18 -2
  27. package/dist/config.js.map +1 -1
  28. package/dist/diagnostic_log.d.ts.map +1 -1
  29. package/dist/diagnostic_log.js +1 -0
  30. package/dist/diagnostic_log.js.map +1 -1
  31. package/dist/sessions.d.ts.map +1 -1
  32. package/dist/sessions.js +5 -1
  33. package/dist/sessions.js.map +1 -1
  34. package/dist/transcript.d.ts +19 -0
  35. package/dist/transcript.d.ts.map +1 -0
  36. package/dist/transcript.js +76 -0
  37. package/dist/transcript.js.map +1 -0
  38. package/dist/turn_summary.d.ts +76 -0
  39. package/dist/turn_summary.d.ts.map +1 -0
  40. package/dist/turn_summary.js +305 -0
  41. package/dist/turn_summary.js.map +1 -0
  42. package/dist/ui/box.d.ts +19 -0
  43. package/dist/ui/box.d.ts.map +1 -1
  44. package/dist/ui/box.js +119 -12
  45. package/dist/ui/box.js.map +1 -1
  46. package/dist/ui/chart.d.ts +2 -0
  47. package/dist/ui/chart.d.ts.map +1 -0
  48. package/dist/ui/chart.js +97 -0
  49. package/dist/ui/chart.js.map +1 -0
  50. package/dist/ui/composer.d.ts +80 -0
  51. package/dist/ui/composer.d.ts.map +1 -0
  52. package/dist/ui/composer.js +883 -0
  53. package/dist/ui/composer.js.map +1 -0
  54. package/dist/ui/help_content.d.ts +2 -2
  55. package/dist/ui/help_content.d.ts.map +1 -1
  56. package/dist/ui/help_content.js +5 -3
  57. package/dist/ui/help_content.js.map +1 -1
  58. package/dist/ui/model_selector.d.ts +1 -0
  59. package/dist/ui/model_selector.d.ts.map +1 -1
  60. package/dist/ui/model_selector.js +61 -18
  61. package/dist/ui/model_selector.js.map +1 -1
  62. package/dist/ui/popup.d.ts.map +1 -1
  63. package/dist/ui/popup.js +7 -0
  64. package/dist/ui/popup.js.map +1 -1
  65. package/dist/ui/provider_connect.d.ts +8 -0
  66. package/dist/ui/provider_connect.d.ts.map +1 -1
  67. package/dist/ui/provider_connect.js +81 -23
  68. package/dist/ui/provider_connect.js.map +1 -1
  69. package/dist/ui/renderer.d.ts +49 -4
  70. package/dist/ui/renderer.d.ts.map +1 -1
  71. package/dist/ui/renderer.js +167 -31
  72. package/dist/ui/renderer.js.map +1 -1
  73. package/dist/ui/terminal_approval.d.ts +21 -0
  74. package/dist/ui/terminal_approval.d.ts.map +1 -1
  75. package/dist/ui/terminal_approval.js +145 -47
  76. package/dist/ui/terminal_approval.js.map +1 -1
  77. package/dist/ui/welcome.d.ts +274 -69
  78. package/dist/ui/welcome.d.ts.map +1 -1
  79. package/dist/ui/welcome.js +729 -700
  80. package/dist/ui/welcome.js.map +1 -1
  81. package/dist/vendor/providers/presets.d.ts +16 -0
  82. package/dist/vendor/providers/presets.d.ts.map +1 -1
  83. package/dist/vendor/providers/presets.js +13 -0
  84. package/dist/vendor/providers/presets.js.map +1 -1
  85. package/dist/vendor/tools/checkpoints.js +5 -5
  86. package/dist/vendor/tools/checkpoints.js.map +1 -1
  87. package/dist/vendor/tools/jail.d.ts +8 -0
  88. package/dist/vendor/tools/jail.d.ts.map +1 -1
  89. package/dist/vendor/tools/jail.js +13 -2
  90. package/dist/vendor/tools/jail.js.map +1 -1
  91. package/dist/vendor/tools/tools/apply_patch.d.ts.map +1 -1
  92. package/dist/vendor/tools/tools/apply_patch.js +6 -3
  93. package/dist/vendor/tools/tools/apply_patch.js.map +1 -1
  94. package/dist/vendor/tools/tools/git_diff.d.ts.map +1 -1
  95. package/dist/vendor/tools/tools/git_diff.js +5 -3
  96. package/dist/vendor/tools/tools/git_diff.js.map +1 -1
  97. package/package.json +1 -1
package/dist/ui/box.js CHANGED
@@ -20,24 +20,117 @@ function isWideCodePoint(code) {
20
20
  (code >= 0x1f900 && code <= 0x1f9ff) ||
21
21
  (code >= 0x20000 && code <= 0x3fffd));
22
22
  }
23
+ /**
24
+ * One terminal cluster: a code point plus any trailing variation selectors or
25
+ * combining marks, with the cells it occupies.
26
+ *
27
+ * The variation selector matters more than it looks: `⚠` is a narrow glyph, but
28
+ * `⚠️` (U+26A0 U+FE0F) asks for emoji presentation and terminals draw it two
29
+ * cells wide. Counting it as one made every approval-box border one cell short
30
+ * of its own top row — the box appeared to spill out of the frame.
31
+ */
32
+ function nextCluster(text, index) {
33
+ const code = text.codePointAt(index) ?? 0;
34
+ let cluster = String.fromCodePoint(code);
35
+ let cursor = index + cluster.length;
36
+ let emojiPresentation = false;
37
+ while (cursor < text.length) {
38
+ const next = text.codePointAt(cursor) ?? 0;
39
+ const isVariationSelector = next >= 0xfe00 && next <= 0xfe0f;
40
+ const isCombining = next >= 0x0300 && next <= 0x036f;
41
+ if (!isVariationSelector && !isCombining)
42
+ break;
43
+ if (next === 0xfe0f)
44
+ emojiPresentation = true;
45
+ const piece = String.fromCodePoint(next);
46
+ cluster += piece;
47
+ cursor += piece.length;
48
+ }
49
+ const cells = code === 0x200b ? 0 : emojiPresentation || isWideCodePoint(code) ? 2 : 1;
50
+ return { text: cluster, cells };
51
+ }
23
52
  /**
24
53
  * Terminal cells occupied by a string. Wide (CJK, emoji) glyphs count as two
25
54
  * columns and combining marks as zero, so box borders stay aligned when the
26
55
  * workspace path or the task text is not ASCII.
27
56
  */
28
57
  export function displayWidth(text) {
58
+ const plain = stripAnsi(text);
29
59
  let width = 0;
30
- for (const char of stripAnsi(text)) {
31
- const code = char.codePointAt(0) ?? 0;
32
- if (code === 0x200b || (code >= 0x0300 && code <= 0x036f) || (code >= 0xfe00 && code <= 0xfe0f))
33
- continue;
34
- width += isWideCodePoint(code) ? 2 : 1;
60
+ for (let index = 0; index < plain.length;) {
61
+ const cluster = nextCluster(plain, index);
62
+ width += cluster.cells;
63
+ index += cluster.text.length;
35
64
  }
36
65
  return width;
37
66
  }
38
67
  export function getVisibleWidth(text) {
39
68
  return displayWidth(text);
40
69
  }
70
+ /** Match an ANSI escape sequence at the start of `text`, if any. */
71
+ const ANSI_AT_START = /^\x1b\[[0-9;?]*[a-zA-Z]/;
72
+ /**
73
+ * Keep the first `max` terminal cells of `text`.
74
+ *
75
+ * `String#slice` counts UTF-16 units, so a CJK or emoji line looks short to it
76
+ * while occupying twice the cells — which is how a status line used to spill
77
+ * past the card and wrap onto the row below. Escape sequences are copied
78
+ * through without being counted.
79
+ */
80
+ export function sliceToWidth(text, max) {
81
+ if (max <= 0)
82
+ return '';
83
+ let width = 0;
84
+ let out = '';
85
+ for (let i = 0; i < text.length;) {
86
+ if (text[i] === '\x1b') {
87
+ const escape = ANSI_AT_START.exec(text.slice(i));
88
+ if (escape) {
89
+ out += escape[0];
90
+ i += escape[0].length;
91
+ continue;
92
+ }
93
+ }
94
+ const cluster = nextCluster(text, i);
95
+ if (width + cluster.cells > max)
96
+ break;
97
+ width += cluster.cells;
98
+ out += cluster.text;
99
+ i += cluster.text.length;
100
+ }
101
+ return out;
102
+ }
103
+ /** Keep the last `max` terminal cells of `text`. */
104
+ export function sliceTailToWidth(text, max) {
105
+ if (max <= 0)
106
+ return '';
107
+ const plain = stripAnsi(text);
108
+ const clusters = [];
109
+ for (let index = 0; index < plain.length;) {
110
+ const cluster = nextCluster(plain, index);
111
+ clusters.push(cluster);
112
+ index += cluster.text.length;
113
+ }
114
+ let width = 0;
115
+ let out = '';
116
+ for (let index = clusters.length - 1; index >= 0; index -= 1) {
117
+ if (width + clusters[index].cells > max)
118
+ break;
119
+ width += clusters[index].cells;
120
+ out = clusters[index].text + out;
121
+ }
122
+ return out;
123
+ }
124
+ /** Clamp to `max` cells, appending an ellipsis when anything was cut. */
125
+ export function truncateToWidth(text, max) {
126
+ if (max <= 0)
127
+ return '';
128
+ if (displayWidth(text) <= max)
129
+ return text;
130
+ if (max === 1)
131
+ return '…';
132
+ return `${sliceToWidth(text, max - 1)}…`;
133
+ }
41
134
  /**
42
135
  * Renders an enclosed Unicode box with mathematically guaranteed alignment
43
136
  * regardless of ANSI color escape codes or string lengths.
@@ -46,9 +139,22 @@ export function renderBox(lines, options = {}) {
46
139
  const border = options.borderColor ?? '\x1b[38;5;240m';
47
140
  const reset = '\x1b[0m';
48
141
  const titleColor = options.titleColor ?? '\x1b[1;38;5;75m';
142
+ // `maxWidth` is the whole box, borders included; `innerWidth` counts only the
143
+ // cells between them, which is what the border and padding arithmetic uses.
144
+ const innerCap = options.maxWidth ? Math.max(20, options.maxWidth - 2) : Number.POSITIVE_INFINITY;
145
+ // Content budget: two cells of padding on each content line.
146
+ const contentCap = innerCap - 4;
147
+ const clamp = (line) => {
148
+ if (line === '---' || getVisibleWidth(line) <= contentCap)
149
+ return line;
150
+ // Re-assert the reset: truncation can cut a line before its own `\x1b[0m`.
151
+ return `${truncateToWidth(line, contentCap)}${reset}`;
152
+ };
153
+ const shown = lines.map(clamp);
154
+ const title = options.title ? truncateToWidth(options.title, Math.max(10, contentCap - 4)) : undefined;
49
155
  // Calculate required width
50
- let maxContentWidth = options.title ? getVisibleWidth(options.title) + 4 : 0;
51
- for (const line of lines) {
156
+ let maxContentWidth = title ? getVisibleWidth(title) + 4 : 0;
157
+ for (const line of shown) {
52
158
  if (line !== '---') {
53
159
  const w = getVisibleWidth(line);
54
160
  if (w > maxContentWidth) {
@@ -56,19 +162,20 @@ export function renderBox(lines, options = {}) {
56
162
  }
57
163
  }
58
164
  }
59
- const innerWidth = Math.max(maxContentWidth + 4, options.minWidth ?? 60);
165
+ const requested = Math.max(maxContentWidth + 4, options.minWidth ?? 60);
166
+ const innerWidth = Math.min(requested, innerCap);
60
167
  let output = '';
61
168
  // 1. Top border
62
- if (options.title) {
63
- const titleVis = getVisibleWidth(options.title);
169
+ if (title) {
170
+ const titleVis = getVisibleWidth(title);
64
171
  const rightDashes = innerWidth - titleVis - 3;
65
- output += `${border}╭─ ${titleColor}${options.title}${reset}${border} ${'─'.repeat(Math.max(0, rightDashes))}╮${reset}\n`;
172
+ output += `${border}╭─ ${titleColor}${title}${reset}${border} ${'─'.repeat(Math.max(0, rightDashes))}╮${reset}\n`;
66
173
  }
67
174
  else {
68
175
  output += `${border}╭${'─'.repeat(innerWidth)}╮${reset}\n`;
69
176
  }
70
177
  // 2. Content lines
71
- for (const line of lines) {
178
+ for (const line of shown) {
72
179
  if (line === '---') {
73
180
  output += `${border}├${'─'.repeat(innerWidth)}┤${reset}\n`;
74
181
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/ui/box.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,4CAA4C;IAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,qFAAqF;AACrF,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,CACL,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC;QACpC,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC;QACpC,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,CACrC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;YAAE,SAAS;QAC1G,KAAK,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAe,EAAE,UAAsB,EAAE;IACjE,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,IAAI,gBAAgB,CAAC;IACvD,MAAM,KAAK,GAAG,SAAS,CAAC;IACxB,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC;IAE3D,2BAA2B;IAC3B,IAAI,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,GAAG,eAAe,EAAE,CAAC;gBACxB,eAAe,GAAG,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,GAAG,CAAC,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAEzE,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,gBAAgB;IAChB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,GAAG,KAAK,GAAG,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;IAC5H,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,GAAG,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC;IAC7D,CAAC;IAED,mBAAmB;IACnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC;YAC3D,SAAS;QACX,CAAC;QAED,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,MAAM,IAAI,KAAK,KAAK,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,IAAI,KAAK,IAAI,CAAC;IACrF,CAAC;IAED,mBAAmB;IACnB,MAAM,IAAI,GAAG,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC;IAE3D,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/ui/box.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function renderChartBlock(source: string, width: number, color?: boolean): string[] | undefined;
2
+ //# sourceMappingURL=chart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../src/ui/chart.ts"],"names":[],"mappings":"AAgBA,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,UAAsE,GAAG,MAAM,EAAE,GAAG,SAAS,CAajK"}
@@ -0,0 +1,97 @@
1
+ import { z } from 'zod';
2
+ import { displayWidth, truncateToWidth } from './box.js';
3
+ const ChartSchema = z.object({
4
+ type: z.enum(['bar', 'line']),
5
+ title: z.string().max(120).regex(/^[^\x00-\x1f\x7f]*$/).optional(),
6
+ data: z.array(z.object({
7
+ label: z.string().min(1).max(80).regex(/^[^\x00-\x1f\x7f]*$/),
8
+ value: z.number().finite(),
9
+ }).strict()).min(1).max(24),
10
+ }).strict();
11
+ const CHART_COLORS = [21, 27, 33, 39, 45, 51, 50, 46, 82, 118, 154, 190, 226, 220, 214, 208, 202, 196];
12
+ const RESET = '\x1b[0m';
13
+ export function renderChartBlock(source, width, color = Boolean(process.stdout.isTTY && process.env.NO_COLOR === undefined)) {
14
+ if (source.length > 16_000)
15
+ return undefined;
16
+ let raw;
17
+ try {
18
+ raw = JSON.parse(source);
19
+ }
20
+ catch {
21
+ return undefined;
22
+ }
23
+ const parsed = ChartSchema.safeParse(raw);
24
+ if (!parsed.success)
25
+ return undefined;
26
+ return parsed.data.type === 'bar'
27
+ ? renderBarChart(parsed.data, Math.max(8, width), color)
28
+ : renderLineChart(parsed.data, Math.max(8, width), color);
29
+ }
30
+ function renderBarChart(chart, width, color) {
31
+ const labelWidth = Math.min(18, Math.max(1, Math.floor(width * 0.3)));
32
+ const valueWidth = Math.max(...chart.data.map(({ value }) => formatNumber(value).length));
33
+ const barWidth = Math.max(1, width - labelWidth - valueWidth - 3);
34
+ const maxValue = Math.max(...chart.data.map(({ value }) => Math.abs(value)), 1);
35
+ const lines = chart.title ? [truncateToWidth(chart.title, width)] : [];
36
+ for (const point of chart.data) {
37
+ const label = truncateToWidth(point.label, labelWidth);
38
+ const paddedLabel = label + ' '.repeat(Math.max(0, labelWidth - displayWidth(label)));
39
+ const length = Math.round(Math.abs(point.value) / maxValue * barWidth);
40
+ const bar = point.value < 0 ? '<'.repeat(length) : '#'.repeat(length);
41
+ const coloredBar = color && bar ? `${chartColor(magnitudeColor(point.value, maxValue))}${bar}${RESET}` : bar;
42
+ lines.push(truncateToWidth(`${paddedLabel} ${coloredBar} ${formatNumber(point.value)}`, width));
43
+ }
44
+ return lines;
45
+ }
46
+ function renderLineChart(chart, width, color) {
47
+ const data = chart.data;
48
+ const plotWidth = Math.max(1, Math.min(48, width - 2));
49
+ const plotHeight = 7;
50
+ const min = Math.min(...data.map(({ value }) => value));
51
+ const max = Math.max(...data.map(({ value }) => value));
52
+ const span = max - min || 1;
53
+ const points = data.map(({ value }, index) => ({
54
+ x: data.length === 1 ? Math.floor((plotWidth - 1) / 2) : Math.round(index * (plotWidth - 1) / (data.length - 1)),
55
+ y: Math.round((max - value) * (plotHeight - 1) / span),
56
+ }));
57
+ const grid = Array.from({ length: plotHeight }, () => Array(plotWidth).fill(' '));
58
+ const colorGrid = Array.from({ length: plotHeight }, () => Array(plotWidth).fill(-1));
59
+ for (let index = 1; index < points.length; index += 1) {
60
+ const from = points[index - 1];
61
+ const to = points[index];
62
+ const steps = Math.max(Math.abs(to.x - from.x), Math.abs(to.y - from.y), 1);
63
+ for (let step = 0; step <= steps; step += 1) {
64
+ const x = Math.round(from.x + (to.x - from.x) * step / steps);
65
+ const y = Math.round(from.y + (to.y - from.y) * step / steps);
66
+ grid[y][x] = '.';
67
+ colorGrid[y][x] = colorAt(index - 1 + step / steps, data.length);
68
+ }
69
+ }
70
+ for (let index = 0; index < points.length; index += 1) {
71
+ const point = points[index];
72
+ grid[point.y][point.x] = 'o';
73
+ colorGrid[point.y][point.x] = colorAt(index, data.length);
74
+ }
75
+ const lines = chart.title ? [truncateToWidth(chart.title, width)] : [];
76
+ lines.push(...grid.map((row, y) => color
77
+ ? `\x1b[38;5;240m|${RESET}${row.map((glyph, x) => colorGrid[y][x] < 0 || glyph === ' ' ? glyph : `${chartColor(colorGrid[y][x])}${glyph}${RESET}`).join('')}\x1b[38;5;240m|${RESET}`
78
+ : `|${row.join('')}|`));
79
+ lines.push(truncateToWidth(` ${formatNumber(max)}${' '.repeat(Math.max(1, plotWidth - 2))}${formatNumber(min)}`, width));
80
+ for (const point of data)
81
+ lines.push(truncateToWidth(`${point.label}: ${formatNumber(point.value)}`, width));
82
+ return lines;
83
+ }
84
+ function chartColor(index) {
85
+ return `\x1b[38;5;${index}m`;
86
+ }
87
+ function colorAt(position, count) {
88
+ const step = count <= 1 ? 0 : position / (count - 1) * (CHART_COLORS.length - 1);
89
+ return CHART_COLORS[Math.round(step)];
90
+ }
91
+ function magnitudeColor(value, max) {
92
+ return CHART_COLORS[Math.round(Math.abs(value) / max * (CHART_COLORS.length - 1))];
93
+ }
94
+ function formatNumber(value) {
95
+ return Number.isInteger(value) ? String(value) : String(Number(value.toPrecision(4)));
96
+ }
97
+ //# sourceMappingURL=chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.js","sourceRoot":"","sources":["../../src/ui/chart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import type { UsageEvent } from '@moderado/contracts';
2
+ import type { ChatActivityBlock } from './welcome.js';
3
+ export interface InteractiveTurnResult {
4
+ text: string;
5
+ mode: 'Plan' | 'Execute';
6
+ autoApprove: boolean;
7
+ workflowAction?: 'build';
8
+ }
9
+ export interface PromptInteractiveTurnOptions {
10
+ model: string;
11
+ getProviderName?: () => string | undefined;
12
+ tokens: number;
13
+ cost: string;
14
+ usageAvailable?: boolean;
15
+ usageEstimated?: boolean;
16
+ workspace: string;
17
+ version?: string;
18
+ initialMode?: 'Plan' | 'Execute';
19
+ initialAutoApprove?: boolean;
20
+ isFirstTurn?: boolean;
21
+ signal?: AbortSignal;
22
+ /** Previous turn's question/answer — when question is set, render the full chat window (no logo). */
23
+ chatQuestion?: string;
24
+ chatAnswer?: string;
25
+ chatThoughtTime?: number;
26
+ chatTaskDone?: boolean;
27
+ outputTokenRate?: number;
28
+ tokenUsage?: UsageEvent;
29
+ questionHistory?: string[];
30
+ /**
31
+ * Called whenever the transcript is scrolled, with the new offset measured in
32
+ * rows up from the tail (0 is the live view).
33
+ *
34
+ * The turn loop paints the transcript on every streamed delta, so without
35
+ * this it would repaint at offset 0 and drag a reader who scrolled up back to
36
+ * the bottom mid-sentence. The offset is the composer's; the loop only needs
37
+ * to be told when it changes.
38
+ */
39
+ onTranscriptScroll?: (offset: number) => void;
40
+ /**
41
+ * Live activity for the turn that is running right now.
42
+ *
43
+ * The composer owns the scroll position, so it also owns the scroll range —
44
+ * and the range has to cover the activity log as well as the answer, because
45
+ * the two are one transcript. The turn loop holds the activity; this is how
46
+ * the composer reads it without the two sharing mutable state.
47
+ */
48
+ getChatActivity?: () => ChatActivityBlock | undefined;
49
+ /**
50
+ * Called when user selects a model via /model. Receives a `drawFrame`
51
+ * callback that composites popup content as a floating layer on top of the
52
+ * main TUI window (background stays as-is). The callback owns the selection
53
+ * UI and returns the new model id, or undefined if cancelled.
54
+ */
55
+ onModelSelect?: (drawFrame: (popupLines: string[]) => void) => Promise<string | undefined>;
56
+ /** Returns a queued prompt that should start immediately after a popup closes. */
57
+ takeAutoContinuePrompt?: () => string | undefined;
58
+ /** Called when user issues /connect. Returns the model label to display. */
59
+ onConnect?: (drawFrame: (popupLines: string[]) => void) => Promise<string | undefined>;
60
+ /** Called when user issues /clear so caller can reset conversation history. */
61
+ onClear?: () => void;
62
+ onExit?: () => string;
63
+ onMcp?: (command: string, drawFrame: (popupLines: string[]) => void) => Promise<void>;
64
+ onSession?: (command: string, drawFrame: (popupLines: string[]) => void) => Promise<void>;
65
+ /**
66
+ * Called for /transcript. Writes the whole conversation to a file and returns
67
+ * its path, which the composer then opens in the pager.
68
+ */
69
+ onTranscript?: () => Promise<string | undefined>;
70
+ onQueue?: (command: string, drawFrame: (popupLines: string[]) => void) => Promise<void>;
71
+ onBtw?: (command: string, drawFrame: (popupLines: string[], options?: {
72
+ waitDismiss?: boolean;
73
+ }) => void | Promise<void>, signal?: AbortSignal) => Promise<void>;
74
+ onWorkflow?: (command: string, drawFrame: (popupLines: string[]) => void) => Promise<'build' | undefined>;
75
+ onInit?: (drawFrame: (popupLines: string[]) => void) => Promise<void>;
76
+ onMentionComplete?: (token: string) => Promise<string[]>;
77
+ queuedCommands?: readonly string[];
78
+ }
79
+ export declare function promptInteractiveTurn(options: PromptInteractiveTurnOptions): Promise<InteractiveTurnResult>;
80
+ //# sourceMappingURL=composer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composer.d.ts","sourceRoot":"","sources":["../../src/ui/composer.ts"],"names":[],"mappings":"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"}