start-vibing-stacks 1.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.
Files changed (40) hide show
  1. package/README.md +100 -0
  2. package/dist/detector.d.ts +16 -0
  3. package/dist/detector.js +103 -0
  4. package/dist/index.d.ts +8 -0
  5. package/dist/index.js +239 -0
  6. package/dist/installer.d.ts +30 -0
  7. package/dist/installer.js +224 -0
  8. package/dist/setup.d.ts +17 -0
  9. package/dist/setup.js +161 -0
  10. package/dist/types.d.ts +88 -0
  11. package/dist/types.js +4 -0
  12. package/dist/ui.d.ts +11 -0
  13. package/dist/ui.js +47 -0
  14. package/package.json +57 -0
  15. package/stacks/_shared/agents/claude-md-compactor.md +44 -0
  16. package/stacks/_shared/agents/commit-manager.md +65 -0
  17. package/stacks/_shared/agents/documenter.md +82 -0
  18. package/stacks/_shared/agents/domain-updater.md +51 -0
  19. package/stacks/_shared/agents/research-web.md +60 -0
  20. package/stacks/_shared/agents/tester.md +61 -0
  21. package/stacks/_shared/commands/feature.md +13 -0
  22. package/stacks/_shared/commands/fix.md +9 -0
  23. package/stacks/_shared/commands/validate.md +10 -0
  24. package/stacks/_shared/config/domain-mapping.json +41 -0
  25. package/stacks/_shared/config/security-rules.json +31 -0
  26. package/stacks/_shared/hooks/stop-validator.ts +171 -0
  27. package/stacks/_shared/hooks/user-prompt-submit.ts +77 -0
  28. package/stacks/_shared/skills/debugging-patterns/SKILL.md +39 -0
  29. package/stacks/_shared/skills/docker-patterns/SKILL.md +47 -0
  30. package/stacks/_shared/skills/git-workflow/SKILL.md +35 -0
  31. package/stacks/nodejs/stack.json +87 -0
  32. package/stacks/php/config/quality-gates.json +23 -0
  33. package/stacks/php/skills/composer-workflow/SKILL.md +78 -0
  34. package/stacks/php/skills/php-patterns/SKILL.md +119 -0
  35. package/stacks/php/skills/phpstan-analysis/SKILL.md +68 -0
  36. package/stacks/php/skills/phpunit-testing/SKILL.md +122 -0
  37. package/stacks/php/skills/security-scan-php/SKILL.md +80 -0
  38. package/stacks/php/stack.json +95 -0
  39. package/templates/CLAUDE-default.md +54 -0
  40. package/templates/CLAUDE-php.md +88 -0
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # 🎸 Start Vibing Stacks
2
+
3
+ **Multi-stack AI-powered development workflow for Claude Code.**
4
+
5
+ One command to set up agents, skills, hooks, and quality gates — tailored to your stack.
6
+
7
+ ## 🚀 Quick Start
8
+
9
+ ```bash
10
+ npx start-vibing-stacks
11
+ ```
12
+
13
+ Or install globally:
14
+
15
+ ```bash
16
+ npm install -g start-vibing-stacks
17
+ svs # shortcut
18
+ ```
19
+
20
+ ## ✨ Features
21
+
22
+ - **🔍 Auto-detection** — Scans your project files to suggest the right stack
23
+ - **🐘 PHP 8.3+** — PHPStan, PHPUnit, Composer, Laravel/Octane, Symfony, Vanilla
24
+ - **📦 Node.js/TS** — Vitest, TypeScript, Bun, Next.js, Express
25
+ - **🎯 Multi-framework** — Choose your framework, database, frontend, deploy target
26
+ - **🤖 6 Universal Agents** — research, documenter, domain-updater, commit-manager, tester, compactor
27
+ - **🛡️ Quality Gates** — Stack-specific validation before every commit
28
+ - **🔒 Security Skills** — OWASP checks adapted per language
29
+ - **📝 .cursorrules support** — Imports existing Cursor IDE rules
30
+ - **⚡ Auto-install** — Validates and installs missing deps (Homebrew on macOS)
31
+
32
+ ## 📋 Supported Stacks
33
+
34
+ | Stack | Status | Frameworks |
35
+ |-------|--------|------------|
36
+ | 🐘 PHP 8.3+ | ✅ Ready | Laravel, Laravel+Octane, Symfony, CodeIgniter, Vanilla |
37
+ | 📦 Node.js/TS | ✅ Ready | Next.js, Nuxt, Astro, Express, Fastify |
38
+ | 🐍 Python | 🔜 Soon | Django, FastAPI, Flask |
39
+ | 🦀 Rust | 🔜 Soon | Actix, Axum |
40
+ | 🐹 Go | 🔜 Soon | Gin, Echo |
41
+
42
+ ## 🏗️ What It Creates
43
+
44
+ ```
45
+ .claude/
46
+ ├── agents/ # 6 universal agents (stack-aware)
47
+ ├── skills/ # Stack-specific + shared skills
48
+ ├── hooks/ # stop-validator + prompt-inject
49
+ ├── config/ # Project config, quality gates, security rules
50
+ ├── commands/ # /feature, /fix, /validate
51
+ └── settings.json # Claude Code permissions
52
+ ```
53
+
54
+ ## 🔧 Options
55
+
56
+ ```bash
57
+ npx start-vibing-stacks [options]
58
+
59
+ --force Overwrite existing configuration
60
+ --no-claude Skip Claude Code installation
61
+ --no-install Skip dependency installation
62
+ --help, -h Show help
63
+ --version, -v Show version
64
+ ```
65
+
66
+ ## 🐘 PHP Requirements
67
+
68
+ When selecting the PHP stack, the tool validates and auto-installs:
69
+
70
+ - **PHP >= 8.3** (via `brew install php@8.3` on macOS)
71
+ - **Composer >= 2.0** (auto-installed using PHP if missing)
72
+ - **Node.js >= 18** (for frontend tooling)
73
+
74
+ ### Laravel + Octane (RoadRunner)
75
+
76
+ Select "Laravel + Octane (RoadRunner)" in the framework menu for:
77
+ - RoadRunner server configuration
78
+ - Octane-specific skills and patterns
79
+ - High-performance deployment guides
80
+
81
+ ## 📝 Cursor IDE Support
82
+
83
+ If `.cursorrules` is detected in your project, the rules are automatically imported into the Claude agent configuration. Both AI tools work with the same context.
84
+
85
+ ## 🔄 How It Works
86
+
87
+ 1. **Detect** — Scans project for `composer.json`, `package.json`, etc.
88
+ 2. **Select** — You choose stack, framework, database, frontend, deploy
89
+ 3. **Validate** — Checks system requirements, installs missing tools
90
+ 4. **Configure** — Copies agents, skills, hooks tailored to your choices
91
+ 5. **Launch** — Starts Claude Code with everything pre-configured
92
+
93
+ ## 📄 License
94
+
95
+ MIT
96
+
97
+ ## 🏠 Credits
98
+
99
+ Inspired by [start-vibing](https://www.npmjs.com/package/start-vibing).
100
+ Built by [FantasyLake](https://github.com/f1sc4ll-ai).
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Start Vibing Stacks — Project Detector
3
+ *
4
+ * Auto-detects project stack by scanning for known files.
5
+ * Also detects .cursorrules, CLAUDE.md, and git presence.
6
+ */
7
+ import type { DetectionResult } from './types.js';
8
+ export declare function detectProject(projectDir: string): DetectionResult;
9
+ /**
10
+ * Detect framework within a PHP project
11
+ */
12
+ export declare function detectPhpFramework(projectDir: string): string | null;
13
+ /**
14
+ * Detect framework within a Node.js project
15
+ */
16
+ export declare function detectNodeFramework(projectDir: string): string | null;
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Start Vibing Stacks — Project Detector
3
+ *
4
+ * Auto-detects project stack by scanning for known files.
5
+ * Also detects .cursorrules, CLAUDE.md, and git presence.
6
+ */
7
+ import { existsSync, readdirSync } from 'fs';
8
+ import { join } from 'path';
9
+ const STACK_SIGNATURES = [
10
+ // PHP
11
+ { id: 'php', files: ['composer.json'], weight: 90, reason: 'composer.json detected' },
12
+ { id: 'php', files: ['index.php'], weight: 60, reason: 'index.php detected' },
13
+ { id: 'php', files: ['artisan'], weight: 95, reason: 'Laravel artisan detected' },
14
+ { id: 'php', files: ['symfony.lock'], weight: 95, reason: 'Symfony lock detected' },
15
+ { id: 'php', files: ['public/index.php'], weight: 70, reason: 'public/index.php detected' },
16
+ { id: 'php', files: ['.php-version'], weight: 80, reason: '.php-version detected' },
17
+ // Node.js / TypeScript
18
+ { id: 'nodejs', files: ['package.json'], weight: 80, reason: 'package.json detected' },
19
+ { id: 'nodejs', files: ['tsconfig.json'], weight: 85, reason: 'tsconfig.json detected' },
20
+ { id: 'nodejs', files: ['bun.lockb'], weight: 90, reason: 'Bun lockfile detected' },
21
+ { id: 'nodejs', files: ['next.config.js'], weight: 95, reason: 'Next.js config detected' },
22
+ { id: 'nodejs', files: ['next.config.ts'], weight: 95, reason: 'Next.js TS config detected' },
23
+ { id: 'nodejs', files: ['next.config.mjs'], weight: 95, reason: 'Next.js config detected' },
24
+ // Python
25
+ { id: 'python', files: ['requirements.txt'], weight: 80, reason: 'requirements.txt detected' },
26
+ { id: 'python', files: ['pyproject.toml'], weight: 90, reason: 'pyproject.toml detected' },
27
+ { id: 'python', files: ['Pipfile'], weight: 85, reason: 'Pipfile detected' },
28
+ { id: 'python', files: ['setup.py'], weight: 75, reason: 'setup.py detected' },
29
+ // Rust
30
+ { id: 'rust', files: ['Cargo.toml'], weight: 95, reason: 'Cargo.toml detected' },
31
+ // Go
32
+ { id: 'go', files: ['go.mod'], weight: 95, reason: 'go.mod detected' },
33
+ ];
34
+ export function detectProject(projectDir) {
35
+ const result = {
36
+ files: [],
37
+ stacks: [],
38
+ hasCursorRules: false,
39
+ hasClaudeMd: false,
40
+ hasGit: false,
41
+ };
42
+ // Scan top-level files
43
+ try {
44
+ result.files = readdirSync(projectDir);
45
+ }
46
+ catch {
47
+ return result;
48
+ }
49
+ // Check for Cursor IDE rules
50
+ result.hasCursorRules =
51
+ existsSync(join(projectDir, '.cursorrules')) ||
52
+ existsSync(join(projectDir, '.cursor', 'rules'));
53
+ // Check for existing CLAUDE.md
54
+ result.hasClaudeMd = existsSync(join(projectDir, 'CLAUDE.md'));
55
+ // Check for git
56
+ result.hasGit = existsSync(join(projectDir, '.git'));
57
+ // Score each stack
58
+ const stackScores = new Map();
59
+ for (const sig of STACK_SIGNATURES) {
60
+ const allExist = sig.files.every((f) => existsSync(join(projectDir, f)));
61
+ if (allExist) {
62
+ const existing = stackScores.get(sig.id) || { confidence: 0, reasons: [] };
63
+ existing.confidence = Math.min(100, existing.confidence + sig.weight);
64
+ existing.reasons.push(sig.reason);
65
+ stackScores.set(sig.id, existing);
66
+ }
67
+ }
68
+ // Convert to sorted array
69
+ result.stacks = Array.from(stackScores.entries())
70
+ .map(([id, data]) => ({
71
+ id,
72
+ confidence: Math.min(100, data.confidence),
73
+ reason: data.reasons.join(', '),
74
+ }))
75
+ .sort((a, b) => b.confidence - a.confidence);
76
+ return result;
77
+ }
78
+ /**
79
+ * Detect framework within a PHP project
80
+ */
81
+ export function detectPhpFramework(projectDir) {
82
+ if (existsSync(join(projectDir, 'artisan')))
83
+ return 'laravel';
84
+ if (existsSync(join(projectDir, 'symfony.lock')))
85
+ return 'symfony';
86
+ if (existsSync(join(projectDir, 'spark')))
87
+ return 'codeigniter';
88
+ return null;
89
+ }
90
+ /**
91
+ * Detect framework within a Node.js project
92
+ */
93
+ export function detectNodeFramework(projectDir) {
94
+ if (existsSync(join(projectDir, 'next.config.js')) ||
95
+ existsSync(join(projectDir, 'next.config.ts')) ||
96
+ existsSync(join(projectDir, 'next.config.mjs')))
97
+ return 'nextjs';
98
+ if (existsSync(join(projectDir, 'nuxt.config.ts')))
99
+ return 'nuxt';
100
+ if (existsSync(join(projectDir, 'astro.config.mjs')))
101
+ return 'astro';
102
+ return null;
103
+ }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Start Vibing Stacks — CLI Entry Point
4
+ *
5
+ * Multi-stack AI-powered development workflow for Claude Code.
6
+ * Detects project stack, validates requirements, and configures agents.
7
+ */
8
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,239 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Start Vibing Stacks — CLI Entry Point
4
+ *
5
+ * Multi-stack AI-powered development workflow for Claude Code.
6
+ * Detects project stack, validates requirements, and configures agents.
7
+ */
8
+ import { basename } from 'path';
9
+ import inquirer from 'inquirer';
10
+ import chalk from 'chalk';
11
+ import * as ui from './ui.js';
12
+ import { detectProject, detectPhpFramework, detectNodeFramework } from './detector.js';
13
+ import { autoInstall, installComposer, installClaudeCode } from './installer.js';
14
+ import { loadStackConfig, setupProject } from './setup.js';
15
+ // =============================================================================
16
+ // CLI Arguments
17
+ // =============================================================================
18
+ const args = process.argv.slice(2);
19
+ const FLAGS = {
20
+ force: args.includes('--force'),
21
+ noClaude: args.includes('--no-claude'),
22
+ noInstall: args.includes('--no-install'),
23
+ help: args.includes('--help') || args.includes('-h'),
24
+ version: args.includes('--version') || args.includes('-v'),
25
+ };
26
+ if (FLAGS.version) {
27
+ console.log('1.0.0');
28
+ process.exit(0);
29
+ }
30
+ if (FLAGS.help) {
31
+ console.log(ui.LOGO);
32
+ console.log(`
33
+ ${chalk.bold('Usage:')}
34
+ npx start-vibing-stacks [options]
35
+
36
+ ${chalk.bold('Options:')}
37
+ --force Overwrite existing configuration
38
+ --no-claude Skip Claude Code installation
39
+ --no-install Skip dependency installation
40
+ --help, -h Show this help
41
+ --version, -v Show version
42
+
43
+ ${chalk.bold('Supported Stacks:')}
44
+ 🐘 PHP 8.3+ Laravel, Symfony, CodeIgniter, Vanilla
45
+ 📦 Node.js/TS Next.js, Nuxt, Express, Fastify
46
+ 🐍 Python Django, FastAPI, Flask (coming soon)
47
+ 🦀 Rust (coming soon)
48
+ 🐹 Go (coming soon)
49
+ `);
50
+ process.exit(0);
51
+ }
52
+ const AVAILABLE_STACKS = [
53
+ { id: 'php', name: 'PHP 8.3+', icon: '🐘', available: true },
54
+ { id: 'nodejs', name: 'Node.js / TypeScript', icon: '📦', available: true },
55
+ { id: 'python', name: 'Python', icon: '🐍', available: false },
56
+ { id: 'rust', name: 'Rust', icon: '🦀', available: false },
57
+ { id: 'go', name: 'Go', icon: '🐹', available: false },
58
+ ];
59
+ // =============================================================================
60
+ // Main Flow
61
+ // =============================================================================
62
+ async function main() {
63
+ console.log(ui.LOGO);
64
+ const projectDir = process.cwd();
65
+ const projectName = basename(projectDir);
66
+ // ─── Step 1: Detect Project ─────────────────────────────────────────────
67
+ ui.header('🔍 Scanning project directory...');
68
+ const detection = detectProject(projectDir);
69
+ if (detection.hasCursorRules) {
70
+ ui.info('.cursorrules detected — will import into Claude config');
71
+ }
72
+ if (detection.hasClaudeMd) {
73
+ ui.info('Existing CLAUDE.md found — will merge with template');
74
+ }
75
+ if (!detection.hasGit) {
76
+ ui.warn('No .git found — recommend initializing git first');
77
+ }
78
+ if (detection.stacks.length > 0) {
79
+ const topStack = detection.stacks[0];
80
+ console.log('');
81
+ ui.success(`Detected: ${topStack.id.toUpperCase()} (${topStack.confidence}% confidence)`);
82
+ ui.info(`Reason: ${topStack.reason}`);
83
+ }
84
+ // ─── Step 2: Select Stack ───────────────────────────────────────────────
85
+ console.log('');
86
+ const { stackId } = await inquirer.prompt([
87
+ {
88
+ type: 'list',
89
+ name: 'stackId',
90
+ message: 'Select your primary stack:',
91
+ default: detection.stacks.length > 0 ? detection.stacks[0].id : undefined,
92
+ choices: AVAILABLE_STACKS.map((s) => ({
93
+ name: `${s.icon} ${s.name}${!s.available ? chalk.dim(' (coming soon)') : ''}`,
94
+ value: s.id,
95
+ disabled: !s.available ? 'Coming soon' : false,
96
+ })),
97
+ },
98
+ ]);
99
+ const stackConfig = loadStackConfig(stackId);
100
+ if (!stackConfig) {
101
+ ui.error(`Stack config not found for: ${stackId}`);
102
+ process.exit(1);
103
+ }
104
+ // ─── Step 3: Select Framework ──────────────────────────────────────────
105
+ const detectedFramework = stackId === 'php'
106
+ ? detectPhpFramework(projectDir)
107
+ : stackId === 'nodejs'
108
+ ? detectNodeFramework(projectDir)
109
+ : null;
110
+ const { framework } = await inquirer.prompt([
111
+ {
112
+ type: 'list',
113
+ name: 'framework',
114
+ message: 'Select framework:',
115
+ default: detectedFramework || undefined,
116
+ choices: stackConfig.frameworks.map((f) => ({
117
+ name: `${f.icon} ${f.name}`,
118
+ value: f.id,
119
+ })),
120
+ },
121
+ ]);
122
+ // ─── Step 4: Select Database ───────────────────────────────────────────
123
+ const { database } = await inquirer.prompt([
124
+ {
125
+ type: 'list',
126
+ name: 'database',
127
+ message: 'Select database:',
128
+ choices: stackConfig.databases.map((d) => ({
129
+ name: `${d.icon} ${d.name}`,
130
+ value: d.id,
131
+ })),
132
+ },
133
+ ]);
134
+ // ─── Step 5: Frontend ──────────────────────────────────────────────────
135
+ const { frontend } = await inquirer.prompt([
136
+ {
137
+ type: 'list',
138
+ name: 'frontend',
139
+ message: 'Frontend included?',
140
+ choices: stackConfig.frontendOptions.map((f) => ({
141
+ name: `${f.icon} ${f.name}`,
142
+ value: f.id,
143
+ })),
144
+ },
145
+ ]);
146
+ // ─── Step 6: Deploy Target ─────────────────────────────────────────────
147
+ const { deploy } = await inquirer.prompt([
148
+ {
149
+ type: 'list',
150
+ name: 'deploy',
151
+ message: 'Deployment target?',
152
+ choices: stackConfig.deployTargets.map((d) => ({
153
+ name: `${d.icon} ${d.name}`,
154
+ value: d.id,
155
+ })),
156
+ },
157
+ ]);
158
+ // ─── Step 7: Show Summary & Confirm ────────────────────────────────────
159
+ const config = {
160
+ name: projectName,
161
+ stack: stackId,
162
+ framework,
163
+ database,
164
+ frontend,
165
+ deploy,
166
+ path: projectDir,
167
+ createdAt: new Date().toISOString(),
168
+ skills: [...stackConfig.skills],
169
+ qualityGates: `stacks/${stackId}/config/quality-gates.json`,
170
+ cursorRules: detection.hasCursorRules,
171
+ domains: {},
172
+ };
173
+ ui.configSummary({
174
+ 'Stack': `${stackConfig.icon} ${stackConfig.name} (${stackConfig.runtime})`,
175
+ 'Framework': framework,
176
+ 'Database': database,
177
+ 'Frontend': frontend,
178
+ 'Deploy': deploy,
179
+ 'Agents': '6 universal',
180
+ 'Skills': `${stackConfig.skills.length} stack + shared`,
181
+ 'Hooks': 'stop-validator + prompt-inject',
182
+ 'Gates': stackConfig.qualityGates.map((g) => g.name).join(' → '),
183
+ });
184
+ const { confirmed } = await inquirer.prompt([
185
+ {
186
+ type: 'confirm',
187
+ name: 'confirmed',
188
+ message: 'Confirm configuration?',
189
+ default: true,
190
+ },
191
+ ]);
192
+ if (!confirmed) {
193
+ ui.info('Setup cancelled.');
194
+ process.exit(0);
195
+ }
196
+ // ─── Step 8: Validate & Install Requirements ──────────────────────────
197
+ if (!FLAGS.noInstall) {
198
+ const reqOk = await autoInstall(stackConfig.requirements);
199
+ if (!reqOk) {
200
+ ui.error('Some requirements could not be installed. Fix manually and retry.');
201
+ process.exit(1);
202
+ }
203
+ // PHP-specific: install Composer
204
+ if (stackId === 'php') {
205
+ const composerOk = await installComposer();
206
+ if (!composerOk) {
207
+ ui.warn('Composer installation failed — you may need to install it manually');
208
+ }
209
+ }
210
+ }
211
+ // ─── Step 9: Setup Project ─────────────────────────────────────────────
212
+ ui.header('⚡ Configuring project...');
213
+ const setupOk = await setupProject(projectDir, config, {
214
+ force: FLAGS.force,
215
+ noClaude: FLAGS.noClaude,
216
+ });
217
+ if (!setupOk) {
218
+ ui.error('Setup failed.');
219
+ process.exit(1);
220
+ }
221
+ // ─── Step 10: Install Claude Code ──────────────────────────────────────
222
+ if (!FLAGS.noClaude) {
223
+ console.log('');
224
+ installClaudeCode();
225
+ }
226
+ // ─── Done ──────────────────────────────────────────────────────────────
227
+ console.log('');
228
+ console.log(chalk.green.bold(' 🎸 Ready to vibe!'));
229
+ console.log('');
230
+ if (!FLAGS.noClaude) {
231
+ console.log(chalk.dim(' Launching Claude Code...'));
232
+ console.log(chalk.dim(' Run: claude --dangerously-skip-permissions'));
233
+ }
234
+ console.log('');
235
+ }
236
+ main().catch((err) => {
237
+ ui.error(`Unexpected error: ${err}`);
238
+ process.exit(1);
239
+ });
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Start Vibing Stacks — Dependency Installer & Validator
3
+ *
4
+ * Validates system requirements and auto-installs missing dependencies.
5
+ * macOS-first with Homebrew, with Linux fallbacks.
6
+ */
7
+ import type { Requirement } from './types.js';
8
+ export interface ValidationResult {
9
+ name: string;
10
+ installed: boolean;
11
+ version: string | null;
12
+ meetsMinimum: boolean;
13
+ minVersion: string;
14
+ }
15
+ /**
16
+ * Validate all requirements for a stack
17
+ */
18
+ export declare function validateRequirements(requirements: Requirement[]): ValidationResult[];
19
+ /**
20
+ * Auto-install missing or outdated requirements
21
+ */
22
+ export declare function autoInstall(requirements: Requirement[]): Promise<boolean>;
23
+ /**
24
+ * Install Composer using PHP 8.3+
25
+ */
26
+ export declare function installComposer(): Promise<boolean>;
27
+ /**
28
+ * Install Claude Code if not present
29
+ */
30
+ export declare function installClaudeCode(): boolean;