@trohde/excal-cli 1.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/core/envelope.ts","../../src/core/errors.ts","../../src/core/exit-codes.ts","../../src/core/request-id.ts","../../src/core/timer.ts","../../src/core/command-wrapper.ts","../../src/scene/schema.ts","../../src/core/io.ts","../../src/core/fingerprint.ts","../../src/scene/load-scene.ts","../../src/scene/inspect-scene.ts","../../src/scene/filters.ts","../../src/cli/commands/inspect.ts","../../src/scene/validate-scene.ts","../../src/cli/commands/validate.ts","../../src/cli/commands/render.ts","../../src/scene/normalize-scene.ts","../../src/render/bridge-page.ts","../../src/render/render-bridge.ts","../../src/render/export-common.ts","../../src/render/export-svg.ts","../../src/render/export-png.ts","../../src/render/export-pdf.ts","../../src/guide/guide-schema.ts","../../src/cli/commands/guide.ts","../../src/guide/skill-content.ts","../../src/cli/commands/skill.ts"],"sourcesContent":["import { Command, CommanderError } from \"commander\";\nimport { registerInspect } from \"./commands/inspect.js\";\nimport { registerValidate } from \"./commands/validate.js\";\nimport { registerRender } from \"./commands/render.js\";\nimport { registerGuide } from \"./commands/guide.js\";\nimport { registerSkill } from \"./commands/skill.js\";\nimport { buildEnvelope } from \"../core/envelope.js\";\nimport { generateRequestId } from \"../core/request-id.js\";\n\ndeclare const __VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name(\"excal\")\n .description(\"Agent-first CLI for Excalidraw scene inspection, validation, and rendering\")\n .version(__VERSION__);\n\n// Bare `excal` with no command → JSON error envelope\nprogram.action(() => {\n const envelope = buildEnvelope({\n request_id: generateRequestId(),\n command: \"\",\n result: null,\n ok: false,\n errors: [\n {\n code: \"ERR_VALIDATION_NO_COMMAND\",\n message: \"No command specified. Run `excal --help` for usage.\",\n retryable: false,\n suggested_action: \"fix_input\",\n },\n ],\n duration_ms: 0,\n });\n process.exitCode = 10;\n process.stdout.write(JSON.stringify(envelope, null, 2) + \"\\n\");\n});\n\n// Suppress Commander's default error output for missing args / unknown commands\nprogram.exitOverride();\nprogram.configureOutput({\n writeOut: () => {},\n writeErr: () => {},\n});\n\nregisterInspect(program);\nregisterValidate(program);\nregisterRender(program);\nregisterGuide(program);\nregisterSkill(program);\n\ntry {\n program.parse();\n} catch (err: unknown) {\n if (err instanceof CommanderError) {\n // Let --help and --version pass through normally\n if (err.code === \"commander.helpDisplayed\") {\n process.stdout.write(program.helpInformation());\n process.exit(0);\n }\n if (err.code === \"commander.version\") {\n process.stdout.write(program.version() + \"\\n\");\n process.exit(0);\n }\n const envelope = buildEnvelope({\n request_id: generateRequestId(),\n command: \"\",\n result: null,\n ok: false,\n errors: [\n {\n code: \"ERR_VALIDATION_INVALID_ARGS\",\n message: err.message,\n retryable: false,\n suggested_action: \"fix_input\",\n },\n ],\n duration_ms: 0,\n });\n process.exitCode = 10;\n process.stdout.write(JSON.stringify(envelope, null, 2) + \"\\n\");\n } else {\n throw err;\n }\n}\n","import type { StructuredError } from \"./errors.js\";\n\nexport interface Envelope<T> {\n schema_version: string;\n request_id: string;\n ok: boolean;\n command: string;\n target: Record<string, unknown> | null;\n result: T | null;\n warnings: StructuredError[];\n errors: StructuredError[];\n metrics: {\n duration_ms: number;\n [key: string]: unknown;\n };\n}\n\nexport function buildEnvelope<T>(opts: {\n request_id: string;\n command: string;\n target?: Record<string, unknown> | null;\n result: T | null;\n ok: boolean;\n warnings?: StructuredError[];\n errors?: StructuredError[];\n duration_ms: number;\n}): Envelope<T> {\n return {\n schema_version: \"1.0\",\n request_id: opts.request_id,\n ok: opts.ok,\n command: opts.command,\n target: opts.target ?? null,\n result: opts.result,\n warnings: opts.warnings ?? [],\n errors: opts.errors ?? [],\n metrics: { duration_ms: opts.duration_ms },\n };\n}\n","export interface StructuredError {\n code: string;\n message: string;\n retryable: boolean;\n suggested_action: \"retry\" | \"fix_input\" | \"escalate\";\n details?: Record<string, unknown>;\n}\n\nexport class CliError extends Error {\n constructor(public readonly structured: StructuredError) {\n super(structured.message);\n this.name = \"CliError\";\n }\n}\n\nexport function validationError(\n code: string,\n message: string,\n details?: Record<string, unknown>,\n): CliError {\n return new CliError({\n code: `ERR_VALIDATION_${code}`,\n message,\n retryable: false,\n suggested_action: \"fix_input\",\n details,\n });\n}\n\nexport function renderError(\n code: string,\n message: string,\n details?: Record<string, unknown>,\n): CliError {\n return new CliError({\n code: `ERR_RENDER_${code}`,\n message,\n retryable: false,\n suggested_action: \"escalate\",\n details,\n });\n}\n\nexport function ioError(\n code: string,\n message: string,\n details?: Record<string, unknown>,\n): CliError {\n return new CliError({\n code: `ERR_IO_${code}`,\n message,\n retryable: true,\n suggested_action: \"retry\",\n details,\n });\n}\n\nexport function internalError(\n message: string,\n details?: Record<string, unknown>,\n): CliError {\n return new CliError({\n code: \"ERR_INTERNAL_UNEXPECTED\",\n message,\n retryable: false,\n suggested_action: \"escalate\",\n details,\n });\n}\n\nexport function errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","export const ExitCode = {\n OK: 0,\n VALIDATION: 10,\n RENDER: 20,\n IO: 50,\n INTERNAL: 90,\n} as const;\n\nexport type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport function exitCodeForError(code: string): ExitCodeValue {\n if (code.startsWith(\"ERR_VALIDATION\")) return ExitCode.VALIDATION;\n if (code.startsWith(\"ERR_RENDER\")) return ExitCode.RENDER;\n if (code.startsWith(\"ERR_IO\")) return ExitCode.IO;\n return ExitCode.INTERNAL;\n}\n","import { randomBytes } from \"node:crypto\";\n\nexport function generateRequestId(): string {\n const now = new Date();\n const pad = (n: number, len = 2) => String(n).padStart(len, \"0\");\n const date = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`;\n const time = `${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;\n const rand = randomBytes(2).toString(\"hex\");\n return `req_${date}_${time}_${rand}`;\n}\n","export class Timer {\n private start: bigint;\n\n constructor() {\n this.start = process.hrtime.bigint();\n }\n\n elapsed(): number {\n const diff = process.hrtime.bigint() - this.start;\n return Number(diff / 1_000_000n);\n }\n}\n","import { buildEnvelope, type Envelope } from \"./envelope.js\";\nimport { CliError, internalError, errorMessage, type StructuredError } from \"./errors.js\";\nimport { exitCodeForError } from \"./exit-codes.js\";\nimport { generateRequestId } from \"./request-id.js\";\nimport { Timer } from \"./timer.js\";\n\nexport interface CommandContext {\n requestId: string;\n timer: Timer;\n warnings: StructuredError[];\n warn(warning: StructuredError): void;\n}\n\ntype CommandHandler<T> = (\n ctx: CommandContext,\n ...args: unknown[]\n) => Promise<{ result: T; target?: Record<string, unknown> | null }>;\n\nexport function wrapCommand<T>(\n command: string,\n handler: CommandHandler<T>,\n): (...args: unknown[]) => Promise<void> {\n return async (...args: unknown[]) => {\n const timer = new Timer();\n const requestId = generateRequestId();\n const warnings: StructuredError[] = [];\n const ctx: CommandContext = {\n requestId,\n timer,\n warnings,\n warn(w) {\n warnings.push(w);\n },\n };\n\n let envelope: Envelope<T>;\n try {\n const { result, target } = await handler(ctx, ...args);\n envelope = buildEnvelope<T>({\n request_id: requestId,\n command,\n target,\n result,\n ok: true,\n warnings,\n duration_ms: timer.elapsed(),\n });\n } catch (err: unknown) {\n const structured =\n err instanceof CliError\n ? err.structured\n : internalError(errorMessage(err)).structured;\n\n envelope = buildEnvelope<T>({\n request_id: requestId,\n command,\n result: null,\n ok: false,\n warnings,\n errors: [structured],\n duration_ms: timer.elapsed(),\n });\n process.exitCode = exitCodeForError(structured.code);\n }\n\n const json = JSON.stringify(envelope, null, 2) + \"\\n\";\n await new Promise<void>((resolve) => {\n process.stdout.write(json, () => resolve());\n });\n };\n}\n","import { z } from \"zod\";\n\nexport const ExcalidrawElementSchema = z\n .object({\n id: z.string(),\n type: z.string(),\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n isDeleted: z.boolean().optional().default(false),\n opacity: z.number().optional().default(100),\n groupIds: z.array(z.string()).optional().default([]),\n frameId: z.string().nullable().optional().default(null),\n boundElements: z\n .array(\n z.object({\n id: z.string(),\n type: z.string(),\n }),\n )\n .nullable()\n .optional()\n .default(null),\n // Text-specific\n text: z.string().optional(),\n fontSize: z.number().optional(),\n fontFamily: z.number().optional(),\n containerId: z.string().nullable().optional().default(null),\n // Arrow-specific\n startBinding: z\n .object({\n elementId: z.string(),\n focus: z.number(),\n gap: z.number(),\n })\n .nullable()\n .optional()\n .default(null),\n endBinding: z\n .object({\n elementId: z.string(),\n focus: z.number(),\n gap: z.number(),\n })\n .nullable()\n .optional()\n .default(null),\n // Image-specific\n fileId: z.string().nullable().optional().default(null),\n // Frame-specific\n name: z.string().nullable().optional().default(null),\n })\n .passthrough();\n\nexport type ExcalidrawElement = z.infer<typeof ExcalidrawElementSchema>;\n\nexport const ExcalidrawSceneSchema = z.object({\n type: z.string().optional().default(\"excalidraw\"),\n version: z.number().optional().default(2),\n source: z.string().optional(),\n elements: z.array(ExcalidrawElementSchema),\n appState: z.record(z.unknown()).optional().default({}),\n files: z.record(z.unknown()).optional().default({}),\n});\n\nexport type ExcalidrawScene = z.infer<typeof ExcalidrawSceneSchema>;\n","import { readFile, writeFile, rename, mkdir } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\nimport { ioError, errorMessage } from \"./errors.js\";\n\nexport interface ReadResult {\n content: string;\n source: string;\n}\n\nexport async function readInput(fileOrDash: string): Promise<ReadResult> {\n if (fileOrDash === \"-\") {\n return readStdin();\n }\n try {\n const content = await readFile(fileOrDash, \"utf-8\");\n return { content, source: fileOrDash };\n } catch (err: unknown) {\n const msg = errorMessage(err);\n throw ioError(\"READ_FAILED\", `Failed to read file: ${fileOrDash}: ${msg}`, {\n path: fileOrDash,\n });\n }\n}\n\nasync function readStdin(): Promise<ReadResult> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n process.stdin.on(\"data\", (chunk) => chunks.push(chunk));\n process.stdin.on(\"end\", () => {\n resolve({\n content: Buffer.concat(chunks).toString(\"utf-8\"),\n source: \"stdin\",\n });\n });\n process.stdin.on(\"error\", (err) => {\n reject(ioError(\"STDIN_FAILED\", `Failed to read stdin: ${err.message}`));\n });\n });\n}\n\nasync function ensureDir(dir: string): Promise<void> {\n await mkdir(dir, { recursive: true });\n}\n\nexport async function writeOutput(path: string, data: string | Buffer): Promise<void> {\n try {\n await ensureDir(dirname(path));\n const tmpPath = join(dirname(path), `.tmp_${randomBytes(4).toString(\"hex\")}`);\n await writeFile(tmpPath, data);\n await rename(tmpPath, path);\n } catch (err: unknown) {\n const msg = errorMessage(err);\n throw ioError(\"WRITE_FAILED\", `Failed to write file: ${path}: ${msg}`, {\n path,\n });\n }\n}\n","import { createHash } from \"node:crypto\";\n\nexport function sha256(data: string | Buffer): string {\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n","import { ExcalidrawSceneSchema, type ExcalidrawScene } from \"./schema.js\";\nimport { readInput } from \"../core/io.js\";\nimport { sha256 } from \"../core/fingerprint.js\";\nimport { validationError } from \"../core/errors.js\";\n\nexport interface LoadedScene {\n parsed: ExcalidrawScene;\n source: string;\n fingerprint: string;\n}\n\nexport async function loadScene(fileOrDash: string): Promise<LoadedScene> {\n const { content, source } = await readInput(fileOrDash);\n const fingerprint = sha256(content);\n\n let json: unknown;\n try {\n json = JSON.parse(content);\n } catch {\n throw validationError(\"INVALID_JSON\", \"Input is not valid JSON\", { source });\n }\n\n // Auto-detect format\n const parsed = detectAndParse(json, source);\n\n return { parsed, source, fingerprint };\n}\n\nfunction detectAndParse(json: unknown, source: string): ExcalidrawScene {\n // Clipboard format (check before full scene since it also has \"elements\")\n if (isObject(json) && json.type === \"excalidraw/clipboard\" && \"elements\" in json) {\n const sceneData = { ...json, type: \"excalidraw\" };\n const result = ExcalidrawSceneSchema.safeParse(sceneData);\n if (result.success) return result.data;\n throw validationError(\n \"INVALID_CLIPBOARD\",\n `Clipboard data validation failed: ${result.error.message}`,\n { source },\n );\n }\n\n // Full scene object\n if (isObject(json) && \"elements\" in json && Array.isArray(json.elements)) {\n const result = ExcalidrawSceneSchema.safeParse(json);\n if (result.success) return result.data;\n throw validationError(\"INVALID_SCENE\", `Scene validation failed: ${result.error.message}`, {\n source,\n issues: result.error.issues,\n });\n }\n\n // Elements-only array\n if (Array.isArray(json)) {\n const wrapped = { type: \"excalidraw\", version: 2, elements: json };\n const result = ExcalidrawSceneSchema.safeParse(wrapped);\n if (result.success) return result.data;\n throw validationError(\n \"INVALID_ELEMENTS\",\n `Elements array validation failed: ${result.error.message}`,\n { source, issues: result.error.issues },\n );\n }\n\n throw validationError(\"UNKNOWN_FORMAT\", \"Input is not a recognized Excalidraw format\", {\n source,\n });\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n","import type { ExcalidrawScene, ExcalidrawElement } from \"./schema.js\";\n\nexport interface SceneInspection {\n element_count: number;\n deleted_count: number;\n counts_by_type: Record<string, number>;\n deleted_counts_by_type: Record<string, number>;\n frames: FrameInfo[];\n images: ImageInfo[];\n text_stats: TextStats;\n bounding_box: BoundingBox | null;\n binary_files: BinaryFileInfo[];\n}\n\nexport interface FrameInfo {\n id: string;\n name: string | null;\n child_count: number;\n}\n\nexport interface ImageInfo {\n id: string;\n fileId: string | null;\n width: number;\n height: number;\n}\n\nexport interface TextStats {\n count: number;\n bound_count: number;\n unbound_count: number;\n}\n\nexport interface BoundingBox {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n width: number;\n height: number;\n}\n\nexport interface BinaryFileInfo {\n id: string;\n mimeType: string;\n size: number;\n}\n\nexport function inspectScene(scene: ExcalidrawScene): SceneInspection {\n const countsByType: Record<string, number> = {};\n const deletedCountsByType: Record<string, number> = {};\n const frameElements: ExcalidrawElement[] = [];\n const images: ImageInfo[] = [];\n const frameChildCounts = new Map<string, number>();\n let deletedCount = 0;\n let textCount = 0;\n let boundTextCount = 0;\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n let liveCount = 0;\n\n // Single pass over all elements\n for (const el of scene.elements) {\n if (el.isDeleted) {\n deletedCount++;\n deletedCountsByType[el.type] = (deletedCountsByType[el.type] ?? 0) + 1;\n continue;\n }\n liveCount++;\n countsByType[el.type] = (countsByType[el.type] ?? 0) + 1;\n\n // Bounding box\n minX = Math.min(minX, el.x);\n minY = Math.min(minY, el.y);\n maxX = Math.max(maxX, el.x + el.width);\n maxY = Math.max(maxY, el.y + el.height);\n\n // Frame child counting\n if (el.frameId) {\n frameChildCounts.set(el.frameId, (frameChildCounts.get(el.frameId) ?? 0) + 1);\n }\n\n // Collect frames\n if (el.type === \"frame\") {\n frameElements.push(el);\n }\n\n // Collect images\n if (el.type === \"image\") {\n images.push({ id: el.id, fileId: el.fileId, width: el.width, height: el.height });\n }\n\n // Text stats\n if (el.type === \"text\") {\n textCount++;\n if (el.containerId) boundTextCount++;\n }\n }\n\n const frames = frameElements.map((f) => ({\n id: f.id,\n name: f.name,\n child_count: frameChildCounts.get(f.id) ?? 0,\n }));\n\n const bounding_box =\n liveCount === 0\n ? null\n : { minX, minY, maxX, maxY, width: maxX - minX, height: maxY - minY };\n\n const binaryFiles: BinaryFileInfo[] = [];\n if (scene.files && typeof scene.files === \"object\") {\n for (const [id, file] of Object.entries(scene.files)) {\n if (isFileEntry(file)) {\n const size = typeof file.dataURL === \"string\" ? Math.round((file.dataURL.length * 3) / 4) : 0;\n binaryFiles.push({ id, mimeType: file.mimeType ?? \"unknown\", size });\n }\n }\n }\n\n return {\n element_count: liveCount,\n deleted_count: deletedCount,\n counts_by_type: countsByType,\n deleted_counts_by_type: deletedCountsByType,\n frames,\n images,\n text_stats: {\n count: textCount,\n bound_count: boundTextCount,\n unbound_count: textCount - boundTextCount,\n },\n bounding_box,\n binary_files: binaryFiles,\n };\n}\n\nfunction isFileEntry(v: unknown): v is { dataURL?: string; mimeType?: string } {\n return typeof v === \"object\" && v !== null;\n}\n","import type { ExcalidrawScene, ExcalidrawElement } from \"./schema.js\";\nimport type { StructuredError } from \"../core/errors.js\";\n\nexport interface FilterOptions {\n frameId?: string;\n frameName?: string;\n elementIds?: string[];\n includeDeleted?: boolean;\n}\n\nexport interface FilterResult {\n scene: ExcalidrawScene;\n warnings: StructuredError[];\n}\n\nexport function applyFilters(\n scene: ExcalidrawScene,\n opts: FilterOptions,\n): FilterResult {\n let elements = scene.elements;\n const warnings: StructuredError[] = [];\n\n // Filter deleted\n if (!opts.includeDeleted) {\n elements = elements.filter((e) => !e.isDeleted);\n }\n\n // Filter by frame\n if (opts.frameId) {\n // Try as ID first, then as name\n const hasById = elements.some((e) => e.id === opts.frameId || e.frameId === opts.frameId);\n if (hasById) {\n elements = filterByFrame(elements, opts.frameId);\n } else {\n // Fall back to name match\n const frame = elements.find(\n (e) => e.type === \"frame\" && e.name === opts.frameId,\n );\n if (frame) {\n elements = filterByFrame(elements, frame.id);\n } else {\n warnings.push({\n code: \"ERR_VALIDATION_FRAME_NOT_FOUND\",\n message: `Frame not found: \"${opts.frameId}\" does not match any frame ID or name`,\n retryable: false,\n suggested_action: \"fix_input\",\n });\n }\n }\n } else if (opts.frameName) {\n const frame = elements.find(\n (e) => e.type === \"frame\" && e.name === opts.frameName,\n );\n if (frame) {\n elements = filterByFrame(elements, frame.id);\n } else {\n warnings.push({\n code: \"ERR_VALIDATION_FRAME_NOT_FOUND\",\n message: `Frame not found: no frame with name \"${opts.frameName}\"`,\n retryable: false,\n suggested_action: \"fix_input\",\n });\n }\n }\n\n // Filter by element IDs\n if (opts.elementIds && opts.elementIds.length > 0) {\n const idSet = new Set(opts.elementIds);\n const before = elements.length;\n elements = elements.filter((e) => idSet.has(e.id));\n const missing = [...idSet].filter((id) => !elements.some((e) => e.id === id));\n if (missing.length > 0) {\n warnings.push({\n code: \"ERR_VALIDATION_ELEMENT_NOT_FOUND\",\n message: `Element IDs not found: ${missing.join(\", \")}`,\n retryable: false,\n suggested_action: \"fix_input\",\n details: { missing_ids: missing },\n });\n }\n }\n\n return { scene: { ...scene, elements }, warnings };\n}\n\nfunction filterByFrame(\n elements: ExcalidrawElement[],\n frameId: string,\n): ExcalidrawElement[] {\n // Include the frame itself plus all children\n return elements.filter((e) => e.id === frameId || e.frameId === frameId);\n}\n","import type { Command } from \"commander\";\nimport { wrapCommand } from \"../../core/command-wrapper.js\";\nimport { loadScene } from \"../../scene/load-scene.js\";\nimport { inspectScene } from \"../../scene/inspect-scene.js\";\nimport { applyFilters } from \"../../scene/filters.js\";\n\nexport function registerInspect(program: Command): void {\n program\n .command(\"inspect <file>\")\n .description(\"Inspect an Excalidraw scene and return metadata\")\n .option(\"--include-deleted\", \"Include deleted elements in inspection\")\n .option(\"--frame <id-or-name>\", \"Filter to a specific frame\")\n .action(\n wrapCommand(\"scene.inspect\", async (ctx, file: unknown, opts: unknown) => {\n const options = opts as { includeDeleted?: boolean; frame?: string };\n const fileStr = file as string;\n\n const loaded = await loadScene(fileStr);\n\n const { scene: filtered, warnings: filterWarnings } = applyFilters(loaded.parsed, {\n includeDeleted: options.includeDeleted,\n frameId: options.frame,\n });\n for (const w of filterWarnings) ctx.warn(w);\n\n const inspection = inspectScene(filtered);\n\n return {\n target: { file: loaded.source, fingerprint: loaded.fingerprint },\n result: inspection,\n };\n }),\n );\n}\n","import type { StructuredError } from \"../core/errors.js\";\nimport type { ExcalidrawScene } from \"./schema.js\";\n\nexport interface ValidationResult {\n valid: boolean;\n checks: ValidationCheck[];\n}\n\nexport interface ValidationCheck {\n name: string;\n passed: boolean;\n message?: string;\n}\n\nexport function validateScene(\n scene: ExcalidrawScene,\n opts: { checkAssets?: boolean } = {},\n): { result: ValidationResult; warnings: StructuredError[] } {\n const checks: ValidationCheck[] = [];\n const warnings: StructuredError[] = [];\n\n const elementMap = new Map(scene.elements.map((e) => [e.id, e]));\n const liveElements = scene.elements.filter((e) => !e.isDeleted);\n\n // Frame reference consistency\n {\n const orphans: string[] = [];\n for (const el of liveElements) {\n if (el.frameId && !elementMap.has(el.frameId)) {\n orphans.push(el.id);\n }\n }\n checks.push({\n name: \"frame_references\",\n passed: orphans.length === 0,\n message:\n orphans.length > 0\n ? `${orphans.length} element(s) reference non-existent frames`\n : undefined,\n });\n if (orphans.length > 0) {\n warnings.push({\n code: \"ERR_VALIDATION_FRAME_ORPHAN\",\n message: `Elements reference non-existent frames: ${orphans.join(\", \")}`,\n retryable: false,\n suggested_action: \"fix_input\",\n details: { element_ids: orphans },\n });\n }\n }\n\n // Bound text consistency\n {\n const broken: string[] = [];\n for (const el of liveElements) {\n if (el.type === \"text\" && el.containerId) {\n const container = elementMap.get(el.containerId);\n if (!container) {\n broken.push(el.id);\n } else if (container.boundElements) {\n const hasRef = container.boundElements.some(\n (b) => b.id === el.id && b.type === \"text\",\n );\n if (!hasRef) broken.push(el.id);\n }\n }\n }\n checks.push({\n name: \"bound_text\",\n passed: broken.length === 0,\n message:\n broken.length > 0\n ? `${broken.length} bound text element(s) have broken references`\n : undefined,\n });\n if (broken.length > 0) {\n warnings.push({\n code: \"ERR_VALIDATION_BOUND_TEXT\",\n message: `Bound text elements with broken references: ${broken.join(\", \")}`,\n retryable: false,\n suggested_action: \"fix_input\",\n details: { element_ids: broken },\n });\n }\n }\n\n // Arrow binding consistency\n {\n const broken: string[] = [];\n for (const el of liveElements) {\n if (el.type === \"arrow\") {\n if (el.startBinding && !elementMap.has(el.startBinding.elementId)) {\n broken.push(`${el.id}:start`);\n }\n if (el.endBinding && !elementMap.has(el.endBinding.elementId)) {\n broken.push(`${el.id}:end`);\n }\n }\n }\n checks.push({\n name: \"arrow_bindings\",\n passed: broken.length === 0,\n message:\n broken.length > 0\n ? `${broken.length} arrow binding(s) reference non-existent elements`\n : undefined,\n });\n if (broken.length > 0) {\n warnings.push({\n code: \"ERR_VALIDATION_ARROW_BINDING\",\n message: `Broken arrow bindings: ${broken.join(\", \")}`,\n retryable: false,\n suggested_action: \"fix_input\",\n details: { bindings: broken },\n });\n }\n }\n\n // Image file references\n if (opts.checkAssets) {\n const missing: string[] = [];\n for (const el of liveElements) {\n if (el.type === \"image\" && el.fileId) {\n if (!scene.files || !(el.fileId in scene.files)) {\n missing.push(el.id);\n }\n }\n }\n checks.push({\n name: \"image_assets\",\n passed: missing.length === 0,\n message:\n missing.length > 0\n ? `${missing.length} image(s) reference missing binary files`\n : undefined,\n });\n if (missing.length > 0) {\n warnings.push({\n code: \"ERR_VALIDATION_MISSING_ASSET\",\n message: `Images with missing file data: ${missing.join(\", \")}`,\n retryable: false,\n suggested_action: \"fix_input\",\n details: { element_ids: missing },\n });\n }\n }\n\n // Unknown element types (warning only)\n {\n const knownTypes = new Set([\n \"rectangle\",\n \"diamond\",\n \"ellipse\",\n \"arrow\",\n \"line\",\n \"freedraw\",\n \"text\",\n \"image\",\n \"frame\",\n \"group\",\n \"embeddable\",\n \"iframe\",\n \"magicframe\",\n ]);\n const unknownTypes = new Set<string>();\n for (const el of liveElements) {\n if (!knownTypes.has(el.type)) unknownTypes.add(el.type);\n }\n if (unknownTypes.size > 0) {\n warnings.push({\n code: \"ERR_VALIDATION_UNKNOWN_TYPE\",\n message: `Unknown element types: ${[...unknownTypes].join(\", \")}`,\n retryable: false,\n suggested_action: \"fix_input\",\n details: { types: [...unknownTypes] },\n });\n }\n }\n\n const valid = checks.every((c) => c.passed);\n return { result: { valid, checks }, warnings };\n}\n","import type { Command } from \"commander\";\nimport { wrapCommand } from \"../../core/command-wrapper.js\";\nimport { loadScene } from \"../../scene/load-scene.js\";\nimport { validateScene } from \"../../scene/validate-scene.js\";\n\nexport function registerValidate(program: Command): void {\n program\n .command(\"validate <file>\")\n .description(\"Validate an Excalidraw scene for structural consistency\")\n .option(\"--check-assets\", \"Verify image file references exist\")\n .action(\n wrapCommand(\"scene.validate\", async (ctx, file: unknown, opts: unknown) => {\n const options = opts as { checkAssets?: boolean };\n const fileStr = file as string;\n\n const loaded = await loadScene(fileStr);\n const { result, warnings } = validateScene(loaded.parsed, {\n checkAssets: options.checkAssets,\n });\n\n for (const w of warnings) ctx.warn(w);\n\n return {\n target: { file: loaded.source, fingerprint: loaded.fingerprint },\n result,\n };\n }),\n );\n}\n","import { basename, extname } from \"node:path\";\nimport type { Command } from \"commander\";\nimport { wrapCommand, type CommandContext } from \"../../core/command-wrapper.js\";\nimport { loadScene } from \"../../scene/load-scene.js\";\nimport { normalizeScene } from \"../../scene/normalize-scene.js\";\nimport { applyFilters } from \"../../scene/filters.js\";\nimport { inspectScene } from \"../../scene/inspect-scene.js\";\nimport { RenderBridge } from \"../../render/render-bridge.js\";\nimport type { ExportResult } from \"../../render/export-common.js\";\nimport { exportSvg } from \"../../render/export-svg.js\";\nimport { exportPng } from \"../../render/export-png.js\";\nimport { exportPdf } from \"../../render/export-pdf.js\";\n\ninterface RenderOptions {\n outDir: string;\n svg: boolean;\n png: boolean;\n pdf: boolean;\n darkMode: boolean;\n background: boolean;\n scale: string;\n padding: string;\n frame?: string;\n element?: string;\n dryRun: boolean;\n}\n\nexport function registerRender(program: Command): void {\n program\n .command(\"render <file>\")\n .description(\"Render an Excalidraw scene to SVG, PNG, or PDF\")\n .option(\"--outDir <dir>\", \"Output directory\", \".\")\n .option(\"--svg\", \"Export SVG\")\n .option(\"--png\", \"Export PNG (requires Playwright)\")\n .option(\"--pdf\", \"Export PDF (requires Playwright)\")\n .option(\"--dark-mode\", \"Use dark theme\")\n .option(\"--no-background\", \"Transparent background\")\n .option(\"--scale <n>\", \"Scale factor for PNG output only\", \"2\")\n .option(\"--padding <n>\", \"Padding in pixels\", \"20\")\n .option(\"--frame <id-or-name>\", \"Export specific frame only\")\n .option(\"--element <id>\", \"Export specific element only\")\n .option(\"--dry-run\", \"Run pipeline but write no files\")\n .action(\n wrapCommand(\"scene.render\", async (ctx: CommandContext, file: unknown, opts: unknown) => {\n const options = opts as RenderOptions;\n const fileStr = file as string;\n\n const loaded = await loadScene(fileStr);\n const normalized = normalizeScene(loaded.parsed);\n\n const { scene: filtered, warnings: filterWarnings } = applyFilters(normalized, {\n frameId: options.frame,\n frameName: options.frame,\n elementIds: options.element ? [options.element] : undefined,\n });\n for (const w of filterWarnings) ctx.warn(w);\n\n const inspection = inspectScene(filtered);\n\n // Determine formats\n const formats = {\n svg: options.svg || (!options.png && !options.pdf),\n png: options.png || false,\n pdf: options.pdf || false,\n };\n\n const scale = parseFloat(options.scale);\n\n // Warn if --scale is set to non-default and only SVG is selected\n if (scale !== 2 && formats.svg && !formats.png && !formats.pdf) {\n ctx.warn({\n code: \"ERR_VALIDATION_SCALE_IGNORED\",\n message: \"--scale has no effect on SVG output; it only applies to PNG\",\n retryable: false,\n suggested_action: \"fix_input\",\n });\n }\n\n // Build appState overrides\n const appState: Record<string, unknown> = { ...filtered.appState };\n if (options.darkMode) appState.exportWithDarkMode = true;\n if (!options.background) appState.exportBackground = false;\n\n const sceneForExport = { ...filtered, appState };\n\n // Base name from input file\n const baseName =\n loaded.source === \"stdin\"\n ? \"scene\"\n : basename(loaded.source, extname(loaded.source));\n\n const shared = {\n bridge: undefined as unknown as RenderBridge,\n scene: sceneForExport,\n outDir: options.outDir,\n baseName,\n dryRun: options.dryRun,\n exportPadding: parseInt(options.padding, 10),\n };\n\n // Initialize bridge\n const bridge = new RenderBridge();\n shared.bridge = bridge;\n try {\n await bridge.initialize();\n\n const artefacts: ExportResult[] = [];\n\n if (formats.svg) {\n artefacts.push(await exportSvg(shared));\n }\n\n if (formats.png) {\n artefacts.push(\n await exportPng({ ...shared, scale }),\n );\n }\n\n if (formats.pdf) {\n artefacts.push(await exportPdf(shared));\n }\n\n return {\n target: { file: loaded.source, fingerprint: loaded.fingerprint },\n result: {\n artefacts,\n scene_summary: {\n element_count: inspection.element_count,\n bounding_box: inspection.bounding_box,\n fingerprint: loaded.fingerprint,\n },\n dry_run: options.dryRun || false,\n },\n };\n } finally {\n await bridge.dispose();\n }\n }),\n );\n}\n","import type { ExcalidrawScene, ExcalidrawElement } from \"./schema.js\";\n\nfunction deterministicSeed(id: string): number {\n let hash = 0;\n for (let i = 0; i < id.length; i++) {\n hash = ((hash << 5) - hash + id.charCodeAt(i)) | 0;\n }\n return Math.abs(hash);\n}\n\nexport function normalizeScene(scene: ExcalidrawScene): ExcalidrawScene {\n const elements = scene.elements.map(normalizeElement);\n // Stable ordering: by type, then by y, then by x, then by id\n elements.sort((a, b) => {\n if (a.type !== b.type) return a.type.localeCompare(b.type);\n if (a.y !== b.y) return a.y - b.y;\n if (a.x !== b.x) return a.x - b.x;\n return a.id.localeCompare(b.id);\n });\n\n return { ...scene, elements };\n}\n\nfunction normalizeElement(el: ExcalidrawElement): ExcalidrawElement {\n const raw = el as Record<string, unknown>;\n const result: Record<string, unknown> = {\n ...el,\n isDeleted: el.isDeleted ?? false,\n opacity: el.opacity ?? 100,\n groupIds: el.groupIds ?? [],\n frameId: el.frameId ?? null,\n boundElements: el.boundElements ?? null,\n containerId: el.containerId ?? null,\n startBinding: el.startBinding ?? null,\n endBinding: el.endBinding ?? null,\n fileId: el.fileId ?? null,\n name: el.name ?? null,\n // Properties required by @excalidraw/utils for rendering\n angle: (raw.angle as number) ?? 0,\n strokeColor: (raw.strokeColor as string) ?? \"#1e1e1e\",\n backgroundColor: (raw.backgroundColor as string) ?? \"transparent\",\n fillStyle: (raw.fillStyle as string) ?? \"solid\",\n strokeWidth: (raw.strokeWidth as number) ?? 2,\n strokeStyle: (raw.strokeStyle as string) ?? \"solid\",\n roughness: (raw.roughness as number) ?? 1,\n roundness: raw.roundness ?? null,\n seed: (raw.seed as number) ?? deterministicSeed(el.id),\n version: (raw.version as number) ?? 1,\n versionNonce: (raw.versionNonce as number) ?? 1,\n updated: (raw.updated as number) ?? Date.now(),\n link: (raw.link as string | null) ?? null,\n locked: (raw.locked as boolean) ?? false,\n };\n\n // Arrows and lines require a points array\n if ((el.type === \"arrow\" || el.type === \"line\" || el.type === \"freedraw\") && !raw.points) {\n result.points = [[0, 0], [el.width, el.height]];\n }\n\n // Text elements require font/layout properties for rendering\n if (el.type === \"text\") {\n result.fontSize = (raw.fontSize as number) ?? 20;\n result.fontFamily = (raw.fontFamily as number) ?? 1;\n result.textAlign = (raw.textAlign as string) ?? \"left\";\n result.verticalAlign = (raw.verticalAlign as string) ?? \"top\";\n result.lineHeight = (raw.lineHeight as number) ?? 1.25;\n result.originalText = (raw.originalText as string) ?? (raw.text as string) ?? \"\";\n result.baseline = (raw.baseline as number) ?? 0;\n }\n\n return result as ExcalidrawElement;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport async function generateBridgeHtml(): Promise<string> {\n // Resolve bridge script relative to this file's dist location\n const thisDir = dirname(fileURLToPath(import.meta.url));\n const bridgePath = resolve(thisDir, \"..\", \"render\", \"bridge.global.js\");\n\n let bridgeScript: string;\n try {\n bridgeScript = await readFile(bridgePath, \"utf-8\");\n } catch {\n // Fallback: try relative to cwd dist\n const fallbackPath = resolve(process.cwd(), \"dist\", \"render\", \"bridge.global.js\");\n bridgeScript = await readFile(fallbackPath, \"utf-8\");\n }\n\n return `<!DOCTYPE html>\n<html>\n<head><meta charset=\"utf-8\"></head>\n<body>\n<script>${bridgeScript}</script>\n<script>\n window.__bridgeReady = typeof window.__excalidrawExport !== 'undefined' && window.__excalidrawExport.ready;\n</script>\n</body>\n</html>`;\n}\n","import { renderError, errorMessage } from \"../core/errors.js\";\nimport { generateBridgeHtml } from \"./bridge-page.js\";\n\ninterface SceneData {\n elements: unknown[];\n appState?: Record<string, unknown>;\n files?: Record<string, unknown>;\n exportPadding?: number;\n}\n\nexport class RenderBridge {\n private browser: any = null;\n private page: any = null;\n private bridgeHtml: string | null = null;\n\n async initialize(): Promise<void> {\n let pw: any;\n try {\n pw = await import(\"playwright\");\n } catch {\n throw renderError(\n \"BROWSER_UNAVAILABLE\",\n \"Playwright is not installed. Install it with: npm install playwright\",\n );\n }\n\n this.browser = await pw.chromium.launch({ headless: true });\n const context = await this.browser.newContext();\n this.page = await context.newPage();\n\n // Route font requests to local @excalidraw/excalidraw dist if available\n try {\n await import(\"@excalidraw/excalidraw\");\n const { resolve, dirname } = await import(\"node:path\");\n const { readFile } = await import(\"node:fs/promises\");\n const { createRequire } = await import(\"node:module\");\n const require = createRequire(import.meta.url);\n const excalidrawDir = dirname(require.resolve(\"@excalidraw/excalidraw/package.json\"));\n\n await this.page.route(\"**/*.woff2\", async (route: any) => {\n try {\n const url = new URL(route.request().url());\n const fontName = url.pathname.split(\"/\").pop();\n if (fontName) {\n const fontPath = resolve(excalidrawDir, \"dist\", \"excalidraw-assets\", fontName);\n const body = await readFile(fontPath);\n await route.fulfill({ body, contentType: \"font/woff2\" });\n return;\n }\n } catch {\n // Fall through to abort\n }\n await route.abort();\n });\n } catch {\n // @excalidraw/excalidraw not installed, fonts won't be routed\n }\n\n this.bridgeHtml = await generateBridgeHtml();\n await this.page.setContent(this.bridgeHtml);\n\n // Wait for bridge to be ready\n await this.page.waitForFunction(\"window.__bridgeReady === true\", {\n timeout: 10_000,\n });\n }\n\n async exportSvg(sceneData: SceneData): Promise<string> {\n if (!this.page) throw renderError(\"EXPORT_FAILED\", \"Bridge not initialized\");\n\n try {\n const svgString: string = await this.page.evaluate(\n async (data: SceneData) => {\n return (window as any).__excalidrawExport.exportToSvg(data);\n },\n sceneData,\n );\n return svgString;\n } catch (err: unknown) {\n throw renderError(\"EXPORT_FAILED\", `SVG export failed: ${errorMessage(err)}`);\n }\n }\n\n async exportPng(sceneData: SceneData, scale = 2): Promise<Buffer> {\n if (!this.page) throw renderError(\"EXPORT_FAILED\", \"Bridge not initialized\");\n\n try {\n const base64: string = await this.page.evaluate(\n async (data: { scene: SceneData; scale: number }) => {\n const appState = { ...data.scene.appState, exportScale: data.scale };\n return (window as any).__excalidrawExport.exportToBlob({\n ...data.scene,\n appState,\n });\n },\n { scene: sceneData, scale },\n );\n return Buffer.from(base64, \"base64\");\n } catch (err: unknown) {\n throw renderError(\"EXPORT_FAILED\", `PNG export failed: ${errorMessage(err)}`);\n }\n }\n\n async exportPdf(sceneData: SceneData): Promise<Buffer> {\n if (!this.page) throw renderError(\"EXPORT_FAILED\", \"Bridge not initialized\");\n\n try {\n // Render SVG into page, then use page.pdf()\n const svgString = await this.exportSvg(sceneData);\n\n await this.page.setContent(`<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<style>\n body { margin: 0; display: flex; justify-content: center; align-items: center; }\n svg { max-width: 100%; height: auto; }\n</style>\n</head>\n<body>${svgString}</body>\n</html>`);\n\n const pdf = await this.page.pdf({\n preferCSSPageSize: true,\n printBackground: true,\n });\n\n // Re-load cached bridge HTML for subsequent calls\n if (this.bridgeHtml) {\n await this.page.setContent(this.bridgeHtml);\n await this.page.waitForFunction(\"window.__bridgeReady === true\", {\n timeout: 10_000,\n });\n }\n\n return Buffer.from(pdf);\n } catch (err: unknown) {\n if (err instanceof Error && err.message.includes(\"ERR_RENDER\")) throw err;\n throw renderError(\"EXPORT_FAILED\", `PDF export failed: ${errorMessage(err)}`);\n }\n }\n\n async dispose(): Promise<void> {\n if (this.browser) {\n await this.browser.close();\n this.browser = null;\n this.page = null;\n this.bridgeHtml = null;\n }\n }\n}\n","import type { RenderBridge } from \"./render-bridge.js\";\nimport type { ExcalidrawScene } from \"../scene/schema.js\";\nimport { writeOutput } from \"../core/io.js\";\nimport { join } from \"node:path\";\n\nexport interface ExportOptions {\n bridge: RenderBridge;\n scene: ExcalidrawScene;\n outDir: string;\n baseName: string;\n dryRun: boolean;\n exportPadding?: number;\n}\n\nexport interface ExportResult {\n type: string;\n path: string;\n bytes: number;\n}\n\ninterface FormatOptions extends ExportOptions {\n ext: string;\n render: (\n bridge: RenderBridge,\n sceneData: { elements: unknown[]; appState: unknown; files: unknown; exportPadding?: number },\n ) => Promise<{ data: string | Buffer; bytes: number }>;\n}\n\nexport async function exportFormat(opts: FormatOptions): Promise<ExportResult> {\n const sceneData = {\n elements: opts.scene.elements,\n appState: opts.scene.appState,\n files: opts.scene.files,\n exportPadding: opts.exportPadding,\n };\n\n const { data, bytes } = await opts.render(opts.bridge, sceneData);\n const path = join(opts.outDir, `${opts.baseName}.${opts.ext}`).replace(/\\\\/g, \"/\");\n\n if (!opts.dryRun) {\n await writeOutput(path, data);\n }\n\n return { type: opts.ext, path, bytes };\n}\n","import type { RenderBridge } from \"./render-bridge.js\";\nimport type { ExportOptions, ExportResult } from \"./export-common.js\";\nimport { exportFormat } from \"./export-common.js\";\n\nexport type SvgExportResult = ExportResult & { type: \"svg\" };\n\nexport async function exportSvg(opts: ExportOptions): Promise<SvgExportResult> {\n return exportFormat({\n ...opts,\n ext: \"svg\",\n render: async (bridge, sceneData) => {\n const svg = await bridge.exportSvg(sceneData);\n return { data: svg, bytes: Buffer.byteLength(svg, \"utf-8\") };\n },\n }) as Promise<SvgExportResult>;\n}\n","import type { ExportOptions, ExportResult } from \"./export-common.js\";\nimport { exportFormat } from \"./export-common.js\";\n\nexport type PngExportResult = ExportResult & { type: \"png\" };\n\nexport async function exportPng(\n opts: ExportOptions & { scale: number },\n): Promise<PngExportResult> {\n return exportFormat({\n ...opts,\n ext: \"png\",\n render: async (bridge, sceneData) => {\n const buf = await bridge.exportPng(sceneData, opts.scale);\n return { data: buf, bytes: buf.length };\n },\n }) as Promise<PngExportResult>;\n}\n","import type { ExportOptions, ExportResult } from \"./export-common.js\";\nimport { exportFormat } from \"./export-common.js\";\n\nexport type PdfExportResult = ExportResult & { type: \"pdf\" };\n\nexport async function exportPdf(opts: ExportOptions): Promise<PdfExportResult> {\n return exportFormat({\n ...opts,\n ext: \"pdf\",\n render: async (bridge, sceneData) => {\n const buf = await bridge.exportPdf(sceneData);\n return { data: buf, bytes: buf.length };\n },\n }) as Promise<PdfExportResult>;\n}\n","export function getGuideContent(): string {\n return `# excal — CLI Guide\n\nAgent-first CLI for Excalidraw scene inspection, validation, and rendering.\n\n## Commands\n\n### excal inspect <file|->\n\nInspect an Excalidraw scene and return element counts, bounds, and metadata.\n\n| Flag | Description |\n|------|-------------|\n| \\`--include-deleted\\` | Include deleted elements |\n| \\`--frame <id\\\\|name>\\` | Filter to a specific frame |\n\n\\`\\`\\`bash\nexcal inspect diagram.excalidraw\ncat scene.json | excal inspect -\n\\`\\`\\`\n\n### excal validate <file|->\n\nValidate scene structure: frame refs, bound text, arrow bindings, assets.\n\n| Flag | Description |\n|------|-------------|\n| \\`--check-assets\\` | Verify image file references exist in scene |\n\n\\`\\`\\`bash\nexcal validate diagram.excalidraw\nexcal validate diagram.excalidraw --check-assets\n\\`\\`\\`\n\n### excal render <file|->\n\nRender scene to SVG, PNG, or PDF. PNG/PDF require Playwright.\n\n| Flag | Description |\n|------|-------------|\n| \\`--outDir <dir>\\` | Output directory (default: .) |\n| \\`--svg\\` | Export SVG (default if no format specified) |\n| \\`--png\\` | Export PNG (requires Playwright) |\n| \\`--pdf\\` | Export PDF (requires Playwright) |\n| \\`--dark-mode\\` | Use dark theme |\n| \\`--no-background\\` | Transparent background |\n| \\`--scale <n>\\` | Scale factor for PNG output only (default: 2) |\n| \\`--padding <n>\\` | Padding in pixels (default: 20) |\n| \\`--frame <id\\\\|name>\\` | Export specific frame only |\n| \\`--element <id>\\` | Export specific element only |\n| \\`--dry-run\\` | Run pipeline but write no files |\n\n\\`\\`\\`bash\nexcal render diagram.excalidraw --outDir ./out\nexcal render diagram.excalidraw --outDir ./out --png --pdf\nexcal render - --outDir ./out < scene.json\n\\`\\`\\`\n\n### excal guide\n\nOutput this CLI guide as Markdown.\n\n### excal skill\n\nReturn Excalidraw domain knowledge for AI agents.\n\n## Error Codes\n\n| Code | Exit | Description |\n|------|------|-------------|\n| \\`ERR_VALIDATION_INVALID_JSON\\` | 10 | Input is not valid JSON |\n| \\`ERR_VALIDATION_INVALID_SCENE\\` | 10 | Scene structure validation failed |\n| \\`ERR_VALIDATION_UNKNOWN_FORMAT\\` | 10 | Input is not a recognized format |\n| \\`ERR_RENDER_BROWSER_UNAVAILABLE\\` | 20 | Playwright not installed |\n| \\`ERR_RENDER_EXPORT_FAILED\\` | 20 | Export failed in browser bridge |\n| \\`ERR_IO_READ_FAILED\\` | 50 | Failed to read input file |\n| \\`ERR_IO_WRITE_FAILED\\` | 50 | Failed to write output file |\n| \\`ERR_INTERNAL_UNEXPECTED\\` | 90 | Unexpected internal error |\n\n## Response Envelope\n\nEvery command returns a JSON envelope on stdout:\n\n\\`\\`\\`jsonc\n{\n \"schema_version\": \"1.0\",\n \"request_id\": \"req_20260302_143000_7f3a\",\n \"ok\": true, // always present\n \"command\": \"scene.inspect\",\n \"target\": { ... }, // what was acted on (null for global commands)\n \"result\": { ... }, // command payload (null on failure)\n \"warnings\": [], // always an array\n \"errors\": [], // always an array\n \"metrics\": { \"duration_ms\": 42 }\n}\n\\`\\`\\`\n\n- \\`errors\\` and \\`warnings\\` are always arrays (possibly empty), never omitted.\n- \\`result\\` is always present; on failure it is \\`null\\`.\n- Each error carries \\`code\\`, \\`message\\`, \\`retryable\\`, and \\`suggested_action\\`.\n- **Note on \\`validate\\`**: \\`ok: true\\` means the command executed successfully, not that the scene is valid. Check \\`result.valid\\` (boolean) for scene validity, and \\`result.issues\\` / \\`warnings\\` for details.\n\n## Concurrency\n\n- **Reads** (inspect, validate): safe to run concurrently.\n- **Renders**: each invocation launches its own browser; safe to parallelize.\n`;\n}\n","import type { Command } from \"commander\";\nimport { wrapCommand } from \"../../core/command-wrapper.js\";\nimport { getGuideContent } from \"../../guide/guide-schema.js\";\n\nexport function registerGuide(program: Command): void {\n program\n .command(\"guide\")\n .description(\"Return CLI guide as Markdown for agent bootstrapping\")\n .action(\n wrapCommand(\"cli.guide\", async () => {\n return { result: { content: getGuideContent(), format: \"markdown\" } };\n }),\n );\n}\n","export function getSkillContent(): string {\n return `# Excalidraw Scene Structure — Agent Guide\n\n## File Format\n\nExcalidraw scenes are JSON files (typically \\`.excalidraw\\`) with this structure:\n\n\\`\\`\\`json\n{\n \"type\": \"excalidraw\",\n \"version\": 2,\n \"source\": \"https://excalidraw.com\",\n \"elements\": [ ... ],\n \"appState\": { ... },\n \"files\": { ... }\n}\n\\`\\`\\`\n\n## Element Types\n\n| Type | Description |\n|------|-------------|\n| rectangle | Box shape |\n| diamond | Diamond/rhombus shape |\n| ellipse | Circle/ellipse shape |\n| arrow | Arrow connector |\n| line | Line/polyline |\n| freedraw | Freehand drawing |\n| text | Text label |\n| image | Embedded image |\n| frame | Grouping frame |\n\n## Key Element Properties\n\nEvery element has: \\`id\\`, \\`type\\`, \\`x\\`, \\`y\\`, \\`width\\`, \\`height\\`, \\`isDeleted\\`, \\`opacity\\`, \\`groupIds\\`, \\`frameId\\`.\n\n## Frames\n\nFrames group elements visually. Elements inside a frame have \\`frameId\\` set to the frame's \\`id\\`. Frames themselves have \\`type: \"frame\"\\` and an optional \\`name\\`.\n\nTo export a single frame: use \\`--frame <id|name>\\`.\n\n## Bound Text\n\nText can be bound to a container (rectangle, diamond, ellipse). The text element has \\`containerId\\` pointing to the container, and the container has a \\`boundElements\\` entry with \\`{ id, type: \"text\" }\\`.\n\n## Arrows & Bindings\n\nArrows connect elements via \\`startBinding\\` and \\`endBinding\\`:\n\\`\\`\\`json\n{\n \"startBinding\": { \"elementId\": \"target-id\", \"focus\": 0, \"gap\": 1 },\n \"endBinding\": { \"elementId\": \"target-id\", \"focus\": 0, \"gap\": 1 }\n}\n\\`\\`\\`\n\n## Images & Binary Files\n\nImage elements have \\`fileId\\` referencing an entry in \\`files\\`. The files object maps IDs to \\`{ mimeType, dataURL }\\` where dataURL is base64-encoded.\n\n## Export Tips\n\n- SVG export inlines fonts; no external dependencies\n- PNG/PDF require Playwright for headless browser rendering\n- Use \\`--scale 2\\` (default) for crisp PNG exports\n- Use \\`--dark-mode\\` for dark theme exports\n- Use \\`--no-background\\` for transparent backgrounds\n- \\`--dry-run\\` validates the full pipeline without writing files\n\n## Common Patterns\n\n1. **Inspect before modifying**: Always run \\`excal inspect\\` to understand scene structure\n2. **Validate after changes**: Run \\`excal validate --check-assets\\` to catch broken references\n3. **Frame-based export**: Use frames to organize sections, export individually with \\`--frame\\`\n4. **Deterministic output**: Same input + same options = same output (for CI/CD)\n`;\n}\n","import type { Command } from \"commander\";\nimport { wrapCommand } from \"../../core/command-wrapper.js\";\nimport { getSkillContent } from \"../../guide/skill-content.js\";\n\nexport function registerSkill(program: Command): void {\n program\n .command(\"skill\")\n .description(\"Return Excalidraw domain knowledge for AI agents\")\n .action(\n wrapCommand(\"cli.skill\", async () => {\n return { result: { content: getSkillContent(), format: \"markdown\" } };\n }),\n );\n}\n"],"mappings":"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","names":["resolve","randomBytes","resolve","randomBytes","program","program","readFile","dirname","resolve","dirname","readFile","require","join","program","program","program"]}