auq-mcp-server 2.7.0 → 2.7.2
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/dist/package.json +3 -3
- package/dist/src/config/__tests__/ConfigLoader.test.js +7 -7
- package/dist/src/config/defaults.js +1 -1
- package/dist/src/config/types.js +1 -1
- package/dist/src/i18n/types.js +0 -1
- package/dist/src/tui/shared/session-events.js +0 -1
- package/dist/src/tui/shared/themes/types.js +0 -1
- package/dist/src/tui/shared/types.js +0 -1
- package/dist/src/tui-opentui/ConfigContext.js +10 -0
- package/dist/src/tui-opentui/ThemeProvider.js +73 -0
- package/dist/src/tui-opentui/app.js +536 -0
- package/dist/src/tui-opentui/components/AnimatedGradient.js +56 -0
- package/dist/src/tui-opentui/components/ConfirmationDialog.js +89 -0
- package/dist/src/tui-opentui/components/CustomInput.js +25 -0
- package/dist/src/tui-opentui/components/ErrorBoundary.js +26 -0
- package/dist/src/tui-opentui/components/Footer.js +92 -0
- package/dist/src/tui-opentui/components/Header.js +46 -0
- package/dist/src/tui-opentui/components/MarkdownPrompt.js +13 -0
- package/dist/src/tui-opentui/components/OptionsList.js +258 -0
- package/dist/src/tui-opentui/components/QuestionDisplay.js +23 -0
- package/dist/src/tui-opentui/components/ReviewScreen.js +81 -0
- package/dist/src/tui-opentui/components/SessionDots.js +86 -0
- package/dist/src/tui-opentui/components/SessionPicker.js +162 -0
- package/dist/src/tui-opentui/components/SingleLineTextInput.js +9 -0
- package/dist/src/tui-opentui/components/StepperView.js +493 -0
- package/dist/src/tui-opentui/components/TabBar.js +79 -0
- package/dist/src/tui-opentui/components/ThemeIndicator.js +35 -0
- package/dist/src/tui-opentui/components/Toast.js +44 -0
- package/dist/src/tui-opentui/components/UpdateBadge.js +24 -0
- package/dist/src/tui-opentui/components/UpdateOverlay.js +162 -0
- package/dist/src/tui-opentui/components/WaitingScreen.js +44 -0
- package/dist/src/tui-opentui/hooks/useSessionWatcher.js +69 -0
- package/dist/src/tui-opentui/hooks/useTerminalDimensions.js +8 -0
- package/dist/src/tui-opentui/utils/syntaxStyle.js +64 -0
- package/dist/src/update/types.js +0 -1
- package/package.json +3 -3
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useKeyboard } from "@opentui/react";
|
|
4
|
+
import { TextAttributes } from "@opentui/core";
|
|
5
|
+
import { useTheme } from "../ThemeProvider.js";
|
|
6
|
+
import { useTerminalDimensions } from "../hooks/useTerminalDimensions.js";
|
|
7
|
+
import { detectPackageManager } from "../../update/package-manager.js";
|
|
8
|
+
import { getManualCommand } from "../../update/installer.js";
|
|
9
|
+
/**
|
|
10
|
+
* UpdateOverlay \u2014 fullscreen modal for minor/major update prompts.
|
|
11
|
+
*
|
|
12
|
+
* Displays version information, changelog (rendered as Markdown), and
|
|
13
|
+
* action buttons. Major updates show a breaking-change warning badge.
|
|
14
|
+
*
|
|
15
|
+
* Navigation:
|
|
16
|
+
* Tab / \u2192 : next button
|
|
17
|
+
* Shift+Tab / \u2190 : previous button
|
|
18
|
+
* Enter : trigger focused action
|
|
19
|
+
* Esc : same as \"Remind me later\"
|
|
20
|
+
*/
|
|
21
|
+
export const UpdateOverlay = ({ isOpen, currentVersion, latestVersion, updateType, changelog, changelogUrl, isInstalling, installError, onInstall, onSkipVersion, onRemindLater, }) => {
|
|
22
|
+
const { theme, syntaxStyle } = useTheme();
|
|
23
|
+
const { width: termWidth } = useTerminalDimensions();
|
|
24
|
+
const [focusedButton, setFocusedButton] = useState(0);
|
|
25
|
+
// \u2500\u2500 Actions bound to button indices \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
26
|
+
const actions = [onInstall, onSkipVersion, onRemindLater];
|
|
27
|
+
const buttonLabels = ["Yes, update", "Skip this version", "Remind me later"];
|
|
28
|
+
const buttonCount = buttonLabels.length;
|
|
29
|
+
// \u2500\u2500 Keyboard handling (only active when overlay is open) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
30
|
+
useKeyboard((key) => {
|
|
31
|
+
if (!isOpen)
|
|
32
|
+
return;
|
|
33
|
+
// Installing or error state \u2014 only Esc closes
|
|
34
|
+
if (isInstalling)
|
|
35
|
+
return;
|
|
36
|
+
if (installError) {
|
|
37
|
+
if (key.name === "return" || key.name === "escape") {
|
|
38
|
+
onRemindLater();
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Tab / Right arrow: next button
|
|
43
|
+
if (key.name === "tab" && !key.shift) {
|
|
44
|
+
setFocusedButton((prev) => (prev + 1) % buttonCount);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (key.name === "right") {
|
|
48
|
+
setFocusedButton((prev) => (prev + 1) % buttonCount);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Shift+Tab / Left arrow: previous button
|
|
52
|
+
if (key.name === "tab" && key.shift) {
|
|
53
|
+
setFocusedButton((prev) => (prev - 1 + buttonCount) % buttonCount);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (key.name === "left") {
|
|
57
|
+
setFocusedButton((prev) => (prev - 1 + buttonCount) % buttonCount);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Enter: trigger focused button
|
|
61
|
+
if (key.name === "return") {
|
|
62
|
+
actions[focusedButton]();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Escape: remind me later
|
|
66
|
+
if (key.name === "escape") {
|
|
67
|
+
onRemindLater();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
// \u2500\u2500 Render nothing when closed \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
72
|
+
if (!isOpen)
|
|
73
|
+
return null;
|
|
74
|
+
// \u2500\u2500 Color mapping for update type badges \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
75
|
+
const typeColorMap = {
|
|
76
|
+
patch: theme.colors.success,
|
|
77
|
+
minor: theme.colors.warning,
|
|
78
|
+
major: theme.colors.error,
|
|
79
|
+
};
|
|
80
|
+
const typeColor = typeColorMap[updateType] ?? theme.colors.info;
|
|
81
|
+
const overlayWidth = Math.min(64, termWidth - 4);
|
|
82
|
+
const innerWidth = overlayWidth - 6; // account for border + paddingX
|
|
83
|
+
// \u2500\u2500 Package manager info for error display \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
84
|
+
const packageManager = detectPackageManager();
|
|
85
|
+
const manualCommand = getManualCommand(packageManager);
|
|
86
|
+
// \u2500\u2500 Installing state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
87
|
+
if (isInstalling) {
|
|
88
|
+
return (_jsx("box", { style: {
|
|
89
|
+
flexDirection: "column",
|
|
90
|
+
alignItems: "center",
|
|
91
|
+
justifyContent: "center",
|
|
92
|
+
}, children: _jsxs("box", { style: {
|
|
93
|
+
flexDirection: "column",
|
|
94
|
+
borderStyle: "rounded",
|
|
95
|
+
borderColor: theme.borders.primary,
|
|
96
|
+
paddingX: 2,
|
|
97
|
+
paddingY: 1,
|
|
98
|
+
width: overlayWidth,
|
|
99
|
+
alignItems: "center",
|
|
100
|
+
}, children: [_jsx("box", { style: { marginBottom: 1 }, children: _jsx("text", { style: { attributes: TextAttributes.BOLD, fg: theme.colors.primary }, children: "Installing Update" }) }), _jsx("box", { style: { marginBottom: 1 }, children: _jsxs("box", { style: { flexDirection: "row" }, children: [_jsx("text", { style: { fg: theme.colors.info }, children: "\u2819 " }), _jsx("text", { children: `Installing v${latestVersion}\u2026` })] }) }), _jsx("box", { children: _jsx("text", { style: { attributes: TextAttributes.DIM }, children: `Running: ${manualCommand}` }) })] }) }));
|
|
101
|
+
}
|
|
102
|
+
// \u2500\u2500 Error state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
103
|
+
if (installError) {
|
|
104
|
+
return (_jsx("box", { style: {
|
|
105
|
+
flexDirection: "column",
|
|
106
|
+
alignItems: "center",
|
|
107
|
+
justifyContent: "center",
|
|
108
|
+
}, children: _jsxs("box", { style: {
|
|
109
|
+
flexDirection: "column",
|
|
110
|
+
borderStyle: "rounded",
|
|
111
|
+
borderColor: theme.borders.error,
|
|
112
|
+
paddingX: 2,
|
|
113
|
+
paddingY: 1,
|
|
114
|
+
width: overlayWidth,
|
|
115
|
+
}, children: [_jsx("box", { style: { marginBottom: 1 }, children: _jsx("text", { style: { attributes: TextAttributes.BOLD, fg: theme.colors.error }, children: "Update Failed" }) }), _jsx("box", { style: { marginBottom: 1 }, children: _jsx("text", { style: { fg: theme.colors.error }, children: installError }) }), _jsxs("box", { style: { marginBottom: 1, flexDirection: "column" }, children: [_jsx("text", { style: { attributes: TextAttributes.DIM }, children: "Try running manually:" }), _jsx("box", { style: { marginTop: 0 }, children: _jsx("text", { style: { attributes: TextAttributes.BOLD, fg: theme.colors.info }, children: ` ${manualCommand}` }) })] }), _jsx("box", { style: { justifyContent: "center", marginTop: 1 }, children: _jsx("text", { style: {
|
|
116
|
+
attributes: TextAttributes.BOLD,
|
|
117
|
+
bg: theme.components.options.focusedBg,
|
|
118
|
+
fg: theme.colors.focused,
|
|
119
|
+
}, children: " Close " }) }), _jsx("box", { style: { justifyContent: "center", marginTop: 1 }, children: _jsx("text", { style: { attributes: TextAttributes.DIM }, children: "Enter or Esc to close" }) })] }) }));
|
|
120
|
+
}
|
|
121
|
+
// \u2500\u2500 Default state: update prompt with buttons \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
122
|
+
return (_jsx("box", { style: {
|
|
123
|
+
flexDirection: "column",
|
|
124
|
+
alignItems: "center",
|
|
125
|
+
justifyContent: "center",
|
|
126
|
+
}, children: _jsxs("box", { style: {
|
|
127
|
+
flexDirection: "column",
|
|
128
|
+
borderStyle: "rounded",
|
|
129
|
+
borderColor: theme.borders.primary,
|
|
130
|
+
paddingX: 2,
|
|
131
|
+
paddingY: 1,
|
|
132
|
+
width: overlayWidth,
|
|
133
|
+
}, children: [_jsx("box", { style: { justifyContent: "center", marginBottom: 1 }, children: _jsx("text", { style: { attributes: TextAttributes.BOLD, fg: theme.colors.primary }, children: "Update Available" }) }), _jsx("box", { style: { justifyContent: "center", marginBottom: 1 }, children: _jsxs("box", { style: { flexDirection: "row" }, children: [_jsx("text", { style: { attributes: TextAttributes.DIM }, children: "Current: " }), _jsx("text", { children: currentVersion }), _jsx("text", { style: { attributes: TextAttributes.DIM }, children: " \u2192 " }), _jsx("text", { style: { attributes: TextAttributes.DIM }, children: "Latest: " }), _jsx("text", { style: { attributes: TextAttributes.BOLD, fg: typeColor }, children: latestVersion }), _jsx("text", { children: " " }), _jsx("text", { style: { bg: typeColor, fg: "#000000", attributes: TextAttributes.BOLD }, children: ` ${updateType.toUpperCase()} ` })] }) }), updateType === "major" && (_jsx("box", { style: {
|
|
134
|
+
borderStyle: "rounded",
|
|
135
|
+
borderColor: theme.borders.warning,
|
|
136
|
+
paddingX: 1,
|
|
137
|
+
marginBottom: 1,
|
|
138
|
+
width: innerWidth,
|
|
139
|
+
}, children: _jsx("text", { style: { fg: theme.colors.warning, attributes: TextAttributes.BOLD }, children: "\\u26a0 Breaking changes may be included" }) })), _jsx("box", { style: { marginBottom: 1 }, children: changelog ? (_jsx("box", { style: {
|
|
140
|
+
borderStyle: "rounded",
|
|
141
|
+
borderColor: theme.borders.neutral,
|
|
142
|
+
flexDirection: "column",
|
|
143
|
+
paddingX: 1,
|
|
144
|
+
paddingY: 1,
|
|
145
|
+
width: innerWidth,
|
|
146
|
+
}, children: _jsx("scrollbox", { style: { maxHeight: 12 }, children: _jsx("markdown", { content: changelog, syntaxStyle: syntaxStyle }) }) })) : (_jsx("box", { style: {
|
|
147
|
+
borderStyle: "rounded",
|
|
148
|
+
borderColor: theme.borders.neutral,
|
|
149
|
+
paddingX: 1,
|
|
150
|
+
paddingY: 1,
|
|
151
|
+
width: innerWidth,
|
|
152
|
+
}, children: _jsx("text", { style: { attributes: TextAttributes.DIM }, children: `View changelog: ${changelogUrl}` }) })) }), _jsx("box", { style: { justifyContent: "center", gap: 1 }, children: buttonLabels.map((label, index) => {
|
|
153
|
+
const isFocused = index === focusedButton;
|
|
154
|
+
return (_jsx("box", { onMouseDown: () => { actions[index](); }, children: _jsxs("text", { style: {
|
|
155
|
+
attributes: isFocused ? TextAttributes.BOLD : TextAttributes.NONE,
|
|
156
|
+
bg: isFocused
|
|
157
|
+
? theme.components.options.focusedBg
|
|
158
|
+
: undefined,
|
|
159
|
+
fg: isFocused ? theme.colors.focused : theme.colors.text,
|
|
160
|
+
}, children: [isFocused ? " ▸ " : " ", label, isFocused ? " " : " "] }) }, label));
|
|
161
|
+
}) }), _jsx("box", { style: { justifyContent: "center", marginTop: 1 }, children: _jsx("text", { style: { attributes: TextAttributes.DIM }, children: "\u2190\u2192/Tab navigate \u00B7 Enter select \u00B7 Esc dismiss \u00B7 click button" }) })] }) }));
|
|
162
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
+
import { TextAttributes } from "@opentui/core";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { t } from "../../i18n/index.js";
|
|
5
|
+
import { useTheme } from "../ThemeProvider.js";
|
|
6
|
+
import { AnimatedGradient } from "./AnimatedGradient.js";
|
|
7
|
+
/**
|
|
8
|
+
* WaitingScreen displays when no question sets are being processed.
|
|
9
|
+
* Shows "Waiting for AI..." message with animated gradient effect and elapsed time.
|
|
10
|
+
*/
|
|
11
|
+
export const WaitingScreen = ({ queueCount }) => {
|
|
12
|
+
const { theme } = useTheme();
|
|
13
|
+
const [startTime] = useState(new Date());
|
|
14
|
+
const [elapsedSeconds, setElapsedSeconds] = useState(0);
|
|
15
|
+
// Update elapsed time every second
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
const timer = setInterval(() => {
|
|
18
|
+
const now = new Date();
|
|
19
|
+
const elapsed = Math.floor((now.getTime() - startTime.getTime()) / 1000);
|
|
20
|
+
setElapsedSeconds(elapsed);
|
|
21
|
+
}, 1000);
|
|
22
|
+
return () => clearInterval(timer);
|
|
23
|
+
}, [startTime]);
|
|
24
|
+
const waitingTitle = queueCount === 0
|
|
25
|
+
? t("waiting.title").replace("...", "…")
|
|
26
|
+
: `${t("waiting.processing").replace("...", "…")} (${t("waiting.queueCount").replace("{count}", String(queueCount))})`;
|
|
27
|
+
return (_jsx("box", { style: {
|
|
28
|
+
flexDirection: "column",
|
|
29
|
+
alignItems: "center",
|
|
30
|
+
justifyContent: "center",
|
|
31
|
+
flexGrow: 1,
|
|
32
|
+
}, children: _jsxs("box", { style: {
|
|
33
|
+
flexDirection: "column",
|
|
34
|
+
paddingLeft: 4,
|
|
35
|
+
paddingRight: 4,
|
|
36
|
+
paddingTop: 2,
|
|
37
|
+
paddingBottom: 2,
|
|
38
|
+
marginLeft: 1,
|
|
39
|
+
marginRight: 1,
|
|
40
|
+
border: true,
|
|
41
|
+
borderStyle: "rounded",
|
|
42
|
+
borderColor: theme.colors.surface,
|
|
43
|
+
}, children: [_jsx("box", { style: { justifyContent: "center" }, children: _jsx(AnimatedGradient, { text: waitingTitle }) }), _jsx("box", { style: { justifyContent: "center", marginTop: 1 }, children: _jsx("text", { style: { attributes: TextAttributes.DIM }, children: `${t("waiting.hint")} • ${elapsedSeconds}s` }) })] }) }));
|
|
44
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useState, useCallback, useRef } from "react";
|
|
2
|
+
import { getNextSessionIndex, getPrevSessionIndex, getDirectJumpIndex, getAdjustedIndexAfterRemoval, } from "../../tui/shared/utils/sessionSwitching.js";
|
|
3
|
+
/**
|
|
4
|
+
* React hook that bridges session events to React state for the OpenTUI renderer.
|
|
5
|
+
* Manages session queue, active session index, and per-session UI state.
|
|
6
|
+
*/
|
|
7
|
+
export function useSessionWatcher(_options = {}) {
|
|
8
|
+
const [sessionQueue, setSessionQueue] = useState([]);
|
|
9
|
+
const [activeSessionIndex, setActiveSessionIndex] = useState(0);
|
|
10
|
+
const [sessionUIStates, setSessionUIStates] = useState({});
|
|
11
|
+
const sessionQueueRef = useRef(sessionQueue);
|
|
12
|
+
sessionQueueRef.current = sessionQueue;
|
|
13
|
+
const activeSessionIndexRef = useRef(activeSessionIndex);
|
|
14
|
+
activeSessionIndexRef.current = activeSessionIndex;
|
|
15
|
+
const activeSession = sessionQueue[activeSessionIndex] ?? null;
|
|
16
|
+
const addSession = useCallback((session) => {
|
|
17
|
+
setSessionQueue((prev) => {
|
|
18
|
+
// Don't add duplicates
|
|
19
|
+
if (prev.some((s) => s.sessionId === session.sessionId))
|
|
20
|
+
return prev;
|
|
21
|
+
return [...prev, session]; // FIFO: append to end
|
|
22
|
+
});
|
|
23
|
+
}, []);
|
|
24
|
+
const removeSession = useCallback((sessionId) => {
|
|
25
|
+
setSessionQueue((prev) => {
|
|
26
|
+
const index = prev.findIndex((s) => s.sessionId === sessionId);
|
|
27
|
+
if (index === -1)
|
|
28
|
+
return prev;
|
|
29
|
+
const newQueue = prev.filter((s) => s.sessionId !== sessionId);
|
|
30
|
+
// Adjust active index after removal
|
|
31
|
+
const newIndex = getAdjustedIndexAfterRemoval(index, activeSessionIndexRef.current, newQueue.length);
|
|
32
|
+
setActiveSessionIndex(newIndex);
|
|
33
|
+
return newQueue;
|
|
34
|
+
});
|
|
35
|
+
// Clean up UI state
|
|
36
|
+
setSessionUIStates((prev) => {
|
|
37
|
+
const next = { ...prev };
|
|
38
|
+
delete next[sessionId];
|
|
39
|
+
return next;
|
|
40
|
+
});
|
|
41
|
+
}, []);
|
|
42
|
+
const nextSession = useCallback(() => {
|
|
43
|
+
setActiveSessionIndex((prev) => getNextSessionIndex(prev, sessionQueueRef.current.length));
|
|
44
|
+
}, []);
|
|
45
|
+
const prevSession = useCallback(() => {
|
|
46
|
+
setActiveSessionIndex((prev) => getPrevSessionIndex(prev, sessionQueueRef.current.length));
|
|
47
|
+
}, []);
|
|
48
|
+
const jumpToSession = useCallback((index) => {
|
|
49
|
+
const safeIndex = getDirectJumpIndex(index, activeSessionIndexRef.current, sessionQueueRef.current.length);
|
|
50
|
+
if (safeIndex !== null)
|
|
51
|
+
setActiveSessionIndex(safeIndex);
|
|
52
|
+
}, []);
|
|
53
|
+
const updateUIState = useCallback((sessionId, state) => {
|
|
54
|
+
setSessionUIStates((prev) => ({ ...prev, [sessionId]: state }));
|
|
55
|
+
}, []);
|
|
56
|
+
return {
|
|
57
|
+
sessionQueue,
|
|
58
|
+
activeSessionIndex,
|
|
59
|
+
activeSession,
|
|
60
|
+
sessionUIStates,
|
|
61
|
+
setActiveSessionIndex,
|
|
62
|
+
nextSession,
|
|
63
|
+
prevSession,
|
|
64
|
+
jumpToSession,
|
|
65
|
+
removeSession,
|
|
66
|
+
updateUIState,
|
|
67
|
+
addSession,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { useTerminalDimensions as useOpenTUIDimensions } from "@opentui/react";
|
|
2
|
+
/**
|
|
3
|
+
* Hook that returns the current terminal dimensions.
|
|
4
|
+
* Wraps OpenTUI's useTerminalDimensions for use in OpenTUI components.
|
|
5
|
+
*/
|
|
6
|
+
export function useTerminalDimensions() {
|
|
7
|
+
return useOpenTUIDimensions();
|
|
8
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { SyntaxStyle, RGBA } from "@opentui/core";
|
|
2
|
+
/**
|
|
3
|
+
* Auto-generate an OpenTUI SyntaxStyle from AUQ theme color tokens.
|
|
4
|
+
*
|
|
5
|
+
* Color mapping (design.md §5):
|
|
6
|
+
* accent → keywords, headings (bold), functions, operators, links, tags
|
|
7
|
+
* success → strings
|
|
8
|
+
* muted → comments (italic), punctuation
|
|
9
|
+
* warning → numbers, constants, types, attributes
|
|
10
|
+
* text → default, variables, list markup
|
|
11
|
+
* info → code/raw blocks, properties
|
|
12
|
+
*/
|
|
13
|
+
export function generateSyntaxStyle(theme) {
|
|
14
|
+
const { colors } = theme;
|
|
15
|
+
// Semantic color tokens → RGBA instances
|
|
16
|
+
const accent = RGBA.fromHex(colors.primary);
|
|
17
|
+
const success = RGBA.fromHex(colors.success);
|
|
18
|
+
const muted = RGBA.fromHex(colors.textDim);
|
|
19
|
+
const warning = RGBA.fromHex(colors.warning);
|
|
20
|
+
const text = RGBA.fromHex(colors.text);
|
|
21
|
+
const info = RGBA.fromHex(colors.info);
|
|
22
|
+
return SyntaxStyle.fromStyles({
|
|
23
|
+
// ── Keywords ──────────────────────────────────────────────
|
|
24
|
+
keyword: { fg: accent, bold: true },
|
|
25
|
+
"keyword.control": { fg: accent },
|
|
26
|
+
"keyword.operator": { fg: accent },
|
|
27
|
+
storage: { fg: accent },
|
|
28
|
+
// ── Strings ──────────────────────────────────────────────
|
|
29
|
+
string: { fg: success },
|
|
30
|
+
"string.special": { fg: success },
|
|
31
|
+
// ── Comments ─────────────────────────────────────────────
|
|
32
|
+
comment: { fg: muted, italic: true },
|
|
33
|
+
"comment.line": { fg: muted, italic: true },
|
|
34
|
+
"comment.block": { fg: muted, italic: true },
|
|
35
|
+
// ── Numeric / Constants ──────────────────────────────────
|
|
36
|
+
number: { fg: warning },
|
|
37
|
+
constant: { fg: warning },
|
|
38
|
+
"constant.numeric": { fg: warning },
|
|
39
|
+
// ── Markup ───────────────────────────────────────────────
|
|
40
|
+
"markup.heading": { fg: accent, bold: true },
|
|
41
|
+
"markup.list": { fg: text },
|
|
42
|
+
"markup.raw": { fg: info },
|
|
43
|
+
"markup.bold": { bold: true },
|
|
44
|
+
"markup.italic": { italic: true },
|
|
45
|
+
"markup.link": { fg: accent, underline: true },
|
|
46
|
+
// ── Types ────────────────────────────────────────────────
|
|
47
|
+
type: { fg: warning },
|
|
48
|
+
"type.builtin": { fg: warning },
|
|
49
|
+
// ── Functions ────────────────────────────────────────────
|
|
50
|
+
function: { fg: accent },
|
|
51
|
+
"function.method": { fg: accent },
|
|
52
|
+
// ── Identifiers ──────────────────────────────────────────
|
|
53
|
+
variable: { fg: text },
|
|
54
|
+
property: { fg: info },
|
|
55
|
+
// ── Delimiters ───────────────────────────────────────────
|
|
56
|
+
punctuation: { fg: muted },
|
|
57
|
+
operator: { fg: accent },
|
|
58
|
+
// ── HTML / JSX ───────────────────────────────────────────
|
|
59
|
+
tag: { fg: accent },
|
|
60
|
+
attribute: { fg: warning },
|
|
61
|
+
// ── Fallback ─────────────────────────────────────────────
|
|
62
|
+
default: { fg: text },
|
|
63
|
+
});
|
|
64
|
+
}
|
package/dist/src/update/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auq-mcp-server",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"auq": "dist/bin/auq.js"
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"packages/opencode-plugin"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
|
-
"build": "bun run sync-plugin-schemas && bun run generate:skill && tsc",
|
|
18
|
+
"build": "bun run sync-plugin-schemas && bun run generate:skill && tsc && tsc -p tsconfig.opentui.json",
|
|
19
19
|
"prepare": "bun run build",
|
|
20
20
|
"postinstall": "node scripts/postinstall.cjs",
|
|
21
21
|
"release": "semantic-release",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"validate:skill": "bunx skills-ref validate skills/ask-user-questions",
|
|
30
30
|
"test": "vitest run",
|
|
31
31
|
"format": "prettier --write . && eslint --fix .",
|
|
32
|
-
"build:opentui": "tsc -p tsconfig.opentui.json
|
|
32
|
+
"build:opentui": "tsc -p tsconfig.opentui.json",
|
|
33
33
|
"test:opentui": "bun test src/tui-opentui",
|
|
34
34
|
"typecheck:all": "tsc --noEmit && tsc -p tsconfig.opentui.json --noEmit"
|
|
35
35
|
},
|