gencode-ai 0.1.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.
Files changed (274) hide show
  1. package/.env.example +11 -0
  2. package/CLAUDE.md +70 -0
  3. package/LICENSE +21 -0
  4. package/README.md +117 -0
  5. package/dist/agent/agent.d.ts +84 -0
  6. package/dist/agent/agent.d.ts.map +1 -0
  7. package/dist/agent/agent.js +233 -0
  8. package/dist/agent/agent.js.map +1 -0
  9. package/dist/agent/index.d.ts +6 -0
  10. package/dist/agent/index.d.ts.map +1 -0
  11. package/dist/agent/index.js +6 -0
  12. package/dist/agent/index.js.map +1 -0
  13. package/dist/agent/types.d.ts +47 -0
  14. package/dist/agent/types.d.ts.map +1 -0
  15. package/dist/agent/types.js +5 -0
  16. package/dist/agent/types.js.map +1 -0
  17. package/dist/cli/components/App.d.ts +14 -0
  18. package/dist/cli/components/App.d.ts.map +1 -0
  19. package/dist/cli/components/App.js +395 -0
  20. package/dist/cli/components/App.js.map +1 -0
  21. package/dist/cli/components/CommandSuggestions.d.ts +13 -0
  22. package/dist/cli/components/CommandSuggestions.d.ts.map +1 -0
  23. package/dist/cli/components/CommandSuggestions.js +32 -0
  24. package/dist/cli/components/CommandSuggestions.js.map +1 -0
  25. package/dist/cli/components/Header.d.ts +9 -0
  26. package/dist/cli/components/Header.d.ts.map +1 -0
  27. package/dist/cli/components/Header.js +13 -0
  28. package/dist/cli/components/Header.js.map +1 -0
  29. package/dist/cli/components/Input.d.ts +13 -0
  30. package/dist/cli/components/Input.d.ts.map +1 -0
  31. package/dist/cli/components/Input.js +27 -0
  32. package/dist/cli/components/Input.js.map +1 -0
  33. package/dist/cli/components/Logo.d.ts +2 -0
  34. package/dist/cli/components/Logo.d.ts.map +1 -0
  35. package/dist/cli/components/Logo.js +8 -0
  36. package/dist/cli/components/Logo.js.map +1 -0
  37. package/dist/cli/components/Messages.d.ts +37 -0
  38. package/dist/cli/components/Messages.d.ts.map +1 -0
  39. package/dist/cli/components/Messages.js +106 -0
  40. package/dist/cli/components/Messages.js.map +1 -0
  41. package/dist/cli/components/ModelSelector.d.ts +13 -0
  42. package/dist/cli/components/ModelSelector.d.ts.map +1 -0
  43. package/dist/cli/components/ModelSelector.js +72 -0
  44. package/dist/cli/components/ModelSelector.js.map +1 -0
  45. package/dist/cli/components/Spinner.d.ts +12 -0
  46. package/dist/cli/components/Spinner.d.ts.map +1 -0
  47. package/dist/cli/components/Spinner.js +45 -0
  48. package/dist/cli/components/Spinner.js.map +1 -0
  49. package/dist/cli/components/index.d.ts +12 -0
  50. package/dist/cli/components/index.d.ts.map +1 -0
  51. package/dist/cli/components/index.js +12 -0
  52. package/dist/cli/components/index.js.map +1 -0
  53. package/dist/cli/components/theme.d.ts +31 -0
  54. package/dist/cli/components/theme.d.ts.map +1 -0
  55. package/dist/cli/components/theme.js +36 -0
  56. package/dist/cli/components/theme.js.map +1 -0
  57. package/dist/cli/index-legacy.d.ts +7 -0
  58. package/dist/cli/index-legacy.d.ts.map +1 -0
  59. package/dist/cli/index-legacy.js +431 -0
  60. package/dist/cli/index-legacy.js.map +1 -0
  61. package/dist/cli/index.d.ts +7 -0
  62. package/dist/cli/index.d.ts.map +1 -0
  63. package/dist/cli/index.js +116 -0
  64. package/dist/cli/index.js.map +1 -0
  65. package/dist/cli/ink-cli.d.ts +7 -0
  66. package/dist/cli/ink-cli.d.ts.map +1 -0
  67. package/dist/cli/ink-cli.js +105 -0
  68. package/dist/cli/ink-cli.js.map +1 -0
  69. package/dist/cli/session-picker.d.ts +16 -0
  70. package/dist/cli/session-picker.d.ts.map +1 -0
  71. package/dist/cli/session-picker.js +280 -0
  72. package/dist/cli/session-picker.js.map +1 -0
  73. package/dist/cli/ui.d.ts +61 -0
  74. package/dist/cli/ui.d.ts.map +1 -0
  75. package/dist/cli/ui.js +364 -0
  76. package/dist/cli/ui.js.map +1 -0
  77. package/dist/config/index.d.ts +7 -0
  78. package/dist/config/index.d.ts.map +1 -0
  79. package/dist/config/index.js +6 -0
  80. package/dist/config/index.js.map +1 -0
  81. package/dist/config/manager.d.ts +31 -0
  82. package/dist/config/manager.d.ts.map +1 -0
  83. package/dist/config/manager.js +65 -0
  84. package/dist/config/manager.js.map +1 -0
  85. package/dist/config/types.d.ts +22 -0
  86. package/dist/config/types.d.ts.map +1 -0
  87. package/dist/config/types.js +6 -0
  88. package/dist/config/types.js.map +1 -0
  89. package/dist/index.d.ts +12 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +21 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/memory/index.d.ts +10 -0
  94. package/dist/memory/index.d.ts.map +1 -0
  95. package/dist/memory/index.js +9 -0
  96. package/dist/memory/index.js.map +1 -0
  97. package/dist/memory/init.d.ts +20 -0
  98. package/dist/memory/init.d.ts.map +1 -0
  99. package/dist/memory/init.js +332 -0
  100. package/dist/memory/init.js.map +1 -0
  101. package/dist/memory/manager.d.ts +85 -0
  102. package/dist/memory/manager.d.ts.map +1 -0
  103. package/dist/memory/manager.js +234 -0
  104. package/dist/memory/manager.js.map +1 -0
  105. package/dist/memory/types.d.ts +74 -0
  106. package/dist/memory/types.d.ts.map +1 -0
  107. package/dist/memory/types.js +6 -0
  108. package/dist/memory/types.js.map +1 -0
  109. package/dist/permissions/index.d.ts +7 -0
  110. package/dist/permissions/index.d.ts.map +1 -0
  111. package/dist/permissions/index.js +6 -0
  112. package/dist/permissions/index.js.map +1 -0
  113. package/dist/permissions/manager.d.ts +32 -0
  114. package/dist/permissions/manager.d.ts.map +1 -0
  115. package/dist/permissions/manager.js +79 -0
  116. package/dist/permissions/manager.js.map +1 -0
  117. package/dist/permissions/types.d.ts +14 -0
  118. package/dist/permissions/types.d.ts.map +1 -0
  119. package/dist/permissions/types.js +17 -0
  120. package/dist/permissions/types.js.map +1 -0
  121. package/dist/providers/anthropic.d.ts +20 -0
  122. package/dist/providers/anthropic.d.ts.map +1 -0
  123. package/dist/providers/anthropic.js +185 -0
  124. package/dist/providers/anthropic.js.map +1 -0
  125. package/dist/providers/gemini.d.ts +21 -0
  126. package/dist/providers/gemini.d.ts.map +1 -0
  127. package/dist/providers/gemini.js +241 -0
  128. package/dist/providers/gemini.js.map +1 -0
  129. package/dist/providers/index.d.ts +34 -0
  130. package/dist/providers/index.d.ts.map +1 -0
  131. package/dist/providers/index.js +72 -0
  132. package/dist/providers/index.js.map +1 -0
  133. package/dist/providers/openai.d.ts +19 -0
  134. package/dist/providers/openai.d.ts.map +1 -0
  135. package/dist/providers/openai.js +221 -0
  136. package/dist/providers/openai.js.map +1 -0
  137. package/dist/providers/types.d.ts +125 -0
  138. package/dist/providers/types.d.ts.map +1 -0
  139. package/dist/providers/types.js +6 -0
  140. package/dist/providers/types.js.map +1 -0
  141. package/dist/session/index.d.ts +6 -0
  142. package/dist/session/index.d.ts.map +1 -0
  143. package/dist/session/index.js +6 -0
  144. package/dist/session/index.js.map +1 -0
  145. package/dist/session/manager.d.ts +101 -0
  146. package/dist/session/manager.d.ts.map +1 -0
  147. package/dist/session/manager.js +295 -0
  148. package/dist/session/manager.js.map +1 -0
  149. package/dist/session/types.d.ts +39 -0
  150. package/dist/session/types.d.ts.map +1 -0
  151. package/dist/session/types.js +10 -0
  152. package/dist/session/types.js.map +1 -0
  153. package/dist/tools/builtin/bash.d.ts +7 -0
  154. package/dist/tools/builtin/bash.d.ts.map +1 -0
  155. package/dist/tools/builtin/bash.js +80 -0
  156. package/dist/tools/builtin/bash.js.map +1 -0
  157. package/dist/tools/builtin/edit.d.ts +7 -0
  158. package/dist/tools/builtin/edit.d.ts.map +1 -0
  159. package/dist/tools/builtin/edit.js +32 -0
  160. package/dist/tools/builtin/edit.js.map +1 -0
  161. package/dist/tools/builtin/glob.d.ts +7 -0
  162. package/dist/tools/builtin/glob.d.ts.map +1 -0
  163. package/dist/tools/builtin/glob.js +36 -0
  164. package/dist/tools/builtin/glob.js.map +1 -0
  165. package/dist/tools/builtin/grep.d.ts +7 -0
  166. package/dist/tools/builtin/grep.d.ts.map +1 -0
  167. package/dist/tools/builtin/grep.js +59 -0
  168. package/dist/tools/builtin/grep.js.map +1 -0
  169. package/dist/tools/builtin/read.d.ts +7 -0
  170. package/dist/tools/builtin/read.d.ts.map +1 -0
  171. package/dist/tools/builtin/read.js +29 -0
  172. package/dist/tools/builtin/read.js.map +1 -0
  173. package/dist/tools/builtin/write.d.ts +7 -0
  174. package/dist/tools/builtin/write.d.ts.map +1 -0
  175. package/dist/tools/builtin/write.js +24 -0
  176. package/dist/tools/builtin/write.js.map +1 -0
  177. package/dist/tools/index.d.ts +38 -0
  178. package/dist/tools/index.d.ts.map +1 -0
  179. package/dist/tools/index.js +32 -0
  180. package/dist/tools/index.js.map +1 -0
  181. package/dist/tools/registry.d.ts +22 -0
  182. package/dist/tools/registry.d.ts.map +1 -0
  183. package/dist/tools/registry.js +71 -0
  184. package/dist/tools/registry.js.map +1 -0
  185. package/dist/tools/types.d.ts +62 -0
  186. package/dist/tools/types.d.ts.map +1 -0
  187. package/dist/tools/types.js +126 -0
  188. package/dist/tools/types.js.map +1 -0
  189. package/docs/README.md +16 -0
  190. package/docs/proposals/0001-web-fetch-tool.md +293 -0
  191. package/docs/proposals/0002-web-search-tool.md +306 -0
  192. package/docs/proposals/0003-task-subagents.md +333 -0
  193. package/docs/proposals/0004-plan-mode.md +338 -0
  194. package/docs/proposals/0005-todo-system.md +299 -0
  195. package/docs/proposals/0006-memory-system.md +539 -0
  196. package/docs/proposals/0007-context-management.md +429 -0
  197. package/docs/proposals/0008-checkpointing.md +327 -0
  198. package/docs/proposals/0009-hooks-system.md +343 -0
  199. package/docs/proposals/0010-mcp-integration.md +382 -0
  200. package/docs/proposals/0011-custom-commands.md +374 -0
  201. package/docs/proposals/0012-ask-user-question.md +317 -0
  202. package/docs/proposals/0013-multi-edit-tool.md +345 -0
  203. package/docs/proposals/0014-lsp-tool.md +478 -0
  204. package/docs/proposals/0015-ls-tool.md +407 -0
  205. package/docs/proposals/0016-kill-shell-tool.md +455 -0
  206. package/docs/proposals/0017-background-tasks.md +489 -0
  207. package/docs/proposals/0018-parallel-tool-execution.md +415 -0
  208. package/docs/proposals/0019-session-enhancements.md +462 -0
  209. package/docs/proposals/0020-session-summarization.md +447 -0
  210. package/docs/proposals/0021-skills-system.md +409 -0
  211. package/docs/proposals/0022-plugin-system.md +467 -0
  212. package/docs/proposals/0023-permission-enhancements.md +470 -0
  213. package/docs/proposals/0024-keyboard-shortcuts.md +443 -0
  214. package/docs/proposals/0025-cost-tracking.md +447 -0
  215. package/docs/proposals/0026-git-integration.md +475 -0
  216. package/docs/proposals/0027-enhanced-read-tool.md +514 -0
  217. package/docs/proposals/0028-enhanced-bash-tool.md +511 -0
  218. package/docs/proposals/0029-notebook-edit-tool.md +413 -0
  219. package/docs/proposals/0030-plugin-marketplace.md +360 -0
  220. package/docs/proposals/0031-command-suggestions.md +295 -0
  221. package/docs/proposals/0032-ide-integrations.md +328 -0
  222. package/docs/proposals/0033-enterprise-deployment.md +221 -0
  223. package/docs/proposals/0034-sandboxing.md +273 -0
  224. package/docs/proposals/0035-auto-updater.md +311 -0
  225. package/docs/proposals/0036-enhanced-glob-tool.md +267 -0
  226. package/docs/proposals/0037-enhanced-grep-tool.md +360 -0
  227. package/docs/proposals/0038-interactive-cli-ui.md +373 -0
  228. package/docs/proposals/0039-streaming-enhancements.md +359 -0
  229. package/docs/proposals/0040-multi-provider-enhancements.md +369 -0
  230. package/docs/proposals/README.md +84 -0
  231. package/docs/proposals/TEMPLATE.md +57 -0
  232. package/docs/proposals/research/claude-code-research.md +307 -0
  233. package/examples/agent-demo.ts +115 -0
  234. package/examples/basic.ts +166 -0
  235. package/package.json +50 -0
  236. package/src/agent/agent.ts +276 -0
  237. package/src/agent/index.ts +6 -0
  238. package/src/agent/types.ts +62 -0
  239. package/src/cli/components/App.tsx +565 -0
  240. package/src/cli/components/CommandSuggestions.tsx +58 -0
  241. package/src/cli/components/Header.tsx +36 -0
  242. package/src/cli/components/Input.tsx +60 -0
  243. package/src/cli/components/Logo.tsx +16 -0
  244. package/src/cli/components/Messages.tsx +210 -0
  245. package/src/cli/components/ModelSelector.tsx +135 -0
  246. package/src/cli/components/Spinner.tsx +72 -0
  247. package/src/cli/components/index.ts +21 -0
  248. package/src/cli/components/theme.ts +36 -0
  249. package/src/cli/index.tsx +136 -0
  250. package/src/config/index.ts +7 -0
  251. package/src/config/manager.ts +77 -0
  252. package/src/config/types.ts +25 -0
  253. package/src/index.ts +86 -0
  254. package/src/permissions/index.ts +7 -0
  255. package/src/permissions/manager.ts +97 -0
  256. package/src/permissions/types.ts +29 -0
  257. package/src/providers/anthropic.ts +224 -0
  258. package/src/providers/gemini.ts +295 -0
  259. package/src/providers/index.ts +97 -0
  260. package/src/providers/openai.ts +261 -0
  261. package/src/providers/types.ts +181 -0
  262. package/src/session/index.ts +6 -0
  263. package/src/session/manager.ts +354 -0
  264. package/src/session/types.ts +49 -0
  265. package/src/tools/builtin/bash.ts +92 -0
  266. package/src/tools/builtin/edit.ts +37 -0
  267. package/src/tools/builtin/glob.ts +42 -0
  268. package/src/tools/builtin/grep.ts +67 -0
  269. package/src/tools/builtin/read.ts +34 -0
  270. package/src/tools/builtin/write.ts +27 -0
  271. package/src/tools/index.ts +36 -0
  272. package/src/tools/registry.ts +83 -0
  273. package/src/tools/types.ts +172 -0
  274. package/tsconfig.json +21 -0
