0.43.0 — human-in-the-loop payments on every paid tool, skills install, setup/debug/upgrade skills - #120
Merged
Merged
Conversation
confirmSpend (MCP elicitation, BLOCKRUN_CONFIRM_SPEND=on) shipped in 0.25.0 wired into blockrun_image only. The other 13 paid tools reserved budget and signed the x402 payment without asking. Each now asks at its budget gate, inside the try so a decline releases the reservation via finally and sends nothing. Free paths (chat mode:free, crypto price, free phone lookups) never prompt because usd<=0 short-circuits inside confirmSpend. test/confirm-spend-coverage.test.ts guards it both ways: statically (every tool that calls reserveBudget also calls confirmSpend) and behaviourally (with a declining client, all 14 tools return a non-error decline, leave budget.spent at 0, and never reach the network). The behavioural half caught the first draft of this change, which placed nine of the confirms before their try and leaked the reservation on decline.
The skills have shipped inside the npm tarball since files: ["skills"] was added, but the only ways to use them were cloning the repo or the Claude Code plugin marketplace. Codex (~/.codex/skills), Cursor, CI images and projects that want skills checked in under .claude/skills had no path. npx -y @blockrun/mcp@latest skills install # ./.claude/skills npx -y @blockrun/mcp@latest skills install --global # ~/.claude/skills npx -y @blockrun/mcp@latest skills install --to ~/.codex/skills npx -y @blockrun/mcp@latest skills install --only blockrun,blockrun-debug Existing skill dirs are skipped unless --force; --force overwrites the files we ship and leaves the user's other files alone. It never deletes. The skills/ dir is located by walking up to the package root so the same code works from src/ under tsx and from the tsup bundle in dist/. The subcommand is handled before the stdio server would start.
All thirteen shipped skills were 'how to call tool X'. Nothing helped the agent that runs the install, hits 'Failed to connect', or sees the Update available notice — the README has that content, but only a human reads it. Each skill was written against a baseline run without it. The unaided agent reached for nvm alias default instead of the -e PATH="$PATH" passthrough, described the key as keychain-only (the file stays authoritative unless BLOCKRUN_KEYCHAIN=strict), skipped blockrun_wallet action:setup, hand-wrote a Codex config.toml, and refreshed copied skills with npm pack + tar. With the skills loaded all three scenarios came back correct; the review pass added Codex --env PATH, claude mcp get to verify scope and env, diagnostics before fixes, and the --force-overwrites-your-edits warning. Registered in .claude-plugin/marketplace.json (marketplace.test.ts) and frontmatter-checked (skill-frontmatter.test.ts).
…lient matrix README gains a feature bullet, a comparison-table row, a Human-in-the-loop payments section with the dialog rendered as text and a per-client support table, a Quick Start step for installing the skills, BLOCKRUN_BUDGET_LIMIT / BLOCKRUN_CONFIRM_SPEND / BLOCKRUN_CONFIRM_THRESHOLD in the configuration table (the first had never been documented), a Troubleshooting pointer to the debug skill, and two FAQ entries. docs/spend-confirmation.md is the long form: when to use the gate versus budgets, the enable snippets per client, the support matrix with sources (verified 2026-08-29 against each client's own docs: Claude Code, Cursor and VS Code render it; Claude Desktop renders it but reports cancel on OK; Windsurf, Codex and Gemini CLI do not document elicitation), what fail-open means, and the limitations. No screenshot: a real dialog needs a live session and a mocked one would mislead.
…/debug/upgrade skills
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Items 1 + 2 of the CopilotKit-derived recommendations, with one scope change: spend confirmation is now wired into every paid tool before it is headlined. It had only ever gated
blockrun_image.feat(confirm) — every paid tool asks before it spends
confirmSpend(MCP elicitation,BLOCKRUN_CONFIRM_SPEND=on) now runs at the budget gate of all 14 remaining paid tools — chat, video, music, speech, realface, search, exa, markets, surf, defi, rpc, modal, phone — inside thetry, so a decline releases the reservation and sends nothing.usd<=0short-circuit).blockrun_polymarketkeeps its own per-orderconfirm:true.test/confirm-spend-coverage.test.ts: static guard (every tool that reserves budget must confirm) + behavioural guard (declining client → non-error decline,budget.spent === 0, zero network calls, for all 14). The behavioural half caught the first draft, which leaked the reservation on nine tools.feat(cli) —
blockrun-mcp skills list | installnpx -y @blockrun/mcp@latest skills install→./.claude/skills;--global→~/.claude/skills;--to ~/.codex/skills;--only a,b;--force(overwrites shipped files, keeps the user's others, never deletes).skills/by walking to the package root, so it works fromsrc/under tsx and from the tsup bundle under npx. Verified end-to-end fromdist/.feat(skills) —
blockrun-setup,blockrun-debug,blockrun-upgradenvm alias defaultover-e PATH="$PATH", called the key keychain-only, hand-wrote Codex TOML, refreshed skills withnpm pack+tar), then verified with the skill loaded, then a refactor pass on the subagents' critique.marketplace.json; frontmatter + marketplace tests pass.docs
BLOCKRUN_BUDGET_LIMIT/BLOCKRUN_CONFIRM_SPEND/BLOCKRUN_CONFIRM_THRESHOLDin the config table, Troubleshooting →blockrun-debug, two FAQs. Brand-number markers untouched.docs/spend-confirmation.md: when to use it vs budgets, enable snippets, support matrix verified 2026-08-29 against each client's own docs (Claude Code ✅, Cursor ✅, VS Code ✅ since 1.102; Claude DesktopVerification
npm run typecheck0 errors ·npm test416/416 ·npm run buildok ·sync-brand-numbers --checkok ·node dist/index.js --version= 0.43.0 ·npm pack --dry-runincludes the three new skills.Out of scope (follow-ups)
BLOCKRUN_CONFIRM_SPENDon by default.Merging publishes 0.43.0 via publish.yml.