create-riebeckite 0.0.32 → 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 (62) hide show
  1. package/dist/src/arguments.d.ts +2 -0
  2. package/dist/src/index.js +379 -42
  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 +329 -36
  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/portfolio/app/components/article.tsx +29 -0
  49. package/templates/scaffold/presets/portfolio/app/components/site-header.tsx +37 -0
  50. package/templates/scaffold/presets/portfolio/app/routes/[slug{.+}].tsx +10 -0
  51. package/templates/scaffold/presets/portfolio/app/routes/_404.tsx +18 -0
  52. package/templates/scaffold/presets/portfolio/app/routes/_renderer.tsx +42 -0
  53. package/templates/scaffold/presets/portfolio/app/routes/index.tsx +10 -0
  54. package/templates/scaffold/presets/portfolio/app/style.css +152 -0
  55. package/templates/scaffold/presets/portfolio/content/about.md +7 -0
  56. package/templates/scaffold/presets/portfolio/content/contact.md +7 -0
  57. package/templates/scaffold/presets/portfolio/content/index.en.md +18 -0
  58. package/templates/scaffold/presets/portfolio/content/projects/field-notes.md +20 -0
  59. package/templates/scaffold/presets/portfolio/content/projects/small-tools.md +10 -0
  60. package/templates/scaffold/presets/showcase/content/deck.md +24 -0
  61. package/templates/scaffold/presets/showcase/content/demo/planning.md +2 -1
  62. 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,55 +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
604
  tocScrollSpy: { depth: 2, value: "true" }
580
605
  });
581
606
  var dailyNotes = np(
582
607
  "@riebeckite/plugin-daily-notes",
583
- "dailyNotesPlugin",
608
+ "dailyNotes",
584
609
  `{ source: { directory: "Daily", pathPattern: "Daily/{YYYY}-{MM}-{DD}" }, extract: { frontmatter: "daily-summary", codeBlock: "daily-snippet" }, widget: { limit: 5 } }`
585
610
  );
586
611
  var rename = np(
587
612
  "@riebeckite/plugin-rename",
588
- "renamePlugin",
613
+ "rename",
589
614
  `{ enabled: true, status: 308, onUnexpectedRemoval: "warning" }`
590
615
  );
591
616
  var textFragment = np(
592
617
  "@riebeckite/plugin-text-fragment",
593
- "textFragmentPlugin",
618
+ "textFragment",
594
619
  (context) => `{ prefix: ${JSON.stringify(`${context.variables.title}: `)} }`
595
620
  );
621
+ var timeline = np("@riebeckite/plugin-timeline", "timeline");
596
622
  var quality = np(
597
623
  "@riebeckite/plugin-quality",
598
- "qualityPlugin",
624
+ "quality",
599
625
  `{ a11y: { enabled: true }, ignoreRules: [] }`
600
626
  );
601
627
  var deploy = np(
602
628
  "@riebeckite/plugin-deploy",
603
- "deployPlugin",
629
+ "deploy",
604
630
  `{ provider: "cloudflare-pages" }`
605
631
  );
