omnius 1.0.88 → 1.0.90
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 +865 -474
- 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"() {
|
|
@@ -544514,9 +544515,6 @@ ${memoryLines.join("\n")}`
|
|
|
544514
544515
|
const churnBlock = this._renderWriteChurnBlock(turn);
|
|
544515
544516
|
if (churnBlock)
|
|
544516
544517
|
_injections.push(churnBlock);
|
|
544517
|
-
const progressBlock = this._renderProgressNudgeBlock(turn);
|
|
544518
|
-
if (progressBlock)
|
|
544519
|
-
_injections.push(progressBlock);
|
|
544520
544518
|
const knowledgeBlock = this._renderKnowledgeBlock(recentToolResults);
|
|
544521
544519
|
if (knowledgeBlock)
|
|
544522
544520
|
_injections.push(knowledgeBlock);
|
|
@@ -545062,55 +545060,6 @@ ${memoryLines.join("\n")}`
|
|
|
545062
545060
|
return { tc, output: _decomp2Block };
|
|
545063
545061
|
}
|
|
545064
545062
|
}
|
|
545065
|
-
const PROGRESS_GATE_BYPASS_TOOLS = /* @__PURE__ */ new Set([
|
|
545066
|
-
"todo_write",
|
|
545067
|
-
"todo_read",
|
|
545068
|
-
"task_complete",
|
|
545069
|
-
"ask_user",
|
|
545070
|
-
"phase_recall"
|
|
545071
|
-
// useful for the agent to consult prior phase state before updating
|
|
545072
|
-
]);
|
|
545073
|
-
if (this._progressGateActive && !PROGRESS_GATE_BYPASS_TOOLS.has(tc.name)) {
|
|
545074
|
-
this.emit({
|
|
545075
|
-
type: "tool_call",
|
|
545076
|
-
toolName: tc.name,
|
|
545077
|
-
toolArgs: tc.arguments,
|
|
545078
|
-
turn,
|
|
545079
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
545080
|
-
});
|
|
545081
|
-
const recentWrites = [];
|
|
545082
|
-
for (const [path12, info] of this._worldFacts.files) {
|
|
545083
|
-
if ((info.writeCount ?? 0) > 0 && (info.lastWriteTurn ?? -1) >= 0 && turn - (info.lastWriteTurn ?? 0) <= 8) {
|
|
545084
|
-
recentWrites.push({ path: path12, turn: info.lastWriteTurn ?? 0 });
|
|
545085
|
-
}
|
|
545086
|
-
}
|
|
545087
|
-
recentWrites.sort((a2, b) => b.turn - a2.turn);
|
|
545088
|
-
const showWrites = recentWrites.slice(0, 16);
|
|
545089
|
-
const gateMsg = [
|
|
545090
|
-
`[PROGRESS GATE — call todo_write FIRST before any other tool]`,
|
|
545091
|
-
``,
|
|
545092
|
-
`You have completed ${this._writesSinceLastTodoWrite} file modification${this._writesSinceLastTodoWrite === 1 ? "" : "s"} since your last todo_write call.`,
|
|
545093
|
-
`The next tool call MUST be todo_write to mark progress. This is enforced — non-todo tool calls are intercepted until plan state is updated.`,
|
|
545094
|
-
``,
|
|
545095
|
-
`Recent file modifications (use these to decide what's done):`,
|
|
545096
|
-
...showWrites.map((w) => ` • ${w.path} (turn ${w.turn})`),
|
|
545097
|
-
recentWrites.length > showWrites.length ? ` • ... +${recentWrites.length - showWrites.length} more` : "",
|
|
545098
|
-
``,
|
|
545099
|
-
`Required action: call todo_write with the updated todo array — mark anything completed that these writes satisfy, advance the next item to in_progress, keep the rest pending.`,
|
|
545100
|
-
`After todo_write succeeds, this gate releases and you can continue normal work.`,
|
|
545101
|
-
``,
|
|
545102
|
-
`Why this exists: without the explicit progress update, your next turn will see the same in_progress todo, re-plan the same work, and re-emit identical tool calls (the "plan replay" failure mode that causes byte-identical writes to appear twice).`
|
|
545103
|
-
].filter(Boolean).join("\n");
|
|
545104
|
-
this.emit({
|
|
545105
|
-
type: "tool_result",
|
|
545106
|
-
toolName: tc.name,
|
|
545107
|
-
success: false,
|
|
545108
|
-
content: gateMsg.slice(0, 120),
|
|
545109
|
-
turn,
|
|
545110
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
545111
|
-
});
|
|
545112
|
-
return { tc, output: gateMsg };
|
|
545113
|
-
}
|
|
545114
545063
|
const _argsKeyForBudget = `${tc.name}:${argsKey}`;
|
|
545115
545064
|
const _isCachedHit = recentToolResults.has(_argsKeyForBudget);
|
|
545116
545065
|
const budgetRemaining = toolCallBudget.get(tc.name);
|
|
@@ -548147,6 +548096,60 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
548147
548096
|
fs11.appendFileSync(path12.join(trajDir, `trajectories.jsonl`), JSON.stringify(trajectory) + "\n", "utf-8");
|
|
548148
548097
|
} catch {
|
|
548149
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
|
+
}
|
|
548150
548153
|
return {
|
|
548151
548154
|
completed,
|
|
548152
548155
|
turns: messages2.filter((m2) => m2.role === "assistant").length,
|
|
@@ -548156,7 +548159,10 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
548156
548159
|
completionTokens,
|
|
548157
548160
|
estimatedTokens,
|
|
548158
548161
|
summary,
|
|
548159
|
-
durationMs
|
|
548162
|
+
durationMs,
|
|
548163
|
+
filesEdited,
|
|
548164
|
+
testsRun,
|
|
548165
|
+
provenanceAnchors
|
|
548160
548166
|
};
|
|
548161
548167
|
}
|
|
548162
548168
|
// -------------------------------------------------------------------------
|
|
@@ -562109,6 +562115,615 @@ var init_command_registry = __esm({
|
|
|
562109
562115
|
}
|
|
562110
562116
|
});
|
|
562111
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
|
+
if (bodyText) {
|
|
562629
|
+
lines.push(buildEmptyRow(w));
|
|
562630
|
+
for (const para of bodyText.split(/\n/)) {
|
|
562631
|
+
const wrapped = wrapToWidth(para, innerWidth);
|
|
562632
|
+
for (const line of wrapped) {
|
|
562633
|
+
lines.push(buildContentRow(line, w));
|
|
562634
|
+
}
|
|
562635
|
+
}
|
|
562636
|
+
lines.push(buildEmptyRow(w));
|
|
562637
|
+
}
|
|
562638
|
+
const hasFooter = (data.testsRun?.length ?? 0) > 0 || (data.filesEdited?.length ?? 0) > 0 || (data.provenanceAnchors?.length ?? 0) > 0;
|
|
562639
|
+
if (hasFooter) {
|
|
562640
|
+
lines.push(buildInnerDivider(w));
|
|
562641
|
+
if (data.testsRun?.length) {
|
|
562642
|
+
lines.push(...buildLabeledFooterLines("Tests", data.testsRun, w));
|
|
562643
|
+
}
|
|
562644
|
+
if (data.filesEdited?.length) {
|
|
562645
|
+
lines.push(...buildLabeledFooterLines("Files", data.filesEdited, w));
|
|
562646
|
+
}
|
|
562647
|
+
if (data.provenanceAnchors?.length) {
|
|
562648
|
+
lines.push(...buildLabeledFooterLines("Provenance", data.provenanceAnchors, w));
|
|
562649
|
+
}
|
|
562650
|
+
}
|
|
562651
|
+
lines.push(buildBottomBorder(w));
|
|
562652
|
+
return lines;
|
|
562653
|
+
}
|
|
562654
|
+
function renderTaskCompleteBox(host, data) {
|
|
562655
|
+
const blockId = `task-complete-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
562656
|
+
const frozen = {
|
|
562657
|
+
task: data.task,
|
|
562658
|
+
summary: data.summary,
|
|
562659
|
+
turns: data.turns,
|
|
562660
|
+
toolCalls: data.toolCalls,
|
|
562661
|
+
durationMs: data.durationMs,
|
|
562662
|
+
tokens: data.tokens ?? null,
|
|
562663
|
+
filesEdited: data.filesEdited ? [...data.filesEdited] : [],
|
|
562664
|
+
testsRun: data.testsRun ? [...data.testsRun] : [],
|
|
562665
|
+
provenanceAnchors: data.provenanceAnchors ? [...data.provenanceAnchors] : []
|
|
562666
|
+
};
|
|
562667
|
+
host.registerDynamicBlock(blockId, (width) => buildBoxLines(frozen, width));
|
|
562668
|
+
host.appendDynamicBlock(blockId);
|
|
562669
|
+
return blockId;
|
|
562670
|
+
}
|
|
562671
|
+
function detectTestRuns(shellCommands) {
|
|
562672
|
+
const out = /* @__PURE__ */ new Set();
|
|
562673
|
+
const runners = [
|
|
562674
|
+
/\b(?:pnpm|npm|yarn)\s+(?:run\s+)?(test|test:[\w-]+|typecheck|lint)\b/,
|
|
562675
|
+
/\bvitest\s+(?:run\s+)?[\w-/.@]*/,
|
|
562676
|
+
/\bjest\s+[\w-/.@]*/,
|
|
562677
|
+
/\bpytest\s+[\w-/.@]*/,
|
|
562678
|
+
/\bmocha\s+[\w-/.@]*/,
|
|
562679
|
+
/\bgo\s+test\s+[\w./]+/,
|
|
562680
|
+
/\bcargo\s+test\b[\w\s-]*/
|
|
562681
|
+
];
|
|
562682
|
+
for (const cmd of shellCommands) {
|
|
562683
|
+
for (const re of runners) {
|
|
562684
|
+
const m2 = cmd.match(re);
|
|
562685
|
+
if (m2) {
|
|
562686
|
+
const label = m2[0].replace(/\s+/g, " ").trim();
|
|
562687
|
+
if (label.length <= 80) out.add(label);
|
|
562688
|
+
}
|
|
562689
|
+
}
|
|
562690
|
+
}
|
|
562691
|
+
return [...out].slice(0, 16);
|
|
562692
|
+
}
|
|
562693
|
+
function detectProvenanceAnchors(toolOutputs) {
|
|
562694
|
+
const out = /* @__PURE__ */ new Set();
|
|
562695
|
+
const re = /(urn:omnius:[^\s"'<>)]+|aiwg-prov:[^\s"'<>)]+)/g;
|
|
562696
|
+
for (const out_ of toolOutputs) {
|
|
562697
|
+
if (!out_) continue;
|
|
562698
|
+
for (const match of out_.matchAll(re)) {
|
|
562699
|
+
const anchor = match[0];
|
|
562700
|
+
if (anchor.length <= 120) out.add(anchor);
|
|
562701
|
+
}
|
|
562702
|
+
}
|
|
562703
|
+
return [...out].slice(0, 16);
|
|
562704
|
+
}
|
|
562705
|
+
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;
|
|
562706
|
+
var init_task_complete_box = __esm({
|
|
562707
|
+
"packages/cli/src/tui/task-complete-box.ts"() {
|
|
562708
|
+
"use strict";
|
|
562709
|
+
init_text_selection();
|
|
562710
|
+
BOX_TL = "╭";
|
|
562711
|
+
BOX_TR = "╮";
|
|
562712
|
+
BOX_BL = "╰";
|
|
562713
|
+
BOX_BR = "╯";
|
|
562714
|
+
BOX_H = "─";
|
|
562715
|
+
BOX_V = "│";
|
|
562716
|
+
BOX_TJ_L = "├";
|
|
562717
|
+
BOX_TJ_R = "┤";
|
|
562718
|
+
RESET = "\x1B[0m";
|
|
562719
|
+
GREEN = "\x1B[38;5;114m";
|
|
562720
|
+
FG_BORDER = "\x1B[38;5;245m";
|
|
562721
|
+
FG_TITLE = "\x1B[1;38;5;117m";
|
|
562722
|
+
FG_METRIC = "\x1B[38;5;222m";
|
|
562723
|
+
FG_LABEL = "\x1B[38;5;147m";
|
|
562724
|
+
}
|
|
562725
|
+
});
|
|
562726
|
+
|
|
562112
562727
|
// packages/cli/src/tui/render.ts
|
|
562113
562728
|
var render_exports = {};
|
|
562114
562729
|
__export(render_exports, {
|
|
@@ -562355,16 +562970,16 @@ function renderToolResult(toolName, success, output, verbose) {
|
|
|
562355
562970
|
`);
|
|
562356
562971
|
return;
|
|
562357
562972
|
}
|
|
562358
|
-
renderCodePreview(output, prefix, maxW,
|
|
562973
|
+
renderCodePreview(output, prefix, maxW, 10);
|
|
562359
562974
|
return;
|
|
562360
562975
|
}
|
|
562361
562976
|
case "shell":
|
|
562362
562977
|
case "background_run": {
|
|
562363
|
-
renderShellOutput(output, success, prefix, maxW,
|
|
562978
|
+
renderShellOutput(output, success, prefix, maxW, 10);
|
|
562364
562979
|
return;
|
|
562365
562980
|
}
|
|
562366
562981
|
case "grep_search": {
|
|
562367
|
-
renderShellOutput(output, success, prefix, maxW,
|
|
562982
|
+
renderShellOutput(output, success, prefix, maxW, 10);
|
|
562368
562983
|
return;
|
|
562369
562984
|
}
|
|
562370
562985
|
case "task_complete": {
|
|
@@ -562513,18 +563128,40 @@ function highlightToolOutput(line) {
|
|
|
562513
563128
|
if (formatted !== line) return formatted;
|
|
562514
563129
|
return c3.dim(line);
|
|
562515
563130
|
}
|
|
562516
|
-
function renderTaskComplete(
|
|
562517
|
-
const
|
|
562518
|
-
|
|
563131
|
+
function renderTaskComplete(arg1, turns, toolCalls, durationMs, tokens) {
|
|
563132
|
+
const opts = typeof arg1 === "string" ? {
|
|
563133
|
+
summary: arg1,
|
|
563134
|
+
turns: turns ?? 0,
|
|
563135
|
+
toolCalls: toolCalls ?? 0,
|
|
563136
|
+
durationMs: durationMs ?? 0,
|
|
563137
|
+
tokens
|
|
563138
|
+
} : arg1;
|
|
563139
|
+
if (opts.host) {
|
|
563140
|
+
const { renderTaskCompleteBox: renderTaskCompleteBox2 } = (init_task_complete_box(), __toCommonJS(task_complete_box_exports));
|
|
563141
|
+
renderTaskCompleteBox2(opts.host, {
|
|
563142
|
+
task: opts.task ?? "",
|
|
563143
|
+
summary: opts.summary,
|
|
563144
|
+
turns: opts.turns,
|
|
563145
|
+
toolCalls: opts.toolCalls,
|
|
563146
|
+
durationMs: opts.durationMs,
|
|
563147
|
+
tokens: opts.tokens ?? null,
|
|
563148
|
+
filesEdited: opts.filesEdited,
|
|
563149
|
+
testsRun: opts.testsRun,
|
|
563150
|
+
provenanceAnchors: opts.provenanceAnchors
|
|
563151
|
+
});
|
|
563152
|
+
return;
|
|
563153
|
+
}
|
|
563154
|
+
const duration = formatDuration3(opts.durationMs);
|
|
563155
|
+
const tokenStr = opts.tokens ? ` ${formatTokenCount2(opts.tokens)}` : "";
|
|
562519
563156
|
process.stdout.write(`
|
|
562520
|
-
${c3.green("✔")} ${c3.bold("Task completed")} ${c3.dim(`(${turns} turns, ${toolCalls} tool calls, ${duration})`)}
|
|
563157
|
+
${c3.green("✔")} ${c3.bold("Task completed")} ${c3.dim(`(${opts.turns} turns, ${opts.toolCalls} tool calls, ${duration})`)}
|
|
562521
563158
|
`);
|
|
562522
563159
|
if (tokenStr) {
|
|
562523
563160
|
process.stdout.write(` ${c3.dim(tokenStr)}
|
|
562524
563161
|
`);
|
|
562525
563162
|
}
|
|
562526
|
-
if (summary) {
|
|
562527
|
-
const formatted = formatMarkdownBlock(wrapTaskCompleteSummary(summary));
|
|
563163
|
+
if (opts.summary) {
|
|
563164
|
+
const formatted = formatMarkdownBlock(wrapTaskCompleteSummary(opts.summary));
|
|
562528
563165
|
const lines = formatted.split("\n");
|
|
562529
563166
|
for (const line of lines) {
|
|
562530
563167
|
process.stdout.write(` ${line}
|
|
@@ -562579,8 +563216,8 @@ function hangingIndentForPlainLine(line, width) {
|
|
|
562579
563216
|
return capped(line.match(/^\s*/)?.[0].length ?? 0);
|
|
562580
563217
|
}
|
|
562581
563218
|
function renderTaskIncomplete(turns, toolCalls, durationMs, tokens) {
|
|
562582
|
-
const duration =
|
|
562583
|
-
const tokenStr = tokens ? ` ${
|
|
563219
|
+
const duration = formatDuration3(durationMs);
|
|
563220
|
+
const tokenStr = tokens ? ` ${formatTokenCount2(tokens)}` : "";
|
|
562584
563221
|
process.stdout.write(`
|
|
562585
563222
|
${c3.yellow("⚠")} ${c3.bold("Task incomplete")} ${c3.dim(`(${turns} turns, ${toolCalls} tool calls, ${duration})`)}
|
|
562586
563223
|
`);
|
|
@@ -562590,7 +563227,7 @@ ${c3.yellow("⚠")} ${c3.bold("Task incomplete")} ${c3.dim(`(${turns} turns, ${t
|
|
|
562590
563227
|
}
|
|
562591
563228
|
process.stdout.write("\n");
|
|
562592
563229
|
}
|
|
562593
|
-
function
|
|
563230
|
+
function formatTokenCount2(tokens) {
|
|
562594
563231
|
if (tokens.total > 0) {
|
|
562595
563232
|
return `Tokens: ${tokens.total.toLocaleString()}`;
|
|
562596
563233
|
}
|
|
@@ -562890,7 +563527,7 @@ function formatToolArgs(toolName, args, verbose) {
|
|
|
562890
563527
|
function truncStr(s2, max) {
|
|
562891
563528
|
return s2.length > max ? s2.slice(0, max) + "..." : s2;
|
|
562892
563529
|
}
|
|
562893
|
-
function
|
|
563530
|
+
function formatDuration3(ms) {
|
|
562894
563531
|
if (ms < 1e3) return `${ms}ms`;
|
|
562895
563532
|
const totalSecs = ms / 1e3;
|
|
562896
563533
|
if (totalSecs < 60) return `${totalSecs.toFixed(1)}s`;
|
|
@@ -563164,7 +563801,7 @@ var init_render = __esm({
|
|
|
563164
563801
|
|
|
563165
563802
|
// packages/cli/src/tui/voice-session.ts
|
|
563166
563803
|
import { createServer as createServer4 } from "node:http";
|
|
563167
|
-
import { spawn as spawn23, execSync as
|
|
563804
|
+
import { spawn as spawn23, execSync as execSync48 } from "node:child_process";
|
|
563168
563805
|
import { EventEmitter as EventEmitter6 } from "node:events";
|
|
563169
563806
|
function generateFrontendHTML() {
|
|
563170
563807
|
return `<!DOCTYPE html>
|
|
@@ -570251,346 +570888,6 @@ var init_system_metrics = __esm({
|
|
|
570251
570888
|
}
|
|
570252
570889
|
});
|
|
570253
570890
|
|
|
570254
|
-
// packages/cli/src/tui/text-selection.ts
|
|
570255
|
-
var text_selection_exports = {};
|
|
570256
|
-
__export(text_selection_exports, {
|
|
570257
|
-
SEL_END: () => SEL_END,
|
|
570258
|
-
SEL_START: () => SEL_START,
|
|
570259
|
-
TextSelection: () => TextSelection,
|
|
570260
|
-
computeHeaderButtons: () => computeHeaderButtons,
|
|
570261
|
-
copyText: () => copyText,
|
|
570262
|
-
hitTestHeaderButton: () => hitTestHeaderButton,
|
|
570263
|
-
pasteText: () => pasteText,
|
|
570264
|
-
renderHeaderButtons: () => renderHeaderButtons,
|
|
570265
|
-
setHoveredButton: () => setHoveredButton,
|
|
570266
|
-
setPressedButton: () => setPressedButton,
|
|
570267
|
-
setUpdateBadgeRegion: () => setUpdateBadgeRegion,
|
|
570268
|
-
stripAnsi: () => stripAnsi,
|
|
570269
|
-
visibleLength: () => visibleLength
|
|
570270
|
-
});
|
|
570271
|
-
import { execSync as execSync48 } from "node:child_process";
|
|
570272
|
-
function stripAnsi(s2) {
|
|
570273
|
-
return s2.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
570274
|
-
}
|
|
570275
|
-
function visibleLength(s2) {
|
|
570276
|
-
return stripAnsi(s2).length;
|
|
570277
|
-
}
|
|
570278
|
-
function copyText(text) {
|
|
570279
|
-
try {
|
|
570280
|
-
const platform7 = process.platform;
|
|
570281
|
-
if (platform7 === "darwin") {
|
|
570282
|
-
execSync48("pbcopy", { input: text, timeout: 3e3 });
|
|
570283
|
-
return true;
|
|
570284
|
-
}
|
|
570285
|
-
if (platform7 === "win32") {
|
|
570286
|
-
execSync48("clip", { input: text, timeout: 3e3 });
|
|
570287
|
-
return true;
|
|
570288
|
-
}
|
|
570289
|
-
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
570290
|
-
try {
|
|
570291
|
-
execSync48(tool, { input: text, timeout: 3e3 });
|
|
570292
|
-
return true;
|
|
570293
|
-
} catch {
|
|
570294
|
-
continue;
|
|
570295
|
-
}
|
|
570296
|
-
}
|
|
570297
|
-
if (!_clipboardAutoInstallAttempted) {
|
|
570298
|
-
_clipboardAutoInstallAttempted = true;
|
|
570299
|
-
try {
|
|
570300
|
-
execSync48("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
570301
|
-
try {
|
|
570302
|
-
execSync48("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
|
|
570303
|
-
execSync48("xclip -selection clipboard", { input: text, timeout: 3e3 });
|
|
570304
|
-
return true;
|
|
570305
|
-
} catch {
|
|
570306
|
-
}
|
|
570307
|
-
} catch {
|
|
570308
|
-
}
|
|
570309
|
-
}
|
|
570310
|
-
} catch {
|
|
570311
|
-
}
|
|
570312
|
-
try {
|
|
570313
|
-
const b64 = Buffer.from(text).toString("base64");
|
|
570314
|
-
process.stdout.write(`\x1B]52;c;${b64}\x07`);
|
|
570315
|
-
return true;
|
|
570316
|
-
} catch {
|
|
570317
|
-
}
|
|
570318
|
-
return false;
|
|
570319
|
-
}
|
|
570320
|
-
function pasteText() {
|
|
570321
|
-
try {
|
|
570322
|
-
const platform7 = process.platform;
|
|
570323
|
-
if (platform7 === "darwin") {
|
|
570324
|
-
return execSync48("pbpaste", { timeout: 3e3, encoding: "utf8" }).trimEnd();
|
|
570325
|
-
}
|
|
570326
|
-
if (platform7 === "win32") {
|
|
570327
|
-
return execSync48("powershell -command Get-Clipboard", { timeout: 3e3, encoding: "utf8" }).trimEnd();
|
|
570328
|
-
}
|
|
570329
|
-
for (const tool of [
|
|
570330
|
-
{ cmd: "xclip", args: ["-selection", "clipboard", "-o"] },
|
|
570331
|
-
{ cmd: "xsel", args: ["--clipboard", "--output"] },
|
|
570332
|
-
{ cmd: "wl-paste", args: [] }
|
|
570333
|
-
]) {
|
|
570334
|
-
try {
|
|
570335
|
-
const result = execSync48(`${tool.cmd} ${tool.args.join(" ")}`, { timeout: 3e3, encoding: "utf8" });
|
|
570336
|
-
return result.trimEnd();
|
|
570337
|
-
} catch {
|
|
570338
|
-
continue;
|
|
570339
|
-
}
|
|
570340
|
-
}
|
|
570341
|
-
} catch {
|
|
570342
|
-
}
|
|
570343
|
-
return null;
|
|
570344
|
-
}
|
|
570345
|
-
function computeHeaderButtons(_termWidth) {
|
|
570346
|
-
return [];
|
|
570347
|
-
}
|
|
570348
|
-
function setHoveredButton(cmd) {
|
|
570349
|
-
_hoveredButtonCmd = cmd;
|
|
570350
|
-
}
|
|
570351
|
-
function setPressedButton(cmd) {
|
|
570352
|
-
_pressedButtonCmd = cmd;
|
|
570353
|
-
}
|
|
570354
|
-
function renderHeaderButtons(_termWidth) {
|
|
570355
|
-
return "";
|
|
570356
|
-
}
|
|
570357
|
-
function setUpdateBadgeRegion(active, startCol, length4) {
|
|
570358
|
-
_updateBadgeActive = active;
|
|
570359
|
-
_updateBadgeCol = startCol;
|
|
570360
|
-
_updateBadgeLen = length4;
|
|
570361
|
-
}
|
|
570362
|
-
function hitTestHeaderButton(row, col, termWidth) {
|
|
570363
|
-
if (_updateBadgeActive && row === 1 && col >= _updateBadgeCol && col < _updateBadgeCol + _updateBadgeLen) {
|
|
570364
|
-
return "/update";
|
|
570365
|
-
}
|
|
570366
|
-
const hdrRow = layout().headerContent;
|
|
570367
|
-
if (row === hdrRow) {
|
|
570368
|
-
if (col <= 3) return "header-prev";
|
|
570369
|
-
if (col >= termWidth - 3) return "header-next";
|
|
570370
|
-
const btnDefs = [
|
|
570371
|
-
{ cmd: "/help", label: " help " },
|
|
570372
|
-
{ cmd: "/voice", label: " voice " },
|
|
570373
|
-
{ cmd: "/model", label: " model " },
|
|
570374
|
-
{ cmd: "/cohere", label: " cohere " }
|
|
570375
|
-
];
|
|
570376
|
-
let btnEnd = termWidth - 4;
|
|
570377
|
-
for (let i2 = btnDefs.length - 1; i2 >= 0; i2--) {
|
|
570378
|
-
const btn = btnDefs[i2];
|
|
570379
|
-
const btnStart = btnEnd - btn.label.length;
|
|
570380
|
-
if (col >= btnStart && col <= btnEnd) return btn.cmd;
|
|
570381
|
-
btnEnd = btnStart - 1;
|
|
570382
|
-
}
|
|
570383
|
-
}
|
|
570384
|
-
return null;
|
|
570385
|
-
}
|
|
570386
|
-
var SEL_BG, SEL_FG, SEL_START, SEL_END, TextSelection, _clipboardAutoInstallAttempted, _hoveredButtonCmd, _pressedButtonCmd, _updateBadgeActive, _updateBadgeCol, _updateBadgeLen;
|
|
570387
|
-
var init_text_selection = __esm({
|
|
570388
|
-
"packages/cli/src/tui/text-selection.ts"() {
|
|
570389
|
-
"use strict";
|
|
570390
|
-
init_layout2();
|
|
570391
|
-
SEL_BG = 37;
|
|
570392
|
-
SEL_FG = 30;
|
|
570393
|
-
SEL_START = `\x1B[${SEL_FG}m\x1B[48;5;${SEL_BG}m`;
|
|
570394
|
-
SEL_END = `\x1B[0m`;
|
|
570395
|
-
TextSelection = class {
|
|
570396
|
-
_selection = null;
|
|
570397
|
-
_active = false;
|
|
570398
|
-
// true while mouse button is held
|
|
570399
|
-
_blockModeArmed = false;
|
|
570400
|
-
// Ctrl+Shift+B pressed, next click starts block select
|
|
570401
|
-
_provider;
|
|
570402
|
-
constructor(provider) {
|
|
570403
|
-
this._provider = provider;
|
|
570404
|
-
}
|
|
570405
|
-
/** Whether a selection currently exists */
|
|
570406
|
-
get hasSelection() {
|
|
570407
|
-
return this._selection !== null;
|
|
570408
|
-
}
|
|
570409
|
-
/** Whether we're actively dragging */
|
|
570410
|
-
get isDragging() {
|
|
570411
|
-
return this._active;
|
|
570412
|
-
}
|
|
570413
|
-
/** Get the current selection range (or null) */
|
|
570414
|
-
get selection() {
|
|
570415
|
-
return this._selection;
|
|
570416
|
-
}
|
|
570417
|
-
/** Arm block selection mode — next click starts rectangular select */
|
|
570418
|
-
armBlockMode() {
|
|
570419
|
-
this._blockModeArmed = true;
|
|
570420
|
-
}
|
|
570421
|
-
/** Clear the current selection */
|
|
570422
|
-
clear() {
|
|
570423
|
-
this._selection = null;
|
|
570424
|
-
this._active = false;
|
|
570425
|
-
this._blockModeArmed = false;
|
|
570426
|
-
}
|
|
570427
|
-
/**
|
|
570428
|
-
* Handle mouse press (button 0, M suffix in SGR).
|
|
570429
|
-
* Starts a new selection from the click position.
|
|
570430
|
-
*/
|
|
570431
|
-
onMousePress(row, col) {
|
|
570432
|
-
const mode = this._blockModeArmed ? "block" : "line";
|
|
570433
|
-
this._blockModeArmed = false;
|
|
570434
|
-
this._selection = {
|
|
570435
|
-
anchor: { row, col },
|
|
570436
|
-
current: { row, col },
|
|
570437
|
-
mode
|
|
570438
|
-
};
|
|
570439
|
-
this._active = true;
|
|
570440
|
-
}
|
|
570441
|
-
/**
|
|
570442
|
-
* Handle mouse drag (button 32, M suffix in SGR).
|
|
570443
|
-
* Extends the selection to the current cursor position.
|
|
570444
|
-
*/
|
|
570445
|
-
onMouseDrag(row, col) {
|
|
570446
|
-
if (!this._active || !this._selection) return;
|
|
570447
|
-
this._selection.current = { row, col };
|
|
570448
|
-
}
|
|
570449
|
-
/**
|
|
570450
|
-
* Handle mouse release (button 0, m suffix in SGR).
|
|
570451
|
-
* Finalizes the selection.
|
|
570452
|
-
*/
|
|
570453
|
-
onMouseRelease(row, col) {
|
|
570454
|
-
if (!this._active || !this._selection) return;
|
|
570455
|
-
this._selection.current = { row, col };
|
|
570456
|
-
this._active = false;
|
|
570457
|
-
if (this._selection.anchor.row === this._selection.current.row && this._selection.anchor.col === this._selection.current.col) {
|
|
570458
|
-
this._selection = null;
|
|
570459
|
-
}
|
|
570460
|
-
}
|
|
570461
|
-
/**
|
|
570462
|
-
* Compute which content buffer indices and column ranges are selected.
|
|
570463
|
-
* Returns an array of { bufferIdx, startCol, endCol } for each selected line.
|
|
570464
|
-
* Columns are 0-based visible character positions.
|
|
570465
|
-
*/
|
|
570466
|
-
getSelectedRanges() {
|
|
570467
|
-
if (!this._selection) return [];
|
|
570468
|
-
const { anchor, current, mode } = this._selection;
|
|
570469
|
-
const top = this._provider.getScrollRegionTop();
|
|
570470
|
-
const height = this._provider.getContentHeight();
|
|
570471
|
-
const offset = this._provider.getScrollOffset();
|
|
570472
|
-
const totalLines = this._provider.getContentLines().length;
|
|
570473
|
-
const startIdx = Math.max(0, totalLines - height - offset);
|
|
570474
|
-
const anchorBufIdx = startIdx + (anchor.row - top);
|
|
570475
|
-
const currentBufIdx = startIdx + (current.row - top);
|
|
570476
|
-
const minRow = Math.min(anchorBufIdx, currentBufIdx);
|
|
570477
|
-
const maxRow = Math.max(anchorBufIdx, currentBufIdx);
|
|
570478
|
-
const minCol = Math.min(anchor.col, current.col);
|
|
570479
|
-
const maxCol = Math.max(anchor.col, current.col);
|
|
570480
|
-
const ranges = [];
|
|
570481
|
-
if (mode === "block") {
|
|
570482
|
-
for (let idx = minRow; idx <= maxRow; idx++) {
|
|
570483
|
-
if (idx >= 0 && idx < totalLines) {
|
|
570484
|
-
ranges.push({ bufferIdx: idx, startCol: minCol - 1, endCol: maxCol - 1 });
|
|
570485
|
-
}
|
|
570486
|
-
}
|
|
570487
|
-
} else {
|
|
570488
|
-
const isForward = anchorBufIdx < currentBufIdx || anchorBufIdx === currentBufIdx && anchor.col <= current.col;
|
|
570489
|
-
const startR = isForward ? anchorBufIdx : currentBufIdx;
|
|
570490
|
-
const endR = isForward ? currentBufIdx : anchorBufIdx;
|
|
570491
|
-
const startC = isForward ? anchor.col - 1 : current.col - 1;
|
|
570492
|
-
const endC = isForward ? current.col - 1 : anchor.col - 1;
|
|
570493
|
-
for (let idx = startR; idx <= endR; idx++) {
|
|
570494
|
-
if (idx < 0 || idx >= totalLines) continue;
|
|
570495
|
-
const lineLen = visibleLength(this._provider.getContentLines()[idx] ?? "");
|
|
570496
|
-
if (idx === startR && idx === endR) {
|
|
570497
|
-
ranges.push({ bufferIdx: idx, startCol: startC, endCol: endC });
|
|
570498
|
-
} else if (idx === startR) {
|
|
570499
|
-
ranges.push({ bufferIdx: idx, startCol: startC, endCol: Math.max(lineLen, startC) });
|
|
570500
|
-
} else if (idx === endR) {
|
|
570501
|
-
ranges.push({ bufferIdx: idx, startCol: 0, endCol: endC });
|
|
570502
|
-
} else {
|
|
570503
|
-
ranges.push({ bufferIdx: idx, startCol: 0, endCol: lineLen });
|
|
570504
|
-
}
|
|
570505
|
-
}
|
|
570506
|
-
}
|
|
570507
|
-
return ranges;
|
|
570508
|
-
}
|
|
570509
|
-
/**
|
|
570510
|
-
* Apply selection highlighting to a content line for rendering.
|
|
570511
|
-
* Takes the original ANSI line and returns it with selection highlight applied.
|
|
570512
|
-
*
|
|
570513
|
-
* @param line Original content line (with ANSI codes)
|
|
570514
|
-
* @param startCol 0-based visible start column to highlight
|
|
570515
|
-
* @param endCol 0-based visible end column to highlight (inclusive)
|
|
570516
|
-
* @returns Line with selection highlight overlay
|
|
570517
|
-
*/
|
|
570518
|
-
static applyHighlight(line, startCol, endCol) {
|
|
570519
|
-
const plain = stripAnsi(line);
|
|
570520
|
-
if (startCol > plain.length || endCol < 0 || startCol > endCol) return line;
|
|
570521
|
-
const sc = Math.max(0, startCol);
|
|
570522
|
-
const ec = Math.min(plain.length - 1, endCol);
|
|
570523
|
-
let result = "";
|
|
570524
|
-
let visPos = 0;
|
|
570525
|
-
let i2 = 0;
|
|
570526
|
-
let inHighlight = false;
|
|
570527
|
-
while (i2 < line.length) {
|
|
570528
|
-
const escMatch = line.slice(i2).match(/^(\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\))/);
|
|
570529
|
-
if (escMatch) {
|
|
570530
|
-
if (inHighlight) {
|
|
570531
|
-
result += SEL_END + escMatch[0] + SEL_START;
|
|
570532
|
-
} else {
|
|
570533
|
-
result += escMatch[0];
|
|
570534
|
-
}
|
|
570535
|
-
i2 += escMatch[0].length;
|
|
570536
|
-
continue;
|
|
570537
|
-
}
|
|
570538
|
-
if (visPos === sc && !inHighlight) {
|
|
570539
|
-
result += SEL_START;
|
|
570540
|
-
inHighlight = true;
|
|
570541
|
-
}
|
|
570542
|
-
result += line[i2];
|
|
570543
|
-
if (visPos === ec && inHighlight) {
|
|
570544
|
-
result += SEL_END;
|
|
570545
|
-
inHighlight = false;
|
|
570546
|
-
}
|
|
570547
|
-
visPos++;
|
|
570548
|
-
i2++;
|
|
570549
|
-
}
|
|
570550
|
-
if (inHighlight) result += SEL_END;
|
|
570551
|
-
return result;
|
|
570552
|
-
}
|
|
570553
|
-
/**
|
|
570554
|
-
* Get the selected text content (plain text, no ANSI codes).
|
|
570555
|
-
* For block mode, each line is joined with newline.
|
|
570556
|
-
* For line mode, text flows continuously with newlines between lines.
|
|
570557
|
-
*/
|
|
570558
|
-
getSelectedText() {
|
|
570559
|
-
const ranges = this.getSelectedRanges();
|
|
570560
|
-
if (ranges.length === 0) return "";
|
|
570561
|
-
const lines = this._provider.getContentLines();
|
|
570562
|
-
const parts = [];
|
|
570563
|
-
for (const { bufferIdx, startCol, endCol } of ranges) {
|
|
570564
|
-
const raw = lines[bufferIdx] ?? "";
|
|
570565
|
-
const plain = stripAnsi(raw);
|
|
570566
|
-
const selected = plain.slice(
|
|
570567
|
-
Math.max(0, startCol),
|
|
570568
|
-
Math.min(plain.length, endCol + 1)
|
|
570569
|
-
);
|
|
570570
|
-
parts.push(selected);
|
|
570571
|
-
}
|
|
570572
|
-
return parts.join("\n");
|
|
570573
|
-
}
|
|
570574
|
-
/**
|
|
570575
|
-
* Copy current selection to system clipboard.
|
|
570576
|
-
* Tries platform commands first, falls back to OSC 52.
|
|
570577
|
-
* Returns true if copy succeeded.
|
|
570578
|
-
*/
|
|
570579
|
-
copyToClipboard() {
|
|
570580
|
-
const text = this.getSelectedText();
|
|
570581
|
-
if (!text) return false;
|
|
570582
|
-
return copyText(text);
|
|
570583
|
-
}
|
|
570584
|
-
};
|
|
570585
|
-
_clipboardAutoInstallAttempted = false;
|
|
570586
|
-
_hoveredButtonCmd = null;
|
|
570587
|
-
_pressedButtonCmd = null;
|
|
570588
|
-
_updateBadgeActive = false;
|
|
570589
|
-
_updateBadgeCol = 0;
|
|
570590
|
-
_updateBadgeLen = 0;
|
|
570591
|
-
}
|
|
570592
|
-
});
|
|
570593
|
-
|
|
570594
570891
|
// packages/cli/src/tui/daemon-registry.ts
|
|
570595
570892
|
var DaemonRegistry, registry2;
|
|
570596
570893
|
var init_daemon_registry = __esm({
|
|
@@ -571003,16 +571300,16 @@ function buildTodoProgressBar(todos, maxWidth) {
|
|
|
571003
571300
|
for (let i2 = 0; i2 < cells; i2++) {
|
|
571004
571301
|
const t2 = todos[i2];
|
|
571005
571302
|
if (t2.status === "completed") {
|
|
571006
|
-
out += `\x1B[1m${DONE_Y}█${
|
|
571303
|
+
out += `\x1B[1m${DONE_Y}█${RESET2}`;
|
|
571007
571304
|
} else if (i2 === inIdx) {
|
|
571008
|
-
out += `${INPROG}▒${
|
|
571305
|
+
out += `${INPROG}▒${RESET2}`;
|
|
571009
571306
|
} else if (i2 === nextIdx && inIdx >= 0) {
|
|
571010
|
-
out += `${NEXT}▒${
|
|
571307
|
+
out += `${NEXT}▒${RESET2}`;
|
|
571011
571308
|
} else {
|
|
571012
|
-
out += `${PEND}░${
|
|
571309
|
+
out += `${PEND}░${RESET2}`;
|
|
571013
571310
|
}
|
|
571014
571311
|
}
|
|
571015
|
-
if (truncated && maxWidth > 0) out += `${DIM_LABEL}…${
|
|
571312
|
+
if (truncated && maxWidth > 0) out += `${DIM_LABEL}…${RESET2}`;
|
|
571016
571313
|
return out;
|
|
571017
571314
|
}
|
|
571018
571315
|
function render() {
|
|
@@ -571034,7 +571331,7 @@ function render() {
|
|
|
571034
571331
|
const total = _lastTodos.length;
|
|
571035
571332
|
const headerColor = ACCENT;
|
|
571036
571333
|
const lines = [];
|
|
571037
|
-
const headerPrefix = `tasks ${headerColor}${completed}/${total}${
|
|
571334
|
+
const headerPrefix = `tasks ${headerColor}${completed}/${total}${RESET2} `;
|
|
571038
571335
|
const headerPrefixWidth = visualLen(headerPrefix);
|
|
571039
571336
|
const maxBarWidth = Math.max(0, cols - 2 - headerPrefixWidth);
|
|
571040
571337
|
const progressBar = buildTodoProgressBar(_lastTodos, maxBarWidth);
|
|
@@ -571046,11 +571343,11 @@ function render() {
|
|
|
571046
571343
|
const contentWidth = Math.max(4, cols - 8);
|
|
571047
571344
|
const contentText = t2.content + (t2.blocker ? ` (blocked: ${t2.blocker})` : "");
|
|
571048
571345
|
const truncated = truncate2(contentText, contentWidth);
|
|
571049
|
-
lines.push(`${color}${mark}${
|
|
571346
|
+
lines.push(`${color}${mark}${RESET2} ${color}${truncated}${RESET2}`);
|
|
571050
571347
|
}
|
|
571051
571348
|
if (_lastTodos.length > visible.length) {
|
|
571052
571349
|
const more = _lastTodos.length - visible.length;
|
|
571053
|
-
lines[lines.length - 1] = `${DIM_LABEL}… +${more} more${
|
|
571350
|
+
lines[lines.length - 1] = `${DIM_LABEL}… +${more} more${RESET2}`;
|
|
571054
571351
|
}
|
|
571055
571352
|
let out = HIDE + SAVE;
|
|
571056
571353
|
const newTop = L.tasksTop;
|
|
@@ -571067,7 +571364,7 @@ function render() {
|
|
|
571067
571364
|
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
571068
571365
|
const row = L.tasksTop + i2;
|
|
571069
571366
|
if (row > L.tasksBottom) break;
|
|
571070
|
-
out += `\x1B[${row};1H${CLEAR_LINE}${BG}${" ".repeat(cols)}\x1B[${row};2H${lines[i2]}${
|
|
571367
|
+
out += `\x1B[${row};1H${CLEAR_LINE}${BG}${" ".repeat(cols)}\x1B[${row};2H${lines[i2]}${RESET2}`;
|
|
571071
571368
|
}
|
|
571072
571369
|
out += RESTORE + SHOW;
|
|
571073
571370
|
try {
|
|
@@ -571095,7 +571392,7 @@ function clearLastPaintedRows() {
|
|
|
571095
571392
|
_lastPaintedTop = -1;
|
|
571096
571393
|
_lastPaintedBottom = -1;
|
|
571097
571394
|
}
|
|
571098
|
-
var chromeWrite, _activeSessionId, _watcher, _lastTodos, _enabled, _redrawScheduled, _onResizeChange, _scopeOverlayActive, _scopeMainViewActive, _scopeNeovimActive, _scopePagerActive, _lastPaintedTop, _lastPaintedBottom, MAX_VISIBLE_ROWS, SAVE, RESTORE, HIDE, SHOW, CLEAR_LINE,
|
|
571395
|
+
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;
|
|
571099
571396
|
var init_tui_tasks_renderer = __esm({
|
|
571100
571397
|
"packages/cli/src/tui/tui-tasks-renderer.ts"() {
|
|
571101
571398
|
"use strict";
|
|
@@ -571122,7 +571419,7 @@ var init_tui_tasks_renderer = __esm({
|
|
|
571122
571419
|
HIDE = "\x1B[?25l";
|
|
571123
571420
|
SHOW = "\x1B[?25h";
|
|
571124
571421
|
CLEAR_LINE = "\x1B[2K";
|
|
571125
|
-
|
|
571422
|
+
RESET2 = "\x1B[0m";
|
|
571126
571423
|
BG = tuiBgSeq();
|
|
571127
571424
|
DIM_LABEL = "";
|
|
571128
571425
|
ACCENT = "";
|
|
@@ -571169,7 +571466,7 @@ function setTerminalTitle(task, version4) {
|
|
|
571169
571466
|
const title = task ? `${task.slice(0, 60)} · ${ver}` : ver;
|
|
571170
571467
|
process.stdout.write(`\x1B]2;${title}\x07`);
|
|
571171
571468
|
}
|
|
571172
|
-
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,
|
|
571469
|
+
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;
|
|
571173
571470
|
var init_status_bar = __esm({
|
|
571174
571471
|
"packages/cli/src/tui/status-bar.ts"() {
|
|
571175
571472
|
"use strict";
|
|
@@ -571348,14 +571645,14 @@ var init_status_bar = __esm({
|
|
|
571348
571645
|
TEXT_PRIMARY = tuiTextPrimary() < 0 ? 252 : tuiTextPrimary();
|
|
571349
571646
|
TEXT_DIM = tuiTextDim();
|
|
571350
571647
|
NO_SUB_AGENTS_HEADER_LABEL = " no sub-agents ";
|
|
571351
|
-
|
|
571352
|
-
|
|
571353
|
-
|
|
571354
|
-
|
|
571355
|
-
|
|
571356
|
-
|
|
571648
|
+
BOX_TL2 = "╭";
|
|
571649
|
+
BOX_TR2 = "╮";
|
|
571650
|
+
BOX_BL2 = "╰";
|
|
571651
|
+
BOX_BR2 = "╯";
|
|
571652
|
+
BOX_H2 = "─";
|
|
571653
|
+
BOX_V2 = "│";
|
|
571357
571654
|
_globalFooterLock = false;
|
|
571358
|
-
|
|
571655
|
+
RESET3 = "\x1B[0m";
|
|
571359
571656
|
CURSOR_BLINK_BLOCK = "\x1B[1 q";
|
|
571360
571657
|
_isWindows = process.platform === "win32";
|
|
571361
571658
|
StatusBar = class _StatusBar {
|
|
@@ -571401,6 +571698,22 @@ var init_status_bar = __esm({
|
|
|
571401
571698
|
_contentScrollOffset = 0;
|
|
571402
571699
|
// 0 = live (bottom), >0 = scrolled back
|
|
571403
571700
|
_contentMaxLines = 1e4;
|
|
571701
|
+
/**
|
|
571702
|
+
* Dynamic content blocks — width-aware regions that re-render themselves
|
|
571703
|
+
* when the terminal resizes. The renderer registered here is called from
|
|
571704
|
+
* the scrollback reflow path: when a sentinel line of the form
|
|
571705
|
+
* `\x01DYNBLOCK:<id>\x01` is encountered, the registered fn is invoked
|
|
571706
|
+
* with the current terminal width and its returned lines replace the
|
|
571707
|
+
* sentinel in the reflowed output. This is how the Task Complete box
|
|
571708
|
+
* stays geometrically correct under SIGWINCH-driven resize.
|
|
571709
|
+
*
|
|
571710
|
+
* Keep the renderer cheap (pure data → strings) — it runs every full
|
|
571711
|
+
* repaint, including selection updates and scroll events.
|
|
571712
|
+
*/
|
|
571713
|
+
_dynamicBlocks = /* @__PURE__ */ new Map();
|
|
571714
|
+
/** Sentinel marker — used both for scrollback storage and reflow detection. */
|
|
571715
|
+
DYNAMIC_BLOCK_MARK_PREFIX = "DYNBLOCK:";
|
|
571716
|
+
DYNAMIC_BLOCK_MARK_SUFFIX = "";
|
|
571404
571717
|
// Partial-line accumulator for the buffered-write layer. Stream output
|
|
571405
571718
|
// arrives in chunks (one per syntax-highlighted token) and a single
|
|
571406
571719
|
// logical line can span many writes. If we naively push each chunk to
|
|
@@ -571511,10 +571824,54 @@ var init_status_bar = __esm({
|
|
|
571511
571824
|
syncEnd() {
|
|
571512
571825
|
this.termWrite("\x1B[?2026l");
|
|
571513
571826
|
}
|
|
571514
|
-
/**
|
|
571827
|
+
/**
|
|
571828
|
+
* Register (or replace) a dynamic content block. Returns the sentinel
|
|
571829
|
+
* line the caller should push into the scrollback to make the block
|
|
571830
|
+
* appear there. The block's renderer is invoked on every repaint and
|
|
571831
|
+
* given the current terminal width; its returned lines are spliced in
|
|
571832
|
+
* place of the sentinel during reflow. Callers MUST also call
|
|
571833
|
+
* `appendDynamicBlock(id)` to actually place the block in scrollback.
|
|
571834
|
+
*
|
|
571835
|
+
* The sentinel is opaque — never write it directly to stdout; route
|
|
571836
|
+
* through `appendDynamicBlock` which also triggers a repaint so the
|
|
571837
|
+
* block becomes visible immediately.
|
|
571838
|
+
*/
|
|
571839
|
+
registerDynamicBlock(id, render2) {
|
|
571840
|
+
this._dynamicBlocks.set(id, render2);
|
|
571841
|
+
return `${this.DYNAMIC_BLOCK_MARK_PREFIX}${id}${this.DYNAMIC_BLOCK_MARK_SUFFIX}`;
|
|
571842
|
+
}
|
|
571843
|
+
/** Unregister a dynamic block. Existing sentinels in scrollback become inert (rendered as empty). */
|
|
571844
|
+
unregisterDynamicBlock(id) {
|
|
571845
|
+
this._dynamicBlocks.delete(id);
|
|
571846
|
+
}
|
|
571847
|
+
/**
|
|
571848
|
+
* Append a previously-registered dynamic block's sentinel to scrollback
|
|
571849
|
+
* and trigger a repaint. The block's renderer fires immediately at the
|
|
571850
|
+
* current terminal width and again on every subsequent SIGWINCH (because
|
|
571851
|
+
* `_handleResizeImmediate` already calls `repaintContent`).
|
|
571852
|
+
*/
|
|
571853
|
+
appendDynamicBlock(id) {
|
|
571854
|
+
if (!this._dynamicBlocks.has(id)) return;
|
|
571855
|
+
const sentinel = `${this.DYNAMIC_BLOCK_MARK_PREFIX}${id}${this.DYNAMIC_BLOCK_MARK_SUFFIX}`;
|
|
571856
|
+
this._contentLines.push(sentinel);
|
|
571857
|
+
if (this._contentLines.length > this._contentMaxLines) {
|
|
571858
|
+
this._contentLines.splice(0, this._contentLines.length - this._contentMaxLines);
|
|
571859
|
+
}
|
|
571860
|
+
if (this.active) this.repaintContent();
|
|
571861
|
+
}
|
|
571862
|
+
/** Force a complete footer redraw (public wrapper for renderFooterAndPositionInput).
|
|
571863
|
+
*
|
|
571864
|
+
* IMPORTANT: do NOT call `updateFooterHeight()` here. The inner render
|
|
571865
|
+
* function captures `oldFooterTop` from the CURRENT `_currentFooterHeight`
|
|
571866
|
+
* BEFORE updating it, so it can detect height changes and clear the
|
|
571867
|
+
* rows that the old (taller) footer used to occupy. Pre-calling
|
|
571868
|
+
* `updateFooterHeight` here would mutate the height to the new value
|
|
571869
|
+
* first, leaving the inner render to think nothing changed and skipping
|
|
571870
|
+
* the transition-row clear — which is exactly what caused stale prompt
|
|
571871
|
+
* text to remain on the input box's top unicode border after submitting
|
|
571872
|
+
* a multi-line input. */
|
|
571515
571873
|
redrawFooter() {
|
|
571516
571874
|
if (!this.active) return;
|
|
571517
|
-
this.updateFooterHeight();
|
|
571518
571875
|
this.renderFooterAndPositionInput();
|
|
571519
571876
|
}
|
|
571520
571877
|
/** Callback to get available slash commands for suggestion matching */
|
|
@@ -571638,7 +571995,7 @@ var init_status_bar = __esm({
|
|
|
571638
571995
|
const segment = segments[i2];
|
|
571639
571996
|
if (i2 > 0) {
|
|
571640
571997
|
separatorOffsets.push(width);
|
|
571641
|
-
text += `${BOX_FG}${
|
|
571998
|
+
text += `${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
571642
571999
|
width += 1;
|
|
571643
572000
|
}
|
|
571644
572001
|
text += `\x1B[1;38;5;${TEXT_PRIMARY}m${PANEL_BG_SEQ}${segment}`;
|
|
@@ -571820,7 +572177,7 @@ var init_status_bar = __esm({
|
|
|
571820
572177
|
const sysSeparatorOffset = sysItems.reduce((sum, item) => sum + item.w, 0);
|
|
571821
572178
|
this._sysSeparatorOffset = sysSeparatorOffset;
|
|
571822
572179
|
sysItems.push({
|
|
571823
|
-
render: () => `${BOX_FG}│${
|
|
572180
|
+
render: () => `${BOX_FG}│${RESET3}${PANEL_BG_SEQ} `,
|
|
571824
572181
|
w: 2
|
|
571825
572182
|
});
|
|
571826
572183
|
const voiceLabel = this._voiceActive ? ` ${this._voiceModelId || "voice"} ` : " voice ";
|
|
@@ -572017,7 +572374,7 @@ var init_status_bar = __esm({
|
|
|
572017
572374
|
const hdrRow = layout().headerContent;
|
|
572018
572375
|
let buf = "\x1B7";
|
|
572019
572376
|
buf += `\x1B[${hdrRow};1H${PANEL_BG_SEQ}\x1B[2K`;
|
|
572020
|
-
buf += `${BOX_FG}│${
|
|
572377
|
+
buf += `${BOX_FG}│${RESET3}${PANEL_BG_SEQ}`;
|
|
572021
572378
|
if (chrome.showPrev) {
|
|
572022
572379
|
buf += leftArrow;
|
|
572023
572380
|
buf += ` `;
|
|
@@ -572028,7 +572385,7 @@ var init_status_bar = __esm({
|
|
|
572028
572385
|
buf += `\x1B[${hdrRow};${w - 1}H`;
|
|
572029
572386
|
buf += rightArrow;
|
|
572030
572387
|
}
|
|
572031
|
-
buf += `\x1B[${hdrRow};${w}H${BOX_FG}│${
|
|
572388
|
+
buf += `\x1B[${hdrRow};${w}H${BOX_FG}│${RESET3}${PANEL_BG_SEQ}`;
|
|
572032
572389
|
buf += "\x1B8";
|
|
572033
572390
|
this.termWrite(buf);
|
|
572034
572391
|
}
|
|
@@ -573231,11 +573588,11 @@ var init_status_bar = __esm({
|
|
|
573231
573588
|
for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
|
|
573232
573589
|
const row = pos.inputStartRow + i2;
|
|
573233
573590
|
const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
|
|
573234
|
-
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${prefix}${inputWrap.lines[i2]}${
|
|
573591
|
+
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${prefix}${inputWrap.lines[i2]}${RESET3}${PANEL_BG_SEQ}`;
|
|
573235
573592
|
}
|
|
573236
573593
|
const boxInnerP = w - 2;
|
|
573237
|
-
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
573238
|
-
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${
|
|
573594
|
+
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}`;
|
|
573595
|
+
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET3}${PANEL_BG_SEQ}\x1B[?7h\x1B[${pos.inputStartRow};1H`;
|
|
573239
573596
|
this.termWrite(buf);
|
|
573240
573597
|
if (this._bannerRefresh) this._bannerRefresh();
|
|
573241
573598
|
} else {
|
|
@@ -573436,7 +573793,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
573436
573793
|
process.stdout.write = this._origWrite;
|
|
573437
573794
|
this._origWrite = null;
|
|
573438
573795
|
}
|
|
573439
|
-
process.stdout.write(
|
|
573796
|
+
process.stdout.write(RESET3);
|
|
573440
573797
|
this._brailleSpinner.setMetrics({ isStreaming: false });
|
|
573441
573798
|
this.renderFooterAndPositionInput();
|
|
573442
573799
|
this.parkCursorInInput();
|
|
@@ -573565,12 +573922,32 @@ ${CONTENT_BG_SEQ}`);
|
|
|
573565
573922
|
reflowContentLines(livePartialLine, width) {
|
|
573566
573923
|
const maxWidth = Math.max(16, width);
|
|
573567
573924
|
const source = livePartialLine ? [...this._contentLines, livePartialLine] : this._contentLines;
|
|
573568
|
-
return source.flatMap(
|
|
573569
|
-
(line
|
|
573925
|
+
return source.flatMap((line, idx) => {
|
|
573926
|
+
if (line.startsWith(this.DYNAMIC_BLOCK_MARK_PREFIX) && line.endsWith(this.DYNAMIC_BLOCK_MARK_SUFFIX)) {
|
|
573927
|
+
const id = line.slice(
|
|
573928
|
+
this.DYNAMIC_BLOCK_MARK_PREFIX.length,
|
|
573929
|
+
line.length - this.DYNAMIC_BLOCK_MARK_SUFFIX.length
|
|
573930
|
+
);
|
|
573931
|
+
const renderer = this._dynamicBlocks.get(id);
|
|
573932
|
+
if (!renderer) return [];
|
|
573933
|
+
let blockLines;
|
|
573934
|
+
try {
|
|
573935
|
+
blockLines = renderer(maxWidth);
|
|
573936
|
+
} catch {
|
|
573937
|
+
return [];
|
|
573938
|
+
}
|
|
573939
|
+
return blockLines.flatMap(
|
|
573940
|
+
(segment) => this.reflowContentLine(segment, maxWidth).map((s2) => ({
|
|
573941
|
+
line: s2,
|
|
573942
|
+
bufferIdx: idx
|
|
573943
|
+
}))
|
|
573944
|
+
);
|
|
573945
|
+
}
|
|
573946
|
+
return this.reflowContentLine(line, maxWidth).map((segment) => ({
|
|
573570
573947
|
line: segment,
|
|
573571
573948
|
bufferIdx: idx
|
|
573572
|
-
}))
|
|
573573
|
-
);
|
|
573949
|
+
}));
|
|
573950
|
+
});
|
|
573574
573951
|
}
|
|
573575
573952
|
reflowContentLine(line, width) {
|
|
573576
573953
|
const visible = stripAnsi(line);
|
|
@@ -573630,7 +574007,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
573630
574007
|
const endRaw = this.rawIndexForVisibleColumn(line, end);
|
|
573631
574008
|
const activeStyle = this.activeSgrAt(line, startRaw);
|
|
573632
574009
|
const raw = line.slice(startRaw, endRaw);
|
|
573633
|
-
return activeStyle ? `${activeStyle}${raw}${
|
|
574010
|
+
return activeStyle ? `${activeStyle}${raw}${RESET3}` : raw;
|
|
573634
574011
|
}
|
|
573635
574012
|
rawIndexForVisibleColumn(line, target) {
|
|
573636
574013
|
if (target <= 0) return 0;
|
|
@@ -573654,7 +574031,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
573654
574031
|
let match;
|
|
573655
574032
|
while ((match = sgr.exec(line)) && match.index < rawIndex) {
|
|
573656
574033
|
const seq = match[0];
|
|
573657
|
-
if (seq ===
|
|
574034
|
+
if (seq === RESET3 || /\x1B\[(?:0|39|49)(?:;0)?m/.test(seq)) {
|
|
573658
574035
|
active = "";
|
|
573659
574036
|
} else {
|
|
573660
574037
|
active += seq;
|
|
@@ -574429,21 +574806,21 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574429
574806
|
const inputWrap = this.wrapInput(w);
|
|
574430
574807
|
let buf = "\x1B[?7l";
|
|
574431
574808
|
const boxInner = w - 2;
|
|
574432
|
-
buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574809
|
+
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}`;
|
|
574433
574810
|
const Lspacer = layout();
|
|
574434
574811
|
const spacerRow = pos.inputStartRow - 1;
|
|
574435
574812
|
const tasksOccupiesSpacer = Lspacer.tasksHeight > 0 && spacerRow >= Lspacer.tasksTop && spacerRow <= Lspacer.tasksBottom;
|
|
574436
574813
|
if (spacerRow >= this.scrollRegionTop && !tasksOccupiesSpacer) {
|
|
574437
|
-
buf += `\x1B[${spacerRow};1H${PANEL_BG_SEQ}\x1B[2K${
|
|
574814
|
+
buf += `\x1B[${spacerRow};1H${PANEL_BG_SEQ}\x1B[2K${RESET3}`;
|
|
574438
574815
|
}
|
|
574439
574816
|
for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
|
|
574440
574817
|
const row = pos.inputStartRow + 1 + i2;
|
|
574441
574818
|
const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
|
|
574442
574819
|
const lineContent = `${prefix}${inputWrap.lines[i2]}`;
|
|
574443
574820
|
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K`;
|
|
574444
|
-
buf += `${BOX_FG}${
|
|
574821
|
+
buf += `${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}${lineContent}`;
|
|
574445
574822
|
buf += `${PANEL_BG_SEQ}\x1B[K`;
|
|
574446
|
-
buf += `\x1B[${row};${w}H${BOX_FG}${
|
|
574823
|
+
buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574447
574824
|
}
|
|
574448
574825
|
const cursorTermRow = pos.inputStartRow + 1 + inputWrap.cursorRow;
|
|
574449
574826
|
if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
|
|
@@ -574455,17 +574832,17 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574455
574832
|
const fg2 = isHighlighted ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
|
|
574456
574833
|
const slash = isHighlighted ? `\x1B[38;5;245m` : `\x1B[38;5;${TEXT_DIM}m`;
|
|
574457
574834
|
const marker = isHighlighted ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
|
|
574458
|
-
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574835
|
+
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574459
574836
|
buf += `${bg} ${marker}${slash}/${fg2}${cmd}`;
|
|
574460
574837
|
buf += `${PANEL_BG_SEQ}\x1B[K`;
|
|
574461
|
-
buf += `\x1B[${row};${w}H${BOX_FG}${
|
|
574838
|
+
buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574462
574839
|
}
|
|
574463
574840
|
const suggestBottomRow = pos.suggestStartRow + this._suggestions.length;
|
|
574464
|
-
buf += `\x1B[${suggestBottomRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574841
|
+
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}`;
|
|
574465
574842
|
} else {
|
|
574466
|
-
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574843
|
+
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}`;
|
|
574467
574844
|
}
|
|
574468
|
-
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${
|
|
574845
|
+
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET3}${PANEL_BG_SEQ}`;
|
|
574469
574846
|
buf += "\x1B[?7h";
|
|
574470
574847
|
if (this.writeDepth === 0) {
|
|
574471
574848
|
buf += `\x1B[${cursorTermRow};${inputWrap.cursorCol}H${CURSOR_BLINK_BLOCK}\x1B[?25h`;
|
|
@@ -574498,7 +574875,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574498
574875
|
const pos = this.rowPositions(termRows());
|
|
574499
574876
|
let buf = "\x1B7\x1B[?7l";
|
|
574500
574877
|
if (pos.tabBarRow > 0) {
|
|
574501
|
-
buf += `\x1B[${pos.tabBarRow};1H${PANEL_BG_SEQ}\x1B[2K${
|
|
574878
|
+
buf += `\x1B[${pos.tabBarRow};1H${PANEL_BG_SEQ}\x1B[2K${RESET3}`;
|
|
574502
574879
|
}
|
|
574503
574880
|
const boxInnerR = w - 2;
|
|
574504
574881
|
if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
|
|
@@ -574508,14 +574885,14 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574508
574885
|
const isHl = si === this._suggestIndex;
|
|
574509
574886
|
const fg2 = isHl ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
|
|
574510
574887
|
const marker = isHl ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
|
|
574511
|
-
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574512
|
-
buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${
|
|
574888
|
+
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}`;
|
|
574889
|
+
buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V2}${RESET3}`;
|
|
574513
574890
|
}
|
|
574514
|
-
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574891
|
+
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL2}${BOX_H2.repeat(Math.max(0, boxInnerR))}${BOX_BR2}${RESET3}`;
|
|
574515
574892
|
} else {
|
|
574516
|
-
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574893
|
+
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL2}${BOX_H2.repeat(Math.max(0, boxInnerR))}${BOX_BR2}${RESET3}`;
|
|
574517
574894
|
}
|
|
574518
|
-
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${
|
|
574895
|
+
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET3}${PANEL_BG_SEQ}\x1B[?7h\x1B8` + // DEC restore cursor
|
|
574519
574896
|
(this.writeDepth === 0 ? `${CURSOR_BLINK_BLOCK}\x1B[?25h` : "");
|
|
574520
574897
|
this.termWrite(buf);
|
|
574521
574898
|
if (pos.tabBarRow > 0) this.renderAgentTabs();
|
|
@@ -574559,12 +574936,12 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574559
574936
|
}
|
|
574560
574937
|
buf += "\x1B[?7l";
|
|
574561
574938
|
const boxInnerH = w - 2;
|
|
574562
|
-
buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574939
|
+
buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL2}${BOX_H2.repeat(Math.max(0, boxInnerH))}${BOX_TR2}${RESET3}`;
|
|
574563
574940
|
for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
|
|
574564
574941
|
const row = pos.inputStartRow + 1 + i2;
|
|
574565
574942
|
const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
|
|
574566
574943
|
const lineContent = `${prefix}${inputWrap.lines[i2]}`;
|
|
574567
|
-
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574944
|
+
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}`;
|
|
574568
574945
|
}
|
|
574569
574946
|
if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
|
|
574570
574947
|
for (let si = 0; si < this._suggestions.length; si++) {
|
|
@@ -574574,14 +574951,14 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574574
574951
|
const bg = isHl ? `\x1B[48;5;235m` : PANEL_BG_SEQ;
|
|
574575
574952
|
const fg2 = isHl ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
|
|
574576
574953
|
const marker = isHl ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
|
|
574577
|
-
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574954
|
+
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574578
574955
|
buf += `${bg} ${marker}\x1B[38;5;${TEXT_DIM}m/${fg2}${cmd}`;
|
|
574579
|
-
buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${
|
|
574956
|
+
buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V2}${RESET3}`;
|
|
574580
574957
|
}
|
|
574581
574958
|
}
|
|
574582
574959
|
const boxInnerS = w - 2;
|
|
574583
|
-
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${
|
|
574584
|
-
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${
|
|
574960
|
+
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL2}${BOX_H2.repeat(Math.max(0, boxInnerS))}${BOX_BR2}${RESET3}`;
|
|
574961
|
+
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET3}`;
|
|
574585
574962
|
buf += "\x1B[?7h";
|
|
574586
574963
|
buf += "\x1B8";
|
|
574587
574964
|
if (heightDelta > 0) {
|
|
@@ -574599,9 +574976,9 @@ ${CONTENT_BG_SEQ}`);
|
|
|
574599
574976
|
const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
|
|
574600
574977
|
const lineContent = `${prefix}${inputWrap.lines[i2]}`;
|
|
574601
574978
|
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K`;
|
|
574602
|
-
buf += `${BOX_FG}${
|
|
574979
|
+
buf += `${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}${lineContent}`;
|
|
574603
574980
|
buf += `${PANEL_BG_SEQ}\x1B[K`;
|
|
574604
|
-
buf += `\x1B[${row};${w}H${BOX_FG}${
|
|
574981
|
+
buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V2}${RESET3}${PANEL_BG_SEQ}`;
|
|
574605
574982
|
}
|
|
574606
574983
|
buf += "\x1B[?7h";
|
|
574607
574984
|
this.termWrite(buf);
|
|
@@ -649776,13 +650153,24 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
649776
650153
|
}
|
|
649777
650154
|
contentWrite(() => {
|
|
649778
650155
|
if (result.completed) {
|
|
649779
|
-
renderTaskComplete(
|
|
649780
|
-
|
|
649781
|
-
result.
|
|
649782
|
-
result.
|
|
649783
|
-
result.
|
|
649784
|
-
|
|
649785
|
-
|
|
650156
|
+
renderTaskComplete({
|
|
650157
|
+
task: effectiveTask,
|
|
650158
|
+
summary: result.summary,
|
|
650159
|
+
turns: result.turns,
|
|
650160
|
+
toolCalls: result.toolCalls,
|
|
650161
|
+
durationMs: result.durationMs,
|
|
650162
|
+
tokens,
|
|
650163
|
+
filesEdited: result.filesEdited,
|
|
650164
|
+
testsRun: result.testsRun,
|
|
650165
|
+
provenanceAnchors: result.provenanceAnchors,
|
|
650166
|
+
// Hand the status bar so the box renders as a resize-aware
|
|
650167
|
+
// dynamic block. When the bar isn't active (tests, headless),
|
|
650168
|
+
// the legacy line-based banner fires instead.
|
|
650169
|
+
host: statusBar?.isActive ? {
|
|
650170
|
+
registerDynamicBlock: (id, render2) => statusBar.registerDynamicBlock(id, render2),
|
|
650171
|
+
appendDynamicBlock: (id) => statusBar.appendDynamicBlock(id)
|
|
650172
|
+
} : void 0
|
|
650173
|
+
});
|
|
649786
650174
|
if (onComplete)
|
|
649787
650175
|
onComplete(result.summary, {
|
|
649788
650176
|
turns: result.turns,
|
|
@@ -654588,6 +654976,9 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
|
|
|
654588
654976
|
if (!setupReady) return;
|
|
654589
654977
|
persistHistoryLine(line);
|
|
654590
654978
|
const input = line.trim();
|
|
654979
|
+
if (statusBar?.isActive && line.length > 0) {
|
|
654980
|
+
statusBar.redrawFooter();
|
|
654981
|
+
}
|
|
654591
654982
|
if (!input) {
|
|
654592
654983
|
if (pasteBuffer.length > 0) {
|
|
654593
654984
|
if (pasteIndicatorShown) {
|