start-vibing 3.0.9 → 4.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/README.md CHANGED
@@ -53,10 +53,8 @@ Creates a `.claude/` folder with:
53
53
 
54
54
  ```
55
55
  .claude/
56
- ├── agents/ # 6 specialized AI subagents
56
+ ├── agents/ # 4 specialized AI subagents
57
57
  │ ├── research-web.md # Best practices research
58
- │ ├── documenter.md # Domain documentation
59
- │ ├── domain-updater.md # Session learnings
60
58
  │ ├── commit-manager.md # Git workflow
61
59
  │ ├── claude-md-compactor.md # CLAUDE.md maintenance
62
60
  │ └── tester-unit.md # Unit testing
@@ -68,7 +66,6 @@ Creates a `.claude/` folder with:
68
66
  │ └── ...
69
67
  ├── config/ # Project configuration
70
68
  │ ├── project-config.json
71
- │ ├── domain-mapping.json
72
69
  │ └── ...
73
70
  └── commands/ # Slash commands
74
71
  ```
@@ -83,18 +80,16 @@ Checks for updates on every run (cached for 1 hour) and notifies you when a new
83
80
 
84
81
  ## Architecture
85
82
 
86
- ### 6 Subagents
83
+ ### 4 Subagents
87
84
 
88
85
  | Agent | Purpose |
89
86
  | ------------------ | ------------------------------------ |
90
87
  | research-web | Researches best practices (2024-2026)|
91
- | documenter | Maps files to domains, creates docs |
92
- | domain-updater | Records learnings in domain docs |
93
88
  | commit-manager | Manages git commits |
94
89
  | claude-md-compactor| Compacts CLAUDE.md when > 40k chars |
95
90
  | tester-unit | Creates unit tests with Vitest |
96
91
 
97
- ### 5 Plugins (auto-install)
92
+ ### 9 Plugins (auto-install)
98
93
 
99
94
  | Plugin | Mechanism | Purpose |
100
95
  | ------------------ | ---------------- | -------------------------- |
@@ -103,6 +98,10 @@ Checks for updates on every run (cached for 1 hour) and notifies you when a new
103
98
  | code-review | /code-review cmd | Code quality analysis |
104
99
  | commit-commands | /commit cmd | Git commit/push/PR flows |
105
100
  | frontend-design | /frontend-design | Production-grade UI design |
101
+ | superpowers | Skills + cmds | TDD, planning, debugging |
102
+ | ralph-loop | /ralph-loop cmd | Autonomous iteration loop |
103
+ | context7 | Skill + agent | Auto library documentation |
104
+ | code-simplifier | /simplify cmd | Code refinement |
106
105
 
107
106
  ### 20 Skills
108
107
 
package/dist/cli.js CHANGED
@@ -122,8 +122,8 @@ async function copyClaudeSetup(targetDir, options = {}) {
122
122
  }
123
123
 
124
124
  // src/cli.ts
125
- import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
126
- import { join as join4, dirname as dirname2 } from "path";
125
+ import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
126
+ import { join as join5, dirname as dirname2 } from "path";
127
127
  import { fileURLToPath as fileURLToPath2 } from "url";
128
128
  import { execSync as execSync3 } from "child_process";
129
129
 
@@ -508,12 +508,6 @@ function ensureHooksEnabled() {
508
508
  // src/mcp.ts
509
509
  import { spawnSync as spawnSync2, spawn as spawn2 } from "child_process";
510
510
  var CORE_MCPS = [
511
- {
512
- name: "context7",
513
- description: "real-time docs",
514
- command: "npx",
515
- args: ["-y", "@upstash/context7-mcp@latest"]
516
- },
517
511
  {
518
512
  name: "sequential-thinking",
519
513
  description: "structured reasoning",
@@ -581,20 +575,10 @@ function isMcpInstalled(name) {
581
575
  }
582
576
  async function installMcp(server) {
583
577
  if (isMcpInstalled(server.name)) {
584
- return {
585
- server: server.name,
586
- success: true,
587
- message: "Already installed",
588
- skipped: true
589
- };
578
+ return { server: server.name, success: true, message: "Already installed", skipped: true };
590
579
  }
591
580
  return new Promise((resolve) => {
592
- let args;
593
- if (server.transport === "http" && server.url) {
594
- args = server.args;
595
- } else {
596
- args = ["mcp", "add", "-s", "user", server.name, "--", server.command, ...server.args];
597
- }
581
+ const args = ["mcp", "add", "-s", "user", server.name, "--", server.command, ...server.args];
598
582
  const proc = spawn2("claude", args, {
599
583
  shell: true,
600
584
  stdio: ["pipe", "pipe", "pipe"]
@@ -608,54 +592,30 @@ async function installMcp(server) {
608
592
  stderr += data.toString();
609
593
  });
610
594
  proc.on("close", (code) => {
611
- if (code === 0) {
612
- resolve({
613
- server: server.name,
614
- success: true,
615
- message: "Installed"
616
- });
617
- } else {
618
- resolve({
619
- server: server.name,
620
- success: false,
621
- message: stderr || stdout || `Exit code: ${code}`
622
- });
623
- }
595
+ resolve(code === 0 ? { server: server.name, success: true, message: "Installed" } : { server: server.name, success: false, message: stderr || stdout || `Exit code: ${code}` });
624
596
  });
625
597
  proc.on("error", (err) => {
626
- resolve({
627
- server: server.name,
628
- success: false,
629
- message: err.message
630
- });
598
+ resolve({ server: server.name, success: false, message: err.message });
631
599
  });
632
600
  setTimeout(() => {
633
601
  proc.kill();
634
- resolve({
635
- server: server.name,
636
- success: false,
637
- message: "Installation timed out"
638
- });
602
+ resolve({ server: server.name, success: false, message: "Installation timed out" });
639
603
  }, 60000);
640
604
  });
641
605
  }
642
606
  async function installMcps(onProgress) {
643
607
  if (!isClaudeMcpReady()) {
644
- return {
645
- installed: 0,
646
- failed: 0,
647
- skipped: CORE_MCPS.length,
648
- results: []
649
- };
608
+ return { installed: 0, failed: 0, skipped: CORE_MCPS.length, results: [] };
650
609
  }
651
- const results = [];
652
610
  const total = CORE_MCPS.length;
653
- for (let i = 0;i < total; i++) {
654
- const server = CORE_MCPS[i];
655
- onProgress?.(i + 1, total, server.name);
611
+ let completed = 0;
612
+ const promises = CORE_MCPS.map(async (server) => {
656
613
  const result = await installMcp(server);
657
- results.push(result);
658
- }
614
+ completed++;
615
+ onProgress?.(completed, total, server.name);
616
+ return result;
617
+ });
618
+ const results = await Promise.all(promises);
659
619
  const installed = results.filter((r) => r.success && !r.skipped).length;
660
620
  const failed = results.filter((r) => !r.success).length;
661
621
  const skipped = results.filter((r) => r.skipped).length;
@@ -668,31 +628,15 @@ function getCoreMcps() {
668
628
  // src/plugins.ts
669
629
  import { spawn as spawn3, spawnSync as spawnSync3 } from "child_process";
670
630
  var RECOMMENDED_PLUGINS = [
671
- {
672
- name: "typescript-lsp",
673
- marketplace: "claude-plugins-official",
674
- description: "code intelligence"
675
- },
676
- {
677
- name: "code-review",
678
- marketplace: "claude-plugins-official",
679
- description: "PR analysis"
680
- },
681
- {
682
- name: "security-guidance",
683
- marketplace: "claude-plugins-official",
684
- description: "OWASP protection"
685
- },
686
- {
687
- name: "commit-commands",
688
- marketplace: "claude-plugins-official",
689
- description: "git workflows"
690
- },
691
- {
692
- name: "frontend-design",
693
- marketplace: "claude-plugins-official",
694
- description: "UI design"
695
- }
631
+ { name: "typescript-lsp", marketplace: "claude-plugins-official", description: "code intelligence" },
632
+ { name: "security-guidance", marketplace: "claude-plugins-official", description: "OWASP protection" },
633
+ { name: "code-review", marketplace: "claude-plugins-official", description: "PR analysis" },
634
+ { name: "commit-commands", marketplace: "claude-plugins-official", description: "git workflows" },
635
+ { name: "frontend-design", marketplace: "claude-plugins-official", description: "UI design" },
636
+ { name: "superpowers", marketplace: "claude-plugins-official", description: "TDD, debugging, planning" },
637
+ { name: "ralph-loop", marketplace: "claude-plugins-official", description: "iterative dev loop" },
638
+ { name: "context7", marketplace: "claude-plugins-official", description: "auto library docs" },
639
+ { name: "code-simplifier", marketplace: "claude-plugins-official", description: "code refinement" }
696
640
  ];
697
641
  function isClaudePluginReady() {
698
642
  if (!commandExists("claude"))
@@ -728,12 +672,7 @@ function isPluginInstalled(name, marketplace) {
728
672
  async function installPlugin(plugin) {
729
673
  const pluginId = `${plugin.name}@${plugin.marketplace}`;
730
674
  if (isPluginInstalled(plugin.name, plugin.marketplace)) {
731
- return {
732
- plugin: pluginId,
733
- success: true,
734
- message: "Already installed",
735
- skipped: true
736
- };
675
+ return { plugin: pluginId, success: true, message: "Already installed", skipped: true };
737
676
  }
738
677
  return new Promise((resolve) => {
739
678
  const args = ["plugin", "install", pluginId, "--scope", "user"];
@@ -743,6 +682,12 @@ async function installPlugin(plugin) {
743
682
  });
744
683
  let stdout = "";
745
684
  let stderr = "";
685
+ if (proc.stdin) {
686
+ proc.stdin.write("y\n");
687
+ proc.stdin.write("y\n");
688
+ proc.stdin.write("y\n");
689
+ proc.stdin.end();
690
+ }
746
691
  proc.stdout?.on("data", (data) => {
747
692
  stdout += data.toString();
748
693
  });
@@ -750,54 +695,30 @@ async function installPlugin(plugin) {
750
695
  stderr += data.toString();
751
696
  });
752
697
  proc.on("close", (code) => {
753
- if (code === 0) {
754
- resolve({
755
- plugin: pluginId,
756
- success: true,
757
- message: "Installed"
758
- });
759
- } else {
760
- resolve({
761
- plugin: pluginId,
762
- success: false,
763
- message: stderr || stdout || `Exit code: ${code}`
764
- });
765
- }
698
+ resolve(code === 0 ? { plugin: pluginId, success: true, message: "Installed" } : { plugin: pluginId, success: false, message: stderr || stdout || `Exit code: ${code}` });
766
699
  });
767
700
  proc.on("error", (err) => {
768
- resolve({
769
- plugin: pluginId,
770
- success: false,
771
- message: err.message
772
- });
701
+ resolve({ plugin: pluginId, success: false, message: err.message });
773
702
  });
774
703
  setTimeout(() => {
775
704
  proc.kill();
776
- resolve({
777
- plugin: pluginId,
778
- success: false,
779
- message: "Installation timed out"
780
- });
705
+ resolve({ plugin: pluginId, success: false, message: "Installation timed out" });
781
706
  }, 30000);
782
707
  });
783
708
  }
784
709
  async function installPlugins(onProgress) {
785
710
  if (!isClaudePluginReady()) {
786
- return {
787
- installed: 0,
788
- failed: 0,
789
- skipped: RECOMMENDED_PLUGINS.length,
790
- results: []
791
- };
711
+ return { installed: 0, failed: 0, skipped: RECOMMENDED_PLUGINS.length, results: [] };
792
712
  }
793
- const results = [];
794
713
  const total = RECOMMENDED_PLUGINS.length;
795
- for (let i = 0;i < total; i++) {
796
- const plugin = RECOMMENDED_PLUGINS[i];
797
- onProgress?.(i + 1, total, plugin.name);
714
+ let completed = 0;
715
+ const promises = RECOMMENDED_PLUGINS.map(async (plugin) => {
798
716
  const result = await installPlugin(plugin);
799
- results.push(result);
800
- }
717
+ completed++;
718
+ onProgress?.(completed, total, plugin.name);
719
+ return result;
720
+ });
721
+ const results = await Promise.all(promises);
801
722
  const installed = results.filter((r) => r.success && !r.skipped).length;
802
723
  const failed = results.filter((r) => !r.success).length;
803
724
  const skipped = results.filter((r) => r.skipped).length;
@@ -807,6 +728,98 @@ function getRecommendedPlugins() {
807
728
  return RECOMMENDED_PLUGINS;
808
729
  }
809
730
 
731
+ // src/skills.ts
732
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
733
+ import { join as join4 } from "path";
734
+ import https from "https";
735
+ var GITHUB_RAW = "https://raw.githubusercontent.com";
736
+ var RECOMMENDED_SKILLS = [
737
+ { name: "react-best-practices", url: `${GITHUB_RAW}/vercel-labs/agent-skills/main/skills/react-best-practices/SKILL.md`, description: "React/Next.js perf rules" },
738
+ { name: "web-design-guidelines", url: `${GITHUB_RAW}/vercel-labs/agent-skills/main/skills/web-design-guidelines/SKILL.md`, description: "WCAG + UX audit" },
739
+ { name: "composition-patterns", url: `${GITHUB_RAW}/vercel-labs/agent-skills/main/skills/composition-patterns/SKILL.md`, description: "compound components" },
740
+ { name: "webapp-testing", url: `${GITHUB_RAW}/anthropics/skills/main/skills/webapp-testing/SKILL.md`, description: "real browser testing" },
741
+ { name: "mcp-builder", url: `${GITHUB_RAW}/anthropics/skills/main/skills/mcp-builder/SKILL.md`, description: "MCP server development" },
742
+ { name: "typeui-artistic", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/artistic/SKILL.md`, description: "artistic design system" },
743
+ { name: "typeui-application", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/application/SKILL.md`, description: "application design system" },
744
+ { name: "typeui-ant", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/ant/SKILL.md`, description: "ant design system" },
745
+ { name: "typeui-dashboard", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/dashboard/SKILL.md`, description: "dashboard design system" },
746
+ { name: "typeui-dramatic", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/dramatic/SKILL.md`, description: "dramatic design system" },
747
+ { name: "typeui-doodle", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/doodle/SKILL.md`, description: "doodle design system" },
748
+ { name: "typeui-bento", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/bento/SKILL.md`, description: "bento design system" },
749
+ { name: "typeui-bold", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/bold/SKILL.md`, description: "bold design system" },
750
+ { name: "typeui-clean", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/clean/SKILL.md`, description: "clean design system" },
751
+ { name: "typeui-enterprise", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/enterprise/SKILL.md`, description: "enterprise design system" },
752
+ { name: "typeui-neobrutalism", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/neobrutalism/SKILL.md`, description: "neobrutalism design system" },
753
+ { name: "typeui-paper", url: `${GITHUB_RAW}/bergside/awesome-design-skills/main/skills/paper/SKILL.md`, description: "paper design system" }
754
+ ];
755
+ function fetchUrl(url) {
756
+ return new Promise((resolve, reject) => {
757
+ const request = https.get(url, { headers: { "User-Agent": '"start-vibing"' } }, (res) => {
758
+ if (res.statusCode === 301 || res.statusCode === 302) {
759
+ const location = res.headers["location"];
760
+ if (location) {
761
+ fetchUrl(location).then(resolve, reject);
762
+ return;
763
+ }
764
+ }
765
+ if (res.statusCode !== 200) {
766
+ reject(new Error(`HTTP ${res.statusCode}`));
767
+ return;
768
+ }
769
+ let data = "";
770
+ res.on("data", (chunk) => {
771
+ data += chunk;
772
+ });
773
+ res.on("end", () => resolve(data));
774
+ res.on("error", reject);
775
+ });
776
+ request.on("error", reject);
777
+ request.setTimeout(15000, () => {
778
+ request.destroy();
779
+ reject(new Error("Timeout"));
780
+ });
781
+ });
782
+ }
783
+ async function installSkill(skill) {
784
+ try {
785
+ const skillDir = join4(process.cwd(), ".claude", "skills", skill.name);
786
+ const skillFile = join4(skillDir, "SKILL.md");
787
+ if (existsSync4(skillFile)) {
788
+ return { skill: skill.name, success: true, message: "Already installed", skipped: true };
789
+ }
790
+ const content = await fetchUrl(skill.url);
791
+ if (!content || content.length < 10) {
792
+ return { skill: skill.name, success: false, message: "Empty response" };
793
+ }
794
+ mkdirSync3(skillDir, { recursive: true });
795
+ writeFileSync4(skillFile, content, "utf-8");
796
+ return { skill: skill.name, success: true, message: "Installed" };
797
+ } catch (err) {
798
+ const msg = err instanceof Error ? err.message : String(err);
799
+ return { skill: skill.name, success: false, message: msg };
800
+ }
801
+ }
802
+ async function installSkills(onProgress) {
803
+ const total = RECOMMENDED_SKILLS.length;
804
+ let completed = 0;
805
+ const promises = RECOMMENDED_SKILLS.map(async (skill) => {
806
+ const result = await installSkill(skill);
807
+ completed++;
808
+ onProgress?.(completed, total, skill.name);
809
+ return result;
810
+ });
811
+ const results = await Promise.all(promises);
812
+ const installed = results.filter((r) => r.success).length;
813
+ const failed = results.filter((r) => !r.success).length;
814
+ return { installed, failed, results };
815
+ }
816
+ function isSkillInstallReady() {
817
+ return true;
818
+ }
819
+ function getRecommendedSkills() {
820
+ return RECOMMENDED_SKILLS;
821
+ }
822
+
810
823
  // src/ui.ts
811
824
  var c = {
812
825
  reset: "\x1B[0m",
@@ -824,15 +837,15 @@ var c = {
824
837
  };
825
838
  var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
826
839
  function createBanner(version) {
840
+ const date = new Date().toISOString().slice(0, 10);
827
841
  return `
828
- ${c.redBright} /\\ /\\
829
- ${c.redBright} / \\\\ ${c.white}\u2588\u2588\u2557 \u2588\u2588\u2557${c.redBright} / \\\\
830
- ${c.redBright} / \\\\ ${c.white}\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551${c.redBright} / \\\\
831
- ${c.redBright} / /\\ \\\\${c.white}\u2588\u2588\u2554\u2550\u2588\u2588\u2554\u2550\u2588\u2588\u2551${c.redBright} / /\\ \\\\
832
- ${c.redBright} / / \\ \\\\${c.white}\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551${c.redBright} / / \\ \\\\
833
- ${c.redBright}/_/ \\__\\\\${c.white}\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D${c.redBright} /_/ \\__\\\\
834
- ${c.reset}
835
- ${c.bright} START VIBING${c.reset}${c.dim} \xB7 AI-powered dev workflow \xB7 v${version}${c.reset}
842
+ ${c.cyan} __ __ ___ ____ ___ _ _ ____
843
+ ${c.cyan} \\ \\ / /|_ _|| __ ) |_ _|| \\ | | / ___|
844
+ ${c.cyan} \\ \\ / / | | | _ \\ | | | \\| || | _
845
+ ${c.cyan} \\ \\/ / | | | |_) | | | | |\\ || |_| |
846
+ ${c.cyan} \\__/ |___||____/ |___||_| \\_| \\____|${c.reset}
847
+
848
+ ${c.bright} v${version}${c.reset}${c.dim} \xB7 ${date} \xB7 9 plugins \xB7 17 skills \xB7 8 MCPs${c.reset}
836
849
  `;
837
850
  }
838
851
  function createSpinner(initialText) {
@@ -895,22 +908,22 @@ function printOptionalMcps() {
895
908
  // src/cli.ts
896
909
  var __filename3 = fileURLToPath2(import.meta.url);
897
910
  var __dirname3 = dirname2(__filename3);
898
- var TOTAL_PHASES = 5;
911
+ var TOTAL_PHASES = 6;
899
912
  function getVersion() {
900
913
  try {
901
914
  const paths = [
902
- join4(__dirname3, "..", "package.json"),
903
- join4(__dirname3, "..", "..", "package.json")
915
+ join5(__dirname3, "..", "package.json"),
916
+ join5(__dirname3, "..", "..", "package.json")
904
917
  ];
905
918
  for (const pkgPath of paths) {
906
- if (existsSync4(pkgPath)) {
919
+ if (existsSync5(pkgPath)) {
907
920
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
908
- return pkg.version || "3.0.0";
921
+ return pkg.version || "4.0.0";
909
922
  }
910
923
  }
911
- return "3.0.0";
924
+ return "4.0.0";
912
925
  } catch {
913
- return "3.0.0";
926
+ return "4.0.0";
914
927
  }
915
928
  }
916
929
  var VERSION = getVersion();
@@ -930,14 +943,14 @@ function autoCommitClaudeFiles(targetDir) {
930
943
  return { success: true, message: "No changes to commit" };
931
944
  }
932
945
  execSync3("git add .claude/ CLAUDE.md", { cwd: targetDir, stdio: "pipe" });
933
- execSync3(`git commit --no-verify -m "chore: update Claude Code agents and skills (start-vibing v${VERSION})"`, { cwd: targetDir, stdio: "pipe" });
946
+ execSync3(`git commit --no-verify -m "chore: update Claude Code setup (start-vibing v${VERSION})"`, { cwd: targetDir, stdio: "pipe" });
934
947
  return { success: true, message: "Changes committed" };
935
948
  } catch {
936
949
  return { success: false, message: "Commit failed (non-critical)" };
937
950
  }
938
951
  }
939
952
  var HELP = `${createBanner(VERSION)}
940
- Setup Claude Code agents, skills, and hooks in your project.
953
+ Setup Claude Code agents, skills, plugins, and MCP servers.
941
954
 
942
955
  ${c.bright}Usage:${c.reset}
943
956
  npx start-vibing [options]
@@ -947,16 +960,26 @@ var HELP = `${createBanner(VERSION)}
947
960
  --force Overwrite all files (including custom domains)
948
961
  --no-claude Skip Claude Code installation and launch
949
962
  --no-mcp Skip MCP server installation
963
+ --no-skills Skip community skills installation
950
964
  --no-update-check Skip checking for start-vibing updates
951
965
  --help, -h Show this help message
952
966
  --version, -v Show version
953
967
 
954
968
  ${c.bright}What it does:${c.reset}
955
- [1] Copies template files (agents, skills, hooks, config)
969
+ [1] Copies template files (agents, skills, config)
956
970
  [2] Sets up Claude Code (install/migrate if needed)
957
- [3] Installs MCP servers (Context7, Playwright, Memory, etc.)
958
- [4] Installs plugins (TypeScript LSP, Code Review, Security, etc.)
959
- [5] Launches Claude Code (resumes last session by default)
971
+ [3] Installs MCP servers in parallel (Playwright, Memory, etc.)
972
+ [4] Installs plugins in parallel (Superpowers, Ralph Loop, Context7, etc.)
973
+ [5] Installs community skills (Vercel, Anthropic, etc.)
974
+ [6] Launches Claude Code (resumes last session by default)
975
+
976
+ ${c.bright}Plugins (9):${c.reset}
977
+ typescript-lsp, security-guidance, code-review, commit-commands,
978
+ frontend-design, superpowers, ralph-loop, context7, code-simplifier
979
+
980
+ ${c.bright}Skills (17):${c.reset}
981
+ react-best-practices, web-design-guidelines, composition-patterns,
982
+ webapp-testing, mcp-builder, + 12 typeui.sh design systems
960
983
 
961
984
  ${c.dim}https://github.com/LimaTechnologies/ai-development${c.reset}
962
985
  `;
@@ -973,6 +996,7 @@ async function main() {
973
996
  const force = args.includes("--force");
974
997
  const skipClaude = args.includes("--no-claude");
975
998
  const skipMcp = args.includes("--no-mcp");
999
+ const skipSkills = args.includes("--no-skills");
976
1000
  const skipUpdateCheck = args.includes("--no-update-check");
977
1001
  const newSession = args.includes("--new");
978
1002
  const targetDir = process.cwd();
@@ -1000,7 +1024,7 @@ async function main() {
1000
1024
  const result = await copyClaudeSetup(targetDir, { force });
1001
1025
  autoCommitClaudeFiles(targetDir);
1002
1026
  ensureHooksEnabled();
1003
- const counts = `${result.agents} agents, ${result.skills} skills, ${result.hooks} hooks`;
1027
+ const counts = `${result.agents} agents, ${result.skills} skills`;
1004
1028
  spinner1.succeed(phaseHeader(1, TOTAL_PHASES, `Template files ${c.dim}${"\xB7".repeat(14)}${c.reset} ${counts} ${c.dim}${formatElapsed(phase1Start)}${c.reset}`));
1005
1029
  if (result.preserved > 0) {
1006
1030
  console.log(` ${c.dim}(preserved ${result.preserved} custom file(s))${c.reset}`);
@@ -1030,9 +1054,9 @@ async function main() {
1030
1054
  spinner2.succeed(phaseHeader(2, TOTAL_PHASES, `Claude Code ${c.dim}${"\xB7".repeat(18)}${c.reset} ${claudeStatus} ${c.dim}${formatElapsed(phase2Start)}${c.reset}`));
1031
1055
  const phase3Start = Date.now();
1032
1056
  if (!skipMcp && isClaudeMcpReady()) {
1033
- const spinner3 = createSpinner(phaseHeader(3, TOTAL_PHASES, "Installing MCP servers..."));
1034
- const mcpResult = await installMcps((current, total, name) => {
1035
- spinner3.update(phaseHeader(3, TOTAL_PHASES, `Installing MCP servers... ${c.dim}${current}/${total} ${name}${c.reset}`));
1057
+ const spinner3 = createSpinner(phaseHeader(3, TOTAL_PHASES, "Installing MCP servers (parallel)..."));
1058
+ const mcpResult = await installMcps((current, total) => {
1059
+ spinner3.update(phaseHeader(3, TOTAL_PHASES, `Installing MCP servers... ${c.dim}${current}/${total} done${c.reset}`));
1036
1060
  });
1037
1061
  const mcpOk = mcpResult.installed + mcpResult.skipped;
1038
1062
  const mcpTotal = mcpOk + mcpResult.failed;
@@ -1055,9 +1079,9 @@ async function main() {
1055
1079
  }
1056
1080
  const phase4Start = Date.now();
1057
1081
  if (!skipMcp && isClaudePluginReady()) {
1058
- const spinner4 = createSpinner(phaseHeader(4, TOTAL_PHASES, "Installing plugins..."));
1059
- const pluginResult = await installPlugins((current, total, name) => {
1060
- spinner4.update(phaseHeader(4, TOTAL_PHASES, `Installing plugins... ${c.dim}${current}/${total} ${name}${c.reset}`));
1082
+ const spinner4 = createSpinner(phaseHeader(4, TOTAL_PHASES, "Installing plugins (parallel)..."));
1083
+ const pluginResult = await installPlugins((current, total) => {
1084
+ spinner4.update(phaseHeader(4, TOTAL_PHASES, `Installing plugins... ${c.dim}${current}/${total} done${c.reset}`));
1061
1085
  });
1062
1086
  const pluginOk = pluginResult.installed + pluginResult.skipped;
1063
1087
  const pluginTotal = pluginOk + pluginResult.failed;
@@ -1074,10 +1098,33 @@ async function main() {
1074
1098
  const spinner4 = createSpinner(phaseHeader(4, TOTAL_PHASES, "Installing plugins..."));
1075
1099
  spinner4.succeed(phaseHeader(4, TOTAL_PHASES, `Plugins ${c.dim}${"\xB7".repeat(21)}${c.reset} ${c.dim}deferred (will auto-prompt)${c.reset}`));
1076
1100
  }
1101
+ const phase5Start = Date.now();
1102
+ if (!skipSkills && isSkillInstallReady()) {
1103
+ const spinner5 = createSpinner(phaseHeader(5, TOTAL_PHASES, "Installing community skills (parallel)..."));
1104
+ const skillResult = await installSkills((current, total) => {
1105
+ spinner5.update(phaseHeader(5, TOTAL_PHASES, `Installing skills... ${c.dim}${current}/${total} done${c.reset}`));
1106
+ });
1107
+ const skillSummary = `${skillResult.installed}/${skillResult.installed + skillResult.failed} installed`;
1108
+ spinner5.succeed(phaseHeader(5, TOTAL_PHASES, `Community skills ${c.dim}${"\xB7".repeat(11)}${c.reset} ${skillSummary} ${c.dim}${formatElapsed(phase5Start)}${c.reset}`));
1109
+ const skills = getRecommendedSkills();
1110
+ for (let i = 0;i < skillResult.results.length; i++) {
1111
+ const r = skillResult.results[i];
1112
+ const skill = skills[i];
1113
+ const isLast = i === skillResult.results.length - 1;
1114
+ console.log(treeItem(skill.name, skill.description, isLast, r.success));
1115
+ }
1116
+ } else {
1117
+ const spinner5 = createSpinner(phaseHeader(5, TOTAL_PHASES, "Installing community skills..."));
1118
+ if (skipSkills) {
1119
+ spinner5.succeed(phaseHeader(5, TOTAL_PHASES, `Community skills ${c.dim}${"\xB7".repeat(11)}${c.reset} skipped (--no-skills)`));
1120
+ } else {
1121
+ spinner5.fail(phaseHeader(5, TOTAL_PHASES, `Community skills ${c.dim}${"\xB7".repeat(11)}${c.reset} skipped (npx not found)`));
1122
+ }
1123
+ }
1077
1124
  const sessionExists = hasExistingSession(targetDir);
1078
1125
  const willResume = !newSession && sessionExists;
1079
1126
  const launchMode = newSession ? "new session" : willResume ? "resuming last session" : "new session";
1080
- console.log(` ${c.green}\u2713${c.reset} ${phaseHeader(5, TOTAL_PHASES, `Launching Claude Code ${c.dim}${"\xB7".repeat(7)}${c.reset} ${launchMode}`)}`);
1127
+ console.log(` ${c.green}\u2713${c.reset} ${phaseHeader(6, TOTAL_PHASES, `Launching Claude Code ${c.dim}${"\xB7".repeat(7)}${c.reset} ${launchMode}`)}`);
1081
1128
  printOptionalMcps();
1082
1129
  console.log("");
1083
1130
  console.log(` ${c.green}Setup complete${c.reset} in ${formatElapsed(globalStart)}`);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "start-vibing",
3
- "version": "3.0.9",
4
- "description": "Setup Claude Code agents, skills, and hooks in your project. Smart copy that preserves your custom domains and configurations.",
3
+ "version": "4.0.0",
4
+ "description": "Setup Claude Code with 9 plugins, 6 community skills, and 8 MCP servers. Parallel install, auto-accept, superpowers + ralph-loop.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "start-vibing": "./dist/cli.js"
@@ -30,7 +30,7 @@
30
30
  "license": "MIT",
31
31
  "repository": {
32
32
  "type": "git",
33
- "url": "https://github.com/joaov/start-vibing"
33
+ "url": "https://github.com/LimaTechnologies/ai-development"
34
34
  },
35
35
  "engines": {
36
36
  "node": ">=18.0.0"