start-vibing-stacks 2.6.0 → 2.7.3

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 (80) hide show
  1. package/README.md +83 -135
  2. package/dist/index.js +16 -2
  3. package/dist/migrate.d.ts +27 -0
  4. package/dist/migrate.js +217 -0
  5. package/dist/setup.js +10 -0
  6. package/package.json +1 -1
  7. package/stacks/_shared/agents/claude-md-compactor.md +1 -0
  8. package/stacks/_shared/agents/commit-manager.md +1 -0
  9. package/stacks/_shared/agents/documenter.md +1 -0
  10. package/stacks/_shared/agents/domain-updater.md +1 -0
  11. package/stacks/_shared/agents/research-web.md +1 -0
  12. package/stacks/_shared/agents/security-auditor.md +168 -0
  13. package/stacks/_shared/agents/tester.md +1 -0
  14. package/stacks/_shared/hooks/final-check.ts +205 -0
  15. package/stacks/_shared/hooks/stop-validator.ts +77 -1
  16. package/stacks/_shared/skills/accessibility-wcag22/SKILL.md +284 -0
  17. package/stacks/_shared/skills/ci-pipelines/SKILL.md +166 -0
  18. package/stacks/_shared/skills/codebase-knowledge/SKILL.md +5 -0
  19. package/stacks/_shared/skills/database-migrations/SKILL.md +256 -0
  20. package/stacks/_shared/skills/debugging-patterns/SKILL.md +5 -0
  21. package/stacks/_shared/skills/docker-patterns/SKILL.md +5 -0
  22. package/stacks/_shared/skills/docs-tracker/SKILL.md +5 -0
  23. package/stacks/_shared/skills/error-handling/SKILL.md +335 -0
  24. package/stacks/_shared/skills/final-check/SKILL.md +74 -37
  25. package/stacks/_shared/skills/git-workflow/SKILL.md +5 -0
  26. package/stacks/_shared/skills/hook-development/SKILL.md +5 -0
  27. package/stacks/_shared/skills/observability/SKILL.md +351 -0
  28. package/stacks/_shared/skills/performance-patterns/SKILL.md +5 -0
  29. package/stacks/_shared/skills/playwright-automation/SKILL.md +5 -0
  30. package/stacks/_shared/skills/quality-gate/SKILL.md +5 -0
  31. package/stacks/_shared/skills/research-cache/SKILL.md +5 -0
  32. package/stacks/_shared/skills/secrets-management/SKILL.md +245 -0
  33. package/stacks/_shared/skills/security-baseline/SKILL.md +202 -0
  34. package/stacks/_shared/skills/test-coverage/SKILL.md +5 -0
  35. package/stacks/_shared/skills/ui-ux-audit/SKILL.md +5 -0
  36. package/stacks/frontend/react/skills/preline-ui/SKILL.md +5 -0
  37. package/stacks/frontend/react/skills/react-patterns/SKILL.md +5 -0
  38. package/stacks/frontend/react/skills/react-standards/SKILL.md +5 -0
  39. package/stacks/frontend/react/skills/react-ui-patterns/SKILL.md +5 -0
  40. package/stacks/frontend/react/skills/shadcn-ui/SKILL.md +5 -0
  41. package/stacks/frontend/react/skills/tailwind-patterns/SKILL.md +5 -0
  42. package/stacks/frontend/react/skills/zod-validation/SKILL.md +5 -0
  43. package/stacks/frontend/react-inertia/skills/inertia-react/SKILL.md +5 -0
  44. package/stacks/frontend/react-inertia/skills/react-standards/SKILL.md +5 -0
  45. package/stacks/nodejs/skills/api-security-node/SKILL.md +275 -0
  46. package/stacks/nodejs/skills/bun-runtime/SKILL.md +5 -0
  47. package/stacks/nodejs/skills/mongoose-patterns/SKILL.md +5 -0
  48. package/stacks/nodejs/skills/nextjs-app-router/SKILL.md +5 -0
  49. package/stacks/nodejs/skills/trpc-api/SKILL.md +5 -0
  50. package/stacks/nodejs/skills/typescript-strict/SKILL.md +5 -0
  51. package/stacks/nodejs/stack.json +2 -1
  52. package/stacks/nodejs/workflows/ci.yml +90 -0
  53. package/stacks/nodejs/workflows/security.yml +45 -0
  54. package/stacks/php/skills/api-design/SKILL.md +5 -0
  55. package/stacks/php/skills/api-security/SKILL.md +5 -0
  56. package/stacks/php/skills/composer-workflow/SKILL.md +5 -0
  57. package/stacks/php/skills/external-api-patterns/SKILL.md +5 -0
  58. package/stacks/php/skills/inertia-react/SKILL.md +5 -0
  59. package/stacks/php/skills/laravel-inertia-i18n/SKILL.md +5 -0
  60. package/stacks/php/skills/laravel-octane/SKILL.md +5 -0
  61. package/stacks/php/skills/laravel-patterns/SKILL.md +5 -0
  62. package/stacks/php/skills/mariadb-octane/SKILL.md +5 -0
  63. package/stacks/php/skills/php-patterns/SKILL.md +5 -0
  64. package/stacks/php/skills/phpstan-analysis/SKILL.md +5 -0
  65. package/stacks/php/skills/phpunit-testing/SKILL.md +5 -0
  66. package/stacks/php/skills/security-scan-php/SKILL.md +5 -0
  67. package/stacks/php/workflows/ci.yml +106 -0
  68. package/stacks/php/workflows/security.yml +36 -0
  69. package/stacks/python/skills/api-security-python/SKILL.md +312 -0
  70. package/stacks/python/skills/async-patterns/SKILL.md +5 -0
  71. package/stacks/python/skills/django-patterns/SKILL.md +5 -0
  72. package/stacks/python/skills/fastapi-patterns/SKILL.md +5 -0
  73. package/stacks/python/skills/pydantic-validation/SKILL.md +5 -0
  74. package/stacks/python/skills/pytest-testing/SKILL.md +5 -0
  75. package/stacks/python/skills/python-patterns/SKILL.md +5 -0
  76. package/stacks/python/skills/python-performance/SKILL.md +5 -0
  77. package/stacks/python/skills/scripting-automation/SKILL.md +5 -0
  78. package/stacks/python/stack.json +2 -1
  79. package/stacks/python/workflows/ci.yml +76 -0
  80. package/stacks/python/workflows/security.yml +56 -0