@@ -0,0 +1,374 @@
1
+ # Proposal: Custom Commands (Slash Commands)
2
+
3
+ - **Proposal ID**: 0011
4
+ - **Author**: mycode team
5
+ - **Status**: Draft
6
+ - **Created**: 2025-01-15
7
+ - **Updated**: 2025-01-15
8
+
9
+ ## Summary
10
+
11
+ Implement a custom commands system that allows users to define reusable prompt templates as slash commands. Commands are stored as markdown files in `.mycode/commands/` and can accept arguments, making common workflows easily accessible.
12
+
13
+ ## Motivation
14
+
15
+ Currently, users must re-type common prompts. This leads to:
16
+
17
+ 1. **Repetition**: Same prompts typed repeatedly
18
+ 2. **Inconsistency**: Variations in how tasks are requested
19
+ 3. **No sharing**: Can't share workflows with team
20
+ 4. **No organization**: Common tasks not documented
21
+ 5. **Slow workflows**: Complex prompts take time to compose
22
+
23
+ Custom commands enable one-command access to common workflows.
24
+
25
+ ## Claude Code Reference
26
+
27
+ Claude Code provides a powerful slash command system:
28
+
29
+ ### Command Definition
30
+ ```markdown
31
+ <!-- .claude/commands/fix-issue.md -->
32
+ ---
33
+ description: Fix a GitHub issue
34
+ argument-hint: <issue-number>
35
+ allowed-tools: Bash(gh:*), Read, Edit, Write
36
+ ---
37
+
38
+ # Fix GitHub Issue
39
+
40
+ Fetch issue $ARGUMENTS from GitHub and implement a fix:
41
+
42
+ 1. Read the issue details using `gh issue view $ARGUMENTS`
43
+ 2. Understand the problem and find relevant code
44
+ 3. Implement the fix
45
+ 4. Create a commit with descriptive message
46
+ 5. Push the changes
47
+ ```
48
+
49
+ ### Usage
50
+ ```
51
+ > /fix-issue 123
52
+
53
+ Agent: [Reads issue #123, implements fix, commits, pushes]
54
+ ```
55
+
56
+ ### Features
57
+ - Markdown files with YAML frontmatter
58
+ - `$ARGUMENTS` for user input
59
+ - `$1`, `$2` for positional arguments
60
+ - `@file` syntax for file inclusion
61
+ - `allowed-tools` for pre-authorized tools
62
+ - Project and user-level commands
63
+
64
+ ### Command Locations
65
+ - `~/.mycode/commands/` - User commands (all projects)
66
+ - `.mycode/commands/` - Project commands
67
+
68
+ ### Built-in Variables
69
+ - `$ARGUMENTS` - All arguments as string
70
+ - `$1`, `$2`, etc. - Positional arguments
71
+ - `@path/to/file` - Include file content
72
+
73
+ ## Detailed Design
74
+
75
+ ### API Design
76
+
77
+ ```typescript
78
+ // src/commands/types.ts
79
+ interface CommandDefinition {
80
+ name: string; // Command name (from filename)
81
+ description?: string; // Short description
82
+ argumentHint?: string; // Usage hint for arguments
83
+ allowedTools?: string[]; // Pre-authorized tools
84
+ content: string; // Prompt template
85
+ filePath: string; // Source file path
86
+ scope: 'user' | 'project'; // Command scope
87
+ }
88
+
89
+ interface CommandInput {
90
+ command: string; // Command name
91
+ arguments: string; // Raw argument string
92
+ }
93
+
94
+ interface ParsedCommand {
95
+ definition: CommandDefinition;
96
+ expandedPrompt: string; // Template with variables filled
97
+ preAuthorizedTools: string[];
98
+ }
99
+ ```
100
+
101
+ ```typescript
102
+ // src/commands/command-manager.ts
103
+ class CommandManager {
104
+ private commands: Map<string, CommandDefinition>;
105
+ private userDir: string;
106
+ private projectDir: string;
107
+
108
+ constructor(projectDir: string);
109
+
110
+ // Load commands from directories
111
+ async loadCommands(): Promise<void>;
112
+
113
+ // Get all available commands
114
+ listCommands(): CommandDefinition[];
115
+
116
+ // Check if command exists
117
+ hasCommand(name: string): boolean;
118
+
119
+ // Parse and expand a command
120
+ parseCommand(input: CommandInput): ParsedCommand;
121
+
122
+ // Get command by name
123
+ getCommand(name: string): CommandDefinition | undefined;
124
+
125
+ // Reload commands
126
+ async refresh(): Promise<void>;
127
+ }
128
+ ```
129
+
130
+ ### Command Parsing
131
+
132
+ ```typescript
133
+ // src/commands/parser.ts
134
+ interface CommandFrontmatter {
135
+ description?: string;
136
+ 'argument-hint'?: string;
137
+ 'allowed-tools'?: string | string[];
138
+ }
139
+
140
+ function parseCommandFile(filePath: string, content: string): CommandDefinition {
141
+ // Parse YAML frontmatter
142
+ const { frontmatter, body } = parseFrontmatter(content);
143
+
144
+ // Extract name from filename
145
+ const name = path.basename(filePath, '.md');
146
+
147
+ return {
148
+ name,
149
+ description: frontmatter.description,
150
+ argumentHint: frontmatter['argument-hint'],
151
+ allowedTools: normalizeAllowedTools(frontmatter['allowed-tools']),
152
+ content: body,
153
+ filePath,
154
+ scope: filePath.includes('~/.mycode') ? 'user' : 'project'
155
+ };
156
+ }
157
+
158
+ function expandTemplate(template: string, args: string): string {
159
+ // Split arguments
160
+ const argList = parseArguments(args);
161
+
162
+ let result = template;
163
+
164
+ // Replace $ARGUMENTS with full string
165
+ result = result.replace(/\$ARGUMENTS/g, args);
166
+
167
+ // Replace positional $1, $2, etc.
168
+ for (let i = 0; i < argList.length; i++) {
169
+ result = result.replace(new RegExp(`\\$${i + 1}`, 'g'), argList[i]);
170
+ }
171
+
172
+ // Handle @file includes
173
+ result = expandFileIncludes(result);
174
+
175
+ return result;
176
+ }
177
+ ```
178
+
179
+ ### Tool Pre-Authorization
180
+
181
+ ```typescript
182
+ // Parse allowed-tools patterns
183
+ function normalizeAllowedTools(tools: string | string[] | undefined): string[] {
184
+ if (!tools) return [];
185
+ if (typeof tools === 'string') {
186
+ return tools.split(',').map(t => t.trim());
187
+ }
188
+ return tools;
189
+ }
190
+
191
+ // Examples:
192
+ // "Bash(npm:*)" - Allow npm commands
193
+ // "Bash(gh:*)" - Allow GitHub CLI
194
+ // "Read, Write" - Allow Read and Write tools
195
+ // "Bash(mkdir:*), Bash(tee:*)" - Multiple Bash patterns
196
+ ```
197
+
198
+ ### File Changes
199
+
200
+ | File | Action | Description |
201
+ |------|--------|-------------|
202
+ | `src/commands/types.ts` | Create | Command type definitions |
203
+ | `src/commands/command-manager.ts` | Create | Command loading and management |
204
+ | `src/commands/parser.ts` | Create | Markdown/frontmatter parsing |
205
+ | `src/commands/expander.ts` | Create | Template expansion |
206
+ | `src/commands/index.ts` | Create | Module exports |
207
+ | `src/cli/input-handler.ts` | Modify | Handle slash command input |
208
+ | `src/permissions/permission-manager.ts` | Modify | Pre-authorize tools |
209
+
210
+ ## User Experience
211
+
212
+ ### Creating a Command
213
+ Create `.mycode/commands/review-pr.md`:
214
+
215
+ ```markdown
216
+ ---
217
+ description: Review a GitHub pull request
218
+ argument-hint: <pr-number>
219
+ allowed-tools: Bash(gh:*), Read, Grep
220
+ ---
221
+
222
+ # Review Pull Request
223
+
224
+ Review PR #$ARGUMENTS:
225
+
226
+ 1. Fetch PR details: `gh pr view $ARGUMENTS`
227
+ 2. Get the diff: `gh pr diff $ARGUMENTS`
228
+ 3. Review code changes for:
229
+ - Code quality issues
230
+ - Potential bugs
231
+ - Style violations
232
+ 4. Provide a summary with actionable feedback
233
+ ```
234
+
235
+ ### Using Commands
236
+ ```
237
+ > /review-pr 42
238
+
239
+ Agent: I'll review PR #42 for you.
240
+ [Fetches PR, analyzes diff, provides feedback]
241
+ ```
242
+
243
+ ### Listing Commands
244
+ ```
245
+ > /help
246
+
247
+ Available Commands:
248
+ ┌───────────────┬────────────────────────────────────────┐
249
+ │ Command │ Description │
250
+ ├───────────────┼────────────────────────────────────────┤
251
+ │ /fix-issue │ Fix a GitHub issue │
252
+ │ /review-pr │ Review a GitHub pull request │
253
+ │ /create-test │ Create unit tests for a file │
254
+ │ /summarize │ Summarize a file or directory │
255
+ └───────────────┴────────────────────────────────────────┘
256
+
257
+ Project commands: .mycode/commands/
258
+ User commands: ~/.mycode/commands/
259
+ ```
260
+
261
+ ### Command with Multiple Arguments
262
+ ```markdown
263
+ ---
264
+ description: Create a component
265
+ argument-hint: <name> <type>
266
+ ---
267
+
268
+ Create a $2 component named $1:
269
+ - File: src/components/$1.$2
270
+ - Include tests
271
+ - Follow project conventions
272
+ ```
273
+
274
+ ```
275
+ > /create-component Button tsx
276
+
277
+ Agent: Creating a tsx component named Button...
278
+ ```
279
+
280
+ ### File Inclusion
281
+ ```markdown
282
+ ---
283
+ description: Apply coding standards
284
+ ---
285
+
286
+ Apply these coding standards to the codebase:
287
+
288
+ @.mycode/standards.md
289
+
290
+ Focus on the most critical violations first.
291
+ ```
292
+
293
+ ## Alternatives Considered
294
+
295
+ ### Alternative 1: JSON Command Format
296
+ Define commands in JSON files.
297
+
298
+ **Pros**: Structured, easier to parse
299
+ **Cons**: Less readable, harder to write prompts
300
+ **Decision**: Rejected - Markdown is more natural
301
+
302
+ ### Alternative 2: Inline Command Definition
303
+ Define commands within settings.json.
304
+
305
+ **Pros**: Single config file
306
+ **Cons**: Hard to manage many commands, no syntax highlighting
307
+ **Decision**: Rejected - Separate files are more manageable
308
+
309
+ ### Alternative 3: JavaScript Commands
310
+ Write commands as JS/TS modules.
311
+
312
+ **Pros**: Full programmability
313
+ **Cons**: Security concerns, higher barrier to entry
314
+ **Decision**: Deferred - Start with templates, add later
315
+
316
+ ## Security Considerations
317
+
318
+ 1. **Tool Restrictions**: Pre-authorized tools respect permission system
319
+ 2. **File Inclusion**: Only allow including files within project
320
+ 3. **Argument Sanitization**: Sanitize arguments before expansion
321
+ 4. **Path Traversal**: Prevent `@../../../etc/passwd`
322
+ 5. **Execution Scope**: Commands run with normal permissions
323
+
324
+ ```typescript
325
+ // Safe file inclusion
326
+ function expandFileIncludes(content: string, projectRoot: string): string {
327
+ return content.replace(/@([^\s]+)/g, (match, filePath) => {
328
+ const absolutePath = path.resolve(projectRoot, filePath);
329
+
330
+ // Prevent path traversal
331
+ if (!absolutePath.startsWith(projectRoot)) {
332
+ return `[Error: Cannot include files outside project]`;
333
+ }
334
+
335
+ if (fs.existsSync(absolutePath)) {
336
+ return fs.readFileSync(absolutePath, 'utf-8');
337
+ }
338
+ return `[File not found: ${filePath}]`;
339
+ });
340
+ }
341
+ ```
342
+
343
+ ## Testing Strategy
344
+
345
+ 1. **Unit Tests**:
346
+ - Frontmatter parsing
347
+ - Argument expansion
348
+ - File inclusion
349
+
350
+ 2. **Integration Tests**:
351
+ - Command loading
352
+ - Command execution
353
+ - Pre-authorization
354
+
355
+ 3. **Manual Testing**:
356
+ - Various command formats
357
+ - Argument edge cases
358
+ - File inclusion
359
+
360
+ ## Migration Path
361
+
362
+ 1. **Phase 1**: Basic command loading and execution
363
+ 2. **Phase 2**: Argument expansion ($ARGUMENTS, $1, $2)
364
+ 3. **Phase 3**: File inclusion (@file)
365
+ 4. **Phase 4**: Tool pre-authorization
366
+ 5. **Phase 5**: /help command and discoverability
367
+
368
+ No breaking changes to existing functionality.
369
+
370
+ ## References
371
+
372
+ - [Claude Code Commands Documentation](https://code.claude.com/docs/en/commands)
373
+ - [Claude Code Plugins Reference](https://code.claude.com/docs/en/plugins-reference)
374
+ - [YAML Frontmatter Specification](https://jekyllrb.com/docs/front-matter/)
@@ -0,0 +1,317 @@
1
+ # Proposal: AskUserQuestion Tool
2
+
3
+ - **Proposal ID**: 0012
4
+ - **Author**: mycode team
5
+ - **Status**: Draft
6
+ - **Created**: 2025-01-15
7
+ - **Updated**: 2025-01-15
8
+
9
+ ## Summary
10
+
11
+ Implement an AskUserQuestion tool that allows the agent to pause execution and present structured questions to the user with predefined options. This enables gathering user preferences, clarifying ambiguous instructions, and making decisions during task execution.
12
+
13
+ ## Motivation
14
+
15
+ Currently, mycode has no structured way for the agent to ask clarifying questions. This leads to:
16
+
17
+ 1. **Assumptions**: Agent guesses when requirements are unclear
18
+ 2. **Wasted work**: Wrong assumptions lead to redoing work
19
+ 3. **Poor UX**: Unstructured questions mixed with output
20
+ 4. **No multi-select**: Can't gather multiple preferences at once
21
+ 5. **No defaults**: Can't recommend options to users
22
+
23
+ A structured question tool enables clear, efficient user interaction.
24
+
25
+ ## Claude Code Reference
26
+
27
+ Claude Code's AskUserQuestion tool provides rich interactive questioning:
28
+
29
+ ### Tool Definition
30
+ ```typescript
31
+ AskUserQuestion({
32
+ questions: [
33
+ {
34
+ question: "Which database should we use?",
35
+ header: "Database", // Short label (max 12 chars)
36
+ options: [
37
+ { label: "PostgreSQL (Recommended)", description: "Relational DB with rich features" },
38
+ { label: "MongoDB", description: "Document-based NoSQL database" },
39
+ { label: "SQLite", description: "Lightweight embedded database" }
40
+ ],
41
+ multiSelect: false
42
+ }
43
+ ]
44
+ })
45
+ ```
46
+
47
+ ### Key Features
48
+ - 1-4 questions per invocation
49
+ - 2-4 options per question
50
+ - Automatic "Other" option for custom input
51
+ - Multi-select support
52
+ - Short headers for chips/tags
53
+ - Descriptions for each option
54
+ - Recommended options (first position + label suffix)
55
+
56
+ ### Example Usage
57
+ ```
58
+ Agent: Before implementing authentication, I need to clarify some details.
59
+
60
+ [AskUserQuestion:
61
+ Q1: "Which authentication method should we use?"
62
+ - OAuth 2.0 (Recommended) - Industry standard, supports social login
63
+ - JWT - Stateless tokens, good for APIs
64
+ - Session-based - Traditional cookie sessions
65
+
66
+ Q2: "Which user storage should we use?"
67
+ - PostgreSQL (Recommended) - Your existing database
68
+ - Firebase Auth - Managed auth service
69
+ ]
70
+
71
+ User selects: OAuth 2.0, PostgreSQL
72
+
73
+ Agent: Great! I'll implement OAuth 2.0 authentication with PostgreSQL storage.
74
+ ```
75
+
76
+ ## Detailed Design
77
+
78
+ ### API Design
79
+
80
+ ```typescript
81
+ // src/tools/ask-user/types.ts
82
+ interface QuestionOption {
83
+ label: string; // Display text (1-5 words)
84
+ description: string; // Explanation of the option
85
+ }
86
+
87
+ interface Question {
88
+ question: string; // The question to ask
89
+ header: string; // Short label (max 12 chars)
90
+ options: QuestionOption[]; // 2-4 options
91
+ multiSelect: boolean; // Allow multiple selections
92
+ }
93
+
94
+ interface AskUserQuestionInput {
95
+ questions: Question[]; // 1-4 questions
96
+ }
97
+
98
+ interface QuestionAnswer {
99
+ question: string;
100
+ selectedOptions: string[]; // Labels of selected options
101
+ customInput?: string; // If "Other" was selected
102
+ }
103
+
104
+ interface AskUserQuestionOutput {
105
+ answers: QuestionAnswer[];
106
+ }
107
+ ```
108
+
109
+ ```typescript
110
+ // src/tools/ask-user/ask-user-tool.ts
111
+ const askUserQuestionTool: Tool<AskUserQuestionInput> = {
112
+ name: 'AskUserQuestion',
113
+ description: `Ask the user structured questions during execution.
114
+
115
+ Use this tool when you need to:
116
+ 1. Gather user preferences or requirements
117
+ 2. Clarify ambiguous instructions
118
+ 3. Get decisions on implementation choices
119
+ 4. Offer choices about direction
120
+
121
+ Guidelines:
122
+ - Use multiSelect: true for non-mutually-exclusive options
123
+ - Put recommended option first with "(Recommended)" suffix
124
+ - Keep headers short (max 12 chars)
125
+ - Users can always select "Other" for custom input
126
+ `,
127
+ parameters: z.object({
128
+ questions: z.array(z.object({
129
+ question: z.string(),
130
+ header: z.string().max(12),
131
+ options: z.array(z.object({
132
+ label: z.string(),
133
+ description: z.string()
134
+ })).min(2).max(4),
135
+ multiSelect: z.boolean()
136
+ })).min(1).max(4)
137
+ }),
138
+ execute: async (input, context) => { ... }
139
+ };
140
+ ```
141
+
142
+ ### Implementation Approach
143
+
144
+ 1. **Tool Registration**: Add AskUserQuestion to tool registry
145
+ 2. **UI Integration**: Create interactive question display
146
+ 3. **Blocking Execution**: Tool blocks until user responds
147
+ 4. **Answer Processing**: Return structured answers to agent
148
+ 5. **Other Handling**: Support custom text input
149
+
150
+ ```typescript
151
+ // Question display and collection
152
+ async function execute(input: AskUserQuestionInput, context: ToolContext): Promise<ToolResult> {
153
+ const { promptUser } = context;
154
+
155
+ const answers: QuestionAnswer[] = [];
156
+
157
+ for (const question of input.questions) {
158
+ // Display question with options
159
+ const response = await promptUser({
160
+ type: question.multiSelect ? 'multiselect' : 'select',
161
+ message: question.question,
162
+ choices: [
163
+ ...question.options.map(opt => ({
164
+ name: opt.label,
165
+ message: opt.label,
166
+ hint: opt.description
167
+ })),
168
+ { name: 'Other', message: 'Other (custom input)' }
169
+ ]
170
+ });
171
+
172
+ let customInput: string | undefined;
173
+ if (response.includes('Other')) {
174
+ customInput = await promptUser({
175
+ type: 'input',
176
+ message: 'Please specify:'
177
+ });
178
+ }
179
+
180
+ answers.push({
181
+ question: question.question,
182
+ selectedOptions: response,
183
+ customInput
184
+ });
185
+ }
186
+
187
+ return {
188
+ success: true,
189
+ output: JSON.stringify({ answers })
190
+ };
191
+ }
192
+ ```
193
+
194
+ ### File Changes
195
+
196
+ | File | Action | Description |
197
+ |------|--------|-------------|
198
+ | `src/tools/ask-user/types.ts` | Create | Question/answer type definitions |
199
+ | `src/tools/ask-user/ask-user-tool.ts` | Create | AskUserQuestion tool implementation |
200
+ | `src/tools/ask-user/index.ts` | Create | Module exports |
201
+ | `src/tools/index.ts` | Modify | Register tool |
202
+ | `src/cli/components/QuestionPrompt.tsx` | Create | Question UI component |
203
+
204
+ ## User Experience
205
+
206
+ ### Single Select Display
207
+ ```
208
+ ┌─ Database ─────────────────────────────────┐
209
+ │ Which database should we use? │
210
+ │ │
211
+ │ ○ PostgreSQL (Recommended) │
212
+ │ Relational DB with rich features │
213
+ │ │
214
+ │ ○ MongoDB │
215
+ │ Document-based NoSQL database │
216
+ │ │
217
+ │ ○ SQLite │
218
+ │ Lightweight embedded database │
219
+ │ │
220
+ │ ○ Other │
221
+ │ Provide custom input │
222
+ └────────────────────────────────────────────┘
223
+ ```
224
+
225
+ ### Multi Select Display
226
+ ```
227
+ ┌─ Features ─────────────────────────────────┐
228
+ │ Which features should we enable? │
229
+ │ (Select multiple with space) │
230
+ │ │
231
+ │ ☑ Dark mode │
232
+ │ Enable dark theme support │
233
+ │ │
234
+ │ ☐ Notifications │
235
+ │ Push notification support │
236
+ │ │
237
+ │ ☑ Offline mode │
238
+ │ Work without internet connection │
239
+ └────────────────────────────────────────────┘
240
+ ```
241
+
242
+ ### Keyboard Navigation
243
+ - `↑/↓` - Navigate options
244
+ - `Space` - Toggle selection (multi-select)
245
+ - `Enter` - Confirm selection
246
+ - `Esc` - Cancel (if allowed)
247
+
248
+ ### Answer Display
249
+ After user answers:
250
+ ```
251
+ ✓ Database: PostgreSQL
252
+ ✓ Features: Dark mode, Offline mode
253
+
254
+ Continuing with implementation...
255
+ ```
256
+
257
+ ## Alternatives Considered
258
+
259
+ ### Alternative 1: Plain Text Questions
260
+ Agent asks questions in regular output.
261
+
262
+ **Pros**: Simpler, no special UI
263
+ **Cons**: No structure, easy to miss, no validation
264
+ **Decision**: Rejected - Structured questions are clearer
265
+
266
+ ### Alternative 2: Form-Based Input
267
+ Complex form with multiple field types.
268
+
269
+ **Pros**: More input flexibility
270
+ **Cons**: Overcomplicated for most use cases
271
+ **Decision**: Rejected - Options are sufficient for most needs
272
+
273
+ ### Alternative 3: Always Allow Custom Input
274
+ Every option is editable text.
275
+
276
+ **Pros**: Maximum flexibility
277
+ **Cons**: Slower, more error-prone
278
+ **Decision**: Rejected - "Other" option provides this when needed
279
+
280
+ ## Security Considerations
281
+
282
+ 1. **Input Sanitization**: Validate user custom input
283
+ 2. **Option Limits**: Enforce max questions and options
284
+ 3. **Timeout**: Consider timeout for unresponsive users
285
+ 4. **No Code Execution**: Custom input is text only
286
+
287
+ ## Testing Strategy
288
+
289
+ 1. **Unit Tests**:
290
+ - Input validation
291
+ - Option parsing
292
+ - Answer formatting
293
+
294
+ 2. **Integration Tests**:
295
+ - Tool registration
296
+ - Agent flow with questions
297
+ - Answer processing
298
+
299
+ 3. **Manual Testing**:
300
+ - UI rendering
301
+ - Keyboard navigation
302
+ - Multi-select behavior
303
+ - Custom input flow
304
+
305
+ ## Migration Path
306
+
307
+ 1. **Phase 1**: Core tool and basic select UI
308
+ 2. **Phase 2**: Multi-select support
309
+ 3. **Phase 3**: Enhanced UI with descriptions
310
+ 4. **Phase 4**: Keyboard shortcuts and accessibility
311
+
312
+ No breaking changes to existing functionality.
313
+
314
+ ## References
315
+
316
+ - [Claude Code AskUserQuestion Tool](https://code.claude.com/docs/en/tools)
317
+ - [Inquirer.js](https://github.com/SBoudrias/Inquirer.js) (inspiration for UI)