create-bunspace 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/bin.js +335 -34
  2. package/dist/templates/fumadocs/MUST-FOLLOW-GUIDELINES.md +1616 -40
  3. package/dist/templates/monorepo/MUST-FOLLOW-GUIDELINES.md +1616 -40
  4. package/dist/templates/react-starter/MUST-FOLLOW-GUIDELINES.md +1845 -0
  5. package/dist/templates/react-starter/README.md +100 -0
  6. package/dist/templates/react-starter/bun.lock +1298 -0
  7. package/dist/templates/react-starter/components.json +27 -0
  8. package/dist/templates/react-starter/eslint.config.js +23 -0
  9. package/dist/templates/react-starter/index.html +36 -0
  10. package/dist/templates/react-starter/package.json +57 -0
  11. package/dist/templates/react-starter/public/registry.json +115 -0
  12. package/dist/templates/react-starter/public/themes/darkmatteviolet-dark.css +34 -0
  13. package/dist/templates/react-starter/public/themes/darkmatteviolet-light.css +34 -0
  14. package/dist/templates/react-starter/public/themes/default-dark.css +33 -0
  15. package/dist/templates/react-starter/public/themes/default-light.css +34 -0
  16. package/dist/templates/react-starter/public/themes/graphite-dark.css +34 -0
  17. package/dist/templates/react-starter/public/themes/graphite-light.css +34 -0
  18. package/dist/templates/react-starter/public/themes/synthwave84-dark.css +34 -0
  19. package/dist/templates/react-starter/public/themes/synthwave84-light.css +34 -0
  20. package/dist/templates/react-starter/public/vite.svg +1 -0
  21. package/dist/templates/react-starter/src/App.tsx +245 -0
  22. package/dist/templates/react-starter/src/assets/react.svg +1 -0
  23. package/dist/templates/react-starter/src/components/ThemeSelector.tsx +106 -0
  24. package/dist/templates/react-starter/src/components/animate-ui/components/buttons/icon.tsx +86 -0
  25. package/dist/templates/react-starter/src/components/animate-ui/components/buttons/theme-toggler.tsx +92 -0
  26. package/dist/templates/react-starter/src/components/animate-ui/primitives/animate/slot.tsx +96 -0
  27. package/dist/templates/react-starter/src/components/animate-ui/primitives/buttons/button.tsx +31 -0
  28. package/dist/templates/react-starter/src/components/animate-ui/primitives/effects/particles.tsx +155 -0
  29. package/dist/templates/react-starter/src/components/animate-ui/primitives/effects/theme-toggler.tsx +148 -0
  30. package/dist/templates/react-starter/src/components/component-example.tsx +444 -0
  31. package/dist/templates/react-starter/src/components/example.tsx +56 -0
  32. package/dist/templates/react-starter/src/index.css +131 -0
  33. package/dist/templates/react-starter/src/main.tsx +13 -0
  34. package/dist/templates/react-starter/src/providers/ThemeProvider.tsx +27 -0
  35. package/dist/templates/react-starter/tsconfig.app.json +36 -0
  36. package/dist/templates/react-starter/tsconfig.json +13 -0
  37. package/dist/templates/react-starter/tsconfig.node.json +26 -0
  38. package/dist/templates/react-starter/vite.config.ts +17 -0
  39. package/dist/templates/telegram-bot/MUST-FOLLOW-GUIDELINES.md +1845 -0
  40. package/package.json +6 -3
  41. package/templates/fumadocs/MUST-FOLLOW-GUIDELINES.md +1616 -40
  42. package/templates/monorepo/MUST-FOLLOW-GUIDELINES.md +1616 -40
  43. package/templates/react-starter/MUST-FOLLOW-GUIDELINES.md +1845 -0
  44. package/templates/react-starter/README.md +100 -0
  45. package/templates/react-starter/bun.lock +1298 -0
  46. package/templates/react-starter/components.json +27 -0
  47. package/templates/react-starter/eslint.config.js +23 -0
  48. package/templates/react-starter/index.html +36 -0
  49. package/templates/react-starter/package.json +57 -0
  50. package/templates/react-starter/public/registry.json +115 -0
  51. package/templates/react-starter/public/themes/darkmatteviolet-dark.css +34 -0
  52. package/templates/react-starter/public/themes/darkmatteviolet-light.css +34 -0
  53. package/templates/react-starter/public/themes/default-dark.css +33 -0
  54. package/templates/react-starter/public/themes/default-light.css +34 -0
  55. package/templates/react-starter/public/themes/graphite-dark.css +34 -0
  56. package/templates/react-starter/public/themes/graphite-light.css +34 -0
  57. package/templates/react-starter/public/themes/synthwave84-dark.css +34 -0
  58. package/templates/react-starter/public/themes/synthwave84-light.css +34 -0
  59. package/templates/react-starter/public/vite.svg +1 -0
  60. package/templates/react-starter/src/App.tsx +245 -0
  61. package/templates/react-starter/src/assets/react.svg +1 -0
  62. package/templates/react-starter/src/components/ThemeSelector.tsx +106 -0
  63. package/templates/react-starter/src/components/animate-ui/components/buttons/icon.tsx +86 -0
  64. package/templates/react-starter/src/components/animate-ui/components/buttons/theme-toggler.tsx +92 -0
  65. package/templates/react-starter/src/components/animate-ui/primitives/animate/slot.tsx +96 -0
  66. package/templates/react-starter/src/components/animate-ui/primitives/buttons/button.tsx +31 -0
  67. package/templates/react-starter/src/components/animate-ui/primitives/effects/particles.tsx +155 -0
  68. package/templates/react-starter/src/components/animate-ui/primitives/effects/theme-toggler.tsx +148 -0
  69. package/templates/react-starter/src/components/component-example.tsx +444 -0
  70. package/templates/react-starter/src/components/example.tsx +56 -0
  71. package/templates/react-starter/src/index.css +131 -0
  72. package/templates/react-starter/src/main.tsx +13 -0
  73. package/templates/react-starter/src/providers/ThemeProvider.tsx +27 -0
  74. package/templates/react-starter/tsconfig.app.json +36 -0
  75. package/templates/react-starter/tsconfig.json +13 -0
  76. package/templates/react-starter/tsconfig.node.json +26 -0
  77. package/templates/react-starter/vite.config.ts +17 -0
  78. package/templates/telegram-bot/MUST-FOLLOW-GUIDELINES.md +1845 -0