package/README.md CHANGED
@@ -1,183 +1,131 @@
1
1
  # Start Vibing Stacks
2
2
 
3
- **Multi-stack AI-powered development workflow for Claude Code & Cursor.**
4
-
5
- One command to set up agents, skills, hooks, security rules, and quality gates — tailored to your stack.
3
+ Multi-stack AI workflow for Claude Code & Cursor. One command installs agents, skills, hooks, and quality gates tailored to your stack.
6
4
 
7
5
  ```bash
8
6
  npx start-vibing-stacks
9
7
  ```
10
8
 
11
- ## What It Does
12
-
13
- Start Vibing Stacks transforms Claude Code into a stack-aware AI partner. Instead of a generic assistant, you get an AI that understands your framework, enforces your coding standards, and blocks insecure patterns — all before a single line of code is written.
9
+ ## What It Installs
14
10
 
15
- ```
16
- You run the CLI
17
-
18
- Detects your stack (PHP/Node.js) from project files
19
-
20
- Scans existing standards (.cursorrules, composer.json, tsconfig, eslint, .env)
21
-
22
- Asks: adapt to YOUR standards or use defaults?
23
-
24
- Copies 6 agents + 25-40 skills + hooks + security rules
25
-
26
- Generates CLAUDE.md with architecture, rules, FORBIDDEN patterns
27
-
28
- Launches Claude Code — fully configured
29
- ```
11
+ | Layer | Count | Purpose |
12
+ |---|---|---|
13
+ | Agents | 7 universal | research-web, documenter, domain-updater, commit-manager, tester, claude-md-compactor, **security-auditor** (VETO) |
14
+ | Skills | 13 shared + 5–13 stack-specific + 7–9 frontend | Versioned (`version:` frontmatter), upgradable via `migrate` |
15
+ | Hooks | `stop-validator`, `final-check`, `user-prompt-submit` | Block completion on git/docs/secrets/code-quality issues |
16
+ | Commands | `/feature`, `/fix`, `/research`, `/validate` | Slash commands |
17
+ | Workflows | `ci.yml` + `security.yml` per stack | Copied to `.github/workflows/` when target is empty |
30
18
 
31
19
  ## Supported Stacks
32
20
 
33
- ### PHP 8.3+
21
+ | Stack | Frameworks | Databases | Frontend |
22
+ |---|---|---|---|
23
+ | 🐘 **PHP 8.3+** | Laravel 12 + Octane, Laravel 12 | MariaDB/MySQL, PostgreSQL, SQLite | Inertia + React, Blade, Livewire, API only |
24
+ | 📦 **Node.js / TS** | Next.js, Nuxt, Astro, Express, Fastify, Vanilla | MongoDB, Postgres, MariaDB/MySQL, SQLite/Turso, Redis, None | React + Tailwind, Vue, Svelte, API only |
25
+ | 🐍 **Python 3.12+** | FastAPI, Django 5, Flask, Local Scripts | MariaDB/MySQL, Postgres, SQLite, MongoDB, None | React, HTMX + Jinja2, API/CLI only |
34
26
 
