scaffold-guard 0.1.0__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.
- scaffold_guard-0.1.0/.github/workflows/ci.yml +49 -0
- scaffold_guard-0.1.0/.github/workflows/publish.yml +76 -0
- scaffold_guard-0.1.0/.gitignore +12 -0
- scaffold_guard-0.1.0/AGENTS.md +222 -0
- scaffold_guard-0.1.0/CHANGELOG.md +16 -0
- scaffold_guard-0.1.0/LICENSE +21 -0
- scaffold_guard-0.1.0/PKG-INFO +168 -0
- scaffold_guard-0.1.0/README.md +137 -0
- scaffold_guard-0.1.0/docs/adapters.md +29 -0
- scaffold_guard-0.1.0/docs/checks.md +55 -0
- scaffold_guard-0.1.0/docs/generated-project.md +58 -0
- scaffold_guard-0.1.0/docs/index.md +28 -0
- scaffold_guard-0.1.0/docs/quickstart.md +45 -0
- scaffold_guard-0.1.0/docs/releasing.md +51 -0
- scaffold_guard-0.1.0/mkdocs.yml +12 -0
- scaffold_guard-0.1.0/pyproject.toml +132 -0
- scaffold_guard-0.1.0/pyrightconfig.json +15 -0
- scaffold_guard-0.1.0/scaffold_guard_v1_implementation_plan.md +1964 -0
- scaffold_guard-0.1.0/src/scaffold_guard/__init__.py +5 -0
- scaffold_guard-0.1.0/src/scaffold_guard/__main__.py +12 -0
- scaffold_guard-0.1.0/src/scaffold_guard/adapters/__init__.py +14 -0
- scaffold_guard-0.1.0/src/scaffold_guard/adapters/base.py +27 -0
- scaffold_guard-0.1.0/src/scaffold_guard/adapters/claude.py +21 -0
- scaffold_guard-0.1.0/src/scaffold_guard/adapters/codex.py +11 -0
- scaffold_guard-0.1.0/src/scaffold_guard/adapters/cursor.py +20 -0
- scaffold_guard-0.1.0/src/scaffold_guard/checks/__init__.py +6 -0
- scaffold_guard-0.1.0/src/scaffold_guard/checks/base.py +93 -0
- scaffold_guard-0.1.0/src/scaffold_guard/checks/config.py +59 -0
- scaffold_guard-0.1.0/src/scaffold_guard/checks/config_consistency.py +150 -0
- scaffold_guard-0.1.0/src/scaffold_guard/checks/files.py +60 -0
- scaffold_guard-0.1.0/src/scaffold_guard/checks/generated_files.py +125 -0
- scaffold_guard-0.1.0/src/scaffold_guard/checks/project_health.py +92 -0
- scaffold_guard-0.1.0/src/scaffold_guard/checks/runner.py +30 -0
- scaffold_guard-0.1.0/src/scaffold_guard/checks/unsafe_patterns.py +131 -0
- scaffold_guard-0.1.0/src/scaffold_guard/cli.py +329 -0
- scaffold_guard-0.1.0/src/scaffold_guard/compile_rules.py +121 -0
- scaffold_guard-0.1.0/src/scaffold_guard/diffing.py +457 -0
- scaffold_guard-0.1.0/src/scaffold_guard/doctor.py +218 -0
- scaffold_guard-0.1.0/src/scaffold_guard/fs.py +48 -0
- scaffold_guard-0.1.0/src/scaffold_guard/models.py +59 -0
- scaffold_guard-0.1.0/src/scaffold_guard/project_config.py +137 -0
- scaffold_guard-0.1.0/src/scaffold_guard/py.typed +1 -0
- scaffold_guard-0.1.0/src/scaffold_guard/renderer.py +27 -0
- scaffold_guard-0.1.0/src/scaffold_guard/scaffold.py +234 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/agents/claude/CLAUDE.md.j2 +9 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/agents/claude/rules/docs.md.j2 +14 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/agents/claude/rules/git-hygiene.md.j2 +7 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/agents/claude/rules/python.md.j2 +15 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/agents/claude/rules/security.md.j2 +7 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/agents/claude/rules/testing.md.j2 +14 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/agents/cursor/rules/docs.mdc.j2 +13 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/agents/cursor/rules/git-hygiene.mdc.j2 +12 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/agents/cursor/rules/python.mdc.j2 +14 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/agents/cursor/rules/security.mdc.j2 +12 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/agents/cursor/rules/testing.mdc.j2 +13 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/AGENTS.md.j2 +92 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/LICENSE.j2 +33 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/README.md.j2 +20 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/docs/index.md.j2 +13 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/examples/hello.py.j2 +12 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/github/workflows/ci.yml.j2 +58 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/github/workflows/docs.yml.j2 +32 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/gitignore.j2 +12 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/pyproject.toml.j2 +100 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/pyrightconfig.json.j2 +15 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/scaffold-guard.toml.j2 +44 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/src/package/__init__.py.j2 +5 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/src/package/core.py.j2 +7 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/src/package/py.typed.j2 +1 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/tests/integration/test_import_package.py.j2 +8 -0
- scaffold_guard-0.1.0/src/scaffold_guard/templates/package/tests/unit/test_core.py.j2 +13 -0
- scaffold_guard-0.1.0/src/scaffold_guard/validation.py +179 -0
- scaffold_guard-0.1.0/tests/integration/test_generated_package_profile.py +266 -0
- scaffold_guard-0.1.0/tests/integration/test_import_package.py +8 -0
- scaffold_guard-0.1.0/tests/integration/test_inspect_diff.py +162 -0
- scaffold_guard-0.1.0/tests/unit/test_checks.py +384 -0
- scaffold_guard-0.1.0/tests/unit/test_cli_version.py +16 -0
- scaffold_guard-0.1.0/tests/unit/test_diffing.py +174 -0
- scaffold_guard-0.1.0/tests/unit/test_fs.py +91 -0
- scaffold_guard-0.1.0/tests/unit/test_milestone6_commands.py +579 -0
- scaffold_guard-0.1.0/tests/unit/test_models.py +49 -0
- scaffold_guard-0.1.0/tests/unit/test_module_entrypoint.py +20 -0
- scaffold_guard-0.1.0/tests/unit/test_renderer.py +25 -0
- scaffold_guard-0.1.0/tests/unit/test_scaffold.py +277 -0
- scaffold_guard-0.1.0/uv.lock +1055 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Python ${{ matrix.python-version }}
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- name: Check out repository
|
|
20
|
+
uses: actions/checkout@v7.0.0
|
|
21
|
+
|
|
22
|
+
- name: Install uv
|
|
23
|
+
uses: astral-sh/setup-uv@v8.3.0
|
|
24
|
+
|
|
25
|
+
- name: Set up Python
|
|
26
|
+
uses: actions/setup-python@v6.3.0
|
|
27
|
+
with:
|
|
28
|
+
python-version: ${{ matrix.python-version }}
|
|
29
|
+
|
|
30
|
+
- name: Install dependencies
|
|
31
|
+
run: uv sync --all-groups --frozen
|
|
32
|
+
|
|
33
|
+
- name: Check formatting
|
|
34
|
+
run: uv run ruff format --check .
|
|
35
|
+
|
|
36
|
+
- name: Lint
|
|
37
|
+
run: uv run ruff check .
|
|
38
|
+
|
|
39
|
+
- name: Type check with mypy
|
|
40
|
+
run: uv run mypy src tests
|
|
41
|
+
|
|
42
|
+
- name: Type check with Pyright
|
|
43
|
+
run: uv run pyright
|
|
44
|
+
|
|
45
|
+
- name: Test
|
|
46
|
+
run: uv run pytest tests --cov=scaffold_guard --cov-report=term-missing --cov-fail-under=95
|
|
47
|
+
|
|
48
|
+
- name: Build docs
|
|
49
|
+
run: uv run mkdocs build --strict
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
name: Build distributions
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
if: github.event_name == 'release' || github.ref == 'refs/heads/main'
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Check out repository
|
|
19
|
+
uses: actions/checkout@v7.0.0
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v8.3.0
|
|
23
|
+
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v6.3.0
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.14"
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: uv sync --all-groups --frozen
|
|
31
|
+
|
|
32
|
+
- name: Check formatting
|
|
33
|
+
run: uv run ruff format --check .
|
|
34
|
+
|
|
35
|
+
- name: Lint
|
|
36
|
+
run: uv run ruff check .
|
|
37
|
+
|
|
38
|
+
- name: Type check with mypy
|
|
39
|
+
run: uv run mypy src tests
|
|
40
|
+
|
|
41
|
+
- name: Type check with Pyright
|
|
42
|
+
run: uv run pyright
|
|
43
|
+
|
|
44
|
+
- name: Test
|
|
45
|
+
run: uv run pytest tests --cov=scaffold_guard --cov-report=term-missing --cov-fail-under=95
|
|
46
|
+
|
|
47
|
+
- name: Build docs
|
|
48
|
+
run: uv run mkdocs build --strict
|
|
49
|
+
|
|
50
|
+
- name: Build distributions
|
|
51
|
+
run: uv build
|
|
52
|
+
|
|
53
|
+
- name: Upload distributions
|
|
54
|
+
uses: actions/upload-artifact@v4
|
|
55
|
+
with:
|
|
56
|
+
name: python-package-distributions
|
|
57
|
+
path: dist/
|
|
58
|
+
|
|
59
|
+
publish:
|
|
60
|
+
name: Publish to PyPI
|
|
61
|
+
runs-on: ubuntu-latest
|
|
62
|
+
needs: build
|
|
63
|
+
environment: pypi
|
|
64
|
+
permissions:
|
|
65
|
+
contents: read
|
|
66
|
+
id-token: write
|
|
67
|
+
|
|
68
|
+
steps:
|
|
69
|
+
- name: Download distributions
|
|
70
|
+
uses: actions/download-artifact@v4
|
|
71
|
+
with:
|
|
72
|
+
name: python-package-distributions
|
|
73
|
+
path: dist/
|
|
74
|
+
|
|
75
|
+
- name: Publish distributions to PyPI
|
|
76
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Agent Instructions
|
|
2
|
+
|
|
3
|
+
These rules apply to every code, test, documentation, template, and
|
|
4
|
+
configuration change in this repository.
|
|
5
|
+
|
|
6
|
+
## Product Orientation
|
|
7
|
+
|
|
8
|
+
- Build `scaffold-guard`: a PyPI-installable Python CLI that generates strict
|
|
9
|
+
Python starter repositories designed for safe coding-agent collaboration.
|
|
10
|
+
- Preserve the V1 promise: generate a Python project with clear agent
|
|
11
|
+
instructions, strict local tooling, GitHub Actions CI, and policy checks that
|
|
12
|
+
catch common agent mistakes.
|
|
13
|
+
- Treat `scaffold_guard_v1_implementation_plan.md` as the source of current
|
|
14
|
+
product scope and acceptance criteria until the plan is moved into formal docs.
|
|
15
|
+
- Keep V1 focused on a developer CLI. Do not add a SaaS dashboard, telemetry,
|
|
16
|
+
external AI calls, complex YAML DSL, plugin ecosystem, publish automation, or
|
|
17
|
+
automatic mutation of mature existing repositories.
|
|
18
|
+
- Always generate `AGENTS.md` for scaffolded projects. Treat it as the shared
|
|
19
|
+
cross-agent instruction source.
|
|
20
|
+
- Keep adapter behavior explicit:
|
|
21
|
+
- Codex uses `AGENTS.md`.
|
|
22
|
+
- Claude Code uses `CLAUDE.md` as a wrapper that imports `AGENTS.md`, with
|
|
23
|
+
optional `.claude/rules/`.
|
|
24
|
+
- Cursor uses `.cursor/rules/*.mdc` plus `AGENTS.md`.
|
|
25
|
+
- Prefer small, shippable V1 behavior over speculative framework design.
|
|
26
|
+
|
|
27
|
+
## Continuous Instruction Feedback Loop
|
|
28
|
+
|
|
29
|
+
- Treat this `AGENTS.md` as the operating manual for agents working in this
|
|
30
|
+
repository.
|
|
31
|
+
- When the user gives durable repo-wide feedback about how agents should work,
|
|
32
|
+
update this file in the same task unless the feedback is clearly one-off or is
|
|
33
|
+
already covered.
|
|
34
|
+
- Keep this file focused on operating rules, ownership boundaries, and completion
|
|
35
|
+
standards. Do not use it as a roadmap, milestone tracker, or implementation
|
|
36
|
+
plan.
|
|
37
|
+
- Keep rules general and actionable. Do not add task-specific history,
|
|
38
|
+
timestamps, workaround diaries, or feature requirements.
|
|
39
|
+
- Final responses for implementation tasks must state whether `AGENTS.md` was
|
|
40
|
+
updated. If explicit feedback or a notable failure did not require an update,
|
|
41
|
+
explain why the existing rules were sufficient.
|
|
42
|
+
|
|
43
|
+
## Working Style and Completion Bar
|
|
44
|
+
|
|
45
|
+
- Start non-trivial tasks by checking the current plan, existing files, package
|
|
46
|
+
boundaries, tests, and repository state.
|
|
47
|
+
- State assumptions, constraints, intended scope, and validation steps before
|
|
48
|
+
substantial implementation.
|
|
49
|
+
- Make the smallest safe change that fully satisfies the request. Avoid
|
|
50
|
+
speculative rewrites and unrelated refactors.
|
|
51
|
+
- Implement work in phases that can be validated independently. Do not treat the
|
|
52
|
+
entire V1 plan as one undifferentiated change.
|
|
53
|
+
- Finish the accepted scope. Do not silently skip requested details or stop after
|
|
54
|
+
a partial implementation.
|
|
55
|
+
- Never claim completion until the relevant checks have run, or until a blocker
|
|
56
|
+
is stated with concrete evidence and the next action.
|
|
57
|
+
- If a bug is found in touched behavior, fix the root cause before calling the
|
|
58
|
+
task complete unless the fix is unsafe or clearly out of scope.
|
|
59
|
+
- Do not lower lint, typing, docs, test, or coverage gates to force a green
|
|
60
|
+
result.
|
|
61
|
+
|
|
62
|
+
## Python Tooling
|
|
63
|
+
|
|
64
|
+
- Use `uv` for dependency management, lockfile updates, virtual environment work,
|
|
65
|
+
and command execution.
|
|
66
|
+
- The CLI package should support Python `>=3.11`.
|
|
67
|
+
- Test the CLI package on every supported Python feature release in CI. Do not
|
|
68
|
+
leave a current supported Python release out of the matrix without an explicit
|
|
69
|
+
compatibility reason.
|
|
70
|
+
- Generated projects should target Python `>=3.13` unless the implementation
|
|
71
|
+
plan changes.
|
|
72
|
+
- Keep CLI runtime dependencies minimal. V1 should use `typer`, `rich`,
|
|
73
|
+
`jinja2`, and `packaging` only when they are genuinely needed.
|
|
74
|
+
- Prefer Hatchling for package builds and make sure generated templates are
|
|
75
|
+
included in wheels.
|
|
76
|
+
- Use `importlib.resources.files()` to load packaged templates.
|
|
77
|
+
- Use `subprocess.run` without `shell=True` for command execution.
|
|
78
|
+
- Keep Ruff, mypy, Pyright, pytest, coverage, and MkDocs gates strict once the
|
|
79
|
+
scaffold exists.
|
|
80
|
+
- Write clear docstrings for public modules, classes, functions, and methods
|
|
81
|
+
when the behavior is not obvious from the name and types.
|
|
82
|
+
|
|
83
|
+
## Types and Data Modeling
|
|
84
|
+
|
|
85
|
+
- Type every public function, method, class attribute, constant, and public
|
|
86
|
+
module export.
|
|
87
|
+
- Avoid `Any`. If it is truly unavoidable, isolate it at a boundary, explain why,
|
|
88
|
+
and add tests around the narrowing.
|
|
89
|
+
- Do not introduce `dict[str, Any]`. Use explicit typed structures for stable
|
|
90
|
+
shapes.
|
|
91
|
+
- Avoid `# type: ignore`, `# pyright: ignore`, `# noqa`, broad exclusions, and
|
|
92
|
+
lint suppressions to hide failures. Fix the type flow or rule violation.
|
|
93
|
+
- Use lightweight dataclasses or typed structures for CLI internals in V1. Do not
|
|
94
|
+
add Pydantic unless the benefit clearly outweighs the dependency cost.
|
|
95
|
+
- Keep filesystem and rendering models explicit enough to test dry-run,
|
|
96
|
+
overwrite, generated-marker, and adapter behavior deterministically.
|
|
97
|
+
|
|
98
|
+
## Scaffold and Adapter Rules
|
|
99
|
+
|
|
100
|
+
- Keep `AGENTS.md` generation in the base scaffold because it is shared by every
|
|
101
|
+
adapter.
|
|
102
|
+
- `CLAUDE.md` must not duplicate the full `AGENTS.md`; it should import or
|
|
103
|
+
reference it and add only Claude-specific notes.
|
|
104
|
+
- Cursor `.mdc` files must include valid frontmatter with `description`,
|
|
105
|
+
`alwaysApply`, and `globs` where appropriate.
|
|
106
|
+
- Generated agent instruction files should be concise, serious, and enforceable
|
|
107
|
+
through `scaffold-guard check` and CI where possible.
|
|
108
|
+
- Use generated markers and checksums or clearly documented overwrite rules for
|
|
109
|
+
files managed by `compile-rules`.
|
|
110
|
+
- Keep template rendering deterministic. Tests should not depend on wall-clock
|
|
111
|
+
time, network access, local credentials, or machine-specific paths.
|
|
112
|
+
|
|
113
|
+
## Filesystem Safety
|
|
114
|
+
|
|
115
|
+
- Validate project names before writing. Reject path traversal, empty names,
|
|
116
|
+
unsafe package identifiers, and unexpected absolute paths.
|
|
117
|
+
- Refuse to overwrite existing directories or manually edited generated files
|
|
118
|
+
unless `--force` or a documented generated-file mechanism applies.
|
|
119
|
+
- Write only inside the requested target project root.
|
|
120
|
+
- Implement `--dry-run` paths so they produce the same planned file list without
|
|
121
|
+
touching the filesystem.
|
|
122
|
+
- Prefer structured path handling with `pathlib` over ad hoc string operations.
|
|
123
|
+
|
|
124
|
+
## Testing Rules
|
|
125
|
+
|
|
126
|
+
- Add or update tests with every behavior change.
|
|
127
|
+
- Unit tests should cover CLI argument handling, rendering, scaffold planning,
|
|
128
|
+
filesystem safety, adapter selection, unsafe-pattern checks, diff
|
|
129
|
+
requirements, generated-file checks, and config consistency.
|
|
130
|
+
- Integration tests should cover generated package profiles, adapter file sets,
|
|
131
|
+
`compile-rules` idempotence, `validate --quick`, JSON modes, and import smoke
|
|
132
|
+
behavior.
|
|
133
|
+
- Tests must verify behavior and regressions, not duplicate implementation
|
|
134
|
+
details or mocked call order.
|
|
135
|
+
- For bug fixes, add a regression test that fails before the fix and passes
|
|
136
|
+
after it.
|
|
137
|
+
- Keep tests deterministic: no real network calls, sleeps, wall-clock coupling,
|
|
138
|
+
or undeclared external services.
|
|
139
|
+
- Maintain the V1 package coverage floor at or above `95` unless the user
|
|
140
|
+
explicitly approves a change.
|
|
141
|
+
|
|
142
|
+
## Documentation and Examples
|
|
143
|
+
|
|
144
|
+
- Keep `README.md`, docs, examples, generated templates, tests, and package
|
|
145
|
+
behavior synchronized in the same change.
|
|
146
|
+
- Update docs when public commands, package layout, configuration, validation
|
|
147
|
+
behavior, generated output, adapter support, or developer workflows change.
|
|
148
|
+
- Never document aspirational behavior as if it works today. Future behavior
|
|
149
|
+
must be marked as future, planned, or unsupported.
|
|
150
|
+
- Examples should be small, deterministic, realistic, and runnable enough to
|
|
151
|
+
become integration fixtures later.
|
|
152
|
+
- Document Codex, Claude Code, and Cursor behavior as adapter facts, not vague
|
|
153
|
+
compatibility claims.
|
|
154
|
+
|
|
155
|
+
## Security and Secret Handling
|
|
156
|
+
|
|
157
|
+
- Never commit secrets, local credentials, provider payloads, private
|
|
158
|
+
transcripts, `.env`, `.venv`, or generated runtime artifacts.
|
|
159
|
+
- Keep policy checks conservative and explainable. Regex-based scanning is fine
|
|
160
|
+
for V1 when it is documented and tested.
|
|
161
|
+
- Do not add external AI calls, telemetry, or network-dependent tests in V1.
|
|
162
|
+
- Treat suspicious credential literals, `shell=True`, unsafe writes outside the
|
|
163
|
+
project root, and committed environment files as policy failures.
|
|
164
|
+
|
|
165
|
+
## Validation Commands
|
|
166
|
+
|
|
167
|
+
Match validation to the actual change and the scaffold that exists.
|
|
168
|
+
|
|
169
|
+
- For markdown-only edits, run `git diff --check` when the repository is
|
|
170
|
+
initialized. If there is no `.git` directory yet, state that the whitespace
|
|
171
|
+
check could not be run for that reason.
|
|
172
|
+
- For documentation pages, README changes, or docs navigation changes, run
|
|
173
|
+
`git diff --check` and `uv run mkdocs build --strict` once the docs toolchain
|
|
174
|
+
exists.
|
|
175
|
+
- For code, package metadata, lockfile, tests, examples, templates, or generated
|
|
176
|
+
assets, run focused checks plus the full gate below when the change is
|
|
177
|
+
substantial.
|
|
178
|
+
|
|
179
|
+
Target full gate once the scaffold exists:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
uv sync --all-groups
|
|
183
|
+
uv run ruff format --check .
|
|
184
|
+
uv run ruff check .
|
|
185
|
+
uv run mypy src tests
|
|
186
|
+
uv run pyright
|
|
187
|
+
uv run pytest tests --cov=scaffold_guard --cov-report=term-missing --cov-fail-under=95
|
|
188
|
+
uv run mkdocs build --strict
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Generated projects should be validated with their configured commands:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
uv run scaffold-guard check
|
|
195
|
+
uv run scaffold-guard inspect-diff
|
|
196
|
+
uv run scaffold-guard validate
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Do not report completion if a required check fails. Fix the failure or clearly
|
|
200
|
+
explain why it is blocked.
|
|
201
|
+
|
|
202
|
+
## Git and Change Hygiene
|
|
203
|
+
|
|
204
|
+
- Keep diffs focused and reviewable.
|
|
205
|
+
- Preserve user changes. Do not revert unrelated work.
|
|
206
|
+
- Keep `uv.lock` synchronized with `pyproject.toml` changes once the lockfile
|
|
207
|
+
exists.
|
|
208
|
+
- Do not commit generated runtime artifacts unless the repository intentionally
|
|
209
|
+
tracks them.
|
|
210
|
+
- Treat this checkout as the workspace boundary unless the user explicitly asks
|
|
211
|
+
to touch another checkout.
|
|
212
|
+
- When a task explicitly includes pushing or publishing, watch the relevant
|
|
213
|
+
GitHub Actions runs after pushing and report the final status.
|
|
214
|
+
|
|
215
|
+
## Final Response Requirements
|
|
216
|
+
|
|
217
|
+
- Summarize the user-visible change and name the main files touched.
|
|
218
|
+
- List the validation commands run and their results. If a relevant check could
|
|
219
|
+
not run, explain why.
|
|
220
|
+
- State whether `AGENTS.md` was updated for implementation tasks.
|
|
221
|
+
- Call out any remaining blocker, risk, or follow-up needed to finish the
|
|
222
|
+
accepted scope.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 - Unreleased
|
|
4
|
+
|
|
5
|
+
- Added the `scaffold-guard` CLI with `init`, `check`, `inspect-diff`, `validate`,
|
|
6
|
+
`compile-rules`, `doctor`, and `version`.
|
|
7
|
+
- Added package-profile project generation with Codex, Claude Code, and Cursor
|
|
8
|
+
adapter files.
|
|
9
|
+
- Added local policy checks, diff guidance, generated-project validation,
|
|
10
|
+
diagnostics, and rule regeneration.
|
|
11
|
+
- Added release-readiness documentation and wheel template inclusion checks.
|
|
12
|
+
- Added Python 3.14 CI coverage and PyPI Trusted Publishing release automation.
|
|
13
|
+
- Updated repository and generated-project GitHub Actions to current action
|
|
14
|
+
releases.
|
|
15
|
+
- Renamed the project, PyPI distribution, module, CLI, and generated config to
|
|
16
|
+
ScaffoldGuard / `scaffold-guard`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Damien Benveniste
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: scaffold-guard
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Generate guarded Python project starters for Codex, Claude Code, and Cursor.
|
|
5
|
+
Project-URL: Homepage, https://github.com/damienbenveniste/ScaffoldGuard
|
|
6
|
+
Project-URL: Repository, https://github.com/damienbenveniste/ScaffoldGuard
|
|
7
|
+
Project-URL: Issues, https://github.com/damienbenveniste/ScaffoldGuard/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/damienbenveniste/ScaffoldGuard#readme
|
|
9
|
+
Author: Damien Benveniste
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: agents,claude,codex,cursor,scaffold,scaffold-guard
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.11
|
|
26
|
+
Requires-Dist: jinja2>=3.1.0
|
|
27
|
+
Requires-Dist: packaging>=24.0
|
|
28
|
+
Requires-Dist: rich>=13.7.0
|
|
29
|
+
Requires-Dist: typer>=0.12.0
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# ScaffoldGuard
|
|
33
|
+
|
|
34
|
+
`scaffold-guard` generates strict Python starter repositories for teams using
|
|
35
|
+
coding agents. It creates a typed package layout, local validation commands,
|
|
36
|
+
GitHub Actions workflows, and agent instructions for Codex, Claude Code, and
|
|
37
|
+
Cursor.
|
|
38
|
+
|
|
39
|
+
The PyPI package and `uvx` entrypoint are `scaffold-guard`; the canonical
|
|
40
|
+
installed command is `scaffold-guard`.
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
After the package is published to PyPI:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
uvx scaffold-guard version
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
From a local checkout or built wheel:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
uv sync --all-groups
|
|
54
|
+
uv run scaffold-guard version
|
|
55
|
+
uv build
|
|
56
|
+
uvx --from dist/scaffold_guard-0.1.0-py3-none-any.whl scaffold-guard version
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Publishing
|
|
60
|
+
|
|
61
|
+
PyPI publishing is prepared through GitHub Actions Trusted Publishing. Before
|
|
62
|
+
the first release, configure a PyPI pending publisher for:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
Project name: scaffold-guard
|
|
66
|
+
Owner: damienbenveniste
|
|
67
|
+
Repository: ScaffoldGuard
|
|
68
|
+
Workflow: publish.yml
|
|
69
|
+
Environment: pypi
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
No PyPI API token is required. After the pending publisher exists, publish a
|
|
73
|
+
GitHub Release or manually run the `Publish` workflow from `main`.
|
|
74
|
+
|
|
75
|
+
## Quickstart
|
|
76
|
+
|
|
77
|
+
Generate a project with every supported adapter:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
uvx scaffold-guard init my_project --agent all
|
|
81
|
+
cd my_project
|
|
82
|
+
uv sync --all-groups
|
|
83
|
+
uv run scaffold-guard check
|
|
84
|
+
uv run scaffold-guard validate --quick
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Generate for one agent surface:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
uvx scaffold-guard init codex_demo --agent codex
|
|
91
|
+
uvx scaffold-guard init claude_demo --agent claude
|
|
92
|
+
uvx scaffold-guard init cursor_demo --agent cursor
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Use `--dry-run` to preview files and `--force` to overwrite known generated
|
|
96
|
+
files.
|
|
97
|
+
|
|
98
|
+
## Generated Project
|
|
99
|
+
|
|
100
|
+
The default `package` profile creates:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
my_project/
|
|
104
|
+
AGENTS.md
|
|
105
|
+
README.md
|
|
106
|
+
LICENSE
|
|
107
|
+
pyproject.toml
|
|
108
|
+
pyrightconfig.json
|
|
109
|
+
scaffold-guard.toml
|
|
110
|
+
.github/workflows/
|
|
111
|
+
docs/
|
|
112
|
+
examples/
|
|
113
|
+
src/my_project/
|
|
114
|
+
tests/unit/
|
|
115
|
+
tests/integration/
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Adapter files are added according to `--agent`:
|
|
119
|
+
|
|
120
|
+
| Agent | Generated instruction files |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `codex` | `AGENTS.md` |
|
|
123
|
+
| `claude` | `AGENTS.md`, `CLAUDE.md`, `.claude/rules/*.md` |
|
|
124
|
+
| `cursor` | `AGENTS.md`, `.cursor/rules/*.mdc` |
|
|
125
|
+
| `all` | all of the above |
|
|
126
|
+
|
|
127
|
+
## Commands
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
scaffold-guard init NAME [--agent codex|claude|cursor|all]
|
|
131
|
+
scaffold-guard check [--path .] [--json]
|
|
132
|
+
scaffold-guard inspect-diff [--path .] [--base main] [--json]
|
|
133
|
+
scaffold-guard validate [--path .] [--quick] [--json]
|
|
134
|
+
scaffold-guard compile-rules [--path .] [--agent codex|claude|cursor|all] [--dry-run] [--force]
|
|
135
|
+
scaffold-guard doctor [--path .] [--json]
|
|
136
|
+
scaffold-guard version
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`check` runs fast policy checks. `inspect-diff` explains validation obligations
|
|
140
|
+
for changed files in a git repository. `validate` runs the generated project's
|
|
141
|
+
configured validation gate. `compile-rules` regenerates managed agent
|
|
142
|
+
instruction files from templates. `doctor` reports local tool and generated
|
|
143
|
+
project health.
|
|
144
|
+
|
|
145
|
+
## Local Development
|
|
146
|
+
|
|
147
|
+
Run the package gate from this repository:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
uv sync --all-groups --frozen
|
|
151
|
+
uv run ruff format --check .
|
|
152
|
+
uv run ruff check .
|
|
153
|
+
uv run mypy src tests
|
|
154
|
+
uv run pyright
|
|
155
|
+
uv run pytest tests --cov=scaffold_guard --cov-report=term-missing --cov-fail-under=95
|
|
156
|
+
uv run mkdocs build --strict
|
|
157
|
+
uv build
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Limitations
|
|
161
|
+
|
|
162
|
+
V1 is a developer CLI, not a SaaS product or policy server. It does not include
|
|
163
|
+
telemetry, external AI calls, Codex or Claude hooks, a plugin system, Homebrew
|
|
164
|
+
automation, or automatic upgrades for mature existing repositories.
|
|
165
|
+
|
|
166
|
+
Homebrew distribution, hook starter templates, more project profiles, and richer
|
|
167
|
+
policy configuration are intentionally deferred until after the PyPI package is
|
|
168
|
+
stable.
|