Skip to content

Add x402-pay skill for public distribution via skill.sh#231

Open
simantak-dabhade wants to merge 1 commit into
mainfrom
feat/x402-pay-skill-public
Open

Add x402-pay skill for public distribution via skill.sh#231
simantak-dabhade wants to merge 1 commit into
mainfrom
feat/x402-pay-skill-public

Conversation

@simantak-dabhade
Copy link
Copy Markdown
Contributor

@simantak-dabhade simantak-dabhade commented May 6, 2026

Summary

  • Publishes the x402-pay Claude Code skill at skill/x402-pay/ so it can be discovered and installed by anyone via skill.sh
  • skill.sh indexes skills from public GitHub repos by looking for SKILL.md files in skill/ directories — placing it here makes it installable with a single command

What the skill does

Lets any Claude Code agent make x402 payments to access paid API endpoints. The agent invokes /x402-pay <url> and gets structured JSON back — it never touches the private key.

  • Full x402 flow: request → 402 → EIP-712 sign → retry with PAYMENT-SIGNATURE header
  • Auto-detects exact (fixed price, EIP-3009) and upto (variable price, Permit2) schemes
  • Private key stored in macOS Keychain, read at runtime by the bundled TypeScript script only
  • Pre-flight checks: USDC balance + Permit2 allowance before signing
  • First-time setup flow guides users through Keychain storage and Permit2 approval

Files

File Purpose
skill/x402-pay/SKILL.md Agent instructions, prereq checks, usage docs, error table, security rules
scripts/x402-fetch.ts Main payment script — full x402 flow, structured JSON output
scripts/setup.ts First-time onboarding — Keychain check, balances, Permit2 approval
scripts/package.json Dependencies: @x402/evm, viem, tsx

Test plan

  • Skill is discoverable via skill.sh after merge (once indexed)
  • pnpm install in skill/x402-pay/scripts/ installs cleanly
  • /x402-pay with no Keychain key → triggers setup flow
  • /x402-pay http://localhost:4001/premium → completes exact payment
  • /x402-pay http://localhost:4001/api/search?q=test → completes upto payment

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Introduced x402-pay skill for making signed payments to access paid API endpoints
    • Added setup verification workflow with optional approval for payment authorization
    • Added payment execution with signature-based authentication and structured JSON output
  • Documentation

    • Added comprehensive guide covering prerequisites, setup steps, usage, expected outputs, error types, and security rules

Publishes the x402-pay Claude Code skill at skill/x402-pay/ so it can
be discovered and installed by anyone via skill.sh, which indexes skills
from public GitHub repos.

The skill lets any Claude Code agent make x402 payments to access paid
API endpoints — handles the full flow (request, 402, EIP-712 signing,
retry) with the private key stored securely in macOS Keychain.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds the x402-pay skill, a complete TypeScript-based implementation for making signed cryptographic payments to HTTP 402-protected API endpoints. The skill validates setup prerequisites, handles optional Permit2 approval, and manages two-phase request/response flows with payment signature generation.

Changes

x402-pay Skill

Layer / File(s) Summary
Skill Documentation & Contract
skill/x402-pay/SKILL.md
Defines skill metadata, prerequisites (macOS Keychain, dependencies), setup flow, usage examples, stdout JSON contract for success/no-payment/error states, error type guidance, and security rules for private key handling.
Build & Package Configuration
skill/x402-pay/scripts/package.json, skill/x402-pay/scripts/tsconfig.json, skill/x402-pay/scripts/.gitignore
Configures ES module package, TypeScript strict compilation (ES2022 target, Node16 modules), development dependencies (tsx, typescript, @types/node), runtime dependencies (@x402/evm, viem), and ignores node_modules/ and dist/.
Setup Initialization Script
skill/x402-pay/scripts/setup.ts
CLI that validates prerequisites: reads private key from macOS Keychain, instantiates Base wallet, queries ETH/USDC balances and Permit2 allowance, optionally submits approve transaction for Permit2 when invoked with --approve, and outputs JSON status (ready/setup_required/error).
Payment Fetch & Signing Script
skill/x402-pay/scripts/x402-fetch.ts
CLI that performs two-phase x402 payment flow: initial request, conditional 402 parsing, USDC/Permit2 pre-flight checks, payment payload signing (UptoEvmScheme or ExactEvmScheme), signed retry, settlement response parsing, and structured JSON output with optional settlement details or error codes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • GTG-Labs/sangria#229: Adds the same x402-pay skill implementation under a different directory structure with identical setup.ts, x402-fetch.ts, and configuration files.
  • GTG-Labs/sangria#152: Implements related x402 payment client flows including 402 request handling, payment-signature header construction, and two-phase request/response management.

