diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..e3abe573 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,49 @@ +# Agent guide for developers.nextcommerce.com + +This file is the navigation and evidence contract for an agent reading the Next Commerce developer documentation. It is not a setup script. Agent setup instructions will live at /agent-setup/prompt.md (tracked in developer-docs#45). + +## What this site is + +https://developers.nextcommerce.com documents the Next Commerce platform for developers: the Admin API (REST), webhooks, storefront themes and the storefront GraphQL API, campaigns and the Campaign Cart SDK, apps and OAuth, AI agent skills, and testing. + +The sibling site, https://docs.nextcommerce.com, is the merchant and operator documentation: dashboard guides, store configuration, payments operations, and the platform changelog. Questions about how to operate a store belong there; questions about how to integrate with it belong here. + +## Where to start + +- https://developers.nextcommerce.com/llms.txt is the page index for this site, with a one-line description per page and absolute URLs. +- https://developers.nextcommerce.com/llms-full.txt is the full corpus in one file. It is large (about 1.5 MB); fetch it only when you need broad coverage rather than a specific page. +- Raw OpenAPI specs, which are the authority for operations, parameters, and fields: + - https://developers.nextcommerce.com/api/admin/2024-04-01.yaml (stable) + - https://developers.nextcommerce.com/api/admin/unstable.yaml + - https://developers.nextcommerce.com/api/admin/2023-02-10.yaml (deprecated) + - https://developers.nextcommerce.com/api/campaigns/v1.yaml +- https://developers.nextcommerce.com/docs/webhooks lists every webhook event and the payload structure. +- https://developers.nextcommerce.com/docs/testing covers test cards, test orders, and sandbox behavior. +- https://docs.nextcommerce.com/llms.txt is the equivalent index for the merchant site. + +## Evidence rules + +- Cite the page URL for every claim you make from this documentation. +- For facts about an operation, parameter, or field, prefer the versioned spec over prose pages. The prose explains; the spec is the contract. +- The changelog at https://docs.nextcommerce.com/changelog is the record of what changed and when. Do not infer release history from page contents. +- NEXT Payments processing rates are not published. If asked, say so rather than estimating. +- Do not "correct" identifiers containing 29next. See Legacy identifiers below. +- If the documentation does not answer a question, say that it does not. Do not fill gaps from general ecommerce knowledge and present the result as Next Commerce behavior. + +## Versions + +The Admin API is versioned by date. The version is selected per request with the `X-29next-API-Version` header. + +- `2024-04-01`: stable, recommended for all new integrations. +- `2023-02-10`: deprecated; documented for existing integrations only. +- `unstable`: in-progress changes; may change without notice. + +Each version has its own spec file (listed above) and its own reference section on the site. When a question names a version, answer from that version's spec. + +## Legacy identifiers + +Next Commerce was formerly 29 Next. Hostnames like `{store}.29next.store`, `accounts.29next.com`, and headers like `X-29next-API-Version` and `X-29Next-Signature` are current, valid technical identifiers and must be used exactly as written. + +## Corrections + +Outside pull requests to this repository are not accepted. The support route for reporting documentation errors is being confirmed and will be linked here. diff --git a/CLAUDE.md b/CLAUDE.md index 1f4a59fb..cbc27f7e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,18 +1,3 @@ - -## Skill routing - -When the user's request matches an available skill, invoke it via the Skill tool. When in doubt, invoke the skill. - -Key routing rules: -- Product ideas/brainstorming → invoke /office-hours -- Strategy/scope → invoke /plan-ceo-review -- Architecture → invoke /plan-eng-review -- Design system/plan review → invoke /design-consultation or /plan-design-review -- Full review pipeline → invoke /autoplan -- Bugs/errors → invoke /investigate -- QA/testing site behavior → invoke /qa or /qa-only -- Code review/diff check → invoke /review -- Visual polish → invoke /design-review -- Ship/deploy/PR → invoke /ship or /land-and-deploy -- Save progress → invoke /context-save -- Resume context → invoke /context-restore +The public contract for agents reading this repository or the site it publishes is AGENTS.md. +See ./AGENTS.md for navigation, evidence rules, API versions, and legacy identifiers. +Internal tool routing for the maintainers' own sessions is not kept in this repository. diff --git a/app/llms.txt/route.ts b/app/llms.txt/route.ts index fc80cb65..16172b56 100644 --- a/app/llms.txt/route.ts +++ b/app/llms.txt/route.ts @@ -1,8 +1,116 @@ import { source } from '@/lib/source'; -import { llms } from 'fumadocs-core/source'; export const revalidate = false; +const SITE = 'https://developers.nextcommerce.com'; +const MERCHANT_SITE = 'https://docs.nextcommerce.com'; + +// Groups named here come first, in this order; any other top-level folder +// follows alphabetically. 'index' is the /docs root page itself. +const PREFERRED_GROUP_ORDER = [ + 'index', + 'admin-api', + 'webhooks', + 'storefront', + 'campaigns', + 'apps', + 'skills', + 'testing', +]; + +const GROUP_TITLES: Record = { + index: 'Overview', + 'admin-api': 'Admin API', + webhooks: 'Webhooks', + storefront: 'Storefront', + campaigns: 'Campaigns', + apps: 'Apps', + skills: 'Skills', + testing: 'Testing', +}; + +function groupTitle(key: string): string { + if (GROUP_TITLES[key]) return GROUP_TITLES[key]; + return key + .split('-') + .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) + .join(' '); +} + +function groupKey(url: string): string { + const rest = url.replace(/^\/docs\/?/, ''); + const first = rest.split('/')[0]; + return first || 'index'; +} + +// Frontmatter values are interpolated into Markdown link syntax; keep each +// page on exactly one line and neutralise the characters that would break it. +function oneLine(value: string): string { + return value.replace(/\s+/g, ' ').trim(); +} + +function linkText(value: string): string { + return oneLine(value).replace(/[\[\]]/g, '\\$&'); +} + +function header(): string { + return [ + '# Next Commerce Developer Docs', + '', + '> API, webhook, storefront theme, campaign, and app documentation for Next Commerce, the ecommerce platform for direct-to-consumer brands. Merchant and operator guides live on the sibling site.', + '', + '## Start here', + '', + `- [Developer docs home](${SITE})`, + `- [Merchant docs](${MERCHANT_SITE}): guides for store operators, on the sibling site`, + `- [Merchant docs index](${MERCHANT_SITE}/llms.txt)`, + `- [Platform and API changelog](${MERCHANT_SITE}/changelog): the developer portal has no changelog of its own`, + `- [Full corpus](${SITE}/llms-full.txt): every page in one file (large, about 1.5 MB)`, + `- [Admin API spec, 2024-04-01](${SITE}/api/admin/2024-04-01.yaml): stable, raw OpenAPI`, + `- [Admin API spec, unstable](${SITE}/api/admin/unstable.yaml): raw OpenAPI`, + `- [Admin API spec, 2023-02-10](${SITE}/api/admin/2023-02-10.yaml): deprecated, raw OpenAPI`, + `- [Campaigns API spec, v1](${SITE}/api/campaigns/v1.yaml): raw OpenAPI`, + `- [Webhooks](${SITE}/docs/webhooks)`, + `- [Skills](${SITE}/docs/skills): AI agent skills for the platform`, + `- [Testing](${SITE}/docs/testing)`, + `- [Agent guide (AGENTS.md)](https://github.com/NextCommerceCo/developer-docs/blob/main/AGENTS.md): navigation and evidence rules for agents reading this site`, + '', + '## Legacy identifiers', + '', + 'Next Commerce was formerly 29 Next. Hostnames like `{store}.29next.store`, `accounts.29next.com`, and headers like `X-29next-API-Version` and `X-29Next-Signature` are current, valid technical identifiers and must be used exactly as written.', + '', + ].join('\n'); +} + export function GET() { - return new Response(llms(source).index()); + const groups = new Map(); + + for (const page of source.getPages()) { + const key = groupKey(page.url); + const title = linkText(page.data.title ?? page.url); + const description = page.data.description ? linkText(page.data.description) : ''; + const line = description + ? `- [${title}](${SITE}${page.url}): ${description}` + : `- [${title}](${SITE}${page.url})`; + const list = groups.get(key) ?? []; + list.push(line); + groups.set(key, list); + } + + const keys = [...groups.keys()].sort((a, b) => { + const ia = PREFERRED_GROUP_ORDER.indexOf(a); + const ib = PREFERRED_GROUP_ORDER.indexOf(b); + if (ia !== -1 && ib !== -1) return ia - ib; + if (ia !== -1) return -1; + if (ib !== -1) return 1; + return a.localeCompare(b); + }); + + const body = keys + .map((key) => `## ${groupTitle(key)}\n\n${groups.get(key)!.join('\n')}\n`) + .join('\n'); + + return new Response(header() + '\n' + body, { + headers: { 'Content-Type': 'text/plain; charset=utf-8' }, + }); } diff --git a/app/not-found.tsx b/app/not-found.tsx new file mode 100644 index 00000000..6925faeb --- /dev/null +++ b/app/not-found.tsx @@ -0,0 +1,26 @@ +import Link from 'next/link'; + +export default function NotFound() { + return ( +
+
+
+

Page not found

+

+ The page you asked for does not exist or has moved. +

+
+ +
+
+ ); +} diff --git a/app/page.tsx b/app/page.tsx index 9bd5f221..15735459 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -14,6 +14,7 @@ import { Sparkles, } from 'lucide-react'; import { siteConfig } from '@/lib/config'; +import stats from '@/lib/generated/stats.json'; import { AlgoliaDocSearch, AlgoliaDocSearchMobile } from '@/components/search'; import { HeroFlow } from '@/components/hero-flow'; import { MouseSpotlight } from '@/components/mouse-spotlight'; @@ -229,11 +230,11 @@ export default function HomePage() {