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,267 @@
1
+ # Proposal: Enhanced Glob Tool
2
+
3
+ - **Proposal ID**: 0036
4
+ - **Author**: mycode team
5
+ - **Status**: Draft
6
+ - **Created**: 2025-01-15
7
+ - **Updated**: 2025-01-15
8
+
9
+ ## Summary
10
+
11
+ Enhance the Glob tool with advanced pattern matching, file metadata, sorting options, and result formatting for more powerful file discovery.
12
+
13
+ ## Motivation
14
+
15
+ The current Glob tool is basic:
16
+
17
+ 1. **Pattern only**: No metadata in results
18
+ 2. **No sorting**: Results in arbitrary order
19
+ 3. **Limited patterns**: Basic glob only
20
+ 4. **No exclusions**: Can't ignore patterns
21
+ 5. **Flat output**: Just file paths
22
+
23
+ Enhanced glob enables sophisticated file discovery.
24
+
25
+ ## Claude Code Reference
26
+
27
+ Claude Code's Glob tool provides fast pattern matching:
28
+
29
+ ### From Tool Description
30
+ ```
31
+ - Fast file pattern matching for any codebase size
32
+ - Supports glob patterns like "**/*.js" or "src/**/*.ts"
33
+ - Returns matching file paths sorted by modification time
34
+ ```
35
+
36
+ ### Key Features
37
+ - Sort by modification time
38
+ - Size-based filtering
39
+ - Exclusion patterns
40
+
41
+ ## Detailed Design
42
+
43
+ ### API Design
44
+
45
+ ```typescript
46
+ // src/tools/glob/types.ts
47
+ interface GlobInput {
48
+ pattern: string;
49
+ path?: string; // Base directory
50
+ ignore?: string[]; // Exclusion patterns
51
+ type?: 'file' | 'directory' | 'all';
52
+ sort?: 'name' | 'modified' | 'size' | 'type';
53
+ reverse?: boolean;
54
+ limit?: number;
55
+ includeMetadata?: boolean; // Include file stats
56
+ dot?: boolean; // Include dotfiles
57
+ }
58
+
59
+ interface GlobMatch {
60
+ path: string; // Relative path
61
+ absolutePath: string;
62
+ type: 'file' | 'directory' | 'symlink';
63
+ // Metadata (when includeMetadata=true)
64
+ size?: number;
65
+ modified?: string;
66
+ created?: string;
67
+ permissions?: string;
68
+ }
69
+
70
+ interface GlobOutput {
71
+ success: boolean;
72
+ matches: GlobMatch[];
73
+ pattern: string;
74
+ total: number;
75
+ truncated: boolean;
76
+ error?: string;
77
+ }
78
+ ```
79
+
80
+ ### Enhanced Glob Implementation
81
+
82
+ ```typescript
83
+ // src/tools/glob/glob-tool.ts
84
+ const globTool: Tool<GlobInput> = {
85
+ name: 'Glob',
86
+ description: `Fast file pattern matching.
87
+
88
+ Parameters:
89
+ - pattern: Glob pattern (e.g., "**/*.ts", "src/**/*.{js,jsx}")
90
+ - path: Base directory (default: cwd)
91
+ - ignore: Patterns to exclude (e.g., ["node_modules/**"])
92
+ - type: Match files, directories, or all
93
+ - sort: Sort by name, modified, size, or type (default: modified)
94
+ - reverse: Reverse sort order
95
+ - limit: Maximum results
96
+ - includeMetadata: Include file stats (size, modified, etc.)
97
+ - dot: Include dotfiles (default: false)
98
+
99
+ Returns matching file paths sorted by modification time.
100
+ `,
101
+ parameters: z.object({
102
+ pattern: z.string(),
103
+ path: z.string().optional(),
104
+ ignore: z.array(z.string()).optional(),
105
+ type: z.enum(['file', 'directory', 'all']).optional(),
106
+ sort: z.enum(['name', 'modified', 'size', 'type']).optional(),
107
+ reverse: z.boolean().optional(),
108
+ limit: z.number().int().positive().optional(),
109
+ includeMetadata: z.boolean().optional(),
110
+ dot: z.boolean().optional()
111
+ }),
112
+ execute: async (input, context) => {
113
+ const basePath = input.path
114
+ ? path.resolve(context.cwd, input.path)
115
+ : context.cwd;
116
+
117
+ const options: GlobOptions = {
118
+ cwd: basePath,
119
+ ignore: input.ignore || ['**/node_modules/**', '**/.git/**'],
120
+ dot: input.dot || false,
121
+ onlyFiles: input.type === 'file',
122
+ onlyDirectories: input.type === 'directory'
123
+ };
124
+
125
+ try {
126
+ const paths = await glob(input.pattern, options);
127
+
128
+ // Build matches with optional metadata
129
+ let matches: GlobMatch[] = await Promise.all(
130
+ paths.map(async (p) => {
131
+ const absolutePath = path.join(basePath, p);
132
+ const match: GlobMatch = {
133
+ path: p,
134
+ absolutePath,
135
+ type: 'file'
136
+ };
137
+
138
+ if (input.includeMetadata) {
139
+ const stats = await fs.stat(absolutePath);
140
+ match.size = stats.size;
141
+ match.modified = stats.mtime.toISOString();
142
+ match.created = stats.birthtime.toISOString();
143
+ match.type = stats.isDirectory() ? 'directory'
144
+ : stats.isSymbolicLink() ? 'symlink' : 'file';
145
+ }
146
+
147
+ return match;
148
+ })
149
+ );
150
+
151
+ // Sort
152
+ matches = sortMatches(matches, input.sort || 'modified', input.reverse);
153
+
154
+ // Limit
155
+ const truncated = input.limit ? matches.length > input.limit : false;
156
+ if (input.limit) {
157
+ matches = matches.slice(0, input.limit);
158
+ }
159
+
160
+ return {
161
+ success: true,
162
+ matches,
163
+ pattern: input.pattern,
164
+ total: paths.length,
165
+ truncated
166
+ };
167
+ } catch (error) {
168
+ return {
169
+ success: false,
170
+ matches: [],
171
+ pattern: input.pattern,
172
+ total: 0,
173
+ truncated: false,
174
+ error: error instanceof Error ? error.message : 'Unknown error'
175
+ };
176
+ }
177
+ }
178
+ };
179
+
180
+ function sortMatches(
181
+ matches: GlobMatch[],
182
+ sortBy: string,
183
+ reverse?: boolean
184
+ ): GlobMatch[] {
185
+ const sorted = [...matches];
186
+
187
+ sorted.sort((a, b) => {
188
+ switch (sortBy) {
189
+ case 'name':
190
+ return a.path.localeCompare(b.path);
191
+ case 'modified':
192
+ return (b.modified || '').localeCompare(a.modified || '');
193
+ case 'size':
194
+ return (b.size || 0) - (a.size || 0);
195
+ case 'type':
196
+ return a.type.localeCompare(b.type);
197
+ default:
198
+ return 0;
199
+ }
200
+ });
201
+
202
+ return reverse ? sorted.reverse() : sorted;
203
+ }
204
+ ```
205
+
206
+ ### File Changes
207
+
208
+ | File | Action | Description |
209
+ |------|--------|-------------|
210
+ | `src/tools/glob/types.ts` | Create | Type definitions |
211
+ | `src/tools/glob/glob-tool.ts` | Modify | Enhanced implementation |
212
+ | `src/tools/glob/utils.ts` | Create | Sorting utilities |
213
+
214
+ ## User Experience
215
+
216
+ ### Basic Pattern
217
+ ```
218
+ Agent: [Glob: pattern="src/**/*.ts"]
219
+
220
+ Found 24 TypeScript files:
221
+ src/index.ts
222
+ src/cli/index.ts
223
+ src/agent/agent.ts
224
+ ...
225
+ ```
226
+
227
+ ### With Metadata
228
+ ```
229
+ Agent: [Glob: pattern="*.md", includeMetadata=true, sort="modified"]
230
+
231
+ ┌─ Markdown Files ──────────────────────────────────┐
232
+ │ File Size Modified │
233
+ ├───────────────────────────────────────────────────┤
234
+ │ README.md 4.2 KB 2025-01-15 10:30 │
235
+ │ CHANGELOG.md 12.8 KB 2025-01-14 16:45 │
236
+ │ CONTRIBUTING.md 2.1 KB 2025-01-10 09:15 │
237
+ └───────────────────────────────────────────────────┘
238
+ ```
239
+
240
+ ### With Exclusions
241
+ ```
242
+ Agent: [Glob: pattern="**/*.js", ignore=["node_modules/**", "dist/**"]]
243
+
244
+ Found 15 JavaScript files (excluding node_modules, dist):
245
+ scripts/build.js
246
+ scripts/deploy.js
247
+ ...
248
+ ```
249
+
250
+ ## Security Considerations
251
+
252
+ 1. Path traversal prevention
253
+ 2. Symlink loop detection
254
+ 3. Result size limits
255
+ 4. Performance limits
256
+
257
+ ## Migration Path
258
+
259
+ 1. **Phase 1**: Sorting and limits
260
+ 2. **Phase 2**: Metadata support
261
+ 3. **Phase 3**: Advanced patterns
262
+ 4. **Phase 4**: Performance optimization
263
+
264
+ ## References
265
+
266
+ - [fast-glob](https://github.com/mrmlnc/fast-glob)
267
+ - [Glob Patterns](https://en.wikipedia.org/wiki/Glob_(programming))
@@ -0,0 +1,360 @@
1
+ # Proposal: Enhanced Grep Tool
2
+
3
+ - **Proposal ID**: 0037
4
+ - **Author**: mycode team
5
+ - **Status**: Draft
6
+ - **Created**: 2025-01-15
7
+ - **Updated**: 2025-01-15
8
+
9
+ ## Summary
10
+
11
+ Enhance the Grep tool with advanced regex features, context lines, multiline matching, output modes, and performance optimizations for powerful content searching.
12
+
13
+ ## Motivation
14
+
15
+ The current Grep tool has limitations:
16
+
17
+ 1. **Basic regex**: No multiline support
18
+ 2. **No context**: Just matching lines
19
+ 3. **Single mode**: Only line output
20
+ 4. **No pagination**: All results at once
21
+ 5. **Limited control**: Few options
22
+
23
+ Enhanced grep enables sophisticated content search.
24
+
25
+ ## Claude Code Reference
26
+
27
+ Claude Code's Grep tool provides comprehensive search:
28
+
29
+ ### From Tool Description
30
+ ```
31
+ - Supports full regex syntax (e.g., "log.*Error", "function\\s+\\w+")
32
+ - Filter files with glob or type parameter
33
+ - Output modes: "content", "files_with_matches", "count"
34
+ - Context lines with -A/-B/-C
35
+ - Multiline matching with multiline: true
36
+ - Line numbers with -n
37
+ ```
38
+
39
+ ### Key Features
40
+ - Multiple output modes
41
+ - Context lines (before/after)
42
+ - File type filtering
43
+ - Multiline patterns
44
+ - Offset/limit pagination
45
+
46
+ ## Detailed Design
47
+
48
+ ### API Design
49
+
50
+ ```typescript
51
+ // src/tools/grep/types.ts
52
+ type OutputMode = 'content' | 'files_with_matches' | 'count';
53
+
54
+ interface GrepInput {
55
+ pattern: string;
56
+ path?: string;
57
+ glob?: string; // File pattern filter
58
+ type?: string; // File type (js, py, etc.)
59
+ output_mode?: OutputMode;
60
+ '-A'?: number; // Lines after match
61
+ '-B'?: number; // Lines before match
62
+ '-C'?: number; // Context lines (both)
63
+ '-i'?: boolean; // Case insensitive
64
+ '-n'?: boolean; // Show line numbers
65
+ multiline?: boolean; // Cross-line matching
66
+ head_limit?: number; // Limit results
67
+ offset?: number; // Skip results
68
+ }
69
+
70
+ interface GrepMatch {
71
+ file: string;
72
+ line: number;
73
+ column: number;
74
+ content: string;
75
+ context?: {
76
+ before: string[];
77
+ after: string[];
78
+ };
79
+ }
80
+
81
+ interface GrepOutput {
82
+ success: boolean;
83
+ mode: OutputMode;
84
+ matches?: GrepMatch[];
85
+ files?: string[];
86
+ counts?: Record<string, number>;
87
+ total: number;
88
+ truncated: boolean;
89
+ error?: string;
90
+ }
91
+ ```
92
+
93
+ ### Enhanced Grep Implementation
94
+
95
+ ```typescript
96
+ // src/tools/grep/grep-tool.ts
97
+ const grepTool: Tool<GrepInput> = {
98
+ name: 'Grep',
99
+ description: `Search file contents with regex patterns.
100
+
101
+ Parameters:
102
+ - pattern: Regex pattern to search for
103
+ - path: Directory or file to search (default: cwd)
104
+ - glob: Filter files by glob pattern (e.g., "*.ts")
105
+ - type: Filter by file type (js, py, rust, go, etc.)
106
+ - output_mode: "content", "files_with_matches", or "count"
107
+ - -A: Lines to show after match
108
+ - -B: Lines to show before match
109
+ - -C: Lines to show before and after match
110
+ - -i: Case insensitive search
111
+ - -n: Show line numbers (default: true)
112
+ - multiline: Enable cross-line matching
113
+ - head_limit: Limit number of results
114
+ - offset: Skip first N results
115
+
116
+ Output modes:
117
+ - content: Show matching lines with context
118
+ - files_with_matches: Show only file paths
119
+ - count: Show match counts per file
120
+ `,
121
+ parameters: z.object({
122
+ pattern: z.string(),
123
+ path: z.string().optional(),
124
+ glob: z.string().optional(),
125
+ type: z.string().optional(),
126
+ output_mode: z.enum(['content', 'files_with_matches', 'count']).optional(),
127
+ '-A': z.number().int().nonnegative().optional(),
128
+ '-B': z.number().int().nonnegative().optional(),
129
+ '-C': z.number().int().nonnegative().optional(),
130
+ '-i': z.boolean().optional(),
131
+ '-n': z.boolean().optional().default(true),
132
+ multiline: z.boolean().optional(),
133
+ head_limit: z.number().int().positive().optional(),
134
+ offset: z.number().int().nonnegative().optional()
135
+ }),
136
+ execute: async (input, context) => {
137
+ return grepExecutor.search(input, context);
138
+ }
139
+ };
140
+
141
+ class GrepExecutor {
142
+ async search(input: GrepInput, context: ToolContext): Promise<GrepOutput> {
143
+ const basePath = input.path
144
+ ? path.resolve(context.cwd, input.path)
145
+ : context.cwd;
146
+
147
+ // Build regex
148
+ let flags = 'g';
149
+ if (input['-i']) flags += 'i';
150
+ if (input.multiline) flags += 'ms';
151
+
152
+ const regex = new RegExp(input.pattern, flags);
153
+
154
+ // Find files to search
155
+ const files = await this.findFiles(basePath, input.glob, input.type);
156
+
157
+ // Search based on output mode
158
+ const mode = input.output_mode || 'files_with_matches';
159
+
160
+ switch (mode) {
161
+ case 'content':
162
+ return this.searchContent(files, regex, input);
163
+ case 'files_with_matches':
164
+ return this.searchFilesOnly(files, regex, input);
165
+ case 'count':
166
+ return this.searchCount(files, regex, input);
167
+ }
168
+ }
169
+
170
+ private async searchContent(
171
+ files: string[],
172
+ regex: RegExp,
173
+ input: GrepInput
174
+ ): Promise<GrepOutput> {
175
+ const matches: GrepMatch[] = [];
176
+ const contextBefore = input['-B'] || input['-C'] || 0;
177
+ const contextAfter = input['-A'] || input['-C'] || 0;
178
+
179
+ for (const file of files) {
180
+ const content = await fs.readFile(file, 'utf-8');
181
+ const lines = content.split('\n');
182
+
183
+ for (let i = 0; i < lines.length; i++) {
184
+ const line = lines[i];
185
+ let match = regex.exec(line);
186
+
187
+ while (match) {
188
+ const grepMatch: GrepMatch = {
189
+ file: path.relative(process.cwd(), file),
190
+ line: i + 1,
191
+ column: match.index + 1,
192
+ content: line
193
+ };
194
+
195
+ if (contextBefore > 0 || contextAfter > 0) {
196
+ grepMatch.context = {
197
+ before: lines.slice(Math.max(0, i - contextBefore), i),
198
+ after: lines.slice(i + 1, i + 1 + contextAfter)
199
+ };
200
+ }
201
+
202
+ matches.push(grepMatch);
203
+ match = regex.exec(line);
204
+ }
205
+
206
+ // Reset regex for next line
207
+ regex.lastIndex = 0;
208
+ }
209
+ }
210
+
211
+ // Apply offset and limit
212
+ const offset = input.offset || 0;
213
+ const limit = input.head_limit;
214
+ const truncated = limit ? matches.length > offset + limit : false;
215
+ const paginatedMatches = limit
216
+ ? matches.slice(offset, offset + limit)
217
+ : matches.slice(offset);
218
+
219
+ return {
220
+ success: true,
221
+ mode: 'content',
222
+ matches: paginatedMatches,
223
+ total: matches.length,
224
+ truncated
225
+ };
226
+ }
227
+
228
+ private async findFiles(
229
+ basePath: string,
230
+ glob?: string,
231
+ type?: string
232
+ ): Promise<string[]> {
233
+ let pattern = '**/*';
234
+
235
+ if (glob) {
236
+ pattern = glob;
237
+ } else if (type) {
238
+ const extensions = this.getExtensionsForType(type);
239
+ pattern = `**/*.{${extensions.join(',')}}`;
240
+ }
241
+
242
+ return globby(pattern, {
243
+ cwd: basePath,
244
+ absolute: true,
245
+ ignore: ['**/node_modules/**', '**/.git/**']
246
+ });
247
+ }
248
+
249
+ private getExtensionsForType(type: string): string[] {
250
+ const typeMap: Record<string, string[]> = {
251
+ js: ['js', 'mjs', 'cjs'],
252
+ ts: ['ts', 'tsx', 'mts', 'cts'],
253
+ py: ['py', 'pyi'],
254
+ go: ['go'],
255
+ rust: ['rs'],
256
+ java: ['java'],
257
+ c: ['c', 'h'],
258
+ cpp: ['cpp', 'cxx', 'cc', 'hpp', 'hxx'],
259
+ md: ['md', 'markdown'],
260
+ json: ['json'],
261
+ yaml: ['yaml', 'yml']
262
+ };
263
+ return typeMap[type] || [type];
264
+ }
265
+ }
266
+ ```
267
+
268
+ ### File Changes
269
+
270
+ | File | Action | Description |
271
+ |------|--------|-------------|
272
+ | `src/tools/grep/types.ts` | Create | Type definitions |
273
+ | `src/tools/grep/grep-tool.ts` | Modify | Enhanced implementation |
274
+ | `src/tools/grep/executor.ts` | Create | Search logic |
275
+ | `src/tools/grep/utils.ts` | Create | Utilities |
276
+
277
+ ## User Experience
278
+
279
+ ### Content with Context
280
+ ```
281
+ Agent: [Grep: pattern="TODO", -C=2, output_mode="content"]
282
+
283
+ Found 5 matches:
284
+
285
+ src/agent/agent.ts:45
286
+ 43: async function processMessage() {
287
+ 44: // Setup connection
288
+ > 45: // TODO: Add retry logic
289
+ 46: const response = await fetch(url);
290
+ 47: }
291
+
292
+ src/cli/ui.ts:112
293
+ 110: function renderOutput() {
294
+ 111: // Format the response
295
+ > 112: // TODO: Add syntax highlighting
296
+ 113: console.log(output);
297
+ 114: }
298
+ ...
299
+ ```
300
+
301
+ ### Files Only Mode
302
+ ```
303
+ Agent: [Grep: pattern="import.*React", output_mode="files_with_matches", type="ts"]
304
+
305
+ Files containing pattern:
306
+ src/components/Button.tsx
307
+ src/components/Modal.tsx
308
+ src/pages/Home.tsx
309
+ src/pages/Settings.tsx
310
+ src/App.tsx
311
+
312
+ 5 files matched
313
+ ```
314
+
315
+ ### Count Mode
316
+ ```
317
+ Agent: [Grep: pattern="console\\.log", output_mode="count"]
318
+
319
+ Match counts:
320
+ src/cli/index.ts 12
321
+ src/tools/bash.ts 8
322
+ src/agent/agent.ts 5
323
+ src/utils/debug.ts 23
324
+
325
+ Total: 48 matches in 4 files
326
+ ```
327
+
328
+ ### Multiline Match
329
+ ```
330
+ Agent: [Grep: pattern="function\\s+\\w+\\([^)]*\\)\\s*\\{[\\s\\S]*?return", multiline=true]
331
+
332
+ Multiline matches found:
333
+ src/utils/helpers.ts:15-22
334
+ function calculateTotal(items) {
335
+ let sum = 0;
336
+ for (const item of items) {
337
+ sum += item.price;
338
+ }
339
+ return sum;
340
+ }
341
+ ```
342
+
343
+ ## Security Considerations
344
+
345
+ 1. Regex DoS prevention (ReDoS)
346
+ 2. File access restrictions
347
+ 3. Output size limits
348
+ 4. Search timeout
349
+
350
+ ## Migration Path
351
+
352
+ 1. **Phase 1**: Output modes
353
+ 2. **Phase 2**: Context lines
354
+ 3. **Phase 3**: Multiline support
355
+ 4. **Phase 4**: Performance optimization
356
+
357
+ ## References
358
+
359
+ - [ripgrep](https://github.com/BurntSushi/ripgrep)
360
+ - [ReDoS Prevention](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)