Suggested reviewers

  • farhan-navas

Poem

🐰 A payment signed by hoppy paws,
Through Keychain vaults and EVM's laws,
Two phases dance, one signature seals,
The x402-pay skill reveals!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately describes the main change: adding a new x402-pay skill for public distribution via skill.sh.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/x402-pay-skill-public

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Microsoft Presidio Analyzer (2.2.362)
skill/x402-pay/SKILL.md

Microsoft Presidio Analyzer failed to scan this file

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@rahulmllvrp
Copy link
Copy Markdown
Contributor

rahulmllvrp commented May 8, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

1 similar comment
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@skill/x402-pay/scripts/setup.ts`:
- Line 136: The current call to walletClient.waitForTransactionReceipt({ hash })
can hang indefinitely; update the await to use a bounded wait (e.g., pass a
timeout option if the client supports one or wrap the call in a Promise.race
with a timeout promise) so it rejects after a reasonable period (e.g., 30–60s);
handle the rejection by returning/throwing a clear error or sentinel (e.g.,
null) from the function and ensure the calling code is updated to log or surface
that result so the caller can check on-chain status manually; focus changes
around waitForTransactionReceipt, walletClient, receipt and hash.

In `@skill/x402-pay/scripts/x402-fetch.ts`:
- Around line 203-211: The code converts balance (a bigint) to a JS Number
(balanceMicro) which can lose precision; change to use bigint arithmetic
instead: remove the Number(balance) conversion and compare balance (bigint)
directly to amountMicro (bigint) in the insufficiency check, and keep using
formatUnits(balance, 6) for human-readable logging and in the fatal metadata
(use formatUnits to render required values), referencing the existing symbols
balance, amountMicro, formatUnits, fatal, and account.address so the conditional
becomes a bigint comparison and no implicit Number cast occurs.
- Around line 87-89: The JSON.parse call that builds extraHeaders from
values.headers is unguarded and will surface a raw SyntaxError (ending up as an
UNEXPECTED error); wrap the parse in a try/catch around the
JSON.parse(values.headers) used to assign extraHeaders and, on parse failure,
throw/return a clear argument error (set errorType to "INVALID_ARGS" or throw a
CLI/argument error) with a message like "Invalid --headers JSON: <original
message>" so the error is reported as bad input rather than an unexpected
internal failure; update the handling path that currently relies on
main().catch() to preserve the new INVALID_ARGS error shape.

In `@skill/x402-pay/SKILL.md`:
- Around line 91-119: Add a blank line between each bold header and its
following fenced JSON block for the three examples labeled "**Success**", "**No
payment needed**", and "**Error**" in SKILL.md so that each code fence is
separated from the preceding header (this fixes MD031 by placing an empty line
before each opening ```json fence).
- Line 37: Add a language identifier to the fenced code block containing the
command string "! security add-generic-password -s x402-agent-key -a x402 -U -w"
in SKILL.md so the block becomes a fenced bash block (e.g., ```bash) to satisfy
markdownlint MD040; locate the fence that wraps that exact command and update
its opening fence to include the language specifier.
- Around line 17-19: The check currently uses "security find-generic-password
-w" which prints the private key to stdout; remove the "-w" flag so the command
only checks existence (use "security find-generic-password -s x402-agent-key -a
x402" with stderr redirected to /dev/null) and keep the existing "&& echo
'KEYCHAIN: CONFIGURED' || echo 'KEYCHAIN: NOT_CONFIGURED'" logic unchanged;
ensure any documentation or examples referencing this existence check (the
"security find-generic-password" invocation) are updated to omit "-w" to avoid
exfiltrating secrets.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b290200b-a705-4ffe-a401-c8fd4014c9c0

📥 Commits

Reviewing files that changed from the base of the PR and between 7de86c7 and b8fcf68.

⛔ Files ignored due to path filters (1)
  • skill/x402-pay/scripts/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • skill/x402-pay/SKILL.md
  • skill/x402-pay/scripts/.gitignore
  • skill/x402-pay/scripts/package.json
  • skill/x402-pay/scripts/setup.ts
  • skill/x402-pay/scripts/tsconfig.json
  • skill/x402-pay/scripts/x402-fetch.ts

});

log(`Approval tx submitted: ${hash}`);
const receipt = await walletClient.waitForTransactionReceipt({ hash });
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

waitForTransactionReceipt will hang indefinitely if the transaction stalls

There is no timeout parameter. On Base mainnet a transaction can get stuck (replaced gas-price, nonce conflict, RPC hiccup), leaving the process blocked forever with no way for the agent to recover.

⏱️ Proposed fix — add a reasonable timeout
-const receipt = await walletClient.waitForTransactionReceipt({ hash });
+const receipt = await walletClient.waitForTransactionReceipt({ hash, timeout: 60_000 });

Add a corresponding error path so the caller knows to check on-chain status manually if the timeout fires.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const receipt = await walletClient.waitForTransactionReceipt({ hash });
const receipt = await walletClient.waitForTransactionReceipt({ hash, timeout: 60_000 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skill/x402-pay/scripts/setup.ts` at line 136, The current call to
walletClient.waitForTransactionReceipt({ hash }) can hang indefinitely; update
the await to use a bounded wait (e.g., pass a timeout option if the client
supports one or wrap the call in a Promise.race with a timeout promise) so it
rejects after a reasonable period (e.g., 30–60s); handle the rejection by
returning/throwing a clear error or sentinel (e.g., null) from the function and
ensure the calling code is updated to log or surface that result so the caller
can check on-chain status manually; focus changes around
waitForTransactionReceipt, walletClient, receipt and hash.

Comment on lines +87 to +89
const extraHeaders: Record<string, string> = values.headers
? JSON.parse(values.headers)
: {};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Unguarded JSON.parse for --headers produces a misleading UNEXPECTED error

If the user passes malformed JSON (e.g., --headers '{bad}'), the thrown SyntaxError propagates to the outer main().catch(), which produces { errorType: "UNEXPECTED" }. This is confusing because the problem is clearly bad CLI input, not an internal error.

🛡️ Proposed fix — catch and convert to INVALID_ARGS
-const extraHeaders: Record<string, string> = values.headers
-  ? JSON.parse(values.headers)
-  : {};
+let extraHeaders: Record<string, string> = {};
+if (values.headers) {
+  try {
+    extraHeaders = JSON.parse(values.headers);
+  } catch {
+    fatal("INVALID_ARGS", `--headers must be a valid JSON object, got: ${values.headers}`);
+  }
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skill/x402-pay/scripts/x402-fetch.ts` around lines 87 - 89, The JSON.parse
call that builds extraHeaders from values.headers is unguarded and will surface
a raw SyntaxError (ending up as an UNEXPECTED error); wrap the parse in a
try/catch around the JSON.parse(values.headers) used to assign extraHeaders and,
on parse failure, throw/return a clear argument error (set errorType to
"INVALID_ARGS" or throw a CLI/argument error) with a message like "Invalid
--headers JSON: <original message>" so the error is reported as bad input rather
than an unexpected internal failure; update the handling path that currently
relies on main().catch() to preserve the new INVALID_ARGS error shape.

Comment on lines +203 to +211
const balanceMicro = Number(balance);
log(`USDC balance: ${formatUnits(balance, 6)} USDC`);

if (balanceMicro < amountMicro) {
fatal("INSUFFICIENT_BALANCE", `USDC balance too low: have ${formatUnits(balance, 6)}, need ${amountUSD}`, {
walletAddress: account.address,
balanceUSDC: formatUnits(balance, 6),
requiredUSDC: amountUSD,
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Number(bigint) loses precision for large USDC balances and enables imprecise comparison

Converting balance (a bigint) to Number at Line 203 silently drops precision for values above Number.MAX_SAFE_INTEGER (≈9 × 10¹⁵ microunits ≈ 9 billion USDC). While this is an astronomically large balance for an agent wallet in practice, the comparison at Line 206 should use bigint arithmetic to stay correct by construction and avoid the implicit cast.

♻️ Proposed refactor — compare as bigint throughout
-    const balanceMicro = Number(balance);
-    log(`USDC balance: ${formatUnits(balance, 6)} USDC`);
-
-    if (balanceMicro < amountMicro) {
-      fatal("INSUFFICIENT_BALANCE", `USDC balance too low: have ${formatUnits(balance, 6)}, need ${amountUSD}`, {
+    log(`USDC balance: ${formatUnits(balance, 6)} USDC`);
+
+    if (balance < BigInt(amountMicro)) {
+      fatal("INSUFFICIENT_BALANCE", `USDC balance too low: have ${formatUnits(balance, 6)}, need ${amountUSD}`, {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const balanceMicro = Number(balance);
log(`USDC balance: ${formatUnits(balance, 6)} USDC`);
if (balanceMicro < amountMicro) {
fatal("INSUFFICIENT_BALANCE", `USDC balance too low: have ${formatUnits(balance, 6)}, need ${amountUSD}`, {
walletAddress: account.address,
balanceUSDC: formatUnits(balance, 6),
requiredUSDC: amountUSD,
});
log(`USDC balance: ${formatUnits(balance, 6)} USDC`);
if (balance < BigInt(amountMicro)) {
fatal("INSUFFICIENT_BALANCE", `USDC balance too low: have ${formatUnits(balance, 6)}, need ${amountUSD}`, {
walletAddress: account.address,
balanceUSDC: formatUnits(balance, 6),
requiredUSDC: amountUSD,
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skill/x402-pay/scripts/x402-fetch.ts` around lines 203 - 211, The code
converts balance (a bigint) to a JS Number (balanceMicro) which can lose
precision; change to use bigint arithmetic instead: remove the Number(balance)
conversion and compare balance (bigint) directly to amountMicro (bigint) in the
insufficiency check, and keep using formatUnits(balance, 6) for human-readable
logging and in the fatal metadata (use formatUnits to render required values),
referencing the existing symbols balance, amountMicro, formatUnits, fatal, and
account.address so the conditional becomes a bigint comparison and no implicit
Number cast occurs.

Comment thread skill/x402-pay/SKILL.md
Comment on lines +17 to +19
```!
security find-generic-password -s x402-agent-key -a x402 -w 2>/dev/null && echo "KEYCHAIN: CONFIGURED" || echo "KEYCHAIN: NOT_CONFIGURED"
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: prerequisite check exposes the private key via -w flag

security find-generic-password -w searches for the keychain item and prints the password when found. The 2>/dev/null only suppresses stderr (errors); stdout — where the key is printed — is not redirected. So the private key lands verbatim in Claude's conversation context, directly violating Security Rules #1 and #3.

Without -w, the command does not print the password — it outputs the keychain object metadata associated with the service name instead. The exit code is still 0 when found and non-zero when absent, so the && / || detection logic works unchanged.

🔒 Proposed fix — remove -w from the existence check
 ```!
-security find-generic-password -s x402-agent-key -a x402 -w 2>/dev/null && echo "KEYCHAIN: CONFIGURED" || echo "KEYCHAIN: NOT_CONFIGURED"
+security find-generic-password -s x402-agent-key -a x402 2>/dev/null && echo "KEYCHAIN: CONFIGURED" || echo "KEYCHAIN: NOT_CONFIGURED"
</details>

Note that `allowed-tools: Bash(security find-generic-password *)` on Line 6 is unrestricted (any arguments), so the agent is technically permitted to re-introduce `-w` later. With the check itself fixed, the security rules serve as the remaining guardrail.

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @skill/x402-pay/SKILL.md around lines 17 - 19, The check currently uses
"security find-generic-password -w" which prints the private key to stdout;
remove the "-w" flag so the command only checks existence (use "security
find-generic-password -s x402-agent-key -a x402" with stderr redirected to
/dev/null) and keep the existing "&& echo 'KEYCHAIN: CONFIGURED' || echo
'KEYCHAIN: NOT_CONFIGURED'" logic unchanged; ensure any documentation or
examples referencing this existence check (the "security find-generic-password"
invocation) are updated to omit "-w" to avoid exfiltrating secrets.


</details>

<!-- fingerprinting:phantom:poseidon:churro -->

<!-- 4e71b3a2 -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment thread skill/x402-pay/SKILL.md

> Your x402 agent private key isn't configured yet. Please run this command — it will prompt you to paste your key securely (it won't be displayed):
>
> ```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Minor markdown lint: fenced code block missing language specifier (MD040)

The !-fenced block at Line 37 has no language identifier, triggering a markdownlint MD040 warning.

✏️ Proposed fix
-> ```
+> ```bash
>  ! security add-generic-password -s x402-agent-key -a x402 -U -w
> ```
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 37-37: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skill/x402-pay/SKILL.md` at line 37, Add a language identifier to the fenced
code block containing the command string "! security add-generic-password -s
x402-agent-key -a x402 -U -w" in SKILL.md so the block becomes a fenced bash
block (e.g., ```bash) to satisfy markdownlint MD040; locate the fence that wraps
that exact command and update its opening fence to include the language
specifier.

