Skip to content

Latest commit

 

History

History
44 lines (29 loc) · 2.8 KB

File metadata and controls

44 lines (29 loc) · 2.8 KB

Project CLAUDE.md — Local File Toolkit + Plugin Marketplace

Resume from disk: read STATE.md first — it always says what's done, what's in flight, and what's next. Decisions live in docs/DECISIONS.md.

Product name — single source of truth

The product name, tagline, and version live ONLY in product.json at the repo root. Never hardcode the name in code. Docs/manifests may use the name in prose, but anything generated (CLI banner, --version, asset text) must read product.json. scripts/finalize.sh performs renames by updating product.json and regenerating derived references.

Stack & layout

  • Python ≥3.12 (dev box: 3.14), managed by uv (pyproject.toml, uv run, uv sync).
  • Core library in src/<pkg>/; umbrella CLI entry in pyproject.toml [project.scripts].
  • All external binaries are called through the single adapter layer src/<pkg>/adapters.py — never subprocess directly from command modules. Adapters do capability detection.
  • Repo root doubles as a Claude Code plugin marketplace: .claude-plugin/marketplace.json + plugins/<name>/.

Coding standards

  • Python: type hints on public functions, pathlib.Path over strings, no global state, f-strings, stdlib argparse-free — we use the CLI framework chosen in Phase 2 (see docs/ARCHITECTURE.md).
  • Every CLI command MUST have: working --help, --json flag when output is data, ≥1 test, graceful degradation when an optional binary is missing (actionable message + install hint, exit code 3 — never a traceback, never a silent no-op).
  • No stubs/TODO/placeholder code in shipped commands. Cut and document in docs/FEATURES.md instead.
  • Wrap, don't rewrite: prefer proven libraries/binaries via the adapter layer; attribute in docs/LICENSES section.

Exit code convention

  • 0 success
  • 1 general/unexpected error (message to stderr, no traceback unless --debug)
  • 2 bad usage/arguments (argparse-style)
  • 3 missing optional dependency (message names the binary + install hint)
  • 4 input file not found / unreadable / unsupported type
  • 5 operation produced no result (e.g., search with no hits when --fail-empty)

Testing

  • uv run pytest from repo root runs everything. Fixtures in tests/fixtures/ (generated by tests/fixtures/generate.py; never hand-edit binaries).
  • Tests that need an optional binary must skip (with reason) when it's absent, not fail.

Subagent rules

Subagents: read your spec in specs/, respect your write boundary exactly, and report: files touched, tests written+run (with real output), deviations from spec, open issues. Claims are verified by execution — write tests that actually run.

Git

  • Branch main. Commits at phase gates phase(N): ... and waves wave(N): ....
  • Never commit generated junk (see .gitignore); fixtures ARE committed once generated.