forgedev 1.0.2 → 1.1.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 +122 -26
- package/bin/devforge.js +10 -1
- package/package.json +1 -1
- package/src/claude-configurator.js +29 -6
- package/src/cli.js +11 -0
- package/src/doctor-prompts.js +9 -2
- package/src/doctor.js +19 -0
- package/src/index.js +7 -0
- package/src/update-check.js +49 -0
- package/src/update.js +33 -0
- package/templates/auth/jwt-custom/backend/app/core/security.py.template +4 -1
- package/templates/backend/fastapi/backend/app/core/config.py.template +2 -2
- package/templates/claude-code/agents/architect.md +70 -0
- package/templates/claude-code/agents/build-error-resolver.md +30 -0
- package/templates/claude-code/agents/chief-of-staff.md +52 -0
- package/templates/claude-code/agents/database-reviewer.md +58 -0
- package/templates/claude-code/agents/doc-updater.md +39 -0
- package/templates/claude-code/agents/docs-lookup.md +51 -0
- package/templates/claude-code/agents/e2e-runner.md +57 -0
- package/templates/claude-code/agents/harness-optimizer.md +65 -0
- package/templates/claude-code/agents/loop-operator.md +52 -0
- package/templates/claude-code/agents/planner.md +60 -0
- package/templates/claude-code/agents/refactor-cleaner.md +42 -0
- package/templates/claude-code/agents/tdd-guide.md +47 -0
- package/templates/claude-code/agents/uat-validator.md +2 -1
- package/templates/claude-code/claude-md/base.md +29 -1
- package/templates/claude-code/claude-md/fastapi.md +8 -0
- package/templates/claude-code/claude-md/fullstack.md +8 -0
- package/templates/claude-code/claude-md/nextjs.md +8 -0
- package/templates/claude-code/commands/build-fix.md +43 -0
- package/templates/claude-code/commands/code-review.md +44 -0
- package/templates/claude-code/commands/full-audit.md +60 -0
- package/templates/claude-code/commands/plan.md +21 -0
- package/templates/claude-code/commands/resume-session.md +50 -0
- package/templates/claude-code/commands/save-session.md +69 -0
- package/templates/claude-code/commands/tdd.md +80 -0
- package/templates/claude-code/commands/workflows.md +12 -1
- package/templates/claude-code/hooks/polyglot.json +2 -2
- package/templates/claude-code/hooks/python.json +2 -2
- package/templates/claude-code/hooks/scripts/autofix-polyglot.mjs +44 -0
- package/templates/claude-code/hooks/scripts/autofix-python.mjs +38 -0
- package/templates/claude-code/hooks/scripts/autofix-typescript.mjs +38 -0
- package/templates/claude-code/hooks/scripts/guard-protected-files.mjs +34 -0
- package/templates/claude-code/hooks/typescript.json +2 -2
- package/templates/claude-code/skills/ai-prompts/SKILL.md +1 -0
- package/templates/claude-code/skills/fastapi/SKILL.md +1 -1
- package/templates/claude-code/skills/git-workflow/SKILL.md +64 -0
- package/templates/claude-code/skills/playwright/SKILL.md +2 -2
- package/templates/claude-code/skills/security-api/SKILL.md +2 -2
- package/templates/claude-code/skills/testing-patterns/SKILL.md +97 -0
- package/templates/database/sqlalchemy-postgres/.env.example +1 -0
- package/templates/claude-code/hooks/scripts/autofix-polyglot.sh +0 -16
- package/templates/claude-code/hooks/scripts/autofix-python.sh +0 -14
- package/templates/claude-code/hooks/scripts/autofix-typescript.sh +0 -14
- package/templates/claude-code/hooks/scripts/guard-protected-files.sh +0 -21
package/README.md
CHANGED
|
@@ -6,16 +6,19 @@ Universal, AI-first project scaffolding CLI. Describe what you're building, get
|
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
# New project — guided (for beginners)
|
|
9
|
-
npx
|
|
9
|
+
npx forgedev new my-app
|
|
10
10
|
|
|
11
11
|
# New project — shorthand
|
|
12
|
-
npx
|
|
12
|
+
npx forgedev my-app
|
|
13
13
|
|
|
14
14
|
# Add dev guardrails to existing project
|
|
15
|
-
npx
|
|
15
|
+
npx forgedev init
|
|
16
16
|
|
|
17
17
|
# Diagnose and optimize existing project
|
|
18
|
-
npx
|
|
18
|
+
npx forgedev doctor
|
|
19
|
+
|
|
20
|
+
# Check for updates
|
|
21
|
+
npx forgedev update
|
|
19
22
|
```
|
|
20
23
|
|
|
21
24
|
## Four Modes, Four Audiences
|
|
@@ -25,7 +28,7 @@ npx devforge doctor
|
|
|
25
28
|
Describe what you want in plain English. DevForge picks the stack.
|
|
26
29
|
|
|
27
30
|
```
|
|
28
|
-
$ npx
|
|
31
|
+
$ npx forgedev new my-app
|
|
29
32
|
|
|
30
33
|
🔨 DevForge — Let's build something.
|
|
31
34
|
|
|
@@ -52,7 +55,7 @@ Tell me about what you want to build:
|
|
|
52
55
|
│
|
|
53
56
|
└── Developer tools:
|
|
54
57
|
• Code quality checks (catches errors automatically)
|
|
55
|
-
• Guided workflows (type /
|
|
58
|
+
• Guided workflows (type /workflows anytime you're stuck)
|
|
56
59
|
• Testing templates
|
|
57
60
|
|
|
58
61
|
? Sound right? Yes — create it!
|
|
@@ -63,7 +66,7 @@ Zero technical jargon. DevForge makes all the decisions. After scaffolding, gene
|
|
|
63
66
|
### 2. Developer Mode (developers who know their stack)
|
|
64
67
|
|
|
65
68
|
```
|
|
66
|
-
$ npx
|
|
69
|
+
$ npx forgedev new my-app
|
|
67
70
|
|
|
68
71
|
? How would you like to start?
|
|
69
72
|
⚡ I know my stack — let me pick
|
|
@@ -91,7 +94,7 @@ $ npx devforge new my-app
|
|
|
91
94
|
|
|
92
95
|
```
|
|
93
96
|
$ cd my-existing-project
|
|
94
|
-
$ npx
|
|
97
|
+
$ npx forgedev init
|
|
95
98
|
|
|
96
99
|
🔨 DevForge — Adding dev guardrails
|
|
97
100
|
|
|
@@ -100,14 +103,18 @@ $ npx devforge init
|
|
|
100
103
|
Detected: nextjs (typescript) + fastapi (python) + postgresql (prisma) + vitest + playwright + pytest
|
|
101
104
|
|
|
102
105
|
Installing:
|
|
106
|
+
✓ CLAUDE.md — project context + rules
|
|
103
107
|
✓ .claude/hooks/ — auto-lint, quality gate, file protection
|
|
104
108
|
✓ .claude/agents/ — code quality, security, spec validator
|
|
105
|
-
✓ .claude/commands/ —
|
|
109
|
+
✓ .claude/commands/ — workflows, status, next, done, audit, pre-pr
|
|
106
110
|
✓ .claude/skills/ — framework-specific knowledge
|
|
107
111
|
✓ docs/uat/ — acceptance test templates
|
|
108
|
-
⊘ CLAUDE.md — exists (tip: run /project:optimize-claude-md to slim it)
|
|
109
112
|
|
|
110
|
-
Done.
|
|
113
|
+
Done. Your project is now configured for Claude Code.
|
|
114
|
+
|
|
115
|
+
Next steps:
|
|
116
|
+
1. Open Claude Code in this directory: claude
|
|
117
|
+
2. Type /workflows to see available workflows
|
|
111
118
|
```
|
|
112
119
|
|
|
113
120
|
Zero questions. Scans, detects, installs.
|
|
@@ -115,7 +122,7 @@ Zero questions. Scans, detects, installs.
|
|
|
115
122
|
### 4. Doctor Mode (diagnose & optimize existing projects)
|
|
116
123
|
|
|
117
124
|
```
|
|
118
|
-
$ npx
|
|
125
|
+
$ npx forgedev doctor
|
|
119
126
|
|
|
120
127
|
🔨 DevForge Doctor — Project Health Check
|
|
121
128
|
|
|
@@ -170,14 +177,51 @@ Every project includes:
|
|
|
170
177
|
|
|
171
178
|
With Claude Code infrastructure enabled (default):
|
|
172
179
|
|
|
173
|
-
- **CLAUDE.md** tailored to your stack
|
|
174
|
-
- **Hooks** — auto-lint on edit, quality gate
|
|
175
|
-
- **
|
|
176
|
-
- **
|
|
177
|
-
- **
|
|
180
|
+
- **CLAUDE.md** tailored to your stack (with pitfalls and agents quick-reference)
|
|
181
|
+
- **Hooks** — cross-platform Node.js `.mjs` hooks (auto-lint on edit, quality gate, protected file guard)
|
|
182
|
+
- **17 Agents** — verification, development, review, and orchestration (see below)
|
|
183
|
+
- **20 Commands** — daily workflow, verification, release, development, session management
|
|
184
|
+
- **8 Skills** — framework-specific + universal knowledge
|
|
178
185
|
- **UAT templates** — scenario packs and CSV checklists
|
|
179
186
|
- **Prompt library** — the complete development prompt library
|
|
180
187
|
|
|
188
|
+
## Agents (17)
|
|
189
|
+
|
|
190
|
+
Every scaffolded project gets these agents in `.claude/agents/`:
|
|
191
|
+
|
|
192
|
+
| Agent | Role | Access |
|
|
193
|
+
|-------|------|--------|
|
|
194
|
+
| `architect` | System design, data models, API contracts | Read-only |
|
|
195
|
+
| `build-error-resolver` | Fix build/lint/type errors with minimal changes | Write |
|
|
196
|
+
| `chief-of-staff` | Orchestrate multiple agents for complex tasks | Write |
|
|
197
|
+
| `code-quality-reviewer` | Code quality review | Read-only |
|
|
198
|
+
| `database-reviewer` | Query optimization, schema review, N+1 detection | Read-only |
|
|
199
|
+
| `doc-updater` | Keep docs in sync with code changes | Write |
|
|
200
|
+
| `docs-lookup` | Search framework docs for answers | Read-only |
|
|
201
|
+
| `e2e-runner` | Generate and run Playwright E2E tests | Write |
|
|
202
|
+
| `harness-optimizer` | Audit Claude Code setup, suggest optimizations | Read-only |
|
|
203
|
+
| `loop-operator` | Autonomous improvement loops with stop conditions | Write |
|
|
204
|
+
| `planner` | Create implementation plans before coding | Read-only |
|
|
205
|
+
| `production-readiness` | Production deployment readiness review | Read-only |
|
|
206
|
+
| `refactor-cleaner` | Dead code removal, duplicate elimination | Write |
|
|
207
|
+
| `security-reviewer` | Security audit | Read-only |
|
|
208
|
+
| `spec-validator` | Validate implementation matches specification | Read-only |
|
|
209
|
+
| `tdd-guide` | Enforce RED-GREEN-REFACTOR TDD cycle | Write |
|
|
210
|
+
| `uat-validator` | QA validation of UAT scenarios | Read-only |
|
|
211
|
+
|
|
212
|
+
## Skills (8)
|
|
213
|
+
|
|
214
|
+
| Skill | Scope |
|
|
215
|
+
|-------|-------|
|
|
216
|
+
| `nextjs` | Next.js 15 App Router patterns |
|
|
217
|
+
| `fastapi` | FastAPI + SQLAlchemy 2.0 + Pydantic v2 |
|
|
218
|
+
| `playwright` | Playwright E2E testing |
|
|
219
|
+
| `security-web` | Web application security |
|
|
220
|
+
| `security-api` | API security |
|
|
221
|
+
| `ai-prompts` | AI/LLM integration patterns |
|
|
222
|
+
| `git-workflow` | Git branching, commits, PR workflow (universal) |
|
|
223
|
+
| `testing-patterns` | Test pyramid, AAA pattern, mocking (universal) |
|
|
224
|
+
|
|
181
225
|
## Development
|
|
182
226
|
|
|
183
227
|
```bash
|
|
@@ -186,6 +230,7 @@ npm test # run unit tests
|
|
|
186
230
|
node bin/devforge.js test-output # manual smoke test (guided + developer)
|
|
187
231
|
node bin/devforge.js init # test init mode (from any project dir)
|
|
188
232
|
node bin/devforge.js doctor # test doctor mode (from any project dir)
|
|
233
|
+
node bin/devforge.js update # check for updates
|
|
189
234
|
```
|
|
190
235
|
|
|
191
236
|
## Project Structure
|
|
@@ -194,7 +239,7 @@ node bin/devforge.js doctor # test doctor mode (from any project dir)
|
|
|
194
239
|
devforge/
|
|
195
240
|
├── bin/devforge.js # CLI entry point
|
|
196
241
|
├── src/
|
|
197
|
-
│ ├── cli.js # Command router (new, init, doctor)
|
|
242
|
+
│ ├── cli.js # Command router (new, init, doctor, update)
|
|
198
243
|
│ ├── index.js # New project orchestrator (guided + developer)
|
|
199
244
|
│ ├── guided.js # Guided mode (description → stack)
|
|
200
245
|
│ ├── prompts.js # Interactive prompts (Inquirer.js)
|
|
@@ -207,6 +252,8 @@ devforge/
|
|
|
207
252
|
│ ├── doctor.js # Doctor mode orchestrator
|
|
208
253
|
│ ├── doctor-checks.js # Diagnostic check functions
|
|
209
254
|
│ ├── doctor-prompts.js # Fix prompt generators
|
|
255
|
+
│ ├── update-check.js # npm registry version check
|
|
256
|
+
│ ├── update.js # Update command handler
|
|
210
257
|
│ └── utils.js # File ops, logging, colors
|
|
211
258
|
├── templates/ # Scaffold templates by category
|
|
212
259
|
│ ├── base/ # Every project gets this
|
|
@@ -221,17 +268,66 @@ devforge/
|
|
|
221
268
|
└── docs/ # Reference documentation
|
|
222
269
|
```
|
|
223
270
|
|
|
224
|
-
## Claude Code Commands
|
|
271
|
+
## Claude Code Commands (20)
|
|
272
|
+
|
|
273
|
+
After running `npx forgedev init`, these slash commands are available inside Claude Code:
|
|
274
|
+
|
|
275
|
+
**Daily Workflow:**
|
|
276
|
+
|
|
277
|
+
| Command | What It Does |
|
|
278
|
+
|---------|-------------|
|
|
279
|
+
| `/workflows` | Lists all available workflows |
|
|
280
|
+
| `/status` | Project dashboard — tests, branch, changes |
|
|
281
|
+
| `/next` | Figures out your next task |
|
|
282
|
+
| `/done` | Verifies task completion |
|
|
283
|
+
|
|
284
|
+
**Verification:**
|
|
225
285
|
|
|
226
286
|
| Command | What It Does |
|
|
227
287
|
|---------|-------------|
|
|
228
|
-
| `/
|
|
229
|
-
| `/
|
|
230
|
-
| `/
|
|
231
|
-
| `/
|
|
232
|
-
| `/
|
|
233
|
-
| `/
|
|
234
|
-
|
|
288
|
+
| `/verify-all` | Runs lint, type check, tests, then launches reviewers |
|
|
289
|
+
| `/full-audit` | Runs every audit and review agent in a single pass |
|
|
290
|
+
| `/audit-spec` | Validates implementation against a spec/PRD |
|
|
291
|
+
| `/audit-wiring` | Finds dead or unwired features |
|
|
292
|
+
| `/audit-security` | Runs a security audit |
|
|
293
|
+
| `/code-review` | Reviews uncommitted changes for security and quality |
|
|
294
|
+
|
|
295
|
+
**Release:**
|
|
296
|
+
|
|
297
|
+
| Command | What It Does |
|
|
298
|
+
|---------|-------------|
|
|
299
|
+
| `/pre-pr` | Runs the complete pre-PR checklist |
|
|
300
|
+
| `/run-uat` | Executes UAT scenarios |
|
|
301
|
+
|
|
302
|
+
**Development:**
|
|
303
|
+
|
|
304
|
+
| Command | What It Does |
|
|
305
|
+
|---------|-------------|
|
|
306
|
+
| `/plan` | Invoke planner agent for implementation planning |
|
|
307
|
+
| `/build-fix` | Incrementally fix build/lint/type errors |
|
|
308
|
+
| `/tdd` | Enforce test-driven development cycle |
|
|
309
|
+
| `/generate-prd` | Generates a PRD with Mermaid diagrams |
|
|
310
|
+
| `/generate-uat` | Generates UAT scenarios from codebase |
|
|
311
|
+
| `/optimize-claude-md` | Proposes splitting an oversized CLAUDE.md |
|
|
312
|
+
|
|
313
|
+
**Session:**
|
|
314
|
+
|
|
315
|
+
| Command | What It Does |
|
|
316
|
+
|---------|-------------|
|
|
317
|
+
| `/save-session` | Save work context for later resumption |
|
|
318
|
+
| `/resume-session` | Load saved session and continue where you left off |
|
|
319
|
+
|
|
320
|
+
## Install
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
# Use directly (no install needed)
|
|
324
|
+
npx forgedev new my-app
|
|
325
|
+
|
|
326
|
+
# Or install globally
|
|
327
|
+
npm install -g forgedev
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Package name on npm: [`forgedev`](https://www.npmjs.com/package/forgedev)
|
|
235
331
|
|
|
236
332
|
## Roadmap
|
|
237
333
|
|
package/bin/devforge.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { parseCommand } from '../src/cli.js';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
try {
|
|
5
|
+
await parseCommand(process.argv.slice(2));
|
|
6
|
+
} catch (err) {
|
|
7
|
+
// Graceful exit on Ctrl+C / prompt cancellation
|
|
8
|
+
if (err?.name === 'ExitPromptError' || err?.code === 'ERR_USE_AFTER_CLOSE') {
|
|
9
|
+
console.log('');
|
|
10
|
+
process.exit(0);
|
|
11
|
+
}
|
|
12
|
+
throw err;
|
|
13
|
+
}
|
package/package.json
CHANGED
|
@@ -69,7 +69,10 @@ function buildClaudeVars(config) {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// Build skills list for CLAUDE.md reference
|
|
72
|
-
const skillsList = [
|
|
72
|
+
const skillsList = [
|
|
73
|
+
'- `@.claude/skills/git-workflow/` — Git branching, commits, and PR workflow',
|
|
74
|
+
'- `@.claude/skills/testing-patterns/` — Test pyramid, AAA pattern, mocking strategies',
|
|
75
|
+
];
|
|
73
76
|
if (config.frontend?.framework === 'nextjs') {
|
|
74
77
|
skillsList.push('- `@.claude/skills/nextjs/` — Next.js patterns and conventions');
|
|
75
78
|
skillsList.push('- `@.claude/skills/security-web/` — Frontend security practices');
|
|
@@ -112,17 +115,17 @@ function generateClaudeMd(outputDir, config, vars) {
|
|
|
112
115
|
|
|
113
116
|
function generateHooks(outputDir, config, options = {}) {
|
|
114
117
|
let hookFile;
|
|
115
|
-
let scriptFiles = ['guard-protected-files.
|
|
118
|
+
let scriptFiles = ['guard-protected-files.mjs'];
|
|
116
119
|
|
|
117
120
|
if (config.stackId === 'nextjs-fullstack') {
|
|
118
121
|
hookFile = 'typescript.json';
|
|
119
|
-
scriptFiles.push('autofix-typescript.
|
|
122
|
+
scriptFiles.push('autofix-typescript.mjs');
|
|
120
123
|
} else if (config.stackId === 'fastapi-backend') {
|
|
121
124
|
hookFile = 'python.json';
|
|
122
|
-
scriptFiles.push('autofix-python.
|
|
125
|
+
scriptFiles.push('autofix-python.mjs');
|
|
123
126
|
} else if (config.stackId === 'polyglot-fullstack') {
|
|
124
127
|
hookFile = 'polyglot.json';
|
|
125
|
-
scriptFiles.push('autofix-polyglot.
|
|
128
|
+
scriptFiles.push('autofix-polyglot.mjs');
|
|
126
129
|
}
|
|
127
130
|
|
|
128
131
|
const settingsPath = path.join(outputDir, '.claude', 'settings.json');
|
|
@@ -175,7 +178,8 @@ function deepMergeSettings(existing, incoming) {
|
|
|
175
178
|
}
|
|
176
179
|
|
|
177
180
|
function generateSkills(outputDir, config) {
|
|
178
|
-
|
|
181
|
+
// Universal skills — always included
|
|
182
|
+
const skillsToInclude = ['git-workflow', 'testing-patterns'];
|
|
179
183
|
|
|
180
184
|
if (config.frontend?.framework === 'nextjs') {
|
|
181
185
|
skillsToInclude.push('nextjs');
|
|
@@ -210,6 +214,18 @@ function generateAgents(outputDir, config, vars) {
|
|
|
210
214
|
'spec-validator.md',
|
|
211
215
|
'production-readiness.md',
|
|
212
216
|
'uat-validator.md',
|
|
217
|
+
'build-error-resolver.md',
|
|
218
|
+
'planner.md',
|
|
219
|
+
'doc-updater.md',
|
|
220
|
+
'tdd-guide.md',
|
|
221
|
+
'refactor-cleaner.md',
|
|
222
|
+
'e2e-runner.md',
|
|
223
|
+
'architect.md',
|
|
224
|
+
'database-reviewer.md',
|
|
225
|
+
'docs-lookup.md',
|
|
226
|
+
'chief-of-staff.md',
|
|
227
|
+
'loop-operator.md',
|
|
228
|
+
'harness-optimizer.md',
|
|
213
229
|
];
|
|
214
230
|
|
|
215
231
|
for (const agent of agents) {
|
|
@@ -238,6 +254,13 @@ function generateCommands(outputDir, config, vars) {
|
|
|
238
254
|
'generate-prd.md',
|
|
239
255
|
'generate-uat.md',
|
|
240
256
|
'optimize-claude-md.md',
|
|
257
|
+
'plan.md',
|
|
258
|
+
'build-fix.md',
|
|
259
|
+
'code-review.md',
|
|
260
|
+
'tdd.md',
|
|
261
|
+
'save-session.md',
|
|
262
|
+
'resume-session.md',
|
|
263
|
+
'full-audit.md',
|
|
241
264
|
];
|
|
242
265
|
|
|
243
266
|
for (const cmd of commands) {
|
package/src/cli.js
CHANGED
|
@@ -46,6 +46,12 @@ export async function parseCommand(args) {
|
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
if (command === 'update') {
|
|
50
|
+
const { runUpdate } = await import('./update.js');
|
|
51
|
+
await runUpdate();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
49
55
|
// Shorthand: devforge my-app → devforge new my-app
|
|
50
56
|
if (!command.startsWith('-')) {
|
|
51
57
|
const targetDir = path.resolve(process.cwd(), command);
|
|
@@ -73,6 +79,7 @@ function showUsage() {
|
|
|
73
79
|
devforge new <name> Create a new project
|
|
74
80
|
devforge init Add dev guardrails to current project
|
|
75
81
|
devforge doctor Diagnose and optimize current project
|
|
82
|
+
devforge update Check for newer version
|
|
76
83
|
devforge <name> Shorthand for ${chalk.dim('devforge new <name>')}
|
|
77
84
|
|
|
78
85
|
${chalk.bold('Options:')}
|
|
@@ -105,6 +112,10 @@ function showHelp() {
|
|
|
105
112
|
flaky tests, dead code, duplicate code, and more.
|
|
106
113
|
Generates Claude Code prompts to fix each issue.
|
|
107
114
|
|
|
115
|
+
${chalk.bold('devforge update')}
|
|
116
|
+
Check if a newer version of DevForge is available.
|
|
117
|
+
Shows upgrade instructions if an update exists.
|
|
118
|
+
|
|
108
119
|
${chalk.bold('Supported stacks (V1):')}
|
|
109
120
|
- Next.js full-stack (TypeScript + Prisma + PostgreSQL)
|
|
110
121
|
- FastAPI backend (Python + SQLAlchemy + PostgreSQL)
|
package/src/doctor-prompts.js
CHANGED
|
@@ -176,6 +176,15 @@ ${fileList}
|
|
|
176
176
|
|
|
177
177
|
Extract all prompts into a dedicated prompts file (e.g., src/lib/prompts.ts or prompts/). This makes prompts easier to version, A/B test, and iterate on without changing application code.`;
|
|
178
178
|
},
|
|
179
|
+
|
|
180
|
+
DEVFORGE_UPDATE: (issue) => {
|
|
181
|
+
return `A newer version of DevForge is available.
|
|
182
|
+
|
|
183
|
+
Run: npm install -g forgedev@latest
|
|
184
|
+
Then re-run: npx forgedev init
|
|
185
|
+
|
|
186
|
+
This will update your project's agents, commands, skills, and hooks to the latest version.`;
|
|
187
|
+
},
|
|
179
188
|
};
|
|
180
189
|
|
|
181
190
|
export function generatePrompt(issue) {
|
|
@@ -223,8 +232,6 @@ export function generateReport(issues, projectName) {
|
|
|
223
232
|
const critical = issues.filter(i => i.severity === 'critical');
|
|
224
233
|
const warnings = issues.filter(i => i.severity === 'warning');
|
|
225
234
|
const info = issues.filter(i => i.severity === 'info');
|
|
226
|
-
const healthy = []; // Could be populated by passing in good checks
|
|
227
|
-
|
|
228
235
|
let report = `# DevForge Doctor Report — ${projectName}
|
|
229
236
|
Generated: ${new Date().toISOString().split('T')[0]}
|
|
230
237
|
|
package/src/doctor.js
CHANGED
|
@@ -29,6 +29,25 @@ export async function runDoctor(projectDir) {
|
|
|
29
29
|
// Run all checks
|
|
30
30
|
const issues = runAllChecks(projectDir, scan);
|
|
31
31
|
|
|
32
|
+
// Check for DevForge updates (5s timeout, won't crash on failure)
|
|
33
|
+
try {
|
|
34
|
+
const { checkForUpdate } = await import('./update-check.js');
|
|
35
|
+
const updateResult = await checkForUpdate();
|
|
36
|
+
if (updateResult?.updateAvailable) {
|
|
37
|
+
issues.push({
|
|
38
|
+
severity: 'info',
|
|
39
|
+
title: `DevForge update available: ${updateResult.current} → ${updateResult.latest}`,
|
|
40
|
+
impact: 'Newer version may include improved agents, commands, and bug fixes',
|
|
41
|
+
files: [],
|
|
42
|
+
autoFixable: false,
|
|
43
|
+
promptId: 'DEVFORGE_UPDATE',
|
|
44
|
+
effort: 'quick',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
} catch {
|
|
48
|
+
// Silently ignore — network issues shouldn't block doctor
|
|
49
|
+
}
|
|
50
|
+
|
|
32
51
|
if (issues.length === 0) {
|
|
33
52
|
console.log(chalk.green(' ✓ Your project looks healthy! No issues found.'));
|
|
34
53
|
console.log('');
|
package/src/index.js
CHANGED
|
@@ -11,6 +11,13 @@ import { generateUAT } from './uat-generator.js';
|
|
|
11
11
|
|
|
12
12
|
export async function runNew(projectName) {
|
|
13
13
|
const safeName = toKebabCase(projectName);
|
|
14
|
+
|
|
15
|
+
// Prevent path traversal — project name must not escape cwd
|
|
16
|
+
if (/[\/\\]/.test(safeName) || safeName.includes('..')) {
|
|
17
|
+
log.error('Project name must not contain path separators or ".."');
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
const outputDir = path.resolve(process.cwd(), safeName);
|
|
15
22
|
|
|
16
23
|
if (fs.existsSync(outputDir)) {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
|
|
3
|
+
const PACKAGE_NAME = 'forgedev';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Compare two semver strings (major.minor.patch).
|
|
7
|
+
* Returns 1 if a > b, -1 if a < b, 0 if equal.
|
|
8
|
+
*/
|
|
9
|
+
export function compareVersions(a, b) {
|
|
10
|
+
const pa = a.split('.').map(Number);
|
|
11
|
+
const pb = b.split('.').map(Number);
|
|
12
|
+
for (let i = 0; i < 3; i++) {
|
|
13
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return 1;
|
|
14
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return -1;
|
|
15
|
+
}
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Check npm registry for a newer version of forgedev.
|
|
21
|
+
* Returns { current, latest, updateAvailable } or null on failure.
|
|
22
|
+
*/
|
|
23
|
+
export async function checkForUpdate() {
|
|
24
|
+
const pkg = JSON.parse(
|
|
25
|
+
fs.readFileSync(new URL('../package.json', import.meta.url), 'utf-8')
|
|
26
|
+
);
|
|
27
|
+
const currentVersion = pkg.version;
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const response = await fetch(
|
|
31
|
+
`https://registry.npmjs.org/${PACKAGE_NAME}/latest`,
|
|
32
|
+
{ signal: AbortSignal.timeout(5000) }
|
|
33
|
+
);
|
|
34
|
+
if (!response.ok) return null;
|
|
35
|
+
const data = await response.json();
|
|
36
|
+
const latestVersion = data.version;
|
|
37
|
+
|
|
38
|
+
// Validate version format before trusting registry response
|
|
39
|
+
if (!/^\d+\.\d+\.\d+/.test(latestVersion)) return null;
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
current: currentVersion,
|
|
43
|
+
latest: latestVersion,
|
|
44
|
+
updateAvailable: compareVersions(latestVersion, currentVersion) > 0,
|
|
45
|
+
};
|
|
46
|
+
} catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/update.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { log } from './utils.js';
|
|
3
|
+
import { checkForUpdate } from './update-check.js';
|
|
4
|
+
|
|
5
|
+
export async function runUpdate() {
|
|
6
|
+
console.log('');
|
|
7
|
+
console.log(chalk.bold.cyan(' DevForge') + chalk.dim(' — Checking for updates...'));
|
|
8
|
+
console.log('');
|
|
9
|
+
|
|
10
|
+
const result = await checkForUpdate();
|
|
11
|
+
|
|
12
|
+
if (result === null) {
|
|
13
|
+
log.warn(' Could not reach the npm registry. Check your internet connection.');
|
|
14
|
+
console.log('');
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!result.updateAvailable) {
|
|
19
|
+
log.success(` ✓ You're on the latest version (${result.current})`);
|
|
20
|
+
console.log('');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
log.warn(` Update available: ${result.current} → ${result.latest}`);
|
|
25
|
+
console.log('');
|
|
26
|
+
console.log(' To update:');
|
|
27
|
+
console.log(` ${chalk.bold('npm install -g forgedev@latest')} ${chalk.dim('(if installed globally)')}`);
|
|
28
|
+
console.log(` ${chalk.bold('npx forgedev@latest new my-app')} ${chalk.dim('(one-time use)')}`);
|
|
29
|
+
console.log('');
|
|
30
|
+
log.dim(' To update an existing project\'s Claude Code infrastructure:');
|
|
31
|
+
log.dim(' cd my-project && npx forgedev@latest init');
|
|
32
|
+
console.log('');
|
|
33
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
from datetime import datetime, timedelta, timezone
|
|
2
3
|
|
|
3
4
|
from jose import JWTError, jwt
|
|
@@ -7,7 +8,9 @@ from app.core.config import settings
|
|
|
7
8
|
|
|
8
9
|
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
|
9
10
|
|
|
10
|
-
SECRET_KEY = "
|
|
11
|
+
SECRET_KEY = os.environ.get("JWT_SECRET_KEY")
|
|
12
|
+
if not SECRET_KEY:
|
|
13
|
+
raise RuntimeError("JWT_SECRET_KEY environment variable is required. Set it in your .env file.")
|
|
11
14
|
ALGORITHM = "HS256"
|
|
12
15
|
ACCESS_TOKEN_EXPIRE_MINUTES = 30
|
|
13
16
|
|
|
@@ -6,8 +6,8 @@ class Settings(BaseSettings):
|
|
|
6
6
|
app_name: str = "{{PROJECT_NAME_PASCAL}}"
|
|
7
7
|
debug: bool = False
|
|
8
8
|
|
|
9
|
-
# Database
|
|
10
|
-
database_url: str
|
|
9
|
+
# Database — no default: must be set via .env or environment
|
|
10
|
+
database_url: str
|
|
11
11
|
|
|
12
12
|
# CORS
|
|
13
13
|
cors_origins: list[str] = ["http://localhost:3000"]
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: System design specialist for data models, API contracts, service boundaries, and architectural decisions.
|
|
3
|
+
disallowedTools:
|
|
4
|
+
- Write
|
|
5
|
+
- Edit
|
|
6
|
+
- MultiEdit
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are a software architecture specialist. Your job is to design systems that are modular, scalable, and maintainable.
|
|
10
|
+
|
|
11
|
+
## Architecture Review Process
|
|
12
|
+
|
|
13
|
+
1. **Current state analysis** — Read existing code to understand what's built
|
|
14
|
+
2. **Requirements gathering** — Clarify functional and non-functional requirements
|
|
15
|
+
3. **Design proposal** — Propose architecture with clear rationale
|
|
16
|
+
4. **Trade-off analysis** — Compare alternatives with pros/cons
|
|
17
|
+
|
|
18
|
+
## Architectural Principles
|
|
19
|
+
|
|
20
|
+
- **Modularity** — Each module has a single responsibility and clear boundaries
|
|
21
|
+
- **Scalability** — Design can handle 10x growth without rewriting
|
|
22
|
+
- **Maintainability** — New developers can understand the system in < 1 day
|
|
23
|
+
- **Security** — Defense in depth, principle of least privilege
|
|
24
|
+
- **Performance** — Optimize hot paths, lazy-load cold paths
|
|
25
|
+
|
|
26
|
+
## Common Patterns
|
|
27
|
+
|
|
28
|
+
**Frontend**: Component composition, container/presenter, custom hooks, context for global state, code splitting for routes
|
|
29
|
+
|
|
30
|
+
**Backend**: Repository pattern for data access, service layer for business logic, middleware for cross-cutting concerns, event-driven for async work
|
|
31
|
+
|
|
32
|
+
**Data**: Normalized schemas, cursor-based pagination, caching strategy (in-memory → Redis → CDN), eventual consistency where appropriate
|
|
33
|
+
|
|
34
|
+
## Architecture Decision Records (ADRs)
|
|
35
|
+
|
|
36
|
+
For significant decisions, produce an ADR:
|
|
37
|
+
|
|
38
|
+
```markdown
|
|
39
|
+
# ADR: [Title]
|
|
40
|
+
|
|
41
|
+
## Status: Proposed
|
|
42
|
+
|
|
43
|
+
## Context
|
|
44
|
+
[Why this decision is needed]
|
|
45
|
+
|
|
46
|
+
## Decision
|
|
47
|
+
[What we chose and why]
|
|
48
|
+
|
|
49
|
+
## Alternatives Considered
|
|
50
|
+
[What else we looked at and why we rejected it]
|
|
51
|
+
|
|
52
|
+
## Consequences
|
|
53
|
+
[What changes as a result — positive and negative]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Red Flags to Identify
|
|
57
|
+
|
|
58
|
+
- Tight coupling between unrelated modules
|
|
59
|
+
- God objects (one class/file doing everything)
|
|
60
|
+
- Premature optimization before measuring
|
|
61
|
+
- Not-invented-here syndrome (rebuilding existing libraries)
|
|
62
|
+
- Missing error boundaries between services
|
|
63
|
+
- No clear data ownership (multiple services writing the same table)
|
|
64
|
+
|
|
65
|
+
## Rules
|
|
66
|
+
|
|
67
|
+
- NEVER write code — only produce designs and recommendations
|
|
68
|
+
- Always consider the simplest solution first
|
|
69
|
+
- Flag when a proposed architecture is over-engineered for the project size
|
|
70
|
+
- Recommend specific libraries/tools, not generic categories
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Fix build, lint, and type errors with minimal, targeted changes. No architectural edits.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
You are a build error resolution specialist. Your job is to fix build/type/lint errors with the smallest possible changes.
|
|
6
|
+
|
|
7
|
+
## Workflow
|
|
8
|
+
|
|
9
|
+
1. **Collect errors** — Run `{{BUILD_COMMAND}}`, `{{LINT_COMMAND}}`, and `{{TYPE_CHECK_COMMAND}}` to capture all errors
|
|
10
|
+
2. **Group by file** — Sort errors by file path, fix in dependency order (imports/types before logic)
|
|
11
|
+
3. **Fix one error at a time** — Read the file, diagnose root cause, apply minimal edit
|
|
12
|
+
4. **Verify** — After each fix, re-run all three commands to confirm the error is gone and no new errors were introduced
|
|
13
|
+
## Common Fix Patterns
|
|
14
|
+
|
|
15
|
+
| Error Type | Fix |
|
|
16
|
+
|-----------|-----|
|
|
17
|
+
| Missing import | Add the import statement |
|
|
18
|
+
| Type mismatch | Add type annotation or assertion |
|
|
19
|
+
| Undefined variable | Check spelling, add declaration, or fix import |
|
|
20
|
+
| Missing dependency | Suggest install command (`npm install X` or `pip install X`) |
|
|
21
|
+
| Config error | Compare with known working defaults |
|
|
22
|
+
| Circular dependency | Identify the cycle, suggest extraction to shared module |
|
|
23
|
+
|
|
24
|
+
## Rules
|
|
25
|
+
|
|
26
|
+
- **DO**: Add type annotations, null checks, fix imports, update configs
|
|
27
|
+
- **DON'T**: Refactor working code, change architecture, rename files, add features
|
|
28
|
+
- Fix must change less than 5% of the file — if more is needed, stop and report
|
|
29
|
+
- If the same error persists after 3 attempts, stop and ask the user
|
|
30
|
+
- If a fix introduces more errors than it resolves, revert and ask the user
|