Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
591479a
feat(ia): add operate, sdks & cli and guides sections
chasegrayoffice Nov 10, 2026
da8e1fd
feat(nav): six-area global nav with product switcher and get api key
chasegrayoffice Nov 10, 2026
0bbb46c
feat(home): lead with the first payment and one card family
chasegrayoffice Nov 10, 2026
07d1def
fix(search): rank guides above api operations and add aliases
chasegrayoffice Nov 10, 2026
fd3fe5f
feat(shell): add docs footer, breadcrumbs and a not-found page
chasegrayoffice Nov 10, 2026
7384bd2
style(docs): quieter page actions, docked ask ai, prose measure and c…
chasegrayoffice Nov 10, 2026
e2d3488
fix(ia): match the get started sidebar label to its page title
chasegrayoffice Nov 10, 2026
a87d7dd
style(docs): previous and next read as next-step cards
chasegrayoffice Nov 10, 2026
c2687b9
style(get-started): format the hero selectors
chasegrayoffice Nov 10, 2026
ca5ad73
fix(nav): keep the header from overlapping between 1080 and 1375px
chasegrayoffice Nov 10, 2026
5bb4171
test(e2e): follow the six-area nav, new home and get started
chasegrayoffice Nov 10, 2026
54479fa
Merge remote-tracking branch 'origin/main' into chase/docs-redesign
chasegrayoffice Nov 12, 2026
7de125f
feat(nav): four tabs, section tabs and a page bar
chasegrayoffice Nov 12, 2026
a282c17
feat(docs): one page action, outline-only rail and sharper system
chasegrayoffice Nov 12, 2026
611f30c
feat(home): one hero action, compact docs footer and a leaner 404
chasegrayoffice Nov 12, 2026
6ece138
style(docs): apply the value rules to content components
chasegrayoffice Nov 12, 2026
f8c5f9b
test(e2e): assert the Nav v2 tabs, section row, page bar and footers
chasegrayoffice Nov 12, 2026
8ad67f5
feat(nav): one bar of products, a DS menu drawer and a page header row
chasegrayoffice Nov 13, 2026
9d63d60
feat(ia): end each product's sidebar with its API reference
chasegrayoffice Nov 13, 2026
e10bd4d
test(e2e): follow the product bar, header row and menu drawer
chasegrayoffice Nov 13, 2026
4efbb4d
style(docs): set copy in Inter, like DS Body
chasegrayoffice Nov 13, 2026
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
10 changes: 6 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ Vocs-powered documentation site for Tempo protocol. Use this guidance when creat

## Documentation IA and agent exports

