@aaronbassett/midnight-local-devnet 0.2.1 → 0.3.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.
Files changed (88) hide show
  1. package/README.md +16 -26
  2. package/dist/cli/commands/dashboard.js +53 -14
  3. package/dist/cli/commands/dashboard.js.map +1 -1
  4. package/dist/cli/dashboard/html.d.ts +3 -0
  5. package/dist/cli/dashboard/html.js +1095 -0
  6. package/dist/cli/dashboard/html.js.map +1 -0
  7. package/dist/cli/dashboard/server.d.ts +17 -0
  8. package/dist/cli/dashboard/server.js +133 -0
  9. package/dist/cli/dashboard/server.js.map +1 -0
  10. package/dist/cli/dashboard/state-collector.d.ts +67 -0
  11. package/dist/cli/dashboard/state-collector.js +121 -0
  12. package/dist/cli/dashboard/state-collector.js.map +1 -0
  13. package/package.json +4 -5
  14. package/dist/cli/dashboard/app.d.ts +0 -9
  15. package/dist/cli/dashboard/app.js +0 -106
  16. package/dist/cli/dashboard/app.js.map +0 -1
  17. package/dist/cli/dashboard/components/gauge.d.ts +0 -9
  18. package/dist/cli/dashboard/components/gauge.js +0 -10
  19. package/dist/cli/dashboard/components/gauge.js.map +0 -1
  20. package/dist/cli/dashboard/components/panel-box.d.ts +0 -10
  21. package/dist/cli/dashboard/components/panel-box.js +0 -6
  22. package/dist/cli/dashboard/components/panel-box.js.map +0 -1
  23. package/dist/cli/dashboard/components/sparkline.d.ts +0 -9
  24. package/dist/cli/dashboard/components/sparkline.js +0 -25
  25. package/dist/cli/dashboard/components/sparkline.js.map +0 -1
  26. package/dist/cli/dashboard/components/status-badge.d.ts +0 -6
  27. package/dist/cli/dashboard/components/status-badge.js +0 -24
  28. package/dist/cli/dashboard/components/status-badge.js.map +0 -1
  29. package/dist/cli/dashboard/hooks/use-breakpoint.d.ts +0 -7
  30. package/dist/cli/dashboard/hooks/use-breakpoint.js +0 -15
  31. package/dist/cli/dashboard/hooks/use-breakpoint.js.map +0 -1
  32. package/dist/cli/dashboard/hooks/use-health.d.ts +0 -9
  33. package/dist/cli/dashboard/hooks/use-health.js +0 -35
  34. package/dist/cli/dashboard/hooks/use-health.js.map +0 -1
  35. package/dist/cli/dashboard/hooks/use-indexer-info.d.ts +0 -5
  36. package/dist/cli/dashboard/hooks/use-indexer-info.js +0 -19
  37. package/dist/cli/dashboard/hooks/use-indexer-info.js.map +0 -1
  38. package/dist/cli/dashboard/hooks/use-logs.d.ts +0 -19
  39. package/dist/cli/dashboard/hooks/use-logs.js +0 -55
  40. package/dist/cli/dashboard/hooks/use-logs.js.map +0 -1
  41. package/dist/cli/dashboard/hooks/use-node-info.d.ts +0 -21
  42. package/dist/cli/dashboard/hooks/use-node-info.js +0 -49
  43. package/dist/cli/dashboard/hooks/use-node-info.js.map +0 -1
  44. package/dist/cli/dashboard/hooks/use-polling.d.ts +0 -7
  45. package/dist/cli/dashboard/hooks/use-polling.js +0 -35
  46. package/dist/cli/dashboard/hooks/use-polling.js.map +0 -1
  47. package/dist/cli/dashboard/hooks/use-proof-server.d.ts +0 -7
  48. package/dist/cli/dashboard/hooks/use-proof-server.js +0 -14
  49. package/dist/cli/dashboard/hooks/use-proof-server.js.map +0 -1
  50. package/dist/cli/dashboard/hooks/use-services.d.ts +0 -3
  51. package/dist/cli/dashboard/hooks/use-services.js +0 -6
  52. package/dist/cli/dashboard/hooks/use-services.js.map +0 -1
  53. package/dist/cli/dashboard/hooks/use-terminal-size.d.ts +0 -5
  54. package/dist/cli/dashboard/hooks/use-terminal-size.js +0 -22
  55. package/dist/cli/dashboard/hooks/use-terminal-size.js.map +0 -1
  56. package/dist/cli/dashboard/hooks/use-wallet-state.d.ts +0 -10
  57. package/dist/cli/dashboard/hooks/use-wallet-state.js +0 -63
  58. package/dist/cli/dashboard/hooks/use-wallet-state.js.map +0 -1
  59. package/dist/cli/dashboard/layouts/large.d.ts +0 -7
  60. package/dist/cli/dashboard/layouts/large.js +0 -13
  61. package/dist/cli/dashboard/layouts/large.js.map +0 -1
  62. package/dist/cli/dashboard/layouts/medium.d.ts +0 -7
  63. package/dist/cli/dashboard/layouts/medium.js +0 -11
  64. package/dist/cli/dashboard/layouts/medium.js.map +0 -1
  65. package/dist/cli/dashboard/layouts/small.d.ts +0 -7
  66. package/dist/cli/dashboard/layouts/small.js +0 -11
  67. package/dist/cli/dashboard/layouts/small.js.map +0 -1
  68. package/dist/cli/dashboard/panels/indexer-panel.d.ts +0 -11
  69. package/dist/cli/dashboard/panels/indexer-panel.js +0 -17
  70. package/dist/cli/dashboard/panels/indexer-panel.js.map +0 -1
  71. package/dist/cli/dashboard/panels/log-panel.d.ts +0 -13
  72. package/dist/cli/dashboard/panels/log-panel.js +0 -27
  73. package/dist/cli/dashboard/panels/log-panel.js.map +0 -1
  74. package/dist/cli/dashboard/panels/node-panel.d.ts +0 -10
  75. package/dist/cli/dashboard/panels/node-panel.js +0 -17
  76. package/dist/cli/dashboard/panels/node-panel.js.map +0 -1
  77. package/dist/cli/dashboard/panels/proof-panel.d.ts +0 -10
  78. package/dist/cli/dashboard/panels/proof-panel.js +0 -20
  79. package/dist/cli/dashboard/panels/proof-panel.js.map +0 -1
  80. package/dist/cli/dashboard/panels/response-graph.d.ts +0 -10
  81. package/dist/cli/dashboard/panels/response-graph.js +0 -12
  82. package/dist/cli/dashboard/panels/response-graph.js.map +0 -1
  83. package/dist/cli/dashboard/panels/wallet-panel.d.ts +0 -9
  84. package/dist/cli/dashboard/panels/wallet-panel.js +0 -24
  85. package/dist/cli/dashboard/panels/wallet-panel.js.map +0 -1
  86. package/dist/cli/dashboard/types.d.ts +0 -39
  87. package/dist/cli/dashboard/types.js +0 -2
  88. package/dist/cli/dashboard/types.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../../src/cli/dashboard/html.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,SAAS,gBAAgB,CAAC,KAAa;IACrC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SACzB,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;SACxB,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EAAE,KAAK,EAAqB;IAChE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAwoBY,gBAAgB,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkbpC,CAAC;AACT,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { Hono } from 'hono';
