@json-to-office/mcp-server 1.2.0
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/LICENSE +18 -0
- package/README.md +340 -0
- package/dist/cli.d.ts +20 -0
- package/dist/cli.js +5797 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +718 -0
- package/dist/index.js +5779 -0
- package/dist/index.js.map +1 -0
- package/package.json +79 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/server.ts","../src/lib/version.ts","../src/tools/info.ts","../src/lib/schema.ts","../src/lib/errors.ts","../src/tools/discover.ts","../src/tools/describe-component.ts","../src/lib/adapters.ts","../src/lib/workspace-store.ts","../src/lib/doc-source.ts","../src/tools/validate.ts","../src/lib/artifacts.ts","../src/lib/diagnostic-budget.ts","../src/lib/render-options.ts","../src/tools/generate.ts","../src/lib/output-root.ts","../src/preview/codes.ts","../src/preview/page-spec.ts","../src/preview/limits.ts","../src/preview/render.ts","../src/preview/cache-key.ts","../src/preview/dependencies.ts","../src/tools/preview.ts","../src/tools/diff.ts","../src/workspace/json-pointer.ts","../src/workspace/json-patch.ts","../src/workspace/store.ts","../src/tools/workspace.ts","../src/resources/index.ts","../src/lib/deps.ts"],"sourcesContent":["/**\n * `jto-mcp` — the stdio entry point.\n *\n * stdout is the protocol. Nothing here writes to it except `--version` and\n * `--help`, both of which exit before a transport exists; the transport\n * failures the SDK hands us go to stderr, and everything a document or a\n * render has to say goes back in the tool result that asked. A single stray\n * `console.log` anywhere in this process desynchronizes the client's framing,\n * which is why the argument parser below is fifteen lines of hand-rolled code\n * rather than commander: fewer things in the graph, fewer things that print.\n */\n\nimport { serveStdio } from '@modelcontextprotocol/server/stdio';\n\nimport { createServerFactory } from './server.js';\nimport { createToolDeps } from './lib/deps.js';\nimport { OUTPUT_DIR_ENV } from './lib/output-root.js';\nimport { SERVER_VERSION } from './lib/version.js';\n\ninterface ParsedArgs {\n outputDir?: string;\n version: boolean;\n help: boolean;\n unknown: string[];\n}\n\nexport function parseArgs(argv: readonly string[]): ParsedArgs {\n const parsed: ParsedArgs = { version: false, help: false, unknown: [] };\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg === '--version' || arg === '-v') {\n parsed.version = true;\n } else if (arg === '--help' || arg === '-h') {\n parsed.help = true;\n } else if (arg === '--output-dir') {\n parsed.outputDir = argv[++index];\n } else if (arg.startsWith('--output-dir=')) {\n parsed.outputDir = arg.slice('--output-dir='.length);\n } else {\n parsed.unknown.push(arg);\n }\n }\n return parsed;\n}\n\nconst HELP = `jto-mcp — Model Context Protocol server for @json-to-office\n\nUsage:\n jto-mcp [options]\n\nSpeaks MCP over stdio; it is started by an MCP client, not run interactively.\n\nOptions:\n --output-dir <path> Directory generated files are written to. Overrides\n ${OUTPUT_DIR_ENV}. Defaults to a per-connection\n directory under the system temp dir.\n -v, --version Print the version and exit.\n -h, --help Print this help and exit.\n\nEnvironment:\n ${OUTPUT_DIR_ENV} Output root, when --output-dir is absent.\n LIBREOFFICE_PATH LibreOffice binary, for preview.\n PDFTOPPM_PATH poppler pdftoppm binary, for preview.\n\nClient configuration:\n { \"mcpServers\": { \"json-to-office\": { \"command\": \"npx\",\n \"args\": [\"-y\", \"@json-to-office/mcp-server\"] } } }\n`;\n\nfunction main(argv: readonly string[]): void {\n const args = parseArgs(argv);\n\n // The only writes to stdout in this process, and both are followed by exit.\n if (args.help) {\n process.stdout.write(HELP);\n return;\n }\n if (args.version) {\n process.stdout.write(`${SERVER_VERSION}\\n`);\n return;\n }\n if (args.unknown.length > 0) {\n process.stderr.write(\n `jto-mcp: unknown argument ${args.unknown[0]}\\nRun jto-mcp --help.\\n`\n );\n process.exitCode = 1;\n return;\n }\n\n const deps = createToolDeps({\n ...(args.outputDir !== undefined && { outputDir: args.outputDir }),\n });\n\n // No diagnostic sink is installed here. `jto-ops` emits its warnings\n // (unresolved fonts, unknown themes) through an AsyncLocalStorage sink, and\n // a sink scoped around this function would be off the stack by the time the\n // first request arrives on a later turn of the loop — it looked like a\n // connection-wide fallback and caught nothing. `guarded` scopes one per tool\n // call instead, where the warnings can be folded into the result the agent\n // actually reads.\n const handle = serveStdio(createServerFactory(deps), {\n legacy: 'serve',\n onerror: (error) => {\n process.stderr.write(`jto-mcp: ${error.stack ?? error.message}\\n`);\n },\n });\n\n // Close the transport but leave the output root alone: the paths this\n // connection handed back are the whole point of `outputMode: 'path'`, and a\n // user opening the .docx after the client disconnects would find it gone.\n // Temp roots are the OS's to reap.\n const shutdown = (): void => {\n void handle.close().catch(() => undefined);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\nmain(process.argv.slice(2));\n","/**\n * The server, assembled once.\n *\n * Every tool module exposes the same `register(server, deps)` and is listed\n * here in a fixed order, so the modules can be written independently and this\n * file never has to change again as they land. Registration order is the order\n * `tools/list` reports, which is also the order an agent reads them in — hence\n * info, then discovery, then the authoring loop, then workspaces.\n */\n\nimport { McpServer } from '@modelcontextprotocol/server';\nimport type { McpServerFactory } from '@modelcontextprotocol/server';\n\nimport type { ToolDeps } from './lib/deps.js';\nimport { SERVER_NAME } from './lib/version.js';\n\nimport { register as registerInfo } from './tools/info.js';\nimport { register as registerDiscover } from './tools/discover.js';\nimport { register as registerDescribeComponent } from './tools/describe-component.js';\nimport { register as registerValidate } from './tools/validate.js';\nimport { register as registerGenerate } from './tools/generate.js';\nimport { register as registerPreview } from './tools/preview.js';\nimport { register as registerDiff } from './tools/diff.js';\nimport { register as registerWorkspace } from './tools/workspace.js';\nimport { register as registerResources } from './resources/index.js';\n\n/**\n * The server's own prompt, surfaced to the client at initialize.\n *\n * These are the invariants an agent gets wrong without being told: that the\n * JSON is the artifact and the file is a build product, that large rewrites\n * lose more than they fix, and that looking at a rendered page is cheaper than\n * reasoning about whether a layout worked (#271).\n */\nexport const SERVER_INSTRUCTIONS = `Author Microsoft Word (.docx) and PowerPoint (.pptx) documents as JSON.\n\nThe JSON is authoritative. A generated file is a build product of the document JSON plus a renderer, a theme, fonts, assets and options — edit the JSON and regenerate; never treat the binary as the source.\n\nWorking rules:\n- Discover before authoring. Call jto_info first, then jto_discover and jto_describe_component (or read the jto:// resources) for the components and renderer ids a format actually supports.\n- Make small edits. With a workspace handle, patch precisely (RFC 6902 over RFC 6901 paths) instead of resending the whole document; without one, change one region at a time.\n- Validate often. Run jto_validate after each edit rather than once at the end; diagnostics are path-addressed, so they map straight back onto the JSON you just changed.\n- Preview when the answer is visual. jto_preview renders pages to PNG; use it whenever layout, overflow or fit is in question, not only before finishing.\n- Snapshot before risky changes. jto_workspace_snapshot pins the current revision so a restructuring you cannot cleanly undo is still recoverable.\n\nDocument defects come back as structured diagnostics with ok: false, not as errors — read them and repair. Generated files are written under the server's output root and returned as paths; ask for base64 only for small artifacts.`;\n\n/** Build a server with every tool and resource registered. */\nexport function createServer(deps: ToolDeps): McpServer {\n const server = new McpServer(\n { name: SERVER_NAME, version: deps.serverVersion },\n {\n capabilities: { tools: {}, resources: {} },\n instructions: SERVER_INSTRUCTIONS,\n }\n );\n\n registerInfo(server, deps);\n registerDiscover(server, deps);\n registerDescribeComponent(server, deps);\n registerValidate(server, deps);\n registerGenerate(server, deps);\n registerPreview(server, deps);\n registerDiff(server, deps);\n registerWorkspace(server, deps);\n registerResources(server, deps);\n\n return server;\n}\n\n/**\n * The factory `serveStdio` wants.\n *\n * It is called once per connection and, on a 2025-era opening, once more for\n * the pinned legacy instance — so it must build a fresh `McpServer` every\n * time. `deps` are deliberately shared: the output root and the workspace\n * store belong to the process, which for stdio is the connection.\n */\nexport function createServerFactory(deps: ToolDeps): McpServerFactory {\n return () => createServer(deps);\n}\n","/**\n * Build-time version, injected by tsup's `define`.\n *\n * The `typeof` guard is what makes this work under vitest and `tsx`, where no\n * bundler ran and the identifier is genuinely absent — same shim as\n * `jto-cli`'s `cli.ts`.\n */\ndeclare const __PACKAGE_VERSION__: string | undefined;\n\nexport const SERVER_VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined' ? __PACKAGE_VERSION__ : 'dev-mode';\n\n/** MCP `serverInfo.name`. Stable: clients key configuration off it. */\nexport const SERVER_NAME = 'json-to-office';\n\n/** npm identity, reported by `jto_info` next to the workspace packages. */\nexport const PACKAGE_NAME = '@json-to-office/mcp-server';\n","/**\n * `jto_info` — what this server is and what it can do here.\n *\n * The first call an agent makes and, on a cold host, the only one that answers\n * \"will preview work at all\". Everything it reports is read from the packages\n * and the filesystem rather than restated, so it cannot claim a renderer or a\n * binary that is not actually there.\n */\n\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { constants as fsConstants } from 'fs';\nimport { createRequire } from 'module';\n\nimport type { McpServer } from '@modelcontextprotocol/server';\n\nimport type { ToolDeps } from '../lib/deps.js';\nimport { FORMAT_NAMES, S, outputSchema } from '../lib/schema.js';\nimport {\n ERROR_CODES,\n diagnostic,\n guarded,\n success,\n toolResult,\n type Diagnostic,\n} from '../lib/errors.js';\nimport { PACKAGE_NAME } from '../lib/version.js';\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Resolvers to try, in order.\n *\n * The cores are not our dependency — `jto-ops` owns them and imports them on\n * demand — so under pnpm's strict layout they are invisible from here. A\n * second resolver rooted at `jto-ops` sees exactly the copies it will load,\n * which is the version that actually decides what a render looks like.\n */\nconst resolvers: NodeJS.Require[] = [require];\ntry {\n // Rooted at `jto-ops`' manifest rather than its entry point: its `exports`\n // map declares `import` only, so a CJS `require.resolve` of the bare\n // specifier throws ERR_PACKAGE_PATH_NOT_EXPORTED. `./package.json` is\n // exported unconditionally and sits in the same directory.\n resolvers.push(\n createRequire(require.resolve('@json-to-office/jto-ops/package.json'))\n );\n} catch {\n /* jto-ops unresolvable: the cores simply go unreported */\n}\n\n/** Workspace packages whose versions pin what a render actually is (#202). */\nconst REPORTED_PACKAGES = [\n '@json-to-office/jto-ops',\n '@json-to-office/shared',\n '@json-to-office/shared-docx',\n '@json-to-office/shared-pptx',\n '@json-to-office/core-docx',\n '@json-to-office/core-pptx',\n] as const;\n\n/**\n * Version of an installed package, or undefined.\n *\n * Two lookups per resolver because the packages disagree: `jto-ops` exports\n * `./package.json` explicitly, while `shared*` map `./*` onto `./dist/*` and\n * would resolve that subpath to a file that does not exist. Resolving the\n * entry point and walking up works for both.\n */\nfunction readPackageVersion(specifier: string): string | undefined {\n for (const resolver of resolvers) {\n const candidates: string[] = [];\n try {\n candidates.push(resolver.resolve(`${specifier}/package.json`));\n } catch {\n /* not exported; fall through to the entry-point walk */\n }\n try {\n let dir = path.dirname(resolver.resolve(specifier));\n for (let depth = 0; depth < 8; depth += 1) {\n candidates.push(path.join(dir, 'package.json'));\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n /* not installed under this resolver */\n }\n for (const candidate of candidates) {\n try {\n const manifest = resolver(candidate) as {\n name?: string;\n version?: string;\n };\n if (\n manifest.name === specifier &&\n typeof manifest.version === 'string'\n ) {\n return manifest.version;\n }\n } catch {\n /* try the next candidate */\n }\n }\n }\n return undefined;\n}\n\nexport interface HostBinaryStatus {\n available: boolean;\n /** The candidate that satisfied the probe. */\n path?: string;\n /** Env var that overrides the search, so the agent can tell the user. */\n envVar: string;\n /** Everything that was looked at, in order. */\n searched: string[];\n}\n\nasync function isExecutable(candidate: string): Promise<boolean> {\n try {\n await fs.access(candidate, fsConstants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Find a host binary without running it.\n *\n * `jto-ops` settles this by spawning `--version`, which is the right call\n * there — it is about to launch the thing anyway. Here it is not: `jto_info`\n * is a discovery call an agent may make on every connection, and a cold\n * `soffice --version` costs about a second. A PATH walk answers the same\n * question for the same money as a stat, at the cost of not catching a binary\n * that exists but is broken; a real preview run still reports that (#205).\n */\nexport async function probeBinary(\n candidates: string[],\n envVar: string\n): Promise<HostBinaryStatus> {\n const searched: string[] = [];\n const pathEntries = (process.env.PATH ?? '').split(path.delimiter);\n const extensions =\n process.platform === 'win32'\n ? (process.env.PATHEXT ?? '.EXE;.CMD;.BAT').split(';')\n : [''];\n\n for (const candidate of candidates) {\n if (candidate.includes('/') || candidate.includes('\\\\')) {\n searched.push(candidate);\n if (await isExecutable(candidate)) {\n return { available: true, path: candidate, envVar, searched };\n }\n continue;\n }\n for (const entry of pathEntries) {\n if (!entry) continue;\n for (const extension of extensions) {\n const full = path.join(entry, candidate + extension);\n searched.push(full);\n if (await isExecutable(full)) {\n return { available: true, path: full, envVar, searched };\n }\n }\n }\n }\n return { available: false, envVar, searched };\n}\n\n/**\n * Candidate lists mirroring `jto-ops`' rasterizer.\n *\n * Duplicated rather than imported because the rasterizer keeps its resolution\n * private and spawn-based; if the two ever disagree the rasterizer wins, and\n * `jto_info` under-reports rather than promising a preview that then fails.\n */\nexport function sofficeCandidates(): string[] {\n const candidates: string[] = [];\n const configured = process.env.LIBREOFFICE_PATH?.trim();\n if (configured) candidates.push(configured);\n if (process.platform === 'darwin') {\n candidates.push('/Applications/LibreOffice.app/Contents/MacOS/soffice');\n } else if (process.platform === 'win32') {\n candidates.push('C:\\\\Program Files\\\\LibreOffice\\\\program\\\\soffice.exe');\n candidates.push(\n 'C:\\\\Program Files (x86)\\\\LibreOffice\\\\program\\\\soffice.exe'\n );\n }\n candidates.push('soffice', 'libreoffice');\n return [...new Set(candidates)];\n}\n\nexport function pdftoppmCandidates(): string[] {\n const configured = process.env.PDFTOPPM_PATH?.trim();\n return [...new Set([...(configured ? [configured] : []), 'pdftoppm'])];\n}\n\n/** Where `core-docx` posts a `highcharts` component when nothing overrides it. */\nconst DEFAULT_HIGHCHARTS_URL = 'http://localhost:7801';\n\n/** How long a service is given to answer before it counts as absent. */\nconst SERVICE_PROBE_TIMEOUT_MS = 1500;\n\nexport interface ServiceStatus {\n available: boolean;\n /** The URL that was probed — the configured one, or the built-in default. */\n url: string;\n /** Env var that overrides it, so the agent can tell the user. */\n envVar: string;\n /** Why the probe failed, when it did. */\n detail?: string;\n}\n\n/** The URL a `highcharts` component will actually be posted to on this host. */\nexport function highchartsServerUrl(): string {\n const configured = process.env.HIGHCHARTS_SERVER_URL?.trim();\n return configured ? configured : DEFAULT_HIGHCHARTS_URL;\n}\n\n/**\n * Is anything listening where the chart service is expected?\n *\n * A TCP connect rather than an HTTP request: the export server has no health\n * endpoint this can rely on, and \"something answers on that port\" is the whole\n * question — a wrong path or a 404 would say nothing useful. The timeout is\n * short because `jto_info` is the call an agent makes first and may make on\n * every connection.\n *\n * The alternative is what happens today: an agent authors a DOCX with two\n * charts, validates clean, and only learns at generation that the render needed\n * a service nobody mentioned.\n */\nexport async function probeService(\n rawUrl: string,\n envVar: string\n): Promise<ServiceStatus> {\n let target: URL;\n try {\n target = new URL(\n /^[a-z]+:\\/\\//i.test(rawUrl) ? rawUrl : `http://${rawUrl}`\n );\n } catch {\n return {\n available: false,\n url: rawUrl,\n envVar,\n detail: 'Not a URL.',\n };\n }\n\n const port = Number(target.port || (target.protocol === 'https:' ? 443 : 80));\n const net = await import('net');\n return new Promise<ServiceStatus>((resolve) => {\n const socket = net.connect({ host: target.hostname, port });\n const settle = (detail?: string): void => {\n socket.destroy();\n resolve({\n available: detail === undefined,\n url: target.origin,\n envVar,\n ...(detail !== undefined && { detail }),\n });\n };\n socket.setTimeout(SERVICE_PROBE_TIMEOUT_MS);\n socket.once('connect', () => settle());\n socket.once('timeout', () => settle('No answer within the probe timeout.'));\n socket.once('error', (error: Error) => settle(error.message));\n });\n}\n\nconst binaryStatusSchema = {\n type: 'object' as const,\n properties: {\n available: { type: 'boolean' as const },\n path: { type: 'string' as const },\n envVar: { type: 'string' as const },\n searched: { type: 'array' as const, items: { type: 'string' as const } },\n },\n required: ['available', 'envVar', 'searched'],\n additionalProperties: false,\n};\n\nconst serviceStatusSchema = {\n type: 'object' as const,\n properties: {\n available: { type: 'boolean' as const },\n url: { type: 'string' as const },\n envVar: { type: 'string' as const },\n detail: { type: 'string' as const },\n },\n required: ['available', 'url', 'envVar'],\n additionalProperties: false,\n};\n\nexport function register(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'jto_info',\n {\n title: 'Server info',\n description:\n 'Versions, supported formats and renderer ids, workspace availability, output-root and size limits, and whether the optional host dependencies (LibreOffice and poppler for jto_preview, a Highcharts export server for the DOCX `highcharts` component) are present on this host. Call this first.',\n annotations: { readOnlyHint: true, openWorldHint: false },\n inputSchema: S<{ includePreviewDependencies?: boolean }>({\n type: 'object',\n properties: {\n includePreviewDependencies: {\n type: 'boolean',\n description:\n 'Probe the host for LibreOffice, poppler and the Highcharts export server. Default true.',\n },\n },\n additionalProperties: false,\n }),\n outputSchema: S(\n outputSchema(\n {\n server: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n package: { type: 'string' },\n version: { type: 'string' },\n protocolTransport: { type: 'string' },\n },\n required: ['name', 'package', 'version'],\n additionalProperties: false,\n },\n runtime: {\n type: 'object',\n properties: {\n node: { type: 'string' },\n platform: { type: 'string' },\n arch: { type: 'string' },\n },\n required: ['node', 'platform', 'arch'],\n additionalProperties: false,\n },\n packages: {\n type: 'object',\n description:\n 'Installed versions of the generation packages. A render is a function of the document plus these.',\n additionalProperties: { type: 'string' },\n },\n formats: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n extension: { type: 'string' },\n label: { type: 'string' },\n rendererIds: {\n type: 'array',\n items: { type: 'string' },\n description: 'Defaults first.',\n },\n },\n required: ['name', 'extension', 'label', 'rendererIds'],\n additionalProperties: false,\n },\n },\n workspaces: {\n type: 'object',\n properties: {\n available: { type: 'boolean' },\n open: { type: 'integer' },\n },\n required: ['available', 'open'],\n additionalProperties: false,\n },\n output: {\n type: 'object',\n properties: {\n root: { type: 'string' },\n ephemeral: { type: 'boolean' },\n maxInlineArtifactBytes: { type: 'integer' },\n },\n required: ['root', 'ephemeral', 'maxInlineArtifactBytes'],\n additionalProperties: false,\n },\n previewDependencies: {\n type: 'object',\n description:\n 'Optional host dependencies, absent when not probed. `libreoffice` and `pdftoppm` must BOTH be available for jto_preview to render; `highchartsExportServer` is needed by the DOCX `highcharts` component in any render, preview or not.',\n properties: {\n libreoffice: binaryStatusSchema,\n pdftoppm: binaryStatusSchema,\n highchartsExportServer: serviceStatusSchema,\n },\n required: ['libreoffice', 'pdftoppm', 'highchartsExportServer'],\n additionalProperties: false,\n },\n },\n // Only the envelope is required, as on every other tool. The SDK\n // validates outgoing `structuredContent` against this schema and\n // discards a result that does not match in favour of an isError\n // blob — so requiring the success fields would make the one case\n // that most needs reporting, an internal failure carrying nothing\n // but diagnostics, the one case an agent cannot read.\n []\n )\n ),\n },\n async (args) =>\n toolResult(\n await guarded(async () => {\n const diagnostics: Diagnostic[] = [];\n\n const packages: Record<string, string> = {};\n for (const name of REPORTED_PACKAGES) {\n const version = readPackageVersion(name);\n if (version) packages[name] = version;\n }\n\n const formats = await Promise.all(\n FORMAT_NAMES.map(async (name) => {\n const adapter = deps.getAdapter(name);\n let rendererIds: string[] = [];\n try {\n rendererIds = [...(await adapter.rendererIds())];\n } catch (error) {\n // A core that fails to load is a broken install, not a broken\n // request: report the format with no renderers so the agent\n // can still see the rest of the picture.\n diagnostics.push(\n diagnostic(\n ERROR_CODES.DEPENDENCY_MISSING,\n `Could not read renderer ids for ${name}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n { severity: 'warning', context: { format: name } }\n )\n );\n }\n return {\n name: adapter.name,\n extension: adapter.extension,\n label: adapter.label,\n rendererIds,\n };\n })\n );\n\n const store = deps.workspaces();\n const listed = await store.list();\n\n const includePreview = args.includePreviewDependencies !== false;\n const previewDependencies = includePreview\n ? {\n libreoffice: await probeBinary(\n sofficeCandidates(),\n 'LIBREOFFICE_PATH'\n ),\n pdftoppm: await probeBinary(\n pdftoppmCandidates(),\n 'PDFTOPPM_PATH'\n ),\n highchartsExportServer: await probeService(\n highchartsServerUrl(),\n 'HIGHCHARTS_SERVER_URL'\n ),\n }\n : undefined;\n\n if (\n previewDependencies &&\n (!previewDependencies.libreoffice.available ||\n !previewDependencies.pdftoppm.available)\n ) {\n diagnostics.push(\n diagnostic(\n ERROR_CODES.DEPENDENCY_MISSING,\n 'Preview needs both LibreOffice and poppler (pdftoppm); at least one is missing on this host.',\n {\n severity: 'info',\n suggestion:\n 'Install LibreOffice and poppler-utils, or set LIBREOFFICE_PATH / PDFTOPPM_PATH. Validation, generation and diff do not need them.',\n }\n )\n );\n }\n\n // Its own diagnostic, not folded into the preview one: this service\n // gates a COMPONENT rather than a tool, so an agent about to author a\n // DOCX chart needs to read it even on a host where preview works.\n if (\n previewDependencies &&\n !previewDependencies.highchartsExportServer.available\n ) {\n diagnostics.push(\n diagnostic(\n ERROR_CODES.DEPENDENCY_MISSING,\n `No Highcharts export server is answering at ${previewDependencies.highchartsExportServer.url}; the DOCX \\`highcharts\\` component cannot render here.`,\n {\n severity: 'info',\n suggestion:\n 'Start it with `npx highcharts-export-server --enableServer true`, or point HIGHCHARTS_SERVER_URL at a running one. The `visual` component draws charts with no external service.',\n context: {\n dependency: 'highchartsExportServer',\n component: 'highcharts',\n },\n }\n )\n );\n }\n\n return success(\n {\n server: {\n name: 'json-to-office',\n package: PACKAGE_NAME,\n version: deps.serverVersion,\n protocolTransport: 'stdio',\n },\n runtime: {\n node: process.versions.node,\n platform: process.platform,\n arch: process.arch,\n },\n packages,\n formats,\n workspaces: {\n available: store.available,\n open: listed.ok ? listed.records.length : 0,\n },\n output: {\n root: deps.outputRoot.path,\n ephemeral: deps.outputRoot.ephemeral,\n maxInlineArtifactBytes: deps.maxInlineArtifactBytes,\n },\n ...(previewDependencies && { previewDependencies }),\n },\n diagnostics\n );\n })\n )\n );\n}\n","/**\n * Tool schemas, authored as plain JSON Schema.\n *\n * `fromJsonSchema` wraps a JSON Schema in the Standard Schema shape the SDK\n * validates against, and passes the schema itself through to `tools/list`\n * verbatim. Authoring JSON Schema directly therefore keeps zod out of our own\n * source and guarantees that what an agent discovers is exactly what the\n * server enforces — no conversion step in between to drift.\n */\n\nimport { fromJsonSchema } from '@modelcontextprotocol/server';\nimport type {\n JsonSchemaType,\n StandardSchemaWithJSON,\n jsonSchemaValidator,\n} from '@modelcontextprotocol/server';\nimport { AjvJsonSchemaValidator } from '@modelcontextprotocol/server/validators/ajv';\n\nimport type { FormatName } from './adapters.js';\n\n/**\n * One validator for every schema in the process.\n *\n * Ajv compiles and caches per schema; a fresh instance per tool would pay that\n * cost again and hold a second copy of every compiled validator for the life\n * of the connection.\n */\nconst validator: jsonSchemaValidator = new AjvJsonSchemaValidator();\n\n/**\n * Wrap a JSON Schema for `registerTool`.\n *\n * The type parameter is the handler's view of the validated value — the SDK\n * infers callback arguments from it and cannot derive it from a runtime schema\n * object, so pass it explicitly: `S<{ format: FormatName }>({ … })`.\n */\nexport function S<T = unknown>(\n schema: JsonSchemaType\n): StandardSchemaWithJSON<T, T> {\n return fromJsonSchema<T>(schema, validator);\n}\n\n/** Every format this server can author. */\nexport const FORMAT_NAMES: readonly FormatName[] = ['docx', 'pptx'];\n\nexport const formatSchema: JsonSchemaType = {\n type: 'string',\n enum: [...FORMAT_NAMES],\n description: 'Office format to operate on.',\n};\n\n/**\n * The document a tool operates on: inline JSON, or a workspace reference.\n *\n * Both are spelled out on every document-taking tool rather than hidden behind\n * a `oneOf`, because a discovering agent reads the flat property list and many\n * clients render nothing else. `doc-source.ts` enforces the exclusivity that\n * the schema deliberately does not.\n */\nexport const documentSourceProperties: Record<string, JsonSchemaType> = {\n document: {\n type: 'object',\n description:\n 'The document JSON, inline. Mutually exclusive with `handle`. This is the portable baseline: it needs no prior state.',\n additionalProperties: true,\n },\n handle: {\n type: 'string',\n description:\n 'Opaque handle of an open workspace document (from jto_workspace_create). Mutually exclusive with `document`.',\n minLength: 1,\n },\n revision: {\n type: 'integer',\n description:\n 'Revision the caller believes `handle` is at. When given and stale, the call fails instead of silently operating on newer JSON.',\n minimum: 1,\n },\n};\n\n/** Human-readable restatement of the rule the schema cannot express. */\nexport const DOCUMENT_SOURCE_RULE =\n 'Supply exactly one of `document` (inline JSON) or `handle` (an open workspace).';\n\n/**\n * Renderer, theme and determinism knobs, mirroring `GeneratorOptions` from\n * `@json-to-office/jto-ops`. Shared verbatim by validate/generate/preview/diff\n * so the same document renders the same way whichever tool an agent reaches\n * for.\n */\nexport const renderOptionProperties: Record<string, JsonSchemaType> = {\n renderer: {\n type: 'string',\n description:\n 'Renderer id for this format (see jto_info.formats[].rendererIds). Omit for the format default.',\n },\n theme: {\n type: 'string',\n description:\n \"Built-in or custom theme name. Omit to keep each document's own `props.theme`.\",\n },\n themePath: {\n type: 'string',\n description:\n 'Path to a data-only JSON theme file, resolved against `baseDir` (or the server working directory when `baseDir` is omitted). Executable theme modules are not accepted over MCP.',\n },\n deterministic: {\n type: 'boolean',\n description:\n 'Strip nondeterministic metadata (timestamps, ids) so identical JSON yields byte-identical output.',\n },\n generatedAt: {\n type: 'string',\n description:\n 'ISO 8601 instant to stamp instead of \"now\"; pairs with `deterministic`.',\n },\n baseDir: {\n type: 'string',\n description:\n 'Directory that relative asset paths in the document resolve against.',\n },\n};\n\n/** How a generated file comes back: written to disk, or inline. */\nexport const artifactOutputProperties: Record<string, JsonSchemaType> = {\n outputMode: {\n type: 'string',\n enum: ['path', 'base64'],\n description:\n '`path` (default) writes under the server output root and returns the path. `base64` inlines the bytes and is refused — never silently downgraded — above the inline size limit (see jto_info.output.maxInlineArtifactBytes).',\n },\n filename: {\n type: 'string',\n description:\n 'File name for the artifact, relative to the output root. Must not escape it: no absolute paths, no `..`.',\n },\n};\n\nexport const diagnosticSchema: JsonSchemaType = {\n type: 'object',\n description: 'One machine-actionable defect.',\n properties: {\n severity: { type: 'string', enum: ['error', 'warning', 'info'] },\n code: {\n type: 'string',\n description: 'Stable machine code, e.g. E_INVALID_DOCUMENT.',\n },\n message: { type: 'string' },\n path: {\n type: 'string',\n description: 'RFC 6901 JSON Pointer into the document, when located.',\n },\n suggestion: { type: 'string' },\n context: { type: 'object', additionalProperties: true },\n },\n required: ['severity', 'code', 'message'],\n additionalProperties: true,\n};\n\nexport const diagnosticsSchema: JsonSchemaType = {\n type: 'array',\n description:\n 'Always present, possibly empty. Document defects arrive here, never as a protocol error.',\n items: diagnosticSchema,\n};\n\n/** The `{ ok, diagnostics }` floor every tool output schema builds on. */\nexport const envelopeProperties: Record<string, JsonSchemaType> = {\n ok: { type: 'boolean' },\n diagnostics: diagnosticsSchema,\n};\n\n/**\n * A delivered file, exactly as `deliverArtifact` returns one.\n *\n * `relative` is not decoration: the SDK validates outgoing\n * `structuredContent` against the declared schema, and this object closes\n * `additionalProperties`, so omitting a field every path-mode artifact\n * carries would turn each successful generation into an output-validation\n * error. Generate, diff, preview and snapshot all report through this one\n * definition.\n */\nexport const artifactSchema: JsonSchemaType = {\n type: 'object',\n description: 'A generated file, delivered by path or inline.',\n properties: {\n mode: { type: 'string', enum: ['path', 'base64'] },\n path: {\n type: 'string',\n description:\n 'Absolute path under the output root. Present when mode=path.',\n },\n relative: {\n type: 'string',\n description:\n 'Path relative to the output root, for display. Present when mode=path.',\n },\n base64: {\n type: 'string',\n description: 'File bytes, base64. Present when mode=base64.',\n },\n bytes: { type: 'integer', description: 'Decoded size in bytes.' },\n filename: { type: 'string' },\n mimeType: { type: 'string' },\n },\n required: ['mode', 'bytes', 'filename', 'mimeType'],\n additionalProperties: false,\n};\n\n/**\n * `documentSourceProperties` as one nested object.\n *\n * A tool that takes two documents cannot spell them both flat — `jto_docx_diff`\n * would need two `document` keys — so `before`/`after` each carry a bag of\n * this shape. Single-document tools stay flat, which is what an agent reading\n * a property list expects.\n */\nexport const documentSourceSchema: JsonSchemaType = {\n type: 'object',\n properties: documentSourceProperties,\n additionalProperties: false,\n};\n\n/** Where a tool actually read its document from, echoed back to the caller. */\nexport const sourceSummarySchema: JsonSchemaType = {\n type: 'object',\n description: 'Where the document was read from.',\n properties: {\n origin: { type: 'string', enum: ['inline', 'workspace'] },\n handle: { type: 'string' },\n revision: {\n type: 'integer',\n description: 'The revision actually read, which may be a pinned one.',\n },\n },\n required: ['origin'],\n additionalProperties: false,\n};\n\n/** Compose an output schema from the standard envelope plus tool-specific fields. */\nexport function outputSchema(\n properties: Record<string, JsonSchemaType>,\n required: readonly string[] = []\n): JsonSchemaType {\n return {\n type: 'object',\n properties: { ...envelopeProperties, ...properties },\n required: ['ok', 'diagnostics', ...required],\n additionalProperties: true,\n };\n}\n\n/** The inline/handle pair, as the tool handlers see it after validation. */\nexport interface DocumentSourceInput {\n document?: unknown;\n handle?: string;\n revision?: number;\n}\n\n/** `sourceSummarySchema`, as the tools report it. */\nexport interface SourceSummary {\n origin: 'inline' | 'workspace';\n handle?: string;\n revision?: number;\n}\n\n/** `renderOptionProperties`, as the tool handlers see it after validation. */\nexport interface RenderOptionsInput {\n renderer?: string;\n theme?: string;\n themePath?: string;\n deterministic?: boolean;\n generatedAt?: string;\n baseDir?: string;\n}\n\n/** `artifactOutputProperties`, as the tool handlers see it after validation. */\nexport interface ArtifactOutputInput {\n outputMode?: 'path' | 'base64';\n filename?: string;\n}\n","/**\n * Structured results, not protocol errors.\n *\n * A JSON-RPC error tells the agent \"the call failed\" and nothing it can act\n * on. Every defect this server can describe — a bad document, an unknown\n * handle, a missing host binary — is therefore a normal tool RESULT carrying\n * path-addressed diagnostics, which the agent can read, repair and retry.\n * Protocol errors stay reserved for transport and server failures (#202).\n */\n\nimport {\n runWithDiagnosticSink,\n type DiagnosticTone,\n} from '@json-to-office/jto-ops';\nimport type { ValidationError } from '@json-to-office/shared';\nimport { ValueErrorType } from '@sinclair/typebox/errors';\n\nexport type DiagnosticSeverity = 'error' | 'warning' | 'info';\n\n/**\n * One machine-actionable defect.\n *\n * `path` is an RFC 6901 JSON Pointer into the document the tool was given, so\n * an agent holding a workspace handle can turn a diagnostic straight into a\n * JSON Patch target (#271).\n */\nexport interface Diagnostic {\n severity: DiagnosticSeverity;\n /** Stable machine code — see `ERROR_CODES`. */\n code: string;\n message: string;\n /** JSON Pointer into the offending document, when the defect has a location. */\n path?: string;\n /** What to do about it, in one sentence. */\n suggestion?: string;\n /** Free-form extras (offending value, component name, renderer id, …). */\n context?: Record<string, unknown>;\n}\n\n/**\n * The envelope every tool's `structuredContent` starts from.\n *\n * `ok` is the single field a caller must branch on; `diagnostics` is always\n * present (possibly empty) so clients never special-case its absence.\n */\nexport interface ToolEnvelope {\n ok: boolean;\n diagnostics: Diagnostic[];\n}\n\n/**\n * Stable codes. Callers — including our own tests and downstream agents —\n * branch on these, so treat them as API: add freely, rename never.\n *\n * `E_` for something that blocks, `W_` for something that does not. Every\n * `code` this server puts on the wire is one of these: the validators speak\n * three private dialects of their own (TypeBox ordinals, snake_case, the\n * cores' own names) and `normalizeCode` maps all three in here at the\n * boundary, so an agent has exactly one vocabulary to branch on.\n */\nexport const ERROR_CODES = {\n /** An exception escaped a tool handler. Always a bug here, never the caller's. */\n INTERNAL: 'E_INTERNAL',\n /** Neither `document` nor `handle` was supplied. */\n DOC_SOURCE_MISSING: 'E_DOC_SOURCE_MISSING',\n /** Both `document` and `handle` were supplied. */\n DOC_SOURCE_AMBIGUOUS: 'E_DOC_SOURCE_AMBIGUOUS',\n /** `handle` names no open workspace on this connection. */\n UNKNOWN_HANDLE: 'E_UNKNOWN_HANDLE',\n /** `revision` does not match the workspace's current revision. */\n STALE_REVISION: 'E_STALE_REVISION',\n /** A handle was used but no workspace store is installed (#271 not wired). */\n WORKSPACES_UNAVAILABLE: 'E_WORKSPACES_UNAVAILABLE',\n /** A requested output name resolved outside the output root. */\n OUTPUT_ROOT_ESCAPE: 'E_OUTPUT_ROOT_ESCAPE',\n /** Inline base64 was requested for an artifact over the size limit. */\n ARTIFACT_TOO_LARGE: 'E_ARTIFACT_TOO_LARGE',\n /** The document failed a rule that has no more specific code. */\n INVALID_DOCUMENT: 'E_INVALID_DOCUMENT',\n /** The document could not be parsed as JSON. */\n INVALID_JSON: 'E_INVALID_JSON',\n /** A property the schema requires is absent. */\n REQUIRED_PROPERTY: 'E_REQUIRED_PROPERTY',\n /** A property the component does not declare. */\n UNEXPECTED_PROPERTY: 'E_UNEXPECTED_PROPERTY',\n /** A value of the wrong JSON type. */\n TYPE_MISMATCH: 'E_TYPE_MISMATCH',\n /** No branch of a union accepted the value. */\n UNION_MISMATCH: 'E_UNION_MISMATCH',\n /** Right type, outside the schema's bounds, length, pattern or format. */\n VALUE_CONSTRAINT: 'E_VALUE_CONSTRAINT',\n /** Right type and shape, but not a value this position accepts. */\n INVALID_VALUE: 'E_INVALID_VALUE',\n /** `name` is not a component this format registers, or not one allowed here. */\n UNKNOWN_COMPONENT: 'E_UNKNOWN_COMPONENT',\n /** Two props that exclude each other were both set. */\n MUTUALLY_EXCLUSIVE: 'E_MUTUALLY_EXCLUSIVE',\n /** A theme the document names does not exist. */\n THEME_NOT_FOUND: 'E_THEME_NOT_FOUND',\n /** The document is empty. */\n EMPTY_DOCUMENT: 'E_EMPTY_DOCUMENT',\n /** The renderer could draw the document, but not this one feature of it. */\n UNSUPPORTED_RENDERER_FEATURE: 'W_UNSUPPORTED_RENDERER_FEATURE',\n /** A note the render host emitted mid-run (unknown theme, unreadable theme file). */\n HOST_NOTE: 'W_HOST_NOTE',\n /** A generation warning the core raised without a code of its own. */\n GENERATION: 'W_GENERATION',\n /** A required host binary (LibreOffice, poppler) is absent. */\n DEPENDENCY_MISSING: 'E_DEPENDENCY_MISSING',\n /** The client cancelled the request. */\n CANCELLED: 'E_CANCELLED',\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/** Build one diagnostic; `severity` defaults to `error`. */\nexport function diagnostic(\n code: string,\n message: string,\n extra: Omit<Diagnostic, 'code' | 'message' | 'severity'> & {\n severity?: DiagnosticSeverity;\n } = {}\n): Diagnostic {\n const { severity = 'error', ...rest } = extra;\n return { severity, code, message, ...rest };\n}\n\n/**\n * TypeBox names its defect kinds by ordinal, bucketed into our vocabulary.\n *\n * Order matters: the first rule that matches wins, so the two property rules\n * run before the constraint rule that would otherwise claim\n * `IntersectUnevaluatedProperties`. Anything left over — `String`, `Number`,\n * `Object`, `Literal`, `Never` — names a JSON type, which is a type mismatch.\n */\nconst TYPEBOX_BUCKETS: readonly (readonly [RegExp, string])[] = [\n [/^ObjectRequiredProperty$/, ERROR_CODES.REQUIRED_PROPERTY],\n [\n /^(ObjectAdditionalProperties|IntersectUnevaluatedProperties)$/,\n ERROR_CODES.UNEXPECTED_PROPERTY,\n ],\n [/^Union$/, ERROR_CODES.UNION_MISMATCH],\n [\n /Maximum|Minimum|MultipleOf|Items|Contains|Length|Pattern|Format|Properties/,\n ERROR_CODES.VALUE_CONSTRAINT,\n ],\n];\n\n/** `ValueErrorType` the other way round: \"45\" -> \"ObjectRequiredProperty\". */\nconst TYPEBOX_NAMES = new Map<string, string>(\n Object.entries(ValueErrorType)\n .filter(([, ordinal]) => typeof ordinal === 'number')\n .map(([name, ordinal]) => [String(ordinal), name])\n);\n\n/**\n * The cores' own spellings, which name defects TypeBox has no kind for.\n *\n * A Map rather than an object literal: the key is a validator's string, and a\n * plain object would answer `constructor` with a function.\n */\nconst CORE_CODES = new Map<string, string>(\n Object.entries({\n required: ERROR_CODES.REQUIRED_PROPERTY,\n required_property: ERROR_CODES.REQUIRED_PROPERTY,\n unknown_field: ERROR_CODES.UNEXPECTED_PROPERTY,\n invalid_type: ERROR_CODES.TYPE_MISMATCH,\n invalid_value: ERROR_CODES.INVALID_VALUE,\n unsupported_value: ERROR_CODES.INVALID_VALUE,\n unknown_component: ERROR_CODES.UNKNOWN_COMPONENT,\n mutually_exclusive: ERROR_CODES.MUTUALLY_EXCLUSIVE,\n theme_not_found: ERROR_CODES.THEME_NOT_FOUND,\n empty_input: ERROR_CODES.EMPTY_DOCUMENT,\n json_parse_error: ERROR_CODES.INVALID_JSON,\n unsupported_renderer_feature: ERROR_CODES.UNSUPPORTED_RENDERER_FEATURE,\n // `shared-docx`'s catch-all for a rule with no kind of its own, and the\n // marker it puts on a validator that threw. Neither is more specific than\n // \"the document did not pass\".\n custom: ERROR_CODES.INVALID_DOCUMENT,\n validation_exception: ERROR_CODES.INTERNAL,\n })\n);\n\n/**\n * One validator code, mapped into the published vocabulary.\n *\n * The transformer in `shared` stringifies TypeBox's `ValueErrorType` straight\n * into `code`, so a wrong prop type reached agents as `\"54\"`. Ordinals are an\n * internal enum — they renumber whenever TypeBox inserts a member — and they\n * appear in no table we publish, so an agent branching on `code` matched\n * nothing for the single commonest defect class there is. The ordinal is\n * therefore resolved back through the enum this package has installed and\n * bucketed by name; the raw spelling survives in `context.validatorCode` for\n * anyone debugging the validator itself.\n *\n * Codes already in the namespace pass through, so a caller that builds one\n * with `diagnostic()` is never rewritten.\n */\nexport function normalizeCode(code: string | undefined): string {\n if (code === undefined) return ERROR_CODES.INVALID_DOCUMENT;\n if (/^[EW]_/.test(code)) return code;\n\n const core = CORE_CODES.get(code);\n if (core !== undefined) return core;\n\n const name = TYPEBOX_NAMES.get(code);\n if (name === undefined) return ERROR_CODES.INVALID_DOCUMENT;\n for (const [pattern, mapped] of TYPEBOX_BUCKETS) {\n if (pattern.test(name)) return mapped;\n }\n return ERROR_CODES.TYPE_MISMATCH;\n}\n\n/**\n * One core generation-warning code, mapped into the published vocabulary.\n *\n * The cores raise warnings under bare SCREAMING_SNAKE names — `FONT_UNRESOLVED`,\n * `CHART_NO_DATA`, `UNKNOWN_SHAPE`. Those carry neither prefix, so an agent\n * deciding whether to stop by reading the first two characters matched neither\n * `E_` nor `W_` and fell through on the one class of diagnostic that is always\n * safe to continue past. Prefixing keeps that test total; the core's own\n * spelling stays on `context.code`, which is what the CLI prints and what a\n * caller comparing the two surfaces reads.\n */\nexport function normalizeWarningCode(code: string | undefined): string {\n if (code === undefined || code === '') return ERROR_CODES.GENERATION;\n if (/^[EW]_/.test(code)) return code;\n return `W_${code.toUpperCase()}`;\n}\n\n/**\n * Adapt the repo's `ValidationError` to a diagnostic.\n *\n * The two shapes already agree on `path`/`message`/`suggestion`; the mapping\n * exists to give every diagnostic a code from one published vocabulary, so\n * clients can always switch on `code`.\n */\nexport function fromValidationError(\n error: ValidationError,\n severity: DiagnosticSeverity = 'error'\n): Diagnostic {\n const code = normalizeCode(error.code);\n const context = {\n ...(error.value !== undefined && { value: error.value }),\n ...(error.code !== undefined &&\n error.code !== code && { validatorCode: error.code }),\n };\n return {\n severity,\n code,\n message: error.message,\n ...(error.path !== undefined && { path: error.path }),\n ...(error.suggestion !== undefined && { suggestion: error.suggestion }),\n ...(Object.keys(context).length > 0 && { context }),\n };\n}\n\nexport function fromValidationErrors(\n errors: readonly ValidationError[] | undefined,\n severity: DiagnosticSeverity = 'error'\n): Diagnostic[] {\n return (errors ?? []).map((error) => fromValidationError(error, severity));\n}\n\n/** A failed operation: `ok: false` plus at least one diagnostic. */\nexport interface Failure extends ToolEnvelope {\n ok: false;\n}\n\nexport function failure(\n code: string,\n message: string,\n extra: Omit<Diagnostic, 'code' | 'message' | 'severity'> & {\n severity?: DiagnosticSeverity;\n } = {}\n): Failure {\n return { ok: false, diagnostics: [diagnostic(code, message, extra)] };\n}\n\nexport function failureFrom(diagnostics: Diagnostic[]): Failure {\n return { ok: false, diagnostics };\n}\n\n/** A successful operation, with room for the non-fatal diagnostics it collected. */\nexport function success<T extends object>(\n payload: T,\n diagnostics: Diagnostic[] = []\n): T & ToolEnvelope {\n return { ok: true, diagnostics, ...payload };\n}\n\n/**\n * The two-channel result every tool returns.\n *\n * `structuredContent` is what the schema-aware client reads; the text block is\n * the same object stringified, which is what a client without structured\n * output support (and every transcript) sees. They are never allowed to\n * disagree, hence one argument.\n */\nexport function toolResult<T extends object>(\n payload: T\n): {\n content: [{ type: 'text'; text: string }];\n structuredContent: T;\n} {\n return {\n content: [{ type: 'text', text: JSON.stringify(payload) }],\n structuredContent: payload,\n };\n}\n\n/**\n * Errors that are the host's fault rather than ours.\n *\n * `shared`'s renderer loader renames a failed optional backend import so the\n * missing package can be told apart from a bug. `E_INTERNAL` on one of those\n * reads as \"a bug here\" and sends the agent to file an issue when the fix is\n * an install line, which the message already carries.\n */\nconst HOST_DEPENDENCY_ERRORS = new Set(['RendererDependencyMissingError']);\n\n/** A line `jto-ops` emitted mid-run, as a diagnostic the agent can read. */\nfunction hostNote(text: string, tone: DiagnosticTone = 'muted'): Diagnostic {\n return {\n // Never `error`. The body has already decided `ok` by the time a note\n // lands, so an error-severity note would contradict the verdict beside it.\n severity: tone === 'error' || tone === 'warning' ? 'warning' : 'info',\n code: ERROR_CODES.HOST_NOTE,\n message: text,\n };\n}\n\n/**\n * Drop the notes the tool already reported properly.\n *\n * `jto-ops` forwards every structured `GenerationWarning` to the sink as\n * `\"<component>: <message>\"` on its way past, so a tool that collects\n * `options.warnings` — `jto_generate` does — would report each of them twice,\n * once with its component and code and once as a bare line. The structured\n * copy is the better one, so the echo goes.\n */\nfunction withoutEchoes(\n notes: readonly Diagnostic[],\n reported: readonly Diagnostic[]\n): Diagnostic[] {\n if (reported.length === 0) return [...notes];\n return notes.filter(\n (note) =>\n !reported.some(\n (entry) =>\n note.message === entry.message ||\n note.message.endsWith(`: ${entry.message}`)\n )\n );\n}\n\n/**\n * Fold the run's notes into the envelope the tool is about to return.\n *\n * Every tool result carries `ok`/`diagnostics`; `jto_preview` alone keeps its\n * envelope one level down in `payload`, because the page bytes ride in content\n * blocks beside it. Those two shapes are exhaustive today — a third would\n * quietly drop its notes rather than grow a field its `outputSchema` does not\n * declare, which the SDK would reject outright.\n */\nfunction withHostNotes<T extends object>(\n result: T,\n notes: readonly Diagnostic[]\n): T {\n if (notes.length === 0) return result;\n const own = (result as { diagnostics?: unknown }).diagnostics;\n if (Array.isArray(own)) {\n const fresh = withoutEchoes(notes, own as Diagnostic[]);\n return fresh.length > 0\n ? { ...result, diagnostics: [...own, ...fresh] }\n : result;\n }\n const payload = (result as { payload?: { diagnostics?: unknown } }).payload;\n if (payload !== undefined && Array.isArray(payload.diagnostics)) {\n const reported = payload.diagnostics as Diagnostic[];\n const fresh = withoutEchoes(notes, reported);\n if (fresh.length === 0) return result;\n return {\n ...result,\n payload: { ...payload, diagnostics: [...reported, ...fresh] },\n };\n }\n return result;\n}\n\n/**\n * Run a tool body, converting anything that escapes into a diagnostic and\n * collecting the warnings the run emitted along the way.\n *\n * Without the first half an exception becomes a JSON-RPC error, which is\n * exactly the signal we reserve for transport failures — the agent would be\n * told the server broke when in fact one document did.\n *\n * The second half is why the sink is installed here and not once per\n * connection: `runWithDiagnosticSink` is `AsyncLocalStorage.run`, so a sink\n * wrapped around server setup is long gone by the time a request arrives on a\n * later turn of the loop, and every \"Unknown theme …\" `jto-ops` emitted was\n * dropped. One request is the largest scope that actually holds, and it is\n * also the one the agent can read — the notes come back in `diagnostics`\n * beside the result they belong to instead of on a stderr no client parses.\n */\nexport async function guarded<T extends object>(\n body: () => Promise<T>\n): Promise<T | Failure> {\n const notes: Diagnostic[] = [];\n try {\n const result = await runWithDiagnosticSink(\n (text, tone) => notes.push(hostNote(text, tone)),\n body\n );\n return withHostNotes(result, notes);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const code =\n error instanceof Error && HOST_DEPENDENCY_ERRORS.has(error.name)\n ? ERROR_CODES.DEPENDENCY_MISSING\n : ERROR_CODES.INTERNAL;\n return withHostNotes(\n failure(code, message, {\n context: {\n ...(error instanceof Error &&\n error.stack !== undefined && { stack: error.stack }),\n },\n }),\n notes\n );\n }\n}\n\n/**\n * Codes for defects in the REQUEST rather than in the document.\n *\n * `ERROR_CODES` covers the document and the transport; these cover the options\n * an agent chose, which are a third thing — an agent that asked for a renderer\n * that does not exist has nothing to repair in its JSON.\n */\nexport const OPTION_ERROR_CODES = {\n /** `renderer` names no renderer this format registers. */\n UNKNOWN_RENDERER: 'E_UNKNOWN_RENDERER',\n /** `date` is not parseable as a date. */\n INVALID_DATE: 'E_INVALID_DATE',\n /** `themePath` is not a data-only JSON theme path. */\n INVALID_THEME_PATH: 'E_INVALID_THEME_PATH',\n /** The tool does not support the requested format. */\n UNSUPPORTED_FORMAT: 'E_UNSUPPORTED_FORMAT',\n} as const;\n\n/**\n * Findings both cores drop from their generation gate.\n *\n * `core-docx`'s `generateBufferWithWarnings` and `core-pptx`'s\n * `assertValidPresentationForGeneration` both filter this code out before\n * deciding whether to throw, because the compiler's capability pass is the\n * authority on what a renderer can actually draw. `jto_validate` exists to\n * predict generation, so it demotes them to warnings rather than sending an\n * agent to repair a document that renders — the finding, its code and its path\n * all survive.\n */\nconst DEFERRED_TO_COMPILER = new Set<string>([\n ERROR_CODES.UNSUPPORTED_RENDERER_FEATURE,\n]);\n\n/** Path spellings the validators use for \"the document itself\". */\nconst ROOT_SENTINELS = new Set(['', '/', '#', 'root']);\n\nfunction escapePointerSegment(segment: string): string {\n return segment.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n\n/**\n * Normalize a validator path to an RFC 6901 JSON Pointer.\n *\n * The validators speak two dialects. The document validators emit\n * pointer-shaped strings already (`/children/0/props/text`) but leave `~`\n * unescaped and spell the root `root`; the older component validators emit\n * JavaScript-ish paths (`children[0].props.text`, `name`). Both end up here so\n * that every diagnostic this server hands back can be used verbatim as a JSON\n * Patch target against a workspace document (#271).\n */\nexport function toJsonPointer(path: string | undefined): string | undefined {\n if (path === undefined) return undefined;\n const trimmed = path.trim();\n if (ROOT_SENTINELS.has(trimmed)) return '';\n\n const segments = trimmed.startsWith('/')\n ? trimmed.slice(1).split('/')\n : trimmed\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .split('.')\n .filter((segment) => segment !== '');\n\n if (segments.length === 0) return '';\n return `/${segments.map(escapePointerSegment).join('/')}`;\n}\n\n/**\n * Drop the type complaint TypeBox adds to a property it just called missing.\n *\n * An absent required prop comes back twice — `ObjectRequiredProperty` and then\n * the type check on the same absent value, at the same pointer. The second is\n * not a second repair: an agent that adds the property fixes both, and an\n * agent that trusts the count thinks its document is twice as broken as it is.\n */\nfunction collapseMissingProperties(diagnostics: Diagnostic[]): Diagnostic[] {\n const missing = new Set(\n diagnostics\n .filter((entry) => entry.code === ERROR_CODES.REQUIRED_PROPERTY)\n .map((entry) => entry.path)\n );\n if (missing.size === 0) return diagnostics;\n return diagnostics.filter(\n (entry) =>\n entry.code !== ERROR_CODES.TYPE_MISMATCH || !missing.has(entry.path)\n );\n}\n\n/** Adapt validator errors to diagnostics, with pointers and gate-faithful severity. */\nexport function validationDiagnostics(\n errors: readonly ValidationError[] | undefined\n): Diagnostic[] {\n return collapseMissingProperties(\n fromValidationErrors(errors).map((entry) => {\n const pointer = toJsonPointer(entry.path);\n return {\n ...entry,\n ...(DEFERRED_TO_COMPILER.has(entry.code) && {\n severity: 'warning' as const,\n }),\n ...(pointer !== undefined && { path: pointer }),\n };\n })\n );\n}\n\nfunction looksLikeValidationErrors(value: unknown): value is ValidationError[] {\n return (\n Array.isArray(value) &&\n value.length > 0 &&\n value.every(\n (entry) =>\n typeof entry === 'object' &&\n entry !== null &&\n typeof (entry as { message?: unknown }).message === 'string'\n )\n );\n}\n\n/**\n * Diagnostics out of an exception, when the exception is really a bad document.\n *\n * Both cores gate generation by throwing — `JsonValidationError` carrying\n * `validationErrors`, `PresentationValidationError` carrying `errors`. Left\n * alone those become `E_INTERNAL`, which tells an agent the server broke when\n * in fact its JSON did. Duck-typed rather than `instanceof`, because the\n * classes live inside the cores that `jto-ops` deliberately imports on demand.\n */\nexport function diagnosticsFromThrown(\n error: unknown\n): Diagnostic[] | undefined {\n if (typeof error !== 'object' || error === null) return undefined;\n const candidate = error as { validationErrors?: unknown; errors?: unknown };\n if (looksLikeValidationErrors(candidate.validationErrors)) {\n return validationDiagnostics(candidate.validationErrors);\n }\n if (looksLikeValidationErrors(candidate.errors)) {\n return validationDiagnostics(candidate.errors);\n }\n return undefined;\n}\n\nexport interface DiagnosticCounts {\n error: number;\n warning: number;\n info: number;\n}\n\n/** Diagnostics by severity. `error > 0` is what every tool gates `ok` on. */\nexport function countDiagnostics(\n diagnostics: readonly Diagnostic[]\n): DiagnosticCounts {\n return {\n error: diagnostics.filter((entry) => entry.severity === 'error').length,\n warning: diagnostics.filter((entry) => entry.severity === 'warning').length,\n info: diagnostics.filter((entry) => entry.severity === 'info').length,\n };\n}\n","/**\n * `jto_discover` — the authoring surface, small enough to read in one call.\n *\n * The first thing an agent that knows nothing about this project reaches for,\n * so it answers \"what can I write?\" and stops there: formats, component names,\n * renderer profiles, themes, starter documents. Deliberately no schemas — the\n * DOCX document schema alone is over 3 MB, and dumping it is the failure this\n * tool and `jto_describe_component` exist between them to prevent.\n *\n * Nothing here is restated. Which components exist, and which renderer accepts\n * which, is read out of the generated JSON Schema — the same artifact that\n * validates a document and drives the editor — while the human-facing metadata\n * comes from the registries that feed that generation and the renderer ids\n * from the cores. Three sources that have to agree; `discovery-drift.test.ts`\n * fails the build when they stop.\n */\n\nimport { createRequire } from 'module';\nimport { pathToFileURL } from 'url';\n\nimport type { McpServer } from '@modelcontextprotocol/server';\n\nimport { convertToJsonSchema, unionBranches } from '@json-to-office/shared';\nimport {\n STANDARD_COMPONENTS_REGISTRY,\n ThemeConfigSchema as DocxThemeConfigSchema,\n generateUnifiedDocumentSchema as generateDocxDocumentSchema,\n} from '@json-to-office/shared-docx';\nimport {\n PPTX_STANDARD_COMPONENTS_REGISTRY,\n ThemeConfigSchema as PptxThemeConfigSchema,\n generateUnifiedDocumentSchema as generatePptxDocumentSchema,\n} from '@json-to-office/shared-pptx';\n\nimport type { FormatName } from '../lib/adapters.js';\nimport type { ToolDeps } from '../lib/deps.js';\nimport {\n ERROR_CODES,\n diagnostic,\n guarded,\n success,\n toolResult,\n type Diagnostic,\n} from '../lib/errors.js';\nimport { FORMAT_NAMES, S, formatSchema, outputSchema } from '../lib/schema.js';\n\n/** A node of a JSON Schema document, walked structurally rather than typed. */\nexport type SchemaNode = Record<string, unknown>;\n\n// ---------------------------------------------------------------------------\n// Generated schemas\n// ---------------------------------------------------------------------------\n\n/**\n * The document schema for a format, generated in process.\n *\n * Same generator, same options and same `$id` as `scripts/generate-schemas.ts`,\n * so this is byte-for-byte what `pnpm schemas` writes to the gitignored\n * `schemas/` directory. Generating rather than reading is what lets the server\n * run from a bare `pnpm install` with no schema build step, and is also the\n * only way plugin-registered components could ever appear here (#204).\n */\nfunction generateDocumentSchema(format: FormatName): SchemaNode {\n return format === 'docx'\n ? (convertToJsonSchema(\n generateDocxDocumentSchema({\n includeStandardComponents: true,\n includeTheme: false,\n customComponents: [],\n title: 'JSON Document Definition',\n description: 'Document definition with standard components',\n }),\n { $id: 'document.schema.json' }\n ) as SchemaNode)\n : (convertToJsonSchema(\n generatePptxDocumentSchema({ customComponents: [] }),\n {\n $id: 'presentation.schema.json',\n }\n ) as SchemaNode);\n}\n\nfunction generateThemeSchema(format: FormatName): SchemaNode {\n return convertToJsonSchema(\n format === 'docx' ? DocxThemeConfigSchema : PptxThemeConfigSchema,\n {\n $id: 'theme.schema.json',\n title: 'Theme Configuration',\n description: 'Theme configuration for styling',\n }\n ) as SchemaNode;\n}\n\n/** One renderer's view of the component union, keyed by component name. */\nexport interface RendererProfile {\n id: string;\n components: ReadonlyMap<string, SchemaNode>;\n}\n\nexport interface FormatSchemas {\n format: FormatName;\n /** The generated document schema, as published at `jto://schema/{f}/document`. */\n document: SchemaNode;\n /** The generated theme schema. */\n theme: SchemaNode;\n /** The document schema's `definitions`, for resolving `$ref`s out of a branch. */\n definitions: Readonly<Record<string, SchemaNode>>;\n /** Renderer profiles, in the order the schema declares them. */\n profiles: readonly RendererProfile[];\n /** The root component's name, e.g. `docx` — the only one carrying `renderer`. */\n rootComponent: string;\n}\n\n/**\n * Generating the DOCX schema costs ~120ms and allocates a 3 MB object graph.\n * Nothing about it varies within a connection (there is no plugin registry\n * behind this server yet), so it is built once and shared by the tools and the\n * resources alike — which is also what keeps them from answering differently.\n */\nconst schemaCache = new Map<FormatName, FormatSchemas>();\n\nexport function formatSchemas(format: FormatName): FormatSchemas {\n const cached = schemaCache.get(format);\n if (cached) return cached;\n\n const document = generateDocumentSchema(format);\n const definitions = (document.definitions ?? {}) as Record<\n string,\n SchemaNode\n >;\n const { profiles, rootComponent } = extractRendererProfiles(document);\n const built: FormatSchemas = {\n format,\n document,\n theme: generateThemeSchema(format),\n definitions,\n profiles,\n rootComponent,\n };\n schemaCache.set(format, built);\n return built;\n}\n\n/** Drop the memoized schemas. Tests use this to prove generation is repeatable. */\nexport function resetSchemaCache(): void {\n schemaCache.clear();\n}\n\n// ---------------------------------------------------------------------------\n// Reading the generated schema\n// ---------------------------------------------------------------------------\n\n/** The `name` const a component branch is discriminated on. */\nfunction componentNameOf(node: unknown): string | undefined {\n const name = (\n (node as SchemaNode | undefined)?.properties as SchemaNode | undefined\n )?.name as SchemaNode | undefined;\n return typeof name?.const === 'string' ? name.const : undefined;\n}\n\n/** The `renderer` const, which only the root component carries. */\nfunction rendererOf(node: unknown): string | undefined {\n const renderer = (\n (node as SchemaNode | undefined)?.properties as SchemaNode | undefined\n )?.renderer as SchemaNode | undefined;\n return typeof renderer?.const === 'string' ? renderer.const : undefined;\n}\n\n/**\n * True when a node is a component union.\n *\n * `unionBranches` reads both shapes the exporter can leave behind — the flat\n * `anyOf` and the `if/then` dispatch `restructureNameDiscriminatedUnions`\n * rewrites it into — so this holds whichever pass last touched the schema.\n */\nexport function isComponentUnion(node: unknown): boolean {\n const branches = unionBranches(node);\n return (\n branches.length >= 2 &&\n branches.every((branch) => typeof componentNameOf(branch) === 'string')\n );\n}\n\n/** Follow `#/definitions/...` to the node it names. */\nexport function deref(\n node: unknown,\n definitions: Readonly<Record<string, SchemaNode>>\n): SchemaNode | undefined {\n let current = node as SchemaNode | undefined;\n for (let hops = 0; current && typeof current.$ref === 'string'; hops += 1) {\n // A cycle here would be a broken schema, not a deep one: definitions in\n // this project are one hop from their reference.\n if (hops > 8) return undefined;\n const match = /^#\\/definitions\\/(.+)$/.exec(current.$ref);\n current = match?.[1] !== undefined ? definitions[match[1]] : undefined;\n }\n return current;\n}\n\n/**\n * Find every renderer's component union.\n *\n * Searched for structurally rather than looked up by name because the\n * definition keys are not stable: DOCX names them per renderer\n * (`ComponentDefinition_docxjs`), while PPTX gets TypeBox's global ordinals\n * (`T1`, `T3`, …) — which shift with how many recursive schemas the process\n * built before this one. What *is* stable is that exactly one union per\n * renderer contains the root component, and the root component is the only one\n * carrying a `renderer` const.\n */\nfunction extractRendererProfiles(document: SchemaNode): {\n profiles: RendererProfile[];\n rootComponent: string;\n} {\n const definitions = (document.definitions ?? {}) as Record<\n string,\n SchemaNode\n >;\n const found = new Map<string, SchemaNode[]>();\n let rootComponent = '';\n\n const seen = new Set<object>();\n const walk = (node: unknown): void => {\n if (typeof node !== 'object' || node === null || seen.has(node)) return;\n seen.add(node);\n if (Array.isArray(node)) {\n node.forEach(walk);\n return;\n }\n if (isComponentUnion(node)) {\n const branches = unionBranches(node) as SchemaNode[];\n const root = branches.find((branch) => rendererOf(branch) !== undefined);\n const id = root ? rendererOf(root) : undefined;\n if (root && id !== undefined) {\n rootComponent = componentNameOf(root) ?? rootComponent;\n const previous = found.get(id);\n if (!previous || branches.length > previous.length) {\n found.set(id, branches);\n }\n }\n }\n for (const value of Object.values(node)) walk(value);\n };\n walk(document);\n // The root union lives under `definitions` for DOCX and is only reachable\n // from the root through a `$ref`, so the definitions are walked too.\n walk(definitions);\n\n const profiles = [...found.entries()].map(([id, branches]) => ({\n id,\n components: new Map(\n branches.map((branch) => [componentNameOf(branch) as string, branch])\n ),\n }));\n return { profiles, rootComponent };\n}\n\n/**\n * The component names a container accepts as direct children, per the schema.\n *\n * The registry declares the same thing in `allowedChildren`, but that is the\n * input to generation, not its result — a narrowing applied downstream would\n * make the two differ, which is one of the divergences the drift test watches.\n */\nexport function childNamesOf(\n branch: SchemaNode,\n definitions: Readonly<Record<string, SchemaNode>>\n): string[] | undefined {\n const children = (branch.properties as SchemaNode | undefined)?.children as\n | SchemaNode\n | undefined;\n if (!children) return undefined;\n const items = deref(children.items, definitions);\n if (!items) return undefined;\n const branches = unionBranches(items);\n if (branches.length > 0) {\n return branches\n .map((entry) => componentNameOf(entry))\n .filter((name): name is string => name !== undefined);\n }\n const single = componentNameOf(items);\n return single !== undefined ? [single] : [];\n}\n\n// ---------------------------------------------------------------------------\n// Registry metadata\n// ---------------------------------------------------------------------------\n\n/**\n * The registry entry behind a component, for the parts a JSON Schema cannot\n * carry: its category, and (once #236 lands) its stability and deprecation.\n */\ninterface RegistryEntry {\n name: string;\n category: string;\n description: string;\n hasChildren: boolean;\n allowedChildren?: readonly string[];\n stability?: string;\n deprecated?: unknown;\n}\n\nexport function registryEntries(format: FormatName): RegistryEntry[] {\n const source =\n format === 'docx'\n ? STANDARD_COMPONENTS_REGISTRY\n : PPTX_STANDARD_COMPONENTS_REGISTRY;\n return source.map((component) => {\n const extra = component as { stability?: string; deprecated?: unknown };\n return {\n name: component.name,\n category: component.category,\n description: component.description,\n hasChildren: component.hasChildren,\n ...(component.allowedChildren !== undefined && {\n allowedChildren: component.allowedChildren,\n }),\n // Absent today; read rather than defaulted so that the day #236 adds it\n // to the registry it appears here with no change on this side.\n ...(extra.stability !== undefined && { stability: extra.stability }),\n ...(extra.deprecated !== undefined && { deprecated: extra.deprecated }),\n };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Built-in themes\n// ---------------------------------------------------------------------------\n\nconst CORE_THEMES: Record<FormatName, { specifier: string; exported: string }> =\n {\n docx: { specifier: '@json-to-office/core-docx', exported: 'themes' },\n pptx: { specifier: '@json-to-office/core-pptx', exported: 'pptxThemes' },\n };\n\n/**\n * A resolver rooted at `jto-ops`, which owns the cores — they are its\n * dependency, not ours, so under pnpm's strict layout a bare specifier here\n * resolves to nothing. Same approach `jto_info` takes to read their versions.\n */\nlet coreResolver: NodeJS.Require | undefined;\ntry {\n const here = createRequire(import.meta.url);\n coreResolver = createRequire(\n here.resolve('@json-to-office/jto-ops/package.json')\n );\n} catch {\n /* jto-ops unresolvable: themes fall back to whatever the adapter reports */\n}\n\n/**\n * Built-in theme names for a format.\n *\n * `FormatAdapter.getBuiltinThemes()` is the intended source and is asked\n * first. It reaches for its core with a synchronous `require`, though, which\n * tsup's ESM shim leaves as a stub that throws — so in this (ESM) process it\n * answers `{}` and the fallback below does the work. Delete the fallback once\n * jto-ops loads its themes asynchronously; the adapter branch will then win on\n * its own.\n */\nasync function builtinThemeNames(\n format: FormatName,\n deps: ToolDeps\n): Promise<string[]> {\n const fromAdapter = Object.keys(deps.getAdapter(format).getBuiltinThemes());\n if (fromAdapter.length > 0) return fromAdapter.sort();\n if (!coreResolver) return [];\n const { specifier, exported } = CORE_THEMES[format];\n try {\n const core = (await import(\n pathToFileURL(coreResolver.resolve(specifier)).href\n )) as Record<string, Record<string, unknown> | undefined>;\n return Object.keys(core[exported] ?? {}).sort();\n } catch {\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Starter documents\n// ---------------------------------------------------------------------------\n\nexport interface Starter {\n id: string;\n format: FormatName;\n title: string;\n description: string;\n document: unknown;\n}\n\n/**\n * The smallest documents that actually build.\n *\n * Kept here rather than pointed at on disk because an agent's first move after\n * discovery is to copy one and edit it, and a path it cannot read is worse\n * than no starter at all. `discovery-drift.test.ts` runs every one of them\n * through the real validator, so a component change that invalidates a starter\n * fails the build instead of shipping a broken example.\n *\n * The slides carry no `props: {}` any more. They only ever did because the\n * published schema required the key on a component that needs nothing in it —\n * a workaround for a defect since fixed in `shared-pptx`, and one an agent\n * copying a starter would have carried into every slide it wrote.\n */\nexport const STARTERS: readonly Starter[] = [\n {\n id: 'docx-minimal',\n format: 'docx',\n title: 'Minimal document',\n description:\n 'The smallest valid .docx: root, one section, a heading and a paragraph.',\n document: {\n name: 'docx',\n props: { metadata: { title: 'Untitled document' } },\n children: [\n {\n name: 'section',\n children: [\n { name: 'heading', props: { text: 'Title', level: 1 } },\n { name: 'paragraph', props: { text: 'First paragraph.' } },\n ],\n },\n ],\n },\n },\n {\n id: 'docx-report',\n format: 'docx',\n title: 'Report with a statistic and a table',\n description:\n 'A themed section showing the shapes that trip agents up: statistic props, and the column-major table model.',\n document: {\n name: 'docx',\n props: {\n metadata: { title: 'Quarterly report', author: 'Your name' },\n theme: 'minimal',\n },\n children: [\n {\n name: 'section',\n props: { meta: { title: 'Summary' } },\n children: [\n { name: 'heading', props: { text: 'Summary', level: 1 } },\n {\n name: 'paragraph',\n props: { text: 'One paragraph of context before the numbers.' },\n },\n {\n name: 'statistic',\n props: {\n number: '42',\n unit: '%',\n description: 'Year-on-year growth',\n },\n },\n {\n name: 'table',\n props: {\n columns: [\n {\n header: { content: 'Metric' },\n cells: [{ content: 'Revenue' }, { content: 'Churn' }],\n },\n {\n header: { content: 'Value' },\n cells: [{ content: '1.2M' }, { content: '3%' }],\n },\n ],\n },\n },\n ],\n },\n ],\n },\n },\n {\n id: 'pptx-minimal',\n format: 'pptx',\n title: 'Minimal presentation',\n description: 'The smallest valid .pptx: root, one slide, one title text.',\n document: {\n name: 'pptx',\n props: { title: 'Untitled deck' },\n children: [\n {\n name: 'slide',\n children: [\n { name: 'text', props: { text: 'Title slide', style: 'title' } },\n ],\n },\n ],\n },\n },\n {\n id: 'pptx-deck',\n format: 'pptx',\n title: 'Two-slide deck',\n description:\n 'A 16:9 deck with a title slide and a content slide, using the named text styles.',\n document: {\n name: 'pptx',\n props: {\n title: 'Quarterly deck',\n theme: 'default',\n slideWidth: 13.333,\n slideHeight: 7.5,\n },\n children: [\n {\n name: 'slide',\n children: [\n {\n name: 'text',\n props: { text: 'Quarterly review', style: 'title' },\n },\n {\n name: 'text',\n props: {\n text: 'Where we are and what changes next',\n style: 'subtitle',\n },\n },\n ],\n },\n {\n name: 'slide',\n children: [\n { name: 'text', props: { text: 'Agenda', style: 'heading1' } },\n {\n name: 'text',\n props: { text: 'Results\\nRisks\\nNext quarter', style: 'body' },\n },\n ],\n },\n ],\n },\n },\n];\n\n// ---------------------------------------------------------------------------\n// The catalogue\n// ---------------------------------------------------------------------------\n\nexport interface CatalogComponent {\n name: string;\n category: string;\n description: string;\n hasChildren: boolean;\n /** True for the one component a document's tree is rooted at. */\n root: boolean;\n /** Renderer ids whose profile accepts this component. */\n renderers: string[];\n /** Direct children the schema accepts, absent for leaves. */\n allowedChildren?: string[];\n /** Containers that accept this component, derived from every profile. */\n allowedParents: string[];\n /** #236, once the registries carry it. */\n stability?: string;\n deprecated?: unknown;\n}\n\nexport interface CatalogRenderer {\n id: string;\n /** The renderer used when a document omits `renderer`. */\n default: boolean;\n /** Components this profile accepts. */\n components: string[];\n /** Components other profiles of this format accept and this one does not. */\n unsupported: string[];\n}\n\nexport interface CatalogFormat {\n name: FormatName;\n extension: string;\n label: string;\n rootComponent: string;\n defaultRenderer: string;\n renderers: CatalogRenderer[];\n components: CatalogComponent[];\n themes: string[];\n starters: Starter[];\n}\n\nexport interface Catalog {\n formats: CatalogFormat[];\n diagnostics: Diagnostic[];\n}\n\n/**\n * Build the catalogue for one format.\n *\n * The component list is the union of the schema profiles, not the registry:\n * the schema is what a document is actually validated against, so a registry\n * entry that never made it into a profile would be a promise this server\n * cannot keep. It is reported as a diagnostic instead — and as a failing drift\n * test.\n */\nasync function catalogFormat(\n format: FormatName,\n deps: ToolDeps,\n diagnostics: Diagnostic[]\n): Promise<CatalogFormat> {\n const schemas = formatSchemas(format);\n const adapter = deps.getAdapter(format);\n\n let rendererIds: string[] = [];\n try {\n rendererIds = [...(await adapter.rendererIds())];\n } catch (error) {\n diagnostics.push(\n diagnostic(\n ERROR_CODES.DEPENDENCY_MISSING,\n `Could not read renderer ids for ${format}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n { severity: 'warning', context: { format } }\n )\n );\n }\n // The cores register the renderers; the schemas profile them. Order comes\n // from the cores (defaults first) and profiles the cores do not know about\n // are appended rather than dropped, so a mismatch is visible instead of\n // quietly resolved in one side's favour.\n const profileIds = schemas.profiles.map((profile) => profile.id);\n const orderedIds = [\n ...rendererIds,\n ...profileIds.filter((id) => !rendererIds.includes(id)),\n ];\n for (const id of orderedIds) {\n if (!profileIds.includes(id)) {\n diagnostics.push(\n diagnostic(\n ERROR_CODES.INTERNAL,\n `Renderer \"${id}\" is registered for ${format} but the generated schema has no profile for it.`,\n { severity: 'warning', context: { format, renderer: id } }\n )\n );\n } else if (!rendererIds.includes(id)) {\n diagnostics.push(\n diagnostic(\n ERROR_CODES.INTERNAL,\n `The generated ${format} schema profiles renderer \"${id}\", which the core does not register.`,\n { severity: 'warning', context: { format, renderer: id } }\n )\n );\n }\n }\n\n const byRenderer = new Map(\n schemas.profiles.map((profile) => [profile.id, profile])\n );\n const allNames = [\n ...new Set(schemas.profiles.flatMap((p) => [...p.components.keys()])),\n ];\n\n const metadata = new Map(\n registryEntries(format).map((entry) => [entry.name, entry])\n );\n for (const entry of metadata.values()) {\n if (!allNames.includes(entry.name)) {\n diagnostics.push(\n diagnostic(\n ERROR_CODES.INTERNAL,\n `Component \"${entry.name}\" is in the ${format} registry but in no renderer profile of the generated schema.`,\n { severity: 'warning', context: { format, component: entry.name } }\n )\n );\n }\n }\n\n // Parents are derived from what the schema actually accepts, so a container\n // that was narrowed downstream reports honestly.\n const parents = new Map<string, Set<string>>();\n for (const profile of schemas.profiles) {\n for (const [name, branch] of profile.components) {\n for (const child of childNamesOf(branch, schemas.definitions) ?? []) {\n let holders = parents.get(child);\n if (!holders) parents.set(child, (holders = new Set()));\n holders.add(name);\n }\n }\n }\n\n const components: CatalogComponent[] = allNames.map((name) => {\n const entry = metadata.get(name);\n const renderers = orderedIds.filter((id) =>\n byRenderer.get(id)?.components.has(name)\n );\n const branch = schemas.profiles\n .map((profile) => profile.components.get(name))\n .find((found): found is SchemaNode => found !== undefined)!;\n const children = childNamesOf(branch, schemas.definitions);\n if (!entry) {\n diagnostics.push(\n diagnostic(\n ERROR_CODES.INTERNAL,\n `Component \"${name}\" is in the generated ${format} schema but not in the registry, so it has no description.`,\n { severity: 'warning', context: { format, component: name } }\n )\n );\n }\n return {\n name,\n category: entry?.category ?? 'content',\n description: entry?.description ?? '',\n hasChildren: children !== undefined,\n root: name === schemas.rootComponent,\n renderers,\n ...(children !== undefined && { allowedChildren: children }),\n allowedParents: [...(parents.get(name) ?? [])].sort(),\n ...(entry?.stability !== undefined && { stability: entry.stability }),\n ...(entry?.deprecated !== undefined && { deprecated: entry.deprecated }),\n };\n });\n\n const themes = await builtinThemeNames(format, deps);\n if (themes.length === 0) {\n diagnostics.push(\n diagnostic(\n ERROR_CODES.DEPENDENCY_MISSING,\n `No built-in themes could be read for ${format}.`,\n {\n severity: 'info',\n suggestion:\n 'Documents still render with their own inline theme, or with a theme file passed as themePath.',\n context: { format },\n }\n )\n );\n }\n\n return {\n name: format,\n extension: adapter.extension,\n label: adapter.label,\n rootComponent: schemas.rootComponent,\n defaultRenderer: orderedIds[0] ?? '',\n renderers: orderedIds.map((id, index) => ({\n id,\n default: index === 0,\n components: [...(byRenderer.get(id)?.components.keys() ?? [])].sort(),\n unsupported: allNames\n .filter((name) => !byRenderer.get(id)?.components.has(name))\n .sort(),\n })),\n components,\n themes,\n starters: STARTERS.filter((starter) => starter.format === format),\n };\n}\n\n/** The whole catalogue, for the tool and the `jto://catalog` resource alike. */\nexport async function buildCatalog(\n deps: ToolDeps,\n formats: readonly FormatName[] = FORMAT_NAMES\n): Promise<Catalog> {\n const diagnostics: Diagnostic[] = [];\n const built: CatalogFormat[] = [];\n for (const format of formats) {\n built.push(await catalogFormat(format, deps, diagnostics));\n }\n return { formats: built, diagnostics };\n}\n\n// ---------------------------------------------------------------------------\n// Registration\n// ---------------------------------------------------------------------------\n\nconst starterSchema = {\n type: 'object' as const,\n properties: {\n id: { type: 'string' as const },\n format: { type: 'string' as const },\n title: { type: 'string' as const },\n description: { type: 'string' as const },\n document: { type: 'object' as const, additionalProperties: true },\n },\n required: ['id', 'format', 'title', 'description'],\n additionalProperties: true,\n};\n\nexport function register(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'jto_discover',\n {\n title: 'Discover the authoring surface',\n description:\n 'Formats, component names per format, renderer profiles and their ids, built-in themes, and starter documents you can copy and edit. Deliberately compact: no schemas. Call jto_describe_component for one component’s exact schema.',\n annotations: { readOnlyHint: true, openWorldHint: false },\n inputSchema: S<{ format?: FormatName; includeStarters?: boolean }>({\n type: 'object',\n properties: {\n format: formatSchema,\n includeStarters: {\n type: 'boolean',\n description:\n 'Include the starter documents inline. Default true; they are a few hundred bytes each.',\n },\n },\n additionalProperties: false,\n }),\n outputSchema: S(\n outputSchema(\n {\n formats: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n extension: { type: 'string' },\n label: { type: 'string' },\n rootComponent: {\n type: 'string',\n description: 'The component every document is rooted at.',\n },\n defaultRenderer: { type: 'string' },\n renderers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n default: { type: 'boolean' },\n components: {\n type: 'array',\n items: { type: 'string' },\n },\n unsupported: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Components another renderer of this format accepts and this one does not.',\n },\n },\n required: ['id', 'default', 'components', 'unsupported'],\n additionalProperties: false,\n },\n },\n components: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n category: { type: 'string' },\n description: { type: 'string' },\n hasChildren: { type: 'boolean' },\n root: { type: 'boolean' },\n renderers: {\n type: 'array',\n items: { type: 'string' },\n },\n allowedChildren: {\n type: 'array',\n items: { type: 'string' },\n },\n allowedParents: {\n type: 'array',\n items: { type: 'string' },\n },\n stability: { type: 'string' },\n },\n required: [\n 'name',\n 'category',\n 'description',\n 'hasChildren',\n 'root',\n 'renderers',\n 'allowedParents',\n ],\n additionalProperties: true,\n },\n },\n themes: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Built-in theme names, usable as the document’s props.theme or the tools’ theme option.',\n },\n starters: { type: 'array', items: starterSchema },\n },\n required: [\n 'name',\n 'extension',\n 'label',\n 'rootComponent',\n 'defaultRenderer',\n 'renderers',\n 'components',\n 'themes',\n 'starters',\n ],\n additionalProperties: false,\n },\n },\n }\n // `formats` is not required: a failure inside the handler comes back\n // as `{ ok: false, diagnostics }` and must stay a result, not become\n // a protocol error.\n )\n ),\n },\n async (args) =>\n toolResult(\n await guarded(async () => {\n const formats =\n args.format !== undefined ? [args.format] : FORMAT_NAMES;\n const catalog = await buildCatalog(deps, formats);\n const includeStarters = args.includeStarters !== false;\n return success(\n {\n formats: catalog.formats.map((format) => ({\n ...format,\n starters: includeStarters\n ? format.starters\n : format.starters.map(({ document: _document, ...rest }) => ({\n ...rest,\n })),\n })),\n },\n catalog.diagnostics\n );\n })\n )\n );\n}\n","/**\n * `jto_describe_component` — one component, exactly, and nothing else.\n *\n * The escape hatch that makes `jto_discover` safe to keep small. An agent that\n * knows a component exists asks here for the schema it must satisfy, and gets\n * the branch the validator itself dispatches on — not a paraphrase, and not\n * the 3 MB document schema it is a leaf of.\n *\n * Two reductions keep the answer readable, and both are reported rather than\n * silent:\n *\n * - Nested component unions are replaced by the list of names they accept.\n * Inlined, `section` alone is 226 KB of its descendants' schemas — which is\n * the same information as \"call this tool again for `paragraph`\", at four\n * orders of magnitude more tokens.\n * - A single prop bigger than `MAX_PROP_SCHEMA_BYTES` is elided and named in\n * `elided`, with the argument that brings it back. `props.themeOverrides` is\n * a whole 191 KB theme schema; an agent asking about the root component\n * almost never wants it, and the one that does can say so.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/server';\n\nimport { unionBranches } from '@json-to-office/shared';\n\nimport type { FormatName } from '../lib/adapters.js';\nimport type { ToolDeps } from '../lib/deps.js';\nimport { failure, guarded, success, toolResult } from '../lib/errors.js';\nimport { S, formatSchema, outputSchema } from '../lib/schema.js';\nimport {\n childNamesOf,\n deref,\n formatSchemas,\n isComponentUnion,\n registryEntries,\n type SchemaNode,\n} from './discover.js';\n\n/**\n * Codes this tool adds. They belong in `lib/errors.ts`' `ERROR_CODES` next to\n * the rest; they are declared here only because that file is another issue's\n * to edit.\n */\nconst UNKNOWN_COMPONENT = 'E_UNKNOWN_COMPONENT';\nconst UNKNOWN_RENDERER = 'E_UNKNOWN_RENDERER';\n\n/**\n * Per-prop budget, in bytes of JSON.\n *\n * Sized from what the schema actually contains: every component prop in either\n * format is under 16 KiB except the four that embed a whole theme or template\n * model (`themeOverrides`, `componentDefaults`, `theme`, `templates`). So this\n * elides exactly the props that are documents in their own right and nothing\n * else.\n */\nconst MAX_PROP_SCHEMA_BYTES = 16 * 1024;\n\ninterface Elision {\n /** JSON Pointer into the returned `schema`. */\n pointer: string;\n prop: string;\n bytes: number;\n hint: string;\n}\n\n/**\n * Every component name a format's schema declares, under any renderer.\n *\n * Not memoized: `formatSchemas` already is, and a second cache would survive\n * the `resetSchemaCache` the tests use to prove generation is repeatable.\n */\nfunction componentNamesOf(format: FormatName): Set<string> {\n return new Set(\n formatSchemas(format).profiles.flatMap((profile) => [\n ...profile.components.keys(),\n ])\n );\n}\n\n/** The other format, which is the only other place a component can live. */\nfunction otherFormat(format: FormatName): FormatName {\n return format === 'docx' ? 'pptx' : 'docx';\n}\n\n/**\n * Which format's registry a collapsed union's names come from.\n *\n * Usually the one being described, but not always: a DOCX `visual` carries a\n * pptx slide in `props.elements`, so its child union names pptx components. A\n * hint that assumed the enclosing format would send an agent to a describe call\n * that fails, and the trail ends there.\n */\nfunction unionFormat(names: string[], described: FormatName): FormatName {\n if (names.every((name) => componentNamesOf(described).has(name))) {\n return described;\n }\n const other = otherFormat(described);\n return names.every((name) => componentNamesOf(other).has(name))\n ? other\n : described;\n}\n\n/** What a nested component union collapses to. */\nfunction unionStub(names: string[], described: FormatName): SchemaNode {\n const format = unionFormat(names, described);\n return {\n type: 'object',\n required: ['name'],\n properties: { name: { type: 'string', enum: names } },\n description: `A nested component: one of ${names.join(', ')}. Call jto_describe_component with format \"${format}\" for its schema.`,\n };\n}\n\n/**\n * Copy a schema, collapsing component unions and collecting the definitions\n * the copy still needs.\n */\nfunction collapse(\n node: unknown,\n definitions: Readonly<Record<string, SchemaNode>>,\n needed: Set<string>,\n described: FormatName\n): unknown {\n if (Array.isArray(node)) {\n return node.map((entry) => collapse(entry, definitions, needed, described));\n }\n if (typeof node !== 'object' || node === null) return node;\n\n const object = node as SchemaNode;\n if (typeof object.$ref === 'string') {\n const target = deref(object, definitions);\n if (target && isComponentUnion(target)) {\n return unionStub(componentNames(target), described);\n }\n const match = /^#\\/definitions\\/(.+)$/.exec(object.$ref);\n if (match?.[1] !== undefined && definitions[match[1]]) needed.add(match[1]);\n return { ...object };\n }\n if (isComponentUnion(object)) {\n return unionStub(componentNames(object), described);\n }\n\n const copy: SchemaNode = {};\n for (const [key, value] of Object.entries(object)) {\n copy[key] = collapse(value, definitions, needed, described);\n }\n return copy;\n}\n\nfunction componentNames(union: unknown): string[] {\n return unionBranches(union)\n .map((branch) => {\n const name = (branch.properties as SchemaNode | undefined)?.name as\n | SchemaNode\n | undefined;\n return typeof name?.const === 'string' ? name.const : undefined;\n })\n .filter((name): name is string => name !== undefined);\n}\n\n/**\n * Elide oversized props in place, returning what was cut.\n *\n * Only top-level props are candidates: they are the unit an agent asks about\n * and the unit `expandProps` brings back, so cutting deeper would leave a hole\n * nothing can reopen.\n */\nfunction elideLargeProps(\n schema: SchemaNode,\n keep: readonly string[]\n): Elision[] {\n const props = (schema.properties as SchemaNode | undefined)?.props as\n | SchemaNode\n | undefined;\n const entries = props?.properties as SchemaNode | undefined;\n if (!entries) return [];\n\n const elided: Elision[] = [];\n for (const [prop, value] of Object.entries(entries)) {\n if (keep.includes(prop)) continue;\n const bytes = JSON.stringify(value).length;\n if (bytes <= MAX_PROP_SCHEMA_BYTES) continue;\n const description = (value as SchemaNode).description;\n entries[prop] = {\n ...(typeof description === 'string' && { description }),\n $comment: `Elided: ${bytes} bytes.`,\n };\n elided.push({\n pointer: `/properties/props/properties/${prop}`,\n prop,\n bytes,\n hint: `Call jto_describe_component again with expandProps: [\"${prop}\"] for this sub-schema.`,\n });\n }\n return elided;\n}\n\nexport function register(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'jto_describe_component',\n {\n title: 'Describe one component',\n description:\n 'The exact JSON Schema one component must satisfy under one renderer, plus the children it accepts, the containers that accept it, and which renderers support it. Nested components collapse to their names — describe those separately rather than reading one giant schema.',\n annotations: { readOnlyHint: true, openWorldHint: false },\n inputSchema: S<{\n format: FormatName;\n name: string;\n renderer?: string;\n expandProps?: string[];\n }>({\n type: 'object',\n properties: {\n format: formatSchema,\n name: {\n type: 'string',\n description:\n 'Component name, as listed by jto_discover (e.g. \"paragraph\", \"slide\").',\n minLength: 1,\n },\n renderer: {\n type: 'string',\n description:\n 'Renderer profile to describe the component under. Omit for the format default; profiles differ wherever a backend cannot draw something.',\n },\n expandProps: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Props to return in full even when oversized. Names come from a previous call’s `elided`.',\n },\n },\n required: ['format', 'name'],\n additionalProperties: false,\n }),\n outputSchema: S(\n outputSchema(\n {\n component: {\n type: 'object',\n properties: {\n format: { type: 'string' },\n name: { type: 'string' },\n category: { type: 'string' },\n description: { type: 'string' },\n hasChildren: { type: 'boolean' },\n root: { type: 'boolean' },\n stability: { type: 'string' },\n },\n required: ['format', 'name', 'hasChildren', 'root'],\n additionalProperties: true,\n },\n renderer: {\n type: 'string',\n description: 'The profile `schema` was taken from.',\n },\n renderers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n default: { type: 'boolean' },\n supported: { type: 'boolean' },\n },\n required: ['id', 'default', 'supported'],\n additionalProperties: false,\n },\n },\n schema: {\n type: 'object',\n description:\n 'The component branch the validator dispatches on, with nested component unions collapsed and oversized props elided.',\n additionalProperties: true,\n },\n definitions: {\n type: 'object',\n description:\n 'Targets of the `$ref`s left in `schema`, so it resolves on its own.',\n additionalProperties: true,\n },\n elided: {\n type: 'array',\n description: 'Props cut for size, and how to get them back.',\n items: {\n type: 'object',\n properties: {\n pointer: { type: 'string' },\n prop: { type: 'string' },\n bytes: { type: 'integer' },\n hint: { type: 'string' },\n },\n required: ['pointer', 'prop', 'bytes', 'hint'],\n additionalProperties: false,\n },\n },\n allowedChildren: {\n type: 'array',\n items: { type: 'string' },\n description: 'Absent when the component takes no children.',\n },\n allowedParents: { type: 'array', items: { type: 'string' } },\n }\n // Everything but the envelope is conditional on `ok`: an unknown\n // component comes back as a normal result with diagnostics, so\n // demanding `schema` here would turn that answer into the protocol\n // error the envelope exists to avoid.\n )\n ),\n },\n async (args) =>\n toolResult(\n await guarded(async () => {\n const schemas = formatSchemas(args.format);\n const profiles = schemas.profiles;\n\n let rendererIds: string[] = [];\n try {\n rendererIds = [\n ...(await deps.getAdapter(args.format).rendererIds()),\n ];\n } catch {\n /* fall back to the order the schema declares */\n }\n const ordered = [\n ...rendererIds.filter((id) => profiles.some((p) => p.id === id)),\n ...profiles\n .map((profile) => profile.id)\n .filter((id) => !rendererIds.includes(id)),\n ];\n\n const known = [\n ...new Set(profiles.flatMap((p) => [...p.components.keys()])),\n ].sort();\n if (!known.includes(args.name)) {\n // The other format is checked before giving up: the DOCX `visual`\n // component embeds pptx elements, so \"describe the chart you just\n // told me about\" legitimately arrives here with the wrong format.\n const elsewhere = otherFormat(args.format);\n const availableElsewhere = componentNamesOf(elsewhere).has(\n args.name\n );\n return failure(\n UNKNOWN_COMPONENT,\n `No component \"${args.name}\" in ${args.format}.`,\n {\n suggestion: availableElsewhere\n ? `It exists in ${elsewhere} — pass format: \"${elsewhere}\". Known ${args.format} components: ${known.join(', ')}.`\n : `Known ${args.format} components: ${known.join(', ')}.`,\n context: {\n format: args.format,\n known,\n ...(availableElsewhere && { availableIn: elsewhere }),\n },\n }\n );\n }\n\n const rendererId = args.renderer ?? ordered[0];\n if (rendererId === undefined || !ordered.includes(rendererId)) {\n return failure(\n UNKNOWN_RENDERER,\n `No renderer \"${String(args.renderer)}\" for ${args.format}.`,\n {\n suggestion: `Known ${args.format} renderers: ${ordered.join(', ')}.`,\n context: { format: args.format, known: ordered },\n }\n );\n }\n\n const profile = profiles.find((entry) => entry.id === rendererId)!;\n const branch = profile.components.get(args.name);\n if (!branch) {\n // Known to the format, absent from this profile: the renderer\n // cannot draw it. That is an answer, not a failure — the agent\n // needs to know which renderer can.\n const supporting = ordered.filter((id) =>\n profiles.find((p) => p.id === id)?.components.has(args.name)\n );\n return failure(\n UNKNOWN_COMPONENT,\n `The \"${rendererId}\" renderer does not support \"${args.name}\".`,\n {\n suggestion:\n supporting.length > 0\n ? `Renderers that do: ${supporting.join(', ')}.`\n : 'No renderer of this format supports it.',\n context: { format: args.format, renderer: rendererId },\n }\n );\n }\n\n const needed = new Set<string>();\n const schema = collapse(\n branch,\n schemas.definitions,\n needed,\n args.format\n ) as SchemaNode;\n\n // Definitions are collapsed on the same terms and chased\n // transitively, so what comes back resolves without the document\n // schema behind it.\n const definitions: Record<string, unknown> = {};\n const queue = [...needed];\n while (queue.length > 0) {\n const key = queue.shift() as string;\n const target = schemas.definitions[key];\n if (definitions[key] !== undefined || !target) continue;\n const nested = new Set<string>();\n definitions[key] = collapse(\n target,\n schemas.definitions,\n nested,\n args.format\n );\n for (const next of nested) {\n if (definitions[next] === undefined) queue.push(next);\n }\n }\n\n const elided = elideLargeProps(schema, args.expandProps ?? []);\n const children = childNamesOf(branch, schemas.definitions);\n const entry = registryEntries(args.format).find(\n (candidate) => candidate.name === args.name\n );\n\n const parents = new Set<string>();\n for (const [name, candidate] of profile.components) {\n if (\n childNamesOf(candidate, schemas.definitions)?.includes(args.name)\n ) {\n parents.add(name);\n }\n }\n\n return success({\n component: {\n format: args.format,\n name: args.name,\n ...(entry !== undefined && {\n category: entry.category,\n description: entry.description,\n }),\n hasChildren: children !== undefined,\n root: args.name === schemas.rootComponent,\n ...(entry?.stability !== undefined && {\n stability: entry.stability,\n }),\n ...(entry?.deprecated !== undefined && {\n deprecated: entry.deprecated,\n }),\n },\n renderer: rendererId,\n renderers: ordered.map((id, index) => ({\n id,\n default: index === 0,\n supported:\n profiles.find((p) => p.id === id)?.components.has(args.name) ??\n false,\n })),\n schema,\n ...(Object.keys(definitions).length > 0 && { definitions }),\n elided,\n ...(children !== undefined && { allowedChildren: children }),\n allowedParents: [...parents].sort(),\n });\n })\n )\n );\n}\n","/**\n * Access to the `@json-to-office/jto-ops` format adapters.\n *\n * The adapters themselves import their core on demand, so constructing one is\n * cheap; memoizing is about identity rather than cost — the DOCX adapter keeps\n * per-instance caches (theme resolution, visual pre-pass counters) that a\n * fresh instance per tool call would throw away every request.\n */\n\nimport {\n DocxFormatAdapter,\n PptxFormatAdapter,\n type FormatAdapter,\n type FormatName,\n} from '@json-to-office/jto-ops';\n\nimport { OPTION_ERROR_CODES, failure, type Failure } from './errors.js';\n\nexport type { FormatAdapter, FormatName };\nexport type {\n GeneratorOptions,\n GeneratorResult,\n} from '@json-to-office/jto-ops';\n\nconst cache = new Map<FormatName, FormatAdapter>();\n\n/** The adapter for `format`, constructed on first use and reused after. */\nexport function getAdapter(format: FormatName): FormatAdapter {\n let adapter = cache.get(format);\n if (!adapter) {\n adapter =\n format === 'docx' ? new DocxFormatAdapter() : new PptxFormatAdapter();\n cache.set(format, adapter);\n }\n return adapter;\n}\n\n/** Drop the memoized adapters. Tests use this to isolate their caches. */\nexport function resetAdapters(): void {\n cache.clear();\n}\n\n/**\n * Reject an unknown renderer before any work happens.\n *\n * The ids come from the core's own registry, so this can never advertise a\n * stale set — same check `jto generate` makes, for the same reason: a typo\n * should cost a message, not a full render followed by one.\n */\nexport async function checkRenderer(\n adapter: FormatAdapter,\n renderer: string | undefined\n): Promise<Failure | undefined> {\n if (renderer === undefined) return undefined;\n const known = await adapter.rendererIds();\n if (known.includes(renderer)) return undefined;\n return failure(\n OPTION_ERROR_CODES.UNKNOWN_RENDERER,\n `Unknown ${adapter.name} renderer \"${renderer}\".`,\n {\n suggestion: `Use one of: ${known.map((id) => `\"${id}\"`).join(', ')}.`,\n context: { format: adapter.name, rendererIds: [...known] },\n }\n );\n}\n\n/**\n * The document as the requested renderer profile sees it.\n *\n * Both formats discriminate their schema on the document's own top-level\n * `renderer`, so asking \"does this validate as office-open?\" means validating\n * a copy that says so. A copy, not a mutation: the caller's tree — which may\n * be a workspace document — must come back unchanged.\n */\nexport function withRenderer(\n document: unknown,\n renderer: string | undefined\n): unknown {\n if (renderer === undefined) return document;\n if (\n typeof document !== 'object' ||\n document === null ||\n Array.isArray(document)\n ) {\n return document;\n }\n return { ...(document as Record<string, unknown>), renderer };\n}\n","/**\n * The workspace contract.\n *\n * #271 adds connection-scoped documents an agent edits by JSON Patch instead\n * of resending the whole tree. This module is the seam: the interface, the\n * holder for a host's process-wide override, and a stand-in that answers every\n * call with a structured \"unavailable\" so the inline path works untouched\n * before #271 lands and on any connection where workspaces are switched off.\n *\n * The holder is deliberately NOT where a connection's own store lives. Handles\n * are scoped to one connection, and a module-global default would hand the\n * second `createServer` in a process the first one's documents; the connection\n * store hangs off its `ToolDeps` instead (`../tools/workspace.ts`).\n *\n * The real store lives in `../workspace/store.ts`.\n *\n * Every method resolves rather than throws. A missing handle and a stale\n * revision are ordinary answers a tool reports to the agent, not server\n * failures (see `errors.ts`).\n */\n\nimport { ERROR_CODES, failure, type Failure } from './errors.js';\nimport type { FormatName } from './adapters.js';\n\nexport type WorkspaceResult<T> = ({ ok: true } & T) | Failure;\n\n/** RFC 6902 operation. Paths are RFC 6901 pointers — no private dialect (#271). */\nexport interface JsonPatchOperation {\n op: 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test';\n path: string;\n from?: string;\n value?: unknown;\n}\n\n/** What `jto_workspace_list` shows, and what every mutation returns. */\nexport interface WorkspaceRecord {\n /** Opaque, server-generated, meaningless outside this connection. */\n handle: string;\n format: FormatName;\n /** Starts at 1 on create; +1 per committed patch. Never reused, never decreases. */\n revision: number;\n /** Size of the serialized document, for the agent's own budgeting. */\n bytes: number;\n createdAt: string;\n updatedAt: string;\n /** Caller-supplied label, echoed back verbatim. */\n title?: string;\n /** Revisions pinned by `snapshot`, still retrievable through `get`. */\n pinnedRevisions: number[];\n}\n\nexport interface WorkspaceStore {\n /**\n * False on the stand-in. Tools read it to describe the connection's\n * capabilities (`jto_info`) without provoking an error.\n */\n readonly available: boolean;\n\n /** Open a document. The returned revision is 1. */\n create(input: {\n format: FormatName;\n document: unknown;\n title?: string;\n }): Promise<WorkspaceResult<{ record: WorkspaceRecord }>>;\n\n /**\n * Read a document.\n *\n * With `revision`, the read is checked: a revision that is neither current\n * nor pinned fails `E_STALE_REVISION` rather than quietly returning newer\n * JSON than the caller reasoned about. With `paths`, only those JSON\n * Pointers are projected, keyed by pointer — that is `jto_workspace_inspect`\n * on a large document.\n */\n get(\n handle: string,\n options?: { revision?: number; paths?: readonly string[] }\n ): Promise<\n WorkspaceResult<{\n record: WorkspaceRecord;\n document: unknown;\n /** Present only when `paths` was given. */\n projection?: Record<string, unknown>;\n }>\n >;\n\n /**\n * Apply a patch atomically.\n *\n * Syntax and paths are checked, the patch is applied to a copy, and only a\n * clean apply commits and bumps the revision — a half-applied document is\n * never observable. `baseRevision` makes the write conditional; omitting it\n * is a deliberate last-writer-wins.\n */\n patch(input: {\n handle: string;\n operations: readonly JsonPatchOperation[];\n baseRevision?: number;\n }): Promise<WorkspaceResult<{ record: WorkspaceRecord }>>;\n\n /**\n * Export the document and pin the revision it was taken at.\n *\n * The pin is what makes \"snapshot before risky changes\" real: after further\n * patches, `get(handle, pinnedRevision)` still returns this exact tree, so\n * an agent can compare or roll back without having kept the JSON in context.\n */\n snapshot(\n handle: string\n ): Promise<WorkspaceResult<{ record: WorkspaceRecord; document: unknown }>>;\n\n /** Every open handle on this connection. Recovers references after context loss. */\n list(): Promise<WorkspaceResult<{ records: WorkspaceRecord[] }>>;\n\n /** Release a handle and its memory. Idempotent: closing twice is not an error. */\n close(\n handle: string\n ): Promise<WorkspaceResult<{ handle: string; closed: boolean }>>;\n\n /**\n * Release every handle at once.\n *\n * A connection's store is reachable only through its `ToolDeps`, so the\n * documents go when the connection's deps do; this is for a host that wants\n * the memory back at a moment of its own choosing.\n */\n closeAll(): Promise<void>;\n}\n\nconst unavailable = (): Failure =>\n failure(\n ERROR_CODES.WORKSPACES_UNAVAILABLE,\n 'Document workspaces are not available on this connection.',\n {\n suggestion:\n 'Pass the document inline via `document` instead of `handle`.',\n }\n );\n\n/**\n * The no-workspaces implementation.\n *\n * Note `list` succeeds with an empty array: \"no open documents\" is a true and\n * useful answer, and failing it would make an agent think its own bookkeeping\n * broke.\n */\nexport const unavailableWorkspaceStore: WorkspaceStore = {\n available: false,\n async create() {\n return unavailable();\n },\n async get() {\n return unavailable();\n },\n async patch() {\n return unavailable();\n },\n async snapshot() {\n return unavailable();\n },\n async list() {\n return { ok: true, records: [] };\n },\n async close() {\n return unavailable();\n },\n async closeAll() {\n /* nothing is open */\n },\n};\n\n/**\n * The host's override, when it installed one.\n *\n * Undefined is not the same as `unavailableWorkspaceStore` here: nothing\n * installed means \"let each connection open its own store\", while an installed\n * stand-in means the host switched workspaces off and is to be left alone.\n * That distinction is why `hasWorkspaceStore` exists.\n */\nlet override: WorkspaceStore | undefined;\n\n/** Install a process-wide store. Passing `undefined` removes the override. */\nexport function setWorkspaceStore(store: WorkspaceStore | undefined): void {\n override = store;\n}\n\nexport function getWorkspaceStore(): WorkspaceStore {\n return override ?? unavailableWorkspaceStore;\n}\n\n/** Whether a host installed a store — `unavailableWorkspaceStore` included. */\nexport function hasWorkspaceStore(): boolean {\n return override !== undefined;\n}\n","/**\n * `{ document? | handle?, revision? }` → one concrete JSON document.\n *\n * Every document-taking tool starts here, so the inline and workspace paths\n * cannot drift: whichever the agent used, the tool body sees the same tree and\n * the same failure vocabulary.\n */\n\nimport { ERROR_CODES, failure, type Failure } from './errors.js';\nimport {\n DOCUMENT_SOURCE_RULE,\n type DocumentSourceInput,\n type SourceSummary,\n} from './schema.js';\nimport { getWorkspaceStore, type WorkspaceStore } from './workspace-store.js';\n\nexport type { DocumentSourceInput, SourceSummary };\n\nexport type ResolvedDocument =\n | {\n ok: true;\n document: unknown;\n origin: 'inline';\n }\n | {\n ok: true;\n document: unknown;\n origin: 'workspace';\n handle: string;\n /** The revision actually read, which may be older than current when pinned. */\n revision: number;\n }\n | Failure;\n\n/**\n * Resolve a document source.\n *\n * The store is a parameter rather than a module lookup so a tool can be tested\n * against a fake without touching the process-wide holder; it defaults to the\n * installed store, which is what production wants.\n */\nexport async function resolveDocumentSource(\n source: DocumentSourceInput,\n store: WorkspaceStore = getWorkspaceStore()\n): Promise<ResolvedDocument> {\n const hasInline = source.document !== undefined && source.document !== null;\n const hasHandle =\n typeof source.handle === 'string' && source.handle.length > 0;\n\n if (hasInline && hasHandle) {\n return failure(\n ERROR_CODES.DOC_SOURCE_AMBIGUOUS,\n 'Both `document` and `handle` were supplied.',\n { suggestion: DOCUMENT_SOURCE_RULE }\n );\n }\n if (!hasInline && !hasHandle) {\n return failure(\n ERROR_CODES.DOC_SOURCE_MISSING,\n 'Neither `document` nor `handle` was supplied.',\n { suggestion: DOCUMENT_SOURCE_RULE }\n );\n }\n\n if (hasInline) {\n // `revision` alone is meaningless and usually means the agent meant to\n // send a handle too; saying so beats validating a document it did not\n // intend to send.\n if (source.revision !== undefined) {\n return failure(\n ERROR_CODES.DOC_SOURCE_AMBIGUOUS,\n '`revision` applies to `handle` and cannot be combined with inline `document`.',\n { suggestion: DOCUMENT_SOURCE_RULE }\n );\n }\n return { ok: true, document: source.document, origin: 'inline' };\n }\n\n const handle = source.handle as string;\n const read = await store.get(handle, {\n ...(source.revision !== undefined && { revision: source.revision }),\n });\n if (!read.ok) return read;\n\n return {\n ok: true,\n document: read.document,\n origin: 'workspace',\n handle,\n revision: read.record.revision,\n };\n}\n\n/**\n * Where the tool read the document from, for the caller's own bookkeeping.\n *\n * Every document-taking tool echoes this, so an agent can tell at a glance\n * whether the answer describes the JSON it sent or the workspace revision the\n * server holds — and, when pinned, which revision that actually was.\n */\nexport function sourceSummary(\n resolved: Extract<ResolvedDocument, { ok: true }>\n): SourceSummary {\n return resolved.origin === 'workspace'\n ? {\n origin: 'workspace',\n handle: resolved.handle,\n revision: resolved.revision,\n }\n : { origin: 'inline' };\n}\n\n/**\n * Parse a document that arrived as a JSON string.\n *\n * Tools take `document` as an object, but a handful of callers (file contents,\n * `jto_docx_diff`'s two sides) hold text; a parse failure is the agent's\n * defect to fix, so it comes back structured like every other one.\n */\nexport function parseDocumentJson(\n text: string,\n path?: string\n): { ok: true; document: unknown } | Failure {\n try {\n return { ok: true, document: JSON.parse(text) };\n } catch (error) {\n return failure(\n ERROR_CODES.INVALID_JSON,\n error instanceof Error ? error.message : String(error),\n { ...(path !== undefined && { path }) }\n );\n }\n}\n","/**\n * `jto_validate` — will this document render, and if not, where is it broken?\n *\n * A document defect is never a protocol error and never `isError`: the whole\n * point of the tool is to hand an agent a list of places to repair, which a\n * JSON-RPC failure cannot carry. So every answer is a normal result, and the\n * only thing a caller branches on is `ok`.\n *\n * The validation plumbing this shares with `jto_generate` and `jto_docx_diff`\n * — the JSON Pointer mapping, the thrown-error adapter, the renderer check —\n * lives in `lib/`, so all three describe the same broken document the same way\n * without one tool module importing another.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/server';\n\nimport {\n checkRenderer,\n withRenderer,\n type FormatName,\n} from '../lib/adapters.js';\nimport type { ToolDeps } from '../lib/deps.js';\nimport { resolveDocumentSource, sourceSummary } from '../lib/doc-source.js';\nimport {\n countDiagnostics,\n guarded,\n toolResult,\n validationDiagnostics,\n type Diagnostic,\n} from '../lib/errors.js';\nimport {\n S,\n documentSourceProperties,\n formatSchema,\n outputSchema,\n renderOptionProperties,\n sourceSummarySchema,\n type DocumentSourceInput,\n} from '../lib/schema.js';\n\nconst SEVERITY_RANK: Record<Diagnostic['severity'], number> = {\n error: 0,\n warning: 1,\n info: 2,\n};\n\n/**\n * Cap the list without losing the fatal entries.\n *\n * A document with a hundred style warnings and one structural error would\n * otherwise report the warnings and drop the only thing that stops it\n * rendering. Sorting by severity is stable, so document order survives within\n * each band.\n */\nfunction capDiagnostics(\n diagnostics: Diagnostic[],\n limit: number\n): { kept: Diagnostic[]; truncated: boolean } {\n if (diagnostics.length <= limit)\n return { kept: diagnostics, truncated: false };\n const ordered = [...diagnostics].sort(\n (a, b) => SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity]\n );\n return { kept: ordered.slice(0, limit), truncated: true };\n}\n\nconst DEFAULT_MAX_DIAGNOSTICS = 100;\n\ninterface ValidateArgs extends DocumentSourceInput {\n format: FormatName;\n renderer?: string;\n maxDiagnostics?: number;\n}\n\nexport function register(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'jto_validate',\n {\n title: 'Validate a document',\n description:\n 'Check a document against its format schema and report every defect as a path-addressed diagnostic. Paths are RFC 6901 JSON Pointers into the document you passed, so they can be used directly as patch targets; codes are the stable `E_`/`W_` vocabulary, e.g. `E_REQUIRED_PROPERTY`, `E_UNEXPECTED_PROPERTY`, `E_TYPE_MISMATCH`, `E_UNKNOWN_COMPONENT`. `ok` mirrors the gate generation applies: schema and semantic errors block it — the semantic rules the published JSON Schema cannot state, such as a text component needing one of `text`/`runs`, are checked here and only here — while renderer-profile findings (code `W_UNSUPPORTED_RENDERER_FEATURE`) come back as warnings because the renderer, not the schema, has the last word on those. A broken document is a normal result with `ok: false`, never an error.',\n annotations: { readOnlyHint: true, openWorldHint: false },\n inputSchema: S<ValidateArgs>({\n type: 'object',\n properties: {\n format: formatSchema,\n ...documentSourceProperties,\n renderer: {\n ...renderOptionProperties.renderer,\n description:\n \"Renderer profile to validate against. Overrides the document's own `renderer` for this check only; omit to validate the document exactly as written.\",\n },\n maxDiagnostics: {\n type: 'integer',\n minimum: 1,\n maximum: 1000,\n description: `Cap on returned diagnostics (default ${DEFAULT_MAX_DIAGNOSTICS}). Errors are kept ahead of warnings when the cap bites.`,\n },\n },\n required: ['format'],\n additionalProperties: false,\n }),\n outputSchema: S(\n outputSchema({\n format: formatSchema,\n renderer: {\n type: 'string',\n description: 'The profile the document was validated against.',\n },\n valid: {\n type: 'boolean',\n description:\n 'True when nothing blocks generation. Equal to `ok` whenever validation actually ran.',\n },\n source: sourceSummarySchema,\n counts: {\n type: 'object',\n description: 'Diagnostics by severity, before any cap.',\n properties: {\n error: { type: 'integer' },\n warning: { type: 'integer' },\n info: { type: 'integer' },\n },\n required: ['error', 'warning', 'info'],\n additionalProperties: false,\n },\n truncated: {\n type: 'boolean',\n description: '`diagnostics` was capped by `maxDiagnostics`.',\n },\n })\n ),\n },\n async (args) =>\n toolResult(\n await guarded(async () => {\n const adapter = deps.getAdapter(args.format);\n\n const rendererError = await checkRenderer(adapter, args.renderer);\n if (rendererError) return { ...rendererError, format: args.format };\n\n const resolved = await resolveDocumentSource(args, deps.workspaces());\n if (!resolved.ok) return { ...resolved, format: args.format };\n\n const result = adapter.validateDocument(\n withRenderer(resolved.document, args.renderer)\n );\n const all = validationDiagnostics(result.errors);\n const counts = countDiagnostics(all);\n const { kept, truncated } = capDiagnostics(\n all,\n args.maxDiagnostics ?? DEFAULT_MAX_DIAGNOSTICS\n );\n\n return {\n ok: counts.error === 0,\n diagnostics: kept,\n valid: counts.error === 0,\n format: args.format,\n ...(args.renderer !== undefined && { renderer: args.renderer }),\n source: sourceSummary(resolved),\n counts,\n truncated,\n };\n })\n )\n );\n}\n","/**\n * Delivery of generated bytes to the client.\n *\n * Default is a path under the output root: a .pptx inlined as base64 costs the\n * agent its context window and the transport a multi-megabyte frame, for a\n * payload it almost always just wants to hand to a viewer. Inlining is\n * available, but only when asked for and only under a hard ceiling (#204).\n */\n\nimport * as fs from 'fs/promises';\n\nimport { ERROR_CODES, failure, type Failure } from './errors.js';\nimport type { OutputRoot } from './output-root.js';\n\n/**\n * Ceiling for `outputMode: 'base64'`.\n *\n * 4 MiB of binary is ~5.5 MiB of base64 — already past what most clients will\n * put in a model context, and the point beyond which a path is strictly better\n * for everyone.\n */\nexport const MAX_INLINE_ARTIFACT_BYTES = 4 * 1024 * 1024;\n\n/**\n * Open flags for the artifact write.\n *\n * `resolveOutputPath` already resolved every symlink on the way to this path,\n * but it returned before the write started; `O_NOFOLLOW` makes the kernel — not\n * a prior check — refuse a link planted in that window. It does not exist on\n * Windows, so an `lstat` immediately before the open backs it everywhere,\n * leaving only the lstat→open sliver uncovered — and only there.\n */\nconst ARTIFACT_WRITE_FLAGS =\n fs.constants.O_WRONLY |\n fs.constants.O_CREAT |\n fs.constants.O_TRUNC |\n (fs.constants.O_NOFOLLOW ?? 0);\n\nexport const MIME_TYPES: Record<string, string> = {\n '.docx':\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n '.pptx':\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n '.pdf': 'application/pdf',\n '.png': 'image/png',\n};\n\nexport type ArtifactMode = 'path' | 'base64';\n\nexport type Artifact =\n | {\n mode: 'path';\n /** Absolute path, always inside the output root. */\n path: string;\n /** Path relative to the output root, for display. */\n relative: string;\n bytes: number;\n filename: string;\n mimeType: string;\n }\n | {\n mode: 'base64';\n base64: string;\n bytes: number;\n filename: string;\n mimeType: string;\n };\n\nexport interface DeliverArtifactOptions {\n /** Name inside the output root; rejected if it escapes (see `output-root.ts`). */\n filename: string;\n mimeType: string;\n /** Defaults to `path`. */\n mode?: ArtifactMode;\n outputRoot: OutputRoot;\n /** Override the inline ceiling; tests and hosts with tighter budgets use it. */\n maxInlineBytes?: number;\n}\n\nexport type DeliverArtifactResult = { ok: true; artifact: Artifact } | Failure;\n\n/**\n * Turn a generated buffer into the payload a tool reports.\n *\n * Over-limit inlining is a refusal, not a silent downgrade to a path: an agent\n * that asked for bytes and got a path would go looking for a file it cannot\n * read on a host with no shared filesystem, and never learn why.\n */\nexport async function deliverArtifact(\n buffer: Buffer,\n options: DeliverArtifactOptions\n): Promise<DeliverArtifactResult> {\n const {\n filename,\n mimeType,\n mode = 'path',\n outputRoot,\n maxInlineBytes = MAX_INLINE_ARTIFACT_BYTES,\n } = options;\n const bytes = buffer.byteLength;\n\n if (mode === 'base64') {\n if (bytes > maxInlineBytes) {\n return failure(\n ERROR_CODES.ARTIFACT_TOO_LARGE,\n `Artifact is ${bytes} bytes, over the ${maxInlineBytes}-byte inline limit.`,\n {\n suggestion:\n 'Re-run with outputMode \"path\" to have the file written under the server output root.',\n context: { bytes, maxInlineBytes, filename },\n }\n );\n }\n return {\n ok: true,\n artifact: {\n mode: 'base64',\n base64: buffer.toString('base64'),\n bytes,\n filename,\n mimeType,\n },\n };\n }\n\n const resolved = await outputRoot.resolveOutputPath(filename);\n if (!resolved.ok) return resolved;\n\n const plantedLink = () =>\n failure(\n ERROR_CODES.OUTPUT_ROOT_ESCAPE,\n `Output path became a symlink while writing: \"${filename}\".`,\n {\n suggestion: 'Retry with a different file name.',\n context: { outputRoot: outputRoot.path, filename },\n }\n );\n\n // The pre-open half of the race guard, and on Windows all of it: O_NOFOLLOW\n // is 0 there, so without this check the open would follow a planted link and\n // truncate whatever it points at.\n const staged = await fs.lstat(resolved.path).catch(() => undefined);\n if (staged?.isSymbolicLink()) return plantedLink();\n\n let handle: fs.FileHandle;\n try {\n // A configured root may itself be shared. New artifacts still default to\n // owner-only; callers that intentionally publish them can chmod afterwards.\n handle = await fs.open(resolved.path, ARTIFACT_WRITE_FLAGS, 0o600);\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code !== 'ELOOP') throw err;\n return plantedLink();\n }\n try {\n await handle.chmod(0o600);\n await handle.writeFile(buffer);\n } finally {\n await handle.close();\n }\n return {\n ok: true,\n artifact: {\n mode: 'path',\n path: resolved.path,\n relative: resolved.relative,\n bytes,\n filename,\n mimeType,\n },\n };\n}\n","/**\n * What a tool is allowed to say back, and in how many words.\n *\n * One wrong prop repeated down sixty paragraphs is sixty near-identical\n * diagnostics: the same code, the same message, a different index. An agent\n * pays for every one of them and learns the same fact once, so the repeats\n * collapse into an occurrence count on the first and the survivors are capped.\n *\n * `jto_validate` grew the cap first and still carries its own copy; both should\n * end up here once that file is free to edit.\n */\n\nimport { type Diagnostic } from './errors.js';\n\n/** Cap applied when the caller names none. */\nexport const DEFAULT_MAX_DIAGNOSTICS = 100;\n\n/** Advertised bound, so every tool's `maxDiagnostics` means the same thing. */\nexport const MAX_DIAGNOSTICS_LIMIT = 1000;\n\nconst SEVERITY_RANK: Record<Diagnostic['severity'], number> = {\n error: 0,\n warning: 1,\n info: 2,\n};\n\n/**\n * Collapse repeats of one defect into the first occurrence.\n *\n * Code and message together identify the defect; the path is what varies, so\n * the first one is kept as the place to look and the rest become a count. A\n * defect that occurred once is returned untouched — an `occurrences: 1` on\n * every diagnostic would be noise on the common case.\n */\nfunction deduplicate(diagnostics: readonly Diagnostic[]): Diagnostic[] {\n const byDefect = new Map<string, { entry: Diagnostic; count: number }>();\n for (const entry of diagnostics) {\n const key = `${entry.severity} ${entry.code} ${entry.message}`;\n const seen = byDefect.get(key);\n if (seen) seen.count += 1;\n else byDefect.set(key, { entry, count: 1 });\n }\n return [...byDefect.values()].map(({ entry, count }) =>\n count === 1\n ? entry\n : { ...entry, context: { ...entry.context, occurrences: count } }\n );\n}\n\n/**\n * Deduplicate, then cap without losing the fatal entries.\n *\n * A document with a hundred style warnings and one structural error would\n * otherwise report the warnings and drop the only thing that stops it\n * rendering. The sort is stable, so document order survives within each band.\n */\nexport function condenseDiagnostics(\n diagnostics: readonly Diagnostic[],\n limit: number = DEFAULT_MAX_DIAGNOSTICS\n): { kept: Diagnostic[]; truncated: boolean } {\n const unique = deduplicate(diagnostics);\n if (unique.length <= limit) return { kept: unique, truncated: false };\n const ordered = [...unique].sort(\n (a, b) => SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity]\n );\n return { kept: ordered.slice(0, limit), truncated: true };\n}\n\n/** The `maxDiagnostics` input property, spelled once for every tool that caps. */\nexport const maxDiagnosticsProperty = {\n type: 'integer' as const,\n minimum: 1,\n maximum: MAX_DIAGNOSTICS_LIMIT,\n description:\n `Cap on returned diagnostics (default ${DEFAULT_MAX_DIAGNOSTICS}). ` +\n 'Repeats of one defect collapse into the first, which then carries ' +\n '`context.occurrences`; errors are kept ahead of warnings when the cap ' +\n 'still bites.',\n};\n\n/** The `truncated` output property that goes with it. */\nexport const truncatedProperty = {\n type: 'boolean' as const,\n description: '`diagnostics` was capped by `maxDiagnostics`.',\n};\n","/**\n * Checks on the render OPTIONS, before any document is touched.\n *\n * `renderOptionProperties` is one bag shared by generate, preview and diff, so\n * a value one tool rejects and another forwards straight into the core is a\n * difference no agent can predict from the schema. Everything here answers in\n * the vocabulary `checkRenderer` already established — the defect is in the\n * request, not in the JSON — and lives beside it rather than inside\n * `lib/errors.ts`, which owns the vocabulary and not the option semantics.\n */\n\nimport { createRequire } from 'module';\nimport path from 'path';\nimport { pathToFileURL } from 'url';\n\nimport type { FormatAdapter, FormatName } from './adapters.js';\nimport {\n OPTION_ERROR_CODES,\n diagnostic,\n failure,\n type Diagnostic,\n type Failure,\n} from './errors.js';\n\n/**\n * A code this module adds. It belongs in `lib/errors.ts`' `OPTION_ERROR_CODES`\n * beside `E_UNKNOWN_RENDERER`, whose shape it deliberately mirrors; it is\n * declared here only because that file is another issue's to edit.\n */\nexport const UNKNOWN_THEME = 'W_UNKNOWN_THEME';\n\n/** Earliest instant a ZIP local-file header can express. */\nconst ZIP_EPOCH_YEAR = 1980;\n\n/**\n * Reject an unparseable date option.\n *\n * Both cores raise a plain `Error` over one, which `guarded` can only report as\n * `E_INTERNAL` — the code documented as \"always a bug here, never the\n * caller's\". It is the caller's, and it is a one-character repair, so it gets a\n * structured refusal naming the option instead of an internal stack trace.\n */\nexport function checkDateOption(\n option: string,\n value: string | undefined,\n omitHint: string\n): Failure | undefined {\n if (value === undefined) return undefined;\n if (!Number.isNaN(new Date(value).getTime())) return undefined;\n return failure(\n OPTION_ERROR_CODES.INVALID_DATE,\n `Invalid ${option} \"${value}\".`,\n {\n suggestion: `Use ISO 8601, e.g. \"2026-06-09T10:00:00Z\", or ${omitHint}`,\n context: { option, value },\n }\n );\n}\n\n/**\n * `generatedAt`: a date option, plus the ZIP floor.\n *\n * .docx and .pptx are ZIP containers whose entry timestamps start at 1980, and\n * both cores refuse an earlier instant for exactly that reason. Checking it\n * here keeps that refusal a repairable answer rather than an internal error\n * raised deep inside a packaging routine.\n */\nexport function checkGeneratedAt(\n value: string | undefined\n): Failure | undefined {\n const unparseable = checkDateOption(\n 'generatedAt',\n value,\n 'omit it to stamp the current time.'\n );\n if (unparseable !== undefined || value === undefined) return unparseable;\n\n if (new Date(value).getUTCFullYear() >= ZIP_EPOCH_YEAR) return undefined;\n return failure(\n OPTION_ERROR_CODES.INVALID_DATE,\n `generatedAt \"${value}\" is before 1980.`,\n {\n suggestion:\n 'Office files are ZIP containers, whose entry timestamps start at 1980-01-01; pick a later instant.',\n context: { option: 'generatedAt', value },\n }\n );\n}\n\nexport type ResolvedThemePath = { ok: true; path?: string } | Failure;\n\n/**\n * Keep the MCP surface data-only and make its relative-path rule explicit.\n *\n * `jto-ops` also serves the CLI, where executable JS theme modules remain a\n * deliberate power-user feature. An MCP caller is different: repository files\n * are untrusted input, so forwarding a module path into dynamic `import()`\n * would execute it with the server's privileges.\n */\nexport function resolveThemePathOption(\n themePath: string | undefined,\n baseDir: string | undefined\n): ResolvedThemePath {\n if (themePath === undefined) return { ok: true };\n if (path.extname(themePath) !== '.json') {\n return failure(\n OPTION_ERROR_CODES.INVALID_THEME_PATH,\n `themePath must name a data-only .json theme, not \"${themePath}\".`,\n {\n suggestion:\n 'Use a .json theme file. Executable JavaScript theme modules are not accepted over MCP.',\n context: { option: 'themePath', value: themePath },\n }\n );\n }\n const root = baseDir === undefined ? process.cwd() : path.resolve(baseDir);\n return { ok: true, path: path.resolve(root, themePath) };\n}\n\nconst CORE_THEMES: Record<FormatName, { specifier: string; exported: string }> =\n {\n docx: { specifier: '@json-to-office/core-docx', exported: 'themes' },\n pptx: { specifier: '@json-to-office/core-pptx', exported: 'pptxThemes' },\n };\n\n/**\n * A resolver rooted at `jto-ops`, which owns the cores: they are its dependency\n * and not ours, so a bare specifier resolves to nothing under pnpm's strict\n * layout. `jto_discover` and `jto_info` reach for their cores the same way.\n */\nlet coreResolver: NodeJS.Require | undefined;\ntry {\n const here = createRequire(import.meta.url);\n coreResolver = createRequire(\n here.resolve('@json-to-office/jto-ops/package.json')\n );\n} catch {\n /* jto-ops unresolvable: a theme diagnostic simply names no alternatives */\n}\n\n/**\n * Built-in theme names, so a diagnostic can list what would have worked.\n *\n * The adapter is the authority and is asked first. It answers `{}` from a\n * bundled ESM build, where its synchronous `require` of the core meets tsup's\n * throwing shim, so the core is imported directly as a fallback. `jto_discover`\n * carries the same fallback for the same reason; both collapse into one the day\n * jto-ops loads its themes asynchronously.\n */\nexport async function builtinThemeNames(\n adapter: FormatAdapter\n): Promise<string[]> {\n const fromAdapter = Object.keys(adapter.getBuiltinThemes());\n if (fromAdapter.length > 0) return fromAdapter.sort();\n if (!coreResolver) return [];\n\n const { specifier, exported } = CORE_THEMES[adapter.name];\n try {\n const core = (await import(\n pathToFileURL(coreResolver.resolve(specifier)).href\n )) as Record<string, Record<string, unknown> | undefined>;\n return Object.keys(core[exported] ?? {}).sort();\n } catch {\n return [];\n }\n}\n\n/**\n * The DOCX core's own `props.theme` warning, as it reaches a diagnostic.\n *\n * The core raises it as `theme_not_found`; `normalizeWarningCode` lifts it into\n * the published namespace before it gets here, so this matches the normalized\n * spelling rather than the core's.\n */\nconst CORE_THEME_NOT_FOUND = 'W_THEME_NOT_FOUND';\n\n/** `props.theme` of a document, when it names one. */\nfunction documentTheme(document: unknown): string | undefined {\n if (typeof document !== 'object' || document === null) return undefined;\n const props = (document as { props?: unknown }).props;\n if (typeof props !== 'object' || props === null) return undefined;\n const theme = (props as { theme?: unknown }).theme;\n return typeof theme === 'string' && theme.length > 0 ? theme : undefined;\n}\n\nfunction unknownTheme(\n format: FormatName,\n name: string,\n known: readonly string[],\n source: 'theme' | 'props.theme'\n): Diagnostic {\n const where =\n source === 'theme' ? '.' : \"; it came from the document's `props.theme`.\";\n // What actually happened differs by source, and an agent comparing two runs\n // will notice: an ignored `theme` leaves the document's own theme standing,\n // while an ignored `props.theme` leaves nothing but the built-in default.\n const fell =\n source === 'theme'\n ? \"This render kept the document's own theme.\"\n : 'This render used the built-in default.';\n const names = known.map((id) => `\"${id}\"`).join(', ');\n return diagnostic(\n UNKNOWN_THEME,\n `Unknown ${format} theme \"${name}\"${where}`,\n {\n severity: 'warning',\n suggestion:\n known.length > 0\n ? `Use one of: ${names}, or a path to a theme file. ${fell}`\n : `Use a name from jto_discover.formats[].themes, or a path to a theme file. ${fell}`,\n context: { format, theme: name, themes: [...known], source },\n }\n );\n}\n\n/**\n * Themes that were asked for and did not happen.\n *\n * `createGenerator` reports the theme it settled on, and both adapters leave\n * that undefined in exactly one case: a named theme that resolved to nothing —\n * no built-in of that name, no readable file, no inline JSON — after which the\n * render falls back without saying so. Reading their verdict rather than\n * re-deciding it here is what keeps a legitimate theme FILE from being reported\n * as a typo.\n *\n * `props.theme` is a separate question, and asked only when no option overrode\n * it: the DOCX core already reports an unresolvable one (as `W_THEME_NOT_FOUND`)\n * and the PPTX core does not, so a warning that is already present is never\n * repeated.\n */\nexport async function themeDiagnostics(\n adapter: FormatAdapter,\n input: {\n requested?: string;\n resolved?: string;\n document: unknown;\n reported: readonly Diagnostic[];\n }\n): Promise<Diagnostic[]> {\n if (input.resolved !== undefined) return [];\n\n if (input.requested !== undefined) {\n return [\n unknownTheme(\n adapter.name,\n input.requested,\n await builtinThemeNames(adapter),\n 'theme'\n ),\n ];\n }\n\n const inDocument = documentTheme(input.document);\n if (inDocument === undefined) return [];\n if (input.reported.some((entry) => entry.code === CORE_THEME_NOT_FOUND)) {\n return [];\n }\n const known = await builtinThemeNames(adapter);\n if (known.length === 0 || known.includes(inDocument)) return [];\n return [unknownTheme(adapter.name, inDocument, known, 'props.theme')];\n}\n","/**\n * `jto_generate` — document JSON in, a real .docx or .pptx out.\n *\n * The file is a build product: the same JSON, renderer, theme, fonts and\n * options always produce it again, which is why the artifact comes back as a\n * path under the server's output root by default rather than as bytes an agent\n * has to carry around in its context.\n *\n * Everything the render learned on the way — an unresolvable font, a theme\n * name that matched nothing — arrives as warning-severity diagnostics in the\n * same envelope as a validation failure, so a caller has exactly one place to\n * look whether generation refused or merely compromised.\n */\n\nimport type { McpServer, ServerContext } from '@modelcontextprotocol/server';\nimport type { GenerationWarning } from '@json-to-office/shared';\n\nimport {\n checkRenderer,\n type FormatName,\n type GeneratorOptions,\n} from '../lib/adapters.js';\nimport { MIME_TYPES, deliverArtifact } from '../lib/artifacts.js';\nimport type { ToolDeps } from '../lib/deps.js';\nimport {\n condenseDiagnostics,\n maxDiagnosticsProperty,\n truncatedProperty,\n} from '../lib/diagnostic-budget.js';\nimport { resolveDocumentSource, sourceSummary } from '../lib/doc-source.js';\nimport {\n ERROR_CODES,\n diagnostic,\n diagnosticsFromThrown,\n failure,\n guarded,\n normalizeWarningCode,\n toolResult,\n type Diagnostic,\n} from '../lib/errors.js';\nimport {\n checkGeneratedAt,\n resolveThemePathOption,\n themeDiagnostics,\n} from '../lib/render-options.js';\nimport {\n S,\n artifactOutputProperties,\n artifactSchema,\n documentSourceProperties,\n formatSchema,\n outputSchema,\n renderOptionProperties,\n sourceSummarySchema,\n type ArtifactOutputInput,\n type DocumentSourceInput,\n type RenderOptionsInput,\n} from '../lib/schema.js';\n\n/** Steps reported through the progress token, when the client sent one. */\nconst PROGRESS_TOTAL = 3;\n\n/**\n * Emit progress, or don't.\n *\n * Only when the client actually asked for it — an unsolicited progress\n * notification is protocol noise — and never fatally: a client that cannot\n * take the notification must still get its document.\n */\nasync function reportProgress(\n ctx: ServerContext,\n progress: number,\n message: string\n): Promise<void> {\n const progressToken = ctx.mcpReq._meta?.progressToken;\n if (progressToken === undefined) return;\n try {\n await ctx.mcpReq.notify({\n method: 'notifications/progress',\n params: { progressToken, progress, total: PROGRESS_TOTAL, message },\n });\n } catch {\n /* progress is advisory; losing it must not lose the generation */\n }\n}\n\nfunction cancelled(format: FormatName): Diagnostic[] {\n return [\n diagnostic(\n ERROR_CODES.CANCELLED,\n `Generation of the ${format} document was cancelled by the client.`,\n { context: { format } }\n ),\n ];\n}\n\n/**\n * A generation warning, as a diagnostic.\n *\n * The cores carry their own stable code inside `context.code`\n * (FONT_UNRESOLVED and friends). It reaches `code` through\n * `normalizeWarningCode`, which prefixes it into the published `W_` namespace\n * rather than passing it through bare: the prefix is what tells an agent the\n * diagnostic does not block, and these are precisely the diagnostics it may\n * always continue past. `context.code` keeps the core's own spelling, so a\n * caller matching this against what the CLI prints still has it. The component\n * rides along because these carry no path.\n */\nfunction warningDiagnostic(warning: GenerationWarning): Diagnostic {\n const code = normalizeWarningCode(\n typeof warning.context?.code === 'string' ? warning.context.code : undefined\n );\n return diagnostic(code, warning.message, {\n severity: warning.severity === 'info' ? 'info' : 'warning',\n context: { component: warning.component, ...warning.context },\n });\n}\n\ninterface FontOptionsInput {\n strict?: boolean;\n mode?: 'substitute' | 'custom';\n substitution?: Record<string, string>;\n baseDir?: string;\n googleFonts?: {\n enabled?: boolean;\n fetchTimeoutMs?: number;\n };\n}\n\ninterface GenerateArgs\n extends DocumentSourceInput,\n RenderOptionsInput,\n ArtifactOutputInput {\n format: FormatName;\n fonts?: FontOptionsInput;\n validation?: { allowUnknownFields?: boolean };\n maxDiagnostics?: number;\n}\n\n/**\n * Apply the caller's diagnostic budget to whatever the body returned.\n *\n * Every exit — a refused option, a rejected document, a success carrying\n * warnings — answers with the same `diagnostics` array, so the cap belongs at\n * the one place they all pass through rather than repeated at each `return`.\n */\nfunction withDiagnosticBudget<T extends { diagnostics: Diagnostic[] }>(\n payload: T,\n limit: number | undefined\n): T & { truncated: boolean } {\n const { kept, truncated } = condenseDiagnostics(payload.diagnostics, limit);\n return { ...payload, diagnostics: kept, truncated };\n}\n\nconst fontsSchema = {\n type: 'object' as const,\n description: 'Font resolution for this render.',\n properties: {\n strict: {\n type: 'boolean' as const,\n description: 'Promote unresolved-font warnings to a generation failure.',\n },\n mode: {\n type: 'string' as const,\n enum: ['custom', 'substitute'],\n description:\n '`custom` (default) keeps font references as written; `substitute` rewrites every non-safe family to a widely installed equivalent so the file renders identically everywhere.',\n },\n substitution: {\n type: 'object' as const,\n description:\n 'Family-name replacements applied when `mode` is `substitute`. Unlisted families fall back to a category-based default.',\n additionalProperties: { type: 'string' as const },\n },\n baseDir: {\n type: 'string' as const,\n description: 'Directory that font file paths resolve against.',\n },\n googleFonts: {\n type: 'object' as const,\n properties: {\n enabled: {\n type: 'boolean' as const,\n description: 'Set false to forbid network font fetches.',\n },\n fetchTimeoutMs: { type: 'integer' as const, minimum: 1 },\n },\n additionalProperties: false,\n },\n },\n additionalProperties: false,\n};\n\nexport function register(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'jto_generate',\n {\n title: 'Generate a document',\n description:\n 'Render a document to a real .docx or .pptx. The file is written under the server output root and returned as a path; pass `outputMode: \"base64\"` only for small artifacts. A document that fails the generation gate comes back with `ok: false` and the same path-addressed diagnostics jto_validate reports, never as an error. Warnings the render emitted (unresolved fonts, a `theme` or `props.theme` naming nothing) arrive as warning-severity diagnostics alongside a successful artifact. The DOCX `highcharts` component draws through a Highcharts export server that must be running on the host (see jto_info.previewDependencies.highchartsExportServer); the `visual` component needs no such service.',\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n openWorldHint: true,\n },\n inputSchema: S<GenerateArgs>({\n type: 'object',\n properties: {\n format: formatSchema,\n ...documentSourceProperties,\n ...renderOptionProperties,\n ...artifactOutputProperties,\n fonts: fontsSchema,\n validation: {\n type: 'object',\n description: 'Overrides for the pre-render validation gate.',\n properties: {\n allowUnknownFields: {\n type: 'boolean',\n description:\n 'Tolerate properties the schema does not know instead of refusing to render.',\n },\n },\n additionalProperties: false,\n },\n maxDiagnostics: maxDiagnosticsProperty,\n },\n required: ['format'],\n additionalProperties: false,\n }),\n outputSchema: S(\n outputSchema({\n format: formatSchema,\n renderer: {\n type: 'string',\n description: 'The renderer that produced the file, when requested.',\n },\n theme: {\n type: 'string',\n description:\n \"Theme forced on the document, when one was requested. Absent when each document's own `props.theme` decided — and also when the name matched nothing, which comes back as a W_UNKNOWN_THEME diagnostic.\",\n },\n artifact: artifactSchema,\n source: sourceSummarySchema,\n truncated: truncatedProperty,\n })\n ),\n },\n async (args, ctx) =>\n toolResult(\n withDiagnosticBudget(\n await guarded(async () => {\n const adapter = deps.getAdapter(args.format);\n const base = { format: args.format };\n\n if (ctx.mcpReq.signal.aborted) {\n return {\n ok: false,\n diagnostics: cancelled(args.format),\n ...base,\n };\n }\n\n const rendererError = await checkRenderer(adapter, args.renderer);\n if (rendererError) return { ...rendererError, ...base };\n\n const dateError = checkGeneratedAt(args.generatedAt);\n if (dateError) return { ...dateError, ...base };\n\n const themePath = resolveThemePathOption(\n args.themePath,\n args.baseDir\n );\n if (!themePath.ok) return { ...themePath, ...base };\n\n await reportProgress(ctx, 0, 'Resolving document');\n const resolved = await resolveDocumentSource(\n args,\n deps.workspaces()\n );\n if (!resolved.ok) return { ...resolved, ...base };\n const source = sourceSummary(resolved);\n\n // One array per request: the adapters PUSH into this sink and never\n // replace it, so a shared array would report a previous document's\n // font problems against this one.\n const warnings: GenerationWarning[] = [];\n const options: GeneratorOptions = {\n ...(args.renderer !== undefined && { renderer: args.renderer }),\n ...(args.theme !== undefined && { theme: args.theme }),\n ...(themePath.path !== undefined && {\n themePath: themePath.path,\n }),\n ...(args.deterministic !== undefined && {\n deterministic: args.deterministic,\n }),\n ...(args.generatedAt !== undefined && {\n generatedAt: args.generatedAt,\n }),\n ...(args.baseDir !== undefined && { baseDir: args.baseDir }),\n ...(args.fonts !== undefined && { fonts: args.fonts }),\n ...(args.validation !== undefined && {\n validation: args.validation,\n }),\n warnings,\n };\n\n await reportProgress(ctx, 1, `Rendering the ${adapter.label}`);\n let buffer: Buffer;\n let themeLabel: string | undefined;\n try {\n // `createGenerator` rather than `generateBuffer`: it resolves the\n // theme once and reports what it settled on, which is the only way\n // to tell the caller which theme actually rendered.\n const generator = await adapter.createGenerator([], options);\n themeLabel = generator.themeLabel;\n buffer = await generator.generateBuffer(resolved.document);\n } catch (error) {\n const diagnostics = diagnosticsFromThrown(error);\n // Not a rejected document: let `guarded` call it what it is.\n if (!diagnostics) throw error;\n return {\n ok: false,\n diagnostics: [\n ...diagnostics,\n ...warnings.map(warningDiagnostic),\n ],\n ...base,\n source,\n };\n }\n\n // Checked before the write, not after: a cancelled request should\n // not leave a file behind for nobody.\n if (ctx.mcpReq.signal.aborted) {\n return {\n ok: false,\n diagnostics: cancelled(args.format),\n ...base,\n source,\n };\n }\n\n await reportProgress(ctx, 2, 'Delivering the artifact');\n\n // The theme is settled by now, so a name that matched nothing can\n // finally be reported. Without this the render silently falls back\n // and returns a file byte-identical to one the caller never asked\n // for — the description promises the opposite.\n const rendered = warnings.map(warningDiagnostic);\n const themeIssues = await themeDiagnostics(adapter, {\n ...(args.theme !== undefined && { requested: args.theme }),\n ...(themeLabel !== undefined && { resolved: themeLabel }),\n document: resolved.document,\n reported: rendered,\n });\n const collected = [...rendered, ...themeIssues];\n\n const mimeType = MIME_TYPES[adapter.extension];\n if (mimeType === undefined) {\n return {\n ...failure(\n ERROR_CODES.INTERNAL,\n `No MIME type registered for \"${adapter.extension}\".`\n ),\n ...base,\n };\n }\n const delivered = await deliverArtifact(buffer, {\n filename: args.filename ?? `${adapter.label}${adapter.extension}`,\n mimeType,\n ...(args.outputMode !== undefined && { mode: args.outputMode }),\n outputRoot: deps.outputRoot,\n maxInlineBytes: deps.maxInlineArtifactBytes,\n });\n if (!delivered.ok) {\n return {\n ...delivered,\n diagnostics: [...delivered.diagnostics, ...collected],\n ...base,\n source,\n };\n }\n\n await reportProgress(ctx, PROGRESS_TOTAL, 'Done');\n return {\n ok: true,\n diagnostics: collected,\n ...base,\n ...(args.renderer !== undefined && { renderer: args.renderer }),\n ...(themeLabel !== undefined && { theme: themeLabel }),\n artifact: delivered.artifact,\n source,\n };\n }),\n args.maxDiagnostics\n )\n )\n );\n}\n","/**\n * The one directory this server is allowed to write to.\n *\n * #204's contract is \"no writes outside the root\", and the caller names the\n * file. Anything a caller can name, a caller can point somewhere else — so the\n * check has to survive `..`, absolute paths, Windows drive letters and, once\n * the root is a real directory on disk, symlinks planted inside it. Every\n * write therefore goes through `resolveOutputPath`, which answers a path only\n * when it provably lands inside the root.\n */\n\nimport * as fs from 'fs/promises';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { randomBytes } from 'crypto';\n\nimport { ERROR_CODES, failure, type Failure } from './errors.js';\n\n/** Env var that names the output root, below the `--output-dir` flag. */\nexport const OUTPUT_DIR_ENV = 'JTO_MCP_OUTPUT_DIR';\n\n/** Prefix for the per-connection temp root, when nothing else was configured. */\nconst TEMP_PREFIX = 'jto-mcp-';\n\nexport interface OutputRoot {\n /** Absolute path of the root. May not exist on disk until first use. */\n readonly path: string;\n /**\n * True when this root is a temp directory this process invented, and so is\n * safe to delete on shutdown. A configured root is never removed.\n */\n readonly ephemeral: boolean;\n /** Create the root if absent; returns its real (symlink-resolved) path. */\n ensure(): Promise<string>;\n /**\n * Absolute path for `name` inside the root, with parent directories created.\n * Fails structurally rather than throwing — the result is a tool result.\n */\n resolveOutputPath(name: string): Promise<ResolvedOutputPath>;\n /** Remove the root, but only when `ephemeral`. */\n dispose(): Promise<void>;\n}\n\nexport type ResolvedOutputPath =\n | { ok: true; path: string; relative: string }\n | Failure;\n\nexport interface OutputRootOptions {\n /** `--output-dir` value, highest precedence. */\n flagDir?: string;\n /** Defaults to `process.env`; injectable so the precedence is testable. */\n env?: NodeJS.ProcessEnv;\n /** Defaults to `os.tmpdir()`; injectable for the same reason. */\n tmpDir?: string;\n}\n\n/**\n * Reject a name before it ever touches the filesystem.\n *\n * Cheap, synchronous and exhaustive about the shapes that cannot possibly be\n * inside the root, so the expensive realpath check below only ever has to\n * worry about symlinks.\n */\nexport function checkOutputName(name: string): Failure | undefined {\n if (typeof name !== 'string' || name.trim() === '') {\n return failure(\n ERROR_CODES.OUTPUT_ROOT_ESCAPE,\n 'Output file name must be a non-empty string.'\n );\n }\n if (name.includes('\\0')) {\n return failure(\n ERROR_CODES.OUTPUT_ROOT_ESCAPE,\n 'Output file name must not contain NUL.'\n );\n }\n if (path.isAbsolute(name) || path.win32.isAbsolute(name)) {\n return failure(\n ERROR_CODES.OUTPUT_ROOT_ESCAPE,\n `Output file name must be relative to the output root: \"${name}\".`,\n { suggestion: 'Pass a bare file name, e.g. \"report.docx\".' }\n );\n }\n // A bare drive-relative path (\"C:report.docx\") is neither absolute nor\n // rooted, and resolves against that drive's CWD on Windows.\n if (/^[A-Za-z]:/.test(name)) {\n return failure(\n ERROR_CODES.OUTPUT_ROOT_ESCAPE,\n `Output file name must not carry a drive letter: \"${name}\".`\n );\n }\n const segments = name.split(/[/\\\\]/);\n if (segments.some((segment) => segment === '..')) {\n return failure(\n ERROR_CODES.OUTPUT_ROOT_ESCAPE,\n `Output file name must not traverse upwards: \"${name}\".`,\n { suggestion: 'Remove the \"..\" segments.' }\n );\n }\n return undefined;\n}\n\n/** True when `candidate` is `root` itself or lives beneath it. */\nfunction isInside(root: string, candidate: string): boolean {\n const relative = path.relative(root, candidate);\n return (\n relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative)\n );\n}\n\n/**\n * Create the parent chain of a candidate path, one segment at a time, and\n * answer with the real path of the deepest one.\n *\n * `mkdir -p` over the whole chain is the wrong primitive here: it follows a\n * directory symlink already planted in the root and creates the missing\n * segments on the far side of it. Checking afterwards still refuses the write,\n * but by then the server has made directories at a caller-chosen location\n * outside the root — a side effect a refusal is not supposed to have. So each\n * segment is resolved and checked before the next one is created, and the walk\n * stops at the link rather than building through it.\n *\n * `root` is already a real path, so the walk starts on solid ground and only\n * has to worry about what it finds below.\n */\nasync function ensureParentInside(\n root: string,\n parentDir: string\n): Promise<{ ok: true; path: string } | Failure> {\n let current = root;\n const segments = path\n .relative(root, parentDir)\n .split(path.sep)\n .filter((segment) => segment !== '');\n\n for (const segment of segments) {\n const next = path.join(current, segment);\n try {\n await fs.mkdir(next);\n } catch (error) {\n // Anything but \"already there\" is a real filesystem problem — a\n // read-only root, a file where a directory belongs — and belongs to the\n // caller, not to this check.\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;\n }\n // Re-resolved even when we just created it: between the mkdir and here,\n // another process could have swapped the directory for a link.\n const real = await fs.realpath(next);\n if (!isInside(root, real)) {\n return failure(\n ERROR_CODES.OUTPUT_ROOT_ESCAPE,\n `Output path leaves the output root through a symlinked directory: \"${segment}\".`,\n { context: { outputRoot: root, resolved: real } }\n );\n }\n current = real;\n }\n\n return { ok: true, path: current };\n}\n\n/**\n * Real path of `target` when it already exists, `target` itself when it does\n * not.\n *\n * The overwrite case is the interesting one: an existing artifact path may be\n * a symlink, and a link that stays inside the root is a legitimate place to\n * write — reported as the file actually written, not as the link.\n */\nasync function realpathIfPresent(target: string): Promise<string> {\n try {\n return await fs.realpath(target);\n } catch {\n return target;\n }\n}\n\n/**\n * Resolve the root: `--output-dir`, then `JTO_MCP_OUTPUT_DIR`, then a temp\n * directory of our own.\n *\n * Creation is deferred — a connection that never generates anything should not\n * leave a directory behind — so the temp root's name is decided here but the\n * `mkdir` happens on first use.\n */\nexport function createOutputRoot(options: OutputRootOptions = {}): OutputRoot {\n const env = options.env ?? process.env;\n const configured = options.flagDir?.trim() || env[OUTPUT_DIR_ENV]?.trim();\n const ephemeral = !configured;\n const rootPath = configured\n ? path.resolve(configured)\n : path.join(\n options.tmpDir ?? os.tmpdir(),\n `${TEMP_PREFIX}${process.pid}-${randomBytes(12).toString('hex')}`\n );\n\n let realRoot: string | undefined;\n let ensurePromise: Promise<string> | undefined;\n\n async function ensure(): Promise<string> {\n if (realRoot !== undefined) return realRoot;\n if (ensurePromise === undefined) {\n ensurePromise = (async () => {\n if (ephemeral) {\n // Exclusive creation means a planted path is a refusal, never a\n // directory (or symlink) this connection silently adopts. The\n // random name makes collision negligible; 0o700 keeps generated\n // documents private on shared system temp directories.\n await fs.mkdir(rootPath, { mode: 0o700 });\n } else {\n await fs.mkdir(rootPath, { recursive: true });\n }\n realRoot = await fs.realpath(rootPath);\n return realRoot;\n })();\n }\n try {\n return await ensurePromise;\n } catch (error) {\n ensurePromise = undefined;\n throw error;\n }\n }\n\n return {\n path: rootPath,\n ephemeral,\n ensure,\n\n async resolveOutputPath(name: string): Promise<ResolvedOutputPath> {\n const rejected = checkOutputName(name);\n if (rejected) return rejected;\n\n const root = await ensure();\n const candidate = path.resolve(root, name);\n if (!isInside(root, candidate)) {\n return failure(\n ERROR_CODES.OUTPUT_ROOT_ESCAPE,\n `Output path escapes the output root: \"${name}\".`,\n { context: { outputRoot: root } }\n );\n }\n\n // The textual check above cannot see symlinks, so the parent chain is\n // built and verified segment by segment before anything is written. The\n // leaf gets resolved too — a link named exactly as the artifact is\n // invisible to a parent-only check, and `writeFile` follows it just as\n // happily as a linked directory.\n const parent = await ensureParentInside(root, path.dirname(candidate));\n if (!parent.ok) return parent;\n const realCandidate = await realpathIfPresent(\n path.join(parent.path, path.basename(candidate))\n );\n if (!isInside(root, realCandidate)) {\n return failure(\n ERROR_CODES.OUTPUT_ROOT_ESCAPE,\n `Output path resolves outside the output root through a symlink: \"${name}\".`,\n { context: { outputRoot: root, resolved: realCandidate } }\n );\n }\n\n return {\n ok: true,\n path: realCandidate,\n relative: path.relative(root, realCandidate),\n };\n },\n\n async dispose(): Promise<void> {\n if (!ephemeral || realRoot === undefined) return;\n await fs.rm(realRoot, { recursive: true, force: true });\n realRoot = undefined;\n ensurePromise = undefined;\n },\n };\n}\n","/**\n * Diagnostic codes only `jto_preview` can raise.\n *\n * They live beside the tool rather than in `lib/errors.ts` because they\n * describe this pipeline's vocabulary — a page selection, an inline budget, a\n * LibreOffice stage — and nothing else in the server can produce them. The\n * shared codes (`E_DEPENDENCY_MISSING`, `E_CANCELLED`, `E_INTERNAL`) still come\n * from `ERROR_CODES`; these extend that set rather than fork it.\n *\n * Same contract as `ERROR_CODES`: agents branch on them, so add freely, rename\n * never.\n */\nexport const PREVIEW_ERROR_CODES = {\n /** `pages` is malformed, or selects pages the document does not have. */\n INVALID_PAGE_SPEC: 'E_INVALID_PAGE_SPEC',\n /** Inline images were demanded for a payload over the client-safe budget. */\n TOO_LARGE: 'E_PREVIEW_TOO_LARGE',\n /** A render stage (build, convert, rasterize) failed on this document. */\n RENDER_FAILED: 'E_PREVIEW_RENDER_FAILED',\n /** The PDF produced no readable page count — nothing to select from. */\n PAGE_COUNT_UNAVAILABLE: 'E_PREVIEW_PAGE_COUNT_UNAVAILABLE',\n} as const;\n\nexport type PreviewErrorCode =\n (typeof PREVIEW_ERROR_CODES)[keyof typeof PREVIEW_ERROR_CODES];\n\n/** Where a preview run failed, reported alongside `E_PREVIEW_RENDER_FAILED`. */\nexport type PreviewStage = 'build' | 'convert' | 'rasterize';\n","/**\n * Page selection: the printer-range syntax, parsed and validated.\n *\n * One spelling, not two. An array (`[1,3]`) and a string (`\"1-3\"`) would each\n * need their own schema branch, their own validation and their own failure\n * messages, and an agent reading `tools/list` would have to guess which the\n * server prefers. The string wins because it is the notation every print\n * dialog on earth already uses, it survives a JSON Schema `pattern`, and it\n * expresses \"from page 4 to the end\" without knowing the page count.\n *\n * Grammar (1-based, inclusive, whitespace ignored):\n *\n * spec := \"all\" | item (\",\" item)*\n * item := N | A \"-\" B | A \"-\" | \"-\" B\n *\n * `\"all\"` is `\"1-\"`. Duplicates and overlaps are collapsed; the result is\n * always ascending, which is also what makes the cache key stable — `\"1,2,3\"`,\n * `\"3,2,1\"` and `\"1-3\"` are one selection and must not be three cache misses.\n */\n\nimport { failure, type Diagnostic, type Failure } from '../lib/errors.js';\nimport { diagnostic } from '../lib/errors.js';\nimport { PREVIEW_ERROR_CODES } from './codes.js';\n\n/** Selects every page. */\nexport const ALL_PAGES = 'all';\n\n/** JSON Schema `pattern` for the syntax above, so bad input fails at the edge. */\nexport const PAGE_SPEC_PATTERN =\n '^\\\\s*(all|(\\\\d+|\\\\d+\\\\s*-\\\\s*\\\\d*|-\\\\s*\\\\d+)(\\\\s*,\\\\s*(\\\\d+|\\\\d+\\\\s*-\\\\s*\\\\d*|-\\\\s*\\\\d+))*)\\\\s*$';\n\n/** One item of a parsed spec. `to === null` means \"to the last page\". */\nexport interface PageRange {\n from: number;\n to: number | null;\n}\n\nexport type ParsedPageSpec = { ok: true; ranges: PageRange[] } | Failure;\n\nfunction badSpec(message: string, suggestion?: string): Failure {\n return failure(PREVIEW_ERROR_CODES.INVALID_PAGE_SPEC, message, {\n suggestion:\n suggestion ??\n 'Use \"all\", a page number, a range, or a comma-separated mix: \"all\", \"3\", \"2-5\", \"4-\", \"-3\", \"1-3,7\".',\n context: { syntax: 'all | N | A-B | A- | -B, comma separated, 1-based' },\n });\n}\n\n/**\n * Parse a spec without knowing how long the document is.\n *\n * Split from resolution deliberately: syntax is the agent's mistake and can be\n * reported before a single LibreOffice process starts, while \"page 9 of 3\"\n * cannot be known until the PDF exists.\n */\nexport function parsePageSpec(spec: string): ParsedPageSpec {\n const trimmed = spec.trim();\n if (trimmed === '') return badSpec('Page selection is empty.');\n if (trimmed.toLowerCase() === ALL_PAGES) {\n return { ok: true, ranges: [{ from: 1, to: null }] };\n }\n\n const ranges: PageRange[] = [];\n for (const rawItem of trimmed.split(',')) {\n const item = rawItem.trim();\n if (item === '') {\n return badSpec(`Empty item in page selection \"${spec}\".`);\n }\n\n const single = /^(\\d+)$/.exec(item);\n if (single) {\n const page = Number(single[1]);\n if (page < 1) return badSpec('Pages are numbered from 1.');\n ranges.push({ from: page, to: page });\n continue;\n }\n\n const range = /^(\\d*)\\s*-\\s*(\\d*)$/.exec(item);\n if (!range || (range[1] === '' && range[2] === '')) {\n return badSpec(`Unrecognized item \"${item}\" in page selection.`);\n }\n const from = range[1] === '' ? 1 : Number(range[1]);\n const to = range[2] === '' ? null : Number(range[2]);\n if (from < 1 || (to !== null && to < 1)) {\n return badSpec('Pages are numbered from 1.');\n }\n if (to !== null && to < from) {\n return badSpec(\n `Range \"${item}\" runs backwards; write it as \"${to}-${from}\".`\n );\n }\n ranges.push({ from, to });\n }\n\n return { ok: true, ranges };\n}\n\nexport type ResolvedPages =\n | { ok: true; pages: number[]; diagnostics: Diagnostic[] }\n | Failure;\n\n/**\n * Turn parsed ranges into concrete page numbers against a real page count.\n *\n * Open ends clamp silently — `\"4-\"` means \"the rest\", and the caller cannot\n * know where that is. A closed range that overshoots clamps too, but says so,\n * because `\"1-20\"` on a 3-page document usually means the agent expected 20\n * pages. A selection that starts past the end is refused outright: there is\n * nothing to render and silently returning zero pages would read as success.\n */\nexport function resolvePages(\n ranges: readonly PageRange[],\n totalPages: number,\n maxPages: number\n): ResolvedPages {\n if (totalPages < 1) {\n return failure(\n PREVIEW_ERROR_CODES.PAGE_COUNT_UNAVAILABLE,\n 'The rendered document has no pages.'\n );\n }\n\n const diagnostics: Diagnostic[] = [];\n const selected = new Set<number>();\n\n for (const range of ranges) {\n if (range.from > totalPages) {\n return failure(\n PREVIEW_ERROR_CODES.INVALID_PAGE_SPEC,\n `Page ${range.from} was requested but the document has ${totalPages} page${\n totalPages === 1 ? '' : 's'\n }.`,\n {\n suggestion: `Select within 1-${totalPages}, or pass \"all\".`,\n context: { totalPages, requestedFrom: range.from },\n }\n );\n }\n const last =\n range.to === null ? totalPages : Math.min(range.to, totalPages);\n if (range.to !== null && range.to > totalPages) {\n diagnostics.push(\n diagnostic(\n PREVIEW_ERROR_CODES.INVALID_PAGE_SPEC,\n `Range ${range.from}-${range.to} was clamped to ${range.from}-${totalPages}: the document has ${totalPages} pages.`,\n { severity: 'info', context: { totalPages } }\n )\n );\n }\n for (let page = range.from; page <= last; page += 1) selected.add(page);\n }\n\n const pages = [...selected].sort((a, b) => a - b);\n if (pages.length > maxPages) {\n return failure(\n PREVIEW_ERROR_CODES.INVALID_PAGE_SPEC,\n `${pages.length} pages were selected; jto_preview renders at most ${maxPages} per call.`,\n {\n suggestion: `Narrow the selection, e.g. \"1-${maxPages}\", and call again for the rest.`,\n context: { selected: pages.length, maxPages, totalPages },\n }\n );\n }\n\n return { ok: true, pages, diagnostics };\n}\n\n/**\n * Canonical spelling of a spec that has not met a page count yet.\n *\n * Sorted, with overlapping and adjacent ranges merged, so `\"1,2,3\"`, `\"3,2,1\"`\n * and `\"1-3\"` all come out `\"1-3\"` — which is what lets the cache key treat\n * three spellings of one request as one request. An open end swallows\n * everything after it, because it already covers every page there could be.\n */\nexport function canonicalRangeSpec(ranges: readonly PageRange[]): string {\n const sorted = [...ranges].sort((a, b) => a.from - b.from);\n const merged: PageRange[] = [];\n\n for (const range of sorted) {\n const last = merged[merged.length - 1];\n if (!last) {\n merged.push({ ...range });\n continue;\n }\n if (last.to === null) break; // Open-ended: nothing after it adds anything.\n if (range.from > last.to + 1) {\n merged.push({ ...range });\n continue;\n }\n last.to = range.to === null ? null : Math.max(last.to, range.to);\n }\n\n return merged\n .map((range) =>\n range.to === null\n ? `${range.from}-`\n : range.to === range.from\n ? `${range.from}`\n : `${range.from}-${range.to}`\n )\n .join(',');\n}\n\n/**\n * Canonical spelling of a resolved selection: `[1,2,3,7]` → `\"1-3,7\"`.\n *\n * This is what joins the cache key, so every spelling of one selection lands\n * on one entry.\n */\nexport function formatPageSelection(pages: readonly number[]): string {\n if (pages.length === 0) return '';\n const sorted = [...new Set(pages)].sort((a, b) => a - b);\n const parts: string[] = [];\n let start = sorted[0];\n let previous = sorted[0];\n\n const flush = () => {\n parts.push(start === previous ? `${start}` : `${start}-${previous}`);\n };\n\n for (const page of sorted.slice(1)) {\n if (page === previous + 1) {\n previous = page;\n continue;\n }\n flush();\n start = page;\n previous = page;\n }\n flush();\n return parts.join(',');\n}\n","/**\n * The size policy, stated as numbers rather than as judgement.\n *\n * A preview exists to be looked at, and \"looked at\" for an agent means the\n * bytes enter a model context. Forty pages at 300 DPI is roughly forty\n * megabytes of PNG and several times that as base64 — a response no client\n * should be asked to hold and no context window can absorb. So the ceiling is\n * declared here, checked twice, and reported in the refusal.\n *\n * Checked twice because each check catches what the other cannot. The estimate\n * runs BEFORE any LibreOffice process starts, so an obviously oversized\n * request is refused in milliseconds instead of after a minute of rendering.\n * The measurement runs after, because a page of dense photography is nothing\n * like a page of body text and only the real bytes settle it.\n */\n\n/** Rendering resolution when the caller does not say. A4 at 150 DPI is ~1754px tall — legible without being wasteful. */\nexport const PREVIEW_DEFAULT_DPI = 150;\n/** Below this, glyphs stop being readable and the preview answers nothing. */\nexport const PREVIEW_MIN_DPI = 36;\n/** Above this the extra pixels buy detail no preview needs; generate the file instead. */\nexport const PREVIEW_MAX_DPI = 600;\n\n/** Hard cap on pages per call, whatever the output mode. Preview is a look, not an export. */\nexport const MAX_PREVIEW_PAGES = 50;\n\n/** Most image blocks one result may carry, regardless of how small they are. */\nexport const MAX_INLINE_IMAGE_PAGES = 10;\n/** Ceiling for a single inlined page. */\nexport const MAX_INLINE_IMAGE_BYTES = 2 * 1024 * 1024;\n/** Ceiling for every inlined page in one result, summed. */\nexport const MAX_TOTAL_INLINE_BYTES = 8 * 1024 * 1024;\n\n/** A4 (8.27in x 11.69in). A 16:9 slide is 100in², close enough for an estimate. */\nexport const PREVIEW_PAGE_AREA_IN2 = 96.7;\n/**\n * Bytes per pixel used by the pre-flight estimate.\n *\n * Measured PNG density for a text page runs ~0.045 B/px at 300 DPI and ~0.12\n * at 96; an image-heavy page runs several times higher. The constant sits at\n * the pessimistic end on purpose — over-estimating costs a caller a fallback\n * to paths, under-estimating costs them a response their client cannot hold.\n */\nexport const ESTIMATED_PNG_BYTES_PER_PIXEL = 0.12;\n\n/** How the caller wants pages delivered. */\nexport type PreviewOutputMode = 'auto' | 'images' | 'path';\n\n/** Which ceiling a payload broke. */\nexport type BudgetOverrun = 'pageCount' | 'imageBytes' | 'totalBytes';\n\nexport interface InlineBudget {\n fits: boolean;\n /** Estimated (pre-render) or measured (post-render) total. */\n bytes: number;\n estimated: boolean;\n pageCount: number;\n exceeded: BudgetOverrun[];\n limits: {\n maxInlineImagePages: number;\n maxInlineImageBytes: number;\n maxTotalInlineBytes: number;\n };\n}\n\nconst LIMITS = {\n maxInlineImagePages: MAX_INLINE_IMAGE_PAGES,\n maxInlineImageBytes: MAX_INLINE_IMAGE_BYTES,\n maxTotalInlineBytes: MAX_TOTAL_INLINE_BYTES,\n} as const;\n\n/** Bytes one rendered page is expected to weigh at `dpi`. */\nexport function estimatePageBytes(dpi: number): number {\n return Math.round(\n PREVIEW_PAGE_AREA_IN2 * dpi * dpi * ESTIMATED_PNG_BYTES_PER_PIXEL\n );\n}\n\n/** Pre-flight verdict, from page count and DPI alone. */\nexport function estimatedInlineBudget(\n pageCount: number,\n dpi: number\n): InlineBudget {\n const perPage = estimatePageBytes(dpi);\n const bytes = perPage * pageCount;\n const exceeded: BudgetOverrun[] = [];\n if (pageCount > MAX_INLINE_IMAGE_PAGES) exceeded.push('pageCount');\n if (perPage > MAX_INLINE_IMAGE_BYTES) exceeded.push('imageBytes');\n if (bytes > MAX_TOTAL_INLINE_BYTES) exceeded.push('totalBytes');\n return {\n fits: exceeded.length === 0,\n bytes,\n estimated: true,\n pageCount,\n exceeded,\n limits: { ...LIMITS },\n };\n}\n\n/** Post-render verdict, from the PNGs actually produced. */\nexport function measuredInlineBudget(\n pageBytes: readonly number[]\n): InlineBudget {\n const bytes = pageBytes.reduce((total, size) => total + size, 0);\n const exceeded: BudgetOverrun[] = [];\n if (pageBytes.length > MAX_INLINE_IMAGE_PAGES) exceeded.push('pageCount');\n if (pageBytes.some((size) => size > MAX_INLINE_IMAGE_BYTES)) {\n exceeded.push('imageBytes');\n }\n if (bytes > MAX_TOTAL_INLINE_BYTES) exceeded.push('totalBytes');\n return {\n fits: exceeded.length === 0,\n bytes,\n estimated: false,\n pageCount: pageBytes.length,\n exceeded,\n limits: { ...LIMITS },\n };\n}\n\n/** One sentence naming every ceiling the payload broke, with the numbers. */\nexport function describeBudget(budget: InlineBudget): string {\n const size = budget.estimated\n ? `about ${formatBytes(budget.bytes)} (estimated)`\n : formatBytes(budget.bytes);\n const clauses = budget.exceeded.map((overrun) => {\n switch (overrun) {\n case 'pageCount':\n return `${budget.pageCount} pages exceeds the ${budget.limits.maxInlineImagePages}-image limit`;\n case 'imageBytes':\n return `a page exceeds the ${formatBytes(budget.limits.maxInlineImageBytes)} per-image limit`;\n case 'totalBytes':\n return `${size} exceeds the ${formatBytes(budget.limits.maxTotalInlineBytes)} total limit`;\n }\n });\n return `Inline images would be ${size} across ${budget.pageCount} page${\n budget.pageCount === 1 ? '' : 's'\n }: ${clauses.join('; ')}.`;\n}\n\n/** What to tell an agent that asked for more than it can be given. */\nexport function budgetSuggestion(dpi: number): string {\n const affordable = Math.max(\n 1,\n Math.min(\n MAX_INLINE_IMAGE_PAGES,\n Math.floor(MAX_TOTAL_INLINE_BYTES / estimatePageBytes(dpi))\n )\n );\n return `Use outputMode \"path\" to have every page written to disk instead, or ask for at most ${affordable} page${\n affordable === 1 ? '' : 's'\n } at ${dpi} DPI, or lower the DPI.`;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes >= 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n if (bytes >= 1024) return `${Math.round(bytes / 1024)} KB`;\n return `${bytes} bytes`;\n}\n","/**\n * Document JSON → PNG pages.\n *\n * Pipeline: JSON → (core) .docx/.pptx → (LibreOffice) PDF → (poppler) one PNG\n * per selected page. `jto-ops`' rasterizer already runs this route for a\n * single slide behind a docx `visual`; what is new here is the whole-document\n * shape — many pages out of one conversion, an arbitrary selection over them,\n * and a page count that is not known until the PDF exists.\n *\n * Three properties are load-bearing and easy to lose:\n *\n * - Profile isolation. Every soffice launch gets its own `UserInstallation`\n * directory. Without it a launch attaches to whatever profile is already\n * open — a developer's running LibreOffice, or a concurrent conversion —\n * and either hangs or silently converts nothing.\n * - Font staging. The document's resolved faces are staged for the launch\n * through the shared `FontStager`, so a preview shows the document's real\n * typography rather than the host's fallbacks. The handle is closed before\n * the temp tree is removed, because the fontconfig stager freezes its\n * directory to 0o555 and `rm` cannot unlink inside it afterwards.\n * - Per-page caching. PNGs are filed under a key that covers every input, so\n * an unchanged document re-previewed launches nothing at all.\n *\n * Nothing here writes to stdout: that stream carries MCP protocol frames.\n * `execFile` captures the child's output — soffice is chatty on stdout — and\n * everything reportable comes back as a diagnostic.\n */\n\nimport { execFile } from 'node:child_process';\nimport crypto from 'node:crypto';\nimport { promises as fs } from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { GenerationWarning, ResolvedFont } from '@json-to-office/shared';\nimport { getFontStager, type FontStageHandle } from '@json-to-office/jto-ops';\n\nimport type { FormatAdapter, FormatName } from '../lib/adapters.js';\nimport {\n ERROR_CODES,\n diagnostic,\n failure,\n failureFrom,\n fromValidationErrors,\n type Diagnostic,\n type Failure,\n} from '../lib/errors.js';\nimport type { RenderOptionsInput } from '../lib/schema.js';\nimport { probeBinary } from '../tools/info.js';\nimport { PREVIEW_ERROR_CODES, type PreviewStage } from './codes.js';\nimport {\n derivePreviewCacheKeys,\n digestAssets,\n digestFonts,\n digestThemeFile,\n type PreviewCacheKeys,\n} from './cache-key.js';\nimport {\n MAX_PREVIEW_PAGES,\n PREVIEW_DEFAULT_DPI,\n budgetSuggestion,\n describeBudget,\n estimatedInlineBudget,\n type PreviewOutputMode,\n} from './limits.js';\nimport {\n missingDependencyFailure,\n probePreviewDependencies,\n readConverterVersions,\n type ConverterVersions,\n type DependencyProbe,\n} from './dependencies.js';\nimport {\n canonicalRangeSpec,\n formatPageSelection,\n parsePageSpec,\n resolvePages,\n ALL_PAGES,\n type PageRange,\n} from './page-spec.js';\n\n/** One conversion of a whole document. Scaled by nothing: it is a single launch. */\nconst SOFFICE_TIMEOUT_MS = 180_000;\n/** One page. pdftoppm is fast; a page that needs longer is pathological. */\nconst PDFTOPPM_TIMEOUT_MS = 60_000;\nconst MAX_BUFFER = 64 * 1024 * 1024;\n\n/** Cached pages older than this are swept, whether or not the cache is large. */\nconst CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;\n/** Ceiling on what survives the age sweep. A 300-DPI page is 1-3 MB. */\nconst CACHE_MAX_BYTES = 512 * 1024 * 1024;\n\n/** Unpredictable per-process namespace inside the shared system temp dir. */\nconst DEFAULT_PREVIEW_CACHE_DIR = path.join(\n os.tmpdir(),\n `jto-mcp-preview-cache-${process.pid}-${crypto\n .randomBytes(12)\n .toString('hex')}`\n);\n\n/** Where PNGs are filed when the caller does not choose. */\nexport function defaultPreviewCacheDir(): string {\n return DEFAULT_PREVIEW_CACHE_DIR;\n}\n\n/** Cache files are content-addressed; unrelated names never belong to us. */\nconst CACHE_ENTRY_NAME = /^[a-f0-9]{64}\\.(?:png|meta\\.json)(?:\\.tmp-\\d+-\\d+)?$/;\n\n/**\n * Verify an existing cache directory without following a planted symlink.\n *\n * The default name is random, but callers inside the package can supply a\n * cache directory. Treat every existing path as hostile: lstat, ownership and\n * permissions remain the security boundary.\n */\nasync function inspectPrivateCacheDir(cacheDir: string): Promise<boolean> {\n const stat = await fs.lstat(cacheDir).catch(() => undefined);\n if (!stat || stat.isSymbolicLink() || !stat.isDirectory()) return false;\n\n if (typeof process.getuid === 'function' && stat.uid !== process.getuid()) {\n return false;\n }\n if (process.platform !== 'win32' && (stat.mode & 0o077) !== 0) {\n try {\n await fs.chmod(cacheDir, 0o700);\n } catch {\n return false;\n }\n }\n return true;\n}\n\n/** Create the dedicated cache directory, or disable caching if it is unsafe. */\nasync function ensurePrivateCacheDir(cacheDir: string): Promise<boolean> {\n try {\n // Non-recursive on purpose: the system temp parent already exists, and a\n // recursive mkdir would follow attacker-controlled intermediate links.\n await fs.mkdir(cacheDir, { mode: 0o700 });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') return false;\n }\n return inspectPrivateCacheDir(cacheDir);\n}\n\nexport interface PreviewCacheSweepOptions {\n maxAgeMs?: number;\n maxBytes?: number;\n /** Injectable clock, so the age rule is testable without touching mtimes. */\n now?: number;\n}\n\nexport interface PreviewCacheSweep {\n removed: number;\n bytes: number;\n}\n\n/**\n * Bound the cache directory.\n *\n * Nothing else ever removes from it: the directory outlives the process, is\n * shared by every connection, and a miss only ever adds. Without this a\n * long-lived host accumulates every page it has ever previewed until the disk\n * says no — and the failure lands on whatever else needed the space, not on\n * this server.\n *\n * Eviction is by age of write, then oldest-first until the survivors fit the\n * ceiling. Not an LRU: a cache hit does not touch the file, and stat-plus-utimes\n * on every hit would cost more than the occasional re-render it saves. Deleting\n * a page or its sibling meta file only ever costs a conversion, so entries are\n * treated as independent and nothing has to be kept in step.\n */\nexport async function sweepPreviewCache(\n cacheDir: string,\n options: PreviewCacheSweepOptions = {}\n): Promise<PreviewCacheSweep> {\n const maxAgeMs = options.maxAgeMs ?? CACHE_MAX_AGE_MS;\n const maxBytes = options.maxBytes ?? CACHE_MAX_BYTES;\n const now = options.now ?? Date.now();\n\n if (!(await inspectPrivateCacheDir(cacheDir))) {\n return { removed: 0, bytes: 0 };\n }\n\n const names = await fs.readdir(cacheDir).catch(() => undefined);\n if (!names) return { removed: 0, bytes: 0 };\n\n const entries: Array<{ file: string; mtimeMs: number; size: number }> = [];\n for (const name of names) {\n if (!CACHE_ENTRY_NAME.test(name)) continue;\n const file = path.join(cacheDir, name);\n const stat = await fs.lstat(file).catch(() => undefined);\n if (!stat?.isFile()) continue;\n entries.push({ file, mtimeMs: stat.mtimeMs, size: stat.size });\n }\n\n const doomed = entries.filter((entry) => now - entry.mtimeMs > maxAgeMs);\n const kept = entries\n .filter((entry) => now - entry.mtimeMs <= maxAgeMs)\n .sort((a, b) => a.mtimeMs - b.mtimeMs);\n\n let total = kept.reduce((sum, entry) => sum + entry.size, 0);\n while (total > maxBytes && kept.length > 0) {\n const oldest = kept.shift() as (typeof kept)[number];\n doomed.push(oldest);\n total -= oldest.size;\n }\n\n let removed = 0;\n let bytes = 0;\n for (const entry of doomed) {\n // Another process may be sweeping or writing the same directory; a file\n // already gone is the outcome we wanted, not a failure.\n const ok = await fs.rm(entry.file, { force: true }).then(\n () => true,\n () => false\n );\n if (!ok) continue;\n removed += 1;\n bytes += entry.size;\n }\n return { removed, bytes };\n}\n\n/** How often a connection re-checks a cache directory it has already swept. */\nconst CACHE_SWEEP_INTERVAL_MS = 60 * 60 * 1000;\n\n/**\n * Sweep before the cache is consulted, at most once an hour per directory.\n *\n * Sweeping on every write would re-walk the directory for no new information.\n * Sweeping only at startup would leave a connection that stays open for days —\n * the normal shape for this server — filling the directory again with nothing\n * to stop it, so the guard is an interval rather than a one-shot.\n */\nconst sweptDirs = new Map<string, { at: number; done: Promise<unknown> }>();\nfunction ensureSwept(cacheDir: string): Promise<unknown> {\n const previous = sweptDirs.get(cacheDir);\n if (previous && Date.now() - previous.at < CACHE_SWEEP_INTERVAL_MS) {\n return previous.done;\n }\n // A cache that cannot be pruned is still a usable cache, so failures here\n // are swallowed rather than failing the preview.\n const done = sweepPreviewCache(cacheDir).catch(() => undefined);\n sweptDirs.set(cacheDir, { at: Date.now(), done });\n return done;\n}\n\nexport interface RenderPreviewOptions {\n format: FormatName;\n document: unknown;\n /** Page spec — see `page-spec.ts`. Defaults to every page. */\n pages?: string;\n dpi?: number;\n render?: RenderOptionsInput;\n /** How the caller intends to receive pages; decides the pre-flight refusal. */\n outputMode?: PreviewOutputMode;\n getAdapter(format: FormatName): FormatAdapter;\n /** Injectable for the missing-dependency path. */\n probe?: DependencyProbe;\n /** `null` disables the disk cache. */\n cacheDir?: string | null;\n signal?: AbortSignal;\n onProgress?: (update: PreviewProgress) => void;\n /** Override the per-call page ceiling. Tests use it; production does not. */\n maxPages?: number;\n}\n\nexport interface PreviewProgress {\n progress: number;\n total: number;\n message: string;\n}\n\nexport interface RenderedPage {\n page: number;\n png: Buffer;\n width: number;\n height: number;\n /** True when the PNG came off disk and no converter ran for it. */\n cached: boolean;\n}\n\nexport interface PreviewRenderSuccess {\n ok: true;\n diagnostics: Diagnostic[];\n format: FormatName;\n totalPages: number;\n pages: RenderedPage[];\n /** Canonical spelling of what was selected, e.g. `\"1-3,7\"`. */\n selection: string;\n dpi: number;\n keys: PreviewCacheKeys;\n converters: ConverterVersions;\n cache: { hits: number; misses: number; enabled: boolean };\n timings: { generateMs: number; convertMs: number; rasterizeMs: number };\n}\n\nexport type PreviewRenderResult = PreviewRenderSuccess | Failure;\n\nfunction elapsed(from: bigint): number {\n return Number((process.hrtime.bigint() - from) / 1_000_000n);\n}\n\nfunction message(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction cancelled(): Failure {\n return failure(ERROR_CODES.CANCELLED, 'The preview was cancelled.', {\n severity: 'info',\n });\n}\n\nfunction renderFailure(\n stage: PreviewStage,\n detail: string,\n context: Record<string, unknown> = {}\n): Failure {\n const suggestion =\n stage === 'build'\n ? 'Run jto_validate on the document: a build failure is a defect in the JSON, not in the renderer.'\n : 'Re-run at a lower DPI or with fewer pages; if it persists, the document may use a feature LibreOffice cannot import.';\n return failure(\n PREVIEW_ERROR_CODES.RENDER_FAILED,\n `Preview failed at the ${stage} stage: ${detail}`,\n { suggestion, context: { stage, ...context } }\n );\n}\n\nconst PNG_SIGNATURE = Buffer.from([\n 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,\n]);\n\n/**\n * Validate a PNG and read its IHDR dimensions.\n *\n * `jto-ops` keeps its own copy of this private, and a truncated PNG is exactly\n * what a killed converter leaves behind — so a cached file is re-checked on\n * every read rather than trusted because it exists.\n */\nexport function parsePngSize(\n png: Buffer\n): { width: number; height: number } | null {\n if (png.length < 24) return null;\n if (!png.subarray(0, 8).equals(PNG_SIGNATURE)) return null;\n if (png.toString('ascii', 12, 16) !== 'IHDR') return null;\n const width = png.readUInt32BE(16);\n const height = png.readUInt32BE(20);\n if (width <= 0 || height <= 0) return null;\n return { width, height };\n}\n\n/**\n * Page count straight out of the PDF bytes.\n *\n * LibreOffice writes page objects uncompressed, so counting them costs a\n * regex and no process. A producer that packs them into object streams\n * returns 0 here and the caller falls back to `pdfinfo`.\n */\nexport function countPdfPages(pdf: Buffer): number {\n const text = pdf.toString('latin1');\n const matches = text.match(/\\/Type\\s*\\/Page(?![a-zA-Z])/g);\n return matches ? matches.length : 0;\n}\n\nfunction exec(\n binary: string,\n args: string[],\n timeoutMs: number,\n options: { env?: Record<string, string>; signal?: AbortSignal } = {}\n): Promise<void> {\n return new Promise((resolve, reject) => {\n execFile(\n binary,\n args,\n {\n timeout: timeoutMs,\n maxBuffer: MAX_BUFFER,\n windowsHide: true,\n env: options.env ? { ...process.env, ...options.env } : process.env,\n ...(options.signal && { signal: options.signal }),\n },\n (error) => (error ? reject(error) : resolve())\n );\n });\n}\n\n/**\n * soffice arguments, mirroring `jto-ops`' rasterizer.\n *\n * `-env:UserInstallation` is the isolation: a `file://` URL built from the\n * profile directory, forward slashes even on Windows. The filter is chosen by\n * format because Writer and Impress export through different ones and the\n * wrong pick converts nothing.\n */\nfunction sofficeArgs(\n format: FormatName,\n profileDir: string,\n outDir: string,\n file: string\n): string[] {\n const filter = format === 'pptx' ? 'impress_pdf_Export' : 'writer_pdf_Export';\n return [\n '--headless',\n '--norestore',\n '--nolockcheck',\n '--nodefault',\n `-env:UserInstallation=file://${profileDir.replace(/\\\\/g, '/')}`,\n '--convert-to',\n `pdf:${filter}`,\n '--outdir',\n outDir,\n file,\n ];\n}\n\n/** Count a spec's pages when every range is closed; undefined when open-ended. */\nexport function boundedPageCount(\n ranges: readonly PageRange[]\n): number | undefined {\n const pages = new Set<number>();\n for (const range of ranges) {\n if (range.to === null) return undefined;\n for (let page = range.from; page <= range.to; page += 1) pages.add(page);\n }\n return pages.size;\n}\n\ninterface CacheIO {\n enabled: boolean;\n readMeta(documentKey: string): Promise<number | undefined>;\n writeMeta(documentKey: string, totalPages: number): Promise<void>;\n readPage(key: string): Promise<Buffer | undefined>;\n writePage(key: string, png: Buffer): Promise<void>;\n}\n\nfunction createCacheIO(cacheDir: string | null): CacheIO {\n if (cacheDir === null) {\n return {\n enabled: false,\n readMeta: async () => undefined,\n writeMeta: async () => {},\n readPage: async () => undefined,\n writePage: async () => {},\n };\n }\n\n const metaPath = (key: string) => path.join(cacheDir, `${key}.meta.json`);\n const pagePath = (key: string) => path.join(cacheDir, `${key}.png`);\n\n return {\n enabled: true,\n\n async readMeta(documentKey) {\n try {\n const raw = await fs.readFile(metaPath(documentKey), 'utf8');\n const parsed = JSON.parse(raw) as { totalPages?: unknown };\n return typeof parsed.totalPages === 'number' &&\n Number.isInteger(parsed.totalPages) &&\n parsed.totalPages > 0\n ? parsed.totalPages\n : undefined;\n } catch {\n return undefined;\n }\n },\n\n async writeMeta(documentKey, totalPages) {\n await writeAtomic(\n cacheDir,\n metaPath(documentKey),\n Buffer.from(JSON.stringify({ totalPages }))\n );\n },\n\n async readPage(key) {\n const file = pagePath(key);\n const png = await fs.readFile(file).catch(() => undefined);\n if (!png) return undefined;\n if (parsePngSize(png)) return png;\n // A killed converter leaves half a PNG behind; discard rather than\n // hand back an image that will not decode.\n await fs.rm(file, { force: true }).catch(() => {});\n return undefined;\n },\n\n async writePage(key, png) {\n await writeAtomic(cacheDir, pagePath(key), png);\n },\n };\n}\n\nlet tempCounter = 0;\n/** Temp file plus rename, so a concurrent reader never sees half a PNG. */\nasync function writeAtomic(\n dir: string,\n target: string,\n data: Buffer\n): Promise<void> {\n const temp = `${target}.tmp-${process.pid}-${tempCounter++}`;\n try {\n // Re-check immediately before writing: the cache is shared across\n // processes and may have been replaced after renderPreview's first check.\n if (!(await inspectPrivateCacheDir(dir))) return;\n await fs.writeFile(temp, data, { flag: 'wx', mode: 0o600 });\n await fs.rename(temp, target);\n } catch {\n // The cache is an optimization; a failure to populate it is not a failure\n // to preview. Clean up the partial file and move on.\n await fs.rm(temp, { force: true }).catch(() => {});\n }\n}\n\n/** `pdfinfo` lives in poppler alongside `pdftoppm`; look next door first. */\nasync function resolvePdfinfo(\n pdftoppmPath: string\n): Promise<string | undefined> {\n const sibling = path.join(\n path.dirname(pdftoppmPath),\n process.platform === 'win32' ? 'pdfinfo.exe' : 'pdfinfo'\n );\n const status = await probeBinary([sibling, 'pdfinfo'], 'PDFTOPPM_PATH');\n return status.available ? status.path : undefined;\n}\n\nasync function pdfinfoPageCount(\n pdfinfo: string,\n pdfPath: string,\n signal?: AbortSignal\n): Promise<number | undefined> {\n return new Promise((resolve) => {\n execFile(\n pdfinfo,\n [pdfPath],\n {\n timeout: 30_000,\n windowsHide: true,\n maxBuffer: 1024 * 1024,\n ...(signal && { signal }),\n },\n (error, stdout) => {\n if (error && !stdout) return resolve(undefined);\n const match = /^Pages:\\s+(\\d+)/m.exec(stdout ?? '');\n resolve(match ? Number(match[1]) : undefined);\n }\n );\n });\n}\n\n/**\n * Render selected pages of a document to PNG.\n *\n * Every failure is a value: a missing binary, a malformed page spec, an\n * oversized request and a LibreOffice crash all come back as `ok: false` with\n * diagnostics the caller can act on. Only a genuine bug throws, and the tool\n * wrapper turns that into `E_INTERNAL`.\n */\nexport async function renderPreview(\n options: RenderPreviewOptions\n): Promise<PreviewRenderResult> {\n const {\n format,\n document,\n signal,\n onProgress,\n outputMode = 'auto',\n maxPages = MAX_PREVIEW_PAGES,\n } = options;\n const dpi = options.dpi ?? PREVIEW_DEFAULT_DPI;\n const render = options.render ?? {};\n const diagnostics: Diagnostic[] = [];\n\n const parsed = parsePageSpec(options.pages ?? ALL_PAGES);\n if (!parsed.ok) return parsed;\n\n // A closed selection is countable before anything runs, so an impossible\n // request is refused for the price of parsing it rather than for the price\n // of a conversion.\n const bounded = boundedPageCount(parsed.ranges);\n if (bounded !== undefined) {\n const refusal = refuseOversized(bounded, dpi, outputMode, maxPages);\n if (refusal) return refusal;\n }\n\n const probe = options.probe ?? probePreviewDependencies;\n const dependencies = await probe();\n const missing = missingDependencyFailure(dependencies);\n if (missing) return missing;\n if (signal?.aborted) return cancelled();\n\n const cacheDir =\n options.cacheDir === undefined\n ? defaultPreviewCacheDir()\n : options.cacheDir;\n const safeCacheDir =\n cacheDir !== null && (await ensurePrivateCacheDir(cacheDir))\n ? cacheDir\n : null;\n const cache = createCacheIO(safeCacheDir);\n if (safeCacheDir !== null) await ensureSwept(safeCacheDir);\n\n // Total progress: generate, convert, then one step per page. The page count\n // is unknown until the PDF exists, so the total is revised upward once —\n // clients render a growing denominator fine, and inventing a fake one would\n // be worse.\n let progressTotal = 3;\n let progressDone = 0;\n const report = (text: string) => {\n progressDone += 1;\n onProgress?.({\n progress: progressDone,\n total: progressTotal,\n message: text,\n });\n };\n\n const generateStarted = process.hrtime.bigint();\n const resolvedFonts: ResolvedFont[] = [];\n const warnings: GenerationWarning[] = [];\n let officeBytes: Buffer;\n let converters: ConverterVersions;\n try {\n // The version probe is a cold `soffice --version`; running it beside\n // generation hides most of its cost behind work that had to happen anyway.\n const [buffer, versions] = await Promise.all([\n options.getAdapter(format).generateBuffer(document, {\n ...render,\n warnings,\n fonts: {\n onResolved: (fonts) => resolvedFonts.push(...fonts),\n },\n }),\n readConverterVersions(dependencies, signal),\n ]);\n officeBytes = buffer;\n converters = versions;\n } catch (error) {\n if (signal?.aborted) return cancelled();\n // \"Document validation failed\" on its own is not something an agent can\n // repair. The adapter can say exactly which pointers are wrong, so ask it\n // and lead with that — the same diagnostics jto_validate would have given.\n return failureFrom([\n ...validationDiagnostics(options.getAdapter(format), document),\n ...renderFailure('build', message(error)).diagnostics,\n ]);\n }\n const generateMs = elapsed(generateStarted);\n diagnostics.push(...toDiagnostics(warnings));\n report('Document generated');\n if (signal?.aborted) return cancelled();\n\n const keys = derivePreviewCacheKeys({\n format,\n document,\n render,\n themeDigest: await digestThemeFile(render.themePath),\n assetsDigest: await digestAssets(document, render.baseDir),\n fontsDigest: digestFonts(resolvedFonts),\n dpi,\n // The run key names a whole request, so it carries the selection; the page\n // keys below deliberately do not, which is what lets two overlapping\n // selections share pages.\n pageSelection: canonicalRangeSpec(parsed.ranges),\n converters: converters.identities,\n });\n\n let hits = 0;\n let misses = 0;\n\n // Fully-cached fast path: the page count was recorded last time, so the\n // selection can be resolved and served without launching anything.\n const cachedTotal = await cache.readMeta(keys.documentKey);\n if (cachedTotal !== undefined) {\n const resolved = resolvePages(parsed.ranges, cachedTotal, maxPages);\n if (!resolved.ok) return resolved;\n const refusal = refuseOversized(\n resolved.pages.length,\n dpi,\n outputMode,\n maxPages\n );\n if (refusal) return refusal;\n\n const served = await readAllCached(cache, keys, resolved.pages);\n if (served) {\n hits = served.length;\n progressTotal = 1 + served.length;\n for (const page of served) report(`Page ${page.page} from cache`);\n return {\n ok: true,\n diagnostics: [...diagnostics, ...resolved.diagnostics],\n format,\n totalPages: cachedTotal,\n pages: served,\n selection: formatPageSelection(resolved.pages),\n dpi,\n keys,\n converters,\n cache: { hits, misses, enabled: cache.enabled },\n timings: { generateMs, convertMs: 0, rasterizeMs: 0 },\n };\n }\n }\n\n const soffice = dependencies.libreoffice.path as string;\n const pdftoppm = dependencies.pdftoppm.path as string;\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'jto-mcp-preview-'));\n const profileDir = path.join(tempDir, 'profile');\n const stem = `preview-${crypto.randomBytes(4).toString('hex')}`;\n const officePath = path.join(\n tempDir,\n `${stem}${format === 'pptx' ? '.pptx' : '.docx'}`\n );\n const pdfPath = path.join(tempDir, `${stem}.pdf`);\n let stageHandle: FontStageHandle | null = null;\n\n try {\n await fs.writeFile(officePath, officeBytes);\n\n // Staged after the cache probe, before the launch: a fully-cached preview\n // must not pay for writing font files it will never use.\n const stageable = resolvedFonts.filter((font) => font.sources.length > 0);\n if (stageable.length > 0) {\n stageHandle = await getFontStager().stage(stageable, tempDir, {\n profileDirs: [profileDir],\n });\n }\n\n const convertStarted = process.hrtime.bigint();\n try {\n await exec(\n soffice,\n sofficeArgs(format, profileDir, tempDir, officePath),\n SOFFICE_TIMEOUT_MS,\n {\n ...(stageHandle?.envOverrides && { env: stageHandle.envOverrides }),\n ...(signal && { signal }),\n }\n );\n } catch (error) {\n if (signal?.aborted) return cancelled();\n return renderFailure('convert', message(error), { binary: soffice });\n }\n const convertMs = elapsed(convertStarted);\n\n const pdf = await fs.readFile(pdfPath).catch(() => undefined);\n if (!pdf) {\n // soffice reports conversion coarsely and can exit 0 having written\n // nothing; the file on disk is the only truth.\n return renderFailure(\n 'convert',\n 'LibreOffice exited without producing a PDF.',\n { binary: soffice }\n );\n }\n report('Converted to PDF');\n if (signal?.aborted) return cancelled();\n\n let totalPages = countPdfPages(pdf);\n if (totalPages === 0) {\n const pdfinfo = await resolvePdfinfo(pdftoppm);\n if (pdfinfo) {\n totalPages = (await pdfinfoPageCount(pdfinfo, pdfPath, signal)) ?? 0;\n }\n }\n if (totalPages === 0) {\n return failure(\n PREVIEW_ERROR_CODES.PAGE_COUNT_UNAVAILABLE,\n 'The page count of the converted PDF could not be determined.',\n {\n suggestion:\n 'Install poppler’s pdfinfo alongside pdftoppm so the page count can be read directly.',\n }\n );\n }\n await cache.writeMeta(keys.documentKey, totalPages);\n\n const resolved = resolvePages(parsed.ranges, totalPages, maxPages);\n if (!resolved.ok) return resolved;\n diagnostics.push(...resolved.diagnostics);\n\n const refusal = refuseOversized(\n resolved.pages.length,\n dpi,\n outputMode,\n maxPages\n );\n if (refusal) return refusal;\n\n progressTotal = 2 + resolved.pages.length;\n const rasterizeStarted = process.hrtime.bigint();\n const pages: RenderedPage[] = [];\n\n for (const page of resolved.pages) {\n if (signal?.aborted) return cancelled();\n\n const key = keys.pageKey(page);\n const cached = await cache.readPage(key);\n if (cached) {\n const size = parsePngSize(cached) as { width: number; height: number };\n hits += 1;\n pages.push({ page, png: cached, cached: true, ...size });\n report(`Page ${page} from cache`);\n continue;\n }\n misses += 1;\n\n // One pdftoppm per page with `-singlefile`: the output name is then\n // exactly `<prefix>.png`, with no zero-padding that varies with the\n // document's page count, and cancellation lands between pages.\n const prefix = path.join(tempDir, `page-${page}`);\n try {\n await exec(\n pdftoppm,\n [\n '-r',\n String(dpi),\n '-png',\n '-f',\n String(page),\n '-l',\n String(page),\n '-singlefile',\n pdfPath,\n prefix,\n ],\n PDFTOPPM_TIMEOUT_MS,\n { ...(signal && { signal }) }\n );\n } catch (error) {\n if (signal?.aborted) return cancelled();\n return renderFailure('rasterize', message(error), {\n page,\n binary: pdftoppm,\n });\n }\n\n const png = await fs.readFile(`${prefix}.png`).catch(() => undefined);\n const size = png ? parsePngSize(png) : null;\n if (!png || !size) {\n return renderFailure(\n 'rasterize',\n `pdftoppm produced no readable PNG for page ${page}.`,\n { page }\n );\n }\n await cache.writePage(key, png);\n pages.push({ page, png, cached: false, ...size });\n report(`Page ${page} rendered`);\n }\n\n return {\n ok: true,\n diagnostics,\n format,\n totalPages,\n pages,\n selection: formatPageSelection(resolved.pages),\n dpi,\n keys,\n converters,\n cache: { hits, misses, enabled: cache.enabled },\n timings: {\n generateMs,\n convertMs,\n rasterizeMs: elapsed(rasterizeStarted),\n },\n };\n } finally {\n // Order matters: the fontconfig stager freezes its staged directory to\n // 0o555, and `rm` cannot unlink inside a directory it cannot write.\n if (stageHandle) await stageHandle.cleanup().catch(() => {});\n await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {});\n }\n}\n\n/** Every requested page, or undefined when any of them is not on disk. */\nasync function readAllCached(\n cache: CacheIO,\n keys: PreviewCacheKeys,\n pages: readonly number[]\n): Promise<RenderedPage[] | undefined> {\n if (!cache.enabled) return undefined;\n const rendered: RenderedPage[] = [];\n for (const page of pages) {\n const png = await cache.readPage(keys.pageKey(page));\n if (!png) return undefined;\n const size = parsePngSize(png) as { width: number; height: number };\n rendered.push({ page, png, cached: true, ...size });\n }\n return rendered;\n}\n\n/**\n * Refuse a request that cannot be answered, before answering it.\n *\n * The page ceiling applies in every mode — preview is a look, and fifty pages\n * is already more than a look. The byte ceiling applies only when the caller\n * insisted on inline images: in `auto` an oversized payload is not a refusal\n * at all, it is a fallback to paths, which the tool decides once the real\n * bytes are known.\n */\nfunction refuseOversized(\n pageCount: number,\n dpi: number,\n outputMode: PreviewOutputMode,\n maxPages: number\n): Failure | undefined {\n if (pageCount > maxPages) {\n return failure(\n PREVIEW_ERROR_CODES.INVALID_PAGE_SPEC,\n `${pageCount} pages were selected; jto_preview renders at most ${maxPages} per call.`,\n {\n suggestion: `Narrow the selection, e.g. \"1-${maxPages}\", and call again for the rest.`,\n context: { selected: pageCount, maxPages },\n }\n );\n }\n if (outputMode !== 'images') return undefined;\n\n const budget = estimatedInlineBudget(pageCount, dpi);\n if (budget.fits) return undefined;\n return failure(PREVIEW_ERROR_CODES.TOO_LARGE, describeBudget(budget), {\n suggestion: budgetSuggestion(dpi),\n context: { budget, dpi },\n });\n}\n\n/**\n * Path-addressed reasons a document would not build.\n *\n * Best-effort: a validator that itself throws must not replace the build\n * failure the caller is already being told about.\n */\nfunction validationDiagnostics(\n adapter: FormatAdapter,\n document: unknown\n): Diagnostic[] {\n try {\n const result = adapter.validateDocument(document);\n return result.valid ? [] : fromValidationErrors(result.errors);\n } catch {\n return [];\n }\n}\n\n/** Generation warnings, preserved as diagnostics rather than dropped. */\nfunction toDiagnostics(warnings: readonly GenerationWarning[]): Diagnostic[] {\n return warnings.map((warning) =>\n diagnostic(\n typeof warning.context?.code === 'string'\n ? warning.context.code\n : 'W_GENERATION',\n `${warning.component}: ${warning.message}`,\n {\n severity: warning.severity === 'info' ? 'info' : 'warning',\n ...(warning.context && { context: warning.context }),\n }\n )\n );\n}\n","/**\n * What makes two previews the same preview.\n *\n * A LibreOffice run costs seconds; the JSON that caused it costs nothing to\n * hash. So every page is filed on disk under a digest of everything that could\n * change its pixels, and an unchanged document re-previewed answers from disk\n * without launching anything.\n *\n * That only holds if the key is complete. A key that omits the DPI serves a\n * 96-DPI page to a caller who asked for 300; one that omits the asset a\n * `image` component points at serves yesterday's logo after the file on disk\n * changed. The material below is therefore the full list — document, renderer,\n * theme, assets, fonts, DPI, selection, converters — and `PREVIEW_CACHE_VERSION`\n * covers the one input it cannot see: this pipeline itself.\n *\n * Two keys come out, and the split is the point. The RUN key identifies a whole\n * request, page selection included, which is the identity the cache contract is\n * stated in. The PAGE key drops the selection and names one page of one\n * document, which is the identity the PNGs are actually filed under — so\n * previewing `\"1-3\"` and then `\"2-5\"` re-renders pages 4 and 5 and reads 2 and\n * 3 off disk.\n */\n\nimport crypto from 'node:crypto';\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport type { ResolvedFont } from '@json-to-office/shared';\n\nimport type { FormatName } from '../lib/adapters.js';\nimport type { RenderOptionsInput } from '../lib/schema.js';\n\n/**\n * Bump when a change to this pipeline would render the same inputs\n * differently — new soffice flags, a different filter, another pdftoppm\n * option. Cached PNGs from older pipelines then simply stop matching.\n */\nexport const PREVIEW_CACHE_VERSION = 1;\n\n/**\n * Stable JSON: object keys sorted at every depth.\n *\n * `JSON.stringify` preserves insertion order, so the same document sent with\n * its keys in a different order would hash differently and miss a cache it\n * should hit. Arrays keep their order — there, order is meaning.\n */\nexport function canonicalJson(value: unknown): string {\n return JSON.stringify(canonicalize(value));\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(canonicalize);\n if (value === null || typeof value !== 'object') return value;\n const source = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(source).sort()) {\n const entry = canonicalize(source[key]);\n // Match JSON.stringify: an undefined property is absent, not null.\n if (entry !== undefined) out[key] = entry;\n }\n return out;\n}\n\nfunction sha256(input: string): string {\n return crypto.createHash('sha256').update(input).digest('hex');\n}\n\n/**\n * Identity of the font faces a render will actually use.\n *\n * Content-addressed over the decoded bytes and order-insensitive, mirroring\n * `jto-ops`' `fontsDigest`: the same faces resolved twice must key the same,\n * and a document that resolves a family to different bytes must not.\n */\nexport function digestFonts(fonts: readonly ResolvedFont[]): string {\n const parts: string[] = [];\n for (const font of fonts) {\n for (const source of font.sources) {\n parts.push(\n `${font.family}|${source.weight}|${source.italic ? 'i' : 'r'}|` +\n crypto.createHash('sha256').update(source.data).digest('hex')\n );\n }\n }\n if (parts.length === 0) return 'none';\n return sha256(parts.sort().join('\\n'));\n}\n\n/** File extensions worth treating as an on-disk render input. */\nconst ASSET_EXTENSIONS = new Set([\n '.png',\n '.jpg',\n '.jpeg',\n '.gif',\n '.webp',\n '.bmp',\n '.tif',\n '.tiff',\n '.svg',\n '.avif',\n '.ico',\n '.emf',\n '.wmf',\n '.ttf',\n '.otf',\n '.woff',\n '.woff2',\n]);\n\n/**\n * Identity of the local files a document points at.\n *\n * Size and mtime rather than content: a preview may reference a 20MB image and\n * hashing it would cost more than the render being avoided. The pair changes\n * whenever a normal edit-and-save does, which is the case that matters.\n *\n * Remote and inline sources are deliberately skipped — a `data:` URI is\n * already inside the document JSON and therefore already in the key, and an\n * `http(s)` URL cannot be identified without fetching it, so the URL string\n * (also in the document JSON) is all the identity available.\n */\nexport async function digestAssets(\n document: unknown,\n baseDir?: string\n): Promise<string> {\n const references = new Set<string>();\n collectAssetReferences(document, references);\n if (references.size === 0) return 'none';\n\n const root = baseDir ?? process.cwd();\n const entries: string[] = [];\n await Promise.all(\n [...references].map(async (reference) => {\n const resolved = path.resolve(root, reference);\n try {\n const stat = await fs.stat(resolved);\n if (!stat.isFile()) return;\n entries.push(`${resolved}|${stat.size}|${stat.mtimeMs}`);\n } catch {\n // Missing file: generation will complain about it, and its absence is\n // already part of the document JSON in the key.\n }\n })\n );\n if (entries.length === 0) return 'none';\n return sha256(entries.sort().join('\\n'));\n}\n\nfunction collectAssetReferences(value: unknown, into: Set<string>): void {\n if (typeof value === 'string') {\n if (value.length === 0 || value.length > 4096) return;\n if (/^[a-z][a-z0-9+.-]*:/i.test(value)) return; // data:, http:, file:, …\n if (ASSET_EXTENSIONS.has(path.extname(value).toLowerCase())) {\n into.add(value);\n }\n return;\n }\n if (Array.isArray(value)) {\n for (const entry of value) collectAssetReferences(entry, into);\n return;\n }\n if (value !== null && typeof value === 'object') {\n for (const entry of Object.values(value as Record<string, unknown>)) {\n collectAssetReferences(entry, into);\n }\n }\n}\n\n/** Identity of a theme file, when one was named. */\nexport async function digestThemeFile(\n themePath: string | undefined\n): Promise<string> {\n if (!themePath) return 'none';\n try {\n const stat = await fs.stat(themePath);\n return `${path.resolve(themePath)}|${stat.size}|${stat.mtimeMs}`;\n } catch {\n return `${path.resolve(themePath)}|missing`;\n }\n}\n\n/** Everything that decides what a preview looks like. */\nexport interface PreviewCacheMaterial {\n format: FormatName;\n document: unknown;\n render: RenderOptionsInput;\n /** From `digestThemeFile`. */\n themeDigest: string;\n /** From `digestAssets`. */\n assetsDigest: string;\n /** From `digestFonts`. */\n fontsDigest: string;\n dpi: number;\n /** Canonical selection from `formatPageSelection`, e.g. `\"1-3,7\"`. */\n pageSelection: string;\n /** Version identities of soffice and pdftoppm. */\n converters: Record<string, string>;\n}\n\nexport interface PreviewCacheKeys {\n /** Document + options + assets + fonts + DPI + converters. Selection-free. */\n documentKey: string;\n /** `documentKey` plus the page selection: the identity of one whole request. */\n runKey: string;\n /** Where one page's PNG is filed. */\n pageKey(page: number): string;\n}\n\nexport function derivePreviewCacheKeys(\n material: PreviewCacheMaterial\n): PreviewCacheKeys {\n const documentKey = sha256(\n canonicalJson({\n v: PREVIEW_CACHE_VERSION,\n format: material.format,\n document: material.document,\n renderer: material.render.renderer ?? null,\n theme: material.render.theme ?? null,\n themePath: material.render.themePath ?? null,\n themeDigest: material.themeDigest,\n deterministic: material.render.deterministic ?? false,\n generatedAt: material.render.generatedAt ?? null,\n baseDir: material.render.baseDir ?? null,\n assets: material.assetsDigest,\n fonts: material.fontsDigest,\n dpi: material.dpi,\n converters: material.converters,\n })\n );\n\n return {\n documentKey,\n runKey: sha256(`${documentKey}|pages=${material.pageSelection}`),\n pageKey: (page: number) => sha256(`${documentKey}|page=${page}`),\n };\n}\n","/**\n * The two host binaries a preview cannot do without.\n *\n * `jto_info` already answers \"is LibreOffice here\"; this module reuses that\n * probe rather than growing a second one that could disagree with it — an\n * agent that was told preview is available and then gets told it is not has\n * learned nothing it can act on. What is added here is the part `jto_info`\n * deliberately skips: actually running the binaries. `jto_info` is a discovery\n * call made on every connection and a cold `soffice --version` costs about a\n * second, so it settles for a PATH walk and defers the rest to a real render.\n * This is that real render, and it needs the versions anyway — they are part\n * of the cache key, because a LibreOffice upgrade is a different renderer.\n */\n\nimport { execFile } from 'node:child_process';\nimport { promises as fs } from 'node:fs';\n\nimport { ERROR_CODES, failure, type Failure } from '../lib/errors.js';\nimport {\n pdftoppmCandidates,\n probeBinary,\n sofficeCandidates,\n type HostBinaryStatus,\n} from '../tools/info.js';\n\nconst VERSION_TIMEOUT_MS = 15000;\n\nexport interface PreviewDependencies {\n libreoffice: HostBinaryStatus;\n pdftoppm: HostBinaryStatus;\n}\n\n/** Injectable so the missing-dependency path is testable on a host that has both. */\nexport type DependencyProbe = () => Promise<PreviewDependencies>;\n\nexport const probePreviewDependencies: DependencyProbe = async () => {\n const [libreoffice, pdftoppm] = await Promise.all([\n probeBinary(sofficeCandidates(), 'LIBREOFFICE_PATH'),\n probeBinary(pdftoppmCandidates(), 'PDFTOPPM_PATH'),\n ]);\n return { libreoffice, pdftoppm };\n};\n\n/** Per-platform install line, so the refusal ends in something runnable. */\nfunction installHint(): string {\n switch (process.platform) {\n case 'darwin':\n return 'brew install --cask libreoffice && brew install poppler';\n case 'win32':\n return 'winget install TheDocumentFoundation.LibreOffice; winget install oschwartz10612.Poppler';\n default:\n return 'sudo apt-get install libreoffice poppler-utils (or your distribution’s equivalent)';\n }\n}\n\n/**\n * The structured refusal for a host that cannot render, or undefined when it can.\n *\n * Names what is missing, where it was looked for, which env var overrides the\n * search and how to install it — everything an agent needs to tell a human\n * exactly one thing to do. Never a protocol error: the server is fine, this\n * host simply lacks an optional dependency, and every other tool still works.\n */\nexport function missingDependencyFailure(\n dependencies: PreviewDependencies\n): Failure | undefined {\n const missing: string[] = [];\n if (!dependencies.libreoffice.available)\n missing.push('LibreOffice (soffice)');\n if (!dependencies.pdftoppm.available) missing.push('poppler (pdftoppm)');\n if (missing.length === 0) return undefined;\n\n return failure(\n ERROR_CODES.DEPENDENCY_MISSING,\n `jto_preview renders through LibreOffice and poppler; this host is missing ${missing.join(' and ')}.`,\n {\n suggestion: `Install them (${installHint()}), or point the server at existing binaries with LIBREOFFICE_PATH / PDFTOPPM_PATH. Validation, generation and diff do not need either.`,\n context: {\n missing,\n libreoffice: dependencies.libreoffice,\n pdftoppm: dependencies.pdftoppm,\n },\n }\n );\n}\n\n/**\n * Version identity of one binary: its own version line plus its size and\n * mtime.\n *\n * The version line alone would be enough if every build reported one, and the\n * stat alone would be enough if binaries were never rebuilt in place. Together\n * they change whenever the converter does, which is all the cache key needs —\n * and the readable half is what gets reported next to the pixels so a caller\n * can tell which LibreOffice produced them.\n */\nasync function binaryIdentity(\n binary: string,\n args: string[],\n signal?: AbortSignal\n): Promise<{ identity: string; version?: string }> {\n const [version, stat] = await Promise.all([\n readVersion(binary, args, signal),\n fs.stat(binary).catch(() => undefined),\n ]);\n const identity = [\n version ?? 'unknown',\n stat ? `${stat.size}:${stat.mtimeMs}` : 'nostat',\n ].join('|');\n return { identity, ...(version !== undefined && { version }) };\n}\n\nfunction readVersion(\n binary: string,\n args: string[],\n signal?: AbortSignal\n): Promise<string | undefined> {\n return new Promise((resolve) => {\n execFile(\n binary,\n args,\n {\n timeout: VERSION_TIMEOUT_MS,\n windowsHide: true,\n maxBuffer: 1024 * 1024,\n ...(signal && { signal }),\n },\n (error, stdout, stderr) => {\n // pdftoppm prints its version to stderr and exits non-zero for `-v`,\n // so neither the exit code nor the stream choice can be assumed.\n const text = `${stdout ?? ''}\\n${stderr ?? ''}`.trim();\n const line = text.split('\\n')[0]?.trim();\n if (!line && error) return resolve(undefined);\n resolve(line || undefined);\n }\n );\n });\n}\n\nexport interface ConverterVersions {\n /** Cache-key material: opaque, changes whenever a converter does. */\n identities: Record<string, string>;\n /** Human-readable, reported next to the rendered pages. */\n libreoffice?: string;\n pdftoppm?: string;\n}\n\n/**\n * Memoized per resolved path: the binaries do not change while the server\n * runs, and a cold `soffice --version` is a second nobody should pay twice.\n */\nconst identityCache = new Map<string, { identity: string; version?: string }>();\n\nexport async function readConverterVersions(\n dependencies: PreviewDependencies,\n signal?: AbortSignal\n): Promise<ConverterVersions> {\n const soffice = dependencies.libreoffice.path;\n const pdftoppm = dependencies.pdftoppm.path;\n if (!soffice || !pdftoppm) {\n // Only reachable when a caller skipped `missingDependencyFailure`; the key\n // still has to be well-defined rather than throw here.\n return { identities: { libreoffice: 'absent', pdftoppm: 'absent' } };\n }\n\n const [office, poppler] = await Promise.all([\n memoized(soffice, ['--version'], signal),\n memoized(pdftoppm, ['-v'], signal),\n ]);\n\n return {\n identities: { libreoffice: office.identity, pdftoppm: poppler.identity },\n ...(office.version !== undefined && { libreoffice: office.version }),\n ...(poppler.version !== undefined && { pdftoppm: poppler.version }),\n };\n}\n\nasync function memoized(\n binary: string,\n args: string[],\n signal?: AbortSignal\n): Promise<{ identity: string; version?: string }> {\n const cached = identityCache.get(binary);\n if (cached) return cached;\n const identity = await binaryIdentity(binary, args, signal);\n identityCache.set(binary, identity);\n return identity;\n}\n\n/** Drop the memoized identities. Tests use this to isolate. */\nexport function resetConverterVersions(): void {\n identityCache.clear();\n}\n","/**\n * `jto_preview` — look at the document instead of reasoning about it.\n *\n * Layout questions are cheap to answer with pixels and expensive to answer\n * with inference: whether a table overflowed, whether a title wrapped, whether\n * a slide is crowded. This renders selected pages to PNG and hands them back\n * as image content blocks the model can actually see — or, when that would\n * cost more than a client should carry, as files under the output root.\n *\n * The renderer is LibreOffice, which is not Word and not PowerPoint. It is\n * close enough to answer \"did this fit\"; it is not the authority on how a\n * recipient's Office will paginate. The tool description says so, and so does\n * every result, because that caveat matters most at the moment someone is\n * looking at the picture.\n */\n\nimport type { McpServer, ServerContext } from '@modelcontextprotocol/server';\n\nimport type { ToolDeps } from '../lib/deps.js';\nimport {\n deliverArtifact,\n MIME_TYPES,\n type Artifact,\n} from '../lib/artifacts.js';\nimport {\n condenseDiagnostics,\n maxDiagnosticsProperty,\n truncatedProperty,\n} from '../lib/diagnostic-budget.js';\nimport { resolveDocumentSource, sourceSummary } from '../lib/doc-source.js';\nimport { checkOutputName } from '../lib/output-root.js';\nimport {\n diagnostic,\n failureFrom,\n guarded,\n success,\n toolResult,\n type Diagnostic,\n type Failure,\n type ToolEnvelope,\n} from '../lib/errors.js';\nimport {\n checkGeneratedAt,\n resolveThemePathOption,\n} from '../lib/render-options.js';\nimport {\n S,\n artifactSchema,\n documentSourceProperties,\n formatSchema,\n outputSchema,\n renderOptionProperties,\n sourceSummarySchema,\n type DocumentSourceInput,\n type RenderOptionsInput,\n type SourceSummary,\n} from '../lib/schema.js';\nimport { checkRenderer, type FormatName } from '../lib/adapters.js';\nimport { PREVIEW_ERROR_CODES } from '../preview/codes.js';\nimport {\n ALL_PAGES,\n PAGE_SPEC_PATTERN,\n formatPageSelection,\n} from '../preview/page-spec.js';\nimport {\n MAX_INLINE_IMAGE_BYTES,\n MAX_INLINE_IMAGE_PAGES,\n MAX_PREVIEW_PAGES,\n MAX_TOTAL_INLINE_BYTES,\n PREVIEW_DEFAULT_DPI,\n PREVIEW_MAX_DPI,\n PREVIEW_MIN_DPI,\n budgetSuggestion,\n describeBudget,\n measuredInlineBudget,\n type InlineBudget,\n type PreviewOutputMode,\n} from '../preview/limits.js';\nimport {\n renderPreview,\n type PreviewProgress,\n type PreviewRenderSuccess,\n type RenderedPage,\n} from '../preview/render.js';\n\n/**\n * The standing caveat, repeated in every result.\n *\n * A model that is looking at a rendered page is at exactly the moment it might\n * conclude something about how Word will lay the document out. This is the\n * sentence that stops it.\n */\nexport const PREVIEW_FIDELITY_NOTE =\n 'Rendered by LibreOffice, not by Microsoft Office. Line breaks, pagination, font substitution and chart rasterization can differ from Word or PowerPoint on the recipient’s machine; treat this as a strong indication of layout, not as the final document.';\n\nexport interface PreviewToolInput\n extends DocumentSourceInput,\n RenderOptionsInput {\n format: FormatName;\n pages?: string;\n dpi?: number;\n outputMode?: PreviewOutputMode;\n filenamePrefix?: string;\n maxDiagnostics?: number;\n}\n\n/**\n * Bridge `renderPreview`'s progress to the client, when it asked for progress.\n *\n * A client that sent no token gets no notifications and no wasted frames.\n * Failures to notify are swallowed: a dropped progress frame must never turn a\n * finished render into a failed one.\n */\nexport function progressReporter(\n ctx: Pick<ServerContext, 'mcpReq'>\n): ((update: PreviewProgress) => void) | undefined {\n const progressToken = ctx.mcpReq._meta?.progressToken;\n if (progressToken === undefined) return undefined;\n return (update) => {\n try {\n void ctx.mcpReq\n .notify({\n method: 'notifications/progress',\n params: {\n progressToken,\n progress: update.progress,\n total: update.total,\n message: update.message,\n },\n })\n .catch(() => {});\n } catch {\n /* a closed transport is not this render's problem */\n }\n };\n}\n\n/**\n * Images or files, and whether an oversized payload is fatal.\n *\n * Split out because the interesting case is expensive to reach through the\n * renderer: proving that `auto` falls back rather than refusing needs a\n * document big enough to break the budget, and this needs only a budget.\n */\nexport function chooseDelivery(\n mode: PreviewOutputMode,\n budget: InlineBudget\n): { inline: boolean; refuse: boolean; fellBack: boolean } {\n if (mode === 'path') return { inline: false, refuse: false, fellBack: false };\n if (mode === 'images') {\n return { inline: budget.fits, refuse: !budget.fits, fellBack: false };\n }\n return { inline: budget.fits, refuse: false, fellBack: !budget.fits };\n}\n\n/** How one page came back. */\ninterface DeliveredPage {\n page: number;\n width: number;\n height: number;\n bytes: number;\n cached: boolean;\n delivery: 'image' | 'path';\n artifact?: Artifact;\n}\n\nfunction pageFilename(prefix: string, page: number): string {\n return `${prefix}-p${String(page).padStart(3, '0')}.png`;\n}\n\nconst pageSchema = {\n type: 'object' as const,\n properties: {\n page: { type: 'integer' as const, description: '1-based page number.' },\n width: { type: 'integer' as const },\n height: { type: 'integer' as const },\n bytes: { type: 'integer' as const },\n cached: {\n type: 'boolean' as const,\n description: 'True when no converter ran for this page.',\n },\n delivery: { type: 'string' as const, enum: ['image', 'path'] },\n artifact: artifactSchema,\n },\n required: ['page', 'width', 'height', 'bytes', 'cached', 'delivery'],\n additionalProperties: false,\n};\n\nexport function register(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'jto_preview',\n {\n title: 'Preview pages',\n description: `Render a document to PNG pages and look at them. Use this whenever the question is visual — did the table overflow, did the title wrap, is the slide crowded — rather than reasoning about the JSON.\n\nPages are selected with printer syntax, 1-based and inclusive: \"all\" (default), \"3\", \"2-5\", \"4-\" (to the end), \"-3\" (from the start), or a comma-separated mix like \"1-3,7\". At most ${MAX_PREVIEW_PAGES} pages per call.\n\nDelivery: outputMode \"auto\" (default) inlines the pages as images when they fit the client-safe budget (at most ${MAX_INLINE_IMAGE_PAGES} pages, ${Math.round(MAX_INLINE_IMAGE_BYTES / 1024 / 1024)} MB per page, ${Math.round(MAX_TOTAL_INLINE_BYTES / 1024 / 1024)} MB total) and otherwise writes PNG files under the server output root and returns their paths. \"images\" refuses rather than falling back; \"path\" always writes files. Image blocks follow the text block in page order and correspond to the entries of \\`pages\\` whose delivery is \"image\".\n\nFIDELITY: ${PREVIEW_FIDELITY_NOTE}\n\nNeeds LibreOffice and poppler on the host (see jto_info.previewDependencies); when either is absent the call returns a structured error naming what to install, never a crash.`,\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n openWorldHint: true,\n },\n inputSchema: S<PreviewToolInput>({\n type: 'object',\n properties: {\n format: formatSchema,\n ...documentSourceProperties,\n ...renderOptionProperties,\n pages: {\n type: 'string',\n description:\n 'Pages to render, 1-based and inclusive: \"all\", \"3\", \"2-5\", \"4-\", \"-3\", or \"1-3,7\". Defaults to \"all\".',\n pattern: PAGE_SPEC_PATTERN,\n default: ALL_PAGES,\n },\n dpi: {\n type: 'integer',\n description: `Rendering resolution. ${PREVIEW_DEFAULT_DPI} is legible without being wasteful; higher costs bytes quadratically and usually forces path delivery.`,\n minimum: PREVIEW_MIN_DPI,\n maximum: PREVIEW_MAX_DPI,\n default: PREVIEW_DEFAULT_DPI,\n },\n outputMode: {\n type: 'string',\n enum: ['auto', 'images', 'path'],\n description:\n '`auto` (default) inlines images when they fit the budget and writes files otherwise. `images` refuses instead of falling back. `path` always writes files under the output root.',\n default: 'auto',\n },\n filenamePrefix: {\n type: 'string',\n description:\n 'Base name for written PNGs, relative to the output root; each page becomes `<prefix>-pNNN.png`. Must not escape the root.',\n },\n maxDiagnostics: maxDiagnosticsProperty,\n },\n required: ['format'],\n additionalProperties: false,\n }),\n outputSchema: S(\n outputSchema(\n {\n format: formatSchema,\n source: sourceSummarySchema,\n totalPages: {\n type: 'integer',\n description: 'Pages in the whole rendered document.',\n },\n selection: {\n type: 'string',\n description:\n 'Canonical spelling of what was rendered, e.g. \"1-3,7\".',\n },\n dpi: { type: 'integer' },\n delivery: {\n type: 'string',\n enum: ['images', 'paths'],\n description: 'How the pages below came back.',\n },\n pages: { type: 'array', items: pageSchema },\n renderer: {\n type: 'object',\n description:\n 'What produced the pixels, and how far to trust them.',\n properties: {\n engine: { type: 'string' },\n libreoffice: { type: 'string' },\n pdftoppm: { type: 'string' },\n fidelity: { type: 'string' },\n },\n required: ['engine', 'fidelity'],\n additionalProperties: false,\n },\n cache: {\n type: 'object',\n properties: {\n key: {\n type: 'string',\n description:\n 'Identity of this whole request: document, options, assets, fonts, DPI, page selection and converter versions.',\n },\n documentKey: {\n type: 'string',\n description:\n 'Identity of the document at this DPI, selection-free. Two overlapping selections share pages under it.',\n },\n hits: { type: 'integer' },\n misses: { type: 'integer' },\n enabled: { type: 'boolean' },\n },\n required: ['key', 'documentKey', 'hits', 'misses', 'enabled'],\n additionalProperties: false,\n },\n timings: {\n type: 'object',\n properties: {\n generateMs: { type: 'integer' },\n convertMs: { type: 'integer' },\n rasterizeMs: { type: 'integer' },\n },\n required: ['generateMs', 'convertMs', 'rasterizeMs'],\n additionalProperties: false,\n },\n truncated: truncatedProperty,\n },\n // Nothing beyond the envelope is required: a structured refusal\n // carries `ok: false` and diagnostics and nothing else, and the SDK\n // validates `structuredContent` against this schema — listing the\n // success fields here would make every refusal unreportable.\n []\n )\n ),\n },\n async (args, ctx) => {\n const outcome = await guarded<Delivery | Failure>(async () => {\n const dateError = checkGeneratedAt(args.generatedAt);\n if (dateError) return dateError;\n\n const adapter = deps.getAdapter(args.format);\n const rendererError = await checkRenderer(adapter, args.renderer);\n if (rendererError) return rendererError;\n\n const themePath = resolveThemePathOption(args.themePath, args.baseDir);\n if (!themePath.ok) return themePath;\n\n if (args.filenamePrefix !== undefined) {\n const outputNameError = checkOutputName(\n pageFilename(args.filenamePrefix, 1)\n );\n if (outputNameError) return outputNameError;\n }\n\n const source = await resolveDocumentSource(args, deps.workspaces());\n if (!source.ok) return source;\n\n const onProgress = progressReporter(ctx);\n const rendered = await renderPreview({\n format: args.format,\n document: source.document,\n ...(args.pages !== undefined && { pages: args.pages }),\n ...(args.dpi !== undefined && { dpi: args.dpi }),\n render: pickRenderOptions(args, themePath.path),\n outputMode: args.outputMode ?? 'auto',\n getAdapter: deps.getAdapter,\n signal: ctx.mcpReq.signal,\n ...(onProgress && { onProgress }),\n });\n if (!rendered.ok) return rendered;\n\n return deliver(rendered, args, deps, sourceSummary(source));\n });\n\n // The budget applies to whichever channel answered. A sixty-paragraph\n // document with one wrong prop refuses with sixty near-identical\n // diagnostics, all of which teach the agent the same single fact.\n if (!('payload' in outcome)) {\n const capped = condenseDiagnostics(\n outcome.diagnostics,\n args.maxDiagnostics\n );\n return toolResult({\n ...outcome,\n diagnostics: capped.kept,\n truncated: capped.truncated,\n });\n }\n\n const capped = condenseDiagnostics(\n outcome.payload.diagnostics,\n args.maxDiagnostics\n );\n const payload = {\n ...outcome.payload,\n diagnostics: capped.kept,\n truncated: capped.truncated,\n };\n\n // Image bytes ride in content blocks and nowhere else: a client reading\n // both channels would otherwise hold every page twice, and the base64 of\n // a 150-DPI page is not something to put in structured output.\n return {\n content: [\n { type: 'text' as const, text: JSON.stringify(payload) },\n ...outcome.images.map((page) => ({\n type: 'image' as const,\n data: page.png.toString('base64'),\n mimeType: MIME_TYPES['.png'] as string,\n })),\n ],\n structuredContent: payload,\n };\n }\n );\n}\n\nfunction pickRenderOptions(\n args: PreviewToolInput,\n resolvedThemePath?: string\n): RenderOptionsInput {\n return {\n ...(args.renderer !== undefined && { renderer: args.renderer }),\n ...(args.theme !== undefined && { theme: args.theme }),\n ...(resolvedThemePath !== undefined && { themePath: resolvedThemePath }),\n ...(args.deterministic !== undefined && {\n deterministic: args.deterministic,\n }),\n ...(args.generatedAt !== undefined && { generatedAt: args.generatedAt }),\n ...(args.baseDir !== undefined && { baseDir: args.baseDir }),\n };\n}\n\n/**\n * Decide how the rendered pages come back, then produce them.\n *\n * The estimate already refused an impossible `images` request before anything\n * rendered; this is the second gate, on the bytes that actually exist. In\n * `auto` an over-budget payload is not a failure — it silently becomes files\n * and says so, because an agent that asked to see forty pages still wants the\n * forty pages, just not in its context window.\n */\n/**\n * The success payload, mirroring the output schema.\n *\n * Written out rather than inferred so the schema and the type are edited\n * together: `structuredContent` is validated against the schema at runtime, so\n * a field that exists in one and not the other is a silent dropped result.\n */\nexport interface PreviewPayload extends ToolEnvelope {\n format: FormatName;\n source: SourceSummary;\n totalPages: number;\n selection: string;\n dpi: number;\n delivery: 'images' | 'paths';\n pages: DeliveredPage[];\n renderer: {\n engine: string;\n libreoffice?: string;\n pdftoppm?: string;\n fidelity: string;\n };\n cache: {\n key: string;\n documentKey: string;\n hits: number;\n misses: number;\n enabled: boolean;\n };\n timings: { generateMs: number; convertMs: number; rasterizeMs: number };\n}\n\n/** The two channels a successful preview answers on. */\ninterface Delivery {\n payload: PreviewPayload;\n /** Empty when the pages were written to disk. */\n images: RenderedPage[];\n}\n\nasync function deliver(\n rendered: PreviewRenderSuccess,\n args: PreviewToolInput,\n deps: ToolDeps,\n source: SourceSummary\n): Promise<Delivery | Failure> {\n const diagnostics: Diagnostic[] = [...rendered.diagnostics];\n const budget = measuredInlineBudget(rendered.pages.map((p) => p.png.length));\n const { inline, refuse, fellBack } = chooseDelivery(\n args.outputMode ?? 'auto',\n budget\n );\n\n if (refuse) {\n return failureFrom([\n ...diagnostics,\n diagnostic(PREVIEW_ERROR_CODES.TOO_LARGE, describeBudget(budget), {\n suggestion: budgetSuggestion(rendered.dpi),\n context: { budget, dpi: rendered.dpi },\n }),\n ]);\n }\n\n if (fellBack) {\n diagnostics.push(\n diagnostic(\n PREVIEW_ERROR_CODES.TOO_LARGE,\n `${describeBudget(budget)} Written to the output root instead.`,\n {\n severity: 'info',\n suggestion: budgetSuggestion(rendered.dpi),\n context: { budget },\n }\n )\n );\n }\n\n const prefix =\n args.filenamePrefix ?? `preview-${rendered.keys.runKey.slice(0, 12)}`;\n const pages: DeliveredPage[] = [];\n\n for (const page of rendered.pages) {\n const base = {\n page: page.page,\n width: page.width,\n height: page.height,\n bytes: page.png.length,\n cached: page.cached,\n };\n if (inline) {\n pages.push({ ...base, delivery: 'image' });\n continue;\n }\n const delivered = await deliverArtifact(page.png, {\n filename: pageFilename(prefix, page.page),\n mimeType: MIME_TYPES['.png'] as string,\n outputRoot: deps.outputRoot,\n });\n if (!delivered.ok)\n return failureFrom([...diagnostics, ...delivered.diagnostics]);\n pages.push({ ...base, delivery: 'path', artifact: delivered.artifact });\n }\n\n const payload: PreviewPayload = success(\n {\n format: rendered.format,\n source,\n totalPages: rendered.totalPages,\n selection: formatPageSelection(rendered.pages.map((p) => p.page)),\n dpi: rendered.dpi,\n delivery: (inline ? 'images' : 'paths') as 'images' | 'paths',\n pages,\n renderer: {\n engine: 'libreoffice',\n ...(rendered.converters.libreoffice !== undefined && {\n libreoffice: rendered.converters.libreoffice,\n }),\n ...(rendered.converters.pdftoppm !== undefined && {\n pdftoppm: rendered.converters.pdftoppm,\n }),\n fidelity: PREVIEW_FIDELITY_NOTE,\n },\n cache: {\n key: rendered.keys.runKey,\n documentKey: rendered.keys.documentKey,\n hits: rendered.cache.hits,\n misses: rendered.cache.misses,\n enabled: rendered.cache.enabled,\n },\n timings: rendered.timings,\n },\n diagnostics\n );\n\n return { payload, images: inline ? rendered.pages : [] };\n}\n","/**\n * `jto_docx_diff` — two document definitions in, one reviewable redline out.\n *\n * The redline is a third DOCX definition whose text changes are `revision`\n * segments, which the renderer turns into native Word tracked changes: the\n * file opens in Word with real insertions and deletions a human can accept or\n * reject, not coloured text pretending to be them.\n *\n * Some changes have no native revision at Word's fidelity — a replaced table,\n * a swapped image. The engine reports those as `summary.untracked` rather than\n * silently dropping them, and this tool passes them through unchanged: an\n * agent that only reads the file would otherwise never learn that part of the\n * diff is invisible in it.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/server';\nimport {\n diffDocuments,\n type DiffDocumentsOptions,\n type JsonNode,\n} from '@json-to-office/shared-docx';\n\nimport { checkRenderer, type GeneratorOptions } from '../lib/adapters.js';\nimport { MIME_TYPES, deliverArtifact } from '../lib/artifacts.js';\nimport type { ToolDeps } from '../lib/deps.js';\nimport { resolveDocumentSource, sourceSummary } from '../lib/doc-source.js';\nimport {\n ERROR_CODES,\n OPTION_ERROR_CODES,\n countDiagnostics,\n diagnosticsFromThrown,\n failure,\n failureFrom,\n guarded,\n toolResult,\n validationDiagnostics,\n type Diagnostic,\n} from '../lib/errors.js';\nimport {\n checkDateOption,\n checkGeneratedAt,\n resolveThemePathOption,\n} from '../lib/render-options.js';\nimport {\n S,\n artifactOutputProperties,\n artifactSchema,\n documentSourceSchema,\n outputSchema,\n renderOptionProperties,\n sourceSummarySchema,\n type ArtifactOutputInput,\n type DocumentSourceInput,\n type RenderOptionsInput,\n} from '../lib/schema.js';\n\n/** Word shows this next to every revision when the caller names nobody. */\nconst DEFAULT_AUTHOR = 'json-to-office';\n\nconst DEFAULT_FILENAME = 'redline.docx';\n\n/** One side of the comparison: a source wrapper, or the document itself. */\ntype DiffSide = DocumentSourceInput & { name?: unknown };\n\ninterface DiffArgs extends RenderOptionsInput, ArtifactOutputInput {\n before: DiffSide;\n after: DiffSide;\n author?: string;\n date?: string;\n dryRun?: boolean;\n includeRedlineDocument?: boolean;\n}\n\n/**\n * A side, as advertised.\n *\n * Two documents cannot both be spelled `document`, so each side is a bag of\n * `documentSourceProperties` — and that made this the one tool in the set that\n * rejected the shape the other twelve accept, with an AJV message naming no\n * property. It now takes either: `additionalProperties` is open so a document\n * definition passes straight through, and the wrapper keys stay advertised\n * flat, which a `oneOf` would hide from every client that renders nothing but\n * a property list.\n */\nconst diffSideSchema = {\n ...documentSourceSchema,\n additionalProperties: true,\n};\n\n/**\n * One side, as `resolveDocumentSource` wants it.\n *\n * A bare document is recognised by its `name`, which every document definition\n * has at its root and no wrapper has at all. Anything else stays a wrapper, so\n * `{}` and a misspelled key still come back as E_DOC_SOURCE_MISSING naming the\n * two spellings that work, rather than being validated as a document nobody\n * sent.\n */\nfunction documentSourceOf(side: DiffSide): DocumentSourceInput {\n if (side.document !== undefined || side.handle !== undefined) return side;\n return typeof side.name === 'string' ? { document: side } : side;\n}\n\nconst untrackedChangeSchema = {\n type: 'object' as const,\n description: 'A change the redline cannot express as a native Word revision.',\n properties: {\n path: {\n type: 'string' as const,\n description: 'RFC 6901 JSON Pointer into the AFTER document.',\n },\n kind: {\n type: 'string' as const,\n enum: ['modified', 'inserted', 'deleted'],\n },\n component: { type: 'string' as const },\n detail: { type: 'string' as const },\n },\n required: ['path', 'kind', 'component', 'detail'],\n additionalProperties: false,\n};\n\nconst summarySchema = {\n type: 'object' as const,\n properties: {\n tracked: {\n type: 'object' as const,\n description: 'Blocks rendered as native tracked changes.',\n properties: {\n modified: { type: 'integer' as const },\n inserted: { type: 'integer' as const },\n deleted: { type: 'integer' as const },\n },\n required: ['modified', 'inserted', 'deleted'],\n additionalProperties: false,\n },\n untracked: { type: 'array' as const, items: untrackedChangeSchema },\n unchangedBlocks: { type: 'integer' as const },\n notes: {\n type: 'array' as const,\n description: 'Fidelity caveats about the redline as a whole.',\n items: { type: 'string' as const },\n },\n },\n required: ['tracked', 'untracked', 'unchangedBlocks', 'notes'],\n additionalProperties: false,\n};\n\n/** Tag a side's diagnostics so a caller knows which document to repair. */\nfunction sideDiagnostics(\n side: 'before' | 'after',\n diagnostics: Diagnostic[]\n): Diagnostic[] {\n return diagnostics.map((entry) => ({\n ...entry,\n context: { ...entry.context, side },\n }));\n}\n\nexport function register(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'jto_docx_diff',\n {\n title: 'Diff two documents into a Word redline',\n description:\n 'Compare two DOCX document definitions and produce a redline .docx that opens in Word with native tracked changes, plus a structured summary of what changed. DOCX only. Changes with no native Word revision (tables, images, charts) are reported under `summary.untracked` — read it, because they are invisible as revisions in the file itself. Pass `dryRun: true` for the summary without rendering.',\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n openWorldHint: true,\n },\n inputSchema: S<DiffArgs>({\n type: 'object',\n properties: {\n before: {\n ...diffSideSchema,\n description:\n 'The base document: the document JSON itself, or a source wrapper — `{\"document\": <json>}` or `{\"handle\": \"ws_...\"}`.',\n },\n after: {\n ...diffSideSchema,\n description:\n 'The revised document: the document JSON itself, or a source wrapper — `{\"document\": <json>}` or `{\"handle\": \"ws_...\"}`.',\n },\n author: {\n type: 'string',\n description: `Revision author shown in Word (default \"${DEFAULT_AUTHOR}\").`,\n },\n date: {\n type: 'string',\n description:\n 'Revision timestamp, ISO 8601. Omit for a deterministic redline: two runs over the same pair then produce the same bytes.',\n },\n dryRun: {\n type: 'boolean',\n description:\n 'Compute the diff and summary without rendering or writing the redline.',\n },\n includeRedlineDocument: {\n type: 'boolean',\n description:\n 'Also return the redline document JSON, so it can be edited before rendering.',\n },\n ...renderOptionProperties,\n ...artifactOutputProperties,\n },\n required: ['before', 'after'],\n additionalProperties: false,\n }),\n outputSchema: S(\n outputSchema({\n summary: summarySchema,\n artifact: artifactSchema,\n redline: {\n type: 'object',\n description:\n 'The redline document JSON. Present only when `includeRedlineDocument` was set.',\n additionalProperties: true,\n },\n dryRun: { type: 'boolean' },\n before: sourceSummarySchema,\n after: sourceSummarySchema,\n })\n ),\n },\n async (args) =>\n toolResult(\n await guarded(async () => {\n // The engine emits `revision` segments only the DOCX renderer knows\n // how to turn into w:ins / w:del, so there is no PPTX equivalent to\n // fall back to.\n const adapter = deps.getAdapter('docx');\n if (adapter.name !== 'docx') {\n return failure(\n OPTION_ERROR_CODES.UNSUPPORTED_FORMAT,\n 'jto_docx_diff supports DOCX documents only.'\n );\n }\n\n const rendererError = await checkRenderer(adapter, args.renderer);\n if (rendererError) return rendererError;\n\n const generatedAtError = checkGeneratedAt(args.generatedAt);\n if (generatedAtError) return generatedAtError;\n\n const themePath = resolveThemePathOption(\n args.themePath,\n args.baseDir\n );\n if (!themePath.ok) return themePath;\n\n const store = deps.workspaces();\n const before = await resolveDocumentSource(\n documentSourceOf(args.before),\n store\n );\n if (!before.ok) {\n return failureFrom(sideDiagnostics('before', before.diagnostics));\n }\n const after = await resolveDocumentSource(\n documentSourceOf(args.after),\n store\n );\n if (!after.ok) {\n return failureFrom(sideDiagnostics('after', after.diagnostics));\n }\n const sources = {\n before: sourceSummary(before),\n after: sourceSummary(after),\n };\n\n // Both sides are validated up front, as `jto docx diff` does: the\n // diff walks the trees structurally and would otherwise produce a\n // confident redline out of a document that cannot render.\n const inputDiagnostics = [\n ...sideDiagnostics(\n 'before',\n validationDiagnostics(\n adapter.validateDocument(before.document).errors\n )\n ),\n ...sideDiagnostics(\n 'after',\n validationDiagnostics(\n adapter.validateDocument(after.document).errors\n )\n ),\n ];\n if (countDiagnostics(inputDiagnostics).error > 0) {\n return { ...failureFrom(inputDiagnostics), ...sources };\n }\n\n const dateError = checkDateOption(\n 'date',\n args.date,\n 'omit it for a deterministic redline.'\n );\n if (dateError) return { ...dateError, ...sources };\n const date =\n args.date === undefined\n ? undefined\n : new Date(args.date).toISOString();\n\n const diffOptions: DiffDocumentsOptions = {\n author: args.author ?? DEFAULT_AUTHOR,\n ...(date !== undefined && { date }),\n };\n const { document, summary } = diffDocuments(\n before.document as JsonNode,\n after.document as JsonNode,\n diffOptions\n );\n\n const common = {\n diagnostics: inputDiagnostics,\n summary,\n ...sources,\n ...(args.includeRedlineDocument === true && { redline: document }),\n };\n\n if (args.dryRun === true) {\n return { ok: true, ...common, dryRun: true };\n }\n\n const options: GeneratorOptions = {\n ...(args.renderer !== undefined && { renderer: args.renderer }),\n ...(args.theme !== undefined && { theme: args.theme }),\n ...(themePath.path !== undefined && { themePath: themePath.path }),\n ...(args.deterministic !== undefined && {\n deterministic: args.deterministic,\n }),\n ...(args.generatedAt !== undefined && {\n generatedAt: args.generatedAt,\n }),\n ...(args.baseDir !== undefined && { baseDir: args.baseDir }),\n };\n\n let buffer: Buffer;\n try {\n const generator = await adapter.createGenerator([], options);\n buffer = await generator.generateBuffer(document);\n } catch (error) {\n const diagnostics = diagnosticsFromThrown(error);\n if (!diagnostics) throw error;\n return {\n ok: false,\n ...common,\n diagnostics: [...inputDiagnostics, ...diagnostics],\n dryRun: false,\n };\n }\n\n const mimeType = MIME_TYPES[adapter.extension];\n if (mimeType === undefined) {\n return {\n ...failure(\n ERROR_CODES.INTERNAL,\n `No MIME type registered for \"${adapter.extension}\".`\n ),\n ...sources,\n };\n }\n const delivered = await deliverArtifact(buffer, {\n filename: args.filename ?? DEFAULT_FILENAME,\n mimeType,\n ...(args.outputMode !== undefined && { mode: args.outputMode }),\n outputRoot: deps.outputRoot,\n maxInlineBytes: deps.maxInlineArtifactBytes,\n });\n if (!delivered.ok) {\n return {\n ok: false,\n ...common,\n diagnostics: [...inputDiagnostics, ...delivered.diagnostics],\n dryRun: false,\n };\n }\n\n return {\n ok: true,\n ...common,\n artifact: delivered.artifact,\n dryRun: false,\n };\n })\n )\n );\n}\n","/**\n * RFC 6901 JSON Pointers.\n *\n * Written out rather than depended on: a tool has to tell an agent *which*\n * pointer failed and *why* in a structured diagnostic it can act on, and the\n * libraries on offer signal that by throwing a formatted `Error` — the parse\n * failure and the \"no such location\" failure arrive as the same string. The\n * spec is one page, and the suite next door covers all of it.\n */\n\nconst ARRAY_INDEX = /^(?:0|[1-9][0-9]*)$/;\n\n/** Code for a pointer that is not RFC 6901. Shared by patching and inspection. */\nexport const POINTER_ERROR_CODE = 'E_INVALID_POINTER';\n\nexport type PointerParseResult =\n | { ok: true; tokens: string[] }\n | { ok: false; message: string };\n\n/** Split a pointer into unescaped reference tokens. `''` is the whole document. */\nexport function parsePointer(pointer: string): PointerParseResult {\n if (typeof pointer !== 'string') {\n return { ok: false, message: 'A JSON Pointer must be a string.' };\n }\n if (pointer === '') return { ok: true, tokens: [] };\n if (!pointer.startsWith('/')) {\n return {\n ok: false,\n message: `JSON Pointer ${JSON.stringify(\n pointer\n )} must be empty (the whole document) or start with \"/\".`,\n };\n }\n\n const tokens: string[] = [];\n for (const raw of pointer.slice(1).split('/')) {\n const token = unescapeToken(raw);\n if (token === undefined) {\n return {\n ok: false,\n message: `JSON Pointer ${JSON.stringify(\n pointer\n )} contains a \"~\" that is not part of \"~0\" or \"~1\".`,\n };\n }\n tokens.push(token);\n }\n return { ok: true, tokens };\n}\n\n/** `~1` → `/` then `~0` → `~`, in that order (RFC 6901 §4). */\nfunction unescapeToken(token: string): string | undefined {\n if (!token.includes('~')) return token;\n let out = '';\n for (let index = 0; index < token.length; index += 1) {\n const char = token[index];\n if (char !== '~') {\n out += char;\n continue;\n }\n const next = token[index + 1];\n if (next === '0') out += '~';\n else if (next === '1') out += '/';\n else return undefined;\n index += 1;\n }\n return out;\n}\n\nexport function escapeToken(token: string): string {\n return token.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n\n/** Rebuild a pointer from tokens — used to name the exact place a walk stopped. */\nexport function formatPointer(tokens: readonly string[]): string {\n return tokens.map((token) => `/${escapeToken(token)}`).join('');\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function hasOwn(object: object, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(object, key);\n}\n\n/**\n * Write a member without letting `__proto__` reach the prototype.\n *\n * `obj.__proto__ = value` mutates the prototype chain instead of adding a\n * member, which is both wrong (the pointer named a member) and a way to poison\n * every object in the process. `defineProperty` stores it as the own, plainly\n * enumerable property JSON semantics call for.\n */\nexport function setMember(\n target: Record<string, unknown>,\n key: string,\n value: unknown\n): void {\n if (key === '__proto__') {\n Object.defineProperty(target, key, {\n value,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n return;\n }\n target[key] = value;\n}\n\nexport type ArrayIndexResult =\n | { ok: true; index: number }\n | { ok: false; reason: 'malformed' | 'out_of_range' };\n\n/**\n * Read an array index token.\n *\n * `allowAppend` is the `add` case, where `-` and `length` both mean \"past the\n * last element\". Leading zeros are malformed per RFC 6901 §4, which matters:\n * `/items/01` silently meaning `/items/1` would let an agent believe a patch\n * landed where it did not.\n */\nexport function arrayIndex(\n token: string,\n length: number,\n allowAppend: boolean\n): ArrayIndexResult {\n if (token === '-') {\n return allowAppend\n ? { ok: true, index: length }\n : { ok: false, reason: 'out_of_range' };\n }\n if (!ARRAY_INDEX.test(token)) return { ok: false, reason: 'malformed' };\n const index = Number(token);\n const limit = allowAppend ? length : length - 1;\n if (index > limit) return { ok: false, reason: 'out_of_range' };\n return { ok: true, index };\n}\n\nexport type PointerLookup =\n | { found: true; value: unknown }\n /** `at` is the deepest pointer prefix that could not be resolved. */\n | { found: false; at: string };\n\n/** Walk `tokens` from `document`, reporting where the walk stopped. */\nexport function resolvePointer(\n document: unknown,\n tokens: readonly string[]\n): PointerLookup {\n let current: unknown = document;\n for (let depth = 0; depth < tokens.length; depth += 1) {\n const token = tokens[depth];\n if (Array.isArray(current)) {\n const index = arrayIndex(token, current.length, false);\n if (!index.ok)\n return { found: false, at: formatPointer(tokens.slice(0, depth + 1)) };\n current = current[index.index];\n } else if (isRecord(current)) {\n if (!hasOwn(current, token)) {\n return { found: false, at: formatPointer(tokens.slice(0, depth + 1)) };\n }\n current = current[token];\n } else {\n return { found: false, at: formatPointer(tokens.slice(0, depth + 1)) };\n }\n }\n return { found: true, value: current };\n}\n\n/** Deep copy of a JSON value. Inserted values are never aliased into the tree. */\nexport function cloneJson<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map((item) => cloneJson(item)) as unknown as T;\n }\n if (isRecord(value)) {\n const copy: Record<string, unknown> = {};\n for (const key of Object.keys(value))\n setMember(copy, key, cloneJson(value[key]));\n return copy as unknown as T;\n }\n return value;\n}\n\n/** RFC 6902 §4.6 equality: same JSON value, member order irrelevant. */\nexport function jsonEqual(left: unknown, right: unknown): boolean {\n if (left === right) return true;\n if (Array.isArray(left) && Array.isArray(right)) {\n if (left.length !== right.length) return false;\n return left.every((item, index) => jsonEqual(item, right[index]));\n }\n if (isRecord(left) && isRecord(right)) {\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n if (leftKeys.length !== rightKeys.length) return false;\n return leftKeys.every(\n (key) => hasOwn(right, key) && jsonEqual(left[key], right[key])\n );\n }\n return false;\n}\n","/**\n * RFC 6902 JSON Patch.\n *\n * Two properties the workspace store depends on and no library gave us for\n * free: every failure is a *value* naming the operation index and the pointer\n * that broke (not a thrown, string-formatted `Error`), and the whole patch is\n * checked for syntax before any of it is applied. The apply itself is still\n * all-or-nothing at the caller's level — see the ownership note on\n * `applyPatch`.\n *\n * Hand-writing it also kept `package.json` — a file this issue does not own —\n * untouched, and the spec is short enough that the suite next door covers it\n * operation by operation, including the array-index and `-` append rules.\n */\n\nimport type { JsonPatchOperation } from '../lib/workspace-store.js';\nimport {\n POINTER_ERROR_CODE,\n arrayIndex,\n cloneJson,\n formatPointer,\n hasOwn,\n isRecord,\n jsonEqual,\n parsePointer,\n resolvePointer,\n setMember,\n} from './json-pointer.js';\n\n/**\n * Patch-specific codes.\n *\n * Kept beside the implementation rather than in `lib/errors.ts`, which #203\n * owns and other agents are editing; they read as ordinary diagnostic codes to\n * a client either way. `TEST_FAILED` is deliberately distinct from `FAILED`:\n * agents use `test` as a precondition guard, and \"your assumption was wrong\"\n * is a different repair from \"that location does not exist\".\n */\nexport const PATCH_ERROR_CODES = {\n SYNTAX: 'E_PATCH_SYNTAX',\n INVALID_POINTER: POINTER_ERROR_CODE,\n FAILED: 'E_PATCH_FAILED',\n TEST_FAILED: 'E_PATCH_TEST_FAILED',\n} as const;\n\nexport const PATCH_OPS = [\n 'add',\n 'remove',\n 'replace',\n 'move',\n 'copy',\n 'test',\n] as const;\n\nexport type PatchOp = (typeof PATCH_OPS)[number];\n\nexport interface PatchProblem {\n code: string;\n message: string;\n /** Index into the operations array, so the agent can fix the right one. */\n operationIndex: number;\n /** The pointer the operation targeted, when it parsed. */\n pointer?: string;\n suggestion?: string;\n context?: Record<string, unknown>;\n}\n\nexport type PatchResult =\n | { ok: true; document: unknown }\n | { ok: false; problem: PatchProblem };\n\ninterface CompiledOperation {\n op: PatchOp;\n path: string;\n tokens: string[];\n from?: string;\n fromTokens?: string[];\n value?: unknown;\n}\n\ntype OpResult =\n | { ok: true; root: unknown }\n | { ok: false; problem: PatchProblem };\n\nconst VALUE_OPS = new Set<PatchOp>(['add', 'replace', 'test']);\nconst FROM_OPS = new Set<PatchOp>(['move', 'copy']);\n\nfunction problem(\n code: string,\n message: string,\n operationIndex: number,\n extra: Omit<PatchProblem, 'code' | 'message' | 'operationIndex'> = {}\n): { ok: false; problem: PatchProblem } {\n return { ok: false, problem: { code, message, operationIndex, ...extra } };\n}\n\n/** Short, safe rendering of a value for a diagnostic — never the whole subtree. */\nfunction preview(value: unknown): string {\n let text: string;\n try {\n text = JSON.stringify(value) ?? String(value);\n } catch {\n return '<unserializable>';\n }\n return text.length > 160 ? `${text.slice(0, 157)}...` : text;\n}\n\n/** Shared with the store, which names the same types in its own messages. */\nexport function typeName(value: unknown): string {\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'array';\n return typeof value;\n}\n\n/**\n * Check every operation's shape and pointers before any of them runs.\n *\n * This is the \"validate the patch first\" half of atomicity: a typo in the last\n * operation of a batch must not leave the first four applied, and the agent\n * gets told about all of the patch's structure being wrong at the point where\n * nothing has happened yet.\n */\nexport function compilePatch(\n operations: readonly JsonPatchOperation[]\n):\n | { ok: true; compiled: CompiledOperation[] }\n | { ok: false; problem: PatchProblem } {\n const compiled: CompiledOperation[] = [];\n\n for (let index = 0; index < operations.length; index += 1) {\n const raw = operations[index] as unknown;\n if (!isRecord(raw)) {\n return problem(\n PATCH_ERROR_CODES.SYNTAX,\n `Operation ${index} is a ${typeName(raw)}; each operation must be an object.`,\n index\n );\n }\n\n const op = raw.op as PatchOp;\n if (\n typeof op !== 'string' ||\n !(PATCH_OPS as readonly string[]).includes(op)\n ) {\n return problem(\n PATCH_ERROR_CODES.SYNTAX,\n `Operation ${index} has op ${preview(raw.op)}, which is not an RFC 6902 operation.`,\n index,\n { suggestion: `Use one of: ${PATCH_OPS.join(', ')}.` }\n );\n }\n\n if (typeof raw.path !== 'string') {\n return problem(\n PATCH_ERROR_CODES.SYNTAX,\n `Operation ${index} (${op}) has no string \\`path\\`.`,\n index,\n {\n suggestion:\n 'Every operation needs an RFC 6901 JSON Pointer in `path`.',\n }\n );\n }\n const path = parsePointer(raw.path);\n if (!path.ok) {\n return problem(PATCH_ERROR_CODES.INVALID_POINTER, path.message, index, {\n context: { op, pointer: raw.path },\n suggestion:\n 'Pointers are RFC 6901: \"/children/0/props/text\", with \"~0\" for \"~\" and \"~1\" for \"/\".',\n });\n }\n\n const entry: CompiledOperation = {\n op,\n path: raw.path,\n tokens: path.tokens,\n };\n\n if (VALUE_OPS.has(op)) {\n if (raw.value === undefined) {\n return problem(\n PATCH_ERROR_CODES.SYNTAX,\n `Operation ${index} (${op} ${raw.path}) has no \\`value\\`.`,\n index,\n {\n pointer: raw.path,\n suggestion: `\\`${op}\\` carries the JSON to write in \\`value\\`; use null for a JSON null.`,\n }\n );\n }\n entry.value = raw.value;\n }\n\n if (FROM_OPS.has(op)) {\n if (typeof raw.from !== 'string') {\n return problem(\n PATCH_ERROR_CODES.SYNTAX,\n `Operation ${index} (${op} ${raw.path}) has no string \\`from\\`.`,\n index,\n {\n pointer: raw.path,\n suggestion: `\\`${op}\\` needs the source pointer in \\`from\\`.`,\n }\n );\n }\n const from = parsePointer(raw.from);\n if (!from.ok) {\n return problem(PATCH_ERROR_CODES.INVALID_POINTER, from.message, index, {\n context: { op, pointer: raw.from, member: 'from' },\n });\n }\n entry.from = raw.from;\n entry.fromTokens = from.tokens;\n }\n\n compiled.push(entry);\n }\n\n return { ok: true, compiled };\n}\n\n/**\n * Apply a patch.\n *\n * **Takes ownership of `document`**: operations mutate it in place, so callers\n * pass a private copy and keep their own. The workspace store hands over a\n * fresh `JSON.parse` of the committed text and only re-serializes on success,\n * which is what makes a failed patch leave the stored document byte-identical.\n */\nexport function applyPatch(\n document: unknown,\n operations: readonly JsonPatchOperation[]\n): PatchResult {\n const compiled = compilePatch(operations);\n if (!compiled.ok) return compiled;\n\n let root = document;\n for (let index = 0; index < compiled.compiled.length; index += 1) {\n const result = applyOne(root, compiled.compiled[index], index);\n if (!result.ok) return result;\n root = result.root;\n }\n return { ok: true, document: root };\n}\n\nfunction applyOne(\n root: unknown,\n operation: CompiledOperation,\n index: number\n): OpResult {\n switch (operation.op) {\n case 'add':\n return add(\n root,\n operation.tokens,\n cloneJson(operation.value),\n operation,\n index\n );\n case 'remove': {\n const removed = remove(root, operation.tokens, operation, index);\n return removed.ok ? { ok: true, root: removed.root } : removed;\n }\n case 'replace':\n return replace(\n root,\n operation.tokens,\n cloneJson(operation.value),\n operation,\n index\n );\n case 'move':\n return move(root, operation, index);\n case 'copy':\n return copy(root, operation, index);\n case 'test':\n return test(root, operation, index);\n }\n}\n\n/** Resolve the container a leaf operation writes into. */\nfunction parentOf(\n root: unknown,\n tokens: readonly string[],\n operation: CompiledOperation,\n index: number\n): { ok: true; parent: unknown } | { ok: false; problem: PatchProblem } {\n const parentTokens = tokens.slice(0, -1);\n const found = resolvePointer(root, parentTokens);\n if (!found.found) {\n return problem(\n PATCH_ERROR_CODES.FAILED,\n `${operation.op} ${operation.path}: the parent location ${\n formatPointer(parentTokens) || '(document root)'\n } does not exist (stopped at ${found.at}).`,\n index,\n {\n pointer: found.at,\n suggestion:\n 'Add the missing container first — RFC 6902 never creates intermediate objects or arrays.',\n context: { op: operation.op, pointer: operation.path },\n }\n );\n }\n return { ok: true, parent: found.value };\n}\n\nfunction badContainer(\n parent: unknown,\n operation: CompiledOperation,\n index: number\n): { ok: false; problem: PatchProblem } {\n return problem(\n PATCH_ERROR_CODES.FAILED,\n `${operation.op} ${operation.path}: the parent location holds a ${typeName(\n parent\n )}, which has no members to address.`,\n index,\n { pointer: operation.path, context: { op: operation.op } }\n );\n}\n\nfunction badIndex(\n reason: 'malformed' | 'out_of_range',\n token: string,\n length: number,\n operation: CompiledOperation,\n index: number,\n allowAppend: boolean\n): { ok: false; problem: PatchProblem } {\n if (reason === 'malformed') {\n return problem(\n PATCH_ERROR_CODES.INVALID_POINTER,\n `${operation.op} ${operation.path}: ${JSON.stringify(\n token\n )} is not an array index (no leading zeros, no negatives).`,\n index,\n {\n pointer: operation.path,\n suggestion: allowAppend\n ? 'Use a decimal index, or \"-\" to append.'\n : 'Use a decimal index of an existing element.',\n context: { op: operation.op, token, length },\n }\n );\n }\n if (token === '-') {\n return problem(\n PATCH_ERROR_CODES.FAILED,\n `${operation.op} ${operation.path}: \"-\" names the position after the last element and is only valid for add.`,\n index,\n { pointer: operation.path, context: { op: operation.op, length } }\n );\n }\n return problem(\n PATCH_ERROR_CODES.FAILED,\n `${operation.op} ${operation.path}: index ${token} is past the end of a ${length}-element array.`,\n index,\n {\n pointer: operation.path,\n suggestion: allowAppend\n ? `Valid indices are 0-${length} (or \"-\" to append).`\n : `Valid indices are 0-${Math.max(length - 1, 0)}.`,\n context: { op: operation.op, token, length },\n }\n );\n}\n\nfunction add(\n root: unknown,\n tokens: readonly string[],\n value: unknown,\n operation: CompiledOperation,\n index: number\n): OpResult {\n if (tokens.length === 0) return { ok: true, root: value };\n\n const parent = parentOf(root, tokens, operation, index);\n if (!parent.ok) return parent;\n\n const key = tokens[tokens.length - 1];\n if (Array.isArray(parent.parent)) {\n const at = arrayIndex(key, parent.parent.length, true);\n if (!at.ok) {\n return badIndex(\n at.reason,\n key,\n parent.parent.length,\n operation,\n index,\n true\n );\n }\n parent.parent.splice(at.index, 0, value);\n return { ok: true, root };\n }\n if (isRecord(parent.parent)) {\n setMember(parent.parent, key, value);\n return { ok: true, root };\n }\n return badContainer(parent.parent, operation, index);\n}\n\nfunction remove(\n root: unknown,\n tokens: readonly string[],\n operation: CompiledOperation,\n index: number\n):\n | { ok: true; root: unknown; removed: unknown }\n | { ok: false; problem: PatchProblem } {\n if (tokens.length === 0) {\n return problem(\n PATCH_ERROR_CODES.FAILED,\n `${operation.op} \"\": the document root cannot be removed.`,\n index,\n {\n suggestion:\n 'Use replace with path \"\" to swap the whole document, or remove a member of it.',\n context: { op: operation.op },\n }\n );\n }\n\n const parent = parentOf(root, tokens, operation, index);\n if (!parent.ok) return parent;\n\n const key = tokens[tokens.length - 1];\n if (Array.isArray(parent.parent)) {\n const at = arrayIndex(key, parent.parent.length, false);\n if (!at.ok) {\n return badIndex(\n at.reason,\n key,\n parent.parent.length,\n operation,\n index,\n false\n );\n }\n const [removed] = parent.parent.splice(at.index, 1);\n return { ok: true, root, removed };\n }\n if (isRecord(parent.parent)) {\n if (!hasOwn(parent.parent, key)) {\n return problem(\n PATCH_ERROR_CODES.FAILED,\n `${operation.op} ${operation.path}: no such member.`,\n index,\n {\n pointer: operation.path,\n context: {\n op: operation.op,\n available: Object.keys(parent.parent).slice(0, 20),\n },\n }\n );\n }\n const removed = parent.parent[key];\n delete parent.parent[key];\n return { ok: true, root, removed };\n }\n return badContainer(parent.parent, operation, index);\n}\n\nfunction replace(\n root: unknown,\n tokens: readonly string[],\n value: unknown,\n operation: CompiledOperation,\n index: number\n): OpResult {\n if (tokens.length === 0) return { ok: true, root: value };\n\n const parent = parentOf(root, tokens, operation, index);\n if (!parent.ok) return parent;\n\n const key = tokens[tokens.length - 1];\n if (Array.isArray(parent.parent)) {\n const at = arrayIndex(key, parent.parent.length, false);\n if (!at.ok) {\n return badIndex(\n at.reason,\n key,\n parent.parent.length,\n operation,\n index,\n false\n );\n }\n parent.parent[at.index] = value;\n return { ok: true, root };\n }\n if (isRecord(parent.parent)) {\n // RFC 6902 §4.3: replace requires the member to exist. Creating it here\n // would hide a typo'd pointer as a silently-added member.\n if (!hasOwn(parent.parent, key)) {\n return problem(\n PATCH_ERROR_CODES.FAILED,\n `replace ${operation.path}: no such member to replace.`,\n index,\n {\n pointer: operation.path,\n suggestion: 'Use add to create a member that does not exist yet.',\n context: {\n op: operation.op,\n available: Object.keys(parent.parent).slice(0, 20),\n },\n }\n );\n }\n setMember(parent.parent, key, value);\n return { ok: true, root };\n }\n return badContainer(parent.parent, operation, index);\n}\n\nfunction move(\n root: unknown,\n operation: CompiledOperation,\n index: number\n): OpResult {\n const fromTokens = operation.fromTokens as string[];\n if (\n isPrefix(fromTokens, operation.tokens) &&\n fromTokens.length < operation.tokens.length\n ) {\n return problem(\n PATCH_ERROR_CODES.FAILED,\n `move ${operation.from} -> ${operation.path}: a location cannot be moved into its own child.`,\n index,\n { pointer: operation.path, context: { op: 'move', from: operation.from } }\n );\n }\n if (jsonEqualTokens(fromTokens, operation.tokens)) return { ok: true, root };\n\n const source = resolvePointer(root, fromTokens);\n if (!source.found) {\n return problem(\n PATCH_ERROR_CODES.FAILED,\n `move ${operation.from}: the source location does not exist (stopped at ${source.at}).`,\n index,\n { pointer: source.at, context: { op: 'move', from: operation.from } }\n );\n }\n\n const removed = remove(\n root,\n fromTokens,\n { ...operation, path: operation.from as string },\n index\n );\n if (!removed.ok) return removed;\n // The removed subtree is already detached and ours, so it goes back in\n // as-is; cloning here would double the cost of moving a large subtree.\n return add(removed.root, operation.tokens, removed.removed, operation, index);\n}\n\nfunction copy(\n root: unknown,\n operation: CompiledOperation,\n index: number\n): OpResult {\n const fromTokens = operation.fromTokens as string[];\n const source = resolvePointer(root, fromTokens);\n if (!source.found) {\n return problem(\n PATCH_ERROR_CODES.FAILED,\n `copy ${operation.from}: the source location does not exist (stopped at ${source.at}).`,\n index,\n { pointer: source.at, context: { op: 'copy', from: operation.from } }\n );\n }\n return add(root, operation.tokens, cloneJson(source.value), operation, index);\n}\n\nfunction test(\n root: unknown,\n operation: CompiledOperation,\n index: number\n): OpResult {\n const found = resolvePointer(root, operation.tokens);\n if (!found.found) {\n return problem(\n PATCH_ERROR_CODES.TEST_FAILED,\n `test ${operation.path}: the location does not exist (stopped at ${found.at}).`,\n index,\n {\n pointer: found.at,\n context: {\n op: 'test',\n reason: 'missing',\n expected: preview(operation.value),\n },\n }\n );\n }\n if (!jsonEqual(found.value, operation.value)) {\n return problem(\n PATCH_ERROR_CODES.TEST_FAILED,\n `test ${operation.path}: expected ${preview(operation.value)} but found ${preview(\n found.value\n )}.`,\n index,\n {\n pointer: operation.path,\n suggestion:\n 'Re-read the location (jto_workspace_inspect) before patching: the document moved under you.',\n context: {\n op: 'test',\n reason: 'mismatch',\n expected: preview(operation.value),\n actual: preview(found.value),\n },\n }\n );\n }\n return { ok: true, root };\n}\n\nfunction isPrefix(\n prefix: readonly string[],\n tokens: readonly string[]\n): boolean {\n if (prefix.length > tokens.length) return false;\n return prefix.every((token, index) => token === tokens[index]);\n}\n\nfunction jsonEqualTokens(\n left: readonly string[],\n right: readonly string[]\n): boolean {\n return left.length === right.length && isPrefix(left, right);\n}\n","/**\n * The in-memory workspace store (#271).\n *\n * Documents are held as **serialized JSON text**, not as live trees. That one\n * decision buys three of the issue's requirements outright:\n *\n * - Isolation. A read is a fresh `JSON.parse`, so a caller can mutate what it\n * got and two workspaces can never share a subtree — the structural-sharing\n * bug this feature invites cannot be written.\n * - Atomicity. A commit is a single string assignment after a successful\n * apply; a patch that fails leaves the stored bytes untouched, literally.\n * - Accounting. `bytes` is the real size, already computed, so the count and\n * byte budgets are exact rather than estimated.\n *\n * The cost is a parse and a stringify per operation, which for documents in\n * the tens to hundreds of kilobytes this format produces is far below the\n * round trip that made the agent call us.\n *\n * Nothing here throws: an unknown handle, a stale revision and a full store\n * are answers an agent repairs, so they come back as structured failures\n * (`lib/errors.ts`) exactly like a bad document does.\n */\n\nimport { randomBytes } from 'crypto';\n\nimport { ERROR_CODES, failure, type Failure } from '../lib/errors.js';\nimport type {\n JsonPatchOperation,\n WorkspaceRecord,\n WorkspaceStore,\n} from '../lib/workspace-store.js';\nimport type { FormatName } from '../lib/adapters.js';\nimport { applyPatch, PATCH_ERROR_CODES, typeName } from './json-patch.js';\nimport {\n POINTER_ERROR_CODE,\n isRecord,\n parsePointer,\n resolvePointer,\n} from './json-pointer.js';\n\n/**\n * Workspace-lifecycle codes.\n *\n * Kept here rather than in `lib/errors.ts` (owned by #203, edited\n * concurrently); they read as ordinary diagnostic codes to a client. TTL\n * eviction gets its own code rather than reusing `E_UNKNOWN_HANDLE` because\n * an agent can reopen and carry on after an idle handle expires.\n */\nexport const WORKSPACE_ERROR_CODES = {\n EVICTED: 'E_WORKSPACE_EVICTED',\n LIMIT: 'E_WORKSPACE_LIMIT',\n DOCUMENT_TOO_LARGE: 'E_DOCUMENT_TOO_LARGE',\n INVALID_ROOT: 'E_INVALID_DOCUMENT_ROOT',\n} as const;\n\nexport type EvictionReason = 'ttl' | 'closed';\n\nexport interface WorkspaceLimits {\n /** Open documents at once. */\n maxWorkspaces: number;\n /** Ceiling for a single serialized document. */\n maxDocumentBytes: number;\n /** Ceiling for every document and pinned snapshot together. */\n maxTotalBytes: number;\n /** Idle time after which a handle is dropped. Any read or write resets it. */\n idleTtlMs: number;\n /** Snapshots kept retrievable per workspace; new pins are refused at the cap. */\n maxPinnedRevisions: number;\n}\n\n/**\n * Deliberately modest.\n *\n * A workspace is a live authoring buffer for one agent on one stdio\n * connection, not a document store: sixteen open documents is already more\n * than an agent can hold in context, and the byte ceilings exist to stop a\n * runaway loop from turning a helper process into the machine's memory\n * problem. The idle TTL is half an hour because an agent's turn can stall on a\n * human for a long while, and losing a document mid-conversation is worse than\n * holding a few megabytes.\n */\nexport const DEFAULT_WORKSPACE_LIMITS: WorkspaceLimits = {\n maxWorkspaces: 16,\n maxDocumentBytes: 16 * 1024 * 1024,\n maxTotalBytes: 64 * 1024 * 1024,\n idleTtlMs: 30 * 60 * 1000,\n maxPinnedRevisions: 8,\n};\n\n/** Tombstones kept so a dropped handle can still explain itself. */\nconst MAX_TOMBSTONES = 64;\n\nexport interface MemoryWorkspaceStoreOptions extends Partial<WorkspaceLimits> {\n /** Injectable clock; the TTL suite drives it instead of waiting. */\n now?: () => number;\n /** Injectable handle source, for tests that need predictable handles. */\n newHandle?: () => string;\n}\n\nexport interface MemoryWorkspaceStore extends WorkspaceStore {\n readonly limits: WorkspaceLimits;\n /** Live totals, for `jto_workspace_list` to show the agent its budget. */\n usage(): { workspaces: number; bytes: number };\n}\n\ninterface Pin {\n text: string;\n bytes: number;\n}\n\ninterface Entry {\n handle: string;\n format: FormatName;\n revision: number;\n text: string;\n bytes: number;\n createdAt: number;\n updatedAt: number;\n /** Last read *or* write — what the idle TTL is measured from. */\n touchedAt: number;\n title?: string;\n pins: Map<number, Pin>;\n}\n\ninterface Tombstone {\n reason: EvictionReason;\n at: number;\n revision: number;\n}\n\nexport function createMemoryWorkspaceStore(\n options: MemoryWorkspaceStoreOptions = {}\n): MemoryWorkspaceStore {\n const limits: WorkspaceLimits = {\n maxWorkspaces:\n options.maxWorkspaces ?? DEFAULT_WORKSPACE_LIMITS.maxWorkspaces,\n maxDocumentBytes:\n options.maxDocumentBytes ?? DEFAULT_WORKSPACE_LIMITS.maxDocumentBytes,\n maxTotalBytes:\n options.maxTotalBytes ?? DEFAULT_WORKSPACE_LIMITS.maxTotalBytes,\n idleTtlMs: options.idleTtlMs ?? DEFAULT_WORKSPACE_LIMITS.idleTtlMs,\n maxPinnedRevisions:\n options.maxPinnedRevisions ?? DEFAULT_WORKSPACE_LIMITS.maxPinnedRevisions,\n };\n const now = options.now ?? Date.now;\n const newHandle = options.newHandle ?? defaultHandle;\n\n /** Insertion-ordered, which is also the order `list` reports. */\n const entries = new Map<string, Entry>();\n const tombstones = new Map<string, Tombstone>();\n\n function footprint(entry: Entry): number {\n let total = entry.bytes;\n for (const pin of entry.pins.values()) total += pin.bytes;\n return total;\n }\n\n function totalBytes(): number {\n let total = 0;\n for (const entry of entries.values()) total += footprint(entry);\n return total;\n }\n\n function tombstone(entry: Entry, reason: EvictionReason): void {\n tombstones.set(entry.handle, {\n reason,\n at: now(),\n revision: entry.revision,\n });\n // Oldest first: `Map` preserves insertion order, and a re-set handle is\n // deleted before it is written, so the order stays honest.\n while (tombstones.size > MAX_TOMBSTONES) {\n const oldest = tombstones.keys().next();\n if (oldest.done) break;\n tombstones.delete(oldest.value);\n }\n }\n\n function evict(entry: Entry, reason: EvictionReason): void {\n entries.delete(entry.handle);\n tombstones.delete(entry.handle);\n tombstone(entry, reason);\n }\n\n /**\n * Drop whatever has gone idle.\n *\n * Lazy rather than on a timer: a `setInterval` in a library that a host\n * embeds is a handle that keeps an event loop alive and a surprise for\n * anyone who imports us in a test. Every entry point calls this first, so\n * the observable behaviour is the same.\n */\n function sweep(): void {\n const at = now();\n for (const entry of [...entries.values()]) {\n if (at - entry.touchedAt > limits.idleTtlMs) evict(entry, 'ttl');\n }\n }\n\n function missing(handle: string): Failure {\n const grave = tombstones.get(handle);\n if (grave?.reason === 'ttl') {\n return failure(\n WORKSPACE_ERROR_CODES.EVICTED,\n `Workspace ${handle} was released after ${Math.round(\n limits.idleTtlMs / 1000\n )}s of inactivity.`,\n {\n suggestion:\n 'Re-create the workspace from your last snapshot, or pass the document inline.',\n context: { handle, reason: 'ttl', revision: grave.revision },\n }\n );\n }\n return failure(\n ERROR_CODES.UNKNOWN_HANDLE,\n grave\n ? `Workspace ${handle} was closed.`\n : `No workspace ${handle} is open on this connection.`,\n {\n suggestion:\n 'Call jto_workspace_list for the open handles, or jto_workspace_create to open one.',\n context: { handle, ...(grave && { reason: 'closed' }) },\n }\n );\n }\n\n /** Capacity failures never destroy an unrelated workspace or snapshot. */\n function hasRoom(needed: number, forNewWorkspace: boolean): boolean {\n return (\n totalBytes() + needed <= limits.maxTotalBytes &&\n (!forNewWorkspace || entries.size < limits.maxWorkspaces)\n );\n }\n\n function toRecord(\n entry: Entry,\n view?: { revision: number; bytes: number }\n ): WorkspaceRecord {\n return {\n handle: entry.handle,\n format: entry.format,\n revision: view?.revision ?? entry.revision,\n bytes: view?.bytes ?? entry.bytes,\n createdAt: new Date(entry.createdAt).toISOString(),\n updatedAt: new Date(entry.updatedAt).toISOString(),\n ...(entry.title !== undefined && { title: entry.title }),\n pinnedRevisions: [...entry.pins.keys()].sort((a, b) => a - b),\n };\n }\n\n return {\n available: true,\n limits,\n\n usage() {\n sweep();\n return { workspaces: entries.size, bytes: totalBytes() };\n },\n\n async create(input) {\n sweep();\n\n const badRoot = rootMustBeObject(input.document, {\n format: input.format,\n });\n if (badRoot) return badRoot;\n\n const serialized = serialize(input.document);\n if (!serialized.ok) return serialized;\n if (serialized.bytes > limits.maxDocumentBytes) {\n return tooLarge(serialized.bytes, limits.maxDocumentBytes);\n }\n if (!hasRoom(serialized.bytes, true)) {\n return failure(\n WORKSPACE_ERROR_CODES.LIMIT,\n `A ${serialized.bytes}-byte document does not fit in the ${limits.maxTotalBytes}-byte workspace budget.`,\n {\n suggestion:\n 'Pass the document inline instead of opening a workspace for it.',\n context: {\n bytes: serialized.bytes,\n maxTotalBytes: limits.maxTotalBytes,\n maxWorkspaces: limits.maxWorkspaces,\n },\n }\n );\n }\n\n const at = now();\n const entry: Entry = {\n handle: newHandle(),\n format: input.format,\n revision: 1,\n text: serialized.text,\n bytes: serialized.bytes,\n createdAt: at,\n updatedAt: at,\n touchedAt: at,\n ...(input.title !== undefined && { title: input.title }),\n pins: new Map(),\n };\n entries.set(entry.handle, entry);\n return { ok: true, record: toRecord(entry) };\n },\n\n async get(handle, readOptions) {\n sweep();\n const entry = entries.get(handle);\n if (!entry) return missing(handle);\n entry.touchedAt = now();\n\n let text = entry.text;\n let bytes = entry.bytes;\n let revision = entry.revision;\n const wanted = readOptions?.revision;\n if (wanted !== undefined && wanted !== entry.revision) {\n const pin = entry.pins.get(wanted);\n if (!pin) return stale(entry, wanted, toRecord(entry).pinnedRevisions);\n text = pin.text;\n bytes = pin.bytes;\n revision = wanted;\n }\n\n const document = JSON.parse(text) as unknown;\n\n // The record describes the document actually handed back, so a pinned\n // read reports the pinned revision — `lib/doc-source.ts` passes\n // `record.revision` on as \"the revision this document is\", and a\n // workspace that answered with the current one there would have every\n // downstream tool label an old tree with a new number.\n const record = toRecord(entry, { revision, bytes });\n\n if (!readOptions?.paths) return { ok: true, record, document };\n\n const projection: Record<string, unknown> = {};\n for (const pointer of readOptions.paths) {\n const parsed = parsePointer(pointer);\n if (!parsed.ok) {\n return failure(POINTER_ERROR_CODE, parsed.message, {\n suggestion:\n 'Pointers are RFC 6901: \"\" is the whole document, \"/children/0/props\" a member of it.',\n context: { handle, pointer },\n });\n }\n const found = resolvePointer(document, parsed.tokens);\n // A pointer that resolves nowhere is left out rather than reported as\n // null: the caller has to be able to tell \"absent\" from \"present and\n // null\", and the tool turns the gap into a diagnostic.\n if (found.found) projection[pointer] = found.value;\n }\n return { ok: true, record, document, projection };\n },\n\n async patch(input) {\n sweep();\n const entry = entries.get(input.handle);\n if (!entry) return missing(input.handle);\n entry.touchedAt = now();\n\n if (\n input.baseRevision !== undefined &&\n input.baseRevision !== entry.revision\n ) {\n return stale(\n entry,\n input.baseRevision,\n toRecord(entry).pinnedRevisions,\n true\n );\n }\n if (input.operations.length === 0) {\n return failure(\n PATCH_ERROR_CODES.SYNTAX,\n 'A patch needs at least one operation.',\n {\n suggestion:\n 'Send the operations you want applied; an empty patch would burn a revision for nothing.',\n context: { handle: input.handle, revision: entry.revision },\n }\n );\n }\n\n // A private parse: `applyPatch` mutates what it is given, and the stored\n // text is not touched until every operation has landed on this copy.\n const draft = JSON.parse(entry.text) as unknown;\n const applied = applyPatch(draft, input.operations);\n if (!applied.ok) {\n const { code, message, operationIndex, pointer, suggestion, context } =\n applied.problem;\n return failure(code, message, {\n ...(pointer !== undefined && { path: pointer }),\n ...(suggestion !== undefined && { suggestion }),\n context: {\n ...context,\n handle: input.handle,\n revision: entry.revision,\n operationIndex,\n },\n });\n }\n\n const badRoot = rootMustBeObject(\n applied.document,\n { handle: input.handle, revision: entry.revision },\n true\n );\n if (badRoot) return badRoot;\n\n const serialized = serialize(applied.document);\n if (!serialized.ok) return serialized;\n if (serialized.bytes > limits.maxDocumentBytes) {\n return tooLarge(serialized.bytes, limits.maxDocumentBytes);\n }\n const growth = serialized.bytes - entry.bytes;\n if (growth > 0 && !hasRoom(growth, false)) {\n return failure(\n WORKSPACE_ERROR_CODES.LIMIT,\n `Applying this patch would take the connection past its ${limits.maxTotalBytes}-byte workspace budget.`,\n {\n suggestion:\n 'Close workspaces you have finished with, or snapshot and continue inline.',\n context: {\n handle: input.handle,\n bytes: serialized.bytes,\n maxTotalBytes: limits.maxTotalBytes,\n },\n }\n );\n }\n\n // The commit. One assignment, so there is no state in which half a patch\n // is visible.\n entry.text = serialized.text;\n entry.bytes = serialized.bytes;\n entry.revision += 1;\n entry.updatedAt = now();\n entry.touchedAt = entry.updatedAt;\n return { ok: true, record: toRecord(entry) };\n },\n\n async snapshot(handle) {\n sweep();\n const entry = entries.get(handle);\n if (!entry) return missing(handle);\n entry.touchedAt = now();\n\n const revision = entry.revision;\n const document = JSON.parse(entry.text) as unknown;\n\n // Pinning is best-effort on purpose: a snapshot is the recovery path, so\n // it returns the JSON even when there is no room to keep a copy. What\n // the agent gets back always tells the truth — `pinnedRevisions` only\n // lists pins that actually took.\n if (\n !entry.pins.has(revision) &&\n entry.pins.size < limits.maxPinnedRevisions\n ) {\n if (hasRoom(entry.bytes, false)) {\n entry.pins.set(revision, { text: entry.text, bytes: entry.bytes });\n }\n }\n\n return { ok: true, record: toRecord(entry), document };\n },\n\n async list() {\n sweep();\n return {\n ok: true,\n records: [...entries.values()].map((entry) => toRecord(entry)),\n };\n },\n\n async close(handle) {\n sweep();\n const entry = entries.get(handle);\n if (!entry) return { ok: true, handle, closed: false };\n evict(entry, 'closed');\n return { ok: true, handle, closed: true };\n },\n\n async closeAll() {\n for (const entry of [...entries.values()]) evict(entry, 'closed');\n },\n };\n\n function stale(\n entry: Entry,\n wanted: number,\n pinned: number[],\n mutation = false\n ): Failure {\n return failure(\n ERROR_CODES.STALE_REVISION,\n `Workspace ${entry.handle} is at revision ${entry.revision}, not ${wanted}.` +\n (mutation ? ' Nothing was applied.' : ''),\n {\n suggestion: mutation\n ? 'Re-read the workspace (jto_workspace_inspect) and rebuild the patch against the current revision.'\n : 'Read without `revision` for the current document, or snapshot a revision before you need to come back to it.',\n context: {\n handle: entry.handle,\n requested: wanted,\n current: entry.revision,\n pinnedRevisions: pinned,\n },\n }\n );\n }\n}\n\nfunction defaultHandle(): string {\n return `ws_${randomBytes(9).toString('base64url')}`;\n}\n\n/**\n * Serialize the authoritative text.\n *\n * `JSON.stringify` returns `undefined` for a top-level `undefined` or function\n * and throws on a cycle; both mean the caller handed us something that is not\n * a JSON document, which is its defect to fix, not ours to guess at.\n */\nfunction serialize(\n document: unknown\n): { ok: true; text: string; bytes: number } | Failure {\n let text: string | undefined;\n try {\n text = JSON.stringify(document);\n } catch (error) {\n return failure(\n ERROR_CODES.INVALID_JSON,\n `The document is not JSON-serializable: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n if (typeof text !== 'string') {\n return failure(\n ERROR_CODES.INVALID_JSON,\n 'The document is not JSON-serializable.',\n {\n suggestion:\n 'Send a JSON object, e.g. { \"name\": \"docx\", \"props\": {}, \"children\": [] }.',\n }\n );\n }\n return { ok: true, text, bytes: Buffer.byteLength(text, 'utf8') };\n}\n\n/**\n * The one invalid state a workspace refuses to hold.\n *\n * Half-finished authoring stays writable on purpose — a missing `name`,\n * children added one at a time, props of the wrong type are all still objects,\n * so `get` reads them back and the next patch repairs them. A root that is not\n * a JSON object is the exception: `jto_workspace_create` takes an object and\n * both read tools declare `document` as one, so committing a scalar or an\n * array would leave the agent holding a handle whose content it can no longer\n * read, with nothing to patch against. The write is the last point at which\n * the document still exists to be kept.\n */\nfunction rootMustBeObject(\n document: unknown,\n context: Record<string, unknown>,\n mutation = false\n): Failure | undefined {\n if (isRecord(document)) return undefined;\n return failure(\n WORKSPACE_ERROR_CODES.INVALID_ROOT,\n `A workspace document must be a JSON object, not ${typeName(document)}.` +\n (mutation ? ' Nothing was applied.' : ''),\n {\n path: '',\n suggestion: mutation\n ? 'Patch members of the document — \"/props/theme\", \"/children/-\" — rather than replacing the root itself.'\n : 'Send a JSON object, e.g. { \"name\": \"docx\", \"props\": {}, \"children\": [] }.',\n context: { ...context, rootType: typeName(document) },\n }\n );\n}\n\nfunction tooLarge(bytes: number, limit: number): Failure {\n return failure(\n WORKSPACE_ERROR_CODES.DOCUMENT_TOO_LARGE,\n `The document is ${bytes} bytes, over this connection's ${limit}-byte per-document limit.`,\n {\n suggestion:\n 'Split the document, or drop inline base64 assets in favour of file paths.',\n context: { bytes, maxDocumentBytes: limit },\n }\n );\n}\n\n/** Re-exported so a caller can name what a patch failure was without importing two modules. */\nexport type { JsonPatchOperation };\n","/**\n * `jto_workspace_*` — connection-scoped documents an agent edits in place.\n *\n * The point is the round trip an agent does NOT have to make: open a document\n * once, read the two pointers it cares about, send a five-operation patch, and\n * never put the whole tree back through the model. The JSON stays\n * authoritative — a workspace holds exactly the document you gave it, and\n * every other tool takes `handle` wherever it takes `document` (#271).\n *\n * Deliberately not validated on write. Half-finished authoring states are the\n * normal case here: an agent adds a section, then its heading, then its rows,\n * and a store that rejected the intermediate steps would force it back to\n * whole-document rewrites — the exact cost this feature removes. Validation is\n * `jto_validate` with the handle, whenever the agent wants it. The single\n * exception is the root's type, which the store refuses to make a non-object:\n * every other bad state can be read back and patched, that one cannot.\n *\n * Every output schema here marks only `ok` and `diagnostics` as required. The\n * SDK validates outgoing `structuredContent` and, when it does not match,\n * throws the whole result away in favour of an isError text blob — so listing\n * `workspace` as required would mean that every failure, which by design\n * carries diagnostics and nothing else, reached the agent as an unreadable\n * protocol-ish error instead of the repairable one it is.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/server';\n\nimport type { ToolDeps } from '../lib/deps.js';\nimport {\n FORMAT_NAMES,\n S,\n artifactSchema,\n formatSchema,\n outputSchema,\n} from '../lib/schema.js';\nimport type { FormatName } from '../lib/adapters.js';\nimport { deliverArtifact } from '../lib/artifacts.js';\nimport {\n ERROR_CODES,\n diagnostic,\n guarded,\n success,\n toolResult,\n type Diagnostic,\n} from '../lib/errors.js';\nimport {\n hasWorkspaceStore,\n type JsonPatchOperation,\n type WorkspaceRecord,\n type WorkspaceStore,\n} from '../lib/workspace-store.js';\nimport { PATCH_OPS } from '../workspace/json-patch.js';\nimport {\n createMemoryWorkspaceStore,\n type MemoryWorkspaceStore,\n type WorkspaceLimits,\n} from '../workspace/store.js';\n\nconst workspaceSchema = {\n type: 'object' as const,\n description: 'The state of one open document.',\n properties: {\n handle: {\n type: 'string' as const,\n description: 'Opaque, valid only on this connection.',\n },\n format: { type: 'string' as const, enum: [...FORMAT_NAMES] },\n revision: {\n type: 'integer' as const,\n description:\n 'Increments by one per committed patch. Pass it as `baseRevision` to make the next write conditional.',\n },\n bytes: {\n type: 'integer' as const,\n description: 'Size of the serialized document.',\n },\n createdAt: { type: 'string' as const },\n updatedAt: { type: 'string' as const },\n title: { type: 'string' as const },\n pinnedRevisions: {\n type: 'array' as const,\n items: { type: 'integer' as const },\n description:\n 'Revisions kept retrievable by jto_workspace_snapshot; read one back with `revision`.',\n },\n },\n required: [\n 'handle',\n 'format',\n 'revision',\n 'bytes',\n 'createdAt',\n 'updatedAt',\n 'pinnedRevisions',\n ],\n additionalProperties: false,\n};\n\nconst limitsSchema = {\n type: 'object' as const,\n description:\n 'What this connection allows. Bounded on purpose; see the codes above.',\n properties: {\n maxWorkspaces: { type: 'integer' as const },\n maxDocumentBytes: { type: 'integer' as const },\n maxTotalBytes: { type: 'integer' as const },\n idleTtlMs: {\n type: 'integer' as const,\n description:\n 'Idle time after which a handle is released. Any use resets it.',\n },\n maxPinnedRevisions: { type: 'integer' as const },\n },\n required: [\n 'maxWorkspaces',\n 'maxDocumentBytes',\n 'maxTotalBytes',\n 'idleTtlMs',\n 'maxPinnedRevisions',\n ],\n additionalProperties: false,\n};\n\nconst pointerDescription =\n 'RFC 6901 JSON Pointer. \"\" is the whole document, \"/children/0/props/text\" a member of it; \"~0\" escapes \"~\" and \"~1\" escapes \"/\".';\n\n/** The skeleton `jto_workspace_create` opens when given no document. */\nexport function blankDocument(format: FormatName): Record<string, unknown> {\n return { name: format, props: {}, children: [] };\n}\n\nfunction isMemoryStore(store: WorkspaceStore): store is MemoryWorkspaceStore {\n return 'limits' in store && 'usage' in store;\n}\n\n/**\n * Give this connection a store, unless it already has one.\n *\n * The store is installed onto the `ToolDeps` the tools were registered with,\n * not into a module global: `deps` is what every other tool reads a handle\n * through, and it is per-connection, so two `createServer` calls in one\n * process cannot list or read each other's documents. That is the whole\n * meaning of \"valid only on this connection\" — a host serving several clients\n * builds `deps` per connection and gets isolation for free. The second\n * `createServer` of a legacy-protocol opening shares the first's store because\n * it shares its `deps`, which is the same connection.\n *\n * A host can still supply `deps.workspaces` itself, or install a store\n * process-wide with `setWorkspaceStore` before `createServer` — including\n * `unavailableWorkspaceStore` to switch the feature off, which is why the\n * question asked here is \"did the host install one\", not \"is it available\".\n */\nfunction ensureStore(deps: ToolDeps): void {\n if (deps.workspaces().available || hasWorkspaceStore()) return;\n const owned = createMemoryWorkspaceStore();\n deps.workspaces = () => owned;\n}\n\nexport function register(server: McpServer, deps: ToolDeps): void {\n ensureStore(deps);\n\n server.registerTool(\n 'jto_workspace_create',\n {\n title: 'Open a document workspace',\n description:\n 'Hold a document on the server so later calls can name it by `handle` instead of resending the JSON. Returns the handle and revision 1. Omit `document` to start from an empty skeleton and patch content in. Nothing is validated here — call jto_validate when you want it.',\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n openWorldHint: false,\n },\n inputSchema: S<{\n format: FormatName;\n document?: Record<string, unknown>;\n title?: string;\n }>({\n type: 'object',\n properties: {\n format: formatSchema,\n document: {\n type: 'object',\n description:\n 'The initial document JSON. Omitted, the workspace opens on an empty skeleton for this format.',\n additionalProperties: true,\n },\n title: {\n type: 'string',\n description:\n 'Your own label for the workspace, echoed back by jto_workspace_list. Never read by the renderer.',\n },\n },\n required: ['format'],\n additionalProperties: false,\n }),\n outputSchema: S(outputSchema({ workspace: workspaceSchema })),\n },\n async (args) =>\n toolResult(\n await guarded(async () => {\n const seeded = args.document === undefined;\n const created = await deps.workspaces().create({\n format: args.format,\n document: seeded ? blankDocument(args.format) : args.document,\n ...(args.title !== undefined && { title: args.title }),\n });\n if (!created.ok) return created;\n\n return success(\n { workspace: created.record },\n seeded\n ? [\n diagnostic(\n 'W_BLANK_DOCUMENT',\n `Opened an empty ${args.format} skeleton; it has no content until you patch some in.`,\n {\n severity: 'info',\n suggestion:\n 'Append with add operations on \"/children/-\", then validate.',\n }\n ),\n ]\n : []\n );\n })\n )\n );\n\n server.registerTool(\n 'jto_workspace_inspect',\n {\n title: 'Read a workspace document',\n description:\n 'Read an open document, or — with `paths` — only the JSON Pointers you name, which is the point of a workspace on anything large. Pointers that resolve nowhere come back in `missingPaths` rather than as null, so \"absent\" stays distinguishable from \"present and null\".',\n annotations: { readOnlyHint: true, openWorldHint: false },\n inputSchema: S<{\n handle: string;\n revision?: number;\n paths?: string[];\n includeDocument?: boolean;\n }>({\n type: 'object',\n properties: {\n handle: { type: 'string', minLength: 1 },\n revision: {\n type: 'integer',\n minimum: 1,\n description:\n 'Read this exact revision: the current one, or one pinned by jto_workspace_snapshot. Anything else fails rather than quietly returning newer JSON.',\n },\n paths: {\n type: 'array',\n items: { type: 'string', description: pointerDescription },\n description:\n 'Project only these locations. Omit to read the whole document.',\n },\n includeDocument: {\n type: 'boolean',\n description:\n 'Return the whole document alongside a projection. Default false when `paths` is given, true when it is not.',\n },\n },\n required: ['handle'],\n additionalProperties: false,\n }),\n outputSchema: S(\n outputSchema({\n workspace: workspaceSchema,\n document: {\n type: 'object',\n description:\n 'The document at the revision named by `workspace.revision`.',\n additionalProperties: true,\n },\n projection: {\n type: 'object',\n description:\n 'Requested pointer → value, for the pointers that resolved.',\n additionalProperties: true,\n },\n missingPaths: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Requested pointers that resolve nowhere in this revision.',\n },\n })\n ),\n },\n async (args) =>\n toolResult(\n await guarded(async () => {\n const read = await deps.workspaces().get(args.handle, {\n ...(args.revision !== undefined && { revision: args.revision }),\n ...(args.paths !== undefined && { paths: args.paths }),\n });\n if (!read.ok) return read;\n\n const projecting = args.paths !== undefined;\n const includeDocument = args.includeDocument ?? !projecting;\n const projection = read.projection ?? {};\n const missingPaths = projecting\n ? (args.paths as string[]).filter(\n (pointer) => !(pointer in projection)\n )\n : [];\n\n const diagnostics: Diagnostic[] = missingPaths.map((pointer) =>\n diagnostic(\n 'W_PATH_NOT_FOUND',\n `${pointer} does not resolve in revision ${read.record.revision}.`,\n {\n severity: 'warning',\n path: pointer,\n suggestion:\n 'Read a shorter prefix of the pointer to see what is actually there.',\n }\n )\n );\n\n return success(\n {\n workspace: read.record,\n ...(includeDocument && { document: read.document }),\n ...(projecting && { projection, missingPaths }),\n },\n diagnostics\n );\n })\n )\n );\n\n server.registerTool(\n 'jto_workspace_patch',\n {\n title: 'Patch a workspace document',\n description:\n 'Apply an RFC 6902 patch atomically: the whole patch is checked, applied to a copy, and committed only if every operation lands — a failure leaves the document exactly as it was and does not burn a revision. Pass `baseRevision` to make the write conditional on the document not having moved. Invalid intermediate states are kept on purpose; validate when you are ready.',\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n inputSchema: S<{\n handle: string;\n operations: JsonPatchOperation[];\n baseRevision?: number;\n }>({\n type: 'object',\n properties: {\n handle: { type: 'string', minLength: 1 },\n operations: {\n type: 'array',\n minItems: 1,\n description: 'RFC 6902 operations, applied in order.',\n items: {\n type: 'object',\n properties: {\n op: { type: 'string', enum: [...PATCH_OPS] },\n path: { type: 'string', description: pointerDescription },\n from: {\n type: 'string',\n description: 'Source pointer for `move` and `copy`.',\n },\n value: {\n description:\n 'JSON to write, for `add`, `replace` and `test`. Any type, including null.',\n },\n },\n required: ['op', 'path'],\n additionalProperties: false,\n },\n },\n baseRevision: {\n type: 'integer',\n minimum: 1,\n description:\n 'Revision you built this patch against. When it no longer matches, the write fails with E_STALE_REVISION and nothing is applied.',\n },\n },\n required: ['handle', 'operations'],\n additionalProperties: false,\n }),\n outputSchema: S(outputSchema({ workspace: workspaceSchema })),\n },\n async (args) =>\n toolResult(\n await guarded(async () => {\n const patched = await deps.workspaces().patch({\n handle: args.handle,\n operations: args.operations,\n ...(args.baseRevision !== undefined && {\n baseRevision: args.baseRevision,\n }),\n });\n if (!patched.ok) return patched;\n return success({ workspace: patched.record });\n })\n )\n );\n\n server.registerTool(\n 'jto_workspace_snapshot',\n {\n title: 'Snapshot a workspace document',\n description:\n 'Export the authoritative JSON and pin the revision it was taken at, so jto_workspace_inspect can still read that exact tree after later patches. Take one before a restructuring you could not cleanly undo. With `filename` the JSON is written under the server output root and returned as a path instead of inline.',\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n inputSchema: S<{ handle: string; filename?: string }>({\n type: 'object',\n properties: {\n handle: { type: 'string', minLength: 1 },\n filename: {\n type: 'string',\n description:\n 'Write the snapshot here, relative to the output root, instead of returning it inline. Must not escape the root: no absolute paths, no \"..\".',\n },\n },\n required: ['handle'],\n additionalProperties: false,\n }),\n outputSchema: S(\n outputSchema({\n workspace: workspaceSchema,\n document: {\n type: 'object',\n description: 'The snapshot, when it was not written to a file.',\n additionalProperties: true,\n },\n artifact: {\n ...artifactSchema,\n description: 'The written snapshot, when `filename` was given.',\n },\n })\n ),\n },\n async (args) =>\n toolResult(\n await guarded(async () => {\n const snapshot = await deps.workspaces().snapshot(args.handle);\n if (!snapshot.ok) return snapshot;\n\n const diagnostics: Diagnostic[] = [];\n if (\n !snapshot.record.pinnedRevisions.includes(snapshot.record.revision)\n ) {\n // The document is in hand either way; only the \"come back to this\n // revision later\" half was refused, and silently is not an option.\n diagnostics.push(\n diagnostic(\n 'W_SNAPSHOT_NOT_PINNED',\n `Revision ${snapshot.record.revision} was exported but not pinned: this connection's workspace budget is full.`,\n {\n severity: 'warning',\n suggestion:\n 'Keep this JSON yourself, or close workspaces you are done with before the next snapshot.',\n }\n )\n );\n }\n\n if (args.filename === undefined) {\n return success(\n { workspace: snapshot.record, document: snapshot.document },\n diagnostics\n );\n }\n\n const written = await deliverArtifact(\n Buffer.from(\n `${JSON.stringify(snapshot.document, null, 2)}\\n`,\n 'utf8'\n ),\n {\n filename: args.filename,\n mimeType: 'application/json',\n outputRoot: deps.outputRoot,\n }\n );\n if (!written.ok) return written;\n return success(\n { workspace: snapshot.record, artifact: written.artifact },\n diagnostics\n );\n })\n )\n );\n\n server.registerTool(\n 'jto_workspace_list',\n {\n title: 'List open workspaces',\n description:\n 'Every document open on this connection, with its revision and size. Call this to recover handles you no longer have — it is the cheapest way back after losing track of what you opened. An empty list means nothing is open, not that anything failed.',\n annotations: { readOnlyHint: true, openWorldHint: false },\n inputSchema: S<Record<string, never>>({\n type: 'object',\n properties: {},\n additionalProperties: false,\n }),\n outputSchema: S(\n outputSchema({\n workspaces: { type: 'array', items: workspaceSchema },\n available: {\n type: 'boolean',\n description:\n 'False when this connection has workspaces switched off.',\n },\n limits: limitsSchema,\n usage: {\n type: 'object',\n properties: {\n workspaces: { type: 'integer' },\n bytes: { type: 'integer' },\n },\n required: ['workspaces', 'bytes'],\n additionalProperties: false,\n },\n })\n ),\n },\n async () =>\n toolResult(\n await guarded(async () => {\n const store = deps.workspaces();\n const listed = await store.list();\n if (!listed.ok) return listed;\n\n const budget: {\n limits?: WorkspaceLimits;\n usage?: ReturnType<MemoryWorkspaceStore['usage']>;\n } = isMemoryStore(store)\n ? { limits: store.limits, usage: store.usage() }\n : {};\n\n return success({\n workspaces: listed.records as WorkspaceRecord[],\n available: store.available,\n ...budget,\n });\n })\n )\n );\n\n server.registerTool(\n 'jto_workspace_close',\n {\n title: 'Close a workspace',\n description:\n 'Release a handle and the memory behind it, including its pinned snapshots. Idempotent: closing a handle that is already gone reports `closed: false` rather than failing. Snapshot anything you still want first — closing is not recoverable.',\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n inputSchema: S<{ handle: string }>({\n type: 'object',\n properties: { handle: { type: 'string', minLength: 1 } },\n required: ['handle'],\n additionalProperties: false,\n }),\n outputSchema: S(\n outputSchema({\n handle: { type: 'string' },\n closed: {\n type: 'boolean',\n description: 'False when the handle was already closed or evicted.',\n },\n })\n ),\n },\n async (args) =>\n toolResult(\n await guarded(async () => {\n const closed = await deps.workspaces().close(args.handle);\n if (!closed.ok) return closed;\n return success(\n { handle: closed.handle, closed: closed.closed },\n closed.closed\n ? []\n : [\n diagnostic(\n ERROR_CODES.UNKNOWN_HANDLE,\n `No workspace ${args.handle} was open; nothing to close.`,\n { severity: 'info' }\n ),\n ]\n );\n })\n )\n );\n}\n","/**\n * The discovery resources.\n *\n * The same knowledge `jto_discover` and `jto_describe_component` serve, offered\n * the other way round: as documents a client can attach, cache and show a user,\n * rather than calls the model has to spend a turn on. Both exist because\n * clients differ — many render resources and never call a discovery tool,\n * plenty support tools and no resources at all — and #204 requires the two\n * views to agree, which `discovery-drift.test.ts` enforces.\n *\n * URIs are `jto://<kind>[/<format>/<what>]` and stable: a client that pinned\n * `jto://schema/docx/document` last release must still find it here.\n *\n * Every body is built on read, never at registration. The DOCX document schema\n * is over 3 MB; a client that only ever calls tools should not pay for it, and\n * a client that asks twice gets it from the same memo the tools use.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/server';\n\nimport type { FormatName } from '../lib/adapters.js';\nimport type { ToolDeps } from '../lib/deps.js';\nimport { FORMAT_NAMES } from '../lib/schema.js';\nimport { buildCatalog, formatSchemas } from '../tools/discover.js';\n\nexport const RESOURCE_URIS = {\n catalog: 'jto://catalog',\n renderers: 'jto://renderers',\n themes: 'jto://themes',\n templates: 'jto://templates',\n documentSchema: (format: FormatName) => `jto://schema/${format}/document`,\n themeSchema: (format: FormatName) => `jto://schema/${format}/theme`,\n} as const;\n\nconst JSON_MIME = 'application/json';\n\n/**\n * Compact, deliberately — indentation is not free at this size.\n *\n * The DOCX document schema is 3.3 MB of JSON; pretty-printed it was 12.8 MB,\n * and both ends of the stock stdio transport cap a frame at 10 MB. Reading\n * that resource therefore tore the connection down on any client using the\n * defaults, which `stdio-resources.test.ts` now covers. Whitespace is the\n * client's to add back if it wants to show the body to a human.\n */\nfunction jsonContents(uri: URL, body: unknown) {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: JSON_MIME,\n text: JSON.stringify(body),\n },\n ],\n };\n}\n\nexport function register(server: McpServer, deps: ToolDeps): void {\n server.registerResource(\n 'catalog',\n RESOURCE_URIS.catalog,\n {\n title: 'Component catalogue',\n description:\n 'Every format, its components with categories and allowed children, its renderer profiles, its built-in themes and its starter documents. The resource form of jto_discover.',\n mimeType: JSON_MIME,\n },\n async (uri) => jsonContents(uri, await buildCatalog(deps))\n );\n\n server.registerResource(\n 'renderers',\n RESOURCE_URIS.renderers,\n {\n title: 'Renderer profiles',\n description:\n 'Renderer ids per format, which is the default, and which components each profile accepts or cannot draw.',\n mimeType: JSON_MIME,\n },\n async (uri) => {\n const catalog = await buildCatalog(deps);\n return jsonContents(uri, {\n formats: catalog.formats.map((format) => ({\n format: format.name,\n defaultRenderer: format.defaultRenderer,\n renderers: format.renderers,\n })),\n });\n }\n );\n\n server.registerResource(\n 'themes',\n RESOURCE_URIS.themes,\n {\n title: 'Built-in themes',\n description:\n 'Theme names shipped with each format, usable as a document’s props.theme or as the tools’ theme option.',\n mimeType: JSON_MIME,\n },\n async (uri) => {\n const catalog = await buildCatalog(deps);\n return jsonContents(uri, {\n formats: catalog.formats.map((format) => ({\n format: format.name,\n themes: format.themes,\n })),\n });\n }\n );\n\n server.registerResource(\n 'templates',\n RESOURCE_URIS.templates,\n {\n title: 'Starter documents',\n description:\n 'Small, valid documents to copy and edit — one minimal and one fuller example per format.',\n mimeType: JSON_MIME,\n },\n async (uri) => {\n const catalog = await buildCatalog(deps);\n return jsonContents(uri, {\n starters: catalog.formats.flatMap((format) => format.starters),\n });\n }\n );\n\n for (const format of FORMAT_NAMES) {\n server.registerResource(\n `${format}-document-schema`,\n RESOURCE_URIS.documentSchema(format),\n {\n title: `${format.toUpperCase()} document schema`,\n description: `Generated JSON Schema for a complete .${format} document, discriminated by renderer. Large (megabytes) — prefer jto_describe_component unless you need the whole thing.`,\n mimeType: JSON_MIME,\n },\n async (uri) => jsonContents(uri, formatSchemas(format).document)\n );\n\n server.registerResource(\n `${format}-theme-schema`,\n RESOURCE_URIS.themeSchema(format),\n {\n title: `${format.toUpperCase()} theme schema`,\n description: `Generated JSON Schema for a .${format} theme file, as passed to the tools’ themePath option.`,\n mimeType: JSON_MIME,\n },\n async (uri) => jsonContents(uri, formatSchemas(format).theme)\n );\n }\n}\n","/**\n * What every tool module is handed at registration.\n *\n * Tools reach for nothing else process-wide: the output root, the adapters and\n * the workspace store all arrive here, so a test can stand a whole server up\n * on a temp directory and a fake store without mutating global state.\n */\n\nimport { getAdapter, type FormatAdapter, type FormatName } from './adapters.js';\nimport { MAX_INLINE_ARTIFACT_BYTES } from './artifacts.js';\nimport { createOutputRoot, type OutputRoot } from './output-root.js';\nimport { SERVER_VERSION } from './version.js';\nimport { getWorkspaceStore, type WorkspaceStore } from './workspace-store.js';\n\nexport interface ToolDeps {\n /** `@json-to-office/mcp-server`'s own version, as reported by `jto_info`. */\n serverVersion: string;\n /** The only directory the server writes to. */\n outputRoot: OutputRoot;\n /** Memoized format adapters from `@json-to-office/jto-ops`. */\n getAdapter(format: FormatName): FormatAdapter;\n /**\n * The connection's workspace store.\n *\n * A function, not a value: #271 installs the real store after the tools are\n * registered, and a snapshot taken at registration would pin the stand-in.\n */\n workspaces(): WorkspaceStore;\n /** Ceiling for `outputMode: 'base64'`, in bytes. */\n maxInlineArtifactBytes: number;\n}\n\nexport interface CreateToolDepsOptions {\n /** `--output-dir`, or an already-built root (tests hand one in). */\n outputDir?: string;\n outputRoot?: OutputRoot;\n env?: NodeJS.ProcessEnv;\n serverVersion?: string;\n workspaces?: () => WorkspaceStore;\n getAdapter?: (format: FormatName) => FormatAdapter;\n maxInlineArtifactBytes?: number;\n}\n\nexport function createToolDeps(options: CreateToolDepsOptions = {}): ToolDeps {\n return {\n serverVersion: options.serverVersion ?? SERVER_VERSION,\n outputRoot:\n options.outputRoot ??\n createOutputRoot({\n ...(options.outputDir !== undefined && { flagDir: options.outputDir }),\n ...(options.env !== undefined && { env: options.env }),\n }),\n getAdapter: options.getAdapter ?? getAdapter,\n workspaces: options.workspaces ?? getWorkspaceStore,\n maxInlineArtifactBytes:\n options.maxInlineArtifactBytes ?? MAX_INLINE_ARTIFACT_BYTES,\n };\n}\n"],"mappings":"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","names":["message","path","require","resolve","createRequire","createRequire","register","unionBranches","copy","unionBranches","register","profile","entry","register","fs","DEFAULT_MAX_DIAGNOSTICS","SEVERITY_RANK","createRequire","path","pathToFileURL","path","CORE_THEMES","coreResolver","createRequire","builtinThemeNames","pathToFileURL","message","register","fs","path","relative","message","execFile","crypto","fs","os","path","fs","path","fs","fs","resolve","path","os","crypto","fs","cancelled","resolve","execFile","cache","validationDiagnostics","size","register","capped","register","copy","message","path","randomBytes","message","randomBytes","register","register","register"]}
|