package/dist/bin.js CHANGED
@@ -5189,6 +5189,11 @@ async function selectTemplate(args) {
5189
5189
  title: "Fumadocs - Documentaci\xF3n con Next.js + MDX + Fumadocs",
5190
5190
  value: "fumadocs",
5191
5191
  description: "Bilingual documentation site with GitHub Pages deployment"
5192
+ },
5193
+ {
5194
+ title: "React Starter - BaseUI + React 19 + Vite 8 + Theme Manager",
5195
+ value: "react-starter",
5196
+ description: "Opinionated React starter with animated UI components and theme management"
5192
5197
  }
5193
5198
  ]
5194
5199
  }, {
@@ -5444,6 +5449,69 @@ Operation cancelled`));
5444
5449
  runInstall: args.noInstall ? false : response.runInstall ?? true
5445
5450
  };
5446
5451
  }
5452
+ async function promptReactStarter(args) {
5453
+ const gitUser = await getGitUser();
5454
+ const parsed = parseProjectArg(args.projectName);
5455
+ const response = await import_prompts.default([
5456
+ {
5457
+ type: args.projectName ? null : "text",
5458
+ name: "name",
5459
+ message: "Project name",
5460
+ initial: parsed.name,
5461
+ validate: (value) => {
5462
+ if (!value)
5463
+ return "Project name is required";
5464
+ if (!isValidProjectName(value)) {
5465
+ return "Invalid name. Use lowercase letters, numbers, and hyphens only";
5466
+ }
5467
+ return true;
5468
+ },
5469
+ format: (value) => value.toLowerCase().trim()
5470
+ },
5471
+ {
5472
+ type: args.description ? null : "text",
5473
+ name: "description",
5474
+ message: "Description",
5475
+ initial: "React app with BaseUI, theme management, and animated components"
5476
+ },
5477
+ {
5478
+ type: args.author ? null : "text",
5479
+ name: "author",
5480
+ message: "Author",
5481
+ initial: gitUser || "Anonymous"
5482
+ },
5483
+ {
5484
+ type: args.noGit ? null : "confirm",
5485
+ name: "initGit",
5486
+ message: "Initialize git repository?",
5487
+ initial: true
5488
+ },
5489
+ {
5490
+ type: args.noInstall ? null : "confirm",
5491
+ name: "runInstall",
5492
+ message: "Run bun install?",
5493
+ initial: true
5494
+ }
5495
+ ], {
5496
+ onCancel: () => {
5497
+ console.log(kleur_default.red(`
5498
+ Operation cancelled`));
5499
+ process.exit(0);
5500
+ }
5501
+ });
5502
+ const name = args.projectName ? parsed.name : response.name;
5503
+ const targetDir = args.dir || `./${name}`;
5504
+ return {
5505
+ template: "react-starter",
5506
+ name,
5507
+ scope: "",
5508
+ description: args.description || response.description || "",
5509
+ author: args.author || response.author || gitUser || "Anonymous",
5510
+ targetDir,
5511
+ initGit: args.noGit ? false : response.initGit ?? true,
5512
+ runInstall: args.noInstall ? false : response.runInstall ?? true
5513
+ };
5514
+ }
5447
5515
  async function promptUser(args, templateType) {
5448
5516
  if (templateType === "telegram-bot") {
5449
5517
  return promptTelegramBot(args);
@@ -5451,6 +5519,9 @@ async function promptUser(args, templateType) {
5451
5519
  if (templateType === "fumadocs") {
5452
5520
  return promptFumadocs(args);
5453
5521
  }
5522
+ if (templateType === "react-starter") {
5523
+ return promptReactStarter(args);
5524
+ }
5454
5525
  return promptMonorepo(args);
5455
5526
  }
5456
5527
  async function getDefaultsMonorepo(args) {
@@ -5512,13 +5583,192 @@ async function getDefaults(args, templateType) {
5512
5583
  if (templateType === "fumadocs") {
5513
5584
  return getDefaultsFumadocs(args);
5514
5585
  }
5586
+ if (templateType === "react-starter") {
5587
+ return getDefaultsReactStarter(args);
5588
+ }
5515
5589
  return getDefaultsMonorepo(args);
5516
5590
  }
5591
+ async function getDefaultsReactStarter(args) {
5592
+ const gitUser = await getGitUser();
5593
+ const parsed = parseProjectArg(args.projectName);
5594
+ const targetDir = args.dir || parsed.targetDir;
5595
+ return {
5596
+ template: "react-starter",
5597
+ name: parsed.name,
5598
+ scope: "",
5599
+ description: args.description || "React app with BaseUI, theme management, and animated components",
5600
+ author: args.author || gitUser || "Anonymous",
5601
+ targetDir,
5602
+ initGit: !args.noGit,
5603
+ runInstall: !args.noInstall
5604
+ };
5605
+ }
5517
5606
 
5518
5607
  // src/generator.ts
5519
- import { mkdir, readdir, stat, readFile, writeFile, copyFile, rename } from "fs/promises";
5520
- import { join, dirname } from "path";
5608
+ import { mkdir, readdir, stat as stat2, readFile as readFile2, writeFile as writeFile2, copyFile, rename } from "fs/promises";
5609
+ import { join as join2, dirname } from "path";
5610
+ import { existsSync as existsSync2 } from "fs";
5611
+
5612
+ // src/guidelines-service.ts
5521
5613
  import { existsSync } from "fs";
5614
+ import { readFile, writeFile } from "fs/promises";
5615
+ import { join } from "path";
5616
+ import { homedir } from "os";
5617
+ var LOCAL_DOTFILES_PATH = join(homedir(), "dotfiles", "MUST-FOLLOW-GUIDELINES.md");
5618
+ var GITHUB_RAW_URL = "https://raw.githubusercontent.com/MKS2508/dotfiles/main/MUST-FOLLOW-GUIDELINES.md";
5619
+ var GUIDELINES_FILENAME = "MUST-FOLLOW-GUIDELINES.md";
5620
+ async function fetchGuidelines() {
5621
+ if (existsSync(LOCAL_DOTFILES_PATH)) {
5622
+ try {
5623
+ const content = await readFile(LOCAL_DOTFILES_PATH, "utf-8");
5624
+ const lines = content.split(`
5625
+ `).length;
5626
+ return { content, source: "local", lines };
5627
+ } catch {
5628
+ console.log(kleur_default.yellow(" \u26A0\uFE0F Failed to read local dotfiles, trying GitHub..."));
5629
+ }
5630
+ }
5631
+ try {
5632
+ const response = await fetch(GITHUB_RAW_URL);
5633
+ if (response.ok) {
5634
+ const content = await response.text();
5635
+ const lines = content.split(`
5636
+ `).length;
5637
+ return { content, source: "github", lines };
5638
+ }
5639
+ } catch {}
5640
+ return null;
5641
+ }
5642
+ async function getGuidelinesForGeneration() {
5643
+ const result = await fetchGuidelines();
5644
+ return result?.content ?? null;
5645
+ }
5646
+ async function syncGuidelinesToTemplate(templatePath, templateName, guidelinesContent) {
5647
+ const guidelinesPath = join(templatePath, GUIDELINES_FILENAME);
5648
+ const linesCount = guidelinesContent.split(`
5649
+ `).length;
5650
+ if (!existsSync(templatePath)) {
5651
+ return {
5652
+ templateName,
5653
+ success: false,
5654
+ action: "skipped",
5655
+ error: "Template directory not found"
5656
+ };
5657
+ }
5658
+ try {
5659
+ if (existsSync(guidelinesPath)) {
5660
+ const existingContent = await readFile(guidelinesPath, "utf-8");
5661
+ if (existingContent === guidelinesContent) {
5662
+ return {
5663
+ templateName,
5664
+ success: true,
5665
+ action: "unchanged",
5666
+ linesCount
5667
+ };
5668
+ }
5669
+ await writeFile(guidelinesPath, guidelinesContent, "utf-8");
5670
+ return {
5671
+ templateName,
5672
+ success: true,
5673
+ action: "updated",
5674
+ linesCount
5675
+ };
5676
+ }
5677
+ await writeFile(guidelinesPath, guidelinesContent, "utf-8");
5678
+ return {
5679
+ templateName,
5680
+ success: true,
5681
+ action: "created",
5682
+ linesCount
5683
+ };
5684
+ } catch (error) {
5685
+ return {
5686
+ templateName,
5687
+ success: false,
5688
+ action: "skipped",
5689
+ error: error instanceof Error ? error.message : "Unknown error"
5690
+ };
5691
+ }
5692
+ }
5693
+ async function syncGuidelinesToAllTemplates(templatesDir, templateNames) {
5694
+ const guidelines = await fetchGuidelines();
5695
+ if (!guidelines) {
5696
+ console.log(kleur_default.yellow(`
5697
+ \u26A0\uFE0F Guidelines not available (no local dotfiles or internet)`));
5698
+ return templateNames.map((name) => ({
5699
+ templateName: name,
5700
+ success: false,
5701
+ action: "skipped",
5702
+ error: "Guidelines source unavailable"
5703
+ }));
5704
+ }
5705
+ console.log(`
5706
+ \uD83D\uDCCB Syncing ${kleur_default.cyan(GUIDELINES_FILENAME)} from ${kleur_default.dim(guidelines.source)}...`);
5707
+ console.log(` ${kleur_default.dim(`(${guidelines.lines} lines)`)}
5708
+ `);
5709
+ const results = [];
5710
+ for (const name of templateNames) {
5711
+ const templatePath = join(templatesDir, name);
5712
+ const result = await syncGuidelinesToTemplate(templatePath, name, guidelines.content);
5713
+ results.push(result);
5714
+ const icon = result.success ? result.action === "unchanged" ? "\u2713" : "\u2705" : "\u274C";
5715
+ const actionText = result.action === "created" ? kleur_default.green("created") : result.action === "updated" ? kleur_default.yellow("updated") : result.action === "unchanged" ? kleur_default.dim("unchanged") : kleur_default.red("skipped");
5716
+ console.log(` ${icon} ${kleur_default.cyan(name)}: ${actionText}${result.error ? ` - ${result.error}` : ""}`);
5717
+ }
5718
+ return results;
5719
+ }
5720
+ async function checkGuidelinesStatus(templatesDir, templateNames) {
5721
+ console.log(`
5722
+ \uD83D\uDCCB ${kleur_default.bold("Guidelines Status Check")}
5723
+ `);
5724
+ const guidelines = await fetchGuidelines();
5725
+ if (guidelines) {
5726
+ console.log(` ${kleur_default.green("\u2713")} Source: ${kleur_default.cyan(guidelines.source)}`);
5727
+ console.log(` ${kleur_default.green("\u2713")} Lines: ${kleur_default.cyan(guidelines.lines.toString())}`);
5728
+ if (guidelines.source === "local") {
5729
+ console.log(` ${kleur_default.dim(` Path: ${LOCAL_DOTFILES_PATH}`)}`);
5730
+ } else {
5731
+ console.log(` ${kleur_default.dim(` URL: ${GITHUB_RAW_URL}`)}`);
5732
+ }
5733
+ } else {
5734
+ console.log(` ${kleur_default.red("\u2717")} Guidelines unavailable`);
5735
+ console.log(` ${kleur_default.dim(` Local: ${LOCAL_DOTFILES_PATH} (not found)`)}`);
5736
+ console.log(` ${kleur_default.dim(` GitHub: ${GITHUB_RAW_URL} (unreachable)`)}`);
5737
+ return;
5738
+ }
5739
+ console.log(`
5740
+ ${kleur_default.bold("Template Status:")}
5741
+ `);
5742
+ for (const name of templateNames) {
5743
+ const templatePath = join(templatesDir, name);
5744
+ const guidelinesPath = join(templatePath, GUIDELINES_FILENAME);
5745
+ if (!existsSync(templatePath)) {
5746
+ console.log(` ${kleur_default.red("\u2717")} ${kleur_default.cyan(name)}: ${kleur_default.dim("template not found")}`);
5747
+ continue;
5748
+ }
5749
+ if (!existsSync(guidelinesPath)) {
5750
+ console.log(` ${kleur_default.yellow("\u26A0")} ${kleur_default.cyan(name)}: ${kleur_default.yellow("missing")}`);
5751
+ continue;
5752
+ }
5753
+ try {
5754
+ const content = await readFile(guidelinesPath, "utf-8");
5755
+ const templateLines = content.split(`
5756
+ `).length;
5757
+ const isUpToDate = content === guidelines.content;
5758
+ if (isUpToDate) {
5759
+ console.log(` ${kleur_default.green("\u2713")} ${kleur_default.cyan(name)}: ${kleur_default.green("up to date")} (${templateLines} lines)`);
5760
+ } else {
5761
+ console.log(` ${kleur_default.yellow("\u26A0")} ${kleur_default.cyan(name)}: ${kleur_default.yellow("outdated")} (${templateLines} lines vs ${guidelines.lines})`);
5762
+ }
5763
+ } catch {
5764
+ console.log(` ${kleur_default.red("\u2717")} ${kleur_default.cyan(name)}: ${kleur_default.red("error reading file")}`);
5765
+ }
5766
+ }
5767
+ console.log("");
5768
+ }
5769
+
5770
+ // src/generator.ts
5771
+ var GUIDELINES_FILENAME2 = "MUST-FOLLOW-GUIDELINES.md";
5522
5772
  var TEXT_EXTENSIONS = new Set([
5523
5773
  ".ts",
5524
5774
  ".tsx",
@@ -5557,12 +5807,12 @@ var EXCLUDED_FILES = new Set([
5557
5807
  ".DS_Store"
5558
5808
  ]);
5559
5809
  async function getTemplateDir(templateType) {
5560
- const submodulePath = join(import.meta.dir, "..", "templates", templateType);
5561
- if (existsSync(submodulePath)) {
5810
+ const submodulePath = join2(import.meta.dir, "..", "templates", templateType);
5811
+ if (existsSync2(submodulePath)) {
5562
5812
  return submodulePath;
5563
5813
  }
5564
- const distPath = join(import.meta.dir, "..", "..", "templates", templateType);
5565
- if (existsSync(distPath)) {
5814
+ const distPath = join2(import.meta.dir, "..", "..", "templates", templateType);
5815
+ if (existsSync2(distPath)) {
5566
5816
  return distPath;
5567
5817
  }
5568
5818
  throw new Error(`Template '${templateType}' not found. Checked submodules and embedded templates.`);
@@ -5570,7 +5820,7 @@ async function getTemplateDir(templateType) {
5570
5820
  async function generateProject(config, templateType) {
5571
5821
  const templateDir = await getTemplateDir(templateType);
5572
5822
  const targetDir = config.targetDir;
5573
- if (existsSync(targetDir)) {
5823
+ if (existsSync2(targetDir)) {
5574
5824
  const entries = await readdir(targetDir);
5575
5825
  if (entries.length > 0) {
5576
5826
  printError(`Directory ${targetDir} is not empty`);
@@ -5583,12 +5833,23 @@ async function generateProject(config, templateType) {
5583
5833
  printStep("Copying template files...");
5584
5834
  await copyTemplateDir(templateDir, targetDir, placeholders);
5585
5835
  if (templateType === "fumadocs") {
5586
- const contentTemplatePath = join(targetDir, "content-template");
5587
- const contentPath = join(targetDir, "content");
5588
- if (existsSync(contentTemplatePath)) {
5836
+ const contentTemplatePath = join2(targetDir, "content-template");
5837
+ const contentPath = join2(targetDir, "content");
5838
+ if (existsSync2(contentTemplatePath)) {
5589
5839
  await rename(contentTemplatePath, contentPath);
5590
5840
  }
5591
5841
  }
5842
+ printStep("Syncing MUST-FOLLOW-GUIDELINES.md...");
5843
+ const guidelinesContent = await getGuidelinesForGeneration();
5844
+ if (guidelinesContent) {
5845
+ const guidelinesPath = join2(targetDir, GUIDELINES_FILENAME2);
5846
+ await writeFile2(guidelinesPath, guidelinesContent, "utf-8");
5847
+ const lines = guidelinesContent.split(`
5848
+ `).length;
5849
+ printStep(`Guidelines synced (${lines} lines)`);
5850
+ } else {
5851
+ printStep("Guidelines source unavailable, using template version");
5852
+ }
5592
5853
  if (config.initGit) {
5593
5854
  printStep("Initializing git repository...");
5594
5855
  await initGit(targetDir);
@@ -5631,6 +5892,15 @@ function generatePlaceholders(config, templateType) {
5631
5892
  SUPPORTED_LOCALES: config.supportedLocales || "es,en"
5632
5893
  };
5633
5894
  }
5895
+ if (templateType === "react-starter") {
5896
+ const projectTitle = config.name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
5897
+ return {
5898
+ ...base,
5899
+ PROJECT_NAME: config.name,
5900
+ PROJECT_TITLE: projectTitle,
5901
+ DESCRIPTION: config.description
5902
+ };
5903
+ }
5634
5904
  throw new Error(`Unknown template: ${templateType}`);
5635
5905
  }
5636
5906
  async function copyTemplateDir(src, dest, placeholders) {
@@ -5638,9 +5908,9 @@ async function copyTemplateDir(src, dest, placeholders) {
5638
5908
  for (const entry of entries) {
5639
5909
  if (EXCLUDED_FILES.has(entry))
5640
5910
  continue;
5641
- const srcPath = join(src, entry);
5642
- const destPath = join(dest, entry);
5643
- const stats = await stat(srcPath);
5911
+ const srcPath = join2(src, entry);
5912
+ const destPath = join2(dest, entry);
5913
+ const stats = await stat2(srcPath);
5644
5914
  if (stats.isDirectory()) {
5645
5915
  await mkdir(destPath, { recursive: true });
5646
5916
  await copyTemplateDir(srcPath, destPath, placeholders);
@@ -5660,9 +5930,9 @@ function shouldReplacePlaceholders(filepath) {
5660
5930
  async function copyTemplateFile(src, dest, placeholders) {
5661
5931
  await mkdir(dirname(dest), { recursive: true });
5662
5932
  if (shouldReplacePlaceholders(src)) {
5663
- const content = await readFile(src, "utf-8");
5933
+ const content = await readFile2(src, "utf-8");
5664
5934
  const replaced = replacePlaceholders(content, placeholders);
5665
- await writeFile(dest, replaced, "utf-8");
5935
+ await writeFile2(dest, replaced, "utf-8");
5666
5936
  } else {
5667
5937
  await copyFile(src, dest);
5668
5938
  }
@@ -5694,24 +5964,25 @@ async function runBunInstall(targetDir) {
5694
5964
 
5695
5965
  // src/template-manager.ts
5696
5966
  import { spawn } from "child_process";
5697
- import { existsSync as existsSync2 } from "fs";
5698
- import { join as join2 } from "path";
5699
- var ROOT_DIR = join2(import.meta.dir, "..");
5700
- var TEMPLATES_DIR = join2(ROOT_DIR, "templates");
5967
+ import { existsSync as existsSync3 } from "fs";
5968
+ import { join as join3 } from "path";
5969
+ var ROOT_DIR = join3(import.meta.dir, "..");
5970
+ var TEMPLATES_DIR = join3(ROOT_DIR, "templates");
5971
+ var ALL_TEMPLATES = ["monorepo", "telegram-bot", "fumadocs"];
5701
5972
  async function listTemplates() {
5702
5973
  console.log(`
5703
5974
  \uD83D\uDCE6 Templates Status:
5704
5975
  `);
5705
5976
  const templates = ["monorepo", "telegram-bot", "fumadocs"];
5706
5977
  for (const name of templates) {
5707
- const templatePath = join2(TEMPLATES_DIR, name);
5708
- if (!existsSync2(templatePath)) {
5978
+ const templatePath = join3(TEMPLATES_DIR, name);
5979
+ if (!existsSync3(templatePath)) {
5709
5980
  console.log(` \u274C ${name} (missing)
5710
5981
  `);
5711
5982
  continue;
5712
5983
  }
5713
- const gitDir = join2(templatePath, ".git");
5714
- if (existsSync2(gitDir)) {
5984
+ const gitDir = join3(templatePath, ".git");
5985
+ if (existsSync3(gitDir)) {
5715
5986
  try {
5716
5987
  const url = await execGit(["config", "remote.origin.url"], { cwd: templatePath, silent: true });
5717
5988
  const branch = await execGit(["rev-parse", "--abbrev-ref", "HEAD"], { cwd: templatePath, silent: true });
@@ -5731,19 +6002,19 @@ async function listTemplates() {
5731
6002
  }
5732
6003
  }
5733
6004
  async function syncTemplates(templateName) {
5734
- const templates = templateName ? [templateName] : ["monorepo", "telegram-bot"];
6005
+ const templates = templateName ? [templateName] : ALL_TEMPLATES;
5735
6006
  console.log(`
5736
6007
  \uD83D\uDD04 Syncing ${templateName ? kleur_default.cyan(templateName) : "all templates"}...
5737
6008
  `);
5738
6009
  for (const name of templates) {
5739
- const templatePath = join2(TEMPLATES_DIR, name);
5740
- if (!existsSync2(templatePath)) {
6010
+ const templatePath = join3(TEMPLATES_DIR, name);
6011
+ if (!existsSync3(templatePath)) {
5741
6012
  console.log(` \u26A0\uFE0F Template '${name}' not found. Skipping.
5742
6013
  `);
5743
6014
  continue;
5744
6015
  }
5745
- const gitDir = join2(templatePath, ".git");
5746
- if (existsSync2(gitDir)) {
6016
+ const gitDir = join3(templatePath, ".git");
6017
+ if (existsSync3(gitDir)) {
5747
6018
  console.log(` \uD83D\uDCE5 ${kleur_default.cyan(name)}:`);
5748
6019
  try {
5749
6020
  await execGit(["pull", "--ff-only"], { cwd: templatePath });
@@ -5758,21 +6029,22 @@ async function syncTemplates(templateName) {
5758
6029
  `);