2
+ import { WebSocketServer } from 'ws';
3
+ import type { Server } from 'node:http';
4
+ import type { NetworkConfig } from '../../core/types.js';
5
+ import type { NetworkManager } from '../../core/network-manager.js';
6
+ export interface DashboardServerOptions {
7
+ config: NetworkConfig;
8
+ manager: NetworkManager;
9
+ port: number;
10
+ }
11
+ export declare function createDashboardApp(opts: DashboardServerOptions): {
12
+ app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
13
+ setupWebSocket: (server: Server) => WebSocketServer;
14
+ startPolling: () => void;
15
+ stopPolling: () => void;
16
+ shutdown: () => void;
17
+ };
@@ -0,0 +1,133 @@
1
+ import { Hono } from 'hono';
2
+ import { WebSocketServer } from 'ws';
3
+ import { StateCollector } from './state-collector.js';
4
+ import { generateDashboardHtml } from './html.js';
5
+ import { getWalletBalances } from '../../core/wallet.js';
6
+ export function createDashboardApp(opts) {
7
+ const { config, manager, port } = opts;
8
+ const app = new Hono();
9
+ const collector = new StateCollector(config);
10
+ const clients = new Set();
11
+ let pollingInterval = null;
12
+ // ---------- GET / — serve dashboard HTML ----------
13
+ app.get('/', (c) => {
14
+ const html = generateDashboardHtml({ wsUrl: `ws://localhost:${port}/ws` });
15
+ return c.html(html);
16
+ });
17
+ // ---------- WebSocket setup ----------
18
+ function setupWebSocket(server) {
19
+ const wss = new WebSocketServer({ server, path: '/ws' });
20
+ wss.on('connection', (ws) => {
21
+ clients.add(ws);
22
+ ws.on('close', () => {
23
+ clients.delete(ws);
24
+ });
25
+ ws.on('message', (raw) => {
26
+ handleClientMessage(ws, raw);
27
+ });
28
+ });
29
+ return wss;
30
+ }
31
+ // ---------- Client message handling ----------
32
+ async function handleClientMessage(ws, raw) {
33
+ try {
34
+ const text = typeof raw === 'string' ? raw : raw.toString();
35
+ const msg = JSON.parse(text);
36
+ if (msg.type === 'command' && msg.action) {
37
+ await handleCommand(ws, msg.action);
38
+ }
39
+ }
40
+ catch {
41
+ // Ignore malformed messages
42
+ }
43
+ }
44
+ async function handleCommand(ws, action) {
45
+ try {
46
+ if (action === 'start') {
47
+ await manager.start({ pull: false });
48
+ }
49
+ else if (action === 'stop') {
50
+ await manager.stop({ removeVolumes: false });
51
+ }
52
+ else {
53
+ sendToClient(ws, { type: 'result', action, success: false, error: `Unknown action: ${action}` });
54
+ return;
55
+ }
56
+ sendToClient(ws, { type: 'result', action, success: true });
57
+ }
58
+ catch (err) {
59
+ const error = err instanceof Error ? err.message : String(err);
60
+ sendToClient(ws, { type: 'result', action, success: false, error });
61
+ }
62
+ }
63
+ function sendToClient(ws, data) {
64
+ if (ws.readyState === ws.OPEN) {
65
+ ws.send(JSON.stringify(data));
66
+ }
67
+ }
68
+ // ---------- Polling + broadcast ----------
69
+ async function collectAndBroadcast() {
70
+ try {
71
+ let walletInfo;
72
+ const walletCtx = manager.getMasterWallet();
73
+ if (walletCtx) {
74
+ try {
75
+ const balances = await getWalletBalances(walletCtx);
76
+ walletInfo = {
77
+ address: null, // Address extraction requires wallet SDK; use null for MVP
78
+ connected: true,
79
+ unshielded: balances.unshielded.toString(),
80
+ shielded: balances.shielded.toString(),
81
+ dust: balances.dust.toString(),
82
+ };
83
+ }
84
+ catch {
85
+ walletInfo = {
86
+ address: null,
87
+ connected: false,
88
+ unshielded: '0',
89
+ shielded: '0',
90
+ dust: '0',
91
+ };
92
+ }
93
+ }
94
+ const state = await collector.collect(walletInfo, manager.getStatus());
95
+ // JSON.stringify with bigint-safe replacer (just in case)
96
+ const json = JSON.stringify({ type: 'state', data: state }, (_key, value) => typeof value === 'bigint' ? value.toString() : value);
97
+ for (const ws of clients) {
98
+ if (ws.readyState === ws.OPEN) {
99
+ ws.send(json);
100
+ }
101
+ }
102
+ }
103
+ catch {
104
+ // Swallow polling errors to keep the interval running
105
+ }
106
+ }
107
+ function startPolling() {
108
+ // Collect immediately, then every 3 seconds
109
+ collectAndBroadcast();
110
+ pollingInterval = setInterval(collectAndBroadcast, 3000);
111
+ }
112
+ function stopPolling() {
113
+ if (pollingInterval !== null) {
114
+ clearInterval(pollingInterval);
115
+ pollingInterval = null;
116
+ }
117
+ }
118
+ function shutdown() {
119
+ stopPolling();
120
+ for (const ws of clients) {
121
+ ws.close();
122
+ }
123
+ clients.clear();
124
+ }
125
+ return {
126
+ app,
127
+ setupWebSocket,
128
+ startPolling,
129
+ stopPolling,
130
+ shutdown,
131
+ };
132
+ }
133
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/cli/dashboard/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type { NetworkConfig, ServiceStatus } from '../../core/types.js';
2
+ import type { ParsedLogLine } from './lib/log-parser.js';
3
+ export interface DashboardState {
4
+ node: {
5
+ chain: string | null;
6
+ name: string | null;
7
+ version: string | null;
8
+ blockHeight: number | null;
9
+ /** Average block production time in milliseconds, or null if insufficient data */
10
+ avgBlockTime: number | null;
11
+ peers: number | null;
12
+ syncing: boolean | null;
13
+ };
14
+ indexer: {
15
+ ready: boolean;
16
+ responseTime: number | null;
17
+ };
18
+ proofServer: {
19
+ version: string | null;
20
+ ready: boolean;
21
+ jobsProcessing: number | null;
22
+ jobsPending: number | null;
23
+ jobCapacity: number | null;
24
+ proofVersions: string[] | null;
25
+ };
26
+ wallet: {
27
+ address: string | null;
28
+ connected: boolean;
29
+ unshielded: string;
30
+ shielded: string;
31
+ dust: string;
32
+ };
33
+ health: {
34
+ node: {
35
+ status: 'healthy' | 'unhealthy';
36
+ history: number[];
37
+ };
38
+ indexer: {
39
+ status: 'healthy' | 'unhealthy';
40
+ history: number[];
41
+ };
42
+ proofServer: {
43
+ status: 'healthy' | 'unhealthy';
44
+ history: number[];
45
+ };
46
+ };
47
+ containers: ServiceStatus[];
48
+ logs: ParsedLogLine[];
49
+ networkStatus: string;
50
+ }
51
+ export interface WalletInfo {
52
+ address: string | null;
53
+ connected: boolean;
54
+ unshielded: string;
55
+ shielded: string;
56
+ dust: string;
57
+ }
58
+ export declare class StateCollector {
59
+ private readonly config;
60
+ private readonly nodeHistory;
61
+ private readonly indexerHistory;
62
+ private readonly proofHistory;
63
+ private lastBlockHeight;
64
+ private lastBlockTime;
65
+ constructor(config: NetworkConfig);
66
+ collect(walletInfo?: WalletInfo, networkStatus?: string): Promise<DashboardState>;
67
+ }
@@ -0,0 +1,121 @@
1
+ import { parseLogLines } from './lib/log-parser.js';
2
+ import { fetchSystemChain, fetchSystemName, fetchSystemVersion, fetchSystemHealth, fetchBestBlockHeader, } from './lib/substrate-rpc.js';
3
+ import { fetchProofServerReady, fetchProofServerVersion, fetchProofVersions, } from './lib/proof-server-api.js';
4
+ import { composePs, composeLogs } from '../../core/docker.js';
5
+ import { checkAllHealth } from '../../core/health.js';
6
+ const MAX_HISTORY = 30;
7
+ async function safeCall(fn, fallback) {
8
+ try {
9
+ return await fn();
10
+ }
11
+ catch {
12
+ return fallback;
13
+ }
14
+ }
15
+ export class StateCollector {
16
+ config;
17
+ nodeHistory = [];
18
+ indexerHistory = [];
19
+ proofHistory = [];
20
+ lastBlockHeight = null;
21
+ lastBlockTime = null;
22
+ constructor(config) {
23
+ this.config = config;
24
+ }
25
+ async collect(walletInfo, networkStatus) {
26
+ const [chain, name, version, systemHealth, blockHeader, proofVersion, proofReady, proofVersions, containers, rawLogs, healthReport,] = await Promise.all([
27
+ safeCall(() => fetchSystemChain(this.config.node), null),
28
+ safeCall(() => fetchSystemName(this.config.node), null),
29
+ safeCall(() => fetchSystemVersion(this.config.node), null),
30
+ safeCall(() => fetchSystemHealth(this.config.node), null),
31
+ safeCall(() => fetchBestBlockHeader(this.config.node), null),
32
+ safeCall(() => fetchProofServerVersion(this.config.proofServer), null),
33
+ safeCall(() => fetchProofServerReady(this.config.proofServer), null),
34
+ safeCall(() => fetchProofVersions(this.config.proofServer), null),
35
+ safeCall(() => composePs(), []),
36
+ safeCall(() => composeLogs({ lines: 100 }), ''),
37
+ safeCall(() => checkAllHealth(this.config), null),
38
+ ]);
39
+ // Compute avgBlockTime
40
+ const blockHeight = blockHeader?.number ?? null;
41
+ let avgBlockTime = null;
42
+ const now = Date.now();
43
+ if (blockHeight !== null &&
44
+ this.lastBlockHeight !== null &&
45
+ this.lastBlockTime !== null &&
46
+ blockHeight > this.lastBlockHeight) {
47
+ const elapsed = now - this.lastBlockTime;
48
+ const blocksProduced = blockHeight - this.lastBlockHeight;
49
+ avgBlockTime = elapsed / blocksProduced;
50
+ }
51
+ if (blockHeight !== null && (this.lastBlockHeight === null || blockHeight > this.lastBlockHeight)) {
52
+ this.lastBlockHeight = blockHeight;
53
+ this.lastBlockTime = now;
54
+ }
55
+ // Update response time history
56
+ if (healthReport?.node.responseTime != null) {
57
+ this.nodeHistory.push(healthReport.node.responseTime);
58
+ if (this.nodeHistory.length > MAX_HISTORY)
59
+ this.nodeHistory.shift();
60
+ }
61
+ if (healthReport?.indexer.responseTime != null) {
62
+ this.indexerHistory.push(healthReport.indexer.responseTime);
63
+ if (this.indexerHistory.length > MAX_HISTORY)
64
+ this.indexerHistory.shift();
65
+ }
66
+ if (healthReport?.proofServer.responseTime != null) {
67
+ this.proofHistory.push(healthReport.proofServer.responseTime);
68
+ if (this.proofHistory.length > MAX_HISTORY)
69
+ this.proofHistory.shift();
70
+ }
71
+ const logs = parseLogLines(rawLogs);
72
+ return {
73
+ node: {
74
+ chain,
75
+ name,
76
+ version,
77
+ blockHeight,
78
+ avgBlockTime,
79
+ peers: systemHealth?.peers ?? null,
80
+ syncing: systemHealth?.isSyncing ?? null,
81
+ },
82
+ indexer: {
83
+ ready: healthReport?.indexer.healthy ?? false,
84
+ responseTime: healthReport?.indexer.responseTime ?? null,
85
+ },
86
+ proofServer: {
87
+ version: proofVersion,
88
+ ready: proofReady?.status === 'ok',
89
+ jobsProcessing: proofReady?.jobsProcessing ?? null,
90
+ jobsPending: proofReady?.jobsPending ?? null,
91
+ jobCapacity: proofReady?.jobCapacity ?? null,
92
+ proofVersions,
93
+ },
94
+ wallet: walletInfo ?? {
95
+ address: null,
96
+ connected: false,
97
+ unshielded: '0',
98
+ shielded: '0',
99
+ dust: '0',
100
+ },
101
+ health: {
102
+ node: {
103
+ status: healthReport?.node.healthy ? 'healthy' : 'unhealthy',
104
+ history: [...this.nodeHistory],
105
+ },
106
+ indexer: {
107
+ status: healthReport?.indexer.healthy ? 'healthy' : 'unhealthy',
108
+ history: [...this.indexerHistory],
109
+ },
110
+ proofServer: {
111
+ status: healthReport?.proofServer.healthy ? 'healthy' : 'unhealthy',
112
+ history: [...this.proofHistory],
113
+ },
114
+ },
115
+ containers,
116
+ logs,
117
+ networkStatus: networkStatus ?? 'unknown',
118
+ };
119
+ }
120
+ }
121
+ //# sourceMappingURL=state-collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-collector.js","sourceRoot":"","sources":["../../../src/cli/dashboard/state-collector.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aaronbassett/midnight-local-devnet",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Local Midnight development network manager — CLI and MCP server",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,6 +39,7 @@
39
39
  "test:watch": "vitest"
