@hoox-sh/hoox-shared 1.2.1 → 1.4.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 (67) hide show
  1. package/dist/agent-config-fields.js +2 -0
  2. package/dist/d1/index.js +4 -2
  3. package/dist/d1/repository.js +4 -2
  4. package/dist/errors.d.ts.map +1 -1
  5. package/dist/errors.js +4 -2
  6. package/dist/health.js +4 -2
  7. package/dist/index.d.ts +5 -5
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +432 -139
  10. package/dist/kill-switch.js +2 -0
  11. package/dist/kvKeys.d.ts +3 -0
  12. package/dist/kvKeys.d.ts.map +1 -1
  13. package/dist/kvKeys.js +3 -0
  14. package/dist/kvUtils.d.ts +34 -1
  15. package/dist/kvUtils.d.ts.map +1 -1
  16. package/dist/kvUtils.js +56 -3
  17. package/dist/middleware/auth.d.ts +6 -3
  18. package/dist/middleware/auth.d.ts.map +1 -1
  19. package/dist/middleware/auth.js +19 -5
  20. package/dist/middleware/index.d.ts +3 -2
  21. package/dist/middleware/index.d.ts.map +1 -1
  22. package/dist/middleware/index.js +88 -8
  23. package/dist/middleware/logger.js +4 -2
  24. package/dist/middleware/validate.d.ts +16 -0
  25. package/dist/middleware/validate.d.ts.map +1 -1
  26. package/dist/middleware/validate.js +37 -1
  27. package/dist/middleware/wait-until.d.ts +32 -0
  28. package/dist/middleware/wait-until.d.ts.map +1 -0
  29. package/dist/middleware/wait-until.js +46 -0
  30. package/dist/path-utils.d.ts +35 -4
  31. package/dist/path-utils.d.ts.map +1 -1
  32. package/dist/path-utils.js +72 -5
  33. package/dist/queue-handler.d.ts +6 -0
  34. package/dist/queue-handler.d.ts.map +1 -1
  35. package/dist/queue-handler.js +51 -20
  36. package/dist/router.d.ts.map +1 -1
  37. package/dist/router.js +12 -2
  38. package/dist/schemas/index.d.ts +2 -1
  39. package/dist/schemas/index.d.ts.map +1 -1
  40. package/dist/schemas/index.js +58 -13
  41. package/dist/schemas/registry.d.ts +13 -0
  42. package/dist/schemas/registry.d.ts.map +1 -1
  43. package/dist/schemas/registry.js +55 -12
  44. package/dist/schemas/types.d.ts +5 -0
  45. package/dist/schemas/types.d.ts.map +1 -1
  46. package/dist/schemas/validators.d.ts.map +1 -1
  47. package/dist/schemas/validators.js +3 -1
  48. package/dist/service-bindings.js +18 -5
  49. package/dist/session.js +69 -5
  50. package/dist/stores/config-store.d.ts +2 -0
  51. package/dist/stores/config-store.d.ts.map +1 -1
  52. package/dist/stores/config-store.js +267 -16
  53. package/dist/stores/service-store.d.ts +12 -0
  54. package/dist/stores/service-store.d.ts.map +1 -1
  55. package/dist/stores/service-store.js +101 -40
  56. package/dist/stores/ui-store.d.ts +14 -0
  57. package/dist/stores/ui-store.d.ts.map +1 -1
  58. package/dist/stores/ui-store.js +8 -1
  59. package/dist/types.d.ts +22 -4
  60. package/dist/types.d.ts.map +1 -1
  61. package/dist/types.js +8 -4
  62. package/dist/wizard/engine.d.ts.map +1 -1
  63. package/dist/wizard/engine.js +18 -35
  64. package/dist/wizard/index.js +18 -35
  65. package/dist/wizard/presets.d.ts.map +1 -1
  66. package/dist/wizard/presets.js +6 -32
  67. package/package.json +1 -1
@@ -131,37 +131,287 @@ function validateConfig(config) {
131
131
  return errors;
132
132
  }
133
133
 
