aider-ce 0.88.20__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.
- aider/__init__.py +20 -0
- aider/__main__.py +4 -0
- aider/_version.py +34 -0
- aider/analytics.py +258 -0
- aider/args.py +1056 -0
- aider/args_formatter.py +228 -0
- aider/change_tracker.py +133 -0
- aider/coders/__init__.py +36 -0
- aider/coders/agent_coder.py +2166 -0
- aider/coders/agent_prompts.py +104 -0
- aider/coders/architect_coder.py +48 -0
- aider/coders/architect_prompts.py +40 -0
- aider/coders/ask_coder.py +9 -0
- aider/coders/ask_prompts.py +35 -0
- aider/coders/base_coder.py +3613 -0
- aider/coders/base_prompts.py +87 -0
- aider/coders/chat_chunks.py +64 -0
- aider/coders/context_coder.py +53 -0
- aider/coders/context_prompts.py +75 -0
- aider/coders/editblock_coder.py +657 -0
- aider/coders/editblock_fenced_coder.py +10 -0
- aider/coders/editblock_fenced_prompts.py +143 -0
- aider/coders/editblock_func_coder.py +141 -0
- aider/coders/editblock_func_prompts.py +27 -0
- aider/coders/editblock_prompts.py +175 -0
- aider/coders/editor_diff_fenced_coder.py +9 -0
- aider/coders/editor_diff_fenced_prompts.py +11 -0
- aider/coders/editor_editblock_coder.py +9 -0
- aider/coders/editor_editblock_prompts.py +21 -0
- aider/coders/editor_whole_coder.py +9 -0
- aider/coders/editor_whole_prompts.py +12 -0
- aider/coders/help_coder.py +16 -0
- aider/coders/help_prompts.py +46 -0
- aider/coders/patch_coder.py +706 -0
- aider/coders/patch_prompts.py +159 -0
- aider/coders/search_replace.py +757 -0
- aider/coders/shell.py +37 -0
- aider/coders/single_wholefile_func_coder.py +102 -0
- aider/coders/single_wholefile_func_prompts.py +27 -0
- aider/coders/udiff_coder.py +429 -0
- aider/coders/udiff_prompts.py +115 -0
- aider/coders/udiff_simple.py +14 -0
- aider/coders/udiff_simple_prompts.py +25 -0
- aider/coders/wholefile_coder.py +144 -0
- aider/coders/wholefile_func_coder.py +134 -0
- aider/coders/wholefile_func_prompts.py +27 -0
- aider/coders/wholefile_prompts.py +65 -0
- aider/commands.py +2173 -0
- aider/copypaste.py +72 -0
- aider/deprecated.py +126 -0
- aider/diffs.py +128 -0
- aider/dump.py +29 -0
- aider/editor.py +147 -0
- aider/exceptions.py +115 -0
- aider/format_settings.py +26 -0
- aider/gui.py +545 -0
- aider/help.py +163 -0
- aider/help_pats.py +19 -0
- aider/helpers/__init__.py +9 -0
- aider/helpers/similarity.py +98 -0
- aider/history.py +180 -0
- aider/io.py +1608 -0
- aider/linter.py +304 -0
- aider/llm.py +55 -0
- aider/main.py +1415 -0
- aider/mcp/__init__.py +174 -0
- aider/mcp/server.py +149 -0
- aider/mdstream.py +243 -0
- aider/models.py +1313 -0
- aider/onboarding.py +429 -0
- aider/openrouter.py +129 -0
- aider/prompts.py +56 -0
- aider/queries/tree-sitter-language-pack/README.md +7 -0
- aider/queries/tree-sitter-language-pack/arduino-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/c-tags.scm +9 -0
- aider/queries/tree-sitter-language-pack/chatito-tags.scm +16 -0
- aider/queries/tree-sitter-language-pack/clojure-tags.scm +7 -0
- aider/queries/tree-sitter-language-pack/commonlisp-tags.scm +122 -0
- aider/queries/tree-sitter-language-pack/cpp-tags.scm +15 -0
- aider/queries/tree-sitter-language-pack/csharp-tags.scm +26 -0
- aider/queries/tree-sitter-language-pack/d-tags.scm +26 -0
- aider/queries/tree-sitter-language-pack/dart-tags.scm +92 -0
- aider/queries/tree-sitter-language-pack/elisp-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/elixir-tags.scm +54 -0
- aider/queries/tree-sitter-language-pack/elm-tags.scm +19 -0
- aider/queries/tree-sitter-language-pack/gleam-tags.scm +41 -0
- aider/queries/tree-sitter-language-pack/go-tags.scm +42 -0
- aider/queries/tree-sitter-language-pack/java-tags.scm +20 -0
- aider/queries/tree-sitter-language-pack/javascript-tags.scm +88 -0
- aider/queries/tree-sitter-language-pack/lua-tags.scm +34 -0
- aider/queries/tree-sitter-language-pack/matlab-tags.scm +10 -0
- aider/queries/tree-sitter-language-pack/ocaml-tags.scm +115 -0
- aider/queries/tree-sitter-language-pack/ocaml_interface-tags.scm +98 -0
- aider/queries/tree-sitter-language-pack/pony-tags.scm +39 -0
- aider/queries/tree-sitter-language-pack/properties-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/python-tags.scm +14 -0
- aider/queries/tree-sitter-language-pack/r-tags.scm +21 -0
- aider/queries/tree-sitter-language-pack/racket-tags.scm +12 -0
- aider/queries/tree-sitter-language-pack/ruby-tags.scm +64 -0
- aider/queries/tree-sitter-language-pack/rust-tags.scm +60 -0
- aider/queries/tree-sitter-language-pack/solidity-tags.scm +43 -0
- aider/queries/tree-sitter-language-pack/swift-tags.scm +51 -0
- aider/queries/tree-sitter-language-pack/udev-tags.scm +20 -0
- aider/queries/tree-sitter-languages/README.md +24 -0
- aider/queries/tree-sitter-languages/c-tags.scm +9 -0
- aider/queries/tree-sitter-languages/c_sharp-tags.scm +46 -0
- aider/queries/tree-sitter-languages/cpp-tags.scm +15 -0
- aider/queries/tree-sitter-languages/dart-tags.scm +91 -0
- aider/queries/tree-sitter-languages/elisp-tags.scm +8 -0
- aider/queries/tree-sitter-languages/elixir-tags.scm +54 -0
- aider/queries/tree-sitter-languages/elm-tags.scm +19 -0
- aider/queries/tree-sitter-languages/fortran-tags.scm +15 -0
- aider/queries/tree-sitter-languages/go-tags.scm +30 -0
- aider/queries/tree-sitter-languages/haskell-tags.scm +3 -0
- aider/queries/tree-sitter-languages/hcl-tags.scm +77 -0
- aider/queries/tree-sitter-languages/java-tags.scm +20 -0
- aider/queries/tree-sitter-languages/javascript-tags.scm +88 -0
- aider/queries/tree-sitter-languages/julia-tags.scm +60 -0
- aider/queries/tree-sitter-languages/kotlin-tags.scm +27 -0
- aider/queries/tree-sitter-languages/matlab-tags.scm +10 -0
- aider/queries/tree-sitter-languages/ocaml-tags.scm +115 -0
- aider/queries/tree-sitter-languages/ocaml_interface-tags.scm +98 -0
- aider/queries/tree-sitter-languages/php-tags.scm +26 -0
- aider/queries/tree-sitter-languages/python-tags.scm +12 -0
- aider/queries/tree-sitter-languages/ql-tags.scm +26 -0
- aider/queries/tree-sitter-languages/ruby-tags.scm +64 -0
- aider/queries/tree-sitter-languages/rust-tags.scm +60 -0
- aider/queries/tree-sitter-languages/scala-tags.scm +65 -0
- aider/queries/tree-sitter-languages/typescript-tags.scm +41 -0
- aider/queries/tree-sitter-languages/zig-tags.scm +3 -0
- aider/reasoning_tags.py +82 -0
- aider/repo.py +621 -0
- aider/repomap.py +1174 -0
- aider/report.py +260 -0
- aider/resources/__init__.py +3 -0
- aider/resources/model-metadata.json +776 -0
- aider/resources/model-settings.yml +2068 -0
- aider/run_cmd.py +133 -0
- aider/scrape.py +293 -0
- aider/sendchat.py +242 -0
- aider/sessions.py +256 -0
- aider/special.py +203 -0
- aider/tools/__init__.py +72 -0
- aider/tools/command.py +105 -0
- aider/tools/command_interactive.py +122 -0
- aider/tools/delete_block.py +182 -0
- aider/tools/delete_line.py +155 -0
- aider/tools/delete_lines.py +184 -0
- aider/tools/extract_lines.py +341 -0
- aider/tools/finished.py +48 -0
- aider/tools/git_branch.py +129 -0
- aider/tools/git_diff.py +60 -0
- aider/tools/git_log.py +57 -0
- aider/tools/git_remote.py +53 -0
- aider/tools/git_show.py +51 -0
- aider/tools/git_status.py +46 -0
- aider/tools/grep.py +256 -0
- aider/tools/indent_lines.py +221 -0
- aider/tools/insert_block.py +288 -0
- aider/tools/list_changes.py +86 -0
- aider/tools/ls.py +93 -0
- aider/tools/make_editable.py +85 -0
- aider/tools/make_readonly.py +69 -0
- aider/tools/remove.py +91 -0
- aider/tools/replace_all.py +126 -0
- aider/tools/replace_line.py +173 -0
- aider/tools/replace_lines.py +217 -0
- aider/tools/replace_text.py +187 -0
- aider/tools/show_numbered_context.py +147 -0
- aider/tools/tool_utils.py +313 -0
- aider/tools/undo_change.py +95 -0
- aider/tools/update_todo_list.py +156 -0
- aider/tools/view.py +57 -0
- aider/tools/view_files_matching.py +141 -0
- aider/tools/view_files_with_symbol.py +129 -0
- aider/urls.py +17 -0
- aider/utils.py +456 -0
- aider/versioncheck.py +113 -0
- aider/voice.py +205 -0
- aider/waiting.py +38 -0
- aider/watch.py +318 -0
- aider/watch_prompts.py +12 -0
- aider/website/Gemfile +8 -0
- aider/website/_includes/blame.md +162 -0
- aider/website/_includes/get-started.md +22 -0
- aider/website/_includes/help-tip.md +5 -0
- aider/website/_includes/help.md +24 -0
- aider/website/_includes/install.md +5 -0
- aider/website/_includes/keys.md +4 -0
- aider/website/_includes/model-warnings.md +67 -0
- aider/website/_includes/multi-line.md +22 -0
- aider/website/_includes/python-m-aider.md +5 -0
- aider/website/_includes/recording.css +228 -0
- aider/website/_includes/recording.md +34 -0
- aider/website/_includes/replit-pipx.md +9 -0
- aider/website/_includes/works-best.md +1 -0
- aider/website/_sass/custom/custom.scss +103 -0
- aider/website/docs/config/adv-model-settings.md +2261 -0
- aider/website/docs/config/agent-mode.md +194 -0
- aider/website/docs/config/aider_conf.md +548 -0
- aider/website/docs/config/api-keys.md +90 -0
- aider/website/docs/config/dotenv.md +493 -0
- aider/website/docs/config/editor.md +127 -0
- aider/website/docs/config/mcp.md +95 -0
- aider/website/docs/config/model-aliases.md +104 -0
- aider/website/docs/config/options.md +890 -0
- aider/website/docs/config/reasoning.md +210 -0
- aider/website/docs/config.md +44 -0
- aider/website/docs/faq.md +384 -0
- aider/website/docs/git.md +76 -0
- aider/website/docs/index.md +47 -0
- aider/website/docs/install/codespaces.md +39 -0
- aider/website/docs/install/docker.md +57 -0
- aider/website/docs/install/optional.md +100 -0
- aider/website/docs/install/replit.md +8 -0
- aider/website/docs/install.md +115 -0
- aider/website/docs/languages.md +264 -0
- aider/website/docs/legal/contributor-agreement.md +111 -0
- aider/website/docs/legal/privacy.md +104 -0
- aider/website/docs/llms/anthropic.md +77 -0
- aider/website/docs/llms/azure.md +48 -0
- aider/website/docs/llms/bedrock.md +132 -0
- aider/website/docs/llms/cohere.md +34 -0
- aider/website/docs/llms/deepseek.md +32 -0
- aider/website/docs/llms/gemini.md +49 -0
- aider/website/docs/llms/github.md +111 -0
- aider/website/docs/llms/groq.md +36 -0
- aider/website/docs/llms/lm-studio.md +39 -0
- aider/website/docs/llms/ollama.md +75 -0
- aider/website/docs/llms/openai-compat.md +39 -0
- aider/website/docs/llms/openai.md +58 -0
- aider/website/docs/llms/openrouter.md +78 -0
- aider/website/docs/llms/other.md +117 -0
- aider/website/docs/llms/vertex.md +50 -0
- aider/website/docs/llms/warnings.md +10 -0
- aider/website/docs/llms/xai.md +53 -0
- aider/website/docs/llms.md +54 -0
- aider/website/docs/more/analytics.md +127 -0
- aider/website/docs/more/edit-formats.md +116 -0
- aider/website/docs/more/infinite-output.md +165 -0
- aider/website/docs/more-info.md +8 -0
- aider/website/docs/recordings/auto-accept-architect.md +31 -0
- aider/website/docs/recordings/dont-drop-original-read-files.md +35 -0
- aider/website/docs/recordings/index.md +21 -0
- aider/website/docs/recordings/model-accepts-settings.md +69 -0
- aider/website/docs/recordings/tree-sitter-language-pack.md +80 -0
- aider/website/docs/repomap.md +112 -0
- aider/website/docs/scripting.md +100 -0
- aider/website/docs/sessions.md +203 -0
- aider/website/docs/troubleshooting/aider-not-found.md +24 -0
- aider/website/docs/troubleshooting/edit-errors.md +76 -0
- aider/website/docs/troubleshooting/imports.md +62 -0
- aider/website/docs/troubleshooting/models-and-keys.md +54 -0
- aider/website/docs/troubleshooting/support.md +79 -0
- aider/website/docs/troubleshooting/token-limits.md +96 -0
- aider/website/docs/troubleshooting/warnings.md +12 -0
- aider/website/docs/troubleshooting.md +11 -0
- aider/website/docs/usage/browser.md +57 -0
- aider/website/docs/usage/caching.md +49 -0
- aider/website/docs/usage/commands.md +133 -0
- aider/website/docs/usage/conventions.md +119 -0
- aider/website/docs/usage/copypaste.md +121 -0
- aider/website/docs/usage/images-urls.md +48 -0
- aider/website/docs/usage/lint-test.md +118 -0
- aider/website/docs/usage/modes.md +211 -0
- aider/website/docs/usage/not-code.md +179 -0
- aider/website/docs/usage/notifications.md +87 -0
- aider/website/docs/usage/tips.md +79 -0
- aider/website/docs/usage/tutorials.md +30 -0
- aider/website/docs/usage/voice.md +121 -0
- aider/website/docs/usage/watch.md +294 -0
- aider/website/docs/usage.md +102 -0
- aider/website/share/index.md +101 -0
- aider_ce-0.88.20.dist-info/METADATA +187 -0
- aider_ce-0.88.20.dist-info/RECORD +279 -0
- aider_ce-0.88.20.dist-info/WHEEL +5 -0
- aider_ce-0.88.20.dist-info/entry_points.txt +2 -0
- aider_ce-0.88.20.dist-info/licenses/LICENSE.txt +202 -0
- aider_ce-0.88.20.dist-info/top_level.txt +1 -0
aider/args_formatter.py
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
|
|
3
|
+
from aider import urls
|
|
4
|
+
|
|
5
|
+
from .dump import dump # noqa: F401
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DotEnvFormatter(argparse.HelpFormatter):
|
|
9
|
+
def start_section(self, heading):
|
|
10
|
+
res = "\n\n"
|
|
11
|
+
res += "#" * (len(heading) + 3)
|
|
12
|
+
res += f"\n# {heading}"
|
|
13
|
+
super().start_section(res)
|
|
14
|
+
|
|
15
|
+
def _format_usage(self, usage, actions, groups, prefix):
|
|
16
|
+
return ""
|
|
17
|
+
|
|
18
|
+
def _format_text(self, text):
|
|
19
|
+
return f"""
|
|
20
|
+
##########################################################
|
|
21
|
+
# Sample aider .env file.
|
|
22
|
+
# Place at the root of your git repo.
|
|
23
|
+
# Or use `aider --env <fname>` to specify.
|
|
24
|
+
##########################################################
|
|
25
|
+
|
|
26
|
+
#################
|
|
27
|
+
# LLM parameters:
|
|
28
|
+
#
|
|
29
|
+
# Include xxx_API_KEY parameters and other params needed for your LLMs.
|
|
30
|
+
# See {urls.llms} for details.
|
|
31
|
+
|
|
32
|
+
## OpenAI
|
|
33
|
+
#OPENAI_API_KEY=
|
|
34
|
+
|
|
35
|
+
## Anthropic
|
|
36
|
+
#ANTHROPIC_API_KEY=
|
|
37
|
+
|
|
38
|
+
##...
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def _format_action(self, action):
|
|
42
|
+
if not action.option_strings:
|
|
43
|
+
return ""
|
|
44
|
+
|
|
45
|
+
if not action.env_var:
|
|
46
|
+
return
|
|
47
|
+
|
|
48
|
+
parts = [""]
|
|
49
|
+
|
|
50
|
+
default = action.default
|
|
51
|
+
if default == argparse.SUPPRESS:
|
|
52
|
+
default = ""
|
|
53
|
+
elif isinstance(default, str):
|
|
54
|
+
pass
|
|
55
|
+
elif isinstance(default, list) and not default:
|
|
56
|
+
default = ""
|
|
57
|
+
elif action.default is not None:
|
|
58
|
+
default = "true" if default else "false"
|
|
59
|
+
else:
|
|
60
|
+
default = ""
|
|
61
|
+
|
|
62
|
+
if action.help:
|
|
63
|
+
parts.append(f"## {action.help}")
|
|
64
|
+
|
|
65
|
+
if action.env_var:
|
|
66
|
+
env_var = action.env_var
|
|
67
|
+
if default:
|
|
68
|
+
parts.append(f"#{env_var}={default}\n")
|
|
69
|
+
else:
|
|
70
|
+
parts.append(f"#{env_var}=\n")
|
|
71
|
+
|
|
72
|
+
return "\n".join(parts) + "\n"
|
|
73
|
+
|
|
74
|
+
def _format_action_invocation(self, action):
|
|
75
|
+
return ""
|
|
76
|
+
|
|
77
|
+
def _format_args(self, action, default_metavar):
|
|
78
|
+
return ""
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class YamlHelpFormatter(argparse.HelpFormatter):
|
|
82
|
+
def start_section(self, heading):
|
|
83
|
+
res = "\n\n"
|
|
84
|
+
res += "#" * (len(heading) + 3)
|
|
85
|
+
res += f"\n# {heading}"
|
|
86
|
+
super().start_section(res)
|
|
87
|
+
|
|
88
|
+
def _format_usage(self, usage, actions, groups, prefix):
|
|
89
|
+
return ""
|
|
90
|
+
|
|
91
|
+
def _format_text(self, text):
|
|
92
|
+
return """
|
|
93
|
+
##########################################################
|
|
94
|
+
# Sample .aider.conf.yml
|
|
95
|
+
# This file lists *all* the valid configuration entries.
|
|
96
|
+
# Place in your home dir, or at the root of your git repo.
|
|
97
|
+
##########################################################
|
|
98
|
+
|
|
99
|
+
# Note: You can only put OpenAI and Anthropic API keys in the YAML
|
|
100
|
+
# config file. Keys for all APIs can be stored in a .env file
|
|
101
|
+
# https://aider.chat/docs/config/dotenv.html
|
|
102
|
+
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
def _format_action(self, action):
|
|
106
|
+
if not action.option_strings:
|
|
107
|
+
return ""
|
|
108
|
+
|
|
109
|
+
parts = [""]
|
|
110
|
+
|
|
111
|
+
metavar = action.metavar
|
|
112
|
+
if not metavar and isinstance(action, argparse._StoreAction):
|
|
113
|
+
metavar = "VALUE"
|
|
114
|
+
|
|
115
|
+
default = action.default
|
|
116
|
+
if default == argparse.SUPPRESS:
|
|
117
|
+
default = ""
|
|
118
|
+
elif isinstance(default, str):
|
|
119
|
+
pass
|
|
120
|
+
elif isinstance(default, list) and not default:
|
|
121
|
+
default = ""
|
|
122
|
+
elif action.default is not None:
|
|
123
|
+
default = "true" if default else "false"
|
|
124
|
+
else:
|
|
125
|
+
default = ""
|
|
126
|
+
|
|
127
|
+
if action.help:
|
|
128
|
+
parts.append(f"## {action.help}")
|
|
129
|
+
|
|
130
|
+
for switch in action.option_strings:
|
|
131
|
+
if switch.startswith("--"):
|
|
132
|
+
break
|
|
133
|
+
switch = switch.lstrip("-")
|
|
134
|
+
|
|
135
|
+
if isinstance(action, argparse._StoreTrueAction):
|
|
136
|
+
default = False
|
|
137
|
+
elif isinstance(action, argparse._StoreConstAction):
|
|
138
|
+
default = False
|
|
139
|
+
|
|
140
|
+
if default is False:
|
|
141
|
+
default = "false"
|
|
142
|
+
if default is True:
|
|
143
|
+
default = "true"
|
|
144
|
+
|
|
145
|
+
if default:
|
|
146
|
+
if "#" in default:
|
|
147
|
+
parts.append(f'#{switch}: "{default}"\n')
|
|
148
|
+
else:
|
|
149
|
+
parts.append(f"#{switch}: {default}\n")
|
|
150
|
+
elif action.nargs in ("*", "+") or isinstance(action, argparse._AppendAction):
|
|
151
|
+
parts.append(f"#{switch}: xxx")
|
|
152
|
+
parts.append("## Specify multiple values like this:")
|
|
153
|
+
parts.append(f"#{switch}:")
|
|
154
|
+
parts.append("# - xxx")
|
|
155
|
+
parts.append("# - yyy")
|
|
156
|
+
parts.append("# - zzz")
|
|
157
|
+
else:
|
|
158
|
+
if switch.endswith("color"):
|
|
159
|
+
parts.append(f'#{switch}: "xxx"\n')
|
|
160
|
+
else:
|
|
161
|
+
parts.append(f"#{switch}: xxx\n")
|
|
162
|
+
|
|
163
|
+
###
|
|
164
|
+
# parts.append(str(action))
|
|
165
|
+
|
|
166
|
+
return "\n".join(parts) + "\n"
|
|
167
|
+
|
|
168
|
+
def _format_action_invocation(self, action):
|
|
169
|
+
return ""
|
|
170
|
+
|
|
171
|
+
def _format_args(self, action, default_metavar):
|
|
172
|
+
return ""
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class MarkdownHelpFormatter(argparse.HelpFormatter):
|
|
176
|
+
def start_section(self, heading):
|
|
177
|
+
super().start_section(f"## {heading}")
|
|
178
|
+
|
|
179
|
+
def _format_usage(self, usage, actions, groups, prefix):
|
|
180
|
+
res = super()._format_usage(usage, actions, groups, prefix)
|
|
181
|
+
quote = "```\n"
|
|
182
|
+
return quote + res + quote
|
|
183
|
+
|
|
184
|
+
def _format_text(self, text):
|
|
185
|
+
return ""
|
|
186
|
+
|
|
187
|
+
def _format_action(self, action):
|
|
188
|
+
if not action.option_strings:
|
|
189
|
+
return ""
|
|
190
|
+
|
|
191
|
+
parts = [""]
|
|
192
|
+
|
|
193
|
+
metavar = action.metavar
|
|
194
|
+
if not metavar and isinstance(action, argparse._StoreAction):
|
|
195
|
+
metavar = "VALUE"
|
|
196
|
+
|
|
197
|
+
for switch in action.option_strings:
|
|
198
|
+
if switch.startswith("--"):
|
|
199
|
+
break
|
|
200
|
+
|
|
201
|
+
if metavar:
|
|
202
|
+
parts.append(f"### `{switch} {metavar}`")
|
|
203
|
+
else:
|
|
204
|
+
parts.append(f"### `{switch}`")
|
|
205
|
+
if action.help:
|
|
206
|
+
parts.append(action.help + " ")
|
|
207
|
+
|
|
208
|
+
if action.default not in (argparse.SUPPRESS, None):
|
|
209
|
+
parts.append(f"Default: {action.default} ")
|
|
210
|
+
|
|
211
|
+
if action.env_var:
|
|
212
|
+
parts.append(f"Environment variable: `{action.env_var}` ")
|
|
213
|
+
|
|
214
|
+
if len(action.option_strings) > 1:
|
|
215
|
+
parts.append("Aliases:")
|
|
216
|
+
for switch in action.option_strings:
|
|
217
|
+
if metavar:
|
|
218
|
+
parts.append(f" - `{switch} {metavar}`")
|
|
219
|
+
else:
|
|
220
|
+
parts.append(f" - `{switch}`")
|
|
221
|
+
|
|
222
|
+
return "\n".join(parts) + "\n"
|
|
223
|
+
|
|
224
|
+
def _format_action_invocation(self, action):
|
|
225
|
+
return ""
|
|
226
|
+
|
|
227
|
+
def _format_args(self, action, default_metavar):
|
|
228
|
+
return ""
|
aider/change_tracker.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import uuid
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ChangeTracker:
|
|
7
|
+
"""
|
|
8
|
+
Tracks changes made to files for the undo functionality.
|
|
9
|
+
This enables granular editing operations with the ability to undo specific changes.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
self.changes = {} # change_id -> change_info
|
|
14
|
+
self.files_changed = defaultdict(list) # file_path -> [change_ids]
|
|
15
|
+
|
|
16
|
+
def track_change(
|
|
17
|
+
self, file_path, change_type, original_content, new_content, metadata=None, change_id=None
|
|
18
|
+
):
|
|
19
|
+
"""
|
|
20
|
+
Record a change to enable future undo operations.
|
|
21
|
+
|
|
22
|
+
Parameters:
|
|
23
|
+
- file_path: Path to the file that was changed
|
|
24
|
+
- change_type: Type of change (e.g., 'replacetext', 'insertlines')
|
|
25
|
+
- original_content: Original content before the change
|
|
26
|
+
- new_content: New content after the change
|
|
27
|
+
- metadata: Additional information about the change (line numbers, positions, etc.)
|
|
28
|
+
- change_id: Optional custom ID for the change (if None, one will be generated)
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
- change_id: Unique identifier for the change
|
|
32
|
+
"""
|
|
33
|
+
if change_id is None:
|
|
34
|
+
generated_id = self._generate_change_id()
|
|
35
|
+
# Ensure the generated ID is treated as a string
|
|
36
|
+
current_change_id = str(generated_id)
|
|
37
|
+
else:
|
|
38
|
+
# If an ID is provided, ensure it's treated as a string key/value
|
|
39
|
+
current_change_id = str(change_id)
|
|
40
|
+
|
|
41
|
+
# Defensive check: Ensure the ID isn't literally the string 'False' or boolean False
|
|
42
|
+
# which might indicate an upstream issue or unexpected input.
|
|
43
|
+
if current_change_id == "False" or current_change_id is False:
|
|
44
|
+
# Log a warning? For now, generate a new ID to prevent storing False.
|
|
45
|
+
print(f"Warning: change_id evaluated to False for {file_path}. Generating new ID.")
|
|
46
|
+
current_change_id = self._generate_change_id()
|
|
47
|
+
|
|
48
|
+
change = {
|
|
49
|
+
# Use the confirmed string ID here
|
|
50
|
+
"id": current_change_id,
|
|
51
|
+
"file_path": file_path,
|
|
52
|
+
"type": change_type,
|
|
53
|
+
"original": original_content,
|
|
54
|
+
"new": new_content,
|
|
55
|
+
"metadata": metadata or {},
|
|
56
|
+
"timestamp": time.time(),
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# Use the confirmed string ID for storage and return
|
|
60
|
+
self.changes[current_change_id] = change
|
|
61
|
+
self.files_changed[file_path].append(current_change_id)
|
|
62
|
+
return current_change_id
|
|
63
|
+
|
|
64
|
+
def undo_change(self, change_id):
|
|
65
|
+
"""
|
|
66
|
+
Get information needed to reverse a specific change by ID.
|
|
67
|
+
|
|
68
|
+
Parameters:
|
|
69
|
+
- change_id: ID of the change to undo
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
- (success, message, change_info): Tuple with success flag, message, and change information
|
|
73
|
+
"""
|
|
74
|
+
if change_id not in self.changes:
|
|
75
|
+
return False, f"Change ID {change_id} not found", None
|
|
76
|
+
|
|
77
|
+
change = self.changes[change_id]
|
|
78
|
+
|
|
79
|
+
# Mark this change as undone by removing it from the tracking dictionaries
|
|
80
|
+
self.files_changed[change["file_path"]].remove(change_id)
|
|
81
|
+
if not self.files_changed[change["file_path"]]:
|
|
82
|
+
del self.files_changed[change["file_path"]]
|
|
83
|
+
|
|
84
|
+
# Keep the change in the changes dict but mark it as undone
|
|
85
|
+
change["undone"] = True
|
|
86
|
+
change["undone_at"] = time.time()
|
|
87
|
+
|
|
88
|
+
return True, f"Undid change {change_id} in {change['file_path']}", change
|
|
89
|
+
|
|
90
|
+
def get_last_change(self, file_path):
|
|
91
|
+
"""
|
|
92
|
+
Get the most recent change for a specific file.
|
|
93
|
+
|
|
94
|
+
Parameters:
|
|
95
|
+
- file_path: Path to the file
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
- change_id or None if no changes found
|
|
99
|
+
"""
|
|
100
|
+
changes = self.files_changed.get(file_path, [])
|
|
101
|
+
if not changes:
|
|
102
|
+
return None
|
|
103
|
+
return changes[-1]
|
|
104
|
+
|
|
105
|
+
def list_changes(self, file_path=None, limit=10):
|
|
106
|
+
"""
|
|
107
|
+
List recent changes, optionally filtered by file.
|
|
108
|
+
|
|
109
|
+
Parameters:
|
|
110
|
+
- file_path: Optional path to filter changes by file
|
|
111
|
+
- limit: Maximum number of changes to list
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
- List of change dictionaries
|
|
115
|
+
"""
|
|
116
|
+
if file_path:
|
|
117
|
+
# Get changes only for the specified file
|
|
118
|
+
change_ids = self.files_changed.get(file_path, [])
|
|
119
|
+
changes = [self.changes[cid] for cid in change_ids if cid in self.changes]
|
|
120
|
+
else:
|
|
121
|
+
# Get all changes
|
|
122
|
+
changes = list(self.changes.values())
|
|
123
|
+
|
|
124
|
+
# Filter out undone changes and sort by timestamp (most recent first)
|
|
125
|
+
changes = [c for c in changes if not c.get("undone", False)]
|
|
126
|
+
changes = sorted(changes, key=lambda c: c["timestamp"], reverse=True)
|
|
127
|
+
|
|
128
|
+
# Apply limit
|
|
129
|
+
return changes[:limit]
|
|
130
|
+
|
|
131
|
+
def _generate_change_id(self):
|
|
132
|
+
"""Generate a unique ID for a change."""
|
|
133
|
+
return str(uuid.uuid4())[:8] # Short, readable ID
|
aider/coders/__init__.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from .agent_coder import AgentCoder
|
|
2
|
+
from .architect_coder import ArchitectCoder
|
|
3
|
+
from .ask_coder import AskCoder
|
|
4
|
+
from .base_coder import Coder
|
|
5
|
+
from .context_coder import ContextCoder
|
|
6
|
+
from .editblock_coder import EditBlockCoder
|
|
7
|
+
from .editblock_fenced_coder import EditBlockFencedCoder
|
|
8
|
+
from .editor_diff_fenced_coder import EditorDiffFencedCoder
|
|
9
|
+
from .editor_editblock_coder import EditorEditBlockCoder
|
|
10
|
+
from .editor_whole_coder import EditorWholeFileCoder
|
|
11
|
+
from .help_coder import HelpCoder
|
|
12
|
+
from .patch_coder import PatchCoder
|
|
13
|
+
from .udiff_coder import UnifiedDiffCoder
|
|
14
|
+
from .udiff_simple import UnifiedDiffSimpleCoder
|
|
15
|
+
from .wholefile_coder import WholeFileCoder
|
|
16
|
+
|
|
17
|
+
# from .single_wholefile_func_coder import SingleWholeFileFunctionCoder
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
HelpCoder,
|
|
21
|
+
AskCoder,
|
|
22
|
+
Coder,
|
|
23
|
+
EditBlockCoder,
|
|
24
|
+
EditBlockFencedCoder,
|
|
25
|
+
WholeFileCoder,
|
|
26
|
+
PatchCoder,
|
|
27
|
+
UnifiedDiffCoder,
|
|
28
|
+
UnifiedDiffSimpleCoder,
|
|
29
|
+
# SingleWholeFileFunctionCoder,
|
|
30
|
+
ArchitectCoder,
|
|
31
|
+
EditorEditBlockCoder,
|
|
32
|
+
EditorWholeFileCoder,
|
|
33
|
+
EditorDiffFencedCoder,
|
|
34
|
+
ContextCoder,
|
|
35
|
+
AgentCoder,
|
|
36
|
+
]
|