40
40
  },
41
41
  "dependencies": {
42
+ "@hono/node-server": "^1.19.9",
42
43
  "@midnight-ntwrk/ledger-v7": "7.0.0",
43
44
  "@midnight-ntwrk/midnight-js-network-id": "3.1.0",
44
45
  "@midnight-ntwrk/wallet-sdk-abstractions": "1.0.0",
@@ -51,19 +52,17 @@
51
52
  "@modelcontextprotocol/sdk": "^1.12.1",
52
53
  "@scure/bip39": "^2.0.1",
53
54
  "commander": "^13.1.0",
54
- "ink": "^6.8.0",
55
+ "hono": "^4.12.3",
56
+ "open": "^11.0.0",
55
57
  "pino": "^10.1.0",
56
58
  "pino-pretty": "^13.1.3",
57
- "react": "^19.2.4",
58
59
  "rxjs": "^7.8.1",
59
60
  "ws": "^8.18.3",
60
61
  "zod": "^3.24.0"
61
62
  },
62
63
  "devDependencies": {
63
64
  "@types/node": "^22.0.0",
64
- "@types/react": "^19.2.14",
65
65
  "@types/ws": "^8.18.1",
66
- "ink-testing-library": "^4.0.0",
67
66
  "typescript": "^5.9.3",
68
67
  "vitest": "^3.1.0"
69
68
  },
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- import type { NetworkManager } from '../../core/network-manager.js';
3
- import type { NetworkConfig } from '../../core/types.js';
4
- interface AppProps {
5
- manager: NetworkManager;
6
- config: NetworkConfig;
7
- }
8
- export declare function App({ manager, config }: AppProps): React.ReactElement;
9
- export {};
@@ -1,106 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Box, Text, useInput, useApp } from 'ink';
4
- import { useBreakpoint } from './hooks/use-breakpoint.js';
5
- import { useNodeInfo } from './hooks/use-node-info.js';
6
- import { useProofServer } from './hooks/use-proof-server.js';
7
- import { useHealth } from './hooks/use-health.js';
8
- import { useIndexerInfo } from './hooks/use-indexer-info.js';
9
- import { useWalletState } from './hooks/use-wallet-state.js';
10
- import { useLogs } from './hooks/use-logs.js';
11
- import { SmallLayout } from './layouts/small.js';
12
- import { MediumLayout } from './layouts/medium.js';
13
- import { LargeLayout } from './layouts/large.js';
14
- const PANEL_CYCLE = ['node', 'indexer', 'proof', 'wallet', 'logs', 'graph'];
15
- export function App({ manager, config }) {
16
- const { exit } = useApp();
17
- const { breakpoint, columns, rows } = useBreakpoint();
18
- // Data hooks
19
- const nodeInfo = useNodeInfo(config.node);
20
- const proofServer = useProofServer(config.proofServer);
21
- const health = useHealth(config);
22
- const indexerInfo = useIndexerInfo(config.indexer);
23
- const walletState = useWalletState(manager);
24
- const logs = useLogs();
25
- // UI state
26
- const [focusedPanel, setFocusedPanel] = useState('node');
27
- const [searchMode, setSearchMode] = useState(false);
28
- const [searchText, setSearchText] = useState('');
29
- const isInteractive = process.stdin.isTTY === true;
30
- useInput((input, key) => {
31
- if (searchMode) {
32
- if (key.escape || key.return) {
33
- setSearchMode(false);
34
- if (key.return)
35
- logs.setSearch(searchText);
36
- if (key.escape) {
37
- setSearchText('');
38
- logs.setSearch('');
39
- }
40
- return;
41
- }
42
- if (key.backspace || key.delete) {
43
- setSearchText((prev) => prev.slice(0, -1));
44
- return;
45
- }
46
- setSearchText((prev) => prev + input);
47
- return;
48
- }
49
- if (input === 'q') {
50
- exit();
51
- return;
52
- }
53
- if (key.tab) {
54
- setFocusedPanel((prev) => {
55
- const idx = PANEL_CYCLE.indexOf(prev);
56
- return PANEL_CYCLE[(idx + 1) % PANEL_CYCLE.length];
57
- });
58
- return;
59
- }
60
- if (input === 's') {
61
- logs.cycleService();
62
- return;
63
- }
64
- if (input === 'l') {
65
- logs.cycleLevel();
66
- return;
67
- }
68
- if (input === '/') {
69
- setSearchMode(true);
70
- setSearchText('');
71
- return;
72
- }
73
- if (key.upArrow) {
74
- if (focusedPanel === 'logs')
75
- logs.scrollUp();
76
- return;
77
- }
78
- if (key.downArrow) {
79
- if (focusedPanel === 'logs')
80
- logs.scrollDown();
81
- return;
82
- }
83
- }, { isActive: isInteractive });
84
- const data = {
85
- node: nodeInfo.data,
86
- nodeLoading: nodeInfo.loading,
87
- indexer: indexerInfo.data,
88
- indexerLoading: indexerInfo.loading,
89
- proofServer: proofServer.data,
90
- proofServerLoading: proofServer.loading,
91
- wallet: walletState,
92
- logs,
93
- healthHistory: {
94
- nodeHistory: health.data?.nodeHistory ?? [],
95
- indexerHistory: health.data?.indexerHistory ?? [],
96
- proofServerHistory: health.data?.proofServerHistory ?? [],
97
- },
98
- focusedPanel,
99
- searchMode,
100
- searchText,
101
- columns,
102
- rows,
103
- };
104
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: "cyan", children: "Midnight Local Devnet" }), _jsxs(Text, { color: "gray", children: [columns, "x", rows, " | ", breakpoint, " | Tab=focus q=quit s=svc l=lvl /=search"] })] }), breakpoint === 'small' && _jsx(SmallLayout, { data: data }), breakpoint === 'medium' && _jsx(MediumLayout, { data: data }), breakpoint === 'large' && _jsx(LargeLayout, { data: data })] }));
105
- }
106
- //# sourceMappingURL=app.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/cli/dashboard/app.tsx"],"names":[],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- interface GaugeProps {
3
- value: number;
4
- max: number;
5
- width?: number;
6
- label?: string;
7
- }
8
- export declare function Gauge({ value, max, width, label }: GaugeProps): React.ReactElement;
9
- export {};
@@ -1,10 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Text } from 'ink';
3
- export function Gauge({ value, max, width = 10, label }) {
4
- const filled = max > 0 ? Math.round((value / max) * width) : 0;
5
- const empty = width - filled;
6
- const percentage = max > 0 ? Math.round((value / max) * 100) : 0;
7
- const color = percentage >= 90 ? 'red' : percentage >= 70 ? 'yellow' : 'green';
8
- return (_jsxs(Text, { children: [_jsx(Text, { color: color, children: '█'.repeat(filled) }), _jsx(Text, { color: "gray", children: '░'.repeat(empty) }), _jsxs(Text, { children: [" ", value, "/", max] }), label ? _jsxs(Text, { children: [" ", label] }) : null] }));
9
- }
10
- //# sourceMappingURL=gauge.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gauge.js","sourceRoot":"","sources":["../../../../src/cli/dashboard/components/gauge.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAS3B,MAAM,UAAU,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,EAAc;IACjE,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC7B,MAAM,UAAU,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjE,MAAM,KAAK,GAAG,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAE/E,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAQ,EAC/C,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAQ,EAC7C,MAAC,IAAI,oBAAG,KAAK,OAAG,GAAG,IAAQ,EAC1B,KAAK,CAAC,CAAC,CAAC,MAAC,IAAI,oBAAG,KAAK,IAAQ,CAAC,CAAC,CAAC,IAAI,IAChC,CACR,CAAC;AACJ,CAAC"}
@@ -1,10 +0,0 @@
1
- import React from 'react';
2
- interface PanelBoxProps {
3
- title: string;
4
- focused?: boolean;
5
- width?: number | string;
6
- height?: number;
7
- children: React.ReactNode;
8
- }
9
- export declare function PanelBox({ title, focused, width, height, children }: PanelBoxProps): React.ReactElement;
10
- export {};
@@ -1,6 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- export function PanelBox({ title, focused, width, height, children }) {
4
- return (_jsxs(Box, { flexDirection: "column", borderStyle: focused ? 'bold' : 'single', borderColor: focused ? 'cyan' : 'gray', width: width, height: height, paddingX: 1, children: [_jsx(Text, { bold: true, color: focused ? 'cyan' : 'white', children: title }), children] }));
5
- }
6
- //# sourceMappingURL=panel-box.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"panel-box.js","sourceRoot":"","sources":["../../../../src/cli/dashboard/components/panel-box.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAUhC,MAAM,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAiB;IACjF,OAAO,CACL,MAAC,GAAG,IACF,aAAa,EAAC,QAAQ,EACtB,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EACxC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EACtC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,aAEX,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,YACzC,KAAK,GACD,EACN,QAAQ,IACL,CACP,CAAC;AACJ,CAAC"}
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- export declare function renderSparkline(data: number[], maxWidth?: number): string;
3
- interface SparklineProps {
4
- data: number[];
5
- maxWidth?: number;
6
- color?: string;
7
- }
8
- export declare function Sparkline({ data, maxWidth, color }: SparklineProps): React.ReactElement;
9
- export {};
@@ -1,25 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Text } from 'ink';
3
- const BARS = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
4
- export function renderSparkline(data, maxWidth) {
5
- if (data.length === 0)
6
- return '';
7
- const values = maxWidth && data.length > maxWidth ? data.slice(-maxWidth) : data;
8
- const min = Math.min(...values);
9
- const max = Math.max(...values);
10
- const range = max - min;
11
- if (range === 0) {
12
- const mid = Math.floor((BARS.length - 1) / 2);
13
- return values.map(() => BARS[mid]).join('');
14
- }
15
- return values
16
- .map((v) => {
17
- const idx = Math.round(((v - min) / range) * (BARS.length - 1));
18
- return BARS[idx];
19
- })
20
- .join('');
21
- }
22
- export function Sparkline({ data, maxWidth, color }) {
23
- return _jsx(Text, { color: color, children: renderSparkline(data, maxWidth) });
24
- }
25
- //# sourceMappingURL=sparkline.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sparkline.js","sourceRoot":"","sources":["../../../../src/cli/dashboard/components/sparkline.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAE3B,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC;AAE/D,MAAM,UAAU,eAAe,CAAC,IAAc,EAAE,QAAiB;IAC/D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,MAAM,MAAM,GAAG,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,CAAC;IAExB,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9C,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAQD,MAAM,UAAU,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAkB;IACjE,OAAO,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAQ,CAAC;AACtE,CAAC"}
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- interface StatusBadgeProps {
3
- status: 'healthy' | 'unhealthy' | 'unknown' | 'running' | 'stopped' | 'busy' | 'ok';
4
- }
5
- export declare function StatusBadge({ status }: StatusBadgeProps): React.ReactElement;
6
- export {};