-
Notifications
You must be signed in to change notification settings - Fork 84
feat(templates): Add AGENTS.md/CLAUDE.md to templates #3399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Reviewer's GuideAdds AGENTS.md AI-agent development guides to tap, target, and mapper cookiecutter templates, and introduces a cookiecutter flag and post-gen hooks to optionally omit these files, updating test cookiecutter configs accordingly. Sequence diagram for cookiecutter project generation with optional AGENTS_mdsequenceDiagram
actor Developer
participant Cookiecutter
participant Post_gen_hook_mapper as Post_gen_hook_mapper
participant Post_gen_hook_tap as Post_gen_hook_tap
participant Post_gen_hook_target as Post_gen_hook_target
participant FileSystem
Developer->>Cookiecutter: Run mapper/tap/target template
Cookiecutter->>FileSystem: Render project files
Note over Cookiecutter,FileSystem: AGENTS_md is rendered by default
alt Mapper template
Cookiecutter->>Post_gen_hook_mapper: Execute post_gen_project
Post_gen_hook_mapper->>Post_gen_hook_mapper: Check include_agents_md flag
alt include_agents_md is false
Post_gen_hook_mapper->>FileSystem: Delete AGENTS_md
else include_agents_md is true
Post_gen_hook_mapper->>FileSystem: Keep AGENTS_md
end
else Tap template
Cookiecutter->>Post_gen_hook_tap: Execute post_gen_project
Post_gen_hook_tap->>Post_gen_hook_tap: Check include_agents_md flag
alt include_agents_md is false
Post_gen_hook_tap->>FileSystem: Delete AGENTS_md
else include_agents_md is true
Post_gen_hook_tap->>FileSystem: Keep AGENTS_md
end
else Target template
Cookiecutter->>Post_gen_hook_target: Execute post_gen_project
Post_gen_hook_target->>Post_gen_hook_target: Check include_agents_md flag
alt include_agents_md is false
Post_gen_hook_target->>FileSystem: Delete AGENTS_md
else include_agents_md is true
Post_gen_hook_target->>FileSystem: Keep AGENTS_md
end
end
Cookiecutter-->>Developer: Generated project (with or without AGENTS_md)
Flow diagram for post_gen_project handling of AGENTS_mdflowchart TD
A_start["Start post_gen_project hook"] --> B_check_ide["Check cookiecutter_ide value"]
B_check_ide -->|ide != VSCode| C_remove_vscode["Remove .vscode directory"]
B_check_ide -->|ide == VSCode| D_skip_vscode["Skip .vscode removal"]
C_remove_vscode --> E_check_agents["Check include_agents_md flag"]
D_skip_vscode --> E_check_agents
E_check_agents -->|include_agents_md is true| F_keep_agents["Keep AGENTS_md in project"]
E_check_agents -->|include_agents_md is false| G_delete_agents["Delete AGENTS_md if present"]
F_keep_agents --> H_end["End hook"]
G_delete_agents --> H_end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
a06bfe9 to
1b413d7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes - here's some feedback:
- In the post-gen hooks, consider using the existing
BASE_PATH(or an equivalent project root Path) when unlinkingAGENTS.mdinstead of relying on the current working directory, to keep path handling consistent with the rest of the hook logic and avoid CWD-related surprises. - The three AGENTS.md templates share a lot of overlapping guidance; consider extracting common sections into shared cookiecutter partials/includes so updates to the guidance only need to be made in one place.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In the post-gen hooks, consider using the existing `BASE_PATH` (or an equivalent project root Path) when unlinking `AGENTS.md` instead of relying on the current working directory, to keep path handling consistent with the rest of the hook logic and avoid CWD-related surprises.
- The three AGENTS.md templates share a lot of overlapping guidance; consider extracting common sections into shared cookiecutter partials/includes so updates to the guidance only need to be made in one place.
## Individual Comments
### Comment 1
<location> `cookiecutter/mapper-template/hooks/post_gen_project.py:27-29` </location>
<code_context>
from pathlib import Path
import shutil
BASE_PATH = Path("{{cookiecutter.library_name}}")
if __name__ == "__main__":
# Handle license selection
license_choice = "{{ cookiecutter.license }}"
if license_choice == "Apache-2.0":
Path("LICENSE-Apache-2.0").rename("LICENSE")
Path("LICENSE-MIT").unlink()
elif license_choice == "MIT":
Path("LICENSE-MIT").rename("LICENSE")
Path("LICENSE-Apache-2.0").unlink()
elif license_choice == "None":
Path("LICENSE-Apache-2.0").unlink()
Path("LICENSE-MIT").unlink()
if "{{ cookiecutter.include_ci_files }}" != "GitHub":
shutil.rmtree(Path(".github"))
if "{{ cookiecutter.ide }}" != "VSCode":
shutil.rmtree(".vscode", ignore_errors=True)
if not {{ cookiecutter.include_agents_md }}:
Path("AGENTS.md").unlink(missing_ok=True)
</code_context>
<issue_to_address>
**suggestion (code-quality):** We've found these issues:
- Remove redundant conditional ([`remove-redundant-if`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/remove-redundant-if/))
- Replace constant collection with boolean in boolean contexts ([`collection-to-bool`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/collection-to-bool/))
```suggestion
```
</issue_to_address>
### Comment 2
<location> `cookiecutter/tap-template/hooks/post_gen_project.py:57-59` </location>
<code_context>
from pathlib import Path
import shutil
PACKAGE_PATH = Path("{{cookiecutter.library_name}}")
if __name__ == "__main__":
# Rename stream type client and delete others
target = PACKAGE_PATH / "client.py"
raw_client_py = PACKAGE_PATH / "{{cookiecutter.stream_type|lower}}-client.py"
raw_client_py.rename(target)
for client_py in PACKAGE_PATH.rglob("*-client.py"):
client_py.unlink()
# Select appropriate tap.py based on stream type
tap_target = PACKAGE_PATH / "tap.py"
if "{{ cookiecutter.stream_type }}" == "SQL":
sql_tap_py = PACKAGE_PATH / "sql-tap.py"
sql_tap_py.rename(tap_target)
else:
non_sql_tap_py = PACKAGE_PATH / "non-sql-tap.py"
non_sql_tap_py.rename(tap_target)
# Clean up remaining tap template files
for tap_py in PACKAGE_PATH.rglob("*-tap.py"):
tap_py.unlink()
if "{{ cookiecutter.stream_type }}" != "REST":
shutil.rmtree(PACKAGE_PATH.joinpath("schemas"), ignore_errors=True)
if "{{ cookiecutter.auth_method }}" not in ("OAuth2", "JWT"):
PACKAGE_PATH.joinpath("auth.py").unlink()
if "{{ cookiecutter.stream_type }}" == "SQL":
PACKAGE_PATH.joinpath("streams.py").unlink()
# Handle license selection
license_choice = "{{ cookiecutter.license }}"
if license_choice == "Apache-2.0":
Path("LICENSE-Apache-2.0").rename("LICENSE")
Path("LICENSE-MIT").unlink()
elif license_choice == "MIT":
Path("LICENSE-MIT").rename("LICENSE")
Path("LICENSE-Apache-2.0").unlink()
elif license_choice == "None":
Path("LICENSE-Apache-2.0").unlink()
Path("LICENSE-MIT").unlink()
if "{{ cookiecutter.include_ci_files }}" != "GitHub":
shutil.rmtree(".github")
if "{{ cookiecutter.ide }}" != "VSCode":
shutil.rmtree(".vscode", ignore_errors=True)
if not {{ cookiecutter.include_agents_md }}:
Path("AGENTS.md").unlink(missing_ok=True)
</code_context>
<issue_to_address>
**suggestion (code-quality):** We've found these issues:
- Remove redundant conditional ([`remove-redundant-if`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/remove-redundant-if/))
- Replace constant collection with boolean in boolean contexts ([`collection-to-bool`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/collection-to-bool/))
```suggestion
```
</issue_to_address>
### Comment 3
<location> `cookiecutter/target-template/hooks/post_gen_project.py:52-54` </location>
<code_context>
from pathlib import Path
import shutil
BASE_PATH = Path("{{cookiecutter.library_name}}")
if __name__ == "__main__":
# Handle license selection
license_choice = "{{ cookiecutter.license }}"
if license_choice == "Apache-2.0":
Path("LICENSE-Apache-2.0").rename("LICENSE")
Path("LICENSE-MIT").unlink()
elif license_choice == "MIT":
Path("LICENSE-MIT").rename("LICENSE")
Path("LICENSE-Apache-2.0").unlink()
elif license_choice == "None":
Path("LICENSE-Apache-2.0").unlink()
Path("LICENSE-MIT").unlink()
if "{{ cookiecutter.include_ci_files }}" != "GitHub":
shutil.rmtree(Path(".github"))
if "{{ cookiecutter.ide }}" != "VSCode":
shutil.rmtree(".vscode", ignore_errors=True)
# Choose the appropriate sinks file based on serialization method
serialization_method = "{{ cookiecutter.serialization_method }}"
if serialization_method == "Per record":
source_file = BASE_PATH / "sinks_record.py"
elif serialization_method == "Per batch":
source_file = BASE_PATH / "sinks_batch.py"
elif serialization_method == "SQL":
source_file = BASE_PATH / "sinks_sql.py"
else:
valid_methods = ["Per record", "Per batch", "SQL"]
msg = (
f"Unknown serialization method: {serialization_method}. "
f"Valid methods are: {', '.join(valid_methods)}"
)
raise ValueError(msg)
# Copy the appropriate sinks file to sinks.py
target_file = BASE_PATH / "sinks.py"
shutil.copy2(source_file, target_file)
# Clean up the unused sink files
for template in ["sinks_record.py", "sinks_batch.py", "sinks_sql.py"]:
(BASE_PATH / template).unlink(missing_ok=True)
if not {{ cookiecutter.include_agents_md }}:
Path("AGENTS.md").unlink(missing_ok=True)
</code_context>
<issue_to_address>
**suggestion (code-quality):** We've found these issues:
- Remove redundant conditional ([`remove-redundant-if`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/remove-redundant-if/))
- Replace constant collection with boolean in boolean contexts ([`collection-to-bool`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/collection-to-bool/))
```suggestion
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Signed-off-by: Edgar Ramírez Mondragón <edgarrm358@gmail.com>
for more information, see https://pre-commit.ci
Update cookiecutter post-generation hooks to create both AGENTS.md (for broad AI tool ecosystem) and CLAUDE.md (for Claude Code) with identical content. This ensures generated projects work with Claude Code immediately while maintaining compatibility with 20+ other AI coding assistants. Uses AGENTS.md as the single source of truth, copying to CLAUDE.md via shutil.copy2 to avoid symlink cross-platform issues on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
f471199 to
42f687b
Compare
Links
Summary by Sourcery
Add optional AGENTS.md AI agent guidance files to tap, target, and mapper cookiecutter templates and ensure they are conditionally included based on a new template flag.
New Features:
Tests: