Each of the four probes is now a natural-language prompt to claude
instead of a bash escape via `!`. The agent uses its Bash tool, runs
the literal curl/git command, and narrates what pipelock or git-gate
returned. More authentic to actual product use, at the cost of a
longer recording (59s vs 26s) and a non-deterministic narration.
To keep claude on-task, the demo agent now ships a system prompt
that frames the bottle as a security-testing sandbox: synthetic
credentials, intentional probes, and an instruction to invoke curl
with `--proxy "$HTTPS_PROXY"` since curl ignores the uppercase
HTTP_PROXY env var (an upstream curl quirk — the env var is set, but
only the explicit flag actually routes through pipelock).
Theme moves to BirdsOfParadise (warmer palette against Claude TUI's
red accents). README copy updated to describe the prompt flow.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous demo harness called the backend Python API directly,
which didn't match what a user typing `./cli.py start <agent>` would
actually see. The recording now goes through the real CLI surface:
- claude-bottle.demo.json + scripts/demo-setup.sh stage a demo
manifest (one bottle, FAKE_TOKEN env, one unreachable git upstream)
alongside a dummy SSH identity at ~/.cache/claude-bottle-demo/.
- docs/demo.tape types `./cli.py start demo`, answers the y/N
preflight, and runs four bash probes via claude's `!` prefix
(curl x3 + git push), so the recording shows real preflight output
and real probe results.
- scripts/demo.sh wraps setup -> cli.py -> teardown for human use;
scripts/demo-record.sh does the same around `vhs docs/demo.tape`.
- .gitignore picks up claude-bottle.json so a user's local manifest
doesn't get tracked alongside .example / .demo siblings.
scripts/demo_harness.py is removed -- its behavior is fully replaced
by the cli.py + `!` flow.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>