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.
Files changed (55) hide show
  1. package/README.md +122 -26
  2. package/bin/devforge.js +10 -1
  3. package/package.json +1 -1
  4. package/src/claude-configurator.js +29 -6
  5. package/src/cli.js +11 -0
  6. package/src/doctor-prompts.js +9 -2
  7. package/src/doctor.js +19 -0
  8. package/src/index.js +7 -0
  9. package/src/update-check.js +49 -0
  10. package/src/update.js +33 -0
  11. package/templates/auth/jwt-custom/backend/app/core/security.py.template +4 -1
  12. package/templates/backend/fastapi/backend/app/core/config.py.template +2 -2
  13. package/templates/claude-code/agents/architect.md +70 -0
  14. package/templates/claude-code/agents/build-error-resolver.md +30 -0
  15. package/templates/claude-code/agents/chief-of-staff.md +52 -0
  16. package/templates/claude-code/agents/database-reviewer.md +58 -0
  17. package/templates/claude-code/agents/doc-updater.md +39 -0
  18. package/templates/claude-code/agents/docs-lookup.md +51 -0
  19. package/templates/claude-code/agents/e2e-runner.md +57 -0
  20. package/templates/claude-code/agents/harness-optimizer.md +65 -0
  21. package/templates/claude-code/agents/loop-operator.md +52 -0
  22. package/templates/claude-code/agents/planner.md +60 -0
  23. package/templates/claude-code/agents/refactor-cleaner.md +42 -0
  24. package/templates/claude-code/agents/tdd-guide.md +47 -0
  25. package/templates/claude-code/agents/uat-validator.md +2 -1
  26. package/templates/claude-code/claude-md/base.md +29 -1
  27. package/templates/claude-code/claude-md/fastapi.md +8 -0
  28. package/templates/claude-code/claude-md/fullstack.md +8 -0
  29. package/templates/claude-code/claude-md/nextjs.md +8 -0
  30. package/templates/claude-code/commands/build-fix.md +43 -0
  31. package/templates/claude-code/commands/code-review.md +44 -0
  32. package/templates/claude-code/commands/full-audit.md +60 -0
  33. package/templates/claude-code/commands/plan.md +21 -0
  34. package/templates/claude-code/commands/resume-session.md +50 -0
  35. package/templates/claude-code/commands/save-session.md +69 -0
  36. package/templates/claude-code/commands/tdd.md +80 -0
  37. package/templates/claude-code/commands/workflows.md +12 -1
  38. package/templates/claude-code/hooks/polyglot.json +2 -2
  39. package/templates/claude-code/hooks/python.json +2 -2
  40. package/templates/claude-code/hooks/scripts/autofix-polyglot.mjs +44 -0
  41. package/templates/claude-code/hooks/scripts/autofix-python.mjs +38 -0
  42. package/templates/claude-code/hooks/scripts/autofix-typescript.mjs +38 -0
  43. package/templates/claude-code/hooks/scripts/guard-protected-files.mjs +34 -0
  44. package/templates/claude-code/hooks/typescript.json +2 -2
  45. package/templates/claude-code/skills/ai-prompts/SKILL.md +1 -0
  46. package/templates/claude-code/skills/fastapi/SKILL.md +1 -1
  47. package/templates/claude-code/skills/git-workflow/SKILL.md +64 -0
  48. package/templates/claude-code/skills/playwright/SKILL.md +2 -2
  49. package/templates/claude-code/skills/security-api/SKILL.md +2 -2
  50. package/templates/claude-code/skills/testing-patterns/SKILL.md +97 -0
  51. package/templates/database/sqlalchemy-postgres/.env.example +1 -0
  52. package/templates/claude-code/hooks/scripts/autofix-polyglot.sh +0 -16
  53. package/templates/claude-code/hooks/scripts/autofix-python.sh +0 -14
  54. package/templates/claude-code/hooks/scripts/autofix-typescript.sh +0 -14
  55. package/templates/claude-code/hooks/scripts/guard-protected-files.sh +0 -21
@@ -0,0 +1,44 @@
1
+ Review uncommitted changes for security issues and code quality.
2
+
3
+ ## Step 1: Get Changed Files
4
+
5
+ ```bash
6
+ git diff --name-only HEAD
7
+ ```
8
+
9
+ ## Step 2: Review Each File
10
+
11
+ For each changed file, check:
12
+
13
+ **Security (CRITICAL):**
14
+ - Hardcoded credentials, API keys, tokens
15
+ - SQL injection vulnerabilities
16
+ - XSS vulnerabilities
17
+ - Missing input validation
18
+ - Path traversal risks
19
+
20
+ **Code Quality (HIGH):**
21
+ - Functions > 50 lines
22
+ - Files > 800 lines
23
+ - Nesting depth > 4 levels
24
+ - Missing error handling
25
+ - console.log / print statements left in
26
+ - TODO/FIXME comments without tracking
27
+
28
+ **Best Practices (MEDIUM):**
29
+ - Missing tests for new code
30
+ - Mutation of shared state (use immutable patterns)
31
+ - Missing accessibility attributes (a11y)
32
+
33
+ ## Step 3: Generate Report
34
+
35
+ For each issue found:
36
+ - **Severity**: CRITICAL, HIGH, MEDIUM
37
+ - **File**: path and line number
38
+ - **Issue**: what's wrong
39
+ - **Fix**: how to fix it
40
+ ## Step 4: Verdict
41
+
42
+ - If CRITICAL issues found → block commit, list required fixes
43
+ - If only MEDIUM/LOW → approve with suggestions
44
+ - Never approve code with security vulnerabilities
@@ -0,0 +1,60 @@
1
+ Run every audit and review agent in a single pass. Use this when you want a comprehensive project health check.
2
+
3
+ ## Step 1: Build + Lint + Tests
4
+
5
+ 1. Run lint: `{{LINT_COMMAND}}`
6
+ 2. Run type check: `{{TYPE_CHECK_COMMAND}}`
7
+ 3. Run tests: `{{TEST_COMMAND}}`
8
+
9
+ If any step fails, report the failures but continue with the remaining audits.
10
+
11
+ ## Step 2: Code Review (changed files)
12
+
13
+ 1. Get changed files: `git diff --name-only HEAD`
14
+ 2. For each changed file, check for:
15
+ - Hardcoded credentials, API keys, tokens
16
+ - SQL injection, XSS, path traversal
17
+ - Functions > 50 lines, files > 800 lines
18
+ - Missing error handling, console.log left in
19
+ - Missing tests for new code
20
+
21
+ ## Step 3: Launch Review Agents
22
+
23
+ Run these agents in sequence on the full codebase:
24
+
25
+ 1. **code-quality-reviewer** — code patterns, duplication, naming
26
+ 2. **security-reviewer** — vulnerabilities, secrets, unsafe operations
27
+ 3. **production-readiness** — deployment readiness, error handling, health checks
28
+ 4. **database-reviewer** — query performance, N+1, schema issues (skip if no database)
29
+
30
+ ## Step 4: Structural Audits
31
+
32
+ 1. **Wiring audit** — verify all API endpoints are connected between frontend and backend
33
+ 2. **Spec audit** — if `docs/` contains a spec/PRD, validate implementation coverage
34
+
35
+ ## Step 5: Claude Code Setup
36
+
37
+ 1. **harness-optimizer** — check if .claude/ setup follows best practices
38
+
39
+ ## Step 6: Summary Report
40
+
41
+ Compile all findings into a single report grouped by severity:
42
+
43
+ ```
44
+ CRITICAL (must fix before merge):
45
+ - [list]
46
+
47
+ HIGH (fix soon):
48
+ - [list]
49
+
50
+ MEDIUM (improve when possible):
51
+ - [list]
52
+
53
+ LOW (nice to have):
54
+ - [list]
55
+
56
+ PASSED:
57
+ - [list of checks that found no issues]
58
+ ```
59
+
60
+ Include total counts: X critical, Y high, Z medium, W low.
@@ -0,0 +1,21 @@
1
+ Invoke the **planner** agent to create a comprehensive implementation plan before writing any code.
2
+
3
+ ## Process
4
+
5
+ 1. Ask the user what they want to build (or use the description they provided)
6
+ 2. Launch the `planner` agent with the feature description
7
+ 3. The planner will analyze the codebase, break down the work into phases, and identify risks
8
+ 4. Present the plan and WAIT for user confirmation before proceeding
9
+
10
+ ## Important
11
+
12
+ - NEVER write code until the user explicitly confirms the plan
13
+ - If the user wants modifications, update the plan and re-present
14
+ - After approval, suggest using `/tdd` to implement with test-driven development
15
+
16
+ ## Integration
17
+
18
+ After planning, use these commands:
19
+ - `/tdd` — implement with test-driven development
20
+ - `/build-fix` — fix any build errors that come up
21
+ - `/code-review` — review the completed implementation
@@ -0,0 +1,50 @@
1
+ Load a saved session file and orient before doing any work.
2
+
3
+ ## Process
4
+
5
+ 1. **Find the session file** — Check `docs/sessions/` for the most recent `*-session.md` file
6
+ 2. **Read the entire file** — Do not summarize yet
7
+ 3. **Present a briefing** in this format:
8
+
9
+ ```
10
+ SESSION LOADED: [file path]
11
+ ════════════════════════════════════════════════
12
+
13
+ PROJECT: [project name / topic]
14
+
15
+ WHAT WE'RE BUILDING:
16
+ [2-3 sentence summary in your own words]
17
+
18
+ CURRENT STATE:
19
+ ✅ Working: [count] items confirmed
20
+ 🔄 In Progress: [list files in progress]
21
+ 🗒️ Not Started: [list planned but untouched]
22
+
23
+ WHAT NOT TO RETRY:
24
+ [list every failed approach with its reason]
25
+
26
+ OPEN QUESTIONS / BLOCKERS:
27
+ [list any blockers]
28
+
29
+ NEXT STEP:
30
+ [exact next step from the file]
31
+
32
+ ════════════════════════════════════════════════
33
+ Ready to continue. What would you like to do?
34
+ ```
35
+
36
+ 4. **WAIT for the user** — Do NOT start working automatically
37
+
38
+ ## Edge Cases
39
+
40
+ - **No session files found** — Tell the user to run `/save-session` first
41
+ - **Session references deleted files** — Note "⚠️ file.ts referenced but not found on disk"
42
+ - **Session is > 7 days old** — Note "⚠️ This session is N days old, things may have changed"
43
+ - **Empty or malformed file** — Report and suggest creating a new session
44
+
45
+ ## Rules
46
+
47
+ - Never modify the session file — it's a read-only historical record
48
+ - Never skip the "What Not To Retry" section — it's the most important
49
+ - Always wait for the user before starting work
50
+ - If the next step is defined and the user says "continue" — proceed with that exact step
@@ -0,0 +1,69 @@
1
+ Save the current session state so work can be resumed in a future conversation.
2
+
3
+ ## Process
4
+
5
+ 1. **Gather context** — Review what was discussed, built, and decided this session
6
+ 2. **Create folder** — `mkdir -p docs/sessions` (or `~/.claude/sessions/`)
7
+ 3. **Write session file** — `docs/sessions/YYYY-MM-DD-session.md`
8
+ 4. **Show to user** — Display contents and ask for corrections
9
+
10
+ ## Session File Format
11
+
12
+ ```markdown
13
+ # Session: YYYY-MM-DD
14
+
15
+ **Project:** [project name]
16
+ **Topic:** [one-line summary]
17
+
18
+ ---
19
+
20
+ ## What We Are Building
21
+ [1-3 paragraphs with enough context for someone with zero memory of this session]
22
+
23
+ ---
24
+
25
+ ## What WORKED (with evidence)
26
+ - **[thing]** — confirmed by: [specific evidence like "tests pass", "200 response"]
27
+
28
+ ---
29
+
30
+ ## What Did NOT Work (and why)
31
+ - **[approach]** — failed because: [exact reason / error message]
32
+
33
+ ---
34
+
35
+ ## What Has NOT Been Tried Yet
36
+ - [approach worth exploring]
37
+
38
+ ---
39
+
40
+ ## Current State of Files
41
+
42
+ | File | Status | Notes |
43
+ |------|--------|-------|
44
+ | `path/file.ts` | ✅ Complete | [what it does] |
45
+ | `path/file.ts` | 🔄 In Progress | [what's left] |
46
+ | `path/file.ts` | 🗒️ Not Started | [planned] |
47
+
48
+ ---
49
+
50
+ ## Decisions Made
51
+ - **[decision]** — reason: [why]
52
+
53
+ ---
54
+
55
+ ## Blockers & Open Questions
56
+ - [blocker or unanswered question]
57
+
58
+ ---
59
+
60
+ ## Exact Next Step
61
+ [The single most important thing to do when resuming]
62
+ ```
63
+
64
+ ## Rules
65
+
66
+ - Write every section honestly — "Nothing yet" is better than skipping a section
67
+ - The "What Did NOT Work" section is the most critical — prevents retrying failed approaches
68
+ - Each session gets its own file — never append to previous sessions
69
+ - Wait for user confirmation before closing
@@ -0,0 +1,80 @@
1
+ Enforce test-driven development: write failing tests FIRST, then implement.
2
+
3
+ ## TDD Cycle
4
+
5
+ ```
6
+ RED → GREEN → REFACTOR → REPEAT
7
+ ```
8
+
9
+ 1. **RED** — Write a failing test (because the code doesn't exist yet)
10
+ 2. **GREEN** — Write the minimum code to make the test pass
11
+ 3. **REFACTOR** — Improve the code while keeping tests green
12
+ 4. **REPEAT** — Next scenario
13
+
14
+ ## Process
15
+
16
+ 1. Ask the user what feature to implement
17
+ 2. Launch the `tdd-guide` agent
18
+ 3. Define types/interfaces first
19
+ 4. Write failing tests covering: happy path, edge cases, error cases
20
+ 5. Run `{{TEST_COMMAND}}` — verify tests FAIL for the right reason
21
+ 6. Implement minimal code to pass
22
+ 7. Run `{{TEST_COMMAND}}` — verify tests PASS
23
+ 8. Refactor if needed, keeping tests green
24
+ 9. Check coverage — target 80%+ minimum
25
+
26
+ ## Example
27
+
28
+ ```
29
+ User: /tdd I need a function to validate email addresses
30
+
31
+ Step 1 — SCAFFOLD:
32
+ Create types/interfaces for input and output
33
+
34
+ Step 2 — RED (write failing tests):
35
+ - "should accept valid email: user@example.com"
36
+ - "should reject email without @"
37
+ - "should reject email without domain"
38
+ - "should reject empty string"
39
+ - "should handle unicode characters"
40
+
41
+ Step 3 — Run tests → all FAIL (expected, no implementation yet)
42
+
43
+ Step 4 — GREEN (implement minimal code):
44
+ Write just enough to pass all tests
45
+
46
+ Step 5 — Run tests → all PASS
47
+
48
+ Step 6 — REFACTOR:
49
+ Extract constants, improve naming, add JSDoc
50
+
51
+ Step 7 — Run tests → still PASS
52
+
53
+ Step 8 — Check coverage → 100%
54
+ ```
55
+
56
+ ## Rules
57
+
58
+ - NEVER write implementation before tests
59
+ - NEVER skip running tests after changes
60
+ - Each test should test ONE behavior
61
+ - Use descriptive names: "should return 404 when user not found"
62
+ - Test behavior, not implementation details
63
+ - Don't mock what you're testing
64
+
65
+ ## Coverage Targets
66
+
67
+ - 80% minimum for all code
68
+ - 100% required for: financial calculations, auth logic, security-critical code
69
+
70
+ ## Test Types to Include
71
+
72
+ - **Unit**: happy path, edge cases (null, empty, max), error conditions, boundary values
73
+ - **Integration**: API endpoints, database operations, auth flows
74
+ - **E2E**: use `/e2e` command for full user journey tests
75
+
76
+ ## After TDD
77
+
78
+ - `/build-fix` — if build errors come up
79
+ - `/code-review` — review the implementation
80
+ - `/done` — verify the task is complete
@@ -2,13 +2,20 @@ Show the developer what workflows are available.
2
2
 
3
3
  ## Available Workflows
4
4
 
5
- ### Daily Development
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
6
12
  - `/status` — Run all checks and show a project dashboard
7
13
  - `/next` — Figure out what to work on next
8
14
  - `/done` — Verify the current task is complete before moving on
9
15
 
10
16
  ### Verification
11
17
  - `/verify-all` — Run lint, type check, tests, then launch all reviewers
18
+ - `/full-audit` — Run every audit and review agent in a single pass
12
19
  - `/audit-spec` — Validate implementation against a spec/PRD
13
20
  - `/audit-wiring` — Find dead or unwired features
14
21
  - `/audit-security` — Run a security audit
@@ -22,5 +29,9 @@ Show the developer what workflows are available.
22
29
  - `/generate-uat` — Generate UAT scenarios and checklists
23
30
  - `/optimize-claude-md` — Slim down an oversized CLAUDE.md
24
31
 
32
+ ### Session
33
+ - `/save-session` — Save current work context for later resumption
34
+ - `/resume-session` — Load a saved session and continue where you left off
35
+
25
36
  ## Quick Start
26
37
  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,44 @@
1
+ #!/usr/bin/env node
2
+ // Auto-fix lint issues on saved TypeScript or Python files (polyglot)
3
+
4
+ import { execFileSync } from 'node:child_process';
5
+ import { resolve } from 'node:path';
6
+
7
+ let input = '';
8
+ process.stdin.setEncoding('utf8');
9
+ process.stdin.on('data', (chunk) => { input += chunk; });
10
+ process.stdin.on('end', () => {
11
+ try {
12
+ const data = JSON.parse(input);
13
+ const filePath = data?.tool_input?.file_path || '';
14
+
15
+ if (!filePath || filePath.includes('..')) {
16
+ process.exit(0);
17
+ }
18
+
19
+ // Ensure path stays within the working directory
20
+ const resolved = resolve(filePath);
21
+ const cwd = resolve('.');
22
+ if (!resolved.startsWith(cwd)) {
23
+ process.exit(0);
24
+ }
25
+
26
+ if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {
27
+ try {
28
+ execFileSync('npx', ['eslint', '--fix', filePath], { stdio: 'pipe', cwd: 'frontend' });
29
+ } catch {
30
+ // eslint may exit non-zero for unfixable issues — that's okay
31
+ }
32
+ } else if (filePath.endsWith('.py')) {
33
+ try {
34
+ execFileSync('ruff', ['check', '--fix', filePath], { stdio: 'pipe', cwd: 'backend' });
35
+ } catch {
36
+ // ruff may exit non-zero for unfixable issues — that's okay
37
+ }
38
+ }
39
+
40
+ process.exit(0);
41
+ } catch {
42
+ process.exit(0);
43
+ }
44
+ });
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ // Auto-fix lint issues on saved Python files
3
+
4
+ import { execFileSync } from 'node:child_process';
5
+ import { resolve } from 'node:path';
6
+
7
+ let input = '';
8
+ process.stdin.setEncoding('utf8');
9
+ process.stdin.on('data', (chunk) => { input += chunk; });
10
+ process.stdin.on('end', () => {
11
+ try {
12
+ const data = JSON.parse(input);
13
+ const filePath = data?.tool_input?.file_path || '';
14
+
15
+ if (!filePath || filePath.includes('..')) {
16
+ process.exit(0);
17
+ }
18
+
19
+ // Ensure path stays within the working directory
20
+ const resolved = resolve(filePath);
21
+ const cwd = resolve('.');
22
+ if (!resolved.startsWith(cwd)) {
23
+ process.exit(0);
24
+ }
25
+
26
+ if (filePath.endsWith('.py')) {
27
+ try {
28
+ execFileSync('ruff', ['check', '--fix', filePath], { stdio: 'pipe', cwd: 'backend' });
29
+ } catch {
30
+ // ruff may exit non-zero for unfixable issues — that's okay
31
+ }
32
+ }
33
+
34
+ process.exit(0);
35
+ } catch {
36
+ process.exit(0);
37
+ }
38
+ });
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ // Auto-fix lint issues on saved TypeScript files
3
+
4
+ import { execFileSync } from 'node:child_process';
5
+ import { resolve } from 'node:path';
6
+
7
+ let input = '';
8
+ process.stdin.setEncoding('utf8');
9
+ process.stdin.on('data', (chunk) => { input += chunk; });
10
+ process.stdin.on('end', () => {
11
+ try {
12
+ const data = JSON.parse(input);
13
+ const filePath = data?.tool_input?.file_path || '';
14
+
15
+ if (!filePath || filePath.includes('..')) {
16
+ process.exit(0);
17
+ }
18
+
19
+ // Ensure path stays within the working directory
20
+ const resolved = resolve(filePath);
21
+ const cwd = resolve('.');
22
+ if (!resolved.startsWith(cwd)) {
23
+ process.exit(0);
24
+ }
25
+
26
+ if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {
27
+ try {
28
+ execFileSync('npx', ['eslint', '--fix', filePath], { stdio: 'pipe' });
29
+ } catch {
30
+ // eslint may exit non-zero for unfixable issues — that's okay
31
+ }
32
+ }
33
+
34
+ process.exit(0);
35
+ } catch {
36
+ process.exit(0);
37
+ }
38
+ });
@@ -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
  }
