4runr-os 2.1.0 → 2.1.2

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.
Files changed (44) hide show
  1. package/dist/tui_mk1/core/eventBus.d.ts +28 -0
  2. package/dist/tui_mk1/core/eventBus.d.ts.map +1 -0
  3. package/dist/tui_mk1/core/eventBus.js +52 -0
  4. package/dist/tui_mk1/core/eventBus.js.map +1 -0
  5. package/dist/tui_mk1/core/feedStore.d.ts +31 -0
  6. package/dist/tui_mk1/core/feedStore.d.ts.map +1 -0
  7. package/dist/tui_mk1/core/feedStore.js +51 -0
  8. package/dist/tui_mk1/core/feedStore.js.map +1 -0
  9. package/dist/tui_mk1/kernel.d.ts.map +1 -1
  10. package/dist/tui_mk1/kernel.js +2 -0
  11. package/dist/tui_mk1/kernel.js.map +1 -1
  12. package/dist/tui_mk1/layout/layoutEngine.d.ts +28 -0
  13. package/dist/tui_mk1/layout/layoutEngine.d.ts.map +1 -0
  14. package/dist/tui_mk1/layout/layoutEngine.js +258 -0
  15. package/dist/tui_mk1/layout/layoutEngine.js.map +1 -0
  16. package/dist/tui_mk1/mk1App.d.ts +18 -11
  17. package/dist/tui_mk1/mk1App.d.ts.map +1 -1
  18. package/dist/tui_mk1/mk1App.js +165 -133
  19. package/dist/tui_mk1/mk1App.js.map +1 -1
  20. package/dist/tui_mk1/ui/debugGutter.d.ts +7 -0
  21. package/dist/tui_mk1/ui/debugGutter.d.ts.map +1 -0
  22. package/dist/tui_mk1/ui/debugGutter.js +60 -0
  23. package/dist/tui_mk1/ui/debugGutter.js.map +1 -0
  24. package/dist/tui_mk1/ui/panels/createSection.d.ts +18 -0
  25. package/dist/tui_mk1/ui/panels/createSection.d.ts.map +1 -0
  26. package/dist/tui_mk1/ui/panels/createSection.js +42 -0
  27. package/dist/tui_mk1/ui/panels/createSection.js.map +1 -0
  28. package/dist/tui_mk1/ui/panels.d.ts +23 -0
  29. package/dist/tui_mk1/ui/panels.d.ts.map +1 -0
  30. package/dist/tui_mk1/ui/panels.js +108 -0
  31. package/dist/tui_mk1/ui/panels.js.map +1 -0
  32. package/dist/tui_mk1/ui/render/sectionRenderer.d.ts +21 -0
  33. package/dist/tui_mk1/ui/render/sectionRenderer.d.ts.map +1 -0
  34. package/dist/tui_mk1/ui/render/sectionRenderer.js +32 -0
  35. package/dist/tui_mk1/ui/render/sectionRenderer.js.map +1 -0
  36. package/dist/tui_mk1/ui/widgetManager.d.ts +58 -0
  37. package/dist/tui_mk1/ui/widgetManager.d.ts.map +1 -0
  38. package/dist/tui_mk1/ui/widgetManager.js +197 -0
  39. package/dist/tui_mk1/ui/widgetManager.js.map +1 -0
  40. package/dist/tui_mk1/viewport/safeViewport.d.ts +19 -0
  41. package/dist/tui_mk1/viewport/safeViewport.d.ts.map +1 -0
  42. package/dist/tui_mk1/viewport/safeViewport.js +39 -0
  43. package/dist/tui_mk1/viewport/safeViewport.js.map +1 -0
  44. package/package.json +2 -2