- `src/lib/docs-sections.ts` owns the section labels, landing routes, and route ownership; `vocs.config.ts` owns the sidebar within each section.
- Primary sections: Get Started (`/get-started`), Accounts (`/docs/accounts`), Earn (`/docs/earn`), Routes (`/docs/routes`), Zones (`/docs/zones`), and Machine Payments (`/docs/agents`). Get Started also owns the SDK, CLI, and wallet CLI pages (`/docs/sdk`, `/docs/cli`, `/docs/wallet`) as its Tempo CLI and Tempo SDK sections.
- Tempo EVM (`/docs/development`) covers wallets and signing keys, transactions, fees, TIP-20 Tokens, contracts, exchange, network details, nodes, protocol specifications, and changelog.
- API reference (`/docs/api`) is its own top-nav link, matching Console's "API Docs" link. Partners (`/docs/partners`) contains third-party integrations. The old APIs & SDKs hub (`/docs/tools`) redirects to `/docs/sdk`.
- `src/lib/docs-sections.ts` owns the section labels, landing routes, and route ownership, plus `docsResourceSectionIds`, the sections in the top bar's Resources menu; `vocs.config.ts` owns the sidebar within each section.
- Top bar: the TEMPO DEVELOPERS lockup (Home), the products as plain links (Get started, Accounts, Earn, Routes, Zones, Machine Payments, Network), then Resources, the only menu (Guides, Partners, SDKs & CLI), search and Get API key, the one primary button. There is no second row. The sidebar lists only the current section's pages, and each product's sidebar ends with an API reference group that links its endpoint pages; the API reference itself keeps the full sidebar generated from the spec. Below 1200px the products move into the menu drawer (products, Resources, then the section's pages); the Vocs sidebar shows from 1080px. Each docs page opens with a header row: Section › Page breadcrumbs, Ask AI and Copy page. Docs pages end at Previous / Next with no footer; Home and Not found keep the full footer.
- Sections: Get started (`/get-started`, onboarding plus the testnet faucet, network details, and Build with AI), Accounts (`/docs/accounts`), Earn (`/docs/earn`), Routes (`/docs/routes`), Zones (`/docs/zones`), Machine Payments (`/docs/agents`), Network (`/docs/development`, plus `/docs/guide/node`, `/docs/changelog`, and `/docs/protocol/upgrades`), API (`/docs/api`), SDKs & CLI (`/docs/sdk`, `/docs/cli`, `/docs/wallet`), Guides (`/docs/resources`) and Partners (`/docs/partners`).
- Network merges the former Tempo EVM and Operate sections under the `developers` id. Its sidebar lists the Tempo EVM groups (wallets and signing keys, transactions, fees, TIP-20 Tokens, contracts, exchange, network details, and protocol specifications), then Run a node, then Changelog (network upgrades, node releases, and operator updates).
- The header has no product switcher, agent popover, or sign-in link. Their links live in context: Tempo Wallet in the Accounts sidebar, the MPP spec in Machine Payments, the Explorer in Network, agent setup in Get started › Build with AI, and Console behind Get API key (it reads "Console" when signed in).
- API reference matches Console's "API Docs" link. Partners contains third-party integrations. The old APIs & SDKs hub (`/docs/tools`) redirects to `/docs/sdk`.
- Keep Earn and Routes beta notices and the Zones availability notice (live on Mainnet, set up with Tempo) on their overview pages. The earlier `/docs/guide/private-zones` sandbox is a separate integration.
- `public/SKILL.md` is the canonical Tempo docs skill, published at `/SKILL.md`. The `tempoxyz/plugins` copy is generated from it by that repo's skill sync, so edit only `public/SKILL.md` here.
- `src/lib/markdown-output-transform.ts` uses `src/lib/ai-docs.ts` to add section context before Vocs validates and writes Markdown exports. `SKILL.md` links to `public/SKILL.md`, the source Vite serves and copies. Never edit `dist` or `.vercel` copies by hand.
Expand Down
30 changes: 20 additions & 10 deletions e2e/blog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,34 @@ for (const width of [390, 1440]) {
await expect(
page.locator('header').getByRole('link', { name: 'Blog', exact: true, includeHidden: true }),
).toHaveCount(0)
await expect(
page
.locator('.docs-section-utilities')
.getByRole('link', { name: 'Blog', exact: true, includeHidden: true }),
).toHaveCount(0)
await expect(page.locator('#blog, .tempo-blog')).toHaveCount(0)
if (width < 1080) {
if (width < 1200) {
await page.getByRole('button', { name: 'Open menu', exact: true }).click()
const menu = page.getByRole('dialog', { name: 'Documentation navigation', exact: true })
const menu = page.getByRole('dialog', { name: 'Tempo Developers menu', exact: true })
await expect(menu).toBeVisible()
await expect(
menu.getByRole('link', { name: 'Blog', exact: true, includeHidden: true }),
).toHaveCount(0)
await expect(menu.getByRole('link', { name: 'Get Started', exact: true })).toBeVisible()
await expect(menu.getByRole('link', { name: 'Get started', exact: true })).toBeVisible()
} else {
const products = page
.locator('header.docs-site-header')
.getByRole('navigation', { name: 'Products', exact: true })
await expect(products).toBeVisible()
await expect(products.getByRole('link')).toHaveText([
'Get started',
'Accounts',
'Earn',
'Routes',
'Zones',
'Machine Payments',
'Network',
])
// Resources, the bar's only menu, opens outside the header.
await products.getByRole('button', { name: 'Resources', exact: true }).click()
await expect(
page.getByRole('navigation', { name: 'Documentation sections', exact: true }),
).toBeVisible()
page.getByRole('menu', { name: 'Resources', exact: true }).getByRole('menuitem'),
).toHaveText(['Guides', 'Partners', 'SDKs & CLI'])
}
})
}
Expand Down
57 changes: 38 additions & 19 deletions e2e/developers-homepage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ test('serves the docs homepage directly at the root URL', async ({ page, request
expect((await request.get('/', { maxRedirects: 0 })).status()).toBe(200)
await page.goto('/')
await expect(page).toHaveURL((url) => url.pathname === '/')
await expect(page.getByRole('heading', { level: 1, name: 'Documentation' })).toBeVisible()
await expect(page.getByRole('navigation', { name: 'Developer navigation' })).toBeVisible()
await expect(
page.getByRole('heading', { level: 1, name: 'Build stablecoin payments on Tempo' }),
).toBeVisible()
await expect(
page
.locator('header.docs-site-header')
.getByRole('navigation', { name: 'Products', exact: true }),
).toBeVisible()
})

test('keeps legacy docs queries and anchors when opening the new landing', async ({ page }) => {
Expand All @@ -40,7 +46,7 @@ test('serves getting started directly with its overview sidebar', async ({ page,
).toBeVisible()
const sidebar = page.locator('[data-v-gutter-left] [data-v-sidebar-container]')
await expect(sidebar).toBeVisible()
await expect(sidebar.getByRole('link', { name: 'Start building', exact: true })).toHaveAttribute(
await expect(sidebar.getByRole('link', { name: 'Build on Tempo', exact: true })).toHaveAttribute(
'href',
'/get-started',
)
Expand Down Expand Up @@ -84,24 +90,30 @@ for (const entry of ['direct', 'client navigation'] as const) {
} else {
await page.goto('/docs/accounts')
await page
.getByRole('navigation', { name: 'Documentation sections' })
.getByRole('link', { name: 'Get Started', exact: true })
.locator('header.docs-site-header')
.getByRole('navigation', { name: 'Products', exact: true })
.getByRole('link', { name: 'Get started', exact: true })
.click()
await page
.locator('article[data-v-content]')
.getByRole('link', { name: 'interactive quickstart', exact: true })
.getByRole('link', { name: 'Send your first payment', exact: true })
.click()
}

await expect(page).toHaveURL((url) => url.pathname === '/get-started/quickstart')
await expect(page.locator('#try-a-payment')).toBeAttached()
await expect(page.locator('h2#try-a-payment')).toBeVisible()
const pageTools = page.getByRole('navigation', { name: 'Page tools' })
await expect(pageTools).toHaveCount(1)
await expect(pageTools.getByRole('link', { name: 'View Markdown' })).toHaveAttribute(
'href',
'/assets/md/get-started/quickstart.md',
)
// One Copy page split button above the H1; its menu links the page's Markdown.
const pageActions = page.locator('.docs-page-actions')
await expect(pageActions).toHaveCount(1)
await expect(pageActions.getByRole('button', { name: 'Copy page', exact: true })).toBeVisible()
await pageActions.getByRole('button', { name: 'More page options', exact: true }).click()
const pageMenu = page.getByRole('menu', { name: 'More page options', exact: true })
await expect(
pageMenu.getByRole('menuitem', { name: 'View as Markdown', exact: true }),
).toHaveAttribute('href', '/assets/md/get-started/quickstart.md')
await page.keyboard.press('Escape')
await expect(pageMenu).toHaveCount(0)
const signIn = getDemoStep(page, 'Create an account, or use an existing one.').getByRole(
'button',
{ name: 'Sign in', exact: true },
Expand Down Expand Up @@ -163,33 +175,40 @@ for (const entry of ['direct', 'client navigation'] as const) {
}) => {
await page.setViewportSize({ width: 1440, height: 1000 })
const sidebar = page.locator('[data-v-gutter-left] [data-v-sidebar-container]')
const sections = page.getByRole('navigation', { name: 'Documentation sections' })
const products = page
.locator('header.docs-site-header')
.getByRole('navigation', { name: 'Products', exact: true })

if (entry === 'direct') {
expect((await request.get('/get-started/quickstart', { maxRedirects: 0 })).status()).toBe(200)
await page.goto('/get-started/quickstart')
} else {
await page.goto('/docs/accounts')
await sections.getByRole('link', { name: 'Get Started', exact: true }).click()
// Get started opens its overview.
await products.getByRole('link', { name: 'Get started', exact: true }).click()
await expect(page).toHaveURL(/\/get-started\/?$/)
await sidebar.getByRole('link', { name: 'Quickstart', exact: true }).click()
}

await expect(page).toHaveURL(/\/get-started\/quickstart\/?$/)
await expect(
page.getByRole('heading', { level: 1, name: 'Quickstart', exact: true }),
).toBeVisible()
await expect(page.getByRole('navigation', { name: 'Developer navigation' })).toBeVisible()
await expect(sections).toBeVisible()
await expect(sections.locator('[aria-current="page"]')).toHaveText('Get Started')
await expect(products).toBeVisible()
await expect(products.locator('[aria-current="page"]')).toHaveText('Get started')
await expect(products.getByRole('link', { name: 'Get started', exact: true })).toHaveAttribute(
'aria-current',
'page',
)
await expect(sidebar).toBeVisible()
await expect(sidebar.locator('a[data-active]')).toHaveAttribute(
'href',
'/get-started/quickstart',
)

await sidebar.getByRole('link', { name: 'Start building', exact: true }).click()
await sidebar.getByRole('link', { name: 'Build on Tempo', exact: true }).click()
await expect(page).toHaveURL(/\/get-started\/?$/)
await expect(sections).toBeVisible()
await expect(products.locator('[aria-current="page"]')).toHaveText('Get started')
await expect(sidebar.locator('a[data-active]')).toHaveAttribute('href', '/get-started')
})
}
Loading