v0.6.2 — an npx rule that works without a prompt
Note: 0.6.3 corrects one line below.
npm ciruns install scripts, so it needs--ignore-scriptstoo — the barenpm cirecommended here does not protect you.
Security
-
An npx rule that holds without a prompt. Since 0.5.0 the mitigation against npx's registry fallback had been "if npx offers to install something, answer NO and stop," carried in SKILL.md, AGENTS.md and README. That rule assumes a prompt. Verified against npm 11: npx only prompts on an interactive TTY. With no TTY — a CI job, a script, or an AI agent running commands through a tool call, which is the context SKILL.md and AGENTS.md exist for — npx installs the fetched package and executes it silently, with nothing displayed and nothing to decline. It protected an interactive human and no one else while reading as general protection. The rule is now one that needs no prompt to work: never run a bare
npxfor a wallet command — usenpm exec --no -- sparkbtcbot <command>or./node_modules/.bin/sparkbtcbot, and never pass-y/--yes. The pinnednpx --package=sparkbtcbot-skill ...form is documented for a human at a terminal and explicitly not offered to agents:--package=names the owned package outright and cannot fall back to a command-name lookup, but it is still an unpinned fetch outside the lockfile. -
Install guidance uses
--ignore-scripts. One production dependency (protobufjs) executes code atnpm installtime, before the consumer's code has imported anything — the supply-chain footgun with the largest blast radius here, since it runs on the developer's machine with the agent's privileges rather than merely risking wallet funds. The flag costs nothing: the CLI resolves and runs, and bothsparkbtcbot-skilland@buildonspark/spark-sdkimport cleanly without install scripts. -
cli.jsargument gate no longer falls through on inheritedObjectproperties. The dispatcher looked upCOMMANDS[cmd], which walks the prototype chain, sosparkbtcbot constructor,toString,valueOfand__proto__resolved to a truthy non-entry and reachedimport(undefined)— a stack trace instead of the usage message, in the one gate whose own comment promises that an unknown command "cannot fall through to anything." NowObject.hasOwn(COMMANDS, cmd). Not exploitable (nothing executed, exit stayed non-zero), but it was the 0.4.3 fall-through class in miniature.
Changed
SECURITY.mdships in the npm tarball and gained a section on registry-name reservations — which names this project owns, and why owning them is what protects the npx fallback. Its scope section also named the packagesparkbtcbot; that name now resolves to the reservation stub, so it readssparkbtcbot-skill.