134
+ // src/path-utils.ts
135
+ import {
136
+ existsSync as existsSync2,
137
+ mkdirSync as mkdirSync2,
138
+ readFileSync as readFileSync2,
139
+ writeFileSync as writeFileSync2,
140
+ chmodSync as chmodSync2
141
+ } from "fs";
142
+ import { homedir as homedir2 } from "os";
143
+ import { dirname, join as join2, resolve } from "path";
144
+ function createHooxPath(path) {
145
+ return path;
146
+ }
147
+ function getHooxHome() {
148
+ try {
149
+ const override = process.env.HOOX_HOME?.trim();
150
+ if (override) {
151
+ return createHooxPath(resolve(override));
152
+ }
153
+ const home = homedir2();
154
+ if (!home || home.length === 0) {
155
+ return createHooxPath(resolve(process.cwd(), ".hoox"));
156
+ }
157
+ return createHooxPath(join2(home, ".hoox"));
158
+ } catch {
159
+ return createHooxPath(resolve(process.cwd(), ".hoox"));
160
+ }
161
+ }
162
+ function isHooxSetupRoot(dir) {
163
+ if (!dir)
164
+ return false;
165
+ try {
166
+ const root = resolve(dir);
167
+ if (!existsSync2(join2(root, "packages", "cli", "package.json"))) {
168
+ return false;
169
+ }
170
+ return existsSync2(join2(root, "wrangler.jsonc")) || existsSync2(join2(root, "wrangler.jsonc.example")) || existsSync2(join2(root, "workers")) || existsSync2(join2(root, ".gitmodules"));
171
+ } catch {
172
+ return false;
173
+ }
174
+ }
175
+ function getRememberedMonorepoPath() {
176
+ return resolveHooxPath("config/monorepo.json");
177
+ }
178
+ function getRememberedMonorepoRoot() {
179
+ try {
180
+ const path = getRememberedMonorepoPath();
181
+ if (!existsSync2(path))
182
+ return null;
183
+ const raw = readFileSync2(path, "utf-8");
184
+ const data = JSON.parse(raw);
185
+ if (!data.root || typeof data.root !== "string")
186
+ return null;
187
+ const resolved = resolve(data.root);
188
+ return isHooxSetupRoot(resolved) ? resolved : null;
189
+ } catch {
190
+ return null;
191
+ }
192
+ }
193
+ function rememberMonorepoRoot(root) {
194
+ try {
195
+ const resolved = resolve(root);
196
+ if (!isHooxSetupRoot(resolved))
197
+ return false;
198
+ const configDir = getHooxConfigDir();
199
+ mkdirSync2(configDir, { recursive: true, mode: 448 });
200
+ try {
201
+ chmodSync2(configDir, 448);
202
+ } catch {}
203
+ const payload = {
204
+ root: resolved,
205
+ updatedAt: new Date().toISOString()
206
+ };
207
+ const path = getRememberedMonorepoPath();
208
+ writeFileSync2(path, JSON.stringify(payload, null, 2) + `
209
+ `, {
210
+ mode: 384
211
+ });
212
+ try {
213
+ chmodSync2(path, 384);
214
+ } catch {}
215
+ return true;
216
+ } catch {
217
+ return false;
218
+ }
219
+ }
220
+ function findHooxSetupRoot(startDir = process.cwd()) {
221
+ let dir = resolve(startDir);
222
+ for (;; ) {
223
+ if (isHooxSetupRoot(dir))
224
+ return dir;
225
+ const parent = dirname(dir);
226
+ if (parent === dir)
227
+ return null;
228
+ dir = parent;
229
+ }
230
+ }
231
+ function resolveHooxRuntimeRoot(options) {
232
+ const env = options?.env ?? process.env;
233
+ const cwd = resolve(options?.cwd ?? process.cwd());
234
+ const globalRepo = getHooxRepoPath();
235
+ const remembered = options?.skipRemembered ? null : getRememberedMonorepoRoot();
236
+ const envRepo = env.HOOX_REPO?.trim();
237
+ if (envRepo) {
238
+ const resolved = resolve(envRepo);
239
+ if (isHooxSetupRoot(resolved)) {
240
+ return {
241
+ root: resolved,
242
+ source: "env",
243
+ checked: {
244
+ env: resolved,
245
+ cwd: findHooxSetupRoot(cwd),
246
+ remembered,
247
+ global: globalRepo
248
+ }
249
+ };
250
+ }
251
+ return {
252
+ root: null,
253
+ source: "env",
254
+ checked: {
255
+ env: resolved,
256
+ cwd: findHooxSetupRoot(cwd),
257
+ remembered,
258
+ global: globalRepo
259
+ }
260
+ };
261
+ }
262
+ const local = findHooxSetupRoot(cwd);
263
+ if (local) {
264
+ return {
265
+ root: local,
266
+ source: "cwd",
267
+ checked: { cwd: local, remembered, global: globalRepo }
268
+ };
269
+ }
270
+ if (remembered) {
271
+ return {
272
+ root: remembered,
273
+ source: "remembered",
274
+ checked: { cwd: null, remembered, global: globalRepo }
275
+ };
276
+ }
277
+ if (isHooxSetupRoot(globalRepo)) {
278
+ return {
279
+ root: globalRepo,
280
+ source: "global",
281
+ checked: { cwd: null, remembered: null, global: globalRepo }
282
+ };
283
+ }
284
+ return {
285
+ root: null,
286
+ source: "none",
287
+ checked: { cwd: null, remembered: null, global: globalRepo }
288
+ };
289
+ }
290
+ function getTuiEntryCandidates(runtimeRoot) {
291
+ const root = resolve(runtimeRoot);
292
+ return [
293
+ join2(root, "packages", "tui", "src", "main.tsx"),
294
+ join2(root, "packages", "tui", "dist", "main.js"),
295
+ join2(root, "packages", "tui", "src", "main.ts")
296
+ ];
297
+ }
298
+ function resolveHooxPath(relativePath) {
299
+ if (!relativePath || typeof relativePath !== "string") {
300
+ throw new Error("relativePath must be a non-empty string");
301
+ }
302
+ if (relativePath.includes("..")) {
303
+ throw new Error(`Path traversal detected in relativePath: "${relativePath}"`);
304
+ }
305
+ const normalizedPath = relativePath.replace(/\\/g, "/");
306
+ const hooxHome = getHooxHome();
307
+ const fullPath = join2(hooxHome, normalizedPath);
308
+ const resolvedPath = resolve(fullPath);
309
+ const resolvedHome = resolve(hooxHome);
310
+ if (!resolvedPath.startsWith(resolvedHome)) {
311
+ throw new Error(`Resolved path "${resolvedPath}" is outside Hoox home directory`);
312
+ }
313
+ return createHooxPath(resolvedPath);
314
+ }
315
+ function isWithinHooxHome(path) {
316
+ try {
317
+ const hooxHome = getHooxHome();
318
+ const resolvedPath = resolve(path);
319
+ const resolvedHome = resolve(hooxHome);
320
+ return resolvedPath.startsWith(resolvedHome);
321
+ } catch {
322
+ return false;
323
+ }
324
+ }
325
+ function getRelativeHooxPath(absolutePath) {
326
+ try {
327
+ if (!isWithinHooxHome(absolutePath)) {
328
+ return null;
329
+ }
330
+ const hooxHome = getHooxHome();
331
+ const resolvedPath = resolve(absolutePath);
332
+ const resolvedHome = resolve(hooxHome);
333
+ const relativePath = resolvedPath.slice(resolvedHome.length);
334
+ return relativePath.startsWith("/") || relativePath.startsWith("\\") ? relativePath.slice(1) : relativePath;
335
+ } catch {
336
+ return null;
337
+ }
338
+ }
339
+ function getHooxRepoPath() {
340
+ return resolveHooxPath("repo");
341
+ }
342
+ function getHooxConfigDir() {
343
+ return resolveHooxPath("config");
344
+ }
345
+ function getHooxDataDir() {
346
+ return resolveHooxPath("data");
347
+ }
348
+ function getHooxWranglerPath() {
349
+ return resolveHooxPath("config/wrangler.jsonc");
350
+ }
351
+ function getHooxStatePath() {
352
+ return resolveHooxPath("data/state.json");
353
+ }
354
+
134
355
  // src/stores/config-store.ts