@@ -33,6 +33,7 @@ description: AI/LLM integration patterns and best practices
33
33
  ## Security
34
34
  - Never include user secrets in prompts
35
35
  - Sanitize user input before including in prompts
36
+ - Protect against prompt injection attacks (delimiter tokens, input validation, output filtering)
36
37
  - Validate and sanitize AI output before using
37
38
  - Don't trust AI output for security decisions
38
39
 
@@ -29,7 +29,7 @@ description: FastAPI + SQLAlchemy 2.0 + Pydantic v2 patterns
29
29
  - Raise `AppError` subclasses, never `HTTPException` with raw strings
30
30
  - Global exception handler catches unhandled errors
31
31
  - Never expose stack traces or internal details to clients
32
- - Use structured error format: `{ error: { code, message } }`
32
+ - Use structured error format: `{ "error": { "code": "ERR_CODE", "message": "Error description" } }`
33
33
 
34
34
  ## Testing
35
35
  - Use `httpx.AsyncClient` with `ASGITransport` for async tests
@@ -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` (pulls current branch's upstream)
@@ -25,8 +25,8 @@ description: Playwright E2E testing patterns and best practices
25
25
 
26
26
  ## Common Patterns
27
27
  - Navigation: `await page.goto('/')` then assert page loaded
28
- - Form filling: `await page.fill('[name=email]', 'test@example.com')`
29
- - Clicking: `await page.click('button[type=submit]')` or `getByRole`
28
+ - Form filling: `await page.getByLabel('Email').fill('test@example.com')`
29
+ - Clicking: `await page.getByRole('button', { name: 'Submit' }).click()`
30
30
  - Waiting: prefer auto-waiting over explicit waits
31
31
  - Network: `page.waitForResponse()` for API-dependent tests
32
32
  - Authentication: use `storageState` for persistent auth across tests