@riebeckite/honox 0.0.11 → 0.0.13

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/index.js CHANGED
@@ -132,10 +132,7 @@ async function loadRiebeckiteConfig(options) {
132
132
  banner: {
133
133
  js: 'import { createRequire as __riebeckiteCreateRequire } from "node:module"; const require = __riebeckiteCreateRequire(import.meta.url);'
134
134
  },
135
- plugins: [
136
- externalizeBareModuleImports(),
137
- ...options.workspaceRoot ? [workspacePackageResolver(options.workspaceRoot)] : []
138
- ]
135
+ plugins: options.workspaceRoot ? [workspacePackageResolver(options.workspaceRoot)] : []
139
136
  });
140
137
  const module = await import(`${pathToFileUrl(outputFile)}?t=${Date.now()}`);
141
138
  return module.default;
@@ -153,17 +150,6 @@ function resolveHonoxConfig(config, appRoot) {
153
150
  }
154
151
  };
155
152
  }
156
- function externalizeBareModuleImports() {
157
- return {
158
- name: "externalize-bare-module-imports",
159
- setup(buildApi) {
160
- buildApi.onResolve({ filter: /^[^./]|^\.[^./]|^\.\.$/ }, (args) => {
161
- if (path2.isAbsolute(args.path)) return null;
162
- return { path: args.path, external: true };
163
- });
164
- }
165
- };
166
- }
167
153
  function pathToFileUrl(filePath) {
168
154
  return `file:///${filePath.replace(/\\/g, "/").replace(/^([A-Za-z]):/, "$1:")}`;
169
155
  }
@@ -269,9 +255,148 @@ function isJavaScriptModule(filePath) {
269
255
  }
270
256
 
271
257
  // src/scaffold/index.ts
272
- import fs6 from "node:fs/promises";
258
+ import fs7 from "node:fs/promises";
273
259
  import path7 from "node:path";
274
260
 
261
+ // src/scaffold/deployment.ts
262
+ var GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
263
+ function assertGitHubRepository(value, option) {
264
+ if (!GITHUB_REPOSITORY_PATTERN.test(value)) {
265
+ throw new Error(
266
+ `${option} must be a GitHub repository in owner/repository form.`
267
+ );
268
+ }
269
+ }
270
+ function deploymentTemplateFiles(options) {
271
+ const contentRepository = options.contentRepository;
272
+ if (contentRepository !== void 0) {
273
+ assertGitHubRepository(contentRepository, "contentRepository");
274
+ }
275
+ if (options.siteRepository !== void 0) {
276
+ assertGitHubRepository(options.siteRepository, "siteRepository");
277
+ }
278
+ if (contentRepository !== void 0 && options.siteRepository === void 0) {
279
+ throw new Error(
280
+ "siteRepository is required when contentRepository is provided."
281
+ );
282
+ }
283
+ return [
284
+ { path: "wrangler.jsonc", content: wranglerConfig() },
285
+ {
286
+ path: ".github/workflows/deploy.yml",
287
+ content: deployWorkflow(contentRepository)
288
+ },
289
+ ...contentRepository !== void 0 && options.siteRepository !== void 0 ? [
290
+ {
291
+ path: "github/notify-site.yml",
292
+ content: notifySiteWorkflow(options.siteRepository)
293
+ }
294
+ ] : []
295
+ ];
296
+ }
297
+ function wranglerConfig() {
298
+ return `${JSON.stringify(
299
+ {
300
+ name: "riebeckite-site",
301
+ compatibility_date: "2026-03-10",
302
+ compatibility_flags: ["nodejs_compat"],
303
+ assets: { directory: "./dist" }
304
+ },
305
+ null,
306
+ 2
307
+ )}
308
+ `;
309
+ }
310
+ function deployWorkflow(contentRepository) {
311
+ const contentCheckout = contentRepository === void 0 ? "" : `
312
+ - name: Check out the external content repository
313
+ uses: actions/checkout@v4
314
+ with:
315
+ repository: ${contentRepository}
316
+ token: \${{ secrets.RIEBECKITE_CONTENT_READ_TOKEN || github.token }}
317
+ path: content
318
+ `;
319
+ return `name: Deploy to Cloudflare Workers
320
+
321
+ on:
322
+ push:
323
+ branches: [main]
324
+ workflow_dispatch:
325
+ repository_dispatch:
326
+ types: [content-updated]
327
+
328
+ concurrency:
329
+ group: riebeckite-deploy
330
+ cancel-in-progress: true
331
+
332
+ jobs:
333
+ deploy:
334
+ runs-on: ubuntu-latest
335
+ permissions:
336
+ contents: read
337
+ steps:
338
+ - name: Check out the site repository
339
+ uses: actions/checkout@v4
340
+ ${contentCheckout}
341
+ - name: Set up Node.js
342
+ uses: actions/setup-node@v4
343
+ with:
344
+ node-version: 22
345
+ cache: npm
346
+
347
+ - name: Install dependencies
348
+ run: npm ci
349
+
350
+ - name: Validate configuration and plugins
351
+ run: npm exec riebeckite check
352
+
353
+ - name: Build the site
354
+ run: npm exec riebeckite build
355
+
356
+ - name: Deploy the built assets
357
+ uses: cloudflare/wrangler-action@v3
358
+ with:
359
+ apiToken: \${{ secrets.CLOUDFLARE_API_TOKEN }}
360
+ accountId: \${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
361
+ command: deploy
362
+ `;
363
+ }
364
+ function notifySiteWorkflow(siteRepository) {
365
+ const [owner, repo] = siteRepository.split("/");
366
+ return `name: Notify Riebeckite site
367
+
368
+ on:
369
+ push:
370
+ branches: [main]
371
+
372
+ permissions: {}
373
+
374
+ jobs:
375
+ notify:
376
+ runs-on: ubuntu-latest
377
+ steps:
378
+ - name: Validate dispatch configuration
379
+ env:
380
+ SITE_DISPATCH_TOKEN: \${{ secrets.SITE_DISPATCH_TOKEN }}
381
+ run: |
382
+ if [ -z "$SITE_DISPATCH_TOKEN" ]; then
383
+ echo "::error::SITE_DISPATCH_TOKEN is not configured. Add a token that can dispatch to ${siteRepository}."
384
+ exit 1
385
+ fi
386
+
387
+ - name: Notify the site repository
388
+ uses: actions/github-script@v7
389
+ with:
390
+ github-token: \${{ secrets.SITE_DISPATCH_TOKEN }}
391
+ script: |
392
+ await github.rest.repos.createDispatchEvent({
393
+ owner: ${JSON.stringify(owner)},
394
+ repo: ${JSON.stringify(repo)},
395
+ event_type: "content-updated",
396
+ });
397
+ `;
398
+ }
399
+
275
400
  // src/scaffold/presets.ts
