Add Plugin
Use this skill when the task is "add another plugin like Bitrefill" or "make plugin onboarding more reusable."
Ground Truth
src/cli.tsis the main CLI entrypoint, but plugin-specific command trees should not be wired inline there.src/plugins/types.tsdefines the sharedCliPluginContextand the generic plugin registrar shape.src/plugins/index.tsis the registry for built-in plugins.src/plugins/bitrefill.tsis the reference implementation for a plugin that owns its own command tree.- Plugin-specific HTTP or browser/bootstrap code belongs in
src/lib/<plugin>.tsorsrc/lib/<plugin>/. - Signing, policy checks, manual approval handling, and raw transaction broadcast plumbing stay on the existing AgentPay path exposed through
CliPluginContext.
Default Architecture
- Create
src/plugins/<plugin>.ts. - Register the plugin in
src/plugins/index.ts. - Keep plugin-local API normalization, transports, cookies, scraping, or challenge handling in
src/lib/<plugin>*. - Keep
src/cli.tsresponsible only for assembling shared dependencies and callingregisterBuiltinCliPlugins(...). - Reuse
context.agent.runJson(...)pluscontext.broadcast.*for any payment flow that reaches the daemon.
Implementation Rules
- Do not add another large inline
.command('<plugin>')block tosrc/cli.ts. - Do not reimplement signing, nonce management, or policy logic in the plugin.
- If the plugin needs onchain payment, default to preview-first behavior and make live payment explicit with
--broadcast. - If the plugin only needs a quote plus an optional live payment path, prefer one
buy-style command over a redundant separatepricecommand. - Keep plugin-specific error handling inside the plugin module when possible.
- If a remote API needs browser bootstrap, Cloudflare handling, or cookies, isolate that behind the plugin's transport/client layer instead of leaking it into the shared CLI.
- Pass only shared helpers through
CliPluginContext; keep plugin business logic inside the plugin module.
Deterministic Workflow
- Inspect
src/plugins/bitrefill.tsto copy the current plugin structure and command style. - Add or extend the plugin client under
src/lib/<plugin>*. - Add a new
CliPluginimplementation undersrc/plugins/<plugin>.ts. - Register it in
src/plugins/index.ts. - If the plugin needs signing or broadcast, use
context.config,context.agent, andcontext.broadcastinstead of shelling around the shared flow. - Add a focused CLI test file or extend the closest existing one under
test/. - Run the plugin-focused tests and at least one
agentpay <plugin> --helpsmoke check.
Testing Rule
- Prefer mocked CLI/integration tests over live third-party dependencies.
- Cover command registration, happy path output, unsupported modes, and any explicit challenge or approval state.
- If the plugin supports
--broadcast, cover both preview-only and broadcast-backed flows.
References
- Read
src/plugins/types.tsfor the shared context contract. - Read
src/plugins/index.tsfor plugin registration. - Read
src/plugins/bitrefill.tsfor the current plugin pattern. - Read the matching
src/lib/<plugin>*module only when implementing that plugin's remote API behavior.
Source: worldliberty/agentpay-sdk — distributed by TomeVault.