omnius 1.0.89 → 1.0.91
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/index.js +873 -421
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3373,8 +3373,9 @@ function hashMismatchMessage(filePath, expectedHash, actualHash) {
|
|
|
3373
3373
|
function fileContextHeader(filePath, content, range) {
|
|
3374
3374
|
const totalLines = content.split("\n").length;
|
|
3375
3375
|
const hash = contentHash(content);
|
|
3376
|
-
const
|
|
3377
|
-
|
|
3376
|
+
const shortHash2 = hash.slice(0, 12);
|
|
3377
|
+
const scope = range && (range.offset !== void 0 || range.limit !== void 0) ? `lines ${range.offset ?? 1}-${range.limit ? (range.offset ?? 1) + range.limit - 1 : totalLines} of ${totalLines}` : `${totalLines} lines`;
|
|
3378
|
+
return `[FILE CONTEXT | ${filePath} | ${scope} | sha256:${shortHash2}]`;
|
|
3378
3379
|
}
|
|
3379
3380
|
var init_edit_metadata = __esm({
|
|
3380
3381
|
"packages/execution/dist/tools/edit-metadata.js"() {
|
|
@@ -548095,6 +548096,60 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
548095
548096
|
fs11.appendFileSync(path12.join(trajDir, `trajectories.jsonl`), JSON.stringify(trajectory) + "\n", "utf-8");
|
|
548096
548097
|
} catch {
|
|
548097
548098
|
}
|
|
548099
|
+
let filesEdited;
|
|
548100
|
+
let testsRun;
|
|
548101
|
+
let provenanceAnchors;
|
|
548102
|
+
try {
|
|
548103
|
+
filesEdited = [...this._taskState.modifiedFiles.keys()].slice(0, 32);
|
|
548104
|
+
} catch {
|
|
548105
|
+
}
|
|
548106
|
+
try {
|
|
548107
|
+
const shellCommands = [];
|
|
548108
|
+
const provText = [];
|
|
548109
|
+
for (const entry of toolCallLog) {
|
|
548110
|
+
if (entry.name === "shell" || entry.name === "background_run") {
|
|
548111
|
+
const m2 = entry.argsKey.match(/(?:^|,)command=([^,]*)/);
|
|
548112
|
+
if (m2 && m2[1])
|
|
548113
|
+
shellCommands.push(m2[1]);
|
|
548114
|
+
}
|
|
548115
|
+
if (entry.outputPreview)
|
|
548116
|
+
provText.push(entry.outputPreview);
|
|
548117
|
+
}
|
|
548118
|
+
const testRunners = [
|
|
548119
|
+
/\b(?:pnpm|npm|yarn)\s+(?:run\s+)?(?:test|test:[\w-]+|typecheck|lint)\b[^&|;]*/,
|
|
548120
|
+
/\bvitest\s+(?:run\s+)?[\w\-/.@\s]*/,
|
|
548121
|
+
/\bjest\s+[\w\-/.@\s]*/,
|
|
548122
|
+
/\bpytest\s+[\w\-/.@\s]*/,
|
|
548123
|
+
/\bmocha\s+[\w\-/.@\s]*/,
|
|
548124
|
+
/\bgo\s+test\s+[\w./\s-]+/,
|
|
548125
|
+
/\bcargo\s+test\b[\w\s-]*/
|
|
548126
|
+
];
|
|
548127
|
+
const tests = /* @__PURE__ */ new Set();
|
|
548128
|
+
for (const cmd of shellCommands) {
|
|
548129
|
+
for (const re of testRunners) {
|
|
548130
|
+
const m2 = cmd.match(re);
|
|
548131
|
+
if (m2) {
|
|
548132
|
+
const label = m2[0].replace(/\s+/g, " ").trim();
|
|
548133
|
+
if (label && label.length <= 80)
|
|
548134
|
+
tests.add(label);
|
|
548135
|
+
}
|
|
548136
|
+
}
|
|
548137
|
+
}
|
|
548138
|
+
if (tests.size > 0)
|
|
548139
|
+
testsRun = [...tests].slice(0, 16);
|
|
548140
|
+
const anchorRe = /(urn:omnius:[^\s"'<>)]+|aiwg-prov:[^\s"'<>)]+)/g;
|
|
548141
|
+
const anchors = /* @__PURE__ */ new Set();
|
|
548142
|
+
for (const text of provText) {
|
|
548143
|
+
for (const m2 of text.matchAll(anchorRe)) {
|
|
548144
|
+
const a2 = m2[0];
|
|
548145
|
+
if (a2.length <= 120)
|
|
548146
|
+
anchors.add(a2);
|
|
548147
|
+
}
|
|
548148
|
+
}
|
|
548149
|
+
if (anchors.size > 0)
|
|
548150
|
+
provenanceAnchors = [...anchors].slice(0, 16);
|
|
548151
|
+
} catch {
|
|
548152
|
+
}
|
|
548098
548153
|
return {
|
|
548099
548154
|
completed,
|
|
548100
548155
|
turns: messages2.filter((m2) => m2.role === "assistant").length,
|
|
@@ -548104,7 +548159,10 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
548104
548159
|
completionTokens,
|
|
548105
548160
|
estimatedTokens,
|
|
548106
548161
|
summary,
|
|
548107
|
-
durationMs
|
|
548162
|
+
durationMs,
|
|
548163
|
+
filesEdited,
|
|
548164
|
+
testsRun,
|
|
548165
|
+
provenanceAnchors
|
|
548108
548166
|
};
|
|
548109
548167
|
}
|
|
548110
548168
|
// -------------------------------------------------------------------------
|
|
@@ -562057,6 +562115,618 @@ var init_command_registry = __esm({
|
|
|
562057
562115
|
}
|
|
562058
562116
|
});
|
|
562059
562117
|
|
|
562118
|
+
// packages/cli/src/tui/text-selection.ts
|
|
562119
|
+
var text_selection_exports = {};
|
|
562120
|
+
__export(text_selection_exports, {
|
|
562121
|
+
SEL_END: () => SEL_END,
|
|
562122
|
+
SEL_START: () => SEL_START,
|
|
562123
|
+
TextSelection: () => TextSelection,
|
|
562124
|
+
computeHeaderButtons: () => computeHeaderButtons,
|
|
562125
|
+
copyText: () => copyText,
|
|
562126
|
+
hitTestHeaderButton: () => hitTestHeaderButton,
|
|
562127
|
+
pasteText: () => pasteText,
|
|
562128
|
+
renderHeaderButtons: () => renderHeaderButtons,
|
|
562129
|
+
setHoveredButton: () => setHoveredButton,
|
|
562130
|
+
setPressedButton: () => setPressedButton,
|
|
562131
|
+
setUpdateBadgeRegion: () => setUpdateBadgeRegion,
|
|
562132
|
+
stripAnsi: () => stripAnsi,
|
|
562133
|
+
visibleLength: () => visibleLength
|
|
562134
|
+
});
|
|
562135
|
+
import { execSync as execSync47 } from "node:child_process";
|
|
562136
|
+
function stripAnsi(s2) {
|
|
562137
|
+
return s2.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
562138
|
+
}
|
|
562139
|
+
function visibleLength(s2) {
|
|
562140
|
+
return stripAnsi(s2).length;
|
|
562141
|
+
}
|
|
562142
|
+
function copyText(text) {
|
|
562143
|
+
try {
|
|
562144
|
+
const platform7 = process.platform;
|
|
562145
|
+
if (platform7 === "darwin") {
|
|
562146
|
+
execSync47("pbcopy", { input: text, timeout: 3e3 });
|
|
562147
|
+
return true;
|
|
562148
|
+
}
|
|
562149
|
+
if (platform7 === "win32") {
|
|
562150
|
+
execSync47("clip", { input: text, timeout: 3e3 });
|
|
562151
|
+
return true;
|
|
562152
|
+
}
|
|
562153
|
+
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
562154
|
+
try {
|
|
562155
|
+
execSync47(tool, { input: text, timeout: 3e3 });
|
|
562156
|
+
return true;
|
|
562157
|
+
} catch {
|
|
562158
|
+
continue;
|
|
562159
|
+
}
|
|
562160
|
+
}
|
|
562161
|
+
if (!_clipboardAutoInstallAttempted) {
|
|
562162
|
+
_clipboardAutoInstallAttempted = true;
|
|
562163
|
+
try {
|
|
562164
|
+
execSync47("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
562165
|
+
try {
|
|
562166
|
+
execSync47("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
|
|
562167
|
+
execSync47("xclip -selection clipboard", { input: text, timeout: 3e3 });
|
|
562168
|
+
return true;
|
|
562169
|
+
} catch {
|
|
562170
|
+
}
|
|
562171
|
+
} catch {
|
|
562172
|
+
}
|
|
562173
|
+
}
|
|
562174
|
+
} catch {
|
|
562175
|
+
}
|
|
562176
|
+
try {
|
|
562177
|
+
const b64 = Buffer.from(text).toString("base64");
|
|
562178
|
+
process.stdout.write(`\x1B]52;c;${b64}\x07`);
|
|
562179
|
+
return true;
|
|
562180
|
+
} catch {
|
|
562181
|
+
}
|
|
562182
|
+
return false;
|
|
562183
|
+
}
|
|
562184
|
+
function pasteText() {
|
|
562185
|
+
try {
|
|
562186
|
+
const platform7 = process.platform;
|
|
562187
|
+
if (platform7 === "darwin") {
|
|
562188
|
+
return execSync47("pbpaste", { timeout: 3e3, encoding: "utf8" }).trimEnd();
|
|
562189
|
+
}
|
|
562190
|
+
if (platform7 === "win32") {
|
|
562191
|
+
return execSync47("powershell -command Get-Clipboard", { timeout: 3e3, encoding: "utf8" }).trimEnd();
|
|
562192
|
+
}
|
|
562193
|
+
for (const tool of [
|
|
562194
|
+
{ cmd: "xclip", args: ["-selection", "clipboard", "-o"] },
|
|
562195
|
+
{ cmd: "xsel", args: ["--clipboard", "--output"] },
|
|
562196
|
+
{ cmd: "wl-paste", args: [] }
|
|
562197
|
+
]) {
|
|
562198
|
+
try {
|
|
562199
|
+
const result = execSync47(`${tool.cmd} ${tool.args.join(" ")}`, { timeout: 3e3, encoding: "utf8" });
|
|
562200
|
+
return result.trimEnd();
|
|
562201
|
+
} catch {
|
|
562202
|
+
continue;
|
|
562203
|
+
}
|
|
562204
|
+
}
|
|
562205
|
+
} catch {
|
|
562206
|
+
}
|
|
562207
|
+
return null;
|
|
562208
|
+
}
|
|
562209
|
+
function computeHeaderButtons(_termWidth) {
|
|
562210
|
+
return [];
|
|
562211
|
+
}
|
|
562212
|
+
function setHoveredButton(cmd) {
|
|
562213
|
+
_hoveredButtonCmd = cmd;
|
|
562214
|
+
}
|
|
562215
|
+
function setPressedButton(cmd) {
|
|
562216
|
+
_pressedButtonCmd = cmd;
|
|
562217
|
+
}
|
|
562218
|
+
function renderHeaderButtons(_termWidth) {
|
|
562219
|
+
return "";
|
|
562220
|
+
}
|
|
562221
|
+
function setUpdateBadgeRegion(active, startCol, length4) {
|
|
562222
|
+
_updateBadgeActive = active;
|
|
562223
|
+
_updateBadgeCol = startCol;
|
|
562224
|
+
_updateBadgeLen = length4;
|
|
562225
|
+
}
|
|
562226
|
+
function hitTestHeaderButton(row, col, termWidth) {
|
|
562227
|
+
if (_updateBadgeActive && row === 1 && col >= _updateBadgeCol && col < _updateBadgeCol + _updateBadgeLen) {
|
|
562228
|
+
return "/update";
|
|
562229
|
+
}
|
|
562230
|
+
const hdrRow = layout().headerContent;
|
|
562231
|
+
if (row === hdrRow) {
|
|
562232
|
+
if (col <= 3) return "header-prev";
|
|
562233
|
+
if (col >= termWidth - 3) return "header-next";
|
|
562234
|
+
const btnDefs = [
|
|
562235
|
+
{ cmd: "/help", label: " help " },
|
|
562236
|
+
{ cmd: "/voice", label: " voice " },
|
|
562237
|
+
{ cmd: "/model", label: " model " },
|
|
562238
|
+
{ cmd: "/cohere", label: " cohere " }
|
|
562239
|
+
];
|
|
562240
|
+
let btnEnd = termWidth - 4;
|
|
562241
|
+
for (let i2 = btnDefs.length - 1; i2 >= 0; i2--) {
|
|
562242
|
+
const btn = btnDefs[i2];
|
|
562243
|
+
const btnStart = btnEnd - btn.label.length;
|
|
562244
|
+
if (col >= btnStart && col <= btnEnd) return btn.cmd;
|
|
562245
|
+
btnEnd = btnStart - 1;
|
|
562246
|
+
}
|
|
562247
|
+
}
|
|
562248
|
+
return null;
|
|
562249
|
+
}
|
|
562250
|
+
var SEL_BG, SEL_FG, SEL_START, SEL_END, TextSelection, _clipboardAutoInstallAttempted, _hoveredButtonCmd, _pressedButtonCmd, _updateBadgeActive, _updateBadgeCol, _updateBadgeLen;
|
|
562251
|
+
var init_text_selection = __esm({
|
|
562252
|
+
"packages/cli/src/tui/text-selection.ts"() {
|
|
562253
|
+
"use strict";
|
|
562254
|
+
init_layout2();
|
|
562255
|
+
SEL_BG = 37;
|
|
562256
|
+
SEL_FG = 30;
|
|
562257
|
+
SEL_START = `\x1B[${SEL_FG}m\x1B[48;5;${SEL_BG}m`;
|
|
562258
|
+
SEL_END = `\x1B[0m`;
|
|
562259
|
+
TextSelection = class {
|
|
562260
|
+
_selection = null;
|
|
562261
|
+
_active = false;
|
|
562262
|
+
// true while mouse button is held
|
|
562263
|
+
_blockModeArmed = false;
|
|
562264
|
+
// Ctrl+Shift+B pressed, next click starts block select
|
|
562265
|
+
_provider;
|
|
562266
|
+
constructor(provider) {
|
|
562267
|
+
this._provider = provider;
|
|
562268
|
+
}
|
|
562269
|
+
/** Whether a selection currently exists */
|
|
562270
|
+
get hasSelection() {
|
|
562271
|
+
return this._selection !== null;
|
|
562272
|
+
}
|
|
562273
|
+
/** Whether we're actively dragging */
|
|
562274
|
+
get isDragging() {
|
|
562275
|
+
return this._active;
|
|
562276
|
+
}
|
|
562277
|
+
/** Get the current selection range (or null) */
|
|
562278
|
+
get selection() {
|
|
562279
|
+
return this._selection;
|
|
562280
|
+
}
|
|
562281
|
+
/** Arm block selection mode — next click starts rectangular select */
|
|
562282
|
+
armBlockMode() {
|
|
562283
|
+
this._blockModeArmed = true;
|
|
562284
|
+
}
|
|
562285
|
+
/** Clear the current selection */
|
|
562286
|
+
clear() {
|
|
562287
|
+
this._selection = null;
|
|
562288
|
+
this._active = false;
|
|
562289
|
+
this._blockModeArmed = false;
|
|
562290
|
+
}
|
|
562291
|
+
/**
|
|
562292
|
+
* Handle mouse press (button 0, M suffix in SGR).
|
|
562293
|
+
* Starts a new selection from the click position.
|
|
562294
|
+
*/
|
|
562295
|
+
onMousePress(row, col) {
|
|
562296
|
+
const mode = this._blockModeArmed ? "block" : "line";
|
|
562297
|
+
this._blockModeArmed = false;
|
|
562298
|
+
this._selection = {
|
|
562299
|
+
anchor: { row, col },
|
|
562300
|
+
current: { row, col },
|
|
562301
|
+
mode
|
|
562302
|
+
};
|
|
562303
|
+
this._active = true;
|
|
562304
|
+
}
|
|
562305
|
+
/**
|
|
562306
|
+
* Handle mouse drag (button 32, M suffix in SGR).
|
|
562307
|
+
* Extends the selection to the current cursor position.
|
|
562308
|
+
*/
|
|
562309
|
+
onMouseDrag(row, col) {
|
|
562310
|
+
if (!this._active || !this._selection) return;
|
|
562311
|
+
this._selection.current = { row, col };
|
|
562312
|
+
}
|
|
562313
|
+
/**
|
|
562314
|
+
* Handle mouse release (button 0, m suffix in SGR).
|
|
562315
|
+
* Finalizes the selection.
|
|
562316
|
+
*/
|
|
562317
|
+
onMouseRelease(row, col) {
|
|
562318
|
+
if (!this._active || !this._selection) return;
|
|
562319
|
+
this._selection.current = { row, col };
|
|
562320
|
+
this._active = false;
|
|
562321
|
+
if (this._selection.anchor.row === this._selection.current.row && this._selection.anchor.col === this._selection.current.col) {
|
|
562322
|
+
this._selection = null;
|
|
562323
|
+
}
|
|
562324
|
+
}
|
|
562325
|
+
/**
|
|
562326
|
+
* Compute which content buffer indices and column ranges are selected.
|
|
562327
|
+
* Returns an array of { bufferIdx, startCol, endCol } for each selected line.
|
|
562328
|
+
* Columns are 0-based visible character positions.
|
|
562329
|
+
*/
|
|
562330
|
+
getSelectedRanges() {
|
|
562331
|
+
if (!this._selection) return [];
|
|
562332
|
+
const { anchor, current, mode } = this._selection;
|
|
562333
|
+
const top = this._provider.getScrollRegionTop();
|
|
562334
|
+
const height = this._provider.getContentHeight();
|
|
562335
|
+
const offset = this._provider.getScrollOffset();
|
|
562336
|
+
const totalLines = this._provider.getContentLines().length;
|
|
562337
|
+
const startIdx = Math.max(0, totalLines - height - offset);
|
|
562338
|
+
const anchorBufIdx = startIdx + (anchor.row - top);
|
|
562339
|
+
const currentBufIdx = startIdx + (current.row - top);
|
|
562340
|
+
const minRow = Math.min(anchorBufIdx, currentBufIdx);
|
|
562341
|
+
const maxRow = Math.max(anchorBufIdx, currentBufIdx);
|
|
562342
|
+
const minCol = Math.min(anchor.col, current.col);
|
|
562343
|
+
const maxCol = Math.max(anchor.col, current.col);
|
|
562344
|
+
const ranges = [];
|
|
562345
|
+
if (mode === "block") {
|
|
562346
|
+
for (let idx = minRow; idx <= maxRow; idx++) {
|
|
562347
|
+
if (idx >= 0 && idx < totalLines) {
|
|
562348
|
+
ranges.push({ bufferIdx: idx, startCol: minCol - 1, endCol: maxCol - 1 });
|
|
562349
|
+
}
|
|
562350
|
+
}
|
|
562351
|
+
} else {
|
|
562352
|
+
const isForward = anchorBufIdx < currentBufIdx || anchorBufIdx === currentBufIdx && anchor.col <= current.col;
|
|
562353
|
+
const startR = isForward ? anchorBufIdx : currentBufIdx;
|
|
562354
|
+
const endR = isForward ? currentBufIdx : anchorBufIdx;
|
|
562355
|
+
const startC = isForward ? anchor.col - 1 : current.col - 1;
|
|
562356
|
+
const endC = isForward ? current.col - 1 : anchor.col - 1;
|
|
562357
|
+
for (let idx = startR; idx <= endR; idx++) {
|
|
562358
|
+
if (idx < 0 || idx >= totalLines) continue;
|
|
562359
|
+
const lineLen = visibleLength(this._provider.getContentLines()[idx] ?? "");
|
|
562360
|
+
if (idx === startR && idx === endR) {
|
|
562361
|
+
ranges.push({ bufferIdx: idx, startCol: startC, endCol: endC });
|
|
562362
|
+
} else if (idx === startR) {
|
|
562363
|
+
ranges.push({ bufferIdx: idx, startCol: startC, endCol: Math.max(lineLen, startC) });
|
|
562364
|
+
} else if (idx === endR) {
|
|
562365
|
+
ranges.push({ bufferIdx: idx, startCol: 0, endCol: endC });
|
|
562366
|
+
} else {
|
|
562367
|
+
ranges.push({ bufferIdx: idx, startCol: 0, endCol: lineLen });
|
|
562368
|
+
}
|
|
562369
|
+
}
|
|
562370
|
+
}
|
|
562371
|
+
return ranges;
|
|
562372
|
+
}
|
|
562373
|
+
/**
|
|
562374
|
+
* Apply selection highlighting to a content line for rendering.
|
|
562375
|
+
* Takes the original ANSI line and returns it with selection highlight applied.
|
|
562376
|
+
*
|
|
562377
|
+
* @param line Original content line (with ANSI codes)
|
|
562378
|
+
* @param startCol 0-based visible start column to highlight
|
|
562379
|
+
* @param endCol 0-based visible end column to highlight (inclusive)
|
|
562380
|
+
* @returns Line with selection highlight overlay
|
|
562381
|
+
*/
|
|
562382
|
+
static applyHighlight(line, startCol, endCol) {
|
|
562383
|
+
const plain = stripAnsi(line);
|
|
562384
|
+
if (startCol > plain.length || endCol < 0 || startCol > endCol) return line;
|
|
562385
|
+
const sc = Math.max(0, startCol);
|
|
562386
|
+
const ec = Math.min(plain.length - 1, endCol);
|
|
562387
|
+
let result = "";
|
|
562388
|
+
let visPos = 0;
|
|
562389
|
+
let i2 = 0;
|
|
562390
|
+
let inHighlight = false;
|
|
562391
|
+
while (i2 < line.length) {
|
|
562392
|
+
const escMatch = line.slice(i2).match(/^(\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\))/);
|
|
562393
|
+
if (escMatch) {
|
|
562394
|
+
if (inHighlight) {
|
|
562395
|
+
result += SEL_END + escMatch[0] + SEL_START;
|
|
562396
|
+
} else {
|
|
562397
|
+
result += escMatch[0];
|
|
562398
|
+
}
|
|
562399
|
+
i2 += escMatch[0].length;
|
|
562400
|
+
continue;
|
|
562401
|
+
}
|
|
562402
|
+
if (visPos === sc && !inHighlight) {
|
|
562403
|
+
result += SEL_START;
|
|
562404
|
+
inHighlight = true;
|
|
562405
|
+
}
|
|
562406
|
+
result += line[i2];
|
|
562407
|
+
if (visPos === ec && inHighlight) {
|
|
562408
|
+
result += SEL_END;
|
|
562409
|
+
inHighlight = false;
|
|
562410
|
+
}
|
|
562411
|
+
visPos++;
|
|
562412
|
+
i2++;
|
|
562413
|
+
}
|
|
562414
|
+
if (inHighlight) result += SEL_END;
|
|
562415
|
+
return result;
|
|
562416
|
+
}
|
|
562417
|
+
/**
|
|
562418
|
+
* Get the selected text content (plain text, no ANSI codes).
|
|
562419
|
+
* For block mode, each line is joined with newline.
|
|
562420
|
+
* For line mode, text flows continuously with newlines between lines.
|
|
562421
|
+
*/
|
|
562422
|
+
getSelectedText() {
|
|
562423
|
+
const ranges = this.getSelectedRanges();
|
|
562424
|
+
if (ranges.length === 0) return "";
|
|
562425
|
+
const lines = this._provider.getContentLines();
|
|
562426
|
+
const parts = [];
|
|
562427
|
+
for (const { bufferIdx, startCol, endCol } of ranges) {
|
|
562428
|
+
const raw = lines[bufferIdx] ?? "";
|
|
562429
|
+
const plain = stripAnsi(raw);
|
|
562430
|
+
const selected = plain.slice(
|
|
562431
|
+
Math.max(0, startCol),
|
|
562432
|
+
Math.min(plain.length, endCol + 1)
|
|
562433
|
+
);
|
|
562434
|
+
parts.push(selected);
|
|
562435
|
+
}
|
|
562436
|
+
return parts.join("\n");
|
|
562437
|
+
}
|
|
562438
|
+
/**
|
|
562439
|
+
* Copy current selection to system clipboard.
|
|
562440
|
+
* Tries platform commands first, falls back to OSC 52.
|
|
562441
|
+
* Returns true if copy succeeded.
|
|
562442
|
+
*/
|
|
562443
|
+
copyToClipboard() {
|
|
562444
|
+
const text = this.getSelectedText();
|
|
562445
|
+
if (!text) return false;
|
|
562446
|
+
return copyText(text);
|
|
562447
|
+
}
|
|
562448
|
+
};
|
|
562449
|
+
_clipboardAutoInstallAttempted = false;
|
|
562450
|
+
_hoveredButtonCmd = null;
|
|
562451
|
+
_pressedButtonCmd = null;
|
|
562452
|
+
_updateBadgeActive = false;
|
|
562453
|
+
_updateBadgeCol = 0;
|
|
562454
|
+
_updateBadgeLen = 0;
|
|
562455
|
+
}
|
|
562456
|
+
});
|
|
562457
|
+
|
|
562458
|
+
// packages/cli/src/tui/task-complete-box.ts
|
|
562459
|
+
var task_complete_box_exports = {};
|
|
562460
|
+
__export(task_complete_box_exports, {
|
|
562461
|
+
buildBoxLines: () => buildBoxLines,
|
|
562462
|
+
deriveTitle: () => deriveTitle,
|
|
562463
|
+
detectProvenanceAnchors: () => detectProvenanceAnchors,
|
|
562464
|
+
detectTestRuns: () => detectTestRuns,
|
|
562465
|
+
renderTaskCompleteBox: () => renderTaskCompleteBox
|
|
562466
|
+
});
|
|
562467
|
+
function deriveTitle(task) {
|
|
562468
|
+
if (!task || !task.trim()) return "Task Complete";
|
|
562469
|
+
const cleaned = task.replace(/```[\s\S]*?```/g, " ").replace(/`[^`]+`/g, " ").replace(/\([^)]*\)/g, " ").replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
|
|
562470
|
+
if (!cleaned) return "Task Complete";
|
|
562471
|
+
const firstSentence = cleaned.split(/(?<=[.!?:])\s/)[0] ?? cleaned;
|
|
562472
|
+
const words = firstSentence.split(/\s+/).filter((w) => w.length > 0);
|
|
562473
|
+
if (words.length === 0) return "Task Complete";
|
|
562474
|
+
if (words.length <= 10) return words.join(" ");
|
|
562475
|
+
return words.slice(0, 10).join(" ") + "…";
|
|
562476
|
+
}
|
|
562477
|
+
function formatDuration2(ms) {
|
|
562478
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
562479
|
+
if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
|
|
562480
|
+
const m2 = Math.floor(ms / 6e4);
|
|
562481
|
+
const s2 = Math.floor(ms % 6e4 / 1e3);
|
|
562482
|
+
return `${m2}m${s2.toString().padStart(2, "0")}s`;
|
|
562483
|
+
}
|
|
562484
|
+
function formatTokenCount(t2) {
|
|
562485
|
+
const n2 = t2.total > 0 ? t2.total : t2.estimated;
|
|
562486
|
+
if (n2 <= 0) return "";
|
|
562487
|
+
if (n2 < 1e3) return `${n2} tok`;
|
|
562488
|
+
if (n2 < 1e6) return `${(n2 / 1e3).toFixed(1)}k tok`;
|
|
562489
|
+
return `${(n2 / 1e6).toFixed(2)}M tok`;
|
|
562490
|
+
}
|
|
562491
|
+
function buildMetricsChip(data) {
|
|
562492
|
+
const parts = [];
|
|
562493
|
+
parts.push(`${data.turns} turn${data.turns === 1 ? "" : "s"}`);
|
|
562494
|
+
parts.push(`${data.toolCalls} call${data.toolCalls === 1 ? "" : "s"}`);
|
|
562495
|
+
if (data.tokens && data.durationMs > 0) {
|
|
562496
|
+
const total = data.tokens.total > 0 ? data.tokens.total : data.tokens.estimated;
|
|
562497
|
+
if (total > 0) {
|
|
562498
|
+
const tps = total / (data.durationMs / 1e3);
|
|
562499
|
+
if (tps >= 1) parts.push(`${tps.toFixed(0)} tps`);
|
|
562500
|
+
}
|
|
562501
|
+
}
|
|
562502
|
+
parts.push(formatDuration2(data.durationMs));
|
|
562503
|
+
if (data.tokens) {
|
|
562504
|
+
const tok = formatTokenCount(data.tokens);
|
|
562505
|
+
if (tok) parts.push(tok);
|
|
562506
|
+
}
|
|
562507
|
+
return parts.join(" · ");
|
|
562508
|
+
}
|
|
562509
|
+
function wrapToWidth(text, width) {
|
|
562510
|
+
if (width <= 0) return [text];
|
|
562511
|
+
const out = [];
|
|
562512
|
+
for (const paragraph of text.split(/\n/)) {
|
|
562513
|
+
if (paragraph.length === 0) {
|
|
562514
|
+
out.push("");
|
|
562515
|
+
continue;
|
|
562516
|
+
}
|
|
562517
|
+
let remaining = paragraph;
|
|
562518
|
+
while (remaining.length > width) {
|
|
562519
|
+
let breakAt = remaining.lastIndexOf(" ", width);
|
|
562520
|
+
if (breakAt <= 0) breakAt = width;
|
|
562521
|
+
out.push(remaining.slice(0, breakAt).trimEnd());
|
|
562522
|
+
remaining = remaining.slice(breakAt).trimStart();
|
|
562523
|
+
}
|
|
562524
|
+
out.push(remaining);
|
|
562525
|
+
}
|
|
562526
|
+
return out;
|
|
562527
|
+
}
|
|
562528
|
+
function wrapListItems(items, width) {
|
|
562529
|
+
if (items.length === 0) return [];
|
|
562530
|
+
const sep4 = " · ";
|
|
562531
|
+
const lines = [];
|
|
562532
|
+
let current = "";
|
|
562533
|
+
for (const item of items) {
|
|
562534
|
+
const candidate = current === "" ? item : current + sep4 + item;
|
|
562535
|
+
if (stripAnsi(candidate).length <= width) {
|
|
562536
|
+
current = candidate;
|
|
562537
|
+
} else {
|
|
562538
|
+
if (current) lines.push(current);
|
|
562539
|
+
if (stripAnsi(item).length > width) {
|
|
562540
|
+
const chunks = wrapToWidth(item, width);
|
|
562541
|
+
lines.push(...chunks.slice(0, -1));
|
|
562542
|
+
current = chunks[chunks.length - 1] ?? "";
|
|
562543
|
+
} else {
|
|
562544
|
+
current = item;
|
|
562545
|
+
}
|
|
562546
|
+
}
|
|
562547
|
+
}
|
|
562548
|
+
if (current) lines.push(current);
|
|
562549
|
+
return lines;
|
|
562550
|
+
}
|
|
562551
|
+
function buildTopBorder(title, metrics2, width) {
|
|
562552
|
+
const inner = Math.max(4, width - 2);
|
|
562553
|
+
const titleVisible = stripAnsi(title);
|
|
562554
|
+
const metricsVisible = stripAnsi(metrics2);
|
|
562555
|
+
const titleChip = ` ${titleVisible} `;
|
|
562556
|
+
const titleSpan = titleChip.length + 2;
|
|
562557
|
+
const metricsChip = metricsVisible ? ` ${metricsVisible} ` : "";
|
|
562558
|
+
const metricsSpan = metricsChip.length > 0 ? metricsChip.length + 2 : 0;
|
|
562559
|
+
let titleSegment;
|
|
562560
|
+
let metricsSegment;
|
|
562561
|
+
let fillerWidth;
|
|
562562
|
+
if (titleSpan + metricsSpan + 4 <= inner) {
|
|
562563
|
+
titleSegment = `${FG_BORDER}[${FG_TITLE}${titleChip}${RESET}${FG_BORDER}]`;
|
|
562564
|
+
metricsSegment = metricsChip ? `${FG_BORDER}[${FG_METRIC}${metricsChip}${RESET}${FG_BORDER}]` : "";
|
|
562565
|
+
fillerWidth = inner - titleSpan - metricsSpan - 2;
|
|
562566
|
+
} else if (titleSpan + 4 <= inner) {
|
|
562567
|
+
titleSegment = `${FG_BORDER}[${FG_TITLE}${titleChip}${RESET}${FG_BORDER}]`;
|
|
562568
|
+
metricsSegment = "";
|
|
562569
|
+
fillerWidth = inner - titleSpan - 2;
|
|
562570
|
+
} else {
|
|
562571
|
+
const room = Math.max(3, inner - 8);
|
|
562572
|
+
const truncated = titleVisible.length > room ? titleVisible.slice(0, Math.max(1, room - 1)) + "…" : titleVisible;
|
|
562573
|
+
titleSegment = `${FG_BORDER}[${FG_TITLE} ${truncated} ${RESET}${FG_BORDER}]`;
|
|
562574
|
+
metricsSegment = "";
|
|
562575
|
+
fillerWidth = Math.max(0, inner - (truncated.length + 4) - 2);
|
|
562576
|
+
}
|
|
562577
|
+
const leadDash = `${FG_BORDER}${BOX_H}`;
|
|
562578
|
+
const trailDash = `${FG_BORDER}${BOX_H}${RESET}`;
|
|
562579
|
+
const filler = fillerWidth > 0 ? `${FG_BORDER}${BOX_H.repeat(fillerWidth)}` : "";
|
|
562580
|
+
return `${FG_BORDER}${BOX_TL}${leadDash}${titleSegment}${filler}${metricsSegment}${trailDash}${FG_BORDER}${BOX_TR}${RESET}`;
|
|
562581
|
+
}
|
|
562582
|
+
function buildBottomBorder(width) {
|
|
562583
|
+
const inner = Math.max(0, width - 2);
|
|
562584
|
+
return `${FG_BORDER}${BOX_BL}${BOX_H.repeat(inner)}${BOX_BR}${RESET}`;
|
|
562585
|
+
}
|
|
562586
|
+
function buildInnerDivider(width) {
|
|
562587
|
+
const inner = Math.max(0, width - 2);
|
|
562588
|
+
return `${FG_BORDER}${BOX_TJ_L}${BOX_H.repeat(inner)}${BOX_TJ_R}${RESET}`;
|
|
562589
|
+
}
|
|
562590
|
+
function buildContentRow(content, width) {
|
|
562591
|
+
const innerWidth = Math.max(1, width - 4);
|
|
562592
|
+
const visible = stripAnsi(content);
|
|
562593
|
+
let padded = content;
|
|
562594
|
+
if (visible.length < innerWidth) {
|
|
562595
|
+
padded = content + " ".repeat(innerWidth - visible.length);
|
|
562596
|
+
} else if (visible.length > innerWidth) {
|
|
562597
|
+
padded = content;
|
|
562598
|
+
}
|
|
562599
|
+
return `${FG_BORDER}${BOX_V}${RESET} ${padded} ${FG_BORDER}${BOX_V}${RESET}`;
|
|
562600
|
+
}
|
|
562601
|
+
function buildEmptyRow(width) {
|
|
562602
|
+
return buildContentRow("", width);
|
|
562603
|
+
}
|
|
562604
|
+
function buildLabeledFooterLines(label, items, width) {
|
|
562605
|
+
if (items.length === 0) return [];
|
|
562606
|
+
const innerWidth = Math.max(8, width - 4);
|
|
562607
|
+
const labelText = `${FG_LABEL}${label}:${RESET} `;
|
|
562608
|
+
const labelVisible = `${label}: `.length;
|
|
562609
|
+
const continuation = " ".repeat(labelVisible);
|
|
562610
|
+
const itemListWidth = Math.max(8, innerWidth - labelVisible);
|
|
562611
|
+
const wrapped = wrapListItems(items, itemListWidth);
|
|
562612
|
+
if (wrapped.length === 0) return [];
|
|
562613
|
+
const lines = [];
|
|
562614
|
+
lines.push(buildContentRow(`${labelText}${wrapped[0]}`, width));
|
|
562615
|
+
for (let i2 = 1; i2 < wrapped.length; i2++) {
|
|
562616
|
+
lines.push(buildContentRow(`${continuation}${wrapped[i2]}`, width));
|
|
562617
|
+
}
|
|
562618
|
+
return lines;
|
|
562619
|
+
}
|
|
562620
|
+
function buildBoxLines(data, width) {
|
|
562621
|
+
const w = Math.max(40, width);
|
|
562622
|
+
const title = deriveTitle(data.task);
|
|
562623
|
+
const metrics2 = buildMetricsChip(data);
|
|
562624
|
+
const lines = [];
|
|
562625
|
+
lines.push(buildTopBorder(`${GREEN}✔${RESET} ${title}`, metrics2, w));
|
|
562626
|
+
const innerWidth = Math.max(1, w - 4);
|
|
562627
|
+
const bodyText = (data.summary ?? "").trim();
|
|
562628
|
+
const hasFooter = (data.testsRun?.length ?? 0) > 0 || (data.filesEdited?.length ?? 0) > 0 || (data.provenanceAnchors?.length ?? 0) > 0;
|
|
562629
|
+
if (bodyText || hasFooter) {
|
|
562630
|
+
lines.push(buildInnerDivider(w));
|
|
562631
|
+
}
|
|
562632
|
+
if (bodyText) {
|
|
562633
|
+
lines.push(buildEmptyRow(w));
|
|
562634
|
+
for (const para of bodyText.split(/\n/)) {
|
|
562635
|
+
const wrapped = wrapToWidth(para, innerWidth);
|
|
562636
|
+
for (const line of wrapped) {
|
|
562637
|
+
lines.push(buildContentRow(line, w));
|
|
562638
|
+
}
|
|
562639
|
+
}
|
|
562640
|
+
lines.push(buildEmptyRow(w));
|
|
562641
|
+
}
|
|
562642
|
+
if (hasFooter) {
|
|
562643
|
+
if (bodyText) lines.push(buildInnerDivider(w));
|
|
562644
|
+
if (data.testsRun?.length) {
|
|
562645
|
+
lines.push(...buildLabeledFooterLines("Tests", data.testsRun, w));
|
|
562646
|
+
}
|
|
562647
|
+
if (data.filesEdited?.length) {
|
|
562648
|
+
lines.push(...buildLabeledFooterLines("Files", data.filesEdited, w));
|
|
562649
|
+
}
|
|
562650
|
+
if (data.provenanceAnchors?.length) {
|
|
562651
|
+
lines.push(...buildLabeledFooterLines("Provenance", data.provenanceAnchors, w));
|
|
562652
|
+
}
|
|
562653
|
+
}
|
|
562654
|
+
lines.push(buildBottomBorder(w));
|
|
562655
|
+
return lines;
|
|
562656
|
+
}
|
|
562657
|
+
function renderTaskCompleteBox(host, data) {
|
|
562658
|
+
const blockId = `task-complete-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
562659
|
+
const frozen = {
|
|
562660
|
+
task: data.task,
|
|
562661
|
+
summary: data.summary,
|
|
562662
|
+
turns: data.turns,
|
|
562663
|
+
toolCalls: data.toolCalls,
|
|
562664
|
+
durationMs: data.durationMs,
|
|
562665
|
+
tokens: data.tokens ?? null,
|
|
562666
|
+
filesEdited: data.filesEdited ? [...data.filesEdited] : [],
|
|
562667
|
+
testsRun: data.testsRun ? [...data.testsRun] : [],
|
|
562668
|
+
provenanceAnchors: data.provenanceAnchors ? [...data.provenanceAnchors] : []
|
|
562669
|
+
};
|
|
562670
|
+
host.registerDynamicBlock(blockId, (width) => buildBoxLines(frozen, width));
|
|
562671
|
+
host.appendDynamicBlock(blockId);
|
|
562672
|
+
return blockId;
|
|
562673
|
+
}
|
|
562674
|
+
function detectTestRuns(shellCommands) {
|
|
562675
|
+
const out = /* @__PURE__ */ new Set();
|
|
562676
|
+
const runners = [
|
|
562677
|
+
/\b(?:pnpm|npm|yarn)\s+(?:run\s+)?(test|test:[\w-]+|typecheck|lint)\b/,
|
|
562678
|
+
/\bvitest\s+(?:run\s+)?[\w-/.@]*/,
|
|
562679
|
+
/\bjest\s+[\w-/.@]*/,
|
|
562680
|
+
/\bpytest\s+[\w-/.@]*/,
|
|
562681
|
+
/\bmocha\s+[\w-/.@]*/,
|
|
562682
|
+
/\bgo\s+test\s+[\w./]+/,
|
|
562683
|
+
/\bcargo\s+test\b[\w\s-]*/
|
|
562684
|
+
];
|
|
562685
|
+
for (const cmd of shellCommands) {
|
|
562686
|
+
for (const re of runners) {
|
|
562687
|
+
const m2 = cmd.match(re);
|
|
562688
|
+
if (m2) {
|
|
562689
|
+
const label = m2[0].replace(/\s+/g, " ").trim();
|
|
562690
|
+
if (label.length <= 80) out.add(label);
|
|
562691
|
+
}
|
|
562692
|
+
}
|
|
562693
|
+
}
|
|
562694
|
+
return [...out].slice(0, 16);
|
|
562695
|
+
}
|
|
562696
|
+
function detectProvenanceAnchors(toolOutputs) {
|
|
562697
|
+
const out = /* @__PURE__ */ new Set();
|
|
562698
|
+
const re = /(urn:omnius:[^\s"'<>)]+|aiwg-prov:[^\s"'<>)]+)/g;
|
|
562699
|
+
for (const out_ of toolOutputs) {
|
|
562700
|
+
if (!out_) continue;
|
|
562701
|
+
for (const match of out_.matchAll(re)) {
|
|
562702
|
+
const anchor = match[0];
|
|
562703
|
+
if (anchor.length <= 120) out.add(anchor);
|
|
562704
|
+
}
|
|
562705
|
+
}
|
|
562706
|
+
return [...out].slice(0, 16);
|
|
562707
|
+
}
|
|
562708
|
+
var BOX_TL, BOX_TR, BOX_BL, BOX_BR, BOX_H, BOX_V, BOX_TJ_L, BOX_TJ_R, RESET, GREEN, FG_BORDER, FG_TITLE, FG_METRIC, FG_LABEL;
|
|
562709
|
+
var init_task_complete_box = __esm({
|
|
562710
|
+
"packages/cli/src/tui/task-complete-box.ts"() {
|
|
562711
|
+
"use strict";
|
|
562712
|
+
init_text_selection();
|
|
562713
|
+
BOX_TL = "╭";
|
|
562714
|
+
BOX_TR = "╮";
|
|
562715
|
+
BOX_BL = "╰";
|
|
562716
|
+
BOX_BR = "╯";
|
|
562717
|
+
BOX_H = "─";
|
|
562718
|
+
BOX_V = "│";
|
|
562719
|
+
BOX_TJ_L = "├";
|
|
562720
|
+
BOX_TJ_R = "┤";
|
|
562721
|
+
RESET = "\x1B[0m";
|
|
562722
|
+
GREEN = "\x1B[38;5;154m";
|
|
562723
|
+
FG_BORDER = "\x1B[38;5;154m";
|
|
562724
|
+
FG_TITLE = "\x1B[1;38;5;154m";
|
|
562725
|
+
FG_METRIC = "\x1B[38;5;222m";
|
|
562726
|
+
FG_LABEL = "\x1B[38;5;147m";
|
|
562727
|
+
}
|
|
562728
|
+
});
|
|
562729
|
+
|
|
562060
562730
|
// packages/cli/src/tui/render.ts
|
|
562061
562731
|
var render_exports = {};
|
|
562062
562732
|
__export(render_exports, {
|
|
@@ -562303,16 +562973,16 @@ function renderToolResult(toolName, success, output, verbose) {
|
|
|
562303
562973
|
`);
|
|
562304
562974
|
return;
|
|
562305
562975
|
}
|
|
562306
|
-
renderCodePreview(output, prefix, maxW,
|
|
562976
|
+
renderCodePreview(output, prefix, maxW, 10);
|
|
562307
562977
|
return;
|
|
562308
562978
|
}
|
|
562309
562979
|
case "shell":
|
|
562310
562980
|
case "background_run": {
|
|
562311
|
-
renderShellOutput(output, success, prefix, maxW,
|
|
562981
|
+
renderShellOutput(output, success, prefix, maxW, 10);
|
|
562312
562982
|
return;
|
|
562313
562983
|
}
|
|
562314
562984
|
case "grep_search": {
|
|
562315
|
-
renderShellOutput(output, success, prefix, maxW,
|
|
562985
|
+
renderShellOutput(output, success, prefix, maxW, 10);
|
|
562316
562986
|
return;
|
|
562317
562987
|
}
|
|
562318
562988
|
case "task_complete": {
|
|
@@ -562461,18 +563131,40 @@ function highlightToolOutput(line) {
|
|
|
562461
563131
|
if (formatted !== line) return formatted;
|
|
562462
563132
|
return c3.dim(line);
|
|
562463
563133
|
}
|
|
562464
|
-
function renderTaskComplete(
|
|
562465
|
-
const
|
|
562466
|
-
|
|
563134
|
+
function renderTaskComplete(arg1, turns, toolCalls, durationMs, tokens) {
|
|
563135
|
+
const opts = typeof arg1 === "string" ? {
|
|
563136
|
+
summary: arg1,
|
|
563137
|
+
turns: turns ?? 0,
|
|
563138
|
+
toolCalls: toolCalls ?? 0,
|
|
563139
|
+
durationMs: durationMs ?? 0,
|
|
563140
|
+
tokens
|
|
563141
|
+
} : arg1;
|
|
563142
|
+
if (opts.host) {
|
|
563143
|
+
const { renderTaskCompleteBox: renderTaskCompleteBox2 } = (init_task_complete_box(), __toCommonJS(task_complete_box_exports));
|
|
563144
|
+
renderTaskCompleteBox2(opts.host, {
|
|
563145
|
+
task: opts.task ?? "",
|
|
563146
|
+
summary: opts.summary,
|
|
563147
|
+
turns: opts.turns,
|
|
563148
|
+
toolCalls: opts.toolCalls,
|
|
563149
|
+
durationMs: opts.durationMs,
|
|
563150
|
+
tokens: opts.tokens ?? null,
|
|
563151
|
+
filesEdited: opts.filesEdited,
|
|
563152
|
+
testsRun: opts.testsRun,
|
|
563153
|
+
provenanceAnchors: opts.provenanceAnchors
|
|
563154
|
+
});
|
|
563155
|
+
return;
|
|
563156
|
+
}
|
|
563157
|
+
const duration = formatDuration3(opts.durationMs);
|
|
563158
|
+
const tokenStr = opts.tokens ? ` ${formatTokenCount2(opts.tokens)}` : "";
|
|
562467
563159
|
process.stdout.write(`
|
|
562468
|
-
${c3.green("✔")} ${c3.bold("Task completed")} ${c3.dim(`(${turns} turns, ${toolCalls} tool calls, ${duration})`)}
|
|
563160
|
+
${c3.green("✔")} ${c3.bold("Task completed")} ${c3.dim(`(${opts.turns} turns, ${opts.toolCalls} tool calls, ${duration})`)}
|
|
562469
563161
|
`);
|
|
562470
563162
|
if (tokenStr) {
|
|
562471
563163
|
process.stdout.write(` ${c3.dim(tokenStr)}
|
|
562472
563164
|
`);
|
|
562473
563165
|
}
|
|
562474
|
-
if (summary) {
|
|
562475
|
-
const formatted = formatMarkdownBlock(wrapTaskCompleteSummary(summary));
|
|
563166
|
+
if (opts.summary) {
|
|
563167
|
+
const formatted = formatMarkdownBlock(wrapTaskCompleteSummary(opts.summary));
|
|
562476
563168
|
const lines = formatted.split("\n");
|
|
562477
563169
|
for (const line of lines) {
|
|
562478
563170
|
process.stdout.write(` ${line}
|
|
@@ -562527,8 +563219,8 @@ function hangingIndentForPlainLine(line, width) {
|
|
|
562527
563219
|
return capped(line.match(/^\s*/)?.[0].length ?? 0);
|
|
562528
563220
|
}
|
|
562529
563221
|
function renderTaskIncomplete(turns, toolCalls, durationMs, tokens) {
|
|
562530
|
-
const duration =
|
|
562531
|
-
const tokenStr = tokens ? ` ${
|
|
563222
|
+
const duration = formatDuration3(durationMs);
|
|
563223
|
+
const tokenStr = tokens ? ` ${formatTokenCount2(tokens)}` : "";
|
|
562532
563224
|
process.stdout.write(`
|
|
562533
563225
|
${c3.yellow("⚠")} ${c3.bold("Task incomplete")} ${c3.dim(`(${turns} turns, ${toolCalls} tool calls, ${duration})`)}
|
|
562534
563226
|
`);
|
|
@@ -562538,7 +563230,7 @@ ${c3.yellow("⚠")} ${c3.bold("Task incomplete")} ${c3.dim(`(${turns} turns, ${t
|
|
|
562538
563230
|
}
|
|
562539
563231
|
process.stdout.write("\n");
|
|
562540
563232
|
}
|
|
562541
|
-
function
|
|
563233
|
+
function formatTokenCount2(tokens) {
|
|
562542
563234
|
if (tokens.total > 0) {
|
|
562543
563235
|
return `Tokens: ${tokens.total.toLocaleString()}`;
|
|
562544
563236
|
}
|
|
@@ -562838,7 +563530,7 @@ function formatToolArgs(toolName, args, verbose) {
|
|
|
562838
563530
|
function truncStr(s2, max) {
|
|
562839
563531
|
return s2.length > max ? s2.slice(0, max) + "..." : s2;
|
|
562840
563532
|
}
|
|
562841
|
-
function
|
|
563533
|
+
function formatDuration3(ms) {
|
|
562842
563534
|
if (ms < 1e3) return `${ms}ms`;
|
|
562843
563535
|
const totalSecs = ms / 1e3;
|
|
562844
563536
|
if (totalSecs < 60) return `${totalSecs.toFixed(1)}s`;
|
|
@@ -563112,7 +563804,7 @@ var init_render = __esm({
|
|
|
563112
563804
|
|
|
563113
563805
|
// packages/cli/src/tui/voice-session.ts
|
|
563114
563806
|
import { createServer as createServer4 } from "node:http";
|
|
563115
|
-
import { spawn as spawn23, execSync as
|
|
563807
|
+
import { spawn as spawn23, execSync as execSync48 } from "node:child_process";
|
|
563116
563808
|
import { EventEmitter as EventEmitter6 } from "node:events";
|
|
563117
563809
|
function generateFrontendHTML() {
|
|
563118
563810
|
return `<!DOCTYPE html>
|
|
@@ -570199,346 +570891,6 @@ var init_system_metrics = __esm({
|
|
|
570199
570891
|
}
|
|
570200
570892
|
});
|
|
570201
570893
|
|
|
570202
|
-
// packages/cli/src/tui/text-selection.ts
|
|
570203
|
-
var text_selection_exports = {};
|
|
570204
|
-
__export(text_selection_exports, {
|
|
570205
|
-
SEL_END: () => SEL_END,
|
|
570206
|
-
SEL_START: () => SEL_START,
|
|
570207
|
-
TextSelection: () => TextSelection,
|
|
570208
|
-
computeHeaderButtons: () => computeHeaderButtons,
|
|
570209
|
-
copyText: () => copyText,
|
|
570210
|
-
hitTestHeaderButton: () => hitTestHeaderButton,
|
|
570211
|
-
pasteText: () => pasteText,
|
|
570212
|
-
renderHeaderButtons: () => renderHeaderButtons,
|
|
570213
|
-
setHoveredButton: () => setHoveredButton,
|
|
570214
|
-
setPressedButton: () => setPressedButton,
|
|
570215
|
-
setUpdateBadgeRegion: () => setUpdateBadgeRegion,
|
|
570216
|
-
stripAnsi: () => stripAnsi,
|
|
570217
|
-
visibleLength: () => visibleLength
|
|
570218
|
-
});
|
|
570219
|
-
import { execSync as execSync48 } from "node:child_process";
|
|
570220
|
-
function stripAnsi(s2) {
|
|
570221
|
-
return s2.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
570222
|
-
}
|
|
570223
|
-
function visibleLength(s2) {
|
|
570224
|
-
return stripAnsi(s2).length;
|
|
570225
|
-
}
|
|
570226
|
-
function copyText(text) {
|
|
570227
|
-
try {
|
|
570228
|
-
const platform7 = process.platform;
|
|
570229
|
-
if (platform7 === "darwin") {
|
|
570230
|
-
execSync48("pbcopy", { input: text, timeout: 3e3 });
|
|
570231
|
-
return true;
|
|
570232
|
-
}
|
|
570233
|
-
if (platform7 === "win32") {
|
|
570234
|
-
execSync48("clip", { input: text, timeout: 3e3 });
|
|
570235
|
-
return true;
|
|
570236
|
-
}
|
|
570237
|
-
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
570238
|
-
try {
|
|
570239
|
-
execSync48(tool, { input: text, timeout: 3e3 });
|
|
570240
|
-
return true;
|
|
570241
|
-
} catch {
|
|
570242
|
-
continue;
|
|
570243
|
-
}
|
|
570244
|
-
}
|
|
570245
|
-
if (!_clipboardAutoInstallAttempted) {
|
|
570246
|
-
_clipboardAutoInstallAttempted = true;
|
|
570247
|
-
try {
|
|
570248
|
-
execSync48("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
570249
|
-
try {
|
|
570250
|
-
execSync48("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
|
|
570251
|
-
execSync48("xclip -selection clipboard", { input: text, timeout: 3e3 });
|
|
570252
|
-
return true;
|
|
570253
|
-
} catch {
|
|
570254
|
-
}
|
|
570255
|
-
} catch {
|
|
570256
|
-
}
|
|
570257
|
-
}
|
|
570258
|
-
} catch {
|
|
570259
|
-
}
|
|
570260
|
-
try {
|
|
570261
|
-
const b64 = Buffer.from(text).toString("base64");
|
|
570262
|
-
process.stdout.write(`\x1B]52;c;${b64}\x07`);
|
|
570263
|
-
return true;
|
|
570264
|
-
} catch {
|
|
570265
|
-
}
|
|
570266
|
-
return false;
|
|
570267
|
-
}
|
|
570268
|
-
function pasteText() {
|
|
570269
|
-
try {
|
|
570270
|
-
const platform7 = process.platform;
|
|
570271
|
-
if (platform7 === "darwin") {
|
|
570272
|
-
return execSync48("pbpaste", { timeout: 3e3, encoding: "utf8" }).trimEnd();
|
|
570273
|
-
}
|
|
570274
|
-
if (platform7 === "win32") {
|
|
570275
|
-
return execSync48("powershell -command Get-Clipboard", { timeout: 3e3, encoding: "utf8" }).trimEnd();
|
|
570276
|
-
}
|
|
570277
|
-
for (const tool of [
|
|
570278
|
-
{ cmd: "xclip", args: ["-selection", "clipboard", "-o"] },
|
|
570279
|
-
{ cmd: "xsel", args: ["--clipboard", "--output"] },
|
|
570280
|
-
{ cmd: "wl-paste", args: [] }
|
|
570281
|
-
]) {
|
|
570282
|
-
try {
|
|
570283
|
-
const result = execSync48(`${tool.cmd} ${tool.args.join(" ")}`, { timeout: 3e3, encoding: "utf8" });
|
|
570284
|
-
return result.trimEnd();
|
|
570285
|
-
} catch {
|
|
570286
|
-
continue;
|
|
570287
|
-
}
|
|
570288
|
-
}
|
|
570289
|
-
} catch {
|
|
570290
|
-
}
|
|
570291
|
-
return null;
|
|
570292
|
-
}
|
|
570293
|
-
function computeHeaderButtons(_termWidth) {
|
|
570294
|
-
return [];
|
|
570295
|
-
}
|
|
570296
|
-
function setHoveredButton(cmd) {
|
|
570297
|
-
_hoveredButtonCmd = cmd;
|
|
570298
|
-
}
|
|
570299
|
-
function setPressedButton(cmd) {
|
|
570300
|
-
_pressedButtonCmd = cmd;
|
|
570301
|
-
}
|
|
570302
|
-
function renderHeaderButtons(_termWidth) {
|
|
570303
|
-
return "";
|
|
570304
|
-
}
|
|
570305
|
-
function setUpdateBadgeRegion(active, startCol, length4) {
|
|
570306
|
-
_updateBadgeActive = active;
|
|
570307
|
-
_updateBadgeCol = startCol;
|
|
570308
|
-
_updateBadgeLen = length4;
|
|
570309
|
-
}
|
|
570310
|
-
function hitTestHeaderButton(row, col, termWidth) {
|
|
570311
|
-
if (_updateBadgeActive && row === 1 && col >= _updateBadgeCol && col < _updateBadgeCol + _updateBadgeLen) {
|
|
570312
|
-
return "/update";
|
|
570313
|
-
}
|
|
570314
|
-
const hdrRow = layout().headerContent;
|
|
570315
|
-
if (row === hdrRow) {
|
|
570316
|
-
if (col <= 3) return "header-prev";
|
|
570317
|
-
if (col >= termWidth - 3) return "header-next";
|
|
570318
|
-
const btnDefs = [
|
|
570319
|
-
{ cmd: "/help", label: " help " },
|
|
570320
|
-
{ cmd: "/voice", label: " voice " },
|
|
570321
|
-
{ cmd: "/model", label: " model " },
|
|
570322
|
-
{ cmd: "/cohere", label: " cohere " }
|
|
570323
|
-
];
|
|
570324
|
-
let btnEnd = termWidth - 4;
|
|
570325
|
-
for (let i2 = btnDefs.length - 1; i2 >= 0; i2--) {
|
|
570326
|
-
const btn = btnDefs[i2];
|
|
570327
|
-
const btnStart = btnEnd - btn.label.length;
|
|
570328
|
-
if (col >= btnStart && col <= btnEnd) return btn.cmd;
|
|
570329
|
-
btnEnd = btnStart - 1;
|
|
570330
|
-
}
|
|
570331
|
-
}
|
|
570332
|
-
return null;
|
|
570333
|
-
}
|
|
570334
|
-
var SEL_BG, SEL_FG, SEL_START, SEL_END, TextSelection, _clipboardAutoInstallAttempted, _hoveredButtonCmd, _pressedButtonCmd, _updateBadgeActive, _updateBadgeCol, _updateBadgeLen;
|
|
570335
|
-
var init_text_selection = __esm({
|
|
570336
|
-
"packages/cli/src/tui/text-selection.ts"() {
|
|
570337
|
-
"use strict";
|
|
570338
|
-
init_layout2();
|
|
570339
|
-
SEL_BG = 37;
|
|
570340
|
-
SEL_FG = 30;
|
|
570341
|
-
SEL_START = `\x1B[${SEL_FG}m\x1B[48;5;${SEL_BG}m`;
|
|
570342
|
-
SEL_END = `\x1B[0m`;
|
|
570343
|
-
TextSelection = class {
|
|
570344
|
-
_selection = null;
|
|
570345
|
-
_active = false;
|
|
570346
|
-
// true while mouse button is held
|
|
570347
|
-
_blockModeArmed = false;
|
|
570348
|
-
// Ctrl+Shift+B pressed, next click starts block select
|
|
570349
|
-
_provider;
|
|
570350
|
-
constructor(provider) {
|
|
570351
|
-
this._provider = provider;
|
|
570352
|
-
}
|
|
570353
|
-
/** Whether a selection currently exists */
|
|
570354
|
-
get hasSelection() {
|
|
570355
|
-
return this._selection !== null;
|
|
570356
|
-
}
|
|
570357
|
-
/** Whether we're actively dragging */
|
|
570358
|
-
get isDragging() {
|
|
570359
|
-
return this._active;
|
|
570360
|
-
}
|
|
570361
|
-
/** Get the current selection range (or null) */
|
|
570362
|
-
get selection() {
|
|
570363
|
-
return this._selection;
|
|
570364
|
-
}
|
|
570365
|
-
/** Arm block selection mode — next click starts rectangular select */
|
|
570366
|
-
armBlockMode() {
|
|
570367
|
-
this._blockModeArmed = true;
|
|
570368
|
-
}
|
|
570369
|
-
/** Clear the current selection */
|
|
570370
|
-
clear() {
|
|
570371
|
-
this._selection = null;
|
|
570372
|
-
this._active = false;
|
|
570373
|
-
this._blockModeArmed = false;
|
|
570374
|
-
}
|
|
570375
|
-
/**
|
|
570376
|
-
* Handle mouse press (button 0, M suffix in SGR).
|
|
570377
|
-
* Starts a new selection from the click position.
|
|
570378
|
-
*/
|
|
570379
|
-
onMousePress(row, col) {
|
|
570380
|
-
const mode = this._blockModeArmed ? "block" : "line";
|
|
570381
|
-
this._blockModeArmed = false;
|
|
570382
|
-
this._selection = {
|
|
570383
|
-
anchor: { row, col },
|
|
570384
|
-
current: { row, col },
|
|
570385
|
-
mode
|
|
570386
|
-
};
|
|
570387
|
-
this._active = true;
|
|
570388
|
-
}
|
|
570389
|
-
/**
|
|
570390
|
-
* Handle mouse drag (button 32, M suffix in SGR).
|
|
570391
|
-
* Extends the selection to the current cursor position.
|
|
570392
|
-
*/
|
|
570393
|
-
onMouseDrag(row, col) {
|
|
570394
|
-
if (!this._active || !this._selection) return;
|
|
570395
|
-
this._selection.current = { row, col };
|
|
570396
|
-
}
|
|
570397
|
-
/**
|
|
570398
|
-
* Handle mouse release (button 0, m suffix in SGR).
|
|
570399
|
-
* Finalizes the selection.
|
|
570400
|
-
*/
|
|
570401
|
-
onMouseRelease(row, col) {
|
|
570402
|
-
if (!this._active || !this._selection) return;
|
|
570403
|
-
this._selection.current = { row, col };
|
|
570404
|
-
this._active = false;
|
|
570405
|
-
if (this._selection.anchor.row === this._selection.current.row && this._selection.anchor.col === this._selection.current.col) {
|
|
570406
|
-
this._selection = null;
|
|
570407
|
-
}
|
|
570408
|
-
}
|
|
570409
|
-
/**
|
|
570410
|
-
* Compute which content buffer indices and column ranges are selected.
|
|
570411
|
-
* Returns an array of { bufferIdx, startCol, endCol } for each selected line.
|
|
570412
|
-
* Columns are 0-based visible character positions.
|
|
570413
|
-
*/
|
|
570414
|
-
getSelectedRanges() {
|
|
570415
|
-
if (!this._selection) return [];
|
|
570416
|
-
const { anchor, current, mode } = this._selection;
|
|
570417
|
-
const top = this._provider.getScrollRegionTop();
|
|
570418
|
-
const height = this._provider.getContentHeight();
|
|
570419
|
-
const offset = this._provider.getScrollOffset();
|
|
570420
|
-
const totalLines = this._provider.getContentLines().length;
|
|
570421
|
-
const startIdx = Math.max(0, totalLines - height - offset);
|
|
570422
|
-
const anchorBufIdx = startIdx + (anchor.row - top);
|
|
570423
|
-
const currentBufIdx = startIdx + (current.row - top);
|
|
570424
|
-
const minRow = Math.min(anchorBufIdx, currentBufIdx);
|
|
570425
|
-
const maxRow = Math.max(anchorBufIdx, currentBufIdx);
|
|
570426
|
-
const minCol = Math.min(anchor.col, current.col);
|
|
570427
|
-
const maxCol = Math.max(anchor.col, current.col);
|
|
570428
|
-
const ranges = [];
|
|
570429
|
-
if (mode === "block") {
|
|
570430
|
-
for (let idx = minRow; idx <= maxRow; idx++) {
|
|
570431
|
-
if (idx >= 0 && idx < totalLines) {
|
|
570432
|
-
ranges.push({ bufferIdx: idx, startCol: minCol - 1, endCol: maxCol - 1 });
|
|
570433
|
-
}
|
|
570434
|
-
}
|
|
570435
|
-
} else {
|
|
570436
|
-
const isForward = anchorBufIdx < currentBufIdx || anchorBufIdx === currentBufIdx && anchor.col <= current.col;
|
|
570437
|
-
const startR = isForward ? anchorBufIdx : currentBufIdx;
|
|
570438
|
-
const endR = isForward ? currentBufIdx : anchorBufIdx;
|
|
570439
|
-
const startC = isForward ? anchor.col - 1 : current.col - 1;
|
|
570440
|
-
const endC = isForward ? current.col - 1 : anchor.col - 1;
|
|
570441
|
-
for (let idx = startR; idx <= endR; idx++) {
|
|
570442
|
-
if (idx < 0 || idx >= totalLines) continue;
|
|
570443
|
-
const lineLen = visibleLength(this._provider.getContentLines()[idx] ?? "");
|
|
570444
|
-
if (idx === startR && idx === endR) {
|
|
570445
|
-
ranges.push({ bufferIdx: idx, startCol: startC, endCol: endC });
|
|
570446
|
-
} else if (idx === startR) {
|
|
570447
|
-
ranges.push({ bufferIdx: idx, startCol: startC, endCol: Math.max(lineLen, startC) });
|
|
570448
|
-
} else if (idx === endR) {
|
|
570449
|
-
ranges.push({ bufferIdx: idx, startCol: 0, endCol: endC });
|
|
570450
|
-
} else {
|
|
570451
|
-
ranges.push({ bufferIdx: idx, startCol: 0, endCol: lineLen });
|
|
570452
|
-
}
|
|
570453
|
-
}
|
|
570454
|
-
}
|
|
570455
|
-
return ranges;
|
|
570456
|
-
}
|
|
570457
|
-
/**
|
|
570458
|
-
* Apply selection highlighting to a content line for rendering.
|
|
570459
|
-
* Takes the original ANSI line and returns it with selection highlight applied.
|
|
570460
|
-
*
|
|
570461
|
-
* @param line Original content line (with ANSI codes)
|
|
570462
|
-
* @param startCol 0-based visible start column to highlight
|
|
570463
|
-
* @param endCol 0-based visible end column to highlight (inclusive)
|
|
570464
|
-
* @returns Line with selection highlight overlay
|
|
570465
|
-
*/
|
|
570466
|
-
static applyHighlight(line, startCol, endCol) {
|
|
570467
|
-
const plain = stripAnsi(line);
|
|
570468
|
-
if (startCol > plain.length || endCol < 0 || startCol > endCol) return line;
|
|
570469
|
-
const sc = Math.max(0, startCol);
|
|
570470
|
-
const ec = Math.min(plain.length - 1, endCol);
|
|
570471
|
-
let result = "";
|
|
570472
|
-
let visPos = 0;
|
|
570473
|
-
let i2 = 0;
|
|
570474
|
-
let inHighlight = false;
|
|
570475
|
-
while (i2 < line.length) {
|
|
570476
|
-
const escMatch = line.slice(i2).match(/^(\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\))/);
|
|
570477
|
-
if (escMatch) {
|
|
570478
|
-
if (inHighlight) {
|
|
570479
|
-
result += SEL_END + escMatch[0] + SEL_START;
|
|
570480
|
-
} else {
|
|
570481
|
-
result += escMatch[0];
|
|
570482
|
-
}
|
|
570483
|
-
i2 += escMatch[0].length;
|
|
570484
|
-
continue;
|
|
570485
|
-
}
|
|
570486
|
-
if (visPos === sc && !inHighlight) {
|
|
570487
|
-
result += SEL_START;
|
|
570488
|
-
inHighlight = true;
|
|
570489
|
-
}
|
|
570490
|
-
result += line[i2];
|
|
570491
|
-
if (visPos === ec && inHighlight) {
|
|
570492
|
-
result += SEL_END;
|
|
570493
|
-
inHighlight = false;
|
|
570494
|
-
}
|
|
570495
|
-
visPos++;
|
|
570496
|
-
i2++;
|
|
570497
|
-
}
|
|
570498
|
-
if (inHighlight) result += SEL_END;
|
|
570499
|
-
return result;
|
|
570500
|
-
}
|
|
570501
|
-
/**
|
|
570502
|
-
* Get the selected text content (plain text, no ANSI codes).
|
|
570503
|
-
* For block mode, each line is joined with newline.
|
|
570504
|
-
* For line mode, text flows continuously with newlines between lines.
|
|
570505
|
-
*/
|
|
570506
|
-
getSelectedText() {
|
|
570507
|
-
const ranges = this.getSelectedRanges();
|
|
570508
|
-
if (ranges.length === 0) return "";
|
|
570509
|
-
const lines = this._provider.getContentLines();
|
|
570510
|
-
const parts = [];
|
|
570511
|
-
for (const { bufferIdx, startCol, endCol } of ranges) {
|
|
570512
|
-
const raw = lines[bufferIdx] ?? "";
|
|
570513
|
-
const plain = stripAnsi(raw);
|
|
570514
|
-
const selected = plain.slice(
|
|
570515
|
-
Math.max(0, startCol),
|
|
570516
|
-
Math.min(plain.length, endCol + 1)
|
|
570517
|
-
);
|
|
570518
|
-
parts.push(selected);
|
|
570519
|
-
}
|
|
570520
|
-
return parts.join("\n");
|
|
570521
|
-
}
|
|
570522
|
-
/**
|
|
570523
|
-
* Copy current selection to system clipboard.
|
|
570524
|
-
* Tries platform commands first, falls back to OSC 52.
|
|
570525
|
-
* Returns true if copy succeeded.
|
|
570526
|
-
*/
|
|
570527
|
-
copyToClipboard() {
|
|
570528
|
-
const text = this.getSelectedText();
|
|
570529
|
-
if (!text) return false;
|
|
570530
|
-
return copyText(text);
|
|
570531
|
-
}
|
|
570532
|
-
};
|
|
570533
|
-
_clipboardAutoInstallAttempted = false;
|
|
570534
|
-
_hoveredButtonCmd = null;
|
|
570535
|
-
_pressedButtonCmd = null;
|
|
570536
|
-
_updateBadgeActive = false;
|
|
570537
|
-
_updateBadgeCol = 0;
|
|
570538
|
-
_updateBadgeLen = 0;
|
|
570539
|
-
}
|
|
570540
|
-
});
|
|
570541
|
-
|
|
570542
570894
|
// packages/cli/src/tui/daemon-registry.ts
|
|
570543
570895
|
var DaemonRegistry, registry2;
|
|
570544
570896
|
var init_daemon_registry = __esm({
|
|
@@ -570951,16 +571303,16 @@ function buildTodoProgressBar(todos, maxWidth) {
|
|
|
570951
571303
|
for (let i2 = 0; i2 < cells; i2++) {
|
|
570952
571304
|
const t2 = todos[i2];
|
|
570953
571305
|
if (t2.status === "completed") {
|
|
570954
|
-
out += `\x1B[1m${DONE_Y}█${
|
|
571306
|
+
out += `\x1B[1m${DONE_Y}█${RESET2}`;
|
|
570955
571307
|
} else if (i2 === inIdx) {
|
|
570956
|
-
out += `${INPROG}▒${
|
|
571308
|
+
out += `${INPROG}▒${RESET2}`;
|
|
570957
571309
|
} else if (i2 === nextIdx && inIdx >= 0) {
|
|
570958
|
-
out += `${NEXT}▒${
|
|
571310
|
+
out += `${NEXT}▒${RESET2}`;
|
|
570959
571311
|
} else {
|
|
570960
|
-
out += `${PEND}░${
|
|
571312
|
+
out += `${PEND}░${RESET2}`;
|
|
570961
571313
|
}
|
|
570962
571314
|
}
|
|
570963
|
-
if (truncated && maxWidth > 0) out += `${DIM_LABEL}…${
|
|
571315
|
+
if (truncated && maxWidth > 0) out += `${DIM_LABEL}…${RESET2}`;
|
|
570964
571316
|
return out;
|
|
570965
571317
|
}
|
|
570966
571318
|
function render() {
|
|
@@ -570982,7 +571334,7 @@ function render() {
|
|
|
570982
571334
|
const total = _lastTodos.length;
|
|
570983
571335
|
const headerColor = ACCENT;
|
|
570984
571336
|
const lines = [];
|
|
570985
|
-
const headerPrefix = `tasks ${headerColor}${completed}/${total}${
|
|
571337
|
+
const headerPrefix = `tasks ${headerColor}${completed}/${total}${RESET2} `;
|
|
570986
571338
|
const headerPrefixWidth = visualLen(headerPrefix);
|
|
570987
571339
|
const maxBarWidth = Math.max(0, cols - 2 - headerPrefixWidth);
|
|
570988
571340
|
const progressBar = buildTodoProgressBar(_lastTodos, maxBarWidth);
|
|
@@ -570994,11 +571346,11 @@ function render() {
|
|
|
570994
571346
|
const contentWidth = Math.max(4, cols - 8);
|
|
570995
571347
|
const contentText = t2.content + (t2.blocker ? ` (blocked: ${t2.blocker})` : "");
|
|
570996
571348
|
const truncated = truncate2(contentText, contentWidth);
|
|
570997
|
-
lines.push(`${color}${mark}${
|
|
571349
|
+
lines.push(`${color}${mark}${RESET2} ${color}${truncated}${RESET2}`);
|
|
570998
571350
|
}
|
|
570999
571351
|
if (_lastTodos.length > visible.length) {
|
|
571000
571352
|
const more = _lastTodos.length - visible.length;
|
|
571001
|
-
lines[lines.length - 1] = `${DIM_LABEL}… +${more} more${
|
|
571353
|
+
lines[lines.length - 1] = `${DIM_LABEL}… +${more} more${RESET2}`;
|
|
571002
571354
|
}
|
|
571003
571355
|
let out = HIDE + SAVE;
|
|
571004
571356
|
const newTop = L.tasksTop;
|
|
@@ -571015,7 +571367,7 @@ function render() {
|
|
|
571015
571367
|
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
571016
571368
|
const row = L.tasksTop + i2;
|
|
571017
571369
|
if (row > L.tasksBottom) break;
|
|
571018
|
-
out += `\x1B[${row};1H${CLEAR_LINE}${BG}${" ".repeat(cols)}\x1B[${row};2H${lines[i2]}${
|
|
571370
|
+
out += `\x1B[${row};1H${CLEAR_LINE}${BG}${" ".repeat(cols)}\x1B[${row};2H${lines[i2]}${RESET2}`;
|
|
571019
571371
|
}
|
|
571020
571372
|
out += RESTORE + SHOW;
|
|
571021
571373
|
try {
|
|
@@ -571043,7 +571395,7 @@ function clearLastPaintedRows() {
|
|
|
571043
571395
|
_lastPaintedTop = -1;
|
|
571044
571396
|
_lastPaintedBottom = -1;
|
|
571045
571397
|
}
|
|
571046
|
-
var chromeWrite, _activeSessionId, _watcher, _lastTodos, _enabled, _redrawScheduled, _onResizeChange, _scopeOverlayActive, _scopeMainViewActive, _scopeNeovimActive, _scopePagerActive, _lastPaintedTop, _lastPaintedBottom, MAX_VISIBLE_ROWS, SAVE, RESTORE, HIDE, SHOW, CLEAR_LINE,
|
|
571398
|
+
var chromeWrite, _activeSessionId, _watcher, _lastTodos, _enabled, _redrawScheduled, _onResizeChange, _scopeOverlayActive, _scopeMainViewActive, _scopeNeovimActive, _scopePagerActive, _lastPaintedTop, _lastPaintedBottom, MAX_VISIBLE_ROWS, SAVE, RESTORE, HIDE, SHOW, CLEAR_LINE, RESET2, BG, DIM_LABEL, ACCENT, DONE2, PENDING, BLOCKED;
|
|
571047
571399
|
var init_tui_tasks_renderer = __esm({
|
|
571048
571400
|
"packages/cli/src/tui/tui-tasks-renderer.ts"() {
|
|
571049
571401
|
"use strict";
|
|
@@ -571070,7 +571422,7 @@ var init_tui_tasks_renderer = __esm({
|
|
|
571070
571422
|
HIDE = "\x1B[?25l";
|
|
571071
571423
|
SHOW = "\x1B[?25h";
|
|
571072
571424
|
CLEAR_LINE = "\x1B[2K";
|
|
571073
|
-
|
|
571425
|
+
RESET2 = "\x1B[0m";
|
|
571074
571426
|
BG = tuiBgSeq();
|
|
571075
571427
|
DIM_LABEL = "";
|
|
571076
571428
|
ACCENT = "";
|
|
@@ -571117,7 +571469,7 @@ function setTerminalTitle(task, version4) {
|
|
|
571117
571469
|
const title = task ? `${task.slice(0, 60)} · ${ver}` : ver;
|
|
571118
571470
|
process.stdout.write(`\x1B]2;${title}\x07`);
|
|
571119
571471
|
}
|
|
571120
|
-
var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL,
|
|
571472
|
+
var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL, BOX_TL2, BOX_TR2, BOX_BL2, BOX_BR2, BOX_H2, BOX_V2, _globalFooterLock, RESET3, CURSOR_BLINK_BLOCK, _isWindows, StatusBar;
|
|
571121
571473
|
var init_status_bar = __esm({
|
|
571122
571474
|
"packages/cli/src/tui/status-bar.ts"() {
|
|
571123
571475
|
"use strict";
|
|
@@ -571296,14 +571648,14 @@ var init_status_bar = __esm({
|
|
|
571296
571648
|
TEXT_PRIMARY = tuiTextPrimary() < 0 ? 252 : tuiTextPrimary();
|
|
571297
571649
|
TEXT_DIM = tuiTextDim();
|
|
571298
571650
|
NO_SUB_AGENTS_HEADER_LABEL = " no sub-agents ";
|
|
571299
|
-
|
|
571300
|
-
|
|
571301
|
-
|
|
571302
|
-
|
|
571303
|
-
|
|
571304
|
-
|
|
571651
|
+
BOX_TL2 = "╭";
|
|
571652
|
+
BOX_TR2 = "╮";
|
|
571653
|
+
BOX_BL2 = "╰";
|
|
571654
|
+
BOX_BR2 = "╯";
|
|
571655
|
+
BOX_H2 = "─";
|
|
571656
|
+
BOX_V2 = "│";
|
|
571305
571657
|
_globalFooterLock = false;
|
|
571306
|
-
|
|
571658
|
+
RESET3 = "\x1B[0m";
|
|
571307
571659
|
CURSOR_BLINK_BLOCK = "\x1B[1 q";
|
|
571308
571660
|
_isWindows = process.platform === "win32";
|
|
571309
571661
|
StatusBar = class _StatusBar {
|
|
@@ -571349,6 +571701,22 @@ var init_status_bar = __esm({
|
|
|
571349
571701
|
_contentScrollOffset = 0;
|
|
571350
571702
|
// 0 = live (bottom), >0 = scrolled back
|
|
571351
571703
|
_contentMaxLines = 1e4;
|
|
571704
|
+
/**
|
|
571705
|
+
* Dynamic content blocks — width-aware regions that re-render themselves
|
|
571706
|
+
* when the terminal resizes. The renderer registered here is called from
|
|
571707
|
+
* the scrollback reflow path: when a sentinel line of the form
|
|
571708
|
+
* `\x01DYNBLOCK:<id>\x01` is encountered, the registered fn is invoked
|
|
571709
|
+
* with the current terminal width and its returned lines replace the
|
|
571710
|
+
* sentinel in the reflowed output. This is how the Task Complete box
|
|
571711
|
+
* stays geometrically correct under SIGWINCH-driven resize.
|
|
571712
|
+
*
|
|
571713
|
+
* Keep the renderer cheap (pure data → strings) — it runs every full
|
|
571714
|
+
* repaint, including selection updates and scroll events.
|
|
571715
|
+
*/
|
|
571716
|
+
_dynamicBlocks = /* @__PURE__ */ new Map();
|
|
571717
|
+
/** Sentinel marker — used both for scrollback storage and reflow detection. */
|
|
571718
|
+
DYNAMIC_BLOCK_MARK_PREFIX = "DYNBLOCK:";
|
|
571719
|
+
DYNAMIC_BLOCK_MARK_SUFFIX = "";
|
|
571352
571720
|
// Partial-line accumulator for the buffered-write layer. Stream output
|
|
571353
571721
|
// arrives in chunks (one per syntax-highlighted token) and a single
|
|
571354
571722
|
// logical line can span many writes. If we naively push each chunk to
|
|
@@ -571459,6 +571827,41 @@ var init_status_bar = __esm({
|
|
|
571459
571827
|
syncEnd() {
|
|
571460
571828
|
this.termWrite("\x1B[?2026l");
|
|
571461
571829
|
}
|
|
571830
|
+
/**
|
|
571831
|
+
* Register (or replace) a dynamic content block. Returns the sentinel
|
|
571832
|
+
* line the caller should push into the scrollback to make the block
|
|
571833
|
+
* appear there. The block's renderer is invoked on every repaint and
|
|
571834
|
+
* given the current terminal width; its returned lines are spliced in
|
|
571835
|
+
* place of the sentinel during reflow. Callers MUST also call
|
|
571836
|
+
* `appendDynamicBlock(id)` to actually place the block in scrollback.
|
|
571837
|
+
*
|
|
571838
|
+
* The sentinel is opaque — never write it directly to stdout; route
|
|
571839
|
+
* through `appendDynamicBlock` which also triggers a repaint so the
|
|
571840
|
+
* block becomes visible immediately.
|
|
571841
|
+
*/
|
|
571842
|
+
registerDynamicBlock(id, render2) {
|
|
571843
|
+
this._dynamicBlocks.set(id, render2);
|
|
571844
|
+
return `${this.DYNAMIC_BLOCK_MARK_PREFIX}${id}${this.DYNAMIC_BLOCK_MARK_SUFFIX}`;
|
|
571845
|
+
}
|
|
571846
|
+
/** Unregister a dynamic block. Existing sentinels in scrollback become inert (rendered as empty). */
|
|
571847
|
+
unregisterDynamicBlock(id) {
|
|
571848
|
+
this._dynamicBlocks.delete(id);
|
|
571849
|
+
}
|
|
571850
|
+
/**
|
|
571851
|
+
* Append a previously-registered dynamic block's sentinel to scrollback
|
|
571852
|
+
* and trigger a repaint. The block's renderer fires immediately at the
|
|
571853
|
+
* current terminal width and again on every subsequent SIGWINCH (because
|
|
571854
|
+
* `_handleResizeImmediate` already calls `repaintContent`).
|
|
571855
|
+
*/
|
|
571856
|
+
appendDynamicBlock(id) {
|
|
571857
|
+
if (!this._dynamicBlocks.has(id)) return;
|
|
571858
|
+
const sentinel = `${this.DYNAMIC_BLOCK_MARK_PREFIX}${id}${this.DYNAMIC_BLOCK_MARK_SUFFIX}`;
|
|
571859
|
+
this._contentLines.push(sentinel);
|
|
571860
|
+
if (this._contentLines.length > this._contentMaxLines) {
|
|
571861
|
+
this._contentLines.splice(0, this._contentLines.length - this._contentMaxLines);
|
|
571862
|
+
}
|
|
571863
|
+
if (this.active) this.repaintContent();
|
|
571864
|
+
}
|
|
571462
571865
|
/** Force a complete footer redraw (public wrapper for renderFooterAndPositionInput).
|
|
571463
571866
|
*
|
|
571464
571867
|
* IMPORTANT: do NOT call `updateFooterHeight()` here. The inner render
|
|
@@ -571595,7 +571998,7 @@ var init_status_bar = __esm({
|
|
|
571595
571998
|
const segment = segments[i2];
|
|
571596
571999
|
if (i2 > 0) {
|
|
571597
572000
|
separatorOffsets.push(width);
|
|
571598
|
-
text += `${BOX_FG}${
|
|
572001
|
+
text += `${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
571599
572002
|
width += 1;
|
|
571600
572003
|
}
|
|
571601
572004
|
text += `\x1B[1;38;5;${TEXT_PRIMARY}m${PANEL_BG_SEQ}${segment}`;
|
|
@@ -571777,7 +572180,7 @@ var init_status_bar = __esm({
|
|
|
571777
572180
|
const sysSeparatorOffset = sysItems.reduce((sum, item) => sum + item.w, 0);
|
|
571778
572181
|
this._sysSeparatorOffset = sysSeparatorOffset;
|
|
571779
572182
|
sysItems.push({
|
|
571780
|
-
render: () => `${BOX_FG}│${
|
|
572183
|
+
render: () => `${BOX_FG}│${RESET3}${PANEL_BG_SEQ} `,
|
|
571781
572184
|
w: 2
|
|
571782
572185
|
});
|
|
571783
572186
|
const voiceLabel = this._voiceActive ? ` ${this._voiceModelId || "voice"} ` : " voice ";
|
|
@@ -571974,7 +572377,7 @@ var init_status_bar = __esm({
|
|
|
571974
572377
|
const hdrRow = layout().headerContent;
|
|
571975
572378
|
let buf = "\x1B7";
|
|
571976
572379
|
buf += `\x1B[${hdrRow};1H${PANEL_BG_SEQ}\x1B[2K`;
|
|
571977
|
-
buf += `${BOX_FG}│${
|
|
572380
|
+
buf += `${BOX_FG}│${RESET3}${PANEL_BG_SEQ}`;
|
|
571978
572381
|
if (chrome.showPrev) {
|
|
571979
572382
|
buf += leftArrow;
|
|
571980
572383
|
buf += ` `;
|
|
@@ -571985,7 +572388,7 @@ var init_status_bar = __esm({
|
|
|
571985
572388
|
buf += `\x1B[${hdrRow};${w - 1}H`;
|
|
571986
572389
|
buf += rightArrow;
|
|
571987
572390
|
}
|
|
571988
|
-
buf += `\x1B[${hdrRow};${w}H${BOX_FG}│${
|
|
572391
|
+
buf += `\x1B[${hdrRow};${w}H${BOX_FG}│${RESET3}${PANEL_BG_SEQ}`;
|
|
571989
572392
|
buf += "\x1B8";
|
|
571990
572393
|
this.termWrite(buf);
|
|
571991
572394
|
}
|
|
@@ -573188,11 +573591,11 @@ var init_status_bar = __esm({
|
|
|
573188
573591
|
for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
|
|
573189
573592
|
const row = pos.inputStartRow + i2;
|
|
573190
573593
|
const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
|
|
573191
|
-
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${prefix}${inputWrap.lines[i2]}${
|
|
573594
|
+
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${prefix}${inputWrap.lines[i2]}${RESET3}${PANEL_BG_SEQ}`;
|
|
573192
573595
|
}
|
|
573193
573596
|
const boxInnerP = w - 2;
|
|
573194
|
-
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
573195
|
-
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${
|
|
573597
|
+
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL2}${BOX_H2.repeat(Math.max(0, boxInnerP))}${BOX_BR2}${RESET3}${PANEL_BG_SEQ}`;
|
|
573598
|
+
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET3}${PANEL_BG_SEQ}\x1B[?7h\x1B[${pos.inputStartRow};1H`;
|
|
573196
573599
|
this.termWrite(buf);
|
|
573197
573600
|
if (this._bannerRefresh) this._bannerRefresh();
|
|
573198
573601
|
} else {
|
|
@@ -573393,7 +573796,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
573393
573796
|
process.stdout.write = this._origWrite;
|
|
573394
573797
|
this._origWrite = null;
|
|
573395
573798
|
}
|
|
573396
|
-
process.stdout.write(
|
|
573799
|
+
process.stdout.write(RESET3);
|
|
573397
573800
|
this._brailleSpinner.setMetrics({ isStreaming: false });
|
|
573398
573801
|
this.renderFooterAndPositionInput();
|
|
573399
573802
|
this.parkCursorInInput();
|
|
@@ -573522,12 +573925,32 @@ ${CONTENT_BG_SEQ}`);
|
|
|
573522
573925
|
reflowContentLines(livePartialLine, width) {
|
|
573523
573926
|
const maxWidth = Math.max(16, width);
|
|
573524
573927
|
const source = livePartialLine ? [...this._contentLines, livePartialLine] : this._contentLines;
|
|
573525
|
-
return source.flatMap(
|
|
573526
|
-
(line
|
|
573928
|
+
return source.flatMap((line, idx) => {
|
|
573929
|
+
if (line.startsWith(this.DYNAMIC_BLOCK_MARK_PREFIX) && line.endsWith(this.DYNAMIC_BLOCK_MARK_SUFFIX)) {
|
|
573930
|
+
const id = line.slice(
|
|
573931
|
+
this.DYNAMIC_BLOCK_MARK_PREFIX.length,
|
|
573932
|
+
line.length - this.DYNAMIC_BLOCK_MARK_SUFFIX.length
|
|
573933
|
+
);
|
|
573934
|
+
const renderer = this._dynamicBlocks.get(id);
|
|
573935
|
+
if (!renderer) return [];
|
|
573936
|
+
let blockLines;
|
|
573937
|
+
try {
|
|
573938
|
+
blockLines = renderer(maxWidth);
|
|
573939
|
+
} catch {
|
|
573940
|
+
return [];
|
|
573941
|
+
}
|
|
573942
|
+
return blockLines.flatMap(
|
|
573943
|
+
(segment) => this.reflowContentLine(segment, maxWidth).map((s2) => ({
|
|
573944
|
+
line: s2,
|
|
573945
|
+
bufferIdx: idx
|
|
573946
|
+
}))
|
|
573947
|
+
);
|
|
573948
|
+
}
|
|
573949
|
+
return this.reflowContentLine(line, maxWidth).map((segment) => ({
|
|
573527
573950
|
line: segment,
|
|
573528
573951
|
bufferIdx: idx
|
|
573529
|
-
}))
|
|
573530
|
-
);
|
|
573952
|
+
}));
|
|
573953
|
+
});
|
|
573531
573954
|
}
|
|
573532
573955
|
reflowContentLine(line, width) {
|
|
573533
573956
|
const visible = stripAnsi(line);
|
|
@@ -573587,7 +574010,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
573587
574010
|
const endRaw = this.rawIndexForVisibleColumn(line, end);
|
|
573588
574011
|
const activeStyle = this.activeSgrAt(line, startRaw);
|
|
573589
574012
|
const raw = line.slice(startRaw, endRaw);
|
|
573590
|
-
return activeStyle ? `${activeStyle}${raw}${
|
|
574013
|
+
return activeStyle ? `${activeStyle}${raw}${RESET3}` : raw;
|
|
573591
574014
|
}
|
|
573592
574015
|
rawIndexForVisibleColumn(line, target) {
|
|
573593
574016
|
if (target <= 0) return 0;
|
|
@@ -573611,7 +574034,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
573611
574034
|
let match;
|
|
573612
574035
|
while ((match = sgr.exec(line)) && match.index < rawIndex) {
|
|
573613
574036
|
const seq = match[0];
|
|
573614
|
-
if (seq ===
|
|
574037
|
+
if (seq === RESET3 || /\x1B\[(?:0|39|49)(?:;0)?m/.test(seq)) {
|
|
573615
574038
|
active = "";
|
|
573616
574039
|
} else {
|
|
573617
574040
|
active += seq;
|
|
@@ -574386,21 +574809,21 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574386
574809
|
const inputWrap = this.wrapInput(w);
|
|
574387
574810
|
let buf = "\x1B[?7l";
|
|
574388
574811
|
const boxInner = w - 2;
|
|
574389
|
-
buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574812
|
+
buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL2}${BOX_H2.repeat(Math.max(0, boxInner))}${BOX_TR2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574390
574813
|
const Lspacer = layout();
|
|
574391
574814
|
const spacerRow = pos.inputStartRow - 1;
|
|
574392
574815
|
const tasksOccupiesSpacer = Lspacer.tasksHeight > 0 && spacerRow >= Lspacer.tasksTop && spacerRow <= Lspacer.tasksBottom;
|
|
574393
574816
|
if (spacerRow >= this.scrollRegionTop && !tasksOccupiesSpacer) {
|
|
574394
|
-
buf += `\x1B[${spacerRow};1H${PANEL_BG_SEQ}\x1B[2K${
|
|
574817
|
+
buf += `\x1B[${spacerRow};1H${PANEL_BG_SEQ}\x1B[2K${RESET3}`;
|
|
574395
574818
|
}
|
|
574396
574819
|
for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
|
|
574397
574820
|
const row = pos.inputStartRow + 1 + i2;
|
|
574398
574821
|
const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
|
|
574399
574822
|
const lineContent = `${prefix}${inputWrap.lines[i2]}`;
|
|
574400
574823
|
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K`;
|
|
574401
|
-
buf += `${BOX_FG}${
|
|
574824
|
+
buf += `${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}${lineContent}`;
|
|
574402
574825
|
buf += `${PANEL_BG_SEQ}\x1B[K`;
|
|
574403
|
-
buf += `\x1B[${row};${w}H${BOX_FG}${
|
|
574826
|
+
buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574404
574827
|
}
|
|
574405
574828
|
const cursorTermRow = pos.inputStartRow + 1 + inputWrap.cursorRow;
|
|
574406
574829
|
if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
|
|
@@ -574412,17 +574835,17 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574412
574835
|
const fg2 = isHighlighted ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
|
|
574413
574836
|
const slash = isHighlighted ? `\x1B[38;5;245m` : `\x1B[38;5;${TEXT_DIM}m`;
|
|
574414
574837
|
const marker = isHighlighted ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
|
|
574415
|
-
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574838
|
+
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574416
574839
|
buf += `${bg} ${marker}${slash}/${fg2}${cmd}`;
|
|
574417
574840
|
buf += `${PANEL_BG_SEQ}\x1B[K`;
|
|
574418
|
-
buf += `\x1B[${row};${w}H${BOX_FG}${
|
|
574841
|
+
buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574419
574842
|
}
|
|
574420
574843
|
const suggestBottomRow = pos.suggestStartRow + this._suggestions.length;
|
|
574421
|
-
buf += `\x1B[${suggestBottomRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574844
|
+
buf += `\x1B[${suggestBottomRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL2}${BOX_H2.repeat(Math.max(0, boxInner))}${BOX_BR2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574422
574845
|
} else {
|
|
574423
|
-
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574846
|
+
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL2}${BOX_H2.repeat(Math.max(0, boxInner))}${BOX_BR2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574424
574847
|
}
|
|
574425
|
-
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${
|
|
574848
|
+
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET3}${PANEL_BG_SEQ}`;
|
|
574426
574849
|
buf += "\x1B[?7h";
|
|
574427
574850
|
if (this.writeDepth === 0) {
|
|
574428
574851
|
buf += `\x1B[${cursorTermRow};${inputWrap.cursorCol}H${CURSOR_BLINK_BLOCK}\x1B[?25h`;
|
|
@@ -574455,7 +574878,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574455
574878
|
const pos = this.rowPositions(termRows());
|
|
574456
574879
|
let buf = "\x1B7\x1B[?7l";
|
|
574457
574880
|
if (pos.tabBarRow > 0) {
|
|
574458
|
-
buf += `\x1B[${pos.tabBarRow};1H${PANEL_BG_SEQ}\x1B[2K${
|
|
574881
|
+
buf += `\x1B[${pos.tabBarRow};1H${PANEL_BG_SEQ}\x1B[2K${RESET3}`;
|
|
574459
574882
|
}
|
|
574460
574883
|
const boxInnerR = w - 2;
|
|
574461
574884
|
if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
|
|
@@ -574465,14 +574888,14 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574465
574888
|
const isHl = si === this._suggestIndex;
|
|
574466
574889
|
const fg2 = isHl ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
|
|
574467
574890
|
const marker = isHl ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
|
|
574468
|
-
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574469
|
-
buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${
|
|
574891
|
+
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ} ${marker}\x1B[38;5;${TEXT_DIM}m/${fg2}${cmd}`;
|
|
574892
|
+
buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V2}${RESET3}`;
|
|
574470
574893
|
}
|
|
574471
|
-
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574894
|
+
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL2}${BOX_H2.repeat(Math.max(0, boxInnerR))}${BOX_BR2}${RESET3}`;
|
|
574472
574895
|
} else {
|
|
574473
|
-
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574896
|
+
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL2}${BOX_H2.repeat(Math.max(0, boxInnerR))}${BOX_BR2}${RESET3}`;
|
|
574474
574897
|
}
|
|
574475
|
-
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${
|
|
574898
|
+
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET3}${PANEL_BG_SEQ}\x1B[?7h\x1B8` + // DEC restore cursor
|
|
574476
574899
|
(this.writeDepth === 0 ? `${CURSOR_BLINK_BLOCK}\x1B[?25h` : "");
|
|
574477
574900
|
this.termWrite(buf);
|
|
574478
574901
|
if (pos.tabBarRow > 0) this.renderAgentTabs();
|
|
@@ -574516,12 +574939,12 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574516
574939
|
}
|
|
574517
574940
|
buf += "\x1B[?7l";
|
|
574518
574941
|
const boxInnerH = w - 2;
|
|
574519
|
-
buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574942
|
+
buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL2}${BOX_H2.repeat(Math.max(0, boxInnerH))}${BOX_TR2}${RESET3}`;
|
|
574520
574943
|
for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
|
|
574521
574944
|
const row = pos.inputStartRow + 1 + i2;
|
|
574522
574945
|
const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
|
|
574523
574946
|
const lineContent = `${prefix}${inputWrap.lines[i2]}`;
|
|
574524
|
-
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574947
|
+
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}${lineContent}${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V2}${RESET3}`;
|
|
574525
574948
|
}
|
|
574526
574949
|
if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
|
|
574527
574950
|
for (let si = 0; si < this._suggestions.length; si++) {
|
|
@@ -574531,14 +574954,14 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574531
574954
|
const bg = isHl ? `\x1B[48;5;235m` : PANEL_BG_SEQ;
|
|
574532
574955
|
const fg2 = isHl ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
|
|
574533
574956
|
const marker = isHl ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
|
|
574534
|
-
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574957
|
+
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574535
574958
|
buf += `${bg} ${marker}\x1B[38;5;${TEXT_DIM}m/${fg2}${cmd}`;
|
|
574536
|
-
buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${
|
|
574959
|
+
buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V2}${RESET3}`;
|
|
574537
574960
|
}
|
|
574538
574961
|
}
|
|
574539
574962
|
const boxInnerS = w - 2;
|
|
574540
|
-
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574541
|
-
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${
|
|
574963
|
+
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL2}${BOX_H2.repeat(Math.max(0, boxInnerS))}${BOX_BR2}${RESET3}`;
|
|
574964
|
+
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET3}`;
|
|
574542
574965
|
buf += "\x1B[?7h";
|
|
574543
574966
|
buf += "\x1B8";
|
|
574544
574967
|
if (heightDelta > 0) {
|
|
@@ -574556,9 +574979,9 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574556
574979
|
const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
|
|
574557
574980
|
const lineContent = `${prefix}${inputWrap.lines[i2]}`;
|
|
574558
574981
|
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K`;
|
|
574559
|
-
buf += `${BOX_FG}${
|
|
574982
|
+
buf += `${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}${lineContent}`;
|
|
574560
574983
|
buf += `${PANEL_BG_SEQ}\x1B[K`;
|
|
574561
|
-
buf += `\x1B[${row};${w}H${BOX_FG}${
|
|
574984
|
+
buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574562
574985
|
}
|
|
574563
574986
|
buf += "\x1B[?7h";
|
|
574564
574987
|
this.termWrite(buf);
|
|
@@ -584685,6 +585108,13 @@ function formatImageAsciiContext(preview, label) {
|
|
|
584685
585108
|
return `[ASCII preview of image: ${label}]
|
|
584686
585109
|
${preview.ascii}`;
|
|
584687
585110
|
}
|
|
585111
|
+
function hasImageExtension(filePath) {
|
|
585112
|
+
const lower = filePath.toLowerCase();
|
|
585113
|
+
for (const ext of IMAGE_PREVIEW_EXTENSIONS) {
|
|
585114
|
+
if (lower.endsWith(ext)) return true;
|
|
585115
|
+
}
|
|
585116
|
+
return false;
|
|
585117
|
+
}
|
|
584688
585118
|
function extractSavedImagePath(text, repoRoot) {
|
|
584689
585119
|
const patterns = [
|
|
584690
585120
|
/Image generated:\s*([^\n\r]+)/i,
|
|
@@ -584700,18 +585130,29 @@ function extractSavedImagePath(text, repoRoot) {
|
|
|
584700
585130
|
const match = text.match(pattern);
|
|
584701
585131
|
if (!match?.[1]) continue;
|
|
584702
585132
|
const raw = match[1].trim().replace(/\s+\([^)]+\)\s*$/g, "").replace(/^["']|["']$/g, "");
|
|
585133
|
+
if (!hasImageExtension(raw)) continue;
|
|
584703
585134
|
const candidate = raw.startsWith("/") ? raw : resolve40(repoRoot, raw);
|
|
584704
585135
|
if (existsSync99(candidate)) return candidate;
|
|
584705
585136
|
}
|
|
584706
585137
|
return null;
|
|
584707
585138
|
}
|
|
584708
|
-
var DEFAULT_PIXELS, ANSI_PATTERN, TERMINAL_CELL_ASPECT;
|
|
585139
|
+
var DEFAULT_PIXELS, ANSI_PATTERN, TERMINAL_CELL_ASPECT, IMAGE_PREVIEW_EXTENSIONS;
|
|
584709
585140
|
var init_image_ascii_preview = __esm({
|
|
584710
585141
|
"packages/cli/src/tui/image-ascii-preview.ts"() {
|
|
584711
585142
|
"use strict";
|
|
584712
585143
|
DEFAULT_PIXELS = " .,:;i1tfLCG08@";
|
|
584713
585144
|
ANSI_PATTERN = /\x1B\[[0-?]*[ -/]*[@-~]/g;
|
|
584714
585145
|
TERMINAL_CELL_ASPECT = 0.52;
|
|
585146
|
+
IMAGE_PREVIEW_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
585147
|
+
".png",
|
|
585148
|
+
".jpg",
|
|
585149
|
+
".jpeg",
|
|
585150
|
+
".gif",
|
|
585151
|
+
".webp",
|
|
585152
|
+
".bmp",
|
|
585153
|
+
".tiff",
|
|
585154
|
+
".tif"
|
|
585155
|
+
]);
|
|
584715
585156
|
}
|
|
584716
585157
|
});
|
|
584717
585158
|
|
|
@@ -649733,13 +650174,24 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
649733
650174
|
}
|
|
649734
650175
|
contentWrite(() => {
|
|
649735
650176
|
if (result.completed) {
|
|
649736
|
-
renderTaskComplete(
|
|
649737
|
-
|
|
649738
|
-
result.
|
|
649739
|
-
result.
|
|
649740
|
-
result.
|
|
649741
|
-
|
|
649742
|
-
|
|
650177
|
+
renderTaskComplete({
|
|
650178
|
+
task: effectiveTask,
|
|
650179
|
+
summary: result.summary,
|
|
650180
|
+
turns: result.turns,
|
|
650181
|
+
toolCalls: result.toolCalls,
|
|
650182
|
+
durationMs: result.durationMs,
|
|
650183
|
+
tokens,
|
|
650184
|
+
filesEdited: result.filesEdited,
|
|
650185
|
+
testsRun: result.testsRun,
|
|
650186
|
+
provenanceAnchors: result.provenanceAnchors,
|
|
650187
|
+
// Hand the status bar so the box renders as a resize-aware
|
|
650188
|
+
// dynamic block. When the bar isn't active (tests, headless),
|
|
650189
|
+
// the legacy line-based banner fires instead.
|
|
650190
|
+
host: statusBar?.isActive ? {
|
|
650191
|
+
registerDynamicBlock: (id, render2) => statusBar.registerDynamicBlock(id, render2),
|
|
650192
|
+
appendDynamicBlock: (id) => statusBar.appendDynamicBlock(id)
|
|
650193
|
+
} : void 0
|
|
650194
|
+
});
|
|
649743
650195
|
if (onComplete)
|
|
649744
650196
|
onComplete(result.summary, {
|
|
649745
650197
|
turns: result.turns,
|