jazz-tools 0.20.16 → 0.20.17
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/.turbo/turbo-build.log +54 -54
- package/CHANGELOG.md +11 -0
- package/dist/browser/createBrowserContext.d.ts +1 -12
- package/dist/browser/createBrowserContext.d.ts.map +1 -1
- package/dist/browser/index.js +1 -2
- package/dist/browser/index.js.map +1 -1
- package/dist/{chunk-WAYFZQXB.js → chunk-3BV3JUMV.js} +418 -70
- package/dist/chunk-3BV3JUMV.js.map +1 -0
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/backend-sqlite.d.ts.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +4 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/react-native/index.js +4 -1
- package/dist/react-native/index.js.map +1 -1
- package/dist/react-native-core/index.js +4 -1
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/react-native-core/platform.d.ts.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/tools/coValues/deepLoading.d.ts +21 -1
- package/dist/tools/coValues/deepLoading.d.ts.map +1 -1
- package/dist/tools/coValues/interfaces.d.ts +1 -0
- package/dist/tools/coValues/interfaces.d.ts.map +1 -1
- package/dist/tools/coValues/registeredSchemas.d.ts +1 -1
- package/dist/tools/coValues/registeredSchemas.d.ts.map +1 -1
- package/dist/tools/coValues/snapshotRef.d.ts +114 -0
- package/dist/tools/coValues/snapshotRef.d.ts.map +1 -0
- package/dist/tools/implementation/invites.d.ts +9 -1
- package/dist/tools/implementation/invites.d.ts.map +1 -1
- package/dist/tools/implementation/schemaRuntime.d.ts +1 -0
- package/dist/tools/implementation/schemaRuntime.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/coExport.d.ts +2 -1
- package/dist/tools/implementation/zodSchema/coExport.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/runtimeConverters/coValueSchemaTransformation.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts +3 -0
- package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaInvariant.d.ts +2 -1
- package/dist/tools/implementation/zodSchema/schemaInvariant.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaPermissions.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/SnapshotRefSchema.d.ts +106 -0
- package/dist/tools/implementation/zodSchema/schemaTypes/SnapshotRefSchema.d.ts.map +1 -0
- package/dist/tools/implementation/zodSchema/typeConverters/CoFieldSchemaInit.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/typeConverters/CoFieldSchemaInit.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesMaybeLoaded.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesMaybeLoaded.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodCo.d.ts +5 -1
- package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodSchema.d.ts +4 -3
- package/dist/tools/implementation/zodSchema/zodSchema.d.ts.map +1 -1
- package/dist/tools/internal.d.ts +2 -0
- package/dist/tools/internal.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/dist/tools/tests/snapshotRef.test.d.ts +2 -0
- package/dist/tools/tests/snapshotRef.test.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/browser/createBrowserContext.ts +0 -67
- package/src/browser/index.ts +1 -1
- package/src/mcp/backend-sqlite.ts +4 -1
- package/src/mcp/server.ts +4 -1
- package/src/react-native-core/platform.ts +4 -1
- package/src/tools/coValues/deepLoading.ts +46 -15
- package/src/tools/coValues/interfaces.ts +29 -24
- package/src/tools/coValues/registeredSchemas.ts +1 -1
- package/src/tools/coValues/snapshotRef.ts +364 -0
- package/src/tools/implementation/invites.ts +26 -2
- package/src/tools/implementation/schemaRuntime.ts +1 -0
- package/src/tools/implementation/zodSchema/coExport.ts +2 -0
- package/src/tools/implementation/zodSchema/runtimeConverters/coValueSchemaTransformation.ts +10 -0
- package/src/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.ts +1 -1
- package/src/tools/implementation/zodSchema/schemaInvariant.ts +3 -1
- package/src/tools/implementation/zodSchema/schemaPermissions.ts +2 -4
- package/src/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.ts +0 -1
- package/src/tools/implementation/zodSchema/schemaTypes/SnapshotRefSchema.ts +259 -0
- package/src/tools/implementation/zodSchema/typeConverters/CoFieldSchemaInit.ts +24 -19
- package/src/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.ts +11 -5
- package/src/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesMaybeLoaded.ts +18 -10
- package/src/tools/implementation/zodSchema/zodCo.ts +17 -0
- package/src/tools/implementation/zodSchema/zodSchema.ts +10 -3
- package/src/tools/internal.ts +2 -0
- package/src/tools/subscribe/SubscriptionScope.ts +22 -4
- package/src/tools/tests/invites.test.ts +13 -0
- package/src/tools/tests/snapshotRef.test.ts +688 -0
- package/dist/chunk-WAYFZQXB.js.map +0 -1
package/dist/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/mcp/backend-sqlite.ts","../../src/mcp/build-index.ts","../../src/mcp/backend-naive.ts","../../src/mcp/server.ts","../../src/mcp/tools.ts"],"sourcesContent":["// NOTE: no top-level `import … from \"node:sqlite\"` — this module must be safe\n// to parse/import on Node <22. DatabaseSync is obtained via dynamic import\n// inside createSqliteBackend().\n\nexport interface SearchResult {\n title: string;\n slug: string;\n section: string;\n snippet: string;\n}\n\nexport interface DocResult {\n title: string;\n slug: string;\n description: string;\n body: string;\n related: string[];\n}\n\nexport interface PageInfo {\n title: string;\n slug: string;\n description: string;\n}\n\nexport interface DocsBackend {\n search(query: string, limit: number): SearchResult[];\n getDoc(slug: string): DocResult | null;\n listPages(): PageInfo[];\n}\n\nexport async function createSqliteBackend(\n dbPath: string,\n): Promise<DocsBackend> {\n // Dynamic import keeps node:sqlite off the top-level parse graph\n const { DatabaseSync } = await import(\"node:sqlite\");\n const db = new DatabaseSync(dbPath, { readOnly: true });\n\n // ------------------------------------------------------------------\n // Prepared statements\n // ------------------------------------------------------------------\n\n const stmtSearch = db.prepare(`\n SELECT\n title,\n slug,\n section_heading,\n snippet(sections_fts, 3, '', '', '…', 32) AS snip,\n bm25(sections_fts) AS score\n FROM sections_fts\n WHERE sections_fts MATCH ?\n ORDER BY bm25(sections_fts)\n LIMIT ?\n `);\n\n const stmtGetPage = db.prepare(\n \"SELECT title, slug, description, body FROM pages WHERE slug = ?\",\n );\n\n const stmtGetTopHeadings = db.prepare(`\n SELECT section_heading\n FROM sections_fts\n WHERE slug = ? AND section_heading != ''\n LIMIT 3\n `);\n\n // Fetch up to 15 rows ordered by bm25; deduplicate by slug in code (max 5 kept).\n // We avoid sum(bm25()) in a GROUP BY because bm25() is only valid in\n // WHERE / ORDER BY clauses of FTS5 queries.\n const stmtRelated = db.prepare(`\n SELECT slug, bm25(sections_fts) AS score\n FROM sections_fts\n WHERE sections_fts MATCH ? AND slug != ?\n ORDER BY bm25(sections_fts)\n LIMIT 15\n `);\n\n const stmtListPages = db.prepare(\n \"SELECT title, slug, description FROM pages ORDER BY slug\",\n );\n\n // ------------------------------------------------------------------\n // Helpers\n // ------------------------------------------------------------------\n\n function buildRelatedQuery(title: string, slug: string): string | null {\n const headingRows = stmtGetTopHeadings.all(slug) as Array<{\n section_heading: string;\n }>;\n\n const rawTerms = [title, ...headingRows.map((r) => r.section_heading)]\n .join(\" \")\n .split(/\\s+/)\n .map((w) => w.replace(/[^a-zA-Z0-9]/g, \"\"))\n .filter((w) => w.length >= 3);\n\n if (rawTerms.length === 0) return null;\n\n // Deduplicate and use OR so we get broader matches\n const unique = [...new Set(rawTerms.map((w) => w.toLowerCase()))];\n return unique.join(\" OR \");\n }\n\n // ------------------------------------------------------------------\n // Backend methods\n // ------------------------------------------------------------------\n\n function search(query: string, limit: number): SearchResult[] {\n try {\n const rows = stmtSearch.all(query, limit) as Array<{\n title: string;\n slug: string;\n section_heading: string;\n snip: string;\n score: number;\n }>;\n return rows.map((r) => ({\n title: r.title,\n slug: r.slug,\n section: r.section_heading,\n snippet: r.snip,\n }));\n } catch {\n return [];\n }\n }\n\n function getDoc(slug: string): DocResult | null {\n const row = stmtGetPage.get(slug) as\n | { title: string; slug: string; description: string; body: string }\n | undefined;\n if (!row) return null;\n\n let related: string[] = [];\n try {\n const relQuery = buildRelatedQuery(row.title, slug);\n if (relQuery) {\n const relRows = stmtRelated.all(relQuery, slug) as Array<{\n slug: string;\n }>;\n // Deduplicate while preserving bm25 order (first occurrence = best)\n const seen = new Set<string>();\n for (const r of relRows) {\n if (!seen.has(r.slug)) {\n seen.add(r.slug);\n related.push(r.slug);\n if (related.length >= 5) break;\n }\n }\n }\n } catch {\n // related stays []\n }\n\n return {\n title: row.title,\n slug: row.slug,\n description: row.description,\n body: row.body,\n related,\n };\n }\n\n function listPages(): PageInfo[] {\n const rows = stmtListPages.all() as Array<{\n title: string;\n slug: string;\n description: string;\n }>;\n return rows;\n }\n\n return { search, getDoc, listPages };\n}\n","import { mkdir, readdir, readFile, unlink, writeFile } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FrontmatterResult {\n title?: string;\n description?: string;\n body: string;\n}\n\nexport interface Section {\n heading: string;\n body: string;\n}\n\nexport interface BuildIndexOptions {\n /** Path to the content/docs directory containing .mdx files. */\n contentDir: string;\n /** Directory where docs-index.db and docs-index.txt are written. */\n outputDir: string;\n /**\n * Base directory used to resolve <include cwd> paths.\n * Mirrors fumadocs' file.cwd (the app working directory).\n * Defaults to contentDir when not specified.\n */\n fileCwd?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Pure helpers (exported for unit testing)\n// ---------------------------------------------------------------------------\n\n/**\n * Splits YAML frontmatter from MDX content.\n * Returns title, optional description, and the body after the closing `---`.\n */\nexport function parseFrontmatter(content: string): FrontmatterResult {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---\\n*([\\s\\S]*)$/);\n if (!match) {\n return { body: content };\n }\n\n const fm = match[1]!;\n const body = match[2]!.trimStart();\n\n const titleMatch = fm.match(/^title:\\s*(.+)$/m);\n const descMatch = fm.match(/^description:\\s*(.+)$/m);\n\n return {\n title: titleMatch?.[1]?.trim(),\n description: descMatch?.[1]?.trim(),\n body,\n };\n}\n\n/**\n * Extracts a description from rendered body text.\n * Strips fenced code blocks and headings, then returns the first three sentences.\n */\nexport function extractDescription(body: string): string {\n if (!body) return \"\";\n\n // Strip all fenced code blocks\n let text = body.replace(/```[\\s\\S]*?```/g, \"\");\n // Strip markdown headings\n text = text.replace(/^#{1,6}\\s+.*/gm, \"\");\n // Strip JSX tags (in case they weren't stripped already)\n text = text.replace(/<\\/?[A-Z][a-zA-Z]*[^>]*>/g, \"\");\n // Collapse all whitespace to single spaces\n text = text.replace(/\\s+/g, \" \").trim();\n\n const sentences: string[] = [];\n const sentenceRe = /[^.!?]+[.!?]+/g;\n let m: RegExpExecArray | null;\n while ((m = sentenceRe.exec(text)) !== null && sentences.length < 3) {\n sentences.push(m[0].trim());\n }\n\n return sentences.join(\" \");\n}\n\n/**\n * Resolves `<include cwd lang=\"…\">path[#anchor]</include>` directives in MDX\n * content, replacing each with a fenced code block. Paths are resolved\n * relative to the MDX file's directory unless the `cwd` attribute is present,\n * in which case fileCwd is used (mirrors fumadocs' file.cwd semantics).\n * Additional attributes (e.g. meta='…') are tolerated and ignored.\n */\nexport async function resolveIncludes(\n content: string,\n mdxFilePath: string,\n fileCwd?: string,\n): Promise<string> {\n // Match <include ...attrs...>path</include> — any attribute combination.\n const includeRe = /<include\\s+([^>]*?)>\\s*([\\s\\S]*?)\\s*<\\/include>/g;\n\n // Collect all replacements first, then apply (to avoid regex state issues)\n const replacements: Array<{ original: string; replacement: string }> = [];\n let m: RegExpExecArray | null;\n\n while ((m = includeRe.exec(content)) !== null) {\n const attrs = m[1]!;\n const hasCwd = /\\bcwd\\b/.test(attrs);\n const langMatch = attrs.match(/\\blang=\"([^\"]+)\"/);\n if (!langMatch) continue; // not a code include — leave untouched\n const lang = langMatch[1]!;\n const rawPath = m[2]!.trim();\n const hashIdx = rawPath.indexOf(\"#\");\n const filePath = hashIdx === -1 ? rawPath : rawPath.slice(0, hashIdx);\n const anchor = hashIdx === -1 ? null : rawPath.slice(hashIdx + 1);\n\n const base = hasCwd && fileCwd ? fileCwd : dirname(mdxFilePath);\n const resolvedPath = resolve(base, filePath.trim());\n let fileContent = await readFile(resolvedPath, \"utf8\");\n\n if (anchor) {\n const regionRe = new RegExp(\n `// #region ${anchor}\\\\n([\\\\s\\\\S]*?)// #endregion ${anchor}`,\n );\n const regionMatch = fileContent.match(regionRe);\n if (regionMatch) {\n fileContent = regionMatch[1]!.trimEnd();\n }\n }\n\n replacements.push({\n original: m[0],\n replacement: `\\`\\`\\`${lang}\\n${fileContent}\\n\\`\\`\\``,\n });\n }\n\n let result = content;\n for (const { original, replacement } of replacements) {\n result = result.replace(original, replacement);\n }\n return result;\n}\n\n/**\n * Strips JSX component tags (uppercase-initial or namespaced) from content,\n * preserving text and fenced code blocks inside them.\n * Also strips MDX import/export declarations.\n */\nexport function stripJsx(content: string): string {\n let result = content;\n // Strip MDX import/export lines\n result = result.replace(/^(?:import|export)\\s+.*$/gm, \"\");\n // Self-closing JSX: <Component />\n result = result.replace(/<[A-Z][a-zA-Z]*(?:\\.[a-zA-Z]+)?[^>]*\\/>/g, \"\");\n // Opening JSX: <Component ...>\n result = result.replace(/<[A-Z][a-zA-Z]*(?:\\.[a-zA-Z]+)?[^>]*>/g, \"\");\n // Closing JSX: </Component>\n result = result.replace(/<\\/[A-Z][a-zA-Z]*(?:\\.[a-zA-Z]+)?>/g, \"\");\n // Strip region marker lines left over from include expansion\n // Covers: // #region, # #region, <!-- #region, /* #region */\n result = result.replace(\n /^[ \\t]*(?:\\/\\/|#|<!--|\\/\\*)\\s*#?(?:end)?region\\b.*$/gm,\n \"\",\n );\n // Collapse lines that contain only whitespace into empty lines\n // (artefact of Tab/Tabs wrapper components being stripped)\n result = result.replace(/^[ \\t]+$/gm, \"\");\n // Collapse 3+ blank lines to 2\n result = result.replace(/\\n{3,}/g, \"\\n\\n\");\n return result.trim();\n}\n\n/**\n * Splits a body string into sections on `## ` heading boundaries.\n * Content before the first heading is returned as a section with an empty heading.\n */\nexport function splitIntoSections(body: string): Section[] {\n const parts = body.split(/(?=^## )/m);\n\n return parts\n .map((part): Section => {\n const headingMatch = part.match(/^## (.+)\\n/);\n if (!headingMatch) {\n return { heading: \"\", body: part.trim() };\n }\n return {\n heading: headingMatch[1]!.trim(),\n body: part.replace(/^## .+\\n/, \"\").trim(),\n };\n })\n .filter((s) => s.body.length > 0 || s.heading.length > 0);\n}\n\n// ---------------------------------------------------------------------------\n// File discovery\n// ---------------------------------------------------------------------------\n\nasync function findMdxFiles(dir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const files: string[] = [];\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n files.push(...(await findMdxFiles(fullPath)));\n } else if (entry.name.endsWith(\".mdx\")) {\n files.push(fullPath);\n }\n }\n\n return files.sort();\n}\n\n// ---------------------------------------------------------------------------\n// Main build function\n// ---------------------------------------------------------------------------\n\nexport async function buildIndex({\n contentDir,\n outputDir,\n fileCwd,\n}: BuildIndexOptions): Promise<void> {\n await mkdir(outputDir, { recursive: true });\n\n const mdxFiles = await findMdxFiles(contentDir);\n\n // fileCwd: base for <include cwd> resolution.\n // Defaults to contentDir (works for tests). Production callers pass the\n // docs app working directory (homepage/homepage/) where ../examples/... resolves correctly.\n const resolvedFileCwd = fileCwd ?? contentDir;\n\n const pages = await Promise.all(\n mdxFiles.map(async (filePath) => {\n const raw = await readFile(filePath, \"utf8\");\n const { title, description, body: rawBody } = parseFrontmatter(raw);\n\n const withIncludes = await resolveIncludes(\n rawBody,\n filePath,\n resolvedFileCwd,\n );\n const body = stripJsx(withIncludes);\n\n // Slug: path relative to contentDir, no extension, forward slashes\n const slug = relative(contentDir, filePath)\n .replace(/\\.mdx$/, \"\")\n .replace(/\\\\/g, \"/\");\n\n const finalDescription = description ?? extractDescription(body);\n\n return {\n slug,\n title: title ?? slug,\n description: finalDescription,\n body,\n };\n }),\n );\n\n // Sort by slug for determinism\n pages.sort((a, b) => a.slug.localeCompare(b.slug));\n\n // --- SQLite DB ---\n const dbPath = join(outputDir, \"docs-index.db\");\n // Remove any stale DB so we always start fresh\n try {\n await unlink(dbPath);\n } catch {\n // File didn't exist — fine\n }\n\n // Use a variable so esbuild cannot statically analyse and strip the \"node:\" prefix.\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n const sqliteMod = \"node:sqlite\";\n const { DatabaseSync } = await import(sqliteMod);\n const db = new DatabaseSync(dbPath);\n\n db.exec(`\n CREATE TABLE pages (\n title TEXT NOT NULL,\n slug TEXT PRIMARY KEY,\n description TEXT NOT NULL,\n body TEXT NOT NULL\n );\n CREATE VIRTUAL TABLE sections_fts USING fts5(\n title,\n slug UNINDEXED,\n section_heading,\n body,\n tokenize = 'unicode61'\n );\n `);\n\n const insertPage = db.prepare(\n \"INSERT INTO pages (title, slug, description, body) VALUES (?, ?, ?, ?)\",\n );\n const insertSection = db.prepare(\n \"INSERT INTO sections_fts (title, slug, section_heading, body) VALUES (?, ?, ?, ?)\",\n );\n\n for (const page of pages) {\n insertPage.run(page.title, page.slug, page.description, page.body);\n\n for (const section of splitIntoSections(page.body)) {\n insertSection.run(page.title, page.slug, section.heading, section.body);\n }\n }\n\n db.close();\n\n // --- Plain-text file ---\n const txtParts = pages.map(\n (p) =>\n `===PAGE:${p.slug}===\\nTITLE:${p.title}\\nDESCRIPTION:${p.description}\\n\\n${p.body}`,\n );\n await writeFile(\n join(outputDir, \"docs-index.txt\"),\n txtParts.join(\"\\n\\n\"),\n \"utf8\",\n );\n}\n\n// ---------------------------------------------------------------------------\n// Script entry point\n// ---------------------------------------------------------------------------\n\nconst isMain =\n typeof process !== \"undefined\" &&\n process.argv[1] === fileURLToPath(import.meta.url);\n\nif (isMain) {\n const here = dirname(fileURLToPath(import.meta.url));\n const contentDir = resolve(\n here,\n \"../../../../homepage/homepage/content/docs\",\n );\n const outDir = resolve(here, \"../../bin\");\n // homepage/homepage/ is the Next.js app working directory; <include cwd> paths\n // in MDX are relative to it (e.g. ../examples/... resolves to the repo examples/).\n const fileCwd = resolve(here, \"../../../../homepage/homepage\");\n\n buildIndex({ contentDir, outputDir: outDir, fileCwd })\n .then(() => console.log(\"docs index built →\", outDir))\n .catch((err: unknown) => {\n console.error(\"build-index failed:\", err);\n process.exit(1);\n });\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport { splitIntoSections, type Section } from \"./build-index.js\";\nimport type {\n DocResult,\n DocsBackend,\n PageInfo,\n SearchResult,\n} from \"./backend-sqlite.js\";\n\nexport type { DocResult, DocsBackend, PageInfo, SearchResult };\n\n// ---------------------------------------------------------------------------\n// Warning — emitted when the naive backend is created.\n// The server only ever creates one backend instance per process, so\n// deduplication is not needed here.\n// ---------------------------------------------------------------------------\n\nfunction emitWarning(): void {\n process.stderr.write(\n \"node:sqlite not available — using basic text search. \" +\n \"Upgrade to Node >=22.13 (current LTS) for better results.\\n\",\n );\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface ParsedPage {\n slug: string;\n title: string;\n description: string;\n body: string;\n sections: Section[];\n}\n\n// ---------------------------------------------------------------------------\n// Parsing\n// ---------------------------------------------------------------------------\n\nfunction parseTxt(content: string): ParsedPage[] {\n // Split on page boundaries; each chunk starts with ===PAGE:slug===\n const chunks = content.split(/(?=^===PAGE:)/m).filter((c) => c.trim());\n const pages: ParsedPage[] = [];\n\n for (const chunk of chunks) {\n const lines = chunk.split(\"\\n\");\n const slugMatch = lines[0]!.match(/^===PAGE:(.+)===$/);\n if (!slugMatch) continue;\n\n const slug = slugMatch[1]!;\n const title = lines[1]?.replace(/^TITLE:/, \"\").trim() ?? slug;\n const description = lines[2]?.replace(/^DESCRIPTION:/, \"\").trim() ?? \"\";\n // lines[3] is blank, body starts at lines[4]\n const body = lines.slice(4).join(\"\\n\").trim();\n\n pages.push({\n slug,\n title,\n description,\n body,\n sections: splitIntoSections(body),\n });\n }\n\n return pages;\n}\n\n// ---------------------------------------------------------------------------\n// Search helpers\n// ---------------------------------------------------------------------------\n\nfunction termFrequency(text: string, terms: string[]): number {\n const lower = text.toLowerCase();\n return terms.reduce((count, term) => {\n let pos = 0;\n while ((pos = lower.indexOf(term, pos)) !== -1) {\n count++;\n pos += term.length;\n }\n return count;\n }, 0);\n}\n\nfunction buildSnippet(body: string, terms: string[]): string {\n const lower = body.toLowerCase();\n let best = 0;\n for (const term of terms) {\n const idx = lower.indexOf(term);\n if (idx !== -1) {\n best = idx;\n break;\n }\n }\n const start = Math.max(0, best - 60);\n const end = Math.min(body.length, best + 100);\n const snip = body.slice(start, end).replace(/\\s+/g, \" \").trim();\n return start > 0 ? \"…\" + snip : snip;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport async function createNaiveBackend(\n txtPath: string,\n): Promise<DocsBackend> {\n emitWarning();\n\n const content = await readFile(txtPath, \"utf8\");\n const pages = parseTxt(content);\n const bySlug = new Map(pages.map((p) => [p.slug, p]));\n\n function search(query: string, limit: number): SearchResult[] {\n const terms = query\n .toLowerCase()\n .split(/\\s+/)\n .filter((t) => t.length > 0);\n\n const results: Array<SearchResult & { _freq: number }> = [];\n\n for (const page of pages) {\n for (const section of page.sections) {\n const combined = (section.heading + \" \" + section.body).toLowerCase();\n if (!terms.every((t) => combined.includes(t))) continue;\n\n const freq = termFrequency(combined, terms);\n results.push({\n title: page.title,\n slug: page.slug,\n section: section.heading,\n snippet: buildSnippet(section.body || section.heading, terms),\n _freq: freq,\n });\n }\n }\n\n results.sort((a, b) => b._freq - a._freq);\n return results.slice(0, limit).map(({ _freq: _, ...r }) => r);\n }\n\n function getDoc(slug: string): DocResult | null {\n const page = bySlug.get(slug);\n if (!page) return null;\n return {\n title: page.title,\n slug: page.slug,\n description: page.description,\n body: page.body,\n related: [],\n };\n }\n\n function listPages(): PageInfo[] {\n return pages.map(({ slug, title, description }) => ({\n slug,\n title,\n description,\n }));\n }\n\n return { search, getDoc, listPages };\n}\n","import { createInterface } from \"node:readline\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport type { DocsBackend } from \"./backend-sqlite.js\";\nimport { callTool, toolDefinitions, ToolError } from \"./tools.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface RunServerOptions {\n input?: NodeJS.ReadableStream;\n output?: NodeJS.WritableStream;\n /** Path to docs-index.db. Defaults to <package-root>/bin/docs-index.db */\n dbPath?: string;\n /** Path to docs-index.txt. Defaults to <package-root>/bin/docs-index.txt */\n txtPath?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Backend selection\n// ---------------------------------------------------------------------------\n\nasync function selectBackend(\n dbPath: string,\n txtPath: string,\n): Promise<DocsBackend> {\n try {\n // Step 1: confirm node:sqlite is importable\n const { DatabaseSync } = await import(\"node:sqlite\");\n\n // Step 2: FTS5 probe on an in-memory DB\n const probe = new DatabaseSync(\":memory:\");\n probe.exec(\"CREATE VIRTUAL TABLE _probe USING fts5(x)\");\n probe.close();\n\n // Both passed — use SQLite backend\n const { createSqliteBackend } = await import(\"./backend-sqlite.js\");\n return createSqliteBackend(dbPath);\n } catch {\n // Fall back to naive backend (it emits its own stderr warning)\n const { createNaiveBackend } = await import(\"./backend-naive.js\");\n return createNaiveBackend(txtPath);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Server\n// ---------------------------------------------------------------------------\n\nexport async function runServer(opts: RunServerOptions = {}): Promise<void> {\n const input = opts.input ?? process.stdin;\n const output = opts.output ?? process.stdout;\n\n // Resolve default index paths relative to this module's package bin/ dir\n const here = dirname(fileURLToPath(import.meta.url));\n const binDir = resolve(here, \"../../bin\");\n const dbPath = opts.dbPath ?? join(binDir, \"docs-index.db\");\n const txtPath = opts.txtPath ?? join(binDir, \"docs-index.txt\");\n\n const backend = await selectBackend(dbPath, txtPath);\n\n function write(obj: unknown): void {\n (output as NodeJS.WritableStream).write(JSON.stringify(obj) + \"\\n\");\n }\n\n function handleLine(line: string): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let msg: any;\n try {\n msg = JSON.parse(line);\n } catch {\n write({\n jsonrpc: \"2.0\",\n id: null,\n error: { code: -32700, message: \"Parse error\" },\n });\n return;\n }\n\n const { id, method, params } = msg;\n\n // JSON-RPC notifications have no id — do not respond\n if (id === undefined || id === null) {\n return;\n }\n\n switch (method as string) {\n case \"initialize\":\n write({\n jsonrpc: \"2.0\",\n id,\n result: {\n protocolVersion: \"2024-11-05\",\n capabilities: { tools: {} },\n serverInfo: { name: \"jazz-docs\", version: \"1.0.0\" },\n },\n });\n break;\n\n case \"ping\":\n write({ jsonrpc: \"2.0\", id, result: {} });\n break;\n\n case \"tools/list\":\n write({ jsonrpc: \"2.0\", id, result: { tools: toolDefinitions } });\n break;\n\n case \"tools/call\": {\n const name = (params as any)?.name as string;\n const args = (params as any)?.arguments ?? {};\n try {\n const result = callTool(\n backend,\n name,\n args as Record<string, unknown>,\n );\n write({\n jsonrpc: \"2.0\",\n id,\n result: {\n content: [{ type: \"text\", text: result }],\n },\n });\n } catch (err: unknown) {\n if (err instanceof ToolError) {\n // Tool-execution failure: surface as a successful result so the\n // model can read the message and recover (MCP spec §tool-errors).\n write({\n jsonrpc: \"2.0\",\n id,\n result: {\n content: [{ type: \"text\", text: err.message }],\n isError: true,\n },\n });\n } else {\n // Protocol-level failure (e.g. malformed params).\n const e = err as { code?: number; message?: string };\n write({\n jsonrpc: \"2.0\",\n id,\n error: {\n code: e.code ?? -32603,\n message: e.message ?? \"Internal error\",\n },\n });\n }\n }\n break;\n }\n\n default:\n write({\n jsonrpc: \"2.0\",\n id,\n error: { code: -32601, message: `Method not found: ${method}` },\n });\n }\n }\n\n await new Promise<void>((res) => {\n const rl = createInterface({ input, terminal: false });\n rl.on(\"line\", handleLine);\n rl.on(\"close\", res);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Script entry point\n// ---------------------------------------------------------------------------\n\nconst isMain =\n typeof process !== \"undefined\" &&\n process.argv[1] === fileURLToPath(import.meta.url);\n\nif (isMain) {\n runServer().catch((err: unknown) => {\n console.error(\"jazz-docs MCP server error:\", err);\n process.exit(1);\n });\n}\n","import type { DocsBackend } from \"./backend-sqlite.js\";\n\n// ---------------------------------------------------------------------------\n// Tool definitions (JSON Schema)\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions = [\n {\n name: \"search_docs\",\n description: \"Search the Jazz documentation.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description:\n \"Search query (FTS5 syntax when available, plain keywords in fallback)\",\n },\n limit: {\n type: \"number\",\n description: \"Max results (default 10)\",\n },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"get_doc\",\n description: \"Retrieve the full content of a documentation page.\",\n inputSchema: {\n type: \"object\",\n properties: {\n slug: {\n type: \"string\",\n description: 'Page slug (e.g. \"reading-data\", \"quickstarts/react\")',\n },\n },\n required: [\"slug\"],\n },\n },\n {\n name: \"list_pages\",\n description: \"List all available documentation pages.\",\n inputSchema: {\n type: \"object\",\n properties: {},\n },\n },\n];\n\n// ---------------------------------------------------------------------------\n// Tool call dispatcher\n// ---------------------------------------------------------------------------\n\ninterface RpcError extends Error {\n code: number;\n}\n\nfunction rpcError(code: number, message: string): RpcError {\n return Object.assign(new Error(message), { code });\n}\n\n/** Thrown for tool-execution failures (e.g. page not found, unknown tool).\n * These are surfaced to the model as isError:true rather than JSON-RPC errors. */\nexport class ToolError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ToolError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// ANSI helpers (no dependencies)\n// ---------------------------------------------------------------------------\n\nconst B = \"\\x1b[1m\"; // bold\nconst D = \"\\x1b[2m\"; // dim\nconst R = \"\\x1b[0m\"; // reset\nconst CYAN = \"\\x1b[36m\";\nconst HR = `${D}${\"─\".repeat(60)}${R}`;\nconst fenceRe = /^[ \\t]*```([^\\n]*)\\n([\\s\\S]*?)^[ \\t]*```[ \\t]*$/gm;\n\n// ---------------------------------------------------------------------------\n// Formatters\n// ---------------------------------------------------------------------------\n\nfunction formatSearchResults(\n results: Array<{\n title: string;\n slug: string;\n section: string;\n snippet: string;\n }>,\n): string {\n if (results.length === 0) return \"No results found.\";\n return results\n .map(({ title, slug, section, snippet }) => {\n const heading = section ? `${title} › ${section}` : title;\n return `${B}${CYAN}${heading}${R}\\n${D}${slug}${R}\\n\\n${renderInline(snippet)}`;\n })\n .join(`\\n\\n${HR}\\n\\n`);\n}\n\nfunction renderInline(text: string): string {\n return text\n .replace(/\\*\\*([^*\\n]+)\\*\\*/g, `${B}$1${R}`)\n .replace(/`([^`\\n]+)`/g, `${CYAN}$1${R}`);\n}\n\nfunction dedent(text: string): string {\n const lines = text.split(\"\\n\");\n const nonEmpty = lines.filter((l) => l.trim().length > 0);\n if (nonEmpty.length === 0) return text;\n const minIndent = Math.min(\n ...nonEmpty.map((l) => (l.match(/^[ \\t]*/)?.[0] ?? \"\").length),\n );\n if (minIndent === 0) return text;\n return lines\n .map((l) => (l.length >= minIndent ? l.slice(minIndent) : l))\n .join(\"\\n\");\n}\n\nfunction renderProse(text: string): string {\n const withHeadings = text.replace(\n /^(#{1,6}) (.+)$/gm,\n (_, hashes: string, heading: string) => {\n if (hashes.length === 1) return `${B}${CYAN}${heading}${R}`;\n if (hashes.length === 2) return `${B}${heading}${R}`;\n return `${D}${heading}${R}`;\n },\n );\n return renderInline(withHeadings);\n}\n\nfunction renderBody(body: string): string {\n // Alternate between prose and code blocks so heading/inline rendering\n // never touches code block content.\n const segments: string[] = [];\n let lastIndex = 0;\n fenceRe.lastIndex = 0;\n let match: RegExpExecArray | null;\n // eslint-disable-next-line no-cond-assign\n while ((match = fenceRe.exec(body)) !== null) {\n const prose = body.slice(lastIndex, match.index);\n if (prose) segments.push(renderProse(prose.trimEnd()));\n const lang = match[1]!.trim();\n const content = dedent(match[2]!.trimEnd());\n segments.push(`\\`\\`\\`${lang}\\n${content}\\n\\`\\`\\``);\n lastIndex = match.index + match[0].length;\n }\n const remaining = body.slice(lastIndex);\n if (remaining) segments.push(renderProse(remaining));\n return segments.join(\"\\n\");\n}\n\nfunction formatDoc(doc: {\n title: string;\n slug: string;\n description: string;\n body: string;\n related: string[];\n}): string {\n const parts: string[] = [`${B}${doc.title}${R}`];\n if (doc.description) parts.push(`${D}${renderInline(doc.description)}${R}`);\n parts.push(renderBody(doc.body));\n if (doc.related.length > 0) {\n parts.push(`${HR}\\n${D}Related:${R} ${doc.related.join(\" \")}`);\n }\n return parts.join(\"\\n\\n\");\n}\n\nfunction formatPageList(\n pages: Array<{ title: string; slug: string; description: string }>,\n): string {\n return pages\n .map(\n ({ title, slug, description }) =>\n `${B}${title}${R} ${D}${slug}${R}\\n ${renderInline(description)}`,\n )\n .join(\"\\n\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Tool call dispatcher\n// ---------------------------------------------------------------------------\n\nexport function callTool(\n backend: DocsBackend,\n name: string,\n args: Record<string, unknown>,\n): string {\n switch (name) {\n case \"search_docs\": {\n const query = args.query;\n if (typeof query !== \"string\" || !query) {\n throw rpcError(-32602, \"search_docs: query (string) is required\");\n }\n const limit =\n typeof args.limit === \"number\" ? Math.floor(args.limit) : 10;\n return formatSearchResults(backend.search(query, limit));\n }\n\n case \"get_doc\": {\n const slug = args.slug;\n if (typeof slug !== \"string\" || !slug) {\n throw rpcError(-32602, \"get_doc: slug (string) is required\");\n }\n const result = backend.getDoc(slug);\n if (!result) {\n throw new ToolError(`get_doc: page not found: ${slug}`);\n }\n return formatDoc(result);\n }\n\n case \"list_pages\":\n return formatPageList(backend.listPages());\n\n default:\n throw new ToolError(`Unknown tool: ${name}`);\n }\n}\n"],"mappings":"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","names":["readFile","dirname","join","resolve","fileURLToPath","createSqliteBackend","createNaiveBackend","dirname","fileURLToPath","resolve","join","isMain"]}
|
|
1
|
+
{"version":3,"sources":["../../src/mcp/backend-sqlite.ts","../../src/mcp/build-index.ts","../../src/mcp/backend-naive.ts","../../src/mcp/server.ts","../../src/mcp/tools.ts"],"sourcesContent":["// NOTE: no top-level `import … from \"node:sqlite\"` — this module must be safe\n// to parse/import on Node <22. DatabaseSync is obtained via dynamic import\n// inside createSqliteBackend().\n\nexport interface SearchResult {\n title: string;\n slug: string;\n section: string;\n snippet: string;\n}\n\nexport interface DocResult {\n title: string;\n slug: string;\n description: string;\n body: string;\n related: string[];\n}\n\nexport interface PageInfo {\n title: string;\n slug: string;\n description: string;\n}\n\nexport interface DocsBackend {\n search(query: string, limit: number): SearchResult[];\n getDoc(slug: string): DocResult | null;\n listPages(): PageInfo[];\n}\n\nexport async function createSqliteBackend(\n dbPath: string,\n): Promise<DocsBackend> {\n // Dynamic import keeps node:sqlite off the top-level parse graph\n // Use a variable so esbuild cannot statically analyse and strip the \"node:\" prefix.\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n const sqliteMod = \"node:sqlite\";\n const { DatabaseSync } = await import(sqliteMod);\n const db = new DatabaseSync(dbPath, { readOnly: true });\n\n // ------------------------------------------------------------------\n // Prepared statements\n // ------------------------------------------------------------------\n\n const stmtSearch = db.prepare(`\n SELECT\n title,\n slug,\n section_heading,\n snippet(sections_fts, 3, '', '', '…', 32) AS snip,\n bm25(sections_fts) AS score\n FROM sections_fts\n WHERE sections_fts MATCH ?\n ORDER BY bm25(sections_fts)\n LIMIT ?\n `);\n\n const stmtGetPage = db.prepare(\n \"SELECT title, slug, description, body FROM pages WHERE slug = ?\",\n );\n\n const stmtGetTopHeadings = db.prepare(`\n SELECT section_heading\n FROM sections_fts\n WHERE slug = ? AND section_heading != ''\n LIMIT 3\n `);\n\n // Fetch up to 15 rows ordered by bm25; deduplicate by slug in code (max 5 kept).\n // We avoid sum(bm25()) in a GROUP BY because bm25() is only valid in\n // WHERE / ORDER BY clauses of FTS5 queries.\n const stmtRelated = db.prepare(`\n SELECT slug, bm25(sections_fts) AS score\n FROM sections_fts\n WHERE sections_fts MATCH ? AND slug != ?\n ORDER BY bm25(sections_fts)\n LIMIT 15\n `);\n\n const stmtListPages = db.prepare(\n \"SELECT title, slug, description FROM pages ORDER BY slug\",\n );\n\n // ------------------------------------------------------------------\n // Helpers\n // ------------------------------------------------------------------\n\n function buildRelatedQuery(title: string, slug: string): string | null {\n const headingRows = stmtGetTopHeadings.all(slug) as Array<{\n section_heading: string;\n }>;\n\n const rawTerms = [title, ...headingRows.map((r) => r.section_heading)]\n .join(\" \")\n .split(/\\s+/)\n .map((w) => w.replace(/[^a-zA-Z0-9]/g, \"\"))\n .filter((w) => w.length >= 3);\n\n if (rawTerms.length === 0) return null;\n\n // Deduplicate and use OR so we get broader matches\n const unique = [...new Set(rawTerms.map((w) => w.toLowerCase()))];\n return unique.join(\" OR \");\n }\n\n // ------------------------------------------------------------------\n // Backend methods\n // ------------------------------------------------------------------\n\n function search(query: string, limit: number): SearchResult[] {\n try {\n const rows = stmtSearch.all(query, limit) as Array<{\n title: string;\n slug: string;\n section_heading: string;\n snip: string;\n score: number;\n }>;\n return rows.map((r) => ({\n title: r.title,\n slug: r.slug,\n section: r.section_heading,\n snippet: r.snip,\n }));\n } catch {\n return [];\n }\n }\n\n function getDoc(slug: string): DocResult | null {\n const row = stmtGetPage.get(slug) as\n | { title: string; slug: string; description: string; body: string }\n | undefined;\n if (!row) return null;\n\n let related: string[] = [];\n try {\n const relQuery = buildRelatedQuery(row.title, slug);\n if (relQuery) {\n const relRows = stmtRelated.all(relQuery, slug) as Array<{\n slug: string;\n }>;\n // Deduplicate while preserving bm25 order (first occurrence = best)\n const seen = new Set<string>();\n for (const r of relRows) {\n if (!seen.has(r.slug)) {\n seen.add(r.slug);\n related.push(r.slug);\n if (related.length >= 5) break;\n }\n }\n }\n } catch {\n // related stays []\n }\n\n return {\n title: row.title,\n slug: row.slug,\n description: row.description,\n body: row.body,\n related,\n };\n }\n\n function listPages(): PageInfo[] {\n const rows = stmtListPages.all() as Array<{\n title: string;\n slug: string;\n description: string;\n }>;\n return rows;\n }\n\n return { search, getDoc, listPages };\n}\n","import { mkdir, readdir, readFile, unlink, writeFile } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FrontmatterResult {\n title?: string;\n description?: string;\n body: string;\n}\n\nexport interface Section {\n heading: string;\n body: string;\n}\n\nexport interface BuildIndexOptions {\n /** Path to the content/docs directory containing .mdx files. */\n contentDir: string;\n /** Directory where docs-index.db and docs-index.txt are written. */\n outputDir: string;\n /**\n * Base directory used to resolve <include cwd> paths.\n * Mirrors fumadocs' file.cwd (the app working directory).\n * Defaults to contentDir when not specified.\n */\n fileCwd?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Pure helpers (exported for unit testing)\n// ---------------------------------------------------------------------------\n\n/**\n * Splits YAML frontmatter from MDX content.\n * Returns title, optional description, and the body after the closing `---`.\n */\nexport function parseFrontmatter(content: string): FrontmatterResult {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---\\n*([\\s\\S]*)$/);\n if (!match) {\n return { body: content };\n }\n\n const fm = match[1]!;\n const body = match[2]!.trimStart();\n\n const titleMatch = fm.match(/^title:\\s*(.+)$/m);\n const descMatch = fm.match(/^description:\\s*(.+)$/m);\n\n return {\n title: titleMatch?.[1]?.trim(),\n description: descMatch?.[1]?.trim(),\n body,\n };\n}\n\n/**\n * Extracts a description from rendered body text.\n * Strips fenced code blocks and headings, then returns the first three sentences.\n */\nexport function extractDescription(body: string): string {\n if (!body) return \"\";\n\n // Strip all fenced code blocks\n let text = body.replace(/```[\\s\\S]*?```/g, \"\");\n // Strip markdown headings\n text = text.replace(/^#{1,6}\\s+.*/gm, \"\");\n // Strip JSX tags (in case they weren't stripped already)\n text = text.replace(/<\\/?[A-Z][a-zA-Z]*[^>]*>/g, \"\");\n // Collapse all whitespace to single spaces\n text = text.replace(/\\s+/g, \" \").trim();\n\n const sentences: string[] = [];\n const sentenceRe = /[^.!?]+[.!?]+/g;\n let m: RegExpExecArray | null;\n while ((m = sentenceRe.exec(text)) !== null && sentences.length < 3) {\n sentences.push(m[0].trim());\n }\n\n return sentences.join(\" \");\n}\n\n/**\n * Resolves `<include cwd lang=\"…\">path[#anchor]</include>` directives in MDX\n * content, replacing each with a fenced code block. Paths are resolved\n * relative to the MDX file's directory unless the `cwd` attribute is present,\n * in which case fileCwd is used (mirrors fumadocs' file.cwd semantics).\n * Additional attributes (e.g. meta='…') are tolerated and ignored.\n */\nexport async function resolveIncludes(\n content: string,\n mdxFilePath: string,\n fileCwd?: string,\n): Promise<string> {\n // Match <include ...attrs...>path</include> — any attribute combination.\n const includeRe = /<include\\s+([^>]*?)>\\s*([\\s\\S]*?)\\s*<\\/include>/g;\n\n // Collect all replacements first, then apply (to avoid regex state issues)\n const replacements: Array<{ original: string; replacement: string }> = [];\n let m: RegExpExecArray | null;\n\n while ((m = includeRe.exec(content)) !== null) {\n const attrs = m[1]!;\n const hasCwd = /\\bcwd\\b/.test(attrs);\n const langMatch = attrs.match(/\\blang=\"([^\"]+)\"/);\n if (!langMatch) continue; // not a code include — leave untouched\n const lang = langMatch[1]!;\n const rawPath = m[2]!.trim();\n const hashIdx = rawPath.indexOf(\"#\");\n const filePath = hashIdx === -1 ? rawPath : rawPath.slice(0, hashIdx);\n const anchor = hashIdx === -1 ? null : rawPath.slice(hashIdx + 1);\n\n const base = hasCwd && fileCwd ? fileCwd : dirname(mdxFilePath);\n const resolvedPath = resolve(base, filePath.trim());\n let fileContent = await readFile(resolvedPath, \"utf8\");\n\n if (anchor) {\n const regionRe = new RegExp(\n `// #region ${anchor}\\\\n([\\\\s\\\\S]*?)// #endregion ${anchor}`,\n );\n const regionMatch = fileContent.match(regionRe);\n if (regionMatch) {\n fileContent = regionMatch[1]!.trimEnd();\n }\n }\n\n replacements.push({\n original: m[0],\n replacement: `\\`\\`\\`${lang}\\n${fileContent}\\n\\`\\`\\``,\n });\n }\n\n let result = content;\n for (const { original, replacement } of replacements) {\n result = result.replace(original, replacement);\n }\n return result;\n}\n\n/**\n * Strips JSX component tags (uppercase-initial or namespaced) from content,\n * preserving text and fenced code blocks inside them.\n * Also strips MDX import/export declarations.\n */\nexport function stripJsx(content: string): string {\n let result = content;\n // Strip MDX import/export lines\n result = result.replace(/^(?:import|export)\\s+.*$/gm, \"\");\n // Self-closing JSX: <Component />\n result = result.replace(/<[A-Z][a-zA-Z]*(?:\\.[a-zA-Z]+)?[^>]*\\/>/g, \"\");\n // Opening JSX: <Component ...>\n result = result.replace(/<[A-Z][a-zA-Z]*(?:\\.[a-zA-Z]+)?[^>]*>/g, \"\");\n // Closing JSX: </Component>\n result = result.replace(/<\\/[A-Z][a-zA-Z]*(?:\\.[a-zA-Z]+)?>/g, \"\");\n // Strip region marker lines left over from include expansion\n // Covers: // #region, # #region, <!-- #region, /* #region */\n result = result.replace(\n /^[ \\t]*(?:\\/\\/|#|<!--|\\/\\*)\\s*#?(?:end)?region\\b.*$/gm,\n \"\",\n );\n // Collapse lines that contain only whitespace into empty lines\n // (artefact of Tab/Tabs wrapper components being stripped)\n result = result.replace(/^[ \\t]+$/gm, \"\");\n // Collapse 3+ blank lines to 2\n result = result.replace(/\\n{3,}/g, \"\\n\\n\");\n return result.trim();\n}\n\n/**\n * Splits a body string into sections on `## ` heading boundaries.\n * Content before the first heading is returned as a section with an empty heading.\n */\nexport function splitIntoSections(body: string): Section[] {\n const parts = body.split(/(?=^## )/m);\n\n return parts\n .map((part): Section => {\n const headingMatch = part.match(/^## (.+)\\n/);\n if (!headingMatch) {\n return { heading: \"\", body: part.trim() };\n }\n return {\n heading: headingMatch[1]!.trim(),\n body: part.replace(/^## .+\\n/, \"\").trim(),\n };\n })\n .filter((s) => s.body.length > 0 || s.heading.length > 0);\n}\n\n// ---------------------------------------------------------------------------\n// File discovery\n// ---------------------------------------------------------------------------\n\nasync function findMdxFiles(dir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const files: string[] = [];\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n files.push(...(await findMdxFiles(fullPath)));\n } else if (entry.name.endsWith(\".mdx\")) {\n files.push(fullPath);\n }\n }\n\n return files.sort();\n}\n\n// ---------------------------------------------------------------------------\n// Main build function\n// ---------------------------------------------------------------------------\n\nexport async function buildIndex({\n contentDir,\n outputDir,\n fileCwd,\n}: BuildIndexOptions): Promise<void> {\n await mkdir(outputDir, { recursive: true });\n\n const mdxFiles = await findMdxFiles(contentDir);\n\n // fileCwd: base for <include cwd> resolution.\n // Defaults to contentDir (works for tests). Production callers pass the\n // docs app working directory (homepage/homepage/) where ../examples/... resolves correctly.\n const resolvedFileCwd = fileCwd ?? contentDir;\n\n const pages = await Promise.all(\n mdxFiles.map(async (filePath) => {\n const raw = await readFile(filePath, \"utf8\");\n const { title, description, body: rawBody } = parseFrontmatter(raw);\n\n const withIncludes = await resolveIncludes(\n rawBody,\n filePath,\n resolvedFileCwd,\n );\n const body = stripJsx(withIncludes);\n\n // Slug: path relative to contentDir, no extension, forward slashes\n const slug = relative(contentDir, filePath)\n .replace(/\\.mdx$/, \"\")\n .replace(/\\\\/g, \"/\");\n\n const finalDescription = description ?? extractDescription(body);\n\n return {\n slug,\n title: title ?? slug,\n description: finalDescription,\n body,\n };\n }),\n );\n\n // Sort by slug for determinism\n pages.sort((a, b) => a.slug.localeCompare(b.slug));\n\n // --- SQLite DB ---\n const dbPath = join(outputDir, \"docs-index.db\");\n // Remove any stale DB so we always start fresh\n try {\n await unlink(dbPath);\n } catch {\n // File didn't exist — fine\n }\n\n // Use a variable so esbuild cannot statically analyse and strip the \"node:\" prefix.\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n const sqliteMod = \"node:sqlite\";\n const { DatabaseSync } = await import(sqliteMod);\n const db = new DatabaseSync(dbPath);\n\n db.exec(`\n CREATE TABLE pages (\n title TEXT NOT NULL,\n slug TEXT PRIMARY KEY,\n description TEXT NOT NULL,\n body TEXT NOT NULL\n );\n CREATE VIRTUAL TABLE sections_fts USING fts5(\n title,\n slug UNINDEXED,\n section_heading,\n body,\n tokenize = 'unicode61'\n );\n `);\n\n const insertPage = db.prepare(\n \"INSERT INTO pages (title, slug, description, body) VALUES (?, ?, ?, ?)\",\n );\n const insertSection = db.prepare(\n \"INSERT INTO sections_fts (title, slug, section_heading, body) VALUES (?, ?, ?, ?)\",\n );\n\n for (const page of pages) {\n insertPage.run(page.title, page.slug, page.description, page.body);\n\n for (const section of splitIntoSections(page.body)) {\n insertSection.run(page.title, page.slug, section.heading, section.body);\n }\n }\n\n db.close();\n\n // --- Plain-text file ---\n const txtParts = pages.map(\n (p) =>\n `===PAGE:${p.slug}===\\nTITLE:${p.title}\\nDESCRIPTION:${p.description}\\n\\n${p.body}`,\n );\n await writeFile(\n join(outputDir, \"docs-index.txt\"),\n txtParts.join(\"\\n\\n\"),\n \"utf8\",\n );\n}\n\n// ---------------------------------------------------------------------------\n// Script entry point\n// ---------------------------------------------------------------------------\n\nconst isMain =\n typeof process !== \"undefined\" &&\n process.argv[1] === fileURLToPath(import.meta.url);\n\nif (isMain) {\n const here = dirname(fileURLToPath(import.meta.url));\n const contentDir = resolve(\n here,\n \"../../../../homepage/homepage/content/docs\",\n );\n const outDir = resolve(here, \"../../bin\");\n // homepage/homepage/ is the Next.js app working directory; <include cwd> paths\n // in MDX are relative to it (e.g. ../examples/... resolves to the repo examples/).\n const fileCwd = resolve(here, \"../../../../homepage/homepage\");\n\n buildIndex({ contentDir, outputDir: outDir, fileCwd })\n .then(() => console.log(\"docs index built →\", outDir))\n .catch((err: unknown) => {\n console.error(\"build-index failed:\", err);\n process.exit(1);\n });\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport { splitIntoSections, type Section } from \"./build-index.js\";\nimport type {\n DocResult,\n DocsBackend,\n PageInfo,\n SearchResult,\n} from \"./backend-sqlite.js\";\n\nexport type { DocResult, DocsBackend, PageInfo, SearchResult };\n\n// ---------------------------------------------------------------------------\n// Warning — emitted when the naive backend is created.\n// The server only ever creates one backend instance per process, so\n// deduplication is not needed here.\n// ---------------------------------------------------------------------------\n\nfunction emitWarning(): void {\n process.stderr.write(\n \"node:sqlite not available — using basic text search. \" +\n \"Upgrade to Node >=22.13 (current LTS) for better results.\\n\",\n );\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface ParsedPage {\n slug: string;\n title: string;\n description: string;\n body: string;\n sections: Section[];\n}\n\n// ---------------------------------------------------------------------------\n// Parsing\n// ---------------------------------------------------------------------------\n\nfunction parseTxt(content: string): ParsedPage[] {\n // Split on page boundaries; each chunk starts with ===PAGE:slug===\n const chunks = content.split(/(?=^===PAGE:)/m).filter((c) => c.trim());\n const pages: ParsedPage[] = [];\n\n for (const chunk of chunks) {\n const lines = chunk.split(\"\\n\");\n const slugMatch = lines[0]!.match(/^===PAGE:(.+)===$/);\n if (!slugMatch) continue;\n\n const slug = slugMatch[1]!;\n const title = lines[1]?.replace(/^TITLE:/, \"\").trim() ?? slug;\n const description = lines[2]?.replace(/^DESCRIPTION:/, \"\").trim() ?? \"\";\n // lines[3] is blank, body starts at lines[4]\n const body = lines.slice(4).join(\"\\n\").trim();\n\n pages.push({\n slug,\n title,\n description,\n body,\n sections: splitIntoSections(body),\n });\n }\n\n return pages;\n}\n\n// ---------------------------------------------------------------------------\n// Search helpers\n// ---------------------------------------------------------------------------\n\nfunction termFrequency(text: string, terms: string[]): number {\n const lower = text.toLowerCase();\n return terms.reduce((count, term) => {\n let pos = 0;\n while ((pos = lower.indexOf(term, pos)) !== -1) {\n count++;\n pos += term.length;\n }\n return count;\n }, 0);\n}\n\nfunction buildSnippet(body: string, terms: string[]): string {\n const lower = body.toLowerCase();\n let best = 0;\n for (const term of terms) {\n const idx = lower.indexOf(term);\n if (idx !== -1) {\n best = idx;\n break;\n }\n }\n const start = Math.max(0, best - 60);\n const end = Math.min(body.length, best + 100);\n const snip = body.slice(start, end).replace(/\\s+/g, \" \").trim();\n return start > 0 ? \"…\" + snip : snip;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport async function createNaiveBackend(\n txtPath: string,\n): Promise<DocsBackend> {\n emitWarning();\n\n const content = await readFile(txtPath, \"utf8\");\n const pages = parseTxt(content);\n const bySlug = new Map(pages.map((p) => [p.slug, p]));\n\n function search(query: string, limit: number): SearchResult[] {\n const terms = query\n .toLowerCase()\n .split(/\\s+/)\n .filter((t) => t.length > 0);\n\n const results: Array<SearchResult & { _freq: number }> = [];\n\n for (const page of pages) {\n for (const section of page.sections) {\n const combined = (section.heading + \" \" + section.body).toLowerCase();\n if (!terms.every((t) => combined.includes(t))) continue;\n\n const freq = termFrequency(combined, terms);\n results.push({\n title: page.title,\n slug: page.slug,\n section: section.heading,\n snippet: buildSnippet(section.body || section.heading, terms),\n _freq: freq,\n });\n }\n }\n\n results.sort((a, b) => b._freq - a._freq);\n return results.slice(0, limit).map(({ _freq: _, ...r }) => r);\n }\n\n function getDoc(slug: string): DocResult | null {\n const page = bySlug.get(slug);\n if (!page) return null;\n return {\n title: page.title,\n slug: page.slug,\n description: page.description,\n body: page.body,\n related: [],\n };\n }\n\n function listPages(): PageInfo[] {\n return pages.map(({ slug, title, description }) => ({\n slug,\n title,\n description,\n }));\n }\n\n return { search, getDoc, listPages };\n}\n","import { createInterface } from \"node:readline\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport type { DocsBackend } from \"./backend-sqlite.js\";\nimport { callTool, toolDefinitions, ToolError } from \"./tools.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface RunServerOptions {\n input?: NodeJS.ReadableStream;\n output?: NodeJS.WritableStream;\n /** Path to docs-index.db. Defaults to <package-root>/bin/docs-index.db */\n dbPath?: string;\n /** Path to docs-index.txt. Defaults to <package-root>/bin/docs-index.txt */\n txtPath?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Backend selection\n// ---------------------------------------------------------------------------\n\nasync function selectBackend(\n dbPath: string,\n txtPath: string,\n): Promise<DocsBackend> {\n try {\n // Step 1: confirm node:sqlite is importable\n // Use a variable so esbuild cannot statically analyse and strip the \"node:\" prefix.\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n const sqliteMod = \"node:sqlite\";\n const { DatabaseSync } = await import(sqliteMod);\n\n // Step 2: FTS5 probe on an in-memory DB\n const probe = new DatabaseSync(\":memory:\");\n probe.exec(\"CREATE VIRTUAL TABLE _probe USING fts5(x)\");\n probe.close();\n\n // Both passed — use SQLite backend\n const { createSqliteBackend } = await import(\"./backend-sqlite.js\");\n return createSqliteBackend(dbPath);\n } catch {\n // Fall back to naive backend (it emits its own stderr warning)\n const { createNaiveBackend } = await import(\"./backend-naive.js\");\n return createNaiveBackend(txtPath);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Server\n// ---------------------------------------------------------------------------\n\nexport async function runServer(opts: RunServerOptions = {}): Promise<void> {\n const input = opts.input ?? process.stdin;\n const output = opts.output ?? process.stdout;\n\n // Resolve default index paths relative to this module's package bin/ dir\n const here = dirname(fileURLToPath(import.meta.url));\n const binDir = resolve(here, \"../../bin\");\n const dbPath = opts.dbPath ?? join(binDir, \"docs-index.db\");\n const txtPath = opts.txtPath ?? join(binDir, \"docs-index.txt\");\n\n const backend = await selectBackend(dbPath, txtPath);\n\n function write(obj: unknown): void {\n (output as NodeJS.WritableStream).write(JSON.stringify(obj) + \"\\n\");\n }\n\n function handleLine(line: string): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let msg: any;\n try {\n msg = JSON.parse(line);\n } catch {\n write({\n jsonrpc: \"2.0\",\n id: null,\n error: { code: -32700, message: \"Parse error\" },\n });\n return;\n }\n\n const { id, method, params } = msg;\n\n // JSON-RPC notifications have no id — do not respond\n if (id === undefined || id === null) {\n return;\n }\n\n switch (method as string) {\n case \"initialize\":\n write({\n jsonrpc: \"2.0\",\n id,\n result: {\n protocolVersion: \"2024-11-05\",\n capabilities: { tools: {} },\n serverInfo: { name: \"jazz-docs\", version: \"1.0.0\" },\n },\n });\n break;\n\n case \"ping\":\n write({ jsonrpc: \"2.0\", id, result: {} });\n break;\n\n case \"tools/list\":\n write({ jsonrpc: \"2.0\", id, result: { tools: toolDefinitions } });\n break;\n\n case \"tools/call\": {\n const name = (params as any)?.name as string;\n const args = (params as any)?.arguments ?? {};\n try {\n const result = callTool(\n backend,\n name,\n args as Record<string, unknown>,\n );\n write({\n jsonrpc: \"2.0\",\n id,\n result: {\n content: [{ type: \"text\", text: result }],\n },\n });\n } catch (err: unknown) {\n if (err instanceof ToolError) {\n // Tool-execution failure: surface as a successful result so the\n // model can read the message and recover (MCP spec §tool-errors).\n write({\n jsonrpc: \"2.0\",\n id,\n result: {\n content: [{ type: \"text\", text: err.message }],\n isError: true,\n },\n });\n } else {\n // Protocol-level failure (e.g. malformed params).\n const e = err as { code?: number; message?: string };\n write({\n jsonrpc: \"2.0\",\n id,\n error: {\n code: e.code ?? -32603,\n message: e.message ?? \"Internal error\",\n },\n });\n }\n }\n break;\n }\n\n default:\n write({\n jsonrpc: \"2.0\",\n id,\n error: { code: -32601, message: `Method not found: ${method}` },\n });\n }\n }\n\n await new Promise<void>((res) => {\n const rl = createInterface({ input, terminal: false });\n rl.on(\"line\", handleLine);\n rl.on(\"close\", res);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Script entry point\n// ---------------------------------------------------------------------------\n\nconst isMain =\n typeof process !== \"undefined\" &&\n process.argv[1] === fileURLToPath(import.meta.url);\n\nif (isMain) {\n runServer().catch((err: unknown) => {\n console.error(\"jazz-docs MCP server error:\", err);\n process.exit(1);\n });\n}\n","import type { DocsBackend } from \"./backend-sqlite.js\";\n\n// ---------------------------------------------------------------------------\n// Tool definitions (JSON Schema)\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions = [\n {\n name: \"search_docs\",\n description: \"Search the Jazz documentation.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description:\n \"Search query (FTS5 syntax when available, plain keywords in fallback)\",\n },\n limit: {\n type: \"number\",\n description: \"Max results (default 10)\",\n },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"get_doc\",\n description: \"Retrieve the full content of a documentation page.\",\n inputSchema: {\n type: \"object\",\n properties: {\n slug: {\n type: \"string\",\n description: 'Page slug (e.g. \"reading-data\", \"quickstarts/react\")',\n },\n },\n required: [\"slug\"],\n },\n },\n {\n name: \"list_pages\",\n description: \"List all available documentation pages.\",\n inputSchema: {\n type: \"object\",\n properties: {},\n },\n },\n];\n\n// ---------------------------------------------------------------------------\n// Tool call dispatcher\n// ---------------------------------------------------------------------------\n\ninterface RpcError extends Error {\n code: number;\n}\n\nfunction rpcError(code: number, message: string): RpcError {\n return Object.assign(new Error(message), { code });\n}\n\n/** Thrown for tool-execution failures (e.g. page not found, unknown tool).\n * These are surfaced to the model as isError:true rather than JSON-RPC errors. */\nexport class ToolError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ToolError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// ANSI helpers (no dependencies)\n// ---------------------------------------------------------------------------\n\nconst B = \"\\x1b[1m\"; // bold\nconst D = \"\\x1b[2m\"; // dim\nconst R = \"\\x1b[0m\"; // reset\nconst CYAN = \"\\x1b[36m\";\nconst HR = `${D}${\"─\".repeat(60)}${R}`;\nconst fenceRe = /^[ \\t]*```([^\\n]*)\\n([\\s\\S]*?)^[ \\t]*```[ \\t]*$/gm;\n\n// ---------------------------------------------------------------------------\n// Formatters\n// ---------------------------------------------------------------------------\n\nfunction formatSearchResults(\n results: Array<{\n title: string;\n slug: string;\n section: string;\n snippet: string;\n }>,\n): string {\n if (results.length === 0) return \"No results found.\";\n return results\n .map(({ title, slug, section, snippet }) => {\n const heading = section ? `${title} › ${section}` : title;\n return `${B}${CYAN}${heading}${R}\\n${D}${slug}${R}\\n\\n${renderInline(snippet)}`;\n })\n .join(`\\n\\n${HR}\\n\\n`);\n}\n\nfunction renderInline(text: string): string {\n return text\n .replace(/\\*\\*([^*\\n]+)\\*\\*/g, `${B}$1${R}`)\n .replace(/`([^`\\n]+)`/g, `${CYAN}$1${R}`);\n}\n\nfunction dedent(text: string): string {\n const lines = text.split(\"\\n\");\n const nonEmpty = lines.filter((l) => l.trim().length > 0);\n if (nonEmpty.length === 0) return text;\n const minIndent = Math.min(\n ...nonEmpty.map((l) => (l.match(/^[ \\t]*/)?.[0] ?? \"\").length),\n );\n if (minIndent === 0) return text;\n return lines\n .map((l) => (l.length >= minIndent ? l.slice(minIndent) : l))\n .join(\"\\n\");\n}\n\nfunction renderProse(text: string): string {\n const withHeadings = text.replace(\n /^(#{1,6}) (.+)$/gm,\n (_, hashes: string, heading: string) => {\n if (hashes.length === 1) return `${B}${CYAN}${heading}${R}`;\n if (hashes.length === 2) return `${B}${heading}${R}`;\n return `${D}${heading}${R}`;\n },\n );\n return renderInline(withHeadings);\n}\n\nfunction renderBody(body: string): string {\n // Alternate between prose and code blocks so heading/inline rendering\n // never touches code block content.\n const segments: string[] = [];\n let lastIndex = 0;\n fenceRe.lastIndex = 0;\n let match: RegExpExecArray | null;\n // eslint-disable-next-line no-cond-assign\n while ((match = fenceRe.exec(body)) !== null) {\n const prose = body.slice(lastIndex, match.index);\n if (prose) segments.push(renderProse(prose.trimEnd()));\n const lang = match[1]!.trim();\n const content = dedent(match[2]!.trimEnd());\n segments.push(`\\`\\`\\`${lang}\\n${content}\\n\\`\\`\\``);\n lastIndex = match.index + match[0].length;\n }\n const remaining = body.slice(lastIndex);\n if (remaining) segments.push(renderProse(remaining));\n return segments.join(\"\\n\");\n}\n\nfunction formatDoc(doc: {\n title: string;\n slug: string;\n description: string;\n body: string;\n related: string[];\n}): string {\n const parts: string[] = [`${B}${doc.title}${R}`];\n if (doc.description) parts.push(`${D}${renderInline(doc.description)}${R}`);\n parts.push(renderBody(doc.body));\n if (doc.related.length > 0) {\n parts.push(`${HR}\\n${D}Related:${R} ${doc.related.join(\" \")}`);\n }\n return parts.join(\"\\n\\n\");\n}\n\nfunction formatPageList(\n pages: Array<{ title: string; slug: string; description: string }>,\n): string {\n return pages\n .map(\n ({ title, slug, description }) =>\n `${B}${title}${R} ${D}${slug}${R}\\n ${renderInline(description)}`,\n )\n .join(\"\\n\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Tool call dispatcher\n// ---------------------------------------------------------------------------\n\nexport function callTool(\n backend: DocsBackend,\n name: string,\n args: Record<string, unknown>,\n): string {\n switch (name) {\n case \"search_docs\": {\n const query = args.query;\n if (typeof query !== \"string\" || !query) {\n throw rpcError(-32602, \"search_docs: query (string) is required\");\n }\n const limit =\n typeof args.limit === \"number\" ? Math.floor(args.limit) : 10;\n return formatSearchResults(backend.search(query, limit));\n }\n\n case \"get_doc\": {\n const slug = args.slug;\n if (typeof slug !== \"string\" || !slug) {\n throw rpcError(-32602, \"get_doc: slug (string) is required\");\n }\n const result = backend.getDoc(slug);\n if (!result) {\n throw new ToolError(`get_doc: page not found: ${slug}`);\n }\n return formatDoc(result);\n }\n\n case \"list_pages\":\n return formatPageList(backend.listPages());\n\n default:\n throw new ToolError(`Unknown tool: ${name}`);\n }\n}\n"],"mappings":"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","names":["readFile","dirname","join","resolve","fileURLToPath","createSqliteBackend","createNaiveBackend","dirname","fileURLToPath","resolve","join","isMain"]}
|
|
@@ -1063,7 +1063,10 @@ async function createJazzReactNativeContext(options) {
|
|
|
1063
1063
|
};
|
|
1064
1064
|
}
|
|
1065
1065
|
function createInviteLink(value, role, { baseURL, valueHint } = {}) {
|
|
1066
|
-
return baseCreateInviteLink(value, role,
|
|
1066
|
+
return baseCreateInviteLink(value, role, {
|
|
1067
|
+
baseURL: baseURL ?? "",
|
|
1068
|
+
valueHint
|
|
1069
|
+
});
|
|
1067
1070
|
}
|
|
1068
1071
|
function setupKvStore(kvStore) {
|
|
1069
1072
|
if (!kvStore) {
|