triflux 10.2.0 → 10.2.1
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/hub/team/ansi.mjs +1 -1
- package/hub/team/tui-lite.mjs +18 -2
- package/package.json +1 -1
package/hub/team/ansi.mjs
CHANGED
|
@@ -163,7 +163,7 @@ export function box(lines, width, borderColor = "", options = {}) {
|
|
|
163
163
|
const bot = botChars
|
|
164
164
|
.map((glyph, col) => renderBorderChar(glyph, totalRows - 1, col, highlightCell, bc(totalRows - 1), highlightSeq))
|
|
165
165
|
.join("");
|
|
166
|
-
const mid = `${bc(Math.floor(totalRows / 2))}${BOX.ml}${BOX.h.repeat(width - 2)}${BOX.mr}${rst}`;
|
|
166
|
+
const mid = `${bc(Math.floor(totalRows / 2))}${BOX.ml}${BOX.h.repeat(Math.max(0, width - 2))}${BOX.mr}${rst}`;
|
|
167
167
|
const body = lines.map((l, i) => {
|
|
168
168
|
const row = i + 1;
|
|
169
169
|
const content = options.titleFlashBg && i === 0
|
package/hub/team/tui-lite.mjs
CHANGED
|
@@ -128,7 +128,7 @@ function buildHeader(width, names, workers, pipeline, startedAt) {
|
|
|
128
128
|
else if (status === "running" || status === "in_progress") counts.running++;
|
|
129
129
|
}
|
|
130
130
|
const elapsed = Math.max(0, Math.round((Date.now() - startedAt) / 1000));
|
|
131
|
-
const line1 = color(` triflux ${VERSION} `, FG.
|
|
131
|
+
const line1 = color(` triflux ${VERSION} `, FG.white, BG.header)
|
|
132
132
|
+ ` ${bold(`phase ${pipeline.phase || "exec"}`)}`
|
|
133
133
|
+ ` ${dim(`+${elapsed}s`)} ${names.length} workers`;
|
|
134
134
|
const line2 = `${color(`ok ${counts.ok}`, MOCHA.ok)} ${color(`partial ${counts.partial}`, MOCHA.partial)} ${color(`failed ${counts.failed}`, MOCHA.fail)} ${color(`running ${counts.running}`, MOCHA.executing)}`;
|
|
@@ -210,6 +210,7 @@ export function createLiteDashboard(opts = {}) {
|
|
|
210
210
|
let focusTab = "log";
|
|
211
211
|
let helpVisible = false;
|
|
212
212
|
let prevFrame = [];
|
|
213
|
+
let prevWidth = 0;
|
|
213
214
|
let inputAttached = false;
|
|
214
215
|
let rawModeEnabled = false;
|
|
215
216
|
|
|
@@ -264,7 +265,14 @@ export function createLiteDashboard(opts = {}) {
|
|
|
264
265
|
return;
|
|
265
266
|
}
|
|
266
267
|
if (key === "\r" || key === "\n") {
|
|
267
|
-
|
|
268
|
+
if (typeof onOpenSelectedWorker !== "function") {
|
|
269
|
+
// 콜백 없으면 탭 순환 (기본 동작)
|
|
270
|
+
const tabs = ["log", "detail", "files"];
|
|
271
|
+
focusTab = tabs[(tabs.indexOf(focusTab) + 1) % tabs.length];
|
|
272
|
+
} else {
|
|
273
|
+
triggerOpenSelected();
|
|
274
|
+
}
|
|
275
|
+
render();
|
|
268
276
|
return;
|
|
269
277
|
}
|
|
270
278
|
if (key === "\x1b[13;2u" || key === "\x1b[27;13;2~" || key === "\x1b\r" || key === "\x1b\n") {
|
|
@@ -339,6 +347,13 @@ export function createLiteDashboard(opts = {}) {
|
|
|
339
347
|
if (isTTY) {
|
|
340
348
|
const width = viewportColumns();
|
|
341
349
|
const padded = rowsOut.map((line) => padRight(String(line ?? ""), width));
|
|
350
|
+
// Full redraw on first frame or terminal resize to avoid artifacts
|
|
351
|
+
if (prevFrame.length === 0 || width !== prevWidth) {
|
|
352
|
+
prevWidth = width;
|
|
353
|
+
write(cursorHome + padded.map((l) => l + clearToEnd).join("\n") + eraseBelow);
|
|
354
|
+
prevFrame = padded;
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
342
357
|
// Diff-based rendering: only rewrite lines that actually changed
|
|
343
358
|
let buf = "";
|
|
344
359
|
for (let i = 0; i < padded.length; i++) {
|
|
@@ -361,6 +376,7 @@ export function createLiteDashboard(opts = {}) {
|
|
|
361
376
|
if (rawModeEnabled && typeof input?.setRawMode === "function") input.setRawMode(false);
|
|
362
377
|
if (inputAttached && typeof input?.pause === "function") input.pause();
|
|
363
378
|
if (isTTY) write(cursorShow + altScreenOff);
|
|
379
|
+
prevFrame = [];
|
|
364
380
|
closed = true;
|
|
365
381
|
}
|
|
366
382
|
|