@defai.digital/ax-cli 3.12.1 → 3.12.5

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.
Files changed (56) hide show
  1. package/README.md +24 -62
  2. package/dist/agent/execution/tool-executor.d.ts +1 -1
  3. package/dist/agent/execution/tool-executor.js +55 -2
  4. package/dist/agent/execution/tool-executor.js.map +1 -1
  5. package/dist/commands/custom-commands.d.ts +77 -0
  6. package/dist/commands/custom-commands.js +249 -0
  7. package/dist/commands/custom-commands.js.map +1 -0
  8. package/dist/hooks/index.d.ts +6 -3
  9. package/dist/hooks/index.js +6 -3
  10. package/dist/hooks/index.js.map +1 -1
  11. package/dist/hooks/manager.d.ts +84 -0
  12. package/dist/hooks/manager.js +344 -0
  13. package/dist/hooks/manager.js.map +1 -0
  14. package/dist/hooks/types.d.ts +134 -0
  15. package/dist/hooks/types.js +9 -0
  16. package/dist/hooks/types.js.map +1 -0
  17. package/dist/llm/tools.js +53 -0
  18. package/dist/llm/tools.js.map +1 -1
  19. package/dist/sdk/version.d.ts +1 -1
  20. package/dist/sdk/version.js +1 -1
  21. package/dist/tools/ask-user.d.ts +122 -0
  22. package/dist/tools/ask-user.js +283 -0
  23. package/dist/tools/ask-user.js.map +1 -0
  24. package/dist/tools/bash.js +6 -3
  25. package/dist/tools/bash.js.map +1 -1
  26. package/dist/ui/components/chat-interface.js +72 -6
  27. package/dist/ui/components/chat-interface.js.map +1 -1
  28. package/dist/ui/components/keyboard-hints.js +3 -1
  29. package/dist/ui/components/keyboard-hints.js.map +1 -1
  30. package/dist/ui/components/question-dialog.d.ts +17 -0
  31. package/dist/ui/components/question-dialog.js +181 -0
  32. package/dist/ui/components/question-dialog.js.map +1 -0
  33. package/dist/ui/components/quick-actions.js +13 -5
  34. package/dist/ui/components/quick-actions.js.map +1 -1
  35. package/dist/ui/components/status-bar.js +2 -0
  36. package/dist/ui/components/status-bar.js.map +1 -1
  37. package/dist/ui/hooks/use-enhanced-input.js +28 -5
  38. package/dist/ui/hooks/use-enhanced-input.js.map +1 -1
  39. package/dist/ui/hooks/use-input-handler.d.ts +10 -0
  40. package/dist/ui/hooks/use-input-handler.js +257 -45
  41. package/dist/ui/hooks/use-input-handler.js.map +1 -1
  42. package/dist/ui/utils/semantic-action-detector.js +19 -1
  43. package/dist/ui/utils/semantic-action-detector.js.map +1 -1
  44. package/dist/ui/utils/tool-grouper.js +13 -1
  45. package/dist/ui/utils/tool-grouper.js.map +1 -1
  46. package/dist/utils/analysis-logger.d.ts +3 -0
  47. package/dist/utils/analysis-logger.js +4 -1
  48. package/dist/utils/analysis-logger.js.map +1 -1
  49. package/dist/utils/background-task-manager.js +9 -5
  50. package/dist/utils/background-task-manager.js.map +1 -1
  51. package/dist/utils/file-mentions.d.ts +68 -0
  52. package/dist/utils/file-mentions.js +225 -0
  53. package/dist/utils/file-mentions.js.map +1 -0
  54. package/dist/utils/paste-utils.js +2 -1
  55. package/dist/utils/paste-utils.js.map +1 -1
  56. package/package.json +1 -1
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Hooks Manager
3
+ *
4
+ * Manages loading, registration, and execution of hooks.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import type { AnyHookConfig, HookEventType, HookInput, HookExecutionResult } from "./types.js";
9
+ /**
10
+ * Hooks Manager
11
+ *
12
+ * Singleton that manages hook registration and execution.
13
+ */
14
+ export declare class HooksManager {
15
+ private static instance;
16
+ private hooks;
17
+ private projectDir;
18
+ private userDir;
19
+ private initialized;
20
+ private constructor();
21
+ /**
22
+ * Get the singleton instance
23
+ */
24
+ static getInstance(): HooksManager;
25
+ /**
26
+ * Reset the singleton (for testing)
27
+ */
28
+ static reset(): void;
29
+ /**
30
+ * Register a hook programmatically
31
+ */
32
+ registerHook(hook: AnyHookConfig): void;
33
+ /**
34
+ * Ensure hooks are initialized (lazy init)
35
+ */
36
+ private ensureInitialized;
37
+ /**
38
+ * Get all hooks for a specific event type
39
+ */
40
+ getHooksForEvent(event: HookEventType, toolName?: string): AnyHookConfig[];
41
+ /**
42
+ * Match a tool name against a glob pattern
43
+ */
44
+ private matchToolPattern;
45
+ /**
46
+ * Execute hooks for an event
47
+ */
48
+ executeHooks(event: HookEventType, input: HookInput): Promise<HookExecutionResult[]>;
49
+ /**
50
+ * Execute a single hook
51
+ */
52
+ private executeHook;
53
+ /**
54
+ * Execute a command hook
55
+ */
56
+ private executeCommandHook;
57
+ /**
58
+ * Check if any PreToolUse hook blocks the tool execution
59
+ */
60
+ shouldBlockTool(toolName: string, toolArgs: Record<string, unknown>, toolId: string): Promise<{
61
+ blocked: boolean;
62
+ reason?: string;
63
+ }>;
64
+ /**
65
+ * Process user input through UserPromptSubmit hooks
66
+ */
67
+ processUserInput(userInput: string): Promise<string>;
68
+ /**
69
+ * Execute PostToolUse hooks (fire-and-forget)
70
+ */
71
+ executePostToolHooks(toolName: string, toolArgs: Record<string, unknown>, toolId: string, toolResult: import("../types/index.js").ToolResult): Promise<void>;
72
+ /**
73
+ * Get the list of registered hooks
74
+ */
75
+ getHooks(): AnyHookConfig[];
76
+ /**
77
+ * Clear all hooks
78
+ */
79
+ clearHooks(): void;
80
+ }
81
+ /**
82
+ * Get the singleton hooks manager instance
83
+ */
84
+ export declare function getHooksManager(): HooksManager;
@@ -0,0 +1,344 @@
1
+ /**
2
+ * Hooks Manager
3
+ *
4
+ * Manages loading, registration, and execution of hooks.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import { spawn } from "child_process";
9
+ import * as fs from "fs";
10
+ import * as path from "path";
11
+ import * as os from "os";
12
+ import { extractErrorMessage } from "../utils/error-handler.js";
13
+ /** Default hook timeout in milliseconds */
14
+ const DEFAULT_HOOK_TIMEOUT = 60000;
15
+ /** Config file names to check */
16
+ const CONFIG_FILE_NAMES = ["hooks.json", "hooks.yaml", "hooks.yml"];
17
+ /**
18
+ * Hooks Manager
19
+ *
20
+ * Singleton that manages hook registration and execution.
21
+ */
22
+ export class HooksManager {
23
+ static instance = null;
24
+ hooks = [];
25
+ projectDir;
26
+ userDir;
27
+ initialized = false;
28
+ constructor() {
29
+ this.projectDir = process.cwd();
30
+ this.userDir = path.join(os.homedir(), ".ax-cli");
31
+ }
32
+ /**
33
+ * Get the singleton instance
34
+ */
35
+ static getInstance() {
36
+ if (!HooksManager.instance) {
37
+ HooksManager.instance = new HooksManager();
38
+ }
39
+ return HooksManager.instance;
40
+ }
41
+ /**
42
+ * Reset the singleton (for testing)
43
+ */
44
+ static reset() {
45
+ HooksManager.instance = null;
46
+ }
47
+ /**
48
+ * Register a hook programmatically
49
+ */
50
+ registerHook(hook) {
51
+ this.hooks.push(hook);
52
+ }
53
+ /**
54
+ * Ensure hooks are initialized (lazy init)
55
+ */
56
+ ensureInitialized() {
57
+ if (this.initialized)
58
+ return;
59
+ this.hooks = [];
60
+ // Load hooks from project directory (.ax-cli/hooks.json)
61
+ const projectHooksDir = path.join(this.projectDir, ".ax-cli");
62
+ for (const fileName of CONFIG_FILE_NAMES) {
63
+ const filePath = path.join(projectHooksDir, fileName);
64
+ if (fs.existsSync(filePath)) {
65
+ try {
66
+ const content = fs.readFileSync(filePath, "utf-8");
67
+ const config = JSON.parse(content);
68
+ this.hooks.push(...(config.hooks || []));
69
+ break;
70
+ }
71
+ catch (error) {
72
+ console.warn(`Failed to load hooks from ${filePath}:`, extractErrorMessage(error));
73
+ }
74
+ }
75
+ }
76
+ // Load hooks from user directory (~/.ax-cli/hooks.json)
77
+ for (const fileName of CONFIG_FILE_NAMES) {
78
+ const filePath = path.join(this.userDir, fileName);
79
+ if (fs.existsSync(filePath)) {
80
+ try {
81
+ const content = fs.readFileSync(filePath, "utf-8");
82
+ const config = JSON.parse(content);
83
+ this.hooks.push(...(config.hooks || []));
84
+ break;
85
+ }
86
+ catch (error) {
87
+ console.warn(`Failed to load hooks from ${filePath}:`, extractErrorMessage(error));
88
+ }
89
+ }
90
+ }
91
+ this.initialized = true;
92
+ }
93
+ /**
94
+ * Get all hooks for a specific event type
95
+ */
96
+ getHooksForEvent(event, toolName) {
97
+ this.ensureInitialized();
98
+ return this.hooks.filter((hook) => {
99
+ if (hook.event !== event)
100
+ return false;
101
+ if (hook.enabled === false)
102
+ return false;
103
+ // For tool-related events, check tool pattern
104
+ if ((event === "PreToolUse" || event === "PostToolUse") && toolName) {
105
+ if (hook.toolPattern) {
106
+ return this.matchToolPattern(toolName, hook.toolPattern);
107
+ }
108
+ }
109
+ return true;
110
+ });
111
+ }
112
+ /**
113
+ * Match a tool name against a glob pattern
114
+ */
115
+ matchToolPattern(toolName, pattern) {
116
+ // Simple glob matching: * matches any characters
117
+ const regexPattern = pattern
118
+ .replace(/[.+?^${}()|[\]\\]/g, "\\$&") // Escape regex special chars
119
+ .replace(/\*/g, ".*"); // Convert * to .*
120
+ const regex = new RegExp(`^${regexPattern}$`);
121
+ return regex.test(toolName);
122
+ }
123
+ /**
124
+ * Execute hooks for an event
125
+ */
126
+ async executeHooks(event, input) {
127
+ const toolName = input.toolCall?.name;
128
+ const hooks = this.getHooksForEvent(event, toolName);
129
+ if (hooks.length === 0) {
130
+ return [];
131
+ }
132
+ // Execute all matching hooks in parallel
133
+ const results = await Promise.all(hooks.map((hook) => this.executeHook(hook, input)));
134
+ return results;
135
+ }
136
+ /**
137
+ * Execute a single hook
138
+ */
139
+ async executeHook(hook, input) {
140
+ const startTime = Date.now();
141
+ try {
142
+ if (hook.type === "command") {
143
+ return await this.executeCommandHook(hook, input);
144
+ }
145
+ else {
146
+ // Prompt hooks would require LLM integration
147
+ // For now, return a placeholder
148
+ return {
149
+ success: false,
150
+ error: "Prompt hooks not yet implemented",
151
+ durationMs: Date.now() - startTime,
152
+ };
153
+ }
154
+ }
155
+ catch (error) {
156
+ return {
157
+ success: false,
158
+ error: extractErrorMessage(error),
159
+ durationMs: Date.now() - startTime,
160
+ };
161
+ }
162
+ }
163
+ /**
164
+ * Execute a command hook
165
+ */
166
+ async executeCommandHook(hook, input) {
167
+ const startTime = Date.now();
168
+ const timeout = hook.timeout || DEFAULT_HOOK_TIMEOUT;
169
+ return new Promise((resolve) => {
170
+ const env = {
171
+ ...process.env,
172
+ ...hook.env,
173
+ AXCLI_PROJECT_DIR: input.projectDir,
174
+ AXCLI_EVENT: input.event,
175
+ AXCLI_HOOK_INPUT: JSON.stringify(input),
176
+ };
177
+ const child = spawn(hook.command, [], {
178
+ shell: true,
179
+ cwd: hook.cwd || input.projectDir,
180
+ env,
181
+ stdio: ["pipe", "pipe", "pipe"],
182
+ });
183
+ let stdout = "";
184
+ let stderr = "";
185
+ let timedOut = false;
186
+ // Send input as JSON to stdin
187
+ child.stdin.write(JSON.stringify(input));
188
+ child.stdin.end();
189
+ child.stdout.on("data", (data) => {
190
+ stdout += data.toString();
191
+ });
192
+ child.stderr.on("data", (data) => {
193
+ stderr += data.toString();
194
+ });
195
+ const timeoutId = setTimeout(() => {
196
+ timedOut = true;
197
+ child.kill("SIGTERM");
198
+ }, timeout);
199
+ child.on("close", (code) => {
200
+ clearTimeout(timeoutId);
201
+ if (timedOut) {
202
+ resolve({
203
+ success: false,
204
+ error: `Hook timed out after ${timeout}ms`,
205
+ durationMs: Date.now() - startTime,
206
+ });
207
+ return;
208
+ }
209
+ // Parse output for special fields
210
+ let output = {
211
+ exitCode: code || 0,
212
+ stdout: stdout.trim(),
213
+ stderr: stderr.trim(),
214
+ };
215
+ // Try to parse JSON output for structured response
216
+ try {
217
+ if (stdout.trim().startsWith("{")) {
218
+ const parsed = JSON.parse(stdout.trim());
219
+ if (parsed.permissionDecision) {
220
+ output.permissionDecision = parsed.permissionDecision;
221
+ }
222
+ if (parsed.updatedInput) {
223
+ output.updatedInput = parsed.updatedInput;
224
+ }
225
+ }
226
+ }
227
+ catch {
228
+ // Not JSON, use raw output
229
+ }
230
+ resolve({
231
+ success: code === 0,
232
+ output,
233
+ durationMs: Date.now() - startTime,
234
+ });
235
+ });
236
+ child.on("error", (error) => {
237
+ clearTimeout(timeoutId);
238
+ resolve({
239
+ success: false,
240
+ error: extractErrorMessage(error),
241
+ durationMs: Date.now() - startTime,
242
+ });
243
+ });
244
+ });
245
+ }
246
+ /**
247
+ * Check if any PreToolUse hook blocks the tool execution
248
+ */
249
+ async shouldBlockTool(toolName, toolArgs, toolId) {
250
+ const input = {
251
+ event: "PreToolUse",
252
+ projectDir: this.projectDir,
253
+ timestamp: new Date().toISOString(),
254
+ toolCall: {
255
+ name: toolName,
256
+ arguments: toolArgs,
257
+ id: toolId,
258
+ },
259
+ };
260
+ const results = await this.executeHooks("PreToolUse", input);
261
+ for (const result of results) {
262
+ if (!result.success) {
263
+ // Hook execution failed - treat as non-blocking but log
264
+ console.warn(`PreToolUse hook failed: ${result.error}`);
265
+ continue;
266
+ }
267
+ // Check for explicit denial
268
+ if (result.output?.permissionDecision === "deny") {
269
+ return {
270
+ blocked: true,
271
+ reason: result.output.stderr || result.output.stdout || "Blocked by hook",
272
+ };
273
+ }
274
+ // Exit code 2 means blocking error
275
+ if (result.output?.exitCode === 2) {
276
+ return {
277
+ blocked: true,
278
+ reason: result.output.stderr || result.output.stdout || "Blocked by hook",
279
+ };
280
+ }
281
+ }
282
+ return { blocked: false };
283
+ }
284
+ /**
285
+ * Process user input through UserPromptSubmit hooks
286
+ */
287
+ async processUserInput(userInput) {
288
+ const input = {
289
+ event: "UserPromptSubmit",
290
+ projectDir: this.projectDir,
291
+ timestamp: new Date().toISOString(),
292
+ userInput,
293
+ };
294
+ const results = await this.executeHooks("UserPromptSubmit", input);
295
+ // Check for modified input from any hook
296
+ for (const result of results) {
297
+ if (result.success && result.output?.updatedInput) {
298
+ return result.output.updatedInput;
299
+ }
300
+ }
301
+ return userInput;
302
+ }
303
+ /**
304
+ * Execute PostToolUse hooks (fire-and-forget)
305
+ */
306
+ async executePostToolHooks(toolName, toolArgs, toolId, toolResult) {
307
+ const input = {
308
+ event: "PostToolUse",
309
+ projectDir: this.projectDir,
310
+ timestamp: new Date().toISOString(),
311
+ toolCall: {
312
+ name: toolName,
313
+ arguments: toolArgs,
314
+ id: toolId,
315
+ },
316
+ toolResult,
317
+ };
318
+ // Execute hooks but don't wait for them
319
+ this.executeHooks("PostToolUse", input).catch((error) => {
320
+ console.warn("PostToolUse hook error:", extractErrorMessage(error));
321
+ });
322
+ }
323
+ /**
324
+ * Get the list of registered hooks
325
+ */
326
+ getHooks() {
327
+ this.ensureInitialized();
328
+ return [...this.hooks];
329
+ }
330
+ /**
331
+ * Clear all hooks
332
+ */
333
+ clearHooks() {
334
+ this.hooks = [];
335
+ this.initialized = false;
336
+ }
337
+ }
338
+ /**
339
+ * Get the singleton hooks manager instance
340
+ */
341
+ export function getHooksManager() {
342
+ return HooksManager.getInstance();
343
+ }
344
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/hooks/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Hooks System Types
3
+ *
4
+ * Event-driven hooks for customizing tool execution and user interaction.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import type { ToolResult } from "../types/index.js";
9
+ /**
10
+ * Hook event types
11
+ */
12
+ export type HookEventType = "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Notification" | "Stop";
13
+ /**
14
+ * Hook type - shell command or prompt-based
15
+ */
16
+ export type HookType = "command" | "prompt";
17
+ /**
18
+ * Hook decision for PreToolUse hooks
19
+ */
20
+ export interface HookDecision {
21
+ /** Whether to allow the tool execution */
22
+ allow: boolean;
23
+ /** Optional reason for blocking */
24
+ reason?: string;
25
+ /** Optional modified input (for UserPromptSubmit) */
26
+ modifiedInput?: string;
27
+ }
28
+ /**
29
+ * Base hook configuration
30
+ */
31
+ export interface HookConfig {
32
+ /** Unique identifier for this hook */
33
+ id?: string;
34
+ /** Event type that triggers this hook */
35
+ event: HookEventType;
36
+ /** Hook type: command (shell) or prompt (LLM evaluation) */
37
+ type: HookType;
38
+ /** Glob pattern to match tool names (for PreToolUse/PostToolUse) */
39
+ toolPattern?: string;
40
+ /** Whether this hook is enabled */
41
+ enabled?: boolean;
42
+ /** Timeout in milliseconds (default: 60000) */
43
+ timeout?: number;
44
+ }
45
+ /**
46
+ * Shell command hook configuration
47
+ */
48
+ export interface CommandHookConfig extends HookConfig {
49
+ type: "command";
50
+ /** Shell command to execute */
51
+ command: string;
52
+ /** Working directory for the command */
53
+ cwd?: string;
54
+ /** Environment variables to set */
55
+ env?: Record<string, string>;
56
+ }
57
+ /**
58
+ * Prompt-based hook configuration (uses Claude Haiku for evaluation)
59
+ */
60
+ export interface PromptHookConfig extends HookConfig {
61
+ type: "prompt";
62
+ /** Prompt template for LLM evaluation */
63
+ prompt: string;
64
+ /** Model to use (default: haiku for speed) */
65
+ model?: string;
66
+ }
67
+ /**
68
+ * Union type for all hook configurations
69
+ */
70
+ export type AnyHookConfig = CommandHookConfig | PromptHookConfig;
71
+ /**
72
+ * Hook input data passed to hook execution
73
+ */
74
+ export interface HookInput {
75
+ /** The event type */
76
+ event: HookEventType;
77
+ /** Session ID */
78
+ sessionId?: string;
79
+ /** Project directory */
80
+ projectDir: string;
81
+ /** Timestamp */
82
+ timestamp: string;
83
+ /** Tool call information (for PreToolUse/PostToolUse) */
84
+ toolCall?: {
85
+ name: string;
86
+ arguments: Record<string, unknown>;
87
+ id: string;
88
+ };
89
+ /** Tool result (for PostToolUse) */
90
+ toolResult?: ToolResult;
91
+ /** User input (for UserPromptSubmit) */
92
+ userInput?: string;
93
+ /** Notification message (for Notification) */
94
+ message?: string;
95
+ }
96
+ /**
97
+ * Hook output data returned from hook execution
98
+ */
99
+ export interface HookOutput {
100
+ /** Exit code (0 = success, 2 = blocking error) */
101
+ exitCode: number;
102
+ /** Standard output */
103
+ stdout?: string;
104
+ /** Standard error */
105
+ stderr?: string;
106
+ /** Permission decision (for PreToolUse) */
107
+ permissionDecision?: "allow" | "deny";
108
+ /** Updated input (for UserPromptSubmit) */
109
+ updatedInput?: string;
110
+ /** Error message */
111
+ error?: string;
112
+ }
113
+ /**
114
+ * Hooks configuration file structure
115
+ */
116
+ export interface HooksConfig {
117
+ /** Version of the hooks config schema */
118
+ version?: string;
119
+ /** Array of hook configurations */
120
+ hooks: AnyHookConfig[];
121
+ }
122
+ /**
123
+ * Hook execution result
124
+ */
125
+ export interface HookExecutionResult {
126
+ /** Whether the hook executed successfully */
127
+ success: boolean;
128
+ /** Hook output */
129
+ output?: HookOutput;
130
+ /** Error if execution failed */
131
+ error?: string;
132
+ /** Execution duration in milliseconds */
133
+ durationMs?: number;
134
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Hooks System Types
3
+ *
4
+ * Event-driven hooks for customizing tool execution and user interaction.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/hooks/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
package/dist/llm/tools.js CHANGED
@@ -369,6 +369,59 @@ const BASE_LLM_TOOLS = [
369
369
  },
370
370
  },