35
- | Option | Choices |
36
- |--------|---------|
37
- | **Frameworks** | Laravel 12 + Octane (RoadRunner) + Inertia.js, Laravel 12 (standard) |
38
- | **Databases** | MySQL / MariaDB, PostgreSQL, SQLite |
39
- | **Frontend** | React 19 + Inertia.js + TailwindCSS 4, Blade + TailwindCSS, Livewire + Alpine.js, API only |
40
- | **Skills** | 13 PHP-specific (Octane, PHPStan, PHPUnit, Eloquent, API Security, Inertia i18n, ...) |
27
+ ## Universal Skills (shared across stacks)
41
28
 
42
- ### Node.js / TypeScript
29
+ | Skill | Topic |
30
+ |---|---|
31
+ | `security-baseline` | OWASP Top 10 with stack-aware examples |
32
+ | `secrets-management` | `.env` hygiene, gitleaks, rotation playbook |
33
+ | `observability` | Structured logs, OpenTelemetry, Sentry, PII redaction |
34
+ | `error-handling` | Result types, error taxonomy, retry/backoff, circuit breaker |
35
+ | `database-migrations` | Parallel change, lock timeouts, chunked backfills |
36
+ | `accessibility-wcag22` | WCAG 2.2 AA + axe-core/Playwright |
37
+ | `ci-pipelines` | GitHub Actions discipline + ready-to-use templates |
38
+ | `quality-gate` · `final-check` · `git-workflow` · `docker-patterns` · `debugging-patterns` · `performance-patterns` · `playwright-automation` · `test-coverage` · `ui-ux-audit` · `codebase-knowledge` · `docs-tracker` · `research-cache` · `hook-development` | Workflow & tooling |
43
39
 
44
- | Option | Choices |
45
- |--------|---------|
46
- | **Frameworks** | Next.js (App Router), Nuxt, Astro, Express, Fastify, Vanilla Node.js |
47
- | **Databases** | MongoDB, PostgreSQL, MySQL, SQLite/Turso, Redis (Upstash), None |
48
- | **Frontend** | React 19 + TailwindCSS 4, Vue.js / Nuxt, Svelte / SvelteKit, API only |
49
- | **Skills** | 5 Node-specific (TypeScript strict, Next.js App Router, tRPC, Bun, Mongoose) + 9 frontend skills |
40
+ Plus stack-specific: `api-security-node`, `api-security-python`, `api-security` (PHP), `typescript-strict`, `nextjs-app-router`, `trpc-api`, `bun-runtime`, `mongoose-patterns`, `pydantic-validation`, `pytest-testing`, `python-patterns`, `python-performance`, `async-patterns`, `fastapi-patterns`, `django-patterns`, `scripting-automation`, `laravel-patterns`, `laravel-octane`, `phpstan-analysis`, `phpunit-testing`, `composer-workflow`, `mariadb-octane`, `external-api-patterns`, `inertia-react`, `laravel-inertia-i18n`, `security-scan-php`, `api-design`, `php-patterns`.
50
41
 
51
- ### Python (Coming Soon)
52
-
53
- Django, FastAPI, Flask support is planned.
54
-
55
- ## What Gets Installed
42
+ ## Layout in Your Project
56
43
 
57
44
  ```
58
45
  your-project/
59
- ├── CLAUDE.md # AI memory architecture, rules, FORBIDDEN patterns
60
- └── .claude/
61
- ├── agents/ # 6 universal agents
62
- │ ├── research-web.md # Researches best practices before new features
63
- │ ├── documenter.md # Maps files to domains, tracks changes
64
- │ ├── domain-updater.md # Records problems, solutions, learnings
65
- ├── commit-manager.md # Conventional commits, merge workflow
66
- │ ├── tester.md # Creates tests (Vitest/PHPUnit/Playwright)
67
- │ └── claude-md-compactor.md # Compacts CLAUDE.md when > 40k chars
68
- ├── skills/ # 25-40 skills (stack + shared + frontend)
69
- │ ├── quality-gate/ # Typecheck, lint, test validation
70
- │ ├── security-scan/ # OWASP checks per language
71
- │ ├── git-workflow/ # Branch management, conventional commits
72
- │ ├── codebase-knowledge/ # Domain documentation system
73
- │ └── ... # Stack-specific skills
74
- ├── hooks/
75
- │ ├── stop-validator.ts # Blocks incomplete tasks (branch, git, docs)
76
- │ └── user-prompt-submit.ts # Injects workflow + standards context
77
- ├── commands/ # /feature, /fix, /research, /validate
78
- ├── config/
79
- │ ├── active-project.json # Stack, framework, database, skills
80
- │ ├── security-rules.json # OWASP checks + env exposure rules
81
- │ ├── standards-review.json # Imported project standards
82
- │ └── ... # Quality gates, testing, domain mapping
83
- └── settings.json # Claude Code permissions & model config
46
+ ├── CLAUDE.md # AI memory: architecture, rules, FORBIDDEN
47
+ ├── .claude/
48
+ ├── agents/ # 7 universal agents
49
+ │ ├── skills/ # versioned skill set (stack + shared + frontend)
50
+ │ ├── hooks/ # stop-validator, final-check, prompt-submit
51
+ │ ├── commands/ # /feature, /fix, /research, /validate
52
+ └── config/ # active-project, security-rules, ...
53
+ └── .github/workflows/ # ci.yml + security.yml (if dir was empty)
84
54
  ```
