create-riebeckite 0.0.31 → 0.0.33

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.
Files changed (67) hide show
  1. package/dist/src/arguments.d.ts +2 -0
  2. package/dist/src/index.js +380 -44
  3. package/dist/src/interactive.d.ts +7 -5
  4. package/dist/src/package-manager.d.ts +2 -1
  5. package/dist/src/publish.d.ts +2 -1
  6. package/dist/src/scaffold/deployment.d.ts +0 -1
  7. package/dist/src/scaffold/features.d.ts +12 -0
  8. package/dist/src/scaffold/index.d.ts +1 -0
  9. package/dist/src/scaffold/index.js +330 -38
  10. package/dist/src/scaffold/options.d.ts +2 -0
  11. package/dist/src/scaffold/presets.d.ts +9 -5
  12. package/dist/src/scaffold/readme_demos.d.ts +2 -1
  13. package/dist/src/scaffold/template_options.d.ts +1 -6
  14. package/dist/src/scaffold/utilities.d.ts +0 -1
  15. package/dist/src/scaffold/version.d.ts +1 -1
  16. package/dist/src/scaffold/wrangler-defaults.d.ts +0 -1
  17. package/package.json +3 -3
  18. package/templates/scaffold/presets/blog/app/components/article.tsx +33 -0
  19. package/templates/scaffold/presets/blog/app/components/site-header.tsx +37 -0
  20. package/templates/scaffold/presets/blog/app/routes/[slug{.+}].tsx +10 -0
  21. package/templates/scaffold/presets/blog/app/routes/_404.tsx +18 -0
  22. package/templates/scaffold/presets/blog/app/routes/_renderer.tsx +42 -0
  23. package/templates/scaffold/presets/blog/app/routes/index.tsx +10 -0
  24. package/templates/scaffold/presets/blog/app/style.css +152 -0
  25. package/templates/scaffold/presets/blog/content/index.md +8 -0
  26. package/templates/scaffold/presets/blog/content/posts/editing-before-publishing.md +12 -0
  27. package/templates/scaffold/presets/blog/content/posts/writing-a-useful-post.md +12 -0
  28. package/templates/scaffold/presets/digital-garden/app/components/article.tsx +31 -0
  29. package/templates/scaffold/presets/digital-garden/app/components/site-header.tsx +37 -0
  30. package/templates/scaffold/presets/digital-garden/app/routes/[slug{.+}].tsx +10 -0
  31. package/templates/scaffold/presets/digital-garden/app/routes/_404.tsx +18 -0
  32. package/templates/scaffold/presets/digital-garden/app/routes/_renderer.tsx +42 -0
  33. package/templates/scaffold/presets/digital-garden/app/routes/index.tsx +10 -0
  34. package/templates/scaffold/presets/digital-garden/app/style.css +152 -0
  35. package/templates/scaffold/presets/digital-garden/content/index.md +10 -0
  36. package/templates/scaffold/presets/digital-garden/content/notes/how-this-garden-works.md +11 -0
  37. package/templates/scaffold/presets/digital-garden/content/notes/seed-idea.md +9 -0
  38. package/templates/scaffold/presets/docs/app/components/article.tsx +26 -0
  39. package/templates/scaffold/presets/docs/app/components/site-header.tsx +37 -0
  40. package/templates/scaffold/presets/docs/app/routes/[slug{.+}].tsx +10 -0
  41. package/templates/scaffold/presets/docs/app/routes/_404.tsx +18 -0
  42. package/templates/scaffold/presets/docs/app/routes/_renderer.tsx +42 -0
  43. package/templates/scaffold/presets/docs/app/routes/index.tsx +10 -0
  44. package/templates/scaffold/presets/docs/app/style.css +169 -0
  45. package/templates/scaffold/presets/docs/content/docs/configuration.md +8 -0
  46. package/templates/scaffold/presets/docs/content/docs/getting-started.md +15 -0
  47. package/templates/scaffold/presets/docs/content/index.md +7 -0
  48. package/templates/scaffold/presets/empty/app/routes/_404.tsx +2 -2
  49. package/templates/scaffold/presets/empty/app/routes/_renderer.tsx +5 -1
  50. package/templates/scaffold/presets/empty/app/routes/index.tsx +2 -2
  51. package/templates/scaffold/presets/minimal/app/routes/_404.tsx +2 -2
  52. package/templates/scaffold/presets/minimal/app/routes/_renderer.tsx +5 -1
  53. package/templates/scaffold/presets/portfolio/app/components/article.tsx +29 -0
  54. package/templates/scaffold/presets/portfolio/app/components/site-header.tsx +37 -0
  55. package/templates/scaffold/presets/portfolio/app/routes/[slug{.+}].tsx +10 -0
  56. package/templates/scaffold/presets/portfolio/app/routes/_404.tsx +18 -0
  57. package/templates/scaffold/presets/portfolio/app/routes/_renderer.tsx +42 -0
  58. package/templates/scaffold/presets/portfolio/app/routes/index.tsx +10 -0
  59. package/templates/scaffold/presets/portfolio/app/style.css +152 -0
  60. package/templates/scaffold/presets/portfolio/content/about.md +7 -0
  61. package/templates/scaffold/presets/portfolio/content/contact.md +7 -0
  62. package/templates/scaffold/presets/portfolio/content/index.en.md +18 -0
  63. package/templates/scaffold/presets/portfolio/content/projects/field-notes.md +20 -0
  64. package/templates/scaffold/presets/portfolio/content/projects/small-tools.md +10 -0
  65. package/templates/scaffold/presets/showcase/content/deck.md +24 -0
  66. package/templates/scaffold/presets/showcase/content/demo/planning.md +2 -1
  67. package/templates/scaffold/presets/showcase/content/demo/writing.md +4 -1
