configure-precommit 1.0.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/LICENSE +21 -0
- package/README.md +219 -0
- package/bin/configure-precommit +196 -0
- package/lib/builder.sh +311 -0
- package/lib/logging.sh +201 -0
- package/lib/sensor.sh +222 -0
- package/lib/verifier.sh +275 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aviv Kaplan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# configure-precommit
|
|
2
|
+
|
|
3
|
+
Automatically configure pre-commit hooks for any repository using AI-powered analysis.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This tool scans your repository, analyzes its structure and tech stack, and generates an optimal `.pre-commit-config.yaml` tailored to your project.
|
|
8
|
+
|
|
9
|
+
**Supported stacks:**
|
|
10
|
+
- Python (ruff, mypy, bandit)
|
|
11
|
+
- JavaScript/TypeScript (eslint, prettier)
|
|
12
|
+
- Go (golangci-lint, go-fmt)
|
|
13
|
+
- Java (pretty-format-java)
|
|
14
|
+
- Terraform (terraform_fmt, tflint, checkov)
|
|
15
|
+
- Docker (hadolint)
|
|
16
|
+
- Shell (shellcheck)
|
|
17
|
+
- Plus security scanning (gitleaks) and general hygiene hooks
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Using npx (no install required)
|
|
23
|
+
npx configure-precommit
|
|
24
|
+
|
|
25
|
+
# Or install globally
|
|
26
|
+
npm install -g configure-precommit
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# 1. Set your API key
|
|
33
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
34
|
+
# OR
|
|
35
|
+
export OPENAI_API_KEY="sk-..."
|
|
36
|
+
|
|
37
|
+
# 2. Run in your repository
|
|
38
|
+
cd /path/to/your/repo
|
|
39
|
+
configure-precommit
|
|
40
|
+
|
|
41
|
+
# Or specify a path
|
|
42
|
+
configure-precommit /path/to/your/repo
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Requirements
|
|
46
|
+
|
|
47
|
+
- **macOS or Linux** (Windows via WSL)
|
|
48
|
+
- **Node.js >= 14** (for npx/npm)
|
|
49
|
+
- **Git repository** (initialized with `git init`)
|
|
50
|
+
- **API key** - Anthropic (preferred) or OpenAI
|
|
51
|
+
- **System tools:** git, jq, curl, python3
|
|
52
|
+
|
|
53
|
+
The script automatically installs `pre-commit` if not present.
|
|
54
|
+
|
|
55
|
+
## How It Works
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
59
|
+
│ Phase 1: SENSOR │
|
|
60
|
+
│ └── Scan repo structure, detect languages/frameworks │
|
|
61
|
+
│ │
|
|
62
|
+
│ Phase 2: AUDITOR (LLM) │
|
|
63
|
+
│ └── AI analyzes repo, generates optimal pre-commit config │
|
|
64
|
+
│ │
|
|
65
|
+
│ Phase 3: BUILDER │
|
|
66
|
+
│ ├── Write .pre-commit-config.yaml │
|
|
67
|
+
│ ├── Run pre-commit autoupdate (get latest versions) │
|
|
68
|
+
│ └── Install git hooks │
|
|
69
|
+
│ │
|
|
70
|
+
│ Phase 4: VERIFICATION & SELF-HEALING │
|
|
71
|
+
│ ├── Run pre-commit on all files │
|
|
72
|
+
│ └── If config errors → AI debugger fixes → retry (max 3x) │
|
|
73
|
+
│ │
|
|
74
|
+
│ Phase 5: SUMMARY │
|
|
75
|
+
│ └── Report installed hooks and any code issues found │
|
|
76
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## CLI Options
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
configure-precommit [OPTIONS] [REPO_PATH]
|
|
83
|
+
|
|
84
|
+
Options:
|
|
85
|
+
-h, --help Show help message
|
|
86
|
+
-v, --version Show version
|
|
87
|
+
--dry-run Generate config without installing hooks
|
|
88
|
+
--skip-autoupdate Skip running pre-commit autoupdate
|
|
89
|
+
--debug Enable debug output
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Supported Hooks
|
|
93
|
+
|
|
94
|
+
| Category | Tools | Trigger |
|
|
95
|
+
|----------|-------|---------|
|
|
96
|
+
| **Python** | ruff, ruff-format, mypy, bandit | `.py` files |
|
|
97
|
+
| **JavaScript/TypeScript** | eslint, prettier | `.js`, `.ts`, `.jsx`, `.tsx` |
|
|
98
|
+
| **Go** | golangci-lint, go-fmt, go-imports | `.go` files |
|
|
99
|
+
| **Java** | pretty-format-java | `.java` files |
|
|
100
|
+
| **Shell** | shellcheck | `.sh`, `.bash` files |
|
|
101
|
+
| **Terraform** | terraform_fmt, tflint, checkov | `.tf` files |
|
|
102
|
+
| **Docker** | hadolint | `Dockerfile` |
|
|
103
|
+
| **YAML** | yamllint, check-yaml | `.yaml`, `.yml` |
|
|
104
|
+
| **JSON** | check-json | `.json` |
|
|
105
|
+
| **Security** | gitleaks, detect-private-key | All files |
|
|
106
|
+
| **General** | trailing-whitespace, end-of-file-fixer, check-merge-conflict, no-commit-to-branch | All files |
|
|
107
|
+
|
|
108
|
+
## Environment Variables
|
|
109
|
+
|
|
110
|
+
| Variable | Description |
|
|
111
|
+
|----------|-------------|
|
|
112
|
+
| `ANTHROPIC_API_KEY` | Anthropic API key (preferred) |
|
|
113
|
+
| `OPENAI_API_KEY` | OpenAI API key (fallback) |
|
|
114
|
+
| `PRECOMMIT_MAX_RETRIES` | Max self-heal attempts (default: 3) |
|
|
115
|
+
| `PRECOMMIT_DRY_RUN` | Generate config without installing |
|
|
116
|
+
| `PRECOMMIT_SKIP_AUTOUPDATE` | Skip version auto-update |
|
|
117
|
+
| `DEBUG` | Enable debug output |
|
|
118
|
+
|
|
119
|
+
## Logging
|
|
120
|
+
|
|
121
|
+
All operations are logged to `/tmp/precommit-setup/`:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# View recent logs
|
|
125
|
+
ls -lt /tmp/precommit-setup/*.log | head -5
|
|
126
|
+
|
|
127
|
+
# Tail a running log
|
|
128
|
+
tail -f /tmp/precommit-setup/myrepo_*.log
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Example Output
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
╔═══════════════════════════════════════════════════════════════╗
|
|
135
|
+
║ AGENTIC PRE-COMMIT SETUP ║
|
|
136
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
137
|
+
|
|
138
|
+
━━━━━━ PHASE 1: CONTEXTUAL SENSOR ━━━━━━
|
|
139
|
+
[INFO] Scanning repository structure...
|
|
140
|
+
[INFO] Found 47 files and 3 manifest files
|
|
141
|
+
|
|
142
|
+
━━━━━━ PHASE 2: AUDITOR (LLM Analysis) ━━━━━━
|
|
143
|
+
[INFO] Analyzing repository and generating configuration...
|
|
144
|
+
[INFO] Configuration generated successfully
|
|
145
|
+
|
|
146
|
+
━━━━━━ PHASE 3: BUILDER ━━━━━━
|
|
147
|
+
[INFO] Wrote configuration to .pre-commit-config.yaml
|
|
148
|
+
[INFO] Updating hook versions to latest...
|
|
149
|
+
[INFO] Git hooks installed successfully
|
|
150
|
+
|
|
151
|
+
━━━━━━ PHASE 4: VERIFICATION ━━━━━━
|
|
152
|
+
[INFO] All hooks passed successfully!
|
|
153
|
+
|
|
154
|
+
━━━━━━ PHASE 5: SUMMARY ━━━━━━
|
|
155
|
+
|
|
156
|
+
INSTALLED HOOKS:
|
|
157
|
+
- gitleaks
|
|
158
|
+
- ruff
|
|
159
|
+
- ruff-format
|
|
160
|
+
- shellcheck
|
|
161
|
+
- check-yaml
|
|
162
|
+
...
|
|
163
|
+
|
|
164
|
+
[INFO] Setup complete!
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Troubleshooting
|
|
168
|
+
|
|
169
|
+
### "Not a git repository"
|
|
170
|
+
Initialize git first: `git init`
|
|
171
|
+
|
|
172
|
+
### ".pre-commit-config.yaml already exists"
|
|
173
|
+
Remove it first: `rm .pre-commit-config.yaml`
|
|
174
|
+
|
|
175
|
+
### "No API key found"
|
|
176
|
+
Set one of:
|
|
177
|
+
```bash
|
|
178
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
179
|
+
export OPENAI_API_KEY="sk-..."
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Hooks fail due to missing tools
|
|
183
|
+
The debugger will automatically move those hooks to `stages: [manual]`. Install the tools later and run manually with `pre-commit run <hook-id> --all-files`.
|
|
184
|
+
|
|
185
|
+
## File Structure
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
configure-precommit/
|
|
189
|
+
├── package.json # npm package config
|
|
190
|
+
├── bin/
|
|
191
|
+
│ └── configure-precommit # CLI entry point
|
|
192
|
+
├── setup-precommit.sh # Main orchestration script
|
|
193
|
+
├── lib/
|
|
194
|
+
│ ├── logging.sh # Logging utilities
|
|
195
|
+
│ ├── sensor.sh # Repository scanning
|
|
196
|
+
│ ├── builder.sh # Pre-commit installation
|
|
197
|
+
│ └── verifier.sh # Verification loop
|
|
198
|
+
├── tests/
|
|
199
|
+
│ └── run_tests.sh # Test suite
|
|
200
|
+
└── README.md
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Development
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# Clone the repo
|
|
207
|
+
git clone https://github.com/avivkaplan/configure-precommit.git
|
|
208
|
+
cd configure-precommit
|
|
209
|
+
|
|
210
|
+
# Run tests (requires API key)
|
|
211
|
+
./tests/run_tests.sh
|
|
212
|
+
|
|
213
|
+
# Lint shell scripts
|
|
214
|
+
shellcheck lib/*.sh bin/configure-precommit setup-precommit.sh
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
MIT
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# configure-precommit - Agentic pre-commit setup
|
|
4
|
+
# Automatically configures pre-commit hooks for any repository using AI
|
|
5
|
+
#
|
|
6
|
+
# Usage: configure-precommit [options] [repo-path]
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
# Colors
|
|
12
|
+
RED='\033[0;31m'
|
|
13
|
+
GREEN='\033[0;32m'
|
|
14
|
+
YELLOW='\033[0;33m'
|
|
15
|
+
CYAN='\033[0;36m'
|
|
16
|
+
NC='\033[0m'
|
|
17
|
+
|
|
18
|
+
# Get the directory where this script is located
|
|
19
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
20
|
+
PACKAGE_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
21
|
+
|
|
22
|
+
# Version from package.json
|
|
23
|
+
VERSION=$(grep '"version"' "$PACKAGE_ROOT/package.json" 2>/dev/null | sed 's/.*"version": "\([^"]*\)".*/\1/' || echo "unknown")
|
|
24
|
+
|
|
25
|
+
#######################################
|
|
26
|
+
# Print usage
|
|
27
|
+
#######################################
|
|
28
|
+
usage() {
|
|
29
|
+
cat << EOF
|
|
30
|
+
${CYAN}configure-precommit${NC} v${VERSION}
|
|
31
|
+
|
|
32
|
+
Agentic pre-commit setup - automatically configures pre-commit hooks
|
|
33
|
+
for any repository using AI analysis.
|
|
34
|
+
|
|
35
|
+
${CYAN}USAGE:${NC}
|
|
36
|
+
configure-precommit [OPTIONS] [REPO_PATH]
|
|
37
|
+
|
|
38
|
+
${CYAN}ARGUMENTS:${NC}
|
|
39
|
+
REPO_PATH Path to the git repository (default: current directory)
|
|
40
|
+
|
|
41
|
+
${CYAN}OPTIONS:${NC}
|
|
42
|
+
-h, --help Show this help message
|
|
43
|
+
-v, --version Show version
|
|
44
|
+
--dry-run Generate config without installing hooks
|
|
45
|
+
--skip-autoupdate Skip running pre-commit autoupdate
|
|
46
|
+
--debug Enable debug output
|
|
47
|
+
|
|
48
|
+
${CYAN}ENVIRONMENT VARIABLES:${NC}
|
|
49
|
+
ANTHROPIC_API_KEY Anthropic API key (preferred)
|
|
50
|
+
OPENAI_API_KEY OpenAI API key (fallback)
|
|
51
|
+
|
|
52
|
+
${CYAN}EXAMPLES:${NC}
|
|
53
|
+
configure-precommit # Setup in current directory
|
|
54
|
+
configure-precommit /path/to/repo # Setup in specific repo
|
|
55
|
+
configure-precommit --dry-run # Preview without installing
|
|
56
|
+
|
|
57
|
+
${CYAN}REQUIREMENTS:${NC}
|
|
58
|
+
- git, jq, curl (for core functionality)
|
|
59
|
+
- python3 with PyYAML (for YAML validation)
|
|
60
|
+
- pre-commit (will be installed if missing)
|
|
61
|
+
|
|
62
|
+
EOF
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
#######################################
|
|
66
|
+
# Print version
|
|
67
|
+
#######################################
|
|
68
|
+
print_version() {
|
|
69
|
+
echo "configure-precommit v${VERSION}"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
#######################################
|
|
73
|
+
# Check single dependency
|
|
74
|
+
#######################################
|
|
75
|
+
check_dep() {
|
|
76
|
+
local cmd="$1"
|
|
77
|
+
local install_hint="$2"
|
|
78
|
+
|
|
79
|
+
if ! command -v "$cmd" &>/dev/null; then
|
|
80
|
+
echo -e "${RED}[ERROR]${NC} Missing dependency: ${YELLOW}$cmd${NC}"
|
|
81
|
+
echo -e " Install with: ${CYAN}$install_hint${NC}"
|
|
82
|
+
return 1
|
|
83
|
+
fi
|
|
84
|
+
return 0
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
#######################################
|
|
88
|
+
# Check all dependencies
|
|
89
|
+
#######################################
|
|
90
|
+
check_dependencies() {
|
|
91
|
+
local missing=0
|
|
92
|
+
|
|
93
|
+
echo -e "${CYAN}Checking dependencies...${NC}"
|
|
94
|
+
|
|
95
|
+
check_dep "git" "brew install git (macOS) or apt install git (Linux)" || ((missing++))
|
|
96
|
+
check_dep "jq" "brew install jq (macOS) or apt install jq (Linux)" || ((missing++))
|
|
97
|
+
check_dep "curl" "brew install curl (macOS) or apt install curl (Linux)" || ((missing++))
|
|
98
|
+
check_dep "python3" "brew install python3 (macOS) or apt install python3 (Linux)" || ((missing++))
|
|
99
|
+
|
|
100
|
+
# Check for PyYAML
|
|
101
|
+
if command -v python3 &>/dev/null; then
|
|
102
|
+
if ! python3 -c "import yaml" 2>/dev/null; then
|
|
103
|
+
echo -e "${RED}[ERROR]${NC} Missing Python package: ${YELLOW}PyYAML${NC}"
|
|
104
|
+
echo -e " Install with: ${CYAN}pip3 install pyyaml${NC}"
|
|
105
|
+
((missing++))
|
|
106
|
+
fi
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
if [[ $missing -gt 0 ]]; then
|
|
110
|
+
echo ""
|
|
111
|
+
echo -e "${RED}Please install missing dependencies and try again.${NC}"
|
|
112
|
+
exit 1
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
echo -e "${GREEN}All dependencies satisfied.${NC}"
|
|
116
|
+
echo ""
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
#######################################
|
|
120
|
+
# Check for API key
|
|
121
|
+
#######################################
|
|
122
|
+
check_api_key() {
|
|
123
|
+
if [[ -z "${ANTHROPIC_API_KEY:-}" ]] && [[ -z "${OPENAI_API_KEY:-}" ]]; then
|
|
124
|
+
echo -e "${RED}[ERROR]${NC} No API key found."
|
|
125
|
+
echo ""
|
|
126
|
+
echo "Please set one of the following environment variables:"
|
|
127
|
+
echo -e " ${CYAN}export ANTHROPIC_API_KEY=your-key-here${NC} (preferred)"
|
|
128
|
+
echo -e " ${CYAN}export OPENAI_API_KEY=your-key-here${NC} (fallback)"
|
|
129
|
+
echo ""
|
|
130
|
+
echo "You can get an API key from:"
|
|
131
|
+
echo " - Anthropic: https://console.anthropic.com/"
|
|
132
|
+
echo " - OpenAI: https://platform.openai.com/"
|
|
133
|
+
exit 1
|
|
134
|
+
fi
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
#######################################
|
|
138
|
+
# Main
|
|
139
|
+
#######################################
|
|
140
|
+
main() {
|
|
141
|
+
local repo_path="."
|
|
142
|
+
local dry_run=""
|
|
143
|
+
local skip_autoupdate=""
|
|
144
|
+
local debug=""
|
|
145
|
+
|
|
146
|
+
# Parse arguments
|
|
147
|
+
while [[ $# -gt 0 ]]; do
|
|
148
|
+
case "$1" in
|
|
149
|
+
-h|--help)
|
|
150
|
+
usage
|
|
151
|
+
exit 0
|
|
152
|
+
;;
|
|
153
|
+
-v|--version)
|
|
154
|
+
print_version
|
|
155
|
+
exit 0
|
|
156
|
+
;;
|
|
157
|
+
--dry-run)
|
|
158
|
+
dry_run="true"
|
|
159
|
+
shift
|
|
160
|
+
;;
|
|
161
|
+
--skip-autoupdate)
|
|
162
|
+
skip_autoupdate="true"
|
|
163
|
+
shift
|
|
164
|
+
;;
|
|
165
|
+
--debug)
|
|
166
|
+
debug="true"
|
|
167
|
+
shift
|
|
168
|
+
;;
|
|
169
|
+
-*)
|
|
170
|
+
echo -e "${RED}Unknown option: $1${NC}"
|
|
171
|
+
echo "Use --help for usage information."
|
|
172
|
+
exit 1
|
|
173
|
+
;;
|
|
174
|
+
*)
|
|
175
|
+
repo_path="$1"
|
|
176
|
+
shift
|
|
177
|
+
;;
|
|
178
|
+
esac
|
|
179
|
+
done
|
|
180
|
+
|
|
181
|
+
# Check dependencies first
|
|
182
|
+
check_dependencies
|
|
183
|
+
|
|
184
|
+
# Check for API key
|
|
185
|
+
check_api_key
|
|
186
|
+
|
|
187
|
+
# Set environment variables for the main script
|
|
188
|
+
[[ -n "$dry_run" ]] && export PRECOMMIT_DRY_RUN="true"
|
|
189
|
+
[[ -n "$skip_autoupdate" ]] && export PRECOMMIT_SKIP_AUTOUPDATE="true"
|
|
190
|
+
[[ -n "$debug" ]] && export DEBUG="true"
|
|
191
|
+
|
|
192
|
+
# Run the main setup script
|
|
193
|
+
exec "$PACKAGE_ROOT/setup-precommit.sh" "$repo_path"
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
main "$@"
|