forgedev 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 (99) hide show
  1. package/CLAUDE.md +38 -0
  2. package/LICENSE +21 -0
  3. package/README.md +246 -0
  4. package/bin/devforge.js +4 -0
  5. package/package.json +33 -0
  6. package/src/claude-configurator.js +260 -0
  7. package/src/cli.js +119 -0
  8. package/src/composer.js +214 -0
  9. package/src/doctor-checks.js +743 -0
  10. package/src/doctor-prompts.js +295 -0
  11. package/src/doctor.js +281 -0
  12. package/src/guided.js +315 -0
  13. package/src/index.js +148 -0
  14. package/src/init-mode.js +134 -0
  15. package/src/prompts.js +155 -0
  16. package/src/recommender.js +186 -0
  17. package/src/scanner.js +368 -0
  18. package/src/uat-generator.js +189 -0
  19. package/src/utils.js +57 -0
  20. package/templates/auth/jwt-custom/backend/app/api/auth.py.template +45 -0
  21. package/templates/auth/jwt-custom/backend/app/api/deps.py.template +16 -0
  22. package/templates/auth/jwt-custom/backend/app/core/security.py.template +34 -0
  23. package/templates/auth/nextauth/src/app/api/auth/[...nextauth]/route.ts.template +3 -0
  24. package/templates/auth/nextauth/src/lib/auth.ts.template +30 -0
  25. package/templates/auth/nextauth/src/middleware.ts.template +14 -0
  26. package/templates/backend/fastapi/backend/Dockerfile.template +12 -0
  27. package/templates/backend/fastapi/backend/app/__init__.py +0 -0
  28. package/templates/backend/fastapi/backend/app/api/__init__.py +0 -0
  29. package/templates/backend/fastapi/backend/app/api/health.py.template +32 -0
  30. package/templates/backend/fastapi/backend/app/core/__init__.py +0 -0
  31. package/templates/backend/fastapi/backend/app/core/config.py.template +25 -0
  32. package/templates/backend/fastapi/backend/app/core/errors.py +37 -0
  33. package/templates/backend/fastapi/backend/app/core/retry.py +32 -0
  34. package/templates/backend/fastapi/backend/app/main.py.template +58 -0
  35. package/templates/backend/fastapi/backend/app/models/__init__.py +0 -0
  36. package/templates/backend/fastapi/backend/app/schemas/__init__.py +0 -0
  37. package/templates/backend/fastapi/backend/pyproject.toml.template +19 -0
  38. package/templates/backend/fastapi/backend/requirements.txt.template +14 -0
  39. package/templates/base/.gitignore.template +29 -0
  40. package/templates/base/README.md.template +25 -0
  41. package/templates/claude-code/agents/code-quality-reviewer.md +41 -0
  42. package/templates/claude-code/agents/production-readiness.md +55 -0
  43. package/templates/claude-code/agents/security-reviewer.md +41 -0
  44. package/templates/claude-code/agents/spec-validator.md +34 -0
  45. package/templates/claude-code/agents/uat-validator.md +37 -0
  46. package/templates/claude-code/claude-md/base.md +33 -0
  47. package/templates/claude-code/claude-md/fastapi.md +12 -0
  48. package/templates/claude-code/claude-md/fullstack.md +12 -0
  49. package/templates/claude-code/claude-md/nextjs.md +11 -0
  50. package/templates/claude-code/commands/audit-security.md +11 -0
  51. package/templates/claude-code/commands/audit-spec.md +9 -0
  52. package/templates/claude-code/commands/audit-wiring.md +17 -0
  53. package/templates/claude-code/commands/done.md +19 -0
  54. package/templates/claude-code/commands/generate-prd.md +45 -0
  55. package/templates/claude-code/commands/generate-uat.md +35 -0
  56. package/templates/claude-code/commands/help.md +26 -0
  57. package/templates/claude-code/commands/next.md +20 -0
  58. package/templates/claude-code/commands/optimize-claude-md.md +31 -0
  59. package/templates/claude-code/commands/pre-pr.md +19 -0
  60. package/templates/claude-code/commands/run-uat.md +21 -0
  61. package/templates/claude-code/commands/status.md +24 -0
  62. package/templates/claude-code/commands/verify-all.md +11 -0
  63. package/templates/claude-code/hooks/polyglot.json +36 -0
  64. package/templates/claude-code/hooks/python.json +36 -0
  65. package/templates/claude-code/hooks/scripts/autofix-polyglot.sh +16 -0
  66. package/templates/claude-code/hooks/scripts/autofix-python.sh +14 -0
  67. package/templates/claude-code/hooks/scripts/autofix-typescript.sh +14 -0
  68. package/templates/claude-code/hooks/scripts/guard-protected-files.sh +21 -0
  69. package/templates/claude-code/hooks/typescript.json +36 -0
  70. package/templates/claude-code/skills/ai-prompts/SKILL.md +43 -0
  71. package/templates/claude-code/skills/fastapi/SKILL.md +38 -0
  72. package/templates/claude-code/skills/nextjs/SKILL.md +39 -0
  73. package/templates/claude-code/skills/playwright/SKILL.md +37 -0
  74. package/templates/claude-code/skills/security-api/SKILL.md +47 -0
  75. package/templates/claude-code/skills/security-web/SKILL.md +41 -0
  76. package/templates/database/prisma-postgres/.env.example +1 -0
  77. package/templates/database/prisma-postgres/prisma/schema.prisma.template +18 -0
  78. package/templates/database/sqlalchemy-postgres/.env.example +1 -0
  79. package/templates/database/sqlalchemy-postgres/backend/alembic/env.py.template +40 -0
  80. package/templates/database/sqlalchemy-postgres/backend/alembic/versions/.gitkeep +0 -0
  81. package/templates/database/sqlalchemy-postgres/backend/alembic.ini.template +36 -0
  82. package/templates/database/sqlalchemy-postgres/backend/app/db/__init__.py +0 -0
  83. package/templates/database/sqlalchemy-postgres/backend/app/db/base.py +5 -0
  84. package/templates/database/sqlalchemy-postgres/backend/app/db/session.py.template +48 -0
  85. package/templates/frontend/nextjs/next.config.ts.template +7 -0
  86. package/templates/frontend/nextjs/package.json.template +41 -0
  87. package/templates/frontend/nextjs/postcss.config.mjs +7 -0
  88. package/templates/frontend/nextjs/src/app/api/health/route.ts.template +10 -0
  89. package/templates/frontend/nextjs/src/app/globals.css +1 -0
  90. package/templates/frontend/nextjs/src/app/layout.tsx.template +22 -0
  91. package/templates/frontend/nextjs/src/app/page.tsx.template +10 -0
  92. package/templates/frontend/nextjs/src/lib/db.ts.template +40 -0
  93. package/templates/frontend/nextjs/src/lib/errors.ts +28 -0
  94. package/templates/frontend/nextjs/src/lib/utils.ts +6 -0
  95. package/templates/frontend/nextjs/tsconfig.json +23 -0
  96. package/templates/infra/docker-compose/docker-compose.yml.template +19 -0
  97. package/templates/testing/playwright/e2e/example.spec.ts.template +15 -0
  98. package/templates/testing/playwright/playwright.config.ts.template +22 -0
  99. package/templates/testing/vitest/src/__tests__/example.test.ts.template +12 -0
