claude-ketchup 0.7.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/README.md +172 -0
- package/bin/cli.ts +6 -0
- package/bin/postinstall.ts +8 -0
- package/bin/preuninstall.ts +8 -0
- package/commands/ketchup.md +107 -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/bin/postinstall.d.ts +3 -0
- package/dist/bin/postinstall.d.ts.map +1 -0
- package/dist/bin/postinstall.js +9 -0
- package/dist/bin/postinstall.js.map +1 -0
- package/dist/bin/preuninstall.d.ts +3 -0
- package/dist/bin/preuninstall.d.ts.map +1 -0
- package/dist/bin/preuninstall.js +9 -0
- package/dist/bin/preuninstall.js.map +1 -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 +62 -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 +68 -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 +71 -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 +71 -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 +26 -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 +20 -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 +8 -0
- package/dist/src/cli/install.d.ts.map +1 -0
- package/dist/src/cli/install.js +8 -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 +106 -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 +96 -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 +83 -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 +35 -0
- package/dist/src/commit-validator.d.ts.map +1 -0
- package/dist/src/commit-validator.js +147 -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 +443 -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 +89 -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 +91 -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 +184 -0
- package/dist/src/hook-logger.test.js.map +1 -0
- package/dist/src/hook-state.d.ts +43 -0
- package/dist/src/hook-state.d.ts.map +1 -0
- package/dist/src/hook-state.js +124 -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 +190 -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 +62 -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 +168 -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 +15 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +39 -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/npm-install.test.d.ts +2 -0
- package/dist/src/npm-install.test.d.ts.map +1 -0
- package/dist/src/npm-install.test.js +70 -0
- package/dist/src/npm-install.test.js.map +1 -0
- package/dist/src/path-resolver.d.ts +11 -0
- package/dist/src/path-resolver.d.ts.map +1 -0
- package/dist/src/path-resolver.js +65 -0
- package/dist/src/path-resolver.js.map +1 -0
- package/dist/src/postinstall.d.ts +8 -0
- package/dist/src/postinstall.d.ts.map +1 -0
- package/dist/src/postinstall.js +112 -0
- package/dist/src/postinstall.js.map +1 -0
- package/dist/src/postinstall.test.d.ts +2 -0
- package/dist/src/postinstall.test.d.ts.map +1 -0
- package/dist/src/postinstall.test.js +203 -0
- package/dist/src/postinstall.test.js.map +1 -0
- package/dist/src/preuninstall.d.ts +3 -0
- package/dist/src/preuninstall.d.ts.map +1 -0
- package/dist/src/preuninstall.js +85 -0
- package/dist/src/preuninstall.js.map +1 -0
- package/dist/src/preuninstall.test.d.ts +2 -0
- package/dist/src/preuninstall.test.d.ts.map +1 -0
- package/dist/src/preuninstall.test.js +114 -0
- package/dist/src/preuninstall.test.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 +90 -0
- package/reminders/ketchup.md +24 -0
- package/reminders/reminder-documentation.md +30 -0
- package/reminders/reminder-emergent-design.md +41 -0
- package/reminders/reminder-extreme-ownership.md +27 -0
- package/reminders/reminder-ide-diagnostics.md +25 -0
- package/reminders/reminder-ketchup.md +145 -0
- package/reminders/reminder-parallelization.md +27 -0
- package/reminders/reminder-rethink-after-revert.md +25 -0
- package/reminders/reminder-sub-agent-rules.md +27 -0
- package/reminders/reminder-test-title-matches-spec.md +37 -0
- package/scripts/auto-continue.ts +34 -0
- package/scripts/generate-changeset.ts +405 -0
- package/scripts/pre-tool-use.ts +35 -0
- package/scripts/session-start.ts +38 -0
- package/scripts/tail-logs.sh +17 -0
- package/scripts/test-hooks.sh +910 -0
- package/scripts/user-prompt-submit.ts +38 -0
- package/templates/settings.json +48 -0
- package/validators/appeal-system.md +55 -0
- package/validators/backwards-compat.md +33 -0
- package/validators/burst-atomicity.md +37 -0
- package/validators/coverage-rules.md +34 -0
- package/validators/dead-code.md +36 -0
- package/validators/hygiene.md +34 -0
- package/validators/infra-commit-format.md +37 -0
- package/validators/ketchup-plan-format.md +42 -0
- package/validators/new-code-requires-tests.md +36 -0
- package/validators/no-comments.md +35 -0
- package/validators/no-dangerous-git.md +35 -0
- package/validators/tcr-workflow.md +31 -0
- package/validators/testing-no-state-peeking.md +37 -0
- package/validators/testing-structure.md +37 -0
- package/validators/testing-stubs-over-mocks.md +42 -0
- package/validators/testing-weak-assertions.md +36 -0
- package/validators/type-organization.md +30 -0
|
@@ -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,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
when:
|
|
3
|
+
hook: SessionStart
|
|
4
|
+
priority: 100
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Ketchup 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,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,34 @@
|
|
|
1
|
+
#!/usr/bin/env npx tsx
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
|
|
5
|
+
import { writeHookLog } from '../src/hook-logger.js';
|
|
6
|
+
import { handleStop, type StopHookInput } from '../src/hooks/auto-continue.js';
|
|
7
|
+
|
|
8
|
+
const projectDir = process.cwd();
|
|
9
|
+
const claudeDir = path.resolve(projectDir, '.claude');
|
|
10
|
+
const stdin = fs.readFileSync(0, 'utf8').trim();
|
|
11
|
+
|
|
12
|
+
if (!stdin) {
|
|
13
|
+
process.exit(0);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const input: StopHookInput = JSON.parse(stdin);
|
|
17
|
+
const startTime = Date.now();
|
|
18
|
+
const result = handleStop(projectDir, input);
|
|
19
|
+
|
|
20
|
+
const output = result.decision === 'block' ? { stopReason: result.reason, forceResult: { behaviour: 'block' } } : null;
|
|
21
|
+
|
|
22
|
+
writeHookLog(claudeDir, {
|
|
23
|
+
hookName: 'auto-continue',
|
|
24
|
+
timestamp: new Date().toISOString(),
|
|
25
|
+
input,
|
|
26
|
+
output: output ?? { decision: result.decision, reason: result.reason },
|
|
27
|
+
durationMs: Date.now() - startTime,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
if (output) {
|
|
31
|
+
console.log(JSON.stringify(output));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
process.exit(0);
|