@@ -0,0 +1,108 @@
1
+ /**
2
+ * MK1 Panel Components - 4Runr feel (placeholder content)
3
+ */
4
+ import blessed from 'neo-blessed';
5
+ /**
6
+ * Create panel with consistent 4Runr style
7
+ */
8
+ export function createPanel(name, rect, content) {
9
+ return blessed.box({
10
+ left: rect.left,
11
+ top: rect.top,
12
+ width: rect.width,
13
+ height: rect.height,
14
+ border: {
15
+ type: 'line',
16
+ },
17
+ style: {
18
+ border: {
19
+ fg: 'cyan',
20
+ },
21
+ fg: 'white',
22
+ },
23
+ label: ` ${name} `,
24
+ tags: true,
25
+ content: content || '',
26
+ scrollable: false, // Disable scrolling - prevent scrollbars
27
+ alwaysScroll: false,
28
+ keys: false,
29
+ mouse: false,
30
+ });
31
+ }
32
+ /**
33
+ * Create operations panel - just section title, no borders
34
+ */
35
+ export function createOperationsPanel(rect, content) {
36
+ const width = rect.width;
37
+ const height = rect.height;
38
+ // Truncate content to fit (reserve 1 line for title)
39
+ const maxLines = Math.max(1, height - 1);
40
+ const lines = content.split('\n');
41
+ const truncatedLines = lines.slice(-maxLines);
42
+ // Just section title, no borders
43
+ const title = 'OPERATIONS';
44
+ const displayContent = title + '\n' + truncatedLines.join('\n');
45
+ return blessed.box({
46
+ left: rect.left,
47
+ top: rect.top,
48
+ width: rect.width,
49
+ height: rect.height,
50
+ content: displayContent,
51
+ style: {
52
+ fg: 'white',
53
+ },
54
+ tags: true,
55
+ scrollable: false,
56
+ alwaysScroll: false,
57
+ wrap: false,
58
+ });
59
+ }
60
+ /**
61
+ * Create status panel
62
+ */
63
+ export function createStatusPanel(rect, content) {
64
+ return blessed.box({
65
+ left: rect.left,
66
+ top: rect.top,
67
+ width: rect.width,
68
+ height: rect.height,
69
+ content,
70
+ style: {
71
+ fg: 'yellow',
72
+ },
73
+ tags: true,
74
+ });
75
+ }
76
+ /**
77
+ * Create command line panel
78
+ */
79
+ export function createCommandLinePanel(rect, prompt) {
80
+ return blessed.box({
81
+ left: rect.left,
82
+ top: rect.top,
83
+ width: rect.width,
84
+ height: rect.height,
85
+ content: prompt,
86
+ style: {
87
+ fg: 'green',
88
+ },
89
+ tags: true,
90
+ });
91
+ }
92
+ /**
93
+ * Create watermark panel
94
+ */
95
+ export function createWatermarkPanel(rect) {
96
+ return blessed.box({
97
+ left: rect.left,
98
+ top: rect.top,
99
+ width: rect.width,
100
+ height: rect.height,
101
+ content: '4RUNR TUI MK1',
102
+ style: {
103
+ fg: 'blue',
104
+ },
105
+ tags: true,
106
+ });
107
+ }
108
+ //# sourceMappingURL=panels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panels.js","sourceRoot":"","sources":["../../../src/tui_mk1/ui/panels.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * MK1 Section Renderer - Text layout inside rects
3
+ *
4
+ * Responsibilities:
5
+ * - Render optional title line
6
+ * - Clip content to available width/height
7
+ * - No overflow (hard clip)
8
+ * - Always respect padding
9
+ */
10
+ import type { Rect } from '../../layout/layoutEngine.js';
11
+ export interface RenderOptions {
12
+ title?: string;
13
+ padX?: number;
14
+ padY?: number;
15
+ maxLines?: number;
16
+ }
17
+ /**
18
+ * Render section content with title and padding
19
+ */
20
+ export declare function renderSectionContent(rect: Rect, content: string, options?: RenderOptions): string;
21
+ //# sourceMappingURL=sectionRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sectionRenderer.d.ts","sourceRoot":"","sources":["../../../../src/tui_mk1/ui/render/sectionRenderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,aAAkB,GAC1B,MAAM,CAiCR"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Render section content with title and padding
3
+ */
4
+ export function renderSectionContent(rect, content, options = {}) {
5
+ const padX = options.padX ?? 1;
6
+ const padY = options.padY ?? 0;
7
+ const maxLines = options.maxLines ?? (rect.height - padY - (options.title ? 1 : 0));
8
+ const usableWidth = rect.width - (padX * 2);
9
+ const lines = [];
10
+ // Add title if provided (with padding)
11
+ if (options.title) {
12
+ const titleLine = ' '.repeat(padX) + options.title;
13
+ lines.push(titleLine);
14
+ }
15
+ // Process content lines
16
+ const contentLines = content.split('\n');
17
+ const truncatedLines = contentLines.slice(-maxLines);
18
+ for (const line of truncatedLines) {
19
+ // Clip line to usable width
20
+ const clipped = line.substring(0, usableWidth);
21
+ // Add padding
22
+ const padded = ' '.repeat(padX) + clipped;
23
+ lines.push(padded);
24
+ }
25
+ // Fill remaining height with empty lines (with padding)
26
+ while (lines.length < rect.height) {
27
+ lines.push(' '.repeat(padX));
28
+ }
29
+ // Clip to exact height
30
+ return lines.slice(0, rect.height).join('\n');
31
+ }
32
+ //# sourceMappingURL=sectionRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sectionRenderer.js","sourceRoot":"","sources":["../../../../src/tui_mk1/ui/render/sectionRenderer.ts"],"names":[],"mappings":"AAkBA;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAU,EACV,OAAe,EACf,UAAyB,EAAE;IAE3B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEpF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,uCAAuC;IACvC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC;QACnD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;IAED,wBAAwB;IACxB,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC;IAErD,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,4BAA4B;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QAC/C,cAAc;QACd,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;IAED,wDAAwD;IACxD,OAAO,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED,uBAAuB;IACvB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * MK1 Widget Manager - Single owner of blessed widgets
3
+ *
4
+ * Rules:
5
+ * - No widget reuse across rebuilds unless done through this manager
6
+ * - Create all panels once per render frame
7
+ * - Destroy widgets cleanly on rebuild
8
+ * - Only place allowed to instantiate blessed widgets
9
+ */
10
+ import type { Widgets } from 'neo-blessed';
11
+ import type { Layout } from '../layout/layoutEngine.js';
12
+ export declare class WidgetManager {
13
+ private widgets;
14
+ private screen;
15
+ private commandValue;
16
+ private currentLayout;
17
+ /**
18
+ * Build all widgets from layout
19
+ */
20
+ build(screen: Widgets.Screen, layout: Layout): void;
21
+ /**
22
+ * Update operations feed content
23
+ */
24
+ updateOperationsFeed(): void;
25
+ /**
26
+ * Apply layout to existing widgets (update positions/sizes)
27
+ */
28
+ applyLayout(layout: Layout): void;
29
+ /**
30
+ * Get widget by name
31
+ */
32
+ getWidget(name: string): Widgets.Box | undefined;
33
+ /**
34
+ * Set command input value
35
+ */
36
+ setCommandValue(value: string): void;
37
+ /**
38
+ * Get command input value
39
+ */
40
+ getCommandValue(): string;
41
+ /**
42
+ * Render all widgets
43
+ */
44
+ render(): void;
45
+ /**
46
+ * Destroy all widgets
47
+ */
48
+ destroyAll(): void;
49
+ /**
50
+ * Format operations feed content
51
+ */
52
+ private formatOperationsFeed;
53
+ /**
54
+ * Get placeholder content for panel
55
+ */
56
+ private getPlaceholderContent;
57
+ }
58
+ //# sourceMappingURL=widgetManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widgetManager.d.ts","sourceRoot":"","sources":["../../../src/tui_mk1/ui/widgetManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAOxD,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,aAAa,CAAuB;IAE5C;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IA0DnD;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAa5B;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAmCjC;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,SAAS;IAIhD;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQpC;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;OAEG;IACH,MAAM,IAAI,IAAI;IAMd;;OAEG;IACH,UAAU,IAAI,IAAI;IAWlB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAgB5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAW9B"}
@@ -0,0 +1,197 @@
1
+ import { createSection } from './panels/createSection.js';
2
+ import { renderSectionContent } from './render/sectionRenderer.js';
3
+ import { createStatusPanel, createCommandLinePanel, createWatermarkPanel } from './panels.js';
4
+ import { feedStore } from '../core/feedStore.js';
5
+ import { logger } from '../logger.js';
6
+ export class WidgetManager {
7
+ widgets = new Map();
8
+ screen = null;
9
+ commandValue = '';
10
+ currentLayout = null;
11
+ /**
12
+ * Build all widgets from layout
13
+ */
14
+ build(screen, layout) {
15
+ this.screen = screen;
16
+ this.currentLayout = layout;
17
+ // Destroy old widgets
18
+ this.destroyAll();
19
+ // Create all panels from layout (borderless sections)
20
+ for (const [name, rect] of Object.entries(layout.rects)) {
21
+ let widget;
22
+ if (name === 'STATUS') {
23
+ const statusText = `cols=${layout.cols} rows=${layout.rows} mode=${layout.mode}`;
24
+ widget = createStatusPanel(rect, statusText);
25
+ }
26
+ else if (name === 'OPERATIONS') {
27
+ // Section with border and title
28
+ const feedContent = this.formatOperationsFeed();
29
+ widget = createSection(screen, rect, {
30
+ key: 'operations',
31
+ title: 'OPERATIONS',
32
+ padX: 1,
33
+ padY: 0,
34
+ style: { fg: 'white' },
35
+ });
36
+ // Content without title (title is in border label)
37
+ const renderedContent = renderSectionContent(rect, feedContent, {
38
+ padX: 1,
39
+ });
40
+ widget.content = renderedContent;
41
+ }
42
+ else if (name === 'COMMAND_LINE') {
43
+ const prompt = '4runr> ' + this.commandValue;
44
+ widget = createCommandLinePanel(rect, prompt);
45
+ }
46
+ else if (name === 'WATERMARK') {
47
+ widget = createWatermarkPanel(rect);
48
+ }
49
+ else {
50
+ // Sections with borders for other panels (POSTURE, RESOURCES, etc.)
51
+ const placeholder = this.getPlaceholderContent(name);
52
+ widget = createSection(screen, rect, {
53
+ key: name.toLowerCase(),
54
+ title: name,
55
+ padX: 1,
56
+ padY: 0,
57
+ style: { fg: 'white' },
58
+ });
59
+ // Content without title (title is in border label)
60
+ const renderedContent = renderSectionContent(rect, placeholder, {
61
+ padX: 1,
62
+ });
63
+ widget.content = renderedContent;
64
+ }
65
+ this.widgets.set(name, widget);
66
+ screen.append(widget);
67
+ }
68
+ logger.debug(`WidgetManager: Built ${this.widgets.size} widgets (${layout.mode} mode)`);
69
+ }
70
+ /**
71
+ * Update operations feed content
72
+ */
73
+ updateOperationsFeed() {
74
+ const widget = this.widgets.get('OPERATIONS');
75
+ if (widget && this.currentLayout) {
76
+ const feedContent = this.formatOperationsFeed();
77
+ const rect = this.currentLayout.rects['OPERATIONS'];
78
+ // Content without title (title is in border label)
79
+ const renderedContent = renderSectionContent(rect, feedContent, {
80
+ padX: 1,
81
+ });
82
+ widget.content = renderedContent;
83
+ }
84
+ }
85
+ /**
86
+ * Apply layout to existing widgets (update positions/sizes)
87
+ */
88
+ applyLayout(layout) {
89
+ for (const [name, rect] of Object.entries(layout.rects)) {
90
+ const widget = this.widgets.get(name);
91
+ if (widget) {
92
+ widget.left = rect.left;
93
+ widget.top = rect.top;
94
+ widget.width = rect.width;
95
+ widget.height = rect.height;
96
+ // Update content for special widgets
97
+ if (name === 'STATUS') {
98
+ const statusText = `cols=${layout.cols} rows=${layout.rows} mode=${layout.mode}`;
99
+ widget.content = statusText;
100
+ }
101
+ else if (name === 'OPERATIONS') {
102
+ const feedContent = this.formatOperationsFeed();
103
+ // Content without title (title is in border label)
104
+ const renderedContent = renderSectionContent(rect, feedContent, {
105
+ padX: 1,
106
+ });
107
+ widget.content = renderedContent;
108
+ }
109
+ else if (name === 'COMMAND_LINE') {
110
+ const prompt = '4runr> ' + this.commandValue;
111
+ widget.content = prompt;
112
+ }
113
+ else if (name !== 'WATERMARK' && name !== 'STATUS') {
114
+ // Update other sections (title is in border label)
115
+ const placeholder = this.getPlaceholderContent(name);
116
+ const renderedContent = renderSectionContent(rect, placeholder, {
117
+ padX: 1,
118
+ });
119
+ widget.content = renderedContent;
120
+ }
121
+ }
122
+ }
123
+ }
124
+ /**
125
+ * Get widget by name
126
+ */
127
+ getWidget(name) {
128
+ return this.widgets.get(name);
129
+ }
130
+ /**
131
+ * Set command input value
132
+ */
133
+ setCommandValue(value) {
134
+ this.commandValue = value;
135
+ const widget = this.getWidget('COMMAND_LINE');
136
+ if (widget) {
137
+ widget.content = '4runr> ' + value;
138
+ }
139
+ }
140
+ /**
141
+ * Get command input value
142
+ */
143
+ getCommandValue() {
144
+ return this.commandValue;
145
+ }
146
+ /**
147
+ * Render all widgets
148
+ */
149
+ render() {
150
+ if (this.screen) {
151
+ this.screen.render();
152
+ }
153
+ }
154
+ /**
155
+ * Destroy all widgets
156
+ */
157
+ destroyAll() {
158
+ for (const widget of this.widgets.values()) {
159
+ try {
160
+ widget.destroy();
161
+ }
162
+ catch {
163
+ // Ignore destroy errors
164
+ }
165
+ }
166
+ this.widgets.clear();
167
+ }
168
+ /**
169
+ * Format operations feed content
170
+ */
171
+ formatOperationsFeed() {
172
+ const events = feedStore.getRecent(15);
173
+ if (events.length === 0) {
174
+ return 'Waiting for events...';
175
+ }
176
+ // Format events as lines (limit to panel height)
177
+ const lines = events.map((event) => {
178
+ const time = new Date(event.timestamp).toLocaleTimeString();
179
+ return `[${time}] [${event.tag}] ${event.message}`;
180
+ });
181
+ return lines.join('\n');
182
+ }
183
+ /**
184
+ * Get placeholder content for panel
185
+ */
186
+ getPlaceholderContent(name) {
187
+ const placeholders = {
188
+ POSTURE: 'Posture status\n\nHealthy',
189
+ RESOURCES: 'System resources\n\nCPU: --\nMemory: --',
190
+ ASSETS: 'Agent assets\n\nCount: 0',
191
+ NETWORK: 'Network status\n\nConnected',
192
+ CAPABILITIES: 'Capabilities\n\nList: --',
193
+ };
194
+ return placeholders[name] || `${name} panel`;
195
+ }
196
+ }
197
+ //# sourceMappingURL=widgetManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widgetManager.js","sourceRoot":"","sources":["../../../src/tui_mk1/ui/widgetManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * MK1 Safe Viewport Calculator
3
+ *
4
+ * Computes safeCols and safeRows that all layout uses.
5
+ * Subtracts configurable margins to prevent overflow in problematic terminals.
6
+ */
7
+ export interface SafeViewport {
8
+ safeCols: number;
9
+ safeRows: number;
10
+ rightMargin: number;
11
+ bottomMargin: number;
12
+ screenCols: number;
13
+ screenRows: number;
14
+ }
15
+ /**
16
+ * Get safe viewport dimensions
17
+ */
18
+ export declare function getSafeViewport(screenCols: number, screenRows: number): SafeViewport;
19
+ //# sourceMappingURL=safeViewport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safeViewport.d.ts","sourceRoot":"","sources":["../../../src/tui_mk1/viewport/safeViewport.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,CA+BpF"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * MK1 Safe Viewport Calculator
3
+ *
4
+ * Computes safeCols and safeRows that all layout uses.
5
+ * Subtracts configurable margins to prevent overflow in problematic terminals.
6
+ */
7
+ /**
8
+ * Get safe viewport dimensions
9
+ */
10
+ export function getSafeViewport(screenCols, screenRows) {
11
+ // Read environment variables
12
+ const safeRightEnv = process.env.TUI_SAFE_RIGHT;
13
+ const safeBottomEnv = process.env.TUI_SAFE_BOTTOM;
14
+ const safePreset = process.env.TUI_SAFE_PRESET;
15
+ let rightMargin = 0;
16
+ let bottomMargin = 0;
17
+ // Check for preset
18
+ if (safePreset === 'aws') {
19
+ rightMargin = 3;
20
+ bottomMargin = 2;
21
+ }
22
+ else {
23
+ // Parse env vars (default to 0)
24
+ rightMargin = safeRightEnv ? parseInt(safeRightEnv, 10) || 0 : 0;
25
+ bottomMargin = safeBottomEnv ? parseInt(safeBottomEnv, 10) || 0 : 0;
26
+ }
27
+ // Clamp to minimums
28
+ const safeCols = Math.max(40, screenCols - rightMargin);
29
+ const safeRows = Math.max(20, screenRows - bottomMargin);
30
+ return {
31
+ safeCols,
32
+ safeRows,
33
+ rightMargin,
34
+ bottomMargin,
35
+ screenCols,
36
+ screenRows,
37
+ };
38
+ }
39
+ //# sourceMappingURL=safeViewport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safeViewport.js","sourceRoot":"","sources":["../../../src/tui_mk1/viewport/safeViewport.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB,EAAE,UAAkB;IACpE,6BAA6B;IAC7B,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAChD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAClD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAE/C,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,mBAAmB;IACnB,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;QACzB,WAAW,GAAG,CAAC,CAAC;QAChB,YAAY,GAAG,CAAC,CAAC;IACnB,CAAC;SAAM,CAAC;QACN,gCAAgC;QAChC,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,oBAAoB;IACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,GAAG,WAAW,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC;IAEzD,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,WAAW;QACX,YAAY;QACZ,UAAU;QACV,UAAU;KACX,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "4runr-os",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "type": "module",
5
5
  "description": "4Runr AI Agent OS - Interactive terminal for managing AI agents",
6
6
  "main": "dist/index.js",
@@ -42,6 +42,6 @@
42
42
  "scripts": {
43
43
  "build": "tsc",
44
44
  "dev": "tsc --watch",
45
- "tui:mk1": "cross-env TUI_MK1=1 TUI_DEBUG=1 TERM=xterm-256color node dist/index.js"
45
+ "tui:mk1": "cross-env TUI_MK1=1 TUI_DEBUG=1 TUI_ALLOW_STDOUT=1 TERM=xterm-256color node dist/index.js"
46
46
  }
47
47
  }