@jango-blockchained/hoox-cli 0.5.1 → 0.5.6

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 (106) hide show
  1. package/bin/hoox.js +3 -4
  2. package/dist/index.js +32545 -0
  3. package/package.json +10 -15
  4. package/src/commands/check/check-command.test.ts +0 -476
  5. package/src/commands/check/check-command.ts +0 -1144
  6. package/src/commands/check/index.ts +0 -10
  7. package/src/commands/check/prerequisites-command.test.ts +0 -19
  8. package/src/commands/check/prerequisites-command.ts +0 -96
  9. package/src/commands/check/types.ts +0 -103
  10. package/src/commands/clone/clone-command.test.ts +0 -442
  11. package/src/commands/clone/clone-command.ts +0 -431
  12. package/src/commands/clone/index.ts +0 -1
  13. package/src/commands/config/config-command.test.ts +0 -583
  14. package/src/commands/config/config-command.ts +0 -897
  15. package/src/commands/config/env-command.test.ts +0 -43
  16. package/src/commands/config/env-command.ts +0 -295
  17. package/src/commands/config/index.ts +0 -3
  18. package/src/commands/config/kv-command.test.ts +0 -14
  19. package/src/commands/config/kv-command.ts +0 -290
  20. package/src/commands/dashboard/dashboard-command.test.ts +0 -47
  21. package/src/commands/dashboard/dashboard-command.ts +0 -128
  22. package/src/commands/dashboard/index.ts +0 -1
  23. package/src/commands/db/db-command.test.ts +0 -21
  24. package/src/commands/db/db-command.ts +0 -312
  25. package/src/commands/db/index.ts +0 -1
  26. package/src/commands/deploy/deploy-command.test.ts +0 -304
  27. package/src/commands/deploy/deploy-command.ts +0 -1135
  28. package/src/commands/deploy/index.ts +0 -2
  29. package/src/commands/deploy/telegram-service.ts +0 -76
  30. package/src/commands/deploy/types.ts +0 -34
  31. package/src/commands/dev/dev-command.test.ts +0 -383
  32. package/src/commands/dev/dev-command.ts +0 -398
  33. package/src/commands/dev/index.ts +0 -1
  34. package/src/commands/infra/index.ts +0 -5
  35. package/src/commands/infra/infra-command.test.ts +0 -719
  36. package/src/commands/infra/infra-command.ts +0 -974
  37. package/src/commands/infra/types.ts +0 -23
  38. package/src/commands/init/__tests__/cli-provisioner.test.ts +0 -17
  39. package/src/commands/init/cli-provisioner.ts +0 -71
  40. package/src/commands/init/index.ts +0 -1
  41. package/src/commands/init/init-command.test.ts +0 -876
  42. package/src/commands/init/init-command.ts +0 -593
  43. package/src/commands/init/types.ts +0 -23
  44. package/src/commands/logs/index.ts +0 -1
  45. package/src/commands/logs/logs-command.test.ts +0 -294
  46. package/src/commands/logs/logs-command.ts +0 -452
  47. package/src/commands/monitor/index.ts +0 -2
  48. package/src/commands/monitor/monitor-command.test.ts +0 -263
  49. package/src/commands/monitor/monitor-command.ts +0 -269
  50. package/src/commands/monitor/monitor-service.ts +0 -65
  51. package/src/commands/monitor/types.ts +0 -13
  52. package/src/commands/repair/index.ts +0 -2
  53. package/src/commands/repair/repair-command.test.ts +0 -224
  54. package/src/commands/repair/repair-command.ts +0 -220
  55. package/src/commands/repair/repair-service.ts +0 -138
  56. package/src/commands/repair/types.ts +0 -13
  57. package/src/commands/test/index.ts +0 -2
  58. package/src/commands/test/test-command.test.ts +0 -319
  59. package/src/commands/test/test-command.ts +0 -406
  60. package/src/commands/tui/index.ts +0 -1
  61. package/src/commands/tui/tui-command.ts +0 -87
  62. package/src/commands/update/index.ts +0 -1
  63. package/src/commands/update/update-command.ts +0 -168
  64. package/src/commands/waf/index.ts +0 -2
  65. package/src/commands/waf/types.ts +0 -48
  66. package/src/commands/waf/waf-command.test.ts +0 -506
  67. package/src/commands/waf/waf-command.ts +0 -548
  68. package/src/index.ts +0 -269
  69. package/src/services/cloudflare/cloudflare-service.test.ts +0 -658
  70. package/src/services/cloudflare/cloudflare-service.ts +0 -433
  71. package/src/services/cloudflare/index.ts +0 -2
  72. package/src/services/cloudflare/types.ts +0 -30
  73. package/src/services/config/config-service.test.ts +0 -395
  74. package/src/services/config/config-service.ts +0 -207
  75. package/src/services/config/index.ts +0 -9
  76. package/src/services/config/types.ts +0 -66
  77. package/src/services/db/db-service.test.ts +0 -51
  78. package/src/services/db/db-service.ts +0 -131
  79. package/src/services/db/index.ts +0 -1
  80. package/src/services/docker/docker-service.ts +0 -155
  81. package/src/services/docker/index.ts +0 -1
  82. package/src/services/env/env-service.test.ts +0 -236
  83. package/src/services/env/env-service.ts +0 -386
  84. package/src/services/env/index.ts +0 -1
  85. package/src/services/kv/index.ts +0 -1
  86. package/src/services/kv/kv-sync-service.test.ts +0 -38
  87. package/src/services/kv/kv-sync-service.ts +0 -234
  88. package/src/services/prerequisites/index.ts +0 -1
  89. package/src/services/prerequisites/prerequisites-service.test.ts +0 -89
  90. package/src/services/prerequisites/prerequisites-service.ts +0 -377
  91. package/src/services/prerequisites/types.ts +0 -48
  92. package/src/services/secrets/index.ts +0 -11
  93. package/src/services/secrets/secrets-service.test.ts +0 -495
  94. package/src/services/secrets/secrets-service.ts +0 -287
  95. package/src/services/secrets/types.ts +0 -50
  96. package/src/services/update/index.ts +0 -2
  97. package/src/services/update/update-service.test.ts +0 -76
  98. package/src/services/update/update-service.ts +0 -193
  99. package/src/ui/banner.ts +0 -141
  100. package/src/ui/index.ts +0 -8
  101. package/src/ui/menu.ts +0 -490
  102. package/src/utils/errors.test.ts +0 -69
  103. package/src/utils/errors.ts +0 -23
  104. package/src/utils/formatters.test.ts +0 -180
  105. package/src/utils/formatters.ts +0 -269
  106. package/src/utils/theme.ts +0 -94