135
356
  import { create } from "zustand";
136
357
  import { immer } from "zustand/middleware/immer";
137
358
  import { persist, createJSONStorage } from "zustand/middleware";
138
- import { chmodSync as chmodSync2, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "fs";
139
- import { homedir as homedir2 } from "os";
140
- import { join as join2 } from "path";
359
+ import { chmodSync as chmodSync3, mkdirSync as mkdirSync3, existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
360
+ import { join as join3 } from "path";
361
+ function getTuiPreferencesPath() {
362
+ return join3(getHooxHome(), ".tui-state", "preferences.json");
363
+ }
364
+ function getLegacyConfigJsonPath() {
365
+ return join3(getHooxHome(), "config.json");
366
+ }
367
+ function extractZustandPrefsPayload(raw) {
368
+ try {
369
+ const parsed = JSON.parse(raw);
370
+ if (parsed && typeof parsed === "object" && parsed.state && typeof parsed.state === "object" && !Array.isArray(parsed.state) && (("theme" in parsed.state) || ("refreshIntervalMs" in parsed.state)) && !("apiToken" in parsed)) {
371
+ return raw;
372
+ }
373
+ } catch {}
374
+ return null;
375
+ }
141
376
  var bunConfigStorage = {
142
377
  getItem: async (_name) => {
143
378
  try {
144
- const file = Bun.file(join2(homedir2(), ".hoox", "config.json"));
145
- const exists = await file.exists();
146
- if (!exists)
147
- return null;
148
- return await file.text();
379
+ const prefsPath = getTuiPreferencesPath();
380
+ const prefsFile = Bun.file(prefsPath);
381
+ if (await prefsFile.exists()) {
382
+ return await prefsFile.text();
383
+ }
384
+ const legacyPath = getLegacyConfigJsonPath();
385
+ if (existsSync3(legacyPath)) {
386
+ const legacyRaw = readFileSync3(legacyPath, "utf-8");
387
+ const envelope = extractZustandPrefsPayload(legacyRaw);
388
+ if (envelope) {
389
+ await bunConfigStorage.setItem(_name, envelope);
390
+ return envelope;
391
+ }
392
+ }
393
+ return null;
149
394
  } catch {
150
395
  return null;
151
396
  }
152
397
  },
153
398
  setItem: async (_name, value) => {
154
- const dir = join2(homedir2(), ".hoox");
155
- if (!existsSync2(dir)) {
156
- mkdirSync2(dir, { recursive: true, mode: HOOX_DIR_MODE });
399
+ const home = getHooxHome();
400
+ const stateDir = join3(home, ".tui-state");
401
+ if (!existsSync3(home)) {
402
+ mkdirSync3(home, { recursive: true, mode: HOOX_DIR_MODE });
403
+ }
404
+ if (!existsSync3(stateDir)) {
405
+ mkdirSync3(stateDir, { recursive: true, mode: HOOX_DIR_MODE });
157
406
  }
158
407
  try {
159
- chmodSync2(dir, HOOX_DIR_MODE);
408
+ chmodSync3(home, HOOX_DIR_MODE);
409
+ chmodSync3(stateDir, HOOX_DIR_MODE);
160
410
  } catch {}
161
- const filePath = join2(dir, "config.json");
411
+ const filePath = getTuiPreferencesPath();
162
412
  await Bun.write(filePath, value);
163
413
  try {
164
- chmodSync2(filePath, HOOX_CONFIG_FILE_MODE);
414
+ chmodSync3(filePath, HOOX_CONFIG_FILE_MODE);
165
415
  } catch {}
166
416
  },
167
417
  removeItem: async (_name) => {}
@@ -233,7 +483,7 @@ var useConfigStore = create()(persist(immer((set) => ({
233
483
  state.notifications[channel] = !state.notifications[channel];
234
484
  })
235
485
  })), {
236
- name: "hoox-config",
486
+ name: "hoox-tui-prefs",
237
487
  storage: createJSONStorage(() => bunConfigStorage),
238
488
  partialize: (state) => ({
239
489
  theme: state.theme,
@@ -251,5 +501,6 @@ var useConfigStore = create()(persist(immer((set) => ({
251
501
  })
252
502
  }));
253
503
  export {
254
- useConfigStore
504
+ useConfigStore,
505
+ getTuiPreferencesPath
255
506
  };
@@ -41,6 +41,12 @@ interface ServiceActions {
41
41
  stopStreams: () => void;
42
42
  addAlert: (alert: Alert) => void;
43
43
  addAlerts: (alerts: Alert[]) => void;
44
+ /** Mark a single alert as acknowledged (UI triage). */
45
+ acknowledgeAlert: (id: string) => void;
46
+ /** Remove a single alert from the ring buffer. */
47
+ dismissAlert: (id: string) => void;
48
+ /** Clear the local log ring buffer (TUI display only). */
49
+ clearLogs: () => void;
44
50
  setConnectionStatus: (status: ConnectionStatus) => void;
45
51
  selectWorker: (id: string | null) => void;
46
52
  setWorkers: (workers: WorkerInfo[]) => void;
@@ -154,6 +160,9 @@ export declare const useServiceStore: import("zustand").UseBoundStore<Omit<impor
154
160
  stopStreams: () => void;
155
161
  addAlert: (alert: Alert) => void;
156
162
  addAlerts: (alerts: Alert[]) => void;
163
+ acknowledgeAlert: (id: string) => void;
164
+ dismissAlert: (id: string) => void;
165
+ clearLogs: () => void;
157
166
  setConnectionStatus: (status: ConnectionStatus) => void;
158
167
  selectWorker: (id: string | null) => void;
159
168
  setWorkers: (workers: WorkerInfo[]) => void;
@@ -247,6 +256,9 @@ export declare const useServiceStore: import("zustand").UseBoundStore<Omit<impor
247
256
  stopStreams: () => void;
248
257
  addAlert: (alert: Alert) => void;
249
258
  addAlerts: (alerts: Alert[]) => void;
259
+ acknowledgeAlert: (id: string) => void;
260
+ dismissAlert: (id: string) => void;
261
+ clearLogs: () => void;
250
262
  setConnectionStatus: (status: ConnectionStatus) => void;
251
263
  selectWorker: (id: string | null) => void;
252
264
  setWorkers: (workers: WorkerInfo[]) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"service-store.d.ts","sourceRoot":"","sources":["../../src/stores/service-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA+BH,OAAO,KAAK,EACV,UAAU,EACV,KAAK,EACL,KAAK,EACL,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,eAAe,EAChB,MAAM,UAAU,CAAC;AAwClB,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,WAAW,EAAE,KAAK,EAAE,CAAC;IACrB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;;OAKG;IACH,gBAAgB,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,sDAAsD;IACtD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAID,UAAU,cAAc;IACtB,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC;;;OAGG;IACH,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACrC,mBAAmB,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,UAAU,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;IAC5C,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,OAAO,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IACjC,UAAU,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IAG7C,6DAA6D;IAC7D,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,gEAAgE;IAChE,uBAAuB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,0DAA0D;IAC1D,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,kDAAkD;IAClD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB;;;;OAIG;IACH,mBAAmB,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/D;;;;OAIG;IACH,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;CACtD;AAkDD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAzHR,gBAAgB;qBACrB,MAAM;0BACD,MAAM,GAAG,IAAI;oBAInB,MAAM;mBAEP,MAAM,GAAG,IAAI;;;;;;;;;;6BASH,MAAM;wBAEX,MAAM;wBAEN,MAAM,GAAG,IAAI;sBAMf,MAAM,OAAO,CAAC,IAAI,CAAC;sBACnB,MAAM,OAAO,CAAC,IAAI,CAAC;oBACrB,MAAM,OAAO,CAAC,IAAI,CAAC;qBAKlB,MAAM,IAAI;kBACb,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI;mBACrB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI;6BACf,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI;sBACzC,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;oBAC7B,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI;mBAChC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI;iBACxB,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI;oBACpB,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI;iCAInB,MAAM,IAAI;iCAEV,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI;sBAEzC,MAAM,IAAI;oBAEZ,MAAM,IAAI;6BAMD,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI;oBAMlD,MAAM,IAAI;0BAMJ,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAtElC,gBAAgB;qBACrB,MAAM;0BACD,MAAM,GAAG,IAAI;oBAInB,MAAM;mBAEP,MAAM,GAAG,IAAI;;;;;;;;;;6BASH,MAAM;wBAEX,MAAM;wBAEN,MAAM,GAAG,IAAI;sBAMf,MAAM,OAAO,CAAC,IAAI,CAAC;sBACnB,MAAM,OAAO,CAAC,IAAI,CAAC;oBACrB,MAAM,OAAO,CAAC,IAAI,CAAC;qBAKlB,MAAM,IAAI;kBACb,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI;mBACrB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI;6BACf,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI;sBACzC,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;oBAC7B,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI;mBAChC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI;iBACxB,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI;oBACpB,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI;iCAInB,MAAM,IAAI;iCAEV,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI;sBAEzC,MAAM,IAAI;oBAEZ,MAAM,IAAI;6BAMD,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI;oBAMlD,MAAM,IAAI;0BAMJ,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI;;EA2WrD,CAAC"}
1
+ {"version":3,"file":"service-store.d.ts","sourceRoot":"","sources":["../../src/stores/service-store.ts"],"names":[],"mappings":"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"}
@@ -277,6 +277,23 @@ function ringPush(arr, item, max) {
277
277
  var tradeStreamAbort = null;
278
278
  var logStreamAbort = null;
279
279
  var fetchWorkersGeneration = 0;
280
+ var reconnectTimer = null;
281
+ function clearReconnectTimer() {
282
+ if (reconnectTimer !== null) {
283
+ clearTimeout(reconnectTimer);
284
+ reconnectTimer = null;
285
+ }
286
+ }
287
+ function scheduleReconnect(delayMs) {
288
+ clearReconnectTimer();
289
+ if (delayMs < 0)
290
+ return;
291
+ reconnectTimer = setTimeout(() => {
292
+ reconnectTimer = null;
293
+ scheduledReconnectTick();
294
+ }, delayMs);
295
+ }
296
+ var scheduledReconnectTick = async () => {};
280
297
  var MAX_TRADES = 500;
281
298
  var MAX_ALERTS = 100;
282
299
  var MAX_LOGS = 1000;
@@ -300,7 +317,7 @@ function getBackoffDelay(retryCount) {
300
317
  if (retryCount <= 0)
301
318
  return 0;
302
319
  const index = Math.min(retryCount - 1, BACKOFF_SEQUENCE.length - 1);
303
- return BACKOFF_SEQUENCE[index];
320
+ return BACKOFF_SEQUENCE[index] ?? 0;
304
321
  }
305
322
  var useServiceStore = create()(immer((set, get) => ({
306
323
  ...initialState,
@@ -311,6 +328,7 @@ var useServiceStore = create()(immer((set, get) => ({
311
328
  const data = await hooxFetch2("/v1/workers");
312
329
  if (gen !== fetchWorkersGeneration)
313
330
  return;
331
+ clearReconnectTimer();
314
332
  set((state) => {
315
333
  state.workers = data;
316
334
  state.lastUpdated = Date.now();
@@ -336,6 +354,7 @@ var useServiceStore = create()(immer((set, get) => ({
336
354
  timestamp: Date.now(),
337
355
  acknowledged: false
338
356
  });
357
+ let nextDelay = 0;
339
358
  set((state) => {
340
359
  state.lastError = msg;
341
360
  state.disconnectedAt = state.disconnectedAt ?? Date.now();
@@ -344,21 +363,26 @@ var useServiceStore = create()(immer((set, get) => ({
344
363
  state.retryCount = state.retryCount + 1;
345
364
  if (state.retryCount >= MAX_RETRIES2) {
346
365
  state.connectionStatus = "offline";
347
- state.lastError = `Connection lost after ${MAX_RETRIES2} retries`;
366
+ state.lastError = `${msg} (gave up after ${MAX_RETRIES2} retries)`;
367
+ state.reconnectDelay = 0;
348
368
  } else {
349
369
  state.reconnectDelay = getBackoffDelay(state.retryCount);
370
+ nextDelay = state.reconnectDelay;
350
371
  }
351
372
  } else if (state.connectionStatus === "reconnecting") {
352
373
  state.retryCount = state.retryCount + 1;
353
374
  if (state.retryCount >= MAX_RETRIES2) {
354
375
  state.connectionStatus = "offline";
355
- state.lastError = `Connection lost after ${MAX_RETRIES2} retries`;
376
+ state.lastError = `${msg} (gave up after ${MAX_RETRIES2} retries)`;
356
377
  state.reconnectDelay = 0;
357
378
  } else {
358
379
  state.reconnectDelay = getBackoffDelay(state.retryCount);
380
+ nextDelay = state.reconnectDelay;
359
381
  }
360
382
  }
361
383
  });
384
+ if (nextDelay > 0)
385
+ scheduleReconnect(nextDelay);
362
386
  }
363
387
  },
364
388
  streamTrades: async () => {
@@ -420,6 +444,17 @@ var useServiceStore = create()(immer((set, get) => ({
420
444
  const merged = [...state.alerts, ...alerts];
421
445
  state.alerts = merged.length > MAX_ALERTS ? merged.slice(merged.length - MAX_ALERTS) : merged;
422
446
  }),
447
+ acknowledgeAlert: (id) => set((state) => {
448
+ const hit = state.alerts.find((a) => a.id === id);
449
+ if (hit)
450
+ hit.acknowledged = true;
451
+ }),
452
+ dismissAlert: (id) => set((state) => {
453
+ state.alerts = state.alerts.filter((a) => a.id !== id);
454
+ }),
455
+ clearLogs: () => set((state) => {
456
+ state.logs = [];
457
+ }),
423
458
  setConnectionStatus: (status) => set((state) => {
424
459
  if (status === "connected") {
425
460
  state.retryCount = 0;
@@ -450,49 +485,69 @@ var useServiceStore = create()(immer((set, get) => ({
450
485
  state.metrics = metrics;
451
486
  state.lastUpdated = metrics.lastUpdated;
452
487
  }),
453
- handleConnectionSuccess: () => set((state) => {
454
- state.lastSuccessfulFetch = Date.now();
455
- state.retryCount = 0;
456
- state.lastError = null;
457
- state.lastErrorDetails = null;
458
- state.reconnectDelay = 0;
459
- state.disconnectedAt = null;
460
- state.connectionStatus = "connected";
461
- }),
462
- handleConnectionFailure: (errorMessage) => set((state) => {
463
- state.lastError = errorMessage;
464
- state.disconnectedAt = state.disconnectedAt ?? Date.now();
465
- if (state.connectionStatus === "connected" || state.connectionStatus === "polling") {
466
- state.connectionStatus = "reconnecting";
467
- state.retryCount = 1;
468
- state.reconnectDelay = getBackoffDelay(1);
469
- } else if (state.connectionStatus === "reconnecting") {
470
- state.retryCount = state.retryCount + 1;
471
- if (state.retryCount >= MAX_RETRIES2) {
472
- state.connectionStatus = "offline";
473
- state.lastError = `Connection lost after ${MAX_RETRIES2} retries`;
474
- state.reconnectDelay = 0;
475
- } else {
476
- state.reconnectDelay = getBackoffDelay(state.retryCount);
488
+ handleConnectionSuccess: () => {
489
+ clearReconnectTimer();
490
+ set((state) => {
491
+ state.lastSuccessfulFetch = Date.now();
492
+ state.retryCount = 0;
493
+ state.lastError = null;
494
+ state.lastErrorDetails = null;
495
+ state.reconnectDelay = 0;
496
+ state.disconnectedAt = null;
497
+ state.connectionStatus = "connected";
498
+ });
499
+ },
500
+ handleConnectionFailure: (errorMessage) => {
501
+ let nextDelay = 0;
502
+ set((state) => {
503
+ state.lastError = errorMessage;
504
+ state.disconnectedAt = state.disconnectedAt ?? Date.now();
505
+ if (state.connectionStatus === "connected" || state.connectionStatus === "polling") {
506
+ state.connectionStatus = "reconnecting";
507
+ state.retryCount = 1;
508
+ state.reconnectDelay = getBackoffDelay(1);
509
+ nextDelay = state.reconnectDelay;
510
+ } else if (state.connectionStatus === "reconnecting") {
511
+ state.retryCount = state.retryCount + 1;
512
+ if (state.retryCount >= MAX_RETRIES2) {
513
+ state.connectionStatus = "offline";
514
+ state.lastError = `${errorMessage} (gave up after ${MAX_RETRIES2} retries)`;
515
+ state.reconnectDelay = 0;
516
+ } else {
517
+ state.reconnectDelay = getBackoffDelay(state.retryCount);
518
+ nextDelay = state.reconnectDelay;
519
+ }
477
520
  }
478
- }
479
- }),
480
- resetRetries: () => set((state) => {
481
- state.retryCount = 0;
482
- state.lastError = null;
483
- state.lastErrorDetails = null;
484
- state.reconnectDelay = 0;
485
- state.disconnectedAt = null;
486
- }),
487
- forceRetry: () => set((state) => {
488
- if (state.connectionStatus === "offline") {
489
- state.connectionStatus = "polling";
521
+ });
522
+ if (nextDelay > 0)
523
+ scheduleReconnect(nextDelay);
524
+ },
525
+ resetRetries: () => {
526
+ clearReconnectTimer();
527
+ set((state) => {
490
528
  state.retryCount = 0;
491
529
  state.lastError = null;
492
530
  state.lastErrorDetails = null;
493
531
  state.reconnectDelay = 0;
532
+ state.disconnectedAt = null;
533
+ });
534
+ },
535
+ forceRetry: () => {
536
+ clearReconnectTimer();
537
+ const wasOffline = get().connectionStatus === "offline";
538
+ set((state) => {
539
+ if (state.connectionStatus === "offline") {
540
+ state.connectionStatus = "polling";
541
+ state.retryCount = 0;
542
+ state.lastError = null;
543
+ state.lastErrorDetails = null;
544
+ state.reconnectDelay = 0;
545
+ }
546
+ });
547
+ if (wasOffline) {
548
+ scheduleReconnect(0);
494
549
  }
495
- }),
550
+ },
496
551
  setLastErrorDetails: (details) => set((state) => {
497
552
  state.lastErrorDetails = details;
498
553
  state.lastError = details === null ? null : summarizeCliError(details);
@@ -515,6 +570,12 @@ var useServiceStore = create()(immer((set, get) => ({
515
570
  }, MAX_ALERTS);
516
571
  })
517
572
  })));
573
+ scheduledReconnectTick = async () => {
574
+ const status = useServiceStore.getState().connectionStatus;
575
+ if (status === "reconnecting" || status === "polling") {
576
+ await useServiceStore.getState().fetchWorkers();
577
+ }
578
+ };
518
579
  export {
519
580
  useServiceStore
520
581
  };
@@ -9,6 +9,11 @@ export interface UIState {
9
9
  modal: ModalState | null;
10
10
  commandPaletteOpen: boolean;
11
11
  previousView: ViewId | null;
12
+ /**
13
+ * Whether the status-bar CLI/connection diagnostics panel is expanded.
14
+ * Shared so palette / Ctrl+Shift+D / mouse can all toggle it.
15
+ */
16
+ statusErrorExpanded: boolean;
12
17
  }
13
18
  interface UIActions {
14
19
  setView: (view: ViewId) => void;
@@ -18,6 +23,9 @@ interface UIActions {
18
23
  showModal: (modal: ModalState) => void;
19
24
  dismissModal: () => void;
20
25
  goBack: () => void;
26
+ /** Toggle status-bar error diagnostics panel. */
27
+ toggleStatusErrorExpanded: () => void;
28
+ setStatusErrorExpanded: (expanded: boolean) => void;
21
29
  }
22
30
  export declare const useUIStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<UIState & UIActions>, "setState"> & {
23
31
  setState(nextStateOrUpdater: (UIState & UIActions) | Partial<UIState & UIActions> | ((state: {
@@ -33,6 +41,7 @@ export declare const useUIStore: import("zustand").UseBoundStore<Omit<import("zu
33
41
  } | null;
34
42
  commandPaletteOpen: boolean;
35
43
  previousView: ViewId | null;
44
+ statusErrorExpanded: boolean;
36
45
  setView: (view: ViewId) => void;
37
46
  toggleSidebar: () => void;
38
47
  openPalette: () => void;
@@ -40,6 +49,8 @@ export declare const useUIStore: import("zustand").UseBoundStore<Omit<import("zu
40
49
  showModal: (modal: ModalState) => void;
41
50
  dismissModal: () => void;
42
51
  goBack: () => void;
52
+ toggleStatusErrorExpanded: () => void;
53
+ setStatusErrorExpanded: (expanded: boolean) => void;
43
54
  }) => void), shouldReplace?: false): void;
44
55
  setState(nextStateOrUpdater: (UIState & UIActions) | ((state: {
45
56
  activeView: ViewId;
@@ -54,6 +65,7 @@ export declare const useUIStore: import("zustand").UseBoundStore<Omit<import("zu
54
65
  } | null;
55
66
  commandPaletteOpen: boolean;
56
67
  previousView: ViewId | null;
68
+ statusErrorExpanded: boolean;
57
69
  setView: (view: ViewId) => void;
58
70
  toggleSidebar: () => void;
59
71
  openPalette: () => void;
@@ -61,6 +73,8 @@ export declare const useUIStore: import("zustand").UseBoundStore<Omit<import("zu
61
73
  showModal: (modal: ModalState) => void;
62
74
  dismissModal: () => void;
63
75
  goBack: () => void;
76
+ toggleStatusErrorExpanded: () => void;
77
+ setStatusErrorExpanded: (expanded: boolean) => void;
64
78
  }) => void), shouldReplace: true): void;
65
79
  }>;
66
80
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"ui-store.d.ts","sourceRoot":"","sources":["../../src/stores/ui-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAInD,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAID,UAAU,SAAS;IACjB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACvC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAgBD,eAAO,MAAM,UAAU;;oBAjCT,MAAM;yBACD,OAAO;;;;;;;;;4BAEJ,OAAO;sBACb,MAAM,GAAG,IAAI;iBAMlB,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;uBAChB,MAAM,IAAI;qBACZ,MAAM,IAAI;sBACT,MAAM,IAAI;mBACb,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;sBACxB,MAAM,IAAI;gBAChB,MAAM,IAAI;;;oBAhBN,MAAM;yBACD,OAAO;;;;;;;;;4BAEJ,OAAO;sBACb,MAAM,GAAG,IAAI;iBAMlB,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;uBAChB,MAAM,IAAI;qBACZ,MAAM,IAAI;sBACT,MAAM,IAAI;mBACb,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;sBACxB,MAAM,IAAI;gBAChB,MAAM,IAAI;;EAiEnB,CAAC"}
1
+ {"version":3,"file":"ui-store.d.ts","sourceRoot":"","sources":["../../src/stores/ui-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAInD,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;OAGG;IACH,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAID,UAAU,SAAS;IACjB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACvC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,iDAAiD;IACjD,yBAAyB,EAAE,MAAM,IAAI,CAAC;IACtC,sBAAsB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD;AAiBD,eAAO,MAAM,UAAU;;oBA1CT,MAAM;yBACD,OAAO;;;;;;;;;4BAEJ,OAAO;sBACb,MAAM,GAAG,IAAI;6BAKN,OAAO;iBAMnB,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;uBAChB,MAAM,IAAI;qBACZ,MAAM,IAAI;sBACT,MAAM,IAAI;mBACb,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;sBACxB,MAAM,IAAI;gBAChB,MAAM,IAAI;mCAES,MAAM,IAAI;gCACb,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI;;;oBAxBvC,MAAM;yBACD,OAAO;;;;;;;;;4BAEJ,OAAO;sBACb,MAAM,GAAG,IAAI;6BAKN,OAAO;iBAMnB,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;uBAChB,MAAM,IAAI;qBACZ,MAAM,IAAI;sBACT,MAAM,IAAI;mBACb,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;sBACxB,MAAM,IAAI;gBAChB,MAAM,IAAI;mCAES,MAAM,IAAI;gCACb,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI;;EA4EpD,CAAC"}
@@ -24,7 +24,8 @@ var initialState = {
24
24
  sidebarExpanded: true,
25
25
  modal: null,
26
26
  commandPaletteOpen: false,
27
- previousView: null
27
+ previousView: null,
28
+ statusErrorExpanded: false
28
29
  };
29
30
  var useUIStore = create()(immer((set) => ({
30
31
  ...initialState,
@@ -55,6 +56,12 @@ var useUIStore = create()(immer((set) => ({
55
56
  state.activeView = state.previousView;
56
57
  state.previousView = null;
57
58
  }
59
+ }),
60
+ toggleStatusErrorExpanded: () => set((state) => {
61
+ state.statusErrorExpanded = !state.statusErrorExpanded;
62
+ }),
63
+ setStatusErrorExpanded: (expanded) => set((state) => {
64
+ state.statusErrorExpanded = expanded;
58
65
  })
59
66
  })));
60
67
  export {