start-vibing 2.0.50 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -94,8 +94,6 @@ async function copyClaudeSetup(targetDir, options = {}) {
94
94
  if (!templateDir) {
95
95
  throw new Error(`Template directory not found. Tried: ${possiblePaths.join(", ")}`);
96
96
  }
97
- console.log(` Using template from: ${templateDir}`);
98
- console.log(` Target directory: ${targetDir}\n`);
99
97
  const destDir = join(targetDir, ".claude");
100
98
  const result = {
101
99
  agents: 0,
@@ -114,15 +112,10 @@ async function copyClaudeSetup(targetDir, options = {}) {
114
112
  if (existsSync(claudeMdTemplate)) {
115
113
  if (!existsSync(claudeMdDest)) {
116
114
  copyFileSync(claudeMdTemplate, claudeMdDest);
117
- console.log(" \u2713 Created CLAUDE.md from template");
118
115
  } else if (options.force) {
119
116
  copyFileSync(claudeMdTemplate, claudeMdDest);
120
- console.log(" \u2713 Overwrote CLAUDE.md (force mode)");
121
117
  } else {
122
118
  copyFileSync(claudeMdTemplate, claudeTemplateDest);
123
- console.log(" \u2713 Preserved your CLAUDE.md");
124
- console.log(" \u2713 Created .claude/CLAUDE.template.md for smart merge");
125
- console.log(" \u2192 The stop hook will help merge new rules on first run");
126
119
  }
127
120
  }
128
121
  return result;
@@ -343,23 +336,13 @@ function isNpmInstallation() {
343
336
  }
344
337
  }
345
338
  async function migrateToNative() {
346
- console.log(" Detected npm installation (deprecated)");
347
- console.log(" Migrating to native installer...");
348
- console.log(" Running: claude install");
349
- console.log("");
350
339
  try {
351
340
  execSync2("claude install", {
352
341
  stdio: "inherit",
353
342
  timeout: 120000
354
343
  });
355
- console.log("");
356
- console.log(" Migration to native installer completed!");
357
- console.log(" Auto-updates are now enabled.");
358
344
  return { success: true, alreadyInstalled: true, migrated: true };
359
345
  } catch (error) {
360
- console.log("");
361
- console.log(" Migration failed, but Claude Code is still functional.");
362
- console.log(" You can manually run: claude install");
363
346
  return {
364
347
  success: true,
365
348
  alreadyInstalled: true,
@@ -376,9 +359,6 @@ async function installClaude() {
376
359
  return { success: true, alreadyInstalled: true };
377
360
  }
378
361
  const { platform: platform2, shell, isWindows } = getPlatformInfo();
379
- console.log(` Detected platform: ${platform2}`);
380
- console.log(` Detected shell: ${shell}`);
381
- console.log("");
382
362
  try {
383
363
  if (isWindows) {
384
364
  return await installClaudeWindows(shell);
@@ -396,17 +376,11 @@ async function installClaude() {
396
376
  async function installClaudeWindows(shell) {
397
377
  try {
398
378
  if (shell === "powershell") {
399
- console.log(" Running PowerShell installer...");
400
- console.log(" Command: irm https://claude.ai/install.ps1 | iex");
401
- console.log("");
402
379
  execSync2('powershell -ExecutionPolicy Bypass -Command "irm https://claude.ai/install.ps1 | iex"', {
403
380
  stdio: "inherit",
404
381
  windowsHide: false
405
382
  });
406
383
  } else {
407
- console.log(" Running CMD installer...");
408
- console.log(" Downloading install script...");
409
- console.log("");
410
384
  execSync2("curl -fsSL https://claude.ai/install.cmd -o %TEMP%\\claude-install.cmd && %TEMP%\\claude-install.cmd", {
411
385
  stdio: "inherit",
412
386
  shell: "cmd.exe",
@@ -420,9 +394,6 @@ async function installClaudeWindows(shell) {
420
394
  } catch {
421
395
  }
422
396
  }
423
- console.log("");
424
- console.log(" Installation completed!");
425
- console.log(" Note: You may need to restart your terminal for PATH changes to take effect.");
426
397
  return { success: true, alreadyInstalled: false };
427
398
  } catch (error) {
428
399
  return {
@@ -434,15 +405,10 @@ async function installClaudeWindows(shell) {
434
405
  }
435
406
  async function installClaudeUnix() {
436
407
  try {
437
- console.log(" Running Unix installer...");
438
- console.log(" Command: curl -fsSL https://claude.ai/install.sh | bash");
439
- console.log("");
440
408
  execSync2("curl -fsSL https://claude.ai/install.sh | bash", {
441
409
  stdio: "inherit",
442
410
  shell: "/bin/bash"
443
411
  });
444
- console.log("");
445
- console.log(" Installation completed!");
446
412
  return { success: true, alreadyInstalled: false };
447
413
  } catch (error) {
448
414
  return {
@@ -452,14 +418,13 @@ async function installClaudeUnix() {
452
418
  };
453
419
  }
454
420
  }
455
- function launchClaude(cwd) {
421
+ function launchClaude(cwd, options = {}) {
456
422
  const { isWindows } = getPlatformInfo();
457
- console.log(" Starting Claude Code...");
458
- console.log(" Running: claude --dangerously-skip-permissions");
459
- console.log("");
460
- console.log(" ========================================");
461
- console.log("");
462
- const claude = spawn("claude", ["--dangerously-skip-permissions"], {
423
+ const args = ["--dangerously-skip-permissions"];
424
+ if (!options.newSession) {
425
+ args.unshift("-c");
426
+ }
427
+ const claude = spawn("claude", args, {
463
428
  cwd,
464
429
  stdio: "inherit",
465
430
  shell: isWindows,
@@ -516,120 +481,29 @@ import { spawnSync as spawnSync2, spawn as spawn2 } from "child_process";
516
481
  var CORE_MCPS = [
517
482
  {
518
483
  name: "context7",
519
- description: "Real-time library documentation",
484
+ description: "real-time docs",
520
485
  command: "npx",
521
486
  args: ["-y", "@upstash/context7-mcp@latest"]
522
487
  },
523
488
  {
524
489
  name: "sequential-thinking",
525
- description: "Structured reasoning for complex problems",
490
+ description: "structured reasoning",
526
491
  command: "npx",
527
492
  args: ["-y", "@modelcontextprotocol/server-sequential-thinking"]
528
493
  },
529
494
  {
530
495
  name: "memory",
531
- description: "Persistent context across sessions",
496
+ description: "persistent context",
532
497
  command: "npx",
533
498
  args: ["-y", "@modelcontextprotocol/server-memory"]
534
499
  },
535
500
  {
536
501
  name: "playwright",
537
- description: "Browser automation and E2E testing",
502
+ description: "browser automation",
538
503
  command: "npx",
539
504
  args: ["-y", "@playwright/mcp@latest"]
540
505
  }
541
506
  ];
542
- var OPTIONAL_MCPS = [
543
- {
544
- name: "nextjs-devtools",
545
- description: "Next.js development tools (requires Next.js project)",
546
- command: "npx",
547
- args: ["-y", "next-devtools-mcp@latest"],
548
- optional: true
549
- },
550
- {
551
- name: "mongodb",
552
- description: "MongoDB database operations",
553
- command: "npx",
554
- args: ["-y", "@mongodb-js/mongodb-mcp-server"],
555
- envVars: ["MONGODB_URI"],
556
- optional: true
557
- },
558
- {
559
- name: "github",
560
- description: "GitHub repository management",
561
- command: "claude",
562
- args: [
563
- "mcp",
564
- "add",
565
- "--transport",
566
- "http",
567
- "-s",
568
- "user",
569
- "github",
570
- "https://api.githubcopilot.com/mcp/"
571
- ],
572
- transport: "http",
573
- url: "https://api.githubcopilot.com/mcp/",
574
- envVars: ["GITHUB_PERSONAL_ACCESS_TOKEN"],
575
- optional: true
576
- },
577
- {
578
- name: "sentry",
579
- description: "Error tracking and monitoring",
580
- command: "claude",
581
- args: [
582
- "mcp",
583
- "add",
584
- "--transport",
585
- "http",
586
- "-s",
587
- "user",
588
- "sentry",
589
- "https://mcp.sentry.dev/mcp"
590
- ],
591
- transport: "http",
592
- url: "https://mcp.sentry.dev/mcp",
593
- optional: true
594
- },
595
- {
596
- name: "brave-search",
597
- description: "Web search for research",
598
- command: "npx",
599
- args: ["-y", "@modelcontextprotocol/server-brave-search"],
600
- envVars: ["BRAVE_API_KEY"],
601
- optional: true
602
- },
603
- {
604
- name: "figma",
605
- description: "Design to code workflows",
606
- command: "claude",
607
- args: [
608
- "mcp",
609
- "add",
610
- "--transport",
611
- "http",
612
- "-s",
613
- "user",
614
- "figma",
615
- "https://mcp.figma.com/mcp"
616
- ],
617
- transport: "http",
618
- url: "https://mcp.figma.com/mcp",
619
- optional: true
620
- }
621
- ];
622
- var c = {
623
- reset: "\x1B[0m",
624
- bright: "\x1B[1m",
625
- dim: "\x1B[2m",
626
- green: "\x1B[32m",
627
- yellow: "\x1B[33m",
628
- blue: "\x1B[34m",
629
- cyan: "\x1B[36m",
630
- red: "\x1B[31m",
631
- magenta: "\x1B[35m"
632
- };
633
507
  function isClaudeMcpReady() {
634
508
  return commandExists("claude");
635
509
  }
@@ -662,8 +536,7 @@ async function installMcp(server) {
662
536
  } else {
663
537
  args = ["mcp", "add", "-s", "user", server.name, "--", server.command, ...server.args];
664
538
  }
665
- const cmd = server.transport === "http" ? "claude" : "claude";
666
- const proc = spawn2(cmd, args, {
539
+ const proc = spawn2("claude", args, {
667
540
  shell: true,
668
541
  stdio: ["pipe", "pipe", "pipe"]
669
542
  });
@@ -707,62 +580,30 @@ async function installMcp(server) {
707
580
  }, 60000);
708
581
  });
709
582
  }
710
- async function installMcpsParallel(servers, concurrency = 3) {
711
- const results = [];
712
- for (let i = 0;i < servers.length; i += concurrency) {
713
- const batch = servers.slice(i, i + concurrency);
714
- const batchResults = await Promise.all(batch.map(async (server) => {
715
- process.stdout.write(` ${c.dim}Installing ${server.name}...${c.reset}`);
716
- const result = await installMcp(server);
717
- process.stdout.clearLine?.(0);
718
- process.stdout.cursorTo?.(0);
719
- const icon = result.success ? `${c.green}\u2713${c.reset}` : `${c.red}\u2717${c.reset}`;
720
- const status = result.skipped ? `${c.dim}(already installed)${c.reset}` : result.success ? `${c.green}OK${c.reset}` : `${c.red}${result.message}${c.reset}`;
721
- console.log(` ${icon} ${c.cyan}${server.name}${c.reset}: ${server.description} ${status}`);
722
- return result;
723
- }));
724
- results.push(...batchResults);
725
- }
726
- return results;
727
- }
728
- async function installMcps() {
729
- console.log("");
730
- console.log(` ${c.bright}${c.magenta}Installing MCP Servers...${c.reset}`);
731
- console.log("");
583
+ async function installMcps(onProgress) {
732
584
  if (!isClaudeMcpReady()) {
733
- console.log(` ${c.yellow}Claude CLI not available. Skipping MCP installation.${c.reset}`);
734
- console.log(` ${c.dim}MCPs will be installed on next run after Claude is ready.${c.reset}`);
735
- return { installed: 0, failed: 0, skipped: CORE_MCPS.length };
585
+ return {
586
+ installed: 0,
587
+ failed: 0,
588
+ skipped: CORE_MCPS.length,
589
+ results: []
590
+ };
591
+ }
592
+ const results = [];
593
+ const total = CORE_MCPS.length;
594
+ for (let i = 0;i < total; i++) {
595
+ const server = CORE_MCPS[i];
596
+ onProgress?.(i + 1, total, server.name);
597
+ const result = await installMcp(server);
598
+ results.push(result);
736
599
  }
737
- console.log(` ${c.blue}Core MCPs (auto-installed):${c.reset}`);
738
- console.log("");
739
- const results = await installMcpsParallel(CORE_MCPS, 3);
740
600
  const installed = results.filter((r) => r.success && !r.skipped).length;
741
601
  const failed = results.filter((r) => !r.success).length;
742
602
  const skipped = results.filter((r) => r.skipped).length;
743
- console.log("");
744
- console.log(` ${c.yellow}Optional MCPs (install manually if needed):${c.reset}`);
745
- console.log("");
746
- for (const mcp of OPTIONAL_MCPS) {
747
- const envNote = mcp.envVars?.length ? `${c.dim}(requires: ${mcp.envVars.join(", ")})${c.reset}` : "";
748
- console.log(` ${c.cyan}${mcp.name}${c.reset}: ${mcp.description} ${envNote}`);
749
- if (mcp.transport === "http") {
750
- console.log(` ${c.dim}claude mcp add --transport http -s user ${mcp.name} ${mcp.url}${c.reset}`);
751
- } else {
752
- console.log(` ${c.dim}claude mcp add -s user ${mcp.name} -- ${mcp.command} ${mcp.args.join(" ")}${c.reset}`);
753
- }
754
- }
755
- console.log("");
756
- console.log(` ${c.bright}MCP Summary:${c.reset}`);
757
- console.log(` ${c.green}Installed: ${installed}${c.reset}`);
758
- if (skipped > 0)
759
- console.log(` ${c.dim}Already installed: ${skipped}${c.reset}`);
760
- if (failed > 0)
761
- console.log(` ${c.red}Failed: ${failed}${c.reset}`);
762
- console.log("");
763
- console.log(` ${c.dim}Verify with: claude mcp list${c.reset}`);
764
- console.log(` ${c.dim}Or inside Claude Code: /mcp${c.reset}`);
765
- return { installed, failed, skipped };
603
+ return { installed, failed, skipped, results };
604
+ }
605
+ function getCoreMcps() {
606
+ return CORE_MCPS;
766
607
  }
767
608
 
768
609
  // src/plugins.ts
@@ -771,35 +612,29 @@ var RECOMMENDED_PLUGINS = [
771
612
  {
772
613
  name: "typescript-lsp",
773
614
  marketplace: "claude-plugins-official",
774
- description: "TypeScript code intelligence (go-to-definition, diagnostics)"
615
+ description: "code intelligence"
775
616
  },
776
617
  {
777
618
  name: "code-review",
778
619
  marketplace: "claude-plugins-official",
779
- description: "Code review workflows and PR analysis"
620
+ description: "PR analysis"
780
621
  },
781
622
  {
782
623
  name: "security-guidance",
783
624
  marketplace: "claude-plugins-official",
784
- description: "Security best practices and vulnerability detection"
625
+ description: "OWASP protection"
785
626
  },
786
627
  {
787
628
  name: "commit-commands",
788
629
  marketplace: "claude-plugins-official",
789
- description: "Git commit, push, and PR workflows"
630
+ description: "git workflows"
631
+ },
632
+ {
633
+ name: "frontend-design",
634
+ marketplace: "claude-plugins-official",
635
+ description: "UI design"
790
636
  }
791
637
  ];
792
- var c2 = {
793
- reset: "\x1B[0m",
794
- bright: "\x1B[1m",
795
- dim: "\x1B[2m",
796
- green: "\x1B[32m",
797
- yellow: "\x1B[33m",
798
- blue: "\x1B[34m",
799
- cyan: "\x1B[36m",
800
- red: "\x1B[31m",
801
- magenta: "\x1B[35m"
802
- };
803
638
  function isClaudePluginReady() {
804
639
  if (!commandExists("claude"))
805
640
  return false;
@@ -887,44 +722,120 @@ async function installPlugin(plugin) {
887
722
  }, 30000);
888
723
  });
889
724
  }
890
- async function installPlugins() {
891
- console.log("");
892
- console.log(` ${c2.bright}${c2.magenta}Installing Plugins...${c2.reset}`);
893
- console.log(` ${c2.dim}(Also pre-configured in .claude/settings.json as fallback)${c2.reset}`);
894
- console.log("");
725
+ async function installPlugins(onProgress) {
895
726
  if (!isClaudePluginReady()) {
896
- console.log(` ${c2.yellow}Plugin commands not available. Skipping CLI installation.${c2.reset}`);
897
- console.log(` ${c2.dim}Plugins will auto-prompt when Claude Code opens the project.${c2.reset}`);
898
- return { installed: 0, failed: 0, skipped: RECOMMENDED_PLUGINS.length };
727
+ return {
728
+ installed: 0,
729
+ failed: 0,
730
+ skipped: RECOMMENDED_PLUGINS.length,
731
+ results: []
732
+ };
899
733
  }
900
734
  const results = [];
901
- for (const plugin of RECOMMENDED_PLUGINS) {
902
- process.stdout.write(` ${c2.dim}Installing ${plugin.name}...${c2.reset}`);
735
+ const total = RECOMMENDED_PLUGINS.length;
736
+ for (let i = 0;i < total; i++) {
737
+ const plugin = RECOMMENDED_PLUGINS[i];
738
+ onProgress?.(i + 1, total, plugin.name);
903
739
  const result = await installPlugin(plugin);
904
- process.stdout.clearLine?.(0);
905
- process.stdout.cursorTo?.(0);
906
- const icon = result.success ? `${c2.green}\u2713${c2.reset}` : `${c2.red}\u2717${c2.reset}`;
907
- const status = result.skipped ? `${c2.dim}(already installed)${c2.reset}` : result.success ? `${c2.green}OK${c2.reset}` : `${c2.yellow}skipped (will auto-prompt)${c2.reset}`;
908
- console.log(` ${icon} ${c2.cyan}${plugin.name}${c2.reset}: ${plugin.description} ${status}`);
909
740
  results.push(result);
910
741
  }
911
742
  const installed = results.filter((r) => r.success && !r.skipped).length;
912
743
  const failed = results.filter((r) => !r.success).length;
913
744
  const skipped = results.filter((r) => r.skipped).length;
745
+ return { installed, failed, skipped, results };
746
+ }
747
+ function getRecommendedPlugins() {
748
+ return RECOMMENDED_PLUGINS;
749
+ }
750
+
751
+ // src/ui.ts
752
+ var c = {
753
+ reset: "\x1B[0m",
754
+ bright: "\x1B[1m",
755
+ dim: "\x1B[2m",
756
+ red: "\x1B[31m",
757
+ green: "\x1B[32m",
758
+ yellow: "\x1B[33m",
759
+ blue: "\x1B[34m",
760
+ magenta: "\x1B[35m",
761
+ cyan: "\x1B[36m",
762
+ white: "\x1B[37m",
763
+ bgRed: "\x1B[41m",
764
+ redBright: "\x1B[91m"
765
+ };
766
+ var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
767
+ function createBanner(version) {
768
+ return `
769
+ ${c.redBright} /\\ /\\
770
+ ${c.redBright} / \\\\ ${c.white}\u2588\u2588\u2557 \u2588\u2588\u2557${c.redBright} / \\\\
771
+ ${c.redBright} / \\\\ ${c.white}\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551${c.redBright} / \\\\
772
+ ${c.redBright} / /\\ \\\\${c.white}\u2588\u2588\u2554\u2550\u2588\u2588\u2554\u2550\u2588\u2588\u2551${c.redBright} / /\\ \\\\
773
+ ${c.redBright} / / \\ \\\\${c.white}\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551${c.redBright} / / \\ \\\\
774
+ ${c.redBright}/_/ \\__\\\\${c.white}\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D${c.redBright} /_/ \\__\\\\
775
+ ${c.reset}
776
+ ${c.bright} START VIBING${c.reset}${c.dim} \xB7 AI-powered dev workflow \xB7 v${version}${c.reset}
777
+ `;
778
+ }
779
+ function createSpinner(initialText) {
780
+ let frame = 0;
781
+ let text = initialText;
782
+ let interval = null;
783
+ const render = () => {
784
+ const spinner = SPINNER_FRAMES[frame % SPINNER_FRAMES.length];
785
+ process.stdout.write(`\r ${c.cyan}${spinner}${c.reset} ${text}`);
786
+ frame++;
787
+ };
788
+ interval = setInterval(render, 80);
789
+ render();
790
+ return {
791
+ update(newText) {
792
+ text = newText;
793
+ },
794
+ succeed(finalText) {
795
+ if (interval)
796
+ clearInterval(interval);
797
+ process.stdout.write(`\r ${c.green}\u2713${c.reset} ${finalText}\x1B[K
798
+ `);
799
+ },
800
+ fail(finalText) {
801
+ if (interval)
802
+ clearInterval(interval);
803
+ process.stdout.write(`\r ${c.red}\u2717${c.reset} ${finalText}\x1B[K
804
+ `);
805
+ },
806
+ stop() {
807
+ if (interval)
808
+ clearInterval(interval);
809
+ process.stdout.write(`\r\x1B[K`);
810
+ }
811
+ };
812
+ }
813
+ function phaseHeader(step, total, label) {
814
+ return `${c.dim}[${step}/${total}]${c.reset} ${label}`;
815
+ }
816
+ function treeItem(name, description, isLast, success) {
817
+ const branch = isLast ? "\u2514" : "\u251C";
818
+ const icon = success ? `${c.green}\u2713${c.reset}` : `${c.red}\u2717${c.reset}`;
819
+ return ` ${c.dim}${branch}${c.reset} ${c.cyan}${name.padEnd(21)}${c.reset}${icon} ${c.dim}${description}${c.reset}`;
820
+ }
821
+ function formatElapsed(startMs) {
822
+ const elapsed = ((Date.now() - startMs) / 1000).toFixed(1);
823
+ return `${elapsed}s`;
824
+ }
825
+ function printOptionalMcps() {
914
826
  console.log("");
915
- console.log(` ${c2.bright}Plugin Summary:${c2.reset}`);
916
- console.log(` ${c2.green}Installed: ${installed}${c2.reset}`);
917
- if (skipped > 0)
918
- console.log(` ${c2.dim}Already installed: ${skipped}${c2.reset}`);
919
- if (failed > 0) {
920
- console.log(` ${c2.yellow}Deferred: ${failed} (will auto-prompt on project open)${c2.reset}`);
921
- }
922
- return { installed, failed, skipped };
827
+ console.log(` ${c.dim}Optional MCPs (install manually):${c.reset}`);
828
+ console.log(` ${c.cyan}nextjs-devtools${c.reset} ${c.dim}\xB7${c.reset} claude mcp add -s user nextjs-devtools -- npx -y next-devtools-mcp@latest`);
829
+ console.log(` ${c.cyan}mongodb${c.reset} ${c.dim}\xB7${c.reset} claude mcp add -s user mongodb -- npx -y @mongodb-js/mongodb-mcp-server`);
830
+ console.log(` ${c.cyan}github${c.reset} ${c.dim}\xB7${c.reset} claude mcp add --transport http -s user github https://api.githubcopilot.com/mcp/`);
831
+ console.log(` ${c.cyan}sentry${c.reset} ${c.dim}\xB7${c.reset} claude mcp add --transport http -s user sentry https://mcp.sentry.dev/mcp`);
832
+ console.log(` ${c.cyan}figma${c.reset} ${c.dim}\xB7${c.reset} claude mcp add --transport http -s user figma https://mcp.figma.com/mcp`);
923
833
  }
924
834
 
925
835
  // src/cli.ts
926
836
  var __filename3 = fileURLToPath2(import.meta.url);
927
837
  var __dirname3 = dirname2(__filename3);
838
+ var TOTAL_PHASES = 5;
928
839
  function getVersion() {
929
840
  try {
930
841
  const paths = [
@@ -934,12 +845,12 @@ function getVersion() {
934
845
  for (const pkgPath of paths) {
935
846
  if (existsSync4(pkgPath)) {
936
847
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
937
- return pkg.version || "1.0.0";
848
+ return pkg.version || "3.0.0";
938
849
  }
939
850
  }
940
- return "1.0.0";
851
+ return "3.0.0";
941
852
  } catch {
942
- return "1.0.0";
853
+ return "3.0.0";
943
854
  }
944
855
  }
945
856
  var VERSION = getVersion();
@@ -958,42 +869,21 @@ function autoCommitClaudeFiles(targetDir) {
958
869
  if (!status) {
959
870
  return { success: true, message: "No changes to commit" };
960
871
  }
961
- execSync3("git add .claude/ CLAUDE.md", {
962
- cwd: targetDir,
963
- stdio: "pipe"
964
- });
965
- execSync3(`git commit --no-verify -m "chore: update Claude Code agents and skills (start-vibing v${VERSION})"`, {
966
- cwd: targetDir,
967
- stdio: "pipe"
968
- });
872
+ execSync3("git add .claude/ CLAUDE.md", { cwd: targetDir, stdio: "pipe" });
873
+ execSync3(`git commit --no-verify -m "chore: update Claude Code agents and skills (start-vibing v${VERSION})"`, { cwd: targetDir, stdio: "pipe" });
969
874
  return { success: true, message: "Changes committed" };
970
- } catch (error) {
971
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
972
- return { success: false, message: errorMessage };
875
+ } catch {
876
+ return { success: false, message: "Commit failed (non-critical)" };
973
877
  }
974
878
  }
975
- var BANNER = `
976
- _____ _ _ __ __ _ _ _
977
- / ____| | | | \\ \\ / /(_)| | (_)
978
- | (___ | |_ __ _ _ __| |_ \\ \\_/ / _ | |__ _ _ __ __ _
979
- \\___ \\| __|/ _\` | '__| __| \\ / | || '_ \\ | || '_ \\ / _\` |
980
- ____) | |_| (_| | | | |_ | | | || |_) || || | | || (_| |
981
- |_____/ \\__|\\__,_|_| \\__| |_| |_||_.__/ |_||_| |_| \\__, |
982
- __/ |
983
- |___/
984
- v${VERSION}
985
- `;
986
- var HELP = `
987
- ${BANNER}
879
+ var HELP = `${createBanner(VERSION)}
988
880
  Setup Claude Code agents, skills, and hooks in your project.
989
- Automatically installs Claude Code if missing and launches it.
990
881
 
991
- Usage:
882
+ ${c.bright}Usage:${c.reset}
992
883
  npx start-vibing [options]
993
- bunx start-vibing [options]
994
- start-vibing [options] (if installed globally)
995
884
 
996
- Options:
885
+ ${c.bright}Options:${c.reset}
886
+ --new Start fresh Claude session (default: resume last)
997
887
  --force Overwrite all files (including custom domains)
998
888
  --no-claude Skip Claude Code installation and launch
999
889
  --no-mcp Skip MCP server installation
@@ -1001,33 +891,14 @@ ${BANNER}
1001
891
  --help, -h Show this help message
1002
892
  --version, -v Show version
1003
893
 
1004
- What it does:
1005
- 1. Checks for start-vibing updates (cached for 1 hour)
1006
- 2. Creates .claude/ folder with agents, skills, hooks, config
1007
- 3. Installs Claude Code if not found on system
1008
- 4. Installs recommended MCP servers (Context7, Playwright, etc.)
1009
- 5. Installs recommended plugins (TypeScript LSP, Code Review, etc.)
1010
- 6. Launches Claude Code with --dangerously-skip-permissions
1011
-
1012
- Smart Copy Behavior:
1013
- - ALWAYS overwrites: agents/*.md, hooks/*.py, settings.json
1014
- - PRESERVES: skills/*/domains/*.md (your custom domains)
1015
- - MERGES: Adds new skills, keeps your customizations
1016
-
1017
- Installation:
1018
- For permanent access, install globally:
1019
- npm install -g start-vibing
1020
-
1021
- Claude Code Installation:
1022
- Automatically uses official native installers:
1023
- - macOS/Linux: curl -fsSL https://claude.ai/install.sh | bash
1024
- - Windows: irm https://claude.ai/install.ps1 | iex
894
+ ${c.bright}What it does:${c.reset}
895
+ [1] Copies template files (agents, skills, hooks, config)
896
+ [2] Sets up Claude Code (install/migrate if needed)
897
+ [3] Installs MCP servers (Context7, Playwright, Memory, etc.)
898
+ [4] Installs plugins (TypeScript LSP, Code Review, Security, etc.)
899
+ [5] Launches Claude Code (resumes last session by default)
1025
900
 
1026
- If npm installation detected, automatically migrates to native
1027
- for better auto-update support.
1028
-
1029
- Documentation:
1030
- https://github.com/LimaTechnologies/ai-development
901
+ ${c.dim}https://github.com/LimaTechnologies/ai-development${c.reset}
1031
902
  `;
1032
903
  async function main() {
1033
904
  const args = process.argv.slice(2);
@@ -1043,124 +914,112 @@ async function main() {
1043
914
  const skipClaude = args.includes("--no-claude");
1044
915
  const skipMcp = args.includes("--no-mcp");
1045
916
  const skipUpdateCheck = args.includes("--no-update-check");
917
+ const newSession = args.includes("--new");
1046
918
  const targetDir = process.cwd();
919
+ const globalStart = Date.now();
1047
920
  if (!skipUpdateCheck) {
1048
921
  try {
1049
- console.log(" Checking for updates...");
1050
922
  const updateResult = await checkForUpdates(VERSION);
1051
923
  if (updateResult.updateAvailable) {
1052
924
  console.log("");
1053
- console.log(` Update available: v${updateResult.currentVersion} -> v${updateResult.latestVersion}`);
1054
- console.log(` Run: ${getUpdateCommand()}`);
1055
- console.log("");
1056
- } else {
1057
- console.log(" You are using the latest version.");
925
+ console.log(` ${c.yellow}Update available:${c.reset} v${updateResult.currentVersion} ${c.dim}->${c.reset} v${updateResult.latestVersion}`);
926
+ console.log(` ${c.dim}Run: ${getUpdateCommand()}${c.reset}`);
1058
927
  console.log("");
1059
928
  }
1060
929
  } catch {
1061
930
  }
1062
931
  }
1063
- console.log(BANNER);
1064
- console.log(" Setting up Claude Code workflow...\n");
932
+ console.log(createBanner(VERSION));
1065
933
  if (isRunningViaNpx()) {
1066
- console.log(" TIP: For permanent access, install globally:");
1067
- console.log(" npm install -g start-vibing");
1068
- console.log(" Then just run: start-vibing");
934
+ console.log(` ${c.dim}TIP: npm install -g start-vibing for permanent access${c.reset}`);
1069
935
  console.log("");
1070
936
  }
1071
- const claudeDir = join4(targetDir, ".claude");
1072
- if (existsSync4(claudeDir) && !force) {
1073
- console.log(" Found existing .claude/ folder.");
1074
- console.log(" Will preserve your custom domains and merge with new files.\n");
1075
- }
937
+ const phase1Start = Date.now();
938
+ const spinner1 = createSpinner(phaseHeader(1, TOTAL_PHASES, "Copying template files..."));
1076
939
  try {
1077
940
  const result = await copyClaudeSetup(targetDir, { force });
1078
- console.log("\n Setup complete!\n");
1079
- console.log(" Files created/updated:");
1080
- console.log(` - Agents: ${result.agents} files`);
1081
- console.log(` - Skills: ${result.skills} files`);
1082
- console.log(` - Hooks: ${result.hooks} files`);
1083
- console.log(` - Config: ${result.config} files`);
941
+ autoCommitClaudeFiles(targetDir);
942
+ ensureHooksEnabled();
943
+ const counts = `${result.agents} agents, ${result.skills} skills, ${result.hooks} hooks`;
944
+ spinner1.succeed(phaseHeader(1, TOTAL_PHASES, `Template files ${c.dim}${"\xB7".repeat(14)}${c.reset} ${counts} ${c.dim}${formatElapsed(phase1Start)}${c.reset}`));
1084
945
  if (result.preserved > 0) {
1085
- console.log(`\n Preserved ${result.preserved} custom file(s) (domains, etc.)`);
946
+ console.log(` ${c.dim}(preserved ${result.preserved} custom file(s))${c.reset}`);
1086
947
  }
1087
- console.log("\n Auto-committing Claude files...");
1088
- const commitResult = autoCommitClaudeFiles(targetDir);
1089
- if (commitResult.success) {
1090
- if (commitResult.message === "No changes to commit") {
1091
- console.log(" No new changes to commit.");
1092
- } else {
1093
- console.log(" Claude files committed (--no-verify used to bypass hooks).");
1094
- }
1095
- } else {
1096
- if (commitResult.message === "Not a git repository") {
1097
- console.log(" Skipped auto-commit (not a git repository).");
1098
- } else {
1099
- console.log(" Auto-commit skipped (non-critical).");
1100
- }
1101
- }
1102
- const hooksResult = ensureHooksEnabled();
1103
- if (hooksResult.modified) {
1104
- console.log("\n Fixed global settings: removed disableAllHooks (hooks now enabled)");
948
+ } catch (error) {
949
+ spinner1.fail(phaseHeader(1, TOTAL_PHASES, `Template files failed`));
950
+ console.error(` ${c.red}${error}${c.reset}`);
951
+ process.exit(1);
952
+ }
953
+ if (skipClaude) {
954
+ console.log("");
955
+ console.log(` ${c.dim}Skipped Claude Code setup (--no-claude)${c.reset}`);
956
+ console.log(` ${c.dim}Run: claude --dangerously-skip-permissions${c.reset}`);
957
+ console.log("");
958
+ console.log(` ${c.green}Setup complete${c.reset} in ${formatElapsed(globalStart)}`);
959
+ process.exit(0);
960
+ }
961
+ const phase2Start = Date.now();
962
+ const spinner2 = createSpinner(phaseHeader(2, TOTAL_PHASES, "Setting up Claude Code..."));
963
+ const installResult = await installClaude();
964
+ if (!installResult.success) {
965
+ spinner2.fail(phaseHeader(2, TOTAL_PHASES, `Claude Code setup failed`));
966
+ console.log(` ${c.dim}Install manually: https://claude.ai/code${c.reset}`);
967
+ process.exit(1);
968
+ }
969
+ const claudeStatus = installResult.migrated ? "migrated to native" : installResult.alreadyInstalled ? "ready (native)" : "installed";
970
+ spinner2.succeed(phaseHeader(2, TOTAL_PHASES, `Claude Code ${c.dim}${"\xB7".repeat(18)}${c.reset} ${claudeStatus} ${c.dim}${formatElapsed(phase2Start)}${c.reset}`));
971
+ const phase3Start = Date.now();
972
+ if (!skipMcp && isClaudeMcpReady()) {
973
+ const spinner3 = createSpinner(phaseHeader(3, TOTAL_PHASES, "Installing MCP servers..."));
974
+ const mcpResult = await installMcps((current, total, name) => {
975
+ spinner3.update(phaseHeader(3, TOTAL_PHASES, `Installing MCP servers... ${c.dim}${current}/${total} ${name}${c.reset}`));
976
+ });
977
+ const mcpOk = mcpResult.installed + mcpResult.skipped;
978
+ const mcpTotal = mcpOk + mcpResult.failed;
979
+ const mcpSummary = `${mcpOk}/${mcpTotal} installed`;
980
+ spinner3.succeed(phaseHeader(3, TOTAL_PHASES, `MCP servers ${c.dim}${"\xB7".repeat(17)}${c.reset} ${mcpSummary} ${c.dim}${formatElapsed(phase3Start)}${c.reset}`));
981
+ const coreMcps = getCoreMcps();
982
+ for (let i = 0;i < mcpResult.results.length; i++) {
983
+ const r = mcpResult.results[i];
984
+ const mcp = coreMcps[i];
985
+ const isLast = i === mcpResult.results.length - 1;
986
+ console.log(treeItem(r.server, mcp.description, isLast, r.success));
1105
987
  }
1106
- if (!skipClaude) {
1107
- console.log("");
1108
- console.log(" ========================================");
1109
- console.log(" Claude Code Setup");
1110
- console.log(" ========================================");
1111
- console.log("");
1112
- const installResult = await installClaude();
1113
- if (!installResult.success) {
1114
- console.error("");
1115
- console.error(" Failed to install Claude Code:", installResult.error);
1116
- console.error("");
1117
- console.error(" You can install manually from: https://claude.ai/code");
1118
- console.error("");
1119
- console.log(" Next steps (manual):");
1120
- console.log(" 1. Install Claude Code from https://claude.ai/code");
1121
- console.log(" 2. Restart your terminal");
1122
- console.log(" 3. Run: claude --dangerously-skip-permissions");
1123
- console.log("");
1124
- process.exit(0);
1125
- }
1126
- if (installResult.migrated) {
1127
- console.log("");
1128
- console.log(" Migrated to native installer (auto-updates enabled).");
1129
- } else if (installResult.alreadyInstalled) {
1130
- console.log(" Claude Code is ready (native installer).");
1131
- } else {
1132
- console.log("");
1133
- console.log(" Claude Code installed successfully!");
1134
- }
1135
- if (!skipMcp && isClaudeMcpReady()) {
1136
- console.log("");
1137
- console.log(" ========================================");
1138
- console.log(" MCP Servers Setup");
1139
- console.log(" ========================================");
1140
- await installMcps();
1141
- } else if (!skipMcp) {
1142
- console.log("");
1143
- console.log(" MCP installation skipped (Claude CLI not ready).");
1144
- console.log(' Run "claude mcp list" after restart to verify.');
1145
- }
1146
- if (!skipMcp && isClaudePluginReady()) {
1147
- console.log("");
1148
- console.log(" ========================================");
1149
- console.log(" Plugin Setup");
1150
- console.log(" ========================================");
1151
- await installPlugins();
1152
- }
1153
- console.log("");
1154
- launchClaude(targetDir);
988
+ } else {
989
+ const spinner3 = createSpinner(phaseHeader(3, TOTAL_PHASES, "Installing MCP servers..."));
990
+ if (skipMcp) {
991
+ spinner3.succeed(phaseHeader(3, TOTAL_PHASES, `MCP servers ${c.dim}${"\xB7".repeat(17)}${c.reset} skipped (--no-mcp)`));
1155
992
  } else {
1156
- console.log("\n Next steps:");
1157
- console.log(" 1. Edit .claude/config/project-config.json with your stack");
1158
- console.log(" 2. Run: claude --dangerously-skip-permissions");
1159
- console.log(" 3. Follow the agent workflow for your development\n");
993
+ spinner3.fail(phaseHeader(3, TOTAL_PHASES, `MCP servers ${c.dim}${"\xB7".repeat(17)}${c.reset} skipped (CLI not ready)`));
1160
994
  }
1161
- } catch (error) {
1162
- console.error("\n Error during setup:", error);
1163
- process.exit(1);
1164
995
  }
996
+ const phase4Start = Date.now();
997
+ if (!skipMcp && isClaudePluginReady()) {
998
+ const spinner4 = createSpinner(phaseHeader(4, TOTAL_PHASES, "Installing plugins..."));
999
+ const pluginResult = await installPlugins((current, total, name) => {
1000
+ spinner4.update(phaseHeader(4, TOTAL_PHASES, `Installing plugins... ${c.dim}${current}/${total} ${name}${c.reset}`));
1001
+ });
1002
+ const pluginOk = pluginResult.installed + pluginResult.skipped;
1003
+ const pluginTotal = pluginOk + pluginResult.failed;
1004
+ const pluginSummary = `${pluginOk}/${pluginTotal} installed`;
1005
+ spinner4.succeed(phaseHeader(4, TOTAL_PHASES, `Plugins ${c.dim}${"\xB7".repeat(21)}${c.reset} ${pluginSummary} ${c.dim}${formatElapsed(phase4Start)}${c.reset}`));
1006
+ const plugins = getRecommendedPlugins();
1007
+ for (let i = 0;i < pluginResult.results.length; i++) {
1008
+ const r = pluginResult.results[i];
1009
+ const plugin = plugins[i];
1010
+ const isLast = i === pluginResult.results.length - 1;
1011
+ console.log(treeItem(plugin.name, plugin.description, isLast, r.success));
1012
+ }
1013
+ } else {
1014
+ const spinner4 = createSpinner(phaseHeader(4, TOTAL_PHASES, "Installing plugins..."));
1015
+ spinner4.succeed(phaseHeader(4, TOTAL_PHASES, `Plugins ${c.dim}${"\xB7".repeat(21)}${c.reset} ${c.dim}deferred (will auto-prompt)${c.reset}`));
1016
+ }
1017
+ const launchMode = newSession ? "new session" : "resuming last session";
1018
+ console.log(` ${c.green}\u2713${c.reset} ${phaseHeader(5, TOTAL_PHASES, `Launching Claude Code ${c.dim}${"\xB7".repeat(7)}${c.reset} ${launchMode}`)}`);
1019
+ printOptionalMcps();
1020
+ console.log("");
1021
+ console.log(` ${c.green}Setup complete${c.reset} in ${formatElapsed(globalStart)}`);
1022
+ console.log("");
1023
+ launchClaude(targetDir, { newSession });
1165
1024
  }
1166
1025
  main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "start-vibing",
3
- "version": "2.0.50",
3
+ "version": "3.0.0",
4
4
  "description": "Setup Claude Code agents, skills, and hooks in your project. Smart copy that preserves your custom domains and configurations.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,7 +23,8 @@
23
23
  "typescript-lsp@claude-plugins-official": true,
24
24
  "code-review@claude-plugins-official": true,
25
25
  "security-guidance@claude-plugins-official": true,
26
- "commit-commands@claude-plugins-official": true
26
+ "commit-commands@claude-plugins-official": true,
27
+ "frontend-design@claude-plugins-official": true
27
28
  },
28
29
 
29
30
  "context": {