forgedev 1.0.1 → 1.1.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 (44) hide show
  1. package/CLAUDE.md +3 -3
  2. package/README.md +44 -20
  3. package/package.json +1 -1
  4. package/src/claude-configurator.js +29 -7
  5. package/src/guided.js +5 -5
  6. package/src/index.js +1 -1
  7. package/src/init-mode.js +2 -2
  8. package/templates/claude-code/agents/architect.md +70 -0
  9. package/templates/claude-code/agents/build-error-resolver.md +31 -0
  10. package/templates/claude-code/agents/chief-of-staff.md +52 -0
  11. package/templates/claude-code/agents/database-reviewer.md +58 -0
  12. package/templates/claude-code/agents/doc-updater.md +39 -0
  13. package/templates/claude-code/agents/docs-lookup.md +51 -0
  14. package/templates/claude-code/agents/e2e-runner.md +57 -0
  15. package/templates/claude-code/agents/harness-optimizer.md +65 -0
  16. package/templates/claude-code/agents/loop-operator.md +53 -0
  17. package/templates/claude-code/agents/planner.md +60 -0
  18. package/templates/claude-code/agents/refactor-cleaner.md +42 -0
  19. package/templates/claude-code/agents/tdd-guide.md +47 -0
  20. package/templates/claude-code/claude-md/base.md +28 -0
  21. package/templates/claude-code/claude-md/fastapi.md +8 -0
  22. package/templates/claude-code/claude-md/fullstack.md +8 -0
  23. package/templates/claude-code/claude-md/nextjs.md +8 -0
  24. package/templates/claude-code/commands/build-fix.md +43 -0
  25. package/templates/claude-code/commands/code-review.md +45 -0
  26. package/templates/claude-code/commands/plan.md +21 -0
  27. package/templates/claude-code/commands/resume-session.md +50 -0
  28. package/templates/claude-code/commands/save-session.md +69 -0
  29. package/templates/claude-code/commands/tdd.md +80 -0
  30. package/templates/claude-code/commands/workflows.md +36 -0
  31. package/templates/claude-code/hooks/polyglot.json +2 -2
  32. package/templates/claude-code/hooks/python.json +2 -2
  33. package/templates/claude-code/hooks/scripts/autofix-polyglot.mjs +36 -0
  34. package/templates/claude-code/hooks/scripts/autofix-python.mjs +30 -0
  35. package/templates/claude-code/hooks/scripts/autofix-typescript.mjs +30 -0
  36. package/templates/claude-code/hooks/scripts/guard-protected-files.mjs +34 -0
  37. package/templates/claude-code/hooks/typescript.json +2 -2
  38. package/templates/claude-code/skills/git-workflow/SKILL.md +64 -0
  39. package/templates/claude-code/skills/testing-patterns/SKILL.md +97 -0
  40. package/templates/claude-code/commands/help.md +0 -26
  41. package/templates/claude-code/hooks/scripts/autofix-polyglot.sh +0 -16
  42. package/templates/claude-code/hooks/scripts/autofix-python.sh +0 -14
  43. package/templates/claude-code/hooks/scripts/autofix-typescript.sh +0 -14
  44. package/templates/claude-code/hooks/scripts/guard-protected-files.sh +0 -21
