@nex-ai/nex 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/dist/agent/adoption.d.ts +23 -0
- package/dist/agent/adoption.js +87 -0
- package/dist/agent/adoption.js.map +1 -0
- package/dist/agent/gossip.d.ts +17 -0
- package/dist/agent/gossip.js +48 -0
- package/dist/agent/gossip.js.map +1 -0
- package/dist/agent/loop.d.ts +59 -0
- package/dist/agent/loop.js +389 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/queues.d.ts +16 -0
- package/dist/agent/queues.js +44 -0
- package/dist/agent/queues.js.map +1 -0
- package/dist/agent/session-store.d.ts +21 -0
- package/dist/agent/session-store.js +96 -0
- package/dist/agent/session-store.js.map +1 -0
- package/dist/agent/templates.d.ts +5 -0
- package/dist/agent/templates.js +48 -0
- package/dist/agent/templates.js.map +1 -0
- package/dist/agent/tools.d.ts +25 -0
- package/dist/agent/tools.js +238 -0
- package/dist/agent/tools.js.map +1 -0
- package/dist/agent/types.d.ts +59 -0
- package/dist/agent/types.js +5 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/calendar/scheduler.d.ts +32 -0
- package/dist/calendar/scheduler.js +178 -0
- package/dist/calendar/scheduler.js.map +1 -0
- package/dist/calendar/store.d.ts +15 -0
- package/dist/calendar/store.js +50 -0
- package/dist/calendar/store.js.map +1 -0
- package/dist/calendar/types.d.ts +17 -0
- package/dist/calendar/types.js +5 -0
- package/dist/calendar/types.js.map +1 -0
- package/dist/chat/channel.d.ts +20 -0
- package/dist/chat/channel.js +84 -0
- package/dist/chat/channel.js.map +1 -0
- package/dist/chat/message-store.d.ts +18 -0
- package/dist/chat/message-store.js +82 -0
- package/dist/chat/message-store.js.map +1 -0
- package/dist/chat/router.d.ts +17 -0
- package/dist/chat/router.js +65 -0
- package/dist/chat/router.js.map +1 -0
- package/dist/chat/suggested-responses.d.ts +6 -0
- package/dist/chat/suggested-responses.js +99 -0
- package/dist/chat/suggested-responses.js.map +1 -0
- package/dist/chat/types.d.ts +28 -0
- package/dist/chat/types.js +5 -0
- package/dist/chat/types.js.map +1 -0
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/dispatch.d.ts +39 -0
- package/dist/commands/dispatch.js +1293 -0
- package/dist/commands/dispatch.js.map +1 -0
- package/dist/commands/init.d.ts +49 -0
- package/dist/commands/init.js +315 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/parse-input.d.ts +5 -0
- package/dist/commands/parse-input.js +37 -0
- package/dist/commands/parse-input.js.map +1 -0
- package/dist/index.d.ts +6 -23
- package/dist/index.js +118 -50
- package/dist/index.js.map +1 -1
- package/dist/lib/client.js +1 -1
- package/dist/lib/client.js.map +1 -1
- package/dist/lib/errors.js +1 -1
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/graph-html.d.ts +1 -0
- package/dist/lib/graph-html.js +16 -3
- package/dist/lib/graph-html.js.map +1 -1
- package/dist/lib/integrations.d.ts +23 -0
- package/dist/lib/integrations.js +25 -0
- package/dist/lib/integrations.js.map +1 -0
- package/dist/lib/nex-mcp-config.d.ts +14 -0
- package/dist/lib/nex-mcp-config.js +26 -0
- package/dist/lib/nex-mcp-config.js.map +1 -0
- package/dist/orchestration/budget.d.ts +32 -0
- package/dist/orchestration/budget.js +72 -0
- package/dist/orchestration/budget.js.map +1 -0
- package/dist/orchestration/executor.d.ts +59 -0
- package/dist/orchestration/executor.js +197 -0
- package/dist/orchestration/executor.js.map +1 -0
- package/dist/orchestration/router.d.ts +30 -0
- package/dist/orchestration/router.js +98 -0
- package/dist/orchestration/router.js.map +1 -0
- package/dist/orchestration/templates.d.ts +11 -0
- package/dist/orchestration/templates.js +99 -0
- package/dist/orchestration/templates.js.map +1 -0
- package/dist/orchestration/types.d.ts +58 -0
- package/dist/orchestration/types.js +7 -0
- package/dist/orchestration/types.js.map +1 -0
- package/dist/plugin/shared.js +1 -1
- package/dist/plugin/shared.js.map +1 -1
- package/dist/tui/agent-colors.d.ts +19 -0
- package/dist/tui/agent-colors.js +34 -0
- package/dist/tui/agent-colors.js.map +1 -0
- package/dist/tui/app.d.ts +14 -0
- package/dist/tui/app.js +267 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/channel-colors.d.ts +16 -0
- package/dist/tui/channel-colors.js +43 -0
- package/dist/tui/channel-colors.js.map +1 -0
- package/dist/tui/components/agent-card.d.ts +11 -0
- package/dist/tui/components/agent-card.js +40 -0
- package/dist/tui/components/agent-card.js.map +1 -0
- package/dist/tui/components/banner.d.ts +44 -0
- package/dist/tui/components/banner.js +130 -0
- package/dist/tui/components/banner.js.map +1 -0
- package/dist/tui/components/channel-colors.d.ts +21 -0
- package/dist/tui/components/channel-colors.js +53 -0
- package/dist/tui/components/channel-colors.js.map +1 -0
- package/dist/tui/components/channel-message.d.ts +53 -0
- package/dist/tui/components/channel-message.js +66 -0
- package/dist/tui/components/channel-message.js.map +1 -0
- package/dist/tui/components/chat-input.d.ts +11 -0
- package/dist/tui/components/chat-input.js +19 -0
- package/dist/tui/components/chat-input.js.map +1 -0
- package/dist/tui/components/data-table.d.ts +11 -0
- package/dist/tui/components/data-table.js +47 -0
- package/dist/tui/components/data-table.js.map +1 -0
- package/dist/tui/components/error-box.d.ts +11 -0
- package/dist/tui/components/error-box.js +59 -0
- package/dist/tui/components/error-box.js.map +1 -0
- package/dist/tui/components/help-screen.d.ts +3 -0
- package/dist/tui/components/help-screen.js +63 -0
- package/dist/tui/components/help-screen.js.map +1 -0
- package/dist/tui/components/index.d.ts +17 -0
- package/dist/tui/components/index.js +10 -0
- package/dist/tui/components/index.js.map +1 -0
- package/dist/tui/components/inline-confirm.d.ts +14 -0
- package/dist/tui/components/inline-confirm.js +13 -0
- package/dist/tui/components/inline-confirm.js.map +1 -0
- package/dist/tui/components/inline-select.d.ts +21 -0
- package/dist/tui/components/inline-select.js +20 -0
- package/dist/tui/components/inline-select.js.map +1 -0
- package/dist/tui/components/markdown.d.ts +6 -0
- package/dist/tui/components/markdown.js +179 -0
- package/dist/tui/components/markdown.js.map +1 -0
- package/dist/tui/components/mention-autocomplete.d.ts +77 -0
- package/dist/tui/components/mention-autocomplete.js +235 -0
- package/dist/tui/components/mention-autocomplete.js.map +1 -0
- package/dist/tui/components/message-list.d.ts +18 -0
- package/dist/tui/components/message-list.js +29 -0
- package/dist/tui/components/message-list.js.map +1 -0
- package/dist/tui/components/picker.d.ts +16 -0
- package/dist/tui/components/picker.js +32 -0
- package/dist/tui/components/picker.js.map +1 -0
- package/dist/tui/components/progress-steps.d.ts +13 -0
- package/dist/tui/components/progress-steps.js +21 -0
- package/dist/tui/components/progress-steps.js.map +1 -0
- package/dist/tui/components/slack/compose.d.ts +27 -0
- package/dist/tui/components/slack/compose.js +123 -0
- package/dist/tui/components/slack/compose.js.map +1 -0
- package/dist/tui/components/slack/layout.d.ts +36 -0
- package/dist/tui/components/slack/layout.js +96 -0
- package/dist/tui/components/slack/layout.js.map +1 -0
- package/dist/tui/components/slack/messages.d.ts +72 -0
- package/dist/tui/components/slack/messages.js +177 -0
- package/dist/tui/components/slack/messages.js.map +1 -0
- package/dist/tui/components/slack/quick-switcher.d.ts +33 -0
- package/dist/tui/components/slack/quick-switcher.js +98 -0
- package/dist/tui/components/slack/quick-switcher.js.map +1 -0
- package/dist/tui/components/slack/sidebar-types.d.ts +65 -0
- package/dist/tui/components/slack/sidebar-types.js +7 -0
- package/dist/tui/components/slack/sidebar-types.js.map +1 -0
- package/dist/tui/components/slack/sidebar.d.ts +46 -0
- package/dist/tui/components/slack/sidebar.js +52 -0
- package/dist/tui/components/slack/sidebar.js.map +1 -0
- package/dist/tui/components/slack/thread-panel.d.ts +45 -0
- package/dist/tui/components/slack/thread-panel.js +47 -0
- package/dist/tui/components/slack/thread-panel.js.map +1 -0
- package/dist/tui/components/slash-autocomplete.d.ts +81 -0
- package/dist/tui/components/slash-autocomplete.js +218 -0
- package/dist/tui/components/slash-autocomplete.js.map +1 -0
- package/dist/tui/components/spinner.d.ts +17 -0
- package/dist/tui/components/spinner.js +30 -0
- package/dist/tui/components/spinner.js.map +1 -0
- package/dist/tui/components/status-bar.d.ts +23 -0
- package/dist/tui/components/status-bar.js +55 -0
- package/dist/tui/components/status-bar.js.map +1 -0
- package/dist/tui/components/success-box.d.ts +7 -0
- package/dist/tui/components/success-box.js +10 -0
- package/dist/tui/components/success-box.js.map +1 -0
- package/dist/tui/components/tool-indicator.d.ts +12 -0
- package/dist/tui/components/tool-indicator.js +18 -0
- package/dist/tui/components/tool-indicator.js.map +1 -0
- package/dist/tui/components/viewport.d.ts +9 -0
- package/dist/tui/components/viewport.js +24 -0
- package/dist/tui/components/viewport.js.map +1 -0
- package/dist/tui/generative/bindings.d.ts +27 -0
- package/dist/tui/generative/bindings.js +152 -0
- package/dist/tui/generative/bindings.js.map +1 -0
- package/dist/tui/generative/registry.d.ts +19 -0
- package/dist/tui/generative/registry.js +31 -0
- package/dist/tui/generative/registry.js.map +1 -0
- package/dist/tui/generative/renderer.d.ts +24 -0
- package/dist/tui/generative/renderer.js +160 -0
- package/dist/tui/generative/renderer.js.map +1 -0
- package/dist/tui/generative/types.d.ts +68 -0
- package/dist/tui/generative/types.js +7 -0
- package/dist/tui/generative/types.js.map +1 -0
- package/dist/tui/hooks/use-cancellable.d.ts +28 -0
- package/dist/tui/hooks/use-cancellable.js +51 -0
- package/dist/tui/hooks/use-cancellable.js.map +1 -0
- package/dist/tui/hooks/use-streaming.d.ts +44 -0
- package/dist/tui/hooks/use-streaming.js +105 -0
- package/dist/tui/hooks/use-streaming.js.map +1 -0
- package/dist/tui/index.d.ts +4 -0
- package/dist/tui/index.js +7 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/keybindings.d.ts +25 -0
- package/dist/tui/keybindings.js +277 -0
- package/dist/tui/keybindings.js.map +1 -0
- package/dist/tui/register-views.d.ts +8 -0
- package/dist/tui/register-views.js +116 -0
- package/dist/tui/register-views.js.map +1 -0
- package/dist/tui/router.d.ts +29 -0
- package/dist/tui/router.js +87 -0
- package/dist/tui/router.js.map +1 -0
- package/dist/tui/services/agent-service.d.ts +58 -0
- package/dist/tui/services/agent-service.js +197 -0
- package/dist/tui/services/agent-service.js.map +1 -0
- package/dist/tui/services/calendar-service.d.ts +31 -0
- package/dist/tui/services/calendar-service.js +133 -0
- package/dist/tui/services/calendar-service.js.map +1 -0
- package/dist/tui/services/chat-service.d.ts +28 -0
- package/dist/tui/services/chat-service.js +91 -0
- package/dist/tui/services/chat-service.js.map +1 -0
- package/dist/tui/services/orchestration-service.d.ts +42 -0
- package/dist/tui/services/orchestration-service.js +153 -0
- package/dist/tui/services/orchestration-service.js.map +1 -0
- package/dist/tui/slash-commands.d.ts +106 -0
- package/dist/tui/slash-commands.js +1421 -0
- package/dist/tui/slash-commands.js.map +1 -0
- package/dist/tui/store.d.ts +96 -0
- package/dist/tui/store.js +120 -0
- package/dist/tui/store.js.map +1 -0
- package/dist/tui/theme.d.ts +40 -0
- package/dist/tui/theme.js +39 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/tui/tui-context.d.ts +22 -0
- package/dist/tui/tui-context.js +17 -0
- package/dist/tui/tui-context.js.map +1 -0
- package/dist/tui/views/agent-list.d.ts +8 -0
- package/dist/tui/views/agent-list.js +11 -0
- package/dist/tui/views/agent-list.js.map +1 -0
- package/dist/tui/views/ask-chat.d.ts +9 -0
- package/dist/tui/views/ask-chat.js +40 -0
- package/dist/tui/views/ask-chat.js.map +1 -0
- package/dist/tui/views/calendar.d.ts +15 -0
- package/dist/tui/views/calendar.js +29 -0
- package/dist/tui/views/calendar.js.map +1 -0
- package/dist/tui/views/chat.d.ts +18 -0
- package/dist/tui/views/chat.js +28 -0
- package/dist/tui/views/chat.js.map +1 -0
- package/dist/tui/views/generative.d.ts +14 -0
- package/dist/tui/views/generative.js +37 -0
- package/dist/tui/views/generative.js.map +1 -0
- package/dist/tui/views/help.d.ts +6 -0
- package/dist/tui/views/help.js +9 -0
- package/dist/tui/views/help.js.map +1 -0
- package/dist/tui/views/home-screen.d.ts +67 -0
- package/dist/tui/views/home-screen.js +192 -0
- package/dist/tui/views/home-screen.js.map +1 -0
- package/dist/tui/views/home.d.ts +33 -0
- package/dist/tui/views/home.js +60 -0
- package/dist/tui/views/home.js.map +1 -0
- package/dist/tui/views/index.d.ts +20 -0
- package/dist/tui/views/index.js +11 -0
- package/dist/tui/views/index.js.map +1 -0
- package/dist/tui/views/insights.d.ts +19 -0
- package/dist/tui/views/insights.js +46 -0
- package/dist/tui/views/insights.js.map +1 -0
- package/dist/tui/views/orchestration.d.ts +18 -0
- package/dist/tui/views/orchestration.js +73 -0
- package/dist/tui/views/orchestration.js.map +1 -0
- package/dist/tui/views/record-detail.d.ts +10 -0
- package/dist/tui/views/record-detail.js +22 -0
- package/dist/tui/views/record-detail.js.map +1 -0
- package/dist/tui/views/record-list.d.ts +15 -0
- package/dist/tui/views/record-list.js +22 -0
- package/dist/tui/views/record-list.js.map +1 -0
- package/dist/tui/views/slack-channel-header.d.ts +15 -0
- package/dist/tui/views/slack-channel-header.js +16 -0
- package/dist/tui/views/slack-channel-header.js.map +1 -0
- package/dist/tui/views/slack-home.d.ts +21 -0
- package/dist/tui/views/slack-home.js +572 -0
- package/dist/tui/views/slack-home.js.map +1 -0
- package/dist/tui/views/task-board.d.ts +21 -0
- package/dist/tui/views/task-board.js +33 -0
- package/dist/tui/views/task-board.js.map +1 -0
- package/dist/tui/views/timeline.d.ts +17 -0
- package/dist/tui/views/timeline.js +24 -0
- package/dist/tui/views/timeline.js.map +1 -0
- package/package.json +8 -3
package/dist/tui/app.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Root Ink application.
|
|
4
|
+
* Wraps everything in theme context + TuiContext, handles global key events,
|
|
5
|
+
* renders the router and a single status bar.
|
|
6
|
+
*
|
|
7
|
+
* Ctrl+C behavior:
|
|
8
|
+
* - During loading: cancels current operation, shows "^C (interrupted)"
|
|
9
|
+
* - When idle: first press shows "Press Ctrl+C again to exit",
|
|
10
|
+
* second press within 1s exits the process
|
|
11
|
+
*/
|
|
12
|
+
import { useState, useEffect, useCallback, useMemo, useRef } from "react";
|
|
13
|
+
import { Box, Text, useInput, useApp } from "ink";
|
|
14
|
+
import { createStore } from "./store.js";
|
|
15
|
+
import { handleKey } from "./keybindings.js";
|
|
16
|
+
import { ThemeProvider } from "./theme.js";
|
|
17
|
+
import { Router } from "./router.js";
|
|
18
|
+
import { StatusBar as ComponentStatusBar } from "./components/status-bar.js";
|
|
19
|
+
import { TuiContext } from "./tui-context.js";
|
|
20
|
+
// Register all views with the router (side-effect import)
|
|
21
|
+
import "./register-views.js";
|
|
22
|
+
// Re-export context hook for convenience
|
|
23
|
+
export { useTuiState } from "./tui-context.js";
|
|
24
|
+
// ── Constants ─────────────────────────────────────────────────────────
|
|
25
|
+
const CTRL_C_WINDOW_MS = 1000;
|
|
26
|
+
const INTERRUPTED_DISPLAY_MS = 2000;
|
|
27
|
+
const EXIT_HINT_DISPLAY_MS = 2000;
|
|
28
|
+
// ── Status bar adapter ─────────────────────────────────────────────
|
|
29
|
+
function AppStatusBar({ state }) {
|
|
30
|
+
const breadcrumbs = state.viewStack.map((v) => v.name);
|
|
31
|
+
const currentViewName = state.viewStack[state.viewStack.length - 1]?.name ?? "home";
|
|
32
|
+
const inputViews = new Set(["home", "chat", "ask-chat"]);
|
|
33
|
+
const isInputView = inputViews.has(currentViewName);
|
|
34
|
+
const focusSec = globalThis.__nexFocusSection;
|
|
35
|
+
const sectionLabel = focusSec ? `[${focusSec}]` : "";
|
|
36
|
+
const hint = state.loading
|
|
37
|
+
? state.loadingHint || "loading..."
|
|
38
|
+
: isInputView
|
|
39
|
+
? currentViewName === "home"
|
|
40
|
+
? `Shift+Tab=focus Ctrl+K=search ${sectionLabel}`
|
|
41
|
+
: "Esc=back | type to send"
|
|
42
|
+
: "Esc=back | j/k=nav Enter=select";
|
|
43
|
+
return (_jsx(ComponentStatusBar, { mode: state.mode, breadcrumbs: breadcrumbs.length > 0 ? breadcrumbs : ["home"], hint: hint, conversationMode: isInputView, session: state.session ?? undefined }));
|
|
44
|
+
}
|
|
45
|
+
// ── App component ──────────────────────────────────────────────────
|
|
46
|
+
export function App() {
|
|
47
|
+
const store = useMemo(() => createStore(), []);
|
|
48
|
+
const [state, setState] = useState(store.getState);
|
|
49
|
+
const [interrupted, setInterrupted] = useState(false);
|
|
50
|
+
const [exitHint, setExitHint] = useState(false);
|
|
51
|
+
const { exit } = useApp();
|
|
52
|
+
// Track last Ctrl+C press time for double-press detection
|
|
53
|
+
const lastCtrlCTime = useRef(0);
|
|
54
|
+
// Subscribe to store changes
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
const unsub = store.subscribe(() => {
|
|
57
|
+
setState(store.getState());
|
|
58
|
+
});
|
|
59
|
+
return unsub;
|
|
60
|
+
}, [store]);
|
|
61
|
+
// Override process.exit for clean shutdown within Ink
|
|
62
|
+
const originalExit = useMemo(() => process.exit, []);
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
const handler = ((_code) => {
|
|
65
|
+
exit();
|
|
66
|
+
// Ensure the Node process actually terminates after Ink unmounts
|
|
67
|
+
setTimeout(() => originalExit(_code ?? 0), 150);
|
|
68
|
+
});
|
|
69
|
+
process.exit = handler;
|
|
70
|
+
return () => {
|
|
71
|
+
process.exit = originalExit;
|
|
72
|
+
};
|
|
73
|
+
}, [exit, originalExit]);
|
|
74
|
+
// Cancel function: aborts current loading operation
|
|
75
|
+
const cancel = useCallback(() => {
|
|
76
|
+
const currentState = store.getState();
|
|
77
|
+
if (currentState.loading) {
|
|
78
|
+
store.dispatch({ type: "SET_LOADING", loading: false, hint: "" });
|
|
79
|
+
setInterrupted(true);
|
|
80
|
+
setTimeout(() => setInterrupted(false), INTERRUPTED_DISPLAY_MS);
|
|
81
|
+
}
|
|
82
|
+
}, [store]);
|
|
83
|
+
// Clear interrupted when new loading starts
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
if (state.loading) {
|
|
86
|
+
setInterrupted(false);
|
|
87
|
+
setExitHint(false);
|
|
88
|
+
}
|
|
89
|
+
}, [state.loading]);
|
|
90
|
+
// Ctrl+C handler
|
|
91
|
+
const handleCtrlC = useCallback(() => {
|
|
92
|
+
const now = Date.now();
|
|
93
|
+
const currentState = store.getState();
|
|
94
|
+
// During loading: cancel the operation
|
|
95
|
+
if (currentState.loading) {
|
|
96
|
+
cancel();
|
|
97
|
+
lastCtrlCTime.current = now;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// When idle: double-press to exit
|
|
101
|
+
if (now - lastCtrlCTime.current <= CTRL_C_WINDOW_MS) {
|
|
102
|
+
// Second press within window → exit
|
|
103
|
+
process.exit(0);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
// First idle press → show exit hint
|
|
107
|
+
lastCtrlCTime.current = now;
|
|
108
|
+
setExitHint(true);
|
|
109
|
+
setTimeout(() => setExitHint(false), EXIT_HINT_DISPLAY_MS);
|
|
110
|
+
}, [store, cancel]);
|
|
111
|
+
// Global key handler
|
|
112
|
+
const onInput = useCallback((input, key) => {
|
|
113
|
+
const currentView = state.viewStack[state.viewStack.length - 1]?.name ?? "home";
|
|
114
|
+
// Views that have their own text input — pass keys through
|
|
115
|
+
// so users can type without vim mode. Only intercept Escape (back)
|
|
116
|
+
// and Ctrl+C (cancel/exit).
|
|
117
|
+
const inputViews = new Set(["home", "chat", "ask-chat"]);
|
|
118
|
+
const isInputView = inputViews.has(currentView);
|
|
119
|
+
if (isInputView) {
|
|
120
|
+
if (key.ctrl && key.name === "c") {
|
|
121
|
+
handleCtrlC();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (key.escape && currentView !== "home") {
|
|
125
|
+
// Pop back from input sub-view
|
|
126
|
+
store.dispatch({ type: "POP_VIEW" });
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
// Home-view specific key interception
|
|
130
|
+
if (currentView === "home") {
|
|
131
|
+
const g = globalThis;
|
|
132
|
+
// Ctrl+K → open quick switcher
|
|
133
|
+
if (key.ctrl && key.name === "k") {
|
|
134
|
+
const openSwitcher = g.__nexQuickSwitcherOpen;
|
|
135
|
+
if (openSwitcher) {
|
|
136
|
+
openSwitcher();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Quick switcher open → route arrow keys and Escape
|
|
141
|
+
const isQS = g.__nexQuickSwitcherIsOpen;
|
|
142
|
+
if (isQS) {
|
|
143
|
+
if (key.escape) {
|
|
144
|
+
const closeSwitcher = g.__nexQuickSwitcherClose;
|
|
145
|
+
if (closeSwitcher)
|
|
146
|
+
closeSwitcher();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (key.name === "up" || key.name === "down") {
|
|
150
|
+
const navFn = g.__nexQuickSwitcherNav;
|
|
151
|
+
if (navFn) {
|
|
152
|
+
navFn(key.name === "up" ? -1 : 1);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Let other keys (typing) pass through to TextInput
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
// Escape → close thread or do nothing
|
|
160
|
+
if (key.escape) {
|
|
161
|
+
const focusSec = g.__nexFocusSection;
|
|
162
|
+
if (focusSec === "thread") {
|
|
163
|
+
const closeThread = g.__nexThreadClose;
|
|
164
|
+
if (closeThread)
|
|
165
|
+
closeThread();
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Tab → autocomplete only (never cycles focus sections)
|
|
171
|
+
if (key.name === "tab" && !key.shift) {
|
|
172
|
+
const tabCompleteFn = g.__nexHomeTabComplete;
|
|
173
|
+
if (tabCompleteFn) {
|
|
174
|
+
tabCompleteFn(1);
|
|
175
|
+
}
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
// Shift+Tab → cycle focus sections (backward)
|
|
179
|
+
if (key.name === "tab" && key.shift) {
|
|
180
|
+
const focusCycle = g.__nexSlackFocusCycle;
|
|
181
|
+
if (focusCycle) {
|
|
182
|
+
focusCycle(-1);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Arrow keys when sidebar is focused → sidebar navigation
|
|
187
|
+
const focusSec = g.__nexFocusSection;
|
|
188
|
+
if (focusSec === "sidebar") {
|
|
189
|
+
if (key.name === "up" || key.name === "down") {
|
|
190
|
+
const navFn = g.__nexSidebarNav;
|
|
191
|
+
if (navFn) {
|
|
192
|
+
navFn(key.name === "up" ? -1 : 1);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (key.name === "return") {
|
|
197
|
+
const selectFn = g.__nexSidebarSelect;
|
|
198
|
+
if (selectFn) {
|
|
199
|
+
selectFn();
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (input === " ") {
|
|
204
|
+
const toggleFn = g.__nexSidebarToggle;
|
|
205
|
+
if (toggleFn) {
|
|
206
|
+
toggleFn();
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// n = new channel, a = new agent DM
|
|
211
|
+
if (input === "n") {
|
|
212
|
+
const addChannelFn = g.__nexAddChannel;
|
|
213
|
+
if (addChannelFn) {
|
|
214
|
+
addChannelFn();
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (input === "a") {
|
|
219
|
+
const addAgentFn = g.__nexAddAgent;
|
|
220
|
+
if (addAgentFn) {
|
|
221
|
+
addAgentFn();
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Let everything else go to the TextInput in the view
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
// In non-input views, use the full keybinding handler
|
|
231
|
+
let raw = input;
|
|
232
|
+
if (key.escape)
|
|
233
|
+
raw = "\x1b";
|
|
234
|
+
if (key.ctrl && key.name) {
|
|
235
|
+
if (key.name === "c") {
|
|
236
|
+
handleCtrlC();
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const code = key.name.charCodeAt(0) - 96;
|
|
240
|
+
if (code > 0 && code <= 26)
|
|
241
|
+
raw = String.fromCharCode(code);
|
|
242
|
+
}
|
|
243
|
+
if (key.name === "up" ||
|
|
244
|
+
key.name === "down" ||
|
|
245
|
+
key.name === "left" ||
|
|
246
|
+
key.name === "right") {
|
|
247
|
+
const arrowMap = {
|
|
248
|
+
up: "\x1b[A",
|
|
249
|
+
down: "\x1b[B",
|
|
250
|
+
right: "\x1b[C",
|
|
251
|
+
left: "\x1b[D",
|
|
252
|
+
};
|
|
253
|
+
raw = arrowMap[key.name] ?? raw;
|
|
254
|
+
}
|
|
255
|
+
if (key.name === "return")
|
|
256
|
+
raw = "\r";
|
|
257
|
+
if (key.name === "tab")
|
|
258
|
+
raw = "\t";
|
|
259
|
+
if (key.name === "backspace")
|
|
260
|
+
raw = "\x7f";
|
|
261
|
+
handleKey(raw, store.getState(), store.dispatch);
|
|
262
|
+
}, [store, state.viewStack, handleCtrlC]);
|
|
263
|
+
useInput(onInput);
|
|
264
|
+
const tuiContextValue = useMemo(() => ({ state, dispatch: store.dispatch, store, cancel }), [state, store, cancel]);
|
|
265
|
+
return (_jsx(ThemeProvider, { children: _jsx(TuiContext.Provider, { value: tuiContextValue, children: _jsxs(Box, { flexDirection: "column", minHeight: 10, children: [_jsx(Box, { flexDirection: "column", flexGrow: 1, children: _jsx(Router, { viewStack: state.viewStack, dispatch: store.dispatch }) }), interrupted && (_jsxs(Box, { paddingX: 2, children: [_jsx(Text, { dimColor: true, children: "^C" }), _jsx(Text, { color: "red", children: " (interrupted)" })] })), exitHint && !interrupted && (_jsx(Box, { paddingX: 2, children: _jsx(Text, { dimColor: true, children: "Press Ctrl+C again to exit" }) })), _jsx(AppStatusBar, { state: state })] }) }) }));
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/tui/app.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent channel color assignment.
|
|
3
|
+
*
|
|
4
|
+
* Well-known channels get fixed colors matching the spec.
|
|
5
|
+
* Unknown channels cycle through the palette like agent-colors.ts.
|
|
6
|
+
*/
|
|
7
|
+
declare const CHANNEL_PALETTE: readonly ["cyan", "green", "yellow", "magenta", "blue", "red"];
|
|
8
|
+
export type ChannelColor = typeof CHANNEL_PALETTE[number];
|
|
9
|
+
/**
|
|
10
|
+
* Return the colour assigned to a channel name, assigning a new one on first
|
|
11
|
+
* encounter. Well-known names get fixed colors; others cycle the palette.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getChannelColor(channelName: string): ChannelColor;
|
|
14
|
+
/** Reset all assignments (useful in tests). */
|
|
15
|
+
export declare function resetChannelColors(): void;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent channel color assignment.
|
|
3
|
+
*
|
|
4
|
+
* Well-known channels get fixed colors matching the spec.
|
|
5
|
+
* Unknown channels cycle through the palette like agent-colors.ts.
|
|
6
|
+
*/
|
|
7
|
+
const CHANNEL_PALETTE = ['cyan', 'green', 'yellow', 'magenta', 'blue', 'red'];
|
|
8
|
+
/** Well-known channel → color mapping. */
|
|
9
|
+
const WELL_KNOWN = {
|
|
10
|
+
general: 'cyan',
|
|
11
|
+
leads: 'green',
|
|
12
|
+
seo: 'yellow',
|
|
13
|
+
support: 'magenta',
|
|
14
|
+
marketing: 'blue',
|
|
15
|
+
alerts: 'red',
|
|
16
|
+
};
|
|
17
|
+
// Module-level state so colours persist across renders.
|
|
18
|
+
const colorMap = new Map();
|
|
19
|
+
let nextIdx = 0;
|
|
20
|
+
/**
|
|
21
|
+
* Return the colour assigned to a channel name, assigning a new one on first
|
|
22
|
+
* encounter. Well-known names get fixed colors; others cycle the palette.
|
|
23
|
+
*/
|
|
24
|
+
export function getChannelColor(channelName) {
|
|
25
|
+
const existing = colorMap.get(channelName);
|
|
26
|
+
if (existing !== undefined)
|
|
27
|
+
return existing;
|
|
28
|
+
const wellKnown = WELL_KNOWN[channelName.toLowerCase()];
|
|
29
|
+
if (wellKnown) {
|
|
30
|
+
colorMap.set(channelName, wellKnown);
|
|
31
|
+
return wellKnown;
|
|
32
|
+
}
|
|
33
|
+
const color = CHANNEL_PALETTE[nextIdx % CHANNEL_PALETTE.length];
|
|
34
|
+
colorMap.set(channelName, color);
|
|
35
|
+
nextIdx++;
|
|
36
|
+
return color;
|
|
37
|
+
}
|
|
38
|
+
/** Reset all assignments (useful in tests). */
|
|
39
|
+
export function resetChannelColors() {
|
|
40
|
+
colorMap.clear();
|
|
41
|
+
nextIdx = 0;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=channel-colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-colors.js","sourceRoot":"","sources":["../../src/tui/channel-colors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAU,CAAC;AAGvF,0CAA0C;AAC1C,MAAM,UAAU,GAAiC;IAC/C,OAAO,EAAE,MAAM;IACf,KAAK,EAAE,OAAO;IACd,GAAG,EAAE,QAAQ;IACb,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,MAAM;IACjB,MAAM,EAAE,KAAK;CACd,CAAC;AAEF,wDAAwD;AACxD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;AACjD,IAAI,OAAO,GAAG,CAAC,CAAC;AAEhB;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAE5C,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;IACxD,IAAI,SAAS,EAAE,CAAC;QACd,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACrC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAChE,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACjC,OAAO,EAAE,CAAC;IACV,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,kBAAkB;IAChC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACjB,OAAO,GAAG,CAAC,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type AgentStatus = "idle" | "running" | "error" | "stopped";
|
|
3
|
+
export interface AgentCardProps {
|
|
4
|
+
name: string;
|
|
5
|
+
status: AgentStatus;
|
|
6
|
+
expertise?: string;
|
|
7
|
+
lastHeartbeat?: number;
|
|
8
|
+
nextHeartbeat?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function AgentCard({ name, status, expertise, lastHeartbeat, nextHeartbeat, }: AgentCardProps): React.JSX.Element;
|
|
11
|
+
export default AgentCard;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
// --- Helpers ---
|
|
4
|
+
const STATUS_CONFIG = {
|
|
5
|
+
idle: { dot: "\u25CB", color: "gray" },
|
|
6
|
+
running: { dot: "\u25CF", color: "green" },
|
|
7
|
+
error: { dot: "\u25CF", color: "red" },
|
|
8
|
+
stopped: { dot: "\u25CF", color: "yellow" },
|
|
9
|
+
};
|
|
10
|
+
function timeAgo(ts) {
|
|
11
|
+
const diff = Date.now() - ts;
|
|
12
|
+
const secs = Math.floor(diff / 1000);
|
|
13
|
+
if (secs < 60)
|
|
14
|
+
return `${secs}s ago`;
|
|
15
|
+
const mins = Math.floor(secs / 60);
|
|
16
|
+
if (mins < 60)
|
|
17
|
+
return `${mins}m ago`;
|
|
18
|
+
const hrs = Math.floor(mins / 60);
|
|
19
|
+
return `${hrs}h ago`;
|
|
20
|
+
}
|
|
21
|
+
function timeUntil(ts) {
|
|
22
|
+
const diff = ts - Date.now();
|
|
23
|
+
if (diff <= 0)
|
|
24
|
+
return "now";
|
|
25
|
+
const secs = Math.floor(diff / 1000);
|
|
26
|
+
if (secs < 60)
|
|
27
|
+
return `in ${secs}s`;
|
|
28
|
+
const mins = Math.floor(secs / 60);
|
|
29
|
+
if (mins < 60)
|
|
30
|
+
return `in ${mins}m`;
|
|
31
|
+
const hrs = Math.floor(mins / 60);
|
|
32
|
+
return `in ${hrs}h`;
|
|
33
|
+
}
|
|
34
|
+
// --- Component ---
|
|
35
|
+
export function AgentCard({ name, status, expertise, lastHeartbeat, nextHeartbeat, }) {
|
|
36
|
+
const cfg = STATUS_CONFIG[status];
|
|
37
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: cfg.color, paddingX: 1, minWidth: 28, children: [_jsxs(Box, { children: [_jsx(Text, { color: cfg.color, children: cfg.dot }), _jsx(Text, { children: " " }), _jsx(Text, { bold: true, children: name }), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: `(${status})` })] }), expertise && (_jsxs(Box, { marginTop: 0, children: [_jsx(Text, { dimColor: true, children: "skill: " }), _jsx(Text, { color: "cyan", children: expertise })] })), lastHeartbeat !== undefined && (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "last: " }), _jsx(Text, { children: timeAgo(lastHeartbeat) })] })), nextHeartbeat !== undefined && (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "next: " }), _jsx(Text, { children: timeUntil(nextHeartbeat) })] }))] }));
|
|
38
|
+
}
|
|
39
|
+
export default AgentCard;
|
|
40
|
+
//# sourceMappingURL=agent-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-card.js","sourceRoot":"","sources":["../../../src/tui/components/agent-card.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Animated ASCII banner — procedurally generated header matching the Go CLI.
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Flowing line patterns with dots/connectors (─●───○──)
|
|
6
|
+
* - "nex · powered by nex.ai" centered
|
|
7
|
+
* - Regenerates on interval (default: every 3 seconds)
|
|
8
|
+
* - Colors: cyan ("NexBlue") for "nex", muted for rest
|
|
9
|
+
* - ~6 lines tall, responsive to terminal width
|
|
10
|
+
*/
|
|
11
|
+
import React from "react";
|
|
12
|
+
/**
|
|
13
|
+
* Build one decorative line of exactly `width` characters.
|
|
14
|
+
* The line is a random mix of horizontal segments, dots, and connectors
|
|
15
|
+
* that gives the flowing "─●───○──" look.
|
|
16
|
+
*/
|
|
17
|
+
export declare function generateLine(width: number, seed?: number): string;
|
|
18
|
+
/**
|
|
19
|
+
* Build a centered brand line within `width` columns.
|
|
20
|
+
* Returns segments for colorized rendering.
|
|
21
|
+
*/
|
|
22
|
+
export interface BrandSegment {
|
|
23
|
+
text: string;
|
|
24
|
+
type: "brand" | "muted" | "line";
|
|
25
|
+
}
|
|
26
|
+
export declare function buildBrandLine(width: number, seed?: number): BrandSegment[];
|
|
27
|
+
/**
|
|
28
|
+
* Generate the full banner frame — an array of line data.
|
|
29
|
+
* Each entry is either "decorative" (a flowing line) or "brand" (the centered text line).
|
|
30
|
+
*/
|
|
31
|
+
export interface BannerFrame {
|
|
32
|
+
lines: Array<{
|
|
33
|
+
segments: BrandSegment[];
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
export declare function generateBannerFrame(width: number, seed?: number): BannerFrame;
|
|
37
|
+
export interface BannerProps {
|
|
38
|
+
/** Override terminal width (for testing or fixed layouts) */
|
|
39
|
+
width?: number;
|
|
40
|
+
/** Regeneration interval in ms. Default 3000. Set 0 to disable animation. */
|
|
41
|
+
interval?: number;
|
|
42
|
+
}
|
|
43
|
+
export declare function Banner({ width: widthProp, interval }: BannerProps): React.JSX.Element;
|
|
44
|
+
export default Banner;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Animated ASCII banner — procedurally generated header matching the Go CLI.
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Flowing line patterns with dots/connectors (─●───○──)
|
|
7
|
+
* - "nex · powered by nex.ai" centered
|
|
8
|
+
* - Regenerates on interval (default: every 3 seconds)
|
|
9
|
+
* - Colors: cyan ("NexBlue") for "nex", muted for rest
|
|
10
|
+
* - ~6 lines tall, responsive to terminal width
|
|
11
|
+
*/
|
|
12
|
+
import { useState, useEffect, useMemo, useCallback } from "react";
|
|
13
|
+
import { Box, Text, useStdout } from "ink";
|
|
14
|
+
// ── Pattern atoms ────────────────────────────────────────────────────
|
|
15
|
+
const LINE_CHARS = ["─", "─", "─", "─", "─", "─", "●", "○", "◦", "·"];
|
|
16
|
+
const CONNECTOR_CHARS = ["┤", "├", "│", "╌"];
|
|
17
|
+
/**
|
|
18
|
+
* Build one decorative line of exactly `width` characters.
|
|
19
|
+
* The line is a random mix of horizontal segments, dots, and connectors
|
|
20
|
+
* that gives the flowing "─●───○──" look.
|
|
21
|
+
*/
|
|
22
|
+
export function generateLine(width, seed) {
|
|
23
|
+
let s = seed ?? Math.floor(Math.random() * 0xffff);
|
|
24
|
+
const next = () => {
|
|
25
|
+
s = (s * 1103515245 + 12345) & 0x7fffffff;
|
|
26
|
+
return s;
|
|
27
|
+
};
|
|
28
|
+
const buf = [];
|
|
29
|
+
let remaining = width;
|
|
30
|
+
while (remaining > 0) {
|
|
31
|
+
const r = next();
|
|
32
|
+
// Mostly horizontal dashes with occasional dots/connectors
|
|
33
|
+
if (remaining > 3 && r % 7 === 0) {
|
|
34
|
+
// Insert a connector surrounded by dashes
|
|
35
|
+
const connector = CONNECTOR_CHARS[r % CONNECTOR_CHARS.length];
|
|
36
|
+
buf.push("─", connector, "─");
|
|
37
|
+
remaining -= 3;
|
|
38
|
+
}
|
|
39
|
+
else if (r % 5 === 0) {
|
|
40
|
+
// Insert a dot character
|
|
41
|
+
const dot = LINE_CHARS[6 + (r % 4)]; // ●, ○, ◦, ·
|
|
42
|
+
buf.push(dot);
|
|
43
|
+
remaining -= 1;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
buf.push("─");
|
|
47
|
+
remaining -= 1;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return buf.join("").slice(0, width);
|
|
51
|
+
}
|
|
52
|
+
export function buildBrandLine(width, seed) {
|
|
53
|
+
const brandText = "nex";
|
|
54
|
+
const tagline = " · powered by nex.ai";
|
|
55
|
+
const inner = brandText + tagline;
|
|
56
|
+
const padding = 2; // space each side of inner text
|
|
57
|
+
const innerWidth = inner.length + padding * 2;
|
|
58
|
+
if (width < innerWidth + 4) {
|
|
59
|
+
// Too narrow — just show brand
|
|
60
|
+
const side = Math.max(0, Math.floor((width - brandText.length) / 2));
|
|
61
|
+
const leftLine = generateLine(side, seed);
|
|
62
|
+
const rightLine = generateLine(Math.max(0, width - side - brandText.length), seed ? seed + 1 : undefined);
|
|
63
|
+
return [
|
|
64
|
+
{ text: leftLine, type: "line" },
|
|
65
|
+
{ text: brandText, type: "brand" },
|
|
66
|
+
{ text: rightLine, type: "line" },
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
const sideWidth = Math.floor((width - innerWidth) / 2);
|
|
70
|
+
const rightWidth = width - sideWidth - innerWidth;
|
|
71
|
+
const leftLine = generateLine(sideWidth, seed);
|
|
72
|
+
const rightLine = generateLine(rightWidth, seed ? seed + 1 : undefined);
|
|
73
|
+
return [
|
|
74
|
+
{ text: leftLine, type: "line" },
|
|
75
|
+
{ text: " ".repeat(padding), type: "muted" },
|
|
76
|
+
{ text: brandText, type: "brand" },
|
|
77
|
+
{ text: tagline, type: "muted" },
|
|
78
|
+
{ text: " ".repeat(padding), type: "muted" },
|
|
79
|
+
{ text: rightLine, type: "line" },
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
export function generateBannerFrame(width, seed) {
|
|
83
|
+
let s = seed ?? Math.floor(Math.random() * 0xffff);
|
|
84
|
+
const lines = [];
|
|
85
|
+
// Line 1: top decorative
|
|
86
|
+
lines.push({ segments: [{ text: generateLine(width, s), type: "line" }] });
|
|
87
|
+
s += 7;
|
|
88
|
+
// Line 2: decorative with a gap
|
|
89
|
+
lines.push({ segments: [{ text: generateLine(width, s), type: "line" }] });
|
|
90
|
+
s += 13;
|
|
91
|
+
// Line 3: brand line
|
|
92
|
+
lines.push({ segments: buildBrandLine(width, s) });
|
|
93
|
+
s += 17;
|
|
94
|
+
// Line 4: decorative
|
|
95
|
+
lines.push({ segments: [{ text: generateLine(width, s), type: "line" }] });
|
|
96
|
+
s += 11;
|
|
97
|
+
// Line 5: decorative
|
|
98
|
+
lines.push({ segments: [{ text: generateLine(width, s), type: "line" }] });
|
|
99
|
+
s += 3;
|
|
100
|
+
// Line 6: bottom decorative (sparser)
|
|
101
|
+
lines.push({ segments: [{ text: generateLine(width, s + 999), type: "line" }] });
|
|
102
|
+
return { lines };
|
|
103
|
+
}
|
|
104
|
+
// ── Component ────────────────────────────────────────────────────────
|
|
105
|
+
export function Banner({ width: widthProp, interval = 3000 }) {
|
|
106
|
+
const { stdout } = useStdout();
|
|
107
|
+
const termWidth = widthProp ?? (stdout?.columns ?? 80);
|
|
108
|
+
const effectiveWidth = Math.min(termWidth, 120); // cap at 120 for readability
|
|
109
|
+
const [tick, setTick] = useState(0);
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
if (interval <= 0)
|
|
112
|
+
return;
|
|
113
|
+
const id = setInterval(() => setTick((t) => t + 1), interval);
|
|
114
|
+
return () => clearInterval(id);
|
|
115
|
+
}, [interval]);
|
|
116
|
+
const frame = useMemo(() => generateBannerFrame(effectiveWidth, tick * 31337), [effectiveWidth, tick]);
|
|
117
|
+
const renderSegment = useCallback((seg, idx) => {
|
|
118
|
+
switch (seg.type) {
|
|
119
|
+
case "brand":
|
|
120
|
+
return (_jsx(Text, { color: "cyan", bold: true, children: seg.text }, idx));
|
|
121
|
+
case "muted":
|
|
122
|
+
return (_jsx(Text, { dimColor: true, children: seg.text }, idx));
|
|
123
|
+
case "line":
|
|
124
|
+
return (_jsx(Text, { dimColor: true, children: seg.text }, idx));
|
|
125
|
+
}
|
|
126
|
+
}, []);
|
|
127
|
+
return (_jsx(Box, { flexDirection: "column", children: frame.lines.map((line, i) => (_jsx(Box, { children: line.segments.map((seg, j) => renderSegment(seg, j)) }, i))) }));
|
|
128
|
+
}
|
|
129
|
+
export default Banner;
|
|
130
|
+
//# sourceMappingURL=banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../../../src/tui/components/banner.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent channel color assignment.
|
|
3
|
+
*
|
|
4
|
+
* Each channel name gets a stable color from a palette of terminal-safe
|
|
5
|
+
* colours. Well-known channels get fixed colors; others cycle through
|
|
6
|
+
* the palette.
|
|
7
|
+
*
|
|
8
|
+
* Pattern mirrors agent-colors.ts but for channels.
|
|
9
|
+
*/
|
|
10
|
+
declare const CHANNEL_PALETTE: readonly ["cyan", "green", "yellow", "magenta", "blue", "red"];
|
|
11
|
+
export type ChannelColor = (typeof CHANNEL_PALETTE)[number];
|
|
12
|
+
/**
|
|
13
|
+
* Return the colour assigned to `channelName`, assigning a new one on
|
|
14
|
+
* first encounter. The same name always returns the same colour.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getChannelColor(channelName: string): ChannelColor;
|
|
17
|
+
/** Read-only snapshot of the current colour map. */
|
|
18
|
+
export declare function getAllChannelColors(): ReadonlyMap<string, ChannelColor>;
|
|
19
|
+
/** Reset all assignments (useful in tests). */
|
|
20
|
+
export declare function resetChannelColors(): void;
|
|
21
|
+
export {};
|