371
371
  },
372
+ {
373
+ type: "function",
374
+ function: {
375
+ name: "ask_user",
376
+ description: "Ask the user questions to gather preferences, clarify requirements, or get decisions on implementation choices. Use this when you need user input before proceeding. Supports multiple choice questions with 2-4 options per question.",
377
+ parameters: {
378
+ type: "object",
379
+ properties: {
380
+ questions: {
381
+ type: "array",
382
+ description: "Questions to ask the user (1-4 questions)",
383
+ items: {
384
+ type: "object",
385
+ properties: {
386
+ question: {
387
+ type: "string",
388
+ description: "The complete question to ask the user. Should be clear and specific.",
389
+ },
390
+ header: {
391
+ type: "string",
392
+ description: "Short label for the question (max 12 chars). E.g., 'Auth method', 'Library'.",
393
+ },
394
+ options: {
395
+ type: "array",
396
+ description: "Available choices (2-4 options). 'Other' is added automatically.",
397
+ items: {
398
+ type: "object",
399
+ properties: {
400
+ label: {
401
+ type: "string",
402
+ description: "Display text for this option (1-5 words).",
403
+ },
404
+ description: {
405
+ type: "string",
406
+ description: "Explanation of what this option means.",
407
+ },
408
+ },
409
+ required: ["label", "description"],
410
+ },
411
+ },
412
+ multiSelect: {
413
+ type: "boolean",
414
+ description: "Allow multiple selections (default: false).",
415
+ },
416
+ },
417
+ required: ["question", "options"],
418
+ },
419
+ },
420
+ },
421
+ required: ["questions"],
422
+ },
423
+ },
424
+ },
372
425
  ];
373
426
  /**
374
427
  * Exported tool definitions