claw-dashboard 1.8.4 → 2.0.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/.c8rc.json +38 -0
- package/.dockerignore +68 -0
- package/.github/dependabot.yml +45 -0
- package/.github/pull_request_template.md +39 -0
- package/.github/workflows/ci.yml +147 -0
- package/.github/workflows/release.yml +40 -0
- package/.github/workflows/security.yml +84 -0
- package/.husky/pre-commit +1 -0
- package/.planning/codebase/ARCHITECTURE.md +206 -0
- package/.planning/codebase/INTEGRATIONS.md +150 -0
- package/.planning/codebase/STACK.md +122 -0
- package/.planning/codebase/STRUCTURE.md +201 -0
- package/CHANGELOG.md +293 -0
- package/CONTRIBUTING.md +378 -0
- package/Dockerfile +54 -0
- package/FEATURES.md +195 -21
- package/README.md +83 -6
- package/TODO.md +28 -0
- package/build-cjs.js +127 -0
- package/cjs-shim.js +13 -0
- package/dist/clawdash +1729 -0
- package/dist/clawdash.meta.json +2236 -0
- package/dist/widgets.cjs +6511 -0
- package/docker-compose.yml +67 -0
- package/docs/API.md +1050 -0
- package/docs/PLUGINS.md +1504 -0
- package/esbuild.config.js +158 -0
- package/eslint.config.js +56 -0
- package/examples/plugins/README.md +122 -0
- package/examples/plugins/api-status/index.js +294 -0
- package/examples/plugins/api-status/plugin.json +19 -0
- package/examples/plugins/hello-world/index.js +104 -0
- package/examples/plugins/hello-world/plugin.json +15 -0
- package/examples/plugins/system-metrics-chart/index.js +339 -0
- package/examples/plugins/system-metrics-chart/plugin.json +18 -0
- package/examples/plugins/weather-widget/index.js +136 -0
- package/examples/plugins/weather-widget/plugin.json +19 -0
- package/index.cjs +23005 -0
- package/index.js +5331 -512
- package/jest.config.js +11 -0
- package/man/clawdash.1 +276 -0
- package/package.json +54 -5
- package/schemas/plugin-manifest.json +128 -0
- package/scripts/release.js +595 -0
- package/src/alerts.js +693 -0
- package/src/auto-save.js +584 -0
- package/src/cache.js +390 -0
- package/src/checksum.js +146 -0
- package/src/cli/args.js +110 -0
- package/src/cli/export-schedule.js +423 -0
- package/src/cli/export-snapshot.js +138 -0
- package/src/cli/help.js +69 -0
- package/src/cli/import-snapshot.js +230 -0
- package/src/cli/index.js +14 -0
- package/src/cli/list-templates.js +69 -0
- package/src/cli/validate-config.js +76 -0
- package/src/cli/validate-plugin.js +187 -0
- package/src/cli/version.js +15 -0
- package/src/config-validator.js +586 -0
- package/src/config-watcher.js +401 -0
- package/src/config.js +684 -0
- package/src/container-detector.js +499 -0
- package/src/database.js +734 -0
- package/src/differential-render.js +327 -0
- package/src/errors.js +169 -0
- package/src/export-scheduler.js +581 -0
- package/src/gateway-manager.js +685 -0
- package/src/hints.js +371 -0
- package/src/loading-states.js +509 -0
- package/src/logger.js +185 -0
- package/src/memory-pressure.js +467 -0
- package/src/performance-monitor.js +374 -0
- package/src/plugin-errors.js +586 -0
- package/src/plugin-manifest-validator.js +219 -0
- package/src/plugin-reload.js +481 -0
- package/src/plugin-scaffold.js +1941 -0
- package/src/plugin-validator.js +284 -0
- package/src/retry.js +218 -0
- package/src/security.js +860 -0
- package/src/snapshot.js +372 -0
- package/src/splash.js +115 -0
- package/src/theme-selector.js +411 -0
- package/src/themes.js +874 -0
- package/src/transitions.js +534 -0
- package/src/types.d.ts +174 -0
- package/src/validation.js +926 -0
- package/src/web-server.js +885 -0
- package/src/widgets/builtin-widgets.js +1057 -0
- package/src/widgets/config-processor.js +401 -0
- package/src/widgets/dependency-resolver.js +596 -0
- package/src/widgets/index.js +79 -0
- package/src/widgets/plugin-api.js +845 -0
- package/src/widgets/widget-error-boundary.js +773 -0
- package/src/widgets/widget-error-isolation.js +551 -0
- package/src/widgets/widget-loader.js +1437 -0
- package/src/workers/system-worker.js +130 -0
- package/src/workers/worker-pool.js +633 -0
- package/tests/alerts.test.js +437 -0
- package/tests/auto-save.test.js +529 -0
- package/tests/cache.test.js +317 -0
- package/tests/cli.test.js +351 -0
- package/tests/command-palette.test.js +320 -0
- package/tests/config-processor.test.js +452 -0
- package/tests/config-validator.test.js +710 -0
- package/tests/config-watcher.test.js +594 -0
- package/tests/config.test.js +755 -0
- package/tests/database.test.js +438 -0
- package/tests/errors.test.js +189 -0
- package/tests/example-plugins.test.js +624 -0
- package/tests/integration.test.js +1321 -0
- package/tests/loading-states.test.js +300 -0
- package/tests/manifest-validation-on-load.test.js +671 -0
- package/tests/performance-monitor.test.js +190 -0
- package/tests/plugin-api-rate-limit.test.js +302 -0
- package/tests/plugin-errors.test.js +311 -0
- package/tests/plugin-lifecycle-e2e.test.js +1036 -0
- package/tests/plugin-reload.test.js +764 -0
- package/tests/rate-limiter.test.js +539 -0
- package/tests/retry.test.js +308 -0
- package/tests/security.test.js +411 -0
- package/tests/settings-modal.test.js +226 -0
- package/tests/theme-selector.test.js +57 -0
- package/tests/utils.js +242 -0
- package/tests/utils.test.js +317 -0
- package/tests/validate-plugin-cli.test.js +359 -0
- package/tests/validation.test.js +837 -0
- package/tests/web-server.test.js +646 -0
- package/tests/widget-arrange-mode.test.js +183 -0
- package/tests/widget-config-hot-reload.test.js +465 -0
- package/tests/widget-dependency.test.js +591 -0
- package/tests/widget-error-boundary.test.js +749 -0
- package/tests/widget-error-isolation.test.js +469 -0
- package/tests/widget-integration.test.js +1147 -0
- package/tests/widget-refresh-intervals.test.js +284 -0
- package/tests/worker-pool.test.js +522 -0
package/docs/API.md
ADDED
|
@@ -0,0 +1,1050 @@
|
|
|
1
|
+
# Claw Dashboard API Documentation
|
|
2
|
+
|
|
3
|
+
This document describes the internal API modules available in Claw Dashboard.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Cache Module](#cache-module)
|
|
8
|
+
- [Gateway Manager](#gateway-manager)
|
|
9
|
+
- [Error Classes](#error-classes)
|
|
10
|
+
- [Logger](#logger)
|
|
11
|
+
- [Configuration](#configuration)
|
|
12
|
+
- [Container Detector](#container-detector)
|
|
13
|
+
- [Worker Pool](#worker-pool)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Cache Module
|
|
18
|
+
|
|
19
|
+
**File:** `src/cache.js`
|
|
20
|
+
|
|
21
|
+
The cache module provides TTL-based caching for expensive system information calls with optional worker thread support.
|
|
22
|
+
|
|
23
|
+
### Functions
|
|
24
|
+
|
|
25
|
+
#### `get(key)`
|
|
26
|
+
|
|
27
|
+
Retrieves a cached value if it exists and hasn't expired.
|
|
28
|
+
|
|
29
|
+
**Parameters:**
|
|
30
|
+
- `key` (string): Cache key
|
|
31
|
+
|
|
32
|
+
**Returns:** `any|null` - The cached value or null if expired/missing
|
|
33
|
+
|
|
34
|
+
**Example:**
|
|
35
|
+
```javascript
|
|
36
|
+
import { get } from './src/cache.js';
|
|
37
|
+
|
|
38
|
+
const cpuData = get('cpu');
|
|
39
|
+
if (cpuData) {
|
|
40
|
+
console.log('Cached CPU:', cpuData);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
#### `set(key, value, ttl?)`
|
|
47
|
+
|
|
48
|
+
Stores a value in the cache with an optional TTL override.
|
|
49
|
+
|
|
50
|
+
**Parameters:**
|
|
51
|
+
- `key` (string): Cache key
|
|
52
|
+
- `value` (any): Value to cache
|
|
53
|
+
- `ttl` (number, optional): Time to live in milliseconds (uses config default if not provided)
|
|
54
|
+
|
|
55
|
+
**Example:**
|
|
56
|
+
```javascript
|
|
57
|
+
import { set } from './src/cache.js';
|
|
58
|
+
|
|
59
|
+
set('cpu', cpuData, 5000); // Cache for 5 seconds
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
#### `getOrFetch(key, fetcher, ttl?)`
|
|
65
|
+
|
|
66
|
+
Gets cached data or fetches fresh data if cache miss.
|
|
67
|
+
|
|
68
|
+
**Parameters:**
|
|
69
|
+
- `key` (string): Cache key
|
|
70
|
+
- `fetcher` (Function): Async function to fetch data if cache miss
|
|
71
|
+
- `ttl` (number, optional): TTL override
|
|
72
|
+
|
|
73
|
+
**Returns:** `Promise<any>` - Cached or fresh data
|
|
74
|
+
|
|
75
|
+
**Example:**
|
|
76
|
+
```javascript
|
|
77
|
+
import { getOrFetch } from './src/cache.js';
|
|
78
|
+
import si from 'systeminformation';
|
|
79
|
+
|
|
80
|
+
const cpuData = await getOrFetch('cpu', async () => {
|
|
81
|
+
return await si.currentLoad();
|
|
82
|
+
}, 1000);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
#### `getCpuData()`
|
|
88
|
+
|
|
89
|
+
Gets cached CPU data or fetches fresh data using worker threads when available.
|
|
90
|
+
|
|
91
|
+
**Returns:** `Promise<Object>` - CPU load data
|
|
92
|
+
|
|
93
|
+
**Example:**
|
|
94
|
+
```javascript
|
|
95
|
+
import { getCpuData } from './src/cache.js';
|
|
96
|
+
|
|
97
|
+
const cpu = await getCpuData();
|
|
98
|
+
console.log(`CPU: ${cpu.currentLoad.toFixed(1)}%`);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
#### `getMemoryData()`
|
|
104
|
+
|
|
105
|
+
Gets cached memory data or fetches fresh data.
|
|
106
|
+
|
|
107
|
+
**Returns:** `Promise<Object>` - Memory data
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
#### `getGpuData()`
|
|
112
|
+
|
|
113
|
+
Gets cached GPU data or fetches fresh data.
|
|
114
|
+
|
|
115
|
+
**Returns:** `Promise<Object>` - GPU/graphics data
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
#### `getNetworkData()`
|
|
120
|
+
|
|
121
|
+
Gets cached network data or fetches fresh data.
|
|
122
|
+
|
|
123
|
+
**Returns:** `Promise<Object>` - Network stats data
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
#### `getDiskData()`
|
|
128
|
+
|
|
129
|
+
Gets cached disk data or fetches fresh data.
|
|
130
|
+
|
|
131
|
+
**Returns:** `Promise<Object>` - Disk size data
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
#### `getSystemData()`
|
|
136
|
+
|
|
137
|
+
Gets cached system info data or fetches fresh data.
|
|
138
|
+
|
|
139
|
+
**Returns:** `Promise<Object>` - System info (osInfo, versions, time)
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
#### `invalidate(key)`
|
|
144
|
+
|
|
145
|
+
Force refreshes a specific cache entry by deleting it.
|
|
146
|
+
|
|
147
|
+
**Parameters:**
|
|
148
|
+
- `key` (string): Cache key to refresh
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
#### `clear()`
|
|
153
|
+
|
|
154
|
+
Clears all cache entries.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
#### `getStatus()`
|
|
159
|
+
|
|
160
|
+
Gets cache status for debugging.
|
|
161
|
+
|
|
162
|
+
**Returns:** `Object` - Cache status info with keys containing:
|
|
163
|
+
- `cached` (boolean): Whether entry exists
|
|
164
|
+
- `age` (number): Age in milliseconds
|
|
165
|
+
- `ttlRemaining` (number): Remaining TTL in milliseconds
|
|
166
|
+
- `configTtl` (number): Configured TTL
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
#### `debounce(fn, delay)`
|
|
171
|
+
|
|
172
|
+
Creates a debounced function that delays execution until after wait period.
|
|
173
|
+
|
|
174
|
+
**Parameters:**
|
|
175
|
+
- `fn` (Function): Function to debounce
|
|
176
|
+
- `delay` (number): Delay in milliseconds
|
|
177
|
+
|
|
178
|
+
**Returns:** `Function` - Debounced function
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
#### `throttle(fn, limit)`
|
|
183
|
+
|
|
184
|
+
Creates a throttled function that limits execution rate.
|
|
185
|
+
|
|
186
|
+
**Parameters:**
|
|
187
|
+
- `fn` (Function): Function to throttle
|
|
188
|
+
- `limit` (number): Minimum interval between calls in ms
|
|
189
|
+
|
|
190
|
+
**Returns:** `Function` - Throttled function
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Gateway Manager
|
|
195
|
+
|
|
196
|
+
**File:** `src/gateway-manager.js`
|
|
197
|
+
|
|
198
|
+
Manages multiple OpenClaw gateway endpoints and aggregates session data.
|
|
199
|
+
|
|
200
|
+
### Class: GatewayManager
|
|
201
|
+
|
|
202
|
+
#### `gatewayManager.init(settings)`
|
|
203
|
+
|
|
204
|
+
Initialize the gateway manager with settings.
|
|
205
|
+
|
|
206
|
+
**Parameters:**
|
|
207
|
+
- `settings` (Object): Dashboard settings containing `gatewayEndpoints` array
|
|
208
|
+
|
|
209
|
+
**Example:**
|
|
210
|
+
```javascript
|
|
211
|
+
import { gatewayManager } from './src/gateway-manager.js';
|
|
212
|
+
|
|
213
|
+
gatewayManager.init({
|
|
214
|
+
gatewayEndpoints: [
|
|
215
|
+
{ name: 'local', host: 'localhost', port: 18789, enabled: true },
|
|
216
|
+
{ name: 'remote', host: '192.168.1.100', port: 18789, token: 'secret', enabled: true }
|
|
217
|
+
]
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
#### `gatewayManager.getEnabledEndpoints()`
|
|
224
|
+
|
|
225
|
+
Gets all enabled endpoints.
|
|
226
|
+
|
|
227
|
+
**Returns:** `GatewayEndpoint[]` - Array of enabled endpoints
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
#### `gatewayManager.getAllEndpoints()`
|
|
232
|
+
|
|
233
|
+
Gets all endpoints (including disabled).
|
|
234
|
+
|
|
235
|
+
**Returns:** `GatewayEndpoint[]` - Array of all endpoints
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
#### `gatewayManager.getEndpoint(name)`
|
|
240
|
+
|
|
241
|
+
Gets a specific endpoint by name.
|
|
242
|
+
|
|
243
|
+
**Parameters:**
|
|
244
|
+
- `name` (string): Endpoint name
|
|
245
|
+
|
|
246
|
+
**Returns:** `GatewayEndpoint|undefined`
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
#### `gatewayManager.addEndpoint(endpointConfig)`
|
|
251
|
+
|
|
252
|
+
Adds a new gateway endpoint.
|
|
253
|
+
|
|
254
|
+
**Parameters:**
|
|
255
|
+
- `endpointConfig` (Object): Endpoint configuration
|
|
256
|
+
- `name` (string): Display name
|
|
257
|
+
- `host` (string): Hostname or IP
|
|
258
|
+
- `port` (number): Port number
|
|
259
|
+
- `token` (string, optional): Authentication token
|
|
260
|
+
- `type` (string): 'local', 'remote', or 'cloud'
|
|
261
|
+
|
|
262
|
+
**Returns:** `GatewayEndpoint|null` - The added endpoint or null if failed
|
|
263
|
+
|
|
264
|
+
**Example:**
|
|
265
|
+
```javascript
|
|
266
|
+
const endpoint = gatewayManager.addEndpoint({
|
|
267
|
+
name: 'prod-server',
|
|
268
|
+
host: '10.0.0.5',
|
|
269
|
+
port: 18789,
|
|
270
|
+
token: 'api-token-here',
|
|
271
|
+
type: 'remote'
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
#### `gatewayManager.removeEndpoint(name)`
|
|
278
|
+
|
|
279
|
+
Removes an endpoint by name.
|
|
280
|
+
|
|
281
|
+
**Parameters:**
|
|
282
|
+
- `name` (string): Endpoint name to remove
|
|
283
|
+
|
|
284
|
+
**Returns:** `boolean` - True if removed, false if not found or last endpoint
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
#### `gatewayManager.updateEndpoint(name, updates)`
|
|
289
|
+
|
|
290
|
+
Updates an existing endpoint.
|
|
291
|
+
|
|
292
|
+
**Parameters:**
|
|
293
|
+
- `name` (string): Endpoint name to update
|
|
294
|
+
- `updates` (Object): Fields to update
|
|
295
|
+
|
|
296
|
+
**Returns:** `GatewayEndpoint|null` - Updated endpoint or null
|
|
297
|
+
|
|
298
|
+
**Example:**
|
|
299
|
+
```javascript
|
|
300
|
+
gatewayManager.updateEndpoint('prod-server', {
|
|
301
|
+
port: 8080,
|
|
302
|
+
token: 'new-token'
|
|
303
|
+
});
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
#### `gatewayManager.toggleEndpoint(name, enabled)`
|
|
309
|
+
|
|
310
|
+
Toggles endpoint enabled state.
|
|
311
|
+
|
|
312
|
+
**Parameters:**
|
|
313
|
+
- `name` (string): Endpoint name
|
|
314
|
+
- `enabled` (boolean): New enabled state
|
|
315
|
+
|
|
316
|
+
**Returns:** `boolean` - True if toggled, false if not found
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
#### `gatewayManager.fetchAllSessions()`
|
|
321
|
+
|
|
322
|
+
Fetches sessions from all enabled endpoints in parallel.
|
|
323
|
+
|
|
324
|
+
**Returns:** `Promise<Object>` - Object containing:
|
|
325
|
+
- `sessions` (AggregatedSession[]): All sessions from all endpoints
|
|
326
|
+
- `stats` (Object): Fetch statistics
|
|
327
|
+
- `totalEndpoints` (number): Total enabled endpoints
|
|
328
|
+
- `reachableEndpoints` (number): Successfully reached endpoints
|
|
329
|
+
- `unreachableEndpoints` (number): Failed endpoints
|
|
330
|
+
|
|
331
|
+
**Example:**
|
|
332
|
+
```javascript
|
|
333
|
+
const { sessions, stats } = await gatewayManager.fetchAllSessions();
|
|
334
|
+
console.log(`Fetched ${sessions.length} sessions from ${stats.reachableEndpoints} endpoints`);
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
#### `gatewayManager.getEndpointHealth()`
|
|
340
|
+
|
|
341
|
+
Gets health status for all endpoints.
|
|
342
|
+
|
|
343
|
+
**Returns:** `Object[]` - Array of endpoint health objects containing:
|
|
344
|
+
- `name` (string): Endpoint name
|
|
345
|
+
- `host` (string): Host
|
|
346
|
+
- `port` (number): Port
|
|
347
|
+
- `enabled` (boolean): Enabled state
|
|
348
|
+
- `reachable` (boolean): Last known reachability
|
|
349
|
+
- `lastSeen` (number|null): Timestamp of last successful connection
|
|
350
|
+
- `latency` (number|null): Response latency in ms
|
|
351
|
+
- `failCount` (number): Consecutive failure count
|
|
352
|
+
- `error` (string|null): Last error message
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
#### `gatewayManager.getSettingsForSave()`
|
|
357
|
+
|
|
358
|
+
Gets settings object for persistence.
|
|
359
|
+
|
|
360
|
+
**Returns:** `Object` - Settings containing `gatewayEndpoints` array
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
### Types
|
|
365
|
+
|
|
366
|
+
#### `GatewayEndpoint`
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
{
|
|
370
|
+
name: string; // Display name
|
|
371
|
+
host: string; // Hostname or IP
|
|
372
|
+
port: number; // Port number
|
|
373
|
+
token: string | null; // Auth token
|
|
374
|
+
enabled: boolean; // Whether enabled
|
|
375
|
+
type: string; // 'local', 'remote', 'cloud'
|
|
376
|
+
reachable?: boolean; // Last known status
|
|
377
|
+
lastSeen?: number; // Timestamp
|
|
378
|
+
error?: string; // Last error
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
#### `AggregatedSession`
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
{
|
|
386
|
+
key: string;
|
|
387
|
+
channel: string;
|
|
388
|
+
displayName: string;
|
|
389
|
+
updatedAt: number;
|
|
390
|
+
sessionId: string;
|
|
391
|
+
model: string;
|
|
392
|
+
contextTokens: number;
|
|
393
|
+
totalTokens: number;
|
|
394
|
+
kind: string;
|
|
395
|
+
gatewayEndpoint: string; // Source endpoint name
|
|
396
|
+
gatewayHost: string; // Source endpoint host
|
|
397
|
+
// ... other session fields
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
#### `gatewayManager.forceRetry(endpointName?)`
|
|
404
|
+
|
|
405
|
+
Force a retry for a specific endpoint or all unreachable endpoints.
|
|
406
|
+
|
|
407
|
+
**Parameters:**
|
|
408
|
+
- `endpointName` (string|null): Name of endpoint to retry, or null for all unreachable
|
|
409
|
+
|
|
410
|
+
**Returns:** `Promise<Object>` - Result containing:
|
|
411
|
+
- `attempted` (number): Number of endpoints attempted
|
|
412
|
+
- `successful` (number): Number of endpoints that reconnected
|
|
413
|
+
- `results` (Array): Per-endpoint results
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
#### `gatewayManager.getEndpointFailCount(name)`
|
|
418
|
+
|
|
419
|
+
Gets the consecutive failure count for an endpoint.
|
|
420
|
+
|
|
421
|
+
**Parameters:**
|
|
422
|
+
- `name` (string): Endpoint name
|
|
423
|
+
|
|
424
|
+
**Returns:** `number` - Consecutive failure count
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
#### `gatewayManager.clearEndpointFailCount(name)`
|
|
429
|
+
|
|
430
|
+
Clears the failure count for a specific endpoint.
|
|
431
|
+
|
|
432
|
+
**Parameters:**
|
|
433
|
+
- `name` (string): Endpoint name
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
#### `gatewayManager.getTotalFailCount()`
|
|
438
|
+
|
|
439
|
+
Gets the total failure count across all endpoints.
|
|
440
|
+
|
|
441
|
+
**Returns:** `number` - Total consecutive failures
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
#### `gatewayManager.clearAllFailCounts()`
|
|
446
|
+
|
|
447
|
+
Clears all failure counts for all endpoints.
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Auto-Retry Configuration
|
|
452
|
+
|
|
453
|
+
**File:** `src/config.js` (constants), `index.js` (implementation)
|
|
454
|
+
|
|
455
|
+
The dashboard automatically retries failed gateway connections with configurable exponential backoff to prevent overwhelming unresponsive gateways.
|
|
456
|
+
|
|
457
|
+
### Configuration Options
|
|
458
|
+
|
|
459
|
+
Add an `autoRetry` section to your `~/.openclaw/dashboard-settings.json`:
|
|
460
|
+
|
|
461
|
+
```json
|
|
462
|
+
{
|
|
463
|
+
"autoRetry": {
|
|
464
|
+
"enabled": true,
|
|
465
|
+
"intervalMs": 30000,
|
|
466
|
+
"exponentialBackoff": true,
|
|
467
|
+
"backoffMultiplier": 2,
|
|
468
|
+
"maxBackoffIntervalMs": 300000,
|
|
469
|
+
"resetAfterSuccess": true,
|
|
470
|
+
"consecutiveFailureThreshold": 3
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### Options Reference
|
|
476
|
+
|
|
477
|
+
| Option | Type | Default | Description |
|
|
478
|
+
|--------|------|---------|-------------|
|
|
479
|
+
| `enabled` | boolean | `true` | Enable/disable auto-retry |
|
|
480
|
+
| `intervalMs` | number | `30000` | Base interval between retries (ms) |
|
|
481
|
+
| `exponentialBackoff` | boolean | `true` | Enable exponential backoff |
|
|
482
|
+
| `backoffMultiplier` | number | `2` | Multiply interval by this after each failure |
|
|
483
|
+
| `maxBackoffIntervalMs` | number | `300000` | Cap backoff at this value (5 min) |
|
|
484
|
+
| `resetAfterSuccess` | boolean | `true` | Reset backoff after successful connection |
|
|
485
|
+
| `consecutiveFailureThreshold` | number | `3` | Failures before backoff kicks in |
|
|
486
|
+
|
|
487
|
+
### Exponential Backoff Behavior
|
|
488
|
+
|
|
489
|
+
When `exponentialBackoff` is enabled:
|
|
490
|
+
|
|
491
|
+
1. First 2 failures: Retry at `intervalMs` (30s)
|
|
492
|
+
2. 3rd failure: Retry at `30s × 2 = 60s`
|
|
493
|
+
3. 4th failure: Retry at `30s × 2² = 120s`
|
|
494
|
+
4. 5th failure: Retry at `30s × 2³ = 240s`
|
|
495
|
+
5. And so on, up to `maxBackoffIntervalMs` (5 min)
|
|
496
|
+
|
|
497
|
+
After a successful connection, if `resetAfterSuccess` is true, the backoff resets to the base interval.
|
|
498
|
+
|
|
499
|
+
### Validation Constraints
|
|
500
|
+
|
|
501
|
+
- `intervalMs`: 5000ms (5s) to 300000ms (5min)
|
|
502
|
+
- `backoffMultiplier`: 1 to 10
|
|
503
|
+
- `maxBackoffIntervalMs`: 10000ms (10s) to 600000ms (10min)
|
|
504
|
+
- `consecutiveFailureThreshold`: 1 to 10
|
|
505
|
+
|
|
506
|
+
### Disabling Auto-Retry
|
|
507
|
+
|
|
508
|
+
To disable auto-retry completely:
|
|
509
|
+
|
|
510
|
+
```json
|
|
511
|
+
{
|
|
512
|
+
"autoRetry": {
|
|
513
|
+
"enabled": false
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## Troubleshooting Gateway Connectivity
|
|
521
|
+
|
|
522
|
+
### Common Issues
|
|
523
|
+
|
|
524
|
+
#### "Gateway unreachable" warnings
|
|
525
|
+
|
|
526
|
+
The dashboard shows yellow/red status for gateways it cannot reach. Check:
|
|
527
|
+
|
|
528
|
+
1. **Is the OpenClaw agent running?**
|
|
529
|
+
```bash
|
|
530
|
+
# Check if agent is listening
|
|
531
|
+
curl http://localhost:18789/sessions
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
2. **Is the correct host/port configured?**
|
|
535
|
+
Verify your `gatewayEndpoints` configuration in settings.
|
|
536
|
+
|
|
537
|
+
3. **Network/firewall issues?**
|
|
538
|
+
Remote gateways may require VPN or specific network access.
|
|
539
|
+
|
|
540
|
+
#### Auto-retry not working
|
|
541
|
+
|
|
542
|
+
1. **Check if auto-retry is enabled:**
|
|
543
|
+
Verify `autoRetry.enabled` is `true` in settings.
|
|
544
|
+
|
|
545
|
+
2. **Verify interval settings:**
|
|
546
|
+
Default is 30 seconds. If you set it higher, retries will be less frequent.
|
|
547
|
+
|
|
548
|
+
3. **Check logs for retry attempts:**
|
|
549
|
+
Look for `[RETRY]` log messages indicating retry activity.
|
|
550
|
+
|
|
551
|
+
#### Excessive retry delays
|
|
552
|
+
|
|
553
|
+
If gateways are retrying too slowly:
|
|
554
|
+
|
|
555
|
+
1. **Reduce the backoff multiplier:**
|
|
556
|
+
```json
|
|
557
|
+
{ "backoffMultiplier": 1.5 }
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
2. **Lower the max backoff:**
|
|
561
|
+
```json
|
|
562
|
+
{ "maxBackoffIntervalMs": 60000 }
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
3. **Lower the failure threshold:**
|
|
566
|
+
```json
|
|
567
|
+
{ "consecutiveFailureThreshold": 1 }
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### Force Retry
|
|
571
|
+
|
|
572
|
+
Manually trigger a retry from the dashboard:
|
|
573
|
+
|
|
574
|
+
1. Press `r` to retry all unreachable gateways immediately
|
|
575
|
+
2. Or use the Gateway Status widget to retry individual endpoints
|
|
576
|
+
|
|
577
|
+
### Debug Logging
|
|
578
|
+
|
|
579
|
+
Enable debug logging to see detailed retry behavior:
|
|
580
|
+
|
|
581
|
+
```bash
|
|
582
|
+
# Start with debug logging
|
|
583
|
+
DEBUG=claw-dashboard npm start
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
Or set in settings:
|
|
587
|
+
```json
|
|
588
|
+
{ "logLevelFilter": "debug" }
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
## Error Classes
|
|
594
|
+
|
|
595
|
+
**File:** `src/errors.js`
|
|
596
|
+
|
|
597
|
+
Custom error classes for better error handling and debugging.
|
|
598
|
+
|
|
599
|
+
### Base Class: DashboardError
|
|
600
|
+
|
|
601
|
+
All dashboard errors extend this base class.
|
|
602
|
+
|
|
603
|
+
**Properties:**
|
|
604
|
+
- `name` (string): Error name
|
|
605
|
+
- `message` (string): Error message
|
|
606
|
+
- `code` (string): Error code constant
|
|
607
|
+
- `details` (Object): Additional error details
|
|
608
|
+
- `timestamp` (string): ISO timestamp
|
|
609
|
+
- `stack` (string): Stack trace
|
|
610
|
+
|
|
611
|
+
**Method:** `toJSON()`
|
|
612
|
+
|
|
613
|
+
Returns a JSON-serializable representation of the error.
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
### Error Types
|
|
618
|
+
|
|
619
|
+
| Class | Code | Use Case |
|
|
620
|
+
|-------|------|----------|
|
|
621
|
+
| `ConfigError` | `CONFIG_ERROR` | Configuration issues |
|
|
622
|
+
| `SettingsError` | `SETTINGS_ERROR` | Settings load/save errors |
|
|
623
|
+
| `GatewayError` | `GATEWAY_ERROR` | Gateway communication |
|
|
624
|
+
| `SessionError` | `SESSION_ERROR` | Session-related errors |
|
|
625
|
+
| `DataFetchError` | `DATA_FETCH_ERROR` | System info fetch failures |
|
|
626
|
+
| `AuthError` | `AUTH_ERROR` | Authentication failures |
|
|
627
|
+
| `NetworkError` | `NETWORK_ERROR` | Network issues |
|
|
628
|
+
| `UIError` | `UI_ERROR` | UI/rendering errors |
|
|
629
|
+
| `DatabaseError` | `DATABASE_ERROR` | Database operations |
|
|
630
|
+
| `ValidationError` | `VALIDATION_ERROR` | Input validation |
|
|
631
|
+
| `TimeoutError` | `TIMEOUT_ERROR` | Operation timeouts |
|
|
632
|
+
|
|
633
|
+
---
|
|
634
|
+
|
|
635
|
+
### Helper Functions
|
|
636
|
+
|
|
637
|
+
#### `isDashboardError(error)`
|
|
638
|
+
|
|
639
|
+
Checks if an error is a DashboardError instance.
|
|
640
|
+
|
|
641
|
+
**Parameters:**
|
|
642
|
+
- `error` (Error): Error to check
|
|
643
|
+
|
|
644
|
+
**Returns:** `boolean`
|
|
645
|
+
|
|
646
|
+
---
|
|
647
|
+
|
|
648
|
+
#### `getErrorCode(error)`
|
|
649
|
+
|
|
650
|
+
Gets the error code from a DashboardError or returns 'UNKNOWN_ERROR'.
|
|
651
|
+
|
|
652
|
+
**Parameters:**
|
|
653
|
+
- `error` (Error): Error to check
|
|
654
|
+
|
|
655
|
+
**Returns:** `string`
|
|
656
|
+
|
|
657
|
+
---
|
|
658
|
+
|
|
659
|
+
### Constants
|
|
660
|
+
|
|
661
|
+
#### `ERROR_CODES`
|
|
662
|
+
|
|
663
|
+
Object containing all error code constants:
|
|
664
|
+
|
|
665
|
+
```javascript
|
|
666
|
+
import { ERROR_CODES } from './src/errors.js';
|
|
667
|
+
|
|
668
|
+
// Available codes:
|
|
669
|
+
// CONFIG_ERROR, SETTINGS_ERROR, GATEWAY_ERROR, SESSION_ERROR,
|
|
670
|
+
// DATA_FETCH_ERROR, AUTH_ERROR, NETWORK_ERROR, UI_ERROR,
|
|
671
|
+
// DATABASE_ERROR, VALIDATION_ERROR, TIMEOUT_ERROR, DASHBOARD_ERROR
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
---
|
|
675
|
+
|
|
676
|
+
## Logger
|
|
677
|
+
|
|
678
|
+
**File:** `src/logger.js`
|
|
679
|
+
|
|
680
|
+
File-only logging module that avoids interfering with the blessed TUI.
|
|
681
|
+
|
|
682
|
+
**Log Location:** `~/.openclaw/claw-dashboard.log`
|
|
683
|
+
|
|
684
|
+
### Methods
|
|
685
|
+
|
|
686
|
+
#### `logger.error(...args)`
|
|
687
|
+
|
|
688
|
+
Logs error level messages.
|
|
689
|
+
|
|
690
|
+
**Example:**
|
|
691
|
+
```javascript
|
|
692
|
+
import logger from './src/logger.js';
|
|
693
|
+
|
|
694
|
+
logger.error('Failed to fetch sessions:', error.message);
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
---
|
|
698
|
+
|
|
699
|
+
#### `logger.warn(...args)`
|
|
700
|
+
|
|
701
|
+
Logs warning level messages.
|
|
702
|
+
|
|
703
|
+
---
|
|
704
|
+
|
|
705
|
+
#### `logger.info(...args)`
|
|
706
|
+
|
|
707
|
+
Logs info level messages.
|
|
708
|
+
|
|
709
|
+
---
|
|
710
|
+
|
|
711
|
+
#### `logger.debug(...args)`
|
|
712
|
+
|
|
713
|
+
Logs debug level messages (only when `DEBUG` env var is set).
|
|
714
|
+
|
|
715
|
+
**Example:**
|
|
716
|
+
```bash
|
|
717
|
+
DEBUG=1 node index.js
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
---
|
|
721
|
+
|
|
722
|
+
### Export: `LOG_FILE_PATH`
|
|
723
|
+
|
|
724
|
+
The full path to the log file.
|
|
725
|
+
|
|
726
|
+
```javascript
|
|
727
|
+
import { LOG_FILE_PATH } from './src/logger.js';
|
|
728
|
+
console.log('Logs at:', LOG_FILE_PATH);
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
---
|
|
732
|
+
|
|
733
|
+
## Configuration
|
|
734
|
+
|
|
735
|
+
**File:** `src/config.js`
|
|
736
|
+
|
|
737
|
+
Centralized configuration containing all constants and defaults.
|
|
738
|
+
|
|
739
|
+
### Refresh Intervals
|
|
740
|
+
|
|
741
|
+
```javascript
|
|
742
|
+
import { REFRESH_INTERVALS } from './src/config.js';
|
|
743
|
+
|
|
744
|
+
REFRESH_INTERVALS.DEFAULT // 2000ms
|
|
745
|
+
REFRESH_INTERVALS.ACTIVE // 2000ms
|
|
746
|
+
REFRESH_INTERVALS.IDLE // 10000ms
|
|
747
|
+
REFRESH_INTERVALS.OPTIONS // [1000, 2000, 5000, 10000]
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
### Gateway Settings
|
|
751
|
+
|
|
752
|
+
```javascript
|
|
753
|
+
import { GATEWAY, DEFAULT_GATEWAY_ENDPOINT } from './src/config.js';
|
|
754
|
+
|
|
755
|
+
GATEWAY.DEFAULT_PORT // 18789
|
|
756
|
+
GATEWAY.TIMEOUT_MS // 3000
|
|
757
|
+
GATEWAY.MAX_ENDPOINTS // 10
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
### Cache TTL
|
|
761
|
+
|
|
762
|
+
```javascript
|
|
763
|
+
import { CACHE_TTL, CACHE_CONFIG } from './src/config.js';
|
|
764
|
+
|
|
765
|
+
CACHE_TTL.CPU // 1000ms
|
|
766
|
+
CACHE_TTL.MEMORY // 1000ms
|
|
767
|
+
CACHE_TTL.GPU // 5000ms
|
|
768
|
+
CACHE_TTL.NETWORK // 1000ms
|
|
769
|
+
CACHE_TTL.DISK // 30000ms
|
|
770
|
+
CACHE_TTL.SYSTEM // 5000ms
|
|
771
|
+
CACHE_TTL.CONTAINER // 30000ms
|
|
772
|
+
CACHE_TTL.DEFAULT // 2000ms
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
### Alert Thresholds
|
|
776
|
+
|
|
777
|
+
```javascript
|
|
778
|
+
import { ALERT_THRESHOLDS, ALERT_RATE_LIMIT } from './src/config.js';
|
|
779
|
+
|
|
780
|
+
ALERT_THRESHOLDS.CPU // { warning: 70, critical: 90 }
|
|
781
|
+
ALERT_THRESHOLDS.MEMORY // { warning: 75, critical: 90 }
|
|
782
|
+
ALERT_THRESHOLDS.DISK // { warning: 80, critical: 95 }
|
|
783
|
+
|
|
784
|
+
ALERT_RATE_LIMIT.ENABLED // true
|
|
785
|
+
ALERT_RATE_LIMIT.WINDOW_MS // 60000
|
|
786
|
+
ALERT_RATE_LIMIT.MAX_ALERTS // 5
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
### Validation Constraints
|
|
790
|
+
|
|
791
|
+
```javascript
|
|
792
|
+
import { VALIDATION } from './src/config.js';
|
|
793
|
+
|
|
794
|
+
VALIDATION.REFRESH_INTERVAL.MIN // 500
|
|
795
|
+
VALIDATION.REFRESH_INTERVAL.MAX // 60000
|
|
796
|
+
VALIDATION.VALID_THEMES // ['default', 'dark', 'high-contrast', 'ocean', 'auto']
|
|
797
|
+
VALIDATION.VALID_SORT_MODES // ['time', 'tokens', 'idle', 'name']
|
|
798
|
+
VALIDATION.ENDPOINT_NAME.PATTERN // /^[a-zA-Z0-9_-]+$/
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
### Worker Settings
|
|
802
|
+
|
|
803
|
+
```javascript
|
|
804
|
+
import { WORKERS } from './src/config.js';
|
|
805
|
+
|
|
806
|
+
WORKERS.ENABLED // true
|
|
807
|
+
WORKERS.MAX_WORKERS // 2
|
|
808
|
+
WORKERS.TASK_TIMEOUT // 10000
|
|
809
|
+
WORKERS.FALLBACK_ON_ERROR // true
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
### Paths
|
|
813
|
+
|
|
814
|
+
```javascript
|
|
815
|
+
import { PATHS } from './src/config.js';
|
|
816
|
+
|
|
817
|
+
PATHS.SETTINGS // ~/.openclaw/dashboard-settings.json
|
|
818
|
+
PATHS.EXPORTS // ~/.openclaw/exports
|
|
819
|
+
PATHS.LOG // ~/.openclaw/claw-dashboard.log
|
|
820
|
+
PATHS.HOME_DIR // ~
|
|
821
|
+
PATHS.OPENCLAW_DIR // ~/.openclaw
|
|
822
|
+
PATHS.AGENTS_DIR // ~/.openclaw/agents
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
### Default Settings
|
|
826
|
+
|
|
827
|
+
```javascript
|
|
828
|
+
import { DEFAULT_SETTINGS } from './src/config.js';
|
|
829
|
+
|
|
830
|
+
// Complete default settings object for dashboard initialization
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
### Version
|
|
834
|
+
|
|
835
|
+
```javascript
|
|
836
|
+
import { DASHBOARD_VERSION } from './src/config.js';
|
|
837
|
+
|
|
838
|
+
console.log('Version:', DASHBOARD_VERSION); // e.g., "1.9.0"
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
---
|
|
842
|
+
|
|
843
|
+
## Container Detector
|
|
844
|
+
|
|
845
|
+
**File:** `src/container-detector.js`
|
|
846
|
+
|
|
847
|
+
Detects containerized environments (Docker, Kubernetes, WSL).
|
|
848
|
+
|
|
849
|
+
### Functions
|
|
850
|
+
|
|
851
|
+
#### `detectContainerEnvironment()`
|
|
852
|
+
|
|
853
|
+
Detects if running in a container environment.
|
|
854
|
+
|
|
855
|
+
**Returns:** `Promise<ContainerEnvironment>`
|
|
856
|
+
|
|
857
|
+
```typescript
|
|
858
|
+
{
|
|
859
|
+
isContainer: boolean;
|
|
860
|
+
runtime: string | null; // 'docker', 'kubernetes', 'containerd', etc.
|
|
861
|
+
containerId: string | null;
|
|
862
|
+
containerName: string | null;
|
|
863
|
+
podName: string | null;
|
|
864
|
+
namespace: string | null;
|
|
865
|
+
wslVersion: number | null; // 1 or 2 for WSL
|
|
866
|
+
wslDistro: string | null; // WSL distribution name
|
|
867
|
+
}
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
**Example:**
|
|
871
|
+
```javascript
|
|
872
|
+
import { detectContainerEnvironment } from './src/container-detector.js';
|
|
873
|
+
|
|
874
|
+
const env = await detectContainerEnvironment();
|
|
875
|
+
if (env.isContainer) {
|
|
876
|
+
console.log(`Running in ${env.runtime}`);
|
|
877
|
+
if (env.wslVersion) {
|
|
878
|
+
console.log(`WSL${env.wslVersion} - ${env.wslDistro}`);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
---
|
|
884
|
+
|
|
885
|
+
#### `checkDocker()`
|
|
886
|
+
|
|
887
|
+
Checks if running inside a Docker container.
|
|
888
|
+
|
|
889
|
+
**Returns:** `Promise<Object|null>` - Container info or null
|
|
890
|
+
|
|
891
|
+
---
|
|
892
|
+
|
|
893
|
+
#### `checkKubernetes()`
|
|
894
|
+
|
|
895
|
+
Checks if running inside a Kubernetes pod.
|
|
896
|
+
|
|
897
|
+
**Returns:** `Promise<Object|null>` - Pod info or null
|
|
898
|
+
|
|
899
|
+
---
|
|
900
|
+
|
|
901
|
+
#### `checkWSL()`
|
|
902
|
+
|
|
903
|
+
Checks if running in WSL (Windows Subsystem for Linux).
|
|
904
|
+
|
|
905
|
+
**Returns:** `Promise<Object|null>` - WSL info or null
|
|
906
|
+
|
|
907
|
+
---
|
|
908
|
+
|
|
909
|
+
## Worker Pool
|
|
910
|
+
|
|
911
|
+
**File:** `src/workers/worker-pool.js`
|
|
912
|
+
|
|
913
|
+
Manages worker threads for executing heavy systeminformation commands off the main thread.
|
|
914
|
+
|
|
915
|
+
### Class: WorkerPool
|
|
916
|
+
|
|
917
|
+
#### `workerPool.execute(command)`
|
|
918
|
+
|
|
919
|
+
Execute a systeminformation command in a worker thread.
|
|
920
|
+
|
|
921
|
+
**Parameters:**
|
|
922
|
+
- `command` (string): Command name
|
|
923
|
+
- `'currentLoad'` - CPU load
|
|
924
|
+
- `'mem'` - Memory info
|
|
925
|
+
- `'graphics'` - GPU info
|
|
926
|
+
- `'networkStats'` - Network stats
|
|
927
|
+
- `'fsSize'` - Filesystem size
|
|
928
|
+
- `'systemData'` - OS info, versions, time
|
|
929
|
+
- `'processes'` - Process list
|
|
930
|
+
- `'diskLayout'` - Disk layout
|
|
931
|
+
- `'battery'` - Battery info
|
|
932
|
+
- `'users'` - User list
|
|
933
|
+
|
|
934
|
+
**Returns:** `Promise<any>` - Command result
|
|
935
|
+
|
|
936
|
+
**Example:**
|
|
937
|
+
```javascript
|
|
938
|
+
import { workerPool } from './src/workers/worker-pool.js';
|
|
939
|
+
|
|
940
|
+
try {
|
|
941
|
+
const cpuData = await workerPool.execute('currentLoad');
|
|
942
|
+
console.log('CPU Load:', cpuData.currentLoad);
|
|
943
|
+
} catch (error) {
|
|
944
|
+
console.error('Worker failed:', error);
|
|
945
|
+
}
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
---
|
|
949
|
+
|
|
950
|
+
#### `workerPool.terminate()`
|
|
951
|
+
|
|
952
|
+
Gracefully terminates all worker threads.
|
|
953
|
+
|
|
954
|
+
**Returns:** `Promise<void>`
|
|
955
|
+
|
|
956
|
+
---
|
|
957
|
+
|
|
958
|
+
### Export: `isWorkerThreadsSupported`
|
|
959
|
+
|
|
960
|
+
Boolean indicating if worker threads are supported in the current Node.js environment.
|
|
961
|
+
|
|
962
|
+
```javascript
|
|
963
|
+
import { isWorkerThreadsSupported } from './src/workers/worker-pool.js';
|
|
964
|
+
|
|
965
|
+
if (isWorkerThreadsSupported) {
|
|
966
|
+
// Can use worker threads
|
|
967
|
+
}
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
---
|
|
971
|
+
|
|
972
|
+
## Usage Examples
|
|
973
|
+
|
|
974
|
+
### Complete Dashboard Setup
|
|
975
|
+
|
|
976
|
+
```javascript
|
|
977
|
+
import { gatewayManager } from './src/gateway-manager.js';
|
|
978
|
+
import logger from './src/logger.js';
|
|
979
|
+
import { DEFAULT_SETTINGS } from './src/config.js';
|
|
980
|
+
|
|
981
|
+
// Initialize gateway manager
|
|
982
|
+
gatewayManager.init(DEFAULT_SETTINGS);
|
|
983
|
+
|
|
984
|
+
// Add a remote endpoint
|
|
985
|
+
const endpoint = gatewayManager.addEndpoint({
|
|
986
|
+
name: 'production',
|
|
987
|
+
host: 'prod.example.com',
|
|
988
|
+
port: 18789,
|
|
989
|
+
token: process.env.OPENCLAW_TOKEN,
|
|
990
|
+
type: 'remote'
|
|
991
|
+
});
|
|
992
|
+
|
|
993
|
+
if (endpoint) {
|
|
994
|
+
logger.info('Added production endpoint');
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
// Fetch all sessions
|
|
998
|
+
try {
|
|
999
|
+
const { sessions, stats } = await gatewayManager.fetchAllSessions();
|
|
1000
|
+
logger.info(`Fetched ${sessions.length} sessions from ${stats.reachableEndpoints} endpoints`);
|
|
1001
|
+
} catch (error) {
|
|
1002
|
+
logger.error('Failed to fetch sessions:', error.message);
|
|
1003
|
+
}
|
|
1004
|
+
```
|
|
1005
|
+
|
|
1006
|
+
### Error Handling Pattern
|
|
1007
|
+
|
|
1008
|
+
```javascript
|
|
1009
|
+
import {
|
|
1010
|
+
isDashboardError,
|
|
1011
|
+
getErrorCode,
|
|
1012
|
+
ERROR_CODES,
|
|
1013
|
+
GatewayError,
|
|
1014
|
+
NetworkError
|
|
1015
|
+
} from './src/errors.js';
|
|
1016
|
+
import logger from './src/logger.js';
|
|
1017
|
+
|
|
1018
|
+
async function fetchWithErrorHandling() {
|
|
1019
|
+
try {
|
|
1020
|
+
return await fetchData();
|
|
1021
|
+
} catch (error) {
|
|
1022
|
+
if (isDashboardError(error)) {
|
|
1023
|
+
const code = getErrorCode(error);
|
|
1024
|
+
|
|
1025
|
+
switch (code) {
|
|
1026
|
+
case ERROR_CODES.GATEWAY_ERROR:
|
|
1027
|
+
logger.warn('Gateway unavailable:', error.message);
|
|
1028
|
+
return null;
|
|
1029
|
+
case ERROR_CODES.NETWORK_ERROR:
|
|
1030
|
+
logger.warn('Network issue:', error.message);
|
|
1031
|
+
return null;
|
|
1032
|
+
default:
|
|
1033
|
+
logger.error('Dashboard error:', error.toJSON());
|
|
1034
|
+
throw error;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
// Re-throw non-dashboard errors
|
|
1039
|
+
throw error;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
---
|
|
1045
|
+
|
|
1046
|
+
## See Also
|
|
1047
|
+
|
|
1048
|
+
- [README.md](../README.md) - Project overview
|
|
1049
|
+
- [CHANGELOG.md](../CHANGELOG.md) - Version history
|
|
1050
|
+
- [TODO.md](../TODO.md) - Planned features and known issues
|