@@ -0,0 +1,36 @@
1
+ Show the developer what workflows are available.
2
+
3
+ ## Available Workflows
4
+
5
+ ### Development
6
+ - `/plan` — Create an implementation plan before writing code
7
+ - `/tdd` — Write failing tests first, then implement (test-driven development)
8
+ - `/build-fix` — Fix build, lint, and type errors incrementally
9
+ - `/code-review` — Review uncommitted changes for security and quality
10
+
11
+ ### Daily
12
+ - `/status` — Run all checks and show a project dashboard
13
+ - `/next` — Figure out what to work on next
14
+ - `/done` — Verify the current task is complete before moving on
15
+
16
+ ### Verification
17
+ - `/verify-all` — Run lint, type check, tests, then launch all reviewers
18
+ - `/audit-spec` — Validate implementation against a spec/PRD
19
+ - `/audit-wiring` — Find dead or unwired features
20
+ - `/audit-security` — Run a security audit
21
+
22
+ ### Release
23
+ - `/pre-pr` — Run the complete pre-PR checklist
24
+ - `/run-uat` — Execute UAT scenarios
25
+
26
+ ### Generation
27
+ - `/generate-prd` — Generate a PRD from the current codebase
28
+ - `/generate-uat` — Generate UAT scenarios and checklists
29
+ - `/optimize-claude-md` — Slim down an oversized CLAUDE.md
30
+
31
+ ### Session
32
+ - `/save-session` — Save current work context for later resumption
33
+ - `/resume-session` — Load a saved session and continue where you left off
34
+
35
+ ## Quick Start
36
+ Run `/status` to see where things stand, then `/next` to pick up work.
@@ -6,7 +6,7 @@
6
6
  "hooks": [
7
7
  {
8
8
  "type": "command",
9
- "command": "bash .claude/hooks/guard-protected-files.sh"
9
+ "command": "node .claude/hooks/guard-protected-files.mjs"
10
10
  }
11
11
  ]
12
12
  }
@@ -17,7 +17,7 @@
17
17
  "hooks": [
18
18
  {
19
19
  "type": "command",
20
- "command": "bash .claude/hooks/autofix-polyglot.sh"
20
+ "command": "node .claude/hooks/autofix-polyglot.mjs"
21
21
  }
22
22
  ]
23
23
  }
@@ -6,7 +6,7 @@
6
6
  "hooks": [
7
7
  {
8
8
  "type": "command",
9
- "command": "bash .claude/hooks/guard-protected-files.sh"
9
+ "command": "node .claude/hooks/guard-protected-files.mjs"
10
10
  }
11
11
  ]
12
12
  }
@@ -17,7 +17,7 @@
17
17
  "hooks": [
18
18
  {
19
19
  "type": "command",
20
- "command": "bash .claude/hooks/autofix-python.sh"
20
+ "command": "node .claude/hooks/autofix-python.mjs"
21
21
  }
22
22
  ]
