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,345 @@
1
+ # Proposal: MultiEdit Tool
2
+
3
+ - **Proposal ID**: 0013
4
+ - **Author**: mycode team
5
+ - **Status**: Draft
6
+ - **Created**: 2025-01-15
7
+ - **Updated**: 2025-01-15
8
+
9
+ ## Summary
10
+
11
+ Implement a MultiEdit tool that performs batch string replacements across multiple files in a single atomic operation. This enables efficient refactoring, renaming, and coordinated multi-file changes without multiple individual Edit tool calls.
12
+
13
+ ## Motivation
14
+
15
+ Currently, mycode's Edit tool operates on one file at a time. This leads to:
16
+
17
+ 1. **Inefficiency**: Renaming a variable across 10 files requires 10 separate Edit calls
18
+ 2. **Non-atomic changes**: Partial failures leave codebase in inconsistent state
19
+ 3. **Context overhead**: Each Edit call consumes conversation context
20
+ 4. **Poor UX**: Users see many individual tool calls for conceptually single operation
21
+ 5. **Error-prone**: Easy to miss files when doing manual multi-file edits
22
+
23
+ A MultiEdit tool enables atomic, efficient, multi-file operations.
24
+
25
+ ## Claude Code Reference
26
+
27
+ Claude Code provides batch editing through its Edit tool with `replace_all` flag and coordinated multi-call patterns:
28
+
29
+ ### Current Edit Tool Pattern
30
+ ```typescript
31
+ Edit({
32
+ file_path: "/path/to/file.ts",
33
+ old_string: "oldName",
34
+ new_string: "newName",
35
+ replace_all: true // Replace all occurrences in file
36
+ })
37
+ ```
38
+
39
+ ### BatchTool Pattern (from /init)
40
+ Claude Code uses BatchTool for coordinated operations:
41
+ ```typescript
42
+ BatchTool({
43
+ description: "Rename variable across files",
44
+ invocations: [
45
+ { tool_name: "Edit", input: { file_path: "file1.ts", ... } },
46
+ { tool_name: "Edit", input: { file_path: "file2.ts", ... } },
47
+ { tool_name: "Edit", input: { file_path: "file3.ts", ... } }
48
+ ]
49
+ })
50
+ ```
51
+
52
+ ### Key Characteristics
53
+ - Atomic: All or nothing execution
54
+ - Parallel execution where possible
55
+ - Rollback on failure
56
+ - Single result summary
57
+
58
+ ## Detailed Design
59
+
60
+ ### API Design
61
+
62
+ ```typescript
63
+ // src/tools/multi-edit/types.ts
64
+ interface FileEdit {
65
+ file_path: string;
66
+ old_string: string;
67
+ new_string: string;
68
+ replace_all?: boolean; // Default: false
69
+ }
70
+
71
+ interface MultiEditInput {
72
+ description: string; // What this batch edit does
73
+ edits: FileEdit[]; // Array of file edits
74
+ atomic?: boolean; // Rollback all on any failure (default: true)
75
+ dry_run?: boolean; // Preview changes without applying
76
+ }
77
+
78
+ interface EditResult {
79
+ file_path: string;
80
+ success: boolean;
81
+ replacements: number; // Number of replacements made
82
+ error?: string;
83
+ }
84
+
85
+ interface MultiEditOutput {
86
+ success: boolean;
87
+ results: EditResult[];
88
+ summary: {
89
+ total_files: number;
90
+ successful_files: number;
91
+ failed_files: number;
92
+ total_replacements: number;
93
+ };
94
+ error?: string;
95
+ rollback_performed?: boolean;
96
+ }
97
+ ```
98
+
99
+ ```typescript
100
+ // src/tools/multi-edit/multi-edit-tool.ts
101
+ const multiEditTool: Tool<MultiEditInput> = {
102
+ name: 'MultiEdit',
103
+ description: `Perform batch edits across multiple files atomically.
104
+
105
+ Features:
106
+ - Edit multiple files in a single operation
107
+ - Atomic mode: rollback all changes if any edit fails
108
+ - Dry run mode: preview changes without applying
109
+ - Replace all occurrences within each file
110
+
111
+ Usage:
112
+ - Provide array of edits with file paths and replacements
113
+ - Each edit specifies old_string and new_string
114
+ - Use replace_all: true for global replacement in file
115
+ - Use dry_run: true to preview changes
116
+
117
+ Best for:
118
+ - Variable/function renaming across codebase
119
+ - Import path updates
120
+ - Configuration value changes
121
+ - License header updates
122
+ `,
123
+ parameters: z.object({
124
+ description: z.string().min(1),
125
+ edits: z.array(z.object({
126
+ file_path: z.string(),
127
+ old_string: z.string(),
128
+ new_string: z.string(),
129
+ replace_all: z.boolean().optional()
130
+ })).min(1),
131
+ atomic: z.boolean().optional().default(true),
132
+ dry_run: z.boolean().optional().default(false)
133
+ }),
134
+ execute: async (input, context) => { ... }
135
+ };
136
+ ```
137
+
138
+ ### Implementation Approach
139
+
140
+ 1. **Pre-validation**: Verify all files exist and are readable
141
+ 2. **Backup creation**: Store original content for rollback
142
+ 3. **Parallel execution**: Process independent files concurrently
143
+ 4. **Atomic commit**: Apply all changes or rollback on failure
144
+ 5. **Result aggregation**: Summarize all edit results
145
+
146
+ ```typescript
147
+ // Core implementation
148
+ async function executeMultiEdit(
149
+ input: MultiEditInput,
150
+ context: ToolContext
151
+ ): Promise<MultiEditOutput> {
152
+ const { edits, atomic, dry_run } = input;
153
+ const backups: Map<string, string> = new Map();
154
+ const results: EditResult[] = [];
155
+
156
+ // Phase 1: Validate and backup
157
+ for (const edit of edits) {
158
+ const fullPath = resolvePath(edit.file_path, context.cwd);
159
+ if (!await fileExists(fullPath)) {
160
+ if (atomic) {
161
+ return { success: false, error: `File not found: ${edit.file_path}` };
162
+ }
163
+ results.push({ file_path: edit.file_path, success: false, error: 'File not found' });
164
+ continue;
165
+ }
166
+ const content = await readFile(fullPath);
167
+ backups.set(fullPath, content);
168
+ }
169
+
170
+ // Phase 2: Apply edits
171
+ for (const edit of edits) {
172
+ const fullPath = resolvePath(edit.file_path, context.cwd);
173
+ const original = backups.get(fullPath);
174
+ if (!original) continue;
175
+
176
+ // Check if old_string exists
177
+ if (!original.includes(edit.old_string)) {
178
+ if (atomic) {
179
+ await rollbackAll(backups);
180
+ return { success: false, error: `String not found in ${edit.file_path}` };
181
+ }
182
+ results.push({ file_path: edit.file_path, success: false, error: 'String not found' });
183
+ continue;
184
+ }
185
+
186
+ // Perform replacement
187
+ const newContent = edit.replace_all
188
+ ? original.replaceAll(edit.old_string, edit.new_string)
189
+ : original.replace(edit.old_string, edit.new_string);
190
+
191
+ const replacements = countReplacements(original, newContent, edit.old_string);
192
+
193
+ if (!dry_run) {
194
+ await writeFile(fullPath, newContent);
195
+ }
196
+
197
+ results.push({
198
+ file_path: edit.file_path,
199
+ success: true,
200
+ replacements
201
+ });
202
+ }
203
+
204
+ // Phase 3: Generate summary
205
+ return {
206
+ success: results.every(r => r.success),
207
+ results,
208
+ summary: {
209
+ total_files: edits.length,
210
+ successful_files: results.filter(r => r.success).length,
211
+ failed_files: results.filter(r => !r.success).length,
212
+ total_replacements: results.reduce((sum, r) => sum + (r.replacements || 0), 0)
213
+ }
214
+ };
215
+ }
216
+ ```
217
+
218
+ ### File Changes
219
+
220
+ | File | Action | Description |
221
+ |------|--------|-------------|
222
+ | `src/tools/multi-edit/types.ts` | Create | Type definitions |
223
+ | `src/tools/multi-edit/multi-edit-tool.ts` | Create | Tool implementation |
224
+ | `src/tools/multi-edit/index.ts` | Create | Module exports |
225
+ | `src/tools/index.ts` | Modify | Register MultiEdit tool |
226
+
227
+ ## User Experience
228
+
229
+ ### Basic Usage - Variable Rename
230
+ ```
231
+ User: Rename the function 'getUserData' to 'fetchUserProfile' across the codebase
232
+
233
+ Agent: I'll search for all occurrences and perform a batch rename.
234
+ [Grep: getUserData]
235
+
236
+ Found in 5 files. Performing batch edit:
237
+
238
+ ┌─ MultiEdit ───────────────────────────────────────┐
239
+ │ Description: Rename getUserData to fetchUserProfile │
240
+ │ Files: 5 │
241
+ │ Mode: Atomic │
242
+ └───────────────────────────────────────────────────┘
243
+
244
+ Results:
245
+ ✓ src/api/users.ts (3 replacements)
246
+ ✓ src/services/auth.ts (2 replacements)
247
+ ✓ src/hooks/useUser.ts (1 replacement)
248
+ ✓ src/tests/users.test.ts (4 replacements)
249
+ ✓ src/types/api.ts (1 replacement)
250
+
251
+ Summary: 5/5 files updated, 11 total replacements
252
+ ```
253
+
254
+ ### Dry Run Preview
255
+ ```
256
+ Agent: Let me preview the changes first:
257
+
258
+ [MultiEdit: dry_run=true]
259
+
260
+ Preview (no changes made):
261
+ • src/api/users.ts: Would make 3 replacements
262
+ • src/services/auth.ts: Would make 2 replacements
263
+ ...
264
+
265
+ Proceed with these changes?
266
+ ```
267
+
268
+ ### Atomic Rollback
269
+ ```
270
+ Agent: [MultiEdit: atomic=true]
271
+
272
+ Error in src/services/auth.ts: String not found
273
+ Rolling back changes to 3 files...
274
+ Rollback complete. No files were modified.
275
+ ```
276
+
277
+ ## Alternatives Considered
278
+
279
+ ### Alternative 1: Enhanced Single Edit
280
+ Add multi-file support to existing Edit tool.
281
+
282
+ **Pros**: No new tool, simpler API
283
+ **Cons**: Overloads Edit semantics, breaks single-responsibility
284
+ **Decision**: Rejected - Separate tool is cleaner
285
+
286
+ ### Alternative 2: Parallel Edit Calls
287
+ Let agent make multiple Edit calls in parallel.
288
+
289
+ **Pros**: No new implementation needed
290
+ **Cons**: No atomicity, no rollback, context overhead
291
+ **Decision**: Rejected - Atomicity is key feature
292
+
293
+ ### Alternative 3: File Glob Pattern
294
+ Support glob patterns for target files.
295
+
296
+ **Pros**: Concise syntax for many files
297
+ **Cons**: Less precise, risk of unintended edits
298
+ **Decision**: Deferred - Can add later
299
+
300
+ ## Security Considerations
301
+
302
+ 1. **Path Validation**: Ensure all paths are within allowed directories
303
+ 2. **Backup Storage**: Store backups securely in temp directory
304
+ 3. **Size Limits**: Limit number of files and total content size
305
+ 4. **Permission Check**: Verify write permission before starting
306
+ 5. **No Secret Exposure**: Don't log file contents in error messages
307
+
308
+ ```typescript
309
+ const MAX_FILES = 100;
310
+ const MAX_TOTAL_SIZE = 50 * 1024 * 1024; // 50MB
311
+ ```
312
+
313
+ ## Testing Strategy
314
+
315
+ 1. **Unit Tests**:
316
+ - Single file edit
317
+ - Multi-file edit
318
+ - Atomic rollback
319
+ - Dry run mode
320
+ - Error handling
321
+
322
+ 2. **Integration Tests**:
323
+ - Large batch edits
324
+ - Permission scenarios
325
+ - Concurrent access
326
+
327
+ 3. **Manual Testing**:
328
+ - Variable renaming workflow
329
+ - Import path updates
330
+ - Cross-platform paths
331
+
332
+ ## Migration Path
333
+
334
+ 1. **Phase 1**: Basic multi-edit with atomic mode
335
+ 2. **Phase 2**: Dry run preview
336
+ 3. **Phase 3**: Rollback functionality
337
+ 4. **Phase 4**: Performance optimization for large batches
338
+
339
+ No breaking changes to existing Edit tool.
340
+
341
+ ## References
342
+
343
+ - [Claude Code Edit Tool Documentation](https://code.claude.com/docs/en/tools)
344
+ - [Atomic File Operations Best Practices](https://en.wikipedia.org/wiki/Atomicity_(database_systems))
345
+ - [Existing Edit Tool Implementation](../../../src/tools/builtin/edit.ts)