diff --git a/app/globals.css b/app/globals.css index f22dceb..b1424c5 100644 --- a/app/globals.css +++ b/app/globals.css @@ -192,10 +192,29 @@ article.prose { margin: 2.5rem 0; } -/* Anchored headings: hover reveals a link affordance. */ -.prose h2:hover::after, -.prose h3:hover::after { - content: " #"; - color: var(--ink-faint); - font-weight: 400; +/* Anchored headings: a clickable link icon (seal-red) that links to the section. + Hidden until the heading is hovered or the icon is keyboard-focused, so a + reader can grab a shareable URL without the icon cluttering the heading. */ +/* The inline wrapper is the hover target — sized to the text + icon only, so the + icon does NOT stay visible when the cursor is elsewhere along the heading's + full-width line. */ +.prose .heading-inner { + position: relative; +} +.prose .heading-anchor { + display: inline-flex; + align-items: center; + margin-left: 0.35em; + color: var(--seal); + border-bottom: none; /* override the .prose a underline */ + opacity: 0; + transition: opacity 130ms ease, color 120ms ease; + vertical-align: middle; +} +.prose .heading-inner:hover .heading-anchor, +.prose .heading-anchor:focus-visible { + opacity: 1; +} +.prose .heading-anchor:hover { + color: var(--seal-deep); } diff --git a/components/markdoc/HeadingAnchor.tsx b/components/markdoc/HeadingAnchor.tsx new file mode 100644 index 0000000..bdc0f2e --- /dev/null +++ b/components/markdoc/HeadingAnchor.tsx @@ -0,0 +1,27 @@ +/** + * The clickable section anchor appended to every heading. Renders a link icon + * (not a literal `#`) that appears on heading hover/keyboard-focus and links to + * `#`, so a reader can grab a shareable URL to the exact section. Visibility + * and color live in `.heading-anchor` (app/globals.css). + */ +export function HeadingAnchor({ id }: { id: string }) { + return ( + + + + ) +} diff --git a/content/docs/mcp/guides/publish-receipts.md b/content/docs/mcp/guides/publish-receipts.md index 07c1d03..e1e4b65 100644 --- a/content/docs/mcp/guides/publish-receipts.md +++ b/content/docs/mcp/guides/publish-receipts.md @@ -63,6 +63,24 @@ https://your.host/agent/audit.json ← the manifest naming the verify inputs - `root` — the root identity of the registry (the identity tooling prints it; it is the anchor the agent's delegation chains to). +## One command: `export-spend-bundle` + +The whole publish step is a single gateway command — it flattens the (rotated) +spend log into one `spend.jsonl`, writes the `audit.json` manifest, and commits +the registry working files in the same motion: + +```bash +auths-mcp export-spend-bundle \ + --live-dir "$AUTHS_MCP_LIVE_DIR" \ + --agent "" \ + --root "" \ + --registry-url "https://github.com/you/agent-registry" \ + --out ./publish +``` + +Serve `./publish` from any static host and you are done. The sections below +describe what the command produces, and remain the manual path if you need it. + ## Commit the working files — or the audit fails The registry's identity history lives in git refs, but the **durable budget counter diff --git a/content/docs/mcp/providers/x402.md b/content/docs/mcp/providers/x402.md index b2034da..e67c104 100644 --- a/content/docs/mcp/providers/x402.md +++ b/content/docs/mcp/providers/x402.md @@ -134,6 +134,6 @@ Use testnet mode to prove the cap refuses the over-cap call before you ever poin ## Useful links -- Testnet USDC faucet (select Base Sepolia): https://faucet.circle.com/ -- MetaMask: https://metamask.io/ -- x402 wallet reference: https://github.com/0xKoda/x402-wallet/blob/main/wallet.md +- [Testnet USDC faucet](https://faucet.circle.com/) — select **Base Sepolia** as the network +- [MetaMask](https://metamask.io/) +- [x402 wallet reference](https://github.com/0xKoda/x402-wallet/blob/main/wallet.md) diff --git a/lib/markdoc-components.tsx b/lib/markdoc-components.tsx index 712ad56..da124fe 100644 --- a/lib/markdoc-components.tsx +++ b/lib/markdoc-components.tsx @@ -6,6 +6,7 @@ import { Card, CardGroup } from '@/components/markdoc/Cards' import { Steps, Step } from '@/components/markdoc/Steps' import { CodeTabs, CodeTab } from '@/components/markdoc/CodeTabs' import { VerdictChip } from '@/components/markdoc/VerdictChip' +import { HeadingAnchor } from '@/components/markdoc/HeadingAnchor' /** The single map from Markdoc tag names to React components. */ const components = { @@ -18,6 +19,7 @@ const components = { CodeTabs, CodeTab, VerdictChip, + HeadingAnchor, } /** Renders a transformed Markdoc tree to React — no HTML strings, ever. */ diff --git a/markdoc/schema.ts b/markdoc/schema.ts index 2d92b9d..281fb18 100644 --- a/markdoc/schema.ts +++ b/markdoc/schema.ts @@ -37,7 +37,17 @@ export function buildConfig(): Config { const attributes = node.transformAttributes(config) const children = node.transformChildren(config) const id = attributes.id ?? slugger.slug(headingText(node)) - return new Tag(`h${node.attributes.level}`, { ...attributes, id }, children) + // A clickable link-icon anchor (shown on hover via .heading-anchor + // CSS) so a reader can grab a shareable link to the exact section. + const anchor = new Tag('HeadingAnchor', { id }, []) + // Wrap the text + anchor in an inline span so the hover trigger is the + // text/icon only — NOT the full-width heading block, which would keep + // the icon visible anywhere along the heading's horizontal line. + const inner = new Tag('span', { className: 'heading-inner' }, [ + ...children, + anchor, + ]) + return new Tag(`h${node.attributes.level}`, { ...attributes, id }, [inner]) }, }, fence: { diff --git a/next-env.d.ts b/next-env.d.ts index 9edff1c..c4b7818 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/types/routes.d.ts"; +import "./.next/dev/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.