claw-dashboard 2.1.0 → 2.1.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/index.js +1 -1
- package/package.json +2 -1
- package/src/widgets/builtin-widgets.js +0 -94
- package/src/widgets/index.js +0 -1
- package/tests/removed-dependencies.test.js +74 -0
package/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import blessed from 'blessed';
|
|
4
|
-
import contrib from 'blessed-contrib';
|
|
5
4
|
import si from 'systeminformation';
|
|
6
5
|
import { exec } from 'child_process';
|
|
7
6
|
import { promisify } from 'util';
|
|
@@ -5974,5 +5973,6 @@ async function main() {
|
|
|
5974
5973
|
// Run main
|
|
5975
5974
|
main().catch(err => {
|
|
5976
5975
|
console.error('Fatal error:', err);
|
|
5976
|
+
if (err.stack) console.error('Stack:', err.stack);
|
|
5977
5977
|
process.exit(1);
|
|
5978
5978
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claw-dashboard",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "A beautiful console dashboard for monitoring OpenClaw instances — inspired by htop/btop/mactop",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"exports": {
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@pm2/blessed": "^0.1.81",
|
|
64
|
+
"blessed": "npm:@pm2/blessed@^0.1.81",
|
|
64
65
|
"chalk": "^5.3.0",
|
|
65
66
|
"sql.js": "^1.14.0",
|
|
66
67
|
"systeminformation": "^5.21.22"
|
|
@@ -238,98 +238,6 @@ export class GpuWidget extends BaseWidget {
|
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
/**
|
|
242
|
-
* Network Widget - Displays network activity
|
|
243
|
-
*/
|
|
244
|
-
export class NetworkWidget extends BaseWidget {
|
|
245
|
-
constructor(options = {}) {
|
|
246
|
-
super(options);
|
|
247
|
-
this.name = 'Network';
|
|
248
|
-
this.description = 'Network activity';
|
|
249
|
-
this.history = [];
|
|
250
|
-
this.maxHistory = 30;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
async create(screen, theme = {}) {
|
|
254
|
-
const C = theme.colors || {};
|
|
255
|
-
|
|
256
|
-
this.box = blessed.box({
|
|
257
|
-
parent: screen,
|
|
258
|
-
height: 5,
|
|
259
|
-
border: { type: 'line' },
|
|
260
|
-
label: ' NETWORK ',
|
|
261
|
-
style: { border: { fg: C.brightCyan || 'bright-cyan' } },
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
this.valueText = blessed.text({
|
|
265
|
-
parent: this.box,
|
|
266
|
-
top: 0,
|
|
267
|
-
left: 'center',
|
|
268
|
-
content: 'Loading...',
|
|
269
|
-
style: { fg: C.brightCyan || 'bright-cyan', bold: true },
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
this.detailText = blessed.text({
|
|
273
|
-
parent: this.box,
|
|
274
|
-
top: 1,
|
|
275
|
-
left: 'center',
|
|
276
|
-
content: '',
|
|
277
|
-
style: { fg: C.gray || 'gray' },
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
this.sparkline = contrib.sparkline({
|
|
281
|
-
parent: this.box,
|
|
282
|
-
top: 2,
|
|
283
|
-
left: 'center',
|
|
284
|
-
width: 20,
|
|
285
|
-
height: 1,
|
|
286
|
-
style: { fg: C.cyan || 'cyan' },
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
return this;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
async getData(dataProvider) {
|
|
293
|
-
if (dataProvider) {
|
|
294
|
-
return dataProvider('network');
|
|
295
|
-
}
|
|
296
|
-
return null;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
formatBytes(bytes) {
|
|
300
|
-
if (bytes === 0) return '0 B';
|
|
301
|
-
const k = 1024;
|
|
302
|
-
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
303
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
304
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
update(data) {
|
|
308
|
-
if (!data || !this.box) return;
|
|
309
|
-
|
|
310
|
-
const iface = data.interface || 'unknown';
|
|
311
|
-
const rx = data.rxSec || 0;
|
|
312
|
-
const tx = data.txSec || 0;
|
|
313
|
-
const total = rx + tx;
|
|
314
|
-
|
|
315
|
-
// Update history
|
|
316
|
-
this.history.push(total);
|
|
317
|
-
if (this.history.length > this.maxHistory) {
|
|
318
|
-
this.history.shift();
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
this.valueText.setContent(iface);
|
|
322
|
-
this.detailText.setContent(`↓${this.formatBytes(rx)} ↑${this.formatBytes(tx)}`);
|
|
323
|
-
|
|
324
|
-
if (this.sparkline && this.history.length > 1) {
|
|
325
|
-
this.sparkline.setData([this.history]);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
render(data) {
|
|
330
|
-
this.update(data);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
241
|
|
|
334
242
|
/**
|
|
335
243
|
* Disk Widget - Displays disk usage
|
|
@@ -1009,7 +917,6 @@ export const WIDGET_REGISTRY = {
|
|
|
1009
917
|
cpu: CpuWidget,
|
|
1010
918
|
memory: MemoryWidget,
|
|
1011
919
|
gpu: GpuWidget,
|
|
1012
|
-
network: NetworkWidget,
|
|
1013
920
|
disk: DiskWidget,
|
|
1014
921
|
system: SystemWidget,
|
|
1015
922
|
uptime: UptimeWidget,
|
|
@@ -1043,7 +950,6 @@ export default {
|
|
|
1043
950
|
CpuWidget,
|
|
1044
951
|
MemoryWidget,
|
|
1045
952
|
GpuWidget,
|
|
1046
|
-
NetworkWidget,
|
|
1047
953
|
DiskWidget,
|
|
1048
954
|
SystemWidget,
|
|
1049
955
|
UptimeWidget,
|
package/src/widgets/index.js
CHANGED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for removed dependencies and widgets
|
|
3
|
+
* Verifies cleanup after blessed-contrib and NetworkWidget removal
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { jest } from '@jest/globals';
|
|
7
|
+
import { describe, test, expect } from '@jest/globals';
|
|
8
|
+
import { readFileSync } from 'fs';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import { dirname, join } from 'path';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = dirname(__filename);
|
|
14
|
+
|
|
15
|
+
describe('Removed dependencies cleanup', () => {
|
|
16
|
+
describe('blessed-contrib removal', () => {
|
|
17
|
+
test('should not have blessed-contrib in package.json dependencies', () => {
|
|
18
|
+
const pkg = JSON.parse(
|
|
19
|
+
readFileSync(join(__dirname, '../package.json'), 'utf8')
|
|
20
|
+
);
|
|
21
|
+
expect(pkg.dependencies).not.toHaveProperty('blessed-contrib');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('should not import blessed-contrib in index.js', () => {
|
|
25
|
+
const indexContent = readFileSync(join(__dirname, '../index.js'), 'utf8');
|
|
26
|
+
expect(indexContent).not.toContain("import contrib from 'blessed-contrib'");
|
|
27
|
+
expect(indexContent).not.toContain('blessed-contrib');
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('NetworkWidget removal', () => {
|
|
32
|
+
test('should not export NetworkWidget from widgets/index.js', async () => {
|
|
33
|
+
const widgets = await import('../src/widgets/index.js');
|
|
34
|
+
expect(widgets.NetworkWidget).toBeUndefined();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('should not have NetworkWidget in builtin-widgets exports', async () => {
|
|
38
|
+
const builtin = await import('../src/widgets/builtin-widgets.js');
|
|
39
|
+
expect(builtin.NetworkWidget).toBeUndefined();
|
|
40
|
+
expect(builtin.WIDGET_REGISTRY).not.toHaveProperty('network');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('builtin-widgets should not reference blessed-contrib', () => {
|
|
44
|
+
const content = readFileSync(
|
|
45
|
+
join(__dirname, '../src/widgets/builtin-widgets.js'),
|
|
46
|
+
'utf8'
|
|
47
|
+
);
|
|
48
|
+
expect(content).not.toContain('blessed-contrib');
|
|
49
|
+
expect(content).not.toContain('contrib.sparkline');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('@pm2/blessed migration', () => {
|
|
54
|
+
test('should have @pm2/blessed as dependency', () => {
|
|
55
|
+
const pkg = JSON.parse(
|
|
56
|
+
readFileSync(join(__dirname, '../package.json'), 'utf8')
|
|
57
|
+
);
|
|
58
|
+
expect(pkg.dependencies).toHaveProperty('@pm2/blessed');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('should have blessed aliased to @pm2/blessed', () => {
|
|
62
|
+
const pkg = JSON.parse(
|
|
63
|
+
readFileSync(join(__dirname, '../package.json'), 'utf8')
|
|
64
|
+
);
|
|
65
|
+
expect(pkg.dependencies.blessed).toBe('npm:@pm2/blessed@^0.1.81');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('should be able to import blessed', async () => {
|
|
69
|
+
// This verifies the alias is working
|
|
70
|
+
const blessed = await import('blessed');
|
|
71
|
+
expect(typeof blessed.default).toBe('function');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|