4runr-os 1.0.46 → 1.0.49
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 +6 -34
- package/dist/index.js.map +1 -1
- package/dist/ui/v3/collectors/resources.d.ts +23 -0
- package/dist/ui/v3/collectors/resources.d.ts.map +1 -0
- package/dist/ui/v3/collectors/resources.js +117 -0
- package/dist/ui/v3/collectors/resources.js.map +1 -0
- package/dist/ui/v3/commands/commandResult.d.ts +25 -0
- package/dist/ui/v3/commands/commandResult.d.ts.map +1 -0
- package/dist/ui/v3/commands/commandResult.js +19 -0
- package/dist/ui/v3/commands/commandResult.js.map +1 -0
- package/dist/ui/v3/commands/parser.d.ts +14 -0
- package/dist/ui/v3/commands/parser.d.ts.map +1 -0
- package/dist/ui/v3/commands/parser.js +29 -0
- package/dist/ui/v3/commands/parser.js.map +1 -0
- package/dist/ui/v3/commands/router.d.ts +13 -0
- package/dist/ui/v3/commands/router.d.ts.map +1 -0
- package/dist/ui/v3/commands/router.js +69 -0
- package/dist/ui/v3/commands/router.js.map +1 -0
- package/dist/ui/v3/core/event.d.ts +19 -0
- package/dist/ui/v3/core/event.d.ts.map +1 -0
- package/dist/ui/v3/core/event.js +7 -0
- package/dist/ui/v3/core/event.js.map +1 -0
- package/dist/ui/v3/core/eventBus.d.ts +33 -0
- package/dist/ui/v3/core/eventBus.d.ts.map +1 -0
- package/dist/ui/v3/core/eventBus.js +78 -0
- package/dist/ui/v3/core/eventBus.js.map +1 -0
- package/dist/ui/v3/index.d.ts +8 -0
- package/dist/ui/v3/index.d.ts.map +1 -0
- package/dist/ui/v3/index.js +30 -0
- package/dist/ui/v3/index.js.map +1 -0
- package/dist/ui/v3/state/defaultState.d.ts +9 -0
- package/dist/ui/v3/state/defaultState.d.ts.map +1 -0
- package/dist/ui/v3/state/defaultState.js +11 -0
- package/dist/ui/v3/state/defaultState.js.map +1 -0
- package/dist/ui/v3/state/feedModel.d.ts +49 -0
- package/dist/ui/v3/state/feedModel.d.ts.map +1 -0
- package/dist/ui/v3/state/feedModel.js +84 -0
- package/dist/ui/v3/state/feedModel.js.map +1 -0
- package/dist/ui/v3/state/resourcesData.d.ts +15 -0
- package/dist/ui/v3/state/resourcesData.d.ts.map +1 -0
- package/dist/ui/v3/state/resourcesData.js +7 -0
- package/dist/ui/v3/state/resourcesData.js.map +1 -0
- package/dist/ui/v3/state/uiState.d.ts +12 -0
- package/dist/ui/v3/state/uiState.d.ts.map +1 -0
- package/dist/ui/v3/state/uiState.js +8 -0
- package/dist/ui/v3/state/uiState.js.map +1 -0
- package/dist/ui/v3/state/uiStateBuilder.d.ts +16 -0
- package/dist/ui/v3/state/uiStateBuilder.d.ts.map +1 -0
- package/dist/ui/v3/state/uiStateBuilder.js +35 -0
- package/dist/ui/v3/state/uiStateBuilder.js.map +1 -0
- package/dist/ui/v3/state/value.d.ts +39 -0
- package/dist/ui/v3/state/value.d.ts.map +1 -0
- package/dist/ui/v3/state/value.js +31 -0
- package/dist/ui/v3/state/value.js.map +1 -0
- package/dist/ui/v3/ui/focus.d.ts +28 -0
- package/dist/ui/v3/ui/focus.d.ts.map +1 -0
- package/dist/ui/v3/ui/focus.js +38 -0
- package/dist/ui/v3/ui/focus.js.map +1 -0
- package/dist/ui/v3/ui/layout/hubLayout.d.ts +43 -0
- package/dist/ui/v3/ui/layout/hubLayout.d.ts.map +1 -0
- package/dist/ui/v3/ui/layout/hubLayout.js +170 -0
- package/dist/ui/v3/ui/layout/hubLayout.js.map +1 -0
- package/dist/ui/v3/ui/layout/phase1Layout.d.ts +34 -0
- package/dist/ui/v3/ui/layout/phase1Layout.d.ts.map +1 -0
- package/dist/ui/v3/ui/layout/phase1Layout.js +107 -0
- package/dist/ui/v3/ui/layout/phase1Layout.js.map +1 -0
- package/dist/ui/v3/ui/minimalRuntime.d.ts +14 -0
- package/dist/ui/v3/ui/minimalRuntime.d.ts.map +1 -0
- package/dist/ui/v3/ui/minimalRuntime.js +111 -0
- package/dist/ui/v3/ui/minimalRuntime.js.map +1 -0
- package/dist/ui/v3/ui/panels/ResourcesPanel.d.ts +16 -0
- package/dist/ui/v3/ui/panels/ResourcesPanel.d.ts.map +1 -0
- package/dist/ui/v3/ui/panels/ResourcesPanel.js +46 -0
- package/dist/ui/v3/ui/panels/ResourcesPanel.js.map +1 -0
- package/dist/ui/v3/ui/phase1Runtime.d.ts +22 -0
- package/dist/ui/v3/ui/phase1Runtime.d.ts.map +1 -0
- package/dist/ui/v3/ui/phase1Runtime.js +574 -0
- package/dist/ui/v3/ui/phase1Runtime.js.map +1 -0
- package/dist/ui/v3/ui/primitives/Panel.d.ts +39 -0
- package/dist/ui/v3/ui/primitives/Panel.d.ts.map +1 -0
- package/dist/ui/v3/ui/primitives/Panel.js +105 -0
- package/dist/ui/v3/ui/primitives/Panel.js.map +1 -0
- package/dist/ui/v3/ui/theme.d.ts +37 -0
- package/dist/ui/v3/ui/theme.d.ts.map +1 -0
- package/dist/ui/v3/ui/theme.js +40 -0
- package/dist/ui/v3/ui/theme.js.map +1 -0
- package/dist/ui/v3/ui/widgets/CommandLine.d.ts +26 -0
- package/dist/ui/v3/ui/widgets/CommandLine.d.ts.map +1 -0
- package/dist/ui/v3/ui/widgets/CommandLine.js +67 -0
- package/dist/ui/v3/ui/widgets/CommandLine.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 1 Runtime
|
|
3
|
+
*
|
|
4
|
+
* Layout skeleton + dedicated command line
|
|
5
|
+
* - 6 read-only panels
|
|
6
|
+
* - 1 command line (only writable area)
|
|
7
|
+
* - Focus locked to command line
|
|
8
|
+
*
|
|
9
|
+
* Phase 2: Command Router
|
|
10
|
+
* - Command parsing and routing
|
|
11
|
+
* - Output to OPERATIONS FEED panel
|
|
12
|
+
*
|
|
13
|
+
* Phase 3: Operations Feed as Only Output Channel
|
|
14
|
+
* - EventBus system
|
|
15
|
+
* - All output goes through EventBus → feedStore
|
|
16
|
+
* - Long line truncation
|
|
17
|
+
*/
|
|
18
|
+
import blessed from 'neo-blessed';
|
|
19
|
+
// Type assertion for blessed (textbox not in types)
|
|
20
|
+
const blessedLib = blessed;
|
|
21
|
+
import { computePhase1Layout } from './layout/phase1Layout.js';
|
|
22
|
+
import { feedStore, formatTimestamp } from '../state/feedModel.js';
|
|
23
|
+
import { parseCommand } from '../commands/parser.js';
|
|
24
|
+
import { routeCommand } from '../commands/router.js';
|
|
25
|
+
import { eventBus } from '../core/eventBus.js';
|
|
26
|
+
import { buildUiState } from '../state/uiStateBuilder.js';
|
|
27
|
+
import { renderResourcesPanel } from './panels/ResourcesPanel.js';
|
|
28
|
+
import { isAvailable, isUnavailable } from '../state/value.js';
|
|
29
|
+
let screen = null;
|
|
30
|
+
let panels = [];
|
|
31
|
+
let commandLine = null;
|
|
32
|
+
let statusStrip = null;
|
|
33
|
+
let isCleaningUp = false;
|
|
34
|
+
let currentCommandValue = '4runr> '; // Track current command value
|
|
35
|
+
let currentUiState = null; // Phase 4: Current UiState
|
|
36
|
+
let lastResourcesAvailable = null; // Phase 4: Track state transitions
|
|
37
|
+
/**
|
|
38
|
+
* Cleanup and exit
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* Update operations panel with latest feed entries (Phase 3)
|
|
42
|
+
*
|
|
43
|
+
* Applies truncation to prevent overflow into adjacent panels
|
|
44
|
+
*/
|
|
45
|
+
function updateOperationsPanel() {
|
|
46
|
+
const operationsPanel = panels[3]; // OPERATIONS is 4th panel (index 3)
|
|
47
|
+
if (!operationsPanel)
|
|
48
|
+
return;
|
|
49
|
+
const contentLines = formatFeedEntries();
|
|
50
|
+
const paddingTop = '\n';
|
|
51
|
+
const paddingLeft = ' ';
|
|
52
|
+
// Calculate available space (account for border and padding)
|
|
53
|
+
const innerHeight = operationsPanel.height - 2; // Top and bottom border
|
|
54
|
+
const innerWidth = operationsPanel.width - 4; // Left/right border + padding
|
|
55
|
+
// Truncate to fit panel height
|
|
56
|
+
const displayLines = contentLines.slice(-innerHeight);
|
|
57
|
+
// Phase 3: Apply truncation to each line (prevents overflow)
|
|
58
|
+
const truncatedLines = displayLines.map(line => {
|
|
59
|
+
return truncateLine(line, innerWidth);
|
|
60
|
+
});
|
|
61
|
+
const content = truncatedLines
|
|
62
|
+
.map(line => paddingLeft + line)
|
|
63
|
+
.join('\n');
|
|
64
|
+
operationsPanel.setContent(paddingTop + content);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Update resources panel content (Phase 4)
|
|
68
|
+
*
|
|
69
|
+
* Updates text in-place without recreating widget (no flicker)
|
|
70
|
+
*/
|
|
71
|
+
function updateResourcesPanel() {
|
|
72
|
+
const resourcesPanel = panels[1]; // RESOURCES is 2nd panel (index 1)
|
|
73
|
+
if (!resourcesPanel || !currentUiState)
|
|
74
|
+
return;
|
|
75
|
+
const contentLines = renderResourcesPanel(currentUiState.resources);
|
|
76
|
+
const paddingTop = '\n';
|
|
77
|
+
const paddingLeft = ' ';
|
|
78
|
+
// Calculate available space (account for border and padding)
|
|
79
|
+
const innerHeight = resourcesPanel.height - 2; // Top and bottom border
|
|
80
|
+
const innerWidth = resourcesPanel.width - 4; // Left/right border + padding
|
|
81
|
+
// Truncate to fit panel height (max ~6 lines)
|
|
82
|
+
const displayLines = contentLines.slice(0, Math.min(contentLines.length, innerHeight));
|
|
83
|
+
// Truncate each line to fit width (Phase 4)
|
|
84
|
+
const truncatedLines = displayLines.map(line => {
|
|
85
|
+
return truncateLine(line, innerWidth);
|
|
86
|
+
});
|
|
87
|
+
// Pad to fill available height if needed
|
|
88
|
+
while (truncatedLines.length < innerHeight) {
|
|
89
|
+
truncatedLines.push('');
|
|
90
|
+
}
|
|
91
|
+
const content = truncatedLines
|
|
92
|
+
.map(line => paddingLeft + line)
|
|
93
|
+
.join('\n');
|
|
94
|
+
// Update content in-place (no widget recreation = no flicker)
|
|
95
|
+
resourcesPanel.setContent(paddingTop + content);
|
|
96
|
+
}
|
|
97
|
+
function cleanupAndExit(code = 0) {
|
|
98
|
+
if (isCleaningUp)
|
|
99
|
+
return;
|
|
100
|
+
isCleaningUp = true;
|
|
101
|
+
// Clear render interval
|
|
102
|
+
if (screen && screen.renderInterval) {
|
|
103
|
+
clearInterval(screen.renderInterval);
|
|
104
|
+
}
|
|
105
|
+
if (screen) {
|
|
106
|
+
try {
|
|
107
|
+
screen.destroy();
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
// Ignore destroy errors
|
|
111
|
+
}
|
|
112
|
+
screen = null;
|
|
113
|
+
}
|
|
114
|
+
// Restore terminal state
|
|
115
|
+
if (process.stdout.isTTY) {
|
|
116
|
+
process.stdout.write('\x1b[?25h'); // Show cursor
|
|
117
|
+
process.stdout.write('\x1b[?1049l'); // Exit alternate screen
|
|
118
|
+
}
|
|
119
|
+
process.exit(code);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Create a read-only panel
|
|
123
|
+
*/
|
|
124
|
+
function createPanel(screen, boxRect, title, getContent) {
|
|
125
|
+
const panel = blessedLib.box({
|
|
126
|
+
top: boxRect.top,
|
|
127
|
+
left: boxRect.left,
|
|
128
|
+
width: boxRect.width,
|
|
129
|
+
height: boxRect.height,
|
|
130
|
+
border: {
|
|
131
|
+
type: 'line',
|
|
132
|
+
},
|
|
133
|
+
tags: true,
|
|
134
|
+
content: '', // Will be updated if getContent is provided
|
|
135
|
+
style: {
|
|
136
|
+
border: {
|
|
137
|
+
fg: 'cyan',
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
// Make panel read-only and non-focusable
|
|
141
|
+
clickable: false,
|
|
142
|
+
keys: false,
|
|
143
|
+
mouse: false,
|
|
144
|
+
input: false,
|
|
145
|
+
});
|
|
146
|
+
// Set title in top border
|
|
147
|
+
panel.setLabel(` {cyan-fg}${title.toUpperCase()}{/}`);
|
|
148
|
+
// Store content getter for updates
|
|
149
|
+
if (getContent) {
|
|
150
|
+
panel.getContent = getContent;
|
|
151
|
+
}
|
|
152
|
+
return panel;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Truncate line to fit width (Phase 3)
|
|
156
|
+
*
|
|
157
|
+
* Rules:
|
|
158
|
+
* - If text.length <= width, return as-is
|
|
159
|
+
* - Else return text.slice(0, width - 1) + "…"
|
|
160
|
+
*/
|
|
161
|
+
function truncateLine(text, width) {
|
|
162
|
+
if (text.length <= width) {
|
|
163
|
+
return text;
|
|
164
|
+
}
|
|
165
|
+
return text.slice(0, Math.max(0, width - 1)) + '…';
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Format feed entries for display in OPERATIONS panel (Phase 3)
|
|
169
|
+
*/
|
|
170
|
+
const FEED_MAX = 12; // Show latest 12 events
|
|
171
|
+
function formatFeedEntries() {
|
|
172
|
+
const events = feedStore.getLast(FEED_MAX);
|
|
173
|
+
const lines = [];
|
|
174
|
+
if (events.length === 0) {
|
|
175
|
+
lines.push('No operations yet');
|
|
176
|
+
lines.push('Type "help" for commands');
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
for (const event of events) {
|
|
180
|
+
const time = formatTimestamp(event.ts);
|
|
181
|
+
const levelColor = event.level === 'ERROR' ? 'red' : event.level === 'WARN' ? 'yellow' : 'white';
|
|
182
|
+
const prefix = `${time} [{${levelColor}-fg}${event.tag}{/}] `;
|
|
183
|
+
const message = event.message;
|
|
184
|
+
// Note: Truncation will be applied based on panel width in updateOperationsPanel
|
|
185
|
+
const line = prefix + message;
|
|
186
|
+
lines.push(line);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return lines;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Start Phase 1 runtime
|
|
193
|
+
*/
|
|
194
|
+
export async function startPhase1Runtime() {
|
|
195
|
+
// Suppress console.log during TUI
|
|
196
|
+
const originalLog = console.log;
|
|
197
|
+
console.log = () => { };
|
|
198
|
+
try {
|
|
199
|
+
// Create screen
|
|
200
|
+
screen = blessedLib.screen({
|
|
201
|
+
smartCSR: true,
|
|
202
|
+
title: '4Runr Terminal UI V3 - Phase 1',
|
|
203
|
+
fullUnicode: true,
|
|
204
|
+
});
|
|
205
|
+
if (!screen) {
|
|
206
|
+
throw new Error('Failed to create screen');
|
|
207
|
+
}
|
|
208
|
+
// Handle exit keys
|
|
209
|
+
screen.key(['q', 'Q', 'C-c'], () => {
|
|
210
|
+
cleanupAndExit(0);
|
|
211
|
+
});
|
|
212
|
+
// Handle signals
|
|
213
|
+
process.on('SIGINT', () => cleanupAndExit(0));
|
|
214
|
+
process.on('SIGTERM', () => cleanupAndExit(0));
|
|
215
|
+
process.on('uncaughtException', (error) => {
|
|
216
|
+
console.log = originalLog;
|
|
217
|
+
console.error('Uncaught exception:', error);
|
|
218
|
+
cleanupAndExit(1);
|
|
219
|
+
});
|
|
220
|
+
// Compute layout
|
|
221
|
+
const width = screen.width;
|
|
222
|
+
const height = screen.height;
|
|
223
|
+
const layoutResult = computePhase1Layout(width, height);
|
|
224
|
+
if (!layoutResult.ok || !layoutResult.layout) {
|
|
225
|
+
// Terminal too small - show error
|
|
226
|
+
const errorBox = blessed.box({
|
|
227
|
+
top: Math.floor((height - 5) / 2),
|
|
228
|
+
left: Math.floor((width - 60) / 2),
|
|
229
|
+
width: 60,
|
|
230
|
+
height: 5,
|
|
231
|
+
border: {
|
|
232
|
+
type: 'line',
|
|
233
|
+
},
|
|
234
|
+
tags: true,
|
|
235
|
+
content: `\n ${layoutResult.errorMessage || 'Terminal too small'}\n\n Press q or Ctrl+C to exit`,
|
|
236
|
+
style: {
|
|
237
|
+
border: {
|
|
238
|
+
fg: 'red',
|
|
239
|
+
},
|
|
240
|
+
fg: 'red',
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
screen.append(errorBox);
|
|
244
|
+
screen.render();
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const layout = layoutResult.layout;
|
|
248
|
+
// Create all panels (read-only)
|
|
249
|
+
if (!screen)
|
|
250
|
+
throw new Error('Screen not initialized');
|
|
251
|
+
panels.push(createPanel(screen, layout.posture, 'POSTURE'));
|
|
252
|
+
// RESOURCES panel (Phase 4: real metrics)
|
|
253
|
+
const resourcesPanel = createPanel(screen, layout.resources, 'RESOURCES');
|
|
254
|
+
panels.push(resourcesPanel);
|
|
255
|
+
panels.push(createPanel(screen, layout.assets, 'ASSETS'));
|
|
256
|
+
// OPERATIONS panel with feed content (Phase 3: EventBus)
|
|
257
|
+
const operationsPanel = createPanel(screen, layout.operations, 'OPERATIONS', formatFeedEntries);
|
|
258
|
+
panels.push(operationsPanel);
|
|
259
|
+
panels.push(createPanel(screen, layout.network, 'NETWORK'));
|
|
260
|
+
panels.push(createPanel(screen, layout.capabilities, 'CAPABILITIES'));
|
|
261
|
+
// Create status strip (left side of bottom bar)
|
|
262
|
+
const statusWidth = Math.floor(layout.commandLine.width * 0.6); // 60% for status
|
|
263
|
+
statusStrip = blessedLib.box({
|
|
264
|
+
top: layout.commandLine.top,
|
|
265
|
+
left: layout.commandLine.left,
|
|
266
|
+
width: statusWidth,
|
|
267
|
+
height: layout.commandLine.height,
|
|
268
|
+
border: {
|
|
269
|
+
type: 'line',
|
|
270
|
+
},
|
|
271
|
+
tags: true,
|
|
272
|
+
content: ' MODE: OFFLINE | CONNECT: NO | POSTURE: UNKNOWN ',
|
|
273
|
+
style: {
|
|
274
|
+
border: {
|
|
275
|
+
fg: 'grey',
|
|
276
|
+
},
|
|
277
|
+
fg: 'grey',
|
|
278
|
+
},
|
|
279
|
+
clickable: false,
|
|
280
|
+
keys: false,
|
|
281
|
+
mouse: false,
|
|
282
|
+
input: false,
|
|
283
|
+
});
|
|
284
|
+
statusStrip.setLabel(' {grey-fg}STATUS{/}');
|
|
285
|
+
// Create command line (right side of bottom bar)
|
|
286
|
+
const commandWidth = layout.commandLine.width - statusWidth - 1; // Remaining width
|
|
287
|
+
commandLine = blessedLib.textbox({
|
|
288
|
+
top: layout.commandLine.top,
|
|
289
|
+
left: layout.commandLine.left + statusWidth + 1,
|
|
290
|
+
width: commandWidth,
|
|
291
|
+
height: layout.commandLine.height,
|
|
292
|
+
border: {
|
|
293
|
+
type: 'line',
|
|
294
|
+
},
|
|
295
|
+
tags: true,
|
|
296
|
+
content: '',
|
|
297
|
+
style: {
|
|
298
|
+
border: {
|
|
299
|
+
fg: 'cyan',
|
|
300
|
+
},
|
|
301
|
+
fg: 'white',
|
|
302
|
+
focus: {
|
|
303
|
+
border: {
|
|
304
|
+
fg: 'green',
|
|
305
|
+
},
|
|
306
|
+
fg: 'white',
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
input: true,
|
|
310
|
+
keys: true,
|
|
311
|
+
mouse: true,
|
|
312
|
+
inputOnFocus: true,
|
|
313
|
+
});
|
|
314
|
+
if (!commandLine)
|
|
315
|
+
throw new Error('Command line not initialized');
|
|
316
|
+
commandLine.setLabel(' {cyan-fg}COMMAND LINE{/}');
|
|
317
|
+
// Set initial prompt
|
|
318
|
+
commandLine.setValue('4runr> ');
|
|
319
|
+
// Command history (in-memory)
|
|
320
|
+
const commandHistory = [];
|
|
321
|
+
// Handle command submission (Phase 3: EventBus)
|
|
322
|
+
if (!commandLine)
|
|
323
|
+
throw new Error('Command line not initialized');
|
|
324
|
+
commandLine.on('submit', (value) => {
|
|
325
|
+
// Parse command
|
|
326
|
+
const parsed = parseCommand(value);
|
|
327
|
+
if (!parsed) {
|
|
328
|
+
// Empty command - do nothing, keep focus
|
|
329
|
+
commandLine?.focus();
|
|
330
|
+
screen?.render();
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
// Add command to history
|
|
334
|
+
commandHistory.push(value);
|
|
335
|
+
// Phase 3: Emit command event first
|
|
336
|
+
eventBus.emitTag('CMD', value.trim());
|
|
337
|
+
// Route command (handlers emit events through EventBus)
|
|
338
|
+
const result = routeCommand(parsed.cmd, parsed.args);
|
|
339
|
+
// Process result
|
|
340
|
+
if (result.exitApp) {
|
|
341
|
+
// Exit the application
|
|
342
|
+
cleanupAndExit(0);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
// Clear input and restore prompt after submission
|
|
346
|
+
currentCommandValue = '4runr> ';
|
|
347
|
+
commandLine?.setValue('4runr> ');
|
|
348
|
+
commandLine?.clearValue();
|
|
349
|
+
// Keep focus on command line
|
|
350
|
+
commandLine?.focus();
|
|
351
|
+
// Update operations panel and rerender
|
|
352
|
+
updateOperationsPanel();
|
|
353
|
+
screen?.render();
|
|
354
|
+
});
|
|
355
|
+
// Track command value changes
|
|
356
|
+
commandLine.on('keypress', () => {
|
|
357
|
+
// Update tracked value (approximate)
|
|
358
|
+
const value = commandLine.value || '';
|
|
359
|
+
if (value) {
|
|
360
|
+
currentCommandValue = value;
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
// Handle resize
|
|
364
|
+
const currentScreen = screen;
|
|
365
|
+
if (currentScreen) {
|
|
366
|
+
currentScreen.on('resize', () => {
|
|
367
|
+
if (!currentScreen)
|
|
368
|
+
return;
|
|
369
|
+
// Recompute layout on resize
|
|
370
|
+
const newWidth = currentScreen.width;
|
|
371
|
+
const newHeight = currentScreen.height;
|
|
372
|
+
const newLayoutResult = computePhase1Layout(newWidth, newHeight);
|
|
373
|
+
if (newLayoutResult.ok && newLayoutResult.layout) {
|
|
374
|
+
// Remove old widgets
|
|
375
|
+
panels.forEach(panel => currentScreen.remove(panel));
|
|
376
|
+
if (statusStrip)
|
|
377
|
+
currentScreen.remove(statusStrip);
|
|
378
|
+
if (commandLine)
|
|
379
|
+
currentScreen.remove(commandLine);
|
|
380
|
+
// Clear arrays
|
|
381
|
+
panels = [];
|
|
382
|
+
// Recreate with new layout
|
|
383
|
+
const newLayout = newLayoutResult.layout;
|
|
384
|
+
panels.push(createPanel(currentScreen, newLayout.posture, 'POSTURE'));
|
|
385
|
+
// RESOURCES panel (Phase 4: real metrics)
|
|
386
|
+
const newResourcesPanel = createPanel(currentScreen, newLayout.resources, 'RESOURCES');
|
|
387
|
+
panels.push(newResourcesPanel);
|
|
388
|
+
panels.push(createPanel(currentScreen, newLayout.assets, 'ASSETS'));
|
|
389
|
+
// OPERATIONS panel with feed content (Phase 3: EventBus)
|
|
390
|
+
const newOperationsPanel = createPanel(currentScreen, newLayout.operations, 'OPERATIONS', formatFeedEntries);
|
|
391
|
+
panels.push(newOperationsPanel);
|
|
392
|
+
panels.push(createPanel(currentScreen, newLayout.network, 'NETWORK'));
|
|
393
|
+
panels.push(createPanel(currentScreen, newLayout.capabilities, 'CAPABILITIES'));
|
|
394
|
+
// Recreate status strip
|
|
395
|
+
const newStatusWidth = Math.floor(newLayout.commandLine.width * 0.6);
|
|
396
|
+
statusStrip = blessedLib.box({
|
|
397
|
+
top: newLayout.commandLine.top,
|
|
398
|
+
left: newLayout.commandLine.left,
|
|
399
|
+
width: newStatusWidth,
|
|
400
|
+
height: newLayout.commandLine.height,
|
|
401
|
+
border: { type: 'line' },
|
|
402
|
+
tags: true,
|
|
403
|
+
content: ' MODE: OFFLINE | CONNECT: NO | POSTURE: UNKNOWN ',
|
|
404
|
+
style: { border: { fg: 'grey' }, fg: 'grey' },
|
|
405
|
+
clickable: false,
|
|
406
|
+
keys: false,
|
|
407
|
+
mouse: false,
|
|
408
|
+
input: false,
|
|
409
|
+
});
|
|
410
|
+
if (!statusStrip)
|
|
411
|
+
throw new Error('Status strip not initialized');
|
|
412
|
+
statusStrip.setLabel(' {grey-fg}STATUS{/}');
|
|
413
|
+
// Recreate command line
|
|
414
|
+
const newCommandWidth = newLayout.commandLine.width - newStatusWidth - 1;
|
|
415
|
+
commandLine = blessedLib.textbox({
|
|
416
|
+
top: newLayout.commandLine.top,
|
|
417
|
+
left: newLayout.commandLine.left + newStatusWidth + 1,
|
|
418
|
+
width: newCommandWidth,
|
|
419
|
+
height: newLayout.commandLine.height,
|
|
420
|
+
border: { type: 'line' },
|
|
421
|
+
tags: true,
|
|
422
|
+
content: '',
|
|
423
|
+
style: {
|
|
424
|
+
border: { fg: 'cyan' },
|
|
425
|
+
fg: 'white',
|
|
426
|
+
focus: { border: { fg: 'green' }, fg: 'white' },
|
|
427
|
+
},
|
|
428
|
+
input: true,
|
|
429
|
+
keys: true,
|
|
430
|
+
mouse: true,
|
|
431
|
+
inputOnFocus: true,
|
|
432
|
+
});
|
|
433
|
+
if (!commandLine)
|
|
434
|
+
throw new Error('Command line not initialized');
|
|
435
|
+
commandLine.setLabel(' {cyan-fg}COMMAND LINE{/}');
|
|
436
|
+
commandLine.setValue(currentCommandValue);
|
|
437
|
+
// Re-attach event handlers (Phase 3: EventBus)
|
|
438
|
+
commandLine.on('submit', (value) => {
|
|
439
|
+
// Parse command
|
|
440
|
+
const parsed = parseCommand(value);
|
|
441
|
+
if (!parsed) {
|
|
442
|
+
// Empty command - do nothing, keep focus
|
|
443
|
+
commandLine?.focus();
|
|
444
|
+
currentScreen?.render();
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
// Add command to history
|
|
448
|
+
commandHistory.push(value);
|
|
449
|
+
// Phase 3: Emit command event first
|
|
450
|
+
eventBus.emitTag('CMD', value.trim());
|
|
451
|
+
// Route command (handlers emit events through EventBus)
|
|
452
|
+
const result = routeCommand(parsed.cmd, parsed.args);
|
|
453
|
+
// Process result
|
|
454
|
+
if (result.exitApp) {
|
|
455
|
+
// Exit the application
|
|
456
|
+
cleanupAndExit(0);
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
// Clear input and restore prompt after submission
|
|
460
|
+
currentCommandValue = '4runr> ';
|
|
461
|
+
commandLine?.setValue('4runr> ');
|
|
462
|
+
commandLine?.clearValue();
|
|
463
|
+
// Keep focus on command line
|
|
464
|
+
commandLine?.focus();
|
|
465
|
+
// Update operations panel and rerender
|
|
466
|
+
updateOperationsPanel();
|
|
467
|
+
updateResourcesPanel();
|
|
468
|
+
currentScreen?.render();
|
|
469
|
+
});
|
|
470
|
+
commandLine.on('keypress', () => {
|
|
471
|
+
const value = commandLine.value || '';
|
|
472
|
+
if (value) {
|
|
473
|
+
currentCommandValue = value;
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
commandLine.key('tab', () => {
|
|
477
|
+
commandLine?.focus();
|
|
478
|
+
screen?.render();
|
|
479
|
+
});
|
|
480
|
+
// Append all widgets
|
|
481
|
+
panels.forEach(panel => currentScreen.append(panel));
|
|
482
|
+
if (statusStrip)
|
|
483
|
+
currentScreen.append(statusStrip);
|
|
484
|
+
if (commandLine) {
|
|
485
|
+
currentScreen.append(commandLine);
|
|
486
|
+
// Force focus back to command line
|
|
487
|
+
commandLine.focus();
|
|
488
|
+
currentScreen.focused = commandLine;
|
|
489
|
+
}
|
|
490
|
+
// Update panels with current state after resize
|
|
491
|
+
updateOperationsPanel();
|
|
492
|
+
updateResourcesPanel();
|
|
493
|
+
}
|
|
494
|
+
currentScreen.render();
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
// Prevent Tab from moving focus to panels
|
|
498
|
+
if (commandLine) {
|
|
499
|
+
commandLine.key('tab', () => {
|
|
500
|
+
// Tab does nothing - stay in command line
|
|
501
|
+
commandLine?.focus();
|
|
502
|
+
screen?.render();
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
// Append all widgets
|
|
506
|
+
panels.forEach(panel => screen?.append(panel));
|
|
507
|
+
if (!screen)
|
|
508
|
+
throw new Error('Screen not initialized');
|
|
509
|
+
if (statusStrip)
|
|
510
|
+
screen.append(statusStrip);
|
|
511
|
+
if (commandLine)
|
|
512
|
+
screen.append(commandLine);
|
|
513
|
+
// CRITICAL: Force focus to command line on startup
|
|
514
|
+
if (commandLine) {
|
|
515
|
+
commandLine.focus();
|
|
516
|
+
screen.focused = commandLine;
|
|
517
|
+
}
|
|
518
|
+
// Prevent focus from entering panels
|
|
519
|
+
// Set screen to only allow focus on command line
|
|
520
|
+
const focusScreen = screen;
|
|
521
|
+
if (focusScreen) {
|
|
522
|
+
focusScreen.on('focus', (widget) => {
|
|
523
|
+
// If focus tries to go to a panel, redirect to command line
|
|
524
|
+
if (widget && typeof widget !== 'string' && panels.includes(widget)) {
|
|
525
|
+
if (commandLine && focusScreen) {
|
|
526
|
+
commandLine.focus();
|
|
527
|
+
focusScreen.focused = commandLine;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
// Update operations panel with feed content
|
|
533
|
+
updateOperationsPanel();
|
|
534
|
+
// Phase 4: Initial UiState build
|
|
535
|
+
currentUiState = await buildUiState();
|
|
536
|
+
lastResourcesAvailable = isAvailable(currentUiState.resources);
|
|
537
|
+
updateResourcesPanel();
|
|
538
|
+
// Initial render
|
|
539
|
+
screen.render();
|
|
540
|
+
// Render loop to update operations feed and resources (every 1500ms)
|
|
541
|
+
const renderInterval = setInterval(async () => {
|
|
542
|
+
// Update operations feed
|
|
543
|
+
updateOperationsPanel();
|
|
544
|
+
// Phase 4: Update resources panel
|
|
545
|
+
try {
|
|
546
|
+
const newState = await buildUiState();
|
|
547
|
+
// Check for state transition (AVAILABLE → UNAVAILABLE)
|
|
548
|
+
const wasAvailable = lastResourcesAvailable;
|
|
549
|
+
const isNowAvailable = isAvailable(newState.resources);
|
|
550
|
+
if (wasAvailable && !isNowAvailable && isUnavailable(newState.resources)) {
|
|
551
|
+
// Transition to UNAVAILABLE - emit event
|
|
552
|
+
eventBus.emitTag('SYS', `RESOURCES UNAVAILABLE: ${newState.resources.reason || 'Unknown reason'}`, 'WARN');
|
|
553
|
+
}
|
|
554
|
+
lastResourcesAvailable = isNowAvailable;
|
|
555
|
+
currentUiState = newState;
|
|
556
|
+
updateResourcesPanel();
|
|
557
|
+
}
|
|
558
|
+
catch (error) {
|
|
559
|
+
// If state building fails, don't crash - just skip this update
|
|
560
|
+
// Error is already logged if DEBUG_NO_TUI=1
|
|
561
|
+
}
|
|
562
|
+
screen?.render();
|
|
563
|
+
}, 1500);
|
|
564
|
+
// Store interval for cleanup
|
|
565
|
+
screen.renderInterval = renderInterval;
|
|
566
|
+
// Restore console.log
|
|
567
|
+
console.log = originalLog;
|
|
568
|
+
}
|
|
569
|
+
catch (error) {
|
|
570
|
+
console.log = originalLog;
|
|
571
|
+
throw error;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
//# sourceMappingURL=phase1Runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase1Runtime.js","sourceRoot":"","sources":["../../../../src/ui/v3/ui/phase1Runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Panel Primitive
|
|
3
|
+
*
|
|
4
|
+
* THE ONLY WAY TO DRAW PANELS
|
|
5
|
+
*
|
|
6
|
+
* Responsibilities:
|
|
7
|
+
* - Draw a bordered box at given position
|
|
8
|
+
* - Render title in top border
|
|
9
|
+
* - Render content with padding
|
|
10
|
+
* - Enforce line budget (truncate safely)
|
|
11
|
+
* - Enforce line width budget (clamp to innerWidth)
|
|
12
|
+
*/
|
|
13
|
+
import type { Widgets } from 'neo-blessed';
|
|
14
|
+
import { theme } from '../theme.js';
|
|
15
|
+
export interface BoxRect {
|
|
16
|
+
top: number;
|
|
17
|
+
left: number;
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
}
|
|
21
|
+
export interface PanelOptions {
|
|
22
|
+
screen: Widgets.Screen;
|
|
23
|
+
boxRect: BoxRect;
|
|
24
|
+
title: string;
|
|
25
|
+
lines: string[];
|
|
26
|
+
borderColor?: keyof typeof theme.colors;
|
|
27
|
+
severity?: 'info' | 'warn' | 'error';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create and render a panel
|
|
31
|
+
*
|
|
32
|
+
* Rules:
|
|
33
|
+
* - Never crashes if content is too long (truncates)
|
|
34
|
+
* - Enforces line budget
|
|
35
|
+
* - Enforces line width budget
|
|
36
|
+
* - No wrapping (truncation only)
|
|
37
|
+
*/
|
|
38
|
+
export declare function createPanel(options: PanelOptions): Widgets.Box;
|
|
39
|
+
//# sourceMappingURL=Panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../../../../src/ui/v3/ui/primitives/Panel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGpC,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,OAAO,KAAK,CAAC,MAAM,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAwE9D"}
|