Uploaded files
This commit is contained in:
23
.claude/settings.json
Normal file
23
.claude/settings.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Bash(date:*)",
|
||||||
|
"Bash(echo:*)",
|
||||||
|
"Bash(cat:*)",
|
||||||
|
"Bash(ls:*)",
|
||||||
|
"Bash(mkdir:*)",
|
||||||
|
"Bash(wc:*)",
|
||||||
|
"Bash(head:*)",
|
||||||
|
"Bash(tail:*)",
|
||||||
|
"Bash(sort:*)",
|
||||||
|
"Bash(grep:*)",
|
||||||
|
"Bash(tr:*)",
|
||||||
|
"Bash(git add:*)",
|
||||||
|
"Bash(git commit:*)",
|
||||||
|
"Bash(git status:*)",
|
||||||
|
"Bash(git log:*)",
|
||||||
|
"Bash(git diff:*)",
|
||||||
|
"Bash(git tag:*)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
14
.claude/skills/check/SKILL.md
Normal file
14
.claude/skills/check/SKILL.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
name: check
|
||||||
|
description: Run repo checks (ruff + pytest).
|
||||||
|
disable-model-invocation: true
|
||||||
|
---
|
||||||
|
|
||||||
|
Run:
|
||||||
|
- Windows: powershell -ExecutionPolicy Bypass -File scripts/check.ps1
|
||||||
|
- Linux/WSL: bash scripts/check.sh
|
||||||
|
|
||||||
|
If a check fails:
|
||||||
|
- capture the error output
|
||||||
|
- propose the smallest safe fix
|
||||||
|
- re-run checks
|
||||||
13
.claude/skills/contextpack/SKILL.md
Normal file
13
.claude/skills/contextpack/SKILL.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
name: contextpack
|
||||||
|
description: Generate a repo snapshot for LLMs (.planning/CONTEXTPACK.md).
|
||||||
|
disable-model-invocation: true
|
||||||
|
---
|
||||||
|
|
||||||
|
Run:
|
||||||
|
- python scripts/contextpack.py
|
||||||
|
|
||||||
|
Then read:
|
||||||
|
- .planning/CONTEXTPACK.md
|
||||||
|
|
||||||
|
Use this before planning work or when resuming after a break.
|
||||||
11
.editorconfig
Normal file
11
.editorconfig
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.py]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
|
||||||
|
# venv
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
|
||||||
|
# tooling
|
||||||
|
.pytest_cache/
|
||||||
|
.ruff_cache/
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# generated
|
||||||
|
.planning/CONTEXTPACK.md
|
||||||
1
.planning/.gitkeep
Normal file
1
.planning/.gitkeep
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(placeholder)
|
||||||
1
.planning/research/.gitkeep
Normal file
1
.planning/research/.gitkeep
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(placeholder)
|
||||||
7
.pre-commit-config.yaml
Normal file
7
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
repos:
|
||||||
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
|
rev: v0.6.9
|
||||||
|
hooks:
|
||||||
|
- id: ruff
|
||||||
|
args: ["--fix"]
|
||||||
|
- id: ruff-format
|
||||||
31
CLAUDE.md
Normal file
31
CLAUDE.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Project Rules (auto-loaded)
|
||||||
|
|
||||||
|
## What matters most
|
||||||
|
- Keep changes small and safe.
|
||||||
|
- Prefer incremental improvements over rewrites.
|
||||||
|
- Add/adjust tests when behavior changes.
|
||||||
|
- Keep commits atomic and descriptive.
|
||||||
|
|
||||||
|
## GSD workflow
|
||||||
|
- Use GSD as the source of truth generator:
|
||||||
|
- /gsd:new-project creates PROJECT.md, REQUIREMENTS.md, ROADMAP.md, STATE.md, and .planning/research/
|
||||||
|
- /gsd:discuss-phase -> /gsd:plan-phase -> /gsd:execute-phase -> /gsd:verify-work
|
||||||
|
|
||||||
|
## Repo quick commands
|
||||||
|
- Bootstrap:
|
||||||
|
- Windows: powershell -ExecutionPolicy Bypass -File scripts/bootstrap.ps1
|
||||||
|
- Linux/WSL: bash scripts/bootstrap.sh
|
||||||
|
|
||||||
|
- Run checks:
|
||||||
|
- Windows: powershell -ExecutionPolicy Bypass -File scripts/check.ps1
|
||||||
|
- Linux/WSL: bash scripts/check.sh
|
||||||
|
|
||||||
|
- Generate LLM context snapshot:
|
||||||
|
- python scripts/contextpack.py
|
||||||
|
- output: .planning/CONTEXTPACK.md
|
||||||
|
|
||||||
|
## Definition of done
|
||||||
|
- ruff check .
|
||||||
|
- ruff format --check .
|
||||||
|
- pytest
|
||||||
|
- Update STATE.md if progress changed
|
||||||
15
PROJECT.md
Normal file
15
PROJECT.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Project
|
||||||
|
|
||||||
|
(Generated/maintained by GSD)
|
||||||
|
|
||||||
|
## One-liner
|
||||||
|
-
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
-
|
||||||
|
|
||||||
|
## Users
|
||||||
|
-
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
-
|
||||||
17
REQUIREMENTS.md
Normal file
17
REQUIREMENTS.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Requirements
|
||||||
|
|
||||||
|
(Generated/maintained by GSD)
|
||||||
|
|
||||||
|
## Must-have (v1)
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
## Nice-to-have (v2)
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
- Platform:
|
||||||
|
- Performance:
|
||||||
|
- Privacy/security:
|
||||||
|
|
||||||
|
## Acceptance tests
|
||||||
|
- [ ] Given ____, when ____, then ____
|
||||||
12
ROADMAP.md
Normal file
12
ROADMAP.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Roadmap
|
||||||
|
|
||||||
|
(Generated/maintained by GSD)
|
||||||
|
|
||||||
|
## Phase 1
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
## Phase 2
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
## Phase 3
|
||||||
|
- [ ]
|
||||||
20
STATE.md
Normal file
20
STATE.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# State
|
||||||
|
|
||||||
|
(Generated/maintained by GSD)
|
||||||
|
|
||||||
|
## Current focus
|
||||||
|
-
|
||||||
|
|
||||||
|
## What works
|
||||||
|
-
|
||||||
|
|
||||||
|
## What’s broken
|
||||||
|
-
|
||||||
|
|
||||||
|
## Next 3 tasks
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
- (date) decision -> why
|
||||||
12
docs/CHECKLIST.md
Normal file
12
docs/CHECKLIST.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Checklists
|
||||||
|
|
||||||
|
## Pre-merge
|
||||||
|
- [ ] ruff check .
|
||||||
|
- [ ] ruff format --check .
|
||||||
|
- [ ] pytest
|
||||||
|
- [ ] docs updated if requirements/decisions changed
|
||||||
|
|
||||||
|
## Release
|
||||||
|
- [ ] version bump
|
||||||
|
- [ ] changelog notes
|
||||||
|
- [ ] basic smoke test
|
||||||
0
docs/CONTEXTPACK.md
Normal file
0
docs/CONTEXTPACK.md
Normal file
13
docs/PROJECT.md
Normal file
13
docs/PROJECT.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Project
|
||||||
|
|
||||||
|
## One-liner
|
||||||
|
What is this?
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Why does it exist?
|
||||||
|
|
||||||
|
## Users
|
||||||
|
Who is it for?
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
What are we intentionally NOT doing?
|
||||||
15
docs/REQUIREMENTS.md
Normal file
15
docs/REQUIREMENTS.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Requirements
|
||||||
|
|
||||||
|
## Must-have (v1)
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
## Nice-to-have (v2)
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
- Platform:
|
||||||
|
- Performance:
|
||||||
|
- Privacy/security:
|
||||||
|
|
||||||
|
## Acceptance tests
|
||||||
|
- [ ] Given ____, when ____, then ____
|
||||||
10
docs/ROADMAP.md
Normal file
10
docs/ROADMAP.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Roadmap
|
||||||
|
|
||||||
|
## Phase 1: MVP
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
## Phase 2: Quality + UX
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
## Phase 3: Scale + polish
|
||||||
|
- [ ]
|
||||||
18
docs/STATE.md
Normal file
18
docs/STATE.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# State
|
||||||
|
|
||||||
|
## Current focus
|
||||||
|
-
|
||||||
|
|
||||||
|
## What works
|
||||||
|
-
|
||||||
|
|
||||||
|
## What’s broken
|
||||||
|
-
|
||||||
|
|
||||||
|
## Next 3 tasks
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
|
## Recent decisions
|
||||||
|
- (date) decision -> why
|
||||||
25
pyproject.toml
Normal file
25
pyproject.toml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
[project]
|
||||||
|
name = "app"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "GSD-native Python template"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
dev = [
|
||||||
|
"pytest>=8.0",
|
||||||
|
"ruff>=0.6",
|
||||||
|
"pre-commit>=3.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
line-length = 100
|
||||||
|
target-version = "py311"
|
||||||
|
|
||||||
|
[tool.ruff.lint]
|
||||||
|
select = ["E", "F", "I", "B", "UP"]
|
||||||
|
ignore = []
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
testpaths = ["tests"]
|
||||||
9
scripts/bootstrap.ps1
Normal file
9
scripts/bootstrap.ps1
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
python -m venv .venv
|
||||||
|
.\.venv\Scripts\Activate.ps1
|
||||||
|
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
python -m pip install -e ".[dev]"
|
||||||
|
|
||||||
|
pre-commit install
|
||||||
|
|
||||||
|
Write-Host "✅ Bootstrapped (.venv created, dev deps installed)"
|
||||||
15
scripts/bootstrap.sh
Normal file
15
scripts/bootstrap.sh
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PY=python
|
||||||
|
command -v python >/dev/null 2>&1 || PY=python3
|
||||||
|
|
||||||
|
$PY -m venv .venv
|
||||||
|
source .venv/bin/activate
|
||||||
|
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
python -m pip install -e ".[dev]"
|
||||||
|
|
||||||
|
pre-commit install || true
|
||||||
|
|
||||||
|
echo "✅ Bootstrapped (.venv created, dev deps installed)"
|
||||||
7
scripts/check.ps1
Normal file
7
scripts/check.ps1
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
.\.venv\Scripts\Activate.ps1
|
||||||
|
|
||||||
|
ruff check .
|
||||||
|
ruff format --check .
|
||||||
|
pytest -q
|
||||||
|
|
||||||
|
Write-Host "✅ Checks passed"
|
||||||
10
scripts/check.sh
Normal file
10
scripts/check.sh
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
source .venv/bin/activate
|
||||||
|
|
||||||
|
ruff check .
|
||||||
|
ruff format --check .
|
||||||
|
pytest -q
|
||||||
|
|
||||||
|
echo "✅ Checks passed"
|
||||||
86
scripts/contextpack.py
Normal file
86
scripts/contextpack.py
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
ROOT = Path(".").resolve()
|
||||||
|
OUT = ROOT / ".planning" / "CONTEXTPACK.md"
|
||||||
|
|
||||||
|
IGNORE_DIRS = {
|
||||||
|
".git",
|
||||||
|
".venv",
|
||||||
|
"venv",
|
||||||
|
"__pycache__",
|
||||||
|
".pytest_cache",
|
||||||
|
".ruff_cache",
|
||||||
|
"dist",
|
||||||
|
"build",
|
||||||
|
"node_modules",
|
||||||
|
}
|
||||||
|
|
||||||
|
KEY_FILES = [
|
||||||
|
"CLAUDE.md",
|
||||||
|
"PROJECT.md",
|
||||||
|
"REQUIREMENTS.md",
|
||||||
|
"ROADMAP.md",
|
||||||
|
"STATE.md",
|
||||||
|
"pyproject.toml",
|
||||||
|
".pre-commit-config.yaml",
|
||||||
|
]
|
||||||
|
|
||||||
|
def run(cmd: list[str]) -> str:
|
||||||
|
try:
|
||||||
|
return subprocess.check_output(cmd, cwd=ROOT, stderr=subprocess.STDOUT, text=True).strip()
|
||||||
|
except Exception as e:
|
||||||
|
return f"(failed: {' '.join(cmd)}): {e}"
|
||||||
|
|
||||||
|
def tree(max_depth: int = 3) -> str:
|
||||||
|
lines: list[str] = []
|
||||||
|
|
||||||
|
def walk(path: Path, depth: int) -> None:
|
||||||
|
if depth > max_depth:
|
||||||
|
return
|
||||||
|
for p in sorted(path.iterdir(), key=lambda x: (x.is_file(), x.name.lower())):
|
||||||
|
if p.name in IGNORE_DIRS:
|
||||||
|
continue
|
||||||
|
rel = p.relative_to(ROOT)
|
||||||
|
indent = " " * depth
|
||||||
|
if p.is_dir():
|
||||||
|
lines.append(f"{indent}📁 {rel}/")
|
||||||
|
walk(p, depth + 1)
|
||||||
|
else:
|
||||||
|
lines.append(f"{indent}📄 {rel}")
|
||||||
|
|
||||||
|
walk(ROOT, 0)
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
def head(path: Path, n: int = 160) -> str:
|
||||||
|
try:
|
||||||
|
return "\n".join(path.read_text(encoding="utf-8", errors="replace").splitlines()[:n])
|
||||||
|
except Exception as e:
|
||||||
|
return f"(failed reading {path}): {e}"
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
OUT.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
parts: list[str] = []
|
||||||
|
parts.append("# Context Pack")
|
||||||
|
parts.append(f"_Generated: {datetime.now().isoformat(timespec='seconds')}_\n")
|
||||||
|
|
||||||
|
parts.append("## Repo tree\n```text\n" + tree() + "\n```")
|
||||||
|
parts.append("## Git status\n```text\n" + run(["git", "status"]) + "\n```")
|
||||||
|
parts.append("## Recent commits\n```text\n" + run(["git", "--no-pager", "log", "-10", "--oneline"]) + "\n```")
|
||||||
|
|
||||||
|
parts.append("## Key files (head)")
|
||||||
|
for f in KEY_FILES:
|
||||||
|
p = ROOT / f
|
||||||
|
if p.exists():
|
||||||
|
parts.append(f"### {f}\n```text\n{head(p)}\n```")
|
||||||
|
|
||||||
|
OUT.write_text("\n\n".join(parts) + "\n", encoding="utf-8")
|
||||||
|
print(f"✅ Wrote {OUT.relative_to(ROOT)}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
1
src/app/__init__.py
Normal file
1
src/app/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
__all__ = []
|
||||||
6
src/app/__main__.py
Normal file
6
src/app/__main__.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
def main() -> None:
|
||||||
|
print("Hello from app!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
6
src/app/main.py
Normal file
6
src/app/main.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
def main() -> None:
|
||||||
|
print("Hello from app!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
2
tests/test_smoke.py
Normal file
2
tests/test_smoke.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
def test_smoke() -> None:
|
||||||
|
assert True
|
||||||
Reference in New Issue
Block a user