85
55
 
86
- ## Security Features
87
-
88
- ### Environment Variable Protection (Node.js)
56
+ ## CLI
89
57
 
90
- The tool enforces strict separation of server and client environment variables:
58
+ ```bash
59
+ npx start-vibing-stacks # setup or resume current project
60
+ npx start-vibing-stacks migrate # show outdated/missing skills
61
+ npx start-vibing-stacks migrate --apply # update outdated skills/agents
91
62
 
92
- - **Scanner**: Detects `NEXT_PUBLIC_` with sensitive words (SECRET, TOKEN, API_KEY) in `.env*` files
93
- - **CLAUDE.md**: FORBIDDEN rules prevent AI from exposing secrets in browser bundles
94
- - **Skills**: Teach API proxy patterns — external API calls must go through Route Handlers
95
- - **security-rules.json**: Automated detection patterns for security audits
63
+ # flags: --force --no-claude --no-mcp --no-install --help --version
64
+ ```
96
65
 
97
- ### PHP Security
66
+ Global install: `npm i -g start-vibing-stacks` → `svs` (alias).
98
67
 
99
- - OWASP Top 10 adapted for Laravel + Octane
100
- - Octane-safe patterns (no static state, no globals)
101
- - `env()` restriction (config files only)
102
- - Frontend secret isolation (Inertia props)
103
- - Rate limiting, CORS, CSP, encryption at rest
68
+ ## Hooks (block completion)
104
69
 
105
- ## Standards Review
70
+ | Hook | Blocks when |
71
+ |---|---|
72
+ | `stop-validator` | not on main, uncommitted changes, CLAUDE.md missing/stale, **secret pattern in diff** (gitleaks or regex) |
73
+ | `final-check` | hardcoded secret, `eval`, SQL string concat, `.skip`/`.only`, `any`, `console.log`, `var_dump` |
74
+ | `user-prompt-submit` | injects workflow + standards context |
106
75
 
107
- Before modifying anything, the CLI scans your project for existing patterns:
76
+ ## Workflow per Task
108
77
 
109
78
  ```
110
- Scans: .cursorrules, composer.json, package.json, tsconfig.json,
111
- eslint config, phpstan.neon, .env files, framework configs,
112
- lockfiles, deploy configs, quality tool configs
113
-
114
- Detects: 50+ npm packages, 17+ Composer packages, TypeScript strict mode,
115
- path aliases, ESLint config, PHPStan level, package manager,
116
- deploy targets, exposed secrets in NEXT_PUBLIC_*
117
-
118
- Result: "Adapt to your standards" or "Use plugin defaults"
119
- → Saved in standards-review.json
120
- → Injected into every Claude prompt via hook
79
+ 1. BRANCH feature/ | fix/ | refactor/ | test/
80
+ 2. RESEARCH research-web agent (new features)
81
+ 3. IMPLEMENT stack rules + strict types + security
82
+ 4. TEST tester agent (Vitest / pytest / PHPUnit / Playwright)
83
+ 5. SECURITY security-auditor agent VETO on findings
84
+ 6. DOCUMENT documenter agent
85
+ 7. UPDATE CLAUDE.md "Last Change" section
86
+ 8. QUALITY typecheck → lint → test → build
87
+ 9. COMMIT conventional commit, merge to main
121
88
  ```
122
89
 
123
- ## CLI Options
124
-
125
- ```bash
126
- npx start-vibing-stacks [options]
127
-
128
- --force Overwrite existing configuration
129
- --no-claude Skip Claude Code launch
130
- --no-install Skip dependency installation
131
- --help, -h Show help
132
- --version, -v Show version
133
- ```
90
+ ## Security Features
134
91
 
135
- Or install globally:
92
+ - **Environment isolation**: scanner blocks `NEXT_PUBLIC_*SECRET|*TOKEN|*PRIVATE` patterns; teaches Route Handler / Server Action proxy patterns.
93
+ - **OWASP Top 10**: stack-aware skills cover A01–A10 (broken access control, injection, SSRF, etc.).
94
+ - **Secret scanning** in `stop-validator` — gitleaks if installed, regex fallback otherwise.
95
+ - **`security-auditor` agent** with VETO — runs after tester, before commit, blocks insecure code.
96
+ - **CI templates**: gitleaks, `npm audit` / `pip-audit` / `composer audit`, CodeQL/Bandit, weekly cron.
136
97
 
137
- ```bash
138
- npm install -g start-vibing-stacks
139
- svs # shortcut alias
140
- ```
98
+ ## Standards Review
141
99
 
