Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions dashboard/app/docs/api/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { CommandBlock } from '@/components/copy';

export const metadata: Metadata = {
alternates: { canonical: '/docs/api' },
title: 'HTTP API',
description:
'Reference for every AgentGate HTTP endpoint: the 402 paywall gateway (health, public metadata, the paywalled proxy, self-service upstream mapping, and the admin API) and the dashboard read-only /api routes.',
Expand Down Expand Up @@ -793,8 +794,8 @@ export default function Page() {

<NextLinks
links={[
{ href: '/docs/buyers', label: 'Client SDK' },
{ href: '/docs/protocol#invoice-rejection-fields', label: 'Error codes' },
{ href: '/docs/sdk', label: 'Client SDK' },
{ href: '/docs/errors', label: 'Error codes' },
]}
/>
</>
Expand Down
6 changes: 4 additions & 2 deletions dashboard/app/docs/architecture/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '@/components/docs';

export const metadata: Metadata = {
alternates: { canonical: '/docs/architecture' },
title: 'Architecture',
description:
'How AgentGate fits together: the monorepo packages and their roles, the ChainClient seam that swaps mock and live backends, the 402 reverse-proxy data flow, where state lives, and the tech stack.',
Expand Down Expand Up @@ -159,8 +160,9 @@ export default function ArchitecturePage() {
<P>
There are exactly two implementations of that interface, both in{' '}
<M>packages/chain</M>. Which one is constructed is selected at startup by{' '}
<M>AGENTGATE_MODE</M> (default <M>mock</M>); the gateway, CLI, buyer agent, and dashboard all
receive an injected <M>ChainClient</M> and are identical regardless of backend.
<M>AGENTGATE_MODE</M>; the gateway, buyer agent, and dashboard default to <M>mock</M> via{' '}
<M>loadConfig()</M>, while the published CLI defaults to <M>live</M>. All of them receive an
injected <M>ChainClient</M> and are identical regardless of backend.
</P>
<DocTable
head={['Aspect', 'MockChainHttpClient', 'LiveCasperClient']}
Expand Down
10 changes: 8 additions & 2 deletions dashboard/app/docs/buyers/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import {
StepFlow,
} from '@/components/docs';

export const metadata = { title: 'Build an agent' };
export const metadata = {
title: 'Build an agent',
description:
'Build a buying agent that discovers services on-chain, handles the HTTP 402, pays with a native CSPR transfer carrying the nonce, and retries with proof — via the bundled LLM agent, the client SDK, or plain curl.',
alternates: { canonical: '/docs/buyers' },
};

const SDK_EXAMPLE = [
"import { createAgentGateClient } from '@agentgate/client';",
Expand Down Expand Up @@ -282,7 +287,8 @@ export default function Page() {
<CodeBlock label="typescript" code={SDK_EXAMPLE} />
<P>
<M>fetchPaid</M> returns a <M>PayAndFetchResult</M> (<M>status</M>, <M>body</M>,{' '}
<M>paid</M>, and on payment <M>invoice</M> / <M>deployHash</M> / <M>priceMotes</M>). A
<M>paid</M>, and on payment <M>requirements</M> / <M>deployHash</M> / <M>priceMotes</M> /{' '}
<M>settlement</M>). A
first response that is not a 402 passes straight through with <M>paid: false</M>. For every
option, field and pending-retry detail, see the{' '}
<DocLink href="/docs/sdk">Client SDK reference</DocLink>.
Expand Down
81 changes: 81 additions & 0 deletions dashboard/app/docs/changelog/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { docMeta } from '@/lib/seo';
import { DOCS_VERSION, REGISTRY_HASH_SHORT } from '@/lib/version';
import { DocHeader, H2, M, P, DocLink, NextLinks } from '@/components/docs';

export const metadata = docMeta(
'/docs/changelog',
'Changelog',
'Notable changes to AgentGate — the CLI, gateway, smart contracts and docs — newest first.',
);

export default function Page() {
return (
<>
<DocHeader
kicker="REFERENCE"
title="Changelog"
lede={
<>
Notable changes to AgentGate, newest first. Current: CLI v{DOCS_VERSION.cli} · SDK v
{DOCS_VERSION.sdk} · registry {REGISTRY_HASH_SHORT} on {DOCS_VERSION.network}.
</>
}
/>

<H2 id="2026-07-01">2026-07-01 — Self-service mapping &amp; docs hardening</H2>
<ul className="mt-4 list-disc space-y-2 pl-5 text-sm leading-6 text-mut">
<li>
<strong className="text-white">Self-service gateway mapping.</strong> <M>wrap</M> now maps
the upstream with an owner-signed request to <M>/services/&lt;id&gt;/map</M> — a live wrap
needs only <M>--pem</M>, no admin token.
</li>
<li>
<strong className="text-white">Role-oriented docs.</strong> The sidebar and overview map
are organized by role (For sellers / For buyers / Run a gateway) from a single source of
truth.
</li>
<li>
<strong className="text-white">Docs accessibility + accuracy pass.</strong> Skip-to-content
link, keyboard focus rings, AA-contrast parameter tables, copy buttons on every code block,
a CLI config-flags reference, a corrected <M>status</M> no-key example, and fixed
cross-links.
</li>
<li>
<strong className="text-white">Discovery.</strong> Added a sitemap, robots, canonical URLs,
OpenGraph/Twitter cards, JSON-LD, in-docs <M>⌘K</M> search, and this changelog.
</li>
</ul>

<H2 id="2026-06-30">2026-06-30 — CLI published to npm</H2>
<ul className="mt-4 list-disc space-y-2 pl-5 text-sm leading-6 text-mut">
<li>
<M>@mdlog/agentgate</M> v{DOCS_VERSION.cli} published — run it with{' '}
<M>npx @mdlog/agentgate</M>, no install or clone.
</li>
<li>
The published CLI defaults to <M>live</M> mode and the deployed registry hash, so{' '}
<M>list</M> and <M>status</M> read Casper Testnet with no configuration. See{' '}
<DocLink href="/docs/cli">CLI</DocLink>.
</li>
</ul>

<H2 id="2026-06-29">2026-06-29 — Live on Casper Testnet</H2>
<ul className="mt-4 list-disc space-y-2 pl-5 text-sm leading-6 text-mut">
<li>
<M>AgentGateRegistry</M> deployed to Casper Testnet (network <M>{DOCS_VERSION.network}</M>),
package hash <M>{REGISTRY_HASH_SHORT}</M>. The full{' '}
<M>register → 402 → pay → serve → attest → score</M> loop runs on-chain. See{' '}
<DocLink href="/docs/contract">Smart contracts</DocLink>.
</li>
<li>Hosted gateway and dashboard brought online so agents can transact without local setup.</li>
</ul>

<NextLinks
links={[
{ href: '/docs/quickstart', label: 'Quickstart' },
{ href: '/docs/contract', label: 'Smart contracts' },
]}
/>
</>
);
}
82 changes: 74 additions & 8 deletions dashboard/app/docs/cli/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from '@/components/docs';

export const metadata: Metadata = {
alternates: { canonical: '/docs/cli' },
title: 'CLI',
description:
'Reference for the agentgate CLI: wrap, list, status, pause, resume and demo-accounts. Every flag, argument, default and example output, verified against packages/cli/src/bin.ts.',
Expand Down Expand Up @@ -158,6 +159,49 @@ export default function Page() {
]}
/>

<H3 id="config-flags">Config flags</H3>
<P>
Each of these overrides the matching environment variable (<M>flag &gt; env &gt; default</M>).{' '}
<M>--mode</M>, <M>--node-url</M> and <M>--registry</M> are accepted by all six commands; the
signer and key flags are read only by the commands that need them.
</P>
<DocTable
head={['Flag', 'Overrides', 'Default', 'Used by']}
rows={[
[<M key="f1">--mode {'<mock|live>'}</M>, <M key="e1">AGENTGATE_MODE</M>, <M key="d1">live</M>, 'all commands'],
[<M key="f2">--node-url {'<url>'}</M>, <M key="e2">CASPER_NODE_URL</M>, 'Casper Testnet', 'all commands'],
[
<M key="f3">--registry {'<hash>'}</M>,
<M key="e3">REGISTRY_CONTRACT_PACKAGE_HASH</M>,
'the deployed package hash',
'all commands',
],
[
<M key="f4">--pem {'<path>'}</M>,
<M key="e4">SELLER_SIGNER_PEM_PATH</M>,
<M key="d4">(none)</M>,
'wrap, pause, resume (live writes)',
],
[
<M key="f5">--admin-token {'<token>'}</M>,
<M key="e5">AGENTGATE_ADMIN_TOKEN</M>,
<M key="d5">dev-admin-token</M>,
'wrap (mock / self-hosted admin)',
],
[
<M key="f6">--api-key {'<key>'}</M>,
<M key="e6">CSPR_CLOUD_API_KEY</M>,
<M key="d6">(none)</M>,
'status (attestation history)',
],
]}
/>
<Callout tone="warn" title="Secrets on the command line">
<M>--pem</M> is a path (safe), but <M>--admin-token</M> and <M>--api-key</M> put the secret
itself into shell history and <M>ps</M> output. Prefer the environment variable for those two
in any shared or CI environment.
</Callout>

{/* ───────────────────────────── wrap ───────────────────────────── */}
<H2 id="wrap">wrap</H2>
<P>
Expand Down Expand Up @@ -222,6 +266,11 @@ export default function Page() {
],
]}
/>
<P>
<M>wrap</M> also reads the <DocLink href="#config-flags">config flags</DocLink> — most
importantly <M>--pem</M> (required for live writes) and <M>--admin-token</M> (mock or
self-hosted admin mapping).
</P>
<H3 id="wrap-example">Example</H3>
<CommandBlock
wrap
Expand Down Expand Up @@ -297,19 +346,24 @@ export default function Page() {
Show one service in depth: the full record, its score, trust tier and recent
attestations.
</P>
<CommandBlock text="npx @mdlog/agentgate status <id>" />
<CommandBlock text="npx @mdlog/agentgate status <id> [--api-key <key>]" />
<DocTable
head={['Argument', 'Required', 'Rule']}
head={['Argument / flag', 'Required', 'Rule']}
rows={[
[
<M key="i">{'<id>'}</M>,
'yes',
'Positive integer (1-based). A non-numeric or < 1 value throws INVALID_SERVICE_ID; an id with no on-chain record throws SERVICE_NOT_FOUND.',
],
[
<M key="k">--api-key {'<key>'}</M>,
'no',
'CSPR.cloud key used only to fetch attestation history (overrides CSPR_CLOUD_API_KEY). Without it, the record, score and tier still print but attestation history is skipped.',
],
]}
/>
<CodeBlock
label="output"
label="output — default (no key)"
code={[
'service: #1 Gold Spot Feed',
'description: USD spot gold with confidence',
Expand All @@ -318,6 +372,19 @@ export default function Page() {
'payment target: account-hash-<64hex>',
'owner: 01<publicKeyHex>',
'attestor: 01<publicKeyHex>',
'trust: reliable (9/10 calls ok)',
'attestations: (set CSPR_CLOUD_API_KEY or pass --api-key to view history)',
].join('\n')}
/>
<P>
The record, score and trust tier always print with no keys. Attestation history is the one
part that needs a <DocLink href="#config-flags">CSPR.cloud key</DocLink>: without{' '}
<M>--api-key</M> (or <M>CSPR_CLOUD_API_KEY</M>) the last line is the hint above and the
command stops. Pass the key to fetch the newest attestations:
</P>
<CodeBlock
label="output — with --api-key"
code={[
'trust: reliable (9/10 calls ok)',
'attestations (latest 10):',
' [ok ] 2026-06-12T10:30:05.123Z payment a1b2c3d4e5f6 tx b2c3d4e5f6a1',
Expand All @@ -326,10 +393,9 @@ export default function Page() {
/>
<P>
At most 10 attestations are shown (<M>STATUS_ATTESTATION_LIMIT</M>), newest first, each
prefixed <M>[ok ]</M> or <M>[FAIL]</M>. With none, it prints{' '}
<M>attestations: none yet</M> and stops. An inactive service is tagged{' '}
<M>[INACTIVE]</M> after its name, and the <M>description:</M> line is omitted when the
description is empty.
prefixed <M>[ok ]</M> or <M>[FAIL]</M>; with a key but no attestations yet it prints{' '}
<M>attestations: none yet</M>. An inactive service is tagged <M>[INACTIVE]</M> after its
name, and the <M>description:</M> line is omitted when the description is empty.
</P>

{/* ───────────────────────────── pause ───────────────────────────── */}
Expand Down Expand Up @@ -361,7 +427,7 @@ export default function Page() {
/>
<P>
Like <M>wrap</M>, <M>pause</M> resolves the owner signer from{' '}
<M>MOCK_SELLER_ACCOUNT</M> (mock) or <M>SELLER_SIGNER_PEM_PATH</M> (live). If the
<M>MOCK_SELLER_ACCOUNT</M> (mock) or <M>SELLER_SIGNER_PEM_PATH</M> / <M>--pem</M> (live). If the
signing key is not the service owner, the chain&apos;s 403 is reworded into a clear
owner-only <M>not_authorized</M> error.
</P>
Expand Down
3 changes: 2 additions & 1 deletion dashboard/app/docs/configuration/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '@/components/docs';

export const metadata: Metadata = {
alternates: { canonical: '/docs/configuration' },
title: 'Configuration',
description:
'Complete reference for every AgentGate environment variable: names, defaults, validation rules, which are required in live mode, and the loadConfig() guardrails that refuse an unsafe live configuration.',
Expand Down Expand Up @@ -498,7 +499,7 @@ export default function ConfigurationPage() {
<Callout tone="info" title="One rule for every CSPR amount">
Any CSPR value anywhere in the system (prices, budgets) allows at most 9 decimal places — 1
mote = 1e-9 CSPR — and is processed as a bigint-backed decimal string. See{' '}
<DocLink href="/docs/protocol">Protocol → Money units</DocLink>.
<DocLink href="/docs/protocol#invoice">Protocol → the 402 invoice body</DocLink>.
</Callout>

<NextLinks
Expand Down
1 change: 1 addition & 0 deletions dashboard/app/docs/contract/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from '@/components/docs';

export const metadata: Metadata = {
alternates: { canonical: '/docs/contract' },
title: 'Smart contracts',
description:
'Reference for the AgentGate Odra/Rust contracts: AgentGateRegistry (service registry + attestation reputation) and SpendGuard (x402 spend-firewall escrow) — storage, entrypoints, events, error codes, and build/deploy.',
Expand Down
3 changes: 2 additions & 1 deletion dashboard/app/docs/deployment/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { CommandBlock } from '@/components/copy';

export const metadata: Metadata = {
alternates: { canonical: '/docs/deployment' },
title: 'Deploy to production',
description:
'Deploy the AgentGate 402 gateway: what to host, the hosting docker-compose stack, Railway + Vercel, the live-mode checklist enforced by loadConfig(), health/readiness probes, and built-in hardening.',
Expand Down Expand Up @@ -259,7 +260,7 @@ export default function DeploymentPage() {
<span key="d">
The deployed registry&apos;s <M>hash-&lt;64hex&gt;</M>. Empty is accepted by{' '}
<M>loadConfig()</M> but every registry read/write then fails — see{' '}
<DocLink href="/docs/contract#deploy-status">Contract → Deploy status</DocLink>.
<DocLink href="/docs/contract#build-deploy">Contract → Build and deploy</DocLink>.
</span>,
],
[
Expand Down
1 change: 1 addition & 0 deletions dashboard/app/docs/errors/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '@/components/docs';

export const metadata: Metadata = {
alternates: { canonical: '/docs/errors' },
title: 'Error codes',
description:
'Every AgentGate error code: the AgentGateError(code, message, httpStatus) shape, the lowercased JSON error body, and a code-by-code reference grouped by config, chain/live, the 402 paywall + admin API, the client SDK, the buyer agent, and the CLI.',
Expand Down
8 changes: 5 additions & 3 deletions dashboard/app/docs/installation/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '@/components/docs';

export const metadata: Metadata = {
alternates: { canonical: '/docs/installation' },
title: 'Installation',
description:
'Requirements, clone-and-install, the workspace layout, mock vs live mode, the environment file, and how to verify your install passes tests, typecheck and the one-shot demo.',
Expand Down Expand Up @@ -188,9 +189,10 @@ export default function InstallationPage() {

<H2 id="modes">Modes — mock vs live</H2>
<P>
The <M>AGENTGATE_MODE</M> environment variable (default <M>mock</M>) selects the chain
backend behind the <M>ChainClient</M> seam. Everything above that seam — the gateway, CLI,
buyer agent and dashboard — is byte-for-byte identical in both modes.
The <M>AGENTGATE_MODE</M> environment variable selects the chain backend behind the{' '}
<M>ChainClient</M> seam. The stack (gateway, buyer agent, dashboard) defaults to <M>mock</M> via{' '}
<M>loadConfig()</M>; the published <M>npx</M> CLI defaults to <M>live</M>. Everything above that
seam — the gateway, CLI, buyer agent and dashboard — is byte-for-byte identical in both modes.
</P>
<DocTable
head={['Aspect', 'mock', 'live (Casper Testnet)']}
Expand Down
4 changes: 4 additions & 0 deletions dashboard/app/docs/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ReactNode } from 'react';
import { DocsSidebar, DocsTopNav, OnThisPage } from '@/components/docs-nav';
import { DocsSearch } from '@/components/docs-search';

/* Server shell for the docs section: a sticky grouped sidebar on desktop, a
compact horizontal nav on mobile, a comfortable prose column, and an
Expand All @@ -16,6 +17,9 @@ export default function DocsLayout({ children }: { children: ReactNode }) {
</div>
</aside>
<div className="min-w-0 flex-1">
<div className="mx-auto mb-6 max-w-3xl">
<DocsSearch />
</div>
<div className="mb-8 lg:hidden">
<DocsTopNav />
</div>
Expand Down
Loading
Loading