5759
6030
  }
5760
6031
  }
6032
+ await syncGuidelinesToAllTemplates(TEMPLATES_DIR, templates);
5761
6033
  console.log(`${kleur_default.green("\u2728")} Sync complete!
5762
6034
  `);
5763
6035
  }
5764
6036
  async function importTemplate(name, sourcePath) {
5765
- const targetPath = join2(TEMPLATES_DIR, name);
6037
+ const targetPath = join3(TEMPLATES_DIR, name);
5766
6038
  console.log(`
5767
6039
  \uD83D\uDCE6 Importing '${kleur_default.cyan(name)}' from ${sourcePath}...
5768
6040
  `);
5769
- if (existsSync2(targetPath)) {
6041
+ if (existsSync3(targetPath)) {
5770
6042
  console.log(` \u26A0\uFE0F Template '${name}' already exists.
5771
6043
  `);
5772
6044
  return;
5773
6045
  }
5774
- const sourceGitDir = join2(sourcePath, ".git");
5775
- if (existsSync2(sourceGitDir)) {
6046
+ const sourceGitDir = join3(sourcePath, ".git");
6047
+ if (existsSync3(sourceGitDir)) {
5776
6048
  console.log(` \uD83D\uDD17 Adding as submodule...`);
5777
6049
  try {
5778
6050
  await execGit(["submodule", "add", sourcePath, `templates/${name}`]);
@@ -5846,6 +6118,10 @@ async function main(args) {
5846
6118
  await handleTemplatesCommand(args.slice(1));
5847
6119
  return;
5848
6120
  }
6121
+ if (args[0] === "guidelines") {
6122
+ await handleGuidelinesCommand(args.slice(1));
6123
+ return;
6124
+ }
5849
6125
  try {
5850
6126
  const templateType = await selectTemplate(parsedArgs);
5851
6127
  const config = parsedArgs.yes ? await getDefaults(parsedArgs, templateType) : await promptUser(parsedArgs, templateType);
@@ -5878,9 +6154,9 @@ async function handleTemplatesCommand(args) {
5878
6154
  break;
5879
6155
  default:
5880
6156
  console.error(`
5881
- ${printError.title("Unknown template command")} ${command}
6157
+ Unknown template command: ${command}
5882
6158
 
5883
- ${printError.info("Available commands:")}
6159
+ Available commands:
5884
6160
  bun run cli templates list List all templates
5885
6161
  bun run cli templates sync [name] Sync templates from git
5886
6162
  bun run cli templates import <name> <path> Import template from local path
@@ -5888,6 +6164,31 @@ ${printError.info("Available commands:")}
5888
6164
  process.exit(1);
5889
6165
  }
5890
6166
  }
6167
+ async function handleGuidelinesCommand(args) {
6168
+ const command = args[0];
6169
+ const templateName = args[1];
6170
+ const templates = templateName ? [templateName] : ALL_TEMPLATES;
6171
+ switch (command) {
6172
+ case "sync":
6173
+ await syncGuidelinesToAllTemplates(TEMPLATES_DIR, templates);
6174
+ console.log(`
6175
+ \u2728 Guidelines sync complete!
6176
+ `);
6177
+ break;
6178
+ case "check":
6179
+ await checkGuidelinesStatus(TEMPLATES_DIR, ALL_TEMPLATES);
6180
+ break;
6181
+ default:
6182
+ console.error(`
6183
+ Unknown guidelines command: ${command || "(none)"}
6184
+
6185
+ Available commands:
6186
+ bun run cli guidelines sync [template] Sync MUST-FOLLOW-GUIDELINES.md to templates
6187
+ bun run cli guidelines check Check guidelines status across templates
6188
+ `);
6189
+ process.exit(1);
6190
+ }
6191
+ }
5891
6192
 
5892
6193
  // bin.ts
5893
6194
  main(process.argv.slice(2));