aider-ce 0.87.2.dev9__py3-none-any.whl

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.

Potentially problematic release.


This version of aider-ce might be problematic. Click here for more details.

Files changed (264) hide show
  1. aider/__init__.py +20 -0
  2. aider/__main__.py +4 -0
  3. aider/_version.py +34 -0
  4. aider/analytics.py +258 -0
  5. aider/args.py +1014 -0
  6. aider/args_formatter.py +228 -0
  7. aider/change_tracker.py +133 -0
  8. aider/coders/__init__.py +36 -0
  9. aider/coders/architect_coder.py +48 -0
  10. aider/coders/architect_prompts.py +40 -0
  11. aider/coders/ask_coder.py +9 -0
  12. aider/coders/ask_prompts.py +35 -0
  13. aider/coders/base_coder.py +3013 -0
  14. aider/coders/base_prompts.py +87 -0
  15. aider/coders/chat_chunks.py +64 -0
  16. aider/coders/context_coder.py +53 -0
  17. aider/coders/context_prompts.py +75 -0
  18. aider/coders/editblock_coder.py +657 -0
  19. aider/coders/editblock_fenced_coder.py +10 -0
  20. aider/coders/editblock_fenced_prompts.py +143 -0
  21. aider/coders/editblock_func_coder.py +141 -0
  22. aider/coders/editblock_func_prompts.py +27 -0
  23. aider/coders/editblock_prompts.py +177 -0
  24. aider/coders/editor_diff_fenced_coder.py +9 -0
  25. aider/coders/editor_diff_fenced_prompts.py +11 -0
  26. aider/coders/editor_editblock_coder.py +9 -0
  27. aider/coders/editor_editblock_prompts.py +21 -0
  28. aider/coders/editor_whole_coder.py +9 -0
  29. aider/coders/editor_whole_prompts.py +12 -0
  30. aider/coders/help_coder.py +16 -0
  31. aider/coders/help_prompts.py +46 -0
  32. aider/coders/navigator_coder.py +2711 -0
  33. aider/coders/navigator_legacy_prompts.py +338 -0
  34. aider/coders/navigator_prompts.py +530 -0
  35. aider/coders/patch_coder.py +706 -0
  36. aider/coders/patch_prompts.py +161 -0
  37. aider/coders/search_replace.py +757 -0
  38. aider/coders/shell.py +37 -0
  39. aider/coders/single_wholefile_func_coder.py +102 -0
  40. aider/coders/single_wholefile_func_prompts.py +27 -0
  41. aider/coders/udiff_coder.py +429 -0
  42. aider/coders/udiff_prompts.py +117 -0
  43. aider/coders/udiff_simple.py +14 -0
  44. aider/coders/udiff_simple_prompts.py +25 -0
  45. aider/coders/wholefile_coder.py +144 -0
  46. aider/coders/wholefile_func_coder.py +134 -0
  47. aider/coders/wholefile_func_prompts.py +27 -0
  48. aider/coders/wholefile_prompts.py +70 -0
  49. aider/commands.py +1946 -0
  50. aider/copypaste.py +72 -0
  51. aider/deprecated.py +126 -0
  52. aider/diffs.py +128 -0
  53. aider/dump.py +29 -0
  54. aider/editor.py +147 -0
  55. aider/exceptions.py +107 -0
  56. aider/format_settings.py +26 -0
  57. aider/gui.py +545 -0
  58. aider/help.py +163 -0
  59. aider/help_pats.py +19 -0
  60. aider/history.py +178 -0
  61. aider/io.py +1257 -0
  62. aider/linter.py +304 -0
  63. aider/llm.py +47 -0
  64. aider/main.py +1297 -0
  65. aider/mcp/__init__.py +94 -0
  66. aider/mcp/server.py +119 -0
  67. aider/mdstream.py +243 -0
  68. aider/models.py +1344 -0
  69. aider/onboarding.py +428 -0
  70. aider/openrouter.py +129 -0
  71. aider/prompts.py +56 -0
  72. aider/queries/tree-sitter-language-pack/README.md +7 -0
  73. aider/queries/tree-sitter-language-pack/arduino-tags.scm +5 -0
  74. aider/queries/tree-sitter-language-pack/c-tags.scm +9 -0
  75. aider/queries/tree-sitter-language-pack/chatito-tags.scm +16 -0
  76. aider/queries/tree-sitter-language-pack/clojure-tags.scm +7 -0
  77. aider/queries/tree-sitter-language-pack/commonlisp-tags.scm +122 -0
  78. aider/queries/tree-sitter-language-pack/cpp-tags.scm +15 -0
  79. aider/queries/tree-sitter-language-pack/csharp-tags.scm +26 -0
  80. aider/queries/tree-sitter-language-pack/d-tags.scm +26 -0
  81. aider/queries/tree-sitter-language-pack/dart-tags.scm +92 -0
  82. aider/queries/tree-sitter-language-pack/elisp-tags.scm +5 -0
  83. aider/queries/tree-sitter-language-pack/elixir-tags.scm +54 -0
  84. aider/queries/tree-sitter-language-pack/elm-tags.scm +19 -0
  85. aider/queries/tree-sitter-language-pack/gleam-tags.scm +41 -0
  86. aider/queries/tree-sitter-language-pack/go-tags.scm +42 -0
  87. aider/queries/tree-sitter-language-pack/java-tags.scm +20 -0
  88. aider/queries/tree-sitter-language-pack/javascript-tags.scm +88 -0
  89. aider/queries/tree-sitter-language-pack/lua-tags.scm +34 -0
  90. aider/queries/tree-sitter-language-pack/matlab-tags.scm +10 -0
  91. aider/queries/tree-sitter-language-pack/ocaml-tags.scm +115 -0
  92. aider/queries/tree-sitter-language-pack/ocaml_interface-tags.scm +98 -0
  93. aider/queries/tree-sitter-language-pack/pony-tags.scm +39 -0
  94. aider/queries/tree-sitter-language-pack/properties-tags.scm +5 -0
  95. aider/queries/tree-sitter-language-pack/python-tags.scm +14 -0
  96. aider/queries/tree-sitter-language-pack/r-tags.scm +21 -0
  97. aider/queries/tree-sitter-language-pack/racket-tags.scm +12 -0
  98. aider/queries/tree-sitter-language-pack/ruby-tags.scm +64 -0
  99. aider/queries/tree-sitter-language-pack/rust-tags.scm +60 -0
  100. aider/queries/tree-sitter-language-pack/solidity-tags.scm +43 -0
  101. aider/queries/tree-sitter-language-pack/swift-tags.scm +51 -0
  102. aider/queries/tree-sitter-language-pack/udev-tags.scm +20 -0
  103. aider/queries/tree-sitter-languages/README.md +23 -0
  104. aider/queries/tree-sitter-languages/c-tags.scm +9 -0
  105. aider/queries/tree-sitter-languages/c_sharp-tags.scm +46 -0
  106. aider/queries/tree-sitter-languages/cpp-tags.scm +15 -0
  107. aider/queries/tree-sitter-languages/dart-tags.scm +91 -0
  108. aider/queries/tree-sitter-languages/elisp-tags.scm +8 -0
  109. aider/queries/tree-sitter-languages/elixir-tags.scm +54 -0
  110. aider/queries/tree-sitter-languages/elm-tags.scm +19 -0
  111. aider/queries/tree-sitter-languages/go-tags.scm +30 -0
  112. aider/queries/tree-sitter-languages/hcl-tags.scm +77 -0
  113. aider/queries/tree-sitter-languages/java-tags.scm +20 -0
  114. aider/queries/tree-sitter-languages/javascript-tags.scm +88 -0
  115. aider/queries/tree-sitter-languages/kotlin-tags.scm +27 -0
  116. aider/queries/tree-sitter-languages/matlab-tags.scm +10 -0
  117. aider/queries/tree-sitter-languages/ocaml-tags.scm +115 -0
  118. aider/queries/tree-sitter-languages/ocaml_interface-tags.scm +98 -0
  119. aider/queries/tree-sitter-languages/php-tags.scm +26 -0
  120. aider/queries/tree-sitter-languages/python-tags.scm +12 -0
  121. aider/queries/tree-sitter-languages/ql-tags.scm +26 -0
  122. aider/queries/tree-sitter-languages/ruby-tags.scm +64 -0
  123. aider/queries/tree-sitter-languages/rust-tags.scm +60 -0
  124. aider/queries/tree-sitter-languages/scala-tags.scm +65 -0
  125. aider/queries/tree-sitter-languages/typescript-tags.scm +41 -0
  126. aider/reasoning_tags.py +82 -0
  127. aider/repo.py +621 -0
  128. aider/repomap.py +988 -0
  129. aider/report.py +200 -0
  130. aider/resources/__init__.py +3 -0
  131. aider/resources/model-metadata.json +699 -0
  132. aider/resources/model-settings.yml +2046 -0
  133. aider/run_cmd.py +132 -0
  134. aider/scrape.py +284 -0
  135. aider/sendchat.py +61 -0
  136. aider/special.py +203 -0
  137. aider/tools/__init__.py +26 -0
  138. aider/tools/command.py +58 -0
  139. aider/tools/command_interactive.py +53 -0
  140. aider/tools/delete_block.py +120 -0
  141. aider/tools/delete_line.py +112 -0
  142. aider/tools/delete_lines.py +137 -0
  143. aider/tools/extract_lines.py +276 -0
  144. aider/tools/grep.py +171 -0
  145. aider/tools/indent_lines.py +155 -0
  146. aider/tools/insert_block.py +211 -0
  147. aider/tools/list_changes.py +51 -0
  148. aider/tools/ls.py +49 -0
  149. aider/tools/make_editable.py +46 -0
  150. aider/tools/make_readonly.py +29 -0
  151. aider/tools/remove.py +48 -0
  152. aider/tools/replace_all.py +77 -0
  153. aider/tools/replace_line.py +125 -0
  154. aider/tools/replace_lines.py +160 -0
  155. aider/tools/replace_text.py +125 -0
  156. aider/tools/show_numbered_context.py +101 -0
  157. aider/tools/tool_utils.py +313 -0
  158. aider/tools/undo_change.py +60 -0
  159. aider/tools/view.py +13 -0
  160. aider/tools/view_files_at_glob.py +65 -0
  161. aider/tools/view_files_matching.py +103 -0
  162. aider/tools/view_files_with_symbol.py +121 -0
  163. aider/urls.py +17 -0
  164. aider/utils.py +454 -0
  165. aider/versioncheck.py +113 -0
  166. aider/voice.py +187 -0
  167. aider/waiting.py +221 -0
  168. aider/watch.py +318 -0
  169. aider/watch_prompts.py +12 -0
  170. aider/website/Gemfile +8 -0
  171. aider/website/_includes/blame.md +162 -0
  172. aider/website/_includes/get-started.md +22 -0
  173. aider/website/_includes/help-tip.md +5 -0
  174. aider/website/_includes/help.md +24 -0
  175. aider/website/_includes/install.md +5 -0
  176. aider/website/_includes/keys.md +4 -0
  177. aider/website/_includes/model-warnings.md +67 -0
  178. aider/website/_includes/multi-line.md +22 -0
  179. aider/website/_includes/python-m-aider.md +5 -0
  180. aider/website/_includes/recording.css +228 -0
  181. aider/website/_includes/recording.md +34 -0
  182. aider/website/_includes/replit-pipx.md +9 -0
  183. aider/website/_includes/works-best.md +1 -0
  184. aider/website/_sass/custom/custom.scss +103 -0
  185. aider/website/docs/config/adv-model-settings.md +2260 -0
  186. aider/website/docs/config/aider_conf.md +548 -0
  187. aider/website/docs/config/api-keys.md +90 -0
  188. aider/website/docs/config/dotenv.md +493 -0
  189. aider/website/docs/config/editor.md +127 -0
  190. aider/website/docs/config/mcp.md +95 -0
  191. aider/website/docs/config/model-aliases.md +104 -0
  192. aider/website/docs/config/options.md +890 -0
  193. aider/website/docs/config/reasoning.md +210 -0
  194. aider/website/docs/config.md +44 -0
  195. aider/website/docs/faq.md +384 -0
  196. aider/website/docs/git.md +76 -0
  197. aider/website/docs/index.md +47 -0
  198. aider/website/docs/install/codespaces.md +39 -0
  199. aider/website/docs/install/docker.md +57 -0
  200. aider/website/docs/install/optional.md +100 -0
  201. aider/website/docs/install/replit.md +8 -0
  202. aider/website/docs/install.md +115 -0
  203. aider/website/docs/languages.md +264 -0
  204. aider/website/docs/legal/contributor-agreement.md +111 -0
  205. aider/website/docs/legal/privacy.md +104 -0
  206. aider/website/docs/llms/anthropic.md +77 -0
  207. aider/website/docs/llms/azure.md +48 -0
  208. aider/website/docs/llms/bedrock.md +132 -0
  209. aider/website/docs/llms/cohere.md +34 -0
  210. aider/website/docs/llms/deepseek.md +32 -0
  211. aider/website/docs/llms/gemini.md +49 -0
  212. aider/website/docs/llms/github.md +111 -0
  213. aider/website/docs/llms/groq.md +36 -0
  214. aider/website/docs/llms/lm-studio.md +39 -0
  215. aider/website/docs/llms/ollama.md +75 -0
  216. aider/website/docs/llms/openai-compat.md +39 -0
  217. aider/website/docs/llms/openai.md +58 -0
  218. aider/website/docs/llms/openrouter.md +78 -0
  219. aider/website/docs/llms/other.md +111 -0
  220. aider/website/docs/llms/vertex.md +50 -0
  221. aider/website/docs/llms/warnings.md +10 -0
  222. aider/website/docs/llms/xai.md +53 -0
  223. aider/website/docs/llms.md +54 -0
  224. aider/website/docs/more/analytics.md +127 -0
  225. aider/website/docs/more/edit-formats.md +116 -0
  226. aider/website/docs/more/infinite-output.md +159 -0
  227. aider/website/docs/more-info.md +8 -0
  228. aider/website/docs/recordings/auto-accept-architect.md +31 -0
  229. aider/website/docs/recordings/dont-drop-original-read-files.md +35 -0
  230. aider/website/docs/recordings/index.md +21 -0
  231. aider/website/docs/recordings/model-accepts-settings.md +69 -0
  232. aider/website/docs/recordings/tree-sitter-language-pack.md +80 -0
  233. aider/website/docs/repomap.md +112 -0
  234. aider/website/docs/scripting.md +100 -0
  235. aider/website/docs/troubleshooting/aider-not-found.md +24 -0
  236. aider/website/docs/troubleshooting/edit-errors.md +76 -0
  237. aider/website/docs/troubleshooting/imports.md +62 -0
  238. aider/website/docs/troubleshooting/models-and-keys.md +54 -0
  239. aider/website/docs/troubleshooting/support.md +79 -0
  240. aider/website/docs/troubleshooting/token-limits.md +96 -0
  241. aider/website/docs/troubleshooting/warnings.md +12 -0
  242. aider/website/docs/troubleshooting.md +11 -0
  243. aider/website/docs/usage/browser.md +57 -0
  244. aider/website/docs/usage/caching.md +49 -0
  245. aider/website/docs/usage/commands.md +133 -0
  246. aider/website/docs/usage/conventions.md +119 -0
  247. aider/website/docs/usage/copypaste.md +121 -0
  248. aider/website/docs/usage/images-urls.md +48 -0
  249. aider/website/docs/usage/lint-test.md +118 -0
  250. aider/website/docs/usage/modes.md +211 -0
  251. aider/website/docs/usage/not-code.md +179 -0
  252. aider/website/docs/usage/notifications.md +87 -0
  253. aider/website/docs/usage/tips.md +79 -0
  254. aider/website/docs/usage/tutorials.md +30 -0
  255. aider/website/docs/usage/voice.md +121 -0
  256. aider/website/docs/usage/watch.md +294 -0
  257. aider/website/docs/usage.md +102 -0
  258. aider/website/share/index.md +101 -0
  259. aider_ce-0.87.2.dev9.dist-info/METADATA +543 -0
  260. aider_ce-0.87.2.dev9.dist-info/RECORD +264 -0
  261. aider_ce-0.87.2.dev9.dist-info/WHEEL +5 -0
  262. aider_ce-0.87.2.dev9.dist-info/entry_points.txt +3 -0
  263. aider_ce-0.87.2.dev9.dist-info/licenses/LICENSE.txt +202 -0
  264. aider_ce-0.87.2.dev9.dist-info/top_level.txt +1 -0
