termweb-dashboard 0.2.1

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/bin/cli.js ADDED
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path');
4
+ const termweb = require('termweb');
5
+ const { startServer } = require('../lib/server');
6
+
7
+ const args = process.argv.slice(2);
8
+ const verbose = args.includes('--verbose') || args.includes('-v');
9
+
10
+ if (args.includes('--help') || args.includes('-h')) {
11
+ console.log(`
12
+ @termweb/dashboard - System Monitoring Dashboard
13
+
14
+ Usage: termweb-dashboard [options]
15
+
16
+ Options:
17
+ -v, --verbose Debug output
18
+ -h, --help Show help
19
+
20
+ Displays system metrics:
21
+ - CPU usage (overall and per-core)
22
+ - Memory usage (RAM and swap)
23
+ - Disk usage
24
+ - Network I/O
25
+ - Process list
26
+ `);
27
+ process.exit(0);
28
+ }
29
+
30
+ async function main() {
31
+ try {
32
+ // Start WebSocket server (random port)
33
+ const { port, wss } = await startServer(0);
34
+ if (verbose) console.log(`[Dashboard] WebSocket server on port ${port}`);
35
+
36
+ // Open page with WebSocket port
37
+ const url = `http://127.0.0.1:${port}/`;
38
+
39
+ termweb.onClose(() => {
40
+ if (verbose) console.log('[Dashboard] Viewer closed');
41
+ process.exit(0);
42
+ });
43
+
44
+ // Key bindings for main view
45
+ const mainBindings = { c: 'view:cpu', m: 'view:memory', n: 'view:network', d: 'view:disk', p: 'view:processes' };
46
+
47
+ function addMainBindings() {
48
+ for (const [key, action] of Object.entries(mainBindings)) {
49
+ termweb.addKeyBinding(key, action);
50
+ }
51
+ }
52
+
53
+ function removeMainBindings() {
54
+ for (const key of Object.keys(mainBindings)) {
55
+ termweb.removeKeyBinding(key);
56
+ }
57
+ }
58
+
59
+ // Listen for view/state changes from page via WebSocket
60
+ wss.on('connection', (ws) => {
61
+ ws.on('message', (message) => {
62
+ try {
63
+ const msg = JSON.parse(message.toString());
64
+ if (msg.type === 'viewChange') {
65
+ if (verbose) console.log(`[View] Changed to: ${msg.view}`);
66
+ if (msg.view === 'main') {
67
+ addMainBindings();
68
+ } else {
69
+ removeMainBindings();
70
+ }
71
+ } else if (msg.type === 'killConfirm') {
72
+ // Add y/n bindings for kill confirmation
73
+ if (verbose) console.log('[Kill] Confirm mode');
74
+ termweb.addKeyBinding('y', 'kill:confirm');
75
+ termweb.addKeyBinding('n', 'kill:cancel');
76
+ } else if (msg.type === 'killCancel') {
77
+ // Remove y/n bindings
78
+ if (verbose) console.log('[Kill] Cancel mode');
79
+ termweb.removeKeyBinding('y');
80
+ termweb.removeKeyBinding('n');
81
+ }
82
+ } catch (e) {}
83
+ });
84
+ });
85
+
86
+ // SDK handles keys, sends action to page
87
+ termweb.onKeyBinding((key, action) => {
88
+ if (verbose) console.log(`[KeyBinding] ${key} -> ${action}`);
89
+ termweb.sendToPage({ type: 'action', action });
90
+ });
91
+
92
+ termweb.openAsync(url, {
93
+ toolbar: false,
94
+ allowedHotkeys: ['quit', 'select_all', 'copy', 'cut', 'paste'],
95
+ singleTab: true,
96
+ keyBindings: mainBindings,
97
+ verbose
98
+ });
99
+
100
+ if (verbose) console.log('[Dashboard] Started, press Ctrl+Q to quit...');
101
+
102
+ } catch (err) {
103
+ console.error('Error:', err.message);
104
+ process.exit(1);
105
+ }
106
+ }
107
+
108
+ main();