142
- ## How the Workflow Works
100
+ CLI scans existing config (cursorrules, composer.json, tsconfig, eslint, phpstan, `.env*`, lockfiles) and asks **"adapt to your standards or use defaults?"** Imported standards are written to `standards-review.json` and injected into every prompt.
143
101
 
144
- Once configured, Claude Code follows this workflow on every task:
102
+ ## Migrate Existing Projects
145
103
 
104
+ ```bash
105
+ npx start-vibing-stacks migrate # report drift
106
+ npx start-vibing-stacks migrate --apply # apply updates
146
107
  ```
147
- 0. TODO LIST → Creates detailed task breakdown
148
- 1. BRANCH → Creates feature/ | fix/ | refactor/ | test/
149
- 2. RESEARCH → Runs research-web agent for new features
150
- 3. IMPLEMENT → Follows stack rules + strict types + security
151
- 4. TEST → Runs tester agent (PHPUnit / Vitest / Playwright)
152
- 5. DOCUMENT → Runs documenter agent for modified files
153
- 6. UPDATE → Updates CLAUDE.md with changes
154
- 7. QUALITY → Runs quality gates (typecheck, lint, test, build)
155
- 8. COMMIT → Conventional commits, merge to main
156
- ```
157
-
158
- The **stop-validator hook** blocks task completion if:
159
- - Not on `main` branch (work must be merged)
160
- - Uncommitted changes exist
161
- - CLAUDE.md wasn't updated
162
- - Source files lack documentation
163
108
 
164
- ## Cursor IDE Support
165
-
166
- If `.cursorrules` is detected, the rules are automatically imported into the Claude configuration. Both AI tools work with the same context.
109
+ Compares `version:` in your installed `SKILL.md` files against the bundled package. Missing → install. Outdated → upgrade. Ahead (you customized) → kept. Unversioned → flagged for manual review.
167
110
 
168
111
  ## Requirements
169
112
 
170
- | Stack | Requirements |
171
- |-------|-------------|
172
- | **PHP** | PHP >= 8.3, Composer >= 2.0, Node.js >= 18 |
173
- | **Node.js** | Node.js >= 18 (Bun optional) |
113
+ | Stack | Required |
114
+ |---|---|
115
+ | PHP | PHP 8.3, Composer 2.0, Node.js 18 |
116
+ | Node.js | Node.js 18 (Bun optional) |
117
+ | Python | Python ≥ 3.12, pip ≥ 23 |
174
118
 
175
119
  Missing dependencies are auto-installed via Homebrew on macOS.
176
120
 
121
+ ## Releases
122
+
123
+ GitHub Release → npm publish (workflow `publish.yml`).
124
+ Version bump in `package.json` on `main` → auto-creates the GitHub Release (workflow `auto-release.yml`). Add `[skip release]` to the commit to opt out.
125
+
177
126
  ## Credits
178
127
 
179
- Inspired by [start-vibing](https://www.npmjs.com/package/start-vibing).
180
- Built by [FantasyLake](https://github.com/f1sc4ll-ai).
128
+ Inspired by [start-vibing](https://www.npmjs.com/package/start-vibing). Built by [FantasyLake](https://github.com/f1sc4ll-ai).
181
129
 
182
130
  ## License
183
131
 
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ const PKG_VERSION = JSON.parse(readFileSync(join(CLI_ROOT, 'package.json'), 'utf
24
24
  // CLI Arguments
25
25
  // =============================================================================
26
26
  const args = process.argv.slice(2);
27
+ const SUBCOMMAND = args[0] && !args[0].startsWith('-') ? args[0] : null;
27
28
  const FLAGS = {
28
29
  force: args.includes('--force'),
29
30
  noClaude: args.includes('--no-claude'),
@@ -31,6 +32,7 @@ const FLAGS = {
31
32
  noInstall: args.includes('--no-install'),
32
33
  help: args.includes('--help') || args.includes('-h'),
33
34
  version: args.includes('--version') || args.includes('-v'),
35
+ apply: args.includes('--apply'),
34
36
  };
35
37
  if (FLAGS.version) {
36
38
  console.log(PKG_VERSION);
@@ -40,10 +42,16 @@ if (FLAGS.help) {
40
42
  console.log(ui.LOGO);
41
43
  console.log(`
42
44
  ${chalk.bold('Usage:')}
43
- npx start-vibing-stacks [options]
45
+ npx start-vibing-stacks [command] [options]
46
+
47
+ ${chalk.bold('Commands:')}
48
+ (default) Setup or resume current project
49
+ migrate Compare installed vs bundled skill/agent versions
50
+ Add --apply to update outdated/missing items
44
51
 
45
52
  ${chalk.bold('Options:')}
46
- --force Overwrite existing configuration
53
+ --force Overwrite existing configuration (default command)
54
+ --apply Apply updates (migrate command)
47
55
  --no-claude Skip Claude Code installation
