codecrate 0.1.0__tar.gz → 0.1.1__tar.gz
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.
- {codecrate-0.1.0 → codecrate-0.1.1}/.gitignore +1 -0
- codecrate-0.1.1/AGENTS.md +159 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/PKG-INFO +1 -1
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/_version.py +3 -3
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/cli.py +6 -5
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/config.py +13 -4
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/parse.py +3 -1
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/PKG-INFO +1 -1
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/SOURCES.txt +1 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/.github/pytest.ini +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/.github/workflows/codecov.yml +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/.github/workflows/pre-commit.yml +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/.github/workflows/python-publish.yml +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/.github/workflows/tests.yml +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/.pre-commit-config.yaml +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/.readthedocs.yaml +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/.ruff.toml +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/LICENSE +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/README.md +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/__init__.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/diffgen.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/discover.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/ids.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/manifest.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/markdown.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/mdparse.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/model.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/packer.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/stubber.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/token_budget.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/udiff.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/unpacker.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/validate.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/dependency_links.txt +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/entry_points.txt +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/requires.txt +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/top_level.txt +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.toml +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/docs/api.rst +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/docs/cli.rst +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/docs/conf.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/docs/format.rst +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/docs/index.rst +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/docs/make.bat +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/docs/make.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/docs/quickstart.rst +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/docs/requirements.txt +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/pyproject.toml +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/requirements-test.txt +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/setup.cfg +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/setup.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/__init__.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_config.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_discover.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_ids.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_markdown_line_numbers.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_model.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_pack_unpack_roundtrip.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_parse.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_patch_apply_roundtrip.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_smoke.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_split_codecrate_pack.py +0 -0
- {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_token_budget.py +0 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This file summarizes how to work in this repository for agentic tooling.
|
|
4
|
+
Follow these conventions unless a task explicitly requires otherwise.
|
|
5
|
+
|
|
6
|
+
## Repository Overview
|
|
7
|
+
|
|
8
|
+
- Project: `codecrate` (Python library + CLI)
|
|
9
|
+
- Package directory: `codecrate/`
|
|
10
|
+
- Tests: `tests/` with pytest
|
|
11
|
+
- Python support: 3.10+ (see `pyproject.toml`)
|
|
12
|
+
- Lint/format tooling: ruff + ruff-format (`.ruff.toml`)
|
|
13
|
+
- Pre-commit hooks: ruff, ruff-format, plus general hooks
|
|
14
|
+
|
|
15
|
+
## Key Config Files
|
|
16
|
+
|
|
17
|
+
- `pyproject.toml`: build metadata, optional deps, mypy config
|
|
18
|
+
- `.ruff.toml`: lint + format rules (target version, import order, complexity)
|
|
19
|
+
- `.pre-commit-config.yaml`: formatting and linting hooks
|
|
20
|
+
- `.github/workflows/tests.yml`: CI test commands
|
|
21
|
+
- `.github/pytest.ini`: pytest defaults (`-rw`, ignore dirs)
|
|
22
|
+
- `codecrate.toml`: runtime config for pack/unpack behavior
|
|
23
|
+
|
|
24
|
+
## Setup
|
|
25
|
+
|
|
26
|
+
Common install paths used in CI and docs:
|
|
27
|
+
|
|
28
|
+
- `uv pip install -e .`
|
|
29
|
+
|
|
30
|
+
## Build, Lint, Format, Test Commands
|
|
31
|
+
|
|
32
|
+
Run these from the repository root:
|
|
33
|
+
|
|
34
|
+
- Format: `ruff format .`
|
|
35
|
+
- Lint: `ruff check .`
|
|
36
|
+
- Lint + autofix: `ruff check --fix .`
|
|
37
|
+
- All tests: `pytest`
|
|
38
|
+
- Pre-commit hooks: `pre-commit run --all-files`
|
|
39
|
+
|
|
40
|
+
## Running a Single Test
|
|
41
|
+
|
|
42
|
+
Typical pytest patterns:
|
|
43
|
+
|
|
44
|
+
- One file: `pytest tests/test_parse.py`
|
|
45
|
+
- One test: `pytest tests/test_parse.py::test_parse_basic`
|
|
46
|
+
- By keyword: `pytest -k line_numbers`
|
|
47
|
+
- Show stdout: `pytest -s tests/test_smoke.py::test_cli_pack`
|
|
48
|
+
|
|
49
|
+
Pytest defaults (`.github/pytest.ini`) include:
|
|
50
|
+
|
|
51
|
+
- `addopts = -rw`
|
|
52
|
+
- `norecursedirs = .git .* *.egg* old dist build`
|
|
53
|
+
|
|
54
|
+
## Formatting and Linting Rules
|
|
55
|
+
|
|
56
|
+
Ruff is the source of truth for formatting and linting.
|
|
57
|
+
Configuration lives in `.ruff.toml`.
|
|
58
|
+
|
|
59
|
+
- Target Python: 3.10 (`target-version = "py310"`)
|
|
60
|
+
- Line length: ruff E501 defaults (88 unless configured otherwise)
|
|
61
|
+
- Import sorting: ruff isort with sections
|
|
62
|
+
- Complexity limit: McCabe max 22
|
|
63
|
+
|
|
64
|
+
When editing code, prefer running:
|
|
65
|
+
|
|
66
|
+
- `ruff format .`
|
|
67
|
+
- `ruff check --fix .`
|
|
68
|
+
|
|
69
|
+
## Import Conventions
|
|
70
|
+
|
|
71
|
+
Follow the existing import layout:
|
|
72
|
+
|
|
73
|
+
- `from __future__ import annotations` at the top of each module
|
|
74
|
+
- Standard library imports first
|
|
75
|
+
- Third-party imports next (rare here)
|
|
76
|
+
- First-party imports last (`codecrate.*` or relative)
|
|
77
|
+
- Keep imports sorted by ruff/isort
|
|
78
|
+
|
|
79
|
+
`__init__.py` files may intentionally have unused imports; ruff ignores
|
|
80
|
+
F401/I001 there (see `.ruff.toml`).
|
|
81
|
+
|
|
82
|
+
## Type Hints and Static Analysis
|
|
83
|
+
|
|
84
|
+
Type hints are expected on public functions and helpers.
|
|
85
|
+
The mypy config is strict, so avoid untyped defs when possible.
|
|
86
|
+
|
|
87
|
+
- Use `list[str]`, `dict[str, str]`, etc. (PEP 585 style)
|
|
88
|
+
- Prefer explicit `Optional[T]` via `T | None`
|
|
89
|
+
- Avoid implicit `Any` in new code
|
|
90
|
+
|
|
91
|
+
## Naming Conventions
|
|
92
|
+
|
|
93
|
+
- Modules, functions, variables: `snake_case`
|
|
94
|
+
- Classes, dataclasses: `PascalCase`
|
|
95
|
+
- Constants: `UPPER_SNAKE_CASE`
|
|
96
|
+
- Private helpers: `_leading_underscore`
|
|
97
|
+
|
|
98
|
+
Follow existing naming in each module; avoid inventing new prefixes.
|
|
99
|
+
|
|
100
|
+
## File and Path Handling
|
|
101
|
+
|
|
102
|
+
The codebase favors `pathlib.Path`:
|
|
103
|
+
|
|
104
|
+
- Use `Path` instead of `os.path`
|
|
105
|
+
- For file IO, use `read_text`/`write_text`
|
|
106
|
+
- When reading text, pass `encoding="utf-8"` and `errors="replace"`
|
|
107
|
+
- Use `as_posix()` when storing relative paths
|
|
108
|
+
|
|
109
|
+
## Error Handling and Warnings
|
|
110
|
+
|
|
111
|
+
Keep error handling explicit and narrow:
|
|
112
|
+
|
|
113
|
+
- Raise `ValueError` for invalid user input
|
|
114
|
+
- Use `warnings.warn(..., RuntimeWarning)` for recoverable issues
|
|
115
|
+
- Avoid bare `except:` and broad `except Exception:` unless needed
|
|
116
|
+
- Prefer returning empty values over crashing when data is missing
|
|
117
|
+
|
|
118
|
+
## General Coding Practices
|
|
119
|
+
|
|
120
|
+
- Prefer small, focused helpers with explicit inputs/outputs
|
|
121
|
+
- Keep side effects near the CLI or IO boundaries
|
|
122
|
+
- Use dataclasses for structured data (see `codecrate/model.py`)
|
|
123
|
+
- Preserve existing section ordering in generated markdown
|
|
124
|
+
|
|
125
|
+
## Markdown and Output Formatting
|
|
126
|
+
|
|
127
|
+
Generated Markdown is line-sensitive. When modifying output:
|
|
128
|
+
|
|
129
|
+
- Preserve existing headings and section order
|
|
130
|
+
- Keep code fences exact (` ```python ` or ` ```diff `)
|
|
131
|
+
- Avoid adding trailing whitespace
|
|
132
|
+
|
|
133
|
+
## Tests and Fixtures
|
|
134
|
+
|
|
135
|
+
Tests are pytest-based and generally use `tmp_path`.
|
|
136
|
+
Keep tests deterministic and avoid external IO or network access.
|
|
137
|
+
|
|
138
|
+
- Use `tmp_path` for temp repos
|
|
139
|
+
- Use `Path.write_text(..., encoding="utf-8")`
|
|
140
|
+
- Prefer exact string comparisons for rendered output
|
|
141
|
+
|
|
142
|
+
## CLI and Commands
|
|
143
|
+
|
|
144
|
+
The CLI entrypoint is `codecrate.cli:main`.
|
|
145
|
+
When adding CLI flags, update both the parser and README if needed.
|
|
146
|
+
|
|
147
|
+
Quick reference:
|
|
148
|
+
|
|
149
|
+
- Pack: `codecrate pack . -o context.md`
|
|
150
|
+
- Unpack: `codecrate unpack context.md -o out_dir/`
|
|
151
|
+
- Patch: `codecrate patch baseline.md . -o changes.md`
|
|
152
|
+
- Apply: `codecrate apply changes.md .`
|
|
153
|
+
- Validate: `codecrate validate-pack context.md`
|
|
154
|
+
|
|
155
|
+
## Docs
|
|
156
|
+
|
|
157
|
+
Sphinx config lives under `docs/` (see `docs/conf.py`).
|
|
158
|
+
No automated doc build is configured in CI, but keep docs consistent
|
|
159
|
+
with CLI and configuration behavior.
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
31
|
+
__version__ = version = '0.1.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 1)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g4591edb4c'
|
|
@@ -175,11 +175,12 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
175
175
|
if args.layout is not None
|
|
176
176
|
else str(getattr(cfg, "layout", "auto")).strip().lower()
|
|
177
177
|
)
|
|
178
|
-
|
|
179
|
-
args.output
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
178
|
+
if args.output is not None:
|
|
179
|
+
out_path = args.output
|
|
180
|
+
else:
|
|
181
|
+
out_path = Path(getattr(cfg, "output", "context.md"))
|
|
182
|
+
if not out_path.is_absolute():
|
|
183
|
+
out_path = root / out_path
|
|
183
184
|
disc = discover_files(
|
|
184
185
|
root=root,
|
|
185
186
|
include=include,
|
|
@@ -61,10 +61,19 @@ def load_config(root: Path) -> Config:
|
|
|
61
61
|
return Config()
|
|
62
62
|
|
|
63
63
|
data = tomllib.loads(cfg_path.read_text(encoding="utf-8"))
|
|
64
|
-
section: dict[str, Any] =
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
section: dict[str, Any] = {}
|
|
65
|
+
if isinstance(data, dict):
|
|
66
|
+
# Preferred: [codecrate]
|
|
67
|
+
cc = data.get("codecrate")
|
|
68
|
+
if isinstance(cc, dict):
|
|
69
|
+
section = cc
|
|
70
|
+
else:
|
|
71
|
+
# Also accept: [tool.codecrate] (common convention from pyproject.toml)
|
|
72
|
+
tool = data.get("tool")
|
|
73
|
+
if isinstance(tool, dict):
|
|
74
|
+
cc2 = tool.get("codecrate")
|
|
75
|
+
if isinstance(cc2, dict):
|
|
76
|
+
section = cc2
|
|
68
77
|
cfg = Config()
|
|
69
78
|
out = section.get("output", cfg.output)
|
|
70
79
|
if isinstance(out, str) and out.strip():
|
|
@@ -127,7 +127,9 @@ class _Visitor(ast.NodeVisitor):
|
|
|
127
127
|
def parse_symbols(
|
|
128
128
|
path: Path, root: Path, text: str
|
|
129
129
|
) -> tuple[list[ClassRef], list[DefRef]]:
|
|
130
|
-
|
|
130
|
+
# Pass filename so SyntaxWarnings (e.g. invalid escape sequences) point to
|
|
131
|
+
# the real file instead of "<unknown>".
|
|
132
|
+
tree = ast.parse(text, filename=path.as_posix())
|
|
131
133
|
v = _Visitor(path=path, root=root)
|
|
132
134
|
v.visit(tree)
|
|
133
135
|
return v.classes, v.defs
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|