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 +241 -382
- package/package.json +1 -1
- package/template/.claude/settings.json +2 -1
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
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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
|
|
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
|
|
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
|
-
|
|
734
|
-
|
|
735
|
-
|
|
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
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
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: "
|
|
615
|
+
description: "code intelligence"
|
|
775
616
|
},
|
|
776
617
|
{
|
|
777
618
|
name: "code-review",
|
|
778
619
|
marketplace: "claude-plugins-official",
|
|
779
|
-
description: "
|
|
620
|
+
description: "PR analysis"
|
|
780
621
|
},
|
|
781
622
|
{
|
|
782
623
|
name: "security-guidance",
|
|
783
624
|
marketplace: "claude-plugins-official",
|
|
784
|
-
description: "
|
|
625
|
+
description: "OWASP protection"
|
|
785
626
|
},
|
|
786
627
|
{
|
|
787
628
|
name: "commit-commands",
|
|
788
629
|
marketplace: "claude-plugins-official",
|
|
789
|
-
description: "
|
|
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
|
-
|
|
897
|
-
|
|
898
|
-
|
|
727
|
+
return {
|
|
728
|
+
installed: 0,
|
|
729
|
+
failed: 0,
|
|
730
|
+
skipped: RECOMMENDED_PLUGINS.length,
|
|
731
|
+
results: []
|
|
732
|
+
};
|
|
899
733
|
}
|
|
900
734
|
const results = [];
|
|
901
|
-
|
|
902
|
-
|
|
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(` ${
|
|
916
|
-
console.log(` ${
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
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 || "
|
|
848
|
+
return pkg.version || "3.0.0";
|
|
938
849
|
}
|
|
939
850
|
}
|
|
940
|
-
return "
|
|
851
|
+
return "3.0.0";
|
|
941
852
|
} catch {
|
|
942
|
-
return "
|
|
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
|
-
|
|
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
|
|
971
|
-
|
|
972
|
-
return { success: false, message: errorMessage };
|
|
875
|
+
} catch {
|
|
876
|
+
return { success: false, message: "Commit failed (non-critical)" };
|
|
973
877
|
}
|
|
974
878
|
}
|
|
975
|
-
var
|
|
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
|
|
1006
|
-
2
|
|
1007
|
-
3
|
|
1008
|
-
4
|
|
1009
|
-
5
|
|
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
|
-
|
|
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
|
|
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(
|
|
1064
|
-
console.log(" Setting up Claude Code workflow...\n");
|
|
932
|
+
console.log(createBanner(VERSION));
|
|
1065
933
|
if (isRunningViaNpx()) {
|
|
1066
|
-
console.log(
|
|
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
|
|
1072
|
-
|
|
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
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
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(
|
|
946
|
+
console.log(` ${c.dim}(preserved ${result.preserved} custom file(s))${c.reset}`);
|
|
1086
947
|
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
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
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
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
|
-
|
|
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
|
@@ -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": {
|