package/dist/src/index.js CHANGED
@@ -269,6 +269,10 @@ function defaultLanguageForLocale(locale) {
269
269
  }
270
270
  var SCAFFOLD_PRESET_NAMES = [
271
271
  "starter",
272
+ "digital-garden",
273
+ "blog",
274
+ "docs",
275
+ "portfolio",
272
276
  "minimal",
273
277
  "showcase",
274
278
  "empty"
@@ -285,7 +289,7 @@ var obsidianMarkdown = np(
285
289
  "@riebeckite/plugin-obsidian-markdown",
286
290
  "obsidianMarkdown"
287
291
  );
288
- var colorMode = np("@riebeckite/plugin-color-mode", "colorModePlugin");
292
+ var colorMode = np("@riebeckite/plugin-color-mode", "colorMode");
289
293
  var l10n = np("@riebeckite/plugin-l10n", "l10n", (context) => {
290
294
  const defaultLang = defaultLanguageForLocale(context.variables.locale);
291
295
  return `{ defaultLang: ${JSON.stringify(defaultLang)}, languages: ${JSON.stringify(context.languages)} }`;
@@ -295,7 +299,12 @@ var seo = np("@riebeckite/plugin-seo", "seo", {
295
299
  robots: { depth: 2, value: "true" },
296
300
  feed: { depth: 3, value: "{ rss: true, atom: true, json: true }" }
297
301
  });
298
- var toc = np("@riebeckite/plugin-toc", "tocPlugin");
302
+ var blogSeo = np(
303
+ "@riebeckite/plugin-seo",
304
+ "seo",
305
+ `{ sitemap: true, robots: true, feed: { rss: true, atom: true, json: true } }`
306
+ );
307
+ var toc = np("@riebeckite/plugin-toc", "toc");
299
308
  var properties = np("@riebeckite/plugin-properties", "properties", {
300
309
  include: { depth: 2, value: '["created", "modified", "tags", "status"]' },
301
310
  fields: {
@@ -303,7 +312,7 @@ var properties = np("@riebeckite/plugin-properties", "properties", {
303
312
  value: '{ created: { type: "date", format: "yyyy-MM-dd" }, modified: { type: "date", format: "yyyy-MM-dd" }, tags: { type: "tags", variant: "chips" }, status: { type: "badge", variants: { active: "success", draft: "warning", archived: "danger" } } }'
304
313
  }
305
314
  });
306
- var alias = np("@riebeckite/plugin-alias", "aliasPlugin", `{ status: 308 }`);
315
+ var alias = np("@riebeckite/plugin-alias", "alias", `{ status: 308 }`);
307
316
  var codeEnhance = np("@riebeckite/plugin-code-enhance", "codeEnhance", {
308
317
  lineNumbers: { depth: 1, value: "true" },
309
318
  copyButton: { depth: 1, value: "true" },
@@ -313,9 +322,9 @@ var codeEnhance = np("@riebeckite/plugin-code-enhance", "codeEnhance", {
313
322
  theme: { depth: 3, value: '{ light: "github-light", dark: "github-dark" }' },
314
323
  wrapToggle: { depth: 3, value: "true" }
315
324
  });
316
- var search = np("@riebeckite/plugin-search", "searchPlugin");
317
- var backlinks = np("@riebeckite/plugin-backlinks", "backlinksPlugin");
318
- var breadcrumbs = np("@riebeckite/plugin-breadcrumbs", "breadcrumbsPlugin");
325
+ var search = np("@riebeckite/plugin-search", "search");
326
+ var backlinks = np("@riebeckite/plugin-backlinks", "backlinks");
327
+ var breadcrumbs = np("@riebeckite/plugin-breadcrumbs", "breadcrumbs");
319
328
  var navigationStarter = np("@riebeckite/plugin-navigation", "navigation");
320
329
  var navigationShowcase = np(
321
330
  "@riebeckite/plugin-navigation",
@@ -338,7 +347,7 @@ var share = np("@riebeckite/plugin-share", "share", {
338
347
  },
339
348
  mastodonInstance: { depth: 3, value: '"mastodon.social"' }
340
349
  });
341
- var recentPosts = np("@riebeckite/plugin-recent-posts", "recentPostsPlugin");
350
+ var recentPosts = np("@riebeckite/plugin-recent-posts", "recentPosts");
342
351
  var changelog = np("@riebeckite/plugin-changelog", "changelog", {
343
352
  perNote: { depth: 2, value: "true" },
344
353
  lookbackDays: { depth: 3, value: "90" },
@@ -382,7 +391,7 @@ var responsiveImage = np(
382
391
  );
383
392
  var lightbox = np(
384
393
  "@riebeckite/plugin-lightbox",
385
- "lightboxPlugin",
394
+ "lightbox",
386
395
  `{ selectorClass: "rr-lightbox-trigger" }`
387
396
  );
388
397
  var highlight = np("@riebeckite/plugin-highlight", "highlight", {
@@ -418,10 +427,15 @@ var taxonomy = np("@riebeckite/plugin-taxonomy", "taxonomy", {
418
427
  feeds: { depth: 3, value: "{ rss: true, atom: true, json: true }" },
419
428
  relatedLimit: { depth: 3, value: "8" }
420
429
  });
421
- var folderPages = np("@riebeckite/plugin-folder-pages", "folderPagesPlugin");
430
+ var blogTaxonomy = np(
431
+ "@riebeckite/plugin-taxonomy",
432
+ "taxonomy",
433
+ `{ tags: true, folders: true, related: true, feeds: { rss: true, atom: true, json: true } }`
434
+ );
435
+ var folderPages = np("@riebeckite/plugin-folder-pages", "folderPages");
422
436
  var autoCardLink = np(
423
437
  "@riebeckite/plugin-autocardlink",
424
- "autoCardLinkPlugin",
438
+ "autoCardLink",
425
439
  `{ className: "rb-cardlink" }`
426
440
  );
427
441
  var richEmbed = np(
@@ -536,12 +550,12 @@ var bases = np("@riebeckite/plugin-bases", "bases", {
536
550
  className: { depth: 3, value: '"rb-bases"' },
537
551
  showFallback: { depth: 3, value: "true" }
538
552
  });
539
- var dataview = np("@riebeckite/plugin-dataview", "dataviewPlugin", {
553
+ var dataview = np("@riebeckite/plugin-dataview", "dataview", {
540
554
  limit: { depth: 2, value: "50" },
541
555
  className: { depth: 3, value: '"rb-dataview"' },
542
556
  hideFallback: { depth: 3, value: "false" }
543
557
  });
544
- var flashcards = np("@riebeckite/plugin-flashcards", "flashcardsPlugin", {
558
+ var flashcards = np("@riebeckite/plugin-flashcards", "flashcards", {
545
559
  shuffle: { depth: 2, value: "true" },
546
560
  fallback: { depth: 2, value: "true" },
547
561
  className: { depth: 3, value: '"rb-flashcards"' }
@@ -552,56 +566,67 @@ var kanban = np("@riebeckite/plugin-kanban", "kanban", {
552
566
  className: { depth: 3, value: '"rb-kanban"' },
553
567
  fallback: { depth: 3, value: "true" }
554
568
  });
555
- var query = np("@riebeckite/plugin-query", "queryPlugin", {
569
+ var query = np("@riebeckite/plugin-query", "query", {
556
570
  defaultFormat: { depth: 2, value: '"list"' },
557
571
  defaultLimit: { depth: 2, value: "50" },
558
572
  className: { depth: 3, value: '"rb-query"' },
559
573
  excludeSelf: { depth: 3, value: "true" }
560
574
  });
561
- var localGraph = np("@riebeckite/plugin-local-graph", "localGraphPlugin");
562
- var hoverPreview = np(
563
- "@riebeckite/plugin-hover-preview",
564
- "hoverPreviewPlugin",
565
- {
566
- delay: { depth: 2, value: "120" },
567
- excerptLength: { depth: 2, value: "160" },
568
- selector: { depth: 2, value: `'a[href^="/"]'` },
569
- includeTitles: { depth: 3, value: "true" }
570
- }
575
+ var localGraph = np("@riebeckite/plugin-local-graph", "localGraph");
576
+ var docs = np(
577
+ "@riebeckite/plugin-docs",
578
+ "docs",
579
+ `{ root: "docs", sidebar: { auto: true }, prevNext: true }`
571
580
  );
581
+ var readingPlugins = [
582
+ obsidianMarkdown,
583
+ colorMode,
584
+ toc,
585
+ codeEnhance,
586
+ search,
587
+ breadcrumbs,
588
+ navigationStarter
589
+ ];
590
+ var hoverPreview = np("@riebeckite/plugin-hover-preview", "hoverPreview", {
591
+ delay: { depth: 2, value: "120" },
592
+ excerptLength: { depth: 2, value: "160" },
593
+ selector: { depth: 2, value: `'a[href^="/"]'` },
594
+ includeTitles: { depth: 3, value: "true" }
595
+ });
572
596
  var gardenExplorer = np(
573
597
  "@riebeckite/plugin-garden-explorer",
574
- "gardenExplorerPlugin"
598
+ "gardenExplorer"
575
599
  );
576
- var ux = np("@riebeckite/plugin-ux", "uxPlugin", {
600
+ var glossary = np("@riebeckite/plugin-glossary", "glossary");
601
+ var ux = np("@riebeckite/plugin-ux", "ux", {
577
602
  progress: { depth: 2, value: "true" },
578
603
  backToTop: { depth: 2, value: "true" },
579
- tocScrollSpy: { depth: 2, value: "true" },
580
- codeCopy: { depth: 3, value: "true" }
604
+ tocScrollSpy: { depth: 2, value: "true" }
581
605
  });
582
606
  var dailyNotes = np(
583
607
  "@riebeckite/plugin-daily-notes",
584
- "dailyNotesPlugin",
608
+ "dailyNotes",
585
609
  `{ source: { directory: "Daily", pathPattern: "Daily/{YYYY}-{MM}-{DD}" }, extract: { frontmatter: "daily-summary", codeBlock: "daily-snippet" }, widget: { limit: 5 } }`
586
610
  );
587
611
  var rename = np(
588
612
  "@riebeckite/plugin-rename",
589
- "renamePlugin",
613
+ "rename",
590
614
  `{ enabled: true, status: 308, onUnexpectedRemoval: "warning" }`
591
615
  );
592
616
  var textFragment = np(
593
617
  "@riebeckite/plugin-text-fragment",
594
- "textFragmentPlugin",
618
+ "textFragment",
595
619
  (context) => `{ prefix: ${JSON.stringify(`${context.variables.title}: `)} }`
596
620
  );
621
+ var timeline = np("@riebeckite/plugin-timeline", "timeline");
597
622
  var quality = np(
598
623
  "@riebeckite/plugin-quality",
599
- "qualityPlugin",
624
+ "quality",
600
625
  `{ a11y: { enabled: true }, ignoreRules: [] }`
601
626
  );
602
627
  var deploy = np(
603
628
  "@riebeckite/plugin-deploy",
604
- "deployPlugin",
629
+ "deploy",
605
630
  `{ provider: "cloudflare-pages" }`
606
631
  );
607
632
  var diagnostics = np(
@@ -613,6 +638,22 @@ var defaultTheme = {
613
638
  package: "@riebeckite/theme-default",
614
639
  factory: "defaultTheme"
615
640
  };
641
+ var gardenTheme = {
642
+ package: "@riebeckite/theme-garden",
643
+ factory: "gardenTheme"
644
+ };
645
+ var editorialTheme = {
646
+ package: "@riebeckite/theme-editorial",
647
+ factory: "editorialTheme"
648
+ };
649
+ var technicalTheme = {
650
+ package: "@riebeckite/theme-technical",
651
+ factory: "technicalTheme"
652
+ };
653
+ var folioTheme = {
654
+ package: "@riebeckite/theme-folio",
655
+ factory: "folioTheme"
656
+ };
616
657
  var showCaseTheme = {
617
658
  package: "@riebeckite/theme-default",
618
659
  factory: "defaultTheme",
@@ -668,6 +709,75 @@ var starter = {
668
709
  contentPages: ["index", "guide", "examples"],
669
710
  readme: "standard"
670
711
  };
712
+ var digitalGarden = {
713
+ name: "digital-garden",
714
+ description: "An Obsidian-compatible digital garden with linked notes, backlinks, and a local graph.",
715
+ languages: ["en"],
716
+ theme: gardenTheme,
717
+ plugins: [
718
+ seo,
719
+ ...readingPlugins,
720
+ properties,
721
+ alias,
722
+ backlinks,
723
+ relatedPosts,
724
+ recentPosts,
725
+ taxonomy,
726
+ folderPages,
727
+ localGraph,
728
+ hoverPreview
729
+ ],
730
+ contentPages: [],
731
+ readme: "standard"
732
+ };
733
+ var blog = {
734
+ name: "blog",
735
+ description: "A publishing-focused blog with tags, series, related posts, sharing, and feeds.",
736
+ languages: ["en"],
737
+ theme: editorialTheme,
738
+ plugins: [
739
+ ...readingPlugins,
740
+ blogSeo,
741
+ properties,
742
+ relatedPosts,
743
+ share,
744
+ recentPosts,
745
+ series,
746
+ blogTaxonomy,
747
+ folderPages
748
+ ],
749
+ contentPages: [],
750
+ readme: "standard"
751
+ };
752
+ var documentation = {
753
+ name: "docs",
754
+ description: "A documentation site with an automatic sidebar, table of contents, and previous/next navigation.",
755
+ languages: ["en"],
756
+ theme: technicalTheme,
757
+ plugins: [seo, ...readingPlugins, docs],
758
+ contentPages: [],
759
+ readme: "standard"
760
+ };
761
+ var portfolio = {
762
+ name: "portfolio",
763
+ description: "A calm portfolio for projects and contact details, with image and media support when you add it.",
764
+ languages: ["en"],
765
+ theme: folioTheme,
766
+ plugins: [
767
+ ...readingPlugins,
768
+ seo,
769
+ properties,
770
+ backlinks,
771
+ relatedPosts,
772
+ recentPosts,
773
+ responsiveImage,
774
+ lightbox,
775
+ media,
776
+ gallery
777
+ ],
778
+ contentPages: [],
779
+ readme: "standard"
780
+ };
671
781
  var showcase = {
672
782
  name: "showcase",
673
783
  description: "A feature-rich example that demonstrates the Riebeckite plugin ecosystem with rendered samples and references.",
@@ -706,6 +816,7 @@ var showcase = {
706
816
  autoCardLink,
707
817
  richEmbed,
708
818
  gallery,
819
+ glossary,
709
820
  mermaidPele,
710
821
  graphviz,
711
822
  d2,
@@ -733,6 +844,7 @@ var showcase = {
733
844
  dailyNotes,
734
845
  rename,
735
846
  textFragment,
847
+ timeline,
736
848
  quality,
737
849
  deploy,
738
850
  diagnostics
@@ -748,22 +860,144 @@ var showcase = {
748
860
  ],
749
861
  readme: "rich"
750
862
  };
751
- var scaffoldPresets = { starter, minimal, showcase, empty };
863
+ var scaffoldPresets = {
864
+ starter,
865
+ "digital-garden": digitalGarden,
866
+ blog,
867
+ docs: documentation,
868
+ portfolio,
869
+ minimal,
870
+ showcase,
871
+ empty
872
+ };
752
873
  var SCAFFOLD_DEFAULT_PRESET = "starter";
753
874
  var SCAFFOLD_PRESETS = SCAFFOLD_PRESET_NAMES.map((name) => ({
754
875
  name,
755
876
  description: scaffoldPresets[name].description
756
877
  }));
757
878
  function resolveScaffoldPreset(value) {
758
- if (value === void 0) return scaffoldPresets[SCAFFOLD_DEFAULT_PRESET];
879
+ if (value === void 0) {
880
+ const preset2 = scaffoldPresets[SCAFFOLD_DEFAULT_PRESET];
881
+ validateScaffoldPreset(preset2);
882
+ return preset2;
883
+ }
759
884
  const preset = scaffoldPresets[value];
760
885
  if (!preset) {
761
886
  throw new Error(
762
887
  `Unknown scaffold preset: ${value}. Available presets: ${SCAFFOLD_PRESET_NAMES.join(", ")}.`
763
888
  );
764
889
  }
890
+ validateScaffoldPreset(preset);
765
891
  return preset;
766
892
  }
893
+ function validateScaffoldPreset(preset) {
894
+ const factories = /* @__PURE__ */ new Map();
895
+ const packages = /* @__PURE__ */ new Map();
896
+ for (const plugin of preset.plugins) {
897
+ if (plugin.package.trim() === "" || plugin.factory.trim() === "") {
898
+ throw new Error(`Invalid plugin declaration in preset "${preset.name}".`);
899
+ }
900
+ const factoryPackage = factories.get(plugin.factory);
901
+ if (factoryPackage !== void 0 && factoryPackage !== plugin.package) {
902
+ throw new Error(
903
+ `Preset "${preset.name}" imports "${plugin.factory}" from both "${factoryPackage}" and "${plugin.package}".`
904
+ );
905
+ }
906
+ const packageFactory = packages.get(plugin.package);
907
+ if (packageFactory === plugin.factory) {
908
+ throw new Error(
909
+ `Preset "${preset.name}" registers "${plugin.factory}" from "${plugin.package}" more than once.`
910
+ );
911
+ }
912
+ factories.set(plugin.factory, plugin.package);
913
+ packages.set(plugin.package, plugin.factory);
914
+ }
915
+ if (preset.theme && preset.plugins.some((plugin) => plugin.factory === preset.theme?.factory)) {
916
+ throw new Error(
917
+ `Preset "${preset.name}" reuses theme factory "${preset.theme.factory}" as a plugin import.`
918
+ );
919
+ }
920
+ }
921
+
922
+ // src/scaffold/features.ts
923
+ var feature = (package_, factory, options) => ({ package: package_, factory, options });
924
+ var featurePacks = {
925
+ knowledge: {
926
+ name: "knowledge",
927
+ description: "Link previews and a local graph for connected notes.",
928
+ plugins: [
929
+ feature("@riebeckite/plugin-hover-preview", "hoverPreview"),
930
+ feature("@riebeckite/plugin-local-graph", "localGraph")
931
+ ]
932
+ },
933
+ diagrams: {
934
+ name: "diagrams",
935
+ description: "Mermaid and Graphviz diagrams in Markdown.",
936
+ plugins: [
937
+ feature("@riebeckite/plugin-mermaid-pele", "mermaidPele"),
938
+ feature("@riebeckite/plugin-graphviz", "graphviz")
939
+ ]
940
+ },
941
+ media: {
942
+ name: "media",
943
+ description: "Embedded audio and video, responsive images, and lightbox.",
944
+ plugins: [
945
+ feature("@riebeckite/plugin-media", "media"),
946
+ feature("@riebeckite/plugin-responsive-image", "responsiveImage"),
947
+ feature("@riebeckite/plugin-lightbox", "lightbox")
948
+ ]
949
+ },
950
+ i18n: {
951
+ name: "i18n",
952
+ description: "English and Japanese localization support for content you add.",
953
+ plugins: [
954
+ feature(
955
+ "@riebeckite/plugin-l10n",
956
+ "l10n",
957
+ '{ defaultLang: "en", languages: ["en", "ja"] }'
958
+ )
959
+ ]
960
+ }
961
+ };
962
+ var SCAFFOLD_FEATURE_NAMES = [
963
+ "knowledge",
964
+ "diagrams",
965
+ "media",
966
+ "i18n"
967
+ ];
968
+ var SCAFFOLD_FEATURE_PACKS = SCAFFOLD_FEATURE_NAMES.map((name) => featurePacks[name]);
969
+ function isScaffoldFeatureName(value) {
970
+ return SCAFFOLD_FEATURE_NAMES.includes(value);
971
+ }
972
+ function parseScaffoldFeatures(value) {
973
+ if (value === "none") return [];
974
+ const names = value.split(",");
975
+ if (names.length === 0 || names.some((name) => !isScaffoldFeatureName(name))) {
976
+ throw new Error(
977
+ `Unknown feature: ${names.find((name) => !isScaffoldFeatureName(name)) ?? "(missing)"}. Available features: ${SCAFFOLD_FEATURE_NAMES.join(", ")}.`
978
+ );
979
+ }
980
+ if (new Set(names).size !== names.length) {
981
+ throw new Error("Features must not be repeated.");
982
+ }
983
+ return names;
984
+ }
985
+ function composeScaffoldPreset(preset, features) {
986
+ const selected = features.map((name) => featurePacks[name]);
987
+ const composed = {
988
+ ...preset,
989
+ languages: features.includes("i18n") ? ["en", "ja"] : preset.languages,
990
+ plugins: [...preset.plugins, ...selected.flatMap((pack) => pack.plugins)]
991
+ };
992
+ try {
993
+ validateScaffoldPreset(composed);
994
+ } catch (error) {
995
+ throw new Error(
996
+ `Feature packs cannot be combined with preset "${preset.name}": ${error instanceof Error ? error.message : String(error)}`
997
+ );
998
+ }
999
+ return composed;
1000
+ }
767
1001
 
768
1002
  // src/scaffold/utilities.ts
769
1003
  var SCAFFOLD_UTILITY_NAMES = [
@@ -861,6 +1095,7 @@ function parseArguments(arguments_) {
861
1095
  let directory;
862
1096
  let force = false;
863
1097
  let preset;
1098
+ let features;
864
1099
  let utilities;
865
1100
  let listPresets = false;
866
1101
  let githubActions = false;
@@ -906,6 +1141,17 @@ function parseArguments(arguments_) {
906
1141
  index += 1;
907
1142
  continue;
908
1143
  }
1144
+ if (argument === "--features") {
1145
+ const value = arguments_[index + 1];
1146
+ if (value === void 0 || value.startsWith("-")) {
1147
+ throw new Error(
1148
+ "--features requires a comma-separated list of feature names."
1149
+ );
1150
+ }
1151
+ features = parseScaffoldFeatures(value);
1152
+ index += 1;
1153
+ continue;
1154
+ }
909
1155
  if (argument === "--utilities") {
910
1156
  const value = arguments_[index + 1];
911
1157
  if (value === void 0 || value.startsWith("-")) {
@@ -922,7 +1168,7 @@ function parseArguments(arguments_) {
922
1168
  }
923
1169
  if (directory !== void 0) {
924
1170
  throw new Error(
925
- "Usage: create-riebeckite [directory] [--preset <name>] [--utilities <names>] [--github-actions | --cloudflare-workers] [--content-repository <owner/repository>] [--site-repository <owner/repository>] [--force]"
1171
+ "Usage: create-riebeckite [directory] [--preset <name>] [--features <names>] [--utilities <names>] [--github-actions | --cloudflare-workers] [--content-repository <owner/repository>] [--site-repository <owner/repository>] [--force]"
926
1172
  );
927
1173
  }
928
1174
  directory = argument;
@@ -931,6 +1177,7 @@ function parseArguments(arguments_) {
931
1177
  directory: directory ?? ".",
932
1178
  force,
933
1179
  preset: preset ?? "starter",
1180
+ ...features ? { features } : {},
934
1181
  utilities: utilities ?? SCAFFOLD_DEFAULT_UTILITIES,
935
1182
  listPresets,
936
1183
  deployment: scaffoldDeploymentFromFlags({
@@ -965,6 +1212,7 @@ function interactiveAnswersToOptions(answers) {
965
1212
  directory: answers.directory,
966
1213
  force: false,
967
1214
  preset: answers.preset,
1215
+ ...answers.features ? { features: answers.features } : {},
968
1216
  utilities: answers.utilities,
969
1217
  listPresets: false,
970
1218
  deployment: deploymentFromAnswers(answers)
@@ -998,15 +1246,30 @@ async function promptInteractiveAnswers() {
998
1246
  if (isCancel(projectInput)) return null;
999
1247
  const directory = projectInput.trim() || DEFAULT_DIRECTORY;
1000
1248
  const preset = await select({
1001
- message: "Choose a preset",
1249
+ message: "What would you like to build?",
1002
1250
  initialValue: "starter",
1003
1251
  options: SCAFFOLD_PRESETS.map(({ name, description }) => ({
1004
1252
  value: name,
1005
- label: capitalize(name),
1253
+ label: presetLabel(name),
1006
1254
  hint: description
1007
1255
  }))
1008
1256
  });
1009
1257
  if (isCancel(preset)) return null;
1258
+ const addFeatures = await confirm({
1259
+ message: "Add optional feature packs?",
1260
+ initialValue: false
1261
+ });
1262
+ if (isCancel(addFeatures)) return null;
1263
+ const features = addFeatures ? await multiselect({
1264
+ message: "Feature packs",
1265
+ options: SCAFFOLD_FEATURE_PACKS.map(({ name, description }) => ({
1266
+ value: name,
1267
+ label: name,
1268
+ hint: description
1269
+ })),
1270
+ required: false
1271
+ }) : [];
1272
+ if (isCancel(features)) return null;
1010
1273
  const customize = await confirm({
1011
1274
  message: "Customize extra project files?",
1012
1275
  initialValue: false
@@ -1050,6 +1313,7 @@ async function promptInteractiveAnswers() {
1050
1313
  answers = {
1051
1314
  directory,
1052
1315
  preset,
1316
+ features,
1053
1317
  utilities,
1054
1318
  contentSource,
1055
1319
  contentRepository: contentRepository.trim(),
@@ -1074,7 +1338,14 @@ async function promptInteractiveAnswers() {
1074
1338
  ]
1075
1339
  });
1076
1340
  if (isCancel(deployment)) return null;
1077
- answers = { directory, preset, utilities, contentSource, deployment };
1341
+ answers = {
1342
+ directory,
1343
+ preset,
1344
+ features,
1345
+ utilities,
1346
+ contentSource,
1347
+ deployment
1348
+ };
1078
1349
  }
1079
1350
  log.step("Creating Riebeckite site...");
1080
1351
  const installDependencies2 = await confirm({
@@ -1096,8 +1367,18 @@ async function promptDeployNow() {
1096
1367
  if (isCancel(answer)) return false;
1097
1368
  return answer === "yes";
1098
1369
  }
1099
- function capitalize(value) {
1100
- return value.charAt(0).toUpperCase() + value.slice(1);
1370
+ function presetLabel(name) {
1371
+ const labels = {
1372
+ starter: "Starter site",
1373
+ "digital-garden": "Digital garden",
1374
+ blog: "Blog",
1375
+ docs: "Documentation",
1376
+ portfolio: "Portfolio",
1377
+ minimal: "Minimal site",
1378
+ showcase: "Plugin showcase",
1379
+ empty: "Empty application"
1380
+ };
1381
+ return labels[name];
1101
1382
  }
1102
1383
 
1103
1384
  // src/package-manager.ts
@@ -1573,6 +1854,10 @@ var README_DEMO_ORDER = [
1573
1854
  // src/scaffold/template_options.ts
1574
1855
  var OPTION_DEPTH = {
1575
1856
  empty: 0,
1857
+ "digital-garden": 2,
1858
+ blog: 2,
1859
+ docs: 2,
1860
+ portfolio: 2,
1576
1861
  minimal: 0,
1577
1862
  starter: 2,
1578
1863
  showcase: 3
@@ -1770,7 +2055,7 @@ var PLUGIN_MARKDOWN_GUIDES = {
1770
2055
  },
1771
2056
  "@riebeckite/plugin-shortcodes": {
1772
2057
  summary: "Expands built-in shortcode syntax inside Markdown.",
1773
- markdown: '::youtube[id=dQw4w9WgXcQ]\n\n::figure[Demo image]{src="/images/demo.png"}'
2058
+ markdown: '::youtube{id=dQw4w9WgXcQ}\n\n::figure[Demo image]{src="/images/demo.png"}'
1774
2059
  },
1775
2060
  "@riebeckite/plugin-series": {
1776
2061
  summary: "Groups Markdown pages into a reading series using frontmatter.",
@@ -2358,6 +2643,18 @@ var PLUGIN_CATEGORIES = [
2358
2643
  ko: "Obsidian 스타일 마크다운: 위키링크, 임베드, 콜아웃, 태그."
2359
2644
  }
2360
2645
  },
2646
+ {
2647
+ slug: "glossary",
2648
+ desc: {
2649
+ en: "An alphabetical glossary page from marked term notes.",
2650
+ ja: "印を付けた用語ノートからアルファベット順の用語集ページを生成。",
2651
+ "zh-CN": "从标记的术语笔记生成按字母排序的术语表页面。",
2652
+ es: "Una página de glosario alfabético a partir de notas de términos marcadas.",
2653
+ de: "Eine alphabetische Glossarseite aus markierten Begriffnotizen.",
2654
+ fr: "Une page de glossaire alphabétique à partir de notes de termes marquées.",
2655
+ ko: "표시한 용어 노트에서 알파벳순 용어집 페이지를 생성."
2656
+ }
2657
+ },
2361
2658
  {
2362
2659
  slug: "attachment",
2363
2660
  desc: {
@@ -2580,6 +2877,18 @@ var PLUGIN_CATEGORIES = [
2580
2877
  ko: "노트 그래프와 검색을 탐색하는 대화형 뷰."
2581
2878
  }
2582
2879
  },
2880
+ {
2881
+ slug: "timeline",
2882
+ desc: {
2883
+ en: "A chronological page from marked, dated notes.",
2884
+ ja: "印を付けた日付付きノートから時系列ページを生成。",
2885
+ "zh-CN": "从标记且带日期的笔记生成时间线页面。",
2886
+ es: "Una página cronológica a partir de notas marcadas y fechadas.",
2887
+ de: "Eine chronologische Seite aus markierten, datierten Notizen.",
2888
+ fr: "Une page chronologique à partir de notes marquées et datées.",
2889
+ ko: "표시한 날짜가 있는 노트에서 시간순 페이지를 생성."
2890
+ }
2891
+ },
2583
2892
  {
2584
2893
  slug: "local-graph",
2585
2894
  desc: {
@@ -2804,6 +3113,10 @@ function pluginsContent(language) {
2804
3113
  function readSummary(text2, language) {
2805
3114
  return language === "ja" ? text2.ja ?? text2.en : text2.en;
2806
3115
  }
3116
+ var SHOWCASE_DECK_LINK = {
3117
+ en: "This preset also ships a whole-document Marp note. Open the [note](/deck/) or its [standalone slide page](/slides/deck/).",
3118
+ ja: "このプリセットには全文が Marp のノートも含まれます。[ノート](/deck/) または [スライド単体ページ](/slides/deck/) を開いてください。"
3119
+ };
2807
3120
  var EXAMPLES_COPY = {
2808
3121
  heading: {
2809
3122
  en: "Examples",
@@ -2905,6 +3218,9 @@ function examplesContent(preset, language) {
2905
3218
  lines.push(heading(2, readSummary(demo.title, language)), "");
2906
3219
  lines.push(readSummary(demo.intro, language), "");
2907
3220
  lines.push(demo.markdown, "");
3221
+ if (preset.name === "showcase" && key === "@riebeckite/plugin-marp") {
3222
+ lines.push(readSummary(SHOWCASE_DECK_LINK, language), "");
3223
+ }
2908
3224
  }
2909
3225
  if (preset.name === "showcase") {
2910
3226
  for (const packageName of SHOWCASE_GUIDE_DEMOS) {
@@ -3032,6 +3348,22 @@ var README_INTRO = {
3032
3348
  en: "Recommended default: a practical Markdown garden with search, navigation, and reading essentials.",
3033
3349
  ja: "大半のサイトにおすすめの既定構成です。検索・ナビゲーション・閲覧に必要な機能を備えた実用的な Markdown サイトを作れます。"
3034
3350
  },
3351
+ "digital-garden": {
3352
+ en: "An Obsidian-compatible digital garden with linked notes, backlinks, and a local graph.",
3353
+ ja: "Obsidian と互換性のあるデジタルガーデンです。ノート間リンク、バックリンク、ローカルグラフを備えます。"
3354
+ },
3355
+ blog: {
3356
+ en: "A publishing-focused blog with tags, series, related posts, sharing, and feeds.",
3357
+ ja: "タグ、シリーズ、関連記事、共有、フィードを備えた公開向けブログです。"
3358
+ },
3359
+ docs: {
3360
+ en: "A documentation site with an automatic sidebar, table of contents, and previous/next navigation.",
3361
+ ja: "自動サイドバー、目次、前後ページナビゲーションを備えたドキュメントサイトです。"
3362
+ },
3363
+ portfolio: {
3364
+ en: "A focused portfolio with pages for selected projects, an introduction, and contact details.",
3365
+ ja: "選んだプロジェクト、自己紹介、連絡先のページから始められる、要点を絞ったポートフォリオです。"
3366
+ },
3035
3367
  showcase: {
3036
3368
  en: "A feature-rich example that demonstrates the Riebeckite plugin ecosystem with rendered samples, reference pages, and local fixtures.",
3037
3369
  ja: "Riebeckite の Plugin エコシステムを実際に確認できる機能紹介用の構成です。描画例・リファレンスページ・ローカルのフィクスチャを含みます。"
@@ -3318,7 +3650,7 @@ function copyPasteDemoLines(preset, words, language) {
3318
3650
  }
3319
3651
 
3320
3652
  // src/scaffold/version.ts
3321
- var RIEBECKITE_VERSION = "^0.0.31";
3653
+ var RIEBECKITE_VERSION = "^0.0.33";
3322
3654
 
3323
3655
  // src/scaffold/templates.ts
3324
3656
  function siteTemplateFiles(preset, variables, options = {}) {
@@ -3414,7 +3746,7 @@ function packageJson(preset, variables, options) {
3414
3746
  "@riebeckite/cli": RIEBECKITE_VERSION,
3415
3747
  "@types/node": "^24.5.2",
3416
3748
  typescript: "^5.0.0",
3417
- vite: "^8.0.9",
3749
+ vite: "^8.3.5",
3418
3750
  ...options.cloudflareWorkers ? { wrangler: WRANGLER_VERSION } : {}
3419
3751
  }
3420
3752
  },
@@ -3509,7 +3841,10 @@ function formatScaffoldNextSteps(relativeDirectory, options = {}) {
3509
3841
  var NO_DEPLOYMENT = { type: "none" };
3510
3842
  async function scaffoldRiebeckiteSite(options) {
3511
3843
  const targetDirectory = path3.resolve(options.targetDirectory);
3512
- const preset = resolveScaffoldPreset(options.preset);
3844
+ const preset = composeScaffoldPreset(
3845
+ resolveScaffoldPreset(options.preset),
3846
+ options.features ?? []
3847
+ );
3513
3848
  const deployment = options.deployment ?? NO_DEPLOYMENT;
3514
3849
  const externalContent = externalContentSource(deployment);
3515
3850
  if (externalContent !== void 0) {
@@ -3624,6 +3959,7 @@ async function runCreateRiebeckite(arguments_) {
3624
3959
  targetDirectory,
3625
3960
  overwrite: options.force,
3626
3961
  preset: options.preset,
3962
+ features: options.features,
3627
3963
  utilities: options.utilities,
3628
3964
  deployment: options.deployment
3629
3965
  });