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 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.0",
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,
@@ -45,7 +45,6 @@ export {
45
45
  CpuWidget,
46
46
  MemoryWidget,
47
47
  GpuWidget,
48
- NetworkWidget,
49
48
  DiskWidget,
50
49
  SystemWidget,
51
50
  UptimeWidget,
@@ -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
+ });