@silicajs/cli 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  main
4
- } from "./chunk-RRZP3KUL.js";
4
+ } from "./chunk-CTUXZSEN.js";
5
5
 
6
6
  // src/bin.ts
7
7
  main().catch((error) => {
@@ -255,10 +255,10 @@ import fs3 from "fs-extra";
255
255
 
256
256
  // src/scaffold-versions.ts
257
257
  var scaffoldDependencyRanges = {
258
- "@silicajs/cli": "^0.1.6",
259
- "@silicajs/core": "^0.4.0",
260
- "@silicajs/next": "^0.2.2",
261
- "@silicajs/theme-amethyst": "^0.2.2"
258
+ "@silicajs/cli": "^0.2.0",
259
+ "@silicajs/core": "^0.5.0",
260
+ "@silicajs/next": "^0.3.0",
261
+ "@silicajs/theme-amethyst": "^0.2.3"
262
262
  };
263
263
 
264
264
  // src/scaffold.ts
@@ -411,13 +411,27 @@ A Silica vault.
411
411
  - \`npm run build\` \u2014 precompute content and build for production.
412
412
  - \`npm run start\` \u2014 serve the production build.
413
413
 
414
+ ## Rendering
415
+
416
+ Silica prerenders all notes by default and caches every rendered note. Large vaults can reduce build work in \`silica.config.ts\`:
417
+
418
+ \`\`\`ts
419
+ export default defineConfig({
420
+ render: {
421
+ prerender: { depth: 2 },
422
+ },
423
+ });
424
+ \`\`\`
425
+
426
+ Use \`prerender: "none"\` for fully on-demand rendering, or \`strategy: "custom"\` with \`include\`, \`exclude\`, and \`limit\` for hot-page selection.
427
+
414
428
  ## Auth
415
429
 
416
430
  Copy \`.env.example\` to \`.env\` and fill in Better Auth / Google OAuth values before enabling \`auth\` in \`silica.config.ts\`. Auth requires at least one \`allowedDomains\` or \`allowedEmails\` entry and a strong \`BETTER_AUTH_SECRET\` in production.
417
431
 
418
432
  ## Docker
419
433
 
420
- The scaffolded Dockerfile builds the generated standalone Next.js output and starts the traced \`server.js\` from wherever Next places it inside the standalone tree.
434
+ The scaffolded Dockerfile builds the generated standalone Next.js output and starts the traced \`server.js\` from wherever Next places it inside the standalone tree. Mount \`/app/.silica/cache/next\` as a volume to preserve rendered-note cache entries across container replacement.
421
435
  `;
422
436
  }
423
437
  function dockerfile() {
@@ -434,6 +448,7 @@ FROM node:22-alpine AS runner
434
448
  WORKDIR /app
435
449
  ENV NODE_ENV=production
436
450
  ENV SILICA_PROJECT_ROOT=/app
451
+ ENV SILICA_CACHE_DIR=/app/.silica/cache/next
437
452
  COPY --from=build /app/.silica/next/.next/standalone ./
438
453
  COPY --from=build /app/.silica/next/.next/static ./.silica/next/.next/static
439
454
  COPY --from=build /app/.silica/next/public ./.silica/next/public
@@ -486,6 +501,8 @@ jobs:
486
501
  // src/watch.ts
487
502
  import path4 from "path";
488
503
  import { watch } from "chokidar";
504
+ import fs4 from "fs-extra";
505
+ import Database from "better-sqlite3";
489
506
  import { precompute } from "@silicajs/core";
490
507
  function resolveWatchPaths(projectRoot) {
491
508
  return [
@@ -509,19 +526,26 @@ function watchContent({
509
526
  await onConfigChange?.();
510
527
  return;
511
528
  }
529
+ const previous = await readRenderHashes(projectRoot);
512
530
  await precompute({ projectRoot });
513
- const response = await fetch(
514
- `http://localhost:${port}/api/silica/revalidate?tag=build`,
515
- {
516
- method: "POST",
517
- headers: {
518
- "x-silica-revalidate-secret": process.env.SILICA_REVALIDATE_SECRET ?? ""
531
+ const current = await readRenderHashes(projectRoot);
532
+ const changedSlugs = getChangedSlugs(previous, current);
533
+ for (const slug of changedSlugs) {
534
+ const response = await fetch(
535
+ `http://localhost:${port}/api/silica/revalidate?tag=${encodeURIComponent(
536
+ `page:${slug}`
537
+ )}`,
538
+ {
539
+ method: "POST",
540
+ headers: {
541
+ "x-silica-revalidate-secret": process.env.SILICA_REVALIDATE_SECRET ?? ""
542
+ }
519
543
  }
544
+ ).catch(() => void 0);
545
+ if (!response?.ok) {
546
+ const detail = response ? `${response.status} ${response.statusText}` : "network error";
547
+ console.warn(`[silica] revalidate failed (${detail})`);
520
548
  }
521
- ).catch(() => void 0);
522
- if (!response?.ok) {
523
- const detail = response ? `${response.status} ${response.statusText}` : "network error";
524
- console.warn(`[silica] revalidate failed (${detail})`);
525
549
  }
526
550
  console.log(`[silica] rebuilt content after ${filePath}`);
527
551
  }).finally(() => {
@@ -530,6 +554,31 @@ function watchContent({
530
554
  });
531
555
  return watcher;
532
556
  }
557
+ async function readRenderHashes(projectRoot) {
558
+ const databasePath = path4.join(projectRoot, ".silica/vault.db");
559
+ if (!await fs4.pathExists(databasePath)) return /* @__PURE__ */ new Map();
560
+ const db = new Database(databasePath, {
561
+ fileMustExist: true,
562
+ readonly: true
563
+ });
564
+ try {
565
+ db.pragma("query_only = ON");
566
+ const rows = db.prepare("SELECT slug, render_hash FROM notes").all();
567
+ return new Map(rows.map((row) => [row.slug, row.render_hash]));
568
+ } finally {
569
+ db.close();
570
+ }
571
+ }
572
+ function getChangedSlugs(previous, current) {
573
+ const changed = [];
574
+ for (const [slug, renderHash] of current) {
575
+ if (previous.get(slug) !== renderHash) changed.push(slug);
576
+ }
577
+ for (const slug of previous.keys()) {
578
+ if (!current.has(slug)) changed.push(slug);
579
+ }
580
+ return changed;
581
+ }
533
582
  function requiresRestart(filePath, projectRoot) {
534
583
  const normalized = path4.isAbsolute(filePath) && projectRoot ? path4.relative(projectRoot, filePath).replace(/\\/g, "/") : filePath.replace(/\\/g, "/");
535
584
  return normalized === "silica.config.ts" || normalized.startsWith("themes/");
@@ -609,4 +658,4 @@ export {
609
658
  startCommand,
610
659
  main
611
660
  };
612
- //# sourceMappingURL=chunk-RRZP3KUL.js.map
661
+ //# sourceMappingURL=chunk-CTUXZSEN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/commands.ts","../src/diagnostics.ts","../src/materialize.ts","../src/next.ts","../src/scaffold.ts","../src/scaffold-versions.ts","../src/watch.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport {\n buildCommand,\n createCommand,\n devCommand,\n startCommand,\n} from \"./commands.js\";\n\nexport {\n buildCommand,\n createCommand,\n devCommand,\n startCommand,\n} from \"./commands.js\";\n\nexport async function main(argv = process.argv): Promise<void> {\n const program = new Command();\n program\n .name(\"silica\")\n .description(\"Publish an Obsidian-flavored markdown vault with Next.js.\")\n .version(\"0.1.0\");\n\n program\n .command(\"create\")\n .argument(\"<directory>\", \"directory to create\")\n .description(\"scaffold a new Silica vault\")\n .action(async (directory: string) => {\n await createCommand(directory);\n });\n\n program\n .command(\"dev\")\n .description(\"materialize the hidden Next.js app and start development\")\n .action(async () => {\n await devCommand();\n });\n\n program\n .command(\"build\")\n .description(\"precompute content and build the hidden Next.js app\")\n .action(async () => {\n await buildCommand();\n });\n\n program\n .command(\"start\")\n .description(\"start the built hidden Next.js app\")\n .action(async () => {\n await startCommand();\n });\n\n await program.parseAsync(argv);\n}\n","import crypto from \"node:crypto\";\nimport { precompute } from \"@silicajs/core\";\nimport { reportBrokenWikilinks } from \"./diagnostics.js\";\nimport { materializeNextApp } from \"./materialize.js\";\nimport { runNext, runStart, startNext } from \"./next.js\";\nimport { scaffoldProject } from \"./scaffold.js\";\nimport { resolveDevPort, watchContent } from \"./watch.js\";\n\nexport async function createCommand(directory: string): Promise<void> {\n await scaffoldProject(directory);\n console.log(`[silica] created ${directory}`);\n}\n\nexport async function devCommand(): Promise<void> {\n const projectRoot = process.cwd();\n let shouldRestart = true;\n\n while (shouldRestart) {\n shouldRestart = false;\n process.env.SILICA_REVALIDATE_SECRET ??= crypto.randomUUID();\n const nextRoot = await materializeNextApp({ projectRoot });\n await precompute({ projectRoot });\n const { subprocess } = await startNext(\"dev\", nextRoot);\n const watcher = watchContent({\n projectRoot,\n port: resolveDevPort(),\n onConfigChange: async () => {\n console.log(\"[silica] config or theme changed; restarting Next.js\");\n shouldRestart = true;\n subprocess.kill(\"SIGTERM\");\n },\n });\n\n try {\n await subprocess;\n } catch (error) {\n if (!shouldRestart) throw error;\n } finally {\n await watcher.close();\n }\n }\n}\n\nexport async function buildCommand(): Promise<void> {\n const projectRoot = process.cwd();\n const nextRoot = await materializeNextApp({ projectRoot });\n const result = await precompute({ projectRoot });\n reportBrokenWikilinks(result.brokenLinks);\n await runNext(\"build\", nextRoot);\n}\n\nexport async function startCommand(): Promise<void> {\n const nextRoot = await materializeNextApp({ projectRoot: process.cwd() });\n await runStart(nextRoot);\n}\n","export type BrokenLinkDiagnostic = {\n source: string;\n target: string;\n};\n\nexport function formatBrokenWikilinks(links: BrokenLinkDiagnostic[]): string {\n if (links.length === 0) return \"\";\n return [\n \"[silica] broken wikilinks:\",\n ...links\n .slice()\n .sort((a, b) =>\n `${a.source}\\0${a.target}`.localeCompare(`${b.source}\\0${b.target}`),\n )\n .map((link) => ` ${link.source} -> ${link.target}`),\n ].join(\"\\n\");\n}\n\nexport function reportBrokenWikilinks(links: BrokenLinkDiagnostic[]): void {\n const message = formatBrokenWikilinks(links);\n if (message) console.warn(message);\n}\n","import path from \"node:path\";\nimport fs from \"fs-extra\";\nimport { loadConfig } from \"@silicajs/core\";\nimport {\n getSilicaTemplates,\n nextConfigTemplate,\n packageJsonTemplate,\n proxyTemplate,\n themeModuleTemplate,\n tsconfigTemplate,\n} from \"@silicajs/next\";\n\nexport type MaterializeOptions = {\n projectRoot?: string;\n};\n\nexport async function materializeNextApp(\n options: MaterializeOptions = {},\n): Promise<string> {\n const projectRoot = options.projectRoot ?? process.cwd();\n const nextRoot = path.join(projectRoot, \".silica/next\");\n const publicRoot = path.join(nextRoot, \"public\");\n const config = await loadConfig(projectRoot);\n const configImport = await resolveUserConfigImport(projectRoot, nextRoot);\n\n await fs.ensureDir(nextRoot);\n await fs.remove(path.join(nextRoot, \"app\"));\n await fs.ensureDir(publicRoot);\n\n for (const template of getSilicaTemplates()) {\n const destination = path.join(nextRoot, template.path);\n await fs.ensureDir(path.dirname(destination));\n await fs.writeFile(destination, template.content);\n }\n\n await fs.writeFile(\n path.join(nextRoot, \"next.config.ts\"),\n nextConfigTemplate(configImport),\n );\n await fs.writeFile(path.join(nextRoot, \"proxy.ts\"), proxyTemplate(config));\n await fs.writeFile(\n path.join(nextRoot, \"silica-theme.ts\"),\n themeModuleTemplate(config.theme),\n );\n await fs.writeFile(\n path.join(nextRoot, \"package.json\"),\n packageJsonTemplate(),\n );\n await fs.writeFile(\n path.join(nextRoot, \"tsconfig.json\"),\n `${tsconfigTemplate(await fs.pathExists(path.join(projectRoot, \"tsconfig.json\")))}\\n`,\n );\n await fs.writeFile(\n path.join(nextRoot, \"next-env.d.ts\"),\n '/// <reference types=\"next\" />\\n/// <reference types=\"next/image-types/global\" />\\n',\n );\n await syncEnvFiles(projectRoot, nextRoot);\n await overlayPublic(projectRoot, publicRoot);\n return nextRoot;\n}\n\nasync function resolveUserConfigImport(\n projectRoot: string,\n nextRoot: string,\n): Promise<string | undefined> {\n const configPath = await findUserConfig(projectRoot);\n if (!configPath) return undefined;\n\n const relativePath = path\n .relative(nextRoot, configPath)\n .split(path.sep)\n .join(\"/\");\n return relativePath.startsWith(\".\") ? relativePath : `./${relativePath}`;\n}\n\nasync function findUserConfig(\n projectRoot: string,\n): Promise<string | undefined> {\n for (const filename of [\"silica.config.ts\", \"silica.config.js\"]) {\n const configPath = path.join(projectRoot, filename);\n if (await fs.pathExists(configPath)) return configPath;\n }\n return undefined;\n}\n\nasync function syncEnvFiles(\n projectRoot: string,\n nextRoot: string,\n): Promise<void> {\n const entries = await fs.readdir(projectRoot).catch(() => []);\n for (const entry of entries.filter(\n (name) => name === \".env\" || name.startsWith(\".env.\"),\n )) {\n const source = path.join(projectRoot, entry);\n const destination = path.join(nextRoot, entry);\n await fs.remove(destination);\n try {\n await fs.symlink(source, destination);\n } catch {\n await fs.copyFile(source, destination);\n }\n }\n}\n\nasync function overlayPublic(\n projectRoot: string,\n publicRoot: string,\n): Promise<void> {\n const sourceRoot = path.join(projectRoot, \"public\");\n if (!(await fs.pathExists(sourceRoot))) return;\n await fs.ensureDir(publicRoot);\n for (const entry of await fs.readdir(sourceRoot)) {\n if (entry === \"silica\") continue;\n const source = path.join(sourceRoot, entry);\n const destination = path.join(publicRoot, entry);\n await fs.remove(destination);\n try {\n await fs.symlink(\n source,\n destination,\n (await fs.stat(source)).isDirectory() ? \"dir\" : \"file\",\n );\n } catch {\n await fs.copy(source, destination);\n }\n }\n}\n","import path from \"node:path\";\nimport { execa, type ResultPromise } from \"execa\";\nimport fs from \"fs-extra\";\nimport { loadConfig } from \"@silicajs/core\";\n\nexport type NextCommand = \"dev\" | \"build\" | \"start\";\nexport type NextSubprocess = {\n subprocess: ResultPromise;\n};\n\nexport async function runNext(\n command: NextCommand,\n nextRoot: string,\n): Promise<void> {\n const { subprocess } = await startNext(command, nextRoot);\n await subprocess;\n}\n\nexport async function runStart(nextRoot: string): Promise<void> {\n const standaloneServer = await findStandaloneServer(nextRoot);\n if (!standaloneServer) {\n await runNext(\"start\", nextRoot);\n return;\n }\n\n await prepareStandaloneAssets(nextRoot, standaloneServer);\n installStackTraceRewrite(nextRoot);\n const subprocess = execa(\"node\", [standaloneServer], {\n stdin: \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n cwd: path.dirname(standaloneServer),\n env: await makeNextEnv(),\n });\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => {\n process.stdout.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n subprocess.stderr?.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n await subprocess;\n}\n\nexport async function startNext(\n command: NextCommand,\n nextRoot: string,\n): Promise<NextSubprocess> {\n installStackTraceRewrite(nextRoot);\n const subprocess = execa(\"next\", [command, nextRoot], {\n stdin: \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n env: await makeNextEnv(),\n });\n\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => {\n process.stdout.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n subprocess.stderr?.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n\n return { subprocess };\n}\n\nexport async function findStandaloneServer(\n nextRoot: string,\n): Promise<string | undefined> {\n const standaloneRoot = path.join(nextRoot, \".next/standalone\");\n if (!(await fs.pathExists(standaloneRoot))) return undefined;\n return findFile(standaloneRoot, \"server.js\");\n}\n\nexport async function prepareStandaloneAssets(\n nextRoot: string,\n standaloneServer: string,\n): Promise<void> {\n const serverRoot = path.dirname(standaloneServer);\n await syncStandaloneAsset(\n path.join(nextRoot, \".next/static\"),\n path.join(serverRoot, \".next/static\"),\n );\n await syncStandaloneAsset(\n path.join(nextRoot, \"public\"),\n path.join(serverRoot, \"public\"),\n );\n}\n\nexport function installStackTraceRewrite(nextRoot: string): void {\n const previous = Error.prepareStackTrace;\n Error.prepareStackTrace = (error, stack) => {\n const rendered = previous\n ? previous(error, stack)\n : `${error.name}: ${error.message}\\n${stack.join(\"\\n\")}`;\n return rewriteFrameworkPaths(String(rendered), nextRoot);\n };\n}\n\nexport function rewriteFrameworkPaths(\n output: string,\n nextRoot: string,\n): string {\n const normalizedRoot = nextRoot.replace(/\\\\/g, \"/\");\n const escapedWindowsRoot = normalizedRoot.replace(/\\//g, \"\\\\\");\n return output\n .replaceAll(`${normalizedRoot}/app/`, \"@silicajs/next [route]/\")\n .replaceAll(`${escapedWindowsRoot}\\\\app\\\\`, \"@silicajs/next [route]\\\\\")\n .replaceAll(`${normalizedRoot}/`, \".silica/next/\")\n .replaceAll(`${escapedWindowsRoot}\\\\`, \".silica\\\\next\\\\\");\n}\n\nasync function makeNextEnv(): Promise<NodeJS.ProcessEnv> {\n const config = await loadConfig(process.cwd());\n const authEnabled =\n Boolean(config.auth) || process.env.SILICA_AUTH_ENABLED === \"true\";\n const allowedDomains = uniqueList([\n ...(config.auth?.allowedDomains ?? []),\n ...parseList(process.env.SILICA_ALLOWED_DOMAINS),\n ]);\n const allowedEmails = uniqueList([\n ...(config.auth?.allowedEmails ?? []),\n ...parseList(process.env.SILICA_ALLOWED_EMAILS),\n ]);\n\n return {\n ...process.env,\n SILICA_PROJECT_ROOT: process.cwd(),\n SILICA_AUTH_ENABLED: authEnabled ? \"true\" : \"false\",\n SILICA_ALLOWED_DOMAINS: allowedDomains.join(\",\"),\n SILICA_ALLOWED_EMAILS: allowedEmails.join(\",\"),\n };\n}\n\nfunction parseList(value: string | undefined): string[] {\n return value\n ? value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean)\n : [];\n}\n\nfunction uniqueList(values: readonly string[]): string[] {\n return [...new Set(values.map((item) => item.trim()).filter(Boolean))];\n}\n\nasync function syncStandaloneAsset(\n source: string,\n destination: string,\n): Promise<void> {\n if (!(await fs.pathExists(source))) return;\n if (path.resolve(source) === path.resolve(destination)) return;\n\n await fs.remove(destination);\n await fs.ensureDir(path.dirname(destination));\n try {\n await fs.symlink(source, destination, \"dir\");\n } catch {\n await fs.copy(source, destination);\n }\n}\n\nasync function findFile(\n root: string,\n filename: string,\n): Promise<string | undefined> {\n const entries = await fs.readdir(root, { withFileTypes: true });\n for (const entry of entries) {\n const absolute = path.join(root, entry.name);\n if (entry.isFile() && entry.name === filename) return absolute;\n if (entry.isDirectory()) {\n const found = await findFile(absolute, filename);\n if (found) return found;\n }\n }\n return undefined;\n}\n","import path from \"node:path\";\nimport fs from \"fs-extra\";\nimport { scaffoldDependencyRanges } from \"./scaffold-versions.js\";\n\nexport async function scaffoldProject(targetDir: string): Promise<void> {\n const root = path.resolve(targetDir);\n if ((await fs.pathExists(root)) && (await fs.readdir(root)).length > 0) {\n throw new Error(`Target directory is not empty: ${root}`);\n }\n\n await fs.ensureDir(path.join(root, \"content/notes\"));\n await fs.ensureDir(path.join(root, \".github/workflows\"));\n await fs.writeFile(path.join(root, \"content/index.md\"), indexMarkdown());\n await fs.writeFile(\n path.join(root, \"content/notes/getting-started.md\"),\n gettingStartedMarkdown(),\n );\n await fs.writeFile(path.join(root, \"silica.config.ts\"), silicaConfig());\n await fs.writeFile(path.join(root, \"tsconfig.json\"), tsconfig());\n await fs.writeFile(\n path.join(root, \"package.json\"),\n packageJson(path.basename(root)),\n );\n await fs.writeFile(path.join(root, \".env.example\"), envExample());\n await fs.writeFile(path.join(root, \".gitignore\"), gitignore());\n await fs.writeFile(path.join(root, \".dockerignore\"), dockerignore());\n await fs.writeFile(path.join(root, \"README.md\"), readme(path.basename(root)));\n await fs.writeFile(path.join(root, \"Dockerfile\"), dockerfile());\n await fs.writeFile(\n path.join(root, \".github/workflows/deploy.yml\"),\n workflow(),\n );\n}\n\nfunction indexMarkdown(): string {\n return `---\\ntitle: Welcome\\ntags: [home]\\n---\\n\\n# Welcome\\n\\nThis is your new Silica vault. Open [[notes/getting-started|Getting started]] to learn the basics.\\n\\n> [!note] Edit freely\\n> Write standard Markdown plus Obsidian-style wikilinks.\\n`;\n}\n\nfunction gettingStartedMarkdown(): string {\n return `---\\ntitle: Getting started\\ntags: [guide]\\n---\\n\\n# Getting started\\n\\nRun \\`npm run dev\\` and edit files in \\`content/\\`. Silica regenerates the hidden Next.js app under \\`.silica/\\`.\\n`;\n}\n\nfunction silicaConfig(): string {\n return `import { defineConfig } from \"@silicajs/core\";\\n\\nexport default defineConfig({\\n title: \"My Silica Site\",\\n description: \"A private knowledge site\",\\n theme: \"default\",\\n // auth: {\\n // provider: \"google\",\\n // allowedDomains: [\"example.com\"],\\n // },\\n});\\n`;\n}\n\nfunction tsconfig(): string {\n return `${JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2022\",\n module: \"NodeNext\",\n moduleResolution: \"NodeNext\",\n strict: true,\n skipLibCheck: true,\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction packageJson(name: string): string {\n return `${JSON.stringify(\n {\n name,\n private: true,\n type: \"module\",\n scripts: {\n dev: \"silica dev\",\n build: \"silica build\",\n start: \"silica start\",\n },\n dependencies: {\n ...scaffoldDependencyRanges,\n next: \"^16.2.6\",\n react: \"^19.2.6\",\n \"react-dom\": \"^19.2.6\",\n },\n devDependencies: {\n \"@tailwindcss/postcss\": \"^4.1.18\",\n \"@types/node\": \"^25.9.1\",\n \"@types/react\": \"^19.2.10\",\n \"@types/react-dom\": \"^19.2.3\",\n tailwindcss: \"^4.1.18\",\n typescript: \"^6.0.3\",\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction envExample(): string {\n return `BETTER_AUTH_SECRET=\\nBETTER_AUTH_URL=http://localhost:3000\\nGOOGLE_CLIENT_ID=\\nGOOGLE_CLIENT_SECRET=\\n`;\n}\n\nfunction gitignore(): string {\n return `.silica/\\nnode_modules/\\n.env\\n.env.*\\n!.env.example\\n`;\n}\n\nfunction dockerignore(): string {\n return `.git\\n.silica\\nnode_modules\\n.env\\n.env.*\\n!.env.example\\n`;\n}\n\nfunction readme(name: string): string {\n return `# ${name}\\n\\nA Silica vault.\\n\\n## Commands\\n\\n- \\`npm run dev\\` — materialize and run the hidden Next.js app.\\n- \\`npm run build\\` — precompute content and build for production.\\n- \\`npm run start\\` — serve the production build.\\n\\n## Rendering\\n\\nSilica prerenders all notes by default and caches every rendered note. Large vaults can reduce build work in \\`silica.config.ts\\`:\\n\\n\\`\\`\\`ts\\nexport default defineConfig({\\n render: {\\n prerender: { depth: 2 },\\n },\\n});\\n\\`\\`\\`\\n\\nUse \\`prerender: \\\"none\\\"\\` for fully on-demand rendering, or \\`strategy: \\\"custom\\\"\\` with \\`include\\`, \\`exclude\\`, and \\`limit\\` for hot-page selection.\\n\\n## Auth\\n\\nCopy \\`.env.example\\` to \\`.env\\` and fill in Better Auth / Google OAuth values before enabling \\`auth\\` in \\`silica.config.ts\\`. Auth requires at least one \\`allowedDomains\\` or \\`allowedEmails\\` entry and a strong \\`BETTER_AUTH_SECRET\\` in production.\\n\\n## Docker\\n\\nThe scaffolded Dockerfile builds the generated standalone Next.js output and starts the traced \\`server.js\\` from wherever Next places it inside the standalone tree. Mount \\`/app/.silica/cache/next\\` as a volume to preserve rendered-note cache entries across container replacement.\\n`;\n}\n\nfunction dockerfile(): string {\n return `FROM node:22-alpine AS deps\\nWORKDIR /app\\nCOPY package*.json ./\\nRUN npm ci\\n\\nFROM deps AS build\\nCOPY . .\\nRUN npm run build\\n\\nFROM node:22-alpine AS runner\\nWORKDIR /app\\nENV NODE_ENV=production\\nENV SILICA_PROJECT_ROOT=/app\\nENV SILICA_CACHE_DIR=/app/.silica/cache/next\\nCOPY --from=build /app/.silica/next/.next/standalone ./\\nCOPY --from=build /app/.silica/next/.next/static ./.silica/next/.next/static\\nCOPY --from=build /app/.silica/next/public ./.silica/next/public\\nCOPY --from=build /app/.silica ./.silica\\nEXPOSE 3000\\nCMD [\"sh\", \"-c\", \"node $(find . -path '*/server.js' -print -quit)\"]\\n`;\n}\n\nfunction workflow(): string {\n return `name: Build Silica image\\n\\non:\\n push:\\n branches: [main]\\n\\njobs:\\n image:\\n runs-on: ubuntu-latest\\n permissions:\\n contents: read\\n packages: write\\n steps:\\n - uses: actions/checkout@v5\\n - uses: docker/login-action@v4\\n with:\\n registry: ghcr.io\\n username: \\${{ github.actor }}\\n password: \\${{ secrets.GITHUB_TOKEN }}\\n - uses: docker/build-push-action@v7\\n with:\\n context: .\\n push: true\\n tags: ghcr.io/\\${{ github.repository }}:latest\\n # Optional SSH deploy:\\n # - name: Deploy on remote host\\n # if: \\${{ secrets.SSH_HOST != '' }}\\n # uses: appleboy/ssh-action@v1.2.0\\n # with:\\n # host: \\${{ secrets.SSH_HOST }}\\n # username: \\${{ secrets.SSH_USER }}\\n # key: \\${{ secrets.SSH_KEY }}\\n # script: |\\n # docker pull ghcr.io/\\${{ github.repository }}:latest\\n # docker stop silica || true\\n # docker rm silica || true\\n # docker run -d --name silica -p 3000:3000 ghcr.io/\\${{ github.repository }}:latest\\n`;\n}\n","// This file is generated by scripts/sync-scaffold-versions.mjs.\n// Run npm run scaffold-versions:update after package version changes.\n\nexport const scaffoldDependencyRanges = {\n \"@silicajs/cli\": \"^0.2.0\",\n \"@silicajs/core\": \"^0.5.0\",\n \"@silicajs/next\": \"^0.3.0\",\n \"@silicajs/theme-amethyst\": \"^0.2.3\",\n} as const;\n","import path from \"node:path\";\nimport { watch } from \"chokidar\";\nimport fs from \"fs-extra\";\nimport Database from \"better-sqlite3\";\nimport { precompute } from \"@silicajs/core\";\n\nexport type WatchOptions = {\n projectRoot: string;\n port?: number;\n onConfigChange?: () => void | Promise<void>;\n};\n\nexport function resolveWatchPaths(projectRoot: string): string[] {\n return [\n path.join(projectRoot, \"content\"),\n path.join(projectRoot, \"themes\"),\n path.join(projectRoot, \"silica.config.ts\"),\n ];\n}\n\nexport function watchContent({\n projectRoot,\n port = 3000,\n onConfigChange,\n}: WatchOptions) {\n const watcher = watch(resolveWatchPaths(projectRoot), {\n ignoreInitial: true,\n });\n\n let pending: Promise<void> | undefined;\n watcher.on(\"all\", (_event, filePath) => {\n pending ??= Promise.resolve()\n .then(async () => {\n if (requiresRestart(filePath, projectRoot)) {\n await onConfigChange?.();\n return;\n }\n const previous = await readRenderHashes(projectRoot);\n await precompute({ projectRoot });\n const current = await readRenderHashes(projectRoot);\n const changedSlugs = getChangedSlugs(previous, current);\n for (const slug of changedSlugs) {\n const response = await fetch(\n `http://localhost:${port}/api/silica/revalidate?tag=${encodeURIComponent(\n `page:${slug}`,\n )}`,\n {\n method: \"POST\",\n headers: {\n \"x-silica-revalidate-secret\":\n process.env.SILICA_REVALIDATE_SECRET ?? \"\",\n },\n },\n ).catch(() => undefined);\n if (!response?.ok) {\n const detail = response\n ? `${response.status} ${response.statusText}`\n : \"network error\";\n console.warn(`[silica] revalidate failed (${detail})`);\n }\n }\n console.log(`[silica] rebuilt content after ${filePath}`);\n })\n .finally(() => {\n pending = undefined;\n });\n });\n\n return watcher;\n}\n\nasync function readRenderHashes(\n projectRoot: string,\n): Promise<Map<string, string>> {\n const databasePath = path.join(projectRoot, \".silica/vault.db\");\n if (!(await fs.pathExists(databasePath))) return new Map();\n const db = new Database(databasePath, {\n fileMustExist: true,\n readonly: true,\n });\n try {\n db.pragma(\"query_only = ON\");\n const rows = db\n .prepare(\"SELECT slug, render_hash FROM notes\")\n .all() as Array<{ slug: string; render_hash: string }>;\n return new Map(rows.map((row) => [row.slug, row.render_hash]));\n } finally {\n db.close();\n }\n}\n\nfunction getChangedSlugs(\n previous: Map<string, string>,\n current: Map<string, string>,\n): string[] {\n const changed: string[] = [];\n for (const [slug, renderHash] of current) {\n if (previous.get(slug) !== renderHash) changed.push(slug);\n }\n for (const slug of previous.keys()) {\n if (!current.has(slug)) changed.push(slug);\n }\n return changed;\n}\n\nexport function requiresRestart(\n filePath: string,\n projectRoot?: string,\n): boolean {\n const normalized =\n path.isAbsolute(filePath) && projectRoot\n ? path.relative(projectRoot, filePath).replace(/\\\\/g, \"/\")\n : filePath.replace(/\\\\/g, \"/\");\n return normalized === \"silica.config.ts\" || normalized.startsWith(\"themes/\");\n}\n\nexport function resolveDevPort(env: NodeJS.ProcessEnv = process.env): number {\n const parsed = Number(env.PORT);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : 3000;\n}\n"],"mappings":"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","names":["precompute","path","fs","loadConfig","path","fs","path","fs","path","fs","precompute"]}
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  devCommand,
6
6
  main,
7
7
  startCommand
8
- } from "./chunk-RRZP3KUL.js";
8
+ } from "./chunk-CTUXZSEN.js";
9
9
  export {
10
10
  buildCommand,
11
11
  createCommand,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@silicajs/cli",
3
- "version": "0.1.6",
3
+ "version": "0.2.0",
4
4
  "description": "Silica command-line interface.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -26,8 +26,9 @@
26
26
  "lint": "tsc --noEmit"
27
27
  },
28
28
  "dependencies": {
29
- "@silicajs/core": "^0.4.0",
30
- "@silicajs/next": "^0.2.2",
29
+ "@silicajs/core": "^0.5.0",
30
+ "@silicajs/next": "^0.3.0",
31
+ "better-sqlite3": "^12.10.0",
31
32
  "chokidar": "^5.0.0",
32
33
  "commander": "^15.0.0",
33
34
  "execa": "^9.6.1",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands.ts","../src/diagnostics.ts","../src/materialize.ts","../src/next.ts","../src/scaffold.ts","../src/scaffold-versions.ts","../src/watch.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport {\n buildCommand,\n createCommand,\n devCommand,\n startCommand,\n} from \"./commands.js\";\n\nexport {\n buildCommand,\n createCommand,\n devCommand,\n startCommand,\n} from \"./commands.js\";\n\nexport async function main(argv = process.argv): Promise<void> {\n const program = new Command();\n program\n .name(\"silica\")\n .description(\"Publish an Obsidian-flavored markdown vault with Next.js.\")\n .version(\"0.1.0\");\n\n program\n .command(\"create\")\n .argument(\"<directory>\", \"directory to create\")\n .description(\"scaffold a new Silica vault\")\n .action(async (directory: string) => {\n await createCommand(directory);\n });\n\n program\n .command(\"dev\")\n .description(\"materialize the hidden Next.js app and start development\")\n .action(async () => {\n await devCommand();\n });\n\n program\n .command(\"build\")\n .description(\"precompute content and build the hidden Next.js app\")\n .action(async () => {\n await buildCommand();\n });\n\n program\n .command(\"start\")\n .description(\"start the built hidden Next.js app\")\n .action(async () => {\n await startCommand();\n });\n\n await program.parseAsync(argv);\n}\n","import crypto from \"node:crypto\";\nimport { precompute } from \"@silicajs/core\";\nimport { reportBrokenWikilinks } from \"./diagnostics.js\";\nimport { materializeNextApp } from \"./materialize.js\";\nimport { runNext, runStart, startNext } from \"./next.js\";\nimport { scaffoldProject } from \"./scaffold.js\";\nimport { resolveDevPort, watchContent } from \"./watch.js\";\n\nexport async function createCommand(directory: string): Promise<void> {\n await scaffoldProject(directory);\n console.log(`[silica] created ${directory}`);\n}\n\nexport async function devCommand(): Promise<void> {\n const projectRoot = process.cwd();\n let shouldRestart = true;\n\n while (shouldRestart) {\n shouldRestart = false;\n process.env.SILICA_REVALIDATE_SECRET ??= crypto.randomUUID();\n const nextRoot = await materializeNextApp({ projectRoot });\n await precompute({ projectRoot });\n const { subprocess } = await startNext(\"dev\", nextRoot);\n const watcher = watchContent({\n projectRoot,\n port: resolveDevPort(),\n onConfigChange: async () => {\n console.log(\"[silica] config or theme changed; restarting Next.js\");\n shouldRestart = true;\n subprocess.kill(\"SIGTERM\");\n },\n });\n\n try {\n await subprocess;\n } catch (error) {\n if (!shouldRestart) throw error;\n } finally {\n await watcher.close();\n }\n }\n}\n\nexport async function buildCommand(): Promise<void> {\n const projectRoot = process.cwd();\n const nextRoot = await materializeNextApp({ projectRoot });\n const result = await precompute({ projectRoot });\n reportBrokenWikilinks(result.brokenLinks);\n await runNext(\"build\", nextRoot);\n}\n\nexport async function startCommand(): Promise<void> {\n const nextRoot = await materializeNextApp({ projectRoot: process.cwd() });\n await runStart(nextRoot);\n}\n","export type BrokenLinkDiagnostic = {\n source: string;\n target: string;\n};\n\nexport function formatBrokenWikilinks(links: BrokenLinkDiagnostic[]): string {\n if (links.length === 0) return \"\";\n return [\n \"[silica] broken wikilinks:\",\n ...links\n .slice()\n .sort((a, b) =>\n `${a.source}\\0${a.target}`.localeCompare(`${b.source}\\0${b.target}`),\n )\n .map((link) => ` ${link.source} -> ${link.target}`),\n ].join(\"\\n\");\n}\n\nexport function reportBrokenWikilinks(links: BrokenLinkDiagnostic[]): void {\n const message = formatBrokenWikilinks(links);\n if (message) console.warn(message);\n}\n","import path from \"node:path\";\nimport fs from \"fs-extra\";\nimport { loadConfig } from \"@silicajs/core\";\nimport {\n getSilicaTemplates,\n nextConfigTemplate,\n packageJsonTemplate,\n proxyTemplate,\n themeModuleTemplate,\n tsconfigTemplate,\n} from \"@silicajs/next\";\n\nexport type MaterializeOptions = {\n projectRoot?: string;\n};\n\nexport async function materializeNextApp(\n options: MaterializeOptions = {},\n): Promise<string> {\n const projectRoot = options.projectRoot ?? process.cwd();\n const nextRoot = path.join(projectRoot, \".silica/next\");\n const publicRoot = path.join(nextRoot, \"public\");\n const config = await loadConfig(projectRoot);\n const configImport = await resolveUserConfigImport(projectRoot, nextRoot);\n\n await fs.ensureDir(nextRoot);\n await fs.remove(path.join(nextRoot, \"app\"));\n await fs.ensureDir(publicRoot);\n\n for (const template of getSilicaTemplates()) {\n const destination = path.join(nextRoot, template.path);\n await fs.ensureDir(path.dirname(destination));\n await fs.writeFile(destination, template.content);\n }\n\n await fs.writeFile(\n path.join(nextRoot, \"next.config.ts\"),\n nextConfigTemplate(configImport),\n );\n await fs.writeFile(path.join(nextRoot, \"proxy.ts\"), proxyTemplate(config));\n await fs.writeFile(\n path.join(nextRoot, \"silica-theme.ts\"),\n themeModuleTemplate(config.theme),\n );\n await fs.writeFile(\n path.join(nextRoot, \"package.json\"),\n packageJsonTemplate(),\n );\n await fs.writeFile(\n path.join(nextRoot, \"tsconfig.json\"),\n `${tsconfigTemplate(await fs.pathExists(path.join(projectRoot, \"tsconfig.json\")))}\\n`,\n );\n await fs.writeFile(\n path.join(nextRoot, \"next-env.d.ts\"),\n '/// <reference types=\"next\" />\\n/// <reference types=\"next/image-types/global\" />\\n',\n );\n await syncEnvFiles(projectRoot, nextRoot);\n await overlayPublic(projectRoot, publicRoot);\n return nextRoot;\n}\n\nasync function resolveUserConfigImport(\n projectRoot: string,\n nextRoot: string,\n): Promise<string | undefined> {\n const configPath = await findUserConfig(projectRoot);\n if (!configPath) return undefined;\n\n const relativePath = path\n .relative(nextRoot, configPath)\n .split(path.sep)\n .join(\"/\");\n return relativePath.startsWith(\".\") ? relativePath : `./${relativePath}`;\n}\n\nasync function findUserConfig(\n projectRoot: string,\n): Promise<string | undefined> {\n for (const filename of [\"silica.config.ts\", \"silica.config.js\"]) {\n const configPath = path.join(projectRoot, filename);\n if (await fs.pathExists(configPath)) return configPath;\n }\n return undefined;\n}\n\nasync function syncEnvFiles(\n projectRoot: string,\n nextRoot: string,\n): Promise<void> {\n const entries = await fs.readdir(projectRoot).catch(() => []);\n for (const entry of entries.filter(\n (name) => name === \".env\" || name.startsWith(\".env.\"),\n )) {\n const source = path.join(projectRoot, entry);\n const destination = path.join(nextRoot, entry);\n await fs.remove(destination);\n try {\n await fs.symlink(source, destination);\n } catch {\n await fs.copyFile(source, destination);\n }\n }\n}\n\nasync function overlayPublic(\n projectRoot: string,\n publicRoot: string,\n): Promise<void> {\n const sourceRoot = path.join(projectRoot, \"public\");\n if (!(await fs.pathExists(sourceRoot))) return;\n await fs.ensureDir(publicRoot);\n for (const entry of await fs.readdir(sourceRoot)) {\n if (entry === \"silica\") continue;\n const source = path.join(sourceRoot, entry);\n const destination = path.join(publicRoot, entry);\n await fs.remove(destination);\n try {\n await fs.symlink(\n source,\n destination,\n (await fs.stat(source)).isDirectory() ? \"dir\" : \"file\",\n );\n } catch {\n await fs.copy(source, destination);\n }\n }\n}\n","import path from \"node:path\";\nimport { execa, type ResultPromise } from \"execa\";\nimport fs from \"fs-extra\";\nimport { loadConfig } from \"@silicajs/core\";\n\nexport type NextCommand = \"dev\" | \"build\" | \"start\";\nexport type NextSubprocess = {\n subprocess: ResultPromise;\n};\n\nexport async function runNext(\n command: NextCommand,\n nextRoot: string,\n): Promise<void> {\n const { subprocess } = await startNext(command, nextRoot);\n await subprocess;\n}\n\nexport async function runStart(nextRoot: string): Promise<void> {\n const standaloneServer = await findStandaloneServer(nextRoot);\n if (!standaloneServer) {\n await runNext(\"start\", nextRoot);\n return;\n }\n\n await prepareStandaloneAssets(nextRoot, standaloneServer);\n installStackTraceRewrite(nextRoot);\n const subprocess = execa(\"node\", [standaloneServer], {\n stdin: \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n cwd: path.dirname(standaloneServer),\n env: await makeNextEnv(),\n });\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => {\n process.stdout.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n subprocess.stderr?.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n await subprocess;\n}\n\nexport async function startNext(\n command: NextCommand,\n nextRoot: string,\n): Promise<NextSubprocess> {\n installStackTraceRewrite(nextRoot);\n const subprocess = execa(\"next\", [command, nextRoot], {\n stdin: \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n env: await makeNextEnv(),\n });\n\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => {\n process.stdout.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n subprocess.stderr?.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n\n return { subprocess };\n}\n\nexport async function findStandaloneServer(\n nextRoot: string,\n): Promise<string | undefined> {\n const standaloneRoot = path.join(nextRoot, \".next/standalone\");\n if (!(await fs.pathExists(standaloneRoot))) return undefined;\n return findFile(standaloneRoot, \"server.js\");\n}\n\nexport async function prepareStandaloneAssets(\n nextRoot: string,\n standaloneServer: string,\n): Promise<void> {\n const serverRoot = path.dirname(standaloneServer);\n await syncStandaloneAsset(\n path.join(nextRoot, \".next/static\"),\n path.join(serverRoot, \".next/static\"),\n );\n await syncStandaloneAsset(\n path.join(nextRoot, \"public\"),\n path.join(serverRoot, \"public\"),\n );\n}\n\nexport function installStackTraceRewrite(nextRoot: string): void {\n const previous = Error.prepareStackTrace;\n Error.prepareStackTrace = (error, stack) => {\n const rendered = previous\n ? previous(error, stack)\n : `${error.name}: ${error.message}\\n${stack.join(\"\\n\")}`;\n return rewriteFrameworkPaths(String(rendered), nextRoot);\n };\n}\n\nexport function rewriteFrameworkPaths(\n output: string,\n nextRoot: string,\n): string {\n const normalizedRoot = nextRoot.replace(/\\\\/g, \"/\");\n const escapedWindowsRoot = normalizedRoot.replace(/\\//g, \"\\\\\");\n return output\n .replaceAll(`${normalizedRoot}/app/`, \"@silicajs/next [route]/\")\n .replaceAll(`${escapedWindowsRoot}\\\\app\\\\`, \"@silicajs/next [route]\\\\\")\n .replaceAll(`${normalizedRoot}/`, \".silica/next/\")\n .replaceAll(`${escapedWindowsRoot}\\\\`, \".silica\\\\next\\\\\");\n}\n\nasync function makeNextEnv(): Promise<NodeJS.ProcessEnv> {\n const config = await loadConfig(process.cwd());\n const authEnabled =\n Boolean(config.auth) || process.env.SILICA_AUTH_ENABLED === \"true\";\n const allowedDomains = uniqueList([\n ...(config.auth?.allowedDomains ?? []),\n ...parseList(process.env.SILICA_ALLOWED_DOMAINS),\n ]);\n const allowedEmails = uniqueList([\n ...(config.auth?.allowedEmails ?? []),\n ...parseList(process.env.SILICA_ALLOWED_EMAILS),\n ]);\n\n return {\n ...process.env,\n SILICA_PROJECT_ROOT: process.cwd(),\n SILICA_AUTH_ENABLED: authEnabled ? \"true\" : \"false\",\n SILICA_ALLOWED_DOMAINS: allowedDomains.join(\",\"),\n SILICA_ALLOWED_EMAILS: allowedEmails.join(\",\"),\n };\n}\n\nfunction parseList(value: string | undefined): string[] {\n return value\n ? value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean)\n : [];\n}\n\nfunction uniqueList(values: readonly string[]): string[] {\n return [...new Set(values.map((item) => item.trim()).filter(Boolean))];\n}\n\nasync function syncStandaloneAsset(\n source: string,\n destination: string,\n): Promise<void> {\n if (!(await fs.pathExists(source))) return;\n if (path.resolve(source) === path.resolve(destination)) return;\n\n await fs.remove(destination);\n await fs.ensureDir(path.dirname(destination));\n try {\n await fs.symlink(source, destination, \"dir\");\n } catch {\n await fs.copy(source, destination);\n }\n}\n\nasync function findFile(\n root: string,\n filename: string,\n): Promise<string | undefined> {\n const entries = await fs.readdir(root, { withFileTypes: true });\n for (const entry of entries) {\n const absolute = path.join(root, entry.name);\n if (entry.isFile() && entry.name === filename) return absolute;\n if (entry.isDirectory()) {\n const found = await findFile(absolute, filename);\n if (found) return found;\n }\n }\n return undefined;\n}\n","import path from \"node:path\";\nimport fs from \"fs-extra\";\nimport { scaffoldDependencyRanges } from \"./scaffold-versions.js\";\n\nexport async function scaffoldProject(targetDir: string): Promise<void> {\n const root = path.resolve(targetDir);\n if ((await fs.pathExists(root)) && (await fs.readdir(root)).length > 0) {\n throw new Error(`Target directory is not empty: ${root}`);\n }\n\n await fs.ensureDir(path.join(root, \"content/notes\"));\n await fs.ensureDir(path.join(root, \".github/workflows\"));\n await fs.writeFile(path.join(root, \"content/index.md\"), indexMarkdown());\n await fs.writeFile(\n path.join(root, \"content/notes/getting-started.md\"),\n gettingStartedMarkdown(),\n );\n await fs.writeFile(path.join(root, \"silica.config.ts\"), silicaConfig());\n await fs.writeFile(path.join(root, \"tsconfig.json\"), tsconfig());\n await fs.writeFile(\n path.join(root, \"package.json\"),\n packageJson(path.basename(root)),\n );\n await fs.writeFile(path.join(root, \".env.example\"), envExample());\n await fs.writeFile(path.join(root, \".gitignore\"), gitignore());\n await fs.writeFile(path.join(root, \".dockerignore\"), dockerignore());\n await fs.writeFile(path.join(root, \"README.md\"), readme(path.basename(root)));\n await fs.writeFile(path.join(root, \"Dockerfile\"), dockerfile());\n await fs.writeFile(\n path.join(root, \".github/workflows/deploy.yml\"),\n workflow(),\n );\n}\n\nfunction indexMarkdown(): string {\n return `---\\ntitle: Welcome\\ntags: [home]\\n---\\n\\n# Welcome\\n\\nThis is your new Silica vault. Open [[notes/getting-started|Getting started]] to learn the basics.\\n\\n> [!note] Edit freely\\n> Write standard Markdown plus Obsidian-style wikilinks.\\n`;\n}\n\nfunction gettingStartedMarkdown(): string {\n return `---\\ntitle: Getting started\\ntags: [guide]\\n---\\n\\n# Getting started\\n\\nRun \\`npm run dev\\` and edit files in \\`content/\\`. Silica regenerates the hidden Next.js app under \\`.silica/\\`.\\n`;\n}\n\nfunction silicaConfig(): string {\n return `import { defineConfig } from \"@silicajs/core\";\\n\\nexport default defineConfig({\\n title: \"My Silica Site\",\\n description: \"A private knowledge site\",\\n theme: \"default\",\\n // auth: {\\n // provider: \"google\",\\n // allowedDomains: [\"example.com\"],\\n // },\\n});\\n`;\n}\n\nfunction tsconfig(): string {\n return `${JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2022\",\n module: \"NodeNext\",\n moduleResolution: \"NodeNext\",\n strict: true,\n skipLibCheck: true,\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction packageJson(name: string): string {\n return `${JSON.stringify(\n {\n name,\n private: true,\n type: \"module\",\n scripts: {\n dev: \"silica dev\",\n build: \"silica build\",\n start: \"silica start\",\n },\n dependencies: {\n ...scaffoldDependencyRanges,\n next: \"^16.2.6\",\n react: \"^19.2.6\",\n \"react-dom\": \"^19.2.6\",\n },\n devDependencies: {\n \"@tailwindcss/postcss\": \"^4.1.18\",\n \"@types/node\": \"^25.9.1\",\n \"@types/react\": \"^19.2.10\",\n \"@types/react-dom\": \"^19.2.3\",\n tailwindcss: \"^4.1.18\",\n typescript: \"^6.0.3\",\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction envExample(): string {\n return `BETTER_AUTH_SECRET=\\nBETTER_AUTH_URL=http://localhost:3000\\nGOOGLE_CLIENT_ID=\\nGOOGLE_CLIENT_SECRET=\\n`;\n}\n\nfunction gitignore(): string {\n return `.silica/\\nnode_modules/\\n.env\\n.env.*\\n!.env.example\\n`;\n}\n\nfunction dockerignore(): string {\n return `.git\\n.silica\\nnode_modules\\n.env\\n.env.*\\n!.env.example\\n`;\n}\n\nfunction readme(name: string): string {\n return `# ${name}\\n\\nA Silica vault.\\n\\n## Commands\\n\\n- \\`npm run dev\\` — materialize and run the hidden Next.js app.\\n- \\`npm run build\\` — precompute content and build for production.\\n- \\`npm run start\\` — serve the production build.\\n\\n## Auth\\n\\nCopy \\`.env.example\\` to \\`.env\\` and fill in Better Auth / Google OAuth values before enabling \\`auth\\` in \\`silica.config.ts\\`. Auth requires at least one \\`allowedDomains\\` or \\`allowedEmails\\` entry and a strong \\`BETTER_AUTH_SECRET\\` in production.\\n\\n## Docker\\n\\nThe scaffolded Dockerfile builds the generated standalone Next.js output and starts the traced \\`server.js\\` from wherever Next places it inside the standalone tree.\\n`;\n}\n\nfunction dockerfile(): string {\n return `FROM node:22-alpine AS deps\\nWORKDIR /app\\nCOPY package*.json ./\\nRUN npm ci\\n\\nFROM deps AS build\\nCOPY . .\\nRUN npm run build\\n\\nFROM node:22-alpine AS runner\\nWORKDIR /app\\nENV NODE_ENV=production\\nENV SILICA_PROJECT_ROOT=/app\\nCOPY --from=build /app/.silica/next/.next/standalone ./\\nCOPY --from=build /app/.silica/next/.next/static ./.silica/next/.next/static\\nCOPY --from=build /app/.silica/next/public ./.silica/next/public\\nCOPY --from=build /app/.silica ./.silica\\nEXPOSE 3000\\nCMD [\"sh\", \"-c\", \"node $(find . -path '*/server.js' -print -quit)\"]\\n`;\n}\n\nfunction workflow(): string {\n return `name: Build Silica image\\n\\non:\\n push:\\n branches: [main]\\n\\njobs:\\n image:\\n runs-on: ubuntu-latest\\n permissions:\\n contents: read\\n packages: write\\n steps:\\n - uses: actions/checkout@v5\\n - uses: docker/login-action@v4\\n with:\\n registry: ghcr.io\\n username: \\${{ github.actor }}\\n password: \\${{ secrets.GITHUB_TOKEN }}\\n - uses: docker/build-push-action@v7\\n with:\\n context: .\\n push: true\\n tags: ghcr.io/\\${{ github.repository }}:latest\\n # Optional SSH deploy:\\n # - name: Deploy on remote host\\n # if: \\${{ secrets.SSH_HOST != '' }}\\n # uses: appleboy/ssh-action@v1.2.0\\n # with:\\n # host: \\${{ secrets.SSH_HOST }}\\n # username: \\${{ secrets.SSH_USER }}\\n # key: \\${{ secrets.SSH_KEY }}\\n # script: |\\n # docker pull ghcr.io/\\${{ github.repository }}:latest\\n # docker stop silica || true\\n # docker rm silica || true\\n # docker run -d --name silica -p 3000:3000 ghcr.io/\\${{ github.repository }}:latest\\n`;\n}\n","// This file is generated by scripts/sync-scaffold-versions.mjs.\n// Run npm run scaffold-versions:update after package version changes.\n\nexport const scaffoldDependencyRanges = {\n \"@silicajs/cli\": \"^0.1.6\",\n \"@silicajs/core\": \"^0.4.0\",\n \"@silicajs/next\": \"^0.2.2\",\n \"@silicajs/theme-amethyst\": \"^0.2.2\",\n} as const;\n","import path from \"node:path\";\nimport { watch } from \"chokidar\";\nimport { precompute } from \"@silicajs/core\";\n\nexport type WatchOptions = {\n projectRoot: string;\n port?: number;\n onConfigChange?: () => void | Promise<void>;\n};\n\nexport function resolveWatchPaths(projectRoot: string): string[] {\n return [\n path.join(projectRoot, \"content\"),\n path.join(projectRoot, \"themes\"),\n path.join(projectRoot, \"silica.config.ts\"),\n ];\n}\n\nexport function watchContent({\n projectRoot,\n port = 3000,\n onConfigChange,\n}: WatchOptions) {\n const watcher = watch(resolveWatchPaths(projectRoot), {\n ignoreInitial: true,\n });\n\n let pending: Promise<void> | undefined;\n watcher.on(\"all\", (_event, filePath) => {\n pending ??= Promise.resolve()\n .then(async () => {\n if (requiresRestart(filePath, projectRoot)) {\n await onConfigChange?.();\n return;\n }\n await precompute({ projectRoot });\n const response = await fetch(\n `http://localhost:${port}/api/silica/revalidate?tag=build`,\n {\n method: \"POST\",\n headers: {\n \"x-silica-revalidate-secret\":\n process.env.SILICA_REVALIDATE_SECRET ?? \"\",\n },\n },\n ).catch(() => undefined);\n if (!response?.ok) {\n const detail = response\n ? `${response.status} ${response.statusText}`\n : \"network error\";\n console.warn(`[silica] revalidate failed (${detail})`);\n }\n console.log(`[silica] rebuilt content after ${filePath}`);\n })\n .finally(() => {\n pending = undefined;\n });\n });\n\n return watcher;\n}\n\nexport function requiresRestart(\n filePath: string,\n projectRoot?: string,\n): boolean {\n const normalized =\n path.isAbsolute(filePath) && projectRoot\n ? path.relative(projectRoot, filePath).replace(/\\\\/g, \"/\")\n : filePath.replace(/\\\\/g, \"/\");\n return normalized === \"silica.config.ts\" || normalized.startsWith(\"themes/\");\n}\n\nexport function resolveDevPort(env: NodeJS.ProcessEnv = process.env): number {\n const parsed = Number(env.PORT);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : 3000;\n}\n"],"mappings":"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","names":["precompute","path","fs","loadConfig","path","fs","path","fs","path","precompute"]}