From efeecef91dcec4cd784984a66b8fe79c6efd12bf Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Thu, 1 Oct 2026 20:29:46 -0500 Subject: [PATCH 1/8] fix(native) Keep search redirects within the port why: Python's generated search redirect has no article, so native shell normalization rejected the complete assembly. Its root URL also lost the selected preview, port and version. what: - Route native search pages to the owned port search page. - Preserve the query and fragment with a static fallback link. - Verify both Sphinx URL forms, repeat normalization and article guards. --- scripts/normalize-native-shell.mjs | 14 +++++++++++++ site/test/normalize-native-shell.test.ts | 26 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/scripts/normalize-native-shell.mjs b/scripts/normalize-native-shell.mjs index 1b28c729..cf533df4 100644 --- a/scripts/normalize-native-shell.mjs +++ b/scripts/normalize-native-shell.mjs @@ -54,6 +54,20 @@ export async function normalizeNativeShell(directory, prefix, { sphinxPort, vers } else if (/\.(html|css)$/.test(entry.name)) { const before = readFileSync(path, 'utf8') let after = normalize(before) + // Native search delegates to the owned search page for this port/version. + if (port && /^search(?:\.html|\/index\.html)$/.test(relative(directory, path).split(sep).join('/'))) { + const target = `${root}/${port.slug}/${version}/search/` + const href = escapeAttribute(target) + const scriptTarget = JSON.stringify(target).replaceAll('<', '\\u003c') + after = ` +Search + + + + +

Search the ${port.name} documentation.

+` + } if (port && entry.name.endsWith('.html') && !/]*http-equiv=["']refresh["']/i.test(after)) { if (!/<\/head>/i.test(after)) throw new Error(`Native page has no closing head: ${path}`) // Old source refs may predate the shell; replace existing integration once. diff --git a/site/test/normalize-native-shell.test.ts b/site/test/normalize-native-shell.test.ts index 8f4f0cd0..9aed7efa 100644 --- a/site/test/normalize-native-shell.test.ts +++ b/site/test/normalize-native-shell.test.ts @@ -1,11 +1,37 @@ import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' +import { runInNewContext } from 'node:vm' import { describe, expect, it } from 'vitest' import { normalizeNativeShell } from '../../scripts/normalize-native-shell.mjs' import { recordBuild, verifyBuild } from '../../scripts/publication-provenance.mjs' describe('native shell URL normalization', () => { + it.each(['search.html', 'search/index.html'])('routes native %s to scoped search with the query intact', async (name) => { + const directory = mkdtempSync(join(tmpdir(), 'native-search-')) + try { + mkdirSync(join(directory, 'search'), { recursive: true }) + const page = join(directory, name) + writeFileSync(page, 'Search') + await normalizeNativeShell(directory, '/pr-42/en', { sphinxPort: 'py', version: 'v0.62.0' }) + const html = readFileSync(page, 'utf8') + const target = '/pr-42/en/py/v0.62.0/search/' + expect(html).toContain(``) + expect(html).toContain(`Search the Python documentation`) + expect(html).not.toContain('data-pagefind-body') + let destination = '' + runInNewContext(html.match(/ diff --git a/site/src/pages/reference/[...slug].astro b/site/src/pages/reference/[...slug].astro index 9f97ec58..98e6de0c 100644 --- a/site/src/pages/reference/[...slug].astro +++ b/site/src/pages/reference/[...slug].astro @@ -3,6 +3,8 @@ import type { ApiModel, ApiSymbol } from '@libtmux/api-model' import { compareMembers, conceptsFor, docSummaryText, memberSignals, moduleOf, modulesIn, sourceUrl as apiSourceUrl, symbolsForProduct } from '@libtmux/api-model' import mentionsData from '../../data/mentions.json' import ApiEntry from '../../components/api/ApiEntry.astro' +import ApiBadge from '../../components/api/ApiBadge.astro' +import ApiQualifiedName from '../../components/api/ApiQualifiedName.astro' import PageToolbar from '../../components/PageToolbar.astro' import { pagePortsFor } from '../../lib/page-ports-for' import { pageBreadcrumbs } from '../../lib/sidebar' @@ -461,7 +463,7 @@ const breadcrumbs = await pageBreadcrumbs(title, slug ? `reference/${slug}` : 'r /> )} -
+
-
+
{model && ( - {(members.length > 0 || (owner.doc?.examples?.length ?? 0) > 0) && + {pageSections.length > 1 && } -