readme2demo 0.7.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.
- readme2demo-0.7.1/.claude/agents/grounding-auditor.md +43 -0
- readme2demo-0.7.1/.claude/agents/run-debugger.md +46 -0
- readme2demo-0.7.1/.claude/commands/ship-check.md +22 -0
- readme2demo-0.7.1/.claude/skills/add-engine/SKILL.md +57 -0
- readme2demo-0.7.1/.claude/skills/add-failure-class/SKILL.md +52 -0
- readme2demo-0.7.1/.claude/skills/debug-run/SKILL.md +74 -0
- readme2demo-0.7.1/.claude/skills/docker-sandbox/SKILL.md +55 -0
- readme2demo-0.7.1/.claude/skills/git-github-operator/SKILL.md +57 -0
- readme2demo-0.7.1/.claude/skills/python-standards/SKILL.md +61 -0
- readme2demo-0.7.1/.claude/skills/sandbox-toolchains/SKILL.md +50 -0
- readme2demo-0.7.1/.claude/skills/vhs-video/SKILL.md +50 -0
- readme2demo-0.7.1/.env.example +36 -0
- readme2demo-0.7.1/.github/CODEOWNERS +10 -0
- readme2demo-0.7.1/.github/FUNDING.yml +6 -0
- readme2demo-0.7.1/.github/ISSUE_TEMPLATE/bug_report.md +50 -0
- readme2demo-0.7.1/.github/ISSUE_TEMPLATE/config.yml +8 -0
- readme2demo-0.7.1/.github/ISSUE_TEMPLATE/feature_request.md +27 -0
- readme2demo-0.7.1/.github/PULL_REQUEST_TEMPLATE.md +39 -0
- readme2demo-0.7.1/.github/dependabot.yml +29 -0
- readme2demo-0.7.1/.github/workflows/action-selftest.yml +35 -0
- readme2demo-0.7.1/.github/workflows/ci.yml +53 -0
- readme2demo-0.7.1/.github/workflows/docs.yml +50 -0
- readme2demo-0.7.1/.github/workflows/release.yml +77 -0
- readme2demo-0.7.1/.gitignore +37 -0
- readme2demo-0.7.1/CHANGELOG.md +303 -0
- readme2demo-0.7.1/CITATION.cff +28 -0
- readme2demo-0.7.1/CLAUDE.md +164 -0
- readme2demo-0.7.1/CODE_OF_CONDUCT.md +136 -0
- readme2demo-0.7.1/CONTRIBUTING.md +57 -0
- readme2demo-0.7.1/LICENSE +21 -0
- readme2demo-0.7.1/PKG-INFO +254 -0
- readme2demo-0.7.1/README.md +190 -0
- readme2demo-0.7.1/ROADMAP.md +57 -0
- readme2demo-0.7.1/SECURITY.md +92 -0
- readme2demo-0.7.1/action.yml +167 -0
- readme2demo-0.7.1/architecture/README.md +131 -0
- readme2demo-0.7.1/assets/social-preview.png +0 -0
- readme2demo-0.7.1/docs/configuration.md +55 -0
- readme2demo-0.7.1/docs/demo.gif +0 -0
- readme2demo-0.7.1/docs/faq.md +73 -0
- readme2demo-0.7.1/docs/google316985d142132f04.html +1 -0
- readme2demo-0.7.1/docs/how-it-works.md +57 -0
- readme2demo-0.7.1/docs/index.md +67 -0
- readme2demo-0.7.1/docs/llms.txt +25 -0
- readme2demo-0.7.1/docs/security.md +32 -0
- readme2demo-0.7.1/docs/step-by-step.md +57 -0
- readme2demo-0.7.1/docs/usage.md +68 -0
- readme2demo-0.7.1/docs/whats-new-0.7.0.md +100 -0
- readme2demo-0.7.1/examples/README.md +55 -0
- readme2demo-0.7.1/examples/readme2demo/commands.sh +24 -0
- readme2demo-0.7.1/examples/readme2demo/demo.gif +0 -0
- readme2demo-0.7.1/examples/readme2demo/demo.mp4 +0 -0
- readme2demo-0.7.1/examples/readme2demo/howto.jsonld +77 -0
- readme2demo-0.7.1/examples/readme2demo/manifest.json +91 -0
- readme2demo-0.7.1/examples/readme2demo/step_by_step.md +57 -0
- readme2demo-0.7.1/examples/readme2demo/troubleshooting.md +56 -0
- readme2demo-0.7.1/examples/readme2demo/tutorial.md +126 -0
- readme2demo-0.7.1/examples/toolhive/commands.sh +21 -0
- readme2demo-0.7.1/examples/toolhive/demo.gif +0 -0
- readme2demo-0.7.1/examples/toolhive/demo.mp4 +0 -0
- readme2demo-0.7.1/examples/toolhive/howto.jsonld +73 -0
- readme2demo-0.7.1/examples/toolhive/manifest.json +96 -0
- readme2demo-0.7.1/examples/toolhive/step_by_step.md +202 -0
- readme2demo-0.7.1/examples/toolhive/troubleshooting.md +5 -0
- readme2demo-0.7.1/examples/toolhive/tutorial.md +130 -0
- readme2demo-0.7.1/images/base/Dockerfile +73 -0
- readme2demo-0.7.1/images/openhands/Dockerfile +94 -0
- readme2demo-0.7.1/mkdocs.yml +69 -0
- readme2demo-0.7.1/pyproject.toml +96 -0
- readme2demo-0.7.1/readme2demo.toml.example +38 -0
- readme2demo-0.7.1/scripts/self-demo.sh +111 -0
- readme2demo-0.7.1/src/readme2demo/__init__.py +21 -0
- readme2demo-0.7.1/src/readme2demo/agent.py +176 -0
- readme2demo-0.7.1/src/readme2demo/cli.py +622 -0
- readme2demo-0.7.1/src/readme2demo/config.py +73 -0
- readme2demo-0.7.1/src/readme2demo/distill.py +798 -0
- readme2demo-0.7.1/src/readme2demo/engines/__init__.py +9 -0
- readme2demo-0.7.1/src/readme2demo/engines/base.py +116 -0
- readme2demo-0.7.1/src/readme2demo/engines/claude_code.py +363 -0
- readme2demo-0.7.1/src/readme2demo/engines/openhands.py +323 -0
- readme2demo-0.7.1/src/readme2demo/ingest.py +287 -0
- readme2demo-0.7.1/src/readme2demo/llm.py +511 -0
- readme2demo-0.7.1/src/readme2demo/manifest.py +161 -0
- readme2demo-0.7.1/src/readme2demo/normalize.py +230 -0
- readme2demo-0.7.1/src/readme2demo/orchestrator.py +424 -0
- readme2demo-0.7.1/src/readme2demo/prompts/agent.md +97 -0
- readme2demo-0.7.1/src/readme2demo/prompts/distill.md +77 -0
- readme2demo-0.7.1/src/readme2demo/prompts/planner.md +99 -0
- readme2demo-0.7.1/src/readme2demo/prompts/tutorial.md +31 -0
- readme2demo-0.7.1/src/readme2demo/render.py +266 -0
- readme2demo-0.7.1/src/readme2demo/sandbox.py +184 -0
- readme2demo-0.7.1/src/readme2demo/templates/demo.tape.j2 +69 -0
- readme2demo-0.7.1/src/readme2demo/templates/tutorial.md.j2 +59 -0
- readme2demo-0.7.1/src/readme2demo/tutorial.py +647 -0
- readme2demo-0.7.1/src/readme2demo/types.py +175 -0
- readme2demo-0.7.1/src/readme2demo/verify.py +199 -0
- readme2demo-0.7.1/tests/conftest.py +21 -0
- readme2demo-0.7.1/tests/fixtures/claude_transcript.ndjson +26 -0
- readme2demo-0.7.1/tests/test_cli.py +631 -0
- readme2demo-0.7.1/tests/test_config.py +154 -0
- readme2demo-0.7.1/tests/test_distill.py +892 -0
- readme2demo-0.7.1/tests/test_ingest.py +387 -0
- readme2demo-0.7.1/tests/test_llm_backend.py +956 -0
- readme2demo-0.7.1/tests/test_normalize.py +727 -0
- readme2demo-0.7.1/tests/test_orchestrator.py +326 -0
- readme2demo-0.7.1/tests/test_render_timeout_image.py +58 -0
- readme2demo-0.7.1/tests/test_sandbox.py +318 -0
- readme2demo-0.7.1/tests/test_tutorial.py +698 -0
- readme2demo-0.7.1/tests/test_verify.py +336 -0
- readme2demo-0.7.1/tests/test_version.py +42 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grounding-auditor
|
|
3
|
+
description: Audit code or prompt changes against readme2demo's grounding invariant before commit. Use PROACTIVELY after any change touching distill.py, tutorial.py, normalize.py, engines/, prompts/, or templates/ — anything on the path between the LLM and the published artifacts.
|
|
4
|
+
tools: Read, Grep, Glob, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are the guardian of readme2demo's core invariant:
|
|
8
|
+
|
|
9
|
+
> The LLM never publishes anything a fresh container didn't independently
|
|
10
|
+
> execute. Grounding is enforced in code, not prompts.
|
|
11
|
+
|
|
12
|
+
Given a diff or a set of changed files, answer ONE question: can any command
|
|
13
|
+
or output now reach a published artifact (tutorial.md, step_by_step.md,
|
|
14
|
+
commands.sh, demo.tape, howto.jsonld) without being backed by the agent log
|
|
15
|
+
or the verify replay?
|
|
16
|
+
|
|
17
|
+
## Checklist
|
|
18
|
+
|
|
19
|
+
1. `distill.py`: every path into `commands.sh`/`demo.tape` still passes
|
|
20
|
+
through `is_grounded`/`validate_grounding` or an explicitly documented
|
|
21
|
+
exception (`cd`, comments, harness clone, pipe variants, heredoc prefixes,
|
|
22
|
+
findings_success entries). New equivalences must be SYMMETRIC in
|
|
23
|
+
`normalize_cmd`/`_grounded_candidates` and regression-tested both ways
|
|
24
|
+
(grounded variant accepted, unproven command still rejected).
|
|
25
|
+
2. `tutorial.py`: `enforce_commands` still restores every command AND
|
|
26
|
+
expected_output from the grounded outline after the LLM polish pass;
|
|
27
|
+
expected outputs come from verify.log or the agent log, never the model.
|
|
28
|
+
3. `normalize.py` + `engines/*`: parsing stays pure/deterministic (no LLM
|
|
29
|
+
calls); `mark_findings_success` only marks entries matching BOTH the
|
|
30
|
+
success command and the expected pattern.
|
|
31
|
+
4. Prompt-only fixes: reject them. A prompt change without a corresponding
|
|
32
|
+
code-level check or test is not a defense (search the diff for prompt
|
|
33
|
+
edits lacking sibling code/test changes).
|
|
34
|
+
5. `sandbox.py`: hardening flags intact (--cap-drop ALL, no-new-privileges,
|
|
35
|
+
limits, non-root); docker-socket mounting stays opt-in.
|
|
36
|
+
6. Run `python -m pytest tests/ -q` and report the count.
|
|
37
|
+
|
|
38
|
+
## Report format
|
|
39
|
+
|
|
40
|
+
- **Verdict**: PASS / FAIL (+ the specific leak path if FAIL).
|
|
41
|
+
- **Weakened checks**: any check made more permissive, with justification
|
|
42
|
+
status (documented + tested, or not).
|
|
43
|
+
- **Missing regression tests**: for each behavior change.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: run-debugger
|
|
3
|
+
description: Diagnose a failed or unverified readme2demo run directory. Use PROACTIVELY whenever a pipeline run fails, verify doesn't pass, a video comes out short/incomplete, or generated docs are missing steps. Input should include the runs/<run-id> path.
|
|
4
|
+
tools: Read, Grep, Glob, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You diagnose failed readme2demo runs. You are read-mostly: produce a precise
|
|
8
|
+
diagnosis and a repair plan; only write files when explicitly asked to repair.
|
|
9
|
+
|
|
10
|
+
## Procedure
|
|
11
|
+
|
|
12
|
+
1. Read `manifest.json` in the run dir: which stage failed/skipped, stage
|
|
13
|
+
`meta` (outcome, adjusted_success, source_modified,
|
|
14
|
+
guide_steps_unattempted, tape_coverage), `verified`, total cost.
|
|
15
|
+
2. Read the failing stage's evidence:
|
|
16
|
+
- verify failures → `verify.log` (find `===== ATTEMPT n =====` markers,
|
|
17
|
+
read the tail of the LAST attempt; the line after the final `+ cmd`
|
|
18
|
+
trace is where it died) and `commands.sh`.
|
|
19
|
+
- agent failures → `command_log.json`: filter entries by exit_code,
|
|
20
|
+
read outputs of the failures; check `fixes`, `adjusted_success_command`,
|
|
21
|
+
`file_edits`.
|
|
22
|
+
- render failures → the RenderError text, `demo.tape`, tape vs
|
|
23
|
+
`expected_min_duration_s`.
|
|
24
|
+
- doc-quality complaints → `step_by_step.md` / `tutorial.md` vs
|
|
25
|
+
`command_log.json`: which proven commands are missing from the docs?
|
|
26
|
+
3. Match against the "Known failure classes" table in CLAUDE.md — most
|
|
27
|
+
failures are a recurrence or a sibling of a known class. Name the class.
|
|
28
|
+
4. If it is genuinely new: state the mechanism (what state/assumption
|
|
29
|
+
diverged between the agent container and the verify/render container),
|
|
30
|
+
which module owns it, and what code-level defense would have caught it.
|
|
31
|
+
|
|
32
|
+
## Report format
|
|
33
|
+
|
|
34
|
+
- **Verdict**: one sentence — what failed and why.
|
|
35
|
+
- **Class**: known-class number from CLAUDE.md, or "NEW".
|
|
36
|
+
- **Evidence**: 2-4 quoted lines from logs.
|
|
37
|
+
- **Systemic fix**: file + function to change (code first; prompt second).
|
|
38
|
+
- **Run repair**: the cheapest way to salvage THIS run (patch commands.sh /
|
|
39
|
+
plan.json / regenerate guide+tape via the pure functions in distill.py and
|
|
40
|
+
tutorial.py) and the exact `readme2demo resume <run> --from-stage <s>`
|
|
41
|
+
command. Never suggest re-running the agent when a downstream repair works.
|
|
42
|
+
|
|
43
|
+
Key fact for repairs: distill/tutorial artifact writers
|
|
44
|
+
(`write_step_by_step`, `tape_from_guide`, `write_tape`) are pure functions —
|
|
45
|
+
they can regenerate a run's guide and tape from `command_log.json` +
|
|
46
|
+
`plan.json` without any LLM cost.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Pre-commit gauntlet for readme2demo — invariant audit, tests, hygiene
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run the pre-commit gauntlet on the current working tree:
|
|
6
|
+
|
|
7
|
+
1. Run `python -m pytest tests/ -q` — must be fully green.
|
|
8
|
+
2. `python -m compileall -q src/` — must be clean.
|
|
9
|
+
3. Use the grounding-auditor agent on the staged/changed files if anything
|
|
10
|
+
under src/readme2demo/{distill,tutorial,normalize,engines,prompts,templates}
|
|
11
|
+
changed.
|
|
12
|
+
4. Hygiene greps: no `runs/` paths staged (`git status --short | grep runs/`
|
|
13
|
+
must be empty), no credentials
|
|
14
|
+
(`git diff --cached | grep -iE 'sk-ant-[a-z0-9]{8}'` empty).
|
|
15
|
+
5. If prompts/*.md changed: confirm the change has a sibling code check or
|
|
16
|
+
test, and note which real run motivated it.
|
|
17
|
+
6. If images/base/Dockerfile changed: remind that users must rebuild
|
|
18
|
+
(`docker build --no-cache -t readme2demo/base:latest images/base/`) and
|
|
19
|
+
check the Claude Code pin ↔ stream-json parser coupling.
|
|
20
|
+
7. Report: test count, files changed by area, any CLAUDE.md failure-class
|
|
21
|
+
entries that should be added for this change, and a suggested
|
|
22
|
+
conventional commit message.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-engine
|
|
3
|
+
description: Add a new AI agent backend (engine) to readme2demo, or fix parsing for an existing one (claude-code stream-json drift, openhands trajectory changes). Use when adding support for a new coding agent or when transcripts stop parsing after an agent CLI upgrade.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Adding or fixing an agent engine
|
|
7
|
+
|
|
8
|
+
Engines are the ONLY place that knows which AI agent ran. Everything
|
|
9
|
+
downstream consumes `command_log.json`.
|
|
10
|
+
|
|
11
|
+
## The contract (`engines/base.py`)
|
|
12
|
+
|
|
13
|
+
Implement `AgentEngine` and decorate with `@register`:
|
|
14
|
+
|
|
15
|
+
- `name`: CLI value for `--engine`.
|
|
16
|
+
- `required_env()` / `resolve_env()`: host env vars forwarded into the
|
|
17
|
+
sandbox at exec time (never baked into images). Support alternative auth
|
|
18
|
+
by overriding `resolve_env` (see ClaudeCodeEngine's key-OR-oauth-token,
|
|
19
|
+
including the credential-format validation — copy it).
|
|
20
|
+
- `build_command(limits)`: one shell string run via `bash -lc` inside the
|
|
21
|
+
container; reads the prompt from `PROMPT_CONTAINER_PATH`, writes the raw
|
|
22
|
+
transcript to `TRANSCRIPT_CONTAINER_PATH`, stderr next to it.
|
|
23
|
+
- `parse_transcript(path) -> CommandLog`: PURE, deterministic, no LLM calls,
|
|
24
|
+
tolerant of malformed lines and schema drift. Reuse `truncate_output`,
|
|
25
|
+
`scan_markers`, `scan_adjusted` from `claude_code.py` so markers and
|
|
26
|
+
truncation behave identically across engines.
|
|
27
|
+
|
|
28
|
+
## Parsing requirements
|
|
29
|
+
|
|
30
|
+
- Pair command events with their results; unpaired commands get
|
|
31
|
+
`exit_code=None` (never fabricate 0).
|
|
32
|
+
- Extract: Bash-equivalent commands + outputs (head 3KB + tail 1KB
|
|
33
|
+
truncation), file edits, FIX/BLOCKED/ADJUSTED_SUCCESS markers, outcome
|
|
34
|
+
(blocked > success-marker > failed), cost/turns/duration when available
|
|
35
|
+
(None when not — budget logic treats None as unknown, not zero).
|
|
36
|
+
|
|
37
|
+
## Checklist
|
|
38
|
+
|
|
39
|
+
1. `engines/<name>.py` with the above; module docstring stating the
|
|
40
|
+
transcript format assumptions and its drift-tolerance strategy.
|
|
41
|
+
2. Fixture transcript in `tests/fixtures/` exercising: success + failure
|
|
42
|
+
pairs, a marker, a malformed line, string-vs-list content shapes.
|
|
43
|
+
3. Tests: parse the fixture, verify counts/exit codes/markers/outcome;
|
|
44
|
+
missing-env EngineError; build_command shape (uses the canonical
|
|
45
|
+
container paths, not hardcoded strings).
|
|
46
|
+
4. If the format VERSION is coupled to a pinned CLI in
|
|
47
|
+
`images/base/Dockerfile`, bump pin and parser together and say so in the
|
|
48
|
+
commit message.
|
|
49
|
+
5. README: add the engine to the auth/requirements section.
|
|
50
|
+
|
|
51
|
+
## Known drift landmines
|
|
52
|
+
|
|
53
|
+
- claude-code stream-json: `tool_result.content` is a string OR a list of
|
|
54
|
+
text blocks; the final `result` event can be absent when the agent is
|
|
55
|
+
killed (marker alone then decides success).
|
|
56
|
+
- openhands trajectories: JSON array, `{"events": [...]}` wrapper, or JSONL
|
|
57
|
+
— detect all three.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-failure-class
|
|
3
|
+
description: The workflow for turning a newly diagnosed readme2demo run failure into a permanent, tested defense. Use after debug-run identifies a failure mechanism that is not yet in CLAUDE.md's known-failure-classes table.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Adding a failure class (the maintenance meta-workflow)
|
|
7
|
+
|
|
8
|
+
Every robustness feature in this repo came from a real failed run processed
|
|
9
|
+
through exactly these steps. Do them in order; skipping the test or the
|
|
10
|
+
CLAUDE.md entry is how knowledge evaporates.
|
|
11
|
+
|
|
12
|
+
## Steps
|
|
13
|
+
|
|
14
|
+
1. **Name the mechanism, not the symptom.** "verify exit 1" is a symptom;
|
|
15
|
+
"findings tools exit nonzero on success and set -e kills the assertion"
|
|
16
|
+
is a mechanism. You must be able to say which two components disagreed
|
|
17
|
+
about an assumption.
|
|
18
|
+
|
|
19
|
+
2. **Pick the owning module** (one, occasionally two):
|
|
20
|
+
- agent behavior → `prompts/agent.md` rule AND a detector in
|
|
21
|
+
`normalize.py` (rule 6 + repo_files_edited is the template)
|
|
22
|
+
- command equivalence → `distill.normalize_cmd` / `_grounded_candidates`
|
|
23
|
+
(always symmetric, both directions tested)
|
|
24
|
+
- replay semantics → `distill._render_commands_sh` (assertion block) or
|
|
25
|
+
`verify.py`
|
|
26
|
+
- video → `templates/demo.tape.j2` / `render.py` gates
|
|
27
|
+
- parsing → the engine adapter, kept pure and tolerant
|
|
28
|
+
|
|
29
|
+
3. **Code first, prompt second.** If the fix involves an LLM behaving
|
|
30
|
+
differently, the prompt edit gets a sibling code-level check or
|
|
31
|
+
validation — prompts alone are not defenses.
|
|
32
|
+
|
|
33
|
+
4. **Regression test named for the run.** Docstring starts with
|
|
34
|
+
`"""Regression (<repo> run): ..."""` describing the real failure. Must
|
|
35
|
+
fail on the old code. Tests stay free of docker/network/API.
|
|
36
|
+
|
|
37
|
+
5. **Repair the triggering run cheaply** (see debug-run skill) and give the
|
|
38
|
+
exact resume command.
|
|
39
|
+
|
|
40
|
+
6. **Document**: add a numbered entry to CLAUDE.md "Known failure classes"
|
|
41
|
+
(symptom → mechanism → defense location). If the class is user-visible,
|
|
42
|
+
consider a line in README or the troubleshooting-relevant prompt.
|
|
43
|
+
|
|
44
|
+
7. **Full suite green** (`python -m pytest tests/ -q`) before claiming done.
|
|
45
|
+
|
|
46
|
+
## Quality bar for grounding changes
|
|
47
|
+
|
|
48
|
+
New equivalences (like the 2>&1 or pipe-variant rules) must:
|
|
49
|
+
- apply to BOTH the candidate set and the queried command (symmetry),
|
|
50
|
+
- never make an unproven command grounded (add a negative test: the evil
|
|
51
|
+
variant is still rejected),
|
|
52
|
+
- be documented in the `is_grounded` docstring's accepted-forms list.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: debug-run
|
|
3
|
+
description: Debug a failed, unverified, or low-quality readme2demo pipeline run. Use when a run fails at any stage, verify won't pass, the demo video is short or missing steps, generated docs lack detail, or the user pastes readme2demo CLI output showing a failure.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Debugging a readme2demo run
|
|
7
|
+
|
|
8
|
+
Every run leaves complete evidence in `runs/<run-id>/`. Read evidence before
|
|
9
|
+
theorizing — the answer is almost always in three files.
|
|
10
|
+
|
|
11
|
+
## Evidence map
|
|
12
|
+
|
|
13
|
+
| File | Tells you |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `manifest.json` | which stage failed, stage meta (outcome, adjusted_success, source_modified, guide_steps_unattempted, tape_coverage), verified flag, cost |
|
|
16
|
+
| `command_log.json` | every command the agent ran, exit codes, outputs, FIX markers, findings_success flags |
|
|
17
|
+
| `verify.log` | the clean-container replay, bash -x traced; last `+ cmd` before silence = point of death; `===== ATTEMPT n =====` separates tries |
|
|
18
|
+
| `commands.sh` | what verify executed — preamble (harness clone), steps, assertion block |
|
|
19
|
+
| `step_by_step.md` + `tape_coverage.json` | what made the docs/video and what was dropped (with reasons) |
|
|
20
|
+
| `transcript.ndjson` | raw agent stream (only needed for parser bugs) |
|
|
21
|
+
|
|
22
|
+
## Decision tree
|
|
23
|
+
|
|
24
|
+
1. **ingest failed** → planner/LLM issue or infeasible repo (read plan.json
|
|
25
|
+
blockers). Infeasible is often CORRECT behavior.
|
|
26
|
+
2. **agent failed/blocked** → read final assistant text in command_log
|
|
27
|
+
result + failed entries. Check for the cutoff-denial pattern ("X isn't
|
|
28
|
+
released yet") and infrastructure rabbit holes (fake sockets). Blocked
|
|
29
|
+
for credentials/GPU is correct behavior.
|
|
30
|
+
3. **distill failed (ungrounded)** → compare the rejected command against
|
|
31
|
+
the log: usually a syntax-equivalence gap (whitespace, 2>&1, env prefix,
|
|
32
|
+
chain, pipe-cap, heredoc body). Fix in `normalize_cmd` /
|
|
33
|
+
`_grounded_candidates` symmetrically, never by weakening validation.
|
|
34
|
+
4. **verify failed** → tail the last attempt in verify.log. Common causes in
|
|
35
|
+
order: missing setup step, cwd drift (run `verify.cwd_hints` on the
|
|
36
|
+
script), findings-tool nonzero exit reaching `set -e`, wrong
|
|
37
|
+
expected_pattern, agent had patched source (manifest source_modified).
|
|
38
|
+
5. **render failed** → duration gate (steps didn't play → stale image or
|
|
39
|
+
tape bug), VHS parse error (quoting), disk exhaustion (docker system
|
|
40
|
+
prune), socket permissions if the tape manages containers.
|
|
41
|
+
6. **docs/video missing steps** → `tape_coverage.json` dropped list +
|
|
42
|
+
normalize's guide_steps_unattempted meta. Unattempted = agent never ran
|
|
43
|
+
it (needs fresh agent run); dropped = grounding gap (fixable + tape
|
|
44
|
+
regenerable without LLM).
|
|
45
|
+
|
|
46
|
+
## Cheap repairs (no agent re-run)
|
|
47
|
+
|
|
48
|
+
The artifact writers are pure functions. From the repo root:
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
# regenerate guide + tape for an existing run after a code fix
|
|
52
|
+
PYTHONPATH=src python3 - <<'EOF'
|
|
53
|
+
from pathlib import Path
|
|
54
|
+
from readme2demo.distill import tape_from_guide, write_tape
|
|
55
|
+
from readme2demo.tutorial import write_step_by_step
|
|
56
|
+
from readme2demo.types import CommandLog, Plan, TutorialOutline
|
|
57
|
+
rd = Path("runs/<run-id>")
|
|
58
|
+
plan = Plan.model_validate_json((rd/"plan.json").read_text())
|
|
59
|
+
log = CommandLog.model_validate_json((rd/"command_log.json").read_text())
|
|
60
|
+
outline = TutorialOutline.model_validate_json((rd/"tutorial_outline.json").read_text())
|
|
61
|
+
write_step_by_step(rd, plan, outline, log, verified=False, repo_url="<url>")
|
|
62
|
+
write_tape(tape_from_guide((rd/"step_by_step.md").read_text(), log, [], "<url>"), rd)
|
|
63
|
+
EOF
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`commands.sh` and `plan.json` can be patched by hand for one run; then
|
|
67
|
+
`readme2demo resume runs/<run-id> --from-stage <verify|render|tutorial>`.
|
|
68
|
+
Resume from the EARLIEST stage whose inputs changed, never earlier.
|
|
69
|
+
|
|
70
|
+
## After the diagnosis
|
|
71
|
+
|
|
72
|
+
If the cause is new, follow the add-failure-class skill: systemic code fix +
|
|
73
|
+
regression test + CLAUDE.md failure-class entry. A run-specific patch without
|
|
74
|
+
a systemic fix just schedules the same debugging session for the next repo.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: docker-sandbox
|
|
3
|
+
description: Docker usage in readme2demo — the base image, hardened sandbox lifecycle, the Docker-socket opt-in, and diagnosing container/daemon failures. Use when touching sandbox.py, images/base/Dockerfile, render.py, verify.py, or when a run fails with a docker/daemon/permission/disk error.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Docker & the sandbox
|
|
7
|
+
|
|
8
|
+
The container IS the security boundary. READMEs are untrusted code; the agent
|
|
9
|
+
runs INSIDE the container so `--dangerously-skip-permissions` is safe.
|
|
10
|
+
|
|
11
|
+
## The base image (`images/base/Dockerfile`)
|
|
12
|
+
|
|
13
|
+
- Built FROM `ghcr.io/charmbracelet/vhs:latest` so ONE image serves the agent
|
|
14
|
+
run, the verify replay, AND the video render (vhs + ttyd + ffmpeg from the
|
|
15
|
+
base; git/Go/Python/Node + Claude Code added on top). This is why the video
|
|
16
|
+
can execute real toolchain steps on camera.
|
|
17
|
+
- `ENTRYPOINT []` + `CMD ["bash"]`: the VHS image ships `ENTRYPOINT ["vhs"]`;
|
|
18
|
+
reset it so `sandbox.py` can run arbitrary commands. The renderer re-invokes
|
|
19
|
+
vhs via `--entrypoint vhs`.
|
|
20
|
+
- Go comes from the official tarball at build time (distro packages lag and
|
|
21
|
+
strand agents on "go >= 1.2x required"). Rebuild periodically to stay current.
|
|
22
|
+
- The Claude Code npm pin is COUPLED to the stream-json parser
|
|
23
|
+
(`engines/claude_code.py`) — bump them together.
|
|
24
|
+
- Rebuild after ANY Dockerfile change:
|
|
25
|
+
`docker build --no-cache -t readme2demo/base:latest images/base/`. The render
|
|
26
|
+
stage preflights the image (`render.check_render_image`) and errors clearly
|
|
27
|
+
if it's stale (missing vhs/ffmpeg/git).
|
|
28
|
+
|
|
29
|
+
## Hardening (`sandbox.py` — never weaken without discussion)
|
|
30
|
+
|
|
31
|
+
Every container: `--cap-drop ALL`, `--security-opt no-new-privileges`,
|
|
32
|
+
`--memory/--cpus/--pids-limit`, non-root user `demo` (uid 1000), wall-clock
|
|
33
|
+
timeout, destroyed after the stage. Run dirs are mounted with ABSOLUTE paths
|
|
34
|
+
(docker -v treats relative as a volume name).
|
|
35
|
+
|
|
36
|
+
## Docker-socket opt-in (`--allow-docker-socket`)
|
|
37
|
+
|
|
38
|
+
For tools that manage containers themselves (toolhive `thv run`,
|
|
39
|
+
testcontainers, compose repos). Mounts `/var/run/docker.sock` into agent +
|
|
40
|
+
verify + render. The non-root user needs `--group-add $(socket gid)` —
|
|
41
|
+
`sandbox.docker_socket_gid` probes it (`stat -c %g`) or every socket call is
|
|
42
|
+
EACCES and the tool reports "no container runtime available" despite the mount.
|
|
43
|
+
Pierces isolation: trusted repos only; the CLI prints the warning in red.
|
|
44
|
+
|
|
45
|
+
## Diagnosing docker failures
|
|
46
|
+
|
|
47
|
+
- `input/output error` / `containerd meta.db` → Docker VM disk full (VHS writes
|
|
48
|
+
a PNG per frame). `docker system prune -af --volumes`; restart Docker
|
|
49
|
+
Desktop; raise the VM disk. The render mitigations (24fps, mp4-only, short
|
|
50
|
+
ffmpeg gif preview) exist because full-length GIFs once filled the disk.
|
|
51
|
+
- exit 125 from `docker run` → bad flags / relative mount path — check the
|
|
52
|
+
Sandbox args.
|
|
53
|
+
- "no container runtime available" WITH `--allow-docker-socket` → group-add gid
|
|
54
|
+
problem (above).
|
|
55
|
+
- verify passes but render image errors → stale base image; rebuild.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-github-operator
|
|
3
|
+
description: Git and GitHub operations for maintaining the readme2demo repo — branching, conventional commits, PRs, releases, and the never-commit rules. Use when committing, opening a PR, tagging a release, or doing any git/gh operation on this repo.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Git & GitHub operator for readme2demo
|
|
7
|
+
|
|
8
|
+
Remote: `https://github.com/alphacrack/readme2demo` (origin). Default branch:
|
|
9
|
+
`main`. In non-interactive sessions you can stage/commit locally but the human
|
|
10
|
+
runs `git push` (auth lives on their machine).
|
|
11
|
+
|
|
12
|
+
## Never commit
|
|
13
|
+
|
|
14
|
+
- `runs/` — every pipeline run (transcripts, videos, cloned repos, and
|
|
15
|
+
potentially the target repo's content). Gitignored; keep it that way.
|
|
16
|
+
Publishable examples are HAND-COPIED into `examples/` after review.
|
|
17
|
+
- `.env`, `readme2demo.toml`, any credential. Before every commit:
|
|
18
|
+
`git diff --cached | grep -iE 'sk-ant-[a-z0-9]{8}'` must be empty, and
|
|
19
|
+
`git status --short | grep runs/` must be empty.
|
|
20
|
+
|
|
21
|
+
## Commit style
|
|
22
|
+
|
|
23
|
+
Conventional-ish, imperative subject, then a body that lists WHAT changed and
|
|
24
|
+
WHY — this repo's history is a design log (read `git log` to see the bar).
|
|
25
|
+
When a commit fixes a failure class, name the run that found it and note the
|
|
26
|
+
regression test. One concern per commit where practical; batch tightly-coupled
|
|
27
|
+
changes (code + test + CLAUDE.md entry) together.
|
|
28
|
+
|
|
29
|
+
## Pre-push gate
|
|
30
|
+
|
|
31
|
+
Run the `/ship-check` command (or the ship-check flow): tests green, compile
|
|
32
|
+
clean, grounding-auditor on any src change touching the LLM→artifact path,
|
|
33
|
+
hygiene greps. If `images/base/Dockerfile` changed, the commit body must tell
|
|
34
|
+
users to rebuild (`docker build --no-cache -t readme2demo/base:latest images/base/`).
|
|
35
|
+
|
|
36
|
+
## Branches & PRs
|
|
37
|
+
|
|
38
|
+
- Feature work on a branch; PR into main. PR description states the failure
|
|
39
|
+
class or feature, the systemic fix (code first), and the regression test.
|
|
40
|
+
- CI (`.github/workflows/ci.yml`) runs the suite on 3.10 and 3.12 — a red CI
|
|
41
|
+
blocks merge. Keep the suite docker/network/API-free so CI stays fast.
|
|
42
|
+
- `good first issue` / `help wanted` labels are seeded for contributors (see
|
|
43
|
+
launch/LAUNCH_CHECKLIST.md).
|
|
44
|
+
|
|
45
|
+
## Releases
|
|
46
|
+
|
|
47
|
+
- Tag `vX.Y.Z` with honest notes (state the MVP tradeoffs — Docker required,
|
|
48
|
+
README treated as untrusted code, API key enters sandbox until the egress
|
|
49
|
+
proxy lands). The pinned Claude Code version in the base image is coupled to
|
|
50
|
+
the stream-json parser — call out a bump in the release notes.
|
|
51
|
+
|
|
52
|
+
## Repairing a user's run without git
|
|
53
|
+
|
|
54
|
+
Run dirs are disposable and gitignored. To salvage a failed run, patch its
|
|
55
|
+
`commands.sh`/`plan.json` or regenerate its guide+tape with the pure functions
|
|
56
|
+
(see the debug-run skill) and give the `resume --from-stage` command — no
|
|
57
|
+
commit involved.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: python-standards
|
|
3
|
+
description: Python coding standards, testing patterns, and pydantic/typing conventions for the readme2demo codebase. Use when writing or reviewing any Python in src/readme2demo/ or tests/, adding a module, or before committing code changes.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Python standards for readme2demo
|
|
7
|
+
|
|
8
|
+
Python ≥3.10. Match the surrounding code; these are the invariants.
|
|
9
|
+
|
|
10
|
+
## Types & models
|
|
11
|
+
|
|
12
|
+
- Type hints on every public function signature; return types included.
|
|
13
|
+
- Data contracts are pydantic v2 models in `types.py` — the single source of
|
|
14
|
+
truth every stage serializes through. Add a field THERE first, never invent
|
|
15
|
+
an ad-hoc dict that crosses a stage boundary. Use `model_dump_json(indent=2)`
|
|
16
|
+
/ `model_validate_json` for run-dir I/O.
|
|
17
|
+
- `Optional[X]` for nullable; default containers via `Field(default_factory=...)`.
|
|
18
|
+
- New fields must be backward-compatible (defaulted) — old run dirs on disk
|
|
19
|
+
must still load.
|
|
20
|
+
|
|
21
|
+
## Purity boundary (enforced, not stylistic)
|
|
22
|
+
|
|
23
|
+
- `normalize.py` and every engine `parse_transcript` are PURE and
|
|
24
|
+
deterministic: no LLM calls, no network, no docker, no clock/random that
|
|
25
|
+
changes output. They are tested against fixtures. If you need an LLM, you
|
|
26
|
+
are in the wrong module.
|
|
27
|
+
- LLM calls live only in ingest (planner), distill, tutorial — via `llm.py`.
|
|
28
|
+
|
|
29
|
+
## Docstrings
|
|
30
|
+
|
|
31
|
+
- One-line summary; then WHY when non-obvious. Regression-critical functions
|
|
32
|
+
carry the failure they defend against (search for "Regression (" in tests).
|
|
33
|
+
- Public functions in the pipeline path get a docstring naming their invariant.
|
|
34
|
+
|
|
35
|
+
## Testing (this is where the repo's value lives)
|
|
36
|
+
|
|
37
|
+
- `python -m pytest tests/ -q` runs in <1s with NO docker/network/API. Keep it
|
|
38
|
+
that way: mock `llm.complete_json`, feed fixture transcripts, build models
|
|
39
|
+
inline. Anything needing real infra is marked `@pytest.mark.integration`.
|
|
40
|
+
- EVERY bug fix carries a regression test whose docstring starts
|
|
41
|
+
`"""Regression (<repo> run): ..."""` and describes the real failure. It must
|
|
42
|
+
fail on the old code.
|
|
43
|
+
- For grounding/equivalence changes: test BOTH directions — the new-variant is
|
|
44
|
+
accepted AND an unproven/evil command is still rejected.
|
|
45
|
+
- Prefer table-style asserts on the actual artifact (the rendered commands.sh,
|
|
46
|
+
the tape text, the guide markdown), not on internal state.
|
|
47
|
+
|
|
48
|
+
## Style
|
|
49
|
+
|
|
50
|
+
- stdlib > third-party; the runtime deps are deliberately few (typer, rich,
|
|
51
|
+
pydantic, jinja2, anthropic). Don't add a dependency for something stdlib
|
|
52
|
+
does.
|
|
53
|
+
- `subprocess.run(..., capture_output=True, text=True, timeout=..., errors="replace")`
|
|
54
|
+
is the house pattern for shelling out; always set a timeout.
|
|
55
|
+
- Fail with a specific, actionable message (name the env var, the file, the
|
|
56
|
+
fix command) — see the preflight and EngineError messages for the tone.
|
|
57
|
+
|
|
58
|
+
## Before you commit
|
|
59
|
+
|
|
60
|
+
Run `/ship-check`. Minimum: full suite green, `python -m compileall -q src/`
|
|
61
|
+
clean, no `runs/` or secrets staged.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sandbox-toolchains
|
|
3
|
+
description: How readme2demo handles TARGET-repo languages and toolchains (Go, Node, Python, Rust, Terraform, etc.) inside the sandbox — version currency, install patterns, and the agent rules that keep runs honest. Use when a run fails on a toolchain install/version, or when extending language support in the base image or agent prompt.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Target-repo toolchains in the sandbox
|
|
7
|
+
|
|
8
|
+
readme2demo runs OTHER projects' quickstarts. The base image ships common
|
|
9
|
+
toolchains; the agent installs anything else. Two recurring hazards, both with
|
|
10
|
+
agent-prompt rules AND code defenses.
|
|
11
|
+
|
|
12
|
+
## Version currency (failure class 2)
|
|
13
|
+
|
|
14
|
+
The agent's training data is STALE — languages/tools newer than it remembers
|
|
15
|
+
almost certainly exist. `prompts/agent.md` rule 4: never declare a version
|
|
16
|
+
"unreleased"; CHECK the official source
|
|
17
|
+
(`curl -sL 'https://go.dev/VERSION?m=text'`, `pyenv install --list`,
|
|
18
|
+
`npm view <pkg> version`) then download it. Keep the base image's Go current
|
|
19
|
+
(built from the official tarball) so the common case needs no download.
|
|
20
|
+
|
|
21
|
+
## Install patterns the agent uses (and that must survive verify)
|
|
22
|
+
|
|
23
|
+
- Python externally-managed sandbox → `pip install --break-system-packages`
|
|
24
|
+
(and `--no-input`). Editable installs (`pip install -e .`) are cwd-sensitive
|
|
25
|
+
— see below.
|
|
26
|
+
- Go: `go build` with a current toolchain; GOTOOLCHAIN pitfalls handled by
|
|
27
|
+
shipping a new-enough Go.
|
|
28
|
+
- Binaries fetched by curl+unzip go to `~/.local/bin` or `~/bin` on PATH.
|
|
29
|
+
|
|
30
|
+
## cwd drift (failure class 6)
|
|
31
|
+
|
|
32
|
+
`cd` persists across script lines. The classic bug: `cd /tmp` to unpack a
|
|
33
|
+
binary, then `pip install -e .` editable-installs /tmp instead of the repo.
|
|
34
|
+
`prompts/distill.md` rule 5b requires a `cd` on/before any relative-path line;
|
|
35
|
+
`verify.cwd_hints` runs a static cwd simulation of a failing script and injects
|
|
36
|
+
precise hints into the distiller retry. The repo is always at `/work`.
|
|
37
|
+
|
|
38
|
+
## Findings tools (failure class 4)
|
|
39
|
+
|
|
40
|
+
Linters, drift detectors, scanners (tfdrift, etc.) exit NONZERO when they find
|
|
41
|
+
what the demo exists to show. The assertion block uses `set +e` +
|
|
42
|
+
pattern-as-criterion; `normalize.mark_findings_success` reclassifies such
|
|
43
|
+
entries as successful so they count for grounding, the tape, and the payoff
|
|
44
|
+
step. When adding language support, remember success ≠ exit 0 for this class.
|
|
45
|
+
|
|
46
|
+
## Extending support
|
|
47
|
+
|
|
48
|
+
Add a toolchain to `images/base/Dockerfile` only if it's common across target
|
|
49
|
+
repos (keep the image lean; the agent can install niche tools). Per-ecosystem
|
|
50
|
+
slim images are a known future optimization, not the MVP.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vhs-video
|
|
3
|
+
description: VHS tape syntax and ffmpeg video handling in readme2demo — how the demo video is generated, the hard-won gotchas, and the duration gate. Use when touching templates/demo.tape.j2, render.py, distill.tape_from_guide, or when a video is short, blank, mis-paced, or fails to render.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# VHS tapes & video
|
|
7
|
+
|
|
8
|
+
The demo video is built from the FINAL `step_by_step.md` (render stage, after
|
|
9
|
+
tutorial finalizes the guide) so the video follows the published guide
|
|
10
|
+
step-for-step. `distill.tape_from_guide` parses the guide's fenced bash blocks
|
|
11
|
+
into `TapeCommand`s; `templates/demo.tape.j2` renders the tape; `render.py`
|
|
12
|
+
runs VHS in the base image.
|
|
13
|
+
|
|
14
|
+
## Non-negotiable tape rules (each is a scar)
|
|
15
|
+
|
|
16
|
+
- **Never use `Wait+Screen` on output text.** It matches only the VISIBLE
|
|
17
|
+
buffer; any pattern in longer-than-one-screen output scrolls off and times
|
|
18
|
+
the render out. Pace with `Wait` (blocks until the shell prompt returns, so
|
|
19
|
+
the command — build included — has finished) then a short `Sleep` to read.
|
|
20
|
+
- **VHS string literals have NO backslash escapes.** `vhs_quote` picks a
|
|
21
|
+
delimiter the text doesn't contain: `"` → `` ` `` → `'`. A string with all
|
|
22
|
+
three can't be typed (rare; that step is skipped).
|
|
23
|
+
- **`Type` is single-line.** Multi-line commands (heredocs) are typed
|
|
24
|
+
LINE-BY-LINE via `TapeCommand.lines` (Type/Enter per line) so file creation
|
|
25
|
+
plays on camera — a real shell reads a heredoc until its terminator.
|
|
26
|
+
- **Framerate 24, `Output demo.mp4` only.** A GIF per-frame render of a
|
|
27
|
+
multi-minute tape once filled the Docker VM disk. `demo.gif` is a short
|
|
28
|
+
downscaled ffmpeg preview cut from the mp4 afterwards (best-effort, never
|
|
29
|
+
gates the stage).
|
|
30
|
+
- Hidden preamble `cd /work && clear` so the guide's own `git clone ... .`
|
|
31
|
+
starts from the empty workspace.
|
|
32
|
+
|
|
33
|
+
## Duration gate (`render.validate_outputs`)
|
|
34
|
+
|
|
35
|
+
`expected_min_duration_s` sums the tape's Sleeps + typing time; real command
|
|
36
|
+
execution (the Waits) only adds on top. A video shorter than ~0.8× that bound
|
|
37
|
+
means steps didn't play (stale image, aborted tape) → HARD error, never a
|
|
38
|
+
silently short clip. Bounds: 5s..1500s.
|
|
39
|
+
|
|
40
|
+
## Coverage
|
|
41
|
+
|
|
42
|
+
`render` writes `tape_coverage.json` (guide_steps / tape_steps / dropped) and
|
|
43
|
+
prints any dropped step. With heredocs now on camera, a dropped step means a
|
|
44
|
+
genuinely ungrounded guide command — investigate, don't ignore.
|
|
45
|
+
|
|
46
|
+
## ffmpeg
|
|
47
|
+
|
|
48
|
+
Used for the gif preview (`fps=10,scale=800`) and, on the host, `ffprobe` for
|
|
49
|
+
the duration check. Both run inside the base image for the preview; the host
|
|
50
|
+
ffprobe check is skipped when ffprobe isn't on PATH.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Copy to `.env` (gitignored) and fill in the auth you use. You need ONE of the
|
|
2
|
+
# options below. Do NOT commit real secrets.
|
|
3
|
+
|
|
4
|
+
# Option A — run on your Claude subscription (no API key), self-hosted single
|
|
5
|
+
# operator. This is the default when no provider flag is given. Create the
|
|
6
|
+
# token with `claude setup-token` and paste it here.
|
|
7
|
+
# (Copy the printed sk-ant-oat01-... value; do not use $(claude setup-token).)
|
|
8
|
+
CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-...
|
|
9
|
+
|
|
10
|
+
# Option B — Anthropic metered API billing (scale, concurrency, or hosting for
|
|
11
|
+
# others). Also powers `--anthropic`, which runs the sandboxed agent on the
|
|
12
|
+
# OpenHands engine with a Claude model.
|
|
13
|
+
# ANTHROPIC_API_KEY=sk-ant-...
|
|
14
|
+
# Optional model override for `--anthropic` (default: the config model):
|
|
15
|
+
# ANTHROPIC_MODEL=claude-sonnet-5
|
|
16
|
+
|
|
17
|
+
# Option C — run the whole session on Google Gemini with `--gemini`. This one
|
|
18
|
+
# key powers both the planner/distiller/tutorial passes and the sandboxed agent
|
|
19
|
+
# (via the OpenHands engine). Install the extra: pip install 'readme2demo[gemini]'.
|
|
20
|
+
# GEMINI_API_KEY=...
|
|
21
|
+
# No Gemini model name is built into readme2demo (Google retires old ones with
|
|
22
|
+
# a hard 404). Name it per run (`--gemini <model>`) or set it once here:
|
|
23
|
+
# GEMINI_MODEL=gemini-3.5-flash
|
|
24
|
+
|
|
25
|
+
# Option D — run the whole session on OpenAI with `--openai`. Same shape as
|
|
26
|
+
# Gemini: one key for the passes and the OpenHands agent, no built-in model
|
|
27
|
+
# name. Install the extra: pip install 'readme2demo[openai]'.
|
|
28
|
+
# OPENAI_API_KEY=sk-...
|
|
29
|
+
# OPENAI_MODEL=gpt-5.1
|
|
30
|
+
|
|
31
|
+
# Optional — only for the experimental OpenHands engine (--engine openhands).
|
|
32
|
+
# The provider presets (--gemini / --openai / --anthropic) fill these in from
|
|
33
|
+
# the provider's key automatically; set them by hand only to point OpenHands
|
|
34
|
+
# at a different litellm model/provider.
|
|
35
|
+
# LLM_API_KEY=...
|
|
36
|
+
# LLM_MODEL=...
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Default review owner for everything in the repo.
|
|
2
|
+
# Replace @alphacrack with the GitHub handle(s) or team that should be
|
|
3
|
+
# auto-requested for review on every pull request.
|
|
4
|
+
* @alphacrack
|
|
5
|
+
|
|
6
|
+
# The grounding invariant lives in these files — guard them closely.
|
|
7
|
+
/src/readme2demo/distill.py @alphacrack
|
|
8
|
+
/src/readme2demo/verify.py @alphacrack
|
|
9
|
+
/src/readme2demo/normalize.py @alphacrack
|
|
10
|
+
/src/readme2demo/sandbox.py @alphacrack
|