tuimon 0.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/CLAUDE.md +80 -0
- package/README.md +153 -0
- package/client/tuimon-client.js +44 -0
- package/dist/browser.d.ts +7 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +57 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +87 -0
- package/dist/cli.js.map +1 -0
- package/dist/detect.d.ts +8 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +141 -0
- package/dist/detect.js.map +1 -0
- package/dist/encoder.d.ts +4 -0
- package/dist/encoder.d.ts.map +1 -0
- package/dist/encoder.js +115 -0
- package/dist/encoder.js.map +1 -0
- package/dist/fkeybar.d.ts +5 -0
- package/dist/fkeybar.d.ts.map +1 -0
- package/dist/fkeybar.js +89 -0
- package/dist/fkeybar.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +166 -0
- package/dist/index.js.map +1 -0
- package/dist/keyhandler.d.ts +5 -0
- package/dist/keyhandler.d.ts.map +1 -0
- package/dist/keyhandler.js +20 -0
- package/dist/keyhandler.js.map +1 -0
- package/dist/router.d.ts +10 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +154 -0
- package/dist/router.js.map +1 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +142 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +108 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -0
- package/templates/internal/confirm-quit.html +94 -0
- package/templates/starter/pages/cpu-detail.html +176 -0
- package/templates/starter/pages/memory-detail.html +166 -0
- package/templates/starter/pages/overview.html +186 -0
- package/templates/starter/tuimon.config.ts +87 -0
- package/tsconfig.json +23 -0
package/dist/encoder.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import sharp from 'sharp';
|
|
2
|
+
const CHUNK_SIZE = 4096;
|
|
3
|
+
const MAX_PALETTE_COLORS = 256;
|
|
4
|
+
export async function encodeAndRender(buffer, opts) {
|
|
5
|
+
if (opts.protocol === 'kitty') {
|
|
6
|
+
renderKitty(buffer);
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
await renderSixel(buffer);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function renderKitty(buffer) {
|
|
13
|
+
process.stdout.write('\x1b[H');
|
|
14
|
+
const b64 = buffer.toString('base64');
|
|
15
|
+
const chunks = [];
|
|
16
|
+
for (let i = 0; i < b64.length; i += CHUNK_SIZE) {
|
|
17
|
+
chunks.push(b64.slice(i, i + CHUNK_SIZE));
|
|
18
|
+
}
|
|
19
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
20
|
+
const hasMore = i < chunks.length - 1;
|
|
21
|
+
if (i === 0) {
|
|
22
|
+
process.stdout.write(`\x1b_Ga=T,f=100,m=${hasMore ? 1 : 0};${chunks[i]}\x1b\\`);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
process.stdout.write(`\x1b_Gm=${hasMore ? 1 : 0};${chunks[i]}\x1b\\`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function renderSixel(buffer) {
|
|
30
|
+
process.stdout.write('\x1b[H');
|
|
31
|
+
let image;
|
|
32
|
+
try {
|
|
33
|
+
image = sharp(buffer);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
console.error('[tuimon] encoder: invalid image buffer', err);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const meta = await image.metadata();
|
|
40
|
+
const width = meta.width ?? 1;
|
|
41
|
+
const height = meta.height ?? 1;
|
|
42
|
+
const { data, info } = await image
|
|
43
|
+
.raw()
|
|
44
|
+
.ensureAlpha()
|
|
45
|
+
.toBuffer({ resolveWithObject: true });
|
|
46
|
+
// Build color palette (up to 256 colors)
|
|
47
|
+
const colorMap = new Map();
|
|
48
|
+
let nextColor = 0;
|
|
49
|
+
let paletteOverflow = false;
|
|
50
|
+
const pixels = new Array(width * height);
|
|
51
|
+
for (let i = 0; i < width * height; i++) {
|
|
52
|
+
const offset = i * info.channels;
|
|
53
|
+
const r = data[offset] ?? 0;
|
|
54
|
+
const g = data[offset + 1] ?? 0;
|
|
55
|
+
const b = data[offset + 2] ?? 0;
|
|
56
|
+
const key = `${r},${g},${b}`;
|
|
57
|
+
if (!colorMap.has(key) && nextColor < MAX_PALETTE_COLORS) {
|
|
58
|
+
colorMap.set(key, nextColor++);
|
|
59
|
+
}
|
|
60
|
+
else if (!colorMap.has(key) && !paletteOverflow) {
|
|
61
|
+
paletteOverflow = true;
|
|
62
|
+
console.error(`[tuimon] sixel: image has >256 colors — some colors will be approximated`);
|
|
63
|
+
}
|
|
64
|
+
pixels[i] = colorMap.get(key) ?? 0;
|
|
65
|
+
}
|
|
66
|
+
// Write DCS header and raster attributes
|
|
67
|
+
process.stdout.write(`\x1bP0;0;0q"1;1;${width};${height}`);
|
|
68
|
+
// Write color definitions
|
|
69
|
+
for (const [key, idx] of colorMap.entries()) {
|
|
70
|
+
const parts = key.split(',').map(Number);
|
|
71
|
+
const r = parts[0] ?? 0;
|
|
72
|
+
const g = parts[1] ?? 0;
|
|
73
|
+
const b = parts[2] ?? 0;
|
|
74
|
+
const rp = Math.round((r / 255) * 100);
|
|
75
|
+
const gp = Math.round((g / 255) * 100);
|
|
76
|
+
const bp = Math.round((b / 255) * 100);
|
|
77
|
+
process.stdout.write(`#${idx};2;${rp};${gp};${bp}`);
|
|
78
|
+
}
|
|
79
|
+
// Write sixel rows in chunks (groups of 6 vertical pixels)
|
|
80
|
+
for (let y = 0; y < height; y += 6) {
|
|
81
|
+
const rowColors = new Map();
|
|
82
|
+
for (let x = 0; x < width; x++) {
|
|
83
|
+
const sixelByte = new Map();
|
|
84
|
+
for (let dy = 0; dy < 6; dy++) {
|
|
85
|
+
const py = y + dy;
|
|
86
|
+
if (py >= height)
|
|
87
|
+
break;
|
|
88
|
+
const colorIdx = pixels[py * width + x] ?? 0;
|
|
89
|
+
sixelByte.set(colorIdx, (sixelByte.get(colorIdx) ?? 0) | (1 << dy));
|
|
90
|
+
}
|
|
91
|
+
for (const [colorIdx, bits] of sixelByte.entries()) {
|
|
92
|
+
if (!rowColors.has(colorIdx)) {
|
|
93
|
+
rowColors.set(colorIdx, new Array(width).fill(0));
|
|
94
|
+
}
|
|
95
|
+
rowColors.get(colorIdx)[x] = bits;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
let bandData = '';
|
|
99
|
+
let first = true;
|
|
100
|
+
for (const [colorIdx, row] of rowColors.entries()) {
|
|
101
|
+
if (!first)
|
|
102
|
+
bandData += '$';
|
|
103
|
+
first = false;
|
|
104
|
+
bandData += `#${colorIdx}`;
|
|
105
|
+
for (let x = 0; x < width; x++) {
|
|
106
|
+
bandData += String.fromCharCode(63 + (row[x] ?? 0));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
bandData += '-';
|
|
110
|
+
process.stdout.write(bandData);
|
|
111
|
+
}
|
|
112
|
+
// String terminator
|
|
113
|
+
process.stdout.write('\x1b\\');
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=encoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoder.js","sourceRoot":"","sources":["../src/encoder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fkeybar.d.ts","sourceRoot":"","sources":["../src/fkeybar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAkD9D,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,aAAa,CAsDxE"}
|
package/dist/fkeybar.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const ALL_FKEYS = ['F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12'];
|
|
2
|
+
const BG = '\x1b[48;5;236m';
|
|
3
|
+
const CYAN = '\x1b[96m';
|
|
4
|
+
const WHITE = '\x1b[97m';
|
|
5
|
+
const RESET = '\x1b[0m';
|
|
6
|
+
const HIDE_CURSOR = '\x1b[?25l';
|
|
7
|
+
const SHOW_CURSOR = '\x1b[?25h';
|
|
8
|
+
function buildBar(keys, cols) {
|
|
9
|
+
const segments = [];
|
|
10
|
+
for (const fk of ALL_FKEYS) {
|
|
11
|
+
const binding = keys[fk];
|
|
12
|
+
if (!binding)
|
|
13
|
+
continue;
|
|
14
|
+
segments.push(`${CYAN}${fk}${WHITE} ${binding.label}`);
|
|
15
|
+
}
|
|
16
|
+
// Build the full rendered line
|
|
17
|
+
let rendered = segments.join(' ');
|
|
18
|
+
// Calculate visible length (strip ANSI)
|
|
19
|
+
const visibleLength = rendered.replace(/\x1b\[[0-9;]*m/g, '').length;
|
|
20
|
+
if (visibleLength > cols) {
|
|
21
|
+
// Truncate: rebuild with fewer segments
|
|
22
|
+
rendered = '';
|
|
23
|
+
let currentLen = 0;
|
|
24
|
+
for (let i = 0; i < segments.length; i++) {
|
|
25
|
+
const segVisible = (segments[i] ?? '').replace(/\x1b\[[0-9;]*m/g, '').length;
|
|
26
|
+
const sepLen = rendered.length > 0 ? 2 : 0;
|
|
27
|
+
if (currentLen + segVisible + sepLen > cols)
|
|
28
|
+
break;
|
|
29
|
+
rendered += (rendered.length > 0 ? ' ' : '') + (segments[i] ?? '');
|
|
30
|
+
currentLen += segVisible + sepLen;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Pad to full width
|
|
34
|
+
const finalVisible = rendered.replace(/\x1b\[[0-9;]*m/g, '').length;
|
|
35
|
+
const padding = Math.max(0, cols - finalVisible);
|
|
36
|
+
return `${BG}${rendered}${' '.repeat(padding)}${RESET}`;
|
|
37
|
+
}
|
|
38
|
+
function renderLine(content, rows) {
|
|
39
|
+
process.stdout.write(`\x1b[${rows};0H${content}`);
|
|
40
|
+
}
|
|
41
|
+
export function renderFKeyBar({ keys }) {
|
|
42
|
+
let currentKeys = keys;
|
|
43
|
+
let notifyTimer = null;
|
|
44
|
+
process.stdout.write(HIDE_CURSOR);
|
|
45
|
+
function draw() {
|
|
46
|
+
const cols = process.stdout.columns || 80;
|
|
47
|
+
const rows = process.stdout.rows || 24;
|
|
48
|
+
const bar = buildBar(currentKeys, cols);
|
|
49
|
+
renderLine(bar, rows);
|
|
50
|
+
}
|
|
51
|
+
function onResize() {
|
|
52
|
+
draw();
|
|
53
|
+
}
|
|
54
|
+
process.stdout.on('resize', onResize);
|
|
55
|
+
draw();
|
|
56
|
+
return {
|
|
57
|
+
setKeys(newKeys) {
|
|
58
|
+
currentKeys = newKeys;
|
|
59
|
+
if (notifyTimer) {
|
|
60
|
+
clearTimeout(notifyTimer);
|
|
61
|
+
notifyTimer = null;
|
|
62
|
+
}
|
|
63
|
+
draw();
|
|
64
|
+
},
|
|
65
|
+
notify(message, duration = 3000) {
|
|
66
|
+
const cols = process.stdout.columns || 80;
|
|
67
|
+
const rows = process.stdout.rows || 24;
|
|
68
|
+
const visible = message.slice(0, cols);
|
|
69
|
+
const padding = Math.max(0, cols - visible.length);
|
|
70
|
+
const line = `${BG}${WHITE}${visible}${' '.repeat(padding)}${RESET}`;
|
|
71
|
+
renderLine(line, rows);
|
|
72
|
+
if (notifyTimer)
|
|
73
|
+
clearTimeout(notifyTimer);
|
|
74
|
+
notifyTimer = setTimeout(() => {
|
|
75
|
+
notifyTimer = null;
|
|
76
|
+
draw();
|
|
77
|
+
}, duration);
|
|
78
|
+
},
|
|
79
|
+
stop() {
|
|
80
|
+
if (notifyTimer) {
|
|
81
|
+
clearTimeout(notifyTimer);
|
|
82
|
+
notifyTimer = null;
|
|
83
|
+
}
|
|
84
|
+
process.stdout.removeListener('resize', onResize);
|
|
85
|
+
process.stdout.write(SHOW_CURSOR);
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=fkeybar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fkeybar.js","sourceRoot":"","sources":["../src/fkeybar.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EAEhB,MAAM,YAAY,CAAA;AAWnB,iBAAe,KAAK,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CA2KrE;;;;AAED,wBAAwB"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { detectGraphicsSupport, getTerminalDimensions } from './detect.js';
|
|
3
|
+
import { startServer } from './server.js';
|
|
4
|
+
import { createBrowser } from './browser.js';
|
|
5
|
+
import { encodeAndRender } from './encoder.js';
|
|
6
|
+
import { startKeyHandler } from './keyhandler.js';
|
|
7
|
+
import { renderFKeyBar } from './fkeybar.js';
|
|
8
|
+
import { createRouter } from './router.js';
|
|
9
|
+
const MAX_REFRESH_FAILURES = 5;
|
|
10
|
+
async function start(options) {
|
|
11
|
+
const { pages } = options;
|
|
12
|
+
const renderDelay = options.renderDelay ?? 50;
|
|
13
|
+
// Validate pages is not empty
|
|
14
|
+
const pageEntries = Object.entries(pages);
|
|
15
|
+
if (pageEntries.length === 0) {
|
|
16
|
+
throw new Error('[tuimon] At least one page must be defined');
|
|
17
|
+
}
|
|
18
|
+
// Detect terminal capabilities
|
|
19
|
+
const graphics = await detectGraphicsSupport();
|
|
20
|
+
const dims = await getTerminalDimensions();
|
|
21
|
+
if (!graphics.protocol) {
|
|
22
|
+
console.error('[tuimon] No supported graphics protocol detected. Falling back to kitty.');
|
|
23
|
+
}
|
|
24
|
+
// iterm2 uses kitty-compatible rendering for our purposes
|
|
25
|
+
const protocol = (graphics.protocol === 'sixel') ? 'sixel' : 'kitty';
|
|
26
|
+
// Resolve all page html paths and find common root
|
|
27
|
+
const resolvedPages = new Map();
|
|
28
|
+
const allDirs = [];
|
|
29
|
+
for (const [id, page] of pageEntries) {
|
|
30
|
+
const resolved = path.resolve(process.cwd(), page.html);
|
|
31
|
+
resolvedPages.set(id, resolved);
|
|
32
|
+
allDirs.push(path.dirname(resolved));
|
|
33
|
+
}
|
|
34
|
+
// Find common parent directory
|
|
35
|
+
let rootDir = allDirs[0] ?? process.cwd();
|
|
36
|
+
if (allDirs.length > 1) {
|
|
37
|
+
const parts = rootDir.split(path.sep);
|
|
38
|
+
for (const dir of allDirs) {
|
|
39
|
+
const dirParts = dir.split(path.sep);
|
|
40
|
+
let common = 0;
|
|
41
|
+
while (common < parts.length && common < dirParts.length && parts[common] === dirParts[common]) {
|
|
42
|
+
common++;
|
|
43
|
+
}
|
|
44
|
+
parts.length = common;
|
|
45
|
+
}
|
|
46
|
+
rootDir = parts.join(path.sep) || '/';
|
|
47
|
+
}
|
|
48
|
+
// Start server
|
|
49
|
+
const server = await startServer({ rootDir });
|
|
50
|
+
// Calculate viewport dimensions (reserve 1 row for F-key bar)
|
|
51
|
+
const cellPixelHeight = Math.floor(dims.pixelHeight / dims.rows);
|
|
52
|
+
const viewportHeight = dims.pixelHeight - cellPixelHeight;
|
|
53
|
+
const viewportWidth = dims.pixelWidth;
|
|
54
|
+
// Start browser
|
|
55
|
+
const browser = await createBrowser({
|
|
56
|
+
url: server.url,
|
|
57
|
+
width: viewportWidth,
|
|
58
|
+
height: viewportHeight,
|
|
59
|
+
});
|
|
60
|
+
// Enter alt screen + hide cursor
|
|
61
|
+
process.stdout.write('\x1b[?1049h\x1b[?25l');
|
|
62
|
+
// Track last data for re-rendering after navigation
|
|
63
|
+
let lastData = {};
|
|
64
|
+
let refreshInterval;
|
|
65
|
+
let stopped = false;
|
|
66
|
+
let rendering = false;
|
|
67
|
+
// Render function with concurrency guard
|
|
68
|
+
async function renderFrame(data) {
|
|
69
|
+
if (stopped || rendering)
|
|
70
|
+
return;
|
|
71
|
+
rendering = true;
|
|
72
|
+
try {
|
|
73
|
+
if (data)
|
|
74
|
+
lastData = data;
|
|
75
|
+
await browser.pushData(lastData);
|
|
76
|
+
await new Promise((resolve) => setTimeout(resolve, renderDelay));
|
|
77
|
+
const screenshot = await browser.screenshot();
|
|
78
|
+
await encodeAndRender(screenshot, { protocol });
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
rendering = false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// F-key bar
|
|
85
|
+
const defaultPageId = pageEntries.find(([, p]) => p.default)?.[0] ?? pageEntries[0][0];
|
|
86
|
+
const defaultPage = pages[defaultPageId];
|
|
87
|
+
const fkeyBar = renderFKeyBar({ keys: defaultPage.keys ?? {} });
|
|
88
|
+
// Router navigate helper
|
|
89
|
+
async function navigateToPage(htmlPath) {
|
|
90
|
+
// Internal paths (e.g., /tuimon/confirm-quit.html) are served as-is
|
|
91
|
+
// Page paths are resolved to their filename
|
|
92
|
+
const url = htmlPath.startsWith('/tuimon/')
|
|
93
|
+
? `${server.url}${htmlPath}`
|
|
94
|
+
: server.urlFor(path.basename(htmlPath));
|
|
95
|
+
await browser.navigate(url);
|
|
96
|
+
}
|
|
97
|
+
// Router
|
|
98
|
+
const router = createRouter({
|
|
99
|
+
pages,
|
|
100
|
+
navigate: navigateToPage,
|
|
101
|
+
render: async () => { await renderFrame(); },
|
|
102
|
+
setKeys: (keys) => { fkeyBar.setKeys(keys); },
|
|
103
|
+
confirmQuitHtml: '/tuimon/confirm-quit.html',
|
|
104
|
+
});
|
|
105
|
+
// Key handler — catch unhandled rejections from handleKey
|
|
106
|
+
const keyHandler = startKeyHandler({
|
|
107
|
+
onKey: (key) => {
|
|
108
|
+
router.handleKey(key).catch((err) => {
|
|
109
|
+
console.error('[tuimon] key handler error:', err);
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
// Auto-refresh with circuit breaker
|
|
114
|
+
if (options.refresh && options.data) {
|
|
115
|
+
const dataFn = options.data;
|
|
116
|
+
let consecutiveFailures = 0;
|
|
117
|
+
refreshInterval = setInterval(async () => {
|
|
118
|
+
try {
|
|
119
|
+
const data = await dataFn();
|
|
120
|
+
await renderFrame(data);
|
|
121
|
+
consecutiveFailures = 0;
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
consecutiveFailures++;
|
|
125
|
+
console.error('[tuimon] refresh error:', err);
|
|
126
|
+
if (consecutiveFailures >= MAX_REFRESH_FAILURES) {
|
|
127
|
+
console.error(`[tuimon] ${MAX_REFRESH_FAILURES} consecutive refresh failures — disabling auto-refresh`);
|
|
128
|
+
if (refreshInterval)
|
|
129
|
+
clearInterval(refreshInterval);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}, options.refresh);
|
|
133
|
+
refreshInterval.unref();
|
|
134
|
+
}
|
|
135
|
+
// Navigate to the default page
|
|
136
|
+
const defaultHtml = defaultPage.html;
|
|
137
|
+
const defaultFilename = path.basename(path.resolve(process.cwd(), defaultHtml));
|
|
138
|
+
await browser.navigate(server.urlFor(defaultFilename));
|
|
139
|
+
// Stop function
|
|
140
|
+
async function stop() {
|
|
141
|
+
if (stopped)
|
|
142
|
+
return;
|
|
143
|
+
stopped = true;
|
|
144
|
+
if (refreshInterval)
|
|
145
|
+
clearInterval(refreshInterval);
|
|
146
|
+
keyHandler.stop();
|
|
147
|
+
fkeyBar.stop();
|
|
148
|
+
await browser.close();
|
|
149
|
+
await server.close();
|
|
150
|
+
// Restore terminal: show cursor + exit alt screen
|
|
151
|
+
process.stdout.write('\x1b[?25h\x1b[?1049l');
|
|
152
|
+
}
|
|
153
|
+
// Await stop on SIGINT to ensure cleanup completes
|
|
154
|
+
process.once('SIGINT', () => {
|
|
155
|
+
stop().catch((err) => {
|
|
156
|
+
console.error('[tuimon] shutdown error:', err);
|
|
157
|
+
process.exit(1);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
return {
|
|
161
|
+
render: async (data) => { await renderFrame(data); },
|
|
162
|
+
stop,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
export default { start };
|
|
166
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyhandler.d.ts","sourceRoot":"","sources":["../src/keyhandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAAG,gBAAgB,CAoB7F"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function startKeyHandler({ onKey }) {
|
|
2
|
+
const onData = (buffer) => {
|
|
3
|
+
onKey(buffer.toString());
|
|
4
|
+
};
|
|
5
|
+
if (process.stdin.isTTY) {
|
|
6
|
+
process.stdin.setRawMode(true);
|
|
7
|
+
}
|
|
8
|
+
process.stdin.resume();
|
|
9
|
+
process.stdin.on('data', onData);
|
|
10
|
+
return {
|
|
11
|
+
stop() {
|
|
12
|
+
process.stdin.removeListener('data', onData);
|
|
13
|
+
if (process.stdin.isTTY) {
|
|
14
|
+
process.stdin.setRawMode(false);
|
|
15
|
+
}
|
|
16
|
+
process.stdin.pause();
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=keyhandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyhandler.js","sourceRoot":"","sources":["../src/keyhandler.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe,CAAC,EAAE,KAAK,EAAoC;IACzE,MAAM,MAAM,GAAG,CAAC,MAAc,EAAQ,EAAE;QACtC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC1B,CAAC,CAAA;IAED,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAA;IACtB,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEhC,OAAO;QACL,IAAI;YACF,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;YAC5C,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;YACjC,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;QACvB,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/dist/router.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PageMap, FKeyMap, RouterHandle } from './types.js';
|
|
2
|
+
export interface RouterDeps {
|
|
3
|
+
pages: PageMap;
|
|
4
|
+
navigate: (url: string) => Promise<void>;
|
|
5
|
+
render: (data?: Record<string, unknown>) => Promise<void>;
|
|
6
|
+
setKeys: (keys: FKeyMap) => void;
|
|
7
|
+
confirmQuitHtml: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function createRouter(deps: RouterDeps): RouterHandle;
|
|
10
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAa,OAAO,EAAQ,YAAY,EAAE,MAAM,YAAY,CAAA;AAEjF,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACzD,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,eAAe,EAAE,MAAM,CAAA;CACxB;AA0BD,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY,CAsK3D"}
|
package/dist/router.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// ─── Key sequence → FKey mapping ─────────────────────────────────────────────
|
|
2
|
+
const SEQ_TO_FKEY = {
|
|
3
|
+
'\x1bOP': 'F1', '\x1b[11~': 'F1',
|
|
4
|
+
'\x1bOQ': 'F2', '\x1b[12~': 'F2',
|
|
5
|
+
'\x1bOR': 'F3', '\x1b[13~': 'F3',
|
|
6
|
+
'\x1bOS': 'F4', '\x1b[14~': 'F4',
|
|
7
|
+
'\x1b[15~': 'F5',
|
|
8
|
+
'\x1b[17~': 'F6',
|
|
9
|
+
'\x1b[18~': 'F7',
|
|
10
|
+
'\x1b[19~': 'F8',
|
|
11
|
+
'\x1b[20~': 'F9',
|
|
12
|
+
'\x1b[21~': 'F10',
|
|
13
|
+
'\x1b[23~': 'F11',
|
|
14
|
+
'\x1b[24~': 'F12',
|
|
15
|
+
};
|
|
16
|
+
const RESERVED_SHORTCUTS = new Set(['y', 'n', '\x1b', '\x03']);
|
|
17
|
+
const ESC = '\x1b';
|
|
18
|
+
const CTRL_C = '\x03';
|
|
19
|
+
// ─── createRouter ────────────────────────────────────────────────────────────
|
|
20
|
+
export function createRouter(deps) {
|
|
21
|
+
const { pages, navigate, render, setKeys, confirmQuitHtml } = deps;
|
|
22
|
+
// ── Validation ──────────────────────────────────────────────────────────
|
|
23
|
+
// Exactly one default page
|
|
24
|
+
const defaultEntries = Object.entries(pages).filter(([, cfg]) => cfg.default);
|
|
25
|
+
if (defaultEntries.length !== 1) {
|
|
26
|
+
throw new Error(`Exactly one page must have default: true, found ${defaultEntries.length}`);
|
|
27
|
+
}
|
|
28
|
+
const [defaultPageId, defaultPageConfig] = defaultEntries[0];
|
|
29
|
+
// Shortcut uniqueness and reserved check
|
|
30
|
+
const seenShortcuts = new Map();
|
|
31
|
+
for (const [id, cfg] of Object.entries(pages)) {
|
|
32
|
+
if (cfg.shortcut != null) {
|
|
33
|
+
if (RESERVED_SHORTCUTS.has(cfg.shortcut)) {
|
|
34
|
+
throw new Error(`Page "${id}" uses reserved shortcut '${cfg.shortcut}'`);
|
|
35
|
+
}
|
|
36
|
+
if (seenShortcuts.has(cfg.shortcut)) {
|
|
37
|
+
throw new Error(`Duplicate shortcut '${cfg.shortcut}' on pages "${seenShortcuts.get(cfg.shortcut)}" and "${id}"`);
|
|
38
|
+
}
|
|
39
|
+
seenShortcuts.set(cfg.shortcut, id);
|
|
40
|
+
}
|
|
41
|
+
// Warn if ESC or Ctrl+C defined in page keys
|
|
42
|
+
if (cfg.keys) {
|
|
43
|
+
for (const key of Object.keys(cfg.keys)) {
|
|
44
|
+
if (key === 'ESC' || key === 'Escape' || key === CTRL_C) {
|
|
45
|
+
console.warn(`[tuimon] Page "${id}" defines reserved key "${key}" in its key map — it will be ignored`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// ── Shortcut → pageId lookup ────────────────────────────────────────────
|
|
51
|
+
const shortcutToPageId = new Map();
|
|
52
|
+
for (const [id, cfg] of Object.entries(pages)) {
|
|
53
|
+
if (cfg.shortcut) {
|
|
54
|
+
shortcutToPageId.set(cfg.shortcut, id);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// ── State ───────────────────────────────────────────────────────────────
|
|
58
|
+
let state = { type: 'overview', pageId: defaultPageId };
|
|
59
|
+
// Set initial keys
|
|
60
|
+
setKeys(defaultPageConfig.keys ?? {});
|
|
61
|
+
// ── Confirm-quit keys ───────────────────────────────────────────────────
|
|
62
|
+
const confirmQuitKeys = {};
|
|
63
|
+
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
64
|
+
function getPageKeys(pageId) {
|
|
65
|
+
return pages[pageId]?.keys ?? {};
|
|
66
|
+
}
|
|
67
|
+
function getPageHtml(pageId) {
|
|
68
|
+
const page = pages[pageId];
|
|
69
|
+
if (!page)
|
|
70
|
+
throw new Error(`[tuimon] Unknown page: "${pageId}"`);
|
|
71
|
+
return page.html;
|
|
72
|
+
}
|
|
73
|
+
async function goToPage(pageState) {
|
|
74
|
+
state = pageState;
|
|
75
|
+
const pageId = pageState.type === 'confirm-quit'
|
|
76
|
+
? null
|
|
77
|
+
: pageState.pageId;
|
|
78
|
+
if (pageState.type === 'confirm-quit') {
|
|
79
|
+
await navigate(confirmQuitHtml);
|
|
80
|
+
setKeys(confirmQuitKeys);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
await navigate(getPageHtml(pageId));
|
|
84
|
+
setKeys(getPageKeys(pageId));
|
|
85
|
+
await render();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// ── handleKey ───────────────────────────────────────────────────────────
|
|
89
|
+
async function handleKey(key) {
|
|
90
|
+
// Ctrl+C always exits immediately
|
|
91
|
+
if (key === CTRL_C) {
|
|
92
|
+
process.exit(0);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// ── confirm-quit state ────────────────────────────────────────────────
|
|
96
|
+
if (state.type === 'confirm-quit') {
|
|
97
|
+
const lower = key.toLowerCase();
|
|
98
|
+
if (lower === 'y') {
|
|
99
|
+
process.exit(0);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (lower === 'n' || key === ESC) {
|
|
103
|
+
await goToPage(state.returnTo);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
// Ignore everything else (including F-keys) on confirm-quit
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
// ── Check for F-key sequences ─────────────────────────────────────────
|
|
110
|
+
const fkey = SEQ_TO_FKEY[key];
|
|
111
|
+
if (fkey) {
|
|
112
|
+
const currentPageId = state.pageId;
|
|
113
|
+
const binding = getPageKeys(currentPageId)[fkey];
|
|
114
|
+
if (binding) {
|
|
115
|
+
try {
|
|
116
|
+
await Promise.resolve(binding.action());
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
console.error('[tuimon]', err);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// ── ESC ───────────────────────────────────────────────────────────────
|
|
125
|
+
if (key === ESC) {
|
|
126
|
+
if (state.type === 'detail') {
|
|
127
|
+
// Back to overview
|
|
128
|
+
await goToPage({ type: 'overview', pageId: defaultPageId });
|
|
129
|
+
}
|
|
130
|
+
else if (state.type === 'overview') {
|
|
131
|
+
// Show confirm-quit
|
|
132
|
+
const returnTo = { ...state };
|
|
133
|
+
state = { type: 'confirm-quit', returnTo };
|
|
134
|
+
await navigate(confirmQuitHtml);
|
|
135
|
+
setKeys(confirmQuitKeys);
|
|
136
|
+
}
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
// ── Shortcut keys (only from overview) ────────────────────────────────
|
|
140
|
+
if (state.type === 'overview') {
|
|
141
|
+
const targetPageId = shortcutToPageId.get(key);
|
|
142
|
+
if (targetPageId) {
|
|
143
|
+
await goToPage({ type: 'detail', pageId: targetPageId });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// detail state ignores shortcut keys — no action needed
|
|
147
|
+
}
|
|
148
|
+
// ── Public API ──────────────────────────────────────────────────────────
|
|
149
|
+
return {
|
|
150
|
+
handleKey,
|
|
151
|
+
getState: () => state,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAqI9C,wBAAsB,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAgCzF"}
|