This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Run all tests (two equivalent ways)
python3 -m unittest discover -s tests -v
uv run pytest tests/ -q --tb=short
# Run a single test file or test
uv run pytest tests/test_reports.py -v
uv run pytest tests/test_cli.py::CLIEnhancementTests::test_history_lists_runs -v
# Check syntax
python3 -m compileall -q autoprojectclaw tests
# CLI entry point
uv run autoprojectclaw --help
uv run autoprojectclaw run --config examples/sz_stib_config.yaml --to-stage 0 --llm-provider dry_run --run-id test-smokeNo linter or type checker is configured. No CI/CD yet.
AutoProjectClaw is a 6-stage pipeline (Stage 0-5) for grant proposal topic selection. Each stage reads artifacts from the prior stage's output directory and writes to its own.
Core pipeline abstractions (read these files first):
autoprojectclaw/pipeline/stages.py—StageIntEnum (0-5),StageStatus,TransitionEvent, state machineadvance()autoprojectclaw/pipeline/contracts.py—StageContract: per-stage input/output files, definition-of-done, error codesautoprojectclaw/pipeline/runner.py—run_pipeline()orchestrator: iterates stages, validates I/O via contracts, writes checkpoint/summary, handles HITL gate at Stage 5
Stage implementations live in autoprojectclaw/pipeline/stage_impls/, one module per stage. _common.py has shared I/O and LLM helpers. Each execute_* function takes (config, run_dir, stage_dir, llm_client).
Key subsystems:
- LLM (
autoprojectclaw/llm/client.py):LLMClientprotocol with 5 adapters.DryRunLLMClientfor testing (no network). Others shell out (codex exec,claude --print) or HTTP POST (OpenAI Responses, Anthropic Messages). All stdlib-only. - Prompts (
autoprojectclaw/prompts.py): 3-layer system: Python defaults →prompts.project.yamloverrides → runtime variables. Each stage hassystem/usertemplates with{variable}placeholders. - Literature (
autoprojectclaw/literature/): Search across 6 academic APIs (PubMed, OpenAlex, Semantic Scholar, arXiv, bioRxiv, medRxiv) withLiteratureCache(SHA256 key, per-source TTL),CircuitBreaker(CLOSED→OPEN→HALF_OPEN), andNoveltyReport(Jaccard + SequenceMatcher). - Scoring (
autoprojectclaw/modules/grant_scorer.py): FINER + differentiation + grant_story weighted scoring. - Avoidance (
autoprojectclaw/modules/avoidance_checker.py): 5-dimension overlap check (population, outcome, method, data_path, question) with configurable red/yellow thresholds. - Reports (
autoprojectclaw/reports.py):scan_runs()scans allpipeline_summary.jsonfiles,generate_weekly_report()writes markdown.
HITL gate: Stage 5 blocks at blocked_approval. CLI provides approve/reject/resume commands. Rejection rolls back to Stage 3 by default.
CLI (autoprojectclaw/cli.py): 8 subcommands — run, approve, reject, resume, llm, setup, status, history, report, cache clear. All run_id inputs validated by _validate_run_id_arg() against path traversal.
Config (autoprojectclaw/config.py): YAML-based with frozen dataclasses (ProjectConfig, LLMConfig, CacheConfig, etc.). Backward-compatible: unknown keys ignored, missing/null fields use defaults.
- Tests use
unittest.TestCase(not pytest fixtures). Noconftest.py. - Each test file is self-contained with its own helper methods.
- Dry-run LLM provider is used in tests — no network calls.
run_pipeline(config, to_stage=N, run_id="...")withavoidancedefaults is the standard pattern for integration tests.- Current baseline: 148 tests, 14 subtests.
Python >=3.11, runtime: pyyaml>=6.0, dev: pytest>=9.0.3. No other external dependencies. All LLM/HTTP code uses stdlib (urllib, subprocess).