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.
- package/README.md +83 -135
- package/dist/index.js +16 -2
- package/dist/migrate.d.ts +27 -0
- package/dist/migrate.js +217 -0
- package/dist/setup.js +10 -0
- package/package.json +1 -1
- package/stacks/_shared/agents/claude-md-compactor.md +1 -0
- package/stacks/_shared/agents/commit-manager.md +1 -0
- package/stacks/_shared/agents/documenter.md +1 -0
- package/stacks/_shared/agents/domain-updater.md +1 -0
- package/stacks/_shared/agents/research-web.md +1 -0
- package/stacks/_shared/agents/security-auditor.md +168 -0
- package/stacks/_shared/agents/tester.md +1 -0
- package/stacks/_shared/hooks/final-check.ts +205 -0
- package/stacks/_shared/hooks/stop-validator.ts +77 -1
- package/stacks/_shared/skills/accessibility-wcag22/SKILL.md +284 -0
- package/stacks/_shared/skills/ci-pipelines/SKILL.md +166 -0
- package/stacks/_shared/skills/codebase-knowledge/SKILL.md +5 -0
- package/stacks/_shared/skills/database-migrations/SKILL.md +256 -0
- package/stacks/_shared/skills/debugging-patterns/SKILL.md +5 -0
- package/stacks/_shared/skills/docker-patterns/SKILL.md +5 -0
- package/stacks/_shared/skills/docs-tracker/SKILL.md +5 -0
- package/stacks/_shared/skills/error-handling/SKILL.md +335 -0
- package/stacks/_shared/skills/final-check/SKILL.md +74 -37
- package/stacks/_shared/skills/git-workflow/SKILL.md +5 -0
- package/stacks/_shared/skills/hook-development/SKILL.md +5 -0
- package/stacks/_shared/skills/observability/SKILL.md +351 -0
- package/stacks/_shared/skills/performance-patterns/SKILL.md +5 -0
- package/stacks/_shared/skills/playwright-automation/SKILL.md +5 -0
- package/stacks/_shared/skills/quality-gate/SKILL.md +5 -0
- package/stacks/_shared/skills/research-cache/SKILL.md +5 -0
- package/stacks/_shared/skills/secrets-management/SKILL.md +245 -0
- package/stacks/_shared/skills/security-baseline/SKILL.md +202 -0
- package/stacks/_shared/skills/test-coverage/SKILL.md +5 -0
- package/stacks/_shared/skills/ui-ux-audit/SKILL.md +5 -0
- package/stacks/frontend/react/skills/preline-ui/SKILL.md +5 -0
- package/stacks/frontend/react/skills/react-patterns/SKILL.md +5 -0
- package/stacks/frontend/react/skills/react-standards/SKILL.md +5 -0
- package/stacks/frontend/react/skills/react-ui-patterns/SKILL.md +5 -0
- package/stacks/frontend/react/skills/shadcn-ui/SKILL.md +5 -0
- package/stacks/frontend/react/skills/tailwind-patterns/SKILL.md +5 -0
- package/stacks/frontend/react/skills/zod-validation/SKILL.md +5 -0
- package/stacks/frontend/react-inertia/skills/inertia-react/SKILL.md +5 -0
- package/stacks/frontend/react-inertia/skills/react-standards/SKILL.md +5 -0
- package/stacks/nodejs/skills/api-security-node/SKILL.md +275 -0
- package/stacks/nodejs/skills/bun-runtime/SKILL.md +5 -0
- package/stacks/nodejs/skills/mongoose-patterns/SKILL.md +5 -0
- package/stacks/nodejs/skills/nextjs-app-router/SKILL.md +5 -0
- package/stacks/nodejs/skills/trpc-api/SKILL.md +5 -0
- package/stacks/nodejs/skills/typescript-strict/SKILL.md +5 -0
- package/stacks/nodejs/stack.json +2 -1
- package/stacks/nodejs/workflows/ci.yml +90 -0
- package/stacks/nodejs/workflows/security.yml +45 -0
- package/stacks/php/skills/api-design/SKILL.md +5 -0
- package/stacks/php/skills/api-security/SKILL.md +5 -0
- package/stacks/php/skills/composer-workflow/SKILL.md +5 -0
- package/stacks/php/skills/external-api-patterns/SKILL.md +5 -0
- package/stacks/php/skills/inertia-react/SKILL.md +5 -0
- package/stacks/php/skills/laravel-inertia-i18n/SKILL.md +5 -0
- package/stacks/php/skills/laravel-octane/SKILL.md +5 -0
- package/stacks/php/skills/laravel-patterns/SKILL.md +5 -0
- package/stacks/php/skills/mariadb-octane/SKILL.md +5 -0
- package/stacks/php/skills/php-patterns/SKILL.md +5 -0
- package/stacks/php/skills/phpstan-analysis/SKILL.md +5 -0
- package/stacks/php/skills/phpunit-testing/SKILL.md +5 -0
- package/stacks/php/skills/security-scan-php/SKILL.md +5 -0
- package/stacks/php/workflows/ci.yml +106 -0
- package/stacks/php/workflows/security.yml +36 -0
- package/stacks/python/skills/api-security-python/SKILL.md +312 -0
- package/stacks/python/skills/async-patterns/SKILL.md +5 -0
- package/stacks/python/skills/django-patterns/SKILL.md +5 -0
- package/stacks/python/skills/fastapi-patterns/SKILL.md +5 -0
- package/stacks/python/skills/pydantic-validation/SKILL.md +5 -0
- package/stacks/python/skills/pytest-testing/SKILL.md +5 -0
- package/stacks/python/skills/python-patterns/SKILL.md +5 -0
- package/stacks/python/skills/python-performance/SKILL.md +5 -0
- package/stacks/python/skills/scripting-automation/SKILL.md +5 -0
- package/stacks/python/stack.json +2 -1
- package/stacks/python/workflows/ci.yml +76 -0
- package/stacks/python/workflows/security.yml +56 -0
package/README.md
CHANGED
|
@@ -1,183 +1,131 @@
|
|
|
1
1
|
# Start Vibing Stacks
|
|
2
2
|
|
|
3
|
-
|
|
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
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
##
|
|
87
|
-
|
|
88
|
-
### Environment Variable Protection (Node.js)
|
|
56
|
+
## CLI
|
|
89
57
|
|
|
90
|
-
|
|
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
|
-
|
|
93
|
-
|
|
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
|
-
|
|
66
|
+
Global install: `npm i -g start-vibing-stacks` → `svs` (alias).
|
|
98
67
|
|
|
99
|
-
|
|
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
|
-
|
|
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
|
-
|
|
76
|
+
## Workflow per Task
|
|
108
77
|
|
|
109
78
|
```
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
138
|
-
npm install -g start-vibing-stacks
|
|
139
|
-
svs # shortcut alias
|
|
140
|
-
```
|
|
98
|
+
## Standards Review
|
|
141
99
|
|
|
142
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 |
|
|
171
|
-
|
|
172
|
-
|
|
|
173
|
-
|
|
|
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>;
|
package/dist/migrate.js
ADDED
|
@@ -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,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: 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
|