23
23
  }
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ // Auto-fix lint issues on saved TypeScript or Python files (polyglot)
3
+
4
+ import { execSync } from 'node:child_process';
5
+
6
+ let input = '';
7
+ process.stdin.setEncoding('utf8');
8
+ process.stdin.on('data', (chunk) => { input += chunk; });
9
+ process.stdin.on('end', () => {
10
+ try {
11
+ const data = JSON.parse(input);
12
+ const filePath = data?.tool_input?.file_path || '';
13
+
14
+ if (!filePath) {
15
+ process.exit(0);
16
+ }
17
+
18
+ if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {
19
+ try {
20
+ execSync(`npx eslint --fix "${filePath}"`, { stdio: 'pipe', cwd: 'frontend' });
21
+ } catch {
22
+ // eslint may exit non-zero for unfixable issues — that's okay
23
+ }
24
+ } else if (filePath.endsWith('.py')) {
25
+ try {
26
+ execSync(`ruff check --fix "${filePath}"`, { stdio: 'pipe', cwd: 'backend' });
27
+ } catch {
28
+ // ruff may exit non-zero for unfixable issues — that's okay
29
+ }
30
+ }
31
+
32
+ process.exit(0);
33
+ } catch {
34
+ process.exit(0);
35
+ }
36
+ });
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ // Auto-fix lint issues on saved Python files
3
+
4
+ import { execSync } from 'node:child_process';
5
+
6
+ let input = '';
7
+ process.stdin.setEncoding('utf8');
8
+ process.stdin.on('data', (chunk) => { input += chunk; });
9
+ process.stdin.on('end', () => {
10
+ try {
11
+ const data = JSON.parse(input);
12
+ const filePath = data?.tool_input?.file_path || '';
13
+
14
+ if (!filePath) {
15
+ process.exit(0);
16
+ }
17
+
18
+ if (filePath.endsWith('.py')) {
19
+ try {
20
+ execSync(`ruff check --fix "${filePath}"`, { stdio: 'pipe', cwd: 'backend' });
21
+ } catch {
22
+ // ruff may exit non-zero for unfixable issues — that's okay
23
+ }
24
+ }
25
+
26
+ process.exit(0);
27
+ } catch {
28
+ process.exit(0);
29
+ }
30
+ });
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ // Auto-fix lint issues on saved TypeScript files
3
+
4
+ import { execSync } from 'node:child_process';
5
+
6
+ let input = '';
7
+ process.stdin.setEncoding('utf8');
8
+ process.stdin.on('data', (chunk) => { input += chunk; });
9
+ process.stdin.on('end', () => {
10
+ try {
11
+ const data = JSON.parse(input);
12
+ const filePath = data?.tool_input?.file_path || '';
13
+
14
+ if (!filePath) {
15
+ process.exit(0);
16
+ }
17
+
18
+ if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {
19
+ try {
20
+ execSync(`npx eslint --fix "${filePath}"`, { stdio: 'pipe' });
21
+ } catch {
22
+ // eslint may exit non-zero for unfixable issues — that's okay
23
+ }
24
+ }
25
+
26
+ process.exit(0);
27
+ } catch {
28
+ process.exit(0);
29
+ }
30
+ });
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ // Block modifications to .env files and migration files
3
+ // Exit 0 = allow, Exit 2 = block
4
+
5
+ let input = '';
6
+ process.stdin.setEncoding('utf8');
7
+ process.stdin.on('data', (chunk) => { input += chunk; });
8
+ process.stdin.on('end', () => {
9
+ try {
10
+ const data = JSON.parse(input);
11
+ const filePath = data?.tool_input?.file_path || '';
12
+
13
+ if (!filePath) {
14
+ process.exit(0);
15
+ }
16
+
17
+ // Block .env files
18
+ const basename = filePath.split('/').pop().split('\\').pop();
19
+ if (basename === '.env' || basename.startsWith('.env.')) {
20
+ process.stderr.write('BLOCKED: Do not modify .env files directly\n');
21
+ process.exit(2);
22
+ }
23
+
24
+ // Block migration files
25
+ if (filePath.includes('prisma/migrations/') || filePath.includes('alembic/versions/')) {
26
+ process.stderr.write('BLOCKED: Do not modify migration files directly\n');
27
+ process.exit(2);
28
+ }
29
+
30
+ process.exit(0);
31
+ } catch {
32
+ process.exit(0);
33
+ }
34
+ });
@@ -6,7 +6,7 @@
6
6
  "hooks": [
7
7
  {
8
8
  "type": "command",
9
- "command": "bash .claude/hooks/guard-protected-files.sh"
9
+ "command": "node .claude/hooks/guard-protected-files.mjs"
10
10
  }
11
11
  ]
12
12
  }
@@ -17,7 +17,7 @@
17
17
  "hooks": [
18
18
  {
19
19
  "type": "command",
20
- "command": "bash .claude/hooks/autofix-typescript.sh"
20
+ "command": "node .claude/hooks/autofix-typescript.mjs"
21
21
  }
22
22
  ]