276
401
  var SCAFFOLD_LANGUAGES = [
277
402
  "en",
@@ -293,13 +418,10 @@ function defaultLanguageForLocale(locale) {
293
418
  return "en";
294
419
  }
295
420
  var SCAFFOLD_PRESET_NAMES = [
296
- "empty",
297
- "minimal",
298
421
  "starter",
299
- "rich",
300
- "full",
301
- "max",
302
- "ultra"
422
+ "minimal",
423
+ "showcase",
424
+ "empty"
303
425
  ];
304
426
  function isScaffoldPresetName(value) {
305
427
  return SCAFFOLD_PRESET_NAMES.includes(value);
@@ -684,38 +806,9 @@ var minimal = {
684
806
  };
685
807
  var starter = {
686
808
  name: "starter",
687
- description: "The default starter: Obsidian Markdown, color mode, seven languages, and a site header.",
809
+ description: "Recommended for most sites: a practical Markdown garden with search, discovery, and reading essentials.",
688
810
  languages: [...SCAFFOLD_LANGUAGES],
689
811
  theme: defaultTheme,
690
- plugins: [obsidianMarkdown, colorMode, l10n],
691
- contentPages: ["index"],
692
- appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
693
- readme: "standard"
694
- };
695
- var rich = {
696
- name: "rich",
697
- description: "A showcasing starter: publishing and reading plugins plus guided ecosystem tour pages in seven languages.",
698
- languages: [...SCAFFOLD_LANGUAGES],
699
- theme: showCaseTheme,
700
- plugins: [
701
- obsidianMarkdown,
702
- colorMode,
703
- l10n,
704
- seo,
705
- toc,
706
- properties,
707
- alias,
708
- codeEnhance
709
- ],
710
- contentPages: ["index", "framework/plugins", "framework/themes"],
711
- appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
712
- readme: "rich"
713
- };
714
- var full = {
715
- name: "full",
716
- description: "A ready blog: discovery, media, and reading plugins plus a build guide.",
717
- languages: [...SCAFFOLD_LANGUAGES],
718
- theme: showCaseTheme,
719
812
  plugins: [
720
813
  obsidianMarkdown,
721
814
  colorMode,
@@ -728,102 +821,19 @@ var full = {
728
821
  search,
729
822
  backlinks,
730
823
  relatedPosts,
731
- share,
732
- changelog,
733
- webmention,
734
824
  recentPosts,
735
- attachment,
736
- pdf,
737
- media,
738
825
  responsiveImage,
739
826
  lightbox,
740
- highlight,
741
- codeTabs,
742
- codeAnnotations,
743
- shortcodes,
744
827
  series,
745
- taxonomy,
746
- autoCardLink,
747
- richEmbed,
748
- gallery
828
+ taxonomy
749
829
  ],
750
- contentPages: ["index", "framework/plugins", "framework/themes", "guide"],
830
+ contentPages: ["index", "guide", "examples"],
751
831
  appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
752
- readme: "rich"
753
- };
754
- var max = {
755
- name: "max",
756
- description: "Diagram and knowledge plugins on top of full, with showcase example pages.",
757
- languages: [...SCAFFOLD_LANGUAGES],
758
- theme: showCaseTheme,
759
- plugins: [
760
- obsidianMarkdown,
761
- colorMode,
762
- l10n,
763
- seo,
764
- toc,
765
- properties,
766
- alias,
767
- codeEnhance,
768
- search,
769
- backlinks,
770
- relatedPosts,
771
- share,
772
- changelog,
773
- webmention,
774
- recentPosts,
775
- attachment,
776
- pdf,
777
- media,
778
- responsiveImage,
779
- lightbox,
780
- highlight,
781
- codeTabs,
782
- codeAnnotations,
783
- shortcodes,
784
- series,
785
- taxonomy,
786
- autoCardLink,
787
- richEmbed,
788
- gallery,
789
- mermaid,
790
- graphviz,
791
- d2,
792
- plantuml,
793
- chartjs,
794
- vegaLite,
795
- wavedrom,
796
- markmap,
797
- map,
798
- marp,
799
- qrCode,
800
- discordEmbed,
801
- excalidraw,
802
- excaliBrain,
803
- canvas,
804
- bases,
805
- dataview,
806
- flashcards,
807
- kanban,
808
- query,
809
- localGraph,
810
- hoverPreview,
811
- gardenExplorer,
812
- ux
813
- ],
814
- contentPages: [
815
- "index",
816
- "framework/plugins",
817
- "framework/themes",
818
- "guide",
819
- "examples"
820
- ],
821
- appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
822
- readme: "rich"
832
+ readme: "standard"
823
833
  };
824
- var ultra = {
825
- name: "ultra",
826
- description: "The full plugin catalog and theme reference pages — everything the ecosystem offers.",
834
+ var showcase = {
835
+ name: "showcase",
836
+ description: "Explore the complete Riebeckite ecosystem with rendered examples, reference pages, and local fixtures.",
827
837
  languages: [...SCAFFOLD_LANGUAGES],
828
838
  theme: showCaseTheme,
829
839
  plugins: [
@@ -899,7 +909,7 @@ var ultra = {
899
909
  appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
900
910
  readme: "rich"
901
911
  };
902
- var scaffoldPresets = { empty, minimal, starter, rich, full, max, ultra };
912
+ var scaffoldPresets = { starter, minimal, showcase, empty };
903
913
  var SCAFFOLD_DEFAULT_PRESET = "starter";
904
914
  function resolveScaffoldPreset(value) {
905
915
  if (value === void 0) return scaffoldPresets[SCAFFOLD_DEFAULT_PRESET];
@@ -913,6 +923,9 @@ function resolveScaffoldPreset(value) {
913
923
  return preset;
914
924
  }
915
925
 
926
+ // src/scaffold/templates.ts
927
+ import fs6 from "node:fs";
928
+
916
929
  // src/vite_plugin.ts
917
930
  import path6 from "node:path";
918
931
 
@@ -996,12 +1009,28 @@ function createClientModule(config) {
996
1009
  `import ${importTarget} from ${JSON.stringify(entry.moduleSpecifier)};`
997
1010
  );
998
1011
  const publicConfig = entry.publicConfig;
1012
+ const initializer = publicConfig === void 0 ? `${localName}()` : `${localName}(${serializePublicClientConfig(publicConfig)})`;
999
1013
  initializers.push(
1000
- publicConfig === void 0 ? `${localName}()` : `${localName}(${serializePublicClientConfig(publicConfig)})`
1014
+ `runPluginClientInitializer(${JSON.stringify(entry.moduleSpecifier)}, () => ${initializer})`
1001
1015
  );
1002
1016
  }
1003
1017
  return `${imports.join("\n")}
1004
1018
 
1019
+ function runPluginClientInitializer(name, initialize) {
1020
+ try {
1021
+ const result = initialize();
1022
+ if (result && typeof result.then === "function") {
1023
+ result.catch((error) => reportPluginClientError(name, error));
1024
+ }
1025
+ } catch (error) {
1026
+ reportPluginClientError(name, error);
1027
+ }
1028
+ }
1029
+
1030
+ function reportPluginClientError(name, error) {
1031
+ console.error("[riebeckite] Plugin client initializer failed: " + name, error);
1032
+ }
1033
+
1005
1034
  export function initRiebeckiteClient() {
1006
1035
  ${initializers.map((initializer) => ` ${initializer};`).join("\n")}
1007
1036
  }
@@ -1479,10 +1508,19 @@ function style(preset) {
1479
1508
  "}",
1480
1509
  "",
1481
1510
  ".site-header__home {",
1511
+ " display: inline-flex;",
1512
+ " align-items: center;",
1513
+ " gap: 0.5rem;",
1482
1514
  " color: #111827;",
1483
1515
  " font-weight: 700;",
1484
1516
  " text-decoration: none;",
1485
1517
  "}",
1518
+ "",
1519
+ ".site-header__logo {",
1520
+ " width: 1.75rem;",
1521
+ " height: 1.75rem;",
1522
+ " object-fit: contain;",
1523
+ "}",
1486
1524
  ""
1487
1525
  );
1488
1526
  }
@@ -1517,6 +1555,13 @@ export function SiteHeader() {
1517
1555
  return (
1518
1556
  <header class="site-header">
1519
1557
  <a href="/" class="site-header__home">
1558
+ <img
1559
+ src="/riebeckite-logo.png"
1560
+ alt=""
1561
+ class="site-header__logo"
1562
+ width="28"
1563
+ height="28"
1564
+ />
1520
1565
  {config.site.title}
1521
1566
  </a>
1522
1567
  <ColorModeToggle />
@@ -1579,6 +1624,10 @@ function themeAttributes() {
1579
1624
  };
1580
1625
  }
1581
1626
 
1627
+ // Riebeckite plugin client entries need the HonoX client bundle even without
1628
+ // an island component.
1629
+ export const __importing_islands = true;
1630
+
1582
1631
  export default jsxRenderer(({ children }, c) => {
1583
1632
  const headTags: readonly PluginHeadTag[] = c.get("headTags") ?? [];
1584
1633
 
@@ -1591,6 +1640,7 @@ export default jsxRenderer(({ children }, c) => {
1591
1640
  <meta charset="utf-8" />
1592
1641
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
1593
1642
  <title>{config.site.title}</title>
1643
+ <link rel="icon" href="/favicon.ico" />
1594
1644
  ${hasColorMode ? ` <ColorModeScript />
1595
1645
  ` : ""} <Link href="/app/style.css" rel="stylesheet" />
1596
1646
  {headTags.map(renderHeadTag)}
@@ -1625,12 +1675,17 @@ function bareRenderer() {
1625
1675
  import { Link, Script } from "honox/server";
1626
1676
  import { config } from "../config";
1627
1677
 
1678
+ // Riebeckite plugin client entries need the HonoX client bundle even without
1679
+ // an island component.
1680
+ export const __importing_islands = true;
1681
+
1628
1682
  export default jsxRenderer(({ children }, c) => (
1629
1683
  <html lang={c.get("htmlLanguage") ?? config.site.locale}>
1630
1684
  <head>
1631
1685
  <meta charset="utf-8" />
1632
1686
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
1633
1687
  <title>{config.site.title}</title>
1688
+ <link rel="icon" href="/favicon.ico" />
1634
1689
  <Link href="/app/style.css" rel="stylesheet" />
1635
1690
  <Script src="/app/client.ts" async />
1636
1691
  </head>
@@ -1691,7 +1746,8 @@ function slugRoute() {
1691
1746
  return `import { isPublished } from "@riebeckite/core";
1692
1747
  import {
1693
1748
  contentRouteSsgParams,
1694
- resolveContentRoute,
1749
+ pluginPageSsgParams,
1750
+ resolveRiebeckiteRoute,
1695
1751
  } from "@riebeckite/honox/server";
1696
1752
  import { createRoute } from "honox/factory";
1697
1753
  import { SiteArticle } from "../components/article";
@@ -1701,21 +1757,27 @@ import { content } from "../content";
1701
1757
  export default createRoute(
1702
1758
  contentRouteSsgParams("/:slug{.+}", async () => {
1703
1759
  const manifest = await content.getManifest();
1704
- return manifest.entries
1760
+ const contentPaths = manifest.entries
1705
1761
  .filter((entry) => isPublished(config, entry.frontmatter))
1706
1762
  .filter((entry) => entry.permalink !== "/")
1707
1763
  .map((entry) => ({ slug: entry.permalink.replace(/^\\/+/, "") }));
1764
+ return [...contentPaths, ...(await pluginPageSsgParams(content))];
1708
1765
  }),
1709
1766
  async (c) => {
1710
1767
  const requestedSlug = c.req.param("slug");
1711
1768
  if (!requestedSlug) return c.notFound();
1712
1769
  if (/\\.[a-zA-Z0-9]+$/.test(requestedSlug)) return c.notFound();
1713
1770
 
1714
- const manifest = await content.getManifest();
1715
- const route = resolveContentRoute(manifest, c.req.path);
1771
+ const route = await resolveRiebeckiteRoute(content, c.req.path);
1716
1772
  if (!route) return c.notFound();
1717
1773
  if (route.kind === "redirect")
1718
1774
  return c.redirect(route.location, route.status);
1775
+ if (route.kind === "page") {
1776
+ c.set("headTags", route.page.headTags ?? []);
1777
+ return c.render(
1778
+ <div dangerouslySetInnerHTML={{ __html: route.page.body }} />,
1779
+ );
1780
+ }
1719
1781
 
1720
1782
  const post = await content.getProcessedContent(route.entry.slug);
1721
1783
  if (!isPublished(config, post.frontmatter)) {
@@ -2004,7 +2066,7 @@ var PLUGIN_MARKDOWN_GUIDES = {
2004
2066
  "---",
2005
2067
  "",
2006
2068
  "```daily-snippet",
2007
- "Fixed the ultra preset examples.",
2069
+ "Updated the showcase examples.",
2008
2070
  "```"
2009
2071
  ].join("\n")
2010
2072
  },
@@ -2083,7 +2145,10 @@ function localizedContentFiles(variables, preset) {
2083
2145
  };
2084
2146
  for (const page of preset.contentPages) {
2085
2147
  if (page === "index") {
2086
- pushLocalized("index", (language) => indexContent(variables, language));
2148
+ pushLocalized(
2149
+ "index",
2150
+ (language) => indexContent(variables, preset, language)
2151
+ );
2087
2152
  } else if (page === "framework/plugins") {
2088
2153
  pushLocalized(
2089
2154
  "framework/plugins",
@@ -2110,6 +2175,12 @@ function localizedContentFiles(variables, preset) {
2110
2175
  pushEnglishOnly("reference/themes", () => referenceThemesContent(preset));
2111
2176
  }
2112
2177
  }
2178
+ if (preset.name === "starter" || preset.name === "showcase") {
2179
+ files.push(...knowledgeFixtureFiles(preset));
2180
+ }
2181
+ if (preset.name === "showcase") {
2182
+ files.push(...showcaseAssetFiles());
2183
+ }
2113
2184
  return files;
2114
2185
  }
2115
2186
  function read(text, language) {
@@ -2127,6 +2198,72 @@ ${code}
2127
2198
  \`\`\`
2128
2199
  `;
2129
2200
  }
2201
+ function knowledgeFixtureFiles(preset) {
2202
+ const prefix = preset.name === "showcase" ? "demo" : "notes";
2203
+ return [
2204
+ {
2205
+ path: `content/${prefix}/planning.md`,
2206
+ content: [
2207
+ "---",
2208
+ "title: Planning a Markdown site",
2209
+ "description: A related note used by the generated discovery examples.",
2210
+ "date: 2026-09-30",
2211
+ "tags: [riebeckite, project]",
2212
+ "status: active",
2213
+ "aliases: [/start-here/]",
2214
+ "series: publish-a-site",
2215
+ "series_title: Publish a site",
2216
+ "series_order: 1",
2217
+ "publish: true",
2218
+ "---",
2219
+ "",
2220
+ "# Planning a Markdown site",
2221
+ "",
2222
+ "Start with [[writing]] to see backlinks, related posts, tags, and the series navigation working together."
2223
+ ].join("\n")
2224
+ },
2225
+ {
2226
+ path: `content/${prefix}/writing.md`,
2227
+ content: [
2228
+ "---",
2229
+ "title: Writing the first note",
2230
+ "description: A second connected note for search and related-content examples.",
2231
+ "date: 2026-10-01",
2232
+ "tags: [riebeckite, project]",
2233
+ "status: active",
2234
+ "series: publish-a-site",
2235
+ "series_title: Publish a site",
2236
+ "series_order: 2",
2237
+ "publish: true",
2238
+ "---",
2239
+ "",
2240
+ "# Writing the first note",
2241
+ "",
2242
+ "This note links back to [[planning]]. Search for **Markdown site** or browse the generated tags."
2243
+ ].join("\n")
2244
+ }
2245
+ ];
2246
+ }
2247
+ function showcaseAssetFiles() {
2248
+ return [
2249
+ {
2250
+ path: "content/images/demo.svg",
2251
+ content: '<svg xmlns="http://www.w3.org/2000/svg" width="640" height="360" viewBox="0 0 640 360"><rect width="640" height="360" fill="#315b8c"/><text x="320" y="180" fill="white" font-size="32" text-anchor="middle">Riebeckite showcase</text></svg>\n'
2252
+ },
2253
+ {
2254
+ path: "content/attachments/project-brief.pdf",
2255
+ content: "%PDF-1.1\n1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj\n2 0 obj<</Type/Pages/Count 0/Kids[]>>endobj\ntrailer<</Root 1 0 R>>\n%%EOF\n"
2256
+ },
2257
+ {
2258
+ path: "content/drawings/Architecture.excalidraw",
2259
+ content: '{"type":"excalidraw","version":2,"elements":[],"appState":{"viewBackgroundColor":"#ffffff"},"files":{}}\n'
2260
+ },
2261
+ {
2262
+ path: "content/drawings/site.canvas",
2263
+ content: '{"nodes":[{"id":"note","type":"text","text":"Note","x":0,"y":0,"width":200,"height":60}],"edges":[]}\n'
2264
+ }
2265
+ ];
2266
+ }
2130
2267
  var INDEX = {
2131
2268
  lead: {
2132
2269
  en: "Welcome to your Riebeckite site.",
@@ -2219,7 +2356,7 @@ var INDEX = {
2219
2356
  ko: "번역 페이지는 기본 파일 옆에 `<base>.<lang>.md` 규칙으로 둡니다(예: `about.ja.md`). l10n 플러그인이 `/lang/` 경로로 서빙하며 자동으로 링크합니다."
2220
2357
  }
2221
2358
  };
2222
- function indexContent(variables, language) {
2359
+ function indexContent(variables, preset, language) {
2223
2360
  const title = variables.title;
2224
2361
  return [
2225
2362
  frontmatter(),
@@ -2228,9 +2365,17 @@ function indexContent(variables, language) {
2228
2365
  read(INDEX.translatedNote, language),
2229
2366
  heading(2, read(INDEX.whatHeading, language)),
2230
2367
  read(INDEX.whatBody, language),
2231
- heading(2, read(INDEX.exploreHeading, language)),
2232
- `- [${read(INDEX.explorePlugins, language)}](/framework/plugins)`,
2233
- `- [${read(INDEX.exploreThemes, language)}](/framework/themes)`,
2368
+ ...preset.name === "showcase" ? [
2369
+ heading(2, read(INDEX.exploreHeading, language)),
2370
+ `- [${read(INDEX.explorePlugins, language)}](/framework/plugins)`,
2371
+ `- [${read(INDEX.exploreThemes, language)}](/framework/themes)`,
2372
+ "- [Working examples](/examples/)",
2373
+ "- [Plugin reference](/reference/plugins/)"
2374
+ ] : preset.name === "starter" ? [
2375
+ heading(2, read(INDEX.exploreHeading, language)),
2376
+ "- [Getting started](/guide/)",
2377
+ "- [Example notes](/examples/)"
2378
+ ] : [],
2234
2379
  heading(2, read(INDEX.editHeading, language)),
2235
2380
  read(INDEX.editLead, language),
2236
2381
  read(INDEX.editL10n, language),
@@ -3098,10 +3243,16 @@ var EXAMPLES_COPY = {
3098
3243
  ja: "サンプル集"
3099
3244
  },
3100
3245
  intro: {
3101
- en: "A working demo of every diagram, chart, and code feature this preset ships. Fenced code blocks are turned into rendered output at build time by the diagram plugins; code blocks gain toolbars from the code plugins. Each section below is also copy-pasteable into any Markdown document.",
3102
- ja: "このプリセットが含む、すべての図表・チャート・コード機能の実例です。フェンス付きコードブロックはビルド時に図表プラグインが描画し、コードブロックにはコードプラグインがツールバーを追加します。以下の各セクションは、任意の Markdown 文書にそのままコピーして使えます。"
3246
+ en: "Rendered examples for the diagram, chart, and code features in this preset. Fenced code blocks are turned into output at build time by the relevant plugins, while code blocks gain toolbars from the code plugins. Each section below is copy-pasteable into a Markdown document.",
3247
+ ja: "このプリセットに含まれる図表・チャート・コード機能の描画例です。フェンス付きコードブロックは対応するプラグインによりビルド時に出力へ変換され、コードブロックにはツールバーが付きます。以下の各セクションは、Markdown 文書にそのままコピーして使えます。"
3103
3248
  }
3104
3249
  };
3250
+ var SHOWCASE_GUIDE_DEMOS = [
3251
+ "@riebeckite/plugin-plantuml",
3252
+ "@riebeckite/plugin-excalidraw",
3253
+ "@riebeckite/plugin-canvas",
3254
+ "@riebeckite/plugin-flashcards"
3255
+ ];
3105
3256
  function examplesContent(preset, language) {
3106
3257
  const lines = [
3107
3258
  frontmatter(),
@@ -3118,6 +3269,19 @@ function examplesContent(preset, language) {
3118
3269
  lines.push(readSummary(demo.intro, language), "");
3119
3270
  lines.push(demo.markdown, "");
3120
3271
  }
3272
+ if (preset.name === "showcase") {
3273
+ for (const packageName of SHOWCASE_GUIDE_DEMOS) {
3274
+ if (!hasPlugin(preset, packageName)) continue;
3275
+ const guide = PLUGIN_MARKDOWN_GUIDES[packageName];
3276
+ if (!guide) continue;
3277
+ lines.push(
3278
+ heading(2, packageName.replace("@riebeckite/plugin-", "")),
3279
+ ""
3280
+ );
3281
+ lines.push(guide.summary, "");
3282
+ lines.push(guide.markdown, "");
3283
+ }
3284
+ }
3121
3285
  return lines.join("\n");
3122
3286
  }
3123
3287
  function referencePluginsContent(preset, variables) {
@@ -3209,7 +3373,7 @@ function referenceThemesContent(preset) {
3209
3373
  }
3210
3374
 
3211
3375
  // src/scaffold/version.ts
3212
- var RIEBECKITE_VERSION = "^0.0.11";
3376
+ var RIEBECKITE_VERSION = "^0.0.13";
3213
3377
 
3214
3378
  // src/scaffold/templates.ts
3215
3379
  function siteTemplateFiles(preset, variables) {
@@ -3223,10 +3387,26 @@ function siteTemplateFiles(preset, variables) {
3223
3387
  { path: "tsconfig.json", content: tsconfig() },
3224
3388
  { path: ".gitignore", content: gitignore() },
3225
3389
  { path: "README.md", content: readme(preset, variables) },
3390
+ { path: "public/favicon.ico", content: readPackageAsset("favicon.ico") },
3391
+ {
3392
+ path: "public/riebeckite-logo.png",
3393
+ content: readPackageAsset("riebeckite-logo.png")
3394
+ },
3226
3395
  ...localizedContentFiles(variables, preset),
3227
3396
  ...appFiles(preset)
3228
3397
  ];
3229
3398
  }
3399
+ function readPackageAsset(fileName) {
3400
+ const candidates = [
3401
+ new URL(`../../assets/${fileName}`, import.meta.url),
3402
+ new URL(`../../../assets/${fileName}`, import.meta.url),
3403
+ new URL(`../assets/${fileName}`, import.meta.url)
3404
+ ];
3405
+ for (const candidate of candidates) {
3406
+ if (fs6.existsSync(candidate)) return fs6.readFileSync(candidate);
3407
+ }
3408
+ throw new Error(`Missing Riebeckite scaffold asset: ${fileName}`);
3409
+ }
3230
3410
  var APP_FILE_LABELS = [
3231
3411
  "server",
3232
3412
  "client",
@@ -3359,11 +3539,8 @@ function riebeckiteConfig(preset, variables) {
3359
3539
  var OPTION_DEPTH = {
3360
3540
  empty: 0,
3361
3541
  minimal: 0,
3362
- starter: 0,
3363
- rich: 1,
3364
- full: 2,
3365
- max: 2,
3366
- ultra: 3
3542
+ starter: 2,
3543
+ showcase: 3
3367
3544
  };
3368
3545
  function optionContext(preset, variables) {
3369
3546
  return {
@@ -3480,24 +3657,12 @@ var README_INTRO = {
3480
3657
  ja: "最小限で実用的な Riebeckite サイトです。Obsidian マークダウン・minimal テーマ・1 ページ構成。"
3481
3658
  },
3482
3659
  starter: {
3483
- en: "The default Riebeckite starter: Obsidian Markdown, a color-mode toggle, and seven languages.",
3484
- ja: "Riebeckite の既定スターターです。Obsidian マークダウン・カラーモード切替・7 言語対応。"
3485
- },
3486
- rich: {
3487
- en: "A showcasing starter: publishing and reading plugins plus guided ecosystem tour pages in seven languages.",
3488
- ja: "紹介を目的としたスターターです。公開・読書体験のプラグインと、7 言語のエコシステム紹介ページ付き。"
3489
- },
3490
- full: {
3491
- en: "A ready-to-use blog preset: discovery, media, and reading plugins plus a getting-started guide.",
3492
- ja: "そのまま使えるブログ向けプリセットです。検索・メディア・読書体験のプラグインと入門ガイド付き。"
3660
+ en: "Recommended for most sites: a practical Markdown garden with search, discovery, and reading essentials.",
3661
+ ja: "大半のサイトにおすすめの構成です。検索・発見・閲覧に必要な機能を備えた実用的な Markdown サイトを作れます。"
3493
3662
  },
3494
- max: {
3495
- en: "Diagram, chart, and knowledge plugins on top of full, with showcase example pages.",
3496
- ja: "full に図解・チャート・ナレッジ系プラグインを加えた構成で、お試し用サンプルページ付き。"
3497
- },
3498
- ultra: {
3499
- en: "The complete plugin catalog with plugin and theme reference pages.",
3500
- ja: "全プラグインを有効化した最上位構成。プラグイン/テーマのリファレンスページ付き。"
3663
+ showcase: {
3664
+ en: "Explore the complete Riebeckite ecosystem with rendered examples, reference pages, and local fixtures.",
3665
+ ja: "描画例・リファレンスページ・ローカルのフィクスチャで、Riebeckite のエコシステム全体を確認できる構成です。"
3501
3666
  }
3502
3667
  };
3503
3668
  var README_WORDS = {
@@ -4100,10 +4265,11 @@ var ScaffoldSiteError = class extends Error {
4100
4265
  async function scaffoldRiebeckiteSite(options) {
4101
4266
  const targetDirectory = path7.resolve(options.targetDirectory);
4102
4267
  const preset = resolveScaffoldPreset(options.preset);
4103
- const files = siteTemplateFiles(
4104
- preset,
4105
- templateVariables(options, targetDirectory)
4106
- );
4268
+ validateDeploymentOptions(options);
4269
+ const files = [
4270
+ ...siteTemplateFiles(preset, templateVariables(options, targetDirectory)),
4271
+ ...options.githubActions ? deploymentTemplateFiles(deploymentOptions(options)) : []
4272
+ ];
4107
4273
  await assertTargetWritable(
4108
4274
  targetDirectory,
4109
4275
  files,
@@ -4111,11 +4277,41 @@ async function scaffoldRiebeckiteSite(options) {
4111
4277
  );
4112
4278
  for (const file of files) {
4113
4279
  const filePath = path7.join(targetDirectory, file.path);
4114
- await fs6.mkdir(path7.dirname(filePath), { recursive: true });
4115
- await fs6.writeFile(filePath, file.content, "utf8");
4280
+ await fs7.mkdir(path7.dirname(filePath), { recursive: true });
4281
+ await fs7.writeFile(filePath, file.content);
4116
4282
  }
4117
4283
  return { targetDirectory, files: files.map((file) => file.path) };
4118
4284
  }
4285
+ function deploymentOptions(options) {
4286
+ return {
4287
+ contentRepository: options.contentRepository,
4288
+ siteRepository: options.siteRepository
4289
+ };
4290
+ }
4291
+ function validateDeploymentOptions(options) {
4292
+ try {
4293
+ if (options.contentRepository !== void 0) {
4294
+ assertGitHubRepository(options.contentRepository, "contentRepository");
4295
+ }
4296
+ if (options.siteRepository !== void 0) {
4297
+ assertGitHubRepository(options.siteRepository, "siteRepository");
4298
+ }
4299
+ } catch (error) {
4300
+ throw new ScaffoldSiteError(
4301
+ error instanceof Error ? error.message : String(error)
4302
+ );
4303
+ }
4304
+ if (options.contentRepository !== void 0 && !options.githubActions) {
4305
+ throw new ScaffoldSiteError(
4306
+ "--content-repository requires --github-actions."
4307
+ );
4308
+ }
4309
+ if (options.contentRepository !== void 0 && options.siteRepository === void 0) {
4310
+ throw new ScaffoldSiteError(
4311
+ "--site-repository is required when --content-repository is used with --github-actions."
4312
+ );
4313
+ }
4314
+ }
4119
4315
  function templateVariables(options, targetDirectory) {
4120
4316
  const name = normalizePackageName(
4121
4317
  options.name ?? path7.basename(targetDirectory)
@@ -4131,7 +4327,7 @@ function templateVariables(options, targetDirectory) {
4131
4327
  async function assertTargetWritable(targetDirectory, files, overwrite) {
4132
4328
  let entries;
4133
4329
  try {
4134
- entries = await fs6.readdir(targetDirectory);
4330
+ entries = await fs7.readdir(targetDirectory);
4135
4331
  } catch (error) {
4136
4332
  if (isNotFoundError2(error)) return;
4137
4333
  throw error;
@@ -4175,9 +4371,11 @@ export {
4175
4371
  createRiebeckiteSsg,
4176
4372
  defaultSsgEntry,
4177
4373
  defaultSsrExternals,
4374
+ empty,
4178
4375
  formatScaffoldNextSteps,
4179
4376
  isScaffoldPresetName,
4180
4377
  loadRiebeckiteConfig,
4378
+ minimal,
4181
4379
  replaceHonoxIslandDependencyPlugin,
4182
4380
  resolveHonoxApplication,
4183
4381
  resolveHonoxApplicationRoot,
@@ -4189,5 +4387,7 @@ export {
4189
4387
  riebeckiteVite,
4190
4388
  scaffoldPresets,
4191
4389
  scaffoldRiebeckiteSite,
4192
- startHonoxDevServer
4390
+ showcase,
4391
+ startHonoxDevServer,
4392
+ starter
4193
4393
  };