auq-mcp-server 1.2.9 → 1.3.1
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 +6 -26
- package/dist/package.json +2 -1
- package/dist/src/__tests__/schema-validation.test.js +1 -1
- package/dist/src/tui/components/ConfirmationDialog.js +3 -3
- package/dist/src/tui/components/Footer.js +7 -9
- package/dist/src/tui/components/MultiLineTextInput.js +11 -24
- package/dist/src/tui/components/OptionsList.js +4 -3
- package/dist/src/tui/components/QuestionDisplay.js +6 -3
- package/dist/src/tui/components/SingleLineTextInput.js +59 -0
- package/dist/src/tui/components/StepperView.js +17 -4
- package/dist/src/tui/components/WaitingScreen.js +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -67,27 +67,20 @@ Recent AI workflows often use parallel sub-agents for concurrent coding. AUQ han
|
|
|
67
67
|
AUQ is designed for the era of parallel multi-agent workflows, with several key advantages:
|
|
68
68
|
|
|
69
69
|
### 🚀 Non-Blocking Parallel Operation
|
|
70
|
+
|
|
70
71
|
Unlike built-in ask tools that halt the entire AI workflow until you respond, AUQ **doesn't block the AI from continuing work**. Questions are queued asynchronously, allowing your AI assistants to keep coding while you review and answer questions at your own pace.
|
|
71
72
|
|
|
72
73
|
### 🎯 Multi-Agent Question Set Support
|
|
73
|
-
|
|
74
|
+
|
|
75
|
+
AUQ can handle question sets from **multiple agents simultaneously**. In modern AI coding workflows, you often have several sub-agents working in parallel—each might need clarification on different aspects of your codebase. With AUQ:
|
|
74
76
|
|
|
75
77
|
- **No more screen switching** between different agent conversations
|
|
76
78
|
- **Unified queue** for all agent questions, regardless of which AI tool they're coming from
|
|
77
79
|
- **Sequential processing** of questions from multiple sources in one interface
|
|
78
80
|
|
|
79
|
-
### 🌐
|
|
80
|
-
AUQ's **unified data origin** means you can answer questions from **different AI clients simultaneously**:
|
|
81
|
-
- Claude Code questions
|
|
82
|
-
- OpenCode questions
|
|
83
|
-
- Cursor/MCP questions
|
|
84
|
-
|
|
85
|
-
All appear in the **same CLI interface**, creating a single source of truth for all AI-agent questions across your entire development environment.
|
|
81
|
+
### 🌐 Question Set Rejection Support
|
|
86
82
|
|
|
87
|
-
|
|
88
|
-
As AI coding moves toward sophisticated multi-agent systems, AUQ becomes essential. Instead of managing blocking questions across multiple agent screens, you get one streamlined interface that handles questions from your entire AI coding ecosystem—keeping your focus on the code, not the coordination.
|
|
89
|
-
|
|
90
|
-
**TL;DR**: AUQ transforms AI-agent questions from blocking interruptions into a smooth, unified workflow that scales with your AI coding setup.
|
|
83
|
+
**Skip irrelevant question sets entirely** - reject whole question batches that don't apply to your current context, saving time and maintaining focus on relevant AI-agent questions.
|
|
91
84
|
|
|
92
85
|
---
|
|
93
86
|
|
|
@@ -103,8 +96,6 @@ First, install the AUQ CLI tool:
|
|
|
103
96
|
# Install globally
|
|
104
97
|
npm install -g auq-mcp-server
|
|
105
98
|
|
|
106
|
-
# Start the TUI
|
|
107
|
-
auq
|
|
108
99
|
```
|
|
109
100
|
|
|
110
101
|
### Local Installation (Project-specific)
|
|
@@ -113,8 +104,6 @@ auq
|
|
|
113
104
|
# Install in your project
|
|
114
105
|
npm install auq-mcp-server
|
|
115
106
|
|
|
116
|
-
# Start the TUI from project directory
|
|
117
|
-
npx auq
|
|
118
107
|
```
|
|
119
108
|
|
|
120
109
|
**Session Storage:**
|
|
@@ -128,7 +117,7 @@ npx auq
|
|
|
128
117
|
|
|
129
118
|
AUQ supports multiple AI coding environments. Choose the one that fits your workflow:
|
|
130
119
|
|
|
131
|
-
### Option A: MCP Server
|
|
120
|
+
### Option A: MCP Server
|
|
132
121
|
|
|
133
122
|
### Cursor
|
|
134
123
|
|
|
@@ -215,14 +204,6 @@ We now have **official OpenCode plugin support**! We support OpenCode because Op
|
|
|
215
204
|
|
|
216
205
|
The OpenCode plugin allows OpenCode to call `auq ask` directly (without MCP), providing seamless integration with OpenCode's workflow.
|
|
217
206
|
|
|
218
|
-
#### Installation
|
|
219
|
-
|
|
220
|
-
```bash
|
|
221
|
-
# Install both CLI and plugin
|
|
222
|
-
npm install -g auq-mcp-server
|
|
223
|
-
npm install -g @paulp-o/opencode-auq
|
|
224
|
-
```
|
|
225
|
-
|
|
226
207
|
#### Configuration
|
|
227
208
|
|
|
228
209
|
Add to `opencode.json`:
|
|
@@ -233,7 +214,6 @@ Add to `opencode.json`:
|
|
|
233
214
|
}
|
|
234
215
|
```
|
|
235
216
|
|
|
236
|
-
|
|
237
217
|
---
|
|
238
218
|
|
|
239
219
|
## 💻 Usage
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auq-mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"auq": "dist/bin/auq.js"
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"prepare": "npm run build",
|
|
20
20
|
"postinstall": "node scripts/postinstall.cjs",
|
|
21
21
|
"deploy": "node scripts/deploy.mjs",
|
|
22
|
+
"semantic-release": "semantic-release",
|
|
22
23
|
"server": "node dist/src/server.js",
|
|
23
24
|
"start": "tsx src/server.ts",
|
|
24
25
|
"dev": "fastmcp dev src/server.ts",
|
|
@@ -3,7 +3,7 @@
|
|
|
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
|
|
6
|
+
import { QuestionSchema, QuestionsSchema } from "../core/ask-user-questions.js";
|
|
7
7
|
describe("Schema Validation - Edge Cases", () => {
|
|
8
8
|
describe("Invalid Input (should reject)", () => {
|
|
9
9
|
it("should reject missing title field", () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Box, Text, useInput } from "ink";
|
|
2
2
|
import React, { useState } from "react";
|
|
3
3
|
import { theme } from "../theme.js";
|
|
4
|
-
import {
|
|
4
|
+
import { SingleLineTextInput } from "./SingleLineTextInput.js";
|
|
5
5
|
/**
|
|
6
6
|
* ConfirmationDialog shows a 3-option prompt for session rejection
|
|
7
7
|
* Options: Reject & inform AI, Cancel, or Quit CLI
|
|
@@ -64,9 +64,9 @@ export const ConfirmationDialog = ({ message, onReject, onCancel, onQuit, }) =>
|
|
|
64
64
|
React.createElement(Box, { marginBottom: 1 },
|
|
65
65
|
React.createElement(Text, { dimColor: true }, "(Optional - helps the AI improve)")),
|
|
66
66
|
React.createElement(Box, { marginBottom: 1 },
|
|
67
|
-
React.createElement(
|
|
67
|
+
React.createElement(SingleLineTextInput, { isFocused: true, onChange: setRejectionReason, onSubmit: handleReasonSubmit, placeholder: "Type your reason here...", value: rejectionReason })),
|
|
68
68
|
React.createElement(Box, { marginTop: 1 },
|
|
69
|
-
React.createElement(Text, { dimColor: true }, "Enter Submit |
|
|
69
|
+
React.createElement(Text, { dimColor: true }, "Enter Submit | Esc Skip"))));
|
|
70
70
|
}
|
|
71
71
|
// Step 1: Confirmation options
|
|
72
72
|
return (React.createElement(Box, { borderColor: theme.borders.warning, borderStyle: "single", flexDirection: "column", padding: 1 },
|
|
@@ -16,25 +16,23 @@ export const Footer = ({ focusContext, multiSelect, isReviewScreen = false, cust
|
|
|
16
16
|
}
|
|
17
17
|
// Custom input focused
|
|
18
18
|
if (focusContext === "custom-input") {
|
|
19
|
-
|
|
20
|
-
const bindings = [
|
|
19
|
+
return [
|
|
21
20
|
{ key: "↑↓", action: "Options" },
|
|
22
|
-
{ key: "
|
|
21
|
+
{ key: "←→", action: "Cursor" },
|
|
22
|
+
{ key: "Tab/S+Tab", action: "Questions" },
|
|
23
|
+
{ key: "Enter", action: "Newline" },
|
|
24
|
+
{ key: "Esc", action: "Reject" },
|
|
23
25
|
];
|
|
24
|
-
if (hasContent) {
|
|
25
|
-
bindings.push({ key: "Enter", action: "Submit" });
|
|
26
|
-
}
|
|
27
|
-
bindings.push({ key: "Shift+Enter", action: "Newline" }, { key: "Esc", action: "Reject" });
|
|
28
|
-
return bindings;
|
|
29
26
|
}
|
|
30
27
|
// Option focused
|
|
31
28
|
if (focusContext === "option") {
|
|
32
29
|
const bindings = [
|
|
33
30
|
{ key: "↑↓", action: "Options" },
|
|
34
31
|
{ key: "←→", action: "Questions" },
|
|
32
|
+
{ key: "Tab/S+Tab", action: "Questions" },
|
|
35
33
|
];
|
|
36
34
|
if (multiSelect) {
|
|
37
|
-
bindings.push({ key: "Space", action: "Toggle" }
|
|
35
|
+
bindings.push({ key: "Space", action: "Toggle" });
|
|
38
36
|
}
|
|
39
37
|
else {
|
|
40
38
|
bindings.push({ key: "Enter", action: "Select" });
|
|
@@ -4,7 +4,7 @@ import { theme } from "../theme.js";
|
|
|
4
4
|
/**
|
|
5
5
|
* Multi-line text input component for Ink with cursor positioning
|
|
6
6
|
* Supports left/right arrow keys for cursor movement
|
|
7
|
-
*
|
|
7
|
+
* Enter for newlines, Tab to submit (portable across terminals)
|
|
8
8
|
*/
|
|
9
9
|
export const MultiLineTextInput = ({ isFocused = true, onChange, onSubmit, placeholder = "Type your answer...", value, }) => {
|
|
10
10
|
const [cursorPosition, setCursorPosition] = useState(value.length);
|
|
@@ -17,33 +17,22 @@ export const MultiLineTextInput = ({ isFocused = true, onChange, onSubmit, place
|
|
|
17
17
|
useInput((input, key) => {
|
|
18
18
|
if (!isFocused)
|
|
19
19
|
return;
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
else if (onSubmit) {
|
|
29
|
-
onSubmit();
|
|
30
|
-
}
|
|
20
|
+
// Tab: Submit (also triggers question navigation via parent)
|
|
21
|
+
if (key.tab && !key.shift) {
|
|
22
|
+
onSubmit?.();
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Shift+Tab: Let parent handle for previous question navigation
|
|
26
|
+
if (key.tab && key.shift) {
|
|
31
27
|
return;
|
|
32
28
|
}
|
|
33
|
-
//
|
|
34
|
-
if (
|
|
29
|
+
// Enter: Always add newline (portable behavior)
|
|
30
|
+
if (input === "\r" || input === "\n" || key.return) {
|
|
35
31
|
const newValue = value.slice(0, cursorPosition) + "\n" + value.slice(cursorPosition);
|
|
36
32
|
onChange(newValue);
|
|
37
33
|
setCursorPosition(cursorPosition + 1);
|
|
38
34
|
return;
|
|
39
35
|
}
|
|
40
|
-
// Enter: Submit (empty input allowed)
|
|
41
|
-
if (key.return) {
|
|
42
|
-
if (onSubmit) {
|
|
43
|
-
onSubmit();
|
|
44
|
-
}
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
36
|
// Left arrow: Move cursor left
|
|
48
37
|
if (key.leftArrow) {
|
|
49
38
|
setCursorPosition(Math.max(0, cursorPosition - 1));
|
|
@@ -75,13 +64,11 @@ export const MultiLineTextInput = ({ isFocused = true, onChange, onSubmit, place
|
|
|
75
64
|
setCursorPosition(cursorPosition + 1);
|
|
76
65
|
}
|
|
77
66
|
}, { isActive: isFocused });
|
|
78
|
-
// Normalize any carriage returns that might already be present in value
|
|
79
67
|
const normalizedValue = value.replace(/\r\n?/g, "\n");
|
|
80
68
|
const hasContent = normalizedValue.length > 0;
|
|
81
69
|
const lines = hasContent ? normalizedValue.split("\n") : [placeholder];
|
|
82
|
-
// Calculate which line and position the cursor is on
|
|
83
70
|
const cursorLineIndex = normalizedValue.slice(0, cursorPosition).split("\n").length - 1;
|
|
84
|
-
const cursorLineStart = normalizedValue.
|
|
71
|
+
const cursorLineStart = normalizedValue.lastIndexOf("\n", cursorPosition - 1) + 1;
|
|
85
72
|
const cursorPositionInLine = cursorPosition - cursorLineStart;
|
|
86
73
|
return (React.createElement(Box, { flexDirection: "column" }, lines.map((line, index) => {
|
|
87
74
|
const isCursorLine = isFocused && index === cursorLineIndex && hasContent;
|
|
@@ -47,8 +47,9 @@ export const OptionsList = ({ isFocused, onSelect, options, selectedOption, show
|
|
|
47
47
|
onToggle?.(options[focusedIndex].label);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
if (key.return
|
|
51
|
-
// Enter
|
|
50
|
+
if (key.return) {
|
|
51
|
+
// Enter: Advance to next question (don't toggle)
|
|
52
|
+
// Note: Tab is handled globally in StepperView for question navigation
|
|
52
53
|
if (!isCustomInputFocused && onAdvance) {
|
|
53
54
|
onAdvance();
|
|
54
55
|
}
|
|
@@ -117,7 +118,7 @@ export const OptionsList = ({ isFocused, onSelect, options, selectedOption, show
|
|
|
117
118
|
customValue ? "●" : "○",
|
|
118
119
|
" Other (custom answer)"),
|
|
119
120
|
isCustomInputFocused && onCustomChange && (React.createElement(Box, { marginLeft: 2, marginTop: 0.5 },
|
|
120
|
-
React.createElement(MultiLineTextInput, { isFocused: true, onChange: onCustomChange, onSubmit: onAdvance, placeholder: "Type your answer... (
|
|
121
|
+
React.createElement(MultiLineTextInput, { isFocused: true, onChange: onCustomChange, onSubmit: onAdvance, placeholder: "Type your answer... (Enter for newline, Tab to submit)", value: customValue }))),
|
|
121
122
|
!isCustomInputFocused && customValue && (React.createElement(Box, { marginLeft: 2, marginTop: 0.5 },
|
|
122
123
|
React.createElement(Text, { dimColor: true }, customLines.map((line, idx) => (React.createElement(React.Fragment, { key: idx },
|
|
123
124
|
idx === 0 ? "❯ " : " ",
|
|
@@ -7,9 +7,12 @@ import { TabBar } from "./TabBar.js";
|
|
|
7
7
|
* QuestionDisplay shows a single question with its options
|
|
8
8
|
* Includes TabBar, question prompt, options list, and footer
|
|
9
9
|
*/
|
|
10
|
-
export const QuestionDisplay = ({ currentQuestion, currentQuestionIndex, customAnswer = "", elapsedLabel, onChangeCustomAnswer, onSelectOption, questions, selectedOption, onAdvanceToNext, answers, onToggleOption, multiSelect, }) => {
|
|
11
|
-
// Track focus context for Footer component
|
|
10
|
+
export const QuestionDisplay = ({ currentQuestion, currentQuestionIndex, customAnswer = "", elapsedLabel, onChangeCustomAnswer, onSelectOption, questions, selectedOption, onAdvanceToNext, answers, onToggleOption, multiSelect, onFocusContextChange, }) => {
|
|
12
11
|
const [focusContext, setFocusContext] = useState("option");
|
|
12
|
+
const handleFocusContextChange = (context) => {
|
|
13
|
+
setFocusContext(context);
|
|
14
|
+
onFocusContextChange?.(context);
|
|
15
|
+
};
|
|
13
16
|
// Handle option selection - clears custom answer only in single-select mode
|
|
14
17
|
const handleSelectOption = (label) => {
|
|
15
18
|
onSelectOption(label);
|
|
@@ -35,6 +38,6 @@ export const QuestionDisplay = ({ currentQuestion, currentQuestionIndex, customA
|
|
|
35
38
|
React.createElement(Text, { dimColor: true },
|
|
36
39
|
"Elapsed ",
|
|
37
40
|
elapsedLabel)),
|
|
38
|
-
React.createElement(OptionsList, { customValue: customAnswer, isFocused: true, onAdvance: onAdvanceToNext, onCustomChange: handleCustomAnswerChange, onSelect: handleSelectOption, options: currentQuestion.options, selectedOption: selectedOption, showCustomInput: true, onToggle: onToggleOption, multiSelect: multiSelect, selectedOptions: answers.get(currentQuestionIndex)?.selectedOptions, onFocusContextChange:
|
|
41
|
+
React.createElement(OptionsList, { customValue: customAnswer, isFocused: true, onAdvance: onAdvanceToNext, onCustomChange: handleCustomAnswerChange, onSelect: handleSelectOption, options: currentQuestion.options, selectedOption: selectedOption, showCustomInput: true, onToggle: onToggleOption, multiSelect: multiSelect, selectedOptions: answers.get(currentQuestionIndex)?.selectedOptions, onFocusContextChange: handleFocusContextChange }),
|
|
39
42
|
React.createElement(Footer, { focusContext: focusContext, multiSelect: multiSelect ?? false, customInputValue: customAnswer })));
|
|
40
43
|
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Text, useInput } from "ink";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import { theme } from "../theme.js";
|
|
4
|
+
export const SingleLineTextInput = ({ isFocused = true, onChange, onSubmit, placeholder = "Type here...", value, }) => {
|
|
5
|
+
const [cursorPosition, setCursorPosition] = useState(value.length);
|
|
6
|
+
React.useEffect(() => {
|
|
7
|
+
if (cursorPosition > value.length) {
|
|
8
|
+
setCursorPosition(value.length);
|
|
9
|
+
}
|
|
10
|
+
}, [value.length, cursorPosition]);
|
|
11
|
+
useInput((input, key) => {
|
|
12
|
+
if (!isFocused)
|
|
13
|
+
return;
|
|
14
|
+
if (key.return) {
|
|
15
|
+
onSubmit?.();
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (key.leftArrow) {
|
|
19
|
+
setCursorPosition(Math.max(0, cursorPosition - 1));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (key.rightArrow) {
|
|
23
|
+
setCursorPosition(Math.min(value.length, cursorPosition + 1));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (key.backspace || key.delete) {
|
|
27
|
+
if (cursorPosition > 0) {
|
|
28
|
+
const newValue = value.slice(0, cursorPosition - 1) + value.slice(cursorPosition);
|
|
29
|
+
onChange(newValue);
|
|
30
|
+
setCursorPosition(cursorPosition - 1);
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (input &&
|
|
35
|
+
!key.ctrl &&
|
|
36
|
+
!key.meta &&
|
|
37
|
+
!key.escape &&
|
|
38
|
+
!key.tab &&
|
|
39
|
+
input !== "\r" &&
|
|
40
|
+
input !== "\n") {
|
|
41
|
+
const newValue = value.slice(0, cursorPosition) + input + value.slice(cursorPosition);
|
|
42
|
+
onChange(newValue);
|
|
43
|
+
setCursorPosition(cursorPosition + 1);
|
|
44
|
+
}
|
|
45
|
+
}, { isActive: isFocused });
|
|
46
|
+
const hasContent = value.length > 0;
|
|
47
|
+
const displayText = hasContent ? value : placeholder;
|
|
48
|
+
if (hasContent && isFocused) {
|
|
49
|
+
const beforeCursor = value.slice(0, cursorPosition);
|
|
50
|
+
const afterCursor = value.slice(cursorPosition);
|
|
51
|
+
return (React.createElement(Text, null,
|
|
52
|
+
beforeCursor,
|
|
53
|
+
React.createElement(Text, { color: theme.colors.focused, dimColor: true }, "\u258C"),
|
|
54
|
+
afterCursor));
|
|
55
|
+
}
|
|
56
|
+
return (React.createElement(Text, { dimColor: !hasContent },
|
|
57
|
+
displayText,
|
|
58
|
+
isFocused && !hasContent && (React.createElement(Text, { color: theme.colors.focused, dimColor: true }, "\u258C"))));
|
|
59
|
+
};
|
|
@@ -18,6 +18,7 @@ export const StepperView = ({ onComplete, sessionId, sessionRequest, }) => {
|
|
|
18
18
|
const [submitting, setSubmitting] = useState(false);
|
|
19
19
|
const [showRejectionConfirm, setShowRejectionConfirm] = useState(false);
|
|
20
20
|
const [elapsedSeconds, setElapsedSeconds] = useState(0);
|
|
21
|
+
const [focusContext, setFocusContext] = useState("option");
|
|
21
22
|
const currentQuestion = sessionRequest.questions[currentQuestionIndex];
|
|
22
23
|
const sessionCreatedAt = useMemo(() => {
|
|
23
24
|
const parsed = Date.parse(sessionRequest.timestamp);
|
|
@@ -163,11 +164,23 @@ export const StepperView = ({ onComplete, sessionId, sessionRequest, }) => {
|
|
|
163
164
|
setShowRejectionConfirm(true);
|
|
164
165
|
return;
|
|
165
166
|
}
|
|
166
|
-
//
|
|
167
|
-
if (key.
|
|
167
|
+
// Tab/Shift+Tab: Global question navigation (works in all contexts)
|
|
168
|
+
if (key.tab && key.shift && currentQuestionIndex > 0) {
|
|
169
|
+
setCurrentQuestionIndex((prev) => prev - 1);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (key.tab &&
|
|
173
|
+
!key.shift &&
|
|
174
|
+
currentQuestionIndex < sessionRequest.questions.length - 1) {
|
|
175
|
+
setCurrentQuestionIndex((prev) => prev + 1);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const shouldNavigate = focusContext !== "custom-input";
|
|
179
|
+
if (shouldNavigate && key.leftArrow && currentQuestionIndex > 0) {
|
|
168
180
|
setCurrentQuestionIndex((prev) => prev - 1);
|
|
169
181
|
}
|
|
170
|
-
if (
|
|
182
|
+
if (shouldNavigate &&
|
|
183
|
+
key.rightArrow &&
|
|
171
184
|
currentQuestionIndex < sessionRequest.questions.length - 1) {
|
|
172
185
|
setCurrentQuestionIndex((prev) => prev + 1);
|
|
173
186
|
}
|
|
@@ -189,5 +202,5 @@ export const StepperView = ({ onComplete, sessionId, sessionRequest, }) => {
|
|
|
189
202
|
return (React.createElement(ReviewScreen, { answers: answers, elapsedLabel: elapsedLabel, onConfirm: handleConfirm, onGoBack: handleGoBack, questions: sessionRequest.questions, sessionId: sessionId }));
|
|
190
203
|
}
|
|
191
204
|
// Show question display (default)
|
|
192
|
-
return (React.createElement(QuestionDisplay, { currentQuestion: currentQuestion, currentQuestionIndex: currentQuestionIndex, customAnswer: currentAnswer?.customText, elapsedLabel: elapsedLabel, onAdvanceToNext: handleAdvanceToNext, onChangeCustomAnswer: handleChangeCustomAnswer, onSelectOption: handleSelectOption, onToggleOption: handleToggleOption, multiSelect: currentQuestion.multiSelect, questions: sessionRequest.questions, selectedOption: currentAnswer?.selectedOption, answers: answers }));
|
|
205
|
+
return (React.createElement(QuestionDisplay, { currentQuestion: currentQuestion, currentQuestionIndex: currentQuestionIndex, customAnswer: currentAnswer?.customText, elapsedLabel: elapsedLabel, onAdvanceToNext: handleAdvanceToNext, onChangeCustomAnswer: handleChangeCustomAnswer, onSelectOption: handleSelectOption, onToggleOption: handleToggleOption, multiSelect: currentQuestion.multiSelect, questions: sessionRequest.questions, selectedOption: currentAnswer?.selectedOption, answers: answers, onFocusContextChange: setFocusContext }));
|
|
193
206
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auq-mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"auq": "dist/bin/auq.js"
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"prepare": "npm run build",
|
|
20
20
|
"postinstall": "node scripts/postinstall.cjs",
|
|
21
21
|
"deploy": "node scripts/deploy.mjs",
|
|
22
|
+
"semantic-release": "semantic-release",
|
|
22
23
|
"server": "node dist/src/server.js",
|
|
23
24
|
"start": "tsx src/server.ts",
|
|
24
25
|
"dev": "fastmcp dev src/server.ts",
|