606
632
  var diagnostics = np(
@@ -612,6 +638,22 @@ var defaultTheme = {
612
638
  package: "@riebeckite/theme-default",
613
639
  factory: "defaultTheme"
614
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
+ };
615
657
  var showCaseTheme = {
616
658
  package: "@riebeckite/theme-default",
617
659
  factory: "defaultTheme",
@@ -667,6 +709,75 @@ var starter = {
667
709
  contentPages: ["index", "guide", "examples"],
668
710
  readme: "standard"
669
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
+ };
670
781
  var showcase = {
671
782
  name: "showcase",
672
783
  description: "A feature-rich example that demonstrates the Riebeckite plugin ecosystem with rendered samples and references.",
@@ -705,6 +816,7 @@ var showcase = {
705
816
  autoCardLink,
706
817
  richEmbed,
707
818
  gallery,
819
+ glossary,
708
820
  mermaidPele,
709
821
  graphviz,
710
822
  d2,
@@ -732,6 +844,7 @@ var showcase = {
732
844
  dailyNotes,
733
845
  rename,
734
846
  textFragment,
847
+ timeline,
735
848
  quality,
736
849
  deploy,
737
850
  diagnostics
@@ -747,22 +860,144 @@ var showcase = {
747
860
  ],
748
861
  readme: "rich"
749
862
  };
750
- 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
+ };
751
873
  var SCAFFOLD_DEFAULT_PRESET = "starter";
752
874
  var SCAFFOLD_PRESETS = SCAFFOLD_PRESET_NAMES.map((name) => ({
753
875
  name,
754
876
  description: scaffoldPresets[name].description
755
877
  }));
756
878
  function resolveScaffoldPreset(value) {
757
- 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
+ }
758
884
  const preset = scaffoldPresets[value];
759
885
  if (!preset) {
760
886
  throw new Error(
761
887
  `Unknown scaffold preset: ${value}. Available presets: ${SCAFFOLD_PRESET_NAMES.join(", ")}.`
762
888
  );
763
889
  }
890
+ validateScaffoldPreset(preset);
764
891
  return preset;
765
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
+ }
766
1001
 
767
1002
  // src/scaffold/utilities.ts
768
1003
  var SCAFFOLD_UTILITY_NAMES = [
@@ -860,6 +1095,7 @@ function parseArguments(arguments_) {
860
1095
  let directory;
861
1096
  let force = false;
862
1097
  let preset;
1098
+ let features;
863
1099
  let utilities;
864
1100
  let listPresets = false;
865
1101
  let githubActions = false;
@@ -905,6 +1141,17 @@ function parseArguments(arguments_) {
905
1141
  index += 1;
906
1142
  continue;
907
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
+ }
908
1155
  if (argument === "--utilities") {
909
1156
  const value = arguments_[index + 1];
910
1157
  if (value === void 0 || value.startsWith("-")) {
@@ -921,7 +1168,7 @@ function parseArguments(arguments_) {
921
1168
  }
922
1169
  if (directory !== void 0) {
923
1170
  throw new Error(
924
- "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]"
925
1172
  );
926
1173
  }
927
1174
  directory = argument;
@@ -930,6 +1177,7 @@ function parseArguments(arguments_) {
930
1177
  directory: directory ?? ".",
931
1178
  force,
932
1179
  preset: preset ?? "starter",
1180
+ ...features ? { features } : {},
933
1181
  utilities: utilities ?? SCAFFOLD_DEFAULT_UTILITIES,
934
1182
  listPresets,
935
1183
  deployment: scaffoldDeploymentFromFlags({
@@ -964,6 +1212,7 @@ function interactiveAnswersToOptions(answers) {
964
1212
  directory: answers.directory,
965
1213
  force: false,
966
1214
  preset: answers.preset,
1215
+ ...answers.features ? { features: answers.features } : {},
967
1216
  utilities: answers.utilities,
968
1217
  listPresets: false,
969
1218
  deployment: deploymentFromAnswers(answers)
@@ -997,15 +1246,30 @@ async function promptInteractiveAnswers() {
997
1246
  if (isCancel(projectInput)) return null;
998
1247
  const directory = projectInput.trim() || DEFAULT_DIRECTORY;
999
1248
  const preset = await select({
1000
- message: "Choose a preset",
1249
+ message: "What would you like to build?",
1001
1250
  initialValue: "starter",
1002
1251
  options: SCAFFOLD_PRESETS.map(({ name, description }) => ({
1003
1252
  value: name,
1004
- label: capitalize(name),
1253
+ label: presetLabel(name),
1005
1254
  hint: description
1006
1255
  }))
1007
1256
  });
1008
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;
1009
1273
  const customize = await confirm({
1010
1274
  message: "Customize extra project files?",
1011
1275
  initialValue: false
@@ -1049,6 +1313,7 @@ async function promptInteractiveAnswers() {
1049
1313
  answers = {
1050
1314
  directory,
1051
1315
  preset,
1316
+ features,
1052
1317
  utilities,
1053
1318
  contentSource,
1054
1319
  contentRepository: contentRepository.trim(),
@@ -1073,7 +1338,14 @@ async function promptInteractiveAnswers() {
1073
1338
  ]
1074
1339
  });
1075
1340
  if (isCancel(deployment)) return null;
1076
- answers = { directory, preset, utilities, contentSource, deployment };
1341
+ answers = {
1342
+ directory,
1343
+ preset,
1344
+ features,
1345
+ utilities,
1346
+ contentSource,
1347
+ deployment
1348
+ };
1077
1349
  }
1078
1350
  log.step("Creating Riebeckite site...");
1079
1351
  const installDependencies2 = await confirm({
@@ -1095,8 +1367,18 @@ async function promptDeployNow() {
1095
1367
  if (isCancel(answer)) return false;
1096
1368
  return answer === "yes";
1097
1369
  }
1098
- function capitalize(value) {
1099
- 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];
1100
1382
  }
1101
1383
 
1102
1384
  // src/package-manager.ts
@@ -1572,6 +1854,10 @@ var README_DEMO_ORDER = [
1572
1854
  // src/scaffold/template_options.ts
1573
1855
  var OPTION_DEPTH = {
1574
1856
  empty: 0,
1857
+ "digital-garden": 2,
1858
+ blog: 2,
1859
+ docs: 2,
1860
+ portfolio: 2,
1575
1861
  minimal: 0,
1576
1862
  starter: 2,
1577
1863
  showcase: 3
@@ -1769,7 +2055,7 @@ var PLUGIN_MARKDOWN_GUIDES = {
1769
2055
  },
1770
2056
  "@riebeckite/plugin-shortcodes": {
1771
2057
  summary: "Expands built-in shortcode syntax inside Markdown.",
1772
- 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"}'
1773
2059
  },
1774
2060
  "@riebeckite/plugin-series": {
1775
2061
  summary: "Groups Markdown pages into a reading series using frontmatter.",
@@ -2357,6 +2643,18 @@ var PLUGIN_CATEGORIES = [
2357
2643
  ko: "Obsidian 스타일 마크다운: 위키링크, 임베드, 콜아웃, 태그."
2358
2644
  }
2359
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
+ },
2360
2658
  {
2361
2659
  slug: "attachment",
2362
2660
  desc: {
@@ -2579,6 +2877,18 @@ var PLUGIN_CATEGORIES = [
2579
2877
  ko: "노트 그래프와 검색을 탐색하는 대화형 뷰."
2580
2878
  }
2581
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
+ },
2582
2892
  {
2583
2893
  slug: "local-graph",
2584
2894
  desc: {
@@ -2803,6 +3113,10 @@ function pluginsContent(language) {
2803
3113
  function readSummary(text2, language) {
2804
3114
  return language === "ja" ? text2.ja ?? text2.en : text2.en;
2805
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
+ };
2806
3120
  var EXAMPLES_COPY = {
2807
3121
  heading: {
2808
3122
  en: "Examples",
@@ -2904,6 +3218,9 @@ function examplesContent(preset, language) {
2904
3218
  lines.push(heading(2, readSummary(demo.title, language)), "");
2905
3219
  lines.push(readSummary(demo.intro, language), "");
2906
3220
  lines.push(demo.markdown, "");
3221
+ if (preset.name === "showcase" && key === "@riebeckite/plugin-marp") {
3222
+ lines.push(readSummary(SHOWCASE_DECK_LINK, language), "");
3223
+ }
2907
3224
  }
2908
3225
  if (preset.name === "showcase") {
2909
3226
  for (const packageName of SHOWCASE_GUIDE_DEMOS) {
@@ -3031,6 +3348,22 @@ var README_INTRO = {
3031
3348
  en: "Recommended default: a practical Markdown garden with search, navigation, and reading essentials.",
3032
3349
  ja: "大半のサイトにおすすめの既定構成です。検索・ナビゲーション・閲覧に必要な機能を備えた実用的な Markdown サイトを作れます。"
3033
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
+ },
3034
3367
  showcase: {
3035
3368
  en: "A feature-rich example that demonstrates the Riebeckite plugin ecosystem with rendered samples, reference pages, and local fixtures.",
3036
3369
  ja: "Riebeckite の Plugin エコシステムを実際に確認できる機能紹介用の構成です。描画例・リファレンスページ・ローカルのフィクスチャを含みます。"
@@ -3317,7 +3650,7 @@ function copyPasteDemoLines(preset, words, language) {
3317
3650
  }
3318
3651
 
3319
3652
  // src/scaffold/version.ts
3320
- var RIEBECKITE_VERSION = "^0.0.32";
3653
+ var RIEBECKITE_VERSION = "^0.0.33";
3321
3654
 
3322
3655
  // src/scaffold/templates.ts
3323
3656
  function siteTemplateFiles(preset, variables, options = {}) {
@@ -3413,7 +3746,7 @@ function packageJson(preset, variables, options) {
3413
3746
  "@riebeckite/cli": RIEBECKITE_VERSION,
3414
3747
  "@types/node": "^24.5.2",
3415
3748
  typescript: "^5.0.0",
3416
- vite: "^8.0.9",
3749
+ vite: "^8.3.5",
3417
3750
  ...options.cloudflareWorkers ? { wrangler: WRANGLER_VERSION } : {}
3418
3751
  }
3419
3752
  },
@@ -3508,7 +3841,10 @@ function formatScaffoldNextSteps(relativeDirectory, options = {}) {
3508
3841
  var NO_DEPLOYMENT = { type: "none" };
3509
3842
  async function scaffoldRiebeckiteSite(options) {
3510
3843
  const targetDirectory = path3.resolve(options.targetDirectory);
3511
- const preset = resolveScaffoldPreset(options.preset);
3844
+ const preset = composeScaffoldPreset(
3845
+ resolveScaffoldPreset(options.preset),
3846
+ options.features ?? []
3847
+ );
3512
3848
  const deployment = options.deployment ?? NO_DEPLOYMENT;
3513
3849
  const externalContent = externalContentSource(deployment);
3514
3850
  if (externalContent !== void 0) {
@@ -3623,6 +3959,7 @@ async function runCreateRiebeckite(arguments_) {
3623
3959
  targetDirectory,
3624
3960
  overwrite: options.force,
3625
3961
  preset: options.preset,
3962
+ features: options.features,
3626
3963
  utilities: options.utilities,
3627
3964
  deployment: options.deployment
3628
3965
  });