@hoox-sh/hoox-tui 0.3.1 → 0.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 (53) hide show
  1. package/dist/main.js +1400 -2764
  2. package/package.json +3 -8
  3. package/src/app.tsx +17 -15
  4. package/src/components/shared/shared.test.tsx +2 -2
  5. package/src/components/ui/connection-toasts.ts +6 -0
  6. package/src/components/ui/dialog-state.ts +17 -0
  7. package/src/components/ui/dialog.tsx +434 -172
  8. package/src/components/views/ai-chat.tsx +6 -1
  9. package/src/components/views/config-editor/code-editor.tsx +8 -6
  10. package/src/components/views/config-editor.test.tsx +20 -17
  11. package/src/components/views/config-editor.tsx +8 -6
  12. package/src/components/views/dashboard/model-health-section.tsx +38 -46
  13. package/src/components/views/dashboard/pyne-health-section.tsx +36 -41
  14. package/src/components/views/dashboard.tsx +25 -28
  15. package/src/components/views/kv-viewer.test.tsx +4 -16
  16. package/src/components/views/kv-viewer.tsx +9 -13
  17. package/src/components/views/logs-viewer.test.tsx +4 -4
  18. package/src/components/views/queue-depth.test.tsx +5 -7
  19. package/src/components/views/queue-depth.tsx +10 -14
  20. package/src/components/views/secrets-viewer.test.tsx +1 -1
  21. package/src/components/views/secrets-viewer.tsx +11 -15
  22. package/src/components/views/service-manager.test.tsx +8 -27
  23. package/src/components/views/service-manager.tsx +1 -0
  24. package/src/components/views/settings.test.tsx +2 -7
  25. package/src/components/views/settings.tsx +43 -60
  26. package/src/components/views/setup-wizard.test.tsx +12 -14
  27. package/src/components/views/setup-wizard.tsx +61 -59
  28. package/src/components/views/worker-detail.test.tsx +2 -2
  29. package/src/components/views/worker-settings.tsx +6 -6
  30. package/src/components/views/workers-overview.tsx +1 -1
  31. package/src/hooks/hooks.test.ts +10 -174
  32. package/src/hooks/index.ts +1 -3
  33. package/src/hooks/renderer-ref.ts +1 -0
  34. package/src/hooks/shell-overlay.ts +3 -2
  35. package/src/hooks/use-polling.ts +12 -0
  36. package/src/services/cli-bridge/index.ts +56 -12
  37. package/src/services/cli-bridge/standalone.ts +4 -1
  38. package/src/services/cli-bridge/types.ts +6 -9
  39. package/src/services/cli-bridge.test.ts +20 -4
  40. package/src/services/clipboard.ts +2 -2
  41. package/src/stores/service-store.test.ts +29 -26
  42. package/src/stores/session-restore.test.ts +2 -0
  43. package/src/test-setup.ts +5 -13
  44. package/src/test-utils.ts +4 -24
  45. package/src/types.ts +9 -47
  46. package/src/utils/colors.test.ts +8 -3
  47. package/src/view-registry.test.ts +2 -19
  48. package/src/view-registry.tsx +7 -20
  49. package/src/components/shared/animated-border.tsx +0 -58
  50. package/src/components/shared/keybinding-hint.tsx +0 -37
  51. package/src/components/ui/select.tsx +0 -197
  52. package/src/hooks/use-keyboard.ts +0 -130
  53. package/src/hooks/use-service-data.ts +0 -35
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hoox-sh/hoox-tui",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Hoox algorithmic trading terminal operations center — OpenTUI dashboard",
5
5
  "type": "module",
6
6
  "main": "./dist/main.js",
@@ -32,8 +32,7 @@
32
32
  "prepublishOnly": "bun run typecheck && bun run build"
33
33
  },
34
34
  "dependencies": {
35
- "@hoox-sh/hoox-shared": "^1.3.0",
36
- "@opentui-ui/dialog": "^0.1.2",
35
+ "@hoox-sh/hoox-shared": "^1.6.0",
37
36
  "@opentui/core": "0.5.1",
38
37
  "@opentui/react": "0.5.1",
39
38
  "immer": "^11.1.8",
@@ -41,12 +40,8 @@
41
40
  "smol-toml": "^1.6.1",
42
41
  "zustand": "^5.0.0"
43
42
  },