@@ -1,263 +0,0 @@
1
- // @ts-nocheck
2
- /**
3
- * Unit tests for the monitor command.
4
- *
5
- * Stubs MonitorService, DbService, and KvSyncService prototypes to verify
6
- * the monitor command logic in isolation. Uses Commander's exitOverride to
7
- * suppress process exits during test runs.
8
- */
9
- import { afterEach, beforeEach, describe, expect, it, mock } from "bun:test";
10
- import { Command } from "commander";
11
- import { MonitorService } from "./monitor-service.js";
12
- import { DbService } from "../../services/db/db-service.js";
13
- import { KvSyncService } from "../../services/kv/kv-sync-service.js";
14
-
15
- // Stub variables
16
- let checkAllWorkerHealthMock: ReturnType<typeof mock>;
17
- let resolveDbNameMock: ReturnType<typeof mock>;
18
- let queryMock: ReturnType<typeof mock>;
19
- let exportMock: ReturnType<typeof mock>;
20
- let resolveNamespaceIdMock: ReturnType<typeof mock>;
21
- let getMock: ReturnType<typeof mock>;
22
- let setMock: ReturnType<typeof mock>;
23
-
24
- // Preserve originals
25
- const origCheckAll = MonitorService.prototype.checkAllWorkerHealth;
26
- const origResolveDbName = DbService.prototype.resolveDbName;
27
- const origQuery = DbService.prototype.query;
28
- const origExport = DbService.prototype.export;
29
- const origResolveNs = KvSyncService.prototype.resolveNamespaceId;
30
- const origGet = KvSyncService.prototype.get;
31
- const origSet = KvSyncService.prototype.set;
32
-
33
- beforeEach(() => {
34
- mock.restore();
35
- process.exitCode = 0;
36
-
37
- // Restore originals
38
- (MonitorService.prototype as Record<string, unknown>).checkAllWorkerHealth =
39
- origCheckAll;
40
- (DbService.prototype as Record<string, unknown>).resolveDbName =
41
- origResolveDbName;
42
- (DbService.prototype as Record<string, unknown>).query = origQuery;
43
- (DbService.prototype as Record<string, unknown>).export = origExport;
44
- (KvSyncService.prototype as Record<string, unknown>).resolveNamespaceId =
45
- origResolveNs;
46
- (KvSyncService.prototype as Record<string, unknown>).get = origGet;
47
- (KvSyncService.prototype as Record<string, unknown>).set = origSet;
48
-
49
- // Fresh mocks
50
- checkAllWorkerHealthMock = mock(async () => ({
51
- workers: [
52
- { worker: "hoox", status: "healthy", statusCode: 200 },
53
- { worker: "trade-worker", status: "healthy", statusCode: 200 },
54
- ],
55
- healthyCount: 2,
56
- degradedCount: 0,
57
- unreachableCount: 0,
58
- }));
59
-
60
- resolveDbNameMock = mock(async () => "trade-data-db");
61
- queryMock = mock(
62
- async (_dbName: string, _sql: string, _remote: boolean) =>
63
- "[mock query result]"
64
- );
65
- exportMock = mock(async (_dbName: string) => "backup-2026-05-13.sql");
66
- resolveNamespaceIdMock = mock(async () => "ns-id-123");
67
- getMock = mock(async (_nsId: string, _key: string) => "false");
68
- setMock = mock(async (_nsId: string, _key: string, _value: string) => {});
69
-
70
- // Install mocks on prototypes
71
- (MonitorService.prototype as Record<string, unknown>).checkAllWorkerHealth =
72
- checkAllWorkerHealthMock;
73
- (DbService.prototype as Record<string, unknown>).resolveDbName =
74
- resolveDbNameMock;
75
- (DbService.prototype as Record<string, unknown>).query = queryMock;
76
- (DbService.prototype as Record<string, unknown>).export = exportMock;
77
- (KvSyncService.prototype as Record<string, unknown>).resolveNamespaceId =
78
- resolveNamespaceIdMock;
79
- (KvSyncService.prototype as Record<string, unknown>).get = getMock;
80
- (KvSyncService.prototype as Record<string, unknown>).set = setMock;
81
- });
82
-
83
- afterEach(() => {
84
- mock.restore();
85
- (MonitorService.prototype as Record<string, unknown>).checkAllWorkerHealth =
86
- origCheckAll;
87
- (DbService.prototype as Record<string, unknown>).resolveDbName =
88
- origResolveDbName;
89
- (DbService.prototype as Record<string, unknown>).query = origQuery;
90
- (DbService.prototype as Record<string, unknown>).export = origExport;
91
- (KvSyncService.prototype as Record<string, unknown>).resolveNamespaceId =
92
- origResolveNs;
93
- (KvSyncService.prototype as Record<string, unknown>).get = origGet;
94
- (KvSyncService.prototype as Record<string, unknown>).set = origSet;
95
- });
96
-
97
- async function importMonitorCommand(): Promise<{
98
- registerMonitorCommand: typeof import("./monitor-command.js").registerMonitorCommand;
99
- }> {
100
- return import("./monitor-command.js");
101
- }
102
-
103
- async function createProgram(): Promise<Command> {
104
- const { registerMonitorCommand } = await importMonitorCommand();
105
- const program = new Command().name("hoox-test").exitOverride(() => {});
106
- registerMonitorCommand(program);
107
- return program;
108
- }
109
-
110
- describe("registerMonitorCommand", () => {
111
- // -- Command registration -------------------------------------------------
112
-
113
- it("registers 'monitor' as a command on the program", async () => {
114
- const program = await createProgram();
115
- const cmd = program.commands.find((c) => c.name() === "monitor");
116
- expect(cmd).toBeDefined();
117
- });
118
-
119
- it("registers 'monitor status' subcommand", async () => {
120
- const program = await createProgram();
121
- const monitorCmd = program.commands.find((c) => c.name() === "monitor")!;
122
- const statusCmd = monitorCmd.commands.find((c) => c.name() === "status");
123
- expect(statusCmd).toBeDefined();
124
- });
125
-
126
- it("registers 'monitor trades' subcommand with argument", async () => {
127
- const program = await createProgram();
128
- const monitorCmd = program.commands.find((c) => c.name() === "monitor")!;
129
- const tradesCmd = monitorCmd.commands.find((c) => c.name() === "trades");
130
- expect(tradesCmd).toBeDefined();
131
- const args = tradesCmd!.registeredArguments;
132
- expect(args.some((a) => a.name() === "limit")).toBe(true);
133
- });
134
-
135
- it("registers 'monitor logs' subcommand with optional argument", async () => {
136
- const program = await createProgram();
137
- const monitorCmd = program.commands.find((c) => c.name() === "monitor")!;
138
- const logsCmd = monitorCmd.commands.find((c) => c.name() === "logs");
139
- expect(logsCmd).toBeDefined();
140
- });
141
-
142
- it("registers 'monitor kill-switch' with show/on/off subcommands", async () => {
143
- const program = await createProgram();
144
- const monitorCmd = program.commands.find((c) => c.name() === "monitor")!;
145
- const ksCmd = monitorCmd.commands.find((c) => c.name() === "kill-switch");
146
- expect(ksCmd).toBeDefined();
147
- expect(ksCmd!.commands.find((c) => c.name() === "show")).toBeDefined();
148
- expect(ksCmd!.commands.find((c) => c.name() === "on")).toBeDefined();
149
- expect(ksCmd!.commands.find((c) => c.name() === "off")).toBeDefined();
150
- });
151
-
152
- it("registers 'monitor queue-depth' subcommand", async () => {
153
- const program = await createProgram();
154
- const monitorCmd = program.commands.find((c) => c.name() === "monitor")!;
155
- const qCmd = monitorCmd.commands.find((c) => c.name() === "queue-depth");
156
- expect(qCmd).toBeDefined();
157
- });
158
-
159
- it("registers 'monitor backup' subcommand", async () => {
160
- const program = await createProgram();
161
- const monitorCmd = program.commands.find((c) => c.name() === "monitor")!;
162
- const backupCmd = monitorCmd.commands.find((c) => c.name() === "backup");
163
- expect(backupCmd).toBeDefined();
164
- });
165
-
166
- // -- monitor status -------------------------------------------------------
167
-
168
- describe("monitor status", () => {
169
- it("calls checkAllWorkerHealth", async () => {
170
- const program = await createProgram();
171
- await program.parseAsync(["monitor", "status"], { from: "user" });
172
- expect(checkAllWorkerHealthMock).toHaveBeenCalled();
173
- });
174
-
175
- it("exits cleanly on success", async () => {
176
- process.exitCode = 0;
177
- const program = await createProgram();
178
- process.exitCode = 0;
179
- await program.parseAsync(["monitor", "status"], { from: "user" });
180
- expect(process.exitCode).toBe(0);
181
- });
182
-
183
- it("sets exitCode on service failure", async () => {
184
- checkAllWorkerHealthMock = mock(async () => {
185
- throw new Error("Connection failed");
186
- });
187
- (
188
- MonitorService.prototype as Record<string, unknown>
189
- ).checkAllWorkerHealth = checkAllWorkerHealthMock;
190
-
191
- const program = await createProgram();
192
- await program.parseAsync(["monitor", "status"], { from: "user" });
193
- expect(process.exitCode).toBe(1);
194
- });
195
- });
196
-
197
- // -- monitor trades -------------------------------------------------------
198
-
199
- describe("monitor trades", () => {
200
- it("calls db.query with trades table", async () => {
201
- const program = await createProgram();
202
- await program.parseAsync(["monitor", "trades"], { from: "user" });
203
- expect(resolveDbNameMock).toHaveBeenCalled();
204
- expect(queryMock).toHaveBeenCalled();
205
- const sql = queryMock.mock.calls[0][1] as string;
206
- expect(sql).toContain("trades");
207
- expect(sql).toContain("ORDER BY timestamp DESC");
208
- });
209
-
210
- it("accepts custom limit", async () => {
211
- const program = await createProgram();
212
- await program.parseAsync(["monitor", "trades", "25"], { from: "user" });
213
- const sql = queryMock.mock.calls[0][1] as string;
214
- expect(sql).toContain("LIMIT 25");
215
- });
216
- });
217
-
218
- // -- monitor kill-switch --------------------------------------------------
219
-
220
- describe("monitor kill-switch", () => {
221
- it("shows kill switch status", async () => {
222
- const program = await createProgram();
223
- await program.parseAsync(["monitor", "kill-switch", "show"], {
224
- from: "user",
225
- });
226
- expect(getMock).toHaveBeenCalledWith("ns-id-123", "trade:kill_switch");
227
- });
228
-
229
- it("turns kill switch on", async () => {
230
- const program = await createProgram();
231
- await program.parseAsync(["monitor", "kill-switch", "on"], {
232
- from: "user",
233
- });
234
- expect(setMock).toHaveBeenCalledWith(
235
- "ns-id-123",
236
- "trade:kill_switch",
237
- "true"
238
- );
239
- });
240
-
241
- it("turns kill switch off", async () => {
242
- const program = await createProgram();
243
- await program.parseAsync(["monitor", "kill-switch", "off"], {
244
- from: "user",
245
- });
246
- expect(setMock).toHaveBeenCalledWith(
247
- "ns-id-123",
248
- "trade:kill_switch",
249
- "false"
250
- );
251
- });
252
- });
253
-
254
- // -- monitor backup -------------------------------------------------------
255
-
256
- describe("monitor backup", () => {
257
- it("calls db.export", async () => {
258
- const program = await createProgram();
259
- await program.parseAsync(["monitor", "backup"], { from: "user" });
260
- expect(exportMock).toHaveBeenCalled();
261
- });
262
- });
263
- });
@@ -1,269 +0,0 @@
1
- import { Command } from "commander";
2
- import { DbService } from "../../services/db/index.js";
3
- import { MonitorService } from "./monitor-service.js";
4
- import { KvSyncService } from "../../services/kv/kv-sync-service.js";
5
- import {
6
- formatSuccess,
7
- formatError,
8
- formatTable,
9
- getFormatOptions,
10
- } from "../../utils/formatters.js";
11
- import type { FormatOptions } from "../../utils/formatters.js";
12
- import { ExitCode } from "../../utils/errors.js";
13
- import { theme } from "../../utils/theme.js";
14
-
15
- async function doMonitorStatus(fmt: FormatOptions): Promise<void> {
16
- try {
17
- const monitor = new MonitorService();
18
- const result = await monitor.checkAllWorkerHealth();
19
-
20
- if (fmt.json) {
21
- process.stdout.write(JSON.stringify(result, null, 2) + "\n");
22
- return;
23
- }
24
-
25
- const rows = result.workers.map((w) => ({
26
- Worker: w.worker,
27
- Status: w.status,
28
- "Status Code": String(w.statusCode ?? "-"),
29
- Error: w.error ?? "-",
30
- }));
31
- formatTable(rows, fmt);
32
-
33
- process.stdout.write(
34
- `\n${theme.heading("Summary:")} ${result.healthyCount} healthy, ${result.degradedCount} degraded, ${result.unreachableCount} unreachable\n`
35
- );
36
- } catch (err) {
37
- formatError(err instanceof Error ? err.message : String(err), fmt);
38
- process.exitCode = ExitCode.ERROR;
39
- }
40
- }
41
-
42
- async function doMonitorTrades(
43
- limit: number,
44
- fmt: FormatOptions
45
- ): Promise<void> {
46
- try {
47
- const db = new DbService();
48
- const dbName = await db.resolveDbName();
49
- const sql = `SELECT * FROM trades ORDER BY timestamp DESC LIMIT ${Math.min(limit, 100)}`;
50
- const output = await db.query(dbName, sql, true);
51
- process.stdout.write(output + "\n");
52
- } catch (err) {
53
- formatError(err instanceof Error ? err.message : String(err), fmt);
54
- process.exitCode = ExitCode.ERROR;
55
- }
56
- }
57
-
58
- async function doMonitorLogs(
59
- workerName: string | undefined,
60
- fmt: FormatOptions
61
- ): Promise<void> {
62
- try {
63
- const db = new DbService();
64
- const dbName = await db.resolveDbName();
65
- let sql: string;
66
- if (workerName) {
67
- sql = `SELECT * FROM system_logs WHERE worker = '${workerName.replace(/'/g, "''")}' ORDER BY timestamp DESC LIMIT 20`;
68
- } else {
69
- sql = "SELECT * FROM system_logs ORDER BY timestamp DESC LIMIT 20";
70
- }
71
- const output = await db.query(dbName, sql, true);
72
- process.stdout.write(output + "\n");
73
- } catch (err) {
74
- formatError(err instanceof Error ? err.message : String(err), fmt);
75
- process.exitCode = ExitCode.ERROR;
76
- }
77
- }
78
-
79
- async function doMonitorKillSwitch(
80
- action: "show" | "on" | "off",
81
- fmt: FormatOptions
82
- ): Promise<void> {
83
- try {
84
- const kv = new KvSyncService();
85
- const namespaceId = await kv.resolveNamespaceId();
86
- const key = "trade:kill_switch";
87
-
88
- if (action === "show") {
89
- const value = await kv.get(namespaceId, key);
90
- const status =
91
- value === "true"
92
- ? "KILL SWITCH IS ON (trading halted)"
93
- : value === "false"
94
- ? "Kill switch is off (trading active)"
95
- : `Kill switch value: ${value ?? "(not set)"}`;
96
- process.stdout.write(`${theme.info(status)}\n`);
97
- } else {
98
- const newValue = action === "on" ? "true" : "false";
99
- await kv.set(namespaceId, key, newValue);
100
- formatSuccess(
101
- `Kill switch turned ${action === "on" ? "ON" : "OFF"}`,
102
- fmt
103
- );
104
- }
105
- } catch (err) {
106
- formatError(err instanceof Error ? err.message : String(err), fmt);
107
- process.exitCode = ExitCode.ERROR;
108
- }
109
- }
110
-
111
- async function doMonitorQueueDepth(fmt: FormatOptions): Promise<void> {
112
- try {
113
- const proc = Bun.spawn(["wrangler", "queues", "list"], {
114
- stdout: "pipe",
115
- stderr: "pipe",
116
- });
117
- const stdout = await new Response(proc.stdout).text();
118
- const stderr = await new Response(proc.stderr).text();
119
- const exitCode = await proc.exited;
120
-
121
- if (exitCode !== 0) {
122
- throw new Error(stderr.trim() || `wrangler exited with code ${exitCode}`);
123
- }
124
-
125
- process.stdout.write(stdout + "\n");
126
- } catch (err) {
127
- formatError(err instanceof Error ? err.message : String(err), fmt);
128
- process.exitCode = ExitCode.ERROR;
129
- }
130
- }
131
-
132
- async function doMonitorBackup(fmt: FormatOptions): Promise<void> {
133
- try {
134
- const db = new DbService();
135
- const dbName = await db.resolveDbName();
136
- const outputPath = await db.export(dbName);
137
- formatSuccess(`Database exported to ${outputPath}`, fmt);
138
- } catch (err) {
139
- formatError(err instanceof Error ? err.message : String(err), fmt);
140
- process.exitCode = ExitCode.ERROR;
141
- }
142
- }
143
-
144
- export function registerMonitorCommand(program: Command): void {
145
- const monitorCmd = program
146
- .command("monitor")
147
- .summary("Monitor and operate the trading system")
148
- .description(
149
- `Monitor worker health, trades, logs, and perform operational tasks.
150
-
151
- SUBCOMMANDS:
152
- status Check health of all workers
153
- trades [N] Show N most recent trades (default: 10)
154
- logs [worker] Show recent system logs from D1
155
- kill-switch Emergency stop/resume trading
156
- queue-depth List queues and pending messages
157
- backup Export D1 database to timestamped .sql file
158
-
159
- EXAMPLES:
160
- hoox monitor status Check all workers health
161
- hoox monitor trades 20 Show 20 recent trades
162
- hoox monitor logs hoox Show logs for hoox worker
163
- hoox monitor kill-switch show Check kill switch status
164
- hoox monitor kill-switch on Halt all trading
165
- hoox monitor kill-switch off Resume trading
166
- hoox monitor queue-depth Show queue info
167
- hoox monitor backup Export D1 database`
168
- );
169
-
170
- monitorCmd
171
- .command("status")
172
- .summary("Check health of all workers")
173
- .description("Probe each worker's /health endpoint and report status.")
174
- .action(async function (this: Command) {
175
- const fmt = getFormatOptions(this);
176
- await doMonitorStatus(fmt);
177
- });
178
-
179
- monitorCmd
180
- .command("trades")
181
- .summary("Show recent trades from D1")
182
- .description("Query the trades table for the most recent entries.")
183
- .argument(
184
- "[limit]",
185
- "Number of trades to show (default: 10, max: 100)",
186
- "10"
187
- )
188
- .action(async function (this: Command, limit: string) {
189
- const fmt = getFormatOptions(this);
190
- await doMonitorTrades(parseInt(limit, 10) || 10, fmt);
191
- });
192
-
193
- monitorCmd
194
- .command("logs")
195
- .summary("Show recent system logs from D1")
196
- .description(
197
- "Query the system_logs table. Optionally filter by worker name."
198
- )
199
- .argument("[worker]", "Worker name to filter (optional)")
200
- .action(async function (this: Command, worker?: string) {
201
- const fmt = getFormatOptions(this);
202
- await doMonitorLogs(worker, fmt);
203
- });
204
-
205
- const ksCmd = monitorCmd
206
- .command("kill-switch")
207
- .summary("Emergency stop or resume trading")
208
- .description(
209
- `Control the trade:kill_switch KV key.
210
-
211
- Commands:
212
- show Display current kill switch status
213
- on Halt all trading (set kill_switch=true)
214
- off Resume trading (set kill_switch=false)`
215
- );
216
-
217
- ksCmd
218
- .command("show")
219
- .summary("Show kill switch status")
220
- .description("Display whether trading is halted or active.")
221
- .action(async function (this: Command) {
222
- const fmt = getFormatOptions(this);
223
- await doMonitorKillSwitch("show", fmt);
224
- });
225
-
226
- ksCmd
227
- .command("on")
228
- .summary("Halt all trading")
229
- .description(
230
- "Set trade:kill_switch=true to stop all trading operations. WARNING: This halts ALL trading activity immediately."
231
- )
232
- .action(async function (this: Command) {
233
- const fmt = getFormatOptions(this);
234
- await doMonitorKillSwitch("on", fmt);
235
- });
236
-
237
- ksCmd
238
- .command("off")
239
- .summary("Resume trading")
240
- .description(
241
- "Set trade:kill_switch=false to resume normal trading operations."
242
- )
243
- .action(async function (this: Command) {
244
- const fmt = getFormatOptions(this);
245
- await doMonitorKillSwitch("off", fmt);
246
- });
247
-
248
- monitorCmd
249
- .command("queue-depth")
250
- .summary("Show queue details")
251
- .description(
252
- "List queues via wrangler queues list to show configured queues."
253
- )
254
- .action(async function (this: Command) {
255
- const fmt = getFormatOptions(this);
256
- await doMonitorQueueDepth(fmt);
257
- });
258
-
259
- monitorCmd
260
- .command("backup")
261
- .summary("Export D1 database to .sql file")
262
- .description(
263
- "Export the D1 database to a timestamped .sql backup file via wrangler d1 export."
264
- )
265
- .action(async function (this: Command) {
266
- const fmt = getFormatOptions(this);
267
- await doMonitorBackup(fmt);
268
- });
269
- }
@@ -1,65 +0,0 @@
1
- import { ConfigService } from "../../services/config/index.js";
2
- import type { WorkerHealthResult } from "./types.js";
3
-
4
- export class MonitorService {
5
- private configService: ConfigService;
6
-
7
- constructor(configService?: ConfigService) {
8
- this.configService = configService ?? new ConfigService();
9
- }
10
-
11
- async checkAllWorkerHealth(): Promise<{
12
- workers: WorkerHealthResult[];
13
- healthyCount: number;
14
- degradedCount: number;
15
- unreachableCount: number;
16
- }> {
17
- await this.configService.load();
18
- const global = this.configService.getGlobal();
19
- const prefix = global.subdomain_prefix ?? "hoox";
20
- const enabled = this.configService.listEnabledWorkers();
21
-
22
- const results: WorkerHealthResult[] = [];
23
- let healthy = 0;
24
- let degraded = 0;
25
- let unreachable = 0;
26
-
27
- for (const name of enabled) {
28
- const url = `https://${name}.${prefix}.workers.dev/health`;
29
- try {
30
- const response = await fetch(url, {
31
- signal: AbortSignal.timeout(5000),
32
- });
33
- if (response.ok) {
34
- results.push({
35
- worker: name,
36
- status: "healthy",
37
- statusCode: response.status,
38
- });
39
- healthy++;
40
- } else {
41
- results.push({
42
- worker: name,
43
- status: "degraded",
44
- statusCode: response.status,
45
- });
46
- degraded++;
47
- }
48
- } catch (err) {
49
- results.push({
50
- worker: name,
51
- status: "unreachable",
52
- error: err instanceof Error ? err.message : String(err),
53
- });
54
- unreachable++;
55
- }
56
- }
57
-
58
- return {
59
- workers: results,
60
- healthyCount: healthy,
61
- degradedCount: degraded,
62
- unreachableCount: unreachable,
63
- };
64
- }
65
- }
@@ -1,13 +0,0 @@
1
- export interface WorkerHealthResult {
2
- worker: string;
3
- status: "healthy" | "degraded" | "unreachable";
4
- statusCode?: number;
5
- error?: string;
6
- }
7
-
8
- export interface MonitorStatusResult {
9
- workers: WorkerHealthResult[];
10
- healthyCount: number;
11
- degradedCount: number;
12
- unreachableCount: number;
13
- }
@@ -1,2 +0,0 @@
1
- export { registerRepairCommand } from "./repair-command.js";
2
- export type { RepairStepResult, RepairCheckResult } from "./types.js";