48
56
  --no-mcp Skip MCP server selection
49
57
  --no-install Skip dependency installation
@@ -57,6 +65,12 @@ if (FLAGS.help) {
57
65
  `);
58
66
  process.exit(0);
59
67
  }
68
+ // Subcommand: migrate
69
+ if (SUBCOMMAND === 'migrate') {
70
+ const { runMigrate } = await import('./migrate.js');
71
+ await runMigrate(process.cwd(), { apply: FLAGS.apply });
72
+ process.exit(0);
73
+ }
60
74
  const AVAILABLE_STACKS = [
61
75
  { id: 'php', name: 'PHP 8.3+', icon: '🐘', available: true },
62
76
  { id: 'nodejs', name: 'Node.js / TypeScript', icon: '📦', available: true },
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Start Vibing Stacks — Migrate
3
+ *
4
+ * Compares the SKILL.md / agent / hook versions installed in .claude/
5
+ * against the bundled stacks/<stack>/ and stacks/_shared/ versions.
6
+ *
7
+ * Reports outdated, missing, and modified items. Optionally upgrades.
8
+ *
9
+ * Skill version contract:
10
+ * YAML frontmatter at top of SKILL.md must include `version: X.Y.Z`.
11
+ * No frontmatter = treated as "v0" / pre-versioning.
12
+ */
13
+ export interface MigrateItem {
14
+ kind: 'skill' | 'agent' | 'hook';
15
+ name: string;
16
+ source: string;
17
+ target: string;
18
+ bundledVersion: string;
19
+ installedVersion: string | null;
20
+ status: 'missing' | 'outdated' | 'current' | 'ahead' | 'modified-no-version';
21
+ }
22
+ export interface MigrateOptions {
23
+ apply: boolean;
24
+ scope?: 'skills' | 'agents' | 'hooks' | 'all';
25
+ }
26
+ export declare function planMigration(projectDir: string, opts: MigrateOptions): MigrateItem[];
27
+ export declare function runMigrate(projectDir: string, opts: MigrateOptions): Promise<void>;
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Start Vibing Stacks — Migrate
3
+ *
4
+ * Compares the SKILL.md / agent / hook versions installed in .claude/
5
+ * against the bundled stacks/<stack>/ and stacks/_shared/ versions.
6
+ *
7
+ * Reports outdated, missing, and modified items. Optionally upgrades.
8
+ *
9
+ * Skill version contract:
10
+ * YAML frontmatter at top of SKILL.md must include `version: X.Y.Z`.
11
+ * No frontmatter = treated as "v0" / pre-versioning.
12
+ */
13
+ import { existsSync, readFileSync, copyFileSync, mkdirSync, statSync, readdirSync } from 'fs';
14
+ import { join, relative, dirname, resolve } from 'path';
15
+ import { fileURLToPath } from 'url';
16
+ import * as semver from 'semver';
17
+ import * as ui from './ui.js';
18
+ const __m_filename = fileURLToPath(import.meta.url);
19
+ const __m_dirname = dirname(__m_filename);
20
+ const CLI_ROOT = resolve(__m_dirname, '..');
21
+ const FRONTMATTER_RE = /^---\s*\n([\s\S]*?)\n---/;
22
+ const VERSION_RE = /^version:\s*["']?([0-9]+\.[0-9]+\.[0-9]+(?:-[A-Za-z0-9.-]+)?)["']?\s*$/m;
23
+ function parseVersion(file) {
24
+ if (!existsSync(file))
25
+ return null;
26
+ try {
27
+ const content = readFileSync(file, 'utf8');
28
+ const fm = FRONTMATTER_RE.exec(content);
29
+ if (!fm)
30
+ return null;
31
+ const v = VERSION_RE.exec(fm[1] ?? '');
32
+ return v?.[1] ?? null;
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ function statusOf(bundled, installed) {
39
+ if (installed === null)
40
+ return 'modified-no-version';
41
+ const cmp = semver.compare(installed, bundled);
42
+ if (cmp < 0)
43
+ return 'outdated';
44
+ if (cmp > 0)
45
+ return 'ahead';
46
+ return 'current';
47
+ }
48
+ function listSubdirs(dir) {
49
+ if (!existsSync(dir))
50
+ return [];
51
+ try {
52
+ return readdirSync(dir).filter(n => {
53
+ try {
54
+ return statSync(join(dir, n)).isDirectory();
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ });
60
+ }
61
+ catch {
62
+ return [];
63
+ }
64
+ }
65
+ function listFiles(dir, suffix) {
66
+ if (!existsSync(dir))
67
+ return [];
68
+ try {
69
+ return readdirSync(dir).filter(n => n.endsWith(suffix));
70
+ }
71
+ catch {
72
+ return [];
73
+ }
74
+ }
75
+ function listSkillSources(stack, frontendSkillsDir) {
76
+ const out = [];
77
+ const sharedDir = join(CLI_ROOT, 'stacks', '_shared', 'skills');
78
+ const stackDir = join(CLI_ROOT, 'stacks', stack, 'skills');
79
+ const frontendDir = frontendSkillsDir
80
+ ? join(CLI_ROOT, 'stacks', 'frontend', frontendSkillsDir, 'skills')
81
+ : null;
82
+ for (const dir of [sharedDir, stackDir, frontendDir].filter(Boolean)) {
83
+ for (const entry of listSubdirs(dir)) {
84
+ const skillPath = join(dir, entry, 'SKILL.md');
85
+ if (existsSync(skillPath))
86
+ out.push({ source: skillPath, name: entry });
87
+ }
88
+ }
89
+ return out;
90
+ }
91
+ function listAgentSources() {
92
+ const dir = join(CLI_ROOT, 'stacks', '_shared', 'agents');
93
+ return listFiles(dir, '.md').map(n => ({ source: join(dir, n), name: n }));
94
+ }
95
+ function listHookSources() {
96
+ const dir = join(CLI_ROOT, 'stacks', '_shared', 'hooks');
97
+ return listFiles(dir, '.ts').map(n => ({ source: join(dir, n), name: n }));
98
+ }
99
+ function loadProjectConfig(projectDir) {
100
+ const path = join(projectDir, '.claude', 'config', 'active-project.json');
101
+ if (!existsSync(path))
102
+ return null;
103
+ try {
104
+ return JSON.parse(readFileSync(path, 'utf8'));
105
+ }
106
+ catch {
107
+ return null;
108
+ }
109
+ }
110
+ export function planMigration(projectDir, opts) {
111
+ const config = loadProjectConfig(projectDir);
112
+ if (!config) {
113
+ ui.error('No .claude/config/active-project.json found. Run `npx start-vibing-stacks` first.');
114
+ return [];
115
+ }
116
+ const items = [];
117
+ const scope = opts.scope ?? 'all';
118
+ if (scope === 'all' || scope === 'skills') {
119
+ for (const { source, name } of listSkillSources(config.stack, config.frontendSkillsDir)) {
120
+ const target = join(projectDir, '.claude', 'skills', name, 'SKILL.md');
121
+ const bundledVersion = parseVersion(source);
122
+ if (!bundledVersion)
123
+ continue;
124
+ const installedVersion = parseVersion(target);
125
+ const status = !existsSync(target)
126
+ ? 'missing'
127
+ : statusOf(bundledVersion, installedVersion);
128
+ items.push({ kind: 'skill', name, source, target, bundledVersion, installedVersion, status });
129
+ }
130
+ }
131
+ if (scope === 'all' || scope === 'agents') {
132
+ for (const { source, name } of listAgentSources()) {
133
+ const target = join(projectDir, '.claude', 'agents', name);
134
+ const bundledVersion = parseVersion(source);
135
+ if (!bundledVersion)
136
+ continue;
137
+ const installedVersion = parseVersion(target);
138
+ const status = !existsSync(target)
139
+ ? 'missing'
140
+ : statusOf(bundledVersion, installedVersion);
141
+ items.push({ kind: 'agent', name, source, target, bundledVersion, installedVersion, status });
142
+ }
143
+ }
144
+ if (scope === 'all' || scope === 'hooks') {
145
+ for (const { source, name } of listHookSources()) {
146
+ const target = join(projectDir, '.claude', 'hooks', name);
147
+ const bundledVersion = '0.0.0';
148
+ const installedVersion = existsSync(target) ? '0.0.0' : null;
149
+ const status = !existsSync(target) ? 'missing' : 'current';
150
+ items.push({ kind: 'hook', name, source, target, bundledVersion, installedVersion, status });
151
+ }
152
+ }
153
+ return items;
154
+ }
155
+ function applyOne(item) {
156
+ mkdirSync(dirname(item.target), { recursive: true });
157
+ copyFileSync(item.source, item.target);
158
+ }
159
+ export async function runMigrate(projectDir, opts) {
160
+ ui.header('🔄 Start Vibing — Migrate');
161
+ const items = planMigration(projectDir, opts);
162
+ if (items.length === 0) {
163
+ ui.info('Nothing to migrate.');
164
+ return;
165
+ }
166
+ const grouped = {
167
+ missing: [], outdated: [], current: [], ahead: [], 'modified-no-version': [],
168
+ };
169
+ for (const it of items)
170
+ grouped[it.status].push(it);
171
+ const summary = (label, list) => {
172
+ if (list.length === 0)
173
+ return;
174
+ console.log(`\n ${label} (${list.length}):`);
175
+ for (const it of list.slice(0, 30)) {
176
+ const v = it.installedVersion ?? '–';
177
+ console.log(` ${it.kind.padEnd(5)} ${it.name.padEnd(32)} installed=${v.padEnd(8)} bundled=${it.bundledVersion}`);
178
+ }
179
+ if (list.length > 30)
180
+ console.log(` ... and ${list.length - 30} more`);
181
+ };
182
+ summary('MISSING', grouped.missing);
183
+ summary('OUTDATED', grouped.outdated);
184
+ summary('AHEAD (installed newer than bundled — kept)', grouped.ahead);
185
+ summary('UNVERSIONED (manual review)', grouped['modified-no-version']);
186
+ summary('CURRENT', grouped.current);
187
+ const upgradable = [...grouped.missing, ...grouped.outdated];
188
+ if (upgradable.length === 0) {
189
+ console.log('');
190
+ ui.success('Everything up to date.');
191
+ return;
192
+ }
193
+ if (!opts.apply) {
194
+ console.log('');
195
+ ui.info(`Run with --apply to install/update ${upgradable.length} item(s).`);
196
+ return;
197
+ }
198
+ console.log('');
199
+ for (const it of upgradable) {
200
+ try {
201
+ applyOne(it);
202
+ ui.success(`updated ${it.kind} ${it.name} (${it.installedVersion ?? '–'} → ${it.bundledVersion})`);
203
+ }
204
+ catch (err) {
205
+ ui.warn(`failed ${it.kind} ${it.name}: ${err instanceof Error ? err.message : String(err)}`);
206
+ }
207
+ }
208
+ console.log('');
209
+ ui.success(`Migration complete: ${upgradable.length} item(s) updated.`);
210
+ if (grouped['modified-no-version'].length > 0) {
211
+ console.log('');
212
+ ui.warn(`${grouped['modified-no-version'].length} unversioned local item(s) skipped — review manually.`);
213
+ for (const it of grouped['modified-no-version'].slice(0, 10)) {
214
+ console.log(` ${relative(projectDir, it.target)}`);
215
+ }
216
+ }
217
+ }
package/dist/setup.js CHANGED
@@ -169,6 +169,16 @@ export async function setupProject(projectDir, config, options = {}) {
169
169
  spinner.text = `Imported ${config.standardsReview.patterns.length} project standards`;
170
170
  }
171
171
  }
172
+ // 11d. Copy CI workflow templates (only when target dir is empty or --force)
173
+ const stackWorkflowsDir = join(PACKAGE_ROOT, 'stacks', config.stack, 'workflows');
174
+ if (existsSync(stackWorkflowsDir)) {
175
+ const ghWorkflowsDir = join(projectDir, '.github', 'workflows');
176
+ const targetIsEmpty = !existsSync(ghWorkflowsDir);
177
+ if (targetIsEmpty || options.force) {
178
+ copyDirRecursive(stackWorkflowsDir, ghWorkflowsDir, options.force);
179
+ spinner.text = 'Installed CI workflow templates';
180
+ }
181
+ }
172
182
  // 12. Copy commands
173
183
  const sharedCommandsDir = join(PACKAGE_ROOT, 'stacks', '_shared', 'commands');
174
184
  if (existsSync(sharedCommandsDir)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "start-vibing-stacks",
3
- "version": "2.6.0",
3
+ "version": "2.7.3",
4
4
  "description": "AI-powered multi-stack dev workflow for Claude Code. Supports PHP, Node.js, Python and more.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: claude-md-compactor
3
+ version: 1.0.0
3
4
  description: "AUTOMATICALLY invoke when CLAUDE.md exceeds 40k chars OR auto memory MEMORY.md exceeds 200 lines. Compacts while preserving critical knowledge by offloading to topic files."
4
5
  model: sonnet
5
6
  tools: Read, Write, Edit, Bash, Grep, Glob
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: commit-manager
3
+ version: 1.0.0
3
4
  description: "AUTOMATICALLY invoke as FINAL AGENT when implementation is complete. Creates conventional commits, merges to main."
4
5
  model: haiku
5
6
  tools: Read, Write, Edit, Bash, Grep, Glob
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: documenter
3
+ version: 1.0.0
3
4
  description: "AUTOMATICALLY invoke AFTER any code implementation. Creates/updates domain documentation. PROACTIVELY runs after implementation."
4
5
  model: sonnet
5
6
  tools: Read, Write, Edit, Grep, Glob, Bash
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: domain-updater
3
+ version: 1.0.0
3
4
  description: "AUTOMATICALLY invoke BEFORE commit-manager at session end. Records problems, solutions, and learnings in domain docs."
4
5
  model: haiku
5
6
  tools: Read, Write, Edit, Bash, Grep, Glob
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: research-web
3
+ version: 1.0.0
3
4
  description: "AUTOMATICALLY invoke BEFORE implementing any new feature or technology. Triggers: new feature, new technology, 'search', 'find info'. Web research specialist."
4
5
  model: sonnet
5
6
  tools: WebSearch, WebFetch, Read, Write