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.
Files changed (63) hide show
  1. {codecrate-0.1.0 → codecrate-0.1.1}/.gitignore +1 -0
  2. codecrate-0.1.1/AGENTS.md +159 -0
  3. {codecrate-0.1.0 → codecrate-0.1.1}/PKG-INFO +1 -1
  4. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/_version.py +3 -3
  5. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/cli.py +6 -5
  6. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/config.py +13 -4
  7. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/parse.py +3 -1
  8. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/PKG-INFO +1 -1
  9. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/SOURCES.txt +1 -0
  10. {codecrate-0.1.0 → codecrate-0.1.1}/.github/pytest.ini +0 -0
  11. {codecrate-0.1.0 → codecrate-0.1.1}/.github/workflows/codecov.yml +0 -0
  12. {codecrate-0.1.0 → codecrate-0.1.1}/.github/workflows/pre-commit.yml +0 -0
  13. {codecrate-0.1.0 → codecrate-0.1.1}/.github/workflows/python-publish.yml +0 -0
  14. {codecrate-0.1.0 → codecrate-0.1.1}/.github/workflows/tests.yml +0 -0
  15. {codecrate-0.1.0 → codecrate-0.1.1}/.pre-commit-config.yaml +0 -0
  16. {codecrate-0.1.0 → codecrate-0.1.1}/.readthedocs.yaml +0 -0
  17. {codecrate-0.1.0 → codecrate-0.1.1}/.ruff.toml +0 -0
  18. {codecrate-0.1.0 → codecrate-0.1.1}/LICENSE +0 -0
  19. {codecrate-0.1.0 → codecrate-0.1.1}/README.md +0 -0
  20. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/__init__.py +0 -0
  21. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/diffgen.py +0 -0
  22. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/discover.py +0 -0
  23. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/ids.py +0 -0
  24. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/manifest.py +0 -0
  25. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/markdown.py +0 -0
  26. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/mdparse.py +0 -0
  27. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/model.py +0 -0
  28. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/packer.py +0 -0
  29. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/stubber.py +0 -0
  30. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/token_budget.py +0 -0
  31. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/udiff.py +0 -0
  32. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/unpacker.py +0 -0
  33. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate/validate.py +0 -0
  34. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/dependency_links.txt +0 -0
  35. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/entry_points.txt +0 -0
  36. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/requires.txt +0 -0
  37. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.egg-info/top_level.txt +0 -0
  38. {codecrate-0.1.0 → codecrate-0.1.1}/codecrate.toml +0 -0
  39. {codecrate-0.1.0 → codecrate-0.1.1}/docs/api.rst +0 -0
  40. {codecrate-0.1.0 → codecrate-0.1.1}/docs/cli.rst +0 -0
  41. {codecrate-0.1.0 → codecrate-0.1.1}/docs/conf.py +0 -0
  42. {codecrate-0.1.0 → codecrate-0.1.1}/docs/format.rst +0 -0
  43. {codecrate-0.1.0 → codecrate-0.1.1}/docs/index.rst +0 -0
  44. {codecrate-0.1.0 → codecrate-0.1.1}/docs/make.bat +0 -0
  45. {codecrate-0.1.0 → codecrate-0.1.1}/docs/make.py +0 -0
  46. {codecrate-0.1.0 → codecrate-0.1.1}/docs/quickstart.rst +0 -0
  47. {codecrate-0.1.0 → codecrate-0.1.1}/docs/requirements.txt +0 -0
  48. {codecrate-0.1.0 → codecrate-0.1.1}/pyproject.toml +0 -0
  49. {codecrate-0.1.0 → codecrate-0.1.1}/requirements-test.txt +0 -0
  50. {codecrate-0.1.0 → codecrate-0.1.1}/setup.cfg +0 -0
  51. {codecrate-0.1.0 → codecrate-0.1.1}/setup.py +0 -0
  52. {codecrate-0.1.0 → codecrate-0.1.1}/tests/__init__.py +0 -0
  53. {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_config.py +0 -0
  54. {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_discover.py +0 -0
  55. {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_ids.py +0 -0
  56. {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_markdown_line_numbers.py +0 -0
  57. {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_model.py +0 -0
  58. {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_pack_unpack_roundtrip.py +0 -0
  59. {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_parse.py +0 -0
  60. {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_patch_apply_roundtrip.py +0 -0
  61. {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_smoke.py +0 -0
  62. {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_split_codecrate_pack.py +0 -0
  63. {codecrate-0.1.0 → codecrate-0.1.1}/tests/test_token_budget.py +0 -0
@@ -206,3 +206,4 @@ marimo/_static/
206
206
  marimo/_lsp/
207
207
  __marimo__/
208
208
  codecrate/_version.py
209
+ context_codecrate.md
@@ -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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codecrate
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Pack Python codebases into Markdown optimized for LLM context delivery (pack/unpack/patch/apply)
5
5
  Author-email: Holger Nahrstaedt <nahrstaedt@gmail.com>
6
6
  License: MIT License
@@ -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.0'
32
- __version_tuple__ = version_tuple = (0, 1, 0)
31
+ __version__ = version = '0.1.1'
32
+ __version_tuple__ = version_tuple = (0, 1, 1)
33
33
 
34
- __commit_id__ = commit_id = 'gbcb2c3a99'
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
- out_path = (
179
- args.output
180
- if args.output is not None
181
- else Path(getattr(cfg, "output", "context.md"))
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
- data.get("codecrate", {}) if isinstance(data, dict) else {}
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
- tree = ast.parse(text)
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codecrate
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Pack Python codebases into Markdown optimized for LLM context delivery (pack/unpack/patch/apply)
5
5
  Author-email: Holger Nahrstaedt <nahrstaedt@gmail.com>
6
6
  License: MIT License
@@ -2,6 +2,7 @@
2
2
  .pre-commit-config.yaml
3
3
  .readthedocs.yaml
4
4
  .ruff.toml
5
+ AGENTS.md
5
6
  LICENSE
6
7
  README.md
7
8
  codecrate.toml
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