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.
- package/CLAUDE.md +3 -3
- package/README.md +44 -20
- package/package.json +1 -1
- package/src/claude-configurator.js +29 -7
- package/src/guided.js +5 -5
- package/src/index.js +1 -1
- package/src/init-mode.js +2 -2
- package/templates/claude-code/agents/architect.md +70 -0
- package/templates/claude-code/agents/build-error-resolver.md +31 -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 +53 -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/claude-md/base.md +28 -0
- 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 +45 -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 +36 -0
- 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 +36 -0
- package/templates/claude-code/hooks/scripts/autofix-python.mjs +30 -0
- package/templates/claude-code/hooks/scripts/autofix-typescript.mjs +30 -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/git-workflow/SKILL.md +64 -0
- package/templates/claude-code/skills/testing-patterns/SKILL.md +97 -0
- package/templates/claude-code/commands/help.md +0 -26
- 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
|
@@ -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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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
|