44
- "overrides": {
45
- "@opentui/core": "0.5.1",
46
- "@opentui/react": "0.5.1"
47
- },
48
43
  "devDependencies": {
49
- "@cloudflare/workers-types": "^5.20260708.1",
44
+ "@cloudflare/workers-types": "^5.20261001.1",
50
45
  "@hoox/test-utils": "^0.0.1",
51
46
  "@types/bun": "latest",
52
47
  "typescript": "^6.0.3"
package/src/app.tsx CHANGED
@@ -20,8 +20,12 @@
20
20
  */
21
21
  import { useState, useEffect, useCallback } from "react";
22
22
  import { useKeyboard } from "@opentui/react";
23
- import { DialogProvider, useDialog } from "@opentui-ui/dialog/react";
24
- import { useServiceStore, useUIStore, Colors } from "@hoox-sh/hoox-shared";
23
+ import {
24
+ useServiceStore,
25
+ useUIStore,
26
+ useConfigStore,
27
+ Colors,
28
+ } from "@hoox-sh/hoox-shared";
25
29
  import { restoreSession, saveSession } from "@hoox-sh/hoox-shared";
26
30
  import type { ViewId } from "@hoox-sh/hoox-shared";
27
31
 
@@ -42,7 +46,7 @@ import {
42
46
  toastReconnectedMode,
43
47
  } from "./components/ui/connection-toasts";
44
48
  import { getRendererRef } from "./hooks";
45
- import type { DialogHandle } from "./components/ui/dialog";
49
+ import { DialogProvider, useDialog } from "./components/ui/dialog";
46
50
  import {
47
51
  getViewFactory,
48
52
  getViewShortcutMap,
@@ -95,19 +99,14 @@ function quitApp(): void {
95
99
  */
96
100
  export function AppRoot({ safeMode = false }: { safeMode?: boolean }) {
97
101
  return (
98
- <DialogProvider
99
- size="medium"
100
- backdropColor={Colors.backdrop}
101
- backdropOpacity={0.35}
102
- >
102
+ <DialogProvider>
103
103
  <AppRootInner safeMode={safeMode} />
104
104
  </DialogProvider>
105
105
  );
106
106
  }
107
107
 
108
108
  function AppRootInner({ safeMode = false }: { safeMode?: boolean }) {
109
- // DialogProvider is required for useDialog; cast to our thin DialogHandle.
110
- const dialog = useDialog() as unknown as DialogHandle;
109
+ const dialog = useDialog();
111
110
  const [restoring, setRestoring] = useState(true);
112
111
  const activeView = useUIStore((s) => s.activeView);
113
112
  const commandPaletteOpen = useUIStore((s) => s.commandPaletteOpen);
@@ -134,11 +133,15 @@ function AppRootInner({ safeMode = false }: { safeMode?: boolean }) {
134
133
  // Shared restoreSession validates all 16 ViewIds (unknown → dashboard).
135
134
  useEffect(() => {
136
135
  let cancelled = false;
137
- (async () => {
136
+ void (async () => {
138
137
  const session = await restoreSession();
139
138
  if (cancelled) return;
140
139
 
141
- const view: ViewId = session.activeView;
140
+ const preferred = useConfigStore.getState().defaultView;
141
+ const view: ViewId =
142
+ !session.fromDisk && isRegisteredViewId(preferred)
143
+ ? preferred
144
+ : session.activeView;
142
145
  const expanded = session.sidebarExpanded;
143
146
 
144
147
  if (isRegisteredViewId(view)) {
@@ -172,7 +175,7 @@ function AppRootInner({ safeMode = false }: { safeMode?: boolean }) {
172
175
  }
173
176
  let cancelled = false;
174
177
 
175
- (async () => {
178
+ void (async () => {
176
179
  const store = useServiceStore.getState();
177
180
  const conn = resolveTuiConnectionEnv();
178
181
  await tuiDevLog.info("connection", "startup data load begin", {
@@ -230,8 +233,7 @@ function AppRootInner({ safeMode = false }: { safeMode?: boolean }) {
230
233
  if (result.success && result.data) {
231
234
  const raw = result.data as Record<string, unknown>;
232
235
  const rawWorkers = (raw.workers ?? raw.status ?? raw) as
233
- | unknown[]
234
- | Record<string, unknown>;
236
+ unknown[] | Record<string, unknown>;
235
237
  const parsed = Array.isArray(rawWorkers)
236
238
  ? rawWorkers
237
239
  : typeof rawWorkers === "object" && rawWorkers !== null
@@ -395,13 +395,13 @@ describe("Shared Components", () => {
395
395
  it("filters to matching commands", () => {
396
396
  const result = filterCommands(SAMPLE_COMMANDS, "dash");
397
397
  expect(result.length).toBe(1);
398
- expect(result[0].name).toBe("Dashboard");
398
+ expect(result[0]?.name).toBe("Dashboard");
399
399
  });
400
400
 
401
401
  it("sorts by score (best match first)", () => {
402
402
  const result = filterCommands(SAMPLE_COMMANDS, "theme");
403
403
  expect(result.length).toBe(2);
404
- expect(result[0].name).toBe("Dark Theme"); // or Light Theme
404
+ expect(result[0]?.name).toBe("Dark Theme"); // or Light Theme
405
405
  });
406
406
 
407
407
  it("deduplicates by id", () => {
@@ -17,16 +17,19 @@ import { remoteAuthMissingHint } from "../../services/tui-connection";
17
17
 
18
18
  // ─── Pure message builders (testable without toast side effects) ─────────────
19
19
 
20
+ /** Status-bar toast copy for a successful LOCAL/REMOTE connect. */
20
21
  export function messageConnected(mode: TuiMode, host: string): string {
21
22
  const label = mode === "remote" ? "REMOTE" : "LOCAL";
22
23
  return `Connected · ${label} · ${host}`;
23
24
  }
24
25
 
26
+ /** Status-bar toast copy when the LOCAL/REMOTE session drops. */
25
27
  export function messageConnectionLost(mode: TuiMode, host: string): string {
26
28
  const label = mode === "remote" ? "REMOTE" : "LOCAL";
27
29
  return `Connection lost · ${label} · ${host}`;
28
30
  }
29
31
 
32
+ /** Status-bar toast copy after a reconnect, including downtime. */
30
33
  export function messageReconnected(
31
34
  mode: TuiMode,
32
35
  host: string,
@@ -38,15 +41,18 @@ export function messageReconnected(
38
41
  return `Reconnected · ${label} · ${host} · ${duration} downtime`;
39
42
  }
40
43
 
44
+ /** Status-bar toast copy when auth is rejected. */
41
45
  export function messageAuthRequired(mode: TuiMode, host: string): string {
42
46
  const label = mode === "remote" ? "REMOTE" : "LOCAL";
43
47
  return `Auth failed · ${label} · ${host}`;
44
48
  }
45
49
 
50
+ /** Status-bar toast copy when remote mode has no API credentials. */
46
51
  export function messageAuthMissing(host: string): string {
47
52
  return `No API credentials · REMOTE · ${host}`;
48
53
  }
49
54
 
55
+ /** Status-bar toast copy when the TUI starts without a live connection. */
50
56
  export function messageOfflineStartup(
51
57
  mode: TuiMode,
52
58
  host: string,
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ /** Module-level open count for DialogProvider (avoids React store cycles). */
7
+ let openDialogCount = 0;
8
+
9
+ /** Record how many Hoox dialogs are currently open (shell overlay gate). */
10
+ export function setOpenDialogCount(n: number): void {
11
+ openDialogCount = Math.max(0, n);
12
+ }
13
+
14
+ /** True when any in-house dialog owns the keyboard. */
15
+ export function isHooxDialogOpen(): boolean {
16
+ return openDialogCount > 0;
17
+ }