@hoardodile/cli 0.1.10 → 0.1.12

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/dist/main.js CHANGED
@@ -1253,11 +1253,13 @@ async function executeDev(opts) {
1253
1253
  // the user's storage root.
1254
1254
  cacheDir: join(pluginDir, ".hoardodile", "cache")
1255
1255
  });
1256
- const { serveWorkbench } = await loadWorkbenchServe(pluginDir);
1256
+ const { serveWorkbench, createRebuildBus } = await loadWorkbenchServe(pluginDir);
1257
+ const rebuildBus = createRebuildBus();
1257
1258
  let workbenchUrl = `http://127.0.0.1:${opts.port}`;
1258
1259
  const server = await serveWorkbench({
1259
1260
  pluginDir: distDir,
1260
1261
  port: opts.port,
1262
+ rebuildBus,
1261
1263
  onReady: (url) => {
1262
1264
  workbenchUrl = url;
1263
1265
  },
@@ -1283,6 +1285,7 @@ async function executeDev(opts) {
1283
1285
  const captured = snapshots?.captured() ?? [];
1284
1286
  snapshots?.invalidate();
1285
1287
  for (const resId of captured) void snapshots?.refresh(resId);
1288
+ rebuildBus.emit({ kind: "rebuild" });
1286
1289
  });
1287
1290
  } else {
1288
1291
  console.error(
@@ -1295,6 +1298,7 @@ async function executeDev(opts) {
1295
1298
  stopDistWatch?.();
1296
1299
  watcher.kill();
1297
1300
  source?.close?.();
1301
+ rebuildBus.close();
1298
1302
  server.close(() => resolveStop());
1299
1303
  };
1300
1304
  process.once("SIGINT", stop);
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runner.ts","../src/bench.ts","../src/template-lint.ts","../src/build.ts","../src/create.ts","../src/hook-snapshot.ts","../src/render-providers.ts","../src/storage.ts","../src/dev.ts","../src/package.ts","../src/main.ts"],"names":["pluginManifestSchema","readFileSync","err","join","existsSync","issue","resolve","readdirSync","copyFileSync","createRequire","spawn","watch","mkdirSync","rmSync","writeFile","createHash","HOOK_NAMES","mkdtempSync","tmpdir","createPluginSandbox","DEFAULT_SANDBOX_CONFIG","dirname","statSync","pathToFileURL","ok"],"mappings":"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","file":"main.js","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\"\nimport { dirname, join, resolve } from \"node:path\"\nimport {\n\tbuildRegistry,\n\tcreateDirectoryContainer,\n\tcreatePluginHooks,\n\tcreatePluginResourceAPI,\n\tcreateProbeCache,\n\tHOOK_NAMES,\n\ttype HookName,\n\ttype PluginHooks,\n\ttype PluginSandbox,\n\ttype ResourceAPI,\n} from \"@hoardodile/host\"\nimport { mediaProbes } from \"@hoardodile/host/probe\"\nimport {\n\terr,\n\tok,\n\ttype PluginManifest,\n\ttype PluginManifestId,\n\ttype Result,\n} from \"@hoardodile/sdk-types\"\nimport { pluginManifest as pluginManifestSchema } from \"@hoardodile/sdk-types/schema\"\n\n/** Exit codes: 0 pass, 1 regression, 2 error. */\nexport const EXIT_PASS = 0\nexport const EXIT_REGRESSION = 1\nexport const EXIT_ERROR = 2\n\nexport class CliError extends Error {}\n\n/** Plugin hooks the CLI can run, in contract order (see {@link HOOK_NAMES}). */\nexport type CliHookName = HookName\n\n/**\n * Fallback manifest for `--main`-only invocations (no manifest.json\n * next to the bundle). Capability gating then denies every permission —\n * use `--plugin-dir` to exercise gated hooks.\n */\nconst FALLBACK_ID: PluginManifestId = \"00000000-0000-4000-8000-000000000000\"\n\nexport type PluginTarget = {\n\treadonly id: PluginManifestId\n\treadonly manifest: PluginManifest\n\treadonly mainPath: string\n\treadonly dirPath: string\n}\n\nexport function resolvePluginTarget(opts: {\n\treadonly main?: string\n\treadonly pluginDir?: string\n}): PluginTarget {\n\tconst dirPath =\n\t\topts.pluginDir !== undefined\n\t\t\t? resolve(opts.pluginDir)\n\t\t\t: opts.main !== undefined\n\t\t\t\t? dirname(resolve(opts.main))\n\t\t\t\t: undefined\n\tif (dirPath === undefined) {\n\t\tthrow new CliError(\"provide --plugin-dir <dir> or --main <main.js>\")\n\t}\n\tconst mainPath =\n\t\topts.main !== undefined ? resolve(opts.main) : join(dirPath, \"main.js\")\n\tif (!existsSync(mainPath)) {\n\t\tthrow new CliError(`plugin main.js not found: ${mainPath}`)\n\t}\n\n\tconst manifestPath = join(dirPath, \"manifest.json\")\n\tlet manifest: PluginManifest\n\tif (existsSync(manifestPath)) {\n\t\tconst parsed = pluginManifestSchema.safeParse(\n\t\t\tJSON.parse(readFileSync(manifestPath, \"utf-8\")),\n\t\t)\n\t\tif (!parsed.success) {\n\t\t\tthrow new CliError(\n\t\t\t\t`invalid manifest.json at ${manifestPath}: ${parsed.error.message}`,\n\t\t\t)\n\t\t}\n\t\tmanifest = parsed.data\n\t} else {\n\t\tmanifest = {\n\t\t\tid: FALLBACK_ID,\n\t\t\tname: \"cli-plugin\",\n\t\t\tdescription: \"CLI-invoked plugin without a manifest.json\",\n\t\t\tversion: \"0.0.0\",\n\t\t\tpermissions: {\n\t\t\t\tsourceMeta: false,\n\t\t\t\tsearchMeta: false,\n\t\t\t\tdanmaku: false,\n\t\t\t\tmessage: false,\n\t\t\t\timageHashes: false,\n\t\t\t\tcontainer: false,\n\t\t\t\tdownload: false,\n\t\t\t},\n\t\t}\n\t}\n\treturn { id: manifest.id, manifest, mainPath, dirPath }\n}\n\n/**\n * One process-wide probe cache for the CLI: a hook that sniffs then\n * probes the same entry (or probes it repeatedly) resolves from memory\n * instead of re-reading the header — the same behaviour the server gets\n * from its per-resource cache. Scoped per directory so distinct\n * fixtures never collide.\n */\nconst cliProbeCache = createProbeCache()\n\n/**\n * The {@link ResourceAPI} the CLI hands to hooks: a directory container\n * with the real probe implementations — identical to what the server\n * wires for its import path. `extractCacheDir` lets `extractArchive`\n * materialize archives next to the fixture during `plugin run`/`dev`.\n */\nexport function buildCliResourceAPI(\n\tdir: string,\n\topts: { readonly extractCacheDir?: string } = {},\n): ResourceAPI {\n\treturn createPluginResourceAPI({\n\t\tview: createDirectoryContainer(dir),\n\t\t...mediaProbes,\n\t\textractCacheDir: opts.extractCacheDir,\n\t\tprobeCache: cliProbeCache,\n\t\tcacheScope: `cli:${dir}`,\n\t})\n}\n\n/**\n * The {@link ResourceAPI} over a resource's bare-file source folder —\n * the exact container the server reads in production, so a hook\n * captured against a real library behaves identically.\n */\nexport function buildArchiveResourceAPI(\n\tresourceDir: string,\n\textractCacheDir?: string,\n): ResourceAPI {\n\treturn createPluginResourceAPI({\n\t\tview: createDirectoryContainer(resourceDir),\n\t\t...mediaProbes,\n\t\textractCacheDir,\n\t\tprobeCache: cliProbeCache,\n\t\tcacheScope: `cli:${resourceDir}`,\n\t})\n}\n\n/**\n * Single-plugin registry + hook facade over the worker sandbox. The\n * strategy layer (capability gating, error swallowing, result\n * validation) is exactly what the server runs.\n */\nexport async function createCliHooks(\n\ttarget: PluginTarget,\n\tsandbox: PluginSandbox,\n): Promise<PluginHooks> {\n\tconst plugin = await sandbox.loadPlugin({\n\t\tid: target.id,\n\t\tmainPath: target.mainPath,\n\t\teager: true,\n\t})\n\tif (plugin === undefined) {\n\t\tthrow new CliError(`plugin failed to load: ${target.mainPath}`)\n\t}\n\tconst registry = buildRegistry([\n\t\t{\n\t\t\tid: target.id,\n\t\t\tmanifest: target.manifest,\n\t\t\tenabled: true,\n\t\t\tpriority: 0,\n\t\t\tpinned: false,\n\t\t\tcolor: \"\",\n\t\t\tmissing: false,\n\t\t\tbuiltin: false,\n\t\t\tdev: false,\n\t\t\tplugin,\n\t\t\tdiskPath: target.dirPath,\n\t\t},\n\t])\n\treturn createPluginHooks({ getRegistry: () => registry })\n}\n\nexport type HookOutcome = Result<\n\t{ readonly result: unknown; readonly durationMs: number },\n\t{ readonly result: string; readonly durationMs: number }\n>\n\n/**\n * Run one hook through the strategy facade. Errors are surfaced on\n * `ok:false` (the facade normally swallows them — `--in-process` raises\n * them instead for debugging).\n */\nexport async function runCliHook(opts: {\n\treadonly id: PluginManifestId\n\treadonly hooks: PluginHooks\n\treadonly hook: CliHookName\n\treadonly dir: string\n\t/** Writable dir for `extractArchive` materialization. */\n\treadonly extractCacheDir?: string\n}): Promise<HookOutcome> {\n\tconst api = buildCliResourceAPI(opts.dir, {\n\t\textractCacheDir: opts.extractCacheDir,\n\t})\n\tconst started = performance.now()\n\tlet result: unknown\n\ttry {\n\t\tswitch (opts.hook) {\n\t\t\tcase \"detect\":\n\t\t\t\tresult = await opts.hooks.detectForPlugin(api, opts.id)\n\t\t\t\tbreak\n\t\t\tcase \"sourceMeta\":\n\t\t\t\tresult = (await opts.hooks.runMetaHooks(api, opts.id)).sourceMeta?.value\n\t\t\t\tbreak\n\t\t\tcase \"searchMeta\":\n\t\t\t\tresult = (await opts.hooks.runMetaHooks(api, opts.id)).searchMeta?.value\n\t\t\t\tbreak\n\t\t\tcase \"coverLocal\":\n\t\t\t\tresult = await opts.hooks.resolveLocalCoverSource(api, opts.id)\n\t\t\t\tbreak\n\t\t\tcase \"listFiles\":\n\t\t\t\tresult = await opts.hooks.buildFileList(api, opts.id)\n\t\t\t\tbreak\n\t\t}\n\t} catch (caught) {\n\t\treturn err({\n\t\t\tresult: caught instanceof Error ? caught.message : String(caught),\n\t\t\tdurationMs: performance.now() - started,\n\t\t})\n\t}\n\treturn ok({ result, durationMs: performance.now() - started })\n}\n","import { readFileSync, writeFileSync } from \"node:fs\"\nimport os from \"node:os\"\nimport type { PluginManifestId } from \"@hoardodile/sdk-types\"\nimport {\n\ttype CliHookName,\n\tEXIT_ERROR,\n\tEXIT_PASS,\n\tEXIT_REGRESSION,\n\ttype HookOutcome,\n} from \"./runner.ts\"\n\n/**\n * Benchmark contract for hook-duration measurement and regression\n * comparison. The report shape matches the server-side bench suites in\n * apps/server/bench: the same machine fingerprint, memory peak, warmup\n * semantics, threshold gating and exit codes. See the `bench` command\n * docs.\n */\n\nexport type BenchStats = {\n\treadonly medianMs: number\n\treadonly meanMs: number\n\treadonly p95Ms: number\n\treadonly minMs: number\n\treadonly maxMs: number\n}\n\n/** Machine fingerprint used to gate baseline comparisons. */\nexport type MachineInfo = {\n\treadonly platform: string\n\treadonly arch: string\n\treadonly cpus: number\n\treadonly cpuModel: string\n\treadonly node: string\n}\n\nexport type BenchReport = {\n\treadonly schema: 1\n\treadonly kind: \"plugin-hook\"\n\treadonly timestamp: string\n\treadonly config: {\n\t\treadonly pluginId: PluginManifestId\n\t\treadonly hook: CliHookName\n\t\treadonly dir: string\n\t\treadonly repeat: number\n\t\treadonly warmupRuns: number\n\t}\n\treadonly machine: MachineInfo\n\treadonly caveats: readonly string[]\n\t/** Peak host RSS observed across the measured runs. */\n\treadonly memoryPeakMb: number\n\treadonly samplesMs: readonly number[]\n\treadonly stats: BenchStats\n}\n\nexport type BenchOptions = {\n\treadonly repeat: number\n\t/** Discarded warmup runs before the measured samples. Default 1. */\n\treadonly warmupRuns: number\n\t/** Fail (exit 1) when the median exceeds baseline × (1 + threshold/100). */\n\treadonly thresholdPercent: number\n}\n\nconst DEFAULT_WARMUP_RUNS = 1\n\nexport function machineInfo(): MachineInfo {\n\treturn {\n\t\tplatform: os.platform(),\n\t\tarch: os.arch(),\n\t\tcpus: os.cpus().length,\n\t\tcpuModel: os.cpus()[0]?.model ?? \"unknown\",\n\t\tnode: process.version,\n\t}\n}\n\nfunction fingerprint(machine: MachineInfo): string {\n\treturn [\n\t\tmachine.platform,\n\t\tmachine.arch,\n\t\tmachine.cpus,\n\t\tmachine.cpuModel,\n\t\tmachine.node,\n\t].join(\"|\")\n}\n\n/** One warmup run is discarded so worker spawn and lazy loads never pollute samples. */\nexport function computeBenchReport(opts: {\n\treadonly pluginId: PluginManifestId\n\treadonly hook: CliHookName\n\treadonly dir: string\n\treadonly repeat: number\n\treadonly warmupRuns: number\n\treadonly run: () => Promise<HookOutcome>\n}): Promise<BenchReport> {\n\treturn (async () => {\n\t\tfor (let i = 0; i < opts.warmupRuns; i++) {\n\t\t\tawait opts.run()\n\t\t}\n\t\tconst samples: number[] = []\n\t\tlet peakRss = 0\n\t\tfor (let i = 0; i < opts.repeat; i++) {\n\t\t\tconst outcome = await opts.run()\n\t\t\tsamples.push(outcome.durationMs)\n\t\t\tpeakRss = Math.max(peakRss, process.memoryUsage().rss)\n\t\t}\n\t\treturn {\n\t\t\tschema: 1,\n\t\t\tkind: \"plugin-hook\",\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tconfig: {\n\t\t\t\tpluginId: opts.pluginId,\n\t\t\t\thook: opts.hook,\n\t\t\t\tdir: opts.dir,\n\t\t\t\trepeat: opts.repeat,\n\t\t\t\twarmupRuns: opts.warmupRuns,\n\t\t\t},\n\t\t\tmachine: machineInfo(),\n\t\t\tcaveats: [\n\t\t\t\t\"Baselines are only valid on the same machine and environment — absolute sandbox timings (worker + protocol + probes) are not comparable across machines.\",\n\t\t\t],\n\t\t\tmemoryPeakMb: Math.round((peakRss / 1024 / 1024) * 10) / 10,\n\t\t\tsamplesMs: samples,\n\t\t\tstats: computeStats(samples),\n\t\t}\n\t})()\n}\n\nexport function computeStats(samples: readonly number[]): BenchStats {\n\tconst sorted = [...samples].sort((a, b) => a - b)\n\tconst median = sorted[Math.floor(sorted.length / 2)] ?? 0\n\tconst mean = samples.reduce((a, b) => a + b, 0) / Math.max(1, samples.length)\n\tconst p95 =\n\t\tsorted[Math.min(sorted.length - 1, Math.floor(sorted.length * 0.95))] ?? 0\n\treturn {\n\t\tmedianMs: round1(median),\n\t\tmeanMs: round1(mean),\n\t\tp95Ms: round1(p95),\n\t\tminMs: round1(sorted[0] ?? 0),\n\t\tmaxMs: round1(sorted[sorted.length - 1] ?? 0),\n\t}\n}\n\nexport function loadBaseline(path: string): BenchReport {\n\tlet parsed: unknown\n\ttry {\n\t\tparsed = JSON.parse(readFileSync(path, \"utf-8\"))\n\t} catch (err) {\n\t\tthrow new Error(\n\t\t\t`cannot read baseline file ${path}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t)\n\t}\n\tif (!isBenchReport(parsed)) {\n\t\tthrow new Error(\n\t\t\t`baseline file ${path} is not a bench report (kind plugin-hook)`,\n\t\t)\n\t}\n\treturn parsed\n}\n\nfunction isBenchReport(value: unknown): value is BenchReport {\n\tif (typeof value !== \"object\" || value === null) return false\n\tconst v = value as Record<string, unknown>\n\tif (v.schema !== 1) return false\n\tif (v.kind !== \"plugin-hook\") return false\n\tif (typeof v.timestamp !== \"string\") return false\n\tconst config = v.config\n\tif (\n\t\ttypeof config !== \"object\" ||\n\t\tconfig === null ||\n\t\ttypeof (config as Record<string, unknown>).pluginId !== \"string\" ||\n\t\ttypeof (config as Record<string, unknown>).hook !== \"string\"\n\t) {\n\t\treturn false\n\t}\n\tconst machine = v.machine\n\tif (\n\t\ttypeof machine !== \"object\" ||\n\t\tmachine === null ||\n\t\ttypeof (machine as Record<string, unknown>).node !== \"string\"\n\t) {\n\t\treturn false\n\t}\n\tconst stats = v.stats\n\treturn (\n\t\ttypeof stats === \"object\" &&\n\t\tstats !== null &&\n\t\ttypeof (stats as Record<string, unknown>).medianMs === \"number\"\n\t)\n}\n\nexport type CompareResult = {\n\treadonly baseline: BenchReport\n\treadonly ratio: number\n\treadonly regressed: boolean\n\treadonly message: string\n}\n\n/** Compare a fresh report against a baseline; exit 1 on regression. */\nexport function compareBaseline(\n\treport: BenchReport,\n\tbaseline: BenchReport,\n\tthresholdPercent: number,\n): CompareResult {\n\tif (fingerprint(report.machine) !== fingerprint(baseline.machine)) {\n\t\tconsole.warn(\n\t\t\t`WARNING: baseline machine differs (fresh: ${fingerprint(report.machine)} vs baseline: ${fingerprint(baseline.machine)}) — sandbox timings are not comparable across machines.`,\n\t\t)\n\t}\n\tconst ratio =\n\t\treport.stats.medianMs / Math.max(0.0001, baseline.stats.medianMs)\n\tconst regressed =\n\t\treport.stats.medianMs >\n\t\tbaseline.stats.medianMs * (1 + thresholdPercent / 100)\n\tconst delta = ((ratio - 1) * 100).toFixed(1)\n\tconst message = regressed\n\t\t? `REGRESSION: median ${report.stats.medianMs}ms vs baseline ${baseline.stats.medianMs}ms (${delta}%) exceeds the ${thresholdPercent}% threshold. Baselines are only valid on the same machine and environment — absolute sandbox timings (worker + protocol + probes) are not comparable across machines.`\n\t\t: `median ${report.stats.medianMs}ms vs baseline ${baseline.stats.medianMs}ms (${delta}%) — within the ${thresholdPercent}% threshold.`\n\treturn { baseline, ratio, regressed, message }\n}\n\nexport function writeReport(path: string, report: BenchReport): void {\n\twriteFileSync(path, `${JSON.stringify(report, null, 2)}\\n`)\n}\n\nexport function formatBenchSummary(report: BenchReport): string {\n\tconst lines = [\n\t\t`hook ${report.config.hook} × ${report.config.repeat} (${report.config.warmupRuns} warmup)`,\n\t\t`plugin ${report.config.pluginId}`,\n\t\t`machine ${report.machine.platform}/${report.machine.arch} · ${report.machine.cpus} cpus (${report.machine.cpuModel}) · node ${report.machine.node} · peak rss ${report.memoryPeakMb}MB`,\n\t\t`samples: ${report.samplesMs.map((ms) => `${ms.toFixed(1)}ms`).join(\" \")}`,\n\t\t`median ${report.stats.medianMs}ms · mean ${report.stats.meanMs}ms · p95 ${report.stats.p95Ms}ms · min ${report.stats.minMs}ms · max ${report.stats.maxMs}ms`,\n\t]\n\treturn lines.join(\"\\n\")\n}\n\nexport function benchExitCode(compare: CompareResult | undefined): number {\n\tif (compare === undefined) return EXIT_PASS\n\treturn compare.regressed ? EXIT_REGRESSION : EXIT_PASS\n}\n\nexport { DEFAULT_WARMUP_RUNS, EXIT_ERROR }\n\nfunction round1(value: number): number {\n\treturn Math.round(value * 10) / 10\n}\n","import type { PluginManifest } from \"@hoardodile/sdk-types\"\nimport {\n\tparseTemplateExpression,\n\tparseTemplateFragments,\n\ttype TemplateArg,\n\ttype TemplateExpr,\n\ttokeniseExpression,\n} from \"@hoardodile/sdk-types/template\"\n\n/**\n * Build-time validation of the manifest's host-rendered template\n * strings (`ui.card` corners, `ui.search` labels/icons, `ui.message`\n * anchors). Runs the same grammar the web renderer evaluates — shared\n * from `@hoardodile/sdk-types/template` — so a template that passes here\n * renders in the app, and the mistakes that would silently render\n * empty covers (malformed expressions, unbalanced parentheses,\n * unknown functions, undeclared i18n keys) fail the build.\n */\n\n/** Function names the host's template engine recognizes. */\nconst KNOWN_FUNCTIONS = new Set([\n\t\"asset\",\n\t\"bytes\",\n\t\"duration\",\n\t\"eq\",\n\t\"gt\",\n\t\"gte\",\n\t\"icon\",\n\t\"if\",\n\t\"inc\",\n\t\"join\",\n\t\"kind\",\n\t\"lt\",\n\t\"lte\",\n\t\"ne\",\n\t\"number\",\n\t\"searchKindIcons\",\n\t\"t\",\n])\n\nexport type TemplateLintIssue = {\n\treadonly template: string\n\treadonly message: string\n}\n\n/**\n * Validate one template string. Returns a list of problems; empty\n * means the template is well-formed.\n */\nexport function lintTemplate(\n\ttemplate: string,\n\ti18nKeys: ReadonlySet<string>,\n): readonly TemplateLintIssue[] {\n\tconst issues: TemplateLintIssue[] = []\n\n\tconst open = (template.match(/\\{\\{/g) ?? []).length\n\tconst close = (template.match(/\\}\\}/g) ?? []).length\n\tif (open !== close) {\n\t\treturn [\n\t\t\t{\n\t\t\t\ttemplate,\n\t\t\t\tmessage: `unbalanced {{ }} braces (${open} open, ${close} close)`,\n\t\t\t},\n\t\t]\n\t}\n\n\tfor (const fragment of parseTemplateFragments(template)) {\n\t\tif (fragment.kind !== \"expr\") continue\n\t\tlintExpression(fragment.source, template, i18nKeys, issues)\n\t}\n\treturn issues\n}\n\nfunction lintExpression(\n\tsource: string,\n\ttemplate: string,\n\ti18nKeys: ReadonlySet<string>,\n\tissues: TemplateLintIssue[],\n): void {\n\tconst tokens = tokeniseExpression(source)\n\tconst opens = tokens.filter((t) => t.kind === \"lparen\").length\n\tconst closes = tokens.filter((t) => t.kind === \"rparen\").length\n\tif (opens !== closes) {\n\t\tissues.push({\n\t\t\ttemplate,\n\t\t\tmessage: `unbalanced parentheses in {{${source}}} (${opens} open, ${closes} close)`,\n\t\t})\n\t\treturn\n\t}\n\tconst expr = parseTemplateExpression(source)\n\tif (expr === undefined) {\n\t\tissues.push({\n\t\t\ttemplate,\n\t\t\tmessage: `cannot parse expression \"{{${source}}}\" (expected a call or path)`,\n\t\t})\n\t\treturn\n\t}\n\twalkExpr(expr, (call) => {\n\t\tif (!KNOWN_FUNCTIONS.has(call.name)) {\n\t\t\tissues.push({\n\t\t\t\ttemplate,\n\t\t\t\tmessage: `unknown function \"${call.name}\" (known: ${[...KNOWN_FUNCTIONS].join(\", \")})`,\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tif (call.name === \"t\") {\n\t\t\tconst key = firstStringArg(call.args)\n\t\t\tif (key !== undefined && !i18nKeys.has(key)) {\n\t\t\t\tissues.push({\n\t\t\t\t\ttemplate,\n\t\t\t\t\tmessage: `t('${key}') references an i18n key the manifest does not declare`,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t})\n}\n\n/** Visit every call node of the AST, nested calls included. */\nfunction walkExpr(\n\texpr: TemplateExpr,\n\tvisit: (call: Extract<TemplateExpr, { readonly kind: \"call\" }>) => void,\n): void {\n\tif (expr.kind !== \"call\") return\n\tvisit(expr)\n\tfor (const arg of expr.args) {\n\t\tif (arg.kind === \"expr\") walkExpr(arg.expr, visit)\n\t}\n}\n\n/** First string literal argument of `fn('...', ...)`, if any. */\nfunction firstStringArg(args: readonly TemplateArg[]): string | undefined {\n\tconst first = args[0]\n\tif (first?.kind === \"string\") return first.value\n\treturn undefined\n}\n\n/** Collect every template string the manifest declares. */\nexport function manifestTemplates(manifest: PluginManifest): readonly string[] {\n\tconst templates: string[] = []\n\tfor (const block of Object.values(manifest.ui?.card ?? {})) {\n\t\tif (block === undefined) continue\n\t\tfor (const corner of [block.tl, block.tr, block.bl, block.br]) {\n\t\t\tif (corner !== undefined) templates.push(...corner)\n\t\t}\n\t}\n\tfor (const kind of manifest.ui?.search?.kinds ?? []) {\n\t\ttemplates.push(kind.label)\n\t\tif (kind.icon !== undefined) templates.push(kind.icon)\n\t}\n\tif (manifest.ui?.message?.anchor !== undefined) {\n\t\ttemplates.push(manifest.ui.message.anchor)\n\t}\n\treturn templates\n}\n\n/**\n * Lint every template in the manifest. Returns the declared i18n keys\n * plus the issues found; callers decide how strict to be.\n */\nexport function lintManifestTemplates(manifest: PluginManifest): {\n\treadonly templates: readonly string[]\n\treadonly issues: readonly TemplateLintIssue[]\n} {\n\tconst templates = manifestTemplates(manifest)\n\t// `i18n` maps label key → { locale: label } (the host's template\n\t// engine looks up `manifest.i18n[key]` then resolves the locale).\n\tconst i18nKeys = new Set(Object.keys(manifest.i18n ?? {}))\n\tconst issues: TemplateLintIssue[] = []\n\tfor (const template of templates) {\n\t\tissues.push(...lintTemplate(template, i18nKeys))\n\t}\n\treturn { templates, issues }\n}\n","import {\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trmSync,\n\twatch,\n} from \"node:fs\"\nimport { join } from \"node:path\"\nimport type { PluginManifest } from \"@hoardodile/sdk-types\"\nimport babel from \"@rolldown/plugin-babel\"\nimport tailwindcss from \"@tailwindcss/vite\"\nimport react, { reactCompilerPreset } from \"@vitejs/plugin-react\"\nimport { build } from \"vite\"\nimport { lintManifestTemplates } from \"./template-lint.ts\"\n\ntype BuildResult = Awaited<ReturnType<typeof build>>\n\n/** In watch mode vite's `build()` returns a live watcher instead of a bundle. */\nfunction isWatcher(\n\tresult: BuildResult,\n): result is Extract<BuildResult, { on: unknown }> {\n\treturn \"on\" in result\n}\n\n/**\n * Build a plugin from `dir` (must contain `manifest.json` and optionally\n * `src/main.ts` / `index.html`). Output goes to `dir/dist/`.\n *\n * Pass `watch: true` to rebuild on file changes instead of exiting.\n */\nexport async function buildPlugin(\n\tdir: string,\n\topts: { readonly watch: boolean },\n): Promise<void> {\n\tconst watchMode = opts.watch\n\tconst manifestPath = join(dir, \"manifest.json\")\n\tif (!existsSync(manifestPath)) {\n\t\tthrow new Error(`No manifest.json found in ${dir}`)\n\t}\n\n\tconst manifest = JSON.parse(readFileSync(manifestPath, \"utf-8\"))\n\tif (typeof manifest.id !== \"string\" || manifest.id.length === 0) {\n\t\tthrow new Error(\"manifest.json missing id field\")\n\t}\n\tlintTemplates(manifest as PluginManifest)\n\n\tconst outDir = join(dir, \"dist\")\n\n\tif (!watchMode) {\n\t\trmSync(outDir, { recursive: true, force: true })\n\t}\n\tmkdirSync(outDir, { recursive: true })\n\n\tconst htmlEntry = join(dir, \"index.html\")\n\tconst mainEntry = join(dir, \"src\", \"main.ts\")\n\n\tif (existsSync(htmlEntry)) {\n\t\tconst result = await build({\n\t\t\troot: dir,\n\t\t\tbase: \"./\",\n\t\t\t// React Compiler only on the iframe client build; the server\n\t\t\t// (SSR) bundle runs in a worker sandbox with no rendering.\n\t\t\tplugins: [\n\t\t\t\treact(),\n\t\t\t\tbabel({ presets: [reactCompilerPreset()] }),\n\t\t\t\ttailwindcss(),\n\t\t\t],\n\t\t\tbuild: {\n\t\t\t\toutDir,\n\t\t\t\temptyOutDir: false,\n\t\t\t\tchunkSizeWarningLimit: Infinity,\n\t\t\t\trollupOptions: {\n\t\t\t\t\tinput: htmlEntry,\n\t\t\t\t},\n\t\t\t\twatch: watchMode ? {} : null,\n\t\t\t},\n\t\t})\n\t\tif (watchMode && isWatcher(result)) {\n\t\t\tresult.on(\"event\", (event) => {\n\t\t\t\tif (event.code === \"END\") {\n\t\t\t\t\tconsole.log(`[watch] ${manifest.id} client rebuilt`)\n\t\t\t\t} else if (event.code === \"ERROR\") {\n\t\t\t\t\tconsole.error(`[watch] ${manifest.id} client error:`, event.error)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\tif (existsSync(mainEntry)) {\n\t\tconst result = await build({\n\t\t\troot: dir,\n\t\t\tplugins: [react()],\n\t\t\t// The server bundle runs inside the permission-model sandbox,\n\t\t\t// which grants fs-read to the plugin dir only and lets the module\n\t\t\t// policy gate load nothing outside it — the bundle must be one\n\t\t\t// self-contained ESM file. Vite's default externalizes\n\t\t\t// node_modules dependencies, which is exactly what an installed\n\t\t\t// (tarball/npm) plugin hits: its `main.js` would keep bare\n\t\t\t// `@hoardodile/*` imports whose resolution the sandbox denies.\n\t\t\t// Inline everything instead (workspace plugins already ended up\n\t\t\t// inlined via source resolution — this makes both cases uniform).\n\t\t\tssr: { noExternal: true },\n\t\t\tbuild: {\n\t\t\t\tssr: mainEntry,\n\t\t\t\toutDir,\n\t\t\t\temptyOutDir: false,\n\t\t\t\ttarget: \"node24\",\n\t\t\t\trollupOptions: {\n\t\t\t\t\toutput: {\n\t\t\t\t\t\tentryFileNames: \"main.js\",\n\t\t\t\t\t\tchunkFileNames: \"[name].js\",\n\t\t\t\t\t},\n\t\t\t\t\texternal: [],\n\t\t\t\t},\n\t\t\t\twatch: watchMode ? {} : null,\n\t\t\t},\n\t\t})\n\t\tassertSelfContainedServerBundle(join(outDir))\n\t\tif (watchMode && isWatcher(result)) {\n\t\t\tresult.on(\"event\", (event) => {\n\t\t\t\tif (event.code === \"END\") {\n\t\t\t\t\tassertSelfContainedServerBundle(join(outDir))\n\t\t\t\t\tconsole.log(`[watch] ${manifest.id} server rebuilt`)\n\t\t\t\t} else if (event.code === \"ERROR\") {\n\t\t\t\t\tconsole.error(`[watch] ${manifest.id} server error:`, event.error)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\tcopyFileSync(manifestPath, join(outDir, \"manifest.json\"))\n\n\tif (watchMode) {\n\t\twatch(manifestPath, () => {\n\t\t\tcopyFileSync(manifestPath, join(outDir, \"manifest.json\"))\n\t\t\tconsole.log(`[watch] ${manifest.id} manifest updated`)\n\t\t})\n\t\tconsole.log(`[watch] ${manifest.id} watching for changes...`)\n\t\tawait new Promise(() => {})\n\t}\n\tconsole.log(`${manifest.id} → ${outDir}`)\n}\n\n/**\n * Fail the build on malformed cover/search/message templates, warn on\n * i18n keys the manifest never declares. A bad template renders a\n * silent empty cover — catching it here beats discovering it in the\n * app.\n */\nfunction lintTemplates(manifest: PluginManifest): void {\n\tconst { templates, issues } = lintManifestTemplates(manifest)\n\tif (templates.length === 0) return\n\tconst errors = issues.filter((issue) => !issue.message.includes(\"i18n key\"))\n\tif (errors.length > 0) {\n\t\tconst detail = errors\n\t\t\t.map((issue) => ` - ${issue.message}\\n ${issue.template}`)\n\t\t\t.join(\"\\n\")\n\t\tthrow new Error(`manifest template validation failed:\\n${detail}`)\n\t}\n\tfor (const issue of issues.filter((issue) =>\n\t\tissue.message.includes(\"i18n key\"),\n\t)) {\n\t\tconsole.warn(`[build] warning: ${issue.message}\\n ${issue.template}`)\n\t}\n}\n\n/**\n * Fail the build when the server bundle is not self-contained. The\n * plugin main process runs in a capability sandbox whose only privileged\n * interface is the host's ResourceAPI RPC: its fs-read grant is the\n * plugin dir, and its module policy gate allows no bare imports — so\n * `node:` imports, `require` and any specifier that must resolve outside\n * the bundle never have a legitimate home in it. (The Vite SSR build\n * inlines the SDK closure via `ssr.noExternal`; this check is an early,\n * friendly error if that ever regresses.)\n */\nfunction assertSelfContainedServerBundle(outDir: string): void {\n\tfor (const file of readdirSync(outDir, { withFileTypes: true })) {\n\t\tif (!file.isFile() || !file.name.endsWith(\".js\")) continue\n\t\tconst source = readFileSync(join(outDir, file.name), \"utf-8\")\n\t\t// Computed specifiers (`import(\"node:\" + x)`) slip past a static\n\t\t// scan by design — the runtime policy gate still denies them.\n\t\tif (/(?:from\\s*[\"']node:|import\\s*\\(\\s*[\"']node:)/.test(source)) {\n\t\t\tthrow new Error(\n\t\t\t\t`plugin main bundle (${file.name}) imports a Node builtin — the plugin main process cannot use node:fs/net/child_process/…; read files and probe metadata through the ResourceAPI instead`,\n\t\t\t)\n\t\t}\n\t\tif (/\\brequire\\s*\\(/.test(source)) {\n\t\t\tthrow new Error(\n\t\t\t\t`plugin main bundle (${file.name}) calls require() — the plugin main process is self-contained; use the ResourceAPI instead`,\n\t\t\t)\n\t\t}\n\t\t// Bare specifiers (anything that is not a relative/absolute path)\n\t\t// resolve through node_modules — outside the sandbox's fs-read\n\t\t// grant. The build keeps them only when a dependency was left\n\t\t// external, which can never load in the sandbox.\n\t\tif (/(?:from\\s*[\"']|import\\s*\\(\\s*[\"'])(?![./])/.test(source)) {\n\t\t\tthrow new Error(\n\t\t\t\t`plugin main bundle (${file.name}) leaves a bare import unresolved — the SDK closure must be inlined; the plugin sandbox cannot load node_modules`,\n\t\t\t)\n\t\t}\n\t}\n}\n","import { spawn } from \"node:child_process\"\nimport { EXIT_ERROR } from \"./runner.ts\"\n\nexport type CreateOptions = {\n\treadonly name?: string\n\treadonly tarballs?: string\n}\n\n/**\n * `hoardodile plugin create` — facade over the published scaffolder.\n * `create-hoardodile-plugin` stays its own package (npm's `create-*`\n * convention), so this runs it via `pnpm dlx` and forwards the args.\n */\nexport function resolveCreateArgs(opts: CreateOptions): string[] {\n\tconst args = [\"dlx\", \"--yes\", \"create-hoardodile-plugin\"]\n\tif (opts.name !== undefined) args.push(opts.name)\n\tif (opts.tarballs !== undefined) args.push(\"--tarballs\", opts.tarballs)\n\treturn args\n}\n\nexport async function executeCreate(opts: CreateOptions): Promise<number> {\n\treturn new Promise((resolveExit) => {\n\t\tconst child = spawn(\"pnpm\", resolveCreateArgs(opts), {\n\t\t\tstdio: \"inherit\",\n\t\t\tshell: process.platform === \"win32\",\n\t\t})\n\t\tchild.on(\"error\", (err) => {\n\t\t\tconsole.error(\n\t\t\t\t`[hoardodile] failed to start create-hoardodile-plugin: ${err.message}`,\n\t\t\t)\n\t\t\tresolveExit(EXIT_ERROR)\n\t\t})\n\t\tchild.on(\"exit\", (code) => {\n\t\t\tresolveExit(code ?? EXIT_ERROR)\n\t\t})\n\t})\n}\n","import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\nimport {\n\tcreatePluginSandbox,\n\tDEFAULT_SANDBOX_CONFIG,\n\ttype PluginHooks,\n\ttype ResourceAPI,\n} from \"@hoardodile/host\"\nimport type { FileStats, PluginManifest } from \"@hoardodile/sdk-types\"\nimport { pluginManifest as pluginManifestSchema } from \"@hoardodile/sdk-types/schema\"\nimport type { PluginTarget } from \"./runner.ts\"\nimport { CliError, createCliHooks } from \"./runner.ts\"\n\n/**\n * The server-side hook results the iframe needs to render exactly like\n * production: the host pushes `sourceMeta`, `searchMeta` and `fileStats`\n * into the plugin context, and answers `listFiles` with the plugin's own\n * hook output. `hoardodile plugin dev` captures them from the real\n * sandbox so the workbench is a faithful stand-in for the app.\n *\n * `errors` records hooks that threw; the facade swallows failures, so\n * without this a broken hook is indistinguishable from an absent one.\n */\nexport type PluginHookSnapshot = {\n\treadonly pluginId: string\n\treadonly detect: {\n\t\treadonly ok: boolean\n\t\treadonly reasons?: readonly string[]\n\t}\n\treadonly sourceMeta: unknown\n\treadonly searchMeta: unknown\n\treadonly coverLocal: string | undefined\n\t/**\n\t * The resource's cover kind (`image` | `video` | `audio`), sniffed\n\t * from the cover source the plugin's `coverLocal` hook picked. The\n\t * host app selects the manifest's `ui.card.<kind>` block from the\n\t * comparable `coverMeta.kind`, so the workbench needs this to render\n\t * the same card templates. `undefined` when there is no cover source\n\t * or the file cannot be classified as a cover kind.\n\t */\n\treadonly coverKind?: string\n\treadonly files: readonly unknown[] | undefined\n\treadonly fileStats: FileStats\n\treadonly imageHashes?: readonly unknown[]\n\treadonly errors: Readonly<Record<string, string>>\n\treadonly capturedAt: number\n}\n\n/**\n * The snapshot's detect entry: `ok` plus the miss reasons only. A\n * successful match may carry a schema payload (flowed to hooks via\n * `api.context`) that the workbench never consumes — keeping it out of\n * the snapshot avoids serializing plugin classifications the mock host\n * has no use for.\n */\nexport function snapshotDetect(detection: {\n\treadonly ok: boolean\n\treadonly reasons?: readonly string[]\n}): PluginHookSnapshot[\"detect\"] {\n\treturn detection.ok ? { ok: true } : { ok: false, reasons: detection.reasons }\n}\n\n/**\n * Assemble the plugin target for a source directory: the manifest is\n * authored next to `src/`, the bundle lands in `dist/`.\n * `resolvePluginTarget` only understands a single base dir, hence the\n * dedicated resolver here.\n */\nexport function resolveBuiltPluginTarget(pluginDir: string): PluginTarget {\n\tconst manifestPath = join(pluginDir, \"manifest.json\")\n\tif (!existsSync(manifestPath)) {\n\t\tthrow new CliError(`no manifest.json found in ${pluginDir}`)\n\t}\n\tconst mainPath = join(pluginDir, \"dist\", \"main.js\")\n\tif (!existsSync(mainPath)) {\n\t\tthrow new CliError(`plugin bundle not built: ${mainPath}`)\n\t}\n\tconst manifest: PluginManifest = pluginManifestSchema.parse(\n\t\tJSON.parse(readFileSync(manifestPath, \"utf8\")),\n\t)\n\treturn { id: manifest.id, manifest, mainPath, dirPath: pluginDir }\n}\n\n/**\n * Run the plugin's server-side hooks against `api` through a throwaway\n * sandbox and collect the results. A fresh sandbox per capture is what\n * makes watch rebuilds visible: the worker caches the module graph it\n * loaded, so reusing one would keep serving the stale bundle.\n */\nexport async function captureHookSnapshot(opts: {\n\treadonly target: PluginTarget\n\t/** Resource view the hooks read (a directory-backed ResourceAPI). */\n\treadonly api: ResourceAPI\n}): Promise<PluginHookSnapshot> {\n\tconst { target, api } = opts\n\tconst sandbox = createPluginSandbox(DEFAULT_SANDBOX_CONFIG)\n\ttry {\n\t\tconst hooks = await createCliHooks(target, sandbox)\n\t\treturn await collectHookResults({ target, api, hooks })\n\t} finally {\n\t\tawait sandbox.disposeAll()\n\t}\n}\n\nasync function collectHookResults(opts: {\n\treadonly target: PluginTarget\n\treadonly api: ResourceAPI\n\treadonly hooks: PluginHooks\n}): Promise<PluginHookSnapshot> {\n\tconst { target, api, hooks } = opts\n\tconst errors: Record<string, string> = {}\n\n\tasync function attempt<T>(\n\t\thook: string,\n\t\trun: () => Promise<T>,\n\t): Promise<T | undefined> {\n\t\ttry {\n\t\t\treturn await run()\n\t\t} catch (err) {\n\t\t\terrors[hook] = err instanceof Error ? err.message : String(err)\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\tconst detect = snapshotDetect(\n\t\t(await attempt(\"detect\", () => hooks.detectForPlugin(api, target.id))) ?? {\n\t\t\tok: false,\n\t\t\treasons: [\"detect threw an exception\"],\n\t\t},\n\t)\n\tconst meta = await attempt(\"meta\", () => hooks.runMetaHooks(api, target.id))\n\tconst files = await attempt(\"listFiles\", () =>\n\t\thooks.buildFileList(api, target.id),\n\t)\n\tconst coverLocal = await attempt(\"coverLocal\", () =>\n\t\thooks.resolveLocalCoverSource(api, target.id),\n\t)\n\t// Hash rows are what the app's duplicate/similar sections are built\n\t// from, so the workbench surfaces the count too.\n\tconst hashes = hooks.supportsImageHashes(target.id)\n\t\t? await attempt(\"imageHashes\", () => hooks.runImageHashes(api, target.id))\n\t\t: undefined\n\tconst fileStats =\n\t\t(await attempt(\"fileStats\", () => measureFileStats(api))) ?? {}\n\t// Sniff the selected cover source so the workbench can pick the same\n\t// `ui.card.<kind>` block the host app does from `coverMeta.kind`.\n\tconst coverKind = await sniffCoverKind(api, coverLocal, attempt)\n\n\treturn {\n\t\tpluginId: target.id,\n\t\tdetect,\n\t\tsourceMeta: meta?.sourceMeta?.value,\n\t\tsearchMeta: meta?.searchMeta?.value,\n\t\tcoverLocal,\n\t\tcoverKind,\n\t\tfiles,\n\t\tfileStats,\n\t\timageHashes: hashes?.hashes,\n\t\terrors,\n\t\tcapturedAt: Date.now(),\n\t}\n}\n\n/** Sniff the cover source's kind (image/video/audio), or `undefined`. */\nasync function sniffCoverKind(\n\tapi: ResourceAPI,\n\tcoverLocal: string | undefined,\n\tattempt: <T>(hook: string, run: () => Promise<T>) => Promise<T | undefined>,\n): Promise<string | undefined> {\n\tif (coverLocal === undefined) return undefined\n\tconst probe = await attempt(\"coverKind\", () => api.sniff(coverLocal!))\n\tconst kind = probe?.kind\n\treturn kind === \"image\" || kind === \"video\" || kind === \"audio\"\n\t\t? kind\n\t\t: undefined\n}\n\n/**\n * File count and total byte size of the resource, mirroring what the\n * server records on import and pushes to the iframe as `fileStats`.\n */\nasync function measureFileStats(api: ResourceAPI): Promise<FileStats> {\n\tconst names = await api.listFileNames()\n\tconst stats = await api.statFiles(names)\n\tlet sizeBytes = 0\n\tfor (const stat of stats) sizeBytes += stat?.sizeBytes ?? 0\n\treturn { count: names.length, sizeBytes }\n}\n\n/** One-line human summary for the dev server log. */\nexport function formatHookSnapshot(snapshot: PluginHookSnapshot): string {\n\tconst parts = [\n\t\tsnapshot.detect.ok\n\t\t\t? \"detect ok\"\n\t\t\t: `detect miss (${(snapshot.detect.reasons ?? []).join(\", \")})`,\n\t\t`${snapshot.fileStats.count ?? 0} files`,\n\t]\n\tif (snapshot.files !== undefined) {\n\t\tparts.push(`listFiles ${snapshot.files.length}`)\n\t}\n\tif (snapshot.sourceMeta !== undefined) parts.push(\"sourceMeta\")\n\tif (snapshot.searchMeta !== undefined) parts.push(\"searchMeta\")\n\tif (snapshot.coverLocal !== undefined) {\n\t\tparts.push(`cover ${snapshot.coverLocal}`)\n\t}\n\tfor (const [hook, message] of Object.entries(snapshot.errors)) {\n\t\tparts.push(`${hook} failed: ${message}`)\n\t}\n\treturn parts.join(\" · \")\n}\n","import { createHash } from \"node:crypto\"\nimport { existsSync } from \"node:fs\"\nimport { mkdir, writeFile } from \"node:fs/promises\"\nimport { extname, join } from \"node:path\"\nimport type { ResourceAPI } from \"@hoardodile/host\"\nimport {\n\ttype ImageVariantQuery,\n\timageVariantCanonical,\n\tnormalizeImageVariantSpec,\n\tparseImageVariantQuery,\n} from \"@hoardodile/sdk-types/image-variant\"\nimport {\n\tRESOURCE_COVER_MAX_AREA,\n\tRESOURCE_PREVIEW_MAX_AREA,\n} from \"@hoardodile/sdk-types/resource\"\n\n/**\n * The workbench's render providers: the same `@hoardodile/host/render`\n * pipeline the server runs, wired to the CLI's resource views. This is\n * what makes file variants (`?size=preview` and the generic\n * `fmt`/`fit`/`area`/`q` parameters), resource covers and the video\n * seek-preview route behave in the workbench exactly as they do in the\n * app.\n *\n * The pipeline is imported lazily because it needs `sharp`, an optional\n * peer a plugin project may not have installed. Loading it on demand\n * keeps `plugin build|run|bench` free of that requirement, and a plugin\n * without sharp still gets the whole dev loop — minus rendered\n * variants, which fall back to the original bytes.\n *\n * Rendered artifacts are cached under the plugin's own directory —\n * never inside the user's storage root, which the dev loop only reads.\n */\n\nexport type Rendered = {\n\treadonly contentType: string\n\treadonly path: string\n}\n\nexport type RenderProviders = {\n\t/**\n\t * Render the resource cover (the entry the plugin's `coverLocal`\n\t * hook selected). `undefined` when the resource has no cover source\n\t * or the render cannot be produced.\n\t */\n\treadonly cover: (resId: string) => Promise<Rendered | undefined>\n\treadonly preview: (\n\t\tresId: string,\n\t\tpath: string,\n\t\t/**\n\t\t * The file route's raw variant query (see\n\t\t * {@link ImageVariantQuery}); `undefined` or empty renders the\n\t\t * default preview variant.\n\t\t */\n\t\tvariant?: ImageVariantQuery,\n\t) => Promise<Rendered | undefined>\n\treadonly frame: (\n\t\tresId: string,\n\t\tpath: string,\n\t\ttimeMs: number,\n\t) => Promise<Rendered | undefined>\n}\n\ntype RenderModule = typeof import(\"@hoardodile/host/render\")\n\n/** Stable, filesystem-safe cache key for a resource entry. */\nfunction cacheKey(resId: string, path: string, suffix = \"\"): string {\n\treturn createHash(\"sha256\")\n\t\t.update(`${resId}\\u0000${path}${suffix}`)\n\t\t.digest(\"hex\")\n\t\t.slice(0, 32)\n}\n\nfunction contentTypeOf(format: \"webp\" | \"avif\"): string {\n\treturn format === \"webp\" ? \"image/webp\" : \"image/avif\"\n}\n\nexport function createRenderProviders(opts: {\n\t/** Resolve the resource view a render reads from. */\n\treadonly resolveApi: (resId: string) => Promise<ResourceAPI | undefined>\n\t/**\n\t * Resolve the cover source entry for a resource (the plugin's\n\t * `coverLocal` result). When omitted, covers are unavailable.\n\t */\n\treadonly resolveCoverSource?: (resId: string) => Promise<string | undefined>\n\t/** Cache root, e.g. `<pluginDir>/.hoardodile/cache`. */\n\treadonly cacheDir: string\n}): RenderProviders {\n\tlet renderPromise: Promise<RenderModule | undefined> | undefined\n\n\t/**\n\t * Load the render pipeline once. A missing `sharp` is a normal\n\t * outcome, reported once so the fallback is never a mystery.\n\t */\n\tfunction loadRender(): Promise<RenderModule | undefined> {\n\t\trenderPromise ??= import(\"@hoardodile/host/render\").catch(\n\t\t\t(err: unknown) => {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[hoardodile] preview and frame rendering are unavailable — install \"sharp\" (and an ffmpeg binary for video) to enable them: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t\t)\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t)\n\t\treturn renderPromise\n\t}\n\n\t/**\n\t * Read an entry into memory for the renderer. Preview and frame\n\t * inputs are single files the user is already looking at, so a whole\n\t * read is the simple, honest choice here.\n\t */\n\tasync function readEntry(\n\t\tapi: ResourceAPI,\n\t\tpath: string,\n\t): Promise<Uint8Array | undefined> {\n\t\ttry {\n\t\t\treturn await api.readFile(path)\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\tfunction cached(base: string): Rendered | undefined {\n\t\tfor (const format of [\"avif\", \"webp\"] as const) {\n\t\t\tconst path = `${base}.${format}`\n\t\t\tif (existsSync(path)) return { path, contentType: contentTypeOf(format) }\n\t\t}\n\t\treturn undefined\n\t}\n\n\tasync function cover(resId: string): Promise<Rendered | undefined> {\n\t\tif (opts.resolveCoverSource === undefined) return undefined\n\t\tconst source = await opts.resolveCoverSource(resId)\n\t\tif (source === undefined) return undefined\n\t\tconst api = await opts.resolveApi(resId)\n\t\tif (api === undefined) return undefined\n\t\tconst type = await api.sniff(source)\n\t\tconst kind = type?.kind\n\t\tif (kind !== \"image\" && kind !== \"video\" && kind !== \"audio\") {\n\t\t\treturn undefined\n\t\t}\n\t\tconst ext = type?.ext ?? extname(source).toLowerCase()\n\t\tconst base = join(opts.cacheDir, `cover-${cacheKey(resId, source)}`)\n\t\tconst hit = cached(base)\n\t\tif (hit !== undefined) return hit\n\t\tconst render = await loadRender()\n\t\tif (render === undefined) return undefined\n\t\tawait mkdir(opts.cacheDir, { recursive: true })\n\t\ttry {\n\t\t\tif (kind === \"image\") {\n\t\t\t\tconst bytes = await readEntry(api, source)\n\t\t\t\tif (bytes === undefined) return undefined\n\t\t\t\tconst rendered = await render.renderImageThumbOnce({\n\t\t\t\t\tinput: Buffer.from(bytes),\n\t\t\t\t\text,\n\t\t\t\t\tresolveDest: (format) => `${base}.${format}`,\n\t\t\t\t\tvariant: {\n\t\t\t\t\t\tformat: \"avif\",\n\t\t\t\t\t\tfit: \"inside\",\n\t\t\t\t\t\tmaxArea: RESOURCE_COVER_MAX_AREA,\n\t\t\t\t\t\twebpQuality: render.WEBP_QUALITY,\n\t\t\t\t\t\tavifQuality: render.AVIF_QUALITY,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\treturn {\n\t\t\t\t\tpath: rendered.path,\n\t\t\t\t\tcontentType: contentTypeOf(rendered.format),\n\t\t\t\t}\n\t\t\t}\n\t\t\t// ffmpeg needs a seekable input, so the entry is materialized\n\t\t\t// into the cache first, mirroring the server's seekable gate.\n\t\t\tconst sourcePath = join(\n\t\t\t\topts.cacheDir,\n\t\t\t\t`source-${cacheKey(resId, source, \"cover\")}${ext}`,\n\t\t\t)\n\t\t\tif (!existsSync(sourcePath)) {\n\t\t\t\tconst bytes = await readEntry(api, source)\n\t\t\t\tif (bytes === undefined) return undefined\n\t\t\t\tawait writeFile(sourcePath, bytes)\n\t\t\t}\n\t\t\tconst destPath = `${base}.avif`\n\t\t\tif (kind === \"video\") {\n\t\t\t\tawait render.renderVideoFrame({\n\t\t\t\t\tsource: sourcePath,\n\t\t\t\t\tdestPath,\n\t\t\t\t\tffmpeg: render.resolveFfmpegPaths(),\n\t\t\t\t\tmaxArea: RESOURCE_COVER_MAX_AREA,\n\t\t\t\t\tquality: render.AVIF_QUALITY,\n\t\t\t\t\tformat: \"avif\",\n\t\t\t\t\ttimeSeconds: 0,\n\t\t\t\t\text,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tawait render.renderAudioCoverArt({\n\t\t\t\t\tsource: sourcePath,\n\t\t\t\t\tdestPath,\n\t\t\t\t\tffmpeg: render.resolveFfmpegPaths(),\n\t\t\t\t\tmaxArea: RESOURCE_COVER_MAX_AREA,\n\t\t\t\t\tquality: render.AVIF_QUALITY,\n\t\t\t\t\tformat: \"avif\",\n\t\t\t\t\text,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn { path: destPath, contentType: \"image/avif\" }\n\t\t} catch (err) {\n\t\t\tconsole.warn(\n\t\t\t\t`[hoardodile] cover render failed for ${source}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t)\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\tasync function preview(\n\t\tresId: string,\n\t\tpath: string,\n\t\tvariant?: ImageVariantQuery,\n\t): Promise<Rendered | undefined> {\n\t\tconst api = await opts.resolveApi(resId)\n\t\tif (api === undefined) return undefined\n\t\tif ((await api.sniff(path))?.kind !== \"image\") return undefined\n\t\tconst parsed = parseImageVariantQuery(variant ?? {})\n\t\t// The workbench mount only routes variant requests here; anything\n\t\t// else (or a malformed query) falls back to the original bytes.\n\t\tif (parsed.kind !== \"variant\") return undefined\n\t\tconst render = await loadRender()\n\t\tif (render === undefined) return undefined\n\t\tconst resolved = normalizeImageVariantSpec(parsed.spec, {\n\t\t\tavifQuality: render.PREVIEW_AVIF_QUALITY,\n\t\t\twebpQuality: render.PREVIEW_WEBP_QUALITY,\n\t\t})\n\t\tconst base = join(\n\t\t\topts.cacheDir,\n\t\t\t`preview-${cacheKey(resId, path, imageVariantCanonical(resolved))}`,\n\t\t)\n\t\tconst hit = cached(base)\n\t\tif (hit !== undefined) return hit\n\t\tconst bytes = await readEntry(api, path)\n\t\tif (bytes === undefined) return undefined\n\t\tawait mkdir(opts.cacheDir, { recursive: true })\n\t\ttry {\n\t\t\tconst rendered = await render.renderImageThumbOnce({\n\t\t\t\tinput: Buffer.from(bytes),\n\t\t\t\tresolveDest: (format) => `${base}.${format}`,\n\t\t\t\tvariant: resolved,\n\t\t\t})\n\t\t\treturn {\n\t\t\t\tpath: rendered.path,\n\t\t\t\tcontentType: contentTypeOf(rendered.format),\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.warn(\n\t\t\t\t`[hoardodile] preview render failed for ${path}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t)\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\tasync function frame(\n\t\tresId: string,\n\t\tpath: string,\n\t\ttimeMs: number,\n\t): Promise<Rendered | undefined> {\n\t\tconst api = await opts.resolveApi(resId)\n\t\tif (api === undefined) return undefined\n\t\tconst type = await api.sniff(path)\n\t\tif (type?.kind !== \"video\") return undefined\n\t\tconst destPath = join(\n\t\t\topts.cacheDir,\n\t\t\t`frame-${cacheKey(resId, path, `@${timeMs}`)}.avif`,\n\t\t)\n\t\tif (existsSync(destPath)) {\n\t\t\treturn { path: destPath, contentType: \"image/avif\" }\n\t\t}\n\t\tconst render = await loadRender()\n\t\tif (render === undefined) return undefined\n\t\t// ffmpeg needs a seekable input to land on an arbitrary\n\t\t// timestamp, so the entry is materialized into the cache first.\n\t\tconst sourcePath = join(\n\t\t\topts.cacheDir,\n\t\t\t`source-${cacheKey(resId, path)}${type.ext}`,\n\t\t)\n\t\tif (!existsSync(sourcePath)) {\n\t\t\tconst bytes = await readEntry(api, path)\n\t\t\tif (bytes === undefined) return undefined\n\t\t\tawait mkdir(opts.cacheDir, { recursive: true })\n\t\t\tawait writeFile(sourcePath, bytes)\n\t\t}\n\t\ttry {\n\t\t\tawait render.renderVideoFrame({\n\t\t\t\tsource: sourcePath,\n\t\t\t\tdestPath,\n\t\t\t\tffmpeg: render.resolveFfmpegPaths(),\n\t\t\t\tmaxArea: RESOURCE_PREVIEW_MAX_AREA,\n\t\t\t\tquality: render.PREVIEW_AVIF_QUALITY,\n\t\t\t\tformat: \"avif\",\n\t\t\t\ttimeSeconds: timeMs / 1000,\n\t\t\t\text: type.ext,\n\t\t\t})\n\t\t\treturn { path: destPath, contentType: \"image/avif\" }\n\t\t} catch (err) {\n\t\t\tconsole.warn(\n\t\t\t\t`[hoardodile] frame render failed for ${path}@${timeMs}ms: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t)\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\treturn { cover, preview, frame }\n}\n","import { copyFileSync, existsSync, mkdtempSync, readdirSync } from \"node:fs\"\nimport { createRequire } from \"node:module\"\nimport { tmpdir } from \"node:os\"\nimport { join, resolve } from \"node:path\"\nimport type { DatabaseSync } from \"node:sqlite\"\nimport { createStoragePaths } from \"@hoardodile/host/hoard\"\n\n/**\n * `node:sqlite` is loaded through `createRequire` rather than a static\n * import: the bundler's builtin table predates it and rewrites the\n * specifier to a bare `sqlite`, which Node cannot resolve. The\n * annotation keeps the call fully typed without an assertion.\n */\nconst requireBuiltin: (id: \"node:sqlite\") => typeof import(\"node:sqlite\") =\n\tcreateRequire(import.meta.url)\n\n/**\n * Read-only access to a real hoardodile storage root, so a plugin can\n * be developed against the library it will actually run in.\n *\n * Two rules shape everything here:\n *\n * 1. **Read-only, always.** The database is opened `readOnly` and the\n * archives are read through the host's zip container. Nothing in the\n * dev loop writes to a user's library — plugin writes land in the\n * workbench's in-memory mock instead.\n * 2. **Only what a plugin could see anyway.** Queries are limited to the\n * resource row, its rebuilt metadata, its comments and danmaku, and\n * this plugin's own preferences and cache. Auth, sessions, the\n * footprint log and every other table stay untouched.\n *\n * `node:sqlite` is a Node builtin, so reading a library costs the CLI no\n * native dependency.\n */\n\nexport type StorageResource = {\n\treadonly id: string\n\treadonly name: string\n\treadonly contentPluginId?: string\n\treadonly fileVersion: number\n\treadonly sourceMeta?: unknown\n\treadonly searchMeta?: unknown\n\treadonly fileStats?: { readonly count?: number; readonly sizeBytes?: number }\n}\n\nexport type StorageResourceState = {\n\treadonly name: string\n\treadonly messages: readonly unknown[]\n\treadonly danmaku: readonly unknown[]\n\treadonly prefs: Readonly<Record<string, string>>\n\treadonly cache: Readonly<Record<string, string>>\n}\n\nexport type StorageReader = {\n\t/** Resources in the library, newest first. */\n\treadonly listResources: () => readonly StorageResource[]\n\treadonly findResource: (resId: string) => StorageResource | undefined\n\t/** Plugin-visible stored state for one resource. */\n\treadonly readState: (resId: string, pluginId: string) => StorageResourceState\n\t/** Absolute path of a resource's bare-file source folder. */\n\treadonly archivePath: (resource: StorageResource) => string\n\treadonly close: () => void\n}\n\nfunction parseJson(value: unknown): unknown {\n\tif (typeof value !== \"string\" || value.length === 0) return undefined\n\ttry {\n\t\treturn JSON.parse(value)\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\nfunction asString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" && value.length > 0 ? value : undefined\n}\n\n/**\n * Open the library database read-only. A live server holds the write\n * lock and keeps its WAL alongside; SQLite can still read that, but a\n * read-only handle cannot recover a hot journal — so on failure the\n * database and its sidecars are copied to a temp dir and the copy is\n * opened instead. The user's files are never modified either way.\n */\nfunction openReadOnly(dbPath: string): DatabaseSync {\n\tconst { DatabaseSync: Database } = requireBuiltin(\"node:sqlite\")\n\ttry {\n\t\treturn new Database(dbPath, { readOnly: true })\n\t} catch (err) {\n\t\tconst snapshotDir = mkdtempSync(join(tmpdir(), \"hoardodile-wb-\"))\n\t\tconst dir = resolve(dbPath, \"..\")\n\t\tconst base = dbPath.slice(dir.length + 1)\n\t\tlet copied = false\n\t\tfor (const entry of readdirSync(dir)) {\n\t\t\tif (!entry.startsWith(base)) continue\n\t\t\tcopyFileSync(join(dir, entry), join(snapshotDir, entry))\n\t\t\tcopied = entry === base || copied\n\t\t}\n\t\tif (!copied) throw err\n\t\tconsole.log(\n\t\t\t`[hoardodile] database is busy — reading a temporary copy (${snapshotDir})`,\n\t\t)\n\t\treturn new Database(join(snapshotDir, base), { readOnly: true })\n\t}\n}\n\nexport function openStorage(rootDir: string): StorageReader {\n\tconst root = resolve(rootDir)\n\tconst dbPath = join(root, \"app.sqlite\")\n\tif (!existsSync(dbPath)) {\n\t\tthrow new Error(\n\t\t\t`no app.sqlite in ${root} — point --storage at a hoardodile data root`,\n\t\t)\n\t}\n\tconst db = openReadOnly(dbPath)\n\tconst paths = createStoragePaths({ root })\n\n\tfunction rowToResource(row: Record<string, unknown>): StorageResource {\n\t\tconst stats = parseJson(row.file_stats)\n\t\treturn {\n\t\t\tid: String(row.id),\n\t\t\tname: String(row.name ?? row.id),\n\t\t\tcontentPluginId: asString(row.content_plugin_id),\n\t\t\tfileVersion: Number(row.file_version ?? 1),\n\t\t\tsourceMeta: parseJson(row.source_meta),\n\t\t\tsearchMeta: parseJson(row.search_meta),\n\t\t\tfileStats:\n\t\t\t\ttypeof stats === \"object\" && stats !== null\n\t\t\t\t\t? (stats as StorageResource[\"fileStats\"])\n\t\t\t\t\t: undefined,\n\t\t}\n\t}\n\n\tconst listStmt = db.prepare(\n\t\t`SELECT r.id, r.name, r.content_plugin_id, r.file_version,\n\t\t m.source_meta, m.search_meta, m.file_stats\n\t\t FROM resources r\n\t\t LEFT JOIN resource_meta m ON m.resource_id = r.id\n\t\t WHERE r.deleted_at IS NULL\n\t\t ORDER BY r.created_at DESC`,\n\t)\n\tconst findStmt = db.prepare(\n\t\t`SELECT r.id, r.name, r.content_plugin_id, r.file_version,\n\t\t m.source_meta, m.search_meta, m.file_stats\n\t\t FROM resources r\n\t\t LEFT JOIN resource_meta m ON m.resource_id = r.id\n\t\t WHERE r.id = ?`,\n\t)\n\tconst commentsStmt = db.prepare(\n\t\t`SELECT c.id, c.body, c.created_at, c.floor, c.anchor_data\n\t\t FROM comments c\n\t\t JOIN comment_resources cr ON cr.comment_id = c.id\n\t\t WHERE cr.resource_id = ? AND c.deleted_at IS NULL\n\t\t ORDER BY c.created_at ASC`,\n\t)\n\tconst danmakuStmt = db.prepare(\n\t\t`SELECT id, anchor_data, text, color, mode, created_at\n\t\t FROM danmakus\n\t\t WHERE anchor_resource_id = ?\n\t\t ORDER BY created_at ASC`,\n\t)\n\tconst prefsStmt = db.prepare(\n\t\t`SELECT key, value FROM plugin_preferences WHERE plugin_id = ?`,\n\t)\n\tconst cacheStmt = db.prepare(\n\t\t`SELECT key, value FROM plugin_cache WHERE plugin_id = ? AND res_id = ?`,\n\t)\n\n\tfunction keyValues(\n\t\trows: readonly Record<string, unknown>[],\n\t): Record<string, string> {\n\t\tconst out: Record<string, string> = {}\n\t\tfor (const row of rows) out[String(row.key)] = String(row.value)\n\t\treturn out\n\t}\n\n\treturn {\n\t\tlistResources() {\n\t\t\treturn listStmt.all().map(rowToResource)\n\t\t},\n\t\tfindResource(resId) {\n\t\t\tconst row = findStmt.get(resId)\n\t\t\treturn row === undefined ? undefined : rowToResource(row)\n\t\t},\n\t\treadState(resId, pluginId) {\n\t\t\tconst resource = this.findResource(resId)\n\t\t\treturn {\n\t\t\t\tname: resource?.name ?? resId,\n\t\t\t\tmessages: commentsStmt.all(resId).map((row) => ({\n\t\t\t\t\tid: String(row.id),\n\t\t\t\t\tbody: String(row.body ?? \"\"),\n\t\t\t\t\tcreatedAt: Number(row.created_at ?? 0),\n\t\t\t\t\tcharIds: [],\n\t\t\t\t\tresIds: [resId],\n\t\t\t\t\tlikeCount: 0,\n\t\t\t\t\tdislikeCount: 0,\n\t\t\t\t\treplyCount: 0,\n\t\t\t\t\tfloor: row.floor === null ? undefined : Number(row.floor),\n\t\t\t\t\tanchor: {\n\t\t\t\t\t\tresId,\n\t\t\t\t\t\tdata: (parseJson(row.anchor_data) as { data?: unknown })?.data,\n\t\t\t\t\t},\n\t\t\t\t})),\n\t\t\t\tdanmaku: danmakuStmt.all(resId).map((row) => ({\n\t\t\t\t\tid: String(row.id),\n\t\t\t\t\tanchor: {\n\t\t\t\t\t\tresId,\n\t\t\t\t\t\tdata: (parseJson(row.anchor_data) as { data?: unknown })?.data,\n\t\t\t\t\t},\n\t\t\t\t\ttext: String(row.text ?? \"\"),\n\t\t\t\t\tcolor: String(row.color ?? \"\"),\n\t\t\t\t\tmode: String(row.mode ?? \"scroll\"),\n\t\t\t\t\tcreatedAt: Number(row.created_at ?? 0),\n\t\t\t\t})),\n\t\t\t\tprefs: keyValues(prefsStmt.all(pluginId)),\n\t\t\t\tcache: keyValues(cacheStmt.all(pluginId, resId)),\n\t\t\t}\n\t\t},\n\t\tarchivePath(resource) {\n\t\t\t// Layout authority lives in @hoardodile/host, shared with the\n\t\t\t// server — no hand-rolled mirror of the versions/<v> shape.\n\t\t\treturn paths.atVersion(resource.fileVersion).resource(resource.id)\n\t\t},\n\t\tclose() {\n\t\t\tdb.close()\n\t\t},\n\t}\n}\n","import { type ChildProcess, spawn } from \"node:child_process\"\nimport { existsSync, readdirSync, readFileSync, statSync, watch } from \"node:fs\"\nimport { createRequire } from \"node:module\"\nimport { join, resolve, sep } from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport type { ResourceAPI } from \"@hoardodile/host\"\nimport {\n\tcaptureHookSnapshot,\n\tformatHookSnapshot,\n\ttype PluginHookSnapshot,\n\tresolveBuiltPluginTarget,\n} from \"./hook-snapshot.ts\"\nimport { createRenderProviders } from \"./render-providers.ts\"\nimport {\n\tbuildArchiveResourceAPI,\n\tbuildCliResourceAPI,\n\tCliError,\n\tEXIT_ERROR,\n\tEXIT_PASS,\n} from \"./runner.ts\"\nimport { openStorage, type StorageReader } from \"./storage.ts\"\n\n/**\n * `hoardodile plugin dev` — the plugin development loop:\n * 1. build the plugin in watch mode (its own `watch` script, or this\n * CLI's `plugin build --watch`),\n * 2. capture the server-side hook results from the real sandbox, so the\n * workbench iframe gets the same `sourceMeta` / `searchMeta` /\n * `fileStats` / file list the app would push,\n * 3. serve the published workbench with the plugin bundle, the resource\n * data, and the same render pipeline the server uses for preview\n * variants and video frames.\n *\n * Data comes either from a plain directory (`--data`, the default\n * `testdata/`) or from a real hoardodile library (`--storage`), which is\n * opened **read-only**: plugin writes land in the workbench's in-memory\n * mock, never in the user's database or archives.\n *\n * Long-running: stays up until SIGINT.\n */\nexport type DevOptions = {\n\treadonly pluginDir: string\n\treadonly dataDir?: string\n\t/** A folder whose direct subfolders are individual resources. Mutually exclusive with `dataDir`/`storageDir`. */\n\treadonly resourceRootDir?: string\n\t/** Real hoardodile storage root, opened read-only. */\n\treadonly storageDir?: string\n\t/** Resource to open first when serving a storage root. */\n\treadonly resId?: string\n\treadonly port: number\n}\n\n/** Debounce for rebuild-triggered recaptures; vite writes dist in bursts. */\nconst RECAPTURE_DEBOUNCE_MS = 300\nconst FIRST_BUILD_TIMEOUT_MS = 60_000\n/** Resources listed in the picker; a library can hold thousands. */\nconst RESOURCE_LIST_LIMIT = 200\nconst DIRECTORY_RES_ID = \"workbench\"\n\nfunction resolvePluginDir(value: string | undefined): string {\n\tconst dir = resolve(value ?? \".\")\n\tif (!existsSync(join(dir, \"manifest.json\"))) {\n\t\tthrow new Error(\n\t\t\t`no manifest.json found in ${dir} — run this from a plugin directory or pass --plugin-dir`,\n\t\t)\n\t}\n\treturn dir\n}\n\nfunction hasWatchScript(pluginDir: string): boolean {\n\ttry {\n\t\tconst pkg = JSON.parse(\n\t\t\treadFileSync(join(pluginDir, \"package.json\"), \"utf8\"),\n\t\t)\n\t\treturn typeof pkg?.scripts?.watch === \"string\"\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Load the workbench serve entry from the PLUGIN's own dependency tree.\n * The workbench is a dev tool, not part of the host runtime — the plugin\n * declares it as a devDependency (the template and scaffolder include it)\n * and `hoardodile plugin dev` serves that installed copy.\n */\nasync function loadWorkbenchServe(pluginDir: string) {\n\tconst requireFromPlugin = createRequire(join(pluginDir, \"package.json\"))\n\tlet workbenchEntry: string\n\ttry {\n\t\tworkbenchEntry = requireFromPlugin.resolve(\"@hoardodile/workbench\")\n\t} catch {\n\t\tthrow new Error(\n\t\t\t\"@hoardodile/workbench not found in this plugin's dependencies — add it to devDependencies (the template and `create-hoardodile-plugin` include it) and run `pnpm install`.\",\n\t\t)\n\t}\n\treturn import(pathToFileURL(workbenchEntry).href)\n}\n\nfunction spawnWatcher(opts: {\n\treadonly command: string\n\treadonly args: readonly string[]\n\treadonly cwd: string\n\treadonly label: string\n}): ChildProcess {\n\tconsole.log(`[hoardodile] starting ${opts.label}`)\n\treturn spawn(opts.command, [...opts.args], {\n\t\tcwd: opts.cwd,\n\t\tstdio: \"inherit\",\n\t\tshell: process.platform === \"win32\",\n\t})\n}\n\nfunction startBuildWatcher(pluginDir: string): ChildProcess {\n\tconst watcher = hasWatchScript(pluginDir)\n\t\t? spawnWatcher({\n\t\t\t\tcommand: \"pnpm\",\n\t\t\t\targs: [\"watch\"],\n\t\t\t\tcwd: pluginDir,\n\t\t\t\tlabel: `\\`pnpm watch\\` in ${pluginDir}`,\n\t\t\t})\n\t\t: spawnWatcher({\n\t\t\t\tcommand: process.execPath,\n\t\t\t\targs: [process.argv[1] ?? \"\", \"plugin\", \"build\", \"--watch\"],\n\t\t\t\tcwd: pluginDir,\n\t\t\t\tlabel: \"`plugin build --watch` (no watch script found)\",\n\t\t\t})\n\twatcher.on(\"error\", (err) => {\n\t\tconsole.error(`[hoardodile] build watcher failed: ${err.message}`)\n\t\tprocess.exitCode = EXIT_ERROR\n\t})\n\twatcher.on(\"exit\", (code) => {\n\t\tif (code !== null && code !== 0) {\n\t\t\tconsole.error(`[hoardodile] build watcher exited with code ${code}`)\n\t\t\tprocess.exitCode = EXIT_ERROR\n\t\t}\n\t})\n\treturn watcher\n}\n\nasync function waitForBuild(\n\tdistDir: string,\n\ttimeoutMs: number,\n): Promise<boolean> {\n\tconst started = Date.now()\n\twhile (Date.now() - started < timeoutMs) {\n\t\tif (existsSync(join(distDir, \"main.js\"))) return true\n\t\tawait new Promise((r) => setTimeout(r, 500))\n\t}\n\treturn false\n}\n\n/**\n * Where the workbench's resources come from. Both shapes answer the\n * same three questions — which resources exist, how to read one, and\n * what stored state a plugin would see — so everything downstream stays\n * unaware of whether it is looking at a directory or a real library.\n */\ntype ResourceSource = {\n\treadonly list: () => readonly {\n\t\treadonly id: string\n\t\treadonly name: string\n\t\treadonly contentPluginId?: string\n\t}[]\n\treadonly apiFor: (resId: string) => ResourceAPI | undefined\n\treadonly stateFor: (\n\t\tresId: string,\n\t\tpluginId: string,\n\t) => Record<string, unknown> | undefined\n\t/** Writable root for `extractArchive` materialization. */\n\treadonly extractCacheDir?: string\n\treadonly close?: () => void\n}\n\nfunction directorySource(\n\tdataDir: string,\n\textractCacheDir?: string,\n): ResourceSource {\n\tconst api = buildCliResourceAPI(dataDir, { extractCacheDir })\n\treturn {\n\t\tlist: () => [{ id: DIRECTORY_RES_ID, name: \"Workbench\" }],\n\t\tapiFor: (resId) => (resId === DIRECTORY_RES_ID ? api : undefined),\n\t\tstateFor: () => undefined,\n\t\textractCacheDir,\n\t}\n}\nfunction storageSource(\n\tstorage: StorageReader,\n\textractCacheDir?: string,\n): ResourceSource {\n\t// One API per resource: archives are immutable, so the container and\n\t// its central-directory cache stay valid for the whole session.\n\tconst apis = new Map<string, ResourceAPI | undefined>()\n\treturn {\n\t\tlist: () =>\n\t\t\tstorage\n\t\t\t\t.listResources()\n\t\t\t\t.slice(0, RESOURCE_LIST_LIMIT)\n\t\t\t\t.map((resource) => ({\n\t\t\t\t\tid: resource.id,\n\t\t\t\t\tname: resource.name,\n\t\t\t\t\tcontentPluginId: resource.contentPluginId,\n\t\t\t\t})),\n\t\tapiFor(resId) {\n\t\t\tif (apis.has(resId)) return apis.get(resId)\n\t\t\tconst resource = storage.findResource(resId)\n\t\t\tconst archive =\n\t\t\t\tresource === undefined ? undefined : storage.archivePath(resource)\n\t\t\tconst api =\n\t\t\t\tarchive !== undefined && existsSync(archive)\n\t\t\t\t\t? buildArchiveResourceAPI(archive, extractCacheDir)\n\t\t\t\t\t: undefined\n\t\t\tif (api === undefined && resource !== undefined) {\n\t\t\t\tconsole.warn(`[hoardodile] no source archive for resource ${resId}`)\n\t\t\t}\n\t\t\tapis.set(resId, api)\n\t\t\treturn api\n\t\t},\n\t\tstateFor: (resId, pluginId) => storage.readState(resId, pluginId),\n\t\textractCacheDir,\n\t\tclose: () => storage.close(),\n\t}\n}\n\n/**\n * A source over a folder whose direct subfolders are individual\n * resources — the \"consolidate my test data\" shape. Each subfolder is\n * one resource (named by its basename); `apiFor` builds a per-resource\n * container only when the id resolves to a real subfolder inside `root`\n * (a traversal id resolves to nothing, never escapes the root).\n */\nexport function resourceRootSource(\n\tresourceRoot: string,\n\textractCacheDir?: string,\n): ResourceSource {\n\tconst root = resolve(resourceRoot)\n\tconst listResources = () =>\n\t\treaddirSync(root, { withFileTypes: true })\n\t\t\t.filter((entry) => entry.isDirectory())\n\t\t\t.map((entry) => ({ id: entry.name, name: entry.name }))\n\t\t\t.sort((a, b) => a.name.localeCompare(b.name))\n\tconst subdirFor = (resId: string): string | undefined => {\n\t\tconst abs = join(root, resId)\n\t\tif (abs !== root && !abs.startsWith(root + sep)) return undefined\n\t\ttry {\n\t\t\treturn statSync(abs).isDirectory() ? abs : undefined\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t}\n\tconst apis = new Map<string, ResourceAPI | undefined>()\n\treturn {\n\t\tlist: listResources,\n\t\tapiFor(resId) {\n\t\t\tif (apis.has(resId)) return apis.get(resId)\n\t\t\tconst dir = subdirFor(resId)\n\t\t\tconst api =\n\t\t\t\tdir === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: buildCliResourceAPI(dir, { extractCacheDir })\n\t\t\tapis.set(resId, api)\n\t\t\treturn api\n\t\t},\n\t\tstateFor: () => undefined,\n\t\textractCacheDir,\n\t}\n}\n\n/**\n * Holds the latest sandboxed hook results per resource. Recaptures are\n * serialised and coalesced: a rebuild burst must not spawn a worker per\n * written file, and two overlapping captures would race for the slot.\n */\nfunction createSnapshotStore(opts: {\n\treadonly pluginDir: string\n\treadonly source: ResourceSource\n}) {\n\tconst snapshots = new Map<string, PluginHookSnapshot>()\n\tconst running = new Map<string, Promise<void>>()\n\n\tasync function capture(resId: string): Promise<void> {\n\t\tconst api = opts.source.apiFor(resId)\n\t\tif (api === undefined) return\n\t\ttry {\n\t\t\tconst target = resolveBuiltPluginTarget(opts.pluginDir)\n\t\t\tconst snapshot = await captureHookSnapshot({ target, api })\n\t\t\tsnapshots.set(resId, snapshot)\n\t\t\tconsole.log(`[hoardodile] ${resId}: ${formatHookSnapshot(snapshot)}`)\n\t\t\tif (!snapshot.detect.ok) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t\"[hoardodile] detect failed — the plugin may not match this resource.\",\n\t\t\t\t)\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(\n\t\t\t\t`[hoardodile] hook snapshot failed: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t)\n\t\t}\n\t}\n\n\tfunction refresh(resId: string): Promise<void> {\n\t\tconst inFlight = running.get(resId)\n\t\tif (inFlight !== undefined) return inFlight\n\t\tconst run = capture(resId).finally(() => running.delete(resId))\n\t\trunning.set(resId, run)\n\t\treturn run\n\t}\n\n\treturn {\n\t\t/** Capture on demand, then serve the cached result. */\n\t\tasync read(resId: string): Promise<PluginHookSnapshot | undefined> {\n\t\t\tif (!snapshots.has(resId)) await refresh(resId)\n\t\t\treturn snapshots.get(resId)\n\t\t},\n\t\t/** Drop every capture so the next read re-runs against the new build. */\n\t\tinvalidate(): void {\n\t\t\tsnapshots.clear()\n\t\t},\n\t\tcaptured: () => [...snapshots.keys()],\n\t\trefresh,\n\t}\n}\n\n/** Recapture whenever the watcher rewrites the bundle. */\nfunction watchDistForRebuilds(\n\tdistDir: string,\n\tonRebuild: () => void,\n): () => void {\n\tlet timer: ReturnType<typeof setTimeout> | undefined\n\tconst watcher = watch(distDir, () => {\n\t\tif (timer !== undefined) clearTimeout(timer)\n\t\ttimer = setTimeout(onRebuild, RECAPTURE_DEBOUNCE_MS)\n\t})\n\treturn () => {\n\t\tif (timer !== undefined) clearTimeout(timer)\n\t\twatcher.close()\n\t}\n}\n\n/** Resolve the data source from the flags, preferring a real library. */\nexport function resolveSource(\n\topts: DevOptions & { readonly pluginDir: string },\n): ResourceSource | undefined {\n\tconst extractCacheDir = join(opts.pluginDir, \".hoardodile\", \"extract\")\n\tif (\n\t\topts.resourceRootDir !== undefined &&\n\t\t(opts.dataDir !== undefined || opts.storageDir !== undefined)\n\t) {\n\t\tthrow new CliError(\n\t\t\t\"--resource-dir is mutually exclusive with --data and --storage\",\n\t\t)\n\t}\n\tif (opts.resourceRootDir !== undefined) {\n\t\tconst root = resolve(opts.resourceRootDir)\n\t\tif (!existsSync(root)) {\n\t\t\tconsole.warn(\n\t\t\t\t`[hoardodile] no resource dir found at ${root} — mount one with --resource-dir (or --storage <hoardodile-root>).`,\n\t\t\t)\n\t\t\treturn undefined\n\t\t}\n\t\tconsole.log(`[hoardodile] resource dir: ${root}`)\n\t\treturn resourceRootSource(root, extractCacheDir)\n\t}\n\tif (opts.storageDir !== undefined) {\n\t\tconst root = resolve(opts.storageDir)\n\t\tconst storage = openStorage(root)\n\t\tconst count = storage.listResources().length\n\t\tconsole.log(`[hoardodile] storage: ${root} (${count} resources, read-only)`)\n\t\treturn storageSource(storage, extractCacheDir)\n\t}\n\tconst dataDir =\n\t\topts.dataDir !== undefined\n\t\t\t? resolve(opts.dataDir)\n\t\t\t: join(resolve(opts.pluginDir ?? \".\"), \"testdata\")\n\tif (!existsSync(dataDir)) {\n\t\tconsole.warn(\n\t\t\t`[hoardodile] no data dir found at ${dataDir} — mount one with --data (or --storage <hoardodile-root>).`,\n\t\t)\n\t\treturn undefined\n\t}\n\tconsole.log(`[hoardodile] data: ${dataDir}`)\n\treturn directorySource(dataDir, extractCacheDir)\n}\n\n/**\n * Framed, easy-to-spot startup notice for the workbench URL. The plugin\n * watcher and vite print continuously, so a plain log line scrolls away;\n * a bordered banner keeps the address findable at the end of the startup\n * burst. ANSI colour is only emitted on a TTY so redirected logs and CI\n * stay clean.\n */\nfunction printWorkbenchBanner(url: string): void {\n\tconst ansi = process.stdout.isTTY\n\tconst headline = \"Workbench running — open in your browser:\"\n\tconst urlLineText = ` ${url}`\n\tconst hint =\n\t\t\"(edits rebuild automatically — reload the page. Ctrl+C to stop.)\"\n\tconst width = Math.max(headline.length, urlLineText.length, hint.length) + 2\n\tconst content = (line: string) => `│ ${line.padEnd(width - 2)}│`\n\tconst urlLine = content(urlLineText)\n\tconsole.log(`\\n┌${\"─\".repeat(width)}┐`)\n\tconsole.log(content(headline))\n\tconsole.log(ansi ? urlLine.replace(url, `\\x1b[1;36m${url}\\x1b[0m`) : urlLine)\n\tconsole.log(content(hint))\n\tconsole.log(`└${\"─\".repeat(width)}┘`)\n}\n\nexport async function executeDev(opts: DevOptions): Promise<number> {\n\tconst pluginDir = resolvePluginDir(opts.pluginDir)\n\tconst distDir = join(pluginDir, \"dist\")\n\tconst source = resolveSource({ ...opts, pluginDir })\n\tconst target = existsSync(join(distDir, \"main.js\"))\n\t\t? resolveBuiltPluginTarget(pluginDir)\n\t\t: undefined\n\n\tconst watcher = startBuildWatcher(pluginDir)\n\tconst snapshots =\n\t\tsource === undefined\n\t\t\t? undefined\n\t\t\t: createSnapshotStore({ pluginDir, source })\n\n\tconst render =\n\t\tsource === undefined\n\t\t\t? undefined\n\t\t\t: createRenderProviders({\n\t\t\t\t\tresolveApi: async (resId) => source.apiFor(resId),\n\t\t\t\t\t// The plugin's coverLocal pick is captured in the hook\n\t\t\t\t\t// snapshot; the cover render feeds the workbench picker.\n\t\t\t\t\tresolveCoverSource: async (resId) =>\n\t\t\t\t\t\t(await snapshots?.read(resId))?.coverLocal,\n\t\t\t\t\t// Rendered artifacts live with the plugin, never inside\n\t\t\t\t\t// the user's storage root.\n\t\t\t\t\tcacheDir: join(pluginDir, \".hoardodile\", \"cache\"),\n\t\t\t\t})\n\n\t// The workbench mounts the BUILT bundle: `hoardodile plugin build`\n\t// emits manifest.json, index.html and main.js into dist/. Serving the\n\t// source root instead would hand the iframe raw .tsx.\n\tconst { serveWorkbench } = await loadWorkbenchServe(pluginDir)\n\t// The workbench may rebind to a free port, so the printed URL must be\n\t// the actual one. Capture it via `onReady` and only surface it after\n\t// the build settles, so the plugin's vite watch-build output does not\n\t// scroll it off-screen.\n\tlet workbenchUrl = `http://127.0.0.1:${opts.port}`\n\tconst server = await serveWorkbench({\n\t\tpluginDir: distDir,\n\t\tport: opts.port,\n\t\tonReady: (url: string) => {\n\t\t\tworkbenchUrl = url\n\t\t},\n\t\t// User-consented dev downloads land in the plugin's own scratch\n\t\t// vault, next to the extraction cache — never in the read-only\n\t\t// storage root or the data dir.\n\t\tvaultRoot: join(pluginDir, \".hoardodile\", \"vault\"),\n\t\tproviders: {\n\t\t\tresources: () => source?.list() ?? [],\n\t\t\tfiles: source === undefined ? undefined : createFileProvider(source),\n\t\t\tsnapshot: (resId: string) => snapshots?.read(resId),\n\t\t\tstate: (resId: string) =>\n\t\t\t\tsource?.stateFor(resId, target?.id ?? \"\") as\n\t\t\t\t\t| Record<string, unknown>\n\t\t\t\t\t| undefined,\n\t\t\tpreview: render?.preview,\n\t\t\tframe: render?.frame,\n\t\t\tcover: render?.cover,\n\t\t},\n\t})\n\n\tlet stopDistWatch: (() => void) | undefined\n\tif (await waitForBuild(distDir, FIRST_BUILD_TIMEOUT_MS)) {\n\t\tconst first = opts.resId ?? source?.list()[0]?.id\n\t\tif (first !== undefined) await snapshots?.refresh(first)\n\t\tstopDistWatch = watchDistForRebuilds(distDir, () => {\n\t\t\t// Rebuilt bundle: drop every capture and re-run the ones the\n\t\t\t// page has already asked for, so a reload shows the new build.\n\t\t\tconst captured = snapshots?.captured() ?? []\n\t\t\tsnapshots?.invalidate()\n\t\t\tfor (const resId of captured) void snapshots?.refresh(resId)\n\t\t})\n\t} else {\n\t\tconsole.error(\n\t\t\t\"[hoardodile] no dist/main.js appeared within 60s — is the build working?\",\n\t\t)\n\t}\n\n\t// Surface the workbench URL last, after the initial build/capture burst,\n\t// framed so it is not lost among the watcher and vite output.\n\tprintWorkbenchBanner(workbenchUrl)\n\n\tawait new Promise<void>((resolveStop) => {\n\t\tconst stop = () => {\n\t\t\tstopDistWatch?.()\n\t\t\twatcher.kill()\n\t\t\tsource?.close?.()\n\t\t\tserver.close(() => resolveStop())\n\t\t}\n\t\tprocess.once(\"SIGINT\", stop)\n\t\tprocess.once(\"SIGTERM\", stop)\n\t})\n\treturn EXIT_PASS\n}\n\n/** File access for the workbench, backed by the resource's own view. */\nfunction createFileProvider(source: ResourceSource) {\n\treturn {\n\t\tasync list(resId: string): Promise<readonly string[]> {\n\t\t\treturn (await source.apiFor(resId)?.listFileNames()) ?? []\n\t\t},\n\t\tasync stat(resId: string, path: string) {\n\t\t\treturn source.apiFor(resId)?.statFile(path)\n\t\t},\n\t\tasync read(resId: string, path: string): Promise<Uint8Array | undefined> {\n\t\t\ttry {\n\t\t\t\treturn await source.apiFor(resId)?.readFile(path)\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t},\n\t\tasync extracted(\n\t\t\t_path: string,\n\t\t\tpath: string,\n\t\t): Promise<Uint8Array | undefined> {\n\t\t\tconst root = source.extractCacheDir\n\t\t\tif (root === undefined) return undefined\n\t\t\tconst abs = resolve(root, path)\n\t\t\tif (abs !== resolve(root) && !abs.startsWith(resolve(root) + sep)) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn readFileSync(abs)\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t},\n\t}\n}\n","import { createHash } from \"node:crypto\"\nimport { existsSync, mkdirSync, readFileSync, rmSync } from \"node:fs\"\nimport { writeFile } from \"node:fs/promises\"\nimport { join, resolve } from \"node:path\"\nimport { packZipDirectory } from \"@hoardodile/host\"\nimport type { PluginManifest } from \"@hoardodile/sdk-types\"\nimport { buildPlugin } from \"./build.ts\"\nimport { CliError } from \"./runner.ts\"\n\nexport type PackageResult = {\n\treadonly id: string\n\treadonly version: string\n\treadonly zipPath: string\n\t/** `release/<id>-<version>.zip.sha256` next to the zip. */\n\treadonly sha256Path: string\n\t/** Publishing hint: push a matching tag — the release workflow builds. */\n\treadonly publishHint: string\n\t/** One line to append to the marketplace registry `plugins` array. */\n\treadonly registryLine: string\n}\n\n/**\n * Build (or reuse) a plugin's `dist/`, then zip its *contents* —\n * `manifest.json` at the zip root, exactly what the app's installer\n * expects — into `release/<id>-<version>.zip` plus a `<zip>.sha256`\n * sidecar (the marketplace verifies it when the release ships one).\n *\n * The file name is the marketplace convention: the app resolves a\n * release's zip by trying `<id>-<tag>.zip` / `<id>-<version>.zip`\n * first, so publishing with this artifact needs no registry metadata.\n *\n * Publishing itself is a CI concern: the template ships a tag-triggered\n * release workflow (`plugins/template/.github/workflows/release.yml`)\n * that uploads both artifacts — no local `gh` CLI or token needed.\n */\nexport async function packPlugin(\n\tdir: string,\n\topts: { readonly skipBuild: boolean },\n): Promise<PackageResult> {\n\tconst pluginDir = resolve(dir)\n\tconst manifestPath = join(pluginDir, \"manifest.json\")\n\tif (!existsSync(manifestPath)) {\n\t\tthrow new CliError(`No manifest.json found in ${pluginDir}`)\n\t}\n\tconst manifest = JSON.parse(\n\t\treadFileSync(manifestPath, \"utf-8\"),\n\t) as PluginManifest\n\tif (typeof manifest.id !== \"string\" || manifest.id.length === 0) {\n\t\tthrow new CliError(\"manifest.json missing id field\")\n\t}\n\tif (typeof manifest.version !== \"string\" || manifest.version.length === 0) {\n\t\tthrow new CliError(\"manifest.json missing version field\")\n\t}\n\n\tif (!opts.skipBuild) {\n\t\tawait buildPlugin(pluginDir, { watch: false })\n\t}\n\n\tconst distDir = join(pluginDir, \"dist\")\n\tif (!existsSync(join(distDir, \"manifest.json\"))) {\n\t\tthrow new CliError(\n\t\t\t`dist/manifest.json not found in ${pluginDir} — run \"hoardodile plugin build\" first`,\n\t\t)\n\t}\n\n\tconst outDir = join(pluginDir, \"release\")\n\tmkdirSync(outDir, { recursive: true })\n\tconst zipPath = join(\n\t\toutDir,\n\t\t`${manifest.id}-${sanitizeFileNamePart(manifest.version)}.zip`,\n\t)\n\n\t// Zip only the files `dist/` produced; entries use forward slashes so\n\t// the archive is identical on every platform. The packer is the same\n\t// yazl engine the host runtime extracts with (streamed to disk, no\n\t// whole-archive buffer).\n\trmSync(zipPath, { force: true })\n\tawait packZipDirectory(distDir, zipPath)\n\n\tconst sha256Path = `${zipPath}.sha256`\n\tconst packed = readFileSync(zipPath)\n\tawait writeFile(\n\t\tsha256Path,\n\t\t`${createHash(\"sha256\").update(packed).digest(\"hex\")}\\n`,\n\t)\n\n\treturn {\n\t\tid: manifest.id,\n\t\tversion: manifest.version,\n\t\tzipPath,\n\t\tsha256Path,\n\t\tpublishHint: `push a tag v${manifest.version} — the release workflow (plugins/template/.github/workflows/release.yml) builds and publishes`,\n\t\tregistryLine: registryLineFor(pluginDir),\n\t}\n}\n\nfunction sanitizeFileNamePart(value: string): string {\n\tconst sanitized = value.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\treturn sanitized.length > 0 ? sanitized : \"0\"\n}\n\n/** Derive the registry line from package.json's repository, if present. */\nfunction registryLineFor(pluginDir: string): string {\n\ttry {\n\t\tconst pkg = JSON.parse(\n\t\t\treadFileSync(join(pluginDir, \"package.json\"), \"utf-8\"),\n\t\t) as { readonly repository?: { readonly url?: string } | string }\n\t\tconst url =\n\t\t\ttypeof pkg.repository === \"string\" ? pkg.repository : pkg.repository?.url\n\t\tif (typeof url === \"string\") {\n\t\t\tconst match = url.match(/github\\.com[:/]([^/]+)\\/([^/#.]+)/)\n\t\t\tif (match !== null) {\n\t\t\t\treturn `\"https://github.com/${match[1]}/${match[2]}\"`\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// No package.json (or unreadable) — fall through to the placeholder.\n\t}\n\treturn '\"https://github.com/<owner>/<repo>\"'\n}\n","import { existsSync, mkdtempSync, readdirSync, rmSync, statSync } from \"node:fs\"\nimport { tmpdir } from \"node:os\"\nimport { dirname, join } from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport {\n\tcreatePluginSandbox,\n\tDEFAULT_SANDBOX_CONFIG,\n\tHOOK_NAMES,\n\ttype HookName,\n\ttype PluginDefinition,\n\ttype PluginHooks,\n} from \"@hoardodile/host\"\nimport { ok } from \"@hoardodile/sdk-types\"\nimport { defineCommand } from \"citty\"\nimport {\n\ttype BenchReport,\n\tbenchExitCode,\n\tcompareBaseline,\n\tcomputeBenchReport,\n\tformatBenchSummary,\n\tloadBaseline,\n\twriteReport,\n} from \"./bench.ts\"\nimport { buildPlugin } from \"./build.ts\"\nimport { executeCreate } from \"./create.ts\"\nimport { executeDev } from \"./dev.ts\"\nimport { packPlugin } from \"./package.ts\"\nimport {\n\tbuildCliResourceAPI,\n\tCliError,\n\tcreateCliHooks,\n\tEXIT_ERROR,\n\tEXIT_PASS,\n\ttype PluginTarget,\n\tresolvePluginTarget,\n\trunCliHook,\n} from \"./runner.ts\"\n\n/**\n * `hoardodile` — the developer CLI. The `plugin` group builds, runs,\n * benchmarks and develops content plugins against the same host\n * implementation the server uses (worker sandbox + hook strategy + real\n * probes), so what you test is what runs in production.\n */\n\nfunction parseRepeat(value: string | undefined): number {\n\tif (value === undefined) return 5\n\tconst n = Number.parseInt(value, 10)\n\tif (!Number.isFinite(n) || n < 1) {\n\t\tthrow new CliError(`--repeat must be a positive integer, got \"${value}\"`)\n\t}\n\treturn n\n}\n\nfunction parseWarmup(value: string | undefined): number {\n\tif (value === undefined) return 1\n\tconst n = Number.parseInt(value, 10)\n\tif (!Number.isFinite(n) || n < 0) {\n\t\tthrow new CliError(\n\t\t\t`--warmup must be a non-negative integer, got \"${value}\"`,\n\t\t)\n\t}\n\treturn n\n}\n\nfunction parseThreshold(value: string | undefined): number {\n\tif (value === undefined) return 20\n\tconst n = Number.parseFloat(value)\n\tif (!Number.isFinite(n) || n < 0) {\n\t\tthrow new CliError(\n\t\t\t`--threshold must be a non-negative number, got \"${value}\"`,\n\t\t)\n\t}\n\treturn n\n}\n\nfunction parseHook(value: string): HookName {\n\tif (!(HOOK_NAMES as readonly string[]).includes(value)) {\n\t\tthrow new CliError(\n\t\t\t`unknown hook \"${value}\" — expected one of: ${HOOK_NAMES.join(\", \")}`,\n\t\t)\n\t}\n\treturn value as HookName\n}\n\nfunction parsePort(value: string): number {\n\tconst n = Number.parseInt(value, 10)\n\tif (!Number.isFinite(n) || n < 1 || n > 65535) {\n\t\tthrow new CliError(`--port must be a valid port number, got \"${value}\"`)\n\t}\n\treturn n\n}\n\nexport const main = defineCommand({\n\tmeta: {\n\t\tname: \"hoardodile\",\n\t\tdescription:\n\t\t\t\"hoardodile developer CLI — content-plugin create, build, run, bench and dev commands.\",\n\t},\n\tsubCommands: {\n\t\tplugin: defineCommand({\n\t\t\tmeta: {\n\t\t\t\tname: \"plugin\",\n\t\t\t\tdescription: \"Content-plugin developer commands.\",\n\t\t\t},\n\t\t\tsubCommands: {\n\t\t\t\tcreate: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"create\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Scaffold a new content plugin (runs create-hoardodile-plugin via pnpm dlx).\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\tname: {\n\t\t\t\t\t\t\ttype: \"positional\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Plugin directory name (npm-style, lowercase letters, digits and dashes). Defaults to an interactive prompt.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttarballs: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Directory of packed SDK tarballs; rewires the scaffolded plugin's SDK deps to them.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executeCreate({\n\t\t\t\t\t\t\tname: args.name,\n\t\t\t\t\t\t\ttarballs: args.tarballs,\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\trun: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"run\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Run one plugin hook against a directory and print the JSON result.\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\thook: {\n\t\t\t\t\t\t\ttype: \"positional\",\n\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\tdescription: `Hook to run: ${HOOK_NAMES.join(\", \")}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdir: {\n\t\t\t\t\t\t\ttype: \"positional\",\n\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\tdescription: \"Data directory the hook reads from.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpluginDir: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Plugin directory (manifest.json + main.js). Defaults to the --main parent.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmain: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Path to the built plugin main.js. Defaults to <plugin-dir>/main.js.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tinProcess: {\n\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Run the hook in-process instead of through the worker sandbox. Debugging only — bypasses the production execution path.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpretty: {\n\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\tdescription: \"Pretty-print the JSON result (indented).\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executeRun({\n\t\t\t\t\t\t\thook: parseHook(args.hook ?? \"\"),\n\t\t\t\t\t\t\tdir: args.dir ?? \"\",\n\t\t\t\t\t\t\tpluginDir: args.pluginDir,\n\t\t\t\t\t\t\tmain: args.main,\n\t\t\t\t\t\t\tinProcess: args.inProcess === true,\n\t\t\t\t\t\t\tpretty: args.pretty === true,\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tbench: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"bench\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Measure hook duration (sandboxed, real probes) and compare against a baseline.\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\thook: {\n\t\t\t\t\t\t\ttype: \"positional\",\n\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\tdescription: `Hook to benchmark: ${HOOK_NAMES.join(\", \")}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdir: {\n\t\t\t\t\t\t\ttype: \"positional\",\n\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\tdescription: \"Data directory the hook reads from.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpluginDir: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Plugin directory (manifest.json + main.js). Defaults to the --main parent.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmain: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Path to the built plugin main.js. Defaults to <plugin-dir>/main.js.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tinProcess: {\n\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Run in-process instead of through the worker sandbox. Debugging only.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\trepeat: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Measured iterations after the warmup runs. Default 5.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\twarmup: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Discarded warmup runs before the measured samples. Default 1.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription: \"Write the JSON report to this file.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsave: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription: \"Save a fresh baseline report to this file.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompare: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Compare against a previous report file; exit 1 when the median regresses past --threshold.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tthreshold: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Regression threshold in percent of the baseline median. Default 20.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executeBench({\n\t\t\t\t\t\t\thook: parseHook(args.hook ?? \"\"),\n\t\t\t\t\t\t\tdir: args.dir ?? \"\",\n\t\t\t\t\t\t\tpluginDir: args.pluginDir,\n\t\t\t\t\t\t\tmain: args.main,\n\t\t\t\t\t\t\tinProcess: args.inProcess === true,\n\t\t\t\t\t\t\trepeat: parseRepeat(args.repeat),\n\t\t\t\t\t\t\twarmupRuns: parseWarmup(args.warmup),\n\t\t\t\t\t\t\tthresholdPercent: parseThreshold(args.threshold),\n\t\t\t\t\t\t\tjsonPath: args.json,\n\t\t\t\t\t\t\tsavePath: args.save,\n\t\t\t\t\t\t\tcomparePath: args.compare,\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tdev: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"dev\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Build a plugin in watch mode and serve it in the workbench (default http://127.0.0.1:5199), with sandboxed hooks, preview variants and video frames.\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\tpluginDir: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Plugin directory (manifest.json + package.json). Defaults to the current directory.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Data directory served as a single resource. Defaults to <plugin-dir>/testdata when it exists.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresourceDir: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Directory whose direct subfolders each become a resource (a folder of many test-data items). Mutually exclusive with --data and --storage.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tstorage: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"hoardodile storage root to develop against. Opened READ-ONLY: resources come from app.sqlite and their bare-file folders, and plugin writes stay in the workbench's in-memory mock.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tres: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Resource id to capture first when serving a storage root.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tport: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription: \"Workbench port. Default 5199.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executeDev({\n\t\t\t\t\t\t\tpluginDir: args.pluginDir ?? \"\",\n\t\t\t\t\t\t\tdataDir: args.data,\n\t\t\t\t\t\t\tresourceRootDir: args.resourceDir,\n\t\t\t\t\t\t\tstorageDir: args.storage,\n\t\t\t\t\t\t\tresId: args.res,\n\t\t\t\t\t\t\tport: args.port === undefined ? 5199 : parsePort(args.port),\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tbuild: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"build\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Build a plugin in the current directory (manifest.json + src/ + index.html) into dist/. Pass --watch to rebuild on change.\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\twatch: {\n\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\tdescription: \"Rebuild on file changes instead of exiting.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executeBuild({\n\t\t\t\t\t\t\tdir: process.cwd(),\n\t\t\t\t\t\t\twatch: args.watch === true,\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tpackage: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"package\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Build a plugin and zip dist/ into release/<id>-<version>.zip — the artifact to attach to a GitHub release for the app's plugin marketplace.\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\tpluginDir: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Plugin directory (manifest.json + package.json). Defaults to the current directory.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tskipBuild: {\n\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Do not rebuild before packaging (uses the existing dist/).\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executePackage({\n\t\t\t\t\t\t\tdir: args.pluginDir ?? process.cwd(),\n\t\t\t\t\t\t\tskipBuild: args.skipBuild === true,\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t}),\n\t},\n})\n\ntype RunOptions = {\n\treadonly hook: HookName\n\treadonly dir: string\n\treadonly pluginDir?: string\n\treadonly main?: string\n\treadonly inProcess: boolean\n\treadonly pretty?: boolean\n}\n\nasync function executeRun(opts: RunOptions): Promise<number> {\n\tconst exitCode = await executeRunInner(opts)\n\tprocess.exitCode = exitCode\n\treturn exitCode\n}\n\nasync function executeRunInner(opts: RunOptions): Promise<number> {\n\ttry {\n\t\tconst target = resolvePluginTarget({\n\t\t\tpluginDir: opts.pluginDir,\n\t\t\tmain: opts.main,\n\t\t})\n\t\tawait ensureFreshBuild(target)\n\t\t// A scratch extraction cache lets `extractArchive`-driven hooks\n\t\t// run against archive fixtures exactly as they do on the server.\n\t\tconst extractCacheDir = mkdtempSync(join(tmpdir(), \"hoard-cli-extract-\"))\n\t\ttry {\n\t\t\tconst outcome = opts.inProcess\n\t\t\t\t? await runInProcess(\n\t\t\t\t\t\ttarget.mainPath,\n\t\t\t\t\t\topts.hook,\n\t\t\t\t\t\topts.dir,\n\t\t\t\t\t\textractCacheDir,\n\t\t\t\t\t)\n\t\t\t\t: await withSandboxHooks(target, (hooks) =>\n\t\t\t\t\t\trunCliHook({\n\t\t\t\t\t\t\tid: target.id,\n\t\t\t\t\t\t\thooks,\n\t\t\t\t\t\t\thook: opts.hook,\n\t\t\t\t\t\t\tdir: opts.dir,\n\t\t\t\t\t\t\textractCacheDir,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\tconsole.log(JSON.stringify(outcome, null, opts.pretty ? 2 : 0))\n\t\t} finally {\n\t\t\trmSync(extractCacheDir, { recursive: true, force: true })\n\t\t}\n\t\treturn EXIT_PASS\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[hoardodile] ${err instanceof Error ? err.message : String(err)}`,\n\t\t)\n\t\treturn EXIT_ERROR\n\t}\n}\n\ntype BenchOptions = {\n\treadonly hook: HookName\n\treadonly dir: string\n\treadonly pluginDir?: string\n\treadonly main?: string\n\treadonly inProcess: boolean\n\treadonly repeat: number\n\treadonly warmupRuns: number\n\treadonly thresholdPercent: number\n\treadonly jsonPath?: string\n\treadonly savePath?: string\n\treadonly comparePath?: string\n}\n\nasync function executeBench(opts: BenchOptions): Promise<number> {\n\tconst exitCode = await executeBenchInner(opts)\n\tprocess.exitCode = exitCode\n\treturn exitCode\n}\n\nasync function executeBenchInner(opts: BenchOptions): Promise<number> {\n\ttry {\n\t\tconst target = resolvePluginTarget({\n\t\t\tpluginDir: opts.pluginDir,\n\t\t\tmain: opts.main,\n\t\t})\n\t\tawait ensureFreshBuild(target)\n\t\tif (opts.inProcess) {\n\t\t\tconst report = await computeBenchReport({\n\t\t\t\tpluginId: target.id,\n\t\t\t\thook: opts.hook,\n\t\t\t\tdir: opts.dir,\n\t\t\t\trepeat: opts.repeat,\n\t\t\t\twarmupRuns: opts.warmupRuns,\n\t\t\t\trun: () => runInProcess(target.mainPath, opts.hook, opts.dir),\n\t\t\t})\n\t\t\treturn finishBench(report, opts)\n\t\t}\n\t\t// One sandbox + one loaded plugin for the whole run: the warmup\n\t\t// iterations pay the worker spawn; samples measure steady-state\n\t\t// hook execution through the strategy facade.\n\t\tconst sandbox = createPluginSandbox(DEFAULT_SANDBOX_CONFIG)\n\t\ttry {\n\t\t\tconst hooks = await createCliHooks(target, sandbox)\n\t\t\tconst report = await computeBenchReport({\n\t\t\t\tpluginId: target.id,\n\t\t\t\thook: opts.hook,\n\t\t\t\tdir: opts.dir,\n\t\t\t\trepeat: opts.repeat,\n\t\t\t\twarmupRuns: opts.warmupRuns,\n\t\t\t\trun: () =>\n\t\t\t\t\trunCliHook({ id: target.id, hooks, hook: opts.hook, dir: opts.dir }),\n\t\t\t})\n\t\t\treturn finishBench(report, opts)\n\t\t} finally {\n\t\t\tawait sandbox.disposeAll()\n\t\t}\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[hoardodile] ${err instanceof Error ? err.message : String(err)}`,\n\t\t)\n\t\treturn EXIT_ERROR\n\t}\n}\n\nfunction finishBench(report: BenchReport, opts: BenchOptions): number {\n\tconsole.log(formatBenchSummary(report))\n\tlet compare: ReturnType<typeof compareBaseline> | undefined\n\tif (opts.comparePath !== undefined) {\n\t\tconst baseline = loadBaseline(opts.comparePath)\n\t\tcompare = compareBaseline(report, baseline, opts.thresholdPercent)\n\t\tconsole.log(compare.message)\n\t}\n\tif (opts.savePath !== undefined) writeReport(opts.savePath, report)\n\tif (opts.jsonPath !== undefined) writeReport(opts.jsonPath, report)\n\treturn benchExitCode(compare)\n}\n\ntype BuildOptions = {\n\treadonly dir: string\n\treadonly watch: boolean\n}\n\nasync function executeBuild(opts: BuildOptions): Promise<number> {\n\ttry {\n\t\tawait buildPlugin(opts.dir, { watch: opts.watch })\n\t\treturn EXIT_PASS\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[hoardodile] ${err instanceof Error ? err.message : String(err)}`,\n\t\t)\n\t\treturn EXIT_ERROR\n\t}\n}\n\ntype PackageOptions = {\n\treadonly dir: string\n\treadonly skipBuild: boolean\n}\n\nasync function executePackage(opts: PackageOptions): Promise<number> {\n\ttry {\n\t\tconst result = await packPlugin(opts.dir, { skipBuild: opts.skipBuild })\n\t\tconsole.log(`${result.id} v${result.version} → ${result.zipPath}`)\n\t\tconsole.log(`checksum: ${result.sha256Path}`)\n\t\tconsole.log(`registry line: ${result.registryLine}`)\n\t\tconsole.log(`publish: ${result.publishHint}`)\n\t\treturn EXIT_PASS\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[hoardodile] ${err instanceof Error ? err.message : String(err)}`,\n\t\t)\n\t\treturn EXIT_ERROR\n\t}\n}\n\n/** One sandbox + one loaded plugin for a single hook invocation. */\nasync function withSandboxHooks<T>(\n\ttarget: PluginTarget,\n\tfn: (hooks: PluginHooks) => Promise<T>,\n): Promise<T> {\n\tconst sandbox = createPluginSandbox(DEFAULT_SANDBOX_CONFIG)\n\ttry {\n\t\tconst hooks = await createCliHooks(target, sandbox)\n\t\treturn await fn(hooks)\n\t} finally {\n\t\tawait sandbox.disposeAll()\n\t}\n}\n\n/**\n * Rebuild a plugin's `dist/` when its sources are newer than the built\n * bundle — `plugin run`/`bench` execute the built `main.js`, so a\n * stale build silently runs old code. Only applies when the target\n * dir is a plugin's `dist/` sitting next to its sources\n * (`<plugin>/dist/` with `<plugin>/src/`); explicit `--main` bundles\n * are used as-is.\n */\nasync function ensureFreshBuild(target: PluginTarget): Promise<void> {\n\tconst distDir = target.dirPath\n\tconst pluginDir = dirname(distDir)\n\tconst srcDir = join(pluginDir, \"src\")\n\tconst manifestPath = join(pluginDir, \"manifest.json\")\n\tif (!existsSync(srcDir) || !existsSync(manifestPath)) return\n\tif (!existsSync(join(distDir, \"main.js\"))) return\n\tconst distMtime = newestFileMtime(distDir)\n\tconst newestSource = Math.max(\n\t\tnewestFileMtime(srcDir),\n\t\tstatSync(manifestPath).mtimeMs,\n\t)\n\t// Small tolerance for coarse filesystem mtime granularity (FAT, zip\n\t// round-trips) so a source written a moment before the build is not\n\t// judged stale by a rounding difference.\n\tconst REBUILD_TOLERANCE_MS = 2_000\n\tif (distMtime + REBUILD_TOLERANCE_MS <= newestSource) {\n\t\tconsole.log(`[hoardodile] dist/ is stale — rebuilding ${pluginDir}`)\n\t\tawait buildPlugin(pluginDir, { watch: false })\n\t}\n}\n\n/** Newest mtime under a directory tree (files only), or 0 when empty. */\nfunction newestFileMtime(dir: string): number {\n\tlet newest = 0\n\tfor (const entry of readdirSync(dir, { withFileTypes: true })) {\n\t\tconst full = join(dir, entry.name)\n\t\tif (entry.isDirectory()) {\n\t\t\tnewest = Math.max(newest, newestFileMtime(full))\n\t\t} else if (entry.isFile()) {\n\t\t\tnewest = Math.max(newest, statSync(full).mtimeMs)\n\t\t}\n\t}\n\treturn newest\n}\n\n/** Unsandboxed hook call for `--in-process` debugging. */\nasync function runInProcess(\n\tmainPath: string,\n\thook: HookName,\n\tdir: string,\n\textractCacheDir?: string,\n) {\n\tconst mod: unknown = await import(pathToFileURL(mainPath).href)\n\tif (typeof mod !== \"object\" || mod === null || !(\"default\" in mod)) {\n\t\tthrow new CliError(\n\t\t\t`plugin at ${mainPath} must default-export a plugin definition`,\n\t\t)\n\t}\n\tconst def = (mod as { default: PluginDefinition }).default\n\tconst fn = def[hook]\n\tif (typeof fn !== \"function\") {\n\t\tthrow new CliError(`plugin has no ${hook} hook`)\n\t}\n\tconst api = buildCliResourceAPI(dir, { extractCacheDir })\n\tconst started = performance.now()\n\tconst result = await fn(api)\n\treturn ok({ result, durationMs: performance.now() - started })\n}\n"]}
1
+ {"version":3,"sources":["../src/runner.ts","../src/bench.ts","../src/template-lint.ts","../src/build.ts","../src/create.ts","../src/hook-snapshot.ts","../src/render-providers.ts","../src/storage.ts","../src/dev.ts","../src/package.ts","../src/main.ts"],"names":["pluginManifestSchema","readFileSync","err","join","existsSync","issue","resolve","readdirSync","copyFileSync","createRequire","spawn","watch","mkdirSync","rmSync","writeFile","createHash","HOOK_NAMES","mkdtempSync","tmpdir","createPluginSandbox","DEFAULT_SANDBOX_CONFIG","dirname","statSync","pathToFileURL","ok"],"mappings":"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","file":"main.js","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\"\nimport { dirname, join, resolve } from \"node:path\"\nimport {\n\tbuildRegistry,\n\tcreateDirectoryContainer,\n\tcreatePluginHooks,\n\tcreatePluginResourceAPI,\n\tcreateProbeCache,\n\tHOOK_NAMES,\n\ttype HookName,\n\ttype PluginHooks,\n\ttype PluginSandbox,\n\ttype ResourceAPI,\n} from \"@hoardodile/host\"\nimport { mediaProbes } from \"@hoardodile/host/probe\"\nimport {\n\terr,\n\tok,\n\ttype PluginManifest,\n\ttype PluginManifestId,\n\ttype Result,\n} from \"@hoardodile/sdk-types\"\nimport { pluginManifest as pluginManifestSchema } from \"@hoardodile/sdk-types/schema\"\n\n/** Exit codes: 0 pass, 1 regression, 2 error. */\nexport const EXIT_PASS = 0\nexport const EXIT_REGRESSION = 1\nexport const EXIT_ERROR = 2\n\nexport class CliError extends Error {}\n\n/** Plugin hooks the CLI can run, in contract order (see {@link HOOK_NAMES}). */\nexport type CliHookName = HookName\n\n/**\n * Fallback manifest for `--main`-only invocations (no manifest.json\n * next to the bundle). Capability gating then denies every permission —\n * use `--plugin-dir` to exercise gated hooks.\n */\nconst FALLBACK_ID: PluginManifestId = \"00000000-0000-4000-8000-000000000000\"\n\nexport type PluginTarget = {\n\treadonly id: PluginManifestId\n\treadonly manifest: PluginManifest\n\treadonly mainPath: string\n\treadonly dirPath: string\n}\n\nexport function resolvePluginTarget(opts: {\n\treadonly main?: string\n\treadonly pluginDir?: string\n}): PluginTarget {\n\tconst dirPath =\n\t\topts.pluginDir !== undefined\n\t\t\t? resolve(opts.pluginDir)\n\t\t\t: opts.main !== undefined\n\t\t\t\t? dirname(resolve(opts.main))\n\t\t\t\t: undefined\n\tif (dirPath === undefined) {\n\t\tthrow new CliError(\"provide --plugin-dir <dir> or --main <main.js>\")\n\t}\n\tconst mainPath =\n\t\topts.main !== undefined ? resolve(opts.main) : join(dirPath, \"main.js\")\n\tif (!existsSync(mainPath)) {\n\t\tthrow new CliError(`plugin main.js not found: ${mainPath}`)\n\t}\n\n\tconst manifestPath = join(dirPath, \"manifest.json\")\n\tlet manifest: PluginManifest\n\tif (existsSync(manifestPath)) {\n\t\tconst parsed = pluginManifestSchema.safeParse(\n\t\t\tJSON.parse(readFileSync(manifestPath, \"utf-8\")),\n\t\t)\n\t\tif (!parsed.success) {\n\t\t\tthrow new CliError(\n\t\t\t\t`invalid manifest.json at ${manifestPath}: ${parsed.error.message}`,\n\t\t\t)\n\t\t}\n\t\tmanifest = parsed.data\n\t} else {\n\t\tmanifest = {\n\t\t\tid: FALLBACK_ID,\n\t\t\tname: \"cli-plugin\",\n\t\t\tdescription: \"CLI-invoked plugin without a manifest.json\",\n\t\t\tversion: \"0.0.0\",\n\t\t\tpermissions: {\n\t\t\t\tsourceMeta: false,\n\t\t\t\tsearchMeta: false,\n\t\t\t\tdanmaku: false,\n\t\t\t\tmessage: false,\n\t\t\t\timageHashes: false,\n\t\t\t\tcontainer: false,\n\t\t\t\tdownload: false,\n\t\t\t},\n\t\t}\n\t}\n\treturn { id: manifest.id, manifest, mainPath, dirPath }\n}\n\n/**\n * One process-wide probe cache for the CLI: a hook that sniffs then\n * probes the same entry (or probes it repeatedly) resolves from memory\n * instead of re-reading the header — the same behaviour the server gets\n * from its per-resource cache. Scoped per directory so distinct\n * fixtures never collide.\n */\nconst cliProbeCache = createProbeCache()\n\n/**\n * The {@link ResourceAPI} the CLI hands to hooks: a directory container\n * with the real probe implementations — identical to what the server\n * wires for its import path. `extractCacheDir` lets `extractArchive`\n * materialize archives next to the fixture during `plugin run`/`dev`.\n */\nexport function buildCliResourceAPI(\n\tdir: string,\n\topts: { readonly extractCacheDir?: string } = {},\n): ResourceAPI {\n\treturn createPluginResourceAPI({\n\t\tview: createDirectoryContainer(dir),\n\t\t...mediaProbes,\n\t\textractCacheDir: opts.extractCacheDir,\n\t\tprobeCache: cliProbeCache,\n\t\tcacheScope: `cli:${dir}`,\n\t})\n}\n\n/**\n * The {@link ResourceAPI} over a resource's bare-file source folder —\n * the exact container the server reads in production, so a hook\n * captured against a real library behaves identically.\n */\nexport function buildArchiveResourceAPI(\n\tresourceDir: string,\n\textractCacheDir?: string,\n): ResourceAPI {\n\treturn createPluginResourceAPI({\n\t\tview: createDirectoryContainer(resourceDir),\n\t\t...mediaProbes,\n\t\textractCacheDir,\n\t\tprobeCache: cliProbeCache,\n\t\tcacheScope: `cli:${resourceDir}`,\n\t})\n}\n\n/**\n * Single-plugin registry + hook facade over the worker sandbox. The\n * strategy layer (capability gating, error swallowing, result\n * validation) is exactly what the server runs.\n */\nexport async function createCliHooks(\n\ttarget: PluginTarget,\n\tsandbox: PluginSandbox,\n): Promise<PluginHooks> {\n\tconst plugin = await sandbox.loadPlugin({\n\t\tid: target.id,\n\t\tmainPath: target.mainPath,\n\t\teager: true,\n\t})\n\tif (plugin === undefined) {\n\t\tthrow new CliError(`plugin failed to load: ${target.mainPath}`)\n\t}\n\tconst registry = buildRegistry([\n\t\t{\n\t\t\tid: target.id,\n\t\t\tmanifest: target.manifest,\n\t\t\tenabled: true,\n\t\t\tpriority: 0,\n\t\t\tpinned: false,\n\t\t\tcolor: \"\",\n\t\t\tmissing: false,\n\t\t\tbuiltin: false,\n\t\t\tdev: false,\n\t\t\tplugin,\n\t\t\tdiskPath: target.dirPath,\n\t\t},\n\t])\n\treturn createPluginHooks({ getRegistry: () => registry })\n}\n\nexport type HookOutcome = Result<\n\t{ readonly result: unknown; readonly durationMs: number },\n\t{ readonly result: string; readonly durationMs: number }\n>\n\n/**\n * Run one hook through the strategy facade. Errors are surfaced on\n * `ok:false` (the facade normally swallows them — `--in-process` raises\n * them instead for debugging).\n */\nexport async function runCliHook(opts: {\n\treadonly id: PluginManifestId\n\treadonly hooks: PluginHooks\n\treadonly hook: CliHookName\n\treadonly dir: string\n\t/** Writable dir for `extractArchive` materialization. */\n\treadonly extractCacheDir?: string\n}): Promise<HookOutcome> {\n\tconst api = buildCliResourceAPI(opts.dir, {\n\t\textractCacheDir: opts.extractCacheDir,\n\t})\n\tconst started = performance.now()\n\tlet result: unknown\n\ttry {\n\t\tswitch (opts.hook) {\n\t\t\tcase \"detect\":\n\t\t\t\tresult = await opts.hooks.detectForPlugin(api, opts.id)\n\t\t\t\tbreak\n\t\t\tcase \"sourceMeta\":\n\t\t\t\tresult = (await opts.hooks.runMetaHooks(api, opts.id)).sourceMeta?.value\n\t\t\t\tbreak\n\t\t\tcase \"searchMeta\":\n\t\t\t\tresult = (await opts.hooks.runMetaHooks(api, opts.id)).searchMeta?.value\n\t\t\t\tbreak\n\t\t\tcase \"coverLocal\":\n\t\t\t\tresult = await opts.hooks.resolveLocalCoverSource(api, opts.id)\n\t\t\t\tbreak\n\t\t\tcase \"listFiles\":\n\t\t\t\tresult = await opts.hooks.buildFileList(api, opts.id)\n\t\t\t\tbreak\n\t\t}\n\t} catch (caught) {\n\t\treturn err({\n\t\t\tresult: caught instanceof Error ? caught.message : String(caught),\n\t\t\tdurationMs: performance.now() - started,\n\t\t})\n\t}\n\treturn ok({ result, durationMs: performance.now() - started })\n}\n","import { readFileSync, writeFileSync } from \"node:fs\"\nimport os from \"node:os\"\nimport type { PluginManifestId } from \"@hoardodile/sdk-types\"\nimport {\n\ttype CliHookName,\n\tEXIT_ERROR,\n\tEXIT_PASS,\n\tEXIT_REGRESSION,\n\ttype HookOutcome,\n} from \"./runner.ts\"\n\n/**\n * Benchmark contract for hook-duration measurement and regression\n * comparison. The report shape matches the server-side bench suites in\n * apps/server/bench: the same machine fingerprint, memory peak, warmup\n * semantics, threshold gating and exit codes. See the `bench` command\n * docs.\n */\n\nexport type BenchStats = {\n\treadonly medianMs: number\n\treadonly meanMs: number\n\treadonly p95Ms: number\n\treadonly minMs: number\n\treadonly maxMs: number\n}\n\n/** Machine fingerprint used to gate baseline comparisons. */\nexport type MachineInfo = {\n\treadonly platform: string\n\treadonly arch: string\n\treadonly cpus: number\n\treadonly cpuModel: string\n\treadonly node: string\n}\n\nexport type BenchReport = {\n\treadonly schema: 1\n\treadonly kind: \"plugin-hook\"\n\treadonly timestamp: string\n\treadonly config: {\n\t\treadonly pluginId: PluginManifestId\n\t\treadonly hook: CliHookName\n\t\treadonly dir: string\n\t\treadonly repeat: number\n\t\treadonly warmupRuns: number\n\t}\n\treadonly machine: MachineInfo\n\treadonly caveats: readonly string[]\n\t/** Peak host RSS observed across the measured runs. */\n\treadonly memoryPeakMb: number\n\treadonly samplesMs: readonly number[]\n\treadonly stats: BenchStats\n}\n\nexport type BenchOptions = {\n\treadonly repeat: number\n\t/** Discarded warmup runs before the measured samples. Default 1. */\n\treadonly warmupRuns: number\n\t/** Fail (exit 1) when the median exceeds baseline × (1 + threshold/100). */\n\treadonly thresholdPercent: number\n}\n\nconst DEFAULT_WARMUP_RUNS = 1\n\nexport function machineInfo(): MachineInfo {\n\treturn {\n\t\tplatform: os.platform(),\n\t\tarch: os.arch(),\n\t\tcpus: os.cpus().length,\n\t\tcpuModel: os.cpus()[0]?.model ?? \"unknown\",\n\t\tnode: process.version,\n\t}\n}\n\nfunction fingerprint(machine: MachineInfo): string {\n\treturn [\n\t\tmachine.platform,\n\t\tmachine.arch,\n\t\tmachine.cpus,\n\t\tmachine.cpuModel,\n\t\tmachine.node,\n\t].join(\"|\")\n}\n\n/** One warmup run is discarded so worker spawn and lazy loads never pollute samples. */\nexport function computeBenchReport(opts: {\n\treadonly pluginId: PluginManifestId\n\treadonly hook: CliHookName\n\treadonly dir: string\n\treadonly repeat: number\n\treadonly warmupRuns: number\n\treadonly run: () => Promise<HookOutcome>\n}): Promise<BenchReport> {\n\treturn (async () => {\n\t\tfor (let i = 0; i < opts.warmupRuns; i++) {\n\t\t\tawait opts.run()\n\t\t}\n\t\tconst samples: number[] = []\n\t\tlet peakRss = 0\n\t\tfor (let i = 0; i < opts.repeat; i++) {\n\t\t\tconst outcome = await opts.run()\n\t\t\tsamples.push(outcome.durationMs)\n\t\t\tpeakRss = Math.max(peakRss, process.memoryUsage().rss)\n\t\t}\n\t\treturn {\n\t\t\tschema: 1,\n\t\t\tkind: \"plugin-hook\",\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tconfig: {\n\t\t\t\tpluginId: opts.pluginId,\n\t\t\t\thook: opts.hook,\n\t\t\t\tdir: opts.dir,\n\t\t\t\trepeat: opts.repeat,\n\t\t\t\twarmupRuns: opts.warmupRuns,\n\t\t\t},\n\t\t\tmachine: machineInfo(),\n\t\t\tcaveats: [\n\t\t\t\t\"Baselines are only valid on the same machine and environment — absolute sandbox timings (worker + protocol + probes) are not comparable across machines.\",\n\t\t\t],\n\t\t\tmemoryPeakMb: Math.round((peakRss / 1024 / 1024) * 10) / 10,\n\t\t\tsamplesMs: samples,\n\t\t\tstats: computeStats(samples),\n\t\t}\n\t})()\n}\n\nexport function computeStats(samples: readonly number[]): BenchStats {\n\tconst sorted = [...samples].sort((a, b) => a - b)\n\tconst median = sorted[Math.floor(sorted.length / 2)] ?? 0\n\tconst mean = samples.reduce((a, b) => a + b, 0) / Math.max(1, samples.length)\n\tconst p95 =\n\t\tsorted[Math.min(sorted.length - 1, Math.floor(sorted.length * 0.95))] ?? 0\n\treturn {\n\t\tmedianMs: round1(median),\n\t\tmeanMs: round1(mean),\n\t\tp95Ms: round1(p95),\n\t\tminMs: round1(sorted[0] ?? 0),\n\t\tmaxMs: round1(sorted[sorted.length - 1] ?? 0),\n\t}\n}\n\nexport function loadBaseline(path: string): BenchReport {\n\tlet parsed: unknown\n\ttry {\n\t\tparsed = JSON.parse(readFileSync(path, \"utf-8\"))\n\t} catch (err) {\n\t\tthrow new Error(\n\t\t\t`cannot read baseline file ${path}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t)\n\t}\n\tif (!isBenchReport(parsed)) {\n\t\tthrow new Error(\n\t\t\t`baseline file ${path} is not a bench report (kind plugin-hook)`,\n\t\t)\n\t}\n\treturn parsed\n}\n\nfunction isBenchReport(value: unknown): value is BenchReport {\n\tif (typeof value !== \"object\" || value === null) return false\n\tconst v = value as Record<string, unknown>\n\tif (v.schema !== 1) return false\n\tif (v.kind !== \"plugin-hook\") return false\n\tif (typeof v.timestamp !== \"string\") return false\n\tconst config = v.config\n\tif (\n\t\ttypeof config !== \"object\" ||\n\t\tconfig === null ||\n\t\ttypeof (config as Record<string, unknown>).pluginId !== \"string\" ||\n\t\ttypeof (config as Record<string, unknown>).hook !== \"string\"\n\t) {\n\t\treturn false\n\t}\n\tconst machine = v.machine\n\tif (\n\t\ttypeof machine !== \"object\" ||\n\t\tmachine === null ||\n\t\ttypeof (machine as Record<string, unknown>).node !== \"string\"\n\t) {\n\t\treturn false\n\t}\n\tconst stats = v.stats\n\treturn (\n\t\ttypeof stats === \"object\" &&\n\t\tstats !== null &&\n\t\ttypeof (stats as Record<string, unknown>).medianMs === \"number\"\n\t)\n}\n\nexport type CompareResult = {\n\treadonly baseline: BenchReport\n\treadonly ratio: number\n\treadonly regressed: boolean\n\treadonly message: string\n}\n\n/** Compare a fresh report against a baseline; exit 1 on regression. */\nexport function compareBaseline(\n\treport: BenchReport,\n\tbaseline: BenchReport,\n\tthresholdPercent: number,\n): CompareResult {\n\tif (fingerprint(report.machine) !== fingerprint(baseline.machine)) {\n\t\tconsole.warn(\n\t\t\t`WARNING: baseline machine differs (fresh: ${fingerprint(report.machine)} vs baseline: ${fingerprint(baseline.machine)}) — sandbox timings are not comparable across machines.`,\n\t\t)\n\t}\n\tconst ratio =\n\t\treport.stats.medianMs / Math.max(0.0001, baseline.stats.medianMs)\n\tconst regressed =\n\t\treport.stats.medianMs >\n\t\tbaseline.stats.medianMs * (1 + thresholdPercent / 100)\n\tconst delta = ((ratio - 1) * 100).toFixed(1)\n\tconst message = regressed\n\t\t? `REGRESSION: median ${report.stats.medianMs}ms vs baseline ${baseline.stats.medianMs}ms (${delta}%) exceeds the ${thresholdPercent}% threshold. Baselines are only valid on the same machine and environment — absolute sandbox timings (worker + protocol + probes) are not comparable across machines.`\n\t\t: `median ${report.stats.medianMs}ms vs baseline ${baseline.stats.medianMs}ms (${delta}%) — within the ${thresholdPercent}% threshold.`\n\treturn { baseline, ratio, regressed, message }\n}\n\nexport function writeReport(path: string, report: BenchReport): void {\n\twriteFileSync(path, `${JSON.stringify(report, null, 2)}\\n`)\n}\n\nexport function formatBenchSummary(report: BenchReport): string {\n\tconst lines = [\n\t\t`hook ${report.config.hook} × ${report.config.repeat} (${report.config.warmupRuns} warmup)`,\n\t\t`plugin ${report.config.pluginId}`,\n\t\t`machine ${report.machine.platform}/${report.machine.arch} · ${report.machine.cpus} cpus (${report.machine.cpuModel}) · node ${report.machine.node} · peak rss ${report.memoryPeakMb}MB`,\n\t\t`samples: ${report.samplesMs.map((ms) => `${ms.toFixed(1)}ms`).join(\" \")}`,\n\t\t`median ${report.stats.medianMs}ms · mean ${report.stats.meanMs}ms · p95 ${report.stats.p95Ms}ms · min ${report.stats.minMs}ms · max ${report.stats.maxMs}ms`,\n\t]\n\treturn lines.join(\"\\n\")\n}\n\nexport function benchExitCode(compare: CompareResult | undefined): number {\n\tif (compare === undefined) return EXIT_PASS\n\treturn compare.regressed ? EXIT_REGRESSION : EXIT_PASS\n}\n\nexport { DEFAULT_WARMUP_RUNS, EXIT_ERROR }\n\nfunction round1(value: number): number {\n\treturn Math.round(value * 10) / 10\n}\n","import type { PluginManifest } from \"@hoardodile/sdk-types\"\nimport {\n\tparseTemplateExpression,\n\tparseTemplateFragments,\n\ttype TemplateArg,\n\ttype TemplateExpr,\n\ttokeniseExpression,\n} from \"@hoardodile/sdk-types/template\"\n\n/**\n * Build-time validation of the manifest's host-rendered template\n * strings (`ui.card` corners, `ui.search` labels/icons, `ui.message`\n * anchors). Runs the same grammar the web renderer evaluates — shared\n * from `@hoardodile/sdk-types/template` — so a template that passes here\n * renders in the app, and the mistakes that would silently render\n * empty covers (malformed expressions, unbalanced parentheses,\n * unknown functions, undeclared i18n keys) fail the build.\n */\n\n/** Function names the host's template engine recognizes. */\nconst KNOWN_FUNCTIONS = new Set([\n\t\"asset\",\n\t\"bytes\",\n\t\"duration\",\n\t\"eq\",\n\t\"gt\",\n\t\"gte\",\n\t\"icon\",\n\t\"if\",\n\t\"inc\",\n\t\"join\",\n\t\"kind\",\n\t\"lt\",\n\t\"lte\",\n\t\"ne\",\n\t\"number\",\n\t\"searchKindIcons\",\n\t\"t\",\n])\n\nexport type TemplateLintIssue = {\n\treadonly template: string\n\treadonly message: string\n}\n\n/**\n * Validate one template string. Returns a list of problems; empty\n * means the template is well-formed.\n */\nexport function lintTemplate(\n\ttemplate: string,\n\ti18nKeys: ReadonlySet<string>,\n): readonly TemplateLintIssue[] {\n\tconst issues: TemplateLintIssue[] = []\n\n\tconst open = (template.match(/\\{\\{/g) ?? []).length\n\tconst close = (template.match(/\\}\\}/g) ?? []).length\n\tif (open !== close) {\n\t\treturn [\n\t\t\t{\n\t\t\t\ttemplate,\n\t\t\t\tmessage: `unbalanced {{ }} braces (${open} open, ${close} close)`,\n\t\t\t},\n\t\t]\n\t}\n\n\tfor (const fragment of parseTemplateFragments(template)) {\n\t\tif (fragment.kind !== \"expr\") continue\n\t\tlintExpression(fragment.source, template, i18nKeys, issues)\n\t}\n\treturn issues\n}\n\nfunction lintExpression(\n\tsource: string,\n\ttemplate: string,\n\ti18nKeys: ReadonlySet<string>,\n\tissues: TemplateLintIssue[],\n): void {\n\tconst tokens = tokeniseExpression(source)\n\tconst opens = tokens.filter((t) => t.kind === \"lparen\").length\n\tconst closes = tokens.filter((t) => t.kind === \"rparen\").length\n\tif (opens !== closes) {\n\t\tissues.push({\n\t\t\ttemplate,\n\t\t\tmessage: `unbalanced parentheses in {{${source}}} (${opens} open, ${closes} close)`,\n\t\t})\n\t\treturn\n\t}\n\tconst expr = parseTemplateExpression(source)\n\tif (expr === undefined) {\n\t\tissues.push({\n\t\t\ttemplate,\n\t\t\tmessage: `cannot parse expression \"{{${source}}}\" (expected a call or path)`,\n\t\t})\n\t\treturn\n\t}\n\twalkExpr(expr, (call) => {\n\t\tif (!KNOWN_FUNCTIONS.has(call.name)) {\n\t\t\tissues.push({\n\t\t\t\ttemplate,\n\t\t\t\tmessage: `unknown function \"${call.name}\" (known: ${[...KNOWN_FUNCTIONS].join(\", \")})`,\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tif (call.name === \"t\") {\n\t\t\tconst key = firstStringArg(call.args)\n\t\t\tif (key !== undefined && !i18nKeys.has(key)) {\n\t\t\t\tissues.push({\n\t\t\t\t\ttemplate,\n\t\t\t\t\tmessage: `t('${key}') references an i18n key the manifest does not declare`,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t})\n}\n\n/** Visit every call node of the AST, nested calls included. */\nfunction walkExpr(\n\texpr: TemplateExpr,\n\tvisit: (call: Extract<TemplateExpr, { readonly kind: \"call\" }>) => void,\n): void {\n\tif (expr.kind !== \"call\") return\n\tvisit(expr)\n\tfor (const arg of expr.args) {\n\t\tif (arg.kind === \"expr\") walkExpr(arg.expr, visit)\n\t}\n}\n\n/** First string literal argument of `fn('...', ...)`, if any. */\nfunction firstStringArg(args: readonly TemplateArg[]): string | undefined {\n\tconst first = args[0]\n\tif (first?.kind === \"string\") return first.value\n\treturn undefined\n}\n\n/** Collect every template string the manifest declares. */\nexport function manifestTemplates(manifest: PluginManifest): readonly string[] {\n\tconst templates: string[] = []\n\tfor (const block of Object.values(manifest.ui?.card ?? {})) {\n\t\tif (block === undefined) continue\n\t\tfor (const corner of [block.tl, block.tr, block.bl, block.br]) {\n\t\t\tif (corner !== undefined) templates.push(...corner)\n\t\t}\n\t}\n\tfor (const kind of manifest.ui?.search?.kinds ?? []) {\n\t\ttemplates.push(kind.label)\n\t\tif (kind.icon !== undefined) templates.push(kind.icon)\n\t}\n\tif (manifest.ui?.message?.anchor !== undefined) {\n\t\ttemplates.push(manifest.ui.message.anchor)\n\t}\n\treturn templates\n}\n\n/**\n * Lint every template in the manifest. Returns the declared i18n keys\n * plus the issues found; callers decide how strict to be.\n */\nexport function lintManifestTemplates(manifest: PluginManifest): {\n\treadonly templates: readonly string[]\n\treadonly issues: readonly TemplateLintIssue[]\n} {\n\tconst templates = manifestTemplates(manifest)\n\t// `i18n` maps label key → { locale: label } (the host's template\n\t// engine looks up `manifest.i18n[key]` then resolves the locale).\n\tconst i18nKeys = new Set(Object.keys(manifest.i18n ?? {}))\n\tconst issues: TemplateLintIssue[] = []\n\tfor (const template of templates) {\n\t\tissues.push(...lintTemplate(template, i18nKeys))\n\t}\n\treturn { templates, issues }\n}\n","import {\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trmSync,\n\twatch,\n} from \"node:fs\"\nimport { join } from \"node:path\"\nimport type { PluginManifest } from \"@hoardodile/sdk-types\"\nimport babel from \"@rolldown/plugin-babel\"\nimport tailwindcss from \"@tailwindcss/vite\"\nimport react, { reactCompilerPreset } from \"@vitejs/plugin-react\"\nimport { build } from \"vite\"\nimport { lintManifestTemplates } from \"./template-lint.ts\"\n\ntype BuildResult = Awaited<ReturnType<typeof build>>\n\n/** In watch mode vite's `build()` returns a live watcher instead of a bundle. */\nfunction isWatcher(\n\tresult: BuildResult,\n): result is Extract<BuildResult, { on: unknown }> {\n\treturn \"on\" in result\n}\n\n/**\n * Build a plugin from `dir` (must contain `manifest.json` and optionally\n * `src/main.ts` / `index.html`). Output goes to `dir/dist/`.\n *\n * Pass `watch: true` to rebuild on file changes instead of exiting.\n */\nexport async function buildPlugin(\n\tdir: string,\n\topts: { readonly watch: boolean },\n): Promise<void> {\n\tconst watchMode = opts.watch\n\tconst manifestPath = join(dir, \"manifest.json\")\n\tif (!existsSync(manifestPath)) {\n\t\tthrow new Error(`No manifest.json found in ${dir}`)\n\t}\n\n\tconst manifest = JSON.parse(readFileSync(manifestPath, \"utf-8\"))\n\tif (typeof manifest.id !== \"string\" || manifest.id.length === 0) {\n\t\tthrow new Error(\"manifest.json missing id field\")\n\t}\n\tlintTemplates(manifest as PluginManifest)\n\n\tconst outDir = join(dir, \"dist\")\n\n\tif (!watchMode) {\n\t\trmSync(outDir, { recursive: true, force: true })\n\t}\n\tmkdirSync(outDir, { recursive: true })\n\n\tconst htmlEntry = join(dir, \"index.html\")\n\tconst mainEntry = join(dir, \"src\", \"main.ts\")\n\n\tif (existsSync(htmlEntry)) {\n\t\tconst result = await build({\n\t\t\troot: dir,\n\t\t\tbase: \"./\",\n\t\t\t// React Compiler only on the iframe client build; the server\n\t\t\t// (SSR) bundle runs in a worker sandbox with no rendering.\n\t\t\tplugins: [\n\t\t\t\treact(),\n\t\t\t\tbabel({ presets: [reactCompilerPreset()] }),\n\t\t\t\ttailwindcss(),\n\t\t\t],\n\t\t\tbuild: {\n\t\t\t\toutDir,\n\t\t\t\temptyOutDir: false,\n\t\t\t\tchunkSizeWarningLimit: Infinity,\n\t\t\t\trollupOptions: {\n\t\t\t\t\tinput: htmlEntry,\n\t\t\t\t},\n\t\t\t\twatch: watchMode ? {} : null,\n\t\t\t},\n\t\t})\n\t\tif (watchMode && isWatcher(result)) {\n\t\t\tresult.on(\"event\", (event) => {\n\t\t\t\tif (event.code === \"END\") {\n\t\t\t\t\tconsole.log(`[watch] ${manifest.id} client rebuilt`)\n\t\t\t\t} else if (event.code === \"ERROR\") {\n\t\t\t\t\tconsole.error(`[watch] ${manifest.id} client error:`, event.error)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\tif (existsSync(mainEntry)) {\n\t\tconst result = await build({\n\t\t\troot: dir,\n\t\t\tplugins: [react()],\n\t\t\t// The server bundle runs inside the permission-model sandbox,\n\t\t\t// which grants fs-read to the plugin dir only and lets the module\n\t\t\t// policy gate load nothing outside it — the bundle must be one\n\t\t\t// self-contained ESM file. Vite's default externalizes\n\t\t\t// node_modules dependencies, which is exactly what an installed\n\t\t\t// (tarball/npm) plugin hits: its `main.js` would keep bare\n\t\t\t// `@hoardodile/*` imports whose resolution the sandbox denies.\n\t\t\t// Inline everything instead (workspace plugins already ended up\n\t\t\t// inlined via source resolution — this makes both cases uniform).\n\t\t\tssr: { noExternal: true },\n\t\t\tbuild: {\n\t\t\t\tssr: mainEntry,\n\t\t\t\toutDir,\n\t\t\t\temptyOutDir: false,\n\t\t\t\ttarget: \"node24\",\n\t\t\t\trollupOptions: {\n\t\t\t\t\toutput: {\n\t\t\t\t\t\tentryFileNames: \"main.js\",\n\t\t\t\t\t\tchunkFileNames: \"[name].js\",\n\t\t\t\t\t},\n\t\t\t\t\texternal: [],\n\t\t\t\t},\n\t\t\t\twatch: watchMode ? {} : null,\n\t\t\t},\n\t\t})\n\t\tassertSelfContainedServerBundle(join(outDir))\n\t\tif (watchMode && isWatcher(result)) {\n\t\t\tresult.on(\"event\", (event) => {\n\t\t\t\tif (event.code === \"END\") {\n\t\t\t\t\tassertSelfContainedServerBundle(join(outDir))\n\t\t\t\t\tconsole.log(`[watch] ${manifest.id} server rebuilt`)\n\t\t\t\t} else if (event.code === \"ERROR\") {\n\t\t\t\t\tconsole.error(`[watch] ${manifest.id} server error:`, event.error)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\tcopyFileSync(manifestPath, join(outDir, \"manifest.json\"))\n\n\tif (watchMode) {\n\t\twatch(manifestPath, () => {\n\t\t\tcopyFileSync(manifestPath, join(outDir, \"manifest.json\"))\n\t\t\tconsole.log(`[watch] ${manifest.id} manifest updated`)\n\t\t})\n\t\tconsole.log(`[watch] ${manifest.id} watching for changes...`)\n\t\tawait new Promise(() => {})\n\t}\n\tconsole.log(`${manifest.id} → ${outDir}`)\n}\n\n/**\n * Fail the build on malformed cover/search/message templates, warn on\n * i18n keys the manifest never declares. A bad template renders a\n * silent empty cover — catching it here beats discovering it in the\n * app.\n */\nfunction lintTemplates(manifest: PluginManifest): void {\n\tconst { templates, issues } = lintManifestTemplates(manifest)\n\tif (templates.length === 0) return\n\tconst errors = issues.filter((issue) => !issue.message.includes(\"i18n key\"))\n\tif (errors.length > 0) {\n\t\tconst detail = errors\n\t\t\t.map((issue) => ` - ${issue.message}\\n ${issue.template}`)\n\t\t\t.join(\"\\n\")\n\t\tthrow new Error(`manifest template validation failed:\\n${detail}`)\n\t}\n\tfor (const issue of issues.filter((issue) =>\n\t\tissue.message.includes(\"i18n key\"),\n\t)) {\n\t\tconsole.warn(`[build] warning: ${issue.message}\\n ${issue.template}`)\n\t}\n}\n\n/**\n * Fail the build when the server bundle is not self-contained. The\n * plugin main process runs in a capability sandbox whose only privileged\n * interface is the host's ResourceAPI RPC: its fs-read grant is the\n * plugin dir, and its module policy gate allows no bare imports — so\n * `node:` imports, `require` and any specifier that must resolve outside\n * the bundle never have a legitimate home in it. (The Vite SSR build\n * inlines the SDK closure via `ssr.noExternal`; this check is an early,\n * friendly error if that ever regresses.)\n */\nfunction assertSelfContainedServerBundle(outDir: string): void {\n\tfor (const file of readdirSync(outDir, { withFileTypes: true })) {\n\t\tif (!file.isFile() || !file.name.endsWith(\".js\")) continue\n\t\tconst source = readFileSync(join(outDir, file.name), \"utf-8\")\n\t\t// Computed specifiers (`import(\"node:\" + x)`) slip past a static\n\t\t// scan by design — the runtime policy gate still denies them.\n\t\tif (/(?:from\\s*[\"']node:|import\\s*\\(\\s*[\"']node:)/.test(source)) {\n\t\t\tthrow new Error(\n\t\t\t\t`plugin main bundle (${file.name}) imports a Node builtin — the plugin main process cannot use node:fs/net/child_process/…; read files and probe metadata through the ResourceAPI instead`,\n\t\t\t)\n\t\t}\n\t\tif (/\\brequire\\s*\\(/.test(source)) {\n\t\t\tthrow new Error(\n\t\t\t\t`plugin main bundle (${file.name}) calls require() — the plugin main process is self-contained; use the ResourceAPI instead`,\n\t\t\t)\n\t\t}\n\t\t// Bare specifiers (anything that is not a relative/absolute path)\n\t\t// resolve through node_modules — outside the sandbox's fs-read\n\t\t// grant. The build keeps them only when a dependency was left\n\t\t// external, which can never load in the sandbox.\n\t\tif (/(?:from\\s*[\"']|import\\s*\\(\\s*[\"'])(?![./])/.test(source)) {\n\t\t\tthrow new Error(\n\t\t\t\t`plugin main bundle (${file.name}) leaves a bare import unresolved — the SDK closure must be inlined; the plugin sandbox cannot load node_modules`,\n\t\t\t)\n\t\t}\n\t}\n}\n","import { spawn } from \"node:child_process\"\nimport { EXIT_ERROR } from \"./runner.ts\"\n\nexport type CreateOptions = {\n\treadonly name?: string\n\treadonly tarballs?: string\n}\n\n/**\n * `hoardodile plugin create` — facade over the published scaffolder.\n * `create-hoardodile-plugin` stays its own package (npm's `create-*`\n * convention), so this runs it via `pnpm dlx` and forwards the args.\n */\nexport function resolveCreateArgs(opts: CreateOptions): string[] {\n\tconst args = [\"dlx\", \"--yes\", \"create-hoardodile-plugin\"]\n\tif (opts.name !== undefined) args.push(opts.name)\n\tif (opts.tarballs !== undefined) args.push(\"--tarballs\", opts.tarballs)\n\treturn args\n}\n\nexport async function executeCreate(opts: CreateOptions): Promise<number> {\n\treturn new Promise((resolveExit) => {\n\t\tconst child = spawn(\"pnpm\", resolveCreateArgs(opts), {\n\t\t\tstdio: \"inherit\",\n\t\t\tshell: process.platform === \"win32\",\n\t\t})\n\t\tchild.on(\"error\", (err) => {\n\t\t\tconsole.error(\n\t\t\t\t`[hoardodile] failed to start create-hoardodile-plugin: ${err.message}`,\n\t\t\t)\n\t\t\tresolveExit(EXIT_ERROR)\n\t\t})\n\t\tchild.on(\"exit\", (code) => {\n\t\t\tresolveExit(code ?? EXIT_ERROR)\n\t\t})\n\t})\n}\n","import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\nimport {\n\tcreatePluginSandbox,\n\tDEFAULT_SANDBOX_CONFIG,\n\ttype PluginHooks,\n\ttype ResourceAPI,\n} from \"@hoardodile/host\"\nimport type { FileStats, PluginManifest } from \"@hoardodile/sdk-types\"\nimport { pluginManifest as pluginManifestSchema } from \"@hoardodile/sdk-types/schema\"\nimport type { PluginTarget } from \"./runner.ts\"\nimport { CliError, createCliHooks } from \"./runner.ts\"\n\n/**\n * The server-side hook results the iframe needs to render exactly like\n * production: the host pushes `sourceMeta`, `searchMeta` and `fileStats`\n * into the plugin context, and answers `listFiles` with the plugin's own\n * hook output. `hoardodile plugin dev` captures them from the real\n * sandbox so the workbench is a faithful stand-in for the app.\n *\n * `errors` records hooks that threw; the facade swallows failures, so\n * without this a broken hook is indistinguishable from an absent one.\n */\nexport type PluginHookSnapshot = {\n\treadonly pluginId: string\n\treadonly detect: {\n\t\treadonly ok: boolean\n\t\treadonly reasons?: readonly string[]\n\t}\n\treadonly sourceMeta: unknown\n\treadonly searchMeta: unknown\n\treadonly coverLocal: string | undefined\n\t/**\n\t * The resource's cover kind (`image` | `video` | `audio`), sniffed\n\t * from the cover source the plugin's `coverLocal` hook picked. The\n\t * host app selects the manifest's `ui.card.<kind>` block from the\n\t * comparable `coverMeta.kind`, so the workbench needs this to render\n\t * the same card templates. `undefined` when there is no cover source\n\t * or the file cannot be classified as a cover kind.\n\t */\n\treadonly coverKind?: string\n\treadonly files: readonly unknown[] | undefined\n\treadonly fileStats: FileStats\n\treadonly imageHashes?: readonly unknown[]\n\treadonly errors: Readonly<Record<string, string>>\n\treadonly capturedAt: number\n}\n\n/**\n * The snapshot's detect entry: `ok` plus the miss reasons only. A\n * successful match may carry a schema payload (flowed to hooks via\n * `api.context`) that the workbench never consumes — keeping it out of\n * the snapshot avoids serializing plugin classifications the mock host\n * has no use for.\n */\nexport function snapshotDetect(detection: {\n\treadonly ok: boolean\n\treadonly reasons?: readonly string[]\n}): PluginHookSnapshot[\"detect\"] {\n\treturn detection.ok ? { ok: true } : { ok: false, reasons: detection.reasons }\n}\n\n/**\n * Assemble the plugin target for a source directory: the manifest is\n * authored next to `src/`, the bundle lands in `dist/`.\n * `resolvePluginTarget` only understands a single base dir, hence the\n * dedicated resolver here.\n */\nexport function resolveBuiltPluginTarget(pluginDir: string): PluginTarget {\n\tconst manifestPath = join(pluginDir, \"manifest.json\")\n\tif (!existsSync(manifestPath)) {\n\t\tthrow new CliError(`no manifest.json found in ${pluginDir}`)\n\t}\n\tconst mainPath = join(pluginDir, \"dist\", \"main.js\")\n\tif (!existsSync(mainPath)) {\n\t\tthrow new CliError(`plugin bundle not built: ${mainPath}`)\n\t}\n\tconst manifest: PluginManifest = pluginManifestSchema.parse(\n\t\tJSON.parse(readFileSync(manifestPath, \"utf8\")),\n\t)\n\treturn { id: manifest.id, manifest, mainPath, dirPath: pluginDir }\n}\n\n/**\n * Run the plugin's server-side hooks against `api` through a throwaway\n * sandbox and collect the results. A fresh sandbox per capture is what\n * makes watch rebuilds visible: the worker caches the module graph it\n * loaded, so reusing one would keep serving the stale bundle.\n */\nexport async function captureHookSnapshot(opts: {\n\treadonly target: PluginTarget\n\t/** Resource view the hooks read (a directory-backed ResourceAPI). */\n\treadonly api: ResourceAPI\n}): Promise<PluginHookSnapshot> {\n\tconst { target, api } = opts\n\tconst sandbox = createPluginSandbox(DEFAULT_SANDBOX_CONFIG)\n\ttry {\n\t\tconst hooks = await createCliHooks(target, sandbox)\n\t\treturn await collectHookResults({ target, api, hooks })\n\t} finally {\n\t\tawait sandbox.disposeAll()\n\t}\n}\n\nasync function collectHookResults(opts: {\n\treadonly target: PluginTarget\n\treadonly api: ResourceAPI\n\treadonly hooks: PluginHooks\n}): Promise<PluginHookSnapshot> {\n\tconst { target, api, hooks } = opts\n\tconst errors: Record<string, string> = {}\n\n\tasync function attempt<T>(\n\t\thook: string,\n\t\trun: () => Promise<T>,\n\t): Promise<T | undefined> {\n\t\ttry {\n\t\t\treturn await run()\n\t\t} catch (err) {\n\t\t\terrors[hook] = err instanceof Error ? err.message : String(err)\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\tconst detect = snapshotDetect(\n\t\t(await attempt(\"detect\", () => hooks.detectForPlugin(api, target.id))) ?? {\n\t\t\tok: false,\n\t\t\treasons: [\"detect threw an exception\"],\n\t\t},\n\t)\n\tconst meta = await attempt(\"meta\", () => hooks.runMetaHooks(api, target.id))\n\tconst files = await attempt(\"listFiles\", () =>\n\t\thooks.buildFileList(api, target.id),\n\t)\n\tconst coverLocal = await attempt(\"coverLocal\", () =>\n\t\thooks.resolveLocalCoverSource(api, target.id),\n\t)\n\t// Hash rows are what the app's duplicate/similar sections are built\n\t// from, so the workbench surfaces the count too.\n\tconst hashes = hooks.supportsImageHashes(target.id)\n\t\t? await attempt(\"imageHashes\", () => hooks.runImageHashes(api, target.id))\n\t\t: undefined\n\tconst fileStats =\n\t\t(await attempt(\"fileStats\", () => measureFileStats(api))) ?? {}\n\t// Sniff the selected cover source so the workbench can pick the same\n\t// `ui.card.<kind>` block the host app does from `coverMeta.kind`.\n\tconst coverKind = await sniffCoverKind(api, coverLocal, attempt)\n\n\treturn {\n\t\tpluginId: target.id,\n\t\tdetect,\n\t\tsourceMeta: meta?.sourceMeta?.value,\n\t\tsearchMeta: meta?.searchMeta?.value,\n\t\tcoverLocal,\n\t\tcoverKind,\n\t\tfiles,\n\t\tfileStats,\n\t\timageHashes: hashes?.hashes,\n\t\terrors,\n\t\tcapturedAt: Date.now(),\n\t}\n}\n\n/** Sniff the cover source's kind (image/video/audio), or `undefined`. */\nasync function sniffCoverKind(\n\tapi: ResourceAPI,\n\tcoverLocal: string | undefined,\n\tattempt: <T>(hook: string, run: () => Promise<T>) => Promise<T | undefined>,\n): Promise<string | undefined> {\n\tif (coverLocal === undefined) return undefined\n\tconst probe = await attempt(\"coverKind\", () => api.sniff(coverLocal!))\n\tconst kind = probe?.kind\n\treturn kind === \"image\" || kind === \"video\" || kind === \"audio\"\n\t\t? kind\n\t\t: undefined\n}\n\n/**\n * File count and total byte size of the resource, mirroring what the\n * server records on import and pushes to the iframe as `fileStats`.\n */\nasync function measureFileStats(api: ResourceAPI): Promise<FileStats> {\n\tconst names = await api.listFileNames()\n\tconst stats = await api.statFiles(names)\n\tlet sizeBytes = 0\n\tfor (const stat of stats) sizeBytes += stat?.sizeBytes ?? 0\n\treturn { count: names.length, sizeBytes }\n}\n\n/** One-line human summary for the dev server log. */\nexport function formatHookSnapshot(snapshot: PluginHookSnapshot): string {\n\tconst parts = [\n\t\tsnapshot.detect.ok\n\t\t\t? \"detect ok\"\n\t\t\t: `detect miss (${(snapshot.detect.reasons ?? []).join(\", \")})`,\n\t\t`${snapshot.fileStats.count ?? 0} files`,\n\t]\n\tif (snapshot.files !== undefined) {\n\t\tparts.push(`listFiles ${snapshot.files.length}`)\n\t}\n\tif (snapshot.sourceMeta !== undefined) parts.push(\"sourceMeta\")\n\tif (snapshot.searchMeta !== undefined) parts.push(\"searchMeta\")\n\tif (snapshot.coverLocal !== undefined) {\n\t\tparts.push(`cover ${snapshot.coverLocal}`)\n\t}\n\tfor (const [hook, message] of Object.entries(snapshot.errors)) {\n\t\tparts.push(`${hook} failed: ${message}`)\n\t}\n\treturn parts.join(\" · \")\n}\n","import { createHash } from \"node:crypto\"\nimport { existsSync } from \"node:fs\"\nimport { mkdir, writeFile } from \"node:fs/promises\"\nimport { extname, join } from \"node:path\"\nimport type { ResourceAPI } from \"@hoardodile/host\"\nimport {\n\ttype ImageVariantQuery,\n\timageVariantCanonical,\n\tnormalizeImageVariantSpec,\n\tparseImageVariantQuery,\n} from \"@hoardodile/sdk-types/image-variant\"\nimport {\n\tRESOURCE_COVER_MAX_AREA,\n\tRESOURCE_PREVIEW_MAX_AREA,\n} from \"@hoardodile/sdk-types/resource\"\n\n/**\n * The workbench's render providers: the same `@hoardodile/host/render`\n * pipeline the server runs, wired to the CLI's resource views. This is\n * what makes file variants (`?size=preview` and the generic\n * `fmt`/`fit`/`area`/`q` parameters), resource covers and the video\n * seek-preview route behave in the workbench exactly as they do in the\n * app.\n *\n * The pipeline is imported lazily because it needs `sharp`, an optional\n * peer a plugin project may not have installed. Loading it on demand\n * keeps `plugin build|run|bench` free of that requirement, and a plugin\n * without sharp still gets the whole dev loop — minus rendered\n * variants, which fall back to the original bytes.\n *\n * Rendered artifacts are cached under the plugin's own directory —\n * never inside the user's storage root, which the dev loop only reads.\n */\n\nexport type Rendered = {\n\treadonly contentType: string\n\treadonly path: string\n}\n\nexport type RenderProviders = {\n\t/**\n\t * Render the resource cover (the entry the plugin's `coverLocal`\n\t * hook selected). `undefined` when the resource has no cover source\n\t * or the render cannot be produced.\n\t */\n\treadonly cover: (resId: string) => Promise<Rendered | undefined>\n\treadonly preview: (\n\t\tresId: string,\n\t\tpath: string,\n\t\t/**\n\t\t * The file route's raw variant query (see\n\t\t * {@link ImageVariantQuery}); `undefined` or empty renders the\n\t\t * default preview variant.\n\t\t */\n\t\tvariant?: ImageVariantQuery,\n\t) => Promise<Rendered | undefined>\n\treadonly frame: (\n\t\tresId: string,\n\t\tpath: string,\n\t\ttimeMs: number,\n\t) => Promise<Rendered | undefined>\n}\n\ntype RenderModule = typeof import(\"@hoardodile/host/render\")\n\n/** Stable, filesystem-safe cache key for a resource entry. */\nfunction cacheKey(resId: string, path: string, suffix = \"\"): string {\n\treturn createHash(\"sha256\")\n\t\t.update(`${resId}\\u0000${path}${suffix}`)\n\t\t.digest(\"hex\")\n\t\t.slice(0, 32)\n}\n\nfunction contentTypeOf(format: \"webp\" | \"avif\"): string {\n\treturn format === \"webp\" ? \"image/webp\" : \"image/avif\"\n}\n\nexport function createRenderProviders(opts: {\n\t/** Resolve the resource view a render reads from. */\n\treadonly resolveApi: (resId: string) => Promise<ResourceAPI | undefined>\n\t/**\n\t * Resolve the cover source entry for a resource (the plugin's\n\t * `coverLocal` result). When omitted, covers are unavailable.\n\t */\n\treadonly resolveCoverSource?: (resId: string) => Promise<string | undefined>\n\t/** Cache root, e.g. `<pluginDir>/.hoardodile/cache`. */\n\treadonly cacheDir: string\n}): RenderProviders {\n\tlet renderPromise: Promise<RenderModule | undefined> | undefined\n\n\t/**\n\t * Load the render pipeline once. A missing `sharp` is a normal\n\t * outcome, reported once so the fallback is never a mystery.\n\t */\n\tfunction loadRender(): Promise<RenderModule | undefined> {\n\t\trenderPromise ??= import(\"@hoardodile/host/render\").catch(\n\t\t\t(err: unknown) => {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[hoardodile] preview and frame rendering are unavailable — install \"sharp\" (and an ffmpeg binary for video) to enable them: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t\t)\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t)\n\t\treturn renderPromise\n\t}\n\n\t/**\n\t * Read an entry into memory for the renderer. Preview and frame\n\t * inputs are single files the user is already looking at, so a whole\n\t * read is the simple, honest choice here.\n\t */\n\tasync function readEntry(\n\t\tapi: ResourceAPI,\n\t\tpath: string,\n\t): Promise<Uint8Array | undefined> {\n\t\ttry {\n\t\t\treturn await api.readFile(path)\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\tfunction cached(base: string): Rendered | undefined {\n\t\tfor (const format of [\"avif\", \"webp\"] as const) {\n\t\t\tconst path = `${base}.${format}`\n\t\t\tif (existsSync(path)) return { path, contentType: contentTypeOf(format) }\n\t\t}\n\t\treturn undefined\n\t}\n\n\tasync function cover(resId: string): Promise<Rendered | undefined> {\n\t\tif (opts.resolveCoverSource === undefined) return undefined\n\t\tconst source = await opts.resolveCoverSource(resId)\n\t\tif (source === undefined) return undefined\n\t\tconst api = await opts.resolveApi(resId)\n\t\tif (api === undefined) return undefined\n\t\tconst type = await api.sniff(source)\n\t\tconst kind = type?.kind\n\t\tif (kind !== \"image\" && kind !== \"video\" && kind !== \"audio\") {\n\t\t\treturn undefined\n\t\t}\n\t\tconst ext = type?.ext ?? extname(source).toLowerCase()\n\t\tconst base = join(opts.cacheDir, `cover-${cacheKey(resId, source)}`)\n\t\tconst hit = cached(base)\n\t\tif (hit !== undefined) return hit\n\t\tconst render = await loadRender()\n\t\tif (render === undefined) return undefined\n\t\tawait mkdir(opts.cacheDir, { recursive: true })\n\t\ttry {\n\t\t\tif (kind === \"image\") {\n\t\t\t\tconst bytes = await readEntry(api, source)\n\t\t\t\tif (bytes === undefined) return undefined\n\t\t\t\tconst rendered = await render.renderImageThumbOnce({\n\t\t\t\t\tinput: Buffer.from(bytes),\n\t\t\t\t\text,\n\t\t\t\t\tresolveDest: (format) => `${base}.${format}`,\n\t\t\t\t\tvariant: {\n\t\t\t\t\t\tformat: \"avif\",\n\t\t\t\t\t\tfit: \"inside\",\n\t\t\t\t\t\tmaxArea: RESOURCE_COVER_MAX_AREA,\n\t\t\t\t\t\twebpQuality: render.WEBP_QUALITY,\n\t\t\t\t\t\tavifQuality: render.AVIF_QUALITY,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\treturn {\n\t\t\t\t\tpath: rendered.path,\n\t\t\t\t\tcontentType: contentTypeOf(rendered.format),\n\t\t\t\t}\n\t\t\t}\n\t\t\t// ffmpeg needs a seekable input, so the entry is materialized\n\t\t\t// into the cache first, mirroring the server's seekable gate.\n\t\t\tconst sourcePath = join(\n\t\t\t\topts.cacheDir,\n\t\t\t\t`source-${cacheKey(resId, source, \"cover\")}${ext}`,\n\t\t\t)\n\t\t\tif (!existsSync(sourcePath)) {\n\t\t\t\tconst bytes = await readEntry(api, source)\n\t\t\t\tif (bytes === undefined) return undefined\n\t\t\t\tawait writeFile(sourcePath, bytes)\n\t\t\t}\n\t\t\tconst destPath = `${base}.avif`\n\t\t\tif (kind === \"video\") {\n\t\t\t\tawait render.renderVideoFrame({\n\t\t\t\t\tsource: sourcePath,\n\t\t\t\t\tdestPath,\n\t\t\t\t\tffmpeg: render.resolveFfmpegPaths(),\n\t\t\t\t\tmaxArea: RESOURCE_COVER_MAX_AREA,\n\t\t\t\t\tquality: render.AVIF_QUALITY,\n\t\t\t\t\tformat: \"avif\",\n\t\t\t\t\ttimeSeconds: 0,\n\t\t\t\t\text,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tawait render.renderAudioCoverArt({\n\t\t\t\t\tsource: sourcePath,\n\t\t\t\t\tdestPath,\n\t\t\t\t\tffmpeg: render.resolveFfmpegPaths(),\n\t\t\t\t\tmaxArea: RESOURCE_COVER_MAX_AREA,\n\t\t\t\t\tquality: render.AVIF_QUALITY,\n\t\t\t\t\tformat: \"avif\",\n\t\t\t\t\text,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn { path: destPath, contentType: \"image/avif\" }\n\t\t} catch (err) {\n\t\t\tconsole.warn(\n\t\t\t\t`[hoardodile] cover render failed for ${source}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t)\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\tasync function preview(\n\t\tresId: string,\n\t\tpath: string,\n\t\tvariant?: ImageVariantQuery,\n\t): Promise<Rendered | undefined> {\n\t\tconst api = await opts.resolveApi(resId)\n\t\tif (api === undefined) return undefined\n\t\tif ((await api.sniff(path))?.kind !== \"image\") return undefined\n\t\tconst parsed = parseImageVariantQuery(variant ?? {})\n\t\t// The workbench mount only routes variant requests here; anything\n\t\t// else (or a malformed query) falls back to the original bytes.\n\t\tif (parsed.kind !== \"variant\") return undefined\n\t\tconst render = await loadRender()\n\t\tif (render === undefined) return undefined\n\t\tconst resolved = normalizeImageVariantSpec(parsed.spec, {\n\t\t\tavifQuality: render.PREVIEW_AVIF_QUALITY,\n\t\t\twebpQuality: render.PREVIEW_WEBP_QUALITY,\n\t\t})\n\t\tconst base = join(\n\t\t\topts.cacheDir,\n\t\t\t`preview-${cacheKey(resId, path, imageVariantCanonical(resolved))}`,\n\t\t)\n\t\tconst hit = cached(base)\n\t\tif (hit !== undefined) return hit\n\t\tconst bytes = await readEntry(api, path)\n\t\tif (bytes === undefined) return undefined\n\t\tawait mkdir(opts.cacheDir, { recursive: true })\n\t\ttry {\n\t\t\tconst rendered = await render.renderImageThumbOnce({\n\t\t\t\tinput: Buffer.from(bytes),\n\t\t\t\tresolveDest: (format) => `${base}.${format}`,\n\t\t\t\tvariant: resolved,\n\t\t\t})\n\t\t\treturn {\n\t\t\t\tpath: rendered.path,\n\t\t\t\tcontentType: contentTypeOf(rendered.format),\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.warn(\n\t\t\t\t`[hoardodile] preview render failed for ${path}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t)\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\tasync function frame(\n\t\tresId: string,\n\t\tpath: string,\n\t\ttimeMs: number,\n\t): Promise<Rendered | undefined> {\n\t\tconst api = await opts.resolveApi(resId)\n\t\tif (api === undefined) return undefined\n\t\tconst type = await api.sniff(path)\n\t\tif (type?.kind !== \"video\") return undefined\n\t\tconst destPath = join(\n\t\t\topts.cacheDir,\n\t\t\t`frame-${cacheKey(resId, path, `@${timeMs}`)}.avif`,\n\t\t)\n\t\tif (existsSync(destPath)) {\n\t\t\treturn { path: destPath, contentType: \"image/avif\" }\n\t\t}\n\t\tconst render = await loadRender()\n\t\tif (render === undefined) return undefined\n\t\t// ffmpeg needs a seekable input to land on an arbitrary\n\t\t// timestamp, so the entry is materialized into the cache first.\n\t\tconst sourcePath = join(\n\t\t\topts.cacheDir,\n\t\t\t`source-${cacheKey(resId, path)}${type.ext}`,\n\t\t)\n\t\tif (!existsSync(sourcePath)) {\n\t\t\tconst bytes = await readEntry(api, path)\n\t\t\tif (bytes === undefined) return undefined\n\t\t\tawait mkdir(opts.cacheDir, { recursive: true })\n\t\t\tawait writeFile(sourcePath, bytes)\n\t\t}\n\t\ttry {\n\t\t\tawait render.renderVideoFrame({\n\t\t\t\tsource: sourcePath,\n\t\t\t\tdestPath,\n\t\t\t\tffmpeg: render.resolveFfmpegPaths(),\n\t\t\t\tmaxArea: RESOURCE_PREVIEW_MAX_AREA,\n\t\t\t\tquality: render.PREVIEW_AVIF_QUALITY,\n\t\t\t\tformat: \"avif\",\n\t\t\t\ttimeSeconds: timeMs / 1000,\n\t\t\t\text: type.ext,\n\t\t\t})\n\t\t\treturn { path: destPath, contentType: \"image/avif\" }\n\t\t} catch (err) {\n\t\t\tconsole.warn(\n\t\t\t\t`[hoardodile] frame render failed for ${path}@${timeMs}ms: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t)\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\treturn { cover, preview, frame }\n}\n","import { copyFileSync, existsSync, mkdtempSync, readdirSync } from \"node:fs\"\nimport { createRequire } from \"node:module\"\nimport { tmpdir } from \"node:os\"\nimport { join, resolve } from \"node:path\"\nimport type { DatabaseSync } from \"node:sqlite\"\nimport { createStoragePaths } from \"@hoardodile/host/hoard\"\n\n/**\n * `node:sqlite` is loaded through `createRequire` rather than a static\n * import: the bundler's builtin table predates it and rewrites the\n * specifier to a bare `sqlite`, which Node cannot resolve. The\n * annotation keeps the call fully typed without an assertion.\n */\nconst requireBuiltin: (id: \"node:sqlite\") => typeof import(\"node:sqlite\") =\n\tcreateRequire(import.meta.url)\n\n/**\n * Read-only access to a real hoardodile storage root, so a plugin can\n * be developed against the library it will actually run in.\n *\n * Two rules shape everything here:\n *\n * 1. **Read-only, always.** The database is opened `readOnly` and the\n * archives are read through the host's zip container. Nothing in the\n * dev loop writes to a user's library — plugin writes land in the\n * workbench's in-memory mock instead.\n * 2. **Only what a plugin could see anyway.** Queries are limited to the\n * resource row, its rebuilt metadata, its comments and danmaku, and\n * this plugin's own preferences and cache. Auth, sessions, the\n * footprint log and every other table stay untouched.\n *\n * `node:sqlite` is a Node builtin, so reading a library costs the CLI no\n * native dependency.\n */\n\nexport type StorageResource = {\n\treadonly id: string\n\treadonly name: string\n\treadonly contentPluginId?: string\n\treadonly fileVersion: number\n\treadonly sourceMeta?: unknown\n\treadonly searchMeta?: unknown\n\treadonly fileStats?: { readonly count?: number; readonly sizeBytes?: number }\n}\n\nexport type StorageResourceState = {\n\treadonly name: string\n\treadonly messages: readonly unknown[]\n\treadonly danmaku: readonly unknown[]\n\treadonly prefs: Readonly<Record<string, string>>\n\treadonly cache: Readonly<Record<string, string>>\n}\n\nexport type StorageReader = {\n\t/** Resources in the library, newest first. */\n\treadonly listResources: () => readonly StorageResource[]\n\treadonly findResource: (resId: string) => StorageResource | undefined\n\t/** Plugin-visible stored state for one resource. */\n\treadonly readState: (resId: string, pluginId: string) => StorageResourceState\n\t/** Absolute path of a resource's bare-file source folder. */\n\treadonly archivePath: (resource: StorageResource) => string\n\treadonly close: () => void\n}\n\nfunction parseJson(value: unknown): unknown {\n\tif (typeof value !== \"string\" || value.length === 0) return undefined\n\ttry {\n\t\treturn JSON.parse(value)\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\nfunction asString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" && value.length > 0 ? value : undefined\n}\n\n/**\n * Open the library database read-only. A live server holds the write\n * lock and keeps its WAL alongside; SQLite can still read that, but a\n * read-only handle cannot recover a hot journal — so on failure the\n * database and its sidecars are copied to a temp dir and the copy is\n * opened instead. The user's files are never modified either way.\n */\nfunction openReadOnly(dbPath: string): DatabaseSync {\n\tconst { DatabaseSync: Database } = requireBuiltin(\"node:sqlite\")\n\ttry {\n\t\treturn new Database(dbPath, { readOnly: true })\n\t} catch (err) {\n\t\tconst snapshotDir = mkdtempSync(join(tmpdir(), \"hoardodile-wb-\"))\n\t\tconst dir = resolve(dbPath, \"..\")\n\t\tconst base = dbPath.slice(dir.length + 1)\n\t\tlet copied = false\n\t\tfor (const entry of readdirSync(dir)) {\n\t\t\tif (!entry.startsWith(base)) continue\n\t\t\tcopyFileSync(join(dir, entry), join(snapshotDir, entry))\n\t\t\tcopied = entry === base || copied\n\t\t}\n\t\tif (!copied) throw err\n\t\tconsole.log(\n\t\t\t`[hoardodile] database is busy — reading a temporary copy (${snapshotDir})`,\n\t\t)\n\t\treturn new Database(join(snapshotDir, base), { readOnly: true })\n\t}\n}\n\nexport function openStorage(rootDir: string): StorageReader {\n\tconst root = resolve(rootDir)\n\tconst dbPath = join(root, \"app.sqlite\")\n\tif (!existsSync(dbPath)) {\n\t\tthrow new Error(\n\t\t\t`no app.sqlite in ${root} — point --storage at a hoardodile data root`,\n\t\t)\n\t}\n\tconst db = openReadOnly(dbPath)\n\tconst paths = createStoragePaths({ root })\n\n\tfunction rowToResource(row: Record<string, unknown>): StorageResource {\n\t\tconst stats = parseJson(row.file_stats)\n\t\treturn {\n\t\t\tid: String(row.id),\n\t\t\tname: String(row.name ?? row.id),\n\t\t\tcontentPluginId: asString(row.content_plugin_id),\n\t\t\tfileVersion: Number(row.file_version ?? 1),\n\t\t\tsourceMeta: parseJson(row.source_meta),\n\t\t\tsearchMeta: parseJson(row.search_meta),\n\t\t\tfileStats:\n\t\t\t\ttypeof stats === \"object\" && stats !== null\n\t\t\t\t\t? (stats as StorageResource[\"fileStats\"])\n\t\t\t\t\t: undefined,\n\t\t}\n\t}\n\n\tconst listStmt = db.prepare(\n\t\t`SELECT r.id, r.name, r.content_plugin_id, r.file_version,\n\t\t m.source_meta, m.search_meta, m.file_stats\n\t\t FROM resources r\n\t\t LEFT JOIN resource_meta m ON m.resource_id = r.id\n\t\t WHERE r.deleted_at IS NULL\n\t\t ORDER BY r.created_at DESC`,\n\t)\n\tconst findStmt = db.prepare(\n\t\t`SELECT r.id, r.name, r.content_plugin_id, r.file_version,\n\t\t m.source_meta, m.search_meta, m.file_stats\n\t\t FROM resources r\n\t\t LEFT JOIN resource_meta m ON m.resource_id = r.id\n\t\t WHERE r.id = ?`,\n\t)\n\tconst commentsStmt = db.prepare(\n\t\t`SELECT c.id, c.body, c.created_at, c.floor, c.anchor_data\n\t\t FROM comments c\n\t\t JOIN comment_resources cr ON cr.comment_id = c.id\n\t\t WHERE cr.resource_id = ? AND c.deleted_at IS NULL\n\t\t ORDER BY c.created_at ASC`,\n\t)\n\tconst danmakuStmt = db.prepare(\n\t\t`SELECT id, anchor_data, text, color, mode, created_at\n\t\t FROM danmakus\n\t\t WHERE anchor_resource_id = ?\n\t\t ORDER BY created_at ASC`,\n\t)\n\tconst prefsStmt = db.prepare(\n\t\t`SELECT key, value FROM plugin_preferences WHERE plugin_id = ?`,\n\t)\n\tconst cacheStmt = db.prepare(\n\t\t`SELECT key, value FROM plugin_cache WHERE plugin_id = ? AND res_id = ?`,\n\t)\n\n\tfunction keyValues(\n\t\trows: readonly Record<string, unknown>[],\n\t): Record<string, string> {\n\t\tconst out: Record<string, string> = {}\n\t\tfor (const row of rows) out[String(row.key)] = String(row.value)\n\t\treturn out\n\t}\n\n\treturn {\n\t\tlistResources() {\n\t\t\treturn listStmt.all().map(rowToResource)\n\t\t},\n\t\tfindResource(resId) {\n\t\t\tconst row = findStmt.get(resId)\n\t\t\treturn row === undefined ? undefined : rowToResource(row)\n\t\t},\n\t\treadState(resId, pluginId) {\n\t\t\tconst resource = this.findResource(resId)\n\t\t\treturn {\n\t\t\t\tname: resource?.name ?? resId,\n\t\t\t\tmessages: commentsStmt.all(resId).map((row) => ({\n\t\t\t\t\tid: String(row.id),\n\t\t\t\t\tbody: String(row.body ?? \"\"),\n\t\t\t\t\tcreatedAt: Number(row.created_at ?? 0),\n\t\t\t\t\tcharIds: [],\n\t\t\t\t\tresIds: [resId],\n\t\t\t\t\tlikeCount: 0,\n\t\t\t\t\tdislikeCount: 0,\n\t\t\t\t\treplyCount: 0,\n\t\t\t\t\tfloor: row.floor === null ? undefined : Number(row.floor),\n\t\t\t\t\tanchor: {\n\t\t\t\t\t\tresId,\n\t\t\t\t\t\tdata: (parseJson(row.anchor_data) as { data?: unknown })?.data,\n\t\t\t\t\t},\n\t\t\t\t})),\n\t\t\t\tdanmaku: danmakuStmt.all(resId).map((row) => ({\n\t\t\t\t\tid: String(row.id),\n\t\t\t\t\tanchor: {\n\t\t\t\t\t\tresId,\n\t\t\t\t\t\tdata: (parseJson(row.anchor_data) as { data?: unknown })?.data,\n\t\t\t\t\t},\n\t\t\t\t\ttext: String(row.text ?? \"\"),\n\t\t\t\t\tcolor: String(row.color ?? \"\"),\n\t\t\t\t\tmode: String(row.mode ?? \"scroll\"),\n\t\t\t\t\tcreatedAt: Number(row.created_at ?? 0),\n\t\t\t\t})),\n\t\t\t\tprefs: keyValues(prefsStmt.all(pluginId)),\n\t\t\t\tcache: keyValues(cacheStmt.all(pluginId, resId)),\n\t\t\t}\n\t\t},\n\t\tarchivePath(resource) {\n\t\t\t// Layout authority lives in @hoardodile/host, shared with the\n\t\t\t// server — no hand-rolled mirror of the versions/<v> shape.\n\t\t\treturn paths.atVersion(resource.fileVersion).resource(resource.id)\n\t\t},\n\t\tclose() {\n\t\t\tdb.close()\n\t\t},\n\t}\n}\n","import { type ChildProcess, spawn } from \"node:child_process\"\nimport { existsSync, readdirSync, readFileSync, statSync, watch } from \"node:fs\"\nimport { createRequire } from \"node:module\"\nimport { join, resolve, sep } from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport type { ResourceAPI } from \"@hoardodile/host\"\nimport {\n\tcaptureHookSnapshot,\n\tformatHookSnapshot,\n\ttype PluginHookSnapshot,\n\tresolveBuiltPluginTarget,\n} from \"./hook-snapshot.ts\"\nimport { createRenderProviders } from \"./render-providers.ts\"\nimport {\n\tbuildArchiveResourceAPI,\n\tbuildCliResourceAPI,\n\tCliError,\n\tEXIT_ERROR,\n\tEXIT_PASS,\n} from \"./runner.ts\"\nimport { openStorage, type StorageReader } from \"./storage.ts\"\n\n/**\n * `hoardodile plugin dev` — the plugin development loop:\n * 1. build the plugin in watch mode (its own `watch` script, or this\n * CLI's `plugin build --watch`),\n * 2. capture the server-side hook results from the real sandbox, so the\n * workbench iframe gets the same `sourceMeta` / `searchMeta` /\n * `fileStats` / file list the app would push,\n * 3. serve the published workbench with the plugin bundle, the resource\n * data, and the same render pipeline the server uses for preview\n * variants and video frames.\n *\n * Data comes either from a plain directory (`--data`, the default\n * `testdata/`) or from a real hoardodile library (`--storage`), which is\n * opened **read-only**: plugin writes land in the workbench's in-memory\n * mock, never in the user's database or archives.\n *\n * Long-running: stays up until SIGINT.\n */\nexport type DevOptions = {\n\treadonly pluginDir: string\n\treadonly dataDir?: string\n\t/** A folder whose direct subfolders are individual resources. Mutually exclusive with `dataDir`/`storageDir`. */\n\treadonly resourceRootDir?: string\n\t/** Real hoardodile storage root, opened read-only. */\n\treadonly storageDir?: string\n\t/** Resource to open first when serving a storage root. */\n\treadonly resId?: string\n\treadonly port: number\n}\n\n/** Debounce for rebuild-triggered recaptures; vite writes dist in bursts. */\nconst RECAPTURE_DEBOUNCE_MS = 300\nconst FIRST_BUILD_TIMEOUT_MS = 60_000\n/** Resources listed in the picker; a library can hold thousands. */\nconst RESOURCE_LIST_LIMIT = 200\nconst DIRECTORY_RES_ID = \"workbench\"\n\nfunction resolvePluginDir(value: string | undefined): string {\n\tconst dir = resolve(value ?? \".\")\n\tif (!existsSync(join(dir, \"manifest.json\"))) {\n\t\tthrow new Error(\n\t\t\t`no manifest.json found in ${dir} — run this from a plugin directory or pass --plugin-dir`,\n\t\t)\n\t}\n\treturn dir\n}\n\nfunction hasWatchScript(pluginDir: string): boolean {\n\ttry {\n\t\tconst pkg = JSON.parse(\n\t\t\treadFileSync(join(pluginDir, \"package.json\"), \"utf8\"),\n\t\t)\n\t\treturn typeof pkg?.scripts?.watch === \"string\"\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Load the workbench serve entry from the PLUGIN's own dependency tree.\n * The workbench is a dev tool, not part of the host runtime — the plugin\n * declares it as a devDependency (the template and scaffolder include it)\n * and `hoardodile plugin dev` serves that installed copy.\n */\nasync function loadWorkbenchServe(pluginDir: string) {\n\tconst requireFromPlugin = createRequire(join(pluginDir, \"package.json\"))\n\tlet workbenchEntry: string\n\ttry {\n\t\tworkbenchEntry = requireFromPlugin.resolve(\"@hoardodile/workbench\")\n\t} catch {\n\t\tthrow new Error(\n\t\t\t\"@hoardodile/workbench not found in this plugin's dependencies — add it to devDependencies (the template and `create-hoardodile-plugin` include it) and run `pnpm install`.\",\n\t\t)\n\t}\n\treturn import(pathToFileURL(workbenchEntry).href)\n}\n\nfunction spawnWatcher(opts: {\n\treadonly command: string\n\treadonly args: readonly string[]\n\treadonly cwd: string\n\treadonly label: string\n}): ChildProcess {\n\tconsole.log(`[hoardodile] starting ${opts.label}`)\n\treturn spawn(opts.command, [...opts.args], {\n\t\tcwd: opts.cwd,\n\t\tstdio: \"inherit\",\n\t\tshell: process.platform === \"win32\",\n\t})\n}\n\nfunction startBuildWatcher(pluginDir: string): ChildProcess {\n\tconst watcher = hasWatchScript(pluginDir)\n\t\t? spawnWatcher({\n\t\t\t\tcommand: \"pnpm\",\n\t\t\t\targs: [\"watch\"],\n\t\t\t\tcwd: pluginDir,\n\t\t\t\tlabel: `\\`pnpm watch\\` in ${pluginDir}`,\n\t\t\t})\n\t\t: spawnWatcher({\n\t\t\t\tcommand: process.execPath,\n\t\t\t\targs: [process.argv[1] ?? \"\", \"plugin\", \"build\", \"--watch\"],\n\t\t\t\tcwd: pluginDir,\n\t\t\t\tlabel: \"`plugin build --watch` (no watch script found)\",\n\t\t\t})\n\twatcher.on(\"error\", (err) => {\n\t\tconsole.error(`[hoardodile] build watcher failed: ${err.message}`)\n\t\tprocess.exitCode = EXIT_ERROR\n\t})\n\twatcher.on(\"exit\", (code) => {\n\t\tif (code !== null && code !== 0) {\n\t\t\tconsole.error(`[hoardodile] build watcher exited with code ${code}`)\n\t\t\tprocess.exitCode = EXIT_ERROR\n\t\t}\n\t})\n\treturn watcher\n}\n\nasync function waitForBuild(\n\tdistDir: string,\n\ttimeoutMs: number,\n): Promise<boolean> {\n\tconst started = Date.now()\n\twhile (Date.now() - started < timeoutMs) {\n\t\tif (existsSync(join(distDir, \"main.js\"))) return true\n\t\tawait new Promise((r) => setTimeout(r, 500))\n\t}\n\treturn false\n}\n\n/**\n * Where the workbench's resources come from. Both shapes answer the\n * same three questions — which resources exist, how to read one, and\n * what stored state a plugin would see — so everything downstream stays\n * unaware of whether it is looking at a directory or a real library.\n */\ntype ResourceSource = {\n\treadonly list: () => readonly {\n\t\treadonly id: string\n\t\treadonly name: string\n\t\treadonly contentPluginId?: string\n\t}[]\n\treadonly apiFor: (resId: string) => ResourceAPI | undefined\n\treadonly stateFor: (\n\t\tresId: string,\n\t\tpluginId: string,\n\t) => Record<string, unknown> | undefined\n\t/** Writable root for `extractArchive` materialization. */\n\treadonly extractCacheDir?: string\n\treadonly close?: () => void\n}\n\nfunction directorySource(\n\tdataDir: string,\n\textractCacheDir?: string,\n): ResourceSource {\n\tconst api = buildCliResourceAPI(dataDir, { extractCacheDir })\n\treturn {\n\t\tlist: () => [{ id: DIRECTORY_RES_ID, name: \"Workbench\" }],\n\t\tapiFor: (resId) => (resId === DIRECTORY_RES_ID ? api : undefined),\n\t\tstateFor: () => undefined,\n\t\textractCacheDir,\n\t}\n}\nfunction storageSource(\n\tstorage: StorageReader,\n\textractCacheDir?: string,\n): ResourceSource {\n\t// One API per resource: archives are immutable, so the container and\n\t// its central-directory cache stay valid for the whole session.\n\tconst apis = new Map<string, ResourceAPI | undefined>()\n\treturn {\n\t\tlist: () =>\n\t\t\tstorage\n\t\t\t\t.listResources()\n\t\t\t\t.slice(0, RESOURCE_LIST_LIMIT)\n\t\t\t\t.map((resource) => ({\n\t\t\t\t\tid: resource.id,\n\t\t\t\t\tname: resource.name,\n\t\t\t\t\tcontentPluginId: resource.contentPluginId,\n\t\t\t\t})),\n\t\tapiFor(resId) {\n\t\t\tif (apis.has(resId)) return apis.get(resId)\n\t\t\tconst resource = storage.findResource(resId)\n\t\t\tconst archive =\n\t\t\t\tresource === undefined ? undefined : storage.archivePath(resource)\n\t\t\tconst api =\n\t\t\t\tarchive !== undefined && existsSync(archive)\n\t\t\t\t\t? buildArchiveResourceAPI(archive, extractCacheDir)\n\t\t\t\t\t: undefined\n\t\t\tif (api === undefined && resource !== undefined) {\n\t\t\t\tconsole.warn(`[hoardodile] no source archive for resource ${resId}`)\n\t\t\t}\n\t\t\tapis.set(resId, api)\n\t\t\treturn api\n\t\t},\n\t\tstateFor: (resId, pluginId) => storage.readState(resId, pluginId),\n\t\textractCacheDir,\n\t\tclose: () => storage.close(),\n\t}\n}\n\n/**\n * A source over a folder whose direct subfolders are individual\n * resources — the \"consolidate my test data\" shape. Each subfolder is\n * one resource (named by its basename); `apiFor` builds a per-resource\n * container only when the id resolves to a real subfolder inside `root`\n * (a traversal id resolves to nothing, never escapes the root).\n */\nexport function resourceRootSource(\n\tresourceRoot: string,\n\textractCacheDir?: string,\n): ResourceSource {\n\tconst root = resolve(resourceRoot)\n\tconst listResources = () =>\n\t\treaddirSync(root, { withFileTypes: true })\n\t\t\t.filter((entry) => entry.isDirectory())\n\t\t\t.map((entry) => ({ id: entry.name, name: entry.name }))\n\t\t\t.sort((a, b) => a.name.localeCompare(b.name))\n\tconst subdirFor = (resId: string): string | undefined => {\n\t\tconst abs = join(root, resId)\n\t\tif (abs !== root && !abs.startsWith(root + sep)) return undefined\n\t\ttry {\n\t\t\treturn statSync(abs).isDirectory() ? abs : undefined\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t}\n\tconst apis = new Map<string, ResourceAPI | undefined>()\n\treturn {\n\t\tlist: listResources,\n\t\tapiFor(resId) {\n\t\t\tif (apis.has(resId)) return apis.get(resId)\n\t\t\tconst dir = subdirFor(resId)\n\t\t\tconst api =\n\t\t\t\tdir === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: buildCliResourceAPI(dir, { extractCacheDir })\n\t\t\tapis.set(resId, api)\n\t\t\treturn api\n\t\t},\n\t\tstateFor: () => undefined,\n\t\textractCacheDir,\n\t}\n}\n\n/**\n * Holds the latest sandboxed hook results per resource. Recaptures are\n * serialised and coalesced: a rebuild burst must not spawn a worker per\n * written file, and two overlapping captures would race for the slot.\n */\nfunction createSnapshotStore(opts: {\n\treadonly pluginDir: string\n\treadonly source: ResourceSource\n}) {\n\tconst snapshots = new Map<string, PluginHookSnapshot>()\n\tconst running = new Map<string, Promise<void>>()\n\n\tasync function capture(resId: string): Promise<void> {\n\t\tconst api = opts.source.apiFor(resId)\n\t\tif (api === undefined) return\n\t\ttry {\n\t\t\tconst target = resolveBuiltPluginTarget(opts.pluginDir)\n\t\t\tconst snapshot = await captureHookSnapshot({ target, api })\n\t\t\tsnapshots.set(resId, snapshot)\n\t\t\tconsole.log(`[hoardodile] ${resId}: ${formatHookSnapshot(snapshot)}`)\n\t\t\tif (!snapshot.detect.ok) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t\"[hoardodile] detect failed — the plugin may not match this resource.\",\n\t\t\t\t)\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(\n\t\t\t\t`[hoardodile] hook snapshot failed: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t)\n\t\t}\n\t}\n\n\tfunction refresh(resId: string): Promise<void> {\n\t\tconst inFlight = running.get(resId)\n\t\tif (inFlight !== undefined) return inFlight\n\t\tconst run = capture(resId).finally(() => running.delete(resId))\n\t\trunning.set(resId, run)\n\t\treturn run\n\t}\n\n\treturn {\n\t\t/** Capture on demand, then serve the cached result. */\n\t\tasync read(resId: string): Promise<PluginHookSnapshot | undefined> {\n\t\t\tif (!snapshots.has(resId)) await refresh(resId)\n\t\t\treturn snapshots.get(resId)\n\t\t},\n\t\t/** Drop every capture so the next read re-runs against the new build. */\n\t\tinvalidate(): void {\n\t\t\tsnapshots.clear()\n\t\t},\n\t\tcaptured: () => [...snapshots.keys()],\n\t\trefresh,\n\t}\n}\n\n/** Recapture whenever the watcher rewrites the bundle. */\nfunction watchDistForRebuilds(\n\tdistDir: string,\n\tonRebuild: () => void,\n): () => void {\n\tlet timer: ReturnType<typeof setTimeout> | undefined\n\tconst watcher = watch(distDir, () => {\n\t\tif (timer !== undefined) clearTimeout(timer)\n\t\ttimer = setTimeout(onRebuild, RECAPTURE_DEBOUNCE_MS)\n\t})\n\treturn () => {\n\t\tif (timer !== undefined) clearTimeout(timer)\n\t\twatcher.close()\n\t}\n}\n\n/** Resolve the data source from the flags, preferring a real library. */\nexport function resolveSource(\n\topts: DevOptions & { readonly pluginDir: string },\n): ResourceSource | undefined {\n\tconst extractCacheDir = join(opts.pluginDir, \".hoardodile\", \"extract\")\n\tif (\n\t\topts.resourceRootDir !== undefined &&\n\t\t(opts.dataDir !== undefined || opts.storageDir !== undefined)\n\t) {\n\t\tthrow new CliError(\n\t\t\t\"--resource-dir is mutually exclusive with --data and --storage\",\n\t\t)\n\t}\n\tif (opts.resourceRootDir !== undefined) {\n\t\tconst root = resolve(opts.resourceRootDir)\n\t\tif (!existsSync(root)) {\n\t\t\tconsole.warn(\n\t\t\t\t`[hoardodile] no resource dir found at ${root} — mount one with --resource-dir (or --storage <hoardodile-root>).`,\n\t\t\t)\n\t\t\treturn undefined\n\t\t}\n\t\tconsole.log(`[hoardodile] resource dir: ${root}`)\n\t\treturn resourceRootSource(root, extractCacheDir)\n\t}\n\tif (opts.storageDir !== undefined) {\n\t\tconst root = resolve(opts.storageDir)\n\t\tconst storage = openStorage(root)\n\t\tconst count = storage.listResources().length\n\t\tconsole.log(`[hoardodile] storage: ${root} (${count} resources, read-only)`)\n\t\treturn storageSource(storage, extractCacheDir)\n\t}\n\tconst dataDir =\n\t\topts.dataDir !== undefined\n\t\t\t? resolve(opts.dataDir)\n\t\t\t: join(resolve(opts.pluginDir ?? \".\"), \"testdata\")\n\tif (!existsSync(dataDir)) {\n\t\tconsole.warn(\n\t\t\t`[hoardodile] no data dir found at ${dataDir} — mount one with --data (or --storage <hoardodile-root>).`,\n\t\t)\n\t\treturn undefined\n\t}\n\tconsole.log(`[hoardodile] data: ${dataDir}`)\n\treturn directorySource(dataDir, extractCacheDir)\n}\n\n/**\n * Framed, easy-to-spot startup notice for the workbench URL. The plugin\n * watcher and vite print continuously, so a plain log line scrolls away;\n * a bordered banner keeps the address findable at the end of the startup\n * burst. ANSI colour is only emitted on a TTY so redirected logs and CI\n * stay clean.\n */\nfunction printWorkbenchBanner(url: string): void {\n\tconst ansi = process.stdout.isTTY\n\tconst headline = \"Workbench running — open in your browser:\"\n\tconst urlLineText = ` ${url}`\n\tconst hint =\n\t\t\"(edits rebuild automatically — reload the page. Ctrl+C to stop.)\"\n\tconst width = Math.max(headline.length, urlLineText.length, hint.length) + 2\n\tconst content = (line: string) => `│ ${line.padEnd(width - 2)}│`\n\tconst urlLine = content(urlLineText)\n\tconsole.log(`\\n┌${\"─\".repeat(width)}┐`)\n\tconsole.log(content(headline))\n\tconsole.log(ansi ? urlLine.replace(url, `\\x1b[1;36m${url}\\x1b[0m`) : urlLine)\n\tconsole.log(content(hint))\n\tconsole.log(`└${\"─\".repeat(width)}┘`)\n}\n\nexport async function executeDev(opts: DevOptions): Promise<number> {\n\tconst pluginDir = resolvePluginDir(opts.pluginDir)\n\tconst distDir = join(pluginDir, \"dist\")\n\tconst source = resolveSource({ ...opts, pluginDir })\n\tconst target = existsSync(join(distDir, \"main.js\"))\n\t\t? resolveBuiltPluginTarget(pluginDir)\n\t\t: undefined\n\n\tconst watcher = startBuildWatcher(pluginDir)\n\tconst snapshots =\n\t\tsource === undefined\n\t\t\t? undefined\n\t\t\t: createSnapshotStore({ pluginDir, source })\n\n\tconst render =\n\t\tsource === undefined\n\t\t\t? undefined\n\t\t\t: createRenderProviders({\n\t\t\t\t\tresolveApi: async (resId) => source.apiFor(resId),\n\t\t\t\t\t// The plugin's coverLocal pick is captured in the hook\n\t\t\t\t\t// snapshot; the cover render feeds the workbench picker.\n\t\t\t\t\tresolveCoverSource: async (resId) =>\n\t\t\t\t\t\t(await snapshots?.read(resId))?.coverLocal,\n\t\t\t\t\t// Rendered artifacts live with the plugin, never inside\n\t\t\t\t\t// the user's storage root.\n\t\t\t\t\tcacheDir: join(pluginDir, \".hoardodile\", \"cache\"),\n\t\t\t\t})\n\n\t// The workbench mounts the BUILT bundle: `hoardodile plugin build`\n\t// emits manifest.json, index.html and main.js into dist/. Serving the\n\t// source root instead would hand the iframe raw .tsx.\n\tconst { serveWorkbench, createRebuildBus } =\n\t\tawait loadWorkbenchServe(pluginDir)\n\t// The workbench may rebind to a free port, so the printed URL must be\n\t// the actual one. Capture it via `onReady` and only surface it after\n\t// the build settles, so the plugin's vite watch-build output does not\n\t// scroll it off-screen.\n\tconst rebuildBus = createRebuildBus()\n\tlet workbenchUrl = `http://127.0.0.1:${opts.port}`\n\tconst server = await serveWorkbench({\n\t\tpluginDir: distDir,\n\t\tport: opts.port,\n\t\trebuildBus,\n\t\tonReady: (url: string) => {\n\t\t\tworkbenchUrl = url\n\t\t},\n\t\t// User-consented dev downloads land in the plugin's own scratch\n\t\t// vault, next to the extraction cache — never in the read-only\n\t\t// storage root or the data dir.\n\t\tvaultRoot: join(pluginDir, \".hoardodile\", \"vault\"),\n\t\tproviders: {\n\t\t\tresources: () => source?.list() ?? [],\n\t\t\tfiles: source === undefined ? undefined : createFileProvider(source),\n\t\t\tsnapshot: (resId: string) => snapshots?.read(resId),\n\t\t\tstate: (resId: string) =>\n\t\t\t\tsource?.stateFor(resId, target?.id ?? \"\") as\n\t\t\t\t\t| Record<string, unknown>\n\t\t\t\t\t| undefined,\n\t\t\tpreview: render?.preview,\n\t\t\tframe: render?.frame,\n\t\t\tcover: render?.cover,\n\t\t},\n\t})\n\n\tlet stopDistWatch: (() => void) | undefined\n\tif (await waitForBuild(distDir, FIRST_BUILD_TIMEOUT_MS)) {\n\t\tconst first = opts.resId ?? source?.list()[0]?.id\n\t\tif (first !== undefined) await snapshots?.refresh(first)\n\t\tstopDistWatch = watchDistForRebuilds(distDir, () => {\n\t\t\t// Rebuilt bundle: drop every capture and re-run the ones the\n\t\t\t// page has already asked for, so a reload shows the new build.\n\t\t\tconst captured = snapshots?.captured() ?? []\n\t\t\tsnapshots?.invalidate()\n\t\t\tfor (const resId of captured) void snapshots?.refresh(resId)\n\t\t\t// Tell the open workbench page to reload its plugin iframe so it\n\t\t\t// picks up the rebuilt client bundle (and, via the invalidated\n\t\t\t// snapshots above, the recaptured server hooks). The context\n\t\t\t// refetch coalesces with any in-flight recapture through the\n\t\t\t// snapshot store's running map, so a reload never shows a stale\n\t\t\t// `sourceMeta` for long.\n\t\t\trebuildBus.emit({ kind: \"rebuild\" })\n\t\t})\n\t} else {\n\t\tconsole.error(\n\t\t\t\"[hoardodile] no dist/main.js appeared within 60s — is the build working?\",\n\t\t)\n\t}\n\n\t// Surface the workbench URL last, after the initial build/capture burst,\n\t// framed so it is not lost among the watcher and vite output.\n\tprintWorkbenchBanner(workbenchUrl)\n\n\tawait new Promise<void>((resolveStop) => {\n\t\tconst stop = () => {\n\t\t\tstopDistWatch?.()\n\t\t\twatcher.kill()\n\t\t\tsource?.close?.()\n\t\t\trebuildBus.close()\n\t\t\tserver.close(() => resolveStop())\n\t\t}\n\t\tprocess.once(\"SIGINT\", stop)\n\t\tprocess.once(\"SIGTERM\", stop)\n\t})\n\treturn EXIT_PASS\n}\n\n/** File access for the workbench, backed by the resource's own view. */\nfunction createFileProvider(source: ResourceSource) {\n\treturn {\n\t\tasync list(resId: string): Promise<readonly string[]> {\n\t\t\treturn (await source.apiFor(resId)?.listFileNames()) ?? []\n\t\t},\n\t\tasync stat(resId: string, path: string) {\n\t\t\treturn source.apiFor(resId)?.statFile(path)\n\t\t},\n\t\tasync read(resId: string, path: string): Promise<Uint8Array | undefined> {\n\t\t\ttry {\n\t\t\t\treturn await source.apiFor(resId)?.readFile(path)\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t},\n\t\tasync extracted(\n\t\t\t_path: string,\n\t\t\tpath: string,\n\t\t): Promise<Uint8Array | undefined> {\n\t\t\tconst root = source.extractCacheDir\n\t\t\tif (root === undefined) return undefined\n\t\t\tconst abs = resolve(root, path)\n\t\t\tif (abs !== resolve(root) && !abs.startsWith(resolve(root) + sep)) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn readFileSync(abs)\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t},\n\t}\n}\n","import { createHash } from \"node:crypto\"\nimport { existsSync, mkdirSync, readFileSync, rmSync } from \"node:fs\"\nimport { writeFile } from \"node:fs/promises\"\nimport { join, resolve } from \"node:path\"\nimport { packZipDirectory } from \"@hoardodile/host\"\nimport type { PluginManifest } from \"@hoardodile/sdk-types\"\nimport { buildPlugin } from \"./build.ts\"\nimport { CliError } from \"./runner.ts\"\n\nexport type PackageResult = {\n\treadonly id: string\n\treadonly version: string\n\treadonly zipPath: string\n\t/** `release/<id>-<version>.zip.sha256` next to the zip. */\n\treadonly sha256Path: string\n\t/** Publishing hint: push a matching tag — the release workflow builds. */\n\treadonly publishHint: string\n\t/** One line to append to the marketplace registry `plugins` array. */\n\treadonly registryLine: string\n}\n\n/**\n * Build (or reuse) a plugin's `dist/`, then zip its *contents* —\n * `manifest.json` at the zip root, exactly what the app's installer\n * expects — into `release/<id>-<version>.zip` plus a `<zip>.sha256`\n * sidecar (the marketplace verifies it when the release ships one).\n *\n * The file name is the marketplace convention: the app resolves a\n * release's zip by trying `<id>-<tag>.zip` / `<id>-<version>.zip`\n * first, so publishing with this artifact needs no registry metadata.\n *\n * Publishing itself is a CI concern: the template ships a tag-triggered\n * release workflow (`plugins/template/.github/workflows/release.yml`)\n * that uploads both artifacts — no local `gh` CLI or token needed.\n */\nexport async function packPlugin(\n\tdir: string,\n\topts: { readonly skipBuild: boolean },\n): Promise<PackageResult> {\n\tconst pluginDir = resolve(dir)\n\tconst manifestPath = join(pluginDir, \"manifest.json\")\n\tif (!existsSync(manifestPath)) {\n\t\tthrow new CliError(`No manifest.json found in ${pluginDir}`)\n\t}\n\tconst manifest = JSON.parse(\n\t\treadFileSync(manifestPath, \"utf-8\"),\n\t) as PluginManifest\n\tif (typeof manifest.id !== \"string\" || manifest.id.length === 0) {\n\t\tthrow new CliError(\"manifest.json missing id field\")\n\t}\n\tif (typeof manifest.version !== \"string\" || manifest.version.length === 0) {\n\t\tthrow new CliError(\"manifest.json missing version field\")\n\t}\n\n\tif (!opts.skipBuild) {\n\t\tawait buildPlugin(pluginDir, { watch: false })\n\t}\n\n\tconst distDir = join(pluginDir, \"dist\")\n\tif (!existsSync(join(distDir, \"manifest.json\"))) {\n\t\tthrow new CliError(\n\t\t\t`dist/manifest.json not found in ${pluginDir} — run \"hoardodile plugin build\" first`,\n\t\t)\n\t}\n\n\tconst outDir = join(pluginDir, \"release\")\n\tmkdirSync(outDir, { recursive: true })\n\tconst zipPath = join(\n\t\toutDir,\n\t\t`${manifest.id}-${sanitizeFileNamePart(manifest.version)}.zip`,\n\t)\n\n\t// Zip only the files `dist/` produced; entries use forward slashes so\n\t// the archive is identical on every platform. The packer is the same\n\t// yazl engine the host runtime extracts with (streamed to disk, no\n\t// whole-archive buffer).\n\trmSync(zipPath, { force: true })\n\tawait packZipDirectory(distDir, zipPath)\n\n\tconst sha256Path = `${zipPath}.sha256`\n\tconst packed = readFileSync(zipPath)\n\tawait writeFile(\n\t\tsha256Path,\n\t\t`${createHash(\"sha256\").update(packed).digest(\"hex\")}\\n`,\n\t)\n\n\treturn {\n\t\tid: manifest.id,\n\t\tversion: manifest.version,\n\t\tzipPath,\n\t\tsha256Path,\n\t\tpublishHint: `push a tag v${manifest.version} — the release workflow (plugins/template/.github/workflows/release.yml) builds and publishes`,\n\t\tregistryLine: registryLineFor(pluginDir),\n\t}\n}\n\nfunction sanitizeFileNamePart(value: string): string {\n\tconst sanitized = value.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\treturn sanitized.length > 0 ? sanitized : \"0\"\n}\n\n/** Derive the registry line from package.json's repository, if present. */\nfunction registryLineFor(pluginDir: string): string {\n\ttry {\n\t\tconst pkg = JSON.parse(\n\t\t\treadFileSync(join(pluginDir, \"package.json\"), \"utf-8\"),\n\t\t) as { readonly repository?: { readonly url?: string } | string }\n\t\tconst url =\n\t\t\ttypeof pkg.repository === \"string\" ? pkg.repository : pkg.repository?.url\n\t\tif (typeof url === \"string\") {\n\t\t\tconst match = url.match(/github\\.com[:/]([^/]+)\\/([^/#.]+)/)\n\t\t\tif (match !== null) {\n\t\t\t\treturn `\"https://github.com/${match[1]}/${match[2]}\"`\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// No package.json (or unreadable) — fall through to the placeholder.\n\t}\n\treturn '\"https://github.com/<owner>/<repo>\"'\n}\n","import { existsSync, mkdtempSync, readdirSync, rmSync, statSync } from \"node:fs\"\nimport { tmpdir } from \"node:os\"\nimport { dirname, join } from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport {\n\tcreatePluginSandbox,\n\tDEFAULT_SANDBOX_CONFIG,\n\tHOOK_NAMES,\n\ttype HookName,\n\ttype PluginDefinition,\n\ttype PluginHooks,\n} from \"@hoardodile/host\"\nimport { ok } from \"@hoardodile/sdk-types\"\nimport { defineCommand } from \"citty\"\nimport {\n\ttype BenchReport,\n\tbenchExitCode,\n\tcompareBaseline,\n\tcomputeBenchReport,\n\tformatBenchSummary,\n\tloadBaseline,\n\twriteReport,\n} from \"./bench.ts\"\nimport { buildPlugin } from \"./build.ts\"\nimport { executeCreate } from \"./create.ts\"\nimport { executeDev } from \"./dev.ts\"\nimport { packPlugin } from \"./package.ts\"\nimport {\n\tbuildCliResourceAPI,\n\tCliError,\n\tcreateCliHooks,\n\tEXIT_ERROR,\n\tEXIT_PASS,\n\ttype PluginTarget,\n\tresolvePluginTarget,\n\trunCliHook,\n} from \"./runner.ts\"\n\n/**\n * `hoardodile` — the developer CLI. The `plugin` group builds, runs,\n * benchmarks and develops content plugins against the same host\n * implementation the server uses (worker sandbox + hook strategy + real\n * probes), so what you test is what runs in production.\n */\n\nfunction parseRepeat(value: string | undefined): number {\n\tif (value === undefined) return 5\n\tconst n = Number.parseInt(value, 10)\n\tif (!Number.isFinite(n) || n < 1) {\n\t\tthrow new CliError(`--repeat must be a positive integer, got \"${value}\"`)\n\t}\n\treturn n\n}\n\nfunction parseWarmup(value: string | undefined): number {\n\tif (value === undefined) return 1\n\tconst n = Number.parseInt(value, 10)\n\tif (!Number.isFinite(n) || n < 0) {\n\t\tthrow new CliError(\n\t\t\t`--warmup must be a non-negative integer, got \"${value}\"`,\n\t\t)\n\t}\n\treturn n\n}\n\nfunction parseThreshold(value: string | undefined): number {\n\tif (value === undefined) return 20\n\tconst n = Number.parseFloat(value)\n\tif (!Number.isFinite(n) || n < 0) {\n\t\tthrow new CliError(\n\t\t\t`--threshold must be a non-negative number, got \"${value}\"`,\n\t\t)\n\t}\n\treturn n\n}\n\nfunction parseHook(value: string): HookName {\n\tif (!(HOOK_NAMES as readonly string[]).includes(value)) {\n\t\tthrow new CliError(\n\t\t\t`unknown hook \"${value}\" — expected one of: ${HOOK_NAMES.join(\", \")}`,\n\t\t)\n\t}\n\treturn value as HookName\n}\n\nfunction parsePort(value: string): number {\n\tconst n = Number.parseInt(value, 10)\n\tif (!Number.isFinite(n) || n < 1 || n > 65535) {\n\t\tthrow new CliError(`--port must be a valid port number, got \"${value}\"`)\n\t}\n\treturn n\n}\n\nexport const main = defineCommand({\n\tmeta: {\n\t\tname: \"hoardodile\",\n\t\tdescription:\n\t\t\t\"hoardodile developer CLI — content-plugin create, build, run, bench and dev commands.\",\n\t},\n\tsubCommands: {\n\t\tplugin: defineCommand({\n\t\t\tmeta: {\n\t\t\t\tname: \"plugin\",\n\t\t\t\tdescription: \"Content-plugin developer commands.\",\n\t\t\t},\n\t\t\tsubCommands: {\n\t\t\t\tcreate: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"create\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Scaffold a new content plugin (runs create-hoardodile-plugin via pnpm dlx).\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\tname: {\n\t\t\t\t\t\t\ttype: \"positional\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Plugin directory name (npm-style, lowercase letters, digits and dashes). Defaults to an interactive prompt.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttarballs: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Directory of packed SDK tarballs; rewires the scaffolded plugin's SDK deps to them.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executeCreate({\n\t\t\t\t\t\t\tname: args.name,\n\t\t\t\t\t\t\ttarballs: args.tarballs,\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\trun: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"run\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Run one plugin hook against a directory and print the JSON result.\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\thook: {\n\t\t\t\t\t\t\ttype: \"positional\",\n\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\tdescription: `Hook to run: ${HOOK_NAMES.join(\", \")}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdir: {\n\t\t\t\t\t\t\ttype: \"positional\",\n\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\tdescription: \"Data directory the hook reads from.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpluginDir: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Plugin directory (manifest.json + main.js). Defaults to the --main parent.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmain: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Path to the built plugin main.js. Defaults to <plugin-dir>/main.js.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tinProcess: {\n\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Run the hook in-process instead of through the worker sandbox. Debugging only — bypasses the production execution path.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpretty: {\n\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\tdescription: \"Pretty-print the JSON result (indented).\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executeRun({\n\t\t\t\t\t\t\thook: parseHook(args.hook ?? \"\"),\n\t\t\t\t\t\t\tdir: args.dir ?? \"\",\n\t\t\t\t\t\t\tpluginDir: args.pluginDir,\n\t\t\t\t\t\t\tmain: args.main,\n\t\t\t\t\t\t\tinProcess: args.inProcess === true,\n\t\t\t\t\t\t\tpretty: args.pretty === true,\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tbench: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"bench\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Measure hook duration (sandboxed, real probes) and compare against a baseline.\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\thook: {\n\t\t\t\t\t\t\ttype: \"positional\",\n\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\tdescription: `Hook to benchmark: ${HOOK_NAMES.join(\", \")}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdir: {\n\t\t\t\t\t\t\ttype: \"positional\",\n\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\tdescription: \"Data directory the hook reads from.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpluginDir: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Plugin directory (manifest.json + main.js). Defaults to the --main parent.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmain: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Path to the built plugin main.js. Defaults to <plugin-dir>/main.js.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tinProcess: {\n\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Run in-process instead of through the worker sandbox. Debugging only.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\trepeat: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Measured iterations after the warmup runs. Default 5.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\twarmup: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Discarded warmup runs before the measured samples. Default 1.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription: \"Write the JSON report to this file.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsave: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription: \"Save a fresh baseline report to this file.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompare: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Compare against a previous report file; exit 1 when the median regresses past --threshold.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tthreshold: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Regression threshold in percent of the baseline median. Default 20.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executeBench({\n\t\t\t\t\t\t\thook: parseHook(args.hook ?? \"\"),\n\t\t\t\t\t\t\tdir: args.dir ?? \"\",\n\t\t\t\t\t\t\tpluginDir: args.pluginDir,\n\t\t\t\t\t\t\tmain: args.main,\n\t\t\t\t\t\t\tinProcess: args.inProcess === true,\n\t\t\t\t\t\t\trepeat: parseRepeat(args.repeat),\n\t\t\t\t\t\t\twarmupRuns: parseWarmup(args.warmup),\n\t\t\t\t\t\t\tthresholdPercent: parseThreshold(args.threshold),\n\t\t\t\t\t\t\tjsonPath: args.json,\n\t\t\t\t\t\t\tsavePath: args.save,\n\t\t\t\t\t\t\tcomparePath: args.compare,\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tdev: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"dev\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Build a plugin in watch mode and serve it in the workbench (default http://127.0.0.1:5199), with sandboxed hooks, preview variants and video frames.\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\tpluginDir: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Plugin directory (manifest.json + package.json). Defaults to the current directory.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Data directory served as a single resource. Defaults to <plugin-dir>/testdata when it exists.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresourceDir: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Directory whose direct subfolders each become a resource (a folder of many test-data items). Mutually exclusive with --data and --storage.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tstorage: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"hoardodile storage root to develop against. Opened READ-ONLY: resources come from app.sqlite and their bare-file folders, and plugin writes stay in the workbench's in-memory mock.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tres: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Resource id to capture first when serving a storage root.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tport: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription: \"Workbench port. Default 5199.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executeDev({\n\t\t\t\t\t\t\tpluginDir: args.pluginDir ?? \"\",\n\t\t\t\t\t\t\tdataDir: args.data,\n\t\t\t\t\t\t\tresourceRootDir: args.resourceDir,\n\t\t\t\t\t\t\tstorageDir: args.storage,\n\t\t\t\t\t\t\tresId: args.res,\n\t\t\t\t\t\t\tport: args.port === undefined ? 5199 : parsePort(args.port),\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tbuild: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"build\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Build a plugin in the current directory (manifest.json + src/ + index.html) into dist/. Pass --watch to rebuild on change.\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\twatch: {\n\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\tdescription: \"Rebuild on file changes instead of exiting.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executeBuild({\n\t\t\t\t\t\t\tdir: process.cwd(),\n\t\t\t\t\t\t\twatch: args.watch === true,\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tpackage: defineCommand({\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tname: \"package\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Build a plugin and zip dist/ into release/<id>-<version>.zip — the artifact to attach to a GitHub release for the app's plugin marketplace.\",\n\t\t\t\t\t},\n\t\t\t\t\targs: {\n\t\t\t\t\t\tpluginDir: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Plugin directory (manifest.json + package.json). Defaults to the current directory.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tskipBuild: {\n\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Do not rebuild before packaging (uses the existing dist/).\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync run({ args }) {\n\t\t\t\t\t\treturn executePackage({\n\t\t\t\t\t\t\tdir: args.pluginDir ?? process.cwd(),\n\t\t\t\t\t\t\tskipBuild: args.skipBuild === true,\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t}),\n\t},\n})\n\ntype RunOptions = {\n\treadonly hook: HookName\n\treadonly dir: string\n\treadonly pluginDir?: string\n\treadonly main?: string\n\treadonly inProcess: boolean\n\treadonly pretty?: boolean\n}\n\nasync function executeRun(opts: RunOptions): Promise<number> {\n\tconst exitCode = await executeRunInner(opts)\n\tprocess.exitCode = exitCode\n\treturn exitCode\n}\n\nasync function executeRunInner(opts: RunOptions): Promise<number> {\n\ttry {\n\t\tconst target = resolvePluginTarget({\n\t\t\tpluginDir: opts.pluginDir,\n\t\t\tmain: opts.main,\n\t\t})\n\t\tawait ensureFreshBuild(target)\n\t\t// A scratch extraction cache lets `extractArchive`-driven hooks\n\t\t// run against archive fixtures exactly as they do on the server.\n\t\tconst extractCacheDir = mkdtempSync(join(tmpdir(), \"hoard-cli-extract-\"))\n\t\ttry {\n\t\t\tconst outcome = opts.inProcess\n\t\t\t\t? await runInProcess(\n\t\t\t\t\t\ttarget.mainPath,\n\t\t\t\t\t\topts.hook,\n\t\t\t\t\t\topts.dir,\n\t\t\t\t\t\textractCacheDir,\n\t\t\t\t\t)\n\t\t\t\t: await withSandboxHooks(target, (hooks) =>\n\t\t\t\t\t\trunCliHook({\n\t\t\t\t\t\t\tid: target.id,\n\t\t\t\t\t\t\thooks,\n\t\t\t\t\t\t\thook: opts.hook,\n\t\t\t\t\t\t\tdir: opts.dir,\n\t\t\t\t\t\t\textractCacheDir,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\tconsole.log(JSON.stringify(outcome, null, opts.pretty ? 2 : 0))\n\t\t} finally {\n\t\t\trmSync(extractCacheDir, { recursive: true, force: true })\n\t\t}\n\t\treturn EXIT_PASS\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[hoardodile] ${err instanceof Error ? err.message : String(err)}`,\n\t\t)\n\t\treturn EXIT_ERROR\n\t}\n}\n\ntype BenchOptions = {\n\treadonly hook: HookName\n\treadonly dir: string\n\treadonly pluginDir?: string\n\treadonly main?: string\n\treadonly inProcess: boolean\n\treadonly repeat: number\n\treadonly warmupRuns: number\n\treadonly thresholdPercent: number\n\treadonly jsonPath?: string\n\treadonly savePath?: string\n\treadonly comparePath?: string\n}\n\nasync function executeBench(opts: BenchOptions): Promise<number> {\n\tconst exitCode = await executeBenchInner(opts)\n\tprocess.exitCode = exitCode\n\treturn exitCode\n}\n\nasync function executeBenchInner(opts: BenchOptions): Promise<number> {\n\ttry {\n\t\tconst target = resolvePluginTarget({\n\t\t\tpluginDir: opts.pluginDir,\n\t\t\tmain: opts.main,\n\t\t})\n\t\tawait ensureFreshBuild(target)\n\t\tif (opts.inProcess) {\n\t\t\tconst report = await computeBenchReport({\n\t\t\t\tpluginId: target.id,\n\t\t\t\thook: opts.hook,\n\t\t\t\tdir: opts.dir,\n\t\t\t\trepeat: opts.repeat,\n\t\t\t\twarmupRuns: opts.warmupRuns,\n\t\t\t\trun: () => runInProcess(target.mainPath, opts.hook, opts.dir),\n\t\t\t})\n\t\t\treturn finishBench(report, opts)\n\t\t}\n\t\t// One sandbox + one loaded plugin for the whole run: the warmup\n\t\t// iterations pay the worker spawn; samples measure steady-state\n\t\t// hook execution through the strategy facade.\n\t\tconst sandbox = createPluginSandbox(DEFAULT_SANDBOX_CONFIG)\n\t\ttry {\n\t\t\tconst hooks = await createCliHooks(target, sandbox)\n\t\t\tconst report = await computeBenchReport({\n\t\t\t\tpluginId: target.id,\n\t\t\t\thook: opts.hook,\n\t\t\t\tdir: opts.dir,\n\t\t\t\trepeat: opts.repeat,\n\t\t\t\twarmupRuns: opts.warmupRuns,\n\t\t\t\trun: () =>\n\t\t\t\t\trunCliHook({ id: target.id, hooks, hook: opts.hook, dir: opts.dir }),\n\t\t\t})\n\t\t\treturn finishBench(report, opts)\n\t\t} finally {\n\t\t\tawait sandbox.disposeAll()\n\t\t}\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[hoardodile] ${err instanceof Error ? err.message : String(err)}`,\n\t\t)\n\t\treturn EXIT_ERROR\n\t}\n}\n\nfunction finishBench(report: BenchReport, opts: BenchOptions): number {\n\tconsole.log(formatBenchSummary(report))\n\tlet compare: ReturnType<typeof compareBaseline> | undefined\n\tif (opts.comparePath !== undefined) {\n\t\tconst baseline = loadBaseline(opts.comparePath)\n\t\tcompare = compareBaseline(report, baseline, opts.thresholdPercent)\n\t\tconsole.log(compare.message)\n\t}\n\tif (opts.savePath !== undefined) writeReport(opts.savePath, report)\n\tif (opts.jsonPath !== undefined) writeReport(opts.jsonPath, report)\n\treturn benchExitCode(compare)\n}\n\ntype BuildOptions = {\n\treadonly dir: string\n\treadonly watch: boolean\n}\n\nasync function executeBuild(opts: BuildOptions): Promise<number> {\n\ttry {\n\t\tawait buildPlugin(opts.dir, { watch: opts.watch })\n\t\treturn EXIT_PASS\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[hoardodile] ${err instanceof Error ? err.message : String(err)}`,\n\t\t)\n\t\treturn EXIT_ERROR\n\t}\n}\n\ntype PackageOptions = {\n\treadonly dir: string\n\treadonly skipBuild: boolean\n}\n\nasync function executePackage(opts: PackageOptions): Promise<number> {\n\ttry {\n\t\tconst result = await packPlugin(opts.dir, { skipBuild: opts.skipBuild })\n\t\tconsole.log(`${result.id} v${result.version} → ${result.zipPath}`)\n\t\tconsole.log(`checksum: ${result.sha256Path}`)\n\t\tconsole.log(`registry line: ${result.registryLine}`)\n\t\tconsole.log(`publish: ${result.publishHint}`)\n\t\treturn EXIT_PASS\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[hoardodile] ${err instanceof Error ? err.message : String(err)}`,\n\t\t)\n\t\treturn EXIT_ERROR\n\t}\n}\n\n/** One sandbox + one loaded plugin for a single hook invocation. */\nasync function withSandboxHooks<T>(\n\ttarget: PluginTarget,\n\tfn: (hooks: PluginHooks) => Promise<T>,\n): Promise<T> {\n\tconst sandbox = createPluginSandbox(DEFAULT_SANDBOX_CONFIG)\n\ttry {\n\t\tconst hooks = await createCliHooks(target, sandbox)\n\t\treturn await fn(hooks)\n\t} finally {\n\t\tawait sandbox.disposeAll()\n\t}\n}\n\n/**\n * Rebuild a plugin's `dist/` when its sources are newer than the built\n * bundle — `plugin run`/`bench` execute the built `main.js`, so a\n * stale build silently runs old code. Only applies when the target\n * dir is a plugin's `dist/` sitting next to its sources\n * (`<plugin>/dist/` with `<plugin>/src/`); explicit `--main` bundles\n * are used as-is.\n */\nasync function ensureFreshBuild(target: PluginTarget): Promise<void> {\n\tconst distDir = target.dirPath\n\tconst pluginDir = dirname(distDir)\n\tconst srcDir = join(pluginDir, \"src\")\n\tconst manifestPath = join(pluginDir, \"manifest.json\")\n\tif (!existsSync(srcDir) || !existsSync(manifestPath)) return\n\tif (!existsSync(join(distDir, \"main.js\"))) return\n\tconst distMtime = newestFileMtime(distDir)\n\tconst newestSource = Math.max(\n\t\tnewestFileMtime(srcDir),\n\t\tstatSync(manifestPath).mtimeMs,\n\t)\n\t// Small tolerance for coarse filesystem mtime granularity (FAT, zip\n\t// round-trips) so a source written a moment before the build is not\n\t// judged stale by a rounding difference.\n\tconst REBUILD_TOLERANCE_MS = 2_000\n\tif (distMtime + REBUILD_TOLERANCE_MS <= newestSource) {\n\t\tconsole.log(`[hoardodile] dist/ is stale — rebuilding ${pluginDir}`)\n\t\tawait buildPlugin(pluginDir, { watch: false })\n\t}\n}\n\n/** Newest mtime under a directory tree (files only), or 0 when empty. */\nfunction newestFileMtime(dir: string): number {\n\tlet newest = 0\n\tfor (const entry of readdirSync(dir, { withFileTypes: true })) {\n\t\tconst full = join(dir, entry.name)\n\t\tif (entry.isDirectory()) {\n\t\t\tnewest = Math.max(newest, newestFileMtime(full))\n\t\t} else if (entry.isFile()) {\n\t\t\tnewest = Math.max(newest, statSync(full).mtimeMs)\n\t\t}\n\t}\n\treturn newest\n}\n\n/** Unsandboxed hook call for `--in-process` debugging. */\nasync function runInProcess(\n\tmainPath: string,\n\thook: HookName,\n\tdir: string,\n\textractCacheDir?: string,\n) {\n\tconst mod: unknown = await import(pathToFileURL(mainPath).href)\n\tif (typeof mod !== \"object\" || mod === null || !(\"default\" in mod)) {\n\t\tthrow new CliError(\n\t\t\t`plugin at ${mainPath} must default-export a plugin definition`,\n\t\t)\n\t}\n\tconst def = (mod as { default: PluginDefinition }).default\n\tconst fn = def[hook]\n\tif (typeof fn !== \"function\") {\n\t\tthrow new CliError(`plugin has no ${hook} hook`)\n\t}\n\tconst api = buildCliResourceAPI(dir, { extractCacheDir })\n\tconst started = performance.now()\n\tconst result = await fn(api)\n\treturn ok({ result, durationMs: performance.now() - started })\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hoardodile/cli",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "license": "MIT",
5
5
  "description": "hoardodile developer CLI: build, run, benchmark and develop content plugins.",
6
6
  "keywords": [
@@ -44,8 +44,8 @@
44
44
  "citty": "^0.2.2",
45
45
  "sharp": "^0.35.3",
46
46
  "vite": "^8.2.2",
47
- "@hoardodile/host": "0.1.10",
48
- "@hoardodile/sdk-types": "0.1.10"
47
+ "@hoardodile/host": "0.1.12",
48
+ "@hoardodile/sdk-types": "0.1.12"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^26.2.0",