auq-mcp-server 3.3.0 → 3.3.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
CHANGED
|
@@ -244,7 +244,10 @@ export const OptionsList = ({ isFocused, onSelect, options, selectedOption, show
|
|
|
244
244
|
return (React.createElement(Text, { backgroundColor: rowBg, bold: isCustomInputFocused || isSelected, color: rowColor }, fitRow(mainLine)));
|
|
245
245
|
})(),
|
|
246
246
|
isCustomInputFocused && onCustomChange && (React.createElement(Box, { borderColor: theme.components.input.borderFocused, borderStyle: "round", marginBottom: 1, marginLeft: 2, marginTop: 0, paddingX: 1, paddingY: 0 },
|
|
247
|
-
React.createElement(MultiLineTextInput, { isFocused: true, onChange: onCustomChange, onSubmit:
|
|
247
|
+
React.createElement(MultiLineTextInput, { isFocused: true, onChange: onCustomChange, onSubmit: () => {
|
|
248
|
+
onCustomChange?.(customValue);
|
|
249
|
+
onAdvance?.();
|
|
250
|
+
}, placeholder: t("input.placeholder"), value: customValue }))),
|
|
248
251
|
!isCustomInputFocused && customValue && (React.createElement(Box, { marginLeft: 2, marginTop: 0 },
|
|
249
252
|
React.createElement(Text, { color: theme.components.options.hint, dimColor: true },
|
|
250
253
|
customLines.slice(0, 3).map((line, idx) => (React.createElement(React.Fragment, { key: idx },
|
|
@@ -275,6 +278,7 @@ export const OptionsList = ({ isFocused, onSelect, options, selectedOption, show
|
|
|
275
278
|
})(),
|
|
276
279
|
isElaborateFocused && onElaborateTextChange && (React.createElement(Box, { borderColor: theme.components.input.borderFocused, borderStyle: "round", marginBottom: 1, marginLeft: 2, marginTop: 0, paddingX: 1, paddingY: 0 },
|
|
277
280
|
React.createElement(MultiLineTextInput, { enterSubmits: true, isFocused: true, onChange: onElaborateTextChange, onSubmit: () => {
|
|
281
|
+
onElaborateTextChange?.(elaborateText);
|
|
278
282
|
// Enter/Tab submits and advance
|
|
279
283
|
// Only call onElaborateSelect if no text (to toggle mark on)
|
|
280
284
|
// If text exists, mark is already set via onElaborateTextChange
|
|
@@ -174,4 +174,24 @@ describe("StepperView SessionUIState boundary", () => {
|
|
|
174
174
|
expect(snapshotState.answers.get(0)?.selectedOption).toBe("Python");
|
|
175
175
|
expect(snapshotState.answers.get(0)?.selectedOption).not.toBe("TypeScript");
|
|
176
176
|
});
|
|
177
|
+
it("custom text is preserved in answers when advancing via Tab", async () => {
|
|
178
|
+
const onStateSnapshot = vi.fn();
|
|
179
|
+
const initialState = {
|
|
180
|
+
currentQuestionIndex: 0,
|
|
181
|
+
answers: new Map([[0, { customText: "my custom answer" }]]),
|
|
182
|
+
elaborateMarks: new Map(),
|
|
183
|
+
focusContext: "option",
|
|
184
|
+
focusedOptionIndex: 0,
|
|
185
|
+
showReview: false,
|
|
186
|
+
};
|
|
187
|
+
const instance = renderStepper({ onStateSnapshot, initialState });
|
|
188
|
+
instance.stdin.write("\t");
|
|
189
|
+
await vi.waitFor(() => {
|
|
190
|
+
expect(onStateSnapshot).toHaveBeenCalled();
|
|
191
|
+
const lastCall = onStateSnapshot.mock.calls[onStateSnapshot.mock.calls.length - 1];
|
|
192
|
+
const [, snapshotState] = lastCall;
|
|
193
|
+
expect(snapshotState.answers.get(0)?.customText).toBe("my custom answer");
|
|
194
|
+
expect(snapshotState.currentQuestionIndex).toBe(1);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
177
197
|
});
|
|
@@ -21,6 +21,7 @@ import { SessionPicker as _SessionPicker } from "./components/SessionPicker.js";
|
|
|
21
21
|
import { UpdateOverlay as _UpdateOverlay } from "./components/UpdateOverlay.js";
|
|
22
22
|
import { Toast as _Toast } from "./components/Toast.js";
|
|
23
23
|
import { ThemeIndicator as _ThemeIndicator } from "./components/ThemeIndicator.js";
|
|
24
|
+
import { createNotificationBatcher, } from "../tui/notifications/index.js";
|
|
24
25
|
// Cast to FC to avoid React class component type mismatch between @opentui/react
|
|
25
26
|
// bundled React version and the project's @types/react (structural type incompatibility).
|
|
26
27
|
// ErrorBoundary is still a valid class component at runtime.
|
|
@@ -54,6 +55,14 @@ function AppInner({ config }) {
|
|
|
54
55
|
const [changelogContent, setChangelogContent] = useState(null);
|
|
55
56
|
const [updateDismissed, setUpdateDismissed] = useState(false);
|
|
56
57
|
const [isCheckingUpdate, setIsCheckingUpdate] = useState(false);
|
|
58
|
+
// Notification configuration from config
|
|
59
|
+
const notificationConfig = useMemo(() => config?.notifications ?? { enabled: true, sound: true }, [config?.notifications]);
|
|
60
|
+
// Create notification batcher (memoized to persist across renders)
|
|
61
|
+
const notificationBatcherRef = useRef(null);
|
|
62
|
+
if (!notificationBatcherRef.current) {
|
|
63
|
+
notificationBatcherRef.current =
|
|
64
|
+
createNotificationBatcher(notificationConfig);
|
|
65
|
+
}
|
|
57
66
|
const sessionDir = getSessionDirectory();
|
|
58
67
|
// ── Show toast helper ────────────────────────────────────────
|
|
59
68
|
const showToast = useCallback((message, type = "success", title) => {
|
|
@@ -95,6 +104,10 @@ function AppInner({ config }) {
|
|
|
95
104
|
setSessionQueue((prev) => {
|
|
96
105
|
if (prev.some((s) => s.sessionId === event.sessionId))
|
|
97
106
|
return prev;
|
|
107
|
+
// Queue notification for new session (batched)
|
|
108
|
+
if (notificationBatcherRef.current) {
|
|
109
|
+
notificationBatcherRef.current.queue(event.sessionId);
|
|
110
|
+
}
|
|
98
111
|
return [
|
|
99
112
|
...prev,
|
|
100
113
|
{
|
|
@@ -115,6 +128,9 @@ function AppInner({ config }) {
|
|
|
115
128
|
return () => {
|
|
116
129
|
if (watcherInstance)
|
|
117
130
|
watcherInstance.stop();
|
|
131
|
+
if (notificationBatcherRef.current) {
|
|
132
|
+
notificationBatcherRef.current.flush();
|
|
133
|
+
}
|
|
118
134
|
};
|
|
119
135
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
120
136
|
}, []);
|
|
@@ -89,6 +89,7 @@ export const OptionsList = ({ isFocused, onSelect, options, selectedOption, show
|
|
|
89
89
|
setFocusedIndex(Math.max(0, options.length - 1));
|
|
90
90
|
}
|
|
91
91
|
else if (key.name === "tab" && !key.shift) {
|
|
92
|
+
onCustomChange?.(customValue);
|
|
92
93
|
onAdvance?.();
|
|
93
94
|
}
|
|
94
95
|
else if (key.name === "return") {
|
|
@@ -99,6 +100,7 @@ export const OptionsList = ({ isFocused, onSelect, options, selectedOption, show
|
|
|
99
100
|
}
|
|
100
101
|
else {
|
|
101
102
|
// Enter: advance to next question
|
|
103
|
+
onCustomChange?.(customValue);
|
|
102
104
|
onAdvance?.();
|
|
103
105
|
}
|
|
104
106
|
}
|
|
@@ -116,6 +118,10 @@ export const OptionsList = ({ isFocused, onSelect, options, selectedOption, show
|
|
|
116
118
|
setFocusedIndex(customInputIndex);
|
|
117
119
|
}
|
|
118
120
|
else if (key.name === "tab" && !key.shift) {
|
|
121
|
+
onElaborateTextChange?.(elaborateText);
|
|
122
|
+
if (!elaborateText.trim()) {
|
|
123
|
+
onElaborateSelect?.();
|
|
124
|
+
}
|
|
119
125
|
onAdvance?.();
|
|
120
126
|
}
|
|
121
127
|
else if (key.name === "return") {
|
|
@@ -126,6 +132,7 @@ export const OptionsList = ({ isFocused, onSelect, options, selectedOption, show
|
|
|
126
132
|
}
|
|
127
133
|
else {
|
|
128
134
|
// Enter: advance to next question
|
|
135
|
+
onElaborateTextChange?.(elaborateText);
|
|
129
136
|
if (!elaborateText.trim()) {
|
|
130
137
|
onElaborateSelect?.();
|
|
131
138
|
}
|