23
23
  }
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: git-workflow
3
+ description: Git branching, commits, PR workflow, and conflict resolution patterns
4
+ ---
5
+
6
+ ## Branching Strategy
7
+
8
+ - `main` — production-ready code, never commit directly
9
+ - `feat/<name>` — new features, branch from main
10
+ - `fix/<name>` — bug fixes, branch from main
11
+ - `chore/<name>` — maintenance, config changes, dependency updates
12
+
13
+ Always create a feature branch before starting work:
14
+ ```bash
15
+ git checkout -b feat/my-feature main
16
+ ```
17
+
18
+ ## Commit Conventions
19
+
20
+ Use conventional commit messages:
21
+
22
+ | Prefix | When |
23
+ |--------|------|
24
+ | `feat:` | New feature |
25
+ | `fix:` | Bug fix |
26
+ | `docs:` | Documentation only |
27
+ | `test:` | Adding or updating tests |
28
+ | `refactor:` | Code change that neither fixes nor adds |
29
+ | `chore:` | Build process, deps, config |
30
+
31
+ Rules:
32
+ - Keep subject under 72 characters
33
+ - Use imperative mood ("add feature" not "added feature")
34
+ - Body explains WHY, not WHAT (the diff shows what)
35
+ - Reference issue numbers: `fix: handle null user (#123)`
36
+
37
+ ## Pull Request Workflow
38
+
39
+ 1. Push feature branch: `git push -u origin feat/my-feature`
40
+ 2. Create PR with clear title and description
41
+ 3. PR description should include: what changed, why, how to test
42
+ 4. Request review, address feedback
43
+ 5. Squash merge to main (keeps history clean)
44
+ 6. Delete the feature branch after merge
45
+
46
+ ## Conflict Resolution
47
+
48
+ When conflicts occur:
49
+ 1. `git fetch origin main`
50
+ 2. `git rebase origin/main` (preferred over merge)
51
+ 3. Resolve conflicts file by file
52
+ 4. `git add <resolved-files>`
53
+ 5. `git rebase --continue`
54
+ 6. Run tests after resolving: ensure nothing broke
55
+
56
+ If rebase gets messy: `git rebase --abort` and start over.
57
+
58
+ ## Common Mistakes
59
+
60
+ - Never force-push to `main`
61
+ - Never commit `.env` files, credentials, or large binaries
62
+ - Never rebase commits that have been pushed and shared
63
+ - Never merge main into feature branches (rebase instead)
64
+ - Always pull before pushing: `git pull --rebase origin main`
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: testing-patterns
3
+ description: Universal testing principles — test pyramid, AAA pattern, mocking strategies, and coverage targets
4
+ ---
5
+
6
+ ## Test Pyramid
7
+
8
+ ```
9
+ / E2E \ — Few, slow, high confidence
10
+ / Integration \ — Some, medium speed
11
+ / Unit Tests \— Many, fast, focused
12
+ ```
13
+
14
+ - **Unit tests** (70%): Test individual functions in isolation. Fast, many.
15
+ - **Integration tests** (20%): Test modules working together (API + DB, component + hook).
16
+ - **E2E tests** (10%): Test full user journeys through the real app. Slow, few.
17
+
18
+ ## Arrange-Act-Assert (AAA)
19
+
20
+ Every test follows this structure:
21
+
22
+ ```
23
+ test('should calculate total with tax', () => {
24
+ // Arrange — set up test data
25
+ const items = [{ price: 10 }, { price: 20 }];
26
+ const taxRate = 0.1;
27
+
28
+ // Act — execute the function
29
+ const total = calculateTotal(items, taxRate);
30
+
31
+ // Assert — verify the result
32
+ expect(total).toBe(33);
33
+ });
34
+ ```
35
+
36
+ ## What to Test
37
+
38
+ **Always test:**
39
+ - Happy path (normal inputs → expected output)
40
+ - Edge cases (empty, null, undefined, zero, max values)
41
+ - Error cases (invalid input, missing data, network failure)
42
+ - Boundary values (off-by-one, exactly at limits)
43
+ - Security-critical paths (auth, permissions, input validation)
44
+
45
+ **Don't test:**
46
+ - Implementation details (private methods, internal state)
47
+ - Third-party library internals
48
+ - Trivial getters/setters with no logic
49
+ - CSS styling or pixel-perfect layouts
50
+
51
+ ## Mocking Strategy
52
+
53
+ | What | When to Mock |
54
+ |------|-------------|
55
+ | External APIs | Always — they're slow and unreliable |
56
+ | Database | Integration tests use real DB, unit tests mock |
57
+ | Time/Date | When testing time-dependent logic |
58
+ | File system | When testing file operations |
59
+ | Environment | When testing env-dependent behavior |
60
+
61
+ Rules:
62
+ - Mock at the boundary, not deep inside
63
+ - Prefer dependency injection over global mocks
64
+ - Reset mocks between tests (`beforeEach` / `afterEach`)
65
+ - Never mock what you're testing
66
+
67
+ ## Test Naming
68
+
69
+ Use descriptive names that explain the scenario:
70
+
71
+ ```
72
+ // Good
73
+ "should return 404 when user does not exist"
74
+ "should hash password before saving to database"
75
+ "should retry failed request up to 3 times"
76
+
77
+ // Bad
78
+ "test1"
79
+ "works correctly"
80
+ "handles error"
81
+ ```
82
+
83
+ ## Coverage Targets
84
+
85
+ - **80% minimum** for all code
86
+ - **100% required** for: auth logic, financial calculations, security-critical code
87
+ - Coverage measures lines hit, not correctness — high coverage with weak assertions is useless
88
+ - Focus on meaningful assertions, not just line coverage
89
+
90
+ ## Common Anti-Patterns
91
+
92
+ - Testing implementation instead of behavior
93
+ - Tests that pass regardless of the implementation
94
+ - Shared mutable state between tests (tests must be independent)
95
+ - Over-mocking (prefer integration tests when possible)
96
+ - Ignoring flaky tests (fix the root cause immediately)
97
+ - Testing only the happy path
@@ -1,26 +0,0 @@
1
- Show the developer what workflows are available.
2
-
3
- ## Available Workflows
4
-
5
- ### Daily Development
6
- - `/project:status` — Run all checks and show a project dashboard
7
- - `/project:next` — Figure out what to work on next
8
- - `/project:done` — Verify the current task is complete before moving on
9
-
10
- ### Verification
11
- - `/project:verify-all` — Run lint, type check, tests, then launch all reviewers
12
- - `/project:audit-spec` — Validate implementation against a spec/PRD
13
- - `/project:audit-wiring` — Find dead or unwired features
14
- - `/project:audit-security` — Run a security audit
15
-
16
- ### Release
17
- - `/project:pre-pr` — Run the complete pre-PR checklist
18
- - `/project:run-uat` — Execute UAT scenarios
19
-
20
- ### Generation
21
- - `/project:generate-prd` — Generate a PRD from the current codebase
22
- - `/project:generate-uat` — Generate UAT scenarios and checklists
23
- - `/project:optimize-claude-md` — Slim down an oversized CLAUDE.md
24
-
25
- ## Quick Start
26
- Run `/project:status` to see where things stand, then `/project:next` to pick up work.
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Auto-fix lint issues on saved TypeScript or Python files (polyglot)
3
- INPUT=$(cat)
4
- FILE_PATH=$(echo "$INPUT" | jq -r ".tool_input.file_path // empty")
5
-
6
- if [ -z "$FILE_PATH" ]; then
7
- exit 0
8
- fi
9
-
10
- if [[ "$FILE_PATH" == *.ts || "$FILE_PATH" == *.tsx ]]; then
11
- cd frontend && npx eslint --fix "$FILE_PATH" 2>&1 || true
12
- elif [[ "$FILE_PATH" == *.py ]]; then
13
- cd backend && ruff check --fix "$FILE_PATH" 2>&1 || true
14
- fi
15
-
16
- exit 0
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Auto-fix lint issues on saved Python files
3
- INPUT=$(cat)
4
- FILE_PATH=$(echo "$INPUT" | jq -r ".tool_input.file_path // empty")
5
-
6
- if [ -z "$FILE_PATH" ]; then
7
- exit 0
8
- fi
9
-
10
- if [[ "$FILE_PATH" == *.py ]]; then
11
- cd backend && ruff check --fix "$FILE_PATH" 2>&1 || true
12
- fi
13
-
14
- exit 0
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Auto-fix lint issues on saved TypeScript files
3
- INPUT=$(cat)
4
- FILE_PATH=$(echo "$INPUT" | jq -r ".tool_input.file_path // empty")
5
-
6
- if [ -z "$FILE_PATH" ]; then
7
- exit 0
8
- fi
9
-
10
- if [[ "$FILE_PATH" == *.ts || "$FILE_PATH" == *.tsx ]]; then
11
- npx eslint --fix "$FILE_PATH" 2>&1 || true
12
- fi
13
-
14
- exit 0
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Block modifications to .env files and migration files
3
- INPUT=$(cat)
4
- FILE_PATH=$(echo "$INPUT" | jq -r ".tool_input.file_path // empty")
5
-
6
- if [ -z "$FILE_PATH" ]; then
7
- exit 0
8
- fi
9
-
10
- case "$FILE_PATH" in
11
- *.env|*.env.*)
12
- echo "BLOCKED: Do not modify .env files directly" >&2
13
- exit 2
14
- ;;
15
- */prisma/migrations/*|*/alembic/versions/*)
16
- echo "BLOCKED: Do not modify migration files directly" >&2
17
- exit 2
18
- ;;
19
- esac
20
-
21
- exit 0