claudekit
Version:
CLI tools for Claude Code development workflow
723 lines (610 loc) • 21.3 kB
Markdown
# Task Breakdown: Migrate claudekit Setup to Embedded Hooks System
Generated: 2025-07-31
Source: specs/feat-migrate-to-embedded-hooks.md
## Overview
This task breakdown implements the migration from bash hook files to the embedded TypeScript hooks system (`claudekit-hooks` executable). The migration eliminates all bash hook files and updates the setup command to generate configurations using the new embedded hooks.
## Phase 1: Core Migration (MVP)
### Task 1.1: Update createProjectSettings to Generate Embedded Hook Commands
**Description**: Modify the settings generation function to use claudekit-hooks commands instead of bash script paths
**Size**: Medium
**Priority**: High
**Dependencies**: None
**Can run parallel with**: Task 1.2
**Technical Requirements**:
- Update `createProjectSettings` function in `cli/commands/setup.ts`
- Replace bash script paths with embedded hook commands
- Maintain existing hook ID to command mapping
- Preserve all matcher patterns and hook configurations
**Implementation Details**:
Change all hook command generation from:
```typescript
hooks: [{
type: 'command',
command: '.claude/hooks/typecheck.sh'
}]
```
To:
```typescript
hooks: [{
type: 'command',
command: 'claudekit-hooks run typecheck'
}]
```
**Hook ID Mapping Table**:
| Hook ID | Old Command | New Command |
|---------|-------------|-------------|
| typecheck | `.claude/hooks/typecheck.sh` | `claudekit-hooks run typecheck` |
| eslint | `.claude/hooks/eslint.sh` | `claudekit-hooks run eslint` |
| no-any | `.claude/hooks/no-any.sh` | `claudekit-hooks run no-any` |
| run-related-tests | `.claude/hooks/run-related-tests.sh` | `claudekit-hooks run run-related-tests` |
| auto-checkpoint | `.claude/hooks/auto-checkpoint.sh` | `claudekit-hooks run auto-checkpoint` |
| validate-todo-completion | `.claude/hooks/validate-todo-completion.sh` | `claudekit-hooks run validate-todo-completion` |
| project-validation | `.claude/hooks/project-validation.sh` | `claudekit-hooks run project-validation` |
**Example Generated Configuration**:
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "claudekit-hooks run typecheck"
},
{
"type": "command",
"command": "claudekit-hooks run no-any"
}
]
}
],
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "claudekit-hooks run auto-checkpoint"
}
]
}
]
}
}
```
**Acceptance Criteria**:
- [ ] All hook commands use `claudekit-hooks run <hook-name>` format
- [ ] Existing matcher patterns are preserved
- [ ] Hook groupings remain the same
- [ ] Generated settings.json structure is unchanged except for command values
- [ ] Tests verify correct command generation
### Task 1.2: Remove Hook File Copying Logic from Setup Command
**Description**: Delete all code that copies hook files during setup installation
**Size**: Small
**Priority**: High
**Dependencies**: None
**Can run parallel with**: Task 1.1
**Technical Requirements**:
- Remove hook file operations from `performInstallation()` in `cli/commands/setup.ts`
- Delete hook directory creation logic
- Remove any references to `.claude/hooks/` directory
**Code to Remove**:
```typescript
// Delete this entire block from performInstallation()
if (component.type === 'hook') {
// DELETE THIS ENTIRE BLOCK - hooks are handled by settings generation only
}
```
**Additional Removals**:
- Hook directory creation (e.g., `fs.ensureDir('.claude/hooks')`)
- Hook file copying operations
- Executable permission setting for hooks
- Any validation of hook file existence
**Acceptance Criteria**:
- [ ] No hook files are copied during setup
- [ ] No `.claude/hooks/` directory is created
- [ ] Setup completes successfully without hook file operations
- [ ] Integration tests verify no hook directories are created
### Task 1.3: Delete All Bash Hook Files
**Description**: Remove all bash script hook files from the repository
**Size**: Small
**Priority**: High
**Dependencies**: Task 1.1, Task 1.2 (to ensure no code references them)
**Can run parallel with**: Task 1.4
**Files to Delete**:
From `src/hooks/` directory:
- `auto-checkpoint.sh`
- `eslint.sh`
- `project-validation.sh`
- `run-related-tests.sh`
- `typecheck.sh`
- `validate-todo-completion.sh`
**Additional Cleanup**:
From `.claude/` directory:
- Remove any symlinks in `.claude/hooks/`
- Delete the `.claude/hooks/` directory itself
**Git Commands**:
```bash
git rm src/hooks/*.sh
git rm -rf .claude/hooks
```
**Acceptance Criteria**:
- [ ] All `.sh` files removed from `src/hooks/`
- [ ] `.claude/hooks/` directory removed
- [ ] No broken references in codebase
- [ ] Git history shows clean removal
### Task 1.4: Remove Legacy setup.sh Script
**Description**: Delete the bash-based setup script entirely
**Size**: Small
**Priority**: High
**Dependencies**: None
**Can run parallel with**: Task 1.3
**File to Delete**:
- `setup.sh` - entire file from project root
**Verification Steps**:
1. Ensure no other scripts or documentation reference `setup.sh`
2. Update any installation instructions that mention the script
3. Remove from package.json scripts if listed
**Git Command**:
```bash
git rm setup.sh
```
**Acceptance Criteria**:
- [ ] setup.sh file removed from repository
- [ ] No references to setup.sh remain in documentation
- [ ] Package.json doesn't reference the script
- [ ] README updated if it mentions setup.sh
### Task 1.5: Update Component Metadata for Hooks
**Description**: Modify hook component definitions to reflect embedded hooks system
**Size**: Medium
**Priority**: High
**Dependencies**: Task 1.1
**Can run parallel with**: None
**Technical Requirements**:
- Update hook component metadata in setup command
- Remove file path references
- Update descriptions to mention embedded hooks
- Ensure hook IDs remain consistent
**Implementation Areas**:
- Component discovery/registration
- Hook metadata definitions
- Component type handling
**Example Update**:
```typescript
// Before
{
id: 'typecheck',
name: 'TypeScript Type Checking',
type: 'hook',
path: '.claude/hooks/typecheck.sh',
description: 'Run TypeScript type checking on file changes'
}
// After
{
id: 'typecheck',
name: 'TypeScript Type Checking',
type: 'hook',
command: 'claudekit-hooks run typecheck',
description: 'Run TypeScript type checking on file changes (embedded hook)'
}
```
**Acceptance Criteria**:
- [ ] All hook components updated to embedded format
- [ ] No file path references remain
- [ ] Hook IDs unchanged for compatibility
- [ ] Component selection UI works correctly
### Task 1.6: Create Unit Tests for Embedded Hook Settings Generation
**Description**: Write comprehensive unit tests for the updated settings generation
**Size**: Medium
**Priority**: High
**Dependencies**: Task 1.1
**Can run parallel with**: Task 1.7
**Test Requirements**:
```typescript
// Purpose: Verify embedded hook commands are generated instead of bash paths
// This ensures the migration from bash hooks to embedded hooks is complete
describe('createProjectSettings with embedded hooks', () => {
it('should generate embedded hook commands in settings', () => {
const components = [
{ id: 'typecheck', type: 'hook' },
{ id: 'eslint', type: 'hook' }
];
const settings = createProjectSettings(components);
// Verify typecheck hook
const typecheckHook = settings.hooks.PostToolUse
.find(h => h.matcher.includes('**/*.ts'))
.hooks[0];
expect(typecheckHook.command).toBe('claudekit-hooks run typecheck');
// Verify no bash paths
expect(JSON.stringify(settings)).not.toContain('.sh');
expect(JSON.stringify(settings)).not.toContain('.claude/hooks/');
});
it('should handle all hook types correctly', () => {
// Test each hook ID maps to correct command
});
it('should preserve matcher patterns', () => {
// Verify matchers remain unchanged
});
});
```
**Test Cases**:
- Generate settings with single hook
- Generate settings with multiple hooks
- Verify all hook IDs map correctly
- Ensure no bash script references
- Test hook grouping logic
- Verify matcher patterns preserved
**Acceptance Criteria**:
- [ ] All test cases pass
- [ ] 100% coverage of settings generation for hooks
- [ ] Tests document the embedded hook migration
- [ ] No references to bash hooks in tests
### Task 1.7: Create Integration Tests for Setup Flow
**Description**: Write integration tests verifying the complete setup flow with embedded hooks
**Size**: Medium
**Priority**: High
**Dependencies**: Task 1.1, Task 1.2
**Can run parallel with**: Task 1.6
**Test Scenarios**:
```typescript
// Purpose: Verify complete setup flow uses embedded hooks without file operations
// This ensures no hook files are copied and settings use embedded commands
describe('Setup command with embedded hooks integration', () => {
it('should complete setup without creating hook directories', async () => {
// Run setup with hook selection
await runSetup(['--hooks', 'typecheck,eslint']);
// Verify no hook directory created
expect(fs.existsSync('.claude/hooks')).toBe(false);
// Verify settings contain embedded commands
const settings = JSON.parse(fs.readFileSync('.claude/settings.json'));
const hookCommands = extractHookCommands(settings);
expect(hookCommands).toContain('claudekit-hooks run typecheck');
expect(hookCommands).toContain('claudekit-hooks run eslint');
});
it('should handle all hook selection methods', async () => {
// Test group selection
// Test individual selection
// Test --all flag
});
});
```
**Test Coverage**:
- Full setup flow with hooks
- Verify no file operations
- Check generated settings
- Test various selection methods
- Verify no `.claude/hooks/` directory
- Ensure claudekit-hooks commands work
**Acceptance Criteria**:
- [ ] Integration tests pass
- [ ] No hook files or directories created
- [ ] Settings contain correct commands
- [ ] Setup completes successfully
## Phase 2: Cleanup and Documentation
### Task 2.1: Remove Hook File Discovery Logic
**Description**: Delete code that discovers hook files from the filesystem
**Size**: Medium
**Priority**: Medium
**Dependencies**: Task 1.3
**Can run parallel with**: Task 2.2
**Technical Requirements**:
- Remove hook discovery from `discoverComponents()` function
- Delete filesystem scanning for `.sh` files in hooks directory
- Update component discovery to use predefined hook list
**Code to Remove**:
```typescript
// Remove hook file discovery logic like:
const hookFiles = await fs.readdir('src/hooks');
const hooks = hookFiles
.filter(file => file.endsWith('.sh'))
.map(file => ({
id: path.basename(file, '.sh'),
type: 'hook',
path: `src/hooks/${file}`
}));
```
**Replacement Implementation**:
```typescript
// Predefined hook list
const AVAILABLE_HOOKS = [
{ id: 'typecheck', name: 'TypeScript Type Checking' },
{ id: 'eslint', name: 'ESLint Code Validation' },
{ id: 'prettier', name: 'Prettier Code Formatting' },
{ id: 'no-any', name: 'Forbid Any Types' },
{ id: 'run-related-tests', name: 'Run Related Tests' },
{ id: 'auto-checkpoint', name: 'Auto Checkpoint' },
{ id: 'validate-todo-completion', name: 'Validate Todo Completion' },
{ id: 'project-validation', name: 'Project Validation' }
];
```
**Acceptance Criteria**:
- [ ] No filesystem scanning for hooks
- [ ] Predefined hook list used instead
- [ ] All hooks still available in setup
- [ ] No broken references to discovery logic
### Task 2.2: Remove Legacy Hook-Related Utilities
**Description**: Delete any utility functions or modules specific to bash hooks
**Size**: Small
**Priority**: Medium
**Dependencies**: Phase 1 completion
**Can run parallel with**: Task 2.1
**Areas to Check**:
- Hook file validation utilities
- Hook path resolution functions
- Hook executable permission setters
- Bash hook specific helpers
**Example Removals**:
```typescript
// Remove functions like:
function getHookPath(hookId: string): string {
return path.join('.claude/hooks', `${hookId}.sh`);
}
function setHookExecutable(hookPath: string): void {
fs.chmodSync(hookPath, '755');
}
function validateHookFile(hookPath: string): boolean {
return fs.existsSync(hookPath) && hookPath.endsWith('.sh');
}
```
**Acceptance Criteria**:
- [ ] All bash hook utilities removed
- [ ] No unused imports remain
- [ ] Code compiles without errors
- [ ] Tests updated to remove hook utility tests
### Task 2.3: Update README.md Hooks Section
**Description**: Rewrite the hooks section to document embedded hooks system
**Size**: Small
**Priority**: Medium
**Dependencies**: Phase 1 completion
**Can run parallel with**: Task 2.4, 2.5
**Documentation Updates**:
```markdown
## Hooks System
Claudekit includes a dedicated hooks system for Claude Code integration.
### Installation
When you install claudekit globally, you get two binaries:
- `claudekit` - Main CLI for commands and project management
- `claudekit-hooks` - Dedicated hooks execution system
### Available Hooks
- `typecheck` - TypeScript type checking
- `no-any` - Forbid any types in TypeScript
- `eslint` - ESLint code validation
- `auto-checkpoint` - Git auto-checkpoint on stop
- `run-related-tests` - Run tests for changed files
- `project-validation` - Full project validation
- `validate-todo-completion` - Validate todo completions
### Claude Code Integration
Update your `.claude/settings.json` to use claudekit hooks:
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{"type": "command", "command": "claudekit-hooks run typecheck"}
]
}
]
}
}
```
```
**Key Changes**:
- Remove references to hook file copying
- Remove `.claude/hooks/` directory mentions
- Update command examples to embedded format
- Add troubleshooting for missing claudekit-hooks
**Acceptance Criteria**:
- [ ] README reflects embedded hooks only
- [ ] All examples use new command format
- [ ] No bash hook references remain
- [ ] Installation instructions updated
### Task 2.4: Update Hook Documentation Files
**Description**: Update all hook-specific documentation to reflect embedded system
**Size**: Medium
**Priority**: Medium
**Dependencies**: Phase 1 completion
**Can run parallel with**: Task 2.3, 2.5
**Files to Update**:
- `docs/hooks-documentation.md`
- `docs/hooks-reference.md`
- Any hook-specific guides
**Documentation Changes**:
- Change all command examples from `.claude/hooks/*.sh` to `claudekit-hooks run *`
- Remove sections about hook file permissions
- Remove hook file copying instructions
- Add troubleshooting for global binary issues
- Update configuration examples
**Example Update**:
```markdown
<!-- Before -->
Hook files are copied to `.claude/hooks/` in your project directory.
Make sure they have executable permissions: `chmod +x .claude/hooks/*.sh`
<!-- After -->
Hooks are provided by the `claudekit-hooks` executable, which must be globally installed.
No files are copied to your project - hooks run directly from the global installation.
```
**Acceptance Criteria**:
- [ ] All documentation uses embedded commands
- [ ] No references to hook files or copying
- [ ] Troubleshooting section for missing binary
- [ ] Configuration examples updated
### Task 2.5: Remove Bash Hook References from Codebase
**Description**: Find and remove all remaining references to bash hooks
**Size**: Medium
**Priority**: Medium
**Dependencies**: Phase 1 completion
**Can run parallel with**: Task 2.3, 2.4
**Search Patterns**:
```bash
# Find bash hook references
grep -r "\.sh" --include="*.ts" --include="*.js" --include="*.md"
grep -r "\.claude/hooks" --include="*.ts" --include="*.js" --include="*.md"
grep -r "bash.*hook" --include="*.ts" --include="*.js" --include="*.md"
```
**Common Locations**:
- Comments in code
- Error messages
- Test fixtures
- Example configurations
- Migration guides
**Replacement Examples**:
```typescript
// Before
throw new Error('Hook file not found: .claude/hooks/typecheck.sh');
// After
throw new Error('Hook not available: claudekit-hooks run typecheck');
```
**Acceptance Criteria**:
- [ ] No `.sh` references for hooks
- [ ] No `.claude/hooks` paths remain
- [ ] All error messages updated
- [ ] Comments reflect embedded system
### Task 2.6: Comprehensive Testing of Migration
**Description**: Run full test suite and manual testing to verify complete migration
**Size**: Large
**Priority**: High
**Dependencies**: Tasks 2.1-2.5
**Can run parallel with**: None
**Test Plan**:
1. **Unit Test Suite**
```bash
npm test -- --grep "hook"
```
2. **Integration Test Suite**
```bash
npm test -- --grep "setup"
```
3. **Manual Testing Checklist**:
- [ ] Fresh claudekit installation
- [ ] Run `claudekit setup` with various options
- [ ] Select different hook combinations
- [ ] Verify generated settings.json
- [ ] Test hooks in Claude Code
- [ ] Verify no `.claude/hooks/` directory
4. **Regression Testing**:
- [ ] Existing projects still work
- [ ] All hook functionality preserved
- [ ] No breaking changes in API
**Acceptance Criteria**:
- [ ] All automated tests pass
- [ ] Manual testing checklist complete
- [ ] No regressions identified
- [ ] Performance benchmarks acceptable
## Phase 3: Final Polish
### Task 3.1: Verify No Legacy Code Remains
**Description**: Final audit to ensure complete removal of bash hook system
**Size**: Small
**Priority**: Low
**Dependencies**: Phase 2 completion
**Can run parallel with**: None
**Verification Checklist**:
```bash
# Verify no bash hooks remain
find . -name "*.sh" -path "*/hooks/*" | wc -l # Should be 0
# Verify no hook file references
grep -r "\.claude/hooks" --include="*.ts" --include="*.js" | wc -l # Should be 0
# Verify no bash hook utilities
grep -r "setExecutablePermission.*hook" --include="*.ts" | wc -l # Should be 0
# Check for setup.sh references
grep -r "setup\.sh" --exclude-dir=".git" | wc -l # Should be 0
```
**Code Review Areas**:
- Setup command implementation
- Component discovery
- Settings generation
- Test files
- Documentation
**Acceptance Criteria**:
- [ ] All verification commands return 0
- [ ] Code review finds no legacy code
- [ ] No TODO comments about migration
- [ ] Clean git history
### Task 3.2: Performance Benchmarking
**Description**: Measure performance improvements from embedded hooks
**Size**: Medium
**Priority**: Low
**Dependencies**: Phase 2 completion
**Can run parallel with**: Task 3.3
**Benchmark Tests**:
```typescript
// Benchmark setup time
describe('Setup Performance', () => {
it('should complete setup faster without file operations', async () => {
const startTime = Date.now();
await runSetup(['--hooks', 'all']);
const duration = Date.now() - startTime;
expect(duration).toBeLessThan(1000); // Should be under 1 second
});
});
// Benchmark hook execution
describe('Hook Execution Performance', () => {
it('should execute embedded hooks faster than bash scripts', async () => {
// Measure claudekit-hooks execution time
const startTime = Date.now();
await exec('claudekit-hooks run typecheck');
const duration = Date.now() - startTime;
expect(duration).toBeLessThan(100); // Should be under 100ms
});
});
```
**Metrics to Capture**:
- Setup time with hooks
- Individual hook execution time
- Memory usage
- Startup overhead
**Acceptance Criteria**:
- [ ] Benchmarks show improvement
- [ ] No performance regressions
- [ ] Results documented
- [ ] Metrics added to documentation
### Task 3.3: Update Examples to Use Embedded Hooks
**Description**: Update all example configurations and scripts to use embedded hooks
**Size**: Small
**Priority**: Low
**Dependencies**: Phase 2 completion
**Can run parallel with**: Task 3.2
**Files to Update**:
- Example settings.json files
- Tutorial documentation
- Quick start guides
- Blog posts or articles
**Example Update**:
```json
// examples/settings.complete.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{"type": "command", "command": "claudekit-hooks run typecheck"},
{"type": "command", "command": "claudekit-hooks run no-any"}
]
}
]
}
}
```
**Acceptance Criteria**:
- [ ] All examples use embedded format
- [ ] Examples are tested and working
- [ ] No bash hook examples remain
- [ ] Documentation links updated
## Summary
**Total Tasks**: 17
**Phase 1 (MVP)**: 7 tasks
**Phase 2 (Cleanup)**: 6 tasks
**Phase 3 (Polish)**: 3 tasks
**Estimated Complexity**:
- Small: 6 tasks
- Medium: 10 tasks
- Large: 1 task
**Parallel Execution Opportunities**:
- Phase 1: Tasks 1.1 & 1.2 can run in parallel, Tasks 1.3 & 1.4 can run in parallel
- Phase 2: Tasks 2.1 & 2.2 in parallel, Tasks 2.3, 2.4, 2.5 in parallel
- Phase 3: Tasks 3.2 & 3.3 can run in parallel
**Critical Path**:
Task 1.1 → Task 1.5 → Task 1.6/1.7 → Task 2.6 → Task 3.1