4runr-os 1.0.79 → 1.0.80

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.
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Section 0 - Stable App Shell
4
+ *
5
+ * Objective: Build a minimal TUI app shell that:
6
+ * - starts reliably
7
+ * - exits cleanly
8
+ * - restores the terminal every time
9
+ * - does not register duplicate handlers or multiple render loops
10
+ *
11
+ * No UI panels, no commands, no collectors yet. Just a stable shell.
12
+ */
13
+ /**
14
+ * Start Section 0 TUI shell
15
+ *
16
+ * Rules:
17
+ * - One render loop only (or none for Section 0 - just render once)
18
+ * - No console.log() while TUI is active
19
+ * - Exit must always restore terminal state
20
+ */
21
+ export declare function startSection0(): Promise<void>;
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/v3/section0/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAaH;;;;;;;GAOG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAwDnD"}
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Section 0 - Stable App Shell
4
+ *
5
+ * Objective: Build a minimal TUI app shell that:
6
+ * - starts reliably
7
+ * - exits cleanly
8
+ * - restores the terminal every time
9
+ * - does not register duplicate handlers or multiple render loops
10
+ *
11
+ * No UI panels, no commands, no collectors yet. Just a stable shell.
12
+ */
13
+ import { createScreen } from './runtime/createScreen.js';
14
+ import { initializeLifecycle } from './runtime/lifecycle.js';
15
+ import blessed from 'neo-blessed';
16
+ const blessedLib = blessed;
17
+ // Suppress console.log during TUI (write debug logs to file if needed)
18
+ const originalConsoleLog = console.log;
19
+ const originalConsoleError = console.error;
20
+ /**
21
+ * Start Section 0 TUI shell
22
+ *
23
+ * Rules:
24
+ * - One render loop only (or none for Section 0 - just render once)
25
+ * - No console.log() while TUI is active
26
+ * - Exit must always restore terminal state
27
+ */
28
+ export async function startSection0() {
29
+ // Suppress console.log during TUI
30
+ console.log = () => { };
31
+ // Keep console.error for fatal errors (but restore before using)
32
+ let consoleErrorRestored = false;
33
+ const restoreConsoleError = () => {
34
+ if (!consoleErrorRestored) {
35
+ console.error = originalConsoleError;
36
+ consoleErrorRestored = true;
37
+ }
38
+ };
39
+ try {
40
+ // Create screen (singleton, guarded)
41
+ const screen = createScreen();
42
+ // Initialize lifecycle (exit handlers, guarded against duplicates)
43
+ initializeLifecycle(screen);
44
+ // Create a single centered text node
45
+ const message = '4Runr OS V3 — Shell OK (press q to exit)';
46
+ const textNode = blessedLib.box({
47
+ top: Math.floor((screen.height - 1) / 2),
48
+ left: Math.floor((screen.width - message.length) / 2),
49
+ width: message.length,
50
+ height: 1,
51
+ content: message,
52
+ tags: true,
53
+ style: {
54
+ fg: 'cyan',
55
+ },
56
+ });
57
+ screen.append(textNode);
58
+ // Single render (no loop for Section 0)
59
+ screen.render();
60
+ // Restore console.log after successful start (for future use if needed)
61
+ // But keep it suppressed during TUI operation
62
+ // console.log = originalConsoleLog; // Commented: keep suppressed during TUI
63
+ }
64
+ catch (error) {
65
+ // Restore console.error for error output
66
+ restoreConsoleError();
67
+ console.error('FATAL: Section 0 TUI failed to start:', error);
68
+ // Ensure terminal is restored even on error
69
+ if (process.stdout.isTTY) {
70
+ process.stdout.write('\x1b[?25h'); // Show cursor
71
+ process.stdout.write('\x1b[?1049l'); // Exit alternate screen
72
+ }
73
+ process.exit(1);
74
+ }
75
+ }
76
+ // If run directly (not imported), start the TUI
77
+ // Simple check: if this file is executed directly, start the TUI
78
+ const scriptPath = process.argv[1]?.replace(/\\/g, '/') || '';
79
+ const isMainModule = scriptPath.includes('section0/index.js') ||
80
+ scriptPath.includes('section0/index.ts') ||
81
+ import.meta.url.includes('section0/index');
82
+ if (isMainModule) {
83
+ startSection0().catch((error) => {
84
+ console.error('FATAL: Section 0 failed:', error);
85
+ process.exit(1);
86
+ });
87
+ }
88
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ui/v3/section0/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Section 0 - Create Screen
3
+ *
4
+ * Responsibilities:
5
+ * - Initialize neo-blessed screen cleanly
6
+ * - Ensure only one screen instance exists
7
+ * - Configure screen with proper settings
8
+ */
9
+ import type { Widgets } from 'neo-blessed';
10
+ /**
11
+ * Create or get the singleton screen instance
12
+ *
13
+ * Rules:
14
+ * - Must only create one screen instance
15
+ * - If screen already exists, return it (do not create another)
16
+ * - Configure with smartCSR, fullUnicode, dockBorders, warnings: false
17
+ */
18
+ export declare function createScreen(): Widgets.Screen;
19
+ /**
20
+ * Get the current screen instance (may be null)
21
+ */
22
+ export declare function getScreen(): Widgets.Screen | null;
23
+ /**
24
+ * Clear the screen instance reference (for testing/cleanup)
25
+ */
26
+ export declare function clearScreen(): void;
27
+ //# sourceMappingURL=createScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/v3/section0/runtime/createScreen.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAM3C;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAAC,MAAM,CAyB7C;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAEjD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Section 0 - Create Screen
3
+ *
4
+ * Responsibilities:
5
+ * - Initialize neo-blessed screen cleanly
6
+ * - Ensure only one screen instance exists
7
+ * - Configure screen with proper settings
8
+ */
9
+ import blessed from 'neo-blessed';
10
+ const blessedLib = blessed;
11
+ let screenInstance = null;
12
+ /**
13
+ * Create or get the singleton screen instance
14
+ *
15
+ * Rules:
16
+ * - Must only create one screen instance
17
+ * - If screen already exists, return it (do not create another)
18
+ * - Configure with smartCSR, fullUnicode, dockBorders, warnings: false
19
+ */
20
+ export function createScreen() {
21
+ if (screenInstance) {
22
+ return screenInstance;
23
+ }
24
+ screenInstance = blessedLib.screen({
25
+ smartCSR: true,
26
+ fullUnicode: true,
27
+ dockBorders: true,
28
+ warnings: false,
29
+ title: '4Runr OS (Terminal UI V3)',
30
+ });
31
+ if (!screenInstance) {
32
+ throw new Error('Failed to create blessed screen');
33
+ }
34
+ // Hide cursor on start (will be restored on exit)
35
+ if (screenInstance.program && screenInstance.program.hideCursor) {
36
+ screenInstance.program.hideCursor();
37
+ }
38
+ else if (process.stdout.isTTY) {
39
+ process.stdout.write('\x1b[?25l'); // ANSI hide cursor
40
+ }
41
+ return screenInstance;
42
+ }
43
+ /**
44
+ * Get the current screen instance (may be null)
45
+ */
46
+ export function getScreen() {
47
+ return screenInstance;
48
+ }
49
+ /**
50
+ * Clear the screen instance reference (for testing/cleanup)
51
+ */
52
+ export function clearScreen() {
53
+ screenInstance = null;
54
+ }
55
+ //# sourceMappingURL=createScreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createScreen.js","sourceRoot":"","sources":["../../../../../src/ui/v3/section0/runtime/createScreen.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,OAAO,MAAM,aAAa,CAAC;AAGlC,MAAM,UAAU,GAAG,OAAc,CAAC;AAElC,IAAI,cAAc,GAA0B,IAAI,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC;QACjC,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,IAAI;QACjB,WAAW,EAAE,IAAI;QACjB,QAAQ,EAAE,KAAK;QACf,KAAK,EAAE,2BAA2B;KACnC,CAAmB,CAAC;IAErB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,kDAAkD;IAClD,IAAK,cAAsB,CAAC,OAAO,IAAK,cAAsB,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACjF,cAAsB,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;IAC/C,CAAC;SAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAmB;IACxD,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Section 0 - Lifecycle Management
3
+ *
4
+ * Responsibilities:
5
+ * - Attach exit handlers (single registration, guarded)
6
+ * - Implement safe shutdown that always restores terminal
7
+ * - Track handler attachment to prevent duplicates
8
+ */
9
+ import type { Widgets } from 'neo-blessed';
10
+ /**
11
+ * Attach exit handlers to screen
12
+ *
13
+ * Rules:
14
+ * - Must attach handlers exactly once (protected by exitHandlersAttached guard)
15
+ * - If called again, must no-op
16
+ * - Registers: q → exit, C-c → exit, escape → exit (optional)
17
+ */
18
+ export declare function attachExitHandlers(screen: Widgets.Screen): void;
19
+ /**
20
+ * Attach process-level exit handlers
21
+ *
22
+ * Rules:
23
+ * - Must attach handlers exactly once (protected by exitHandlersAttached guard)
24
+ * - If called again, must no-op
25
+ * - Registers: SIGINT, SIGTERM
26
+ * - Tracks listeners for cleanup
27
+ */
28
+ export declare function attachProcessExitHandlers(): void;
29
+ /**
30
+ * Initialize all exit handlers (screen + process)
31
+ *
32
+ * This is the main entry point for lifecycle setup.
33
+ */
34
+ export declare function initializeLifecycle(screen: Widgets.Screen): void;
35
+ /**
36
+ * Get internal debug counters (for checkpoint verification)
37
+ *
38
+ * These counters verify:
39
+ * - Exit handlers attach exactly once
40
+ * - Shutdown runs exactly once
41
+ *
42
+ * Example expectation: Pressing q triggers exactly one shutdown path.
43
+ */
44
+ export declare function getDebugCounters(): {
45
+ shutdownCallCount: number;
46
+ screenHandlerAttachmentCount: number;
47
+ processHandlerAttachmentCount: number;
48
+ };
49
+ /**
50
+ * Reset lifecycle state (for testing only)
51
+ */
52
+ export declare function resetLifecycle(): void;
53
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../../../src/ui/v3/section0/runtime/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAmF3C;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAsB/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAuBhD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAGhE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,IAAI;IAClC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,4BAA4B,EAAE,MAAM,CAAC;IACrC,6BAA6B,EAAE,MAAM,CAAC;CACvC,CAMA;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAQrC"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Section 0 - Lifecycle Management
3
+ *
4
+ * Responsibilities:
5
+ * - Attach exit handlers (single registration, guarded)
6
+ * - Implement safe shutdown that always restores terminal
7
+ * - Track handler attachment to prevent duplicates
8
+ */
9
+ import { getScreen } from './createScreen.js';
10
+ // Guards to prevent duplicate handler attachment
11
+ let screenHandlersAttached = false;
12
+ let processHandlersAttached = false;
13
+ let shuttingDown = false;
14
+ // Internal debug counters (NOT console.log - for checkpoint verification)
15
+ // These track handler attachment and shutdown calls
16
+ let shutdownCallCount = 0;
17
+ let screenHandlerAttachmentCount = 0;
18
+ let processHandlerAttachmentCount = 0;
19
+ // Track attached process listeners for cleanup
20
+ const attachedProcessListeners = [];
21
+ /**
22
+ * Shutdown function that always restores terminal state
23
+ *
24
+ * Rules:
25
+ * - Must run exactly once (protected by shuttingDown guard)
26
+ * - Steps (in order):
27
+ * 1. screen.program.showCursor()
28
+ * 2. screen.destroy() (restores terminal modes)
29
+ * 3. Remove any process listeners we attached
30
+ * 4. process.exit(0)
31
+ */
32
+ function shutdown(reason) {
33
+ // Internal debug counter
34
+ shutdownCallCount++;
35
+ // Guard: ensure shutdown runs exactly once
36
+ if (shuttingDown) {
37
+ return;
38
+ }
39
+ shuttingDown = true;
40
+ const screen = getScreen();
41
+ if (screen) {
42
+ try {
43
+ // Step 1: Show cursor
44
+ if (screen.program && screen.program.showCursor) {
45
+ screen.program.showCursor();
46
+ }
47
+ else if (process.stdout.isTTY) {
48
+ process.stdout.write('\x1b[?25h'); // ANSI show cursor
49
+ }
50
+ // Step 2: Destroy screen (restores terminal modes)
51
+ screen.destroy();
52
+ }
53
+ catch (e) {
54
+ // Ignore destroy errors, but ensure cursor is shown
55
+ if (process.stdout.isTTY) {
56
+ process.stdout.write('\x1b[?25h');
57
+ process.stdout.write('\x1b[?1049l'); // Exit alternate screen if needed
58
+ }
59
+ }
60
+ }
61
+ else {
62
+ // No screen, but ensure cursor is visible
63
+ if (process.stdout.isTTY) {
64
+ process.stdout.write('\x1b[?25h');
65
+ process.stdout.write('\x1b[?1049l');
66
+ }
67
+ }
68
+ // Step 3: Remove process listeners we attached
69
+ for (const { event, listener } of attachedProcessListeners) {
70
+ try {
71
+ process.removeListener(event, listener);
72
+ }
73
+ catch (e) {
74
+ // Ignore removal errors
75
+ }
76
+ }
77
+ attachedProcessListeners.length = 0;
78
+ // Step 4: Exit
79
+ process.exit(0);
80
+ }
81
+ /**
82
+ * Attach exit handlers to screen
83
+ *
84
+ * Rules:
85
+ * - Must attach handlers exactly once (protected by exitHandlersAttached guard)
86
+ * - If called again, must no-op
87
+ * - Registers: q → exit, C-c → exit, escape → exit (optional)
88
+ */
89
+ export function attachExitHandlers(screen) {
90
+ // Guard: ensure handlers are attached exactly once
91
+ if (screenHandlersAttached) {
92
+ return;
93
+ }
94
+ screenHandlersAttached = true;
95
+ screenHandlerAttachmentCount++;
96
+ // q → exit
97
+ screen.key(['q', 'Q'], () => {
98
+ shutdown('q pressed');
99
+ });
100
+ // C-c → exit
101
+ screen.key(['C-c'], () => {
102
+ shutdown('Ctrl+C pressed');
103
+ });
104
+ // escape → exit (optional, as requested)
105
+ screen.key(['escape'], () => {
106
+ shutdown('Escape pressed');
107
+ });
108
+ }
109
+ /**
110
+ * Attach process-level exit handlers
111
+ *
112
+ * Rules:
113
+ * - Must attach handlers exactly once (protected by exitHandlersAttached guard)
114
+ * - If called again, must no-op
115
+ * - Registers: SIGINT, SIGTERM
116
+ * - Tracks listeners for cleanup
117
+ */
118
+ export function attachProcessExitHandlers() {
119
+ // Guard: ensure handlers are attached exactly once
120
+ if (processHandlersAttached) {
121
+ return;
122
+ }
123
+ processHandlersAttached = true;
124
+ processHandlerAttachmentCount++;
125
+ const sigintHandler = () => {
126
+ shutdown('SIGINT received');
127
+ };
128
+ const sigtermHandler = () => {
129
+ shutdown('SIGTERM received');
130
+ };
131
+ process.on('SIGINT', sigintHandler);
132
+ process.on('SIGTERM', sigtermHandler);
133
+ attachedProcessListeners.push({ event: 'SIGINT', listener: sigintHandler }, { event: 'SIGTERM', listener: sigtermHandler });
134
+ }
135
+ /**
136
+ * Initialize all exit handlers (screen + process)
137
+ *
138
+ * This is the main entry point for lifecycle setup.
139
+ */
140
+ export function initializeLifecycle(screen) {
141
+ attachExitHandlers(screen);
142
+ attachProcessExitHandlers();
143
+ }
144
+ /**
145
+ * Get internal debug counters (for checkpoint verification)
146
+ *
147
+ * These counters verify:
148
+ * - Exit handlers attach exactly once
149
+ * - Shutdown runs exactly once
150
+ *
151
+ * Example expectation: Pressing q triggers exactly one shutdown path.
152
+ */
153
+ export function getDebugCounters() {
154
+ return {
155
+ shutdownCallCount,
156
+ screenHandlerAttachmentCount,
157
+ processHandlerAttachmentCount,
158
+ };
159
+ }
160
+ /**
161
+ * Reset lifecycle state (for testing only)
162
+ */
163
+ export function resetLifecycle() {
164
+ screenHandlersAttached = false;
165
+ processHandlersAttached = false;
166
+ shuttingDown = false;
167
+ attachedProcessListeners.length = 0;
168
+ shutdownCallCount = 0;
169
+ screenHandlerAttachmentCount = 0;
170
+ processHandlerAttachmentCount = 0;
171
+ }
172
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../../../src/ui/v3/section0/runtime/lifecycle.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "4runr-os",
3
- "version": "1.0.79",
3
+ "version": "1.0.80",
4
4
  "type": "module",
5
5
  "description": "4Runr AI Agent OS - Interactive terminal for managing AI agents",
6
6
  "main": "dist/index.js",