claude-auto 0.12.4
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-auto/.claude.hooks.json +25 -0
- package/.claude-auto/reminders/reminder-auto.md +145 -0
- package/.claude-auto/reminders/reminder-documentation.md +30 -0
- package/.claude-auto/reminders/reminder-emergent-design.md +41 -0
- package/.claude-auto/reminders/reminder-extreme-ownership.md +27 -0
- package/.claude-auto/reminders/reminder-ide-diagnostics.md +25 -0
- package/.claude-auto/reminders/reminder-parallelization.md +27 -0
- package/.claude-auto/reminders/reminder-rethink-after-revert.md +25 -0
- package/.claude-auto/reminders/reminder-sub-agent-rules.md +27 -0
- package/.claude-auto/reminders/reminder-test-title-matches-spec.md +37 -0
- package/.claude-auto/validators/appeal-system.md +55 -0
- package/.claude-auto/validators/backwards-compat.md +33 -0
- package/.claude-auto/validators/burst-atomicity.md +37 -0
- package/.claude-auto/validators/coverage-rules.md +34 -0
- package/.claude-auto/validators/dead-code.md +36 -0
- package/.claude-auto/validators/hygiene.md +34 -0
- package/.claude-auto/validators/infra-commit-format.md +37 -0
- package/.claude-auto/validators/ketchup-plan-format.md +42 -0
- package/.claude-auto/validators/new-code-requires-tests.md +36 -0
- package/.claude-auto/validators/no-comments.md +35 -0
- package/.claude-auto/validators/no-dangerous-git.md +35 -0
- package/.claude-auto/validators/tcr-workflow.md +31 -0
- package/.claude-auto/validators/testing-no-state-peeking.md +37 -0
- package/.claude-auto/validators/testing-structure.md +37 -0
- package/.claude-auto/validators/testing-stubs-over-mocks.md +42 -0
- package/.claude-auto/validators/testing-weak-assertions.md +36 -0
- package/.claude-auto/validators/type-organization.md +30 -0
- package/README.md +172 -0
- package/bin/cli.ts +6 -0
- package/dist/bin/cli.d.ts +3 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +7 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/bundle/scripts/auto-continue.js +5045 -0
- package/dist/bundle/scripts/pre-tool-use.js +11719 -0
- package/dist/bundle/scripts/session-start.js +8571 -0
- package/dist/bundle/scripts/user-prompt-submit.js +8585 -0
- package/dist/scripts/auto-continue.d.ts +3 -0
- package/dist/scripts/auto-continue.d.ts.map +1 -0
- package/dist/scripts/auto-continue.js +65 -0
- package/dist/scripts/auto-continue.js.map +1 -0
- package/dist/scripts/generate-changeset.d.ts +13 -0
- package/dist/scripts/generate-changeset.d.ts.map +1 -0
- package/dist/scripts/generate-changeset.js +322 -0
- package/dist/scripts/generate-changeset.js.map +1 -0
- package/dist/scripts/pre-tool-use.d.ts +3 -0
- package/dist/scripts/pre-tool-use.d.ts.map +1 -0
- package/dist/scripts/pre-tool-use.js +78 -0
- package/dist/scripts/pre-tool-use.js.map +1 -0
- package/dist/scripts/session-start.d.ts +3 -0
- package/dist/scripts/session-start.d.ts.map +1 -0
- package/dist/scripts/session-start.js +76 -0
- package/dist/scripts/session-start.js.map +1 -0
- package/dist/scripts/user-prompt-submit.d.ts +3 -0
- package/dist/scripts/user-prompt-submit.d.ts.map +1 -0
- package/dist/scripts/user-prompt-submit.js +76 -0
- package/dist/scripts/user-prompt-submit.js.map +1 -0
- package/dist/src/activity-logger.d.ts +2 -0
- package/dist/src/activity-logger.d.ts.map +1 -0
- package/dist/src/activity-logger.js +47 -0
- package/dist/src/activity-logger.js.map +1 -0
- package/dist/src/activity-logger.test.d.ts +2 -0
- package/dist/src/activity-logger.test.d.ts.map +1 -0
- package/dist/src/activity-logger.test.js +121 -0
- package/dist/src/activity-logger.test.js.map +1 -0
- package/dist/src/clean-logs.d.ts +6 -0
- package/dist/src/clean-logs.d.ts.map +1 -0
- package/dist/src/clean-logs.js +38 -0
- package/dist/src/clean-logs.js.map +1 -0
- package/dist/src/clean-logs.test.d.ts +2 -0
- package/dist/src/clean-logs.test.d.ts.map +1 -0
- package/dist/src/clean-logs.test.js +101 -0
- package/dist/src/clean-logs.test.js.map +1 -0
- package/dist/src/cli/cli.d.ts +3 -0
- package/dist/src/cli/cli.d.ts.map +1 -0
- package/dist/src/cli/cli.js +32 -0
- package/dist/src/cli/cli.js.map +1 -0
- package/dist/src/cli/cli.test.d.ts +2 -0
- package/dist/src/cli/cli.test.d.ts.map +1 -0
- package/dist/src/cli/cli.test.js +27 -0
- package/dist/src/cli/cli.test.js.map +1 -0
- package/dist/src/cli/doctor.d.ts +7 -0
- package/dist/src/cli/doctor.d.ts.map +1 -0
- package/dist/src/cli/doctor.js +67 -0
- package/dist/src/cli/doctor.js.map +1 -0
- package/dist/src/cli/doctor.test.d.ts +2 -0
- package/dist/src/cli/doctor.test.d.ts.map +1 -0
- package/dist/src/cli/doctor.test.js +87 -0
- package/dist/src/cli/doctor.test.js.map +1 -0
- package/dist/src/cli/install.d.ts +10 -0
- package/dist/src/cli/install.d.ts.map +1 -0
- package/dist/src/cli/install.js +116 -0
- package/dist/src/cli/install.js.map +1 -0
- package/dist/src/cli/install.test.d.ts +2 -0
- package/dist/src/cli/install.test.d.ts.map +1 -0
- package/dist/src/cli/install.test.js +217 -0
- package/dist/src/cli/install.test.js.map +1 -0
- package/dist/src/cli/reminders.d.ts +12 -0
- package/dist/src/cli/reminders.d.ts.map +1 -0
- package/dist/src/cli/reminders.js +52 -0
- package/dist/src/cli/reminders.js.map +1 -0
- package/dist/src/cli/reminders.test.d.ts +2 -0
- package/dist/src/cli/reminders.test.d.ts.map +1 -0
- package/dist/src/cli/reminders.test.js +72 -0
- package/dist/src/cli/reminders.test.js.map +1 -0
- package/dist/src/cli/repair.d.ts +11 -0
- package/dist/src/cli/repair.d.ts.map +1 -0
- package/dist/src/cli/repair.js +91 -0
- package/dist/src/cli/repair.js.map +1 -0
- package/dist/src/cli/repair.test.d.ts +2 -0
- package/dist/src/cli/repair.test.d.ts.map +1 -0
- package/dist/src/cli/repair.test.js +95 -0
- package/dist/src/cli/repair.test.js.map +1 -0
- package/dist/src/cli/status.d.ts +10 -0
- package/dist/src/cli/status.d.ts.map +1 -0
- package/dist/src/cli/status.js +55 -0
- package/dist/src/cli/status.js.map +1 -0
- package/dist/src/cli/status.test.d.ts +2 -0
- package/dist/src/cli/status.test.d.ts.map +1 -0
- package/dist/src/cli/status.test.js +80 -0
- package/dist/src/cli/status.test.js.map +1 -0
- package/dist/src/clue-collector.d.ts +23 -0
- package/dist/src/clue-collector.d.ts.map +1 -0
- package/dist/src/clue-collector.js +221 -0
- package/dist/src/clue-collector.js.map +1 -0
- package/dist/src/clue-collector.test.d.ts +2 -0
- package/dist/src/clue-collector.test.d.ts.map +1 -0
- package/dist/src/clue-collector.test.js +278 -0
- package/dist/src/clue-collector.test.js.map +1 -0
- package/dist/src/commit-validator.d.ts +53 -0
- package/dist/src/commit-validator.d.ts.map +1 -0
- package/dist/src/commit-validator.js +356 -0
- package/dist/src/commit-validator.js.map +1 -0
- package/dist/src/commit-validator.test.d.ts +2 -0
- package/dist/src/commit-validator.test.d.ts.map +1 -0
- package/dist/src/commit-validator.test.js +733 -0
- package/dist/src/commit-validator.test.js.map +1 -0
- package/dist/src/config-loader.d.ts +15 -0
- package/dist/src/config-loader.d.ts.map +1 -0
- package/dist/src/config-loader.js +12 -0
- package/dist/src/config-loader.js.map +1 -0
- package/dist/src/config-loader.test.d.ts +2 -0
- package/dist/src/config-loader.test.d.ts.map +1 -0
- package/dist/src/config-loader.test.js +69 -0
- package/dist/src/config-loader.test.js.map +1 -0
- package/dist/src/debug-logger.d.ts +2 -0
- package/dist/src/debug-logger.d.ts.map +1 -0
- package/dist/src/debug-logger.js +23 -0
- package/dist/src/debug-logger.js.map +1 -0
- package/dist/src/debug-logger.test.d.ts +2 -0
- package/dist/src/debug-logger.test.d.ts.map +1 -0
- package/dist/src/debug-logger.test.js +63 -0
- package/dist/src/debug-logger.test.js.map +1 -0
- package/dist/src/default-validators.test.d.ts +2 -0
- package/dist/src/default-validators.test.d.ts.map +1 -0
- package/dist/src/default-validators.test.js +119 -0
- package/dist/src/default-validators.test.js.map +1 -0
- package/dist/src/deny-list.d.ts +3 -0
- package/dist/src/deny-list.d.ts.map +1 -0
- package/dist/src/deny-list.js +62 -0
- package/dist/src/deny-list.js.map +1 -0
- package/dist/src/deny-list.test.d.ts +2 -0
- package/dist/src/deny-list.test.d.ts.map +1 -0
- package/dist/src/deny-list.test.js +93 -0
- package/dist/src/deny-list.test.js.map +1 -0
- package/dist/src/e2e.test.d.ts +2 -0
- package/dist/src/e2e.test.d.ts.map +1 -0
- package/dist/src/e2e.test.js +82 -0
- package/dist/src/e2e.test.js.map +1 -0
- package/dist/src/gitignore-manager.d.ts +2 -0
- package/dist/src/gitignore-manager.d.ts.map +1 -0
- package/dist/src/gitignore-manager.js +45 -0
- package/dist/src/gitignore-manager.js.map +1 -0
- package/dist/src/gitignore-manager.test.d.ts +2 -0
- package/dist/src/gitignore-manager.test.d.ts.map +1 -0
- package/dist/src/gitignore-manager.test.js +65 -0
- package/dist/src/gitignore-manager.test.js.map +1 -0
- package/dist/src/hook-input.d.ts +9 -0
- package/dist/src/hook-input.d.ts.map +1 -0
- package/dist/src/hook-input.js +7 -0
- package/dist/src/hook-input.js.map +1 -0
- package/dist/src/hook-input.test.d.ts +2 -0
- package/dist/src/hook-input.test.d.ts.map +1 -0
- package/dist/src/hook-input.test.js +20 -0
- package/dist/src/hook-input.test.js.map +1 -0
- package/dist/src/hook-logger.d.ts +16 -0
- package/dist/src/hook-logger.d.ts.map +1 -0
- package/dist/src/hook-logger.js +90 -0
- package/dist/src/hook-logger.js.map +1 -0
- package/dist/src/hook-logger.test.d.ts +2 -0
- package/dist/src/hook-logger.test.d.ts.map +1 -0
- package/dist/src/hook-logger.test.js +205 -0
- package/dist/src/hook-logger.test.js.map +1 -0
- package/dist/src/hook-state.d.ts +44 -0
- package/dist/src/hook-state.d.ts.map +1 -0
- package/dist/src/hook-state.js +128 -0
- package/dist/src/hook-state.js.map +1 -0
- package/dist/src/hook-state.test.d.ts +2 -0
- package/dist/src/hook-state.test.d.ts.map +1 -0
- package/dist/src/hook-state.test.js +204 -0
- package/dist/src/hook-state.test.js.map +1 -0
- package/dist/src/hooks/auto-continue.d.ts +21 -0
- package/dist/src/hooks/auto-continue.d.ts.map +1 -0
- package/dist/src/hooks/auto-continue.js +70 -0
- package/dist/src/hooks/auto-continue.js.map +1 -0
- package/dist/src/hooks/auto-continue.test.d.ts +2 -0
- package/dist/src/hooks/auto-continue.test.d.ts.map +1 -0
- package/dist/src/hooks/auto-continue.test.js +171 -0
- package/dist/src/hooks/auto-continue.test.js.map +1 -0
- package/dist/src/hooks/pre-tool-use.d.ts +14 -0
- package/dist/src/hooks/pre-tool-use.d.ts.map +1 -0
- package/dist/src/hooks/pre-tool-use.js +66 -0
- package/dist/src/hooks/pre-tool-use.js.map +1 -0
- package/dist/src/hooks/pre-tool-use.test.d.ts +2 -0
- package/dist/src/hooks/pre-tool-use.test.d.ts.map +1 -0
- package/dist/src/hooks/pre-tool-use.test.js +255 -0
- package/dist/src/hooks/pre-tool-use.test.js.map +1 -0
- package/dist/src/hooks/session-start.d.ts +20 -0
- package/dist/src/hooks/session-start.d.ts.map +1 -0
- package/dist/src/hooks/session-start.js +27 -0
- package/dist/src/hooks/session-start.js.map +1 -0
- package/dist/src/hooks/session-start.test.d.ts +2 -0
- package/dist/src/hooks/session-start.test.d.ts.map +1 -0
- package/dist/src/hooks/session-start.test.js +125 -0
- package/dist/src/hooks/session-start.test.js.map +1 -0
- package/dist/src/hooks/user-prompt-submit.d.ts +17 -0
- package/dist/src/hooks/user-prompt-submit.d.ts.map +1 -0
- package/dist/src/hooks/user-prompt-submit.js +28 -0
- package/dist/src/hooks/user-prompt-submit.js.map +1 -0
- package/dist/src/hooks/user-prompt-submit.test.d.ts +2 -0
- package/dist/src/hooks/user-prompt-submit.test.d.ts.map +1 -0
- package/dist/src/hooks/user-prompt-submit.test.js +119 -0
- package/dist/src/hooks/user-prompt-submit.test.js.map +1 -0
- package/dist/src/hooks/validate-commit.d.ts +12 -0
- package/dist/src/hooks/validate-commit.d.ts.map +1 -0
- package/dist/src/hooks/validate-commit.js +58 -0
- package/dist/src/hooks/validate-commit.js.map +1 -0
- package/dist/src/hooks/validate-commit.test.d.ts +2 -0
- package/dist/src/hooks/validate-commit.test.d.ts.map +1 -0
- package/dist/src/hooks/validate-commit.test.js +150 -0
- package/dist/src/hooks/validate-commit.test.js.map +1 -0
- package/dist/src/index.d.ts +18 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +42 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/linker.d.ts +6 -0
- package/dist/src/linker.d.ts.map +1 -0
- package/dist/src/linker.js +78 -0
- package/dist/src/linker.js.map +1 -0
- package/dist/src/linker.test.d.ts +2 -0
- package/dist/src/linker.test.d.ts.map +1 -0
- package/dist/src/linker.test.js +192 -0
- package/dist/src/linker.test.js.map +1 -0
- package/dist/src/logger.d.ts +21 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +117 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/logger.test.d.ts +2 -0
- package/dist/src/logger.test.d.ts.map +1 -0
- package/dist/src/logger.test.js +159 -0
- package/dist/src/logger.test.js.map +1 -0
- package/dist/src/path-resolver.d.ts +9 -0
- package/dist/src/path-resolver.d.ts.map +1 -0
- package/dist/src/path-resolver.js +52 -0
- package/dist/src/path-resolver.js.map +1 -0
- package/dist/src/reminder-loader.d.ts +24 -0
- package/dist/src/reminder-loader.d.ts.map +1 -0
- package/dist/src/reminder-loader.js +84 -0
- package/dist/src/reminder-loader.js.map +1 -0
- package/dist/src/reminder-loader.test.d.ts +2 -0
- package/dist/src/reminder-loader.test.d.ts.map +1 -0
- package/dist/src/reminder-loader.test.js +152 -0
- package/dist/src/reminder-loader.test.js.map +1 -0
- package/dist/src/root-finder.d.ts +2 -0
- package/dist/src/root-finder.d.ts.map +1 -0
- package/dist/src/root-finder.js +71 -0
- package/dist/src/root-finder.js.map +1 -0
- package/dist/src/root-finder.test.d.ts +2 -0
- package/dist/src/root-finder.test.d.ts.map +1 -0
- package/dist/src/root-finder.test.js +111 -0
- package/dist/src/root-finder.test.js.map +1 -0
- package/dist/src/settings-merger.d.ts +2 -0
- package/dist/src/settings-merger.d.ts.map +1 -0
- package/dist/src/settings-merger.js +133 -0
- package/dist/src/settings-merger.js.map +1 -0
- package/dist/src/settings-merger.test.d.ts +2 -0
- package/dist/src/settings-merger.test.d.ts.map +1 -0
- package/dist/src/settings-merger.test.js +379 -0
- package/dist/src/settings-merger.test.js.map +1 -0
- package/dist/src/settings-template.test.d.ts +2 -0
- package/dist/src/settings-template.test.d.ts.map +1 -0
- package/dist/src/settings-template.test.js +88 -0
- package/dist/src/settings-template.test.js.map +1 -0
- package/dist/src/state-manager.d.ts +5 -0
- package/dist/src/state-manager.d.ts.map +1 -0
- package/dist/src/state-manager.js +55 -0
- package/dist/src/state-manager.js.map +1 -0
- package/dist/src/state-manager.test.d.ts +2 -0
- package/dist/src/state-manager.test.d.ts.map +1 -0
- package/dist/src/state-manager.test.js +85 -0
- package/dist/src/state-manager.test.js.map +1 -0
- package/dist/src/subagent-classifier.d.ts +4 -0
- package/dist/src/subagent-classifier.d.ts.map +1 -0
- package/dist/src/subagent-classifier.js +53 -0
- package/dist/src/subagent-classifier.js.map +1 -0
- package/dist/src/subagent-classifier.test.d.ts +2 -0
- package/dist/src/subagent-classifier.test.d.ts.map +1 -0
- package/dist/src/subagent-classifier.test.js +84 -0
- package/dist/src/subagent-classifier.test.js.map +1 -0
- package/dist/src/validator-loader.d.ts +9 -0
- package/dist/src/validator-loader.d.ts.map +1 -0
- package/dist/src/validator-loader.js +71 -0
- package/dist/src/validator-loader.js.map +1 -0
- package/dist/src/validator-loader.test.d.ts +2 -0
- package/dist/src/validator-loader.test.d.ts.map +1 -0
- package/dist/src/validator-loader.test.js +140 -0
- package/dist/src/validator-loader.test.js.map +1 -0
- package/package.json +91 -0
- package/scripts/auto-continue.ts +39 -0
- package/scripts/generate-changeset.ts +405 -0
- package/scripts/pre-tool-use.ts +44 -0
- package/scripts/session-start.ts +42 -0
- package/scripts/tail-logs.sh +17 -0
- package/scripts/test-hooks.sh +910 -0
- package/scripts/user-prompt-submit.ts +42 -0
- package/templates/settings.json +48 -0
- package/templates/settings.local.json +48 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"autoContinue": {
|
|
3
|
+
"mode": "smart",
|
|
4
|
+
"maxIterations": 0,
|
|
5
|
+
"iteration": 0,
|
|
6
|
+
"skipModes": ["plan"]
|
|
7
|
+
},
|
|
8
|
+
"validateCommit": {
|
|
9
|
+
"mode": "strict"
|
|
10
|
+
},
|
|
11
|
+
"denyList": {
|
|
12
|
+
"enabled": true,
|
|
13
|
+
"extraPatterns": []
|
|
14
|
+
},
|
|
15
|
+
"promptReminder": {
|
|
16
|
+
"enabled": true
|
|
17
|
+
},
|
|
18
|
+
"subagentHooks": {
|
|
19
|
+
"validateCommitOnExplore": false,
|
|
20
|
+
"validateCommitOnWork": true,
|
|
21
|
+
"validateCommitOnUnknown": true
|
|
22
|
+
},
|
|
23
|
+
"updatedAt": "2026-02-02T03:14:27.243Z",
|
|
24
|
+
"updatedBy": "init"
|
|
25
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
when:
|
|
3
|
+
hook: SessionStart
|
|
4
|
+
priority: 100
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Claude Auto Core Reminder
|
|
8
|
+
|
|
9
|
+
> Controlled Bursts | TDD | TCR | 100% Coverage
|
|
10
|
+
|
|
11
|
+
## Core Loop
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Red → Green → TCR → Refactor → TCR → Done
|
|
15
|
+
TCR: test && commit || revert
|
|
16
|
+
- Pass → commit → continue
|
|
17
|
+
- Fail → REVERT → RETHINK (smaller steps or new design)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Never patch failing code. Revert, learn, try differently.
|
|
21
|
+
|
|
22
|
+
## Bursts
|
|
23
|
+
|
|
24
|
+
One test, one behavior, one commit. No exceptions.
|
|
25
|
+
|
|
26
|
+
Each burst: independent, valuable, small, testable, reviewable.
|
|
27
|
+
|
|
28
|
+
The constraint is scope, not time. Keep bursts small enough that:
|
|
29
|
+
|
|
30
|
+
- You stay focused on one thing
|
|
31
|
+
- The operator can verify quickly
|
|
32
|
+
- A revert loses minimal work
|
|
33
|
+
|
|
34
|
+
E2E exception: E2E tests may combine 2 tightly-coupled bursts when splitting creates artificial boundaries.
|
|
35
|
+
|
|
36
|
+
## Workflow
|
|
37
|
+
|
|
38
|
+
1. Create `ketchup-plan.md` with TODO/DONE sections, commit before coding
|
|
39
|
+
2. Write ONE failing test
|
|
40
|
+
3. Write MINIMAL passing code
|
|
41
|
+
4. TCR (update plan in same commit)
|
|
42
|
+
5. Refactor if needed → TCR
|
|
43
|
+
6. Move burst to DONE → TCR
|
|
44
|
+
7. Next burst
|
|
45
|
+
|
|
46
|
+
```markdown
|
|
47
|
+
# Ketchup Plan: [Feature]
|
|
48
|
+
|
|
49
|
+
## TODO
|
|
50
|
+
|
|
51
|
+
- [ ] Burst 1: [description]
|
|
52
|
+
|
|
53
|
+
## DONE
|
|
54
|
+
|
|
55
|
+
- [x] Burst N: [description] (hash)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Refactoring
|
|
59
|
+
|
|
60
|
+
Refactor for readability, not for explanation. If code is complex, rename variables or extract functions. Do not add comments.
|
|
61
|
+
|
|
62
|
+
## Coverage
|
|
63
|
+
|
|
64
|
+
100% enforced. No escape hatches.
|
|
65
|
+
|
|
66
|
+
Exclusions allowed ONLY for: barrel `index.ts` re-exports, `*.test.ts` files
|
|
67
|
+
|
|
68
|
+
Forbidden:
|
|
69
|
+
|
|
70
|
+
- Excluding files to avoid testing them
|
|
71
|
+
- Standalone type files (`types.ts`, `interfaces.ts`) — types live inline where used
|
|
72
|
+
- `@ts-ignore`, `any`, `as SomeType` casts
|
|
73
|
+
|
|
74
|
+
| Do | Don't |
|
|
75
|
+
| ------------------------------- | ---------------------------------------- |
|
|
76
|
+
| Let tests drive all code | Write code without a failing test first |
|
|
77
|
+
| Add branches only when tested | Defensive `??`, `?:`, `if/else` untested |
|
|
78
|
+
| Test all error paths | Leave error handling unverified |
|
|
79
|
+
| Remove dead code after each run | Keep unused code "just in case" |
|
|
80
|
+
|
|
81
|
+
## Testing Rules
|
|
82
|
+
|
|
83
|
+
**Assertion Strength:** Never use weak assertions (`toBeDefined`, `toBeTruthy`, `not.toBeNull`). Assert the exact shape and value. If you don't know the exact value, use `expect.any(String)` or `expect.any(Number)`.
|
|
84
|
+
|
|
85
|
+
**Stubs over mocks:** Deterministic stubs preferred. Mock only at boundaries.
|
|
86
|
+
|
|
87
|
+
**Assert whole objects:** `expect(result).toEqual({...})` not cherry-picked properties.
|
|
88
|
+
|
|
89
|
+
**Squint test:** All tests must follow: SETUP (data) → EXECUTE (function call) → VERIFY (whole object assertion). No multiple execute/verify cycles in one test.
|
|
90
|
+
|
|
91
|
+
**No state peeking:** Test observable behavior, not internal state.
|
|
92
|
+
|
|
93
|
+
Litmus Test: "If I changed the internal data structure (e.g., Map to Array), would this test still pass?" If no, the test is coupled to implementation.
|
|
94
|
+
|
|
95
|
+
| Forbidden (Implementation) | Allowed (Behavior) |
|
|
96
|
+
| ------------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
97
|
+
| `expect(tracker.getActiveCount()).toBe(0)` | Test via callbacks/events |
|
|
98
|
+
| `expect(manager.clientCount).toBe(3)` | `tracker.onEvent(e => events.push(e))` |
|
|
99
|
+
| `expect(service["internalMap"].size).toBe(2)` | Test via return values |
|
|
100
|
+
| `tracker.cleanup(); expect(tracker.getCount()).toBe(0)` | Test cleanup by re-triggering: start same id, verify callback fires again |
|
|
101
|
+
|
|
102
|
+
**Do NOT expose methods solely for testing.** If you're adding `.getCount()` or `.getActiveSessionCount()` just to make tests pass, you're testing implementation, not behavior.
|
|
103
|
+
|
|
104
|
+
## Guardrails
|
|
105
|
+
|
|
106
|
+
- No comments — write self-expressing code
|
|
107
|
+
- No excuses, no "you're right" — keep working
|
|
108
|
+
- JS files only in `dist/`
|
|
109
|
+
- When tests fail, assume you broke it. CI passed before; your change is the variable.
|
|
110
|
+
|
|
111
|
+
**Backwards compatibility:** Ask first. Default to clean breaks. No silent preservation unless explicitly requested.
|
|
112
|
+
|
|
113
|
+
Backwards-compatibility hacks to avoid:
|
|
114
|
+
|
|
115
|
+
- Re-exporting moved/renamed symbols
|
|
116
|
+
- Keeping unused parameters with `_` prefix
|
|
117
|
+
- Adding `// @deprecated` comments for removed code
|
|
118
|
+
- Wrapper functions that delegate to new implementations
|
|
119
|
+
|
|
120
|
+
## Infrastructure Commits
|
|
121
|
+
|
|
122
|
+
Config files need no tests: `package.json`, `tsconfig.json`, `wrangler.toml`, `vite.config.ts`, `vitest.config.ts`, `.gitignore`, `ketchup-plan.md`
|
|
123
|
+
|
|
124
|
+
Format: `chore(scope): description`
|
|
125
|
+
|
|
126
|
+
First behavioral `.ts` file requires a test.
|
|
127
|
+
|
|
128
|
+
## Plea System
|
|
129
|
+
|
|
130
|
+
If the commit validator rejects your commit but you believe it's valid, add `plea: <reason>` to your commit message.
|
|
131
|
+
|
|
132
|
+
**Valid pleas:**
|
|
133
|
+
|
|
134
|
+
- Files must be committed together for coherence
|
|
135
|
+
- Existing code lacked coverage before your changes
|
|
136
|
+
|
|
137
|
+
**Invalid pleas (will be rejected):**
|
|
138
|
+
|
|
139
|
+
- Skipping tests for new code
|
|
140
|
+
- Untested code paths
|
|
141
|
+
- Any other CLAUDE.md rule bypass
|
|
142
|
+
|
|
143
|
+
## Misc
|
|
144
|
+
|
|
145
|
+
- No "Generated with Claude Code" in commits
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
when:
|
|
3
|
+
hook: SessionStart
|
|
4
|
+
priority: 100
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Documentation Reminder
|
|
8
|
+
|
|
9
|
+
Documentation is code. Outdated docs are bugs.
|
|
10
|
+
|
|
11
|
+
## When to Update Docs
|
|
12
|
+
|
|
13
|
+
Update documentation when:
|
|
14
|
+
- Adding features
|
|
15
|
+
- Changing APIs
|
|
16
|
+
- Completing milestones
|
|
17
|
+
|
|
18
|
+
## When NOT to Create New Docs
|
|
19
|
+
|
|
20
|
+
Do not create new documentation files unless the feature explicitly requires them.
|
|
21
|
+
|
|
22
|
+
Avoid:
|
|
23
|
+
- Creating README files proactively
|
|
24
|
+
- Adding markdown files "for completeness"
|
|
25
|
+
- Documenting internal implementation details
|
|
26
|
+
|
|
27
|
+
Prefer:
|
|
28
|
+
- Self-documenting code
|
|
29
|
+
- Updating existing docs
|
|
30
|
+
- Inline JSDoc for public APIs only
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
when:
|
|
3
|
+
hook: SessionStart
|
|
4
|
+
priority: 100
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Emergent Design Reminder
|
|
8
|
+
|
|
9
|
+
Behavior first. Types/interfaces emerge from tests.
|
|
10
|
+
|
|
11
|
+
## The Principle
|
|
12
|
+
|
|
13
|
+
Don't design types upfront. Let them emerge from what the tests require.
|
|
14
|
+
|
|
15
|
+
## Example
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// First: Write a test that calls a function and asserts output
|
|
19
|
+
it("creates user with generated id", () => {
|
|
20
|
+
const result = createUser({ name: "Alice" });
|
|
21
|
+
expect(result).toEqual({ id: expect.any(String), name: "Alice" });
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Then: Types emerge because the function needs them
|
|
25
|
+
// The test drove the need for: input type, output type, id generation
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Anti-Pattern
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// Don't do this: types/user.ts
|
|
32
|
+
interface User {
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
email: string;
|
|
36
|
+
createdAt: Date;
|
|
37
|
+
// ... 20 more fields "just in case"
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Types should be minimal and driven by actual test requirements, not speculative design.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
when:
|
|
3
|
+
hook: SessionStart
|
|
4
|
+
priority: 100
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Extreme Ownership Reminder
|
|
8
|
+
|
|
9
|
+
Every problem is your problem. No deflection. No explaining why something is broken.
|
|
10
|
+
|
|
11
|
+
## The Rule
|
|
12
|
+
|
|
13
|
+
See a problem → fix it or add a burst to fix it. No third option.
|
|
14
|
+
|
|
15
|
+
If you read a file, you're responsible for its state when you're done.
|
|
16
|
+
|
|
17
|
+
## Wrong vs Right Responses
|
|
18
|
+
|
|
19
|
+
| Situation | Wrong Response | Ownership Response |
|
|
20
|
+
| ------------------------ | --------------------------------------- | ----------------------------- |
|
|
21
|
+
| Bug in existing code | "The existing code has a bug where..." | Fix it or add burst to fix it |
|
|
22
|
+
| Test suite has gaps | "Coverage was incomplete before..." | Add the missing tests |
|
|
23
|
+
| Confusing function names | "The naming is unclear in this file..." | Rename in refactor step |
|
|
24
|
+
| Missing error handling | "Error handling wasn't implemented..." | Add it now |
|
|
25
|
+
| Flaky test | "This test appears to be unreliable..." | Stabilize it or add burst |
|
|
26
|
+
|
|
27
|
+
No excuses. No "you're right." Keep working.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
when:
|
|
3
|
+
hook: SessionStart
|
|
4
|
+
priority: 100
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# IDE Diagnostics Reminder
|
|
8
|
+
|
|
9
|
+
Before committing, check IDE diagnostics on all uncommitted files.
|
|
10
|
+
|
|
11
|
+
## Pre-Commit Checklist
|
|
12
|
+
|
|
13
|
+
1. Review all files with uncommitted changes
|
|
14
|
+
2. Check for TypeScript errors (red squiggles)
|
|
15
|
+
3. Check for warnings (yellow squiggles)
|
|
16
|
+
4. Ensure no linting errors remain
|
|
17
|
+
5. Verify imports are correctly resolved
|
|
18
|
+
|
|
19
|
+
## TCR Command
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm test --run && git add -A && git commit -m "<MSG>" || git checkout -- .
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The tests will catch most issues, but IDE diagnostics can catch type errors and import issues before you even run tests.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
when:
|
|
3
|
+
hook: SessionStart
|
|
4
|
+
priority: 100
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Parallelization Reminder
|
|
8
|
+
|
|
9
|
+
Maximize parallel execution. Launch multiple sub-agents when:
|
|
10
|
+
|
|
11
|
+
- Bursts have no dependencies on each other (`[depends: none]`)
|
|
12
|
+
- Exploration can be split by area (e.g., "search tests" + "search implementation")
|
|
13
|
+
- Multiple files need similar changes
|
|
14
|
+
|
|
15
|
+
## Dependency Notation
|
|
16
|
+
|
|
17
|
+
```markdown
|
|
18
|
+
### Bottle: Authentication
|
|
19
|
+
- [ ] Burst 10: createUser returns user object [depends: none]
|
|
20
|
+
- [ ] Burst 11: hashPassword uses bcrypt [depends: none]
|
|
21
|
+
- [ ] Burst 12: validatePassword checks hash [depends: 11]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Rules:**
|
|
25
|
+
- `[depends: none]` - can start immediately, parallelizable with other `none` bursts
|
|
26
|
+
- `[depends: N]` - must wait for burst N to complete
|
|
27
|
+
- Bursts at the same dependency level can run in parallel
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
when:
|
|
3
|
+
hook: SessionStart
|
|
4
|
+
priority: 100
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# RETHINK After Revert Reminder
|
|
8
|
+
|
|
9
|
+
After a revert, do NOT immediately retry the same approach.
|
|
10
|
+
|
|
11
|
+
## Ask These Questions First
|
|
12
|
+
|
|
13
|
+
1. **Was the burst too big?** → Split it into smaller bursts
|
|
14
|
+
2. **Was the design flawed?** → Try a different approach entirely
|
|
15
|
+
3. **Was the test wrong?** → Clarify the requirement before writing code
|
|
16
|
+
|
|
17
|
+
## Then
|
|
18
|
+
|
|
19
|
+
Only after answering these questions, write the next failing test.
|
|
20
|
+
|
|
21
|
+
Never patch failing code. The TCR pattern means:
|
|
22
|
+
- Pass → commit → continue
|
|
23
|
+
- Fail → REVERT → RETHINK (smaller steps or new design)
|
|
24
|
+
|
|
25
|
+
A revert is a signal to change your approach, not to try harder at the same thing.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
when:
|
|
3
|
+
hook: SessionStart
|
|
4
|
+
priority: 100
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Sub-Agent Rules Reminder
|
|
8
|
+
|
|
9
|
+
When spawning a Task agent (sub-agent), ensure:
|
|
10
|
+
|
|
11
|
+
1. **Include CLAUDE.md context** - Sub-agents must receive and follow these rules
|
|
12
|
+
2. **Include ketchup-plan.md** - Sub-agents work from the same plan
|
|
13
|
+
3. **No orphan work** - Sub-agent output must be committed by parent or sub-agent
|
|
14
|
+
|
|
15
|
+
Sub-agents follow identical rules to the parent. They are not exempt from any CLAUDE.md requirements.
|
|
16
|
+
|
|
17
|
+
## Prompt Pattern
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
You are working on [bottle name]. Follow CLAUDE.md rules exactly.
|
|
21
|
+
|
|
22
|
+
Your burst: [burst description]
|
|
23
|
+
Dependencies: [list completed bursts this depends on, or "none"]
|
|
24
|
+
Parallel with: [list of bursts running concurrently]
|
|
25
|
+
|
|
26
|
+
[specific instructions]
|
|
27
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
when:
|
|
3
|
+
hook: SessionStart
|
|
4
|
+
priority: 100
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Test Title = Spec Reminder
|
|
8
|
+
|
|
9
|
+
The test body must prove exactly what `it('should...')` claims.
|
|
10
|
+
|
|
11
|
+
## The Principle
|
|
12
|
+
|
|
13
|
+
**Title = Spec:** One assertion per behavior. The test title is the specification; the test body is the proof.
|
|
14
|
+
|
|
15
|
+
## Example
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// Good: Title matches what's being tested
|
|
19
|
+
it("creates user with generated id", () => {
|
|
20
|
+
const result = createUser({ name: "Alice" });
|
|
21
|
+
expect(result).toEqual({ id: expect.any(String), name: "Alice" });
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Bad: Title doesn't match assertion
|
|
25
|
+
it("creates user with generated id", () => {
|
|
26
|
+
const result = createUser({ name: "Alice" });
|
|
27
|
+
expect(result.name).toBe("Alice"); // Not testing the ID!
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Ask Yourself
|
|
32
|
+
|
|
33
|
+
"Does this test body prove exactly what the `it()` description claims?"
|
|
34
|
+
|
|
35
|
+
If not, either:
|
|
36
|
+
1. Fix the test body to prove the claim
|
|
37
|
+
2. Fix the title to match what you're actually testing
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: appeal-system
|
|
3
|
+
description: Evaluates appeals against validator NACKs
|
|
4
|
+
enabled: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are the appeal system. You receive validator results and an appeal, and decide whether the appeal justifies overriding the NACKs.
|
|
8
|
+
|
|
9
|
+
You MUST respond with ONLY a JSON object, no other text.
|
|
10
|
+
|
|
11
|
+
Valid responses:
|
|
12
|
+
{"decision":"ACK"}
|
|
13
|
+
{"decision":"NACK","reason":"one sentence explanation"}
|
|
14
|
+
|
|
15
|
+
**Input you receive:**
|
|
16
|
+
- Full commit context (diff, files, commit message)
|
|
17
|
+
- All validator results (which validators ran, their decisions, their reasons)
|
|
18
|
+
- Appeal text extracted from the commit message
|
|
19
|
+
|
|
20
|
+
**Valid appeal scenarios:**
|
|
21
|
+
|
|
22
|
+
1. **Coherence**: Files must be committed together for coherence. The changes are tightly coupled and splitting them would create an inconsistent state.
|
|
23
|
+
|
|
24
|
+
2. **Existing Gap**: Existing code lacked coverage before these changes. The violation existed before this commit and is not introduced by the current changes.
|
|
25
|
+
|
|
26
|
+
3. **Debug Branchless**: Test coverage not required for branchless debug statements. Simple logging or debug output that contains no conditional logic.
|
|
27
|
+
|
|
28
|
+
**ALWAYS NACK if:**
|
|
29
|
+
- The `no-dangerous-git` validator appears in the results with a NACK (this is non-appealable - dangerous git operations cannot be overridden)
|
|
30
|
+
- The appeal text does not describe one of the valid scenarios above
|
|
31
|
+
- The appeal does not justify each NACK - every rejected validator must be addressed by the appeal
|
|
32
|
+
|
|
33
|
+
**ACK if:**
|
|
34
|
+
- The appeal text describes a valid scenario from the list above
|
|
35
|
+
- The appeal reasonably justifies each appealable NACK
|
|
36
|
+
- The `no-dangerous-git` validator either did not run or returned ACK
|
|
37
|
+
|
|
38
|
+
**Examples:**
|
|
39
|
+
|
|
40
|
+
Appeal: "these files are tightly coupled and must be committed together"
|
|
41
|
+
→ Valid coherence appeal
|
|
42
|
+
|
|
43
|
+
Appeal: "the coverage gap existed before my changes"
|
|
44
|
+
→ Valid existing-gap appeal
|
|
45
|
+
|
|
46
|
+
Appeal: "this is just a console.log with no branches"
|
|
47
|
+
→ Valid debug-branchless appeal
|
|
48
|
+
|
|
49
|
+
Appeal: "I don't have time to write tests"
|
|
50
|
+
→ Invalid - not a valid scenario
|
|
51
|
+
|
|
52
|
+
Appeal: "please let this through"
|
|
53
|
+
→ Invalid - not a valid scenario
|
|
54
|
+
|
|
55
|
+
RESPOND WITH JSON ONLY - NO PROSE, NO MARKDOWN, NO EXPLANATION OUTSIDE THE JSON.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: backwards-compat
|
|
3
|
+
description: Enforces clean breaks over compatibility hacks
|
|
4
|
+
enabled: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a commit validator. You MUST respond with ONLY a JSON object, no other text.
|
|
8
|
+
|
|
9
|
+
Valid responses:
|
|
10
|
+
{"decision":"ACK"}
|
|
11
|
+
{"decision":"NACK","reason":"one sentence explanation"}
|
|
12
|
+
|
|
13
|
+
**Scope:** Validate any .ts file changes in the diff.
|
|
14
|
+
|
|
15
|
+
Default to clean breaks. No silent preservation of old APIs.
|
|
16
|
+
|
|
17
|
+
**NACK if the diff contains:**
|
|
18
|
+
- Re-exports of moved/renamed symbols for backwards compatibility
|
|
19
|
+
- `@deprecated` comments or JSDoc tags
|
|
20
|
+
- Wrapper functions that only delegate to new implementations
|
|
21
|
+
- Unused parameters with `_` prefix kept for signature compatibility
|
|
22
|
+
- Shim files that import from new location and re-export
|
|
23
|
+
- `// removed` or similar comments for deleted code
|
|
24
|
+
|
|
25
|
+
**ACK if:**
|
|
26
|
+
- The diff makes clean changes without compatibility layers
|
|
27
|
+
- Old code is simply removed, not shimmed
|
|
28
|
+
- The diff only contains non-.ts files
|
|
29
|
+
- Refactoring removes old code entirely
|
|
30
|
+
|
|
31
|
+
**Plea override:** If files must be committed together for coherence during a rename/refactor, use `plea: files must be committed together for coherence` in the commit message.
|
|
32
|
+
|
|
33
|
+
RESPOND WITH JSON ONLY - NO PROSE, NO MARKDOWN, NO EXPLANATION OUTSIDE THE JSON.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: burst-atomicity
|
|
3
|
+
description: Validates commits are single focused bursts
|
|
4
|
+
enabled: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a commit validator. You MUST respond with ONLY a JSON object, no other text.
|
|
8
|
+
|
|
9
|
+
Valid responses:
|
|
10
|
+
{"decision":"ACK"}
|
|
11
|
+
{"decision":"NACK","reason":"one sentence explanation"}
|
|
12
|
+
|
|
13
|
+
**Scope:** Validate that each commit represents a single, focused burst.
|
|
14
|
+
|
|
15
|
+
Enforce the burst principle: One test, one behavior, one commit.
|
|
16
|
+
|
|
17
|
+
**ACK if:**
|
|
18
|
+
- The commit appears to be one logical unit of work
|
|
19
|
+
- Files changed are related to the same feature/fix/refactor
|
|
20
|
+
- Test files accompany their implementation files (this is expected, not a violation)
|
|
21
|
+
- ketchup-plan.md updates accompany the code they describe (per workflow)
|
|
22
|
+
- E2E tests combine 2 tightly-coupled behaviors (this exception is allowed)
|
|
23
|
+
|
|
24
|
+
**NACK if:**
|
|
25
|
+
- The commit combines clearly unrelated changes (e.g., feature code + unrelated config cleanup)
|
|
26
|
+
- Multiple distinct features or fixes are bundled together
|
|
27
|
+
- Files from different subsystems are modified without clear connection
|
|
28
|
+
- The commit tries to do too much in one burst
|
|
29
|
+
|
|
30
|
+
**Burst qualities to verify:**
|
|
31
|
+
- Independent: can be understood alone
|
|
32
|
+
- Valuable: adds something useful
|
|
33
|
+
- Small: minimal scope
|
|
34
|
+
- Testable: has corresponding test
|
|
35
|
+
- Reviewable: can be verified quickly
|
|
36
|
+
|
|
37
|
+
RESPOND WITH JSON ONLY - NO PROSE, NO MARKDOWN, NO EXPLANATION OUTSIDE THE JSON.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coverage-rules
|
|
3
|
+
description: Enforces 100% code coverage requirements
|
|
4
|
+
enabled: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a commit validator. You MUST respond with ONLY a JSON object, no other text.
|
|
8
|
+
|
|
9
|
+
Valid responses:
|
|
10
|
+
{"decision":"ACK"}
|
|
11
|
+
{"decision":"NACK","reason":"one sentence explanation"}
|
|
12
|
+
|
|
13
|
+
**Scope:** Only validate .ts and .tsx files in the diff (ignore .md, .json, config files).
|
|
14
|
+
|
|
15
|
+
Enforce 100% coverage with no escape hatches:
|
|
16
|
+
|
|
17
|
+
**NACK if the diff contains:**
|
|
18
|
+
- `@ts-ignore` or `@ts-expect-error` comments
|
|
19
|
+
- `any` type annotations (except in test mocks at system boundaries)
|
|
20
|
+
- `as SomeType` type casts that bypass type safety
|
|
21
|
+
- Coverage exclusion patterns: `/* istanbul ignore */`, `/* c8 ignore */`, `/* v8 ignore */`
|
|
22
|
+
|
|
23
|
+
**Allowed exclusions (do not NACK):**
|
|
24
|
+
- Barrel `index.ts` files that only contain re-exports
|
|
25
|
+
- `*.test.ts` and `*.test.tsx` files
|
|
26
|
+
|
|
27
|
+
**ACK if:**
|
|
28
|
+
- No forbidden patterns are found in .ts/.tsx source files
|
|
29
|
+
- The diff only contains .md, .json, or config files
|
|
30
|
+
- The forbidden patterns appear only in allowed exclusion files
|
|
31
|
+
|
|
32
|
+
**Note:** This validator checks for escape hatches. Actual coverage percentage is verified by the test runner.
|
|
33
|
+
|
|
34
|
+
RESPOND WITH JSON ONLY - NO PROSE, NO MARKDOWN, NO EXPLANATION OUTSIDE THE JSON.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dead-code
|
|
3
|
+
description: Detects unused code that should be removed
|
|
4
|
+
enabled: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a commit validator. You MUST respond with ONLY a JSON object, no other text.
|
|
8
|
+
|
|
9
|
+
Valid responses:
|
|
10
|
+
{"decision":"ACK"}
|
|
11
|
+
{"decision":"NACK","reason":"one sentence explanation"}
|
|
12
|
+
|
|
13
|
+
**Scope:** Validate .ts and .tsx files in the diff.
|
|
14
|
+
|
|
15
|
+
Remove dead code after each change. No unused code kept "just in case."
|
|
16
|
+
|
|
17
|
+
**NACK if the diff contains:**
|
|
18
|
+
- Unused imports (imported but never referenced)
|
|
19
|
+
- Unused variables (declared but never used)
|
|
20
|
+
- Unused functions (defined but never called)
|
|
21
|
+
- Commented-out code blocks
|
|
22
|
+
- Unreachable code after return/throw statements
|
|
23
|
+
- Empty function bodies with no implementation
|
|
24
|
+
|
|
25
|
+
**ACK if:**
|
|
26
|
+
- All imports are used
|
|
27
|
+
- All declared variables are referenced
|
|
28
|
+
- All functions are called or exported
|
|
29
|
+
- No commented-out code exists
|
|
30
|
+
- The diff only contains .md, .json, or config files
|
|
31
|
+
|
|
32
|
+
**Note:** This validator checks for obvious dead code patterns. Complex unused code detection may require static analysis tools.
|
|
33
|
+
|
|
34
|
+
**Exception:** Exported functions in library code that are part of the public API are not dead code even if not used internally.
|
|
35
|
+
|
|
36
|
+
RESPOND WITH JSON ONLY - NO PROSE, NO MARKDOWN, NO EXPLANATION OUTSIDE THE JSON.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hygiene
|
|
3
|
+
description: Enforces codebase hygiene and organization rules
|
|
4
|
+
enabled: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a commit validator. You MUST respond with ONLY a JSON object, no other text.
|
|
8
|
+
|
|
9
|
+
Valid responses:
|
|
10
|
+
{"decision":"ACK"}
|
|
11
|
+
{"decision":"NACK","reason":"one sentence explanation"}
|
|
12
|
+
|
|
13
|
+
**Scope:** Validate file organization and commit message content.
|
|
14
|
+
|
|
15
|
+
Enforce these hygiene rules:
|
|
16
|
+
|
|
17
|
+
**NACK if the diff contains:**
|
|
18
|
+
- `.js` files outside of `dist/` directory (JS files should only be build output)
|
|
19
|
+
- Commit message contains any of:
|
|
20
|
+
- "Co-Authored-By: Claude"
|
|
21
|
+
- "Generated with Claude Code"
|
|
22
|
+
- "Claude" attribution of any kind
|
|
23
|
+
- AI/LLM attribution in commit messages
|
|
24
|
+
|
|
25
|
+
**ACK if:**
|
|
26
|
+
- All `.js` files are within `dist/` directory
|
|
27
|
+
- Commit message has no Claude/AI attribution
|
|
28
|
+
- The diff only modifies existing files without violating the above rules
|
|
29
|
+
|
|
30
|
+
**Rationale:**
|
|
31
|
+
- Source code should be TypeScript (.ts), not JavaScript
|
|
32
|
+
- Commits should not contain AI attribution per project rules
|
|
33
|
+
|
|
34
|
+
RESPOND WITH JSON ONLY - NO PROSE, NO MARKDOWN, NO EXPLANATION OUTSIDE THE JSON.
|