seemore 1.4.1 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -20
- package/dist/cli/index.js +5 -2
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -83,6 +83,10 @@ Run it in your folder of Markdown files (Node.js 20 or newer) and open the addre
|
|
|
83
83
|
|
|
84
84
|
Install **seemore** from the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=arifszn.seemore-vscode) or [Open VSX](https://open-vsx.org/extension/arifszn/seemore-vscode) to get the same rendered site as a panel beside your editor — no terminal, no `npx`, no browser tab to manage. The extension bundles the CLI, so nothing is downloaded or put on your PATH. Open VSX also covers VS Code-compatible editors — Cursor, Antigravity, and others.
|
|
85
85
|
|
|
86
|
+
<p align="center">
|
|
87
|
+
<img src="https://raw.githubusercontent.com/arifszn/seemore/main/packages/site/assets/vscode-extension.png" alt="VS Code with a Markdown file open in the editor and the seemore panel rendering the same folder as a site beside it" width="640"/>
|
|
88
|
+
</p>
|
|
89
|
+
|
|
86
90
|
1. Open any Markdown file.
|
|
87
91
|
2. Click the **seemore** icon in the editor's title bar, or right-click a folder in the explorer and choose **Open Folder in seemore**.
|
|
88
92
|
3. The rendered site opens beside your editor, scoped to that file's folder.
|
|
@@ -228,30 +232,17 @@ Supports `.md` and `.mdx` both.
|
|
|
228
232
|
|
|
229
233
|
### Code blocks
|
|
230
234
|
|
|
231
|
-
|
|
235
|
+
Code is syntax-highlighted automatically — nothing to configure. Add a filename or line numbers by putting them after the language on the fence line:
|
|
232
236
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
| --- | --- |
|
|
237
|
-
| `title="server.ts"` | Filename bar above the block |
|
|
238
|
-
| `lineNumbers` | Numbers down the side; `lineNumbers=5` starts the count at 5 |
|
|
239
|
-
| `noCopy` | No copy button on this one block |
|
|
240
|
-
|
|
241
|
-
Comments mark individual lines and never reach the page:
|
|
242
|
-
|
|
243
|
-
| In the code | Effect |
|
|
244
|
-
| --- | --- |
|
|
245
|
-
| `// [!code highlight]` | Marks the line |
|
|
246
|
-
| `// [!code ++]`, `// [!code --]` | Diff lines: green with a `+`, red with a `-` |
|
|
247
|
-
| `// [!code focus]` | Blurs every other line until the pointer is over the block |
|
|
248
|
-
| `// [!code word:needle]` | Marks that word everywhere it appears in the block |
|
|
237
|
+
```ts title="server.ts" lineNumbers
|
|
238
|
+
const port = 4040;
|
|
239
|
+
```
|
|
249
240
|
|
|
250
|
-
|
|
241
|
+
You can also highlight a line, mark it as added/removed, or focus it, with a comment right in the code — `// [!code highlight]` and friends. See it all rendered live, with the full list of options, on the [Content page](https://arifszn.github.io/seemore/content#code-blocks).
|
|
251
242
|
|
|
252
243
|
### Components
|
|
253
244
|
|
|
254
|
-
|
|
245
|
+
`.mdx` files can use `<Callout>`, `<Card>`, `<Cards>`, `<CodeBlockTabs>`, `<Mermaid>`, `<D2>` and `<Pdf>` with no imports needed — plain `.md` files just keep the tag as text, so components need the `.mdx` extension. Full syntax for each is on the [Content page](https://arifszn.github.io/seemore/content).
|
|
255
246
|
|
|
256
247
|
Numbered headings — `## 1. Install it`, `## 2. Point it at a folder` — become a numbered sequence.
|
|
257
248
|
|
|
@@ -272,7 +263,6 @@ Pages are ordered by:
|
|
|
272
263
|
1. `meta.json` in the directory — an explicit list, with `...` standing in for anything you didn't name:
|
|
273
264
|
|
|
274
265
|
```json
|
|
275
|
-
// guide/meta.json
|
|
276
266
|
{ "pages": ["getting-started", "installation", "..."] }
|
|
277
267
|
```
|
|
278
268
|
|
package/dist/cli/index.js
CHANGED
|
@@ -327,6 +327,9 @@ function findConfigFile({ root, configPath }) {
|
|
|
327
327
|
}
|
|
328
328
|
return void 0;
|
|
329
329
|
}
|
|
330
|
+
function resolveConfigPath(options) {
|
|
331
|
+
return options.configPath === void 0 ? void 0 : resolveFrom(options.cwd, options.configPath);
|
|
332
|
+
}
|
|
330
333
|
function resolveFrom(root, path) {
|
|
331
334
|
return isAbsolute(path) ? path : resolve(root, path);
|
|
332
335
|
}
|
|
@@ -1644,7 +1647,7 @@ async function importOptional(specifier) {
|
|
|
1644
1647
|
// src/cli/build.ts
|
|
1645
1648
|
async function runBuild(options) {
|
|
1646
1649
|
const contentRoot = resolveContentRoot(options.cwd, options.dir);
|
|
1647
|
-
const loaded = await loadConfig({ root:
|
|
1650
|
+
const loaded = await loadConfig({ root: contentRoot, configPath: resolveConfigPath(options) });
|
|
1648
1651
|
const config = { ...loaded.config, base: options.base === void 0 ? loaded.config.base : normaliseBase(options.base) };
|
|
1649
1652
|
warnAboutMissingBase(config.base, loaded.file);
|
|
1650
1653
|
const ctx = createContext({ config, contentRoot });
|
|
@@ -1744,7 +1747,7 @@ init_paths();
|
|
|
1744
1747
|
var DEFAULT_PORT = 4040;
|
|
1745
1748
|
async function runDev(options) {
|
|
1746
1749
|
const contentRoot = resolveContentRoot(options.cwd, options.dir);
|
|
1747
|
-
const loaded = await loadConfig({ root:
|
|
1750
|
+
const loaded = await loadConfig({ root: contentRoot, configPath: resolveConfigPath(options) });
|
|
1748
1751
|
const config = {
|
|
1749
1752
|
...loaded.config,
|
|
1750
1753
|
base: options.base === void 0 ? loaded.config.base : normaliseBase(options.base)
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/node/paths.ts","../../src/cli/index.ts","../../src/cli/build.ts","../../src/node/config/load.ts","../../src/shared/base.ts","../../src/shared/types.ts","../../src/node/config/features.ts","../../src/node/config/schema.ts","../../src/node/content/links.ts","../../src/node/content/slug.ts","../../src/node/content/source.ts","../../src/node/content/scan.ts","../../src/node/content/frontmatter.ts","../../src/node/report.ts","../../src/node/context.ts","../../src/node/prerender/emit.ts","../../src/node/prerender/deploy.ts","../../src/node/prerender/render.ts","../../src/node/vite/config.ts","../../src/node/vite/mdx.ts","../../src/node/vite/remark.ts","../../src/node/vite/positions.ts","../../src/node/vite/plugin.ts","../../src/node/search/build.ts","../../src/node/content/edit.ts","../../src/node/vite/watcher.ts","../../src/node/social/cards.ts","../../src/shared/og.ts","../../src/cli/dev.ts"],"sourcesContent":["import { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { createHash } from 'node:crypto';\nimport { tmpdir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * The installed seemore package directory.\n *\n * Works from the bundled CLI (`dist/cli/index.js`) and from the sources during tests, which\n * is why it walks for `package.json` rather than assuming a depth.\n */\nexport function packageRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url));\n for (let depth = 0; depth < 10; depth++) {\n if (existsSync(join(dir, 'package.json'))) return dir;\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error('seemore: could not locate its own package root.');\n}\n\n/** The browser layer, which ships as source and is compiled in-process. */\nexport function appRoot(): string {\n return join(packageRoot(), 'src', 'app');\n}\n\n/**\n * Walks up from a resolved file to the `package.json` that names it.\n *\n * For a dependency subpath its own `exports` map doesn't list — `dist/browser/index.js`\n * inside `@terrastruct/d2`, say — there's no portable `require.resolve` for it; only the\n * package's declared entry point is guaranteed reachable. This finds the package's own\n * directory from that entry point, so a caller can build the rest of the path itself.\n */\nexport function packageDirOf(name: string, fromFile: string): string {\n let dir = dirname(fromFile);\n for (let depth = 0; depth < 10; depth++) {\n const manifest = join(dir, 'package.json');\n if (existsSync(manifest) && (JSON.parse(readFileSync(manifest, 'utf8')) as { name?: string }).name === name) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(`seemore: could not locate the \"${name}\" package directory.`);\n}\n\n/**\n * Vite's caches go to the OS temp directory, keyed by content root.\n *\n * Dev writes nothing into the user's folder, and that has to include the\n * dependency-optimiser cache Vite would otherwise put in `node_modules/.vite`.\n */\nexport function cacheDir(contentRoot: string): string {\n const key = createHash('sha256').update(resolve(contentRoot)).digest('hex').slice(0, 12);\n return join(tmpdir(), 'seemore', key);\n}\n\n/**\n * `seemore [dir]`, else the folder the command runs in. Nothing is probed: which Markdown\n * becomes the site is decided by where the user stands, never by what happens to exist.\n *\n * The result is canonicalised through the filesystem. Every module id seemore derives from\n * the root — import specifiers, watcher lookups — must use the real spelling, because Vite\n * refuses to *load* a path containing a Windows 8.3 short-name segment (`RUNNER~1`) no\n * matter what the fs allow list says. Real users hit this too: `C:\\Users\\<long name>\\`\n * carries a short alias on any drive with 8.3 names enabled.\n */\nexport function resolveContentRoot(cwd: string, explicit?: string): string {\n return explicit !== undefined ? canonicalise(resolve(cwd, explicit)) : canonicalise(cwd);\n}\n\n/**\n * Resolve a path through the filesystem to its real spelling — the same treatment\n * {@link resolveContentRoot} gives the content root, needed anywhere else a path arriving\n * from outside seemore (an editor's `document.uri.fsPath`, say) has to be compared against\n * one of its own, which are already canonicalised. A symlinked ancestor (`/tmp` on macOS)\n * or a Windows 8.3 short name would otherwise make the same file compare unequal to itself.\n */\nexport function canonicalise(dir: string): string {\n try {\n return realpathSync.native(dir);\n } catch {\n // Does not exist, or not readable: keep the literal spelling rather than throw.\n return dir;\n }\n}\n","#!/usr/bin/env node\nimport { parseArgs } from 'node:util';\nimport pc from 'picocolors';\nimport { runBuild } from './build.js';\nimport { runDev } from './dev.js';\n\nconst USAGE = `\n${pc.bold('seemore')} — turn a folder of Markdown into a docs site\n\n seemore [dir] start the dev server\n seemore build [dir] build a static site into dist/\n\nOptions\n --port <number> dev server port (default 4040)\n --host [host] expose the dev server on the network\n --open / --no-open open a browser on start (default: no)\n --json print one machine-readable JSON line instead of the summary (dev only)\n --config <path> path to seemore.config.ts\n --out <dir> build output directory (default: dist)\n --base <path> subpath the site is served from, e.g. /my-repo/\n -h, --help show this message\n -v, --version show the version\n`;\n\n/**\n * `parseArgs` has no notion of an optional value, so a bare `--host` — the documented form,\n * and the one Vite uses for \"listen on every interface\" — is rewritten to `--host=` first.\n */\nfunction normaliseHostFlag(argv: string[]): string[] {\n const index = argv.indexOf('--host');\n if (index === -1) return argv;\n const next = argv[index + 1];\n if (next !== undefined && !next.startsWith('-')) return argv;\n return [...argv.slice(0, index), '--host=', ...argv.slice(index + 1)];\n}\n\nexport async function main(argv: string[] = process.argv.slice(2)): Promise<void> {\n const { values, positionals } = parseArgs({\n args: normaliseHostFlag(argv),\n allowPositionals: true,\n options: {\n port: { type: 'string' },\n host: { type: 'string' },\n open: { type: 'boolean' },\n 'no-open': { type: 'boolean' },\n json: { type: 'boolean' },\n config: { type: 'string' },\n out: { type: 'string' },\n base: { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n version: { type: 'boolean', short: 'v' },\n },\n });\n\n if (values.help === true) {\n console.log(USAGE);\n return;\n }\n\n if (values.version === true) {\n const { readFileSync } = await import('node:fs');\n const { join } = await import('node:path');\n const { packageRoot } = await import('../node/paths.js');\n const pkg = JSON.parse(readFileSync(join(packageRoot(), 'package.json'), 'utf8')) as { version: string };\n console.log(pkg.version);\n return;\n }\n\n const [command, ...rest] = positionals;\n const isBuild = command === 'build';\n const dir = isBuild ? rest[0] : command;\n\n const shared = { cwd: process.cwd(), dir, configPath: values.config, base: values.base };\n\n if (isBuild) {\n await runBuild({ ...shared, outDir: values.out });\n return;\n }\n\n await runDev({\n ...shared,\n port: values.port === undefined ? undefined : Number(values.port),\n host: values.host === undefined ? undefined : values.host === '' ? true : values.host,\n open: values.open === true && values['no-open'] !== true,\n json: values.json === true,\n });\n}\n\nmain().catch((error: unknown) => {\n console.error(`\\n${pc.red('seemore')} ${error instanceof Error ? error.message : String(error)}\\n`);\n process.exitCode = 1;\n});\n","import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { tmpdir } from 'node:os';\nimport { isAbsolute, join, relative, resolve } from 'node:path';\nimport pc from 'picocolors';\nimport { build as viteBuild } from 'vite';\nimport { loadConfig } from '../node/config/load.js';\nimport { createContext, type SeemoreContext } from '../node/context.js';\nimport { normaliseBase } from '../shared/base.js';\nimport { resolveContentRoot } from '../node/paths.js';\nimport { applyTemplate, outputPathFor, writeHtml } from '../node/prerender/emit.js';\nimport { writeDeployArtifacts } from '../node/prerender/deploy.js';\nimport { loadPrerenderModule } from '../node/prerender/render.js';\nimport { buildSearchIndex, formatBytes, measureIndex } from '../node/search/build.js';\nimport { generateSocialCards } from '../node/social/cards.js';\nimport { createViteConfig } from '../node/vite/config.js';\n\nexport interface BuildOptions {\n cwd: string;\n dir?: string;\n configPath?: string;\n outDir?: string;\n base?: string;\n}\n\nexport async function runBuild(options: BuildOptions): Promise<{ outDir: string; routes: number }> {\n const contentRoot = resolveContentRoot(options.cwd, options.dir);\n const loaded = await loadConfig({ root: options.cwd, configPath: options.configPath });\n\n const config = { ...loaded.config, base: options.base === undefined ? loaded.config.base : normaliseBase(options.base) };\n warnAboutMissingBase(config.base, loaded.file);\n\n const ctx = createContext({ config, contentRoot });\n const outDir = resolve(options.cwd, options.outDir ?? 'dist');\n assertSafeOutDir(outDir, options.cwd, contentRoot);\n\n const scan = ctx.source.current();\n failOnErrors(ctx.errors(), contentRoot);\n if (scan.pages.length === 0) {\n throw new Error(`No Markdown files found under ${contentRoot}. Point seemore at a folder that has some, or check \\`exclude\\`.`);\n }\n for (const warning of scan.warnings) ctx.warnings.add(warning);\n\n console.log(pc.dim(`seemore ${scan.pages.length} pages from ${relative(options.cwd, contentRoot) || '.'}`));\n\n // 1. The client bundle, which also produces the HTML template every page is injected into.\n await viteBuild(createViteConfig({ ctx, mode: 'build', outDir }));\n const template = readFileSync(join(outDir, 'index.html'), 'utf8');\n\n // 2. The same module graph, evaluated in node.\n const ssrOutDir = mkdtempSync(join(tmpdir(), 'seemore-ssr-'));\n try {\n const prerender = await loadPrerenderModule(ctx, ssrOutDir);\n const urls = prerender.listRoutes();\n // When no page claims `/`, the router generates an index page there — the same component\n // the dev server renders — so the client build's empty shell never ships as the home page.\n const routes = urls.includes('/') ? urls : ['/', ...urls];\n if (routes.length > urls.length) {\n console.log(pc.dim('seemore no index page; generated one listing every page at /'));\n }\n\n for (const url of routes) {\n writeHtml(outDir, outputPathFor(url), applyTemplate(template, await prerender.render(url)));\n }\n\n // 3. The shell an unknown address falls back to, which is also Surge's `200.html`.\n const notFound = applyTemplate(template, await prerender.render('/__seemore_not_found'));\n writeHtml(outDir, '404.html', notFound);\n writeDeployArtifacts(outDir, config.base, notFound);\n\n // 4. The search index, at the same path the dev middleware serves.\n if (config.search.provider === 'static') {\n const index = await buildSearchIndex(ctx);\n mkdirSync(join(outDir, 'api'), { recursive: true });\n writeFileSync(join(outDir, 'api', 'search.json'), index, 'utf8');\n\n const size = measureIndex(index);\n console.log(pc.dim(`seemore search index ${formatBytes(size.gzipped)} gzipped`));\n if (size.warning !== undefined) ctx.warnings.add(size.warning);\n }\n\n if (config.search.provider !== 'static') await warnIfSearchSdkMissing(ctx, config.search.provider);\n\n if (config.features['social.cards']) await generateSocialCards(ctx, outDir);\n\n ctx.warnings.flush();\n console.log(pc.green(`seemore ${routes.length} pages written to ${relative(options.cwd, outDir) || outDir}`));\n\n return { outDir, routes: routes.length };\n } finally {\n rmSync(ssrOutDir, { recursive: true, force: true });\n }\n}\n\n/**\n * The build empties `outDir` before writing, and `outDir` is always outside the Vite root —\n * seemore's root is its own package — so Vite's own guard against that never fires. A typo\n * like `--out .` would delete the project, so it is refused here instead.\n */\nfunction assertSafeOutDir(outDir: string, cwd: string, contentRoot: string): void {\n const contains = (parent: string, child: string): boolean => {\n const rel = relative(parent, child);\n return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));\n };\n\n for (const [name, dir] of [\n ['the current directory', cwd],\n ['the content directory', contentRoot],\n ] as const) {\n if (contains(outDir, dir)) {\n throw new Error(\n `Refusing to build into ${outDir}: it is, or contains, ${name}, and the build empties its output directory first. Pass --out with a directory of its own.`,\n );\n }\n }\n}\n\n/**\n * The hosted search providers need an SDK that seemore does not depend on. Finding out in the\n * browser means an empty search box; finding out here means a line in the build log.\n */\nasync function warnIfSearchSdkMissing(ctx: SeemoreContext, provider: 'algolia' | 'orama-cloud'): Promise<void> {\n const packageName = provider === 'algolia' ? 'algoliasearch' : '@orama/core';\n try {\n createRequire(join(ctx.config.root, 'noop.js')).resolve(packageName);\n } catch {\n ctx.warnings.add(\n `\\`search.provider\\` is '${provider}', which needs ${packageName}. Run \\`npm install ${packageName}\\` or search will find nothing.`,\n );\n }\n}\n\n/** Failing conditions produce a silently wrong site; warnings produce a visibly wrong page. */\nfunction failOnErrors(errors: string[], contentRoot: string): void {\n if (errors.length === 0) return;\n throw new Error(`seemore found ${errors.length} problem(s) in ${contentRoot}:\\n\\n${errors.join('\\n\\n')}`);\n}\n\n/**\n * `base` is never inferred. Under CI, where getting it wrong ships a broken site,\n * say so — with the exact line to add.\n */\nfunction warnAboutMissingBase(base: string, configFile: string | undefined): void {\n if (base !== '/' || process.env.GITHUB_ACTIONS !== 'true') return;\n const repo = process.env.GITHUB_REPOSITORY?.split('/')[1];\n console.warn(\n pc.yellow(\n `seemore \\`base\\` is not set, and GitHub Pages serves project sites from a subpath.\\n` +\n ` Add this to ${configFile ?? 'seemore.config.ts'}:\\n\\n` +\n ` base: '/${repo ?? 'your-repo'}/',\\n\\n` +\n ` Or pass --base '/${repo ?? 'your-repo'}/'. Ignore this if you deploy to a domain root.`,\n ),\n );\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { createJiti } from 'jiti';\nimport { z } from 'zod';\nimport { normaliseBase } from '../base.js';\nimport { resolveFeatures, type FeatureFlag } from './features.js';\nimport { configSchema, THEMES, type SeemoreConfig, type ResolvedSeemoreConfig, type SearchConfig } from './schema.js';\n\nconst CONFIG_NAMES = ['seemore.config.ts', 'seemore.config.mts', 'seemore.config.js', 'seemore.config.mjs'];\n\nexport interface LoadConfigOptions {\n /** Directory to look in, and the base for relative paths inside the config. */\n root: string;\n /** `--config`; when given, a missing file is an error rather than a fallback to defaults. */\n configPath?: string;\n}\n\n/** Turn a validated config into the fully-resolved shape the rest of seemore consumes. */\nexport function resolveConfig(\n input: SeemoreConfig,\n options: { root: string; configFile?: string },\n): ResolvedSeemoreConfig {\n const parsed = parseOrThrow(input, options.configFile);\n\n const search: SearchConfig = parsed.search === 'static' ? { provider: 'static' } : (parsed.search as SearchConfig);\n\n const features = resolveFeatures(parsed.features as FeatureFlag[], {\n // Nothing to link to without an edit base, so the flag follows the option.\n 'content.action.edit': parsed.editLink !== undefined,\n });\n\n return {\n // Only reached without a config file (see parseOrThrow): 'Docs' is the best name we can know.\n title: parsed.title ?? 'Docs',\n description: parsed.description,\n favicon: parsed.favicon,\n base: normaliseBase(parsed.base),\n theme: parsed.theme,\n css: parsed.css === undefined ? undefined : resolveFrom(options.root, parsed.css),\n features,\n nav: parsed.nav,\n footer: parsed.footer,\n editLink: parsed.editLink,\n search,\n exclude: parsed.exclude,\n root: options.root,\n configFile: options.configFile,\n };\n}\n\nexport interface LoadedConfig {\n config: ResolvedSeemoreConfig;\n /** Absolute path of the config file that was used, if any. */\n file?: string;\n}\n\n/**\n * Load `seemore.config.ts` with jiti. Not Vite's `ssrLoadModule`: the config\n * decides `base`, `base` configures Vite, and Vite would have to already exist to load it.\n */\nexport async function loadConfig(options: LoadConfigOptions): Promise<LoadedConfig> {\n const file = findConfigFile(options);\n\n if (file === undefined) {\n return { config: resolveConfig({}, { root: options.root }) };\n }\n\n const jiti = createJiti(import.meta.url, { moduleCache: false, fsCache: false });\n let loaded: unknown;\n try {\n loaded = await jiti.import(file, { default: true });\n } catch (error) {\n throw new Error(`Failed to load ${file}:\\n${error instanceof Error ? error.message : String(error)}`, {\n cause: error,\n });\n }\n\n if (loaded === null || typeof loaded !== 'object') {\n throw new Error(`${file} must export a config object as its default export, got ${typeof loaded}.`);\n }\n\n return {\n config: resolveConfig(loaded as SeemoreConfig, { root: dirname(file), configFile: file }),\n file,\n };\n}\n\nfunction findConfigFile({ root, configPath }: LoadConfigOptions): string | undefined {\n if (configPath !== undefined) {\n const absolute = resolveFrom(root, configPath);\n if (!existsSync(absolute)) {\n throw new Error(`Config file not found: ${absolute}`);\n }\n return absolute;\n }\n\n for (const name of CONFIG_NAMES) {\n const candidate = resolve(root, name);\n if (existsSync(candidate)) return candidate;\n }\n return undefined;\n}\n\nfunction resolveFrom(root: string, path: string): string {\n return isAbsolute(path) ? path : resolve(root, path);\n}\n\nfunction parseOrThrow(input: SeemoreConfig, file: string | undefined): z.output<typeof configSchema> {\n const result = configSchema.safeParse(input);\n if (result.success) {\n // A written config is an intentional site, so it must name itself; the no-config\n // quickstart is a preview, and falls back to 'Docs' instead.\n if (file !== undefined && result.data.title === undefined) {\n throw new Error(\n `Invalid ${file}:\\n` +\n ` - title: required when a config file exists — it names the site in the header, tab, and social cards. Add: title: 'My Site'`,\n );\n }\n return result.data;\n }\n\n const where = file === undefined ? 'seemore config' : file;\n const issues = result.error.issues.map((issue) => {\n const field = issue.path.length === 0 ? '(root)' : issue.path.join('.');\n return ` - ${field}: ${explain(issue)}`;\n });\n throw new Error(`Invalid ${where}:\\n${issues.join('\\n')}`);\n}\n\nfunction explain(issue: z.core.$ZodIssue): string {\n // zod's default message for a large enum truncates badly; the valid set is the useful part.\n if (issue.code === 'invalid_value' && issue.path.join('.') === 'theme') {\n return `unknown theme. Valid themes: ${THEMES.join(', ')}.`;\n }\n return issue.message;\n}\n","/**\n * Base-path handling.\n *\n * Internally a base is always normalised to leading + trailing slash (`/sub/`), because a\n * single canonical shape is what makes the \"no absolute-root URL leaks\" test possible. The\n * trailing slash is stripped again only at the point of output.\n */\n\nconst EXTERNAL = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\n\n/** `undefined` | `sub` | `/sub` | `/sub/` → `/sub/`. The root base is `/`. */\nexport function normaliseBase(base: string | undefined): string {\n if (base === undefined || base === '') return '/';\n if (EXTERNAL.test(base)) {\n throw new Error(\n `Invalid \\`base\\`: ${JSON.stringify(base)}. \\`base\\` is a path on the host, not a URL — use \"/${base.replace(/^.*?:\\/\\/[^/]*/, '').replace(/^\\/+/, '')}\".`,\n );\n }\n const trimmed = base.replace(/^\\/+/, '').replace(/\\/+$/, '');\n return trimmed === '' ? '/' : `/${trimmed}/`;\n}\n\n/** True for hrefs that a base must never touch: external, protocol-relative, hash, or relative. */\nexport function isExternalHref(href: string): boolean {\n return EXTERNAL.test(href) || href.startsWith('#') || !href.startsWith('/');\n}\n\n/** Prefix a root-relative path with the base. Idempotent; leaves external hrefs alone. */\nexport function withBase(base: string, href: string): string {\n const b = normaliseBase(base);\n if (b === '/' || isExternalHref(href)) return href;\n if (href === '/') return b;\n if (href === b.slice(0, -1) || href.startsWith(b)) return href;\n return b + href.replace(/^\\/+/, '');\n}\n\n/** Inverse of {@link withBase}: turn a browser pathname back into an internal route URL. */\nexport function stripBase(base: string, pathname: string): string {\n const b = normaliseBase(base);\n if (b === '/') return pathname;\n if (pathname === b || pathname === b.slice(0, -1)) return '/';\n if (!pathname.startsWith(b)) return pathname;\n return `/${pathname.slice(b.length)}`;\n}\n\n/** The form React Router wants for `basename`: leading slash, no trailing slash, `/` at root. */\nexport function toBasename(base: string): string {\n const b = normaliseBase(base);\n return b === '/' ? '/' : b.slice(0, -1);\n}\n\n/**\n * Browser pathnames are percent-encoded; route URLs are not.\n *\n * `/guía/página-uno` arrives from `location.pathname` as `/gu%C3%ADa/p%C3%A1gina-uno`, and a\n * lookup against the route map misses — so a correctly prerendered page hydrates into \"Page\n * not found\". `decodeURI`, not `decodeURIComponent`: a literal `%2F` in a filename must stay\n * encoded or it would split into two path segments.\n */\nexport function decodePath(pathname: string): string {\n try {\n return decodeURI(pathname);\n } catch {\n // Malformed escapes are the browser's problem, not ours; match on what we were given.\n return pathname;\n }\n}\n","import type { ComponentType, ReactNode } from 'react';\n\n/**\n * Types shared by the node pipeline and the browser app. This file ships as source, next to\n * `src/app`, so both halves agree on the shape of the virtual modules.\n */\n\nexport const FEATURES = [\n 'navigation.instant.prefetch',\n 'navigation.instant.preview',\n 'navigation.footer',\n 'navigation.top',\n 'navigation.path',\n 'navigation.sections',\n 'navigation.prune',\n 'toc.follow',\n 'toc.integrate',\n 'content.code.copy',\n 'content.action.edit',\n 'content.edit',\n 'content.image.zoom',\n 'search.suggest',\n 'search.highlight',\n 'social.cards',\n] as const;\n\nexport type Feature = (typeof FEATURES)[number];\n/** What a user may write in `features`: a flag, or `!flag` to switch a default-on flag off. */\nexport type FeatureFlag = Feature | `!${Feature}`;\nexport type ResolvedFeatures = Record<Feature, boolean>;\n\nexport interface NavItem {\n text: string;\n link?: string;\n items?: NavItem[];\n}\n\nexport type ClientSearchConfig =\n | { provider: 'static'; from: string }\n | { provider: 'orama-cloud'; endpoint: string; apiKey: string }\n | { provider: 'algolia'; appId: string; apiKey: string; indexName: string };\n\n/** The payload of `virtual:seemore/config`. */\nexport interface ClientConfig {\n title: string;\n description?: string;\n base: string;\n theme: string;\n features: ResolvedFeatures;\n nav?: NavItem[];\n footer?: { text?: string; links?: { text: string; link: string }[] };\n editLink?: { base: string; text: string };\n favicon?: string;\n search: ClientSearchConfig;\n contentRoot: string;\n}\n\n/** One entry of `virtual:seemore/routes`. */\nexport interface RouteEntry {\n url: string;\n /** Virtual path relative to the content root — what an edit link points at. */\n file: string;\n absPath: string;\n title: string;\n description: string | null;\n /** Content hash; a new value means `load()` now resolves to a different module. */\n version: string;\n load: () => Promise<PageModule>;\n}\n\nexport interface TocEntry {\n title: ReactNode;\n url: string;\n depth: number;\n}\n\nexport interface PageModule {\n default: ComponentType<{ components?: Record<string, unknown> }>;\n /** Exported by fumadocs' `rehype-toc`. */\n toc?: TocEntry[];\n}\n","import type { Feature, FeatureFlag, ResolvedFeatures } from '../../shared/types.js';\n\n/**\n * Feature flags.\n *\n * MkDocs Material's model — one flat list of dotted strings — but typed as a union, which\n * their YAML cannot do. Because seemore has default-on features where MkDocs has none, the\n * list is additive over the defaults and a `!` prefix turns a default-on feature off.\n */\n\nexport { FEATURES } from '../../shared/types.js';\nexport type { Feature, FeatureFlag, ResolvedFeatures } from '../../shared/types.js';\n\nexport const FEATURE_DEFAULTS: Record<Feature, boolean> = {\n 'navigation.instant.prefetch': true,\n 'navigation.instant.preview': false,\n 'navigation.footer': true,\n 'navigation.top': true,\n 'navigation.path': false,\n 'navigation.sections': false,\n 'navigation.prune': false,\n 'toc.follow': true,\n 'toc.integrate': false,\n 'content.code.copy': true,\n // Implicitly on when `editLink` is configured; there is nothing to link to otherwise.\n 'content.action.edit': false,\n // On by default, but only ever active in dev: the stamping that makes a block editable is\n // not emitted by `seemore build`, and the endpoint that writes is registered only by the\n // dev server. Switch it off with '!content.edit'.\n 'content.edit': true,\n 'content.image.zoom': true,\n 'search.suggest': true,\n 'search.highlight': true,\n 'social.cards': false,\n};\n\nexport function isFeatureEnabled(features: ResolvedFeatures, feature: Feature): boolean {\n return features[feature];\n}\n\n/**\n * Rules the flag set must satisfy. MkDocs reports its equivalents in prose and lets the\n * site build wrong; we fail in the config loader with the fix in the message.\n */\ntype Rule =\n | { kind: 'conflict'; a: Feature; b: Feature; why: string }\n | { kind: 'requires'; flag: Feature; needs: Feature; why: string };\n\nconst RULES: Rule[] = [\n {\n kind: 'conflict',\n a: 'toc.integrate',\n b: 'toc.follow',\n why: '`toc.integrate` merges the table of contents into the sidebar, leaving no separate TOC pane for `toc.follow` to scroll.',\n },\n {\n kind: 'requires',\n flag: 'navigation.instant.preview',\n needs: 'navigation.instant.prefetch',\n why: '`navigation.instant.preview` renders the target page in a popover, which is only possible once prefetch has loaded it.',\n },\n];\n\nexport function resolveFeatures(\n input: readonly FeatureFlag[],\n implicit: Partial<ResolvedFeatures> = {},\n): ResolvedFeatures {\n const resolved: ResolvedFeatures = { ...FEATURE_DEFAULTS, ...implicit };\n\n for (const flag of input) {\n const off = flag.startsWith('!');\n const name = (off ? flag.slice(1) : flag) as Feature;\n resolved[name] = !off;\n }\n\n const problems: string[] = [];\n for (const rule of RULES) {\n if (rule.kind === 'conflict') {\n if (!resolved[rule.a] || !resolved[rule.b]) continue;\n const fix = FEATURE_DEFAULTS[rule.b]\n ? `Add '!${rule.b}' to \\`features\\` to switch it off.`\n : `Remove '${rule.b}' from \\`features\\`.`;\n problems.push(`\\`${rule.a}\\` cannot be combined with \\`${rule.b}\\`. ${rule.why} ${fix}`);\n } else if (resolved[rule.flag] && !resolved[rule.needs]) {\n problems.push(\n `\\`${rule.flag}\\` requires \\`${rule.needs}\\`, which is switched off. ${rule.why}`,\n );\n }\n }\n\n if (problems.length > 0) {\n throw new Error(\n `Incompatible \\`features\\` in seemore config:\\n${problems.map((p) => ` - ${p}`).join('\\n')}`,\n );\n }\n\n return resolved;\n}\n","import { z } from 'zod';\nimport { FEATURES, type FeatureFlag, type ResolvedFeatures } from './features.js';\n\n/** The CSS presets fumadocs-ui ships. We do not invent a token system. */\nexport const THEMES = [\n 'neutral',\n 'black',\n 'catppuccin',\n 'dusk',\n 'ocean',\n 'purple',\n 'ruby',\n 'solar',\n 'aspen',\n 'emerald',\n 'vitepress',\n 'shadcn',\n] as const;\n\nexport type Theme = (typeof THEMES)[number];\n\nconst featureFlag = z.enum([...FEATURES, ...FEATURES.map((f) => `!${f}` as const)] as [string, ...string[]]);\n\nconst navItem: z.ZodType<NavItem> = z.lazy(() =>\n z.object({\n text: z.string(),\n link: z.string().optional(),\n items: z.array(navItem).optional(),\n }),\n);\n\nexport interface NavItem {\n text: string;\n link?: string;\n items?: NavItem[];\n}\n\nconst searchSchema = z.union([\n z.literal('static'),\n z.object({ provider: z.literal('static') }),\n z.object({\n provider: z.literal('orama-cloud'),\n endpoint: z.string(),\n apiKey: z.string(),\n }),\n z.object({\n provider: z.literal('algolia'),\n appId: z.string(),\n apiKey: z.string(),\n indexName: z.string(),\n }),\n]);\n\nexport const configSchema = z.object({\n /**\n * Optional here, but required whenever a config file exists — load.ts enforces that,\n * since it knows whether the config came from a file or from the no-config quickstart,\n * where the fallback is the only sensible name.\n */\n title: z.string().optional(),\n description: z.string().optional(),\n favicon: z.string().optional(),\n /** Subpath the site is served from, e.g. `/my-repo/`. Never inferred. */\n base: z.string().optional(),\n theme: z.enum(THEMES).default('neutral'),\n /** A CSS file appended after everything else, so it wins. */\n css: z.string().optional(),\n features: z.array(featureFlag).default([]),\n nav: z.array(navItem).optional(),\n footer: z\n .object({\n text: z.string().optional(),\n links: z.array(z.object({ text: z.string(), link: z.string() })).optional(),\n })\n .optional(),\n editLink: z\n .object({\n base: z.string(),\n text: z.string().default('Edit this page'),\n })\n .optional(),\n search: searchSchema.default('static'),\n exclude: z.array(z.string()).default([]),\n});\n\n/** What a user writes in `seemore.config.ts`. */\nexport type SeemoreConfig = Omit<z.input<typeof configSchema>, 'features' | 'theme' | 'search'> & {\n features?: FeatureFlag[];\n theme?: Theme;\n search?: z.input<typeof searchSchema>;\n};\n\nexport type SearchConfig =\n | { provider: 'static' }\n | { provider: 'orama-cloud'; endpoint: string; apiKey: string }\n | { provider: 'algolia'; appId: string; apiKey: string; indexName: string };\n\n/** What the rest of seemore consumes: every optional filled in, every path absolute. */\nexport interface ResolvedSeemoreConfig {\n title: string;\n description?: string;\n favicon?: string;\n /** Always normalised to leading + trailing slash. */\n base: string;\n theme: Theme;\n /** Absolute path, resolved against the config file's directory. */\n css?: string;\n features: ResolvedFeatures;\n nav?: NavItem[];\n footer?: { text?: string; links?: { text: string; link: string }[] };\n editLink?: { base: string; text: string };\n search: SearchConfig;\n exclude: string[];\n /** Directory the config was resolved from — relative paths in it hang off this. */\n root: string;\n /** Absolute path of the config file, when there is one. */\n configFile?: string;\n}\n","import { slug as slugify } from 'github-slugger';\nimport { isExternalHref, withBase } from '../base.js';\nimport type { ContentPage } from './scan.js';\nimport { slugifySegment, toPosix } from './slug.js';\n\nconst CONTENT_EXT = /\\.mdx?$/i;\n\nexport interface ResolvedLink {\n /** The href to emit. Unchanged from the input when nothing needed resolving. */\n href: string;\n warning?: string;\n}\n\nexport interface ResolvedWikilink {\n /** `undefined` when the target does not exist — render the label as plain text. */\n href?: string;\n label: string;\n warning?: string;\n}\n\nexport interface LinkResolver {\n /** Relative `.md`/`.mdx` links → routes. Everything else passes through untouched. */\n resolveHref(href: string, fromFile: string): ResolvedLink;\n /** The inside of a `[[…]]`, i.e. `Target`, `Target|label`, `Target#Heading`, or both. */\n resolveWikilink(target: string, fromFile: string): ResolvedWikilink;\n}\n\nexport function createLinkResolver(pages: readonly ContentPage[], base: string): LinkResolver {\n /** `guide/deep-dive` (extension stripped, original casing) → page. */\n const byPath = new Map<string, ContentPage>();\n /** Lowercased basename, and its slugified form → every page that answers to it. */\n const byName = new Map<string, ContentPage[]>();\n\n const add = (map: Map<string, ContentPage[]>, key: string, page: ContentPage) => {\n const bucket = map.get(key);\n if (bucket) bucket.push(page);\n else map.set(key, [page]);\n };\n\n for (const page of pages) {\n const withoutExt = page.file.replace(CONTENT_EXT, '');\n byPath.set(withoutExt.toLowerCase(), page);\n byPath.set(page.file.toLowerCase(), page);\n // A directory index answers to its directory, so `[[guide]]` finds `guide/index.md`.\n if (page.isIndex) {\n const dir = withoutExt.split('/').slice(0, -1).join('/');\n if (dir !== '') byPath.set(dir.toLowerCase(), page);\n }\n\n const basename = withoutExt.split('/').pop() ?? '';\n add(byName, basename.toLowerCase(), page);\n const slugged = slugifySegment(basename);\n if (slugged !== basename.toLowerCase()) add(byName, slugged, page);\n }\n\n /** Shallowest path first, then alphabetically — stable regardless of scan order. */\n const pick = (candidates: ContentPage[]): ContentPage =>\n [...candidates].sort((a, b) => {\n const depth = a.file.split('/').length - b.file.split('/').length;\n return depth !== 0 ? depth : a.file.localeCompare(b.file);\n })[0]!;\n\n function lookup(target: string): { page?: ContentPage; ambiguous?: ContentPage[] } {\n const cleaned = toPosix(target).replace(/^\\/+/, '').replace(CONTENT_EXT, '');\n const key = cleaned.toLowerCase();\n\n // 1. Exact path match relative to the content root.\n const exact = byPath.get(key);\n if (exact) return { page: exact };\n\n // 2 and 3. Basename match, then slugified basename match.\n const named = byName.get(key) ?? byName.get(slugifySegment(cleaned));\n if (named === undefined || named.length === 0) return {};\n if (named.length === 1) return { page: named[0]! };\n return { page: pick(named), ambiguous: named };\n }\n\n function href(page: ContentPage, hash: string | undefined): string {\n const url = withBase(base, page.url);\n return hash === undefined ? url : `${url}#${slugify(hash)}`;\n }\n\n return {\n resolveHref(raw, fromFile) {\n if (isExternalHref(raw) && !raw.startsWith('.') && !CONTENT_EXT.test(raw.split('#')[0] ?? '')) {\n return { href: raw };\n }\n const [pathPart = '', hashPart] = splitHash(raw);\n if (!CONTENT_EXT.test(pathPart)) return { href: raw };\n\n // A leading slash means \"from the content root\", so the linking file's directory is\n // not the starting point.\n const fromDir = pathPart.startsWith('/') ? [] : toPosix(fromFile).split('/').slice(0, -1);\n const resolved = joinPosix(fromDir, pathPart);\n const page = byPath.get(resolved.toLowerCase());\n\n if (page === undefined) {\n return {\n href: raw,\n warning: `Broken link ${raw} in ${toPosix(fromFile)}: no page at ${resolved}.`,\n };\n }\n return { href: href(page, hashPart) };\n },\n\n resolveWikilink(target, fromFile) {\n const pipe = target.indexOf('|');\n const linkPart = (pipe === -1 ? target : target.slice(0, pipe)).trim();\n const label = (pipe === -1 ? target : target.slice(pipe + 1)).trim();\n const [pathPart = '', hashPart] = splitHash(linkPart);\n\n const { page, ambiguous } = lookup(pathPart);\n if (page === undefined) {\n return {\n label,\n warning: `Dead wikilink [[${target}]] in ${toPosix(fromFile)}: no page matches \"${pathPart}\".`,\n };\n }\n\n const warning =\n ambiguous === undefined\n ? undefined\n : `Ambiguous wikilink [[${target}]] in ${toPosix(fromFile)}: matches ${ambiguous\n .map((c) => c.file)\n .sort()\n .join(', ')}. Using ${page.file}.`;\n\n return { href: href(page, hashPart), label, warning };\n },\n };\n}\n\nfunction splitHash(value: string): [string, string | undefined] {\n const index = value.indexOf('#');\n if (index === -1) return [value, undefined];\n return [value.slice(0, index), value.slice(index + 1)];\n}\n\n/** Resolve `./a`, `../a`, `a` against a directory, without touching the real filesystem. */\nfunction joinPosix(fromDir: readonly string[], relative: string): string {\n const segments = [...fromDir];\n for (const part of toPosix(relative).split('/')) {\n if (part === '' || part === '.') continue;\n if (part === '..') segments.pop();\n else segments.push(part);\n }\n return segments.join('/').replace(CONTENT_EXT, '');\n}\n","/**\n * Path → URL resolution.\n *\n * One slug algorithm, `github-slugger`, is used for URLs, heading anchors and the search\n * index alike — it is already a fumadocs dependency, so agreeing with it is free.\n */\nimport { slug as slugify } from 'github-slugger';\n\nconst INDEX_NAMES = new Set(['index', 'readme']);\nconst CONTENT_EXT = /\\.mdx?$/i;\n\nexport interface RouteInfo {\n /** Virtual path relative to the content root, posix separators. */\n file: string;\n /** Route URL: leading slash, never a trailing slash. The site root is `/`. */\n url: string;\n /** Slug segments; the site root is the empty array. */\n slugs: string[];\n /** Path of the emitted HTML relative to `dist/`. */\n output: string;\n /** Whether this file stands for its directory rather than for itself. */\n isIndex: boolean;\n}\n\n/** Normalise a possibly-Windows path to a posix virtual path. */\nexport function toPosix(file: string): string {\n return file.replace(/\\\\/g, '/').replace(/^\\.\\//, '').replace(/^\\/+/, '');\n}\n\n/**\n * Slugify a single path segment. Segments that slugify to nothing (`...`, emoji-only) fall\n * back to a lowercased, punctuation-stripped form so that a URL is never empty.\n */\nexport function slugifySegment(segment: string): string {\n const slugged = slugify(segment);\n if (slugged !== '') return slugged;\n const fallback = segment.toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, '-').replace(/^-+|-+$/g, '');\n return fallback === '' ? 'untitled' : fallback;\n}\n\nexport function toRoute(file: string): RouteInfo {\n const posix = toPosix(file);\n const segments = posix.split('/');\n const basename = segments.pop() ?? '';\n const stem = basename.replace(CONTENT_EXT, '');\n const isIndex = INDEX_NAMES.has(stem.toLowerCase());\n\n const slugs = segments.map(slugifySegment);\n if (!isIndex) slugs.push(slugifySegment(stem));\n\n return {\n file: posix,\n url: slugs.length === 0 ? '/' : `/${slugs.join('/')}`,\n slugs,\n output: [...slugs, 'index.html'].join('/'),\n isIndex,\n };\n}\n\nexport interface ResolvedRoutes {\n routes: RouteInfo[];\n /** Conditions that make the site silently wrong — a build error. */\n errors: string[];\n /** Conditions that are visible on the page itself — a warning. */\n warnings: string[];\n}\n\n/**\n * Resolve a whole corpus at once, because the interesting failures are corpus-level:\n * `index.md` vs `README.md` in one directory, and two different files slugifying alike.\n */\nexport function resolveRoutes(files: string[]): ResolvedRoutes {\n const sorted = [...files].map(toPosix).sort();\n const byUrl = new Map<string, RouteInfo[]>();\n const warnings: string[] = [];\n const errors: string[] = [];\n\n for (const file of sorted) {\n const route = toRoute(file);\n const bucket = byUrl.get(route.url);\n if (bucket) bucket.push(route);\n else byUrl.set(route.url, [route]);\n }\n\n const routes: RouteInfo[] = [];\n for (const [url, candidates] of [...byUrl.entries()].sort(([a], [b]) => (a < b ? -1 : 1))) {\n if (candidates.length === 1) {\n routes.push(candidates[0]!);\n continue;\n }\n\n // `index.md` beating `README.md` is a documented preference, not a collision.\n const indexes = candidates.filter((c) => c.isIndex);\n if (indexes.length === candidates.length) {\n const winner =\n indexes.find((c) => c.file.split('/').pop()?.toLowerCase().startsWith('index')) ?? indexes[0]!;\n const losers = indexes.filter((c) => c !== winner);\n warnings.push(\n `${url} has more than one index file: using ${winner.file}, ignoring ${losers\n .map((l) => l.file)\n .join(', ')}.`,\n );\n routes.push(winner);\n continue;\n }\n\n errors.push(\n `Duplicate route ${url} produced by ${candidates.length} files:\\n` +\n candidates.map((c) => ` - ${c.file}`).join('\\n') +\n `\\nRename one of them, or exclude it with \\`exclude\\` in seemore.config.ts.`,\n );\n }\n\n return { routes, errors, warnings };\n}\n","import { dynamicLoader } from 'fumadocs-core/source';\nimport type { Root } from 'fumadocs-core/page-tree';\nimport { scan, type ContentPage, type ScanOptions, type ScanResult } from './scan.js';\n\nexport interface SeemoreSource {\n /** The most recent scan. Never triggers filesystem work. */\n current(): ScanResult;\n /** Re-read the corpus and let fumadocs decide what changed. */\n refresh(): ScanResult;\n getPageTree(): Promise<Root>;\n /** Serialized for the browser — the payload of `virtual:seemore/tree`. */\n serializeTree(): Promise<unknown>;\n pages(): ContentPage[];\n loader: ReturnType<typeof dynamicLoader>;\n}\n\n/**\n * Wire the scanner to fumadocs' dynamic loader.\n *\n * `cache: 'custom'` puts us in charge of when a scan happens: the watcher calls\n * {@link SeemoreSource.refresh}, and fumadocs recomputes the page tree because the array\n * identity changed. Between refreshes `files()` hands back the same array, so reading the\n * tree is free.\n */\nexport function createSource(options: ScanOptions): SeemoreSource {\n let cached: ScanResult | undefined;\n\n const read = (): ScanResult => (cached ??= scan(options));\n\n const loader = dynamicLoader(\n {\n cache: 'custom',\n files: () => read().files,\n invalidate: () => {\n cached = undefined;\n },\n },\n { baseUrl: '/' },\n );\n\n return {\n loader,\n current: read,\n pages: () => read().pages,\n refresh() {\n loader.invalidate();\n return read();\n },\n async getPageTree() {\n const output = await loader.get();\n return output.getPageTree();\n },\n async serializeTree() {\n const output = await loader.get();\n return output.serializePageTree(output.getPageTree());\n },\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { createHash } from 'node:crypto';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { globSync } from 'tinyglobby';\nimport { z } from 'zod';\nimport type { VirtualFile } from 'fumadocs-core/source';\nimport { parseFrontmatter, type FrontmatterData } from './frontmatter.js';\nimport { resolveRoutes, toPosix, type RouteInfo } from './slug.js';\n\n/** Appended to, never replaced by, `config.exclude`. */\nexport const DEFAULT_EXCLUDES = [\n '**/node_modules/**',\n '**/.git/**',\n '**/dist/**',\n '**/build/**',\n '**/out/**',\n '**/vendor/**',\n '**/target/**',\n '**/venv/**',\n '**/deps/**',\n '**/Pods/**',\n '**/bower_components/**',\n '**/.seemore/**',\n '**/.*/**',\n '**/.*',\n];\n\n/** fumadocs' `meta.json` shape, validated so a typo reports a file rather than a blank folder. */\nconst metaSchema = z\n .object({\n title: z.string().optional(),\n icon: z.string().optional(),\n root: z.boolean().optional(),\n pages: z.array(z.string()).optional(),\n pagesIndex: z.string().optional(),\n defaultOpen: z.boolean().optional(),\n collapsible: z.boolean().optional(),\n description: z.string().optional(),\n })\n .loose();\n\nexport interface ContentPage extends RouteInfo {\n /** Absolute path on disk — what the generated import map imports. */\n absPath: string;\n /**\n * Hash of the file's text. Changes exactly when the module behind the URL does, which is\n * what lets the browser tell \"this page was edited\" from \"some other page was\".\n */\n version: string;\n data: FrontmatterData & { title: string };\n}\n\nexport interface ScanResult {\n /** What fumadocs' loader consumes. */\n files: VirtualFile[];\n /** What the router, prefetch map and prerender driver consume. */\n pages: ContentPage[];\n errors: string[];\n warnings: string[];\n}\n\nexport interface ScanOptions {\n contentRoot: string;\n exclude?: string[];\n /** Used as the title of a root index page that has no frontmatter title. */\n siteTitle?: string;\n /** Dev keeps drafts so they can be written; the build drops them. */\n includeDrafts?: boolean;\n}\n\nexport function scan(options: ScanOptions): ScanResult {\n const contentRoot = resolve(options.contentRoot);\n const ignore = [...DEFAULT_EXCLUDES, ...(options.exclude ?? [])];\n\n const contentFiles = globSync(['**/*.md', '**/*.mdx'], {\n cwd: contentRoot,\n ignore,\n dot: false,\n absolute: false,\n }).map(toPosix);\n\n const metaFiles = globSync(['**/meta.json'], { cwd: contentRoot, ignore, dot: false, absolute: false }).map(toPosix);\n\n const { routes, errors, warnings } = resolveRoutes(contentFiles);\n\n const pages: ContentPage[] = [];\n for (const route of routes) {\n const absPath = join(contentRoot, route.file);\n let data: FrontmatterData;\n let version: string;\n try {\n const text = readFileSync(absPath, 'utf8');\n data = parseFrontmatter(text, route.file).data;\n version = createHash('sha256').update(text).digest('hex').slice(0, 12);\n } catch (error) {\n errors.push(error instanceof Error ? error.message : String(error));\n continue;\n }\n\n if (data.draft === true && options.includeDrafts !== true) continue;\n\n pages.push({ ...route, absPath, version, data: { ...data, title: titleFor(route, data, options.siteTitle) } });\n }\n\n const files: VirtualFile[] = pages.map((page) => ({\n type: 'page',\n path: page.file,\n absolutePath: page.absPath,\n // Our slugs, not fumadocs' — one algorithm decides URLs, anchors and the index.\n slugs: page.slugs,\n data: page.data,\n }));\n\n const metaDirs = new Set<string>();\n for (const file of metaFiles) {\n const absPath = join(contentRoot, file);\n try {\n const parsed = metaSchema.safeParse(JSON.parse(readFileSync(absPath, 'utf8')));\n if (!parsed.success) {\n errors.push(\n `Invalid ${file}:\\n${parsed.error.issues.map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`).join('\\n')}`,\n );\n continue;\n }\n metaDirs.add(dirname(file));\n files.push({ type: 'meta', path: file, absolutePath: absPath, data: parsed.data });\n } catch (error) {\n errors.push(`Invalid ${file}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n files.push(...synthesiseOrderMeta(pages, metaDirs));\n\n return { files, pages, errors, warnings };\n}\n\n/**\n * Ordering: a real `meta.json` wins; otherwise frontmatter `order` decides, then\n * title. fumadocs has no native `order`, so we express the intent in the mechanism it does\n * have — a synthetic `meta.json` whose `pages` list ends in the `...` rest marker, leaving\n * anything we did not mention in fumadocs' own alphabetical order.\n */\nfunction synthesiseOrderMeta(pages: ContentPage[], metaDirs: Set<string>): VirtualFile[] {\n const byDir = new Map<string, ContentPage[]>();\n for (const page of pages) {\n const dir = dirname(page.file);\n const bucket = byDir.get(dir);\n if (bucket) bucket.push(page);\n else byDir.set(dir, [page]);\n }\n\n const out: VirtualFile[] = [];\n for (const [dir, dirPages] of byDir) {\n if (metaDirs.has(dir)) continue;\n // Nothing to express unless something wants to move: an explicit `order`, or an index\n // page that would otherwise sort alphabetically into the middle of its own directory.\n if (!dirPages.some((p) => typeof p.data.order === 'number' || p.isIndex)) continue;\n\n const ordered = [...dirPages].sort(compareForOrder).map((p) => basename(p.file).replace(/\\.mdx?$/i, ''));\n\n out.push({\n type: 'meta',\n path: dir === '.' ? 'meta.json' : `${dir}/meta.json`,\n data: { pages: [...ordered, '...'] },\n });\n }\n return out;\n}\n\nfunction compareForOrder(a: ContentPage, b: ContentPage): number {\n // An index page stands for its directory, so it leads unless it asks not to.\n const ao = orderOf(a);\n const bo = orderOf(b);\n if (ao !== bo) return ao - bo;\n return a.data.title.localeCompare(b.data.title);\n}\n\nfunction orderOf(page: ContentPage): number {\n if (typeof page.data.order === 'number') return page.data.order;\n return page.isIndex ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY;\n}\n\nfunction titleFor(route: RouteInfo, data: FrontmatterData, siteTitle: string | undefined): string {\n if (typeof data.title === 'string' && data.title !== '') return data.title;\n if (route.url === '/') return siteTitle ?? 'Home';\n return humanise(route.slugs[route.slugs.length - 1] ?? 'Untitled');\n}\n\n/** `getting-started` → `Getting Started`. Good enough to never show a raw slug in a sidebar. */\nfunction humanise(slug: string): string {\n return slug\n .split('-')\n .filter((word) => word !== '')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n","import matter from 'gray-matter';\nimport { z } from 'zod';\n\n/**\n * Frontmatter is validated, not restricted: unknown keys pass through so that a corpus\n * written for another tool still builds. Only the keys seemore acts on are typed.\n */\nexport const frontmatterSchema = z\n .object({\n title: z.string().optional(),\n description: z.string().optional(),\n icon: z.string().optional(),\n /** Sidebar ordering, second only to `meta.json`. */\n order: z.number().optional(),\n /**\n * Excluded from the build. Dev keeps drafts so they can be written, so a link to one\n * works while you write it and warns as a dead link when you build.\n */\n draft: z.boolean().optional(),\n })\n .loose();\n\nexport type FrontmatterData = z.output<typeof frontmatterSchema> & Record<string, unknown>;\n\n/** Split a source file into validated frontmatter and body. `file` is only for messages. */\nexport function parseFrontmatter(source: string, file: string): { data: FrontmatterData; content: string } {\n let parsed;\n try {\n parsed = matter(source);\n } catch (error) {\n throw new Error(\n `Invalid frontmatter in ${file}: ${error instanceof Error ? error.message.split('\\n')[0] : String(error)}`,\n { cause: error },\n );\n }\n\n return { data: validateFrontmatter(parsed.data, file), content: parsed.content };\n}\n\nexport function validateFrontmatter(data: unknown, file: string): FrontmatterData {\n const result = frontmatterSchema.safeParse(data ?? {});\n if (result.success) return result.data as FrontmatterData;\n\n const issues = result.error.issues.map((issue) => {\n const field = issue.path.length === 0 ? '(root)' : issue.path.join('.');\n return ` - ${field}: ${issue.message}`;\n });\n throw new Error(`Invalid frontmatter in ${file}:\\n${issues.join('\\n')}`);\n}\n","import pc from 'picocolors';\n\n/**\n * Warnings are collected and printed once, as a grouped summary, rather than interleaved\n * with progress output — a build that prints forty warnings between chunks is a\n * build whose warnings nobody reads.\n */\nexport interface WarningCollector {\n add(message: string): void;\n list(): string[];\n clear(): void;\n /** Print the grouped summary. Returns the number of warnings printed. */\n flush(log?: (line: string) => void): number;\n}\n\nexport function createWarningCollector(): WarningCollector {\n const seen = new Set<string>();\n\n return {\n add(message) {\n seen.add(message);\n },\n list: () => [...seen],\n clear: () => seen.clear(),\n flush(log = console.warn) {\n const messages = [...seen].sort();\n seen.clear();\n if (messages.length === 0) return 0;\n log('');\n log(pc.yellow(`${messages.length} warning${messages.length === 1 ? '' : 's'}:`));\n for (const message of messages) log(pc.yellow(` - ${message}`));\n log('');\n return messages.length;\n },\n };\n}\n","import { createLinkResolver, type LinkResolver } from './content/links.js';\nimport type { ContentPage, ScanResult } from './content/scan.js';\nimport { createSource, type SeemoreSource } from './content/source.js';\nimport type { ResolvedSeemoreConfig } from './config/schema.js';\nimport { createWarningCollector, type WarningCollector } from './report.js';\n\nexport interface SeemoreContext {\n config: ResolvedSeemoreConfig;\n /** Absolute path of the directory being documented. Usually outside the Vite root. */\n contentRoot: string;\n source: SeemoreSource;\n warnings: WarningCollector;\n pages(): ContentPage[];\n /** Rebuilt on every refresh, so remark plugins must read it late. */\n resolver(): LinkResolver;\n /** Re-read the corpus after a filesystem change. */\n refresh(): ScanResult;\n /** Slug collisions and frontmatter failures found by the most recent scan. */\n errors(): string[];\n}\n\nexport interface CreateContextOptions {\n config: ResolvedSeemoreConfig;\n contentRoot: string;\n /** Dev keeps drafts so they can be written; the build drops them. */\n includeDrafts?: boolean;\n}\n\nexport function createContext(options: CreateContextOptions): SeemoreContext {\n const { config, contentRoot } = options;\n\n const source = createSource({\n contentRoot,\n exclude: config.exclude,\n siteTitle: config.title,\n includeDrafts: options.includeDrafts,\n });\n\n let resolver = createLinkResolver(source.pages(), config.base);\n\n return {\n config,\n contentRoot,\n source,\n warnings: createWarningCollector(),\n pages: () => source.pages(),\n resolver: () => resolver,\n errors: () => source.current().errors,\n refresh() {\n const result = source.refresh();\n resolver = createLinkResolver(result.pages, config.base);\n return result;\n },\n };\n}\n","import { mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\n/** Turn a route URL into the file that serves it. */\nexport function outputPathFor(url: string): string {\n const clean = url.replace(/^\\/+|\\/+$/g, '');\n return clean === '' ? 'index.html' : join(clean, 'index.html');\n}\n\nexport function writeHtml(outDir: string, relativePath: string, html: string): void {\n const target = join(outDir, relativePath);\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, html, 'utf8');\n}\n\n/**\n * Inject a rendered page into the client build's `index.html`.\n *\n * The template already carries the hashed script and stylesheet Vite emitted, so the markup\n * and the assets can never drift apart.\n */\nexport function applyTemplate(template: string, { html, head }: { html: string; head: string }): string {\n // Replacer functions, not strings: a page containing `$&` or `` $` `` would otherwise\n // splice the marker — or the whole document head — into its own body.\n return template.replace('<!--seemore-head-->', () => head).replace('<!--seemore-app-->', () => html);\n}\n","import { writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Host conventions.\n *\n * The portable output is everything else: one real `index.html` per route, plus `404.html`,\n * which every static host honours. These files are additive — small, named conventions that\n * particular hosts look for — not a list of hosts seemore supports.\n */\nexport function writeDeployArtifacts(outDir: string, base: string, shell: string): void {\n const prefix = base === '/' ? '' : base.replace(/\\/+$/, '');\n\n // Netlify and Cloudflare Pages share this format. It applies after the real files they\n // already serve, so it only catches addresses that do not exist.\n writeFileSync(join(outDir, '_redirects'), `${prefix}/* ${prefix}/index.html 200\\n`, 'utf8');\n\n // Surge looks for `200.html` as its SPA fallback.\n writeFileSync(join(outDir, '200.html'), shell, 'utf8');\n\n // GitHub Pages runs the output through Jekyll unless this file exists, and Jekyll drops\n // every file and directory whose name starts with `_`. A `docs/_internal/` folder would\n // build correctly and then 404 once deployed — the exact failure seemore exists to prevent.\n writeFileSync(join(outDir, '.nojekyll'), '', 'utf8');\n}\n","import { pathToFileURL } from 'node:url';\nimport { join } from 'node:path';\nimport { build } from 'vite';\nimport type { SeemoreContext } from '../context.js';\nimport { createViteConfig } from '../vite/config.js';\n\nexport interface RenderResult {\n html: string;\n head: string;\n}\n\nexport interface PrerenderModule {\n render(url: string): Promise<RenderResult>;\n listRoutes(): string[];\n}\n\n/**\n * Build the prerender entry for node and load it.\n *\n * This is a second Vite build rather than a reuse of the client bundle because the client\n * bundle is compiled for the browser; the driver needs the same module graph evaluated in\n * node, with the same virtual modules, so the two can never describe different sites.\n */\nexport async function loadPrerenderModule(ctx: SeemoreContext, ssrOutDir: string): Promise<PrerenderModule> {\n await build(createViteConfig({ ctx, mode: 'build', ssrOutDir }));\n\n const entry = join(ssrOutDir, 'entry.prerender.js');\n const loaded = (await import(pathToFileURL(entry).href)) as Partial<PrerenderModule>;\n\n if (typeof loaded.render !== 'function' || typeof loaded.listRoutes !== 'function') {\n throw new Error(`seemore: the prerender build at ${entry} did not export \\`render\\` and \\`listRoutes\\`.`);\n }\n\n return { render: loaded.render, listRoutes: loaded.listRoutes };\n}\n","import { realpathSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { join } from 'node:path';\nimport type { InlineConfig, Plugin } from 'vite';\nimport react from '@vitejs/plugin-react';\nimport tailwindcss from '@tailwindcss/vite';\nimport mdx from '@mdx-js/rollup';\nimport type { SeemoreContext } from '../context.js';\nimport { appRoot, cacheDir, packageDirOf, packageRoot } from '../paths.js';\nimport { createRehypePlugins, createRemarkPlugins } from './mdx.js';\nimport { seemorePlugin } from './plugin.js';\nimport { seemoreWatcherPlugin } from './watcher.js';\n\nconst require_ = createRequire(import.meta.url);\n\n/**\n * `@terrastruct/d2`'s `exports` map only picks its browser bundle when a `browser`\n * condition is present. Dev's `worker`-only condition set below deliberately excludes it\n * (see the comment there), and even build's own defaults are one more custom `conditions`\n * tweak away from excluding it by accident again — so this resolves it directly rather than\n * leaning on whatever the shared condition set happens to be.\n */\nfunction d2BrowserEntry(): string {\n const entry = require_.resolve('@terrastruct/d2');\n return join(packageDirOf('@terrastruct/d2', entry), 'dist', 'browser', 'index.js');\n}\n\nexport interface ViteConfigOptions {\n ctx: SeemoreContext;\n mode: 'dev' | 'build';\n /** Absolute output directory. Ignored in dev. */\n outDir?: string;\n /** When set, build the prerender entry for node instead of the client bundle. */\n ssrOutDir?: string;\n}\n\nexport function createViteConfig({ ctx, mode, outDir, ssrOutDir }: ViteConfigOptions): InlineConfig {\n const root = appRoot();\n const isSsr = ssrOutDir !== undefined;\n\n const mdxOptions = {\n // `format` is inferred per file, so a plain `.md` never needs MDX syntax.\n remarkPlugins: createRemarkPlugins({\n contentRoot: ctx.contentRoot,\n getResolver: () => ctx.resolver(),\n onWarning: (message) => ctx.warnings.add(message),\n }),\n rehypePlugins: createRehypePlugins({ positions: mode === 'dev' && ctx.config.features['content.edit'] }),\n // MDX compiles its own JSX. Vite's builtin transform infers a file's language from its\n // extension and does not know `.md`/`.mdx`, so leaving JSX in the output would fail to\n // parse. Fast Refresh is unaffected: it is a separate transform, applied to these files\n // through the React plugin's `include` below, which is what turns a content edit into an\n // in-place component swap rather than a reload.\n jsx: false,\n };\n\n return {\n root,\n base: ctx.config.base,\n cacheDir: cacheDir(ctx.contentRoot),\n configFile: false,\n envDir: false,\n clearScreen: false,\n logLevel: mode === 'build' ? 'warn' : 'info',\n\n plugins: [\n // Order matters: MDX first, then React, so JSX from MDX is transformed and refreshed.\n { ...mdx(mdxOptions), enforce: 'pre' },\n react({ include: /\\.(?:mdx?|jsx?|tsx?)$/ }),\n // Before Tailwind: our plugin injects the theme preset into the root stylesheet, and\n // Tailwind must see the injected version.\n seemorePlugin({ ctx, serveSearch: mode === 'dev' }),\n tailwindcss(),\n ...(mode === 'dev' ? [seemoreWatcherPlugin(ctx)] : []),\n ],\n\n // Vite bundles workers with the browser export condition, but a worker has no `document`.\n // `decode-named-character-reference` — pulled in through fumadocs' search client, via\n // remark — calls `document.createElement` at module scope in its browser build, so the\n // search worker threw on load. The package ships a DOM-free `worker` entry; use it.\n worker: { plugins: () => [workerConditionPlugin()] },\n\n resolve: {\n // The app is compiled from seemore's own sources, so its dependencies must resolve\n // from seemore's directory rather than from the user's project.\n dedupe: ['react', 'react-dom', 'react-router', 'fumadocs-core', 'fumadocs-ui'],\n // Not needed for the SSR bundle: the dynamic `import('@terrastruct/d2')` inside `D2`'s\n // effect never actually runs there (effects don't run during prerendering), but Rollup\n // still bundles it as a reachable chunk, and Vite's own server conditions already point\n // that at the Node build — which is what actually running in Node would want anyway.\n alias: isSsr ? undefined : [{ find: '@terrastruct/d2', replacement: d2BrowserEntry() }],\n // In dev the module worker is served through the shared module graph and its fumadocs\n // chunk comes from the dep optimizer, where `worker.plugins` never runs — the browser\n // build of `decode-named-character-reference` is inlined into the prebundle and the\n // worker throws on load. Adding the package's own `worker` condition graph-wide flips\n // the whole dev graph (main thread included) to its DOM-free build, which behaves the\n // same; production doesn't need it — its worker chunk is a real Rollup build of its own,\n // where the targeted swap above runs. Leaving this unset in production keeps Vite's own\n // default conditions.\n conditions: mode === 'dev' ? ['worker'] : undefined,\n },\n\n server: {\n fs: {\n // The content root is normally *outside* the Vite root, and files outside `allow`\n // 404 silently — the single most likely cause of \"the watcher does nothing\".\n allow: withRealPaths([root, packageRoot(), ctx.contentRoot, ctx.config.root, process.cwd()]),\n },\n watch: {\n // Only real exclusions here. Vite merges these into chokidar's ignore *list*, where a\n // leading `!` is a negated matcher that matches everything it is not — so the obvious\n // `!<contentRoot>/**` \"re-include\" would silently ignore the entire project instead.\n // Content outside the Vite root is watched by seemore's own chokidar instance.\n ignored: ['**/node_modules/**', '**/.git/**'],\n },\n },\n\n build: isSsr\n ? {\n ssr: join(root, 'entry.prerender.tsx'),\n outDir: ssrOutDir,\n emptyOutDir: true,\n copyPublicDir: false,\n minify: false,\n rollupOptions: { output: { entryFileNames: 'entry.prerender.js' } },\n }\n : {\n outDir,\n emptyOutDir: true,\n rollupOptions: { input: join(root, 'index.html') },\n // The app bundle is seemore's own, not the user's; warning them about a size they\n // cannot act on is noise.\n chunkSizeWarningLimit: 2_000,\n },\n\n // The prerender bundle is written to a scratch directory outside any `node_modules`, so\n // it has to be self-contained: an externalised `react` there resolves against the scratch\n // directory and is simply not found.\n ssr: isSsr ? { noExternal: true } : undefined,\n };\n}\n\n/**\n * Every path, plus where it actually points.\n *\n * Vite resolves a module to its real path before checking `fs.allow`, so a content root\n * reached through a symlink — `/var` on macOS, or anything under a linked directory — is\n * denied unless both spellings are listed. The failure is a silent 404, so it is worth the\n * two extra entries.\n */\nfunction withRealPaths(paths: string[]): string[] {\n const out = new Set<string>();\n for (const path of paths) {\n out.add(path);\n try {\n out.add(realpathSync.native(path));\n } catch {\n // A path that does not exist yet cannot be resolved, and does not need to be.\n }\n }\n return [...out];\n}\n\n/**\n * Point worker bundles at the DOM-free build of packages that ship two.\n *\n * Resolution goes through Vite so pnpm's layout is respected — these packages are deep\n * transitive dependencies and are not resolvable from seemore's own directory — and only the\n * final `index.dom.js` is swapped for its sibling.\n */\nfunction workerConditionPlugin(): Plugin {\n return {\n name: 'seemore:worker-conditions',\n enforce: 'pre',\n async resolveId(source, importer, options) {\n if (!WORKER_SAFE_ENTRIES.has(source)) return undefined;\n\n const resolved = await this.resolve(source, importer, options);\n if (resolved === null) return undefined;\n\n const domFree = resolved.id.replace(/index\\.dom\\.js$/, 'index.js');\n return domFree === resolved.id ? resolved : { ...resolved, id: domFree };\n },\n };\n}\n\n/**\n * Packages whose browser build touches the DOM at module scope and whose default build does\n * not. `decode-named-character-reference` reaches the worker through remark, by way of\n * fumadocs' search client.\n */\nconst WORKER_SAFE_ENTRIES = new Set(['decode-named-character-reference']);\n","import type { PluggableList } from 'unified';\nimport remarkFrontmatter from 'remark-frontmatter';\nimport {\n rehypeCode,\n rehypeToc,\n remarkAdmonition,\n remarkDirectiveAdmonition,\n remarkGfm,\n remarkHeading,\n remarkImage,\n remarkMdxMermaid,\n remarkSteps,\n} from 'fumadocs-core/mdx-plugins';\nimport {\n remarkSeemoreAlerts,\n remarkSeemoreAssets,\n remarkSeemoreD2,\n remarkSeemoreLinks,\n remarkSeemoreWikilinks,\n type SeemoreRemarkOptions,\n} from './remark.js';\nimport { rehypeSeemorePositions } from './positions.js';\n\n/**\n * The remark/rehype chain. Order matters:\n *\n * - headings get their ids before `rehype-toc` reads them;\n * - our link rewriting runs after the fumadocs transforms that can create links;\n * - Shiki runs at build time in `rehype-code`, so no highlighter ships to the browser.\n *\n * `remark-structure` is deliberately absent: search indexing runs node-side over the raw\n * markdown, where it works identically in dev and build without depending on a\n * browser module having been evaluated.\n */\nexport function createRemarkPlugins(options: SeemoreRemarkOptions): PluggableList {\n return [\n // Strips the `---` block so it never renders. Its data already came from the scan.\n [remarkFrontmatter, ['yaml']],\n remarkGfm,\n remarkHeading,\n remarkAdmonition,\n remarkDirectiveAdmonition,\n // After the fumadocs admonition plugins, which handle `:::note`, and before anything that\n // rewrites link or text nodes inside the quote.\n remarkSeemoreAlerts,\n remarkSteps,\n // Before `remark-image`: a reference to a file that is not there becomes a warning and a\n // visibly broken image, rather than a failed build.\n () => remarkSeemoreAssets(options),\n [\n remarkImage,\n {\n onError: (error: Error) => {\n options.onWarning(error.message);\n },\n },\n ],\n // Rewrites ```mermaid fences to <Mermaid chart=\"…\" />. We supply the component.\n remarkMdxMermaid,\n // Rewrites ```d2 fences to <D2 chart=\"…\" />, mermaid's sibling for D2 diagrams.\n remarkSeemoreD2,\n () => remarkSeemoreWikilinks(options),\n () => remarkSeemoreLinks(options),\n ];\n}\n\nexport interface SeemoreRehypeOptions {\n /**\n * Stamp each editable block with its source range, for the browser's inline editor.\n * Dev only: a static build has no server to write an edit back to.\n */\n positions?: boolean;\n}\n\nexport function createRehypePlugins(options: SeemoreRehypeOptions = {}): PluggableList {\n return [\n // A fence in a language Shiki has no grammar for (anything an AI dreamt up) is plain code\n // on the page, not a dead one: `plaintext` is special-cased by Shiki and never needs\n // loading.\n [rehypeCode, { fallbackLanguage: 'plaintext' }],\n rehypeToc,\n // After `rehype-code`, so a fence Shiki rebuilt is passed over rather than stamped with\n // the position of whatever it replaced.\n ...(options.positions === true ? [rehypeSeemorePositions] : []),\n ];\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, relative, resolve } from 'node:path';\nimport { visit } from 'unist-util-visit';\nimport type { Blockquote, Code, Image, Paragraph, PhrasingContent, Root, Text } from 'mdast';\nimport type { Transformer } from 'unified';\nimport type { VFile } from 'vfile';\nimport type { LinkResolver } from '../content/links.js';\nimport { toPosix } from '../content/slug.js';\n\nexport interface SeemoreRemarkOptions {\n contentRoot: string;\n /** Read late: the resolver is replaced on every rescan. */\n getResolver: () => LinkResolver;\n onWarning: (message: string) => void;\n}\n\nconst WIKILINK = /\\[\\[([^\\]\\n]+)\\]\\]/g;\n\n/** GitHub's alert syntax, and the fumadocs callout each kind maps onto. */\nconst ALERTS: Record<string, { type: string; title: string }> = {\n NOTE: { type: 'info', title: 'Note' },\n TIP: { type: 'idea', title: 'Tip' },\n IMPORTANT: { type: 'info', title: 'Important' },\n WARNING: { type: 'warn', title: 'Warning' },\n CAUTION: { type: 'error', title: 'Caution' },\n};\n\nconst ALERT_MARKER = /^\\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\]\\s*/;\n\n/**\n * GitHub alerts — `> [!NOTE]` — become fumadocs callouts.\n *\n * fumadocs ships `:::note` and directive admonitions, neither of which is what people\n * actually have in their repositories. seemore points at folders that already exist, so the\n * syntax GitHub renders is the syntax that has to work.\n */\nexport function remarkSeemoreAlerts(): Transformer<Root, Root> {\n return (tree) => {\n visit(tree, 'blockquote', (node: Blockquote, index, parent) => {\n if (parent === undefined || index === undefined) return;\n\n const first = node.children[0];\n if (first === undefined || first.type !== 'paragraph') return;\n\n const marker = ALERT_MARKER.exec(textOf(first));\n const alert = marker === null ? undefined : ALERTS[marker[1] ?? ''];\n if (marker === undefined || marker === null || alert === undefined) return;\n\n stripMarker(first, marker[0]);\n\n parent.children[index] = {\n type: 'mdxJsxFlowElement',\n name: 'Callout',\n attributes: [\n { type: 'mdxJsxAttribute', name: 'type', value: alert.type },\n { type: 'mdxJsxAttribute', name: 'title', value: alert.title },\n ],\n children: node.children,\n } as unknown as Blockquote;\n });\n };\n}\n\n/** The paragraph's leading text, which is where the marker lives. */\nfunction textOf(paragraph: Paragraph): string {\n const first = paragraph.children[0];\n return first !== undefined && first.type === 'text' ? first.value.trimStart() : '';\n}\n\n/** Remove the `[!NOTE]` marker, and the line break that followed it. */\nfunction stripMarker(paragraph: Paragraph, marker: string): void {\n const first = paragraph.children[0];\n if (first === undefined || first.type !== 'text') return;\n\n first.value = first.value.trimStart().slice(marker.length).replace(/^\\n/, '');\n if (first.value === '') paragraph.children.shift();\n if (paragraph.children[0]?.type === 'break') paragraph.children.shift();\n}\n\n/**\n * `[[Page]]`, `[[Page|label]]`, `[[Page#Heading]]`. fumadocs has no equivalent.\n *\n * Unresolved targets become styled plain text rather than dead links, because a link that\n * goes nowhere is worse than visibly missing text.\n */\nexport function remarkSeemoreWikilinks(options: SeemoreRemarkOptions): Transformer<Root, Root> {\n return (tree, file) => {\n const from = virtualPath(options.contentRoot, file);\n const resolver = options.getResolver();\n\n visit(tree, 'text', (node: Text, index, parent) => {\n if (parent === undefined || index === undefined) return;\n if (!node.value.includes('[[')) return;\n\n const replacement: PhrasingContent[] = [];\n let cursor = 0;\n WIKILINK.lastIndex = 0;\n\n for (let match = WIKILINK.exec(node.value); match !== null; match = WIKILINK.exec(node.value)) {\n const target = match[1] ?? '';\n if (match.index > cursor) {\n replacement.push({ type: 'text', value: node.value.slice(cursor, match.index) });\n }\n cursor = match.index + match[0].length;\n\n const resolved = resolver.resolveWikilink(target, from);\n if (resolved.warning !== undefined) options.onWarning(resolved.warning);\n\n if (resolved.href === undefined) {\n // An MDX JSX node, not raw HTML: `.md` files run through `rehypeRemoveRaw`, which\n // would silently drop an `html` node, whereas JSX nodes are passed through.\n replacement.push({\n type: 'mdxJsxTextElement',\n name: 'span',\n attributes: [\n { type: 'mdxJsxAttribute', name: 'className', value: 'seemore-broken-wikilink' },\n { type: 'mdxJsxAttribute', name: 'title', value: 'Unresolved link' },\n ],\n children: [{ type: 'text', value: resolved.label }],\n } as unknown as PhrasingContent);\n } else {\n replacement.push({\n type: 'link',\n url: resolved.href,\n children: [{ type: 'text', value: resolved.label }],\n });\n }\n }\n\n if (replacement.length === 0) return;\n if (cursor < node.value.length) replacement.push({ type: 'text', value: node.value.slice(cursor) });\n\n parent.children.splice(index, 1, ...replacement);\n return index + replacement.length;\n });\n };\n}\n\n/**\n * ```d2 fences become `<D2 chart=\"…\" />` — the sibling of `remark-mdx-mermaid`'s rewrite for\n * ```mermaid, but D2 has no fumadocs-shipped equivalent, so this one is ours.\n */\nexport function remarkSeemoreD2(): Transformer<Root, Root> {\n return (tree) => {\n visit(tree, 'code', (node: Code, index, parent) => {\n if (node.lang !== 'd2' || index === undefined || parent === undefined) return;\n\n parent.children[index] = {\n type: 'mdxJsxFlowElement',\n name: 'D2',\n attributes: [{ type: 'mdxJsxAttribute', name: 'chart', value: node.value.trim() }],\n children: [],\n } as unknown as Code;\n });\n };\n}\n\n/**\n * A referenced asset that is not on disk is a warning, not a build failure: the page is\n * visibly wrong on its own, which is the point of the distinction.\n *\n * It has to run before fumadocs' `remark-image`, which turns every image into a bundler\n * import — and an import of a file that does not exist fails the build. Turning the node\n * into JSX first takes it out of that plugin's way, leaving the broken reference visible on\n * the page exactly as the author wrote it.\n */\nexport function remarkSeemoreAssets(options: SeemoreRemarkOptions): Transformer<Root, Root> {\n return (tree, file) => {\n if (typeof file.path !== 'string' || file.path === '') return;\n const dir = dirname(file.path);\n const from = virtualPath(options.contentRoot, file);\n\n visit(tree, 'image', (node: Image, index, parent) => {\n if (parent === undefined || index === undefined) return;\n if (isExternal(node.url) || node.url.startsWith('/')) return;\n\n const target = resolve(dir, decodeURIComponent(node.url.split(/[?#]/)[0] ?? ''));\n if (existsSync(target)) return;\n\n options.onWarning(`Missing asset ${node.url} referenced by ${from}.`);\n\n parent.children.splice(index, 1, {\n type: 'mdxJsxTextElement',\n name: 'img',\n attributes: [\n { type: 'mdxJsxAttribute', name: 'src', value: node.url },\n { type: 'mdxJsxAttribute', name: 'alt', value: node.alt ?? '' },\n { type: 'mdxJsxAttribute', name: 'data-seemore-missing', value: 'true' },\n ],\n children: [],\n } as unknown as PhrasingContent);\n });\n };\n}\n\nfunction isExternal(url: string): boolean {\n return /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i.test(url);\n}\n\n/** Relative `.md`/`.mdx` links become routes, base included. */\nexport function remarkSeemoreLinks(options: SeemoreRemarkOptions): Transformer<Root, Root> {\n return (tree, file) => {\n const from = virtualPath(options.contentRoot, file);\n const resolver = options.getResolver();\n\n const rewrite = (node: { url: string }) => {\n const resolved = resolver.resolveHref(node.url, from);\n if (resolved.warning !== undefined) options.onWarning(resolved.warning);\n node.url = resolved.href;\n };\n\n visit(tree, 'link', rewrite);\n visit(tree, 'definition', rewrite);\n };\n}\n\nfunction virtualPath(contentRoot: string, file: VFile): string {\n if (typeof file.path !== 'string' || file.path === '') return '';\n return toPosix(relative(contentRoot, file.path));\n}\n","import { visit } from 'unist-util-visit';\nimport type { Element, Root } from 'hast';\nimport type { Transformer } from 'unified';\n\n/** The attribute a stamped block carries, read by the browser's inline editor. */\nexport const POSITION_ATTRIBUTE = 'data-seemore-pos';\n\n/**\n * Blocks whose source range is safe to hand back to a text editor.\n *\n * Deliberately narrow. A fence is absent because `rehype-code` rebuilds the `<pre>` from\n * Shiki's own tree and drops the position with it; a `<ul>` is absent because its children\n * are the editable unit. Anything not listed here — and anything a remark plugin\n * synthesised, which has no position at all — simply renders without the attribute and is\n * not offered for editing. That is the intended failure mode: no pointer, no edit, never a\n * wrong write.\n */\nconst EDITABLE = new Set(['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'blockquote', 'td', 'th']);\n\n/**\n * Stamp each editable block with its `start:end` offsets into the original file.\n *\n * The offsets are **JavaScript string indices**, not byte offsets — `Café — naïve 😀` is 22\n * of these and 27 UTF-8 bytes — so every consumer has to stay in string space. See\n * `spliceSource`, which is the only thing that writes them back.\n *\n * Dev-only: a static build has no server to write to, so the attributes would be dead weight\n * in the output.\n */\nexport function rehypeSeemorePositions(): Transformer<Root, Root> {\n return (tree) => {\n visit(tree, 'element', (node: Element) => {\n if (!EDITABLE.has(node.tagName)) return;\n\n const { start, end } = node.position ?? {};\n // A synthesised node has no position; a partially-positioned one is not trustworthy.\n if (start?.offset === undefined || end?.offset === undefined) return;\n\n node.properties ??= {};\n node.properties[POSITION_ATTRIBUTE] = `${start.offset}:${end.offset}`;\n });\n };\n}\n","import { readFileSync, writeFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname } from 'node:path';\nimport type { Plugin, ViteDevServer } from 'vite';\nimport { withBase } from '../base.js';\nimport type { SeemoreContext } from '../context.js';\nimport { buildSearchIndex } from '../search/build.js';\nimport { toPosix } from '../content/slug.js';\nimport { canonicalise } from '../paths.js';\nimport { spliceSource } from '../content/edit.js';\nimport type { ContentPage } from '../content/scan.js';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nexport const VIRTUAL = {\n tree: 'virtual:seemore/tree',\n routes: 'virtual:seemore/routes',\n config: 'virtual:seemore/config',\n} as const;\n\n/**\n * Prefix for content-body imports emitted into `virtual:seemore/routes`.\n *\n * A bare absolute path would be read as *root*-relative by Vite, and the content root is\n * normally outside the Vite root. Resolving our own prefix to the real file id keeps dev and\n * build identical, and lets `@mdx-js/rollup` transform the file as it normally would.\n */\nconst PAGE_PREFIX = 'seemore-page:';\n\nconst resolvedId = (id: string) => `\\0${id}`;\n\n/**\n * Two markers, deliberately: see the comments in `src/app/styles/globals.css`.\n *\n * `@import` is only valid before the first style rule, so the theme has to go at the top —\n * and the user's own stylesheet has to go at the bottom, or it loses to the rules it is\n * meant to override and, worse, invalidates the imports it was inlined above.\n */\nconst IMPORTS_MARKER = /\\/\\* seemore:imports[\\s\\S]*?\\*\\//;\nconst USER_CSS_MARKER = /\\/\\* seemore:user-css[\\s\\S]*?\\*\\//;\n\nconst require_ = createRequire(import.meta.url);\n\nfunction styleImports(ctx: SeemoreContext): string {\n const lines: string[] = [`@import 'fumadocs-ui/css/${ctx.config.theme}.css';`];\n\n // Tailwind cannot scan class names it never sees, and fumadocs-ui ships compiled JS.\n try {\n lines.push(`@source '${dirname(require_.resolve('fumadocs-ui/package.json'))}/dist';`);\n } catch {\n // A layout without the package resolvable is already broken elsewhere; do not add noise.\n }\n\n return lines.join('\\n');\n}\n\nfunction userCss(ctx: SeemoreContext): string {\n if (ctx.config.css === undefined) return '';\n\n const css = readIfExists(ctx.config.css);\n if (css === undefined) {\n ctx.warnings.add(`The stylesheet named by \\`css\\` was not found: ${ctx.config.css}`);\n return '';\n }\n\n // Inlined rather than imported: an `@import` this far down the file is not valid CSS.\n return `/* ${ctx.config.css} */\\n${css}`;\n}\n\nexport interface SeemorePluginOptions {\n ctx: SeemoreContext;\n /** Dev serves the index from memory; build writes it to `dist/api/search.json`. */\n serveSearch?: boolean;\n}\n\nexport function seemorePlugin({ ctx, serveSearch = false }: SeemorePluginOptions): Plugin {\n let server: ViteDevServer | undefined;\n\n return {\n name: 'seemore',\n enforce: 'pre',\n\n resolveId(id) {\n // Native separators from `page.absPath` would key a second, unloadable module in\n // Vite's URL-addressed graph — canonical ids are always forward slashes.\n if (id.startsWith(PAGE_PREFIX)) return id.slice(PAGE_PREFIX.length).replace(/\\\\/g, '/');\n for (const virtualId of Object.values(VIRTUAL)) {\n if (id === virtualId) return resolvedId(virtualId);\n }\n return undefined;\n },\n\n /**\n * The theme preset, the paths Tailwind must scan, and the user's own stylesheet are\n * injected into our root stylesheet rather than imported from it.\n *\n * Tailwind v4 only processes the file that contains `@import \"tailwindcss\"`, and bare\n * specifiers in a virtual stylesheet have no directory to resolve from — injecting into\n * the real `globals.css` keeps both working.\n */\n transform(code, id) {\n const path = id.replace(/\\\\/g, '/').split('?')[0] ?? '';\n if (!path.endsWith('/src/app/styles/globals.css')) return undefined;\n const transformed = code\n .replace(IMPORTS_MARKER, () => styleImports(ctx))\n .replace(USER_CSS_MARKER, () => userCss(ctx));\n return { code: transformed, map: null };\n },\n\n async load(id) {\n if (id === resolvedId(VIRTUAL.tree)) {\n return hotStoreModule('Tree', json(await ctx.source.serializeTree()));\n }\n if (id === resolvedId(VIRTUAL.routes)) {\n return hotStoreModule('Routes', renderRoutesValue(ctx));\n }\n // Config is not a store: a change to it can alter `base`, which reconfigures Vite, so\n // the page reloads rather than patching itself.\n if (id === resolvedId(VIRTUAL.config)) return `export const config = ${json(clientConfig(ctx))};`;\n return undefined;\n },\n\n configureServer(devServer) {\n server = devServer;\n if (!serveSearch) return;\n\n // The same JSON the build emits, at the same path, so the client has one code path.\n devServer.middlewares.use(async (req, res, next) => {\n const path = (req.url ?? '').split('?')[0] ?? '';\n if (path !== withBase(ctx.config.base, '/api/search.json') && path !== '/api/search.json') return next();\n try {\n const index = await buildSearchIndex(ctx);\n res.setHeader('Content-Type', 'application/json');\n res.end(index);\n } catch (error) {\n next(error);\n }\n });\n\n // Lets a caller that only knows an absolute file path — an editor extension, say —\n // ask the running server what URL that file resolved to, rather than reimplementing\n // `resolveRoutes`. Dev-only: the answer depends on a live corpus scan.\n devServer.middlewares.use((req, res, next) => {\n const [path = '', query = ''] = (req.url ?? '').split('?');\n if (path !== '/__seemore/route') return next();\n\n const file = new URLSearchParams(query).get('file');\n if (file === null) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'Missing \"file\" query parameter.' }));\n return;\n }\n\n // `page.absPath` is built on the canonicalised content root; a caller outside\n // seemore (an editor's `document.uri.fsPath`) has no reason to have canonicalised\n // its side, so the comparison must go through the filesystem, not just `resolve`.\n const absFile = canonicalise(file);\n const page = ctx.pages().find((p) => p.absPath === absFile);\n if (page === undefined) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: `${file} is not part of this site — excluded, or lost a duplicate slug.` }));\n return;\n }\n\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ url: withBase(ctx.config.base, page.url) }));\n });\n\n // Reads and writes one block of a page's Markdown, for the browser's inline editor.\n //\n // Dev-only for the obvious reason — a static build has no server — and behind a\n // feature flag because it is the one endpoint seemore has that writes to the user's\n // files. Not registered at all when the flag is off, so there is nothing to reach.\n if (ctx.config.features['content.edit']) {\n devServer.middlewares.use((req, res, next) => {\n const path = (req.url ?? '').split('?')[0] ?? '';\n if (path !== SOURCE_ENDPOINT && path !== withBase(ctx.config.base, SOURCE_ENDPOINT)) return next();\n void handleSource(ctx, req, res).catch(next);\n });\n }\n },\n\n /** Called by the watcher after a rescan. */\n api: {\n invalidate() {\n if (server === undefined) return;\n for (const virtualId of [VIRTUAL.tree, VIRTUAL.routes]) {\n const mod = server.moduleGraph.getModuleById(resolvedId(virtualId));\n if (mod) server.moduleGraph.invalidateModule(mod);\n }\n server.ws.send({ type: 'update', updates: [] });\n },\n },\n };\n}\n\n/** Reads and writes a block of Markdown, addressed by source offsets. */\nconst SOURCE_ENDPOINT = '/__seemore/source';\n\nasync function handleSource(ctx: SeemoreContext, req: IncomingMessage, res: ServerResponse): Promise<void> {\n if (req.method === 'GET') return handleSourceRead(ctx, req, res);\n if (req.method === 'PUT') return handleSourceWrite(ctx, req, res);\n\n res.setHeader('Allow', 'GET, PUT');\n return send(res, 405, { error: `${req.method ?? 'This method'} is not allowed here.` });\n}\n\n/** Hands the browser the exact characters behind a block, so it can edit its real source. */\nfunction handleSourceRead(ctx: SeemoreContext, req: IncomingMessage, res: ServerResponse): void {\n const query = new URLSearchParams((req.url ?? '').split('?')[1] ?? '');\n const page = resolvePage(ctx, query.get('file'));\n if (page === undefined) return send(res, 404, { error: 'That file is not part of this site.' });\n\n const start = Number(query.get('start'));\n const end = Number(query.get('end'));\n const content = readFileSync(page.absPath, 'utf8');\n if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start || end > content.length) {\n return send(res, 400, { error: 'The requested range is not inside this file.' });\n }\n\n return send(res, 200, { text: content.slice(start, end) });\n}\n\nasync function handleSourceWrite(ctx: SeemoreContext, req: IncomingMessage, res: ServerResponse): Promise<void> {\n let body: Partial<{ file: string; start: number; end: number; expected: string; text: string }>;\n try {\n body = JSON.parse(await readBody(req)) as typeof body;\n } catch {\n return send(res, 400, { error: 'The request body was not valid JSON.' });\n }\n\n const page = resolvePage(ctx, body.file);\n if (page === undefined) return send(res, 404, { error: 'That file is not part of this site.' });\n if (typeof body.expected !== 'string' || typeof body.text !== 'string') {\n return send(res, 400, { error: 'Both `expected` and `text` are required.' });\n }\n\n // Read, splice and write as one string: the offsets are JavaScript string indices, so any\n // detour through a Buffer would cut a multi-byte character in half.\n const content = readFileSync(page.absPath, 'utf8');\n const result = spliceSource(content, {\n start: body.start as number,\n end: body.end as number,\n expected: body.expected,\n text: body.text,\n });\n if (!result.ok) return send(res, result.status, { error: result.error });\n\n writeFileSync(page.absPath, result.content, 'utf8');\n // Nothing to invalidate by hand: the watcher sees the write and hot-reloads the page,\n // which is the same path an edit in an editor takes.\n return send(res, 200, { ok: true });\n}\n\n/**\n * The file a request names, but only if it is a page of this site.\n *\n * The comparison goes through {@link canonicalise} for the same reason `/__seemore/route`\n * does — a caller's spelling of a path is not seemore's — and it doubles as the containment\n * check: a path that is not one of the scanned pages is not writable, whatever it points at.\n */\nfunction resolvePage(ctx: SeemoreContext, file: string | null | undefined): ContentPage | undefined {\n if (typeof file !== 'string' || file === '') return undefined;\n const absFile = canonicalise(file);\n return ctx.pages().find((page) => page.absPath === absFile);\n}\n\nasync function readBody(req: IncomingMessage): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks).toString('utf8');\n}\n\nfunction send(res: ServerResponse, status: number, payload: unknown): void {\n res.statusCode = status;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(payload));\n}\n\n/**\n * A self-accepting module holding one value, with subscribers that survive replacement.\n *\n * State lives on `import.meta.hot.data`, so when the module re-executes after an edit the\n * new copy still has the listeners the old one handed to React. `accept()` stops the update\n * propagating to importers, which is the difference between the sidebar re-rendering in\n * place and the page reloading.\n */\nfunction hotStoreModule(suffix: string, value: string): string {\n // `import.meta.hot.accept()` is written out in full because Vite detects self-accepting\n // modules syntactically — through an alias it sees an ordinary module and reloads the page.\n return `const state = import.meta.hot\n ? (import.meta.hot.data.seemore${suffix} ||= { listeners: new Set() })\n : { listeners: new Set() };\n\nstate.value = ${value};\n\nexport function get${suffix}() {\n return state.value;\n}\n\nexport function subscribe${suffix}(listener) {\n state.listeners.add(listener);\n return () => {\n state.listeners.delete(listener);\n };\n}\n\nif (import.meta.hot) {\n import.meta.hot.accept();\n for (const listener of state.listeners) listener();\n}\n`;\n}\n\n/**\n * `virtual:seemore/routes`: one entry per page, with the body behind a dynamic\n * import so the router, the hover prefetch and the prerender driver all read one map.\n *\n * `import.meta.glob` is deliberately not used: glob patterns that escape the Vite root fail\n * silently, which is the exact failure class seemore exists to prevent.\n */\nfunction renderRoutesValue(ctx: SeemoreContext): string {\n const entries = ctx.pages().map((page) => {\n // Backslashes are legal in a Windows path and fatal in an import specifier.\n const specifier = `${PAGE_PREFIX}${page.absPath.replace(/\\\\/g, '/')}`;\n return [\n ' {',\n ` url: ${json(page.url)},`,\n ` file: ${json(page.file)},`,\n ` absPath: ${json(page.absPath)},`,\n ` version: ${json(page.version)},`,\n ` title: ${json(page.data.title)},`,\n ` description: ${json(page.data.description ?? null)},`,\n ` load: () => import(${json(specifier)}),`,\n ' },',\n ].join('\\n');\n });\n\n return `[\\n${entries.join('\\n')}\\n]`;\n}\n\n/** The serialisable slice of the config the browser needs. */\nfunction clientConfig(ctx: SeemoreContext) {\n const { config } = ctx;\n return {\n title: config.title,\n description: config.description,\n base: config.base,\n theme: config.theme,\n features: config.features,\n nav: config.nav,\n footer: config.footer,\n editLink: config.editLink,\n favicon: config.favicon === undefined ? undefined : withBase(config.base, `/${toPosix(config.favicon)}`),\n search:\n config.search.provider === 'static'\n ? { provider: 'static' as const, from: withBase(config.base, '/api/search.json') }\n : config.search,\n contentRoot: config.root,\n };\n}\n\n/** JSON that is always safe to paste into a module body. */\nfunction json(value: unknown): string {\n return JSON.stringify(value ?? null)\n .replace(/</g, '\\\\u003c')\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029');\n}\n\nexport function readIfExists(path: string): string | undefined {\n try {\n return readFileSync(path, 'utf8');\n } catch {\n return undefined;\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { gzipSync } from 'node:zlib';\nimport { createFromSource } from 'fumadocs-core/search/server';\nimport { structure } from 'fumadocs-core/mdx-plugins';\nimport { withBase } from '../base.js';\nimport { parseFrontmatter } from '../content/frontmatter.js';\nimport type { SeemoreContext } from '../context.js';\n\n/** Above this, a static index is a real download cost worth naming. */\nexport const SIZE_WARNING_BYTES = 1_500_000;\n\n/**\n * `structure()` indexes plain text, so seemore's own authoring syntax would reach search\n * results as raw markers. Wikilinks collapse to their label, or to the linked file's name\n * when there is no label, and admonition markers drop while the quoted content stays.\n */\nexport function toSearchableText(body: string): string {\n return body\n .replace(/^>\\s*\\[!\\w+\\]\\s*$/gm, '>')\n .replace(\n /\\[\\[([^\\]|#]*)(?:#[^\\]|]*)?(?:\\|([^\\]]*))?\\]\\]/g,\n (_match, target: string, label?: string) => (label || target.split('/').pop() || '').trim(),\n );\n}\n\n/**\n * Build the static search index.\n *\n * The index is produced node-side from the raw markdown rather than from the compiled MDX\n * modules, so dev and build share one code path and neither has to evaluate browser code.\n */\nexport async function buildSearchIndex(ctx: SeemoreContext): Promise<string> {\n const loader = await ctx.source.loader.get();\n const bodies = new Map<string, string>();\n\n for (const page of ctx.pages()) {\n try {\n // The body only: `structure` reads plain Markdown, where a frontmatter block's closing\n // `---` turns its keys into a setext heading and lands in the index as content.\n bodies.set(page.url, parseFrontmatter(readFileSync(page.absPath, 'utf8'), page.file).content);\n } catch {\n // A file deleted between scan and index is not worth failing a dev rebuild over.\n }\n }\n\n const server = createFromSource(loader, {\n buildIndex(page) {\n const body = bodies.get(page.url) ?? '';\n return {\n id: page.url,\n url: withBase(ctx.config.base, page.url),\n title: typeof page.data.title === 'string' ? page.data.title : page.url,\n description: typeof page.data.description === 'string' ? page.data.description : undefined,\n structuredData: structure(toSearchableText(body)),\n };\n },\n });\n\n const response = await server.staticGET();\n return await response.text();\n}\n\nexport interface IndexSize {\n bytes: number;\n gzipped: number;\n /** Set when the gzipped index passed {@link SIZE_WARNING_BYTES}. */\n warning?: string;\n}\n\nexport function measureIndex(json: string): IndexSize {\n const bytes = Buffer.byteLength(json);\n const gzipped = gzipSync(json).byteLength;\n\n if (gzipped <= SIZE_WARNING_BYTES) return { bytes, gzipped };\n\n return {\n bytes,\n gzipped,\n warning:\n `The static search index is ${formatBytes(gzipped)} gzipped, which every visitor downloads before ` +\n `their first search. Above ${formatBytes(SIZE_WARNING_BYTES)} consider a hosted index: set ` +\n `\\`search: { provider: 'orama-cloud', … }\\` or \\`search: { provider: 'algolia', … }\\` in seemore.config.ts.`,\n };\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} kB`;\n return `${(bytes / 1024 / 1024).toFixed(2)} MB`;\n}\n","/**\n * Writing an edited block back into its source file.\n *\n * The unit is a byte range that a rehype plugin stamped onto the rendered block\n * (`rehypeSeemorePositions`), so an edit replaces exactly the characters that produced that\n * block and leaves every other character in the file untouched — no reflow, no\n * re-serialisation, nothing for a Markdown printer to normalise on its way past.\n */\n\nexport interface SpliceRequest {\n /** Offsets into the file, as JavaScript string indices. */\n start: number;\n end: number;\n /**\n * The slice the client was originally handed, unmodified.\n *\n * Kept separate from `text` on purpose: a `<textarea>` reports its value with `\\n`\n * regardless of what was put into it, so the round-tripped copy cannot be compared against\n * a CRLF file. This one never went through the DOM.\n */\n expected: string;\n /** The replacement, with whatever line endings the browser saw fit to give us. */\n text: string;\n}\n\nexport type SpliceResult =\n | { ok: true; content: string }\n | { ok: false; status: number; error: string };\n\nexport function spliceSource(content: string, request: SpliceRequest): SpliceResult {\n const { start, end, expected, text } = request;\n\n if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start || end > content.length) {\n return { ok: false, status: 400, error: 'The edited range is not inside this file.' };\n }\n\n // The file may have moved under us — an editor saved it, or a previous edit landed — and\n // the offsets the browser is holding would then point at unrelated text. Comparing the\n // slice is cheaper than versioning and catches every case that matters.\n if (content.slice(start, end) !== expected) {\n return {\n ok: false,\n status: 409,\n error: 'This file changed since the page was rendered. Reload and try the edit again.',\n };\n }\n\n return { ok: true, content: content.slice(0, start) + withEol(text, dominantEol(content)) + content.slice(end) };\n}\n\n/**\n * The line ending the file already uses.\n *\n * Without this, editing a multi-line block on Windows silently rewrites its `\\r\\n` to `\\n` —\n * the browser normalises a textarea's value — and the next `git diff` shows every line of the\n * block as changed. Mixed endings within one file are decided by majority, so the common case\n * of a file that is already consistent stays consistent.\n */\nexport function dominantEol(content: string): '\\r\\n' | '\\n' {\n const crlf = content.match(/\\r\\n/g)?.length ?? 0;\n const lf = (content.match(/\\n/g)?.length ?? 0) - crlf;\n return crlf > lf ? '\\r\\n' : '\\n';\n}\n\nfunction withEol(text: string, eol: '\\r\\n' | '\\n'): string {\n const normalised = text.replace(/\\r\\n/g, '\\n');\n return eol === '\\n' ? normalised : normalised.replace(/\\n/g, '\\r\\n');\n}\n","import chokidar, { type FSWatcher } from 'chokidar';\nimport type { Plugin, ViteDevServer } from 'vite';\nimport type { SeemoreContext } from '../context.js';\nimport { VIRTUAL } from './plugin.js';\n\nconst CONTENT_FILE = /\\.(?:mdx?|json)$/i;\n\n/**\n * The watcher/sidebar-refresh cycle.\n *\n * The page tree, sidebar and search index are not in the module graph, so nothing invalidates\n * them on its own. chokidar watches the content root; every event rescans, and the two\n * virtual modules that depend on the corpus are reloaded through Vite's own HMR machinery so\n * the sidebar re-renders in place instead of reloading the page.\n */\nexport function seemoreWatcherPlugin(ctx: SeemoreContext): Plugin {\n let watcher: FSWatcher | undefined;\n\n return {\n name: 'seemore:watcher',\n apply: 'serve',\n\n configureServer(server) {\n watcher = chokidar.watch(ctx.contentRoot, {\n ignoreInitial: true,\n ignored: (path: string, stats?: { isFile(): boolean }) => {\n // `ignored` applies to explicitly added paths too, so the config file — which is\n // neither Markdown nor JSON — has to be let through by name.\n if (path === ctx.config.configFile) return false;\n // chokidar reports native separators, so compare against a normalised path.\n const posix = path.replace(/\\\\/g, '/');\n if (/(?:^|\\/)(?:node_modules|\\.git|dist|build|out|vendor|target|\\.seemore)(?:$|\\/)/.test(posix)) return true;\n if (/(?:^|\\/)\\.[^/]+/.test(posix)) return true;\n return stats?.isFile() === true && !CONTENT_FILE.test(posix);\n },\n });\n\n const onEvent = (event: string, path: string) => {\n void handleContentChange(server, ctx, event, path);\n };\n\n watcher.on('add', (p) => onEvent('add', p));\n watcher.on('change', (p) => onEvent('change', p));\n watcher.on('unlink', (p) => onEvent('unlink', p));\n watcher.on('addDir', (p) => onEvent('addDir', p));\n watcher.on('unlinkDir', (p) => onEvent('unlinkDir', p));\n\n // A config edit can change `base`, which reconfigures Vite itself, so the page reloads\n // rather than patching itself.\n if (ctx.config.configFile !== undefined) {\n watcher.add(ctx.config.configFile);\n watcher.on('change', (path) => {\n if (path !== ctx.config.configFile) return;\n server.environments.client.hot.send({ type: 'full-reload', path: '*' });\n server.config.logger.info(\n 'seemore config changed — reloading. Changes to `base` need a restart to take effect.',\n );\n });\n }\n\n server.httpServer?.once('close', () => void watcher?.close());\n },\n\n async closeBundle() {\n await watcher?.close();\n watcher = undefined;\n },\n };\n}\n\n/** Exported for the watcher test, which drives it without going through chokidar's timing. */\nexport async function handleContentChange(\n server: ViteDevServer,\n ctx: SeemoreContext,\n event: string,\n path: string,\n): Promise<void> {\n const scan = ctx.refresh();\n\n // Dev never exits on a content error, but it must not swallow one either: editing a file\n // back to valid has to recover without a restart, so problems are reported each time.\n for (const message of [...scan.errors, ...scan.warnings]) ctx.warnings.add(message);\n ctx.warnings.flush((line) => server.config.logger.warn(line));\n\n // Order matters: the tree must be current before anything re-renders against it.\n await reloadVirtual(server, VIRTUAL.tree);\n await reloadVirtual(server, VIRTUAL.routes);\n\n // A body edit is a plain MDX swap; the component is replaced and scroll position kept.\n if (event === 'change' && /\\.mdx?$/i.test(path)) {\n await reloadFile(server, path);\n }\n}\n\nasync function reloadVirtual(server: ViteDevServer, id: string): Promise<void> {\n await reloadById(server, `\\0${id}`);\n}\n\nasync function reloadFile(server: ViteDevServer, absolutePath: string): Promise<void> {\n // chokidar reports native separators; the module graph is addressed in forward slashes.\n await reloadById(server, absolutePath.replace(/\\\\/g, '/'));\n}\n\n/**\n * Reload a module in every environment that has it. `server.reloadModule` handles\n * invalidation and the HMR message together, which keeps us out of the business of\n * constructing update payloads by hand.\n */\nasync function reloadById(server: ViteDevServer, id: string): Promise<void> {\n const environments = Object.values(server.environments ?? {});\n\n if (environments.length === 0) {\n const legacy = server.moduleGraph.getModuleById(id);\n if (legacy) await server.reloadModule(legacy);\n return;\n }\n\n for (const environment of environments) {\n const mod = environment.moduleGraph?.getModuleById(id);\n if (mod === undefined || mod === null) continue;\n if (typeof environment.reloadModule === 'function') await environment.reloadModule(mod);\n else environment.moduleGraph.invalidateModule(mod);\n }\n}\n","import { mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { ogImagePath } from '../../shared/og.js';\nimport type { SeemoreContext } from '../context.js';\n\n/**\n * `social.cards`: one OG image per page, rendered at build time.\n *\n * `takumi-js` is an optional peer of fumadocs-ui and is not installed by default, so the\n * flag degrades to a warning rather than to an install-time cost everybody pays.\n */\nexport async function generateSocialCards(ctx: SeemoreContext, outDir: string): Promise<number> {\n // `takumi-js` is an optional peer, so it is loaded by specifier and typed structurally —\n // a hard import would make it a required dependency of every build.\n let takumi: TakumiModule;\n try {\n takumi = (await importOptional('takumi-js')) as TakumiModule;\n } catch {\n ctx.warnings.add(\n \"`social.cards` is enabled but `takumi-js` is not installed. Run `npm install takumi-js`, or remove the flag.\",\n );\n return 0;\n }\n\n let written = 0;\n for (const page of ctx.pages()) {\n const png = await renderCard(takumi, ctx.config.title, page.data.title, page.data.description);\n if (png === undefined) continue;\n\n const target = join(outDir, ogImagePath(page.url));\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, png);\n written++;\n }\n\n return written;\n}\n\ninterface TakumiModule {\n Renderer: new (options: { fonts: unknown[] }) => {\n renderAsync(node: unknown, options: { width: number; height: number; format: 'png' }): Promise<Uint8Array>;\n };\n container(props: unknown, children: unknown[]): unknown;\n text(value: string, props: unknown): unknown;\n}\n\nasync function renderCard(\n takumi: TakumiModule,\n site: string,\n title: string,\n description: unknown,\n): Promise<Uint8Array | undefined> {\n const renderer = new takumi.Renderer({ fonts: [] });\n const node = takumi.container(\n {\n style: {\n width: 1200,\n height: 630,\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n padding: 80,\n backgroundColor: '#0b0b0b',\n color: '#ffffff',\n gap: 24,\n },\n },\n [\n takumi.text(site, { style: { fontSize: 28, opacity: 0.6 } }),\n takumi.text(title, { style: { fontSize: 64, fontWeight: 700 } }),\n ...(typeof description === 'string' ? [takumi.text(description, { style: { fontSize: 30, opacity: 0.8 } })] : []),\n ],\n );\n\n return await renderer.renderAsync(node, { width: 1200, height: 630, format: 'png' });\n}\n\n/** Import by a specifier TypeScript will not try to resolve at build time. */\nasync function importOptional(specifier: string): Promise<unknown> {\n return await import(specifier);\n}\n","/**\n * Where a page's social card lives.\n *\n * Shared, because the build writes the file and the prerendered `<head>` points at it — and\n * a card nothing references is a card nobody sees.\n */\nexport function ogImagePath(url: string): string {\n const clean = url.replace(/^\\/+|\\/+$/g, '');\n // A path per route, rather than a flattened filename: `/a/b` and `/a-b` are different\n // routes and must not write to the same file.\n return clean === '' ? '/api/og/card.png' : `/api/og/${clean}/card.png`;\n}\n","import { createServer, type ViteDevServer } from 'vite';\nimport pc from 'picocolors';\nimport { loadConfig } from '../node/config/load.js';\nimport { createContext, type SeemoreContext } from '../node/context.js';\nimport { normaliseBase } from '../shared/base.js';\nimport { resolveContentRoot } from '../node/paths.js';\nimport { createViteConfig } from '../node/vite/config.js';\n\nconst DEFAULT_PORT = 4040;\n\nexport interface DevOptions {\n cwd: string;\n dir?: string;\n configPath?: string;\n base?: string;\n port?: number;\n host?: string | boolean;\n open?: boolean;\n /**\n * Print one JSON line on stdout at startup instead of the human summary — a stable\n * contract for a caller that spawns this as a child process, so it never has to\n * screen-scrape colored text.\n */\n json?: boolean;\n}\n\n/** The single line a `json: true` caller parses to learn where the server ended up. */\nexport interface DevReady {\n url: string;\n port: number;\n contentRoot: string;\n pageCount: number;\n}\n\nexport interface DevServer {\n server: ViteDevServer;\n ctx: SeemoreContext;\n url: string;\n close(): Promise<void>;\n}\n\n/**\n * The dev server. Nothing is written into the user's folder: the Vite root is\n * seemore's own `src/app`, and caches go to the OS temp directory.\n */\nexport async function runDev(options: DevOptions): Promise<DevServer> {\n const contentRoot = resolveContentRoot(options.cwd, options.dir);\n const loaded = await loadConfig({ root: options.cwd, configPath: options.configPath });\n const config = {\n ...loaded.config,\n base: options.base === undefined ? loaded.config.base : normaliseBase(options.base),\n };\n\n // Dev never exits on a content error: editing a file back to valid must recover without a\n // restart, so problems that fail the build are warnings here.\n const ctx = createContext({ config, contentRoot, includeDrafts: true });\n const scan = ctx.source.current();\n for (const message of [...scan.errors, ...scan.warnings]) ctx.warnings.add(message);\n if (scan.pages.length === 0) {\n ctx.warnings.add(`No Markdown files found under ${contentRoot}. seemore will serve an empty site until there are.`);\n }\n\n const base = createViteConfig({ ctx, mode: 'dev' });\n const server = await createServer({\n ...base,\n server: {\n ...base.server,\n port: options.port ?? DEFAULT_PORT,\n host: options.host,\n open: options.open === true ? config.base : false,\n },\n });\n\n await server.listen();\n\n const resolvedPort = server.config.server.port ?? DEFAULT_PORT;\n const url = `http://localhost:${resolvedPort}${config.base}`;\n\n ctx.warnings.flush();\n if (options.json === true) {\n const ready: DevReady = { url, port: resolvedPort, contentRoot, pageCount: scan.pages.length };\n console.log(JSON.stringify(ready));\n } else {\n console.log(`\\n ${pc.green('seemore')} ${pc.bold(url)}`);\n console.log(` ${pc.dim(`${scan.pages.length} pages from ${contentRoot}`)}\\n`);\n }\n\n return {\n server,\n ctx,\n url,\n close: async () => {\n await server.close();\n },\n };\n}\n"],"mappings":"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","names":["existsSync","readFileSync","createHash","dirname","join","resolve","pc","mkdirSync","readFileSync","writeFileSync","createRequire","tmpdir","isAbsolute","join","relative","resolve","pc","slugify","basename","CONTENT_EXT","basename","slugify","relative","dirname","resolve","z","z","z","resolve","dirname","dirname","join","writeFileSync","join","join","realpathSync","createRequire","join","existsSync","dirname","resolve","dirname","resolve","existsSync","visit","readFileSync","writeFileSync","dirname","readFileSync","readFileSync","json","dirname","readFileSync","writeFileSync","scan","require_","createRequire","join","realpathSync","join","mkdirSync","writeFileSync","dirname","join","join","mkdirSync","dirname","writeFileSync","resolve","scan","pc","relative","readFileSync","join","tmpdir","mkdirSync","writeFileSync","isAbsolute","createRequire","pc","scan","pc","pc","readFileSync","join","packageRoot"]}
|
|
1
|
+
{"version":3,"sources":["../../src/node/paths.ts","../../src/cli/index.ts","../../src/cli/build.ts","../../src/node/config/load.ts","../../src/shared/base.ts","../../src/shared/types.ts","../../src/node/config/features.ts","../../src/node/config/schema.ts","../../src/node/content/links.ts","../../src/node/content/slug.ts","../../src/node/content/source.ts","../../src/node/content/scan.ts","../../src/node/content/frontmatter.ts","../../src/node/report.ts","../../src/node/context.ts","../../src/node/prerender/emit.ts","../../src/node/prerender/deploy.ts","../../src/node/prerender/render.ts","../../src/node/vite/config.ts","../../src/node/vite/mdx.ts","../../src/node/vite/remark.ts","../../src/node/vite/positions.ts","../../src/node/vite/plugin.ts","../../src/node/search/build.ts","../../src/node/content/edit.ts","../../src/node/vite/watcher.ts","../../src/node/social/cards.ts","../../src/shared/og.ts","../../src/cli/dev.ts"],"sourcesContent":["import { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { createHash } from 'node:crypto';\nimport { tmpdir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * The installed seemore package directory.\n *\n * Works from the bundled CLI (`dist/cli/index.js`) and from the sources during tests, which\n * is why it walks for `package.json` rather than assuming a depth.\n */\nexport function packageRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url));\n for (let depth = 0; depth < 10; depth++) {\n if (existsSync(join(dir, 'package.json'))) return dir;\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error('seemore: could not locate its own package root.');\n}\n\n/** The browser layer, which ships as source and is compiled in-process. */\nexport function appRoot(): string {\n return join(packageRoot(), 'src', 'app');\n}\n\n/**\n * Walks up from a resolved file to the `package.json` that names it.\n *\n * For a dependency subpath its own `exports` map doesn't list — `dist/browser/index.js`\n * inside `@terrastruct/d2`, say — there's no portable `require.resolve` for it; only the\n * package's declared entry point is guaranteed reachable. This finds the package's own\n * directory from that entry point, so a caller can build the rest of the path itself.\n */\nexport function packageDirOf(name: string, fromFile: string): string {\n let dir = dirname(fromFile);\n for (let depth = 0; depth < 10; depth++) {\n const manifest = join(dir, 'package.json');\n if (existsSync(manifest) && (JSON.parse(readFileSync(manifest, 'utf8')) as { name?: string }).name === name) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(`seemore: could not locate the \"${name}\" package directory.`);\n}\n\n/**\n * Vite's caches go to the OS temp directory, keyed by content root.\n *\n * Dev writes nothing into the user's folder, and that has to include the\n * dependency-optimiser cache Vite would otherwise put in `node_modules/.vite`.\n */\nexport function cacheDir(contentRoot: string): string {\n const key = createHash('sha256').update(resolve(contentRoot)).digest('hex').slice(0, 12);\n return join(tmpdir(), 'seemore', key);\n}\n\n/**\n * `seemore [dir]`, else the folder the command runs in. Nothing is probed: which Markdown\n * becomes the site is decided by where the user stands, never by what happens to exist.\n *\n * The result is canonicalised through the filesystem. Every module id seemore derives from\n * the root — import specifiers, watcher lookups — must use the real spelling, because Vite\n * refuses to *load* a path containing a Windows 8.3 short-name segment (`RUNNER~1`) no\n * matter what the fs allow list says. Real users hit this too: `C:\\Users\\<long name>\\`\n * carries a short alias on any drive with 8.3 names enabled.\n */\nexport function resolveContentRoot(cwd: string, explicit?: string): string {\n return explicit !== undefined ? canonicalise(resolve(cwd, explicit)) : canonicalise(cwd);\n}\n\n/**\n * Resolve a path through the filesystem to its real spelling — the same treatment\n * {@link resolveContentRoot} gives the content root, needed anywhere else a path arriving\n * from outside seemore (an editor's `document.uri.fsPath`, say) has to be compared against\n * one of its own, which are already canonicalised. A symlinked ancestor (`/tmp` on macOS)\n * or a Windows 8.3 short name would otherwise make the same file compare unequal to itself.\n */\nexport function canonicalise(dir: string): string {\n try {\n return realpathSync.native(dir);\n } catch {\n // Does not exist, or not readable: keep the literal spelling rather than throw.\n return dir;\n }\n}\n","#!/usr/bin/env node\nimport { parseArgs } from 'node:util';\nimport pc from 'picocolors';\nimport { runBuild } from './build.js';\nimport { runDev } from './dev.js';\n\nconst USAGE = `\n${pc.bold('seemore')} — turn a folder of Markdown into a docs site\n\n seemore [dir] start the dev server\n seemore build [dir] build a static site into dist/\n\nOptions\n --port <number> dev server port (default 4040)\n --host [host] expose the dev server on the network\n --open / --no-open open a browser on start (default: no)\n --json print one machine-readable JSON line instead of the summary (dev only)\n --config <path> path to seemore.config.ts\n --out <dir> build output directory (default: dist)\n --base <path> subpath the site is served from, e.g. /my-repo/\n -h, --help show this message\n -v, --version show the version\n`;\n\n/**\n * `parseArgs` has no notion of an optional value, so a bare `--host` — the documented form,\n * and the one Vite uses for \"listen on every interface\" — is rewritten to `--host=` first.\n */\nfunction normaliseHostFlag(argv: string[]): string[] {\n const index = argv.indexOf('--host');\n if (index === -1) return argv;\n const next = argv[index + 1];\n if (next !== undefined && !next.startsWith('-')) return argv;\n return [...argv.slice(0, index), '--host=', ...argv.slice(index + 1)];\n}\n\nexport async function main(argv: string[] = process.argv.slice(2)): Promise<void> {\n const { values, positionals } = parseArgs({\n args: normaliseHostFlag(argv),\n allowPositionals: true,\n options: {\n port: { type: 'string' },\n host: { type: 'string' },\n open: { type: 'boolean' },\n 'no-open': { type: 'boolean' },\n json: { type: 'boolean' },\n config: { type: 'string' },\n out: { type: 'string' },\n base: { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n version: { type: 'boolean', short: 'v' },\n },\n });\n\n if (values.help === true) {\n console.log(USAGE);\n return;\n }\n\n if (values.version === true) {\n const { readFileSync } = await import('node:fs');\n const { join } = await import('node:path');\n const { packageRoot } = await import('../node/paths.js');\n const pkg = JSON.parse(readFileSync(join(packageRoot(), 'package.json'), 'utf8')) as { version: string };\n console.log(pkg.version);\n return;\n }\n\n const [command, ...rest] = positionals;\n const isBuild = command === 'build';\n const dir = isBuild ? rest[0] : command;\n\n const shared = { cwd: process.cwd(), dir, configPath: values.config, base: values.base };\n\n if (isBuild) {\n await runBuild({ ...shared, outDir: values.out });\n return;\n }\n\n await runDev({\n ...shared,\n port: values.port === undefined ? undefined : Number(values.port),\n host: values.host === undefined ? undefined : values.host === '' ? true : values.host,\n open: values.open === true && values['no-open'] !== true,\n json: values.json === true,\n });\n}\n\nmain().catch((error: unknown) => {\n console.error(`\\n${pc.red('seemore')} ${error instanceof Error ? error.message : String(error)}\\n`);\n process.exitCode = 1;\n});\n","import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { tmpdir } from 'node:os';\nimport { isAbsolute, join, relative, resolve } from 'node:path';\nimport pc from 'picocolors';\nimport { build as viteBuild } from 'vite';\nimport { loadConfig, resolveConfigPath } from '../node/config/load.js';\nimport { createContext, type SeemoreContext } from '../node/context.js';\nimport { normaliseBase } from '../shared/base.js';\nimport { resolveContentRoot } from '../node/paths.js';\nimport { applyTemplate, outputPathFor, writeHtml } from '../node/prerender/emit.js';\nimport { writeDeployArtifacts } from '../node/prerender/deploy.js';\nimport { loadPrerenderModule } from '../node/prerender/render.js';\nimport { buildSearchIndex, formatBytes, measureIndex } from '../node/search/build.js';\nimport { generateSocialCards } from '../node/social/cards.js';\nimport { createViteConfig } from '../node/vite/config.js';\n\nexport interface BuildOptions {\n cwd: string;\n dir?: string;\n configPath?: string;\n outDir?: string;\n base?: string;\n}\n\nexport async function runBuild(options: BuildOptions): Promise<{ outDir: string; routes: number }> {\n const contentRoot = resolveContentRoot(options.cwd, options.dir);\n const loaded = await loadConfig({ root: contentRoot, configPath: resolveConfigPath(options) });\n\n const config = { ...loaded.config, base: options.base === undefined ? loaded.config.base : normaliseBase(options.base) };\n warnAboutMissingBase(config.base, loaded.file);\n\n const ctx = createContext({ config, contentRoot });\n const outDir = resolve(options.cwd, options.outDir ?? 'dist');\n assertSafeOutDir(outDir, options.cwd, contentRoot);\n\n const scan = ctx.source.current();\n failOnErrors(ctx.errors(), contentRoot);\n if (scan.pages.length === 0) {\n throw new Error(`No Markdown files found under ${contentRoot}. Point seemore at a folder that has some, or check \\`exclude\\`.`);\n }\n for (const warning of scan.warnings) ctx.warnings.add(warning);\n\n console.log(pc.dim(`seemore ${scan.pages.length} pages from ${relative(options.cwd, contentRoot) || '.'}`));\n\n // 1. The client bundle, which also produces the HTML template every page is injected into.\n await viteBuild(createViteConfig({ ctx, mode: 'build', outDir }));\n const template = readFileSync(join(outDir, 'index.html'), 'utf8');\n\n // 2. The same module graph, evaluated in node.\n const ssrOutDir = mkdtempSync(join(tmpdir(), 'seemore-ssr-'));\n try {\n const prerender = await loadPrerenderModule(ctx, ssrOutDir);\n const urls = prerender.listRoutes();\n // When no page claims `/`, the router generates an index page there — the same component\n // the dev server renders — so the client build's empty shell never ships as the home page.\n const routes = urls.includes('/') ? urls : ['/', ...urls];\n if (routes.length > urls.length) {\n console.log(pc.dim('seemore no index page; generated one listing every page at /'));\n }\n\n for (const url of routes) {\n writeHtml(outDir, outputPathFor(url), applyTemplate(template, await prerender.render(url)));\n }\n\n // 3. The shell an unknown address falls back to, which is also Surge's `200.html`.\n const notFound = applyTemplate(template, await prerender.render('/__seemore_not_found'));\n writeHtml(outDir, '404.html', notFound);\n writeDeployArtifacts(outDir, config.base, notFound);\n\n // 4. The search index, at the same path the dev middleware serves.\n if (config.search.provider === 'static') {\n const index = await buildSearchIndex(ctx);\n mkdirSync(join(outDir, 'api'), { recursive: true });\n writeFileSync(join(outDir, 'api', 'search.json'), index, 'utf8');\n\n const size = measureIndex(index);\n console.log(pc.dim(`seemore search index ${formatBytes(size.gzipped)} gzipped`));\n if (size.warning !== undefined) ctx.warnings.add(size.warning);\n }\n\n if (config.search.provider !== 'static') await warnIfSearchSdkMissing(ctx, config.search.provider);\n\n if (config.features['social.cards']) await generateSocialCards(ctx, outDir);\n\n ctx.warnings.flush();\n console.log(pc.green(`seemore ${routes.length} pages written to ${relative(options.cwd, outDir) || outDir}`));\n\n return { outDir, routes: routes.length };\n } finally {\n rmSync(ssrOutDir, { recursive: true, force: true });\n }\n}\n\n/**\n * The build empties `outDir` before writing, and `outDir` is always outside the Vite root —\n * seemore's root is its own package — so Vite's own guard against that never fires. A typo\n * like `--out .` would delete the project, so it is refused here instead.\n */\nfunction assertSafeOutDir(outDir: string, cwd: string, contentRoot: string): void {\n const contains = (parent: string, child: string): boolean => {\n const rel = relative(parent, child);\n return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));\n };\n\n for (const [name, dir] of [\n ['the current directory', cwd],\n ['the content directory', contentRoot],\n ] as const) {\n if (contains(outDir, dir)) {\n throw new Error(\n `Refusing to build into ${outDir}: it is, or contains, ${name}, and the build empties its output directory first. Pass --out with a directory of its own.`,\n );\n }\n }\n}\n\n/**\n * The hosted search providers need an SDK that seemore does not depend on. Finding out in the\n * browser means an empty search box; finding out here means a line in the build log.\n */\nasync function warnIfSearchSdkMissing(ctx: SeemoreContext, provider: 'algolia' | 'orama-cloud'): Promise<void> {\n const packageName = provider === 'algolia' ? 'algoliasearch' : '@orama/core';\n try {\n createRequire(join(ctx.config.root, 'noop.js')).resolve(packageName);\n } catch {\n ctx.warnings.add(\n `\\`search.provider\\` is '${provider}', which needs ${packageName}. Run \\`npm install ${packageName}\\` or search will find nothing.`,\n );\n }\n}\n\n/** Failing conditions produce a silently wrong site; warnings produce a visibly wrong page. */\nfunction failOnErrors(errors: string[], contentRoot: string): void {\n if (errors.length === 0) return;\n throw new Error(`seemore found ${errors.length} problem(s) in ${contentRoot}:\\n\\n${errors.join('\\n\\n')}`);\n}\n\n/**\n * `base` is never inferred. Under CI, where getting it wrong ships a broken site,\n * say so — with the exact line to add.\n */\nfunction warnAboutMissingBase(base: string, configFile: string | undefined): void {\n if (base !== '/' || process.env.GITHUB_ACTIONS !== 'true') return;\n const repo = process.env.GITHUB_REPOSITORY?.split('/')[1];\n console.warn(\n pc.yellow(\n `seemore \\`base\\` is not set, and GitHub Pages serves project sites from a subpath.\\n` +\n ` Add this to ${configFile ?? 'seemore.config.ts'}:\\n\\n` +\n ` base: '/${repo ?? 'your-repo'}/',\\n\\n` +\n ` Or pass --base '/${repo ?? 'your-repo'}/'. Ignore this if you deploy to a domain root.`,\n ),\n );\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { createJiti } from 'jiti';\nimport { z } from 'zod';\nimport { normaliseBase } from '../base.js';\nimport { resolveFeatures, type FeatureFlag } from './features.js';\nimport { configSchema, THEMES, type SeemoreConfig, type ResolvedSeemoreConfig, type SearchConfig } from './schema.js';\n\nconst CONFIG_NAMES = ['seemore.config.ts', 'seemore.config.mts', 'seemore.config.js', 'seemore.config.mjs'];\n\nexport interface LoadConfigOptions {\n /**\n * Directory to look in, and the base for relative paths inside the config. This is the\n * content root — the folder being documented — not the process's cwd: `seemore [dir]`\n * documents `dir`, so `dir/seemore.config.ts` is the config that names that site.\n */\n root: string;\n /** `--config`; when given, a missing file is an error rather than a fallback to defaults. */\n configPath?: string;\n}\n\n/** Turn a validated config into the fully-resolved shape the rest of seemore consumes. */\nexport function resolveConfig(\n input: SeemoreConfig,\n options: { root: string; configFile?: string },\n): ResolvedSeemoreConfig {\n const parsed = parseOrThrow(input, options.configFile);\n\n const search: SearchConfig = parsed.search === 'static' ? { provider: 'static' } : (parsed.search as SearchConfig);\n\n const features = resolveFeatures(parsed.features as FeatureFlag[], {\n // Nothing to link to without an edit base, so the flag follows the option.\n 'content.action.edit': parsed.editLink !== undefined,\n });\n\n return {\n // Only reached without a config file (see parseOrThrow): 'Docs' is the best name we can know.\n title: parsed.title ?? 'Docs',\n description: parsed.description,\n favicon: parsed.favicon,\n base: normaliseBase(parsed.base),\n theme: parsed.theme,\n css: parsed.css === undefined ? undefined : resolveFrom(options.root, parsed.css),\n features,\n nav: parsed.nav,\n footer: parsed.footer,\n editLink: parsed.editLink,\n search,\n exclude: parsed.exclude,\n root: options.root,\n configFile: options.configFile,\n };\n}\n\nexport interface LoadedConfig {\n config: ResolvedSeemoreConfig;\n /** Absolute path of the config file that was used, if any. */\n file?: string;\n}\n\n/**\n * Load `seemore.config.ts` with jiti. Not Vite's `ssrLoadModule`: the config\n * decides `base`, `base` configures Vite, and Vite would have to already exist to load it.\n */\nexport async function loadConfig(options: LoadConfigOptions): Promise<LoadedConfig> {\n const file = findConfigFile(options);\n\n if (file === undefined) {\n return { config: resolveConfig({}, { root: options.root }) };\n }\n\n const jiti = createJiti(import.meta.url, { moduleCache: false, fsCache: false });\n let loaded: unknown;\n try {\n loaded = await jiti.import(file, { default: true });\n } catch (error) {\n throw new Error(`Failed to load ${file}:\\n${error instanceof Error ? error.message : String(error)}`, {\n cause: error,\n });\n }\n\n if (loaded === null || typeof loaded !== 'object') {\n throw new Error(`${file} must export a config object as its default export, got ${typeof loaded}.`);\n }\n\n return {\n config: resolveConfig(loaded as SeemoreConfig, { root: dirname(file), configFile: file }),\n file,\n };\n}\n\nfunction findConfigFile({ root, configPath }: LoadConfigOptions): string | undefined {\n if (configPath !== undefined) {\n const absolute = resolveFrom(root, configPath);\n if (!existsSync(absolute)) {\n throw new Error(`Config file not found: ${absolute}`);\n }\n return absolute;\n }\n\n for (const name of CONFIG_NAMES) {\n const candidate = resolve(root, name);\n if (existsSync(candidate)) return candidate;\n }\n return undefined;\n}\n\n/**\n * `--config` is a path the user typed at a shell prompt, so it is relative to where they\n * stood — not to the content root, which `seemore [dir]` may have moved elsewhere. Made\n * absolute here so {@link loadConfig} can take `root` to mean the content root throughout.\n */\nexport function resolveConfigPath(options: { cwd: string; configPath?: string }): string | undefined {\n return options.configPath === undefined ? undefined : resolveFrom(options.cwd, options.configPath);\n}\n\nfunction resolveFrom(root: string, path: string): string {\n return isAbsolute(path) ? path : resolve(root, path);\n}\n\nfunction parseOrThrow(input: SeemoreConfig, file: string | undefined): z.output<typeof configSchema> {\n const result = configSchema.safeParse(input);\n if (result.success) {\n // A written config is an intentional site, so it must name itself; the no-config\n // quickstart is a preview, and falls back to 'Docs' instead.\n if (file !== undefined && result.data.title === undefined) {\n throw new Error(\n `Invalid ${file}:\\n` +\n ` - title: required when a config file exists — it names the site in the header, tab, and social cards. Add: title: 'My Site'`,\n );\n }\n return result.data;\n }\n\n const where = file === undefined ? 'seemore config' : file;\n const issues = result.error.issues.map((issue) => {\n const field = issue.path.length === 0 ? '(root)' : issue.path.join('.');\n return ` - ${field}: ${explain(issue)}`;\n });\n throw new Error(`Invalid ${where}:\\n${issues.join('\\n')}`);\n}\n\nfunction explain(issue: z.core.$ZodIssue): string {\n // zod's default message for a large enum truncates badly; the valid set is the useful part.\n if (issue.code === 'invalid_value' && issue.path.join('.') === 'theme') {\n return `unknown theme. Valid themes: ${THEMES.join(', ')}.`;\n }\n return issue.message;\n}\n","/**\n * Base-path handling.\n *\n * Internally a base is always normalised to leading + trailing slash (`/sub/`), because a\n * single canonical shape is what makes the \"no absolute-root URL leaks\" test possible. The\n * trailing slash is stripped again only at the point of output.\n */\n\nconst EXTERNAL = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\n\n/** `undefined` | `sub` | `/sub` | `/sub/` → `/sub/`. The root base is `/`. */\nexport function normaliseBase(base: string | undefined): string {\n if (base === undefined || base === '') return '/';\n if (EXTERNAL.test(base)) {\n throw new Error(\n `Invalid \\`base\\`: ${JSON.stringify(base)}. \\`base\\` is a path on the host, not a URL — use \"/${base.replace(/^.*?:\\/\\/[^/]*/, '').replace(/^\\/+/, '')}\".`,\n );\n }\n const trimmed = base.replace(/^\\/+/, '').replace(/\\/+$/, '');\n return trimmed === '' ? '/' : `/${trimmed}/`;\n}\n\n/** True for hrefs that a base must never touch: external, protocol-relative, hash, or relative. */\nexport function isExternalHref(href: string): boolean {\n return EXTERNAL.test(href) || href.startsWith('#') || !href.startsWith('/');\n}\n\n/** Prefix a root-relative path with the base. Idempotent; leaves external hrefs alone. */\nexport function withBase(base: string, href: string): string {\n const b = normaliseBase(base);\n if (b === '/' || isExternalHref(href)) return href;\n if (href === '/') return b;\n if (href === b.slice(0, -1) || href.startsWith(b)) return href;\n return b + href.replace(/^\\/+/, '');\n}\n\n/** Inverse of {@link withBase}: turn a browser pathname back into an internal route URL. */\nexport function stripBase(base: string, pathname: string): string {\n const b = normaliseBase(base);\n if (b === '/') return pathname;\n if (pathname === b || pathname === b.slice(0, -1)) return '/';\n if (!pathname.startsWith(b)) return pathname;\n return `/${pathname.slice(b.length)}`;\n}\n\n/** The form React Router wants for `basename`: leading slash, no trailing slash, `/` at root. */\nexport function toBasename(base: string): string {\n const b = normaliseBase(base);\n return b === '/' ? '/' : b.slice(0, -1);\n}\n\n/**\n * Browser pathnames are percent-encoded; route URLs are not.\n *\n * `/guía/página-uno` arrives from `location.pathname` as `/gu%C3%ADa/p%C3%A1gina-uno`, and a\n * lookup against the route map misses — so a correctly prerendered page hydrates into \"Page\n * not found\". `decodeURI`, not `decodeURIComponent`: a literal `%2F` in a filename must stay\n * encoded or it would split into two path segments.\n */\nexport function decodePath(pathname: string): string {\n try {\n return decodeURI(pathname);\n } catch {\n // Malformed escapes are the browser's problem, not ours; match on what we were given.\n return pathname;\n }\n}\n","import type { ComponentType, ReactNode } from 'react';\n\n/**\n * Types shared by the node pipeline and the browser app. This file ships as source, next to\n * `src/app`, so both halves agree on the shape of the virtual modules.\n */\n\nexport const FEATURES = [\n 'navigation.instant.prefetch',\n 'navigation.instant.preview',\n 'navigation.footer',\n 'navigation.top',\n 'navigation.path',\n 'navigation.sections',\n 'navigation.prune',\n 'toc.follow',\n 'toc.integrate',\n 'content.code.copy',\n 'content.action.edit',\n 'content.edit',\n 'content.image.zoom',\n 'search.suggest',\n 'search.highlight',\n 'social.cards',\n] as const;\n\nexport type Feature = (typeof FEATURES)[number];\n/** What a user may write in `features`: a flag, or `!flag` to switch a default-on flag off. */\nexport type FeatureFlag = Feature | `!${Feature}`;\nexport type ResolvedFeatures = Record<Feature, boolean>;\n\nexport interface NavItem {\n text: string;\n link?: string;\n items?: NavItem[];\n}\n\nexport type ClientSearchConfig =\n | { provider: 'static'; from: string }\n | { provider: 'orama-cloud'; endpoint: string; apiKey: string }\n | { provider: 'algolia'; appId: string; apiKey: string; indexName: string };\n\n/** The payload of `virtual:seemore/config`. */\nexport interface ClientConfig {\n title: string;\n description?: string;\n base: string;\n theme: string;\n features: ResolvedFeatures;\n nav?: NavItem[];\n footer?: { text?: string; links?: { text: string; link: string }[] };\n editLink?: { base: string; text: string };\n favicon?: string;\n search: ClientSearchConfig;\n contentRoot: string;\n}\n\n/** One entry of `virtual:seemore/routes`. */\nexport interface RouteEntry {\n url: string;\n /** Virtual path relative to the content root — what an edit link points at. */\n file: string;\n absPath: string;\n title: string;\n description: string | null;\n /** Content hash; a new value means `load()` now resolves to a different module. */\n version: string;\n load: () => Promise<PageModule>;\n}\n\nexport interface TocEntry {\n title: ReactNode;\n url: string;\n depth: number;\n}\n\nexport interface PageModule {\n default: ComponentType<{ components?: Record<string, unknown> }>;\n /** Exported by fumadocs' `rehype-toc`. */\n toc?: TocEntry[];\n}\n","import type { Feature, FeatureFlag, ResolvedFeatures } from '../../shared/types.js';\n\n/**\n * Feature flags.\n *\n * MkDocs Material's model — one flat list of dotted strings — but typed as a union, which\n * their YAML cannot do. Because seemore has default-on features where MkDocs has none, the\n * list is additive over the defaults and a `!` prefix turns a default-on feature off.\n */\n\nexport { FEATURES } from '../../shared/types.js';\nexport type { Feature, FeatureFlag, ResolvedFeatures } from '../../shared/types.js';\n\nexport const FEATURE_DEFAULTS: Record<Feature, boolean> = {\n 'navigation.instant.prefetch': true,\n 'navigation.instant.preview': false,\n 'navigation.footer': true,\n 'navigation.top': true,\n 'navigation.path': false,\n 'navigation.sections': false,\n 'navigation.prune': false,\n 'toc.follow': true,\n 'toc.integrate': false,\n 'content.code.copy': true,\n // Implicitly on when `editLink` is configured; there is nothing to link to otherwise.\n 'content.action.edit': false,\n // On by default, but only ever active in dev: the stamping that makes a block editable is\n // not emitted by `seemore build`, and the endpoint that writes is registered only by the\n // dev server. Switch it off with '!content.edit'.\n 'content.edit': true,\n 'content.image.zoom': true,\n 'search.suggest': true,\n 'search.highlight': true,\n 'social.cards': false,\n};\n\nexport function isFeatureEnabled(features: ResolvedFeatures, feature: Feature): boolean {\n return features[feature];\n}\n\n/**\n * Rules the flag set must satisfy. MkDocs reports its equivalents in prose and lets the\n * site build wrong; we fail in the config loader with the fix in the message.\n */\ntype Rule =\n | { kind: 'conflict'; a: Feature; b: Feature; why: string }\n | { kind: 'requires'; flag: Feature; needs: Feature; why: string };\n\nconst RULES: Rule[] = [\n {\n kind: 'conflict',\n a: 'toc.integrate',\n b: 'toc.follow',\n why: '`toc.integrate` merges the table of contents into the sidebar, leaving no separate TOC pane for `toc.follow` to scroll.',\n },\n {\n kind: 'requires',\n flag: 'navigation.instant.preview',\n needs: 'navigation.instant.prefetch',\n why: '`navigation.instant.preview` renders the target page in a popover, which is only possible once prefetch has loaded it.',\n },\n];\n\nexport function resolveFeatures(\n input: readonly FeatureFlag[],\n implicit: Partial<ResolvedFeatures> = {},\n): ResolvedFeatures {\n const resolved: ResolvedFeatures = { ...FEATURE_DEFAULTS, ...implicit };\n\n for (const flag of input) {\n const off = flag.startsWith('!');\n const name = (off ? flag.slice(1) : flag) as Feature;\n resolved[name] = !off;\n }\n\n const problems: string[] = [];\n for (const rule of RULES) {\n if (rule.kind === 'conflict') {\n if (!resolved[rule.a] || !resolved[rule.b]) continue;\n const fix = FEATURE_DEFAULTS[rule.b]\n ? `Add '!${rule.b}' to \\`features\\` to switch it off.`\n : `Remove '${rule.b}' from \\`features\\`.`;\n problems.push(`\\`${rule.a}\\` cannot be combined with \\`${rule.b}\\`. ${rule.why} ${fix}`);\n } else if (resolved[rule.flag] && !resolved[rule.needs]) {\n problems.push(\n `\\`${rule.flag}\\` requires \\`${rule.needs}\\`, which is switched off. ${rule.why}`,\n );\n }\n }\n\n if (problems.length > 0) {\n throw new Error(\n `Incompatible \\`features\\` in seemore config:\\n${problems.map((p) => ` - ${p}`).join('\\n')}`,\n );\n }\n\n return resolved;\n}\n","import { z } from 'zod';\nimport { FEATURES, type FeatureFlag, type ResolvedFeatures } from './features.js';\n\n/** The CSS presets fumadocs-ui ships. We do not invent a token system. */\nexport const THEMES = [\n 'neutral',\n 'black',\n 'catppuccin',\n 'dusk',\n 'ocean',\n 'purple',\n 'ruby',\n 'solar',\n 'aspen',\n 'emerald',\n 'vitepress',\n 'shadcn',\n] as const;\n\nexport type Theme = (typeof THEMES)[number];\n\nconst featureFlag = z.enum([...FEATURES, ...FEATURES.map((f) => `!${f}` as const)] as [string, ...string[]]);\n\nconst navItem: z.ZodType<NavItem> = z.lazy(() =>\n z.object({\n text: z.string(),\n link: z.string().optional(),\n items: z.array(navItem).optional(),\n }),\n);\n\nexport interface NavItem {\n text: string;\n link?: string;\n items?: NavItem[];\n}\n\nconst searchSchema = z.union([\n z.literal('static'),\n z.object({ provider: z.literal('static') }),\n z.object({\n provider: z.literal('orama-cloud'),\n endpoint: z.string(),\n apiKey: z.string(),\n }),\n z.object({\n provider: z.literal('algolia'),\n appId: z.string(),\n apiKey: z.string(),\n indexName: z.string(),\n }),\n]);\n\nexport const configSchema = z.object({\n /**\n * Optional here, but required whenever a config file exists — load.ts enforces that,\n * since it knows whether the config came from a file or from the no-config quickstart,\n * where the fallback is the only sensible name.\n */\n title: z.string().optional(),\n description: z.string().optional(),\n favicon: z.string().optional(),\n /** Subpath the site is served from, e.g. `/my-repo/`. Never inferred. */\n base: z.string().optional(),\n theme: z.enum(THEMES).default('neutral'),\n /** A CSS file appended after everything else, so it wins. */\n css: z.string().optional(),\n features: z.array(featureFlag).default([]),\n nav: z.array(navItem).optional(),\n footer: z\n .object({\n text: z.string().optional(),\n links: z.array(z.object({ text: z.string(), link: z.string() })).optional(),\n })\n .optional(),\n editLink: z\n .object({\n base: z.string(),\n text: z.string().default('Edit this page'),\n })\n .optional(),\n search: searchSchema.default('static'),\n exclude: z.array(z.string()).default([]),\n});\n\n/** What a user writes in `seemore.config.ts`. */\nexport type SeemoreConfig = Omit<z.input<typeof configSchema>, 'features' | 'theme' | 'search'> & {\n features?: FeatureFlag[];\n theme?: Theme;\n search?: z.input<typeof searchSchema>;\n};\n\nexport type SearchConfig =\n | { provider: 'static' }\n | { provider: 'orama-cloud'; endpoint: string; apiKey: string }\n | { provider: 'algolia'; appId: string; apiKey: string; indexName: string };\n\n/** What the rest of seemore consumes: every optional filled in, every path absolute. */\nexport interface ResolvedSeemoreConfig {\n title: string;\n description?: string;\n favicon?: string;\n /** Always normalised to leading + trailing slash. */\n base: string;\n theme: Theme;\n /** Absolute path, resolved against the config file's directory. */\n css?: string;\n features: ResolvedFeatures;\n nav?: NavItem[];\n footer?: { text?: string; links?: { text: string; link: string }[] };\n editLink?: { base: string; text: string };\n search: SearchConfig;\n exclude: string[];\n /** Directory the config was resolved from — relative paths in it hang off this. */\n root: string;\n /** Absolute path of the config file, when there is one. */\n configFile?: string;\n}\n","import { slug as slugify } from 'github-slugger';\nimport { isExternalHref, withBase } from '../base.js';\nimport type { ContentPage } from './scan.js';\nimport { slugifySegment, toPosix } from './slug.js';\n\nconst CONTENT_EXT = /\\.mdx?$/i;\n\nexport interface ResolvedLink {\n /** The href to emit. Unchanged from the input when nothing needed resolving. */\n href: string;\n warning?: string;\n}\n\nexport interface ResolvedWikilink {\n /** `undefined` when the target does not exist — render the label as plain text. */\n href?: string;\n label: string;\n warning?: string;\n}\n\nexport interface LinkResolver {\n /** Relative `.md`/`.mdx` links → routes. Everything else passes through untouched. */\n resolveHref(href: string, fromFile: string): ResolvedLink;\n /** The inside of a `[[…]]`, i.e. `Target`, `Target|label`, `Target#Heading`, or both. */\n resolveWikilink(target: string, fromFile: string): ResolvedWikilink;\n}\n\nexport function createLinkResolver(pages: readonly ContentPage[], base: string): LinkResolver {\n /** `guide/deep-dive` (extension stripped, original casing) → page. */\n const byPath = new Map<string, ContentPage>();\n /** Lowercased basename, and its slugified form → every page that answers to it. */\n const byName = new Map<string, ContentPage[]>();\n\n const add = (map: Map<string, ContentPage[]>, key: string, page: ContentPage) => {\n const bucket = map.get(key);\n if (bucket) bucket.push(page);\n else map.set(key, [page]);\n };\n\n for (const page of pages) {\n const withoutExt = page.file.replace(CONTENT_EXT, '');\n byPath.set(withoutExt.toLowerCase(), page);\n byPath.set(page.file.toLowerCase(), page);\n // A directory index answers to its directory, so `[[guide]]` finds `guide/index.md`.\n if (page.isIndex) {\n const dir = withoutExt.split('/').slice(0, -1).join('/');\n if (dir !== '') byPath.set(dir.toLowerCase(), page);\n }\n\n const basename = withoutExt.split('/').pop() ?? '';\n add(byName, basename.toLowerCase(), page);\n const slugged = slugifySegment(basename);\n if (slugged !== basename.toLowerCase()) add(byName, slugged, page);\n }\n\n /** Shallowest path first, then alphabetically — stable regardless of scan order. */\n const pick = (candidates: ContentPage[]): ContentPage =>\n [...candidates].sort((a, b) => {\n const depth = a.file.split('/').length - b.file.split('/').length;\n return depth !== 0 ? depth : a.file.localeCompare(b.file);\n })[0]!;\n\n function lookup(target: string): { page?: ContentPage; ambiguous?: ContentPage[] } {\n const cleaned = toPosix(target).replace(/^\\/+/, '').replace(CONTENT_EXT, '');\n const key = cleaned.toLowerCase();\n\n // 1. Exact path match relative to the content root.\n const exact = byPath.get(key);\n if (exact) return { page: exact };\n\n // 2 and 3. Basename match, then slugified basename match.\n const named = byName.get(key) ?? byName.get(slugifySegment(cleaned));\n if (named === undefined || named.length === 0) return {};\n if (named.length === 1) return { page: named[0]! };\n return { page: pick(named), ambiguous: named };\n }\n\n function href(page: ContentPage, hash: string | undefined): string {\n const url = withBase(base, page.url);\n return hash === undefined ? url : `${url}#${slugify(hash)}`;\n }\n\n return {\n resolveHref(raw, fromFile) {\n if (isExternalHref(raw) && !raw.startsWith('.') && !CONTENT_EXT.test(raw.split('#')[0] ?? '')) {\n return { href: raw };\n }\n const [pathPart = '', hashPart] = splitHash(raw);\n if (!CONTENT_EXT.test(pathPart)) return { href: raw };\n\n // A leading slash means \"from the content root\", so the linking file's directory is\n // not the starting point.\n const fromDir = pathPart.startsWith('/') ? [] : toPosix(fromFile).split('/').slice(0, -1);\n const resolved = joinPosix(fromDir, pathPart);\n const page = byPath.get(resolved.toLowerCase());\n\n if (page === undefined) {\n return {\n href: raw,\n warning: `Broken link ${raw} in ${toPosix(fromFile)}: no page at ${resolved}.`,\n };\n }\n return { href: href(page, hashPart) };\n },\n\n resolveWikilink(target, fromFile) {\n const pipe = target.indexOf('|');\n const linkPart = (pipe === -1 ? target : target.slice(0, pipe)).trim();\n const label = (pipe === -1 ? target : target.slice(pipe + 1)).trim();\n const [pathPart = '', hashPart] = splitHash(linkPart);\n\n const { page, ambiguous } = lookup(pathPart);\n if (page === undefined) {\n return {\n label,\n warning: `Dead wikilink [[${target}]] in ${toPosix(fromFile)}: no page matches \"${pathPart}\".`,\n };\n }\n\n const warning =\n ambiguous === undefined\n ? undefined\n : `Ambiguous wikilink [[${target}]] in ${toPosix(fromFile)}: matches ${ambiguous\n .map((c) => c.file)\n .sort()\n .join(', ')}. Using ${page.file}.`;\n\n return { href: href(page, hashPart), label, warning };\n },\n };\n}\n\nfunction splitHash(value: string): [string, string | undefined] {\n const index = value.indexOf('#');\n if (index === -1) return [value, undefined];\n return [value.slice(0, index), value.slice(index + 1)];\n}\n\n/** Resolve `./a`, `../a`, `a` against a directory, without touching the real filesystem. */\nfunction joinPosix(fromDir: readonly string[], relative: string): string {\n const segments = [...fromDir];\n for (const part of toPosix(relative).split('/')) {\n if (part === '' || part === '.') continue;\n if (part === '..') segments.pop();\n else segments.push(part);\n }\n return segments.join('/').replace(CONTENT_EXT, '');\n}\n","/**\n * Path → URL resolution.\n *\n * One slug algorithm, `github-slugger`, is used for URLs, heading anchors and the search\n * index alike — it is already a fumadocs dependency, so agreeing with it is free.\n */\nimport { slug as slugify } from 'github-slugger';\n\nconst INDEX_NAMES = new Set(['index', 'readme']);\nconst CONTENT_EXT = /\\.mdx?$/i;\n\nexport interface RouteInfo {\n /** Virtual path relative to the content root, posix separators. */\n file: string;\n /** Route URL: leading slash, never a trailing slash. The site root is `/`. */\n url: string;\n /** Slug segments; the site root is the empty array. */\n slugs: string[];\n /** Path of the emitted HTML relative to `dist/`. */\n output: string;\n /** Whether this file stands for its directory rather than for itself. */\n isIndex: boolean;\n}\n\n/** Normalise a possibly-Windows path to a posix virtual path. */\nexport function toPosix(file: string): string {\n return file.replace(/\\\\/g, '/').replace(/^\\.\\//, '').replace(/^\\/+/, '');\n}\n\n/**\n * Slugify a single path segment. Segments that slugify to nothing (`...`, emoji-only) fall\n * back to a lowercased, punctuation-stripped form so that a URL is never empty.\n */\nexport function slugifySegment(segment: string): string {\n const slugged = slugify(segment);\n if (slugged !== '') return slugged;\n const fallback = segment.toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, '-').replace(/^-+|-+$/g, '');\n return fallback === '' ? 'untitled' : fallback;\n}\n\nexport function toRoute(file: string): RouteInfo {\n const posix = toPosix(file);\n const segments = posix.split('/');\n const basename = segments.pop() ?? '';\n const stem = basename.replace(CONTENT_EXT, '');\n const isIndex = INDEX_NAMES.has(stem.toLowerCase());\n\n const slugs = segments.map(slugifySegment);\n if (!isIndex) slugs.push(slugifySegment(stem));\n\n return {\n file: posix,\n url: slugs.length === 0 ? '/' : `/${slugs.join('/')}`,\n slugs,\n output: [...slugs, 'index.html'].join('/'),\n isIndex,\n };\n}\n\nexport interface ResolvedRoutes {\n routes: RouteInfo[];\n /** Conditions that make the site silently wrong — a build error. */\n errors: string[];\n /** Conditions that are visible on the page itself — a warning. */\n warnings: string[];\n}\n\n/**\n * Resolve a whole corpus at once, because the interesting failures are corpus-level:\n * `index.md` vs `README.md` in one directory, and two different files slugifying alike.\n */\nexport function resolveRoutes(files: string[]): ResolvedRoutes {\n const sorted = [...files].map(toPosix).sort();\n const byUrl = new Map<string, RouteInfo[]>();\n const warnings: string[] = [];\n const errors: string[] = [];\n\n for (const file of sorted) {\n const route = toRoute(file);\n const bucket = byUrl.get(route.url);\n if (bucket) bucket.push(route);\n else byUrl.set(route.url, [route]);\n }\n\n const routes: RouteInfo[] = [];\n for (const [url, candidates] of [...byUrl.entries()].sort(([a], [b]) => (a < b ? -1 : 1))) {\n if (candidates.length === 1) {\n routes.push(candidates[0]!);\n continue;\n }\n\n // `index.md` beating `README.md` is a documented preference, not a collision.\n const indexes = candidates.filter((c) => c.isIndex);\n if (indexes.length === candidates.length) {\n const winner =\n indexes.find((c) => c.file.split('/').pop()?.toLowerCase().startsWith('index')) ?? indexes[0]!;\n const losers = indexes.filter((c) => c !== winner);\n warnings.push(\n `${url} has more than one index file: using ${winner.file}, ignoring ${losers\n .map((l) => l.file)\n .join(', ')}.`,\n );\n routes.push(winner);\n continue;\n }\n\n errors.push(\n `Duplicate route ${url} produced by ${candidates.length} files:\\n` +\n candidates.map((c) => ` - ${c.file}`).join('\\n') +\n `\\nRename one of them, or exclude it with \\`exclude\\` in seemore.config.ts.`,\n );\n }\n\n return { routes, errors, warnings };\n}\n","import { dynamicLoader } from 'fumadocs-core/source';\nimport type { Root } from 'fumadocs-core/page-tree';\nimport { scan, type ContentPage, type ScanOptions, type ScanResult } from './scan.js';\n\nexport interface SeemoreSource {\n /** The most recent scan. Never triggers filesystem work. */\n current(): ScanResult;\n /** Re-read the corpus and let fumadocs decide what changed. */\n refresh(): ScanResult;\n getPageTree(): Promise<Root>;\n /** Serialized for the browser — the payload of `virtual:seemore/tree`. */\n serializeTree(): Promise<unknown>;\n pages(): ContentPage[];\n loader: ReturnType<typeof dynamicLoader>;\n}\n\n/**\n * Wire the scanner to fumadocs' dynamic loader.\n *\n * `cache: 'custom'` puts us in charge of when a scan happens: the watcher calls\n * {@link SeemoreSource.refresh}, and fumadocs recomputes the page tree because the array\n * identity changed. Between refreshes `files()` hands back the same array, so reading the\n * tree is free.\n */\nexport function createSource(options: ScanOptions): SeemoreSource {\n let cached: ScanResult | undefined;\n\n const read = (): ScanResult => (cached ??= scan(options));\n\n const loader = dynamicLoader(\n {\n cache: 'custom',\n files: () => read().files,\n invalidate: () => {\n cached = undefined;\n },\n },\n { baseUrl: '/' },\n );\n\n return {\n loader,\n current: read,\n pages: () => read().pages,\n refresh() {\n loader.invalidate();\n return read();\n },\n async getPageTree() {\n const output = await loader.get();\n return output.getPageTree();\n },\n async serializeTree() {\n const output = await loader.get();\n return output.serializePageTree(output.getPageTree());\n },\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { createHash } from 'node:crypto';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { globSync } from 'tinyglobby';\nimport { z } from 'zod';\nimport type { VirtualFile } from 'fumadocs-core/source';\nimport { parseFrontmatter, type FrontmatterData } from './frontmatter.js';\nimport { resolveRoutes, toPosix, type RouteInfo } from './slug.js';\n\n/** Appended to, never replaced by, `config.exclude`. */\nexport const DEFAULT_EXCLUDES = [\n '**/node_modules/**',\n '**/.git/**',\n '**/dist/**',\n '**/build/**',\n '**/out/**',\n '**/vendor/**',\n '**/target/**',\n '**/venv/**',\n '**/deps/**',\n '**/Pods/**',\n '**/bower_components/**',\n '**/.seemore/**',\n '**/.*/**',\n '**/.*',\n];\n\n/** fumadocs' `meta.json` shape, validated so a typo reports a file rather than a blank folder. */\nconst metaSchema = z\n .object({\n title: z.string().optional(),\n icon: z.string().optional(),\n root: z.boolean().optional(),\n pages: z.array(z.string()).optional(),\n pagesIndex: z.string().optional(),\n defaultOpen: z.boolean().optional(),\n collapsible: z.boolean().optional(),\n description: z.string().optional(),\n })\n .loose();\n\nexport interface ContentPage extends RouteInfo {\n /** Absolute path on disk — what the generated import map imports. */\n absPath: string;\n /**\n * Hash of the file's text. Changes exactly when the module behind the URL does, which is\n * what lets the browser tell \"this page was edited\" from \"some other page was\".\n */\n version: string;\n data: FrontmatterData & { title: string };\n}\n\nexport interface ScanResult {\n /** What fumadocs' loader consumes. */\n files: VirtualFile[];\n /** What the router, prefetch map and prerender driver consume. */\n pages: ContentPage[];\n errors: string[];\n warnings: string[];\n}\n\nexport interface ScanOptions {\n contentRoot: string;\n exclude?: string[];\n /** Used as the title of a root index page that has no frontmatter title. */\n siteTitle?: string;\n /** Dev keeps drafts so they can be written; the build drops them. */\n includeDrafts?: boolean;\n}\n\nexport function scan(options: ScanOptions): ScanResult {\n const contentRoot = resolve(options.contentRoot);\n const ignore = [...DEFAULT_EXCLUDES, ...(options.exclude ?? [])];\n\n const contentFiles = globSync(['**/*.md', '**/*.mdx'], {\n cwd: contentRoot,\n ignore,\n dot: false,\n absolute: false,\n }).map(toPosix);\n\n const metaFiles = globSync(['**/meta.json'], { cwd: contentRoot, ignore, dot: false, absolute: false }).map(toPosix);\n\n const { routes, errors, warnings } = resolveRoutes(contentFiles);\n\n const pages: ContentPage[] = [];\n for (const route of routes) {\n const absPath = join(contentRoot, route.file);\n let data: FrontmatterData;\n let version: string;\n try {\n const text = readFileSync(absPath, 'utf8');\n data = parseFrontmatter(text, route.file).data;\n version = createHash('sha256').update(text).digest('hex').slice(0, 12);\n } catch (error) {\n errors.push(error instanceof Error ? error.message : String(error));\n continue;\n }\n\n if (data.draft === true && options.includeDrafts !== true) continue;\n\n pages.push({ ...route, absPath, version, data: { ...data, title: titleFor(route, data, options.siteTitle) } });\n }\n\n const files: VirtualFile[] = pages.map((page) => ({\n type: 'page',\n path: page.file,\n absolutePath: page.absPath,\n // Our slugs, not fumadocs' — one algorithm decides URLs, anchors and the index.\n slugs: page.slugs,\n data: page.data,\n }));\n\n const metaDirs = new Set<string>();\n for (const file of metaFiles) {\n const absPath = join(contentRoot, file);\n try {\n const parsed = metaSchema.safeParse(JSON.parse(readFileSync(absPath, 'utf8')));\n if (!parsed.success) {\n errors.push(\n `Invalid ${file}:\\n${parsed.error.issues.map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`).join('\\n')}`,\n );\n continue;\n }\n metaDirs.add(dirname(file));\n files.push({ type: 'meta', path: file, absolutePath: absPath, data: parsed.data });\n } catch (error) {\n errors.push(`Invalid ${file}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n files.push(...synthesiseOrderMeta(pages, metaDirs));\n\n return { files, pages, errors, warnings };\n}\n\n/**\n * Ordering: a real `meta.json` wins; otherwise frontmatter `order` decides, then\n * title. fumadocs has no native `order`, so we express the intent in the mechanism it does\n * have — a synthetic `meta.json` whose `pages` list ends in the `...` rest marker, leaving\n * anything we did not mention in fumadocs' own alphabetical order.\n */\nfunction synthesiseOrderMeta(pages: ContentPage[], metaDirs: Set<string>): VirtualFile[] {\n const byDir = new Map<string, ContentPage[]>();\n for (const page of pages) {\n const dir = dirname(page.file);\n const bucket = byDir.get(dir);\n if (bucket) bucket.push(page);\n else byDir.set(dir, [page]);\n }\n\n const out: VirtualFile[] = [];\n for (const [dir, dirPages] of byDir) {\n if (metaDirs.has(dir)) continue;\n // Nothing to express unless something wants to move: an explicit `order`, or an index\n // page that would otherwise sort alphabetically into the middle of its own directory.\n if (!dirPages.some((p) => typeof p.data.order === 'number' || p.isIndex)) continue;\n\n const ordered = [...dirPages].sort(compareForOrder).map((p) => basename(p.file).replace(/\\.mdx?$/i, ''));\n\n out.push({\n type: 'meta',\n path: dir === '.' ? 'meta.json' : `${dir}/meta.json`,\n data: { pages: [...ordered, '...'] },\n });\n }\n return out;\n}\n\nfunction compareForOrder(a: ContentPage, b: ContentPage): number {\n // An index page stands for its directory, so it leads unless it asks not to.\n const ao = orderOf(a);\n const bo = orderOf(b);\n if (ao !== bo) return ao - bo;\n return a.data.title.localeCompare(b.data.title);\n}\n\nfunction orderOf(page: ContentPage): number {\n if (typeof page.data.order === 'number') return page.data.order;\n return page.isIndex ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY;\n}\n\nfunction titleFor(route: RouteInfo, data: FrontmatterData, siteTitle: string | undefined): string {\n if (typeof data.title === 'string' && data.title !== '') return data.title;\n if (route.url === '/') return siteTitle ?? 'Home';\n return humanise(route.slugs[route.slugs.length - 1] ?? 'Untitled');\n}\n\n/** `getting-started` → `Getting Started`. Good enough to never show a raw slug in a sidebar. */\nfunction humanise(slug: string): string {\n return slug\n .split('-')\n .filter((word) => word !== '')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n","import matter from 'gray-matter';\nimport { z } from 'zod';\n\n/**\n * Frontmatter is validated, not restricted: unknown keys pass through so that a corpus\n * written for another tool still builds. Only the keys seemore acts on are typed.\n */\nexport const frontmatterSchema = z\n .object({\n title: z.string().optional(),\n description: z.string().optional(),\n icon: z.string().optional(),\n /** Sidebar ordering, second only to `meta.json`. */\n order: z.number().optional(),\n /**\n * Excluded from the build. Dev keeps drafts so they can be written, so a link to one\n * works while you write it and warns as a dead link when you build.\n */\n draft: z.boolean().optional(),\n })\n .loose();\n\nexport type FrontmatterData = z.output<typeof frontmatterSchema> & Record<string, unknown>;\n\n/** Split a source file into validated frontmatter and body. `file` is only for messages. */\nexport function parseFrontmatter(source: string, file: string): { data: FrontmatterData; content: string } {\n let parsed;\n try {\n parsed = matter(source);\n } catch (error) {\n throw new Error(\n `Invalid frontmatter in ${file}: ${error instanceof Error ? error.message.split('\\n')[0] : String(error)}`,\n { cause: error },\n );\n }\n\n return { data: validateFrontmatter(parsed.data, file), content: parsed.content };\n}\n\nexport function validateFrontmatter(data: unknown, file: string): FrontmatterData {\n const result = frontmatterSchema.safeParse(data ?? {});\n if (result.success) return result.data as FrontmatterData;\n\n const issues = result.error.issues.map((issue) => {\n const field = issue.path.length === 0 ? '(root)' : issue.path.join('.');\n return ` - ${field}: ${issue.message}`;\n });\n throw new Error(`Invalid frontmatter in ${file}:\\n${issues.join('\\n')}`);\n}\n","import pc from 'picocolors';\n\n/**\n * Warnings are collected and printed once, as a grouped summary, rather than interleaved\n * with progress output — a build that prints forty warnings between chunks is a\n * build whose warnings nobody reads.\n */\nexport interface WarningCollector {\n add(message: string): void;\n list(): string[];\n clear(): void;\n /** Print the grouped summary. Returns the number of warnings printed. */\n flush(log?: (line: string) => void): number;\n}\n\nexport function createWarningCollector(): WarningCollector {\n const seen = new Set<string>();\n\n return {\n add(message) {\n seen.add(message);\n },\n list: () => [...seen],\n clear: () => seen.clear(),\n flush(log = console.warn) {\n const messages = [...seen].sort();\n seen.clear();\n if (messages.length === 0) return 0;\n log('');\n log(pc.yellow(`${messages.length} warning${messages.length === 1 ? '' : 's'}:`));\n for (const message of messages) log(pc.yellow(` - ${message}`));\n log('');\n return messages.length;\n },\n };\n}\n","import { createLinkResolver, type LinkResolver } from './content/links.js';\nimport type { ContentPage, ScanResult } from './content/scan.js';\nimport { createSource, type SeemoreSource } from './content/source.js';\nimport type { ResolvedSeemoreConfig } from './config/schema.js';\nimport { createWarningCollector, type WarningCollector } from './report.js';\n\nexport interface SeemoreContext {\n config: ResolvedSeemoreConfig;\n /** Absolute path of the directory being documented. Usually outside the Vite root. */\n contentRoot: string;\n source: SeemoreSource;\n warnings: WarningCollector;\n pages(): ContentPage[];\n /** Rebuilt on every refresh, so remark plugins must read it late. */\n resolver(): LinkResolver;\n /** Re-read the corpus after a filesystem change. */\n refresh(): ScanResult;\n /** Slug collisions and frontmatter failures found by the most recent scan. */\n errors(): string[];\n}\n\nexport interface CreateContextOptions {\n config: ResolvedSeemoreConfig;\n contentRoot: string;\n /** Dev keeps drafts so they can be written; the build drops them. */\n includeDrafts?: boolean;\n}\n\nexport function createContext(options: CreateContextOptions): SeemoreContext {\n const { config, contentRoot } = options;\n\n const source = createSource({\n contentRoot,\n exclude: config.exclude,\n siteTitle: config.title,\n includeDrafts: options.includeDrafts,\n });\n\n let resolver = createLinkResolver(source.pages(), config.base);\n\n return {\n config,\n contentRoot,\n source,\n warnings: createWarningCollector(),\n pages: () => source.pages(),\n resolver: () => resolver,\n errors: () => source.current().errors,\n refresh() {\n const result = source.refresh();\n resolver = createLinkResolver(result.pages, config.base);\n return result;\n },\n };\n}\n","import { mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\n/** Turn a route URL into the file that serves it. */\nexport function outputPathFor(url: string): string {\n const clean = url.replace(/^\\/+|\\/+$/g, '');\n return clean === '' ? 'index.html' : join(clean, 'index.html');\n}\n\nexport function writeHtml(outDir: string, relativePath: string, html: string): void {\n const target = join(outDir, relativePath);\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, html, 'utf8');\n}\n\n/**\n * Inject a rendered page into the client build's `index.html`.\n *\n * The template already carries the hashed script and stylesheet Vite emitted, so the markup\n * and the assets can never drift apart.\n */\nexport function applyTemplate(template: string, { html, head }: { html: string; head: string }): string {\n // Replacer functions, not strings: a page containing `$&` or `` $` `` would otherwise\n // splice the marker — or the whole document head — into its own body.\n return template.replace('<!--seemore-head-->', () => head).replace('<!--seemore-app-->', () => html);\n}\n","import { writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Host conventions.\n *\n * The portable output is everything else: one real `index.html` per route, plus `404.html`,\n * which every static host honours. These files are additive — small, named conventions that\n * particular hosts look for — not a list of hosts seemore supports.\n */\nexport function writeDeployArtifacts(outDir: string, base: string, shell: string): void {\n const prefix = base === '/' ? '' : base.replace(/\\/+$/, '');\n\n // Netlify and Cloudflare Pages share this format. It applies after the real files they\n // already serve, so it only catches addresses that do not exist.\n writeFileSync(join(outDir, '_redirects'), `${prefix}/* ${prefix}/index.html 200\\n`, 'utf8');\n\n // Surge looks for `200.html` as its SPA fallback.\n writeFileSync(join(outDir, '200.html'), shell, 'utf8');\n\n // GitHub Pages runs the output through Jekyll unless this file exists, and Jekyll drops\n // every file and directory whose name starts with `_`. A `docs/_internal/` folder would\n // build correctly and then 404 once deployed — the exact failure seemore exists to prevent.\n writeFileSync(join(outDir, '.nojekyll'), '', 'utf8');\n}\n","import { pathToFileURL } from 'node:url';\nimport { join } from 'node:path';\nimport { build } from 'vite';\nimport type { SeemoreContext } from '../context.js';\nimport { createViteConfig } from '../vite/config.js';\n\nexport interface RenderResult {\n html: string;\n head: string;\n}\n\nexport interface PrerenderModule {\n render(url: string): Promise<RenderResult>;\n listRoutes(): string[];\n}\n\n/**\n * Build the prerender entry for node and load it.\n *\n * This is a second Vite build rather than a reuse of the client bundle because the client\n * bundle is compiled for the browser; the driver needs the same module graph evaluated in\n * node, with the same virtual modules, so the two can never describe different sites.\n */\nexport async function loadPrerenderModule(ctx: SeemoreContext, ssrOutDir: string): Promise<PrerenderModule> {\n await build(createViteConfig({ ctx, mode: 'build', ssrOutDir }));\n\n const entry = join(ssrOutDir, 'entry.prerender.js');\n const loaded = (await import(pathToFileURL(entry).href)) as Partial<PrerenderModule>;\n\n if (typeof loaded.render !== 'function' || typeof loaded.listRoutes !== 'function') {\n throw new Error(`seemore: the prerender build at ${entry} did not export \\`render\\` and \\`listRoutes\\`.`);\n }\n\n return { render: loaded.render, listRoutes: loaded.listRoutes };\n}\n","import { realpathSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { join } from 'node:path';\nimport type { InlineConfig, Plugin } from 'vite';\nimport react from '@vitejs/plugin-react';\nimport tailwindcss from '@tailwindcss/vite';\nimport mdx from '@mdx-js/rollup';\nimport type { SeemoreContext } from '../context.js';\nimport { appRoot, cacheDir, packageDirOf, packageRoot } from '../paths.js';\nimport { createRehypePlugins, createRemarkPlugins } from './mdx.js';\nimport { seemorePlugin } from './plugin.js';\nimport { seemoreWatcherPlugin } from './watcher.js';\n\nconst require_ = createRequire(import.meta.url);\n\n/**\n * `@terrastruct/d2`'s `exports` map only picks its browser bundle when a `browser`\n * condition is present. Dev's `worker`-only condition set below deliberately excludes it\n * (see the comment there), and even build's own defaults are one more custom `conditions`\n * tweak away from excluding it by accident again — so this resolves it directly rather than\n * leaning on whatever the shared condition set happens to be.\n */\nfunction d2BrowserEntry(): string {\n const entry = require_.resolve('@terrastruct/d2');\n return join(packageDirOf('@terrastruct/d2', entry), 'dist', 'browser', 'index.js');\n}\n\nexport interface ViteConfigOptions {\n ctx: SeemoreContext;\n mode: 'dev' | 'build';\n /** Absolute output directory. Ignored in dev. */\n outDir?: string;\n /** When set, build the prerender entry for node instead of the client bundle. */\n ssrOutDir?: string;\n}\n\nexport function createViteConfig({ ctx, mode, outDir, ssrOutDir }: ViteConfigOptions): InlineConfig {\n const root = appRoot();\n const isSsr = ssrOutDir !== undefined;\n\n const mdxOptions = {\n // `format` is inferred per file, so a plain `.md` never needs MDX syntax.\n remarkPlugins: createRemarkPlugins({\n contentRoot: ctx.contentRoot,\n getResolver: () => ctx.resolver(),\n onWarning: (message) => ctx.warnings.add(message),\n }),\n rehypePlugins: createRehypePlugins({ positions: mode === 'dev' && ctx.config.features['content.edit'] }),\n // MDX compiles its own JSX. Vite's builtin transform infers a file's language from its\n // extension and does not know `.md`/`.mdx`, so leaving JSX in the output would fail to\n // parse. Fast Refresh is unaffected: it is a separate transform, applied to these files\n // through the React plugin's `include` below, which is what turns a content edit into an\n // in-place component swap rather than a reload.\n jsx: false,\n };\n\n return {\n root,\n base: ctx.config.base,\n cacheDir: cacheDir(ctx.contentRoot),\n configFile: false,\n envDir: false,\n clearScreen: false,\n logLevel: mode === 'build' ? 'warn' : 'info',\n\n plugins: [\n // Order matters: MDX first, then React, so JSX from MDX is transformed and refreshed.\n { ...mdx(mdxOptions), enforce: 'pre' },\n react({ include: /\\.(?:mdx?|jsx?|tsx?)$/ }),\n // Before Tailwind: our plugin injects the theme preset into the root stylesheet, and\n // Tailwind must see the injected version.\n seemorePlugin({ ctx, serveSearch: mode === 'dev' }),\n tailwindcss(),\n ...(mode === 'dev' ? [seemoreWatcherPlugin(ctx)] : []),\n ],\n\n // Vite bundles workers with the browser export condition, but a worker has no `document`.\n // `decode-named-character-reference` — pulled in through fumadocs' search client, via\n // remark — calls `document.createElement` at module scope in its browser build, so the\n // search worker threw on load. The package ships a DOM-free `worker` entry; use it.\n worker: { plugins: () => [workerConditionPlugin()] },\n\n resolve: {\n // The app is compiled from seemore's own sources, so its dependencies must resolve\n // from seemore's directory rather than from the user's project.\n dedupe: ['react', 'react-dom', 'react-router', 'fumadocs-core', 'fumadocs-ui'],\n // Not needed for the SSR bundle: the dynamic `import('@terrastruct/d2')` inside `D2`'s\n // effect never actually runs there (effects don't run during prerendering), but Rollup\n // still bundles it as a reachable chunk, and Vite's own server conditions already point\n // that at the Node build — which is what actually running in Node would want anyway.\n alias: isSsr ? undefined : [{ find: '@terrastruct/d2', replacement: d2BrowserEntry() }],\n // In dev the module worker is served through the shared module graph and its fumadocs\n // chunk comes from the dep optimizer, where `worker.plugins` never runs — the browser\n // build of `decode-named-character-reference` is inlined into the prebundle and the\n // worker throws on load. Adding the package's own `worker` condition graph-wide flips\n // the whole dev graph (main thread included) to its DOM-free build, which behaves the\n // same; production doesn't need it — its worker chunk is a real Rollup build of its own,\n // where the targeted swap above runs. Leaving this unset in production keeps Vite's own\n // default conditions.\n conditions: mode === 'dev' ? ['worker'] : undefined,\n },\n\n server: {\n fs: {\n // The content root is normally *outside* the Vite root, and files outside `allow`\n // 404 silently — the single most likely cause of \"the watcher does nothing\".\n allow: withRealPaths([root, packageRoot(), ctx.contentRoot, ctx.config.root, process.cwd()]),\n },\n watch: {\n // Only real exclusions here. Vite merges these into chokidar's ignore *list*, where a\n // leading `!` is a negated matcher that matches everything it is not — so the obvious\n // `!<contentRoot>/**` \"re-include\" would silently ignore the entire project instead.\n // Content outside the Vite root is watched by seemore's own chokidar instance.\n ignored: ['**/node_modules/**', '**/.git/**'],\n },\n },\n\n build: isSsr\n ? {\n ssr: join(root, 'entry.prerender.tsx'),\n outDir: ssrOutDir,\n emptyOutDir: true,\n copyPublicDir: false,\n minify: false,\n rollupOptions: { output: { entryFileNames: 'entry.prerender.js' } },\n }\n : {\n outDir,\n emptyOutDir: true,\n rollupOptions: { input: join(root, 'index.html') },\n // The app bundle is seemore's own, not the user's; warning them about a size they\n // cannot act on is noise.\n chunkSizeWarningLimit: 2_000,\n },\n\n // The prerender bundle is written to a scratch directory outside any `node_modules`, so\n // it has to be self-contained: an externalised `react` there resolves against the scratch\n // directory and is simply not found.\n ssr: isSsr ? { noExternal: true } : undefined,\n };\n}\n\n/**\n * Every path, plus where it actually points.\n *\n * Vite resolves a module to its real path before checking `fs.allow`, so a content root\n * reached through a symlink — `/var` on macOS, or anything under a linked directory — is\n * denied unless both spellings are listed. The failure is a silent 404, so it is worth the\n * two extra entries.\n */\nfunction withRealPaths(paths: string[]): string[] {\n const out = new Set<string>();\n for (const path of paths) {\n out.add(path);\n try {\n out.add(realpathSync.native(path));\n } catch {\n // A path that does not exist yet cannot be resolved, and does not need to be.\n }\n }\n return [...out];\n}\n\n/**\n * Point worker bundles at the DOM-free build of packages that ship two.\n *\n * Resolution goes through Vite so pnpm's layout is respected — these packages are deep\n * transitive dependencies and are not resolvable from seemore's own directory — and only the\n * final `index.dom.js` is swapped for its sibling.\n */\nfunction workerConditionPlugin(): Plugin {\n return {\n name: 'seemore:worker-conditions',\n enforce: 'pre',\n async resolveId(source, importer, options) {\n if (!WORKER_SAFE_ENTRIES.has(source)) return undefined;\n\n const resolved = await this.resolve(source, importer, options);\n if (resolved === null) return undefined;\n\n const domFree = resolved.id.replace(/index\\.dom\\.js$/, 'index.js');\n return domFree === resolved.id ? resolved : { ...resolved, id: domFree };\n },\n };\n}\n\n/**\n * Packages whose browser build touches the DOM at module scope and whose default build does\n * not. `decode-named-character-reference` reaches the worker through remark, by way of\n * fumadocs' search client.\n */\nconst WORKER_SAFE_ENTRIES = new Set(['decode-named-character-reference']);\n","import type { PluggableList } from 'unified';\nimport remarkFrontmatter from 'remark-frontmatter';\nimport {\n rehypeCode,\n rehypeToc,\n remarkAdmonition,\n remarkDirectiveAdmonition,\n remarkGfm,\n remarkHeading,\n remarkImage,\n remarkMdxMermaid,\n remarkSteps,\n} from 'fumadocs-core/mdx-plugins';\nimport {\n remarkSeemoreAlerts,\n remarkSeemoreAssets,\n remarkSeemoreD2,\n remarkSeemoreLinks,\n remarkSeemoreWikilinks,\n type SeemoreRemarkOptions,\n} from './remark.js';\nimport { rehypeSeemorePositions } from './positions.js';\n\n/**\n * The remark/rehype chain. Order matters:\n *\n * - headings get their ids before `rehype-toc` reads them;\n * - our link rewriting runs after the fumadocs transforms that can create links;\n * - Shiki runs at build time in `rehype-code`, so no highlighter ships to the browser.\n *\n * `remark-structure` is deliberately absent: search indexing runs node-side over the raw\n * markdown, where it works identically in dev and build without depending on a\n * browser module having been evaluated.\n */\nexport function createRemarkPlugins(options: SeemoreRemarkOptions): PluggableList {\n return [\n // Strips the `---` block so it never renders. Its data already came from the scan.\n [remarkFrontmatter, ['yaml']],\n remarkGfm,\n remarkHeading,\n remarkAdmonition,\n remarkDirectiveAdmonition,\n // After the fumadocs admonition plugins, which handle `:::note`, and before anything that\n // rewrites link or text nodes inside the quote.\n remarkSeemoreAlerts,\n remarkSteps,\n // Before `remark-image`: a reference to a file that is not there becomes a warning and a\n // visibly broken image, rather than a failed build.\n () => remarkSeemoreAssets(options),\n [\n remarkImage,\n {\n onError: (error: Error) => {\n options.onWarning(error.message);\n },\n },\n ],\n // Rewrites ```mermaid fences to <Mermaid chart=\"…\" />. We supply the component.\n remarkMdxMermaid,\n // Rewrites ```d2 fences to <D2 chart=\"…\" />, mermaid's sibling for D2 diagrams.\n remarkSeemoreD2,\n () => remarkSeemoreWikilinks(options),\n () => remarkSeemoreLinks(options),\n ];\n}\n\nexport interface SeemoreRehypeOptions {\n /**\n * Stamp each editable block with its source range, for the browser's inline editor.\n * Dev only: a static build has no server to write an edit back to.\n */\n positions?: boolean;\n}\n\nexport function createRehypePlugins(options: SeemoreRehypeOptions = {}): PluggableList {\n return [\n // A fence in a language Shiki has no grammar for (anything an AI dreamt up) is plain code\n // on the page, not a dead one: `plaintext` is special-cased by Shiki and never needs\n // loading.\n [rehypeCode, { fallbackLanguage: 'plaintext' }],\n rehypeToc,\n // After `rehype-code`, so a fence Shiki rebuilt is passed over rather than stamped with\n // the position of whatever it replaced.\n ...(options.positions === true ? [rehypeSeemorePositions] : []),\n ];\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, relative, resolve } from 'node:path';\nimport { visit } from 'unist-util-visit';\nimport type { Blockquote, Code, Image, Paragraph, PhrasingContent, Root, Text } from 'mdast';\nimport type { Transformer } from 'unified';\nimport type { VFile } from 'vfile';\nimport type { LinkResolver } from '../content/links.js';\nimport { toPosix } from '../content/slug.js';\n\nexport interface SeemoreRemarkOptions {\n contentRoot: string;\n /** Read late: the resolver is replaced on every rescan. */\n getResolver: () => LinkResolver;\n onWarning: (message: string) => void;\n}\n\nconst WIKILINK = /\\[\\[([^\\]\\n]+)\\]\\]/g;\n\n/** GitHub's alert syntax, and the fumadocs callout each kind maps onto. */\nconst ALERTS: Record<string, { type: string; title: string }> = {\n NOTE: { type: 'info', title: 'Note' },\n TIP: { type: 'idea', title: 'Tip' },\n IMPORTANT: { type: 'info', title: 'Important' },\n WARNING: { type: 'warn', title: 'Warning' },\n CAUTION: { type: 'error', title: 'Caution' },\n};\n\nconst ALERT_MARKER = /^\\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\]\\s*/;\n\n/**\n * GitHub alerts — `> [!NOTE]` — become fumadocs callouts.\n *\n * fumadocs ships `:::note` and directive admonitions, neither of which is what people\n * actually have in their repositories. seemore points at folders that already exist, so the\n * syntax GitHub renders is the syntax that has to work.\n */\nexport function remarkSeemoreAlerts(): Transformer<Root, Root> {\n return (tree) => {\n visit(tree, 'blockquote', (node: Blockquote, index, parent) => {\n if (parent === undefined || index === undefined) return;\n\n const first = node.children[0];\n if (first === undefined || first.type !== 'paragraph') return;\n\n const marker = ALERT_MARKER.exec(textOf(first));\n const alert = marker === null ? undefined : ALERTS[marker[1] ?? ''];\n if (marker === undefined || marker === null || alert === undefined) return;\n\n stripMarker(first, marker[0]);\n\n parent.children[index] = {\n type: 'mdxJsxFlowElement',\n name: 'Callout',\n attributes: [\n { type: 'mdxJsxAttribute', name: 'type', value: alert.type },\n { type: 'mdxJsxAttribute', name: 'title', value: alert.title },\n ],\n children: node.children,\n } as unknown as Blockquote;\n });\n };\n}\n\n/** The paragraph's leading text, which is where the marker lives. */\nfunction textOf(paragraph: Paragraph): string {\n const first = paragraph.children[0];\n return first !== undefined && first.type === 'text' ? first.value.trimStart() : '';\n}\n\n/** Remove the `[!NOTE]` marker, and the line break that followed it. */\nfunction stripMarker(paragraph: Paragraph, marker: string): void {\n const first = paragraph.children[0];\n if (first === undefined || first.type !== 'text') return;\n\n first.value = first.value.trimStart().slice(marker.length).replace(/^\\n/, '');\n if (first.value === '') paragraph.children.shift();\n if (paragraph.children[0]?.type === 'break') paragraph.children.shift();\n}\n\n/**\n * `[[Page]]`, `[[Page|label]]`, `[[Page#Heading]]`. fumadocs has no equivalent.\n *\n * Unresolved targets become styled plain text rather than dead links, because a link that\n * goes nowhere is worse than visibly missing text.\n */\nexport function remarkSeemoreWikilinks(options: SeemoreRemarkOptions): Transformer<Root, Root> {\n return (tree, file) => {\n const from = virtualPath(options.contentRoot, file);\n const resolver = options.getResolver();\n\n visit(tree, 'text', (node: Text, index, parent) => {\n if (parent === undefined || index === undefined) return;\n if (!node.value.includes('[[')) return;\n\n const replacement: PhrasingContent[] = [];\n let cursor = 0;\n WIKILINK.lastIndex = 0;\n\n for (let match = WIKILINK.exec(node.value); match !== null; match = WIKILINK.exec(node.value)) {\n const target = match[1] ?? '';\n if (match.index > cursor) {\n replacement.push({ type: 'text', value: node.value.slice(cursor, match.index) });\n }\n cursor = match.index + match[0].length;\n\n const resolved = resolver.resolveWikilink(target, from);\n if (resolved.warning !== undefined) options.onWarning(resolved.warning);\n\n if (resolved.href === undefined) {\n // An MDX JSX node, not raw HTML: `.md` files run through `rehypeRemoveRaw`, which\n // would silently drop an `html` node, whereas JSX nodes are passed through.\n replacement.push({\n type: 'mdxJsxTextElement',\n name: 'span',\n attributes: [\n { type: 'mdxJsxAttribute', name: 'className', value: 'seemore-broken-wikilink' },\n { type: 'mdxJsxAttribute', name: 'title', value: 'Unresolved link' },\n ],\n children: [{ type: 'text', value: resolved.label }],\n } as unknown as PhrasingContent);\n } else {\n replacement.push({\n type: 'link',\n url: resolved.href,\n children: [{ type: 'text', value: resolved.label }],\n });\n }\n }\n\n if (replacement.length === 0) return;\n if (cursor < node.value.length) replacement.push({ type: 'text', value: node.value.slice(cursor) });\n\n parent.children.splice(index, 1, ...replacement);\n return index + replacement.length;\n });\n };\n}\n\n/**\n * ```d2 fences become `<D2 chart=\"…\" />` — the sibling of `remark-mdx-mermaid`'s rewrite for\n * ```mermaid, but D2 has no fumadocs-shipped equivalent, so this one is ours.\n */\nexport function remarkSeemoreD2(): Transformer<Root, Root> {\n return (tree) => {\n visit(tree, 'code', (node: Code, index, parent) => {\n if (node.lang !== 'd2' || index === undefined || parent === undefined) return;\n\n parent.children[index] = {\n type: 'mdxJsxFlowElement',\n name: 'D2',\n attributes: [{ type: 'mdxJsxAttribute', name: 'chart', value: node.value.trim() }],\n children: [],\n } as unknown as Code;\n });\n };\n}\n\n/**\n * A referenced asset that is not on disk is a warning, not a build failure: the page is\n * visibly wrong on its own, which is the point of the distinction.\n *\n * It has to run before fumadocs' `remark-image`, which turns every image into a bundler\n * import — and an import of a file that does not exist fails the build. Turning the node\n * into JSX first takes it out of that plugin's way, leaving the broken reference visible on\n * the page exactly as the author wrote it.\n */\nexport function remarkSeemoreAssets(options: SeemoreRemarkOptions): Transformer<Root, Root> {\n return (tree, file) => {\n if (typeof file.path !== 'string' || file.path === '') return;\n const dir = dirname(file.path);\n const from = virtualPath(options.contentRoot, file);\n\n visit(tree, 'image', (node: Image, index, parent) => {\n if (parent === undefined || index === undefined) return;\n if (isExternal(node.url) || node.url.startsWith('/')) return;\n\n const target = resolve(dir, decodeURIComponent(node.url.split(/[?#]/)[0] ?? ''));\n if (existsSync(target)) return;\n\n options.onWarning(`Missing asset ${node.url} referenced by ${from}.`);\n\n parent.children.splice(index, 1, {\n type: 'mdxJsxTextElement',\n name: 'img',\n attributes: [\n { type: 'mdxJsxAttribute', name: 'src', value: node.url },\n { type: 'mdxJsxAttribute', name: 'alt', value: node.alt ?? '' },\n { type: 'mdxJsxAttribute', name: 'data-seemore-missing', value: 'true' },\n ],\n children: [],\n } as unknown as PhrasingContent);\n });\n };\n}\n\nfunction isExternal(url: string): boolean {\n return /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i.test(url);\n}\n\n/** Relative `.md`/`.mdx` links become routes, base included. */\nexport function remarkSeemoreLinks(options: SeemoreRemarkOptions): Transformer<Root, Root> {\n return (tree, file) => {\n const from = virtualPath(options.contentRoot, file);\n const resolver = options.getResolver();\n\n const rewrite = (node: { url: string }) => {\n const resolved = resolver.resolveHref(node.url, from);\n if (resolved.warning !== undefined) options.onWarning(resolved.warning);\n node.url = resolved.href;\n };\n\n visit(tree, 'link', rewrite);\n visit(tree, 'definition', rewrite);\n };\n}\n\nfunction virtualPath(contentRoot: string, file: VFile): string {\n if (typeof file.path !== 'string' || file.path === '') return '';\n return toPosix(relative(contentRoot, file.path));\n}\n","import { visit } from 'unist-util-visit';\nimport type { Element, Root } from 'hast';\nimport type { Transformer } from 'unified';\n\n/** The attribute a stamped block carries, read by the browser's inline editor. */\nexport const POSITION_ATTRIBUTE = 'data-seemore-pos';\n\n/**\n * Blocks whose source range is safe to hand back to a text editor.\n *\n * Deliberately narrow. A fence is absent because `rehype-code` rebuilds the `<pre>` from\n * Shiki's own tree and drops the position with it; a `<ul>` is absent because its children\n * are the editable unit. Anything not listed here — and anything a remark plugin\n * synthesised, which has no position at all — simply renders without the attribute and is\n * not offered for editing. That is the intended failure mode: no pointer, no edit, never a\n * wrong write.\n */\nconst EDITABLE = new Set(['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'blockquote', 'td', 'th']);\n\n/**\n * Stamp each editable block with its `start:end` offsets into the original file.\n *\n * The offsets are **JavaScript string indices**, not byte offsets — `Café — naïve 😀` is 22\n * of these and 27 UTF-8 bytes — so every consumer has to stay in string space. See\n * `spliceSource`, which is the only thing that writes them back.\n *\n * Dev-only: a static build has no server to write to, so the attributes would be dead weight\n * in the output.\n */\nexport function rehypeSeemorePositions(): Transformer<Root, Root> {\n return (tree) => {\n visit(tree, 'element', (node: Element) => {\n if (!EDITABLE.has(node.tagName)) return;\n\n const { start, end } = node.position ?? {};\n // A synthesised node has no position; a partially-positioned one is not trustworthy.\n if (start?.offset === undefined || end?.offset === undefined) return;\n\n node.properties ??= {};\n node.properties[POSITION_ATTRIBUTE] = `${start.offset}:${end.offset}`;\n });\n };\n}\n","import { readFileSync, writeFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname } from 'node:path';\nimport type { Plugin, ViteDevServer } from 'vite';\nimport { withBase } from '../base.js';\nimport type { SeemoreContext } from '../context.js';\nimport { buildSearchIndex } from '../search/build.js';\nimport { toPosix } from '../content/slug.js';\nimport { canonicalise } from '../paths.js';\nimport { spliceSource } from '../content/edit.js';\nimport type { ContentPage } from '../content/scan.js';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nexport const VIRTUAL = {\n tree: 'virtual:seemore/tree',\n routes: 'virtual:seemore/routes',\n config: 'virtual:seemore/config',\n} as const;\n\n/**\n * Prefix for content-body imports emitted into `virtual:seemore/routes`.\n *\n * A bare absolute path would be read as *root*-relative by Vite, and the content root is\n * normally outside the Vite root. Resolving our own prefix to the real file id keeps dev and\n * build identical, and lets `@mdx-js/rollup` transform the file as it normally would.\n */\nconst PAGE_PREFIX = 'seemore-page:';\n\nconst resolvedId = (id: string) => `\\0${id}`;\n\n/**\n * Two markers, deliberately: see the comments in `src/app/styles/globals.css`.\n *\n * `@import` is only valid before the first style rule, so the theme has to go at the top —\n * and the user's own stylesheet has to go at the bottom, or it loses to the rules it is\n * meant to override and, worse, invalidates the imports it was inlined above.\n */\nconst IMPORTS_MARKER = /\\/\\* seemore:imports[\\s\\S]*?\\*\\//;\nconst USER_CSS_MARKER = /\\/\\* seemore:user-css[\\s\\S]*?\\*\\//;\n\nconst require_ = createRequire(import.meta.url);\n\nfunction styleImports(ctx: SeemoreContext): string {\n const lines: string[] = [`@import 'fumadocs-ui/css/${ctx.config.theme}.css';`];\n\n // Tailwind cannot scan class names it never sees, and fumadocs-ui ships compiled JS.\n try {\n lines.push(`@source '${dirname(require_.resolve('fumadocs-ui/package.json'))}/dist';`);\n } catch {\n // A layout without the package resolvable is already broken elsewhere; do not add noise.\n }\n\n return lines.join('\\n');\n}\n\nfunction userCss(ctx: SeemoreContext): string {\n if (ctx.config.css === undefined) return '';\n\n const css = readIfExists(ctx.config.css);\n if (css === undefined) {\n ctx.warnings.add(`The stylesheet named by \\`css\\` was not found: ${ctx.config.css}`);\n return '';\n }\n\n // Inlined rather than imported: an `@import` this far down the file is not valid CSS.\n return `/* ${ctx.config.css} */\\n${css}`;\n}\n\nexport interface SeemorePluginOptions {\n ctx: SeemoreContext;\n /** Dev serves the index from memory; build writes it to `dist/api/search.json`. */\n serveSearch?: boolean;\n}\n\nexport function seemorePlugin({ ctx, serveSearch = false }: SeemorePluginOptions): Plugin {\n let server: ViteDevServer | undefined;\n\n return {\n name: 'seemore',\n enforce: 'pre',\n\n resolveId(id) {\n // Native separators from `page.absPath` would key a second, unloadable module in\n // Vite's URL-addressed graph — canonical ids are always forward slashes.\n if (id.startsWith(PAGE_PREFIX)) return id.slice(PAGE_PREFIX.length).replace(/\\\\/g, '/');\n for (const virtualId of Object.values(VIRTUAL)) {\n if (id === virtualId) return resolvedId(virtualId);\n }\n return undefined;\n },\n\n /**\n * The theme preset, the paths Tailwind must scan, and the user's own stylesheet are\n * injected into our root stylesheet rather than imported from it.\n *\n * Tailwind v4 only processes the file that contains `@import \"tailwindcss\"`, and bare\n * specifiers in a virtual stylesheet have no directory to resolve from — injecting into\n * the real `globals.css` keeps both working.\n */\n transform(code, id) {\n const path = id.replace(/\\\\/g, '/').split('?')[0] ?? '';\n if (!path.endsWith('/src/app/styles/globals.css')) return undefined;\n const transformed = code\n .replace(IMPORTS_MARKER, () => styleImports(ctx))\n .replace(USER_CSS_MARKER, () => userCss(ctx));\n return { code: transformed, map: null };\n },\n\n async load(id) {\n if (id === resolvedId(VIRTUAL.tree)) {\n return hotStoreModule('Tree', json(await ctx.source.serializeTree()));\n }\n if (id === resolvedId(VIRTUAL.routes)) {\n return hotStoreModule('Routes', renderRoutesValue(ctx));\n }\n // Config is not a store: a change to it can alter `base`, which reconfigures Vite, so\n // the page reloads rather than patching itself.\n if (id === resolvedId(VIRTUAL.config)) return `export const config = ${json(clientConfig(ctx))};`;\n return undefined;\n },\n\n configureServer(devServer) {\n server = devServer;\n if (!serveSearch) return;\n\n // The same JSON the build emits, at the same path, so the client has one code path.\n devServer.middlewares.use(async (req, res, next) => {\n const path = (req.url ?? '').split('?')[0] ?? '';\n if (path !== withBase(ctx.config.base, '/api/search.json') && path !== '/api/search.json') return next();\n try {\n const index = await buildSearchIndex(ctx);\n res.setHeader('Content-Type', 'application/json');\n res.end(index);\n } catch (error) {\n next(error);\n }\n });\n\n // Lets a caller that only knows an absolute file path — an editor extension, say —\n // ask the running server what URL that file resolved to, rather than reimplementing\n // `resolveRoutes`. Dev-only: the answer depends on a live corpus scan.\n devServer.middlewares.use((req, res, next) => {\n const [path = '', query = ''] = (req.url ?? '').split('?');\n if (path !== '/__seemore/route') return next();\n\n const file = new URLSearchParams(query).get('file');\n if (file === null) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'Missing \"file\" query parameter.' }));\n return;\n }\n\n // `page.absPath` is built on the canonicalised content root; a caller outside\n // seemore (an editor's `document.uri.fsPath`) has no reason to have canonicalised\n // its side, so the comparison must go through the filesystem, not just `resolve`.\n const absFile = canonicalise(file);\n const page = ctx.pages().find((p) => p.absPath === absFile);\n if (page === undefined) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: `${file} is not part of this site — excluded, or lost a duplicate slug.` }));\n return;\n }\n\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ url: withBase(ctx.config.base, page.url) }));\n });\n\n // Reads and writes one block of a page's Markdown, for the browser's inline editor.\n //\n // Dev-only for the obvious reason — a static build has no server — and behind a\n // feature flag because it is the one endpoint seemore has that writes to the user's\n // files. Not registered at all when the flag is off, so there is nothing to reach.\n if (ctx.config.features['content.edit']) {\n devServer.middlewares.use((req, res, next) => {\n const path = (req.url ?? '').split('?')[0] ?? '';\n if (path !== SOURCE_ENDPOINT && path !== withBase(ctx.config.base, SOURCE_ENDPOINT)) return next();\n void handleSource(ctx, req, res).catch(next);\n });\n }\n },\n\n /** Called by the watcher after a rescan. */\n api: {\n invalidate() {\n if (server === undefined) return;\n for (const virtualId of [VIRTUAL.tree, VIRTUAL.routes]) {\n const mod = server.moduleGraph.getModuleById(resolvedId(virtualId));\n if (mod) server.moduleGraph.invalidateModule(mod);\n }\n server.ws.send({ type: 'update', updates: [] });\n },\n },\n };\n}\n\n/** Reads and writes a block of Markdown, addressed by source offsets. */\nconst SOURCE_ENDPOINT = '/__seemore/source';\n\nasync function handleSource(ctx: SeemoreContext, req: IncomingMessage, res: ServerResponse): Promise<void> {\n if (req.method === 'GET') return handleSourceRead(ctx, req, res);\n if (req.method === 'PUT') return handleSourceWrite(ctx, req, res);\n\n res.setHeader('Allow', 'GET, PUT');\n return send(res, 405, { error: `${req.method ?? 'This method'} is not allowed here.` });\n}\n\n/** Hands the browser the exact characters behind a block, so it can edit its real source. */\nfunction handleSourceRead(ctx: SeemoreContext, req: IncomingMessage, res: ServerResponse): void {\n const query = new URLSearchParams((req.url ?? '').split('?')[1] ?? '');\n const page = resolvePage(ctx, query.get('file'));\n if (page === undefined) return send(res, 404, { error: 'That file is not part of this site.' });\n\n const start = Number(query.get('start'));\n const end = Number(query.get('end'));\n const content = readFileSync(page.absPath, 'utf8');\n if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start || end > content.length) {\n return send(res, 400, { error: 'The requested range is not inside this file.' });\n }\n\n return send(res, 200, { text: content.slice(start, end) });\n}\n\nasync function handleSourceWrite(ctx: SeemoreContext, req: IncomingMessage, res: ServerResponse): Promise<void> {\n let body: Partial<{ file: string; start: number; end: number; expected: string; text: string }>;\n try {\n body = JSON.parse(await readBody(req)) as typeof body;\n } catch {\n return send(res, 400, { error: 'The request body was not valid JSON.' });\n }\n\n const page = resolvePage(ctx, body.file);\n if (page === undefined) return send(res, 404, { error: 'That file is not part of this site.' });\n if (typeof body.expected !== 'string' || typeof body.text !== 'string') {\n return send(res, 400, { error: 'Both `expected` and `text` are required.' });\n }\n\n // Read, splice and write as one string: the offsets are JavaScript string indices, so any\n // detour through a Buffer would cut a multi-byte character in half.\n const content = readFileSync(page.absPath, 'utf8');\n const result = spliceSource(content, {\n start: body.start as number,\n end: body.end as number,\n expected: body.expected,\n text: body.text,\n });\n if (!result.ok) return send(res, result.status, { error: result.error });\n\n writeFileSync(page.absPath, result.content, 'utf8');\n // Nothing to invalidate by hand: the watcher sees the write and hot-reloads the page,\n // which is the same path an edit in an editor takes.\n return send(res, 200, { ok: true });\n}\n\n/**\n * The file a request names, but only if it is a page of this site.\n *\n * The comparison goes through {@link canonicalise} for the same reason `/__seemore/route`\n * does — a caller's spelling of a path is not seemore's — and it doubles as the containment\n * check: a path that is not one of the scanned pages is not writable, whatever it points at.\n */\nfunction resolvePage(ctx: SeemoreContext, file: string | null | undefined): ContentPage | undefined {\n if (typeof file !== 'string' || file === '') return undefined;\n const absFile = canonicalise(file);\n return ctx.pages().find((page) => page.absPath === absFile);\n}\n\nasync function readBody(req: IncomingMessage): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks).toString('utf8');\n}\n\nfunction send(res: ServerResponse, status: number, payload: unknown): void {\n res.statusCode = status;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(payload));\n}\n\n/**\n * A self-accepting module holding one value, with subscribers that survive replacement.\n *\n * State lives on `import.meta.hot.data`, so when the module re-executes after an edit the\n * new copy still has the listeners the old one handed to React. `accept()` stops the update\n * propagating to importers, which is the difference between the sidebar re-rendering in\n * place and the page reloading.\n */\nfunction hotStoreModule(suffix: string, value: string): string {\n // `import.meta.hot.accept()` is written out in full because Vite detects self-accepting\n // modules syntactically — through an alias it sees an ordinary module and reloads the page.\n return `const state = import.meta.hot\n ? (import.meta.hot.data.seemore${suffix} ||= { listeners: new Set() })\n : { listeners: new Set() };\n\nstate.value = ${value};\n\nexport function get${suffix}() {\n return state.value;\n}\n\nexport function subscribe${suffix}(listener) {\n state.listeners.add(listener);\n return () => {\n state.listeners.delete(listener);\n };\n}\n\nif (import.meta.hot) {\n import.meta.hot.accept();\n for (const listener of state.listeners) listener();\n}\n`;\n}\n\n/**\n * `virtual:seemore/routes`: one entry per page, with the body behind a dynamic\n * import so the router, the hover prefetch and the prerender driver all read one map.\n *\n * `import.meta.glob` is deliberately not used: glob patterns that escape the Vite root fail\n * silently, which is the exact failure class seemore exists to prevent.\n */\nfunction renderRoutesValue(ctx: SeemoreContext): string {\n const entries = ctx.pages().map((page) => {\n // Backslashes are legal in a Windows path and fatal in an import specifier.\n const specifier = `${PAGE_PREFIX}${page.absPath.replace(/\\\\/g, '/')}`;\n return [\n ' {',\n ` url: ${json(page.url)},`,\n ` file: ${json(page.file)},`,\n ` absPath: ${json(page.absPath)},`,\n ` version: ${json(page.version)},`,\n ` title: ${json(page.data.title)},`,\n ` description: ${json(page.data.description ?? null)},`,\n ` load: () => import(${json(specifier)}),`,\n ' },',\n ].join('\\n');\n });\n\n return `[\\n${entries.join('\\n')}\\n]`;\n}\n\n/** The serialisable slice of the config the browser needs. */\nfunction clientConfig(ctx: SeemoreContext) {\n const { config } = ctx;\n return {\n title: config.title,\n description: config.description,\n base: config.base,\n theme: config.theme,\n features: config.features,\n nav: config.nav,\n footer: config.footer,\n editLink: config.editLink,\n favicon: config.favicon === undefined ? undefined : withBase(config.base, `/${toPosix(config.favicon)}`),\n search:\n config.search.provider === 'static'\n ? { provider: 'static' as const, from: withBase(config.base, '/api/search.json') }\n : config.search,\n contentRoot: config.root,\n };\n}\n\n/** JSON that is always safe to paste into a module body. */\nfunction json(value: unknown): string {\n return JSON.stringify(value ?? null)\n .replace(/</g, '\\\\u003c')\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029');\n}\n\nexport function readIfExists(path: string): string | undefined {\n try {\n return readFileSync(path, 'utf8');\n } catch {\n return undefined;\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { gzipSync } from 'node:zlib';\nimport { createFromSource } from 'fumadocs-core/search/server';\nimport { structure } from 'fumadocs-core/mdx-plugins';\nimport { withBase } from '../base.js';\nimport { parseFrontmatter } from '../content/frontmatter.js';\nimport type { SeemoreContext } from '../context.js';\n\n/** Above this, a static index is a real download cost worth naming. */\nexport const SIZE_WARNING_BYTES = 1_500_000;\n\n/**\n * `structure()` indexes plain text, so seemore's own authoring syntax would reach search\n * results as raw markers. Wikilinks collapse to their label, or to the linked file's name\n * when there is no label, and admonition markers drop while the quoted content stays.\n */\nexport function toSearchableText(body: string): string {\n return body\n .replace(/^>\\s*\\[!\\w+\\]\\s*$/gm, '>')\n .replace(\n /\\[\\[([^\\]|#]*)(?:#[^\\]|]*)?(?:\\|([^\\]]*))?\\]\\]/g,\n (_match, target: string, label?: string) => (label || target.split('/').pop() || '').trim(),\n );\n}\n\n/**\n * Build the static search index.\n *\n * The index is produced node-side from the raw markdown rather than from the compiled MDX\n * modules, so dev and build share one code path and neither has to evaluate browser code.\n */\nexport async function buildSearchIndex(ctx: SeemoreContext): Promise<string> {\n const loader = await ctx.source.loader.get();\n const bodies = new Map<string, string>();\n\n for (const page of ctx.pages()) {\n try {\n // The body only: `structure` reads plain Markdown, where a frontmatter block's closing\n // `---` turns its keys into a setext heading and lands in the index as content.\n bodies.set(page.url, parseFrontmatter(readFileSync(page.absPath, 'utf8'), page.file).content);\n } catch {\n // A file deleted between scan and index is not worth failing a dev rebuild over.\n }\n }\n\n const server = createFromSource(loader, {\n buildIndex(page) {\n const body = bodies.get(page.url) ?? '';\n return {\n id: page.url,\n url: withBase(ctx.config.base, page.url),\n title: typeof page.data.title === 'string' ? page.data.title : page.url,\n description: typeof page.data.description === 'string' ? page.data.description : undefined,\n structuredData: structure(toSearchableText(body)),\n };\n },\n });\n\n const response = await server.staticGET();\n return await response.text();\n}\n\nexport interface IndexSize {\n bytes: number;\n gzipped: number;\n /** Set when the gzipped index passed {@link SIZE_WARNING_BYTES}. */\n warning?: string;\n}\n\nexport function measureIndex(json: string): IndexSize {\n const bytes = Buffer.byteLength(json);\n const gzipped = gzipSync(json).byteLength;\n\n if (gzipped <= SIZE_WARNING_BYTES) return { bytes, gzipped };\n\n return {\n bytes,\n gzipped,\n warning:\n `The static search index is ${formatBytes(gzipped)} gzipped, which every visitor downloads before ` +\n `their first search. Above ${formatBytes(SIZE_WARNING_BYTES)} consider a hosted index: set ` +\n `\\`search: { provider: 'orama-cloud', … }\\` or \\`search: { provider: 'algolia', … }\\` in seemore.config.ts.`,\n };\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} kB`;\n return `${(bytes / 1024 / 1024).toFixed(2)} MB`;\n}\n","/**\n * Writing an edited block back into its source file.\n *\n * The unit is a byte range that a rehype plugin stamped onto the rendered block\n * (`rehypeSeemorePositions`), so an edit replaces exactly the characters that produced that\n * block and leaves every other character in the file untouched — no reflow, no\n * re-serialisation, nothing for a Markdown printer to normalise on its way past.\n */\n\nexport interface SpliceRequest {\n /** Offsets into the file, as JavaScript string indices. */\n start: number;\n end: number;\n /**\n * The slice the client was originally handed, unmodified.\n *\n * Kept separate from `text` on purpose: a `<textarea>` reports its value with `\\n`\n * regardless of what was put into it, so the round-tripped copy cannot be compared against\n * a CRLF file. This one never went through the DOM.\n */\n expected: string;\n /** The replacement, with whatever line endings the browser saw fit to give us. */\n text: string;\n}\n\nexport type SpliceResult =\n | { ok: true; content: string }\n | { ok: false; status: number; error: string };\n\nexport function spliceSource(content: string, request: SpliceRequest): SpliceResult {\n const { start, end, expected, text } = request;\n\n if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start || end > content.length) {\n return { ok: false, status: 400, error: 'The edited range is not inside this file.' };\n }\n\n // The file may have moved under us — an editor saved it, or a previous edit landed — and\n // the offsets the browser is holding would then point at unrelated text. Comparing the\n // slice is cheaper than versioning and catches every case that matters.\n if (content.slice(start, end) !== expected) {\n return {\n ok: false,\n status: 409,\n error: 'This file changed since the page was rendered. Reload and try the edit again.',\n };\n }\n\n return { ok: true, content: content.slice(0, start) + withEol(text, dominantEol(content)) + content.slice(end) };\n}\n\n/**\n * The line ending the file already uses.\n *\n * Without this, editing a multi-line block on Windows silently rewrites its `\\r\\n` to `\\n` —\n * the browser normalises a textarea's value — and the next `git diff` shows every line of the\n * block as changed. Mixed endings within one file are decided by majority, so the common case\n * of a file that is already consistent stays consistent.\n */\nexport function dominantEol(content: string): '\\r\\n' | '\\n' {\n const crlf = content.match(/\\r\\n/g)?.length ?? 0;\n const lf = (content.match(/\\n/g)?.length ?? 0) - crlf;\n return crlf > lf ? '\\r\\n' : '\\n';\n}\n\nfunction withEol(text: string, eol: '\\r\\n' | '\\n'): string {\n const normalised = text.replace(/\\r\\n/g, '\\n');\n return eol === '\\n' ? normalised : normalised.replace(/\\n/g, '\\r\\n');\n}\n","import chokidar, { type FSWatcher } from 'chokidar';\nimport type { Plugin, ViteDevServer } from 'vite';\nimport type { SeemoreContext } from '../context.js';\nimport { VIRTUAL } from './plugin.js';\n\nconst CONTENT_FILE = /\\.(?:mdx?|json)$/i;\n\n/**\n * The watcher/sidebar-refresh cycle.\n *\n * The page tree, sidebar and search index are not in the module graph, so nothing invalidates\n * them on its own. chokidar watches the content root; every event rescans, and the two\n * virtual modules that depend on the corpus are reloaded through Vite's own HMR machinery so\n * the sidebar re-renders in place instead of reloading the page.\n */\nexport function seemoreWatcherPlugin(ctx: SeemoreContext): Plugin {\n let watcher: FSWatcher | undefined;\n\n return {\n name: 'seemore:watcher',\n apply: 'serve',\n\n configureServer(server) {\n watcher = chokidar.watch(ctx.contentRoot, {\n ignoreInitial: true,\n ignored: (path: string, stats?: { isFile(): boolean }) => {\n // `ignored` applies to explicitly added paths too, so the config file — which is\n // neither Markdown nor JSON — has to be let through by name.\n if (path === ctx.config.configFile) return false;\n // chokidar reports native separators, so compare against a normalised path.\n const posix = path.replace(/\\\\/g, '/');\n if (/(?:^|\\/)(?:node_modules|\\.git|dist|build|out|vendor|target|\\.seemore)(?:$|\\/)/.test(posix)) return true;\n if (/(?:^|\\/)\\.[^/]+/.test(posix)) return true;\n return stats?.isFile() === true && !CONTENT_FILE.test(posix);\n },\n });\n\n const onEvent = (event: string, path: string) => {\n void handleContentChange(server, ctx, event, path);\n };\n\n watcher.on('add', (p) => onEvent('add', p));\n watcher.on('change', (p) => onEvent('change', p));\n watcher.on('unlink', (p) => onEvent('unlink', p));\n watcher.on('addDir', (p) => onEvent('addDir', p));\n watcher.on('unlinkDir', (p) => onEvent('unlinkDir', p));\n\n // A config edit can change `base`, which reconfigures Vite itself, so the page reloads\n // rather than patching itself.\n if (ctx.config.configFile !== undefined) {\n watcher.add(ctx.config.configFile);\n watcher.on('change', (path) => {\n if (path !== ctx.config.configFile) return;\n server.environments.client.hot.send({ type: 'full-reload', path: '*' });\n server.config.logger.info(\n 'seemore config changed — reloading. Changes to `base` need a restart to take effect.',\n );\n });\n }\n\n server.httpServer?.once('close', () => void watcher?.close());\n },\n\n async closeBundle() {\n await watcher?.close();\n watcher = undefined;\n },\n };\n}\n\n/** Exported for the watcher test, which drives it without going through chokidar's timing. */\nexport async function handleContentChange(\n server: ViteDevServer,\n ctx: SeemoreContext,\n event: string,\n path: string,\n): Promise<void> {\n const scan = ctx.refresh();\n\n // Dev never exits on a content error, but it must not swallow one either: editing a file\n // back to valid has to recover without a restart, so problems are reported each time.\n for (const message of [...scan.errors, ...scan.warnings]) ctx.warnings.add(message);\n ctx.warnings.flush((line) => server.config.logger.warn(line));\n\n // Order matters: the tree must be current before anything re-renders against it.\n await reloadVirtual(server, VIRTUAL.tree);\n await reloadVirtual(server, VIRTUAL.routes);\n\n // A body edit is a plain MDX swap; the component is replaced and scroll position kept.\n if (event === 'change' && /\\.mdx?$/i.test(path)) {\n await reloadFile(server, path);\n }\n}\n\nasync function reloadVirtual(server: ViteDevServer, id: string): Promise<void> {\n await reloadById(server, `\\0${id}`);\n}\n\nasync function reloadFile(server: ViteDevServer, absolutePath: string): Promise<void> {\n // chokidar reports native separators; the module graph is addressed in forward slashes.\n await reloadById(server, absolutePath.replace(/\\\\/g, '/'));\n}\n\n/**\n * Reload a module in every environment that has it. `server.reloadModule` handles\n * invalidation and the HMR message together, which keeps us out of the business of\n * constructing update payloads by hand.\n */\nasync function reloadById(server: ViteDevServer, id: string): Promise<void> {\n const environments = Object.values(server.environments ?? {});\n\n if (environments.length === 0) {\n const legacy = server.moduleGraph.getModuleById(id);\n if (legacy) await server.reloadModule(legacy);\n return;\n }\n\n for (const environment of environments) {\n const mod = environment.moduleGraph?.getModuleById(id);\n if (mod === undefined || mod === null) continue;\n if (typeof environment.reloadModule === 'function') await environment.reloadModule(mod);\n else environment.moduleGraph.invalidateModule(mod);\n }\n}\n","import { mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { ogImagePath } from '../../shared/og.js';\nimport type { SeemoreContext } from '../context.js';\n\n/**\n * `social.cards`: one OG image per page, rendered at build time.\n *\n * `takumi-js` is an optional peer of fumadocs-ui and is not installed by default, so the\n * flag degrades to a warning rather than to an install-time cost everybody pays.\n */\nexport async function generateSocialCards(ctx: SeemoreContext, outDir: string): Promise<number> {\n // `takumi-js` is an optional peer, so it is loaded by specifier and typed structurally —\n // a hard import would make it a required dependency of every build.\n let takumi: TakumiModule;\n try {\n takumi = (await importOptional('takumi-js')) as TakumiModule;\n } catch {\n ctx.warnings.add(\n \"`social.cards` is enabled but `takumi-js` is not installed. Run `npm install takumi-js`, or remove the flag.\",\n );\n return 0;\n }\n\n let written = 0;\n for (const page of ctx.pages()) {\n const png = await renderCard(takumi, ctx.config.title, page.data.title, page.data.description);\n if (png === undefined) continue;\n\n const target = join(outDir, ogImagePath(page.url));\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, png);\n written++;\n }\n\n return written;\n}\n\ninterface TakumiModule {\n Renderer: new (options: { fonts: unknown[] }) => {\n renderAsync(node: unknown, options: { width: number; height: number; format: 'png' }): Promise<Uint8Array>;\n };\n container(props: unknown, children: unknown[]): unknown;\n text(value: string, props: unknown): unknown;\n}\n\nasync function renderCard(\n takumi: TakumiModule,\n site: string,\n title: string,\n description: unknown,\n): Promise<Uint8Array | undefined> {\n const renderer = new takumi.Renderer({ fonts: [] });\n const node = takumi.container(\n {\n style: {\n width: 1200,\n height: 630,\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n padding: 80,\n backgroundColor: '#0b0b0b',\n color: '#ffffff',\n gap: 24,\n },\n },\n [\n takumi.text(site, { style: { fontSize: 28, opacity: 0.6 } }),\n takumi.text(title, { style: { fontSize: 64, fontWeight: 700 } }),\n ...(typeof description === 'string' ? [takumi.text(description, { style: { fontSize: 30, opacity: 0.8 } })] : []),\n ],\n );\n\n return await renderer.renderAsync(node, { width: 1200, height: 630, format: 'png' });\n}\n\n/** Import by a specifier TypeScript will not try to resolve at build time. */\nasync function importOptional(specifier: string): Promise<unknown> {\n return await import(specifier);\n}\n","/**\n * Where a page's social card lives.\n *\n * Shared, because the build writes the file and the prerendered `<head>` points at it — and\n * a card nothing references is a card nobody sees.\n */\nexport function ogImagePath(url: string): string {\n const clean = url.replace(/^\\/+|\\/+$/g, '');\n // A path per route, rather than a flattened filename: `/a/b` and `/a-b` are different\n // routes and must not write to the same file.\n return clean === '' ? '/api/og/card.png' : `/api/og/${clean}/card.png`;\n}\n","import { createServer, type ViteDevServer } from 'vite';\nimport pc from 'picocolors';\nimport { loadConfig, resolveConfigPath } from '../node/config/load.js';\nimport { createContext, type SeemoreContext } from '../node/context.js';\nimport { normaliseBase } from '../shared/base.js';\nimport { resolveContentRoot } from '../node/paths.js';\nimport { createViteConfig } from '../node/vite/config.js';\n\nconst DEFAULT_PORT = 4040;\n\nexport interface DevOptions {\n cwd: string;\n dir?: string;\n configPath?: string;\n base?: string;\n port?: number;\n host?: string | boolean;\n open?: boolean;\n /**\n * Print one JSON line on stdout at startup instead of the human summary — a stable\n * contract for a caller that spawns this as a child process, so it never has to\n * screen-scrape colored text.\n */\n json?: boolean;\n}\n\n/** The single line a `json: true` caller parses to learn where the server ended up. */\nexport interface DevReady {\n url: string;\n port: number;\n contentRoot: string;\n pageCount: number;\n}\n\nexport interface DevServer {\n server: ViteDevServer;\n ctx: SeemoreContext;\n url: string;\n close(): Promise<void>;\n}\n\n/**\n * The dev server. Nothing is written into the user's folder: the Vite root is\n * seemore's own `src/app`, and caches go to the OS temp directory.\n */\nexport async function runDev(options: DevOptions): Promise<DevServer> {\n const contentRoot = resolveContentRoot(options.cwd, options.dir);\n const loaded = await loadConfig({ root: contentRoot, configPath: resolveConfigPath(options) });\n const config = {\n ...loaded.config,\n base: options.base === undefined ? loaded.config.base : normaliseBase(options.base),\n };\n\n // Dev never exits on a content error: editing a file back to valid must recover without a\n // restart, so problems that fail the build are warnings here.\n const ctx = createContext({ config, contentRoot, includeDrafts: true });\n const scan = ctx.source.current();\n for (const message of [...scan.errors, ...scan.warnings]) ctx.warnings.add(message);\n if (scan.pages.length === 0) {\n ctx.warnings.add(`No Markdown files found under ${contentRoot}. seemore will serve an empty site until there are.`);\n }\n\n const base = createViteConfig({ ctx, mode: 'dev' });\n const server = await createServer({\n ...base,\n server: {\n ...base.server,\n port: options.port ?? DEFAULT_PORT,\n host: options.host,\n open: options.open === true ? config.base : false,\n },\n });\n\n await server.listen();\n\n const resolvedPort = server.config.server.port ?? DEFAULT_PORT;\n const url = `http://localhost:${resolvedPort}${config.base}`;\n\n ctx.warnings.flush();\n if (options.json === true) {\n const ready: DevReady = { url, port: resolvedPort, contentRoot, pageCount: scan.pages.length };\n console.log(JSON.stringify(ready));\n } else {\n console.log(`\\n ${pc.green('seemore')} ${pc.bold(url)}`);\n console.log(` ${pc.dim(`${scan.pages.length} pages from ${contentRoot}`)}\\n`);\n }\n\n return {\n server,\n ctx,\n url,\n close: async () => {\n await server.close();\n },\n };\n}\n"],"mappings":"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","names":["existsSync","readFileSync","createHash","dirname","join","resolve","pc","mkdirSync","readFileSync","writeFileSync","createRequire","tmpdir","isAbsolute","join","relative","resolve","pc","slugify","basename","CONTENT_EXT","basename","slugify","relative","dirname","resolve","z","z","z","resolve","dirname","dirname","join","writeFileSync","join","join","realpathSync","createRequire","join","existsSync","dirname","resolve","dirname","resolve","existsSync","visit","readFileSync","writeFileSync","dirname","readFileSync","readFileSync","json","dirname","readFileSync","writeFileSync","scan","require_","createRequire","join","realpathSync","join","mkdirSync","writeFileSync","dirname","join","join","mkdirSync","dirname","writeFileSync","resolve","scan","pc","relative","readFileSync","join","tmpdir","mkdirSync","writeFileSync","isAbsolute","createRequire","pc","scan","pc","pc","readFileSync","join","packageRoot"]}
|