auq-mcp-server 2.6.3 → 2.7.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.
- package/README.md +56 -2
- package/dist/bin/auq.js +36 -3
- package/dist/bin/tui-app.js +30 -15
- package/dist/package.json +7 -2
- package/dist/src/__tests__/schema-validation.test.js +61 -1
- package/dist/src/cli/commands/__tests__/fetch-answers.test.js +310 -0
- package/dist/src/cli/commands/__tests__/history.test.js +211 -0
- package/dist/src/cli/commands/answer.js +11 -0
- package/dist/src/cli/commands/config.js +48 -0
- package/dist/src/cli/commands/fetch-answers.js +205 -0
- package/dist/src/cli/commands/history.js +375 -0
- package/dist/src/config/__tests__/ConfigLoader.test.js +38 -0
- package/dist/src/config/defaults.js +1 -0
- package/dist/src/config/types.js +1 -0
- package/dist/src/core/ask-user-questions.js +63 -0
- package/dist/src/i18n/locales/en.js +2 -2
- package/dist/src/server.js +59 -2
- package/dist/src/session/ResponseFormatter.js +79 -2
- package/dist/src/session/SessionManager.js +36 -0
- package/dist/src/session/__tests__/ResponseFormatter.test.js +86 -0
- package/dist/src/session/__tests__/SessionManager.test.js +129 -0
- package/dist/src/shared/schemas.js +8 -0
- package/dist/src/tui/ThemeProvider.js +3 -3
- package/dist/src/tui/components/Header.js +2 -1
- package/dist/src/tui/components/OptionsList.js +1 -1
- package/dist/src/tui/components/SessionPicker.js +1 -1
- package/dist/src/tui/components/StepperView.js +1 -1
- package/dist/src/tui/components/__tests__/ConfirmationDialog.test.js +1 -1
- package/dist/src/tui/components/__tests__/Footer.test.js +1 -1
- package/dist/src/tui/components/__tests__/MarkdownPrompt.test.js +1 -1
- package/dist/src/tui/components/__tests__/ReviewScreen.test.js +1 -1
- package/dist/src/tui/components/__tests__/SessionDots.test.js +1 -1
- package/dist/src/tui/components/__tests__/SessionPicker.test.js +1 -1
- package/dist/src/tui/components/__tests__/StepperView.abandoned.test.js +1 -1
- package/dist/src/tui/components/__tests__/StepperView.keyboard.test.js +1 -1
- package/dist/src/tui/components/__tests__/StepperView.state.test.js +1 -1
- package/dist/src/tui/components/__tests__/WaitingScreen.test.js +1 -1
- package/dist/src/tui/shared/session-events.js +4 -0
- package/dist/src/tui/shared/themes/catppuccin-latte.js +130 -0
- package/dist/src/tui/shared/themes/catppuccin-mocha.js +131 -0
- package/dist/src/tui/shared/themes/dark.js +131 -0
- package/dist/src/tui/shared/themes/dracula.js +131 -0
- package/dist/src/tui/shared/themes/github-dark.js +129 -0
- package/dist/src/tui/shared/themes/github-light.js +129 -0
- package/dist/src/tui/shared/themes/gruvbox-dark.js +130 -0
- package/dist/src/tui/shared/themes/gruvbox-light.js +130 -0
- package/dist/src/tui/shared/themes/index.js +70 -0
- package/dist/src/tui/shared/themes/light.js +130 -0
- package/dist/src/tui/shared/themes/loader.js +111 -0
- package/dist/src/tui/shared/themes/monokai.js +132 -0
- package/dist/src/tui/shared/themes/nord.js +130 -0
- package/dist/src/tui/shared/themes/one-dark.js +131 -0
- package/dist/src/tui/shared/themes/rose-pine.js +131 -0
- package/dist/src/tui/shared/themes/solarized-dark.js +130 -0
- package/dist/src/tui/shared/themes/solarized-light.js +130 -0
- package/dist/src/tui/shared/themes/tokyo-night.js +131 -0
- package/dist/src/tui/shared/themes/types.js +1 -0
- package/dist/src/tui/shared/types.js +1 -0
- package/dist/src/tui/shared/utils/config.js +80 -0
- package/dist/src/tui/shared/utils/detectTheme.js +33 -0
- package/dist/src/tui/shared/utils/index.js +6 -0
- package/dist/src/tui/shared/utils/recommended.js +52 -0
- package/dist/src/tui/shared/utils/relativeTime.js +24 -0
- package/dist/src/tui/shared/utils/sessionSwitching.js +56 -0
- package/dist/src/tui/shared/utils/staleDetection.js +51 -0
- package/dist/src/tui/themes/catppuccin-latte.js +2 -127
- package/dist/src/tui/themes/catppuccin-mocha.js +2 -127
- package/dist/src/tui/themes/dark.js +2 -128
- package/dist/src/tui/themes/dracula.js +2 -127
- package/dist/src/tui/themes/github-dark.js +2 -126
- package/dist/src/tui/themes/github-light.js +2 -126
- package/dist/src/tui/themes/gruvbox-dark.js +2 -127
- package/dist/src/tui/themes/gruvbox-light.js +2 -127
- package/dist/src/tui/themes/index.js +2 -70
- package/dist/src/tui/themes/light.js +2 -127
- package/dist/src/tui/themes/loader.js +2 -111
- package/dist/src/tui/themes/monokai.js +2 -128
- package/dist/src/tui/themes/nord.js +2 -127
- package/dist/src/tui/themes/one-dark.js +2 -127
- package/dist/src/tui/themes/rose-pine.js +2 -128
- package/dist/src/tui/themes/solarized-dark.js +2 -127
- package/dist/src/tui/themes/solarized-light.js +2 -127
- package/dist/src/tui/themes/tokyo-night.js +2 -127
- package/dist/src/tui/themes/types.js +2 -1
- package/dist/src/tui/types.js +1 -1
- package/dist/src/tui/utils/__tests__/recommended.test.js +1 -1
- package/dist/src/tui/utils/__tests__/relativeTime.test.js +1 -1
- package/dist/src/tui/utils/__tests__/sessionSwitching.test.js +1 -1
- package/dist/src/tui/utils/__tests__/staleDetection.test.js +1 -1
- package/dist/src/tui/utils/config.js +1 -80
- package/dist/src/tui/utils/detectTheme.js +1 -22
- package/dist/src/tui/utils/recommended.js +1 -52
- package/dist/src/tui/utils/relativeTime.js +1 -24
- package/dist/src/tui/utils/sessionSwitching.js +1 -56
- package/dist/src/tui/utils/staleDetection.js +1 -51
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -212,6 +212,38 @@ Whenever you need clarification on what you are working on, never guess, and cal
|
|
|
212
212
|
|
|
213
213
|
When the AI asks questions, you'll see them appear in the AUQ TUI. Answer them **at your convenience**.
|
|
214
214
|
|
|
215
|
+
### Renderer Selection
|
|
216
|
+
|
|
217
|
+
AUQ supports two terminal rendering engines:
|
|
218
|
+
|
|
219
|
+
| Renderer | Description | Status |
|
|
220
|
+
| ----------------- | --------------------------------------------------- | ------------------- |
|
|
221
|
+
| **ink** (default) | React-based terminal renderer | Stable |
|
|
222
|
+
| **OpenTUI** | Native Zig-based renderer with improved performance | Opt-in/Experimental |
|
|
223
|
+
|
|
224
|
+
**To use OpenTUI**, set one of the following (in priority order):
|
|
225
|
+
|
|
226
|
+
1. **Environment variable** (highest priority):
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
AUQ_RENDERER=opentui auq
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
2. **Config file** (`.auqrc.json`):
|
|
233
|
+
|
|
234
|
+
```json
|
|
235
|
+
{
|
|
236
|
+
"renderer": "opentui"
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
3. **CLI command**:
|
|
241
|
+
```bash
|
|
242
|
+
auq config set renderer opentui
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
> **Note:** OpenTUI is currently opt-in and experimental. It provides native CJK character support, built-in markdown rendering with syntax highlighting, and mouse support. The environment variable overrides any config setting.
|
|
246
|
+
|
|
215
247
|
### Markdown rendering in question prompts
|
|
216
248
|
|
|
217
249
|
Question prompts now support **Markdown formatting** in the `prompt` text.
|
|
@@ -240,6 +272,15 @@ It is recommended to **disable** the built-in questioning tool in your harness (
|
|
|
240
272
|
| `Ctrl+R` | Quick Submit | Auto-select recommended options for all questions and go to review |
|
|
241
273
|
| `Esc` | Reject | Reject the whole question set and optionally explain why to the AI |
|
|
242
274
|
| `Ctrl+T` | Theme | Cycle through available color themes |
|
|
275
|
+
| `[`/`]` | Sessions | Switch to previous/next session (OpenTUI: also click session dots) |
|
|
276
|
+
|
|
277
|
+
**Mouse Support (OpenTUI renderer only):**
|
|
278
|
+
|
|
279
|
+
| Action | Description |
|
|
280
|
+
| ----------------- | ----------------------------------------------- |
|
|
281
|
+
| Click option | Select/toggle option |
|
|
282
|
+
| Scroll | Scroll through session picker or update overlay |
|
|
283
|
+
| Click session dot | Switch to that session |
|
|
243
284
|
|
|
244
285
|
<details>
|
|
245
286
|
<summary><strong>More Commands (advanced)</strong></summary>
|
|
@@ -372,10 +413,21 @@ Update checks are automatically disabled in CI environments (`CI=true`).
|
|
|
372
413
|
|
|
373
414
|
The `auq update` command always works regardless of these settings.
|
|
374
415
|
|
|
375
|
-
###
|
|
416
|
+
### Theme System
|
|
376
417
|
|
|
377
418
|
AUQ supports **16 built-in color themes** with automatic persistence. Press `Ctrl+T` to cycle through themes.
|
|
378
419
|
|
|
420
|
+
#### Theme Differences by Renderer
|
|
421
|
+
|
|
422
|
+
| Feature | ink | OpenTUI |
|
|
423
|
+
| ---------------- | ------------------ | ----------------------------------------- |
|
|
424
|
+
| Header text | Gradient animation | Solid accent color |
|
|
425
|
+
| Toast animations | `setTimeout` based | `useTimeline` based |
|
|
426
|
+
| Markdown syntax | Basic highlighting | Tree-sitter powered |
|
|
427
|
+
| Mouse support | No | Yes (click options, scroll, session dots) |
|
|
428
|
+
|
|
429
|
+
> Both renderers support all 16 built-in themes and custom themes. Colors are consistent; only implementation details differ.
|
|
430
|
+
|
|
379
431
|
<details>
|
|
380
432
|
<summary><strong>Built-in Themes</strong></summary>
|
|
381
433
|
|
|
@@ -547,12 +599,13 @@ _Settings from local config override global config, which overrides defaults._
|
|
|
547
599
|
|
|
548
600
|
```json
|
|
549
601
|
{
|
|
602
|
+
"renderer": "ink",
|
|
550
603
|
"maxOptions": 5,
|
|
551
604
|
"maxQuestions": 5,
|
|
552
605
|
"recommendedOptions": 4,
|
|
553
606
|
"recommendedQuestions": 4,
|
|
554
607
|
"sessionTimeout": 0,
|
|
555
|
-
"retentionPeriod": 604800000,
|
|
608
|
+
"retentionPeriod": 604800000,
|
|
556
609
|
"language": "auto",
|
|
557
610
|
"theme": "system",
|
|
558
611
|
"autoSelectRecommended": true,
|
|
@@ -569,6 +622,7 @@ _Settings from local config override global config, which overrides defaults._
|
|
|
569
622
|
|
|
570
623
|
| Setting | Type | Default | Range/Values | Description |
|
|
571
624
|
| ----------------------- | ------- | --------- | ------------------------------- | ----------------------------------------------------- |
|
|
625
|
+
| `renderer` | string | "ink" | "ink", "opentui" | Terminal rendering engine (ink or OpenTUI) |
|
|
572
626
|
| `maxOptions` | number | 5 | 2-10 | Maximum options per question |
|
|
573
627
|
| `maxQuestions` | number | 5 | 1-10 | Maximum questions per session |
|
|
574
628
|
| `recommendedOptions` | number | 4 | 1-10 | Suggested number of options (for AI guidance) |
|
package/dist/bin/auq.js
CHANGED
|
@@ -21,10 +21,19 @@ Commands:
|
|
|
21
21
|
sessions <sub> [flags] List/dismiss sessions
|
|
22
22
|
config <sub> [flags] Get/set configuration
|
|
23
23
|
update Check for and install updates
|
|
24
|
+
fetch-answers [flags] Fetch answers for non-blocking sessions
|
|
25
|
+
history [sub] [flags] Browse session history
|
|
26
|
+
|
|
27
|
+
Ask:
|
|
28
|
+
auq ask '<json>'
|
|
29
|
+
auq ask - (read JSON from stdin)
|
|
30
|
+
Format: {"questions":[{"prompt":"...","title":"...","options":[{"label":"..."}]}]}
|
|
24
31
|
|
|
25
32
|
Answer:
|
|
26
|
-
auq answer <id> --answers '<json>'
|
|
27
|
-
auq answer <id> --reject [--reason]
|
|
33
|
+
auq answer <id> --answers '<json>' Submit answers
|
|
34
|
+
auq answer <id> --reject [--reason "text"] Reject session
|
|
35
|
+
Format: --answers '{"0":{"selectedOption":"Label"}}'
|
|
36
|
+
Keys = question indices (0,1,2…); values: selectedOption, selectedOptions[], customText
|
|
28
37
|
Flags: --force --json
|
|
29
38
|
|
|
30
39
|
Sessions:
|
|
@@ -32,9 +41,19 @@ Sessions:
|
|
|
32
41
|
auq sessions show <id> [--json]
|
|
33
42
|
auq sessions dismiss <id> [--force] [--json]
|
|
34
43
|
|
|
44
|
+
Fetch Answers:
|
|
45
|
+
auq fetch-answers [session-id] [--blocking] [--json]
|
|
46
|
+
auq fetch-answers --unread [--json]
|
|
47
|
+
|
|
48
|
+
History:
|
|
49
|
+
auq history [--all] [--json] [--limit N] [--unread] [--search TEXT]
|
|
50
|
+
auq history show <id> [--json]
|
|
51
|
+
|
|
35
52
|
Config:
|
|
36
53
|
auq config get [key] [--json]
|
|
37
54
|
auq config set <key> <value> [--global] [--json]
|
|
55
|
+
Keys: maxOptions (2-10) maxQuestions (1-10) sessionTimeout (ms)
|
|
56
|
+
theme language renderer (ink|opentui) staleAction (warn|remove|archive)
|
|
38
57
|
|
|
39
58
|
Options:
|
|
40
59
|
-h, --help Show this help
|
|
@@ -46,7 +65,7 @@ Keys (TUI):
|
|
|
46
65
|
[/] sessions 1-9 jump Ctrl+S picker Ctrl+T theme
|
|
47
66
|
|
|
48
67
|
Config: ./.auqrc.json (local) > ~/.config/auq/.auqrc.json (global)
|
|
49
|
-
Env: AUQ_SESSION_DIR XDG_CONFIG_HOME`);
|
|
68
|
+
Env: AUQ_SESSION_DIR XDG_CONFIG_HOME AUQ_RENDERER`);
|
|
50
69
|
process.exit(0);
|
|
51
70
|
}
|
|
52
71
|
// Display version
|
|
@@ -214,6 +233,20 @@ if (command === "config") {
|
|
|
214
233
|
await updateNotification;
|
|
215
234
|
process.exit(0);
|
|
216
235
|
}
|
|
236
|
+
// Handle 'fetch-answers' command
|
|
237
|
+
if (command === "fetch-answers") {
|
|
238
|
+
const { runFetchAnswersCommand } = await import("../src/cli/commands/fetch-answers.js");
|
|
239
|
+
await runFetchAnswersCommand(args.slice(1));
|
|
240
|
+
await updateNotification;
|
|
241
|
+
process.exit(0);
|
|
242
|
+
}
|
|
243
|
+
// Handle 'history' command
|
|
244
|
+
if (command === "history") {
|
|
245
|
+
const { runHistoryCommand } = await import("../src/cli/commands/history.js");
|
|
246
|
+
await runHistoryCommand(args.slice(1));
|
|
247
|
+
await updateNotification;
|
|
248
|
+
process.exit(0);
|
|
249
|
+
}
|
|
217
250
|
// Default: Start TUI
|
|
218
251
|
// Important: Lazy-load Ink/React so non-interactive commands (ask/server) don't pull them in.
|
|
219
252
|
// Also force production mode before importing React/Ink to avoid perf_hooks measure accumulation warnings.
|
package/dist/bin/tui-app.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Box, render, Text, useInput } from "ink";
|
|
2
2
|
import { promises as fs } from "fs";
|
|
3
3
|
import React, { useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
4
|
+
import { DEFAULT_CONFIG } from "../src/config/defaults.js";
|
|
4
5
|
import { ensureDirectoryExists, getSessionDirectory, } from "../src/session/utils.js";
|
|
5
6
|
import { Header } from "../src/tui/components/Header.js";
|
|
6
7
|
import { SessionDots } from "../src/tui/components/SessionDots.js";
|
|
@@ -11,10 +12,10 @@ import { Toast } from "../src/tui/components/Toast.js";
|
|
|
11
12
|
import { WaitingScreen } from "../src/tui/components/WaitingScreen.js";
|
|
12
13
|
import { createNotificationBatcher, showProgress, clearProgress, calculateProgress, checkLinuxDependencies, } from "../src/tui/notifications/index.js";
|
|
13
14
|
import { createTUIWatcher } from "../src/tui/session-watcher.js";
|
|
14
|
-
import { isSessionStale, isSessionAbandoned, formatStaleToastMessage, } from "../src/tui/utils/staleDetection.js";
|
|
15
|
+
import { isSessionStale, isSessionAbandoned, formatStaleToastMessage, } from "../src/tui/shared/utils/staleDetection.js";
|
|
15
16
|
import { ThemeProvider } from "../src/tui/ThemeProvider.js";
|
|
16
17
|
import { ConfigProvider } from "../src/tui/ConfigContext.js";
|
|
17
|
-
import { getAdjustedIndexAfterRemoval, getDirectJumpIndex, getNextSessionIndex, getPrevSessionIndex, } from "../src/tui/utils/sessionSwitching.js";
|
|
18
|
+
import { getAdjustedIndexAfterRemoval, getDirectJumpIndex, getNextSessionIndex, getPrevSessionIndex, } from "../src/tui/shared/utils/sessionSwitching.js";
|
|
18
19
|
import { UpdateChecker, fetchChangelog, installUpdate, detectPackageManager, readCache, writeCache, } from "../src/update/index.js";
|
|
19
20
|
import { UpdateOverlay } from "../src/tui/components/UpdateOverlay.js";
|
|
20
21
|
import { KEYS } from "../src/tui/constants/keybindings.js";
|
|
@@ -37,7 +38,7 @@ const App = ({ config }) => {
|
|
|
37
38
|
const [installError, setInstallError] = useState(null);
|
|
38
39
|
const [changelogContent, setChangelogContent] = useState(null);
|
|
39
40
|
const [updateDismissed, setUpdateDismissed] = useState(false);
|
|
40
|
-
const [
|
|
41
|
+
const [isCheckingUpdate, setIsCheckingUpdate] = useState(false);
|
|
41
42
|
// Get session directory for logging
|
|
42
43
|
const sessionDir = getSessionDirectory();
|
|
43
44
|
// Notification configuration from config
|
|
@@ -55,10 +56,6 @@ const App = ({ config }) => {
|
|
|
55
56
|
}, 3000);
|
|
56
57
|
return () => clearTimeout(timer);
|
|
57
58
|
}, []);
|
|
58
|
-
// Show agent hint for exactly 1 render tick, then hide
|
|
59
|
-
useEffect(() => {
|
|
60
|
-
setShowAgentHint(false);
|
|
61
|
-
}, []);
|
|
62
59
|
// Initialize: Load existing sessions + start persistent watcher
|
|
63
60
|
useEffect(() => {
|
|
64
61
|
let watcherInstance = null;
|
|
@@ -187,7 +184,8 @@ const App = ({ config }) => {
|
|
|
187
184
|
// Silently fail — update checks should never break the TUI
|
|
188
185
|
}
|
|
189
186
|
};
|
|
190
|
-
|
|
187
|
+
setIsCheckingUpdate(true);
|
|
188
|
+
void runCheck().finally(() => { setIsCheckingUpdate(false); });
|
|
191
189
|
intervalId = setInterval(() => {
|
|
192
190
|
checker.clearCache();
|
|
193
191
|
runCheck();
|
|
@@ -545,7 +543,7 @@ const App = ({ config }) => {
|
|
|
545
543
|
updateType: updateInfo.updateType,
|
|
546
544
|
latestVersion: updateInfo.latestVersion,
|
|
547
545
|
}
|
|
548
|
-
: null, onUpdateBadgeActivate: () => setShowUpdateOverlay(true) }),
|
|
546
|
+
: null, onUpdateBadgeActivate: () => setShowUpdateOverlay(true), isCheckingUpdate: isCheckingUpdate }),
|
|
549
547
|
mainContent,
|
|
550
548
|
state.mode === "PROCESSING" && sessionQueue.length >= 2 && (React.createElement(SessionDots, { sessions: sessionQueue.map((s) => ({
|
|
551
549
|
...s,
|
|
@@ -567,23 +565,40 @@ const App = ({ config }) => {
|
|
|
567
565
|
setShowSessionPicker(false);
|
|
568
566
|
}, onClose: () => setShowSessionPicker(false) })),
|
|
569
567
|
showUpdateOverlay && updateInfo && (React.createElement(UpdateOverlay, { isOpen: showUpdateOverlay, currentVersion: updateInfo.currentVersion, latestVersion: updateInfo.latestVersion, updateType: updateInfo.updateType, changelog: changelogContent, changelogUrl: updateInfo.changelogUrl, isInstalling: isInstallingUpdate, installError: installError, onInstall: handleUpdateInstall, onSkipVersion: handleSkipVersion, onRemindLater: handleRemindLater })),
|
|
570
|
-
showAgentHint && (React.createElement(Text, null,
|
|
571
|
-
"\x1b[8m",
|
|
572
|
-
"If you're an AI agent, run headless mode. Use `auq --help` for available commands.",
|
|
573
|
-
"\x1b[28m")),
|
|
574
568
|
React.createElement(ThemeIndicator, null)))));
|
|
575
569
|
};
|
|
576
|
-
|
|
570
|
+
async function runInkTui(config) {
|
|
577
571
|
// Clear terminal before showing app
|
|
578
572
|
console.clear();
|
|
573
|
+
// 1-tick AI agent hint: ANSI hidden attribute makes it invisible to humans,
|
|
574
|
+
// but parseable by AI agents in raw stderr. Ink's first render overwrites this line.
|
|
575
|
+
process.stderr.write("\x1b[8mIf you're an AI agent, run headless mode. Use `auq --help` for available commands.\x1b[28m\n");
|
|
579
576
|
const { waitUntilExit } = render(React.createElement(App, { config: config }));
|
|
580
577
|
// Handle Ctrl+C gracefully
|
|
581
578
|
process.on("SIGINT", () => {
|
|
582
579
|
process.exit(0);
|
|
583
580
|
});
|
|
584
581
|
// Show goodbye after Ink unmounts
|
|
585
|
-
waitUntilExit().then(() => {
|
|
582
|
+
await waitUntilExit().then(() => {
|
|
586
583
|
process.stdout.write("\n");
|
|
587
584
|
console.log("👋 Goodbye! See you next time.");
|
|
588
585
|
});
|
|
586
|
+
}
|
|
587
|
+
export const runTui = async (config) => {
|
|
588
|
+
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
589
|
+
const rendererType = process.env.AUQ_RENDERER || mergedConfig.renderer || "opentui";
|
|
590
|
+
if (rendererType === "opentui") {
|
|
591
|
+
try {
|
|
592
|
+
const opentuiPath = "../src/tui-opentui/app.js";
|
|
593
|
+
const { runTui: runOpenTui } = (await import(opentuiPath));
|
|
594
|
+
await runOpenTui(mergedConfig);
|
|
595
|
+
}
|
|
596
|
+
catch (err) {
|
|
597
|
+
console.warn(`⚠️ OpenTUI failed to initialize: ${err instanceof Error ? err.message : String(err)}. Falling back to ink renderer.`);
|
|
598
|
+
await runInkTui(mergedConfig);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
await runInkTui(mergedConfig);
|
|
603
|
+
}
|
|
589
604
|
};
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auq-mcp-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"auq": "dist/bin/auq.js"
|
|
@@ -28,7 +28,10 @@
|
|
|
28
28
|
"generate:skill": "bun run scripts/generate-skill.ts",
|
|
29
29
|
"validate:skill": "bunx skills-ref validate skills/ask-user-questions",
|
|
30
30
|
"test": "vitest run",
|
|
31
|
-
"format": "prettier --write . && eslint --fix ."
|
|
31
|
+
"format": "prettier --write . && eslint --fix .",
|
|
32
|
+
"build:opentui": "tsc -p tsconfig.opentui.json --noEmit",
|
|
33
|
+
"test:opentui": "bun test src/tui-opentui",
|
|
34
|
+
"typecheck:all": "tsc --noEmit && tsc -p tsconfig.opentui.json --noEmit"
|
|
32
35
|
},
|
|
33
36
|
"keywords": [
|
|
34
37
|
"fastmcp",
|
|
@@ -50,6 +53,8 @@
|
|
|
50
53
|
"description": "An MCP server that provides a tool to ask a user questions via the terminal",
|
|
51
54
|
"dependencies": {
|
|
52
55
|
"@inkjs/ui": "^2.0.0",
|
|
56
|
+
"@opentui/core": "0.1.87",
|
|
57
|
+
"@opentui/react": "0.1.87",
|
|
53
58
|
"@modelcontextprotocol/sdk": "1.17.2",
|
|
54
59
|
"@types/uuid": "^10.0.0",
|
|
55
60
|
"chalk": "^5.6.2",
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Tests the most common edge cases to catch obvious bugs
|
|
4
4
|
*/
|
|
5
5
|
import { describe, expect, it } from "vitest";
|
|
6
|
-
import { QuestionSchema, QuestionsSchema } from "../core/ask-user-questions.js";
|
|
6
|
+
import { QuestionSchema, QuestionsSchema, AskUserQuestionsParametersSchema } from "../core/ask-user-questions.js";
|
|
7
|
+
import { GetAnsweredQuestionsArgsSchema } from "../shared/schemas.js";
|
|
7
8
|
describe("Schema Validation - Edge Cases", () => {
|
|
8
9
|
describe("Invalid Input (should reject)", () => {
|
|
9
10
|
it("should reject missing title field", () => {
|
|
@@ -176,3 +177,62 @@ describe("Schema Validation - Edge Cases", () => {
|
|
|
176
177
|
});
|
|
177
178
|
});
|
|
178
179
|
});
|
|
180
|
+
describe("nonBlocking parameter", () => {
|
|
181
|
+
const validQuestion = {
|
|
182
|
+
options: [{ label: "Option A" }, { label: "Option B" }],
|
|
183
|
+
prompt: "Which do you prefer?",
|
|
184
|
+
title: "Preference",
|
|
185
|
+
multiSelect: false,
|
|
186
|
+
};
|
|
187
|
+
it("should accept nonBlocking: true", () => {
|
|
188
|
+
const result = AskUserQuestionsParametersSchema.parse({
|
|
189
|
+
questions: [validQuestion],
|
|
190
|
+
nonBlocking: true,
|
|
191
|
+
});
|
|
192
|
+
expect(result.nonBlocking).toBe(true);
|
|
193
|
+
});
|
|
194
|
+
it("should accept nonBlocking: false", () => {
|
|
195
|
+
const result = AskUserQuestionsParametersSchema.parse({
|
|
196
|
+
questions: [validQuestion],
|
|
197
|
+
nonBlocking: false,
|
|
198
|
+
});
|
|
199
|
+
expect(result.nonBlocking).toBe(false);
|
|
200
|
+
});
|
|
201
|
+
it("should default nonBlocking to false when omitted", () => {
|
|
202
|
+
const result = AskUserQuestionsParametersSchema.parse({
|
|
203
|
+
questions: [validQuestion],
|
|
204
|
+
});
|
|
205
|
+
expect(result.nonBlocking).toBe(false);
|
|
206
|
+
});
|
|
207
|
+
it("should reject non-boolean nonBlocking", () => {
|
|
208
|
+
expect(() => AskUserQuestionsParametersSchema.parse({
|
|
209
|
+
questions: [validQuestion],
|
|
210
|
+
nonBlocking: "yes",
|
|
211
|
+
})).toThrow();
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
describe("GetAnsweredQuestionsArgsSchema", () => {
|
|
215
|
+
it("should accept valid session_id", () => {
|
|
216
|
+
const result = GetAnsweredQuestionsArgsSchema.parse({
|
|
217
|
+
session_id: "a3f2e8b1-1234-4567-89ab-cdef01234567",
|
|
218
|
+
});
|
|
219
|
+
expect(result.session_id).toBe("a3f2e8b1-1234-4567-89ab-cdef01234567");
|
|
220
|
+
expect(result.blocking).toBe(false);
|
|
221
|
+
});
|
|
222
|
+
it("should accept session_id with blocking: true", () => {
|
|
223
|
+
const result = GetAnsweredQuestionsArgsSchema.parse({
|
|
224
|
+
session_id: "a3f2e8b1",
|
|
225
|
+
blocking: true,
|
|
226
|
+
});
|
|
227
|
+
expect(result.blocking).toBe(true);
|
|
228
|
+
});
|
|
229
|
+
it("should reject missing session_id", () => {
|
|
230
|
+
expect(() => GetAnsweredQuestionsArgsSchema.parse({})).toThrow();
|
|
231
|
+
});
|
|
232
|
+
it("should reject non-boolean blocking", () => {
|
|
233
|
+
expect(() => GetAnsweredQuestionsArgsSchema.parse({
|
|
234
|
+
session_id: "test",
|
|
235
|
+
blocking: "yes",
|
|
236
|
+
})).toThrow();
|
|
237
|
+
});
|
|
238
|
+
});
|