UNPKG

claudekit

Version:

CLI tools for Claude Code development workflow

230 lines (172 loc) 8.34 kB
# Eliminate validation-lib.sh by Making Hooks Self-Contained **Status**: Completed **Authors**: Claude, 2025-07-16 **Type**: Refactoring ## Overview Refactor all validation hooks to be self-contained by inlining the functions from validation-lib.sh directly into each hook that uses them. This eliminates a common source of setup failures and makes hooks more robust and portable. ## Background/Problem Statement Currently, several hooks depend on sourcing `validation-lib.sh`, which causes multiple issues: ### Current Architecture Problems - **Missing dependency errors**: Users frequently forget to copy `validation-lib.sh` during setup - **Path resolution issues**: Hooks fail when they can't find the library file - **Setup complexity**: Additional file that must be managed and deployed - **Version mismatch risks**: Library and hooks can get out of sync - **Team collaboration friction**: Another file that must be committed and maintained ### Affected Hooks Based on codebase analysis, three hooks currently depend on validation-lib.sh: 1. `typecheck.sh` - TypeScript validation hook 2. `eslint.sh` - ESLint validation hook 3. `project-validation.sh` - Combined project validation hook ### User Impact From recent user feedback: - "Claude Code tells the file does not exist" errors when validation-lib.sh is missing - Setup script doesn't currently copy validation-lib.sh (critical bug) - Users must manually ensure this dependency exists in every project ## Goals -**Eliminate external dependencies**: Each hook should be completely self-contained -**Simplify setup**: Reduce files that need to be copied/managed -**Improve reliability**: Remove a common failure point -**Maintain functionality**: All current validation features must continue working -**Easier debugging**: All code in one place for each hook ## Non-Goals -**Creating new validation features**: Only refactoring existing functionality -**Changing hook behavior**: Validation logic remains the same -**Optimizing shared code**: Accept reasonable duplication for reliability -**Creating a build process**: Keep hooks as simple bash scripts ## Technical Dependencies No new dependencies. This refactoring only reorganizes existing bash code. ## Detailed Design ### Functions to Inline From validation-lib.sh, these functions need to be copied into hooks that use them: 1. **Core utility functions** (used by all hooks): - `find_project_root()` - 3 lines - `parse_json_field()` - 9 lines 2. **Detection functions** (used selectively): - `has_typescript()` - 3 lines (used by typecheck.sh, project-validation.sh) - `has_eslint()` - 3 lines (used by eslint.sh, project-validation.sh) - `has_tests()` - 3 lines (used by project-validation.sh) 3. **Validation functions** (used selectively): - `validate_typescript_file()` - 41 lines (used by typecheck.sh) - `validate_eslint_file()` - 14 lines (used by eslint.sh) - `validate_typescript_project()` - 14 lines (used by project-validation.sh) - `validate_eslint_project()` - 14 lines (used by project-validation.sh) - `validate_tests()` - 14 lines (used by project-validation.sh) - `format_validation_output()` - 9 lines (used by project-validation.sh) ### Refactoring Strategy 1. **typecheck.sh** needs: - `find_project_root()` - `parse_json_field()` - `has_typescript()` - `validate_typescript_file()` - Total: ~56 lines of functions to inline 2. **eslint.sh** needs: - `find_project_root()` - `parse_json_field()` - `has_eslint()` - `validate_eslint_file()` - Total: ~29 lines of functions to inline 3. **project-validation.sh** needs: - `find_project_root()` - `parse_json_field()` - `has_typescript()` - `has_eslint()` - `has_tests()` - `validate_typescript_project()` - `validate_eslint_project()` - `validate_tests()` - `format_validation_output()` - Total: ~76 lines of functions to inline ### Code Structure After Refactoring Each hook will have this structure: ```bash #!/usr/bin/env bash set -euo pipefail ################################################################################ # [Hook Name] - [Description] # # Self-contained validation hook with all dependencies included # ################################################################################ # === Inlined Helper Functions === find_project_root() { local start_dir="${1:-$(pwd)}" git -C "$start_dir" rev-parse --show-toplevel 2>/dev/null || pwd } parse_json_field() { # ... implementation ... } # === Inlined Validation Functions === [specific functions needed by this hook] # === Main Hook Logic === [existing hook logic unchanged] ``` ## User Experience For end users: - **No visible changes** - Hooks work exactly the same way - **Fewer setup failures** - No missing validation-lib.sh errors - **Simpler mental model** - Each hook is just one file For developers: - **Easier to understand** - All code in one place - **Easier to modify** - No need to check shared library - **Easier to test** - Can test each hook independently ## Testing Strategy ### Unit Tests - **Verify identical behavior**: Each refactored hook must produce same output as original - **Test all code paths**: Ensure inlined functions work correctly in context - **Error handling**: Verify error cases still handled properly ### Integration Tests - **Run test-validation-hooks.sh**: Existing test suite must pass without modification - **Test missing dependencies**: Verify hooks work without validation-lib.sh present - **Cross-project testing**: Test hooks in different project types ### Manual Testing Test each hook in real projects: 1. TypeScript project with type errors 2. JavaScript project with ESLint violations 3. Project with no TypeScript/ESLint configuration 4. Mixed project with both TypeScript and JavaScript ## Performance Considerations - **Negligible impact**: ~50-75 lines of bash code duplication per hook - **No runtime overhead**: Same functions, just in different locations - **Slightly larger hook files**: From ~50 lines to ~100-125 lines each - **Acceptable tradeoff**: Reliability > minimal code duplication ## Security Considerations - **No new security implications**: Same code, different organization - **Reduced attack surface**: Fewer files to potentially tamper with - **Same permission model**: Hooks still need executable permissions ## Documentation ### Updates Required 1. **setup.sh**: Remove any references to validation-lib.sh 2. **hooks-documentation.md**: Update to reflect self-contained hooks 3. **README.md**: Simplify setup instructions (fewer files) 4. **AGENT.md**: Update setup process documentation ### Developer Notes Add comment in each hook explaining the self-contained design: ```bash # This hook is self-contained and includes all necessary validation functions. # No external dependencies required - just copy this file and it works. ``` ## Implementation Phases ### Phase 1: Refactor Individual Hooks 1. Create new version of typecheck.sh with inlined functions 2. Create new version of eslint.sh with inlined functions 3. Create new version of project-validation.sh with inlined functions 4. Test each hook independently ### Phase 2: Update Test Suite 1. Update test-validation-hooks.sh to not source validation-lib.sh 2. Verify all tests pass with new self-contained hooks 3. Add tests for missing validation-lib.sh scenario ### Phase 3: Cleanup and Migration 1. Update setup.sh to not copy validation-lib.sh 2. Remove validation-lib.sh from the repository 3. Update all documentation 4. Create migration notes for existing users ## Open Questions 1. **Should we use a build process instead?** - Decision: No, keep it simple. Direct duplication is more maintainable than adding build complexity. 2. **What about future shared functions?** - Decision: Evaluate case-by-case. Only share if complexity warrants it. 3. **Should we keep validation-lib.sh for backwards compatibility?** - Decision: No, clean break. The hooks will work without it. ## References - Current validation-lib.sh implementation - User feedback about setup issues - Existing hook architecture - Test suite in tests/test-validation-hooks.sh