Comment thread skill/x402-pay/SKILL.md
Comment on lines +91 to +119
**Success** (payment completed, resource returned):
```json
{
"status": "success",
"httpStatus": 200,
"body": { "...resource data..." },
"settlement": { "txHash": "0x...", "network": "eip155:8453", "payer": "0x..." },
"payment": { "scheme": "exact", "amountMicro": 10000, "amountUSD": "0.010000" }
}
```

**No payment needed** (endpoint didn't return 402):
```json
{
"status": "no_payment_required",
"httpStatus": 200,
"body": { "...response data..." }
}
```

**Error** (something went wrong):
```json
{
"status": "error",
"errorType": "INSUFFICIENT_BALANCE",
"message": "human-readable explanation",
"details": { "walletAddress": "0x...", "balanceUSDC": "0.5", "requiredUSDC": "1.0" }
}
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Minor markdown lint: fenced code blocks missing surrounding blank lines (MD031)

Three json code blocks (Lines 92, 103, 112) immediately follow bold-text headers without a blank line separator, triggering MD031 warnings. Adding a blank line before each opening fence resolves all three.

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 92-92: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 103-103: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 112-112: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skill/x402-pay/SKILL.md` around lines 91 - 119, Add a blank line between each
bold header and its following fenced JSON block for the three examples labeled
"**Success**", "**No payment needed**", and "**Error**" in SKILL.md so that each
code fence is separated from the preceding header (this fixes MD031 by placing
an empty line before each opening ```json fence).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants