auq-mcp-server 1.3.2 β†’ 1.5.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 CHANGED
@@ -106,10 +106,7 @@ npm install auq-mcp-server
106
106
 
107
107
  ```
108
108
 
109
- **Session Storage:**
110
-
111
- - **Global install**: `~/Library/Application Support/auq/sessions` (macOS), `~/.local/share/auq/sessions` (Linux)
112
- - **Local install**: `.auq/sessions/` in your project root
109
+ **Note:** Sessions are stored globally regardless of installation method. See [Troubleshooting](#troubleshooting) for session locations.
113
110
 
114
111
  ---
115
112
 
@@ -208,7 +205,7 @@ Add to `opencode.json`:
208
205
 
209
206
  ```json
210
207
  {
211
- "plugin": ["@paulp-o/opencode-auq"]
208
+ "plugin": ["@paulp-o/opencode-auq@latest"]
212
209
  }
213
210
  ```
214
211
 
@@ -219,8 +216,8 @@ Add to `opencode.json`:
219
216
  ### Starting the CLI tool
220
217
 
221
218
  ```bash
222
- auq # if you installed globally
223
- npx auq # if you installed locally
219
+ auq # if installed globally (npm install -g)
220
+ npx auq # works from anywhere
224
221
  ```
225
222
 
226
223
  Then just start working with your coding agent or AI assistant. You may prompt to ask questions with the tool the agent got; it will mostly just get what you mean.
@@ -234,66 +231,101 @@ auq --version # Show version
234
231
  auq --help # Show help
235
232
  ```
236
233
 
234
+ ---
235
+
236
+ ### Manual session cleanup
237
+
238
+ Sessions auto-clean after completion or timeout. However, you can manually clean them up if you want to.
239
+
240
+ ```bash
241
+ rm -rf ~/Library/Application\ Support/auq/sessions/* # macOS
242
+ rm -rf ~/.local/share/auq/sessions/* # Linux
243
+ ```
244
+
245
+ ---
246
+
237
247
  <details>
238
- <summary><strong>πŸ” auq ask λͺ…λ Ήμ–΄ 상세 μ„€λͺ… (ν΄λ¦­ν•˜μ—¬ 펼치기)</strong></summary>
248
+ <summary>Local Development & Testing</summary>
249
+
250
+ To test the MCP server and CLI locally during development:
239
251
 
240
- <br>
252
+ ### 1. Start the MCP Server (Terminal 1)
241
253
 
242
- `auq ask`λŠ” AI μ½”λ”© μ—μ΄μ „νŠΈκ°€ μ‚¬μš©μžμ—κ²Œ μ§ˆλ¬Έμ„ ν•  λ•Œ μ‚¬μš©ν•˜λŠ” 핡심 λͺ…λ Ήμ–΄μž…λ‹ˆλ‹€.
254
+ ```bash
255
+ # Option A: Run with tsx (recommended for development)
256
+ npm run start
257
+
258
+ # Option B: Run with fastmcp dev mode (includes web inspector at http://localhost:6274)
259
+ npm run dev
260
+
261
+ # Option C: Run the built version
262
+ npm run build && npm run server
263
+ ```
243
264
 
244
- #### κΈ°λ³Έ μ‚¬μš©λ²•
265
+ ### 2. Create a Test Session (Terminal 2)
266
+
267
+ Use the `auq ask` command to create a session and wait for answers:
245
268
 
246
269
  ```bash
247
- auq ask
270
+ # Run directly with tsx during development
271
+ npx tsx bin/auq.tsx ask '{"questions": [{"prompt": "Which language?", "title": "Lang", "options": [{"label": "TypeScript"}, {"label": "Python"}], "multiSelect": false}]}'
272
+
273
+ # Or pipe JSON to stdin
274
+ echo '{"questions": [{"prompt": "Which database?", "title": "DB", "options": [{"label": "PostgreSQL"}, {"label": "MongoDB"}], "multiSelect": false}]}' | npx tsx bin/auq.tsx ask
248
275
  ```
249
276
 
250
- 이 λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•˜λ©΄ λŒ€ν™”ν˜• 터미널 μΈν„°νŽ˜μ΄μŠ€κ°€ μ‹œμž‘λ˜μ–΄ AI μ—μ΄μ „νŠΈμ˜ 질문 μ„ΈνŠΈλ₯Ό κΈ°λ‹€λ¦½λ‹ˆλ‹€.
277
+ This will create a session and wait for the TUI to provide answers.
251
278
 
252
- #### μž‘λ™ 방식
279
+ ### 3. Answer with the TUI (Terminal 3)
253
280
 
254
- 1. **질문 μˆ˜μ‹  λŒ€κΈ°**: AI μ—μ΄μ „νŠΈ(MCP ν΄λΌμ΄μ–ΈνŠΈ)κ°€ μ§ˆλ¬Έμ„ 보내면 μžλ™μœΌλ‘œ ν‘œμ‹œλ©λ‹ˆλ‹€
255
- 2. **질문 μ„ΈνŠΈ 처리**: μ—¬λŸ¬ 개의 μ—°κ΄€λœ μ§ˆλ¬Έμ„ ν•˜λ‚˜μ˜ μ„ΈνŠΈλ‘œ λ¬Άμ–΄μ„œ 처리
256
- 3. **μ‚¬μš©μž 응닡**: 각 μ§ˆλ¬Έμ— λŒ€ν•΄ 닡변을 μž…λ ₯ν•˜κ±°λ‚˜ κ±΄λ„ˆλ›Έ 수 있음
257
- 4. **응닡 전솑**: λͺ¨λ“  닡변을 μ™„λ£Œν•˜λ©΄ AI μ—μ΄μ „νŠΈλ‘œ κ²°κ³Όκ°€ μ „μ†‘λ©λ‹ˆλ‹€
281
+ ```bash
282
+ # Run the TUI to answer pending questions
283
+ npx tsx bin/auq.tsx
284
+ ```
258
285
 
259
- #### μ£Όμš” νŠΉμ§•
286
+ ### Create Mock Sessions for TUI Testing
260
287
 
261
- - **비차단 방식**: AIκ°€ μ§ˆλ¬Έμ„ λ³΄λ‚΄λŠ” λ™μ•ˆμ—λ„ 계속 μž‘μ—…ν•  수 있음
262
- - **닀쀑 μ—μ΄μ „νŠΈ 지원**: μ—¬λŸ¬ AI μ—μ΄μ „νŠΈμ˜ μ§ˆλ¬Έμ„ λ™μ‹œμ— 처리
263
- - **μ„Έμ…˜ 관리**: 각 질문 μ„ΈνŠΈλŠ” 독립적인 μ„Έμ…˜μœΌλ‘œ 관리됨
264
- - **νƒ€μž„μ•„μ›ƒ 처리**: 일정 μ‹œκ°„ λ™μ•ˆ 응닡이 μ—†μœΌλ©΄ μ„Έμ…˜μ΄ μžλ™ μ’…λ£Œ
288
+ To test the TUI with multiple pending sessions:
265
289
 
266
- #### μ˜ˆμ‹œ μ›Œν¬ν”Œλ‘œμš°
290
+ ```bash
291
+ # Create 3 mock sessions (default)
292
+ npx tsx scripts/create-mock-session.ts
267
293
 
294
+ # Create a specific number of sessions
295
+ npx tsx scripts/create-mock-session.ts 5
268
296
  ```
269
- 1. AI μ—μ΄μ „νŠΈκ°€ λ³΅μž‘ν•œ μ½”λ“œλ₯Ό μž‘μ„± 쀑
270
- 2. AIκ°€ "이 ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μ„ μ–΄λ–»κ²Œ ν• κΉŒμš”?"라고 질문
271
- 3. auq askκ°€ μ‹€ν–‰λ˜μ–΄ 질문이 터미널에 ν‘œμ‹œ
272
- 4. μ‚¬μš©μžκ°€ λ‹΅λ³€ μž…λ ₯
273
- 5. AIκ°€ 닡변을 λ°›μ•„μ„œ μ½”λ“œ μž‘μ„± 계속 μ§„ν–‰
297
+
298
+ Then run the TUI to see and answer them:
299
+
300
+ ```bash
301
+ npx tsx bin/auq.tsx
274
302
  ```
275
303
 
276
- #### 문제 ν•΄κ²°
304
+ ### Verify MCP and CLI Use Same Session Directory
305
+
306
+ Both components should report the same session directory path. Check the logs:
277
307
 
278
- - **질문이 ν‘œμ‹œλ˜μ§€ μ•ŠμŒ**: MCP μ„œλ²„κ°€ μ œλŒ€λ‘œ μ‹€ν–‰λ˜κ³  μžˆλŠ”μ§€ 확인
279
- - **응닡이 μ „μ†‘λ˜μ§€ μ•ŠμŒ**: λ„€νŠΈμ›Œν¬ μ—°κ²°κ³Ό μ„Έμ…˜ μƒνƒœ 확인
280
- - **μ„Έμ…˜μ΄ 쀑단됨**: νƒ€μž„μ•„μ›ƒ μ„€μ •μ΄λ‚˜ μ„Έμ…˜ 관리 확인
308
+ - MCP server logs session directory on startup
309
+ - `auq ask` prints `[AUQ] Session directory: <path>` to stderr
310
+
311
+ On macOS, both should use: `~/Library/Application Support/auq/sessions`
281
312
 
282
313
  </details>
283
314
 
284
- ---
315
+ ## Troubleshooting
285
316
 
286
- ### Manual session cleanup
317
+ ### Session Storage
287
318
 
288
- Sessions auto-clean after completion or timeout. However, you can manually clean them up if you want to.
319
+ Sessions are stored in platform-specific global locations:
289
320
 
