throughline 0.3.7 → 0.3.9
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/package.json +1 -1
- package/src/token-monitor.mjs +33 -12
package/package.json
CHANGED
package/src/token-monitor.mjs
CHANGED
|
@@ -33,6 +33,12 @@ let lastTimeAgoRefresh = Date.now();
|
|
|
33
33
|
const ANSI = {
|
|
34
34
|
hideCursor: '\x1b[?25l',
|
|
35
35
|
showCursor: '\x1b[?25h',
|
|
36
|
+
// オルタネートスクリーンバッファ (htop / vim / less が使うやつ)。
|
|
37
|
+
// プライマリバッファでの `\x1b[2J` は xterm.js だと「描画済み行をスクロール履歴に
|
|
38
|
+
// 押し上げる」挙動になり、狭い VSCode task terminal で描画が永遠に積み上がる
|
|
39
|
+
// 症状を引き起こす。alt バッファならスクロール履歴に残らず真にクリアできる。
|
|
40
|
+
enterAltScreen: '\x1b[?1049h',
|
|
41
|
+
leaveAltScreen: '\x1b[?1049l',
|
|
36
42
|
clearLine: '\x1b[2K',
|
|
37
43
|
clearScreen: '\x1b[2J\x1b[H',
|
|
38
44
|
clearBelow: '\x1b[0J', // 現在位置から画面末尾までをクリア
|
|
@@ -420,13 +426,20 @@ function renderFrame(args) {
|
|
|
420
426
|
const columns = resolveColumns();
|
|
421
427
|
const clipped = lines.map((l) => truncateToCells(l, columns));
|
|
422
428
|
|
|
423
|
-
//
|
|
424
|
-
//
|
|
425
|
-
//
|
|
426
|
-
//
|
|
427
|
-
//
|
|
428
|
-
|
|
429
|
-
|
|
429
|
+
// 再描画戦略:
|
|
430
|
+
// - TTY: 真の columns が分かるので CUU + clearBelow で部分再描画(省フリッカ)
|
|
431
|
+
// - 非 TTY (VSCode の type:process タスク等): columns を信用できないので 200 で
|
|
432
|
+
// truncate しているが、実ターミナル幅が 200 未満なら自動改行が起き、論理行数と
|
|
433
|
+
// 物理行数がズレて CUU が誤作動する(「1 セッション」行が毎フレーム積み上がる
|
|
434
|
+
// バグを実機で確認)。非 TTY では画面全クリアで愚直に描き直す方が確実。
|
|
435
|
+
// どちらも差分検知 (needsRerender) を通過したフレームのみ書き込むので、
|
|
436
|
+
// フリッカ量はデータ変化頻度に比例するだけで爆発しない。
|
|
437
|
+
if (process.stdout.isTTY) {
|
|
438
|
+
if (lastRenderedLines > 0) {
|
|
439
|
+
process.stdout.write(ANSI.up(lastRenderedLines) + '\r' + ANSI.clearBelow);
|
|
440
|
+
}
|
|
441
|
+
} else {
|
|
442
|
+
process.stdout.write(ANSI.clearScreen);
|
|
430
443
|
}
|
|
431
444
|
|
|
432
445
|
process.stdout.write(clipped.join('\n') + '\n');
|
|
@@ -434,12 +447,18 @@ function renderFrame(args) {
|
|
|
434
447
|
}
|
|
435
448
|
|
|
436
449
|
// --- 起動 ---
|
|
437
|
-
let
|
|
450
|
+
let terminalRestored = false;
|
|
451
|
+
/**
|
|
452
|
+
* 終了時に端末状態を元に戻す:
|
|
453
|
+
* - オルタネートスクリーンバッファから抜ける (起動前の画面に戻る)
|
|
454
|
+
* - カーソル表示を復活
|
|
455
|
+
* 2 回以上呼ばれても安全 (冪等)。
|
|
456
|
+
*/
|
|
438
457
|
function restoreCursor() {
|
|
439
|
-
if (
|
|
440
|
-
|
|
458
|
+
if (terminalRestored) return;
|
|
459
|
+
terminalRestored = true;
|
|
441
460
|
try {
|
|
442
|
-
process.stdout.write(ANSI.showCursor);
|
|
461
|
+
process.stdout.write(ANSI.leaveAltScreen + ANSI.showCursor);
|
|
443
462
|
} catch {
|
|
444
463
|
// stdout がすでに閉じていても無視
|
|
445
464
|
}
|
|
@@ -465,7 +484,9 @@ export function main() {
|
|
|
465
484
|
process.exit(2);
|
|
466
485
|
}
|
|
467
486
|
|
|
468
|
-
|
|
487
|
+
// オルタネートスクリーンバッファに入る → プライマリ画面を保存、クリア時に履歴に残らない。
|
|
488
|
+
// これにより「1 セッション」ヘッダが再描画のたびに積み上がる不具合を根絶できる。
|
|
489
|
+
process.stdout.write(ANSI.enterAltScreen + ANSI.hideCursor);
|
|
469
490
|
process.stdout.write(color(ANSI.dim, `[Throughline] モニター起動 (state: ${getStateDir()}, Ctrl+C で終了)\n`));
|
|
470
491
|
|
|
471
492
|
safeRenderFrame(args);
|