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.
- package/dist/commands/chat.d.ts +7 -70
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +279 -453
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/chat_meta.d.ts +36 -0
- package/dist/commands/chat_meta.d.ts.map +1 -0
- package/dist/commands/chat_meta.js +102 -0
- package/dist/commands/chat_meta.js.map +1 -0
- package/dist/commands/chat_outcome.d.ts +31 -0
- package/dist/commands/chat_outcome.d.ts.map +1 -0
- package/dist/commands/chat_outcome.js +70 -0
- package/dist/commands/chat_outcome.js.map +1 -0
- package/dist/commands/chat_search.d.ts +24 -0
- package/dist/commands/chat_search.d.ts.map +1 -0
- package/dist/commands/chat_search.js +61 -0
- package/dist/commands/chat_search.js.map +1 -0
- package/dist/commands/chat_slash.d.ts +17 -0
- package/dist/commands/chat_slash.d.ts.map +1 -0
- package/dist/commands/chat_slash.js +109 -0
- package/dist/commands/chat_slash.js.map +1 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +25 -1
- package/dist/commands/run.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -2
- package/dist/config.js.map +1 -1
- package/dist/diagnostic_log.d.ts.map +1 -1
- package/dist/diagnostic_log.js +1 -0
- package/dist/diagnostic_log.js.map +1 -1
- package/dist/sessions.d.ts.map +1 -1
- package/dist/sessions.js +5 -1
- package/dist/sessions.js.map +1 -1
- package/dist/transcript.d.ts +19 -0
- package/dist/transcript.d.ts.map +1 -0
- package/dist/transcript.js +76 -0
- package/dist/transcript.js.map +1 -0
- package/dist/turn_summary.d.ts +76 -0
- package/dist/turn_summary.d.ts.map +1 -0
- package/dist/turn_summary.js +305 -0
- package/dist/turn_summary.js.map +1 -0
- package/dist/ui/box.d.ts +19 -0
- package/dist/ui/box.d.ts.map +1 -1
- package/dist/ui/box.js +119 -12
- package/dist/ui/box.js.map +1 -1
- package/dist/ui/chart.d.ts +2 -0
- package/dist/ui/chart.d.ts.map +1 -0
- package/dist/ui/chart.js +97 -0
- package/dist/ui/chart.js.map +1 -0
- package/dist/ui/composer.d.ts +80 -0
- package/dist/ui/composer.d.ts.map +1 -0
- package/dist/ui/composer.js +883 -0
- package/dist/ui/composer.js.map +1 -0
- package/dist/ui/help_content.d.ts +2 -2
- package/dist/ui/help_content.d.ts.map +1 -1
- package/dist/ui/help_content.js +5 -3
- package/dist/ui/help_content.js.map +1 -1
- package/dist/ui/model_selector.d.ts +1 -0
- package/dist/ui/model_selector.d.ts.map +1 -1
- package/dist/ui/model_selector.js +61 -18
- package/dist/ui/model_selector.js.map +1 -1
- package/dist/ui/popup.d.ts.map +1 -1
- package/dist/ui/popup.js +7 -0
- package/dist/ui/popup.js.map +1 -1
- package/dist/ui/provider_connect.d.ts +8 -0
- package/dist/ui/provider_connect.d.ts.map +1 -1
- package/dist/ui/provider_connect.js +81 -23
- package/dist/ui/provider_connect.js.map +1 -1
- package/dist/ui/renderer.d.ts +49 -4
- package/dist/ui/renderer.d.ts.map +1 -1
- package/dist/ui/renderer.js +167 -31
- package/dist/ui/renderer.js.map +1 -1
- package/dist/ui/terminal_approval.d.ts +21 -0
- package/dist/ui/terminal_approval.d.ts.map +1 -1
- package/dist/ui/terminal_approval.js +145 -47
- package/dist/ui/terminal_approval.js.map +1 -1
- package/dist/ui/welcome.d.ts +274 -69
- package/dist/ui/welcome.d.ts.map +1 -1
- package/dist/ui/welcome.js +729 -700
- package/dist/ui/welcome.js.map +1 -1
- package/dist/vendor/providers/presets.d.ts +16 -0
- package/dist/vendor/providers/presets.d.ts.map +1 -1
- package/dist/vendor/providers/presets.js +13 -0
- package/dist/vendor/providers/presets.js.map +1 -1
- package/dist/vendor/tools/checkpoints.js +5 -5
- package/dist/vendor/tools/checkpoints.js.map +1 -1
- package/dist/vendor/tools/jail.d.ts +8 -0
- package/dist/vendor/tools/jail.d.ts.map +1 -1
- package/dist/vendor/tools/jail.js +13 -2
- package/dist/vendor/tools/jail.js.map +1 -1
- package/dist/vendor/tools/tools/apply_patch.d.ts.map +1 -1
- package/dist/vendor/tools/tools/apply_patch.js +6 -3
- package/dist/vendor/tools/tools/apply_patch.js.map +1 -1
- package/dist/vendor/tools/tools/git_diff.d.ts.map +1 -1
- package/dist/vendor/tools/tools/git_diff.js +5 -3
- package/dist/vendor/tools/tools/git_diff.js.map +1 -1
- 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 (
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
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 =
|
|
51
|
-
for (const line of
|
|
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
|
|
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 (
|
|
63
|
-
const titleVis = getVisibleWidth(
|
|
169
|
+
if (title) {
|
|
170
|
+
const titleVis = getVisibleWidth(title);
|
|
64
171
|
const rightDashes = innerWidth - titleVis - 3;
|
|
65
|
-
output += `${border}╭─ ${titleColor}${
|
|
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
|
|
178
|
+
for (const line of shown) {
|
|
72
179
|
if (line === '---') {
|
|
73
180
|
output += `${border}├${'─'.repeat(innerWidth)}┤${reset}\n`;
|
|
74
181
|
continue;
|
package/dist/ui/box.js.map
CHANGED
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/ui/box.ts"],"names":[],"mappings":"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"}
|
|
@@ -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"}
|
package/dist/ui/chart.js
ADDED
|
@@ -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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"}
|