290
- ```bash
291
- # Global install
292
- rm -rf ~/Library/Application\ Support/auq/sessions/* # macOS
293
- rm -rf ~/.local/share/auq/sessions/* # Linux
321
+ - **macOS**: `~/Library/Application Support/auq/sessions`
322
+ - **Linux**: `~/.local/share/auq/sessions` (or `$XDG_DATA_HOME/auq/sessions`)
323
+ - **Windows**: `%APPDATA%\auq\sessions`
294
324
 
295
- # Local install
296
- rm -rf .auq/sessions/*
325
+ To override the default location, set the `AUQ_SESSION_DIR` environment variable:
326
+
327
+ ```bash
328
+ export AUQ_SESSION_DIR=/custom/path
297
329
  ```
298
330
 
299
331
  ---
package/dist/bin/auq.js CHANGED
@@ -40,12 +40,11 @@ ASK COMMAND:
40
40
  - Multi-select mode (multiSelect: true): User can select MULTIPLE options
41
41
 
42
42
  USAGE NOTES:
43
- - Always provide a descriptive 'title' field (max 12 chars) for each question
43
+ - Provide a descriptive 'title' field (max 12 chars) for each question
44
44
  - Use multiSelect: true when choices are not mutually exclusive
45
45
  - Option labels should be concise (1-5 words)
46
- - Questions should end with a question mark
46
+ - To mark a recommended option, append '(recommended)' to its label
47
47
  - Don't include an 'Other' option - it's provided automatically
48
- - Mark one option as recommended.
49
48
 
50
49
  Returns a formatted summary of all questions and answers.
51
50
 
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auq-mcp-server",
3
- "version": "1.3.2",
3
+ "version": "1.5.0",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "auq": "dist/bin/auq.js"
@@ -15,17 +15,16 @@
15
15
  "packages/opencode-plugin"
16
16
  ],
17
17
  "scripts": {
18
- "build": "npm run sync-schemas && tsc",
18
+ "build": "npm run sync-plugin-schemas && tsc",
19
19
  "prepare": "npm run build",
20
20
  "postinstall": "node scripts/postinstall.cjs",
21
- "deploy": "node scripts/deploy.mjs",
22
21
  "release": "semantic-release",
23
22
  "release:dry-run": "semantic-release --dry-run",
24
23
  "server": "node dist/src/server.js",
25
24
  "start": "tsx src/server.ts",
26
25
  "dev": "fastmcp dev src/server.ts",
27
26
  "lint": "prettier --check . && eslint . && tsc --noEmit",
28
- "sync-schemas": "node scripts/sync-schemas.mjs",
27
+ "sync-plugin-schemas": "node scripts/sync-plugin-schemas.mjs",
29
28
  "test": "vitest run",
30
29
  "format": "prettier --write . && eslint --fix ."
31
30
  },
@@ -72,7 +71,12 @@
72
71
  "changelogFile": "CHANGELOG.md"
73
72
  }
74
73
  ],
75
- "@semantic-release/npm",
74
+ [
75
+ "@semantic-release/npm",
76
+ {
77
+ "workspaces": true
78
+ }
79
+ ],
76
80
  "@semantic-release/github"
77
81
  ]
78
82
  },
@@ -1,6 +1,7 @@
1
1
  import { FastMCP } from "fastmcp";
2
2
  import { randomUUID } from "crypto";
3
3
  import { AskUserQuestionsParametersSchema, createAskUserQuestionsCore, } from "./core/ask-user-questions.js";
4
+ import { TOOL_DESCRIPTION } from "./shared/schemas.js";
4
5
  const askUserQuestionsCore = createAskUserQuestionsCore();
5
6
  const server = new FastMCP({
6
7
  name: "AskUserQuestions",
@@ -17,27 +18,7 @@ server.addTool({
17
18
  readOnlyHint: false, // This tool waits for user input
18
19
  idempotentHint: true,
19
20
  },
20
- description: "Use this tool when you need to ask the user questions during execution. " +
21
- "This allows you to:\n" +
22
- "1. Gather user preferences or requirements\n" +
23
- "2. Clarify ambiguous instructions\n" +
24
- "3. Get decisions on implementation choices as you work\n" +
25
- "4. Offer choices to the user about what direction to take\n\n" +
26
- "FEATURES:\n" +
27
- "- Ask 1-4 structured questions via an interactive terminal interface\n" +
28
- "- Each question includes 2-4 multiple-choice options with explanatory descriptions\n" +
29
- "- Users can always provide custom free-text input as an alternative to predefined options\n" +
30
- "- Single-select mode (default): User picks ONE option or provides custom text\n" +
31
- "- Multi-select mode (multiSelect: true): User can select MULTIPLE options\n\n" +
32
- "USAGE NOTES:\n" +
33
- "- Always provide a descriptive 'title' field (max 12 chars) for each question\n" +
34
- "- Use multiSelect: true when choices are not mutually exclusive\n" +
35
- "- Option labels should be concise (1-5 words)\n" +
36
- "- Questions should end with a question mark\n" +
37
- "- Don't include an 'Other' option - it's provided automatically\n" +
38
- "- Mark one option as recommended.\n\n" +
39
- "- If user seems not aware how to answer the question, inform them that they need to install the 'auq' cli tool.\n\n" +
40
- "Returns a formatted summary of all questions and answers.",
21
+ description: TOOL_DESCRIPTION,
41
22
  execute: async (args, ctx) => {
42
23
  const { log } = ctx;
43
24
  try {
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Unit tests for session utility functions
3
+ */
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { homedir } from "os";
6
+ import { getSessionDirectory, resolveSessionDirectory } from "../utils.js";
7
+ describe("session utilities", () => {
8
+ const originalEnv = { ...process.env };
9
+ const originalPlatform = process.platform;
10
+ beforeEach(() => {
11
+ // Reset process.env to original state before each test
12
+ process.env = { ...originalEnv };
13
+ vi.restoreAllMocks();
14
+ });
15
+ afterEach(() => {
16
+ // Clean up process.env after each test
17
+ process.env = { ...originalEnv };
18
+ });
19
+ describe("getSessionDirectory", () => {
20
+ it("should return macOS XDG path when no env var is set", () => {
21
+ // Mock platform to macOS
22
+ vi.stubGlobal("process", {
23
+ ...process,
24
+ platform: "darwin",
25
+ });
26
+ // Ensure AUQ_SESSION_DIR is not set
27
+ delete process.env.AUQ_SESSION_DIR;
28
+ const result = getSessionDirectory();
29
+ expect(result).toBe(`${homedir()}/Library/Application Support/auq/sessions`);
30
+ });
31
+ it("should return Linux XDG path when no env var is set", () => {
32
+ // Mock platform to Linux
33
+ vi.stubGlobal("process", {
34
+ ...process,
35
+ platform: "linux",
36
+ });
37
+ // Ensure AUQ_SESSION_DIR is not set
38
+ delete process.env.AUQ_SESSION_DIR;
39
+ const result = getSessionDirectory();
40
+ expect(result).toBe(`${homedir()}/.local/share/auq/sessions`);
41
+ });
42
+ it("should use AUQ_SESSION_DIR env var when set", () => {
43
+ const customDir = "/custom/session/dir";
44
+ process.env.AUQ_SESSION_DIR = customDir;
45
+ const result = getSessionDirectory();
46
+ expect(result).toBe(customDir);
47
+ });
48
+ it("should expand tilde in AUQ_SESSION_DIR env var", () => {
49
+ process.env.AUQ_SESSION_DIR = "~/custom/sessions";
50
+ const result = getSessionDirectory();
51
+ expect(result).toBe(`${homedir()}/custom/sessions`);
52
+ });
53
+ it("should not expand tilde when AUQ_SESSION_DIR does not start with ~", () => {
54
+ const customDir = "/absolute/path/to/sessions";
55
+ process.env.AUQ_SESSION_DIR = customDir;
56
+ const result = getSessionDirectory();
57
+ expect(result).toBe(customDir);
58
+ });
59
+ it("should prefer AUQ_SESSION_DIR over XDG path", () => {
60
+ const customDir = "/custom/sessions";
61
+ process.env.AUQ_SESSION_DIR = customDir;
62
+ // Mock platform to macOS
63
+ vi.stubGlobal("process", {
64
+ ...process,
65
+ platform: "darwin",
66
+ });
67
+ const result = getSessionDirectory();
68
+ // Should use env var, not the macOS default
69
+ expect(result).toBe(customDir);
70
+ expect(result).not.toBe(`${homedir()}/Library/Application Support/auq/sessions`);
71
+ });
72
+ });
73
+ describe("resolveSessionDirectory", () => {
74
+ it("should return macOS path when platform is darwin", () => {
75
+ vi.stubGlobal("process", {
76
+ ...process,
77
+ platform: "darwin",
78
+ });
79
+ const result = resolveSessionDirectory();
80
+ expect(result).toBe(`${homedir()}/Library/Application Support/auq/sessions`);
81
+ });
82
+ it("should return Linux path when platform is linux", () => {
83
+ vi.stubGlobal("process", {
84
+ ...process,
85
+ platform: "linux",
86
+ });
87
+ const result = resolveSessionDirectory();
88
+ expect(result).toBe(`${homedir()}/.local/share/auq/sessions`);
89
+ });
90
+ it("should return Windows path when platform is win32 with APPDATA", () => {
91
+ vi.stubGlobal("process", {
92
+ ...process,
93
+ platform: "win32",
94
+ env: {
95
+ ...process.env,
96
+ APPDATA: "C:/Users/Test/AppData/Roaming",
97
+ },
98
+ });
99
+ const result = resolveSessionDirectory();
100
+ // Note: join() uses forward slashes when running on Unix systems
101
+ expect(result).toBe("C:/Users/Test/AppData/Roaming/auq/sessions");
102
+ });
103
+ it("should return Windows path with USERPROFILE fallback when APPDATA not set", () => {
104
+ vi.stubGlobal("process", {
105
+ ...process,
106
+ platform: "win32",
107
+ env: {
108
+ ...process.env,
109
+ APPDATA: undefined,
110
+ USERPROFILE: "C:/Users/Test",
111
+ },
112
+ });
113
+ const result = resolveSessionDirectory();
114
+ // Note: join() uses forward slashes when running on Unix systems
115
+ expect(result).toBe("C:/Users/Test/auq/sessions");
116
+ });
117
+ it("should return Linux XDG_DATA_HOME path when env var is set", () => {
118
+ vi.stubGlobal("process", {
119
+ ...process,
120
+ platform: "linux",
121
+ env: {
122
+ ...process.env,
123
+ XDG_DATA_HOME: "/custom/xdg/data",
124
+ },
125
+ });
126
+ const result = resolveSessionDirectory();
127
+ expect(result).toBe("/custom/xdg/data/auq/sessions");
128
+ });
129
+ it("should expand tilde in provided baseDir", () => {
130
+ const result = resolveSessionDirectory("~/custom/base");
131
+ expect(result).toBe(`${homedir()}/custom/base`);
132
+ });
133
+ it("should use provided baseDir when it does not start with tilde", () => {
134
+ const result = resolveSessionDirectory("/absolute/custom/path");
135
+ expect(result).toBe("/absolute/custom/path");
136
+ });
137
+ it("should handle other Unix platforms (e.g., freebsd)", () => {
138
+ vi.stubGlobal("process", {
139
+ ...process,
140
+ platform: "freebsd",
141
+ });
142
+ const result = resolveSessionDirectory();
143
+ expect(result).toBe(`${homedir()}/.local/share/auq/sessions`);
144
+ });
145
+ it("should handle empty baseDir parameter", () => {
146
+ const result = resolveSessionDirectory("");
147
+ // Should treat empty string as falsy and use default XDG path
148
+ expect(result).toContain(homedir());
149
+ expect(result).toContain("auq/sessions");
150
+ });
151
+ });
152
+ });
@@ -1,11 +1,10 @@
1
1
  /**
2
2
  * Utility functions for session management
3
3
  */
4
- import { constants, existsSync } from "fs";
4
+ import { constants } from "fs";
5
5
  import { promises as fs } from "fs";
6
6
  import { homedir } from "os";
7
7
  import { join } from "path";
8
- import { fileURLToPath } from "url";
9
8
  /**
10
9
  * Create a safe filename from a session ID (basic validation)
11
10
  */
@@ -125,39 +124,13 @@ export async function validateSessionDirectory(baseDir) {
125
124
  }
126
125
  }
127
126
  /**
128
- * Detect whether AUQ is installed globally or locally
129
- * by inspecting the module's location
130
- */
131
- export function detectInstallMode() {
132
- try {
133
- // Get current module's file path
134
- const __filename = fileURLToPath(import.meta.url);
135
- const parts = __filename.split(/[/\\]/); // Handle both Unix and Windows separators
136
- // Find the last occurrence of 'node_modules' in the path
137
- const nodeModulesIndex = parts.lastIndexOf("node_modules");
138
- if (nodeModulesIndex === -1) {
139
- // Not in node_modules (development or global install without node_modules in path)
140
- return { mode: "global" };
141
- }
142
- // We're inside node_modules - check if there's a project package.json above
143
- const potentialProjectRoot = parts.slice(0, nodeModulesIndex).join("/");
144
- const packageJsonPath = join(potentialProjectRoot, "package.json");
145
- if (existsSync(packageJsonPath)) {
146
- // Found a package.json above node_modules β†’ local install
147
- return { mode: "local", projectRoot: potentialProjectRoot };
148
- }
149
- // In node_modules but no project context β†’ global install
150
- return { mode: "global" };
151
- }
152
- catch (error) {
153
- // Fallback to global mode if detection fails
154
- console.error("[AUQ] Failed to detect install mode:", error);
155
- return { mode: "global" };
156
- }
157
- }
158
- /**
159
- * Get the appropriate session directory based on installation mode
160
- * Supports environment variable override via AUQ_SESSION_DIR
127
+ * Get the session directory path.
128
+ * Always uses global XDG-compliant paths to ensure MCP server and CLI
129
+ * always find each other's sessions regardless of installation location.
130
+ *
131
+ * Priority:
132
+ * 1. AUQ_SESSION_DIR environment variable (if set)
133
+ * 2. Platform-specific XDG-compliant path
161
134
  */
162
135
  export function getSessionDirectory() {
163
136
  // Check for environment variable override first
@@ -169,12 +142,6 @@ export function getSessionDirectory() {
169
142
  }
170
143
  return envDir;
171
144
  }
172
- // Auto-detect installation mode
173
- const { mode, projectRoot } = detectInstallMode();
174
- if (mode === "local" && projectRoot) {
175
- // Local install: use project-relative .auq/sessions directory
176
- return join(projectRoot, ".auq", "sessions");
177
- }
178
- // Global install: use XDG-compliant system paths
145
+ // Always use global XDG-compliant paths
179
146
  return resolveSessionDirectory();
180
147
  }
@@ -2,8 +2,8 @@ import { z } from "zod";
2
2
  export const OptionSchema = z.object({
3
3
  label: z
4
4
  .string()
5
- .describe("The display text for this option that the user will see and select. " +
6
- "Should be concise (1-5 words) and clearly describe the choice."),
5
+ .describe("The display text for this option. Should be concise (1-5 words). " +
6
+ "To mark as recommended, append '(recommended)' to the label text."),
7
7
  description: z
8
8
  .string()
9
9
  .optional()
@@ -38,13 +38,19 @@ export const QuestionsSchema = z.array(QuestionSchema).min(1).max(4);
38
38
  export const AskUserQuestionsParametersSchema = z.object({
39
39
  questions: QuestionsSchema.describe("Questions to ask the user (1-4 questions). " +
40
40
  "Each question must include: prompt (full question text), title (short label, max 12 chars), " +
41
- "options (2-4 choices with labels and descriptions), and multiSelect (boolean). " +
42
- "Mark one choice as recommended if possible."),
41
+ "options (2-4 choices with labels and descriptions), and multiSelect (boolean)."),
43
42
  });
44
- export const TOOL_DESCRIPTION = "Ask users structured questions during execution to gather preferences, clarify requirements, or make implementation decisions.\n\n" +
45
- "FEATURES:\n" +
46
- "- Non-blocking: doesn't halt AI workflow\n" +
47
- "- 1-4 questions with 2-4 options each\n" +
48
- "- Single/multi-select modes\n" +
49
- "- Custom text input always available\n\n" +
50
- "Returns formatted responses for continued reasoning.";
43
+ /**
44
+ * Comprehensive tool description - single source of truth.
45
+ * Used by MCP server and should be synced to opencode-plugin.
46
+ */
47
+ export const TOOL_DESCRIPTION = "Use this tool when you need to ask the user questions during execution. This allows you to:\n\n" +
48
+ "Gather user preferences or requirements\n" +
49
+ "Clarify ambiguous instructions\n" +
50
+ "Get decisions on implementation choices as you work\n" +
51
+ "Offer choices to the user about what direction to take.\n" +
52
+ "Usage notes:\n\n" +
53
+ "Users will always be able to select \"Other\" to provide custom text input\n" +
54
+ "Use multiSelect: true to allow multiple answers to be selected for a question\n" +
55
+ "Recommend an option unless absolutely necessary, make it the first option in the list and add \"(Recommended)\" at the end of the label\n" +
56
+ "Do NOT use this tool to ask \"Is my plan ready?\" or \"Should I proceed?\"";
@@ -24,7 +24,7 @@ export const Header = ({ pendingCount }) => {
24
24
  return packageJson.version || "unknown";
25
25
  }, []);
26
26
  // Use the selected gradient theme from theme.ts
27
- const headerText = gradient[theme.headerGradient](".π–₯” AUQ ⋆ Ask User Questions MCP ⋆ ");
27
+ const headerText = gradient[theme.headerGradient](".π–₯” AUQ ⋆ Ask User Questions ⋆ ");
28
28
  return (React.createElement(Box, { borderColor: theme.components.header.border, borderStyle: "single", flexDirection: "row", justifyContent: "space-between", paddingX: 1 },
29
29
  React.createElement(Text, { bold: true }, headerText),
30
30
  React.createElement(Box, null,
@@ -164,7 +164,7 @@ export class EnhancedTUISessionWatcher extends TUISessionWatcher {
164
164
  }
165
165
  /**
166
166
  * Create a simple TUI session watcher instance
167
- * Auto-detects session directory based on global vs local install
167
+ * Uses global XDG-compliant session directory path
168
168
  */
169
169
  export function createTUIWatcher(config) {
170
170
  // Auto-detect session directory if not provided in config
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auq-mcp-server",
3
- "version": "1.3.2",
3
+ "version": "1.5.0",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "auq": "dist/bin/auq.js"
@@ -15,17 +15,16 @@
15
15
  "packages/opencode-plugin"
16
16
  ],
17
17
  "scripts": {
18
- "build": "npm run sync-schemas && tsc",
18
+ "build": "npm run sync-plugin-schemas && tsc",
19
19
  "prepare": "npm run build",
20
20
  "postinstall": "node scripts/postinstall.cjs",
21
- "deploy": "node scripts/deploy.mjs",
22
21
  "release": "semantic-release",
23
22
  "release:dry-run": "semantic-release --dry-run",
24
23
  "server": "node dist/src/server.js",
25
24
  "start": "tsx src/server.ts",
26
25
  "dev": "fastmcp dev src/server.ts",
27
26
  "lint": "prettier --check . && eslint . && tsc --noEmit",
28
- "sync-schemas": "node scripts/sync-schemas.mjs",
27
+ "sync-plugin-schemas": "node scripts/sync-plugin-schemas.mjs",
29
28
  "test": "vitest run",
30
29
  "format": "prettier --write . && eslint --fix ."
31
30
  },
@@ -72,7 +71,12 @@
72
71
  "changelogFile": "CHANGELOG.md"
73
72
  }
74
73
  ],
75
- "@semantic-release/npm",
74
+ [
75
+ "@semantic-release/npm",
76
+ {
77
+ "workspaces": true
78
+ }
79
+ ],
76
80
  "@semantic-release/github"
77
81
  ]
78
82
  },