@htmlbin/cli cloud + --upsert)
Adds one new file: .github/workflows/pr-explainer.yml. No source, no tests, no docs touched.
The workflow runs on every pull_request event (opened, synchronize, reopened, closed) and does two things:
@anthropic-ai/claude-code, invokes Claude with a fixed prompt that diffs the PR and writes a self-contained ./preview.html, then publishes it through npx @htmlbin/cli@latest publish ./preview.html --upsert --metadata repo=… --metadata pr=…. A sticky comment (header htmlbin-pr-explainer) carries the resulting URL.list --metadata repo=… --metadata pr=…, deletes it, and rewrites the sticky comment to say "deleted".
Two motivations in one workflow. First, product dogfooding: this repo's own CI now exercises the --upsert + --metadata path that examples/cloud-upsert-workflow.yml teaches users to copy. Bugs in the agent-idempotent bridge surface on this repo's PRs before users hit them.
Second, reviewer ergonomics: PR diffs in a CLI tool are often small but consequential (a flag rename, a new error code, a backend boundary tweak). The explainer gives a 30-second read of what the PR means, hosted at a stable URL that updates in place across pushes.
| Surface | Impact |
|---|---|
| CLI flags | none Uses already-shipped flags only: publish --upsert --metadata, --title, --output json, list --metadata, delete <slug>. |
| Verbs | none No new verb; no change to publish / update / list / delete semantics. |
| Error codes | none src/errors.ts untouched. |
| Backend interface | none src/backend.ts and all src/backends/* untouched. |
| Package contents | none .github/ is excluded from the npm tarball; this does not ship to users. |
| Breaking change? | no CI-only addition. |
| New repo secrets | action needed Requires HTMLBIN_TOKEN and ANTHROPIC_API_KEY to be set on the repository for the workflow to run. |
--dangerously-skip-permissions on the Claude invocation
Added by the second commit (e744b3d "Added skip permissions"). The agent runs unattended in CI with read-only repo contents and no secrets in its environment besides ANTHROPIC_API_KEY, so the blast radius is bounded, but worth confirming the threat model matches your bar for an auto-merged-prompt agent.
pull_request, not pull_request_target. Forked-PR runs intentionally get no secrets and the publish step will fail. The header comment in the YAML documents this. Verify that's the intended trade-off (vs. running for forks via pull_request_target, which would be unsafe with --dangerously-skip-permissions).
htmlbin login locally and read ~/.config/htmlbin/token. CLI stores the token at 0o600 under .htmlbin/ per CLAUDE.md; the example path in the YAML (~/.config/htmlbin/token) follows the XDG convention used elsewhere — sanity-check it matches the CLI's actual write path.
.[0].slug
list --metadata repo=… --metadata pr=… should return at most one match given --upsert's uniqueness contract, so .[0] is fine. If you ever loosen that contract, this becomes a silent partial-delete.
concurrency.cancel-in-progress: true means a fast follow-up push cancels the previous run. The explicit check step + exit 1 on a missing preview.html is the right shape; just confirm the sticky no-explainer comment is acceptable as the failure signal (the job also reds the PR check).