@darksol/terminal 0.14.1 → 0.14.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darksol/terminal",
3
- "version": "0.14.1",
3
+ "version": "0.14.2",
4
4
  "description": "DARKSOL Terminal — unified CLI for all DARKSOL services. Market intel, trading, oracle, casino, and more.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -26,6 +26,7 @@ import { casinoBet, casinoTables, casinoStats, casinoReceipt, casinoHealth, casi
26
26
  import { pokerNewGame, pokerAction, pokerStatus, pokerHistory } from './services/poker.js';
27
27
  import { cardsCatalog, cardsOrder, cardsStatus } from './services/cards.js';
28
28
  import { facilitatorHealth, facilitatorVerify, facilitatorSettle } from './services/facilitator.js';
29
+ import { healthCommand } from './services/health.js';
29
30
  import { buildersLeaderboard, buildersLookup, buildersFeed } from './services/builders.js';
30
31
  import { createScript, listScripts, runScript, showScript, editScript, deleteScript, cloneScript, listTemplates } from './scripts/engine.js';
31
32
  import {
@@ -1712,6 +1713,14 @@ export function cli(argv) {
1712
1713
  }
1713
1714
  });
1714
1715
 
1716
+ // ═══════════════════════════════════════
1717
+ // HEALTH CHECK
1718
+ // ═══════════════════════════════════════
1719
+ program
1720
+ .command('health')
1721
+ .description('Check status of all DARKSOL services')
1722
+ .action(() => healthCommand());
1723
+
1715
1724
  program
1716
1725
  .command('dash')
1717
1726
  .description('Launch the live terminal dashboard')
@@ -0,0 +1,131 @@
1
+ import fetch from 'node-fetch';
2
+ import { getServiceURL } from '../config/store.js';
3
+ import { theme } from '../ui/theme.js';
4
+ import { spinner, kvDisplay, success, error, info, table } from '../ui/components.js';
5
+ import { showSection } from '../ui/banner.js';
6
+
7
+ // Service definitions — each has a name, URL resolver, and endpoint to ping
8
+ const SERVICES = [
9
+ {
10
+ name: 'Facilitator',
11
+ url: () => (getServiceURL('facilitator') || 'https://facilitator.darksol.net') + '/',
12
+ desc: 'x402 payment facilitator',
13
+ },
14
+ {
15
+ name: 'Casino',
16
+ url: () => (getServiceURL('casino') || 'https://casino.darksol.net') + '/api/stats',
17
+ desc: 'On-chain casino',
18
+ },
19
+ {
20
+ name: 'Oracle',
21
+ url: () => (getServiceURL('oracle') || 'https://acp.darksol.net/api/oracle') + '/health',
22
+ desc: 'Random oracle (x402)',
23
+ },
24
+ {
25
+ name: 'Cards',
26
+ url: () => (getServiceURL('cards') || 'https://acp.darksol.net') + '/api/cards/catalog',
27
+ desc: 'Prepaid crypto cards',
28
+ },
29
+ {
30
+ name: 'LI.FI',
31
+ url: () => 'https://li.quest/v1/status',
32
+ desc: 'Cross-chain swaps & bridges',
33
+ },
34
+ {
35
+ name: 'Agent Signer',
36
+ url: () => 'http://127.0.0.1:18790/status',
37
+ desc: 'Local signing proxy',
38
+ },
39
+ ];
40
+
41
+ const TIMEOUT_MS = 5000;
42
+
43
+ /**
44
+ * Ping a single service endpoint.
45
+ * Returns { name, url, status: 'up'|'down'|'timeout', responseMs, error? }
46
+ */
47
+ async function pingService(service) {
48
+ const url = service.url();
49
+ const start = Date.now();
50
+
51
+ try {
52
+ const controller = new AbortController();
53
+ const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
54
+
55
+ const resp = await fetch(url, { signal: controller.signal });
56
+ clearTimeout(timer);
57
+
58
+ const responseMs = Date.now() - start;
59
+
60
+ if (resp.ok || resp.status < 500) {
61
+ return { name: service.name, url, status: 'up', responseMs, desc: service.desc };
62
+ }
63
+ return { name: service.name, url, status: 'down', responseMs, desc: service.desc, error: `HTTP ${resp.status}` };
64
+ } catch (err) {
65
+ const responseMs = Date.now() - start;
66
+ if (err.name === 'AbortError') {
67
+ return { name: service.name, url, status: 'timeout', responseMs, desc: service.desc, error: 'Timed out' };
68
+ }
69
+ // Connection refused, DNS failure, etc.
70
+ const msg = err.code === 'ECONNREFUSED' ? 'Connection refused' : (err.message || 'Unknown error');
71
+ return { name: service.name, url, status: 'down', responseMs, desc: service.desc, error: msg };
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Check health of all configured services.
77
+ * Returns array of results.
78
+ */
79
+ export async function checkHealth() {
80
+ return Promise.all(SERVICES.map(s => pingService(s)));
81
+ }
82
+
83
+ /**
84
+ * CLI handler — check all services and display results.
85
+ */
86
+ export async function healthCommand() {
87
+ showSection('SERVICE HEALTH CHECK 🏥');
88
+ const spin = spinner('Checking all services...').start();
89
+
90
+ const results = await checkHealth();
91
+ spin.stop();
92
+
93
+ // Status indicators
94
+ const statusIcon = (s) => {
95
+ if (s === 'up') return theme.success('● UP');
96
+ if (s === 'timeout') return theme.warning('◐ TIMEOUT');
97
+ return theme.error('○ DOWN');
98
+ };
99
+
100
+ const latencyColor = (ms) => {
101
+ if (ms < 300) return theme.success(`${ms}ms`);
102
+ if (ms < 1000) return theme.warning(`${ms}ms`);
103
+ return theme.error(`${ms}ms`);
104
+ };
105
+
106
+ // Display table
107
+ const headers = ['Service', 'Status', 'Latency', 'Details'];
108
+ const rows = results.map(r => [
109
+ theme.bright(r.name),
110
+ statusIcon(r.status),
111
+ latencyColor(r.responseMs),
112
+ r.status === 'up' ? theme.dim(r.desc) : theme.error(r.error || ''),
113
+ ]);
114
+
115
+ console.log('');
116
+ table(headers, rows);
117
+
118
+ // Summary
119
+ const healthy = results.filter(r => r.status === 'up').length;
120
+ const total = results.length;
121
+ console.log('');
122
+
123
+ if (healthy === total) {
124
+ success(`${healthy}/${total} services healthy`);
125
+ } else if (healthy > 0) {
126
+ info(`${healthy}/${total} services healthy`);
127
+ } else {
128
+ error(`${healthy}/${total} services healthy`);
129
+ }
130
+ console.log('');
131
+ }