@@ -0,0 +1,60 @@
1
+ import traceback
2
+
3
+
4
+ def _execute_undo_change(coder, change_id=None, file_path=None):
5
+ """
6
+ Undo a specific change by ID, or the last change to a file.
7
+
8
+ Parameters:
9
+ - coder: The Coder instance
10
+ - change_id: ID of the change to undo
11
+ - file_path: Path to file where the last change should be undone
12
+
13
+ Returns a result message.
14
+ """
15
+ # Note: Undo does not have a dry_run parameter as it's inherently about reverting a previous action.
16
+ try:
17
+ # Validate parameters
18
+ if change_id is None and file_path is None:
19
+ coder.io.tool_error("Must specify either change_id or file_path for UndoChange")
20
+ return "Error: Must specify either change_id or file_path"
21
+
22
+ # If file_path is specified, get the most recent change for that file
23
+ if file_path:
24
+ abs_path = coder.abs_root_path(file_path)
25
+ rel_path = coder.get_rel_fname(abs_path)
26
+
27
+ change_id = coder.change_tracker.get_last_change(rel_path)
28
+ if not change_id:
29
+ coder.io.tool_error(f"No tracked changes found for file '{file_path}' to undo.")
30
+ return f"Error: No changes found for file '{file_path}'"
31
+
32
+ # Attempt to get undo information from the tracker
33
+ success, message, change_info = coder.change_tracker.undo_change(change_id)
34
+
35
+ if not success:
36
+ coder.io.tool_error(f"Failed to undo change '{change_id}': {message}")
37
+ return f"Error: {message}"
38
+
39
+ # Apply the undo by restoring the original content
40
+ if change_info:
41
+ file_path = change_info["file_path"]
42
+ abs_path = coder.abs_root_path(file_path)
43
+ # Write the original content back to the file
44
+ coder.io.write_text(abs_path, change_info["original"])
45
+ coder.aider_edited_files.add(file_path) # Track that the file was modified by the undo
46
+
47
+ change_type = change_info["type"]
48
+ coder.io.tool_output(f"✅ Undid {change_type} change '{change_id}' in {file_path}")
49
+ return f"Successfully undid {change_type} change '{change_id}'."
50
+ else:
51
+ # This case should ideally not be reached if tracker returns success
52
+ coder.io.tool_error(
53
+ f"Failed to undo change '{change_id}': Change info missing after successful tracker"
54
+ " update."
55
+ )
56
+ return f"Error: Failed to undo change '{change_id}' (missing change info)"
57
+
58
+ except Exception as e:
59
+ coder.io.tool_error(f"Error in UndoChange: {str(e)}\n{traceback.format_exc()}")
60
+ return f"Error: {str(e)}"
aider/tools/view.py ADDED
@@ -0,0 +1,13 @@
1
+ def execute_view(coder, file_path):
2
+ """
3
+ Explicitly add a file to context as read-only.
4
+
5
+ This gives the LLM explicit control over what files to view,
6
+ rather than relying on indirect mentions.
7
+ """
8
+ try:
9
+ # Use the coder's helper, marking it as an explicit view request
10
+ return coder._add_file_to_context(file_path, explicit=True)
11
+ except Exception as e:
12
+ coder.io.tool_error(f"Error viewing file: {str(e)}")
13
+ return f"Error: {str(e)}"
@@ -0,0 +1,65 @@
1
+ import fnmatch
2
+ import os
3
+
4
+
5
+ def execute_view_files_at_glob(coder, pattern):
6
+ """
7
+ Execute a glob pattern and add matching files to context as read-only.
8
+
9
+ This tool helps the LLM find files by pattern matching, similar to
10
+ how a developer would use glob patterns to find files.
11
+ """
12
+ try:
13
+ # Find files matching the pattern
14
+ matching_files = []
15
+
16
+ # Make the pattern relative to root if it's absolute
17
+ if pattern.startswith("/"):
18
+ pattern = os.path.relpath(pattern, coder.root)
19
+
20
+ # Get all files in the repo
21
+ all_files = coder.get_all_relative_files()
22
+
23
+ # Find matches with pattern matching
24
+ for file in all_files:
25
+ if fnmatch.fnmatch(file, pattern):
26
+ matching_files.append(file)
27
+
28
+ # Limit the number of files added if there are too many matches
29
+ if len(matching_files) > coder.max_files_per_glob:
30
+ coder.io.tool_output(
31
+ f"⚠️ Found {len(matching_files)} files matching '{pattern}', "
32
+ f"limiting to {coder.max_files_per_glob} most relevant files."
33
+ )
34
+ # Sort by modification time (most recent first)
35
+ matching_files.sort(
36
+ key=lambda f: os.path.getmtime(coder.abs_root_path(f)), reverse=True
37
+ )
38
+ matching_files = matching_files[: coder.max_files_per_glob]
39
+
40
+ # Add files to context
41
+ for file in matching_files:
42
+ # Use the coder's internal method to add files
43
+ coder._add_file_to_context(file)
44
+
45
+ # Return a user-friendly result
46
+ if matching_files:
47
+ if len(matching_files) > 10:
48
+ brief = ", ".join(matching_files[:5]) + f", and {len(matching_files) - 5} more"
49
+ coder.io.tool_output(
50
+ f"📂 Added {len(matching_files)} files matching '{pattern}': {brief}"
51
+ )
52
+ else:
53
+ coder.io.tool_output(
54
+ f"📂 Added files matching '{pattern}': {', '.join(matching_files)}"
55
+ )
56
+ return (
57
+ f"Added {len(matching_files)} files:"
58
+ f" {', '.join(matching_files[:5])}{' and more' if len(matching_files) > 5 else ''}"
59
+ )
60
+ else:
61
+ coder.io.tool_output(f"⚠️ No files found matching '{pattern}'")
62
+ return f"No files found matching '{pattern}'"
63
+ except Exception as e:
64
+ coder.io.tool_error(f"Error in ViewFilesAtGlob: {str(e)}")
65
+ return f"Error: {str(e)}"
@@ -0,0 +1,103 @@
1
+ import fnmatch
2
+ import re
3
+
4
+
5
+ def execute_view_files_matching(coder, search_pattern, file_pattern=None, regex=False):
6
+ """
7
+ Search for pattern (literal string or regex) in files and add matching files to context as read-only.
8
+
9
+ Args:
10
+ coder: The Coder instance.
11
+ search_pattern (str): The pattern to search for.
12
+ Treated as a literal string by default.
13
+ file_pattern (str, optional): Glob pattern to filter which files are searched.
14
+ Defaults to None (search all files).
15
+ regex (bool, optional): If True, treat search_pattern as a regular expression.
16
+ Defaults to False.
17
+
18
+ This tool lets the LLM search for content within files, mimicking
19
+ how a developer would use grep or regex search to find relevant code.
20
+ """
21
+ try:
22
+ # Get list of files to search
23
+ if file_pattern:
24
+ # Use glob pattern to filter files
25
+ all_files = coder.get_all_relative_files()
26
+ files_to_search = []
27
+ for file in all_files:
28
+ if fnmatch.fnmatch(file, file_pattern):
29
+ files_to_search.append(file)
30
+
31
+ if not files_to_search:
32
+ return (
33
+ f"No files matching '{file_pattern}' to search for pattern '{search_pattern}'"
34
+ )
35
+ else:
36
+ # Search all files if no pattern provided
37
+ files_to_search = coder.get_all_relative_files()
38
+
39
+ # Search for pattern in files
40
+ matches = {}
41
+ for file in files_to_search:
42
+ abs_path = coder.abs_root_path(file)
43
+ try:
44
+ with open(abs_path, "r", encoding="utf-8") as f:
45
+ content = f.read()
46
+ match_count = 0
47
+ if regex:
48
+ try:
49
+ matches_found = re.findall(search_pattern, content)
50
+ match_count = len(matches_found)
51
+ except re.error as e:
52
+ # Handle invalid regex patterns gracefully
53
+ coder.io.tool_error(f"Invalid regex pattern '{search_pattern}': {e}")
54
+ # Skip this file for this search if regex is invalid
55
+ continue
56
+ else:
57
+ # Exact string matching
58
+ match_count = content.count(search_pattern)
59
+
60
+ if match_count > 0:
61
+ matches[file] = match_count
62
+ except Exception:
63
+ # Skip files that can't be read (binary, etc.)
64
+ pass
65
+
66
+ # Limit the number of files added if there are too many matches
67
+ if len(matches) > coder.max_files_per_glob:
68
+ coder.io.tool_output(
69
+ f"⚠️ Found '{search_pattern}' in {len(matches)} files, "
70
+ f"limiting to {coder.max_files_per_glob} files with most matches."
71
+ )
72
+ # Sort by number of matches (most matches first)
73
+ sorted_matches = sorted(matches.items(), key=lambda x: x[1], reverse=True)
74
+ matches = dict(sorted_matches[: coder.max_files_per_glob])
75
+
76
+ # Add matching files to context
77
+ for file in matches:
78
+ coder._add_file_to_context(file)
79
+
80
+ # Return a user-friendly result
81
+ if matches:
82
+ # Sort by number of matches (most matches first)
83
+ sorted_matches = sorted(matches.items(), key=lambda x: x[1], reverse=True)
84
+ match_list = [f"{file} ({count} matches)" for file, count in sorted_matches[:5]]
85
+
86
+ if len(sorted_matches) > 5:
87
+ coder.io.tool_output(
88
+ f"🔍 Found '{search_pattern}' in {len(matches)} files:"
89
+ f" {', '.join(match_list)} and {len(matches) - 5} more"
90
+ )
91
+ return (
92
+ f"Found in {len(matches)} files: {', '.join(match_list)} and"
93
+ f" {len(matches) - 5} more"
94
+ )
95
+ else:
96
+ coder.io.tool_output(f"🔍 Found '{search_pattern}' in: {', '.join(match_list)}")
97
+ return f"Found in {len(matches)} files: {', '.join(match_list)}"
98
+ else:
99
+ coder.io.tool_output(f"⚠️ Pattern '{search_pattern}' not found in any files")
100
+ return "Pattern not found in any files"
101
+ except Exception as e:
102
+ coder.io.tool_error(f"Error in ViewFilesMatching: {str(e)}")
103
+ return f"Error: {str(e)}"
@@ -0,0 +1,121 @@
1
+ import os
2
+
3
+
4
+ def _execute_view_files_with_symbol(coder, symbol):
5
+ """
6
+ Find files containing a symbol using RepoMap and add them to context.
7
+ Checks files already in context first.
8
+ """
9
+ if not coder.repo_map:
10
+ coder.io.tool_output("⚠️ Repo map not available, cannot use ViewFilesWithSymbol tool.")
11
+ return "Repo map not available"
12
+
13
+ if not symbol:
14
+ return "Error: Missing 'symbol' parameter for ViewFilesWithSymbol"
15
+
16
+ # --- Start Modification ---
17
+ # 1. Check files already in context
18
+ files_in_context = list(coder.abs_fnames) + list(coder.abs_read_only_fnames)
19
+ found_in_context = []
20
+ for abs_fname in files_in_context:
21
+ rel_fname = coder.get_rel_fname(abs_fname)
22
+ try:
23
+ # Use get_tags for consistency with RepoMap usage elsewhere for now.
24
+ tags = coder.repo_map.get_tags(abs_fname, rel_fname)
25
+ for tag in tags:
26
+ if tag.name == symbol:
27
+ found_in_context.append(rel_fname)
28
+ break # Found in this file, move to next
29
+ except Exception as e:
30
+ coder.io.tool_warning(
31
+ f"Could not get symbols for {rel_fname} while checking context: {e}"
32
+ )
33
+
34
+ if found_in_context:
35
+ # Symbol found in already loaded files. Report this and stop.
36
+ file_list = ", ".join(sorted(list(set(found_in_context))))
37
+ coder.io.tool_output(
38
+ f"Symbol '{symbol}' found in already loaded file(s): {file_list}. No external search"
39
+ " performed."
40
+ )
41
+ return (
42
+ f"Symbol '{symbol}' found in already loaded file(s): {file_list}. No external search"
43
+ " performed."
44
+ )
45
+ # --- End Modification ---
46
+
47
+ # 2. If not found in context, search the repository using RepoMap
48
+ coder.io.tool_output(
49
+ f"🔎 Searching for symbol '{symbol}' in repository (excluding current context)..."
50
+ )
51
+ try:
52
+ found_files = set()
53
+ current_context_files = coder.abs_fnames | coder.abs_read_only_fnames
54
+ files_to_search = set(coder.get_all_abs_files()) - current_context_files
55
+
56
+ rel_fname_to_abs = {}
57
+ all_tags = []
58
+
59
+ for fname in files_to_search:
60
+ rel_fname = coder.get_rel_fname(fname)
61
+ rel_fname_to_abs[rel_fname] = fname
62
+ try:
63
+ tags = coder.repo_map.get_tags(fname, rel_fname)
64
+ all_tags.extend(tags)
65
+ except Exception as e:
66
+ coder.io.tool_warning(f"Could not get tags for {rel_fname}: {e}")
67
+
68
+ # Find matching symbols
69
+ for tag in all_tags:
70
+ if tag.name == symbol:
71
+ # Use absolute path directly if available, otherwise resolve from relative path
72
+ abs_fname = rel_fname_to_abs.get(tag.rel_fname) or coder.abs_root_path(tag.fname)
73
+ if abs_fname in files_to_search: # Ensure we only add files we intended to search
74
+ found_files.add(abs_fname)
75
+
76
+ # Limit the number of files added
77
+ if len(found_files) > coder.max_files_per_glob:
78
+ coder.io.tool_output(
79
+ f"⚠️ Found symbol '{symbol}' in {len(found_files)} files, "
80
+ f"limiting to {coder.max_files_per_glob} most relevant files."
81
+ )
82
+ # Sort by modification time (most recent first) - approximate relevance
83
+ sorted_found_files = sorted(
84
+ list(found_files), key=lambda f: os.path.getmtime(f), reverse=True
85
+ )
86
+ found_files = set(sorted_found_files[: coder.max_files_per_glob])
87
+
88
+ # Add files to context (as read-only)
89
+ added_count = 0
90
+ added_files_rel = []
91
+ for abs_file_path in found_files:
92
+ rel_path = coder.get_rel_fname(abs_file_path)
93
+ # Double check it's not already added somehow
94
+ if (
95
+ abs_file_path not in coder.abs_fnames
96
+ and abs_file_path not in coder.abs_read_only_fnames
97
+ ):
98
+ # Use explicit=True for clear output, even though it's an external search result
99
+ add_result = coder._add_file_to_context(rel_path, explicit=True)
100
+ if "Added" in add_result or "Viewed" in add_result: # Count successful adds/views
101
+ added_count += 1
102
+ added_files_rel.append(rel_path)
103
+
104
+ if added_count > 0:
105
+ if added_count > 5:
106
+ brief = ", ".join(added_files_rel[:5]) + f", and {added_count - 5} more"
107
+ coder.io.tool_output(f"🔎 Found '{symbol}' and added {added_count} files: {brief}")
108
+ else:
109
+ coder.io.tool_output(
110
+ f"🔎 Found '{symbol}' and added files: {', '.join(added_files_rel)}"
111
+ )
112
+ return f"Found symbol '{symbol}' and added {added_count} files as read-only."
113
+ else:
114
+ coder.io.tool_output(
115
+ f"⚠️ Symbol '{symbol}' not found in searchable files (outside current context)."
116
+ )
117
+ return f"Symbol '{symbol}' not found in searchable files (outside current context)."
118
+
119
+ except Exception as e:
120
+ coder.io.tool_error(f"Error in ViewFilesWithSymbol: {str(e)}")
121
+ return f"Error: {str(e)}"
aider/urls.py ADDED
@@ -0,0 +1,17 @@
1
+ website = "https://aider.chat/"
2
+ add_all_files = "https://aider.chat/docs/faq.html#how-can-i-add-all-the-files-to-the-chat"
3
+ edit_errors = "https://aider.chat/docs/troubleshooting/edit-errors.html"
4
+ git = "https://aider.chat/docs/git.html"
5
+ enable_playwright = "https://aider.chat/docs/install/optional.html#enable-playwright"
6
+ favicon = "https://aider.chat/assets/icons/favicon-32x32.png"
7
+ model_warnings = "https://aider.chat/docs/llms/warnings.html"
8
+ token_limits = "https://aider.chat/docs/troubleshooting/token-limits.html"
9
+ llms = "https://aider.chat/docs/llms.html"
10
+ large_repos = "https://aider.chat/docs/faq.html#can-i-use-aider-in-a-large-mono-repo"
11
+ github_issues = "https://github.com/Aider-AI/aider/issues/new"
12
+ git_index_version = "https://github.com/Aider-AI/aider/issues/211"
13
+ install_properly = "https://aider.chat/docs/troubleshooting/imports.html"
14
+ analytics = "https://aider.chat/docs/more/analytics.html"
15
+ release_notes = "https://aider.chat/HISTORY.html#release-notes"
16
+ edit_formats = "https://aider.chat/docs/more/edit-formats.html"
17
+ models_and_keys = "https://aider.chat/docs/troubleshooting/models-and-keys.html"