4runr-os 2.0.71 → 2.1.0
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 +47 -38
- package/dist/index.js.map +1 -1
- package/dist/tui_mk1/kernel.d.ts +32 -0
- package/dist/tui_mk1/kernel.d.ts.map +1 -0
- package/dist/tui_mk1/kernel.js +115 -0
- package/dist/tui_mk1/kernel.js.map +1 -0
- package/dist/tui_mk1/logger.d.ts +11 -0
- package/dist/tui_mk1/logger.d.ts.map +1 -0
- package/dist/tui_mk1/logger.js +86 -0
- package/dist/tui_mk1/logger.js.map +1 -0
- package/dist/tui_mk1/mk1App.d.ts +45 -0
- package/dist/tui_mk1/mk1App.d.ts.map +1 -0
- package/dist/tui_mk1/mk1App.js +283 -0
- package/dist/tui_mk1/mk1App.js.map +1 -0
- package/dist/tui_mk1/resizeController.d.ts +39 -0
- package/dist/tui_mk1/resizeController.d.ts.map +1 -0
- package/dist/tui_mk1/resizeController.js +108 -0
- package/dist/tui_mk1/resizeController.js.map +1 -0
- package/dist/tui_mk1/stdoutGuard.d.ts +15 -0
- package/dist/tui_mk1/stdoutGuard.d.ts.map +1 -0
- package/dist/tui_mk1/stdoutGuard.js +66 -0
- package/dist/tui_mk1/stdoutGuard.js.map +1 -0
- package/dist/tui_mk1/terminalRestore.d.ts +22 -0
- package/dist/tui_mk1/terminalRestore.d.ts.map +1 -0
- package/dist/tui_mk1/terminalRestore.js +78 -0
- package/dist/tui_mk1/terminalRestore.js.map +1 -0
- package/dist/ui/v5/viewport/getViewport.d.ts.map +1 -1
- package/dist/ui/v5/viewport/getViewport.js +7 -6
- package/dist/ui/v5/viewport/getViewport.js.map +1 -1
- package/package.json +9 -8
- package/dist/ui/v3/state/feedModel.d.ts +0 -49
- package/dist/ui/v3/state/feedModel.d.ts.map +0 -1
- package/dist/ui/v3/state/feedModel.js +0 -84
- package/dist/ui/v3/state/feedModel.js.map +0 -1
- package/dist/ui/v3/v1Adapters/__tests__/smoke.test.d.ts +0 -16
- package/dist/ui/v3/v1Adapters/__tests__/smoke.test.d.ts.map +0 -1
- package/dist/ui/v3/v1Adapters/__tests__/smoke.test.js +0 -141
- package/dist/ui/v3/v1Adapters/__tests__/smoke.test.js.map +0 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Widgets } from 'neo-blessed';
|
|
2
|
+
declare global {
|
|
3
|
+
var __MK1_SCREEN__: Widgets.Screen | undefined;
|
|
4
|
+
}
|
|
5
|
+
export interface KernelOptions {
|
|
6
|
+
onRebuild?: (cols: number, rows: number) => void | Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export declare class MK1Kernel {
|
|
9
|
+
private screen;
|
|
10
|
+
private onRebuild;
|
|
11
|
+
/**
|
|
12
|
+
* Start kernel
|
|
13
|
+
*/
|
|
14
|
+
start(renderFn: () => void, options?: KernelOptions): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Rebuild (destroy + recreate)
|
|
17
|
+
*/
|
|
18
|
+
rebuild(reason: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Force rebuild (for dbg:panic)
|
|
21
|
+
*/
|
|
22
|
+
panic(): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Get screen instance
|
|
25
|
+
*/
|
|
26
|
+
getScreen(): Widgets.Screen | null;
|
|
27
|
+
/**
|
|
28
|
+
* Stop kernel
|
|
29
|
+
*/
|
|
30
|
+
stop(): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=kernel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel.d.ts","sourceRoot":"","sources":["../../src/tui_mk1/kernel.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAO3C,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,cAAc,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAChD;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,SAAS,CAAuE;IAExF;;OAEG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmD7E;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU5C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B;;OAEG;IACH,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,IAAI,IAAI,IAAI;CA8Bb"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MK1 Kernel - Owns everything
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Create screen with stable options
|
|
6
|
+
* - Attach resize controller
|
|
7
|
+
* - Attach exit handlers
|
|
8
|
+
* - Enforce singleton (destroy old screen before creating new)
|
|
9
|
+
*/
|
|
10
|
+
import blessed from 'neo-blessed';
|
|
11
|
+
import { enableStdoutGuard, disableStdoutGuard } from './stdoutGuard.js';
|
|
12
|
+
import { registerScreen, unregisterScreen, restoreTerminal } from './terminalRestore.js';
|
|
13
|
+
import { initResizeController, destroyResizeController, forceRebuild } from './resizeController.js';
|
|
14
|
+
import { logger } from './logger.js';
|
|
15
|
+
export class MK1Kernel {
|
|
16
|
+
screen = null;
|
|
17
|
+
onRebuild = null;
|
|
18
|
+
/**
|
|
19
|
+
* Start kernel
|
|
20
|
+
*/
|
|
21
|
+
async start(renderFn, options = {}) {
|
|
22
|
+
// Enforce singleton: destroy old screen if exists
|
|
23
|
+
if (globalThis.__MK1_SCREEN__) {
|
|
24
|
+
logger.warn('Old MK1 screen detected, destroying...');
|
|
25
|
+
try {
|
|
26
|
+
globalThis.__MK1_SCREEN__.destroy();
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Ignore
|
|
30
|
+
}
|
|
31
|
+
globalThis.__MK1_SCREEN__ = undefined;
|
|
32
|
+
}
|
|
33
|
+
// Enable stdout guard BEFORE creating screen
|
|
34
|
+
enableStdoutGuard();
|
|
35
|
+
// Create screen with stable options
|
|
36
|
+
this.screen = blessed.screen({
|
|
37
|
+
smartCSR: true,
|
|
38
|
+
fullUnicode: true,
|
|
39
|
+
warnings: false,
|
|
40
|
+
title: '4Runr MK1',
|
|
41
|
+
output: process.stdout,
|
|
42
|
+
input: process.stdin,
|
|
43
|
+
});
|
|
44
|
+
// Register singleton
|
|
45
|
+
globalThis.__MK1_SCREEN__ = this.screen;
|
|
46
|
+
// Register for terminal restore
|
|
47
|
+
registerScreen(this.screen);
|
|
48
|
+
// Store rebuild callback
|
|
49
|
+
this.onRebuild = options.onRebuild || null;
|
|
50
|
+
// Initialize resize controller
|
|
51
|
+
if (this.onRebuild) {
|
|
52
|
+
initResizeController(this.screen, this.onRebuild);
|
|
53
|
+
}
|
|
54
|
+
// Hide cursor initially
|
|
55
|
+
if (this.screen.program?.hideCursor) {
|
|
56
|
+
this.screen.program.hideCursor();
|
|
57
|
+
}
|
|
58
|
+
// Initial render
|
|
59
|
+
renderFn();
|
|
60
|
+
this.screen.render();
|
|
61
|
+
logger.info('MK1 Kernel started');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Rebuild (destroy + recreate)
|
|
65
|
+
*/
|
|
66
|
+
async rebuild(reason) {
|
|
67
|
+
logger.debug(`Rebuild requested: ${reason}`);
|
|
68
|
+
if (this.screen && this.onRebuild) {
|
|
69
|
+
const cols = this.screen.width;
|
|
70
|
+
const rows = this.screen.height;
|
|
71
|
+
await this.onRebuild(cols, rows);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Force rebuild (for dbg:panic)
|
|
76
|
+
*/
|
|
77
|
+
async panic() {
|
|
78
|
+
logger.warn('PANIC: Force rebuild');
|
|
79
|
+
await forceRebuild();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get screen instance
|
|
83
|
+
*/
|
|
84
|
+
getScreen() {
|
|
85
|
+
return this.screen;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Stop kernel
|
|
89
|
+
*/
|
|
90
|
+
stop() {
|
|
91
|
+
logger.info('Stopping MK1 Kernel');
|
|
92
|
+
// Destroy resize controller
|
|
93
|
+
destroyResizeController();
|
|
94
|
+
// Unregister screen
|
|
95
|
+
unregisterScreen();
|
|
96
|
+
// Disable stdout guard
|
|
97
|
+
disableStdoutGuard();
|
|
98
|
+
// Destroy screen
|
|
99
|
+
if (this.screen) {
|
|
100
|
+
try {
|
|
101
|
+
this.screen.destroy();
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Ignore
|
|
105
|
+
}
|
|
106
|
+
this.screen = null;
|
|
107
|
+
}
|
|
108
|
+
// Clear singleton
|
|
109
|
+
globalThis.__MK1_SCREEN__ = undefined;
|
|
110
|
+
// Restore terminal
|
|
111
|
+
restoreTerminal();
|
|
112
|
+
logger.info('MK1 Kernel stopped');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=kernel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel.js","sourceRoot":"","sources":["../../src/tui_mk1/kernel.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,OAAO,MAAM,aAAa,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAYrC,MAAM,OAAO,SAAS;IACZ,MAAM,GAA0B,IAAI,CAAC;IACrC,SAAS,GAAkE,IAAI,CAAC;IAExF;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,QAAoB,EAAE,UAAyB,EAAE;QAC3D,kDAAkD;QAClD,IAAK,UAAkB,CAAC,cAAc,EAAE,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;YACtD,IAAI,CAAC;gBACF,UAAkB,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACA,UAAkB,CAAC,cAAc,GAAG,SAAS,CAAC;QACjD,CAAC;QAED,6CAA6C;QAC7C,iBAAiB,EAAE,CAAC;QAEpB,oCAAoC;QACpC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC3B,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,KAAK;YACf,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,KAAK,EAAE,OAAO,CAAC,KAAK;SACd,CAAmB,CAAC;QAE5B,qBAAqB;QACpB,UAAkB,CAAC,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;QAEjD,gCAAgC;QAChC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE5B,yBAAyB;QACzB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;QAE3C,+BAA+B;QAC/B,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,CAAC;QAED,wBAAwB;QACxB,IAAK,IAAI,CAAC,MAAc,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;YAC5C,IAAI,CAAC,MAAc,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAC5C,CAAC;QAED,iBAAiB;QACjB,QAAQ,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAErB,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,MAAM,CAAC,KAAK,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;QAE7C,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;YAChC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACpC,MAAM,YAAY,EAAE,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,IAAI;QACF,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAEnC,4BAA4B;QAC5B,uBAAuB,EAAE,CAAC;QAE1B,oBAAoB;QACpB,gBAAgB,EAAE,CAAC;QAEnB,uBAAuB;QACvB,kBAAkB,EAAE,CAAC;QAErB,iBAAiB;QACjB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,kBAAkB;QACjB,UAAkB,CAAC,cAAc,GAAG,SAAS,CAAC;QAE/C,mBAAmB;QACnB,eAAe,EAAE,CAAC;QAElB,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACpC,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const logger: {
|
|
2
|
+
info: (message: string) => void;
|
|
3
|
+
warn: (message: string) => void;
|
|
4
|
+
error: (message: string) => void;
|
|
5
|
+
debug: (message: string) => void;
|
|
6
|
+
/**
|
|
7
|
+
* Get log file path
|
|
8
|
+
*/
|
|
9
|
+
getLogFile: () => string;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/tui_mk1/logger.ts"],"names":[],"mappings":"AAgFA,eAAO,MAAM,MAAM;oBACD,MAAM;oBACN,MAAM;qBACL,MAAM;qBACN,MAAM;IAMvB;;OAEG;;CAEJ,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MK1 Logger - stderr/file only, NEVER stdout
|
|
3
|
+
*
|
|
4
|
+
* Rules:
|
|
5
|
+
* - All logging goes to stderr OR log file
|
|
6
|
+
* - Never use console.log
|
|
7
|
+
* - Rate-limited to prevent spam
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import * as os from 'os';
|
|
12
|
+
const LOG_FILE = path.join(os.tmpdir(), '4runr_tui_mk1.log');
|
|
13
|
+
const MAX_LOG_SIZE = 1024 * 1024; // 1MB max log file
|
|
14
|
+
// Rate limiting
|
|
15
|
+
let lastLogTime = 0;
|
|
16
|
+
let logCount = 0;
|
|
17
|
+
const RATE_LIMIT_MS = 100; // Max 1 log per 100ms
|
|
18
|
+
const RATE_LIMIT_BURST = 10; // Allow 10 logs in burst
|
|
19
|
+
/**
|
|
20
|
+
* Write to log file (with rotation)
|
|
21
|
+
*/
|
|
22
|
+
function writeToFile(level, message) {
|
|
23
|
+
try {
|
|
24
|
+
// Check file size and rotate if needed
|
|
25
|
+
if (fs.existsSync(LOG_FILE)) {
|
|
26
|
+
const stats = fs.statSync(LOG_FILE);
|
|
27
|
+
if (stats.size > MAX_LOG_SIZE) {
|
|
28
|
+
// Rotate: move to .old
|
|
29
|
+
const oldFile = LOG_FILE + '.old';
|
|
30
|
+
if (fs.existsSync(oldFile)) {
|
|
31
|
+
fs.unlinkSync(oldFile);
|
|
32
|
+
}
|
|
33
|
+
fs.renameSync(LOG_FILE, oldFile);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const timestamp = new Date().toISOString();
|
|
37
|
+
const logLine = `[${timestamp}] [${level}] ${message}\n`;
|
|
38
|
+
fs.appendFileSync(LOG_FILE, logLine, 'utf8');
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
// If file write fails, silently ignore (we don't want to break the TUI)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Rate-limited log writer
|
|
46
|
+
*/
|
|
47
|
+
function rateLimitedLog(level, message) {
|
|
48
|
+
const now = Date.now();
|
|
49
|
+
// Reset counter if enough time has passed
|
|
50
|
+
if (now - lastLogTime > RATE_LIMIT_MS) {
|
|
51
|
+
logCount = 0;
|
|
52
|
+
}
|
|
53
|
+
// Check rate limit
|
|
54
|
+
if (logCount >= RATE_LIMIT_BURST && (now - lastLogTime) < RATE_LIMIT_MS) {
|
|
55
|
+
// Rate limited - skip this log
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
logCount++;
|
|
59
|
+
lastLogTime = now;
|
|
60
|
+
// Write to stderr
|
|
61
|
+
try {
|
|
62
|
+
process.stderr.write(`[MK1 ${level}] ${message}\n`);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Ignore stderr errors
|
|
66
|
+
}
|
|
67
|
+
// Write to file if debug enabled
|
|
68
|
+
if (process.env.TUI_DEBUG === '1') {
|
|
69
|
+
writeToFile(level, message);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export const logger = {
|
|
73
|
+
info: (message) => rateLimitedLog('INFO', message),
|
|
74
|
+
warn: (message) => rateLimitedLog('WARN', message),
|
|
75
|
+
error: (message) => rateLimitedLog('ERROR', message),
|
|
76
|
+
debug: (message) => {
|
|
77
|
+
if (process.env.TUI_DEBUG === '1') {
|
|
78
|
+
rateLimitedLog('DEBUG', message);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
/**
|
|
82
|
+
* Get log file path
|
|
83
|
+
*/
|
|
84
|
+
getLogFile: () => LOG_FILE,
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/tui_mk1/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export declare class MK1App {
|
|
2
|
+
private kernel;
|
|
3
|
+
private widgets;
|
|
4
|
+
private commandValue;
|
|
5
|
+
private lastRebuildReason;
|
|
6
|
+
private inputHandlersAttached;
|
|
7
|
+
constructor();
|
|
8
|
+
/**
|
|
9
|
+
* Start MK1 App
|
|
10
|
+
*/
|
|
11
|
+
start(): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Render minimal UI
|
|
14
|
+
*/
|
|
15
|
+
private render;
|
|
16
|
+
/**
|
|
17
|
+
* Update status line
|
|
18
|
+
*/
|
|
19
|
+
private updateStatusLine;
|
|
20
|
+
/**
|
|
21
|
+
* Handle resize
|
|
22
|
+
*/
|
|
23
|
+
private handleResize;
|
|
24
|
+
/**
|
|
25
|
+
* Setup input handling (manual - works on all terminals)
|
|
26
|
+
*/
|
|
27
|
+
private setupInputHandling;
|
|
28
|
+
/**
|
|
29
|
+
* Update command input display
|
|
30
|
+
*/
|
|
31
|
+
private updateCommandDisplay;
|
|
32
|
+
/**
|
|
33
|
+
* Handle command
|
|
34
|
+
*/
|
|
35
|
+
private handleCommand;
|
|
36
|
+
/**
|
|
37
|
+
* Stop app
|
|
38
|
+
*/
|
|
39
|
+
stop(): void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Start MK1 App (entry point)
|
|
43
|
+
*/
|
|
44
|
+
export declare function startMK1(): Promise<void>;
|
|
45
|
+
//# sourceMappingURL=mk1App.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mk1App.d.ts","sourceRoot":"","sources":["../../src/tui_mk1/mk1App.ts"],"names":[],"mappings":"AAyBA,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,iBAAiB,CAAqB;IAC9C,OAAO,CAAC,qBAAqB,CAAkB;;IAM/C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB5B;;OAEG;IACH,OAAO,CAAC,MAAM;IAyEd;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAiBxB;;OAEG;YACW,YAAY;IAkB1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAuD1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAW5B;;OAEG;YACW,aAAa;IAwD3B;;OAEG;IACH,IAAI,IAAI,IAAI;CAIb;AAED;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAG9C"}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MK1 App - Minimal UI
|
|
3
|
+
*
|
|
4
|
+
* Render:
|
|
5
|
+
* - One full-screen border box titled: "4Runr MK1"
|
|
6
|
+
* - One status line (top-left) showing: cols/rows, mode (mk1), resize burst count
|
|
7
|
+
* - One command input at bottom: 4runr>
|
|
8
|
+
*
|
|
9
|
+
* Commands:
|
|
10
|
+
* - dbg:size → prints to stderr log file, not UI
|
|
11
|
+
* - dbg:panic → forces rebuild (destroy + recreate screen)
|
|
12
|
+
* - help → prints in status line
|
|
13
|
+
*/
|
|
14
|
+
import blessed from 'neo-blessed';
|
|
15
|
+
import { MK1Kernel } from './kernel.js';
|
|
16
|
+
import { getResizeStats } from './resizeController.js';
|
|
17
|
+
import { logger } from './logger.js';
|
|
18
|
+
export class MK1App {
|
|
19
|
+
kernel;
|
|
20
|
+
widgets = null;
|
|
21
|
+
commandValue = '';
|
|
22
|
+
lastRebuildReason = 'initial';
|
|
23
|
+
inputHandlersAttached = false;
|
|
24
|
+
constructor() {
|
|
25
|
+
this.kernel = new MK1Kernel();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Start MK1 App
|
|
29
|
+
*/
|
|
30
|
+
async start() {
|
|
31
|
+
await this.kernel.start(() => {
|
|
32
|
+
this.render();
|
|
33
|
+
// Setup input handling after first render
|
|
34
|
+
this.setupInputHandling();
|
|
35
|
+
}, {
|
|
36
|
+
onRebuild: async (cols, rows) => {
|
|
37
|
+
// Reset input handlers flag (will re-attach after rebuild)
|
|
38
|
+
this.inputHandlersAttached = false;
|
|
39
|
+
await this.handleResize(cols, rows);
|
|
40
|
+
// Re-setup input handling after rebuild
|
|
41
|
+
this.setupInputHandling();
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
logger.info('MK1 App started');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Render minimal UI
|
|
48
|
+
*/
|
|
49
|
+
render() {
|
|
50
|
+
const screen = this.kernel.getScreen();
|
|
51
|
+
if (!screen) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// Destroy old widgets if they exist
|
|
55
|
+
if (this.widgets) {
|
|
56
|
+
try {
|
|
57
|
+
this.widgets.rootBox.destroy();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Ignore
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Root box (full screen)
|
|
64
|
+
this.widgets = {
|
|
65
|
+
rootBox: blessed.box({
|
|
66
|
+
top: 0,
|
|
67
|
+
left: 0,
|
|
68
|
+
width: '100%',
|
|
69
|
+
height: '100%',
|
|
70
|
+
border: {
|
|
71
|
+
type: 'line',
|
|
72
|
+
},
|
|
73
|
+
style: {
|
|
74
|
+
border: {
|
|
75
|
+
fg: 'cyan',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
content: '4Runr MK1',
|
|
79
|
+
tags: true,
|
|
80
|
+
}),
|
|
81
|
+
statusLine: blessed.box({
|
|
82
|
+
top: 0,
|
|
83
|
+
left: 0,
|
|
84
|
+
width: '100%',
|
|
85
|
+
height: 1,
|
|
86
|
+
content: '',
|
|
87
|
+
style: {
|
|
88
|
+
fg: 'yellow',
|
|
89
|
+
},
|
|
90
|
+
tags: true,
|
|
91
|
+
}),
|
|
92
|
+
commandInput: blessed.box({
|
|
93
|
+
bottom: 0,
|
|
94
|
+
left: 0,
|
|
95
|
+
width: '100%',
|
|
96
|
+
height: 1,
|
|
97
|
+
content: '4runr> ',
|
|
98
|
+
style: {
|
|
99
|
+
fg: 'green',
|
|
100
|
+
},
|
|
101
|
+
tags: true,
|
|
102
|
+
}),
|
|
103
|
+
};
|
|
104
|
+
// Append to screen
|
|
105
|
+
screen.append(this.widgets.rootBox);
|
|
106
|
+
screen.append(this.widgets.statusLine);
|
|
107
|
+
screen.append(this.widgets.commandInput);
|
|
108
|
+
// Update status line
|
|
109
|
+
this.updateStatusLine();
|
|
110
|
+
// Set command input content
|
|
111
|
+
const prompt = '4runr> ';
|
|
112
|
+
const displayText = prompt + this.commandValue;
|
|
113
|
+
this.widgets.commandInput.setContent(displayText);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Update status line
|
|
117
|
+
*/
|
|
118
|
+
updateStatusLine() {
|
|
119
|
+
if (!this.widgets) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const screen = this.kernel.getScreen();
|
|
123
|
+
if (!screen) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const stats = getResizeStats();
|
|
127
|
+
const statusText = `cols=${screen.width} rows=${screen.height} mode=mk1 bursts=${stats.burstCount} reason=${this.lastRebuildReason}`;
|
|
128
|
+
// Update content property directly
|
|
129
|
+
this.widgets.statusLine.content = statusText;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Handle resize
|
|
133
|
+
*/
|
|
134
|
+
async handleResize(cols, rows) {
|
|
135
|
+
this.lastRebuildReason = `resize:${cols}x${rows}`;
|
|
136
|
+
// Preserve command input value (already stored in this.commandValue)
|
|
137
|
+
// Rebuild (destroy + recreate)
|
|
138
|
+
this.render();
|
|
139
|
+
// Update command display
|
|
140
|
+
this.updateCommandDisplay();
|
|
141
|
+
// Re-render
|
|
142
|
+
const screen = this.kernel.getScreen();
|
|
143
|
+
if (screen) {
|
|
144
|
+
screen.render();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Setup input handling (manual - works on all terminals)
|
|
149
|
+
*/
|
|
150
|
+
setupInputHandling() {
|
|
151
|
+
const screen = this.kernel.getScreen();
|
|
152
|
+
if (!screen || !this.widgets) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
// Prevent duplicate handlers
|
|
156
|
+
if (this.inputHandlersAttached) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
this.inputHandlersAttached = true;
|
|
160
|
+
// Manual input handling via screen.key() events
|
|
161
|
+
screen.on('keypress', async (ch, key) => {
|
|
162
|
+
// Handle Enter key (submit)
|
|
163
|
+
if (key.name === 'enter' || key.name === 'return') {
|
|
164
|
+
if (this.commandValue.trim()) {
|
|
165
|
+
const command = this.commandValue.trim();
|
|
166
|
+
this.commandValue = '';
|
|
167
|
+
this.updateCommandDisplay();
|
|
168
|
+
screen.render();
|
|
169
|
+
// Handle command
|
|
170
|
+
await this.handleCommand(command);
|
|
171
|
+
// Clear and re-render
|
|
172
|
+
this.updateCommandDisplay();
|
|
173
|
+
screen.render();
|
|
174
|
+
}
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// Handle Backspace
|
|
178
|
+
if (key.name === 'backspace' || key.name === 'delete') {
|
|
179
|
+
this.commandValue = this.commandValue.slice(0, -1);
|
|
180
|
+
this.updateCommandDisplay();
|
|
181
|
+
screen.render();
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
// Handle printable characters (ASCII only)
|
|
185
|
+
if (ch && typeof ch === 'string' && /[\x20-\x7E]/.test(ch)) {
|
|
186
|
+
this.commandValue += ch;
|
|
187
|
+
this.updateCommandDisplay();
|
|
188
|
+
screen.render();
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
// Handle Ctrl+C
|
|
192
|
+
screen.key(['C-c'], () => {
|
|
193
|
+
this.stop();
|
|
194
|
+
process.exit(0);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Update command input display
|
|
199
|
+
*/
|
|
200
|
+
updateCommandDisplay() {
|
|
201
|
+
if (!this.widgets) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const prompt = '4runr> ';
|
|
205
|
+
const displayText = prompt + this.commandValue;
|
|
206
|
+
// Update content property directly
|
|
207
|
+
this.widgets.commandInput.content = displayText;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Handle command
|
|
211
|
+
*/
|
|
212
|
+
async handleCommand(command) {
|
|
213
|
+
if (command === 'dbg:size') {
|
|
214
|
+
// Print to stderr log file, not UI
|
|
215
|
+
const screen = this.kernel.getScreen();
|
|
216
|
+
if (screen) {
|
|
217
|
+
const info = {
|
|
218
|
+
'screen.cols': screen.width,
|
|
219
|
+
'screen.rows': screen.height,
|
|
220
|
+
'stdout.columns': process.stdout.columns,
|
|
221
|
+
'stdout.rows': process.stdout.rows,
|
|
222
|
+
'TERM': process.env.TERM,
|
|
223
|
+
'platform': process.platform,
|
|
224
|
+
'isTTY': process.stdout.isTTY,
|
|
225
|
+
};
|
|
226
|
+
logger.debug(`dbg:size output:\n${JSON.stringify(info, null, 2)}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
else if (command === 'dbg:panic') {
|
|
230
|
+
// Force rebuild
|
|
231
|
+
this.lastRebuildReason = 'panic';
|
|
232
|
+
await this.kernel.panic();
|
|
233
|
+
}
|
|
234
|
+
else if (command === 'help') {
|
|
235
|
+
// Show help in status line
|
|
236
|
+
if (this.widgets) {
|
|
237
|
+
this.widgets.statusLine.content = 'Commands: dbg:size, dbg:panic, help, exit';
|
|
238
|
+
const screen = this.kernel.getScreen();
|
|
239
|
+
if (screen) {
|
|
240
|
+
screen.render();
|
|
241
|
+
// Reset status line after 3 seconds
|
|
242
|
+
setTimeout(() => {
|
|
243
|
+
this.updateStatusLine();
|
|
244
|
+
screen.render();
|
|
245
|
+
}, 3000);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
else if (command === 'exit') {
|
|
250
|
+
this.stop();
|
|
251
|
+
process.exit(0);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
// Unknown command - show in status line
|
|
255
|
+
if (this.widgets) {
|
|
256
|
+
this.widgets.statusLine.content = `Unknown command: ${command} (type 'help')`;
|
|
257
|
+
const screen = this.kernel.getScreen();
|
|
258
|
+
if (screen) {
|
|
259
|
+
screen.render();
|
|
260
|
+
setTimeout(() => {
|
|
261
|
+
this.updateStatusLine();
|
|
262
|
+
screen.render();
|
|
263
|
+
}, 2000);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Stop app
|
|
270
|
+
*/
|
|
271
|
+
stop() {
|
|
272
|
+
this.kernel.stop();
|
|
273
|
+
logger.info('MK1 App stopped');
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Start MK1 App (entry point)
|
|
278
|
+
*/
|
|
279
|
+
export async function startMK1() {
|
|
280
|
+
const app = new MK1App();
|
|
281
|
+
await app.start();
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=mk1App.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mk1App.js","sourceRoot":"","sources":["../../src/tui_mk1/mk1App.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MK1 Resize Controller - Atomic rebuild (no partial updates)
|
|
3
|
+
*
|
|
4
|
+
* Behavior:
|
|
5
|
+
* - Listen only: screen.on("resize", ...)
|
|
6
|
+
* - Debounce: 150ms
|
|
7
|
+
* - On commit: destroy + recreate entire screen + widgets
|
|
8
|
+
* - Always re-focus input after rebuild
|
|
9
|
+
* - Track: last cols/rows, burst count, last resize timestamp
|
|
10
|
+
*
|
|
11
|
+
* CRITICAL: No partial updates. No widget reuse. Ever.
|
|
12
|
+
*/
|
|
13
|
+
import type { Widgets } from 'neo-blessed';
|
|
14
|
+
export interface ResizeStats {
|
|
15
|
+
lastCols: number;
|
|
16
|
+
lastRows: number;
|
|
17
|
+
burstCount: number;
|
|
18
|
+
lastResizeTime: number;
|
|
19
|
+
totalResizes: number;
|
|
20
|
+
}
|
|
21
|
+
type RebuildCallback = (cols: number, rows: number) => void | Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Initialize resize controller
|
|
24
|
+
*/
|
|
25
|
+
export declare function initResizeController(screen: Widgets.Screen, onRebuild: RebuildCallback): void;
|
|
26
|
+
/**
|
|
27
|
+
* Get resize statistics
|
|
28
|
+
*/
|
|
29
|
+
export declare function getResizeStats(): ResizeStats;
|
|
30
|
+
/**
|
|
31
|
+
* Force immediate rebuild (for dbg:panic)
|
|
32
|
+
*/
|
|
33
|
+
export declare function forceRebuild(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Destroy resize controller
|
|
36
|
+
*/
|
|
37
|
+
export declare function destroyResizeController(): void;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=resizeController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resizeController.d.ts","sourceRoot":"","sources":["../../src/tui_mk1/resizeController.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAeD,KAAK,eAAe,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAG5E;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,CAAC,MAAM,EACtB,SAAS,EAAE,eAAe,GACzB,IAAI,CAaN;AA0DD;;GAEG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAE5C;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAYlD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAU9C"}
|