package/CLAUDE.md ADDED
@@ -0,0 +1,38 @@
1
+ # DevForge
2
+
3
+ ## WHAT
4
+ - Node.js CLI tool for universal project scaffolding
5
+ - ESM modules only (no require/CommonJS)
6
+ - Dependencies: Inquirer.js (prompts), Chalk (colors), Vitest (tests)
7
+
8
+ ## Directory Map
9
+ - `bin/` — CLI entry point (`devforge.js`)
10
+ - `src/` — Core logic (index, prompts, recommender, composer, claude-configurator, uat-generator, utils)
11
+ - `templates/` — Scaffold templates organized by category (base, frontend, backend, database, auth, testing, infra, claude-code)
12
+ - `tests/` — Vitest test files
13
+ - `docs/` — Reference documentation (prompt library, playbook, multi-agent verification)
14
+
15
+ ## HOW
16
+ - Lint: `npx eslint . --ext .js` (when eslint is added)
17
+ - Test: `npx vitest run`
18
+ - Test (watch): `npx vitest`
19
+ - Manual test: `node bin/devforge.js test-output`
20
+
21
+ ## Commands
22
+ - `/project:help`, `/project:status`, `/project:next`, `/project:done` — daily workflow
23
+ - `/project:verify-all`, `/project:audit-spec`, `/project:audit-wiring`, `/project:audit-security` — verification
24
+ - `/project:pre-pr`, `/project:run-uat` — release workflow
25
+
26
+ ## Agents (all READ-ONLY, disallowedTools: Write/Edit/MultiEdit)
27
+ - code-quality-reviewer, security-reviewer, spec-validator, production-readiness, uat-validator
28
+
29
+ ## RULES
30
+ - ESM only — use `import`/`export`, never `require()`
31
+ - All source files are plain `.js` (no TypeScript for the CLI itself)
32
+ - Templates use `{{VARIABLE_NAME}}` placeholders — replaced via simple regex
33
+ - Files ending in `.template` get variable substitution; all others are binary-copied
34
+ - Template modules are composable: `templates/<category>/<stack>/` mirrors the output project structure
35
+ - Never modify files in `docs/` — those are read-only reference documents
36
+ - Keep `src/` files focused: each file has a single responsibility
37
+ - The recommender is a pure function: `(serviceType, refinements) → stackConfig`
38
+ - V1 supports 3 stacks: Next.js full-stack, FastAPI backend, polyglot (Next.js + FastAPI)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DevForge Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,246 @@
1
+ # DevForge
2
+
3
+ Universal, AI-first project scaffolding CLI. Describe what you're building, get the right stack recommended, and ship with Claude Code infrastructure pre-configured.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # New project — guided (for beginners)
9
+ npx devforge new my-app
10
+
11
+ # New project — shorthand
12
+ npx devforge my-app
13
+
14
+ # Add dev guardrails to existing project
15
+ npx devforge init
16
+
17
+ # Diagnose and optimize existing project
18
+ npx devforge doctor
19
+ ```
20
+
21
+ ## Four Modes, Four Audiences
22
+
23
+ ### 1. Guided Mode (beginners & non-developers)
24
+
25
+ Describe what you want in plain English. DevForge picks the stack.
26
+
27
+ ```
28
+ $ npx devforge new my-app
29
+
30
+ 🔨 DevForge — Let's build something.
31
+
32
+ ? How would you like to start?
33
+ 💬 Describe what you want to build (recommended for beginners)
34
+ ⚡ I know my stack — let me pick (for developers)
35
+
36
+ > Describe
37
+
38
+ Tell me about what you want to build:
39
+ > I want an app where restaurants manage their menu and customers order food
40
+
41
+ Got it! Here's what I'll set up for you:
42
+
43
+ What you'll get:
44
+ ├── A website where you can:
45
+ │ • Manage menu
46
+ │ • Manage orders
47
+
48
+ ├── User accounts (with different roles like admin and user)
49
+ ├── Payment processing for orders or subscriptions
50
+ ├── Search and filtering
51
+ ├── A database to store all your data
52
+
53
+ └── Developer tools:
54
+ • Code quality checks (catches errors automatically)
55
+ • Guided workflows (type /project:help anytime you're stuck)
56
+ • Testing templates
57
+
58
+ ? Sound right? Yes — create it!
59
+ ```
60
+
61
+ Zero technical jargon. DevForge makes all the decisions. After scaffolding, generates `docs/getting-started.md` with a beginner-friendly walkthrough.
62
+
63
+ ### 2. Developer Mode (developers who know their stack)
64
+
65
+ ```
66
+ $ npx devforge new my-app
67
+
68
+ ? How would you like to start?
69
+ ⚡ I know my stack — let me pick
70
+
71
+ ? What are you building? Full-stack app
72
+ ? Backend language? Python (polyglot)
73
+ ? Need authentication? Yes
74
+ ? Deployment target? Docker
75
+
76
+ Recommended stack:
77
+ Frontend: nextjs + typescript + tailwind + shadcn
78
+ Backend: fastapi + python + sqlalchemy
79
+ Database: postgresql (both)
80
+ Auth: both
81
+ Testing: vitest + playwright + pytest
82
+ Deploy: docker
83
+ Claude: CLAUDE.md + hooks + skills + agents + commands
84
+
85
+ ? Proceed with this stack? Yes
86
+
87
+ ✓ Done! Your project is ready.
88
+ ```
89
+
90
+ ### 3. Init Mode (add guardrails to existing projects)
91
+
92
+ ```
93
+ $ cd my-existing-project
94
+ $ npx devforge init
95
+
96
+ 🔨 DevForge — Adding dev guardrails
97
+
98
+ Scanning...
99
+
100
+ Detected: nextjs (typescript) + fastapi (python) + postgresql (prisma) + vitest + playwright + pytest
101
+
102
+ Installing:
103
+ ✓ .claude/hooks/ — auto-lint, quality gate, file protection
104
+ ✓ .claude/agents/ — code quality, security, spec validator
105
+ ✓ .claude/commands/ — help, status, next, done, audit, pre-pr
106
+ ✓ .claude/skills/ — framework-specific knowledge
107
+ ✓ docs/uat/ — acceptance test templates
108
+ ⊘ CLAUDE.md — exists (tip: run /project:optimize-claude-md to slim it)
109
+
110
+ Done. Type /project:help to get started.
111
+ ```
112
+
113
+ Zero questions. Scans, detects, installs.
114
+
115
+ ### 4. Doctor Mode (diagnose & optimize existing projects)
116
+
117
+ ```
118
+ $ npx devforge doctor
119
+
120
+ 🔨 DevForge Doctor — Project Health Check
121
+
122
+ Scanning...
123
+
124
+ 📊 Project Vitals:
125
+ Frontend: nextjs (typescript)
126
+ Backend: fastapi (python)
127
+ Database: postgresql (sqlalchemy)
128
+ Testing: vitest + playwright + pytest
129
+
130
+ Health Issues Found:
131
+
132
+ 🔴 CRITICAL
133
+ 1. CLAUDE.md is 647 lines (recommended limit: 150)
134
+ → Instructions are being dropped
135
+ 2. 4 endpoints have no authentication
136
+ → Security vulnerability
137
+
138
+ 🟡 WARNING
139
+ 3. No health check endpoint
140
+ 4. No UAT scenarios
141
+ 5. 3 bare except: blocks
142
+
143
+ ? What would you like to do?
144
+ 🚑 Fix critical issues (guided, one at a time)
145
+ 📋 Generate a full report (save to docs/doctor-report.md)
146
+ ⚡ Auto-fix what's safe to auto-fix
147
+ 📖 Just show me what to do (generates prompts for Claude Code)
148
+ ```
149
+
150
+ Doctor diagnoses problems and generates the exact Claude Code prompt to fix each one.
151
+
152
+ ## Supported Stacks (V1)
153
+
154
+ | Selection | Stack |
155
+ |---|---|
156
+ | Web app / Full-stack + TypeScript | Next.js 15 + Prisma + PostgreSQL + NextAuth + Vitest + Playwright |
157
+ | API service + Python | FastAPI + SQLAlchemy 2.0 + PostgreSQL + Alembic + Pytest |
158
+ | Full-stack + TS + Python | Next.js frontend + FastAPI backend (polyglot monorepo) |
159
+ | AI/ML service | Polyglot full-stack with AI integration flag |
160
+
161
+ ## What Gets Generated
162
+
163
+ Every project includes:
164
+
165
+ - **Project scaffold** with working code, configs, and dependencies
166
+ - **Health check endpoints** (`/health`, `/healthz`)
167
+ - **Graceful shutdown handlers**
168
+ - **Database connection retry** with exponential backoff
169
+ - **Structured error responses** (never leaks stack traces)
170
+
171
+ With Claude Code infrastructure enabled (default):
172
+
173
+ - **CLAUDE.md** tailored to your stack
174
+ - **Hooks** — auto-lint on edit, quality gate on stop
175
+ - **Skills** — framework-specific knowledge
176
+ - **Agents** — 5-agent verification chain
177
+ - **Commands** — verify-all, audit-spec, audit-wiring, audit-security, pre-pr, run-uat, generate-prd, generate-uat, optimize-claude-md
178
+ - **UAT templates** — scenario packs and CSV checklists
179
+ - **Prompt library** — the complete development prompt library
180
+
181
+ ## Development
182
+
183
+ ```bash
184
+ npm install
185
+ npm test # run unit tests
186
+ node bin/devforge.js test-output # manual smoke test (guided + developer)
187
+ node bin/devforge.js init # test init mode (from any project dir)
188
+ node bin/devforge.js doctor # test doctor mode (from any project dir)
189
+ ```
190
+
191
+ ## Project Structure
192
+
193
+ ```
194
+ devforge/
195
+ ├── bin/devforge.js # CLI entry point
196
+ ├── src/
197
+ │ ├── cli.js # Command router (new, init, doctor)
198
+ │ ├── index.js # New project orchestrator (guided + developer)
199
+ │ ├── guided.js # Guided mode (description → stack)
200
+ │ ├── prompts.js # Interactive prompts (Inquirer.js)
201
+ │ ├── recommender.js # Service type → stack recommendation
202
+ │ ├── composer.js # Template composition engine
203
+ │ ├── claude-configurator.js # Generates .claude/ infrastructure
204
+ │ ├── uat-generator.js # Generates UAT templates
205
+ │ ├── scanner.js # Project scanner (for init + doctor)
206
+ │ ├── init-mode.js # Init mode orchestrator
207
+ │ ├── doctor.js # Doctor mode orchestrator
208
+ │ ├── doctor-checks.js # Diagnostic check functions
209
+ │ ├── doctor-prompts.js # Fix prompt generators
210
+ │ └── utils.js # File ops, logging, colors
211
+ ├── templates/ # Scaffold templates by category
212
+ │ ├── base/ # Every project gets this
213
+ │ ├── frontend/nextjs/ # Next.js App Router
214
+ │ ├── backend/fastapi/ # FastAPI + SQLAlchemy
215
+ │ ├── database/ # Prisma, SQLAlchemy
216
+ │ ├── auth/ # NextAuth, JWT
217
+ │ ├── testing/ # Vitest, Playwright, Pytest
218
+ │ ├── infra/ # Docker Compose, GitHub Actions
219
+ │ └── claude-code/ # Hooks, CLAUDE.md, skills, agents, commands
220
+ ├── tests/ # Vitest tests
221
+ └── docs/ # Reference documentation
222
+ ```
223
+
224
+ ## Claude Code Commands
225
+
226
+ | Command | What It Does |
227
+ |---------|-------------|
228
+ | `/project:help` | Asks your situation, gives the exact prompt |
229
+ | `/project:status` | Project dashboard — tests, branch, changes |
230
+ | `/project:next` | Figures out your next task |
231
+ | `/project:done` | Verifies task completion |
232
+ | `/project:generate-prd` | Generates a PRD with Mermaid diagrams |
233
+ | `/project:generate-uat` | Generates UAT scenarios from codebase |
234
+ | `/project:optimize-claude-md` | Proposes splitting an oversized CLAUDE.md |
235
+
236
+ ## Roadmap
237
+
238
+ - [ ] Go + Gin/Chi backend
239
+ - [ ] Rust + Axum backend
240
+ - [ ] React + Vite SPA (frontend-only)
241
+ - [ ] React Native / Expo mobile
242
+ - [ ] Plugin ecosystem for community templates
243
+
244
+ ## License
245
+
246
+ MIT
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { parseCommand } from '../src/cli.js';
3
+
4
+ parseCommand(process.argv.slice(2));
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "forgedev",
3
+ "version": "1.0.0",
4
+ "description": "Universal, AI-first project scaffolding CLI with Claude Code infrastructure",
5
+ "type": "module",
6
+ "bin": {
7
+ "forgedev": "bin/devforge.js",
8
+ "devforge": "bin/devforge.js"
9
+ },
10
+ "scripts": {
11
+ "test": "vitest run",
12
+ "test:watch": "vitest"
13
+ },
14
+ "keywords": [
15
+ "scaffolding",
16
+ "cli",
17
+ "project-generator",
18
+ "claude-code",
19
+ "ai-first"
20
+ ],
21
+ "author": "",
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "chalk": "^5.4.1",
25
+ "@inquirer/prompts": "^7.10.0"
26
+ },
27
+ "devDependencies": {
28
+ "vitest": "^3.1.1"
29
+ },
30
+ "engines": {
31
+ "node": ">=18.0.0"
32
+ }
33
+ }
@@ -0,0 +1,260 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { ROOT_DIR, ensureDir, writeFile, readTemplate, replaceVars, log } from './utils.js';
4
+
5
+ const CLAUDE_TEMPLATES_DIR = path.join(ROOT_DIR, 'templates', 'claude-code');
6
+ const DOCS_DIR = path.join(ROOT_DIR, 'docs');
7
+
8
+ export async function generateClaudeConfig(outputDir, stackConfig, options = {}) {
9
+ const vars = buildClaudeVars(stackConfig);
10
+
11
+ if (!options.skipClaudeMd) {
12
+ generateClaudeMd(outputDir, stackConfig, vars);
13
+ }
14
+ generateHooks(outputDir, stackConfig, { merge: options.mergeSettings });
15
+ generateSkills(outputDir, stackConfig);
16
+ generateAgents(outputDir, stackConfig, vars);
17
+ generateCommands(outputDir, stackConfig, vars);
18
+ copyPromptLibrary(outputDir);
19
+ }
20
+
21
+ function buildClaudeVars(config) {
22
+ const vars = {
23
+ PROJECT_NAME: config.projectName,
24
+ PROJECT_NAME_PASCAL: config.projectName.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(''),
25
+ };
26
+
27
+ if (config.stackId === 'nextjs-fullstack') {
28
+ vars.STACK_SUMMARY = 'Next.js 15 (App Router) + TypeScript + Tailwind CSS + Prisma + PostgreSQL';
29
+ vars.LINT_COMMAND = 'npx eslint .';
30
+ vars.TYPE_CHECK_COMMAND = 'npx tsc --noEmit';
31
+ vars.TEST_COMMAND = 'npx vitest run';
32
+ vars.BUILD_COMMAND = 'npm run build';
33
+ vars.DEV_COMMAND = 'npm run dev';
34
+ vars.DIR_MAP = `- src/app/ — Next.js App Router pages and API routes
35
+ - src/lib/ — Shared utilities, database client, error handling
36
+ - src/components/ — React components
37
+ - prisma/ — Database schema and migrations
38
+ - e2e/ — Playwright E2E tests`;
39
+ } else if (config.stackId === 'fastapi-backend') {
40
+ vars.STACK_SUMMARY = 'FastAPI + Python + SQLAlchemy 2.0 + PostgreSQL + Alembic';
41
+ vars.LINT_COMMAND = 'ruff check .';
42
+ vars.TYPE_CHECK_COMMAND = 'pyright';
43
+ vars.TEST_COMMAND = 'pytest';
44
+ vars.BUILD_COMMAND = 'docker build -t app .';
45
+ vars.DEV_COMMAND = 'uvicorn app.main:app --reload';
46
+ vars.DIR_MAP = `- backend/app/ — FastAPI application
47
+ - backend/app/api/ — API route handlers
48
+ - backend/app/core/ — Config, security, error handling
49
+ - backend/app/db/ — Database session and models
50
+ - backend/app/models/ — SQLAlchemy models
51
+ - backend/app/schemas/ — Pydantic schemas
52
+ - backend/tests/ — Pytest tests
53
+ - backend/alembic/ — Database migrations`;
54
+ } else if (config.stackId === 'polyglot-fullstack') {
55
+ vars.STACK_SUMMARY = 'Next.js 15 (frontend) + FastAPI (backend) + PostgreSQL';
56
+ vars.LINT_COMMAND = 'cd frontend && npx eslint . && cd ../backend && ruff check .';
57
+ vars.TYPE_CHECK_COMMAND = 'cd frontend && npx tsc --noEmit';
58
+ vars.TEST_COMMAND = 'cd frontend && npx vitest run && cd ../backend && pytest';
59
+ vars.BUILD_COMMAND = 'docker compose build';
60
+ vars.DEV_COMMAND = 'docker compose up';
61
+ vars.DIR_MAP = `- frontend/ — Next.js 15 App Router application
62
+ - frontend/src/app/ — Pages and API routes
63
+ - frontend/src/lib/ — Shared utilities
64
+ - backend/ — FastAPI application
65
+ - backend/app/api/ — API route handlers
66
+ - backend/app/core/ — Config, security, error handling
67
+ - backend/app/db/ — Database session and models
68
+ - e2e/ — Playwright E2E tests`;
69
+ }
70
+
71
+ // Build skills list for CLAUDE.md reference
72
+ const skillsList = [];
73
+ if (config.frontend?.framework === 'nextjs') {
74
+ skillsList.push('- `@.claude/skills/nextjs/` — Next.js patterns and conventions');
75
+ skillsList.push('- `@.claude/skills/security-web/` — Frontend security practices');
76
+ }
77
+ if (config.backend?.framework === 'fastapi') {
78
+ skillsList.push('- `@.claude/skills/fastapi/` — FastAPI patterns and conventions');
79
+ skillsList.push('- `@.claude/skills/security-api/` — API security practices');
80
+ }
81
+ if (config.testing?.e2e === 'playwright') {
82
+ skillsList.push('- `@.claude/skills/playwright/` — E2E testing patterns');
83
+ }
84
+ if (config.ai) {
85
+ skillsList.push('- `@.claude/skills/ai-prompts/` — AI/LLM prompt patterns');
86
+ }
87
+ vars.SKILLS_LIST = skillsList.length > 0 ? skillsList.join('\n') : '- (none generated)';
88
+
89
+ return vars;
90
+ }
91
+
92
+ function generateClaudeMd(outputDir, config, vars) {
93
+ // Read base template
94
+ const basePath = path.join(CLAUDE_TEMPLATES_DIR, 'claude-md', 'base.md');
95
+ let content = readTemplate(basePath);
96
+
97
+ // Read stack-specific section
98
+ let stackSection = '';
99
+ if (config.stackId === 'nextjs-fullstack') {
100
+ stackSection = readTemplate(path.join(CLAUDE_TEMPLATES_DIR, 'claude-md', 'nextjs.md'));
101
+ } else if (config.stackId === 'fastapi-backend') {
102
+ stackSection = readTemplate(path.join(CLAUDE_TEMPLATES_DIR, 'claude-md', 'fastapi.md'));
103
+ } else if (config.stackId === 'polyglot-fullstack') {
104
+ stackSection = readTemplate(path.join(CLAUDE_TEMPLATES_DIR, 'claude-md', 'fullstack.md'));
105
+ }
106
+
107
+ content = content.replace('{{STACK_SPECIFIC_RULES}}', stackSection);
108
+ content = replaceVars(content, vars);
109
+
110
+ writeFile(path.join(outputDir, 'CLAUDE.md'), content);
111
+ }
112
+
113
+ function generateHooks(outputDir, config, options = {}) {
114
+ let hookFile;
115
+ let scriptFiles = ['guard-protected-files.sh'];
116
+
117
+ if (config.stackId === 'nextjs-fullstack') {
118
+ hookFile = 'typescript.json';
119
+ scriptFiles.push('autofix-typescript.sh');
120
+ } else if (config.stackId === 'fastapi-backend') {
121
+ hookFile = 'python.json';
122
+ scriptFiles.push('autofix-python.sh');
123
+ } else if (config.stackId === 'polyglot-fullstack') {
124
+ hookFile = 'polyglot.json';
125
+ scriptFiles.push('autofix-polyglot.sh');
126
+ }
127
+
128
+ const settingsPath = path.join(outputDir, '.claude', 'settings.json');
129
+
130
+ if (options.merge && fs.existsSync(settingsPath)) {
131
+ // Merge hooks into existing settings.json
132
+ const existing = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
133
+ const incoming = JSON.parse(readTemplate(path.join(CLAUDE_TEMPLATES_DIR, 'hooks', hookFile)));
134
+ const merged = deepMergeSettings(existing, incoming);
135
+ writeFile(settingsPath, JSON.stringify(merged, null, 2));
136
+ } else {
137
+ const hookPath = path.join(CLAUDE_TEMPLATES_DIR, 'hooks', hookFile);
138
+ const content = readTemplate(hookPath);
139
+ writeFile(settingsPath, content);
140
+ }
141
+
142
+ // Copy hook scripts
143
+ const hooksDir = path.join(outputDir, '.claude', 'hooks');
144
+ ensureDir(hooksDir);
145
+ for (const script of scriptFiles) {
146
+ const srcPath = path.join(CLAUDE_TEMPLATES_DIR, 'hooks', 'scripts', script);
147
+ if (fs.existsSync(srcPath)) {
148
+ fs.copyFileSync(srcPath, path.join(hooksDir, script));
149
+ }
150
+ }
151
+ }
152
+
153
+ function deepMergeSettings(existing, incoming) {
154
+ const merged = { ...existing };
155
+ if (incoming.hooks) {
156
+ merged.hooks = merged.hooks || {};
157
+ for (const [hookType, hookArr] of Object.entries(incoming.hooks)) {
158
+ if (!merged.hooks[hookType]) {
159
+ merged.hooks[hookType] = hookArr;
160
+ } else {
161
+ // Append incoming hooks that don't already exist (by command)
162
+ const existingCommands = new Set(
163
+ merged.hooks[hookType].flatMap(h => (h.hooks || []).map(hk => hk.command))
164
+ );
165
+ for (const hook of hookArr) {
166
+ const isNew = (hook.hooks || []).some(hk => !existingCommands.has(hk.command));
167
+ if (isNew) {
168
+ merged.hooks[hookType].push(hook);
169
+ }
170
+ }
171
+ }
172
+ }
173
+ }
174
+ return merged;
175
+ }
176
+
177
+ function generateSkills(outputDir, config) {
178
+ const skillsToInclude = [];
179
+
180
+ if (config.frontend?.framework === 'nextjs') {
181
+ skillsToInclude.push('nextjs');
182
+ skillsToInclude.push('security-web');
183
+ }
184
+ if (config.backend?.framework === 'fastapi') {
185
+ skillsToInclude.push('fastapi');
186
+ skillsToInclude.push('security-api');
187
+ }
188
+ if (config.testing?.e2e === 'playwright') {
189
+ skillsToInclude.push('playwright');
190
+ }
191
+ if (config.ai) {
192
+ skillsToInclude.push('ai-prompts');
193
+ }
194
+
195
+ for (const skill of skillsToInclude) {
196
+ const srcPath = path.join(CLAUDE_TEMPLATES_DIR, 'skills', skill, 'SKILL.md');
197
+ if (fs.existsSync(srcPath)) {
198
+ const destPath = path.join(outputDir, '.claude', 'skills', skill, 'SKILL.md');
199
+ ensureDir(path.dirname(destPath));
200
+ fs.copyFileSync(srcPath, destPath);
201
+ }
202
+ }
203
+ }
204
+
205
+ function generateAgents(outputDir, config, vars) {
206
+ const agentsDir = path.join(CLAUDE_TEMPLATES_DIR, 'agents');
207
+ const agents = [
208
+ 'code-quality-reviewer.md',
209
+ 'security-reviewer.md',
210
+ 'spec-validator.md',
211
+ 'production-readiness.md',
212
+ 'uat-validator.md',
213
+ ];
214
+
215
+ for (const agent of agents) {
216
+ const srcPath = path.join(agentsDir, agent);
217
+ if (fs.existsSync(srcPath)) {
218
+ let content = readTemplate(srcPath);
219
+ content = replaceVars(content, vars);
220
+ writeFile(path.join(outputDir, '.claude', 'agents', agent), content);
221
+ }
222
+ }
223
+ }
224
+
225
+ function generateCommands(outputDir, config, vars) {
226
+ const commandsDir = path.join(CLAUDE_TEMPLATES_DIR, 'commands');
227
+ const commands = [
228
+ 'help.md',
229
+ 'status.md',
230
+ 'next.md',
231
+ 'done.md',
232
+ 'verify-all.md',
233
+ 'audit-spec.md',
234
+ 'audit-wiring.md',
235
+ 'audit-security.md',
236
+ 'pre-pr.md',
237
+ 'run-uat.md',
238
+ 'generate-prd.md',
239
+ 'generate-uat.md',
240
+ 'optimize-claude-md.md',
241
+ ];
242
+
243
+ for (const cmd of commands) {
244
+ const srcPath = path.join(commandsDir, cmd);
245
+ if (fs.existsSync(srcPath)) {
246
+ let content = readTemplate(srcPath);
247
+ content = replaceVars(content, vars);
248
+ writeFile(path.join(outputDir, '.claude', 'commands', cmd), content);
249
+ }
250
+ }
251
+ }
252
+
253
+ function copyPromptLibrary(outputDir) {
254
+ const srcPath = path.join(DOCS_DIR, '01-universal-prompt-library.md');
255
+ if (fs.existsSync(srcPath)) {
256
+ const destPath = path.join(outputDir, 'docs', 'prompt-library.md');
257
+ ensureDir(path.dirname(destPath));
258
+ fs.copyFileSync(srcPath, destPath);
259
+ }
260
+ }