claude-git-hooks 2.17.2 → 2.18.1
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/CHANGELOG.md +27 -0
- package/CLAUDE.md +821 -0
- package/README.md +12 -4
- package/bin/claude-hooks +2 -0
- package/lib/commands/bump-version.js +11 -4
- package/lib/commands/generate-changelog.js +8 -2
- package/lib/commands/help.js +380 -5
- package/lib/commands/helpers.js +2 -2
- package/lib/commands/hooks.js +7 -7
- package/lib/utils/changelog-generator.js +108 -6
- package/lib/utils/file-utils.js +41 -3
- package/lib/utils/github-api.js +160 -0
- package/lib/utils/version-manager.js +26 -56
- package/package.json +69 -68
- package/templates/HELP_COMPOSE_ISSUE.md +12 -0
- package/templates/HELP_QUERY.md +23 -0
- package/templates/HELP_REPORT_ISSUE.md +17 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,821 @@
|
|
|
1
|
+
# Repository Context
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`claude-git-hooks` is an intelligent Git hooks system that integrates Claude CLI to automate code analysis, commit message generation, and PR creation. It functions as a pre-commit code quality tool (for pre-commit code quality checks) that blocks commits with critical issues and assists throughout the development workflow.
|
|
6
|
+
|
|
7
|
+
**Main use cases:**
|
|
8
|
+
|
|
9
|
+
1. **Pre-commit analysis**: Detects security issues, bugs, and code smells before each commit (blocks on CRITICAL/BLOCKER only)
|
|
10
|
+
2. **Interactive analysis**: `claude-hooks analyze` - review all issues (INFO to BLOCKER) interactively before committing
|
|
11
|
+
3. **Automatic messages**: Write `git commit -m "auto"` and Claude generates the message in Conventional Commits format with task-id extracted from branch
|
|
12
|
+
4. **PR analysis**: `claude-hooks analyze-diff [branch]` generates title, description, and test plan for PRs
|
|
13
|
+
5. **PR creation**: `claude-hooks create-pr [branch]` creates the PR on GitHub with automatic metadata (reviewers from CODEOWNERS, labels by preset)
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
### Technology Stack
|
|
18
|
+
|
|
19
|
+
- **Runtime**: Node.js >=16.9.0 (compatible up to 24+)
|
|
20
|
+
- **Module type**: ES6 modules (`"type": "module"` in package.json)
|
|
21
|
+
- **Main dependencies**:
|
|
22
|
+
- `@octokit/rest`: GitHub client for PR creation (v2.5.0+)
|
|
23
|
+
- **Dev dependencies**: Jest, ESLint, Prettier
|
|
24
|
+
- **Distribution**: NPM global package (`npm install -g claude-git-hooks`)
|
|
25
|
+
|
|
26
|
+
### Design Philosophy
|
|
27
|
+
|
|
28
|
+
**Modular, decoupled, reusable code.** Each component has a single responsibility:
|
|
29
|
+
|
|
30
|
+
- **bin/claude-hooks**: Thin CLI router - only argument parsing and command dispatch
|
|
31
|
+
- **lib/commands/**: Command modules - one file per CLI command, self-contained logic
|
|
32
|
+
- **lib/hooks/**: Git hook logic - Node.js implementations invoked by bash wrappers
|
|
33
|
+
- **lib/utils/**: Reusable utilities - shared across commands, no CLI dependencies
|
|
34
|
+
- **templates/**: Static assets - copied during installation, user-customizable
|
|
35
|
+
|
|
36
|
+
This separation enables:
|
|
37
|
+
|
|
38
|
+
- **Testability**: Each module can be unit tested independently
|
|
39
|
+
- **Maintainability**: Changes to one command don't risk breaking others
|
|
40
|
+
- **Discoverability**: Find code by filename matching command name
|
|
41
|
+
- **Extensibility**: Add new commands by creating new module files
|
|
42
|
+
|
|
43
|
+
### Directory Structure
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
claude-git-hooks/
|
|
47
|
+
├── bin/
|
|
48
|
+
│ └── claude-hooks # Thin CLI router - argument parsing, command dispatch
|
|
49
|
+
├── lib/
|
|
50
|
+
│ ├── config.js # Config system - load/merge with priority
|
|
51
|
+
│ ├── commands/ # Command modules - one file per CLI command
|
|
52
|
+
│ │ ├── helpers.js # Shared CLI utilities - colors, output, platform
|
|
53
|
+
│ │ ├── install.js # Install command - dependencies, hooks, templates
|
|
54
|
+
│ │ ├── hooks.js # Hook management - enable, disable, status, uninstall
|
|
55
|
+
│ │ ├── analyze-diff.js # Diff analysis - generate PR metadata from git diff
|
|
56
|
+
│ │ ├── create-pr.js # PR creation - full Octokit workflow
|
|
57
|
+
│ │ ├── setup-github.js # Token setup - interactive GitHub configuration
|
|
58
|
+
│ │ ├── presets.js # Preset management - list, set, show current
|
|
59
|
+
│ │ ├── update.js # Self-update - check and install latest version
|
|
60
|
+
│ │ ├── migrate-config.js # Config migration - legacy to v2.8.0 format
|
|
61
|
+
│ │ ├── debug.js # Debug toggle - enable/disable verbose logging
|
|
62
|
+
│ │ ├── telemetry-cmd.js # Telemetry commands - show/clear statistics
|
|
63
|
+
│ │ ├── bump-version.js # Version management - bump with commit, CHANGELOG and tags
|
|
64
|
+
│ │ ├── generate-changelog.js # CHANGELOG generation - standalone command
|
|
65
|
+
│ │ └── help.js # Help, AI help, and report-issue commands
|
|
66
|
+
│ ├── hooks/ # Git hooks - Node.js implementations
|
|
67
|
+
│ │ ├── pre-commit.js # Pre-commit analysis - code quality gate
|
|
68
|
+
│ │ └── prepare-commit-msg.js # Message generation - auto commit messages
|
|
69
|
+
│ └── utils/ # Reusable modules - shared logic
|
|
70
|
+
│ ├── analysis-engine.js # Shared analysis logic - file data, orchestration, results (v2.13.0)
|
|
71
|
+
│ ├── claude-client.js # Claude CLI wrapper - spawn, retry, parallel
|
|
72
|
+
│ ├── prompt-builder.js # Prompt construction - load templates, replace vars
|
|
73
|
+
│ ├── git-operations.js # Git abstractions - staged files, diff, repo root, push, commit
|
|
74
|
+
│ ├── file-utils.js # File operations - repo-relative paths
|
|
75
|
+
│ ├── logger.js # Logging system - centralized output, debug mode
|
|
76
|
+
│ ├── preset-loader.js # Preset system - load tech-stack configurations
|
|
77
|
+
│ ├── pr-metadata-engine.js # PR metadata generation - branch context, diff reduction, metadata (v2.14.0)
|
|
78
|
+
│ ├── github-api.js # Octokit integration - PR creation, token validation
|
|
79
|
+
│ ├── github-client.js # GitHub helpers - CODEOWNERS parsing, reviewers
|
|
80
|
+
│ ├── task-id.js # Task ID extraction - Jira, GitHub, Linear patterns
|
|
81
|
+
│ ├── interactive-ui.js # CLI UI components - previews, prompts, spinners
|
|
82
|
+
│ ├── resolution-prompt.js # Issue resolution - AI-friendly fix prompts
|
|
83
|
+
│ ├── installation-diagnostics.js # Installation diagnostics - error context
|
|
84
|
+
│ ├── claude-diagnostics.js # Claude errors - rate limit, auth, formatting
|
|
85
|
+
│ ├── which-command.js # Executable resolution - cross-platform paths
|
|
86
|
+
│ ├── sanitize.js # Input sanitization - shell safety
|
|
87
|
+
│ ├── telemetry.js # Local telemetry - track JSON parsing, retries
|
|
88
|
+
│ ├── version-manager.js # Version detection - parse, increment, validate, per-file targets (v2.12.0)
|
|
89
|
+
│ ├── git-tag-manager.js # Git tag operations - create, list, compare, push, isSemverTag (v2.12.0)
|
|
90
|
+
│ └── changelog-generator.js # CHANGELOG generation - Claude-powered analysis (v2.12.0)
|
|
91
|
+
├── templates/ # Static assets - copied during install
|
|
92
|
+
│ ├── pre-commit # Bash wrapper - invokes lib/hooks/pre-commit.js
|
|
93
|
+
│ ├── prepare-commit-msg # Bash wrapper - invokes lib/hooks/prepare-commit-msg.js
|
|
94
|
+
│ ├── check-version.sh # Version check - auto-update prompt
|
|
95
|
+
│ ├── CLAUDE_PRE_COMMIT.md # Analysis criteria - evaluation guidelines
|
|
96
|
+
│ ├── CLAUDE_ANALYSIS_PROMPT.md # Analysis prompt - code review template
|
|
97
|
+
│ ├── CLAUDE_RESOLUTION_PROMPT.md # Resolution prompt - issue fix template
|
|
98
|
+
│ ├── ANALYZE_DIFF.md # PR analysis - diff review template
|
|
99
|
+
│ ├── GENERATE_CHANGELOG.md # CHANGELOG generation - commit analysis template (v2.12.0)
|
|
100
|
+
│ ├── HELP_QUERY.md # AI help - question answering with NEED_MORE_CONTEXT protocol (v2.18.0)
|
|
101
|
+
│ ├── HELP_REPORT_ISSUE.md # Report issue - question generation from templates (v2.18.0)
|
|
102
|
+
│ ├── HELP_COMPOSE_ISSUE.md # Report issue - issue body composition from answers (v2.18.0)
|
|
103
|
+
│ ├── config.example.json # Config example - minimal setup
|
|
104
|
+
│ ├── config.advanced.example.json # Config advanced - all options documented
|
|
105
|
+
│ ├── settings.local.example.json # Local settings - token storage template
|
|
106
|
+
│ └── CUSTOMIZATION_GUIDE.md # Customization - preset creation guide
|
|
107
|
+
└── test/ # Tests - Jest with ES6 modules
|
|
108
|
+
└── unit/
|
|
109
|
+
└── *.test.js
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Execution Architecture
|
|
113
|
+
|
|
114
|
+
**1. Git Hooks (bash wrappers → Node.js)**
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
.git/hooks/pre-commit (bash)
|
|
118
|
+
↓
|
|
119
|
+
node lib/hooks/pre-commit.js
|
|
120
|
+
↓ (reads config + preset)
|
|
121
|
+
lib/config.js → merges: defaults < user config < preset config
|
|
122
|
+
↓ (gets staged files)
|
|
123
|
+
lib/utils/git-operations.js → getStagedFiles()
|
|
124
|
+
↓ (filters by preset extensions + size)
|
|
125
|
+
lib/utils/file-operations.js → filterFiles()
|
|
126
|
+
↓ (builds file data + runs analysis)
|
|
127
|
+
lib/utils/analysis-engine.js → buildFilesData(), runAnalysis()
|
|
128
|
+
↓ (orchestrates parallel/sequential Claude CLI calls)
|
|
129
|
+
lib/utils/claude-client.js → analyzeCode() or analyzeCodeParallel()
|
|
130
|
+
↓ (displays results)
|
|
131
|
+
lib/utils/analysis-engine.js → displayResults()
|
|
132
|
+
↓ (if blocking issues found)
|
|
133
|
+
lib/utils/resolution-prompt.js → generates claude_resolution_prompt.md
|
|
134
|
+
↓
|
|
135
|
+
exit 1 (blocks commit) or exit 0 (allows commit)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**2. Configuration System (priorities)**
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
defaults (lib/config.js)
|
|
142
|
+
↓ overridden by
|
|
143
|
+
user config (.claude/config.json)
|
|
144
|
+
↓ overridden by
|
|
145
|
+
preset config (.claude/presets/{name}/config.json) ← HIGHEST PRIORITY
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Rationale**: User configures general preferences, preset provides tech-stack-specific overrides.
|
|
149
|
+
|
|
150
|
+
**Config format (v2.8.0):**
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"version": "2.8.0",
|
|
155
|
+
"preset": "backend",
|
|
156
|
+
"overrides": {
|
|
157
|
+
"github": {
|
|
158
|
+
"pr": {
|
|
159
|
+
"defaultBase": "develop",
|
|
160
|
+
"reviewers": ["user"],
|
|
161
|
+
"autoPush": true, // Auto-push unpublished branches (v2.11.0)
|
|
162
|
+
"pushConfirm": true, // Prompt before push (v2.11.0)
|
|
163
|
+
"showCommits": true, // Show commit preview (v2.11.0)
|
|
164
|
+
"verifyRemote": true // Verify remote exists (v2.11.0)
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"subagents": { "batchSize": 2 }
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Hardcoded defaults (v2.8.0):**
|
|
173
|
+
|
|
174
|
+
| Parameter | Value | Notes |
|
|
175
|
+
| -------------------- | ------- | ---------------------------- |
|
|
176
|
+
| Max file size | 1MB | Files larger are skipped |
|
|
177
|
+
| Max files per commit | 20 | Excess files trigger warning |
|
|
178
|
+
| Parallel analysis | enabled | Always on for 3+ files |
|
|
179
|
+
| Parallel model | haiku | Fast, cost-effective |
|
|
180
|
+
| Parallel batch size | 3 | Files per Claude process |
|
|
181
|
+
| Analysis timeout | 300s | Per-batch timeout |
|
|
182
|
+
| Commit msg timeout | 300s | Message generation timeout |
|
|
183
|
+
| PR metadata timeout | 180s | Engine default (reads config)|
|
|
184
|
+
|
|
185
|
+
**3. Presets System**
|
|
186
|
+
|
|
187
|
+
| Preset | Extensions | Stack | Key Verifications |
|
|
188
|
+
| ----------- | -------------------------------------------------------------------------- | ------------------------ | --------------------------------------------------- |
|
|
189
|
+
| `backend` | `.java`, `.xml`, `.yml`, `.yaml` | Spring Boot + SQL Server | REST API, JPA, OWASP Top 10, SQL injection |
|
|
190
|
+
| `frontend` | `.js`, `.jsx`, `.ts`, `.tsx`, `.css`, `.scss`, `.html` | React + Material-UI | Hooks, XSS, a11y, performance |
|
|
191
|
+
| `fullstack` | backend + frontend | Spring Boot + React | **API contract consistency** (priority) |
|
|
192
|
+
| `database` | `.sql` | SQL Server | SQL injection, UPDATE/DELETE without WHERE, indexes |
|
|
193
|
+
| `ai` | `.js`, `.json`, `.md`, `.sh` | Node.js + Claude API | Prompts, API key security, cross-platform |
|
|
194
|
+
| `default` | `.js`, `.sh`, `.py`, `.rb`, `.pl`, `.sql`, `.yaml`, `.json`, `.xml`, `.md` | Multiple | Quality and security fundamentals |
|
|
195
|
+
|
|
196
|
+
**4. Parallel Analysis (v2.2.0+)**
|
|
197
|
+
|
|
198
|
+
When 3+ files are present, the system divides into batches and executes multiple `claude` CLI processes in parallel:
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
4 files + batchSize=2
|
|
202
|
+
↓
|
|
203
|
+
Batch 1: [file1, file2] → claude CLI process #1 (parallel)
|
|
204
|
+
Batch 2: [file3, file4] → claude CLI process #2 (parallel)
|
|
205
|
+
↓
|
|
206
|
+
Wait for both → consolidate results
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
- **Configuration**: `.claude/config.json` → `subagents.batchSize`, `subagents.model` (haiku/sonnet/opus)
|
|
210
|
+
- **Speed-up**: ~4x faster with batch=1 (1 file per process)
|
|
211
|
+
|
|
212
|
+
### Key Module Exports
|
|
213
|
+
|
|
214
|
+
**Command Modules (`lib/commands/`):**
|
|
215
|
+
|
|
216
|
+
| Module | Purpose | Key Exports |
|
|
217
|
+
| ----------------------- | ------------------------- | ----------------------------------------------------------------------------- |
|
|
218
|
+
| `helpers.js` | Shared CLI utilities | `colors`, `error()`, `success()`, `info()`, `checkGitRepo()`, `getGitHooksPath()`, `Entertainment` |
|
|
219
|
+
| `install.js` | Installation logic | `runInstall()`, `extractLegacySettings()` |
|
|
220
|
+
| `hooks.js` | Hook management | `runEnable()`, `runDisable()`, `runStatus()`, `runUninstall()` |
|
|
221
|
+
| `analyze.js` | Interactive code analysis | `runAnalyze()` |
|
|
222
|
+
| `analyze-diff.js` | Diff analysis | `runAnalyzeDiff()` |
|
|
223
|
+
| `create-pr.js` | PR creation | `runCreatePr()` |
|
|
224
|
+
| `bump-version.js` | Version management | `runBumpVersion()` |
|
|
225
|
+
| `generate-changelog.js` | CHANGELOG generation | `runGenerateChangelog()` |
|
|
226
|
+
| `setup-github.js` | Token setup | `runSetupGitHub()` |
|
|
227
|
+
| `presets.js` | Preset management | `runShowPresets()`, `runSetPreset()`, `runCurrentPreset()` |
|
|
228
|
+
| `update.js` | Self-update | `runUpdate()` |
|
|
229
|
+
| `migrate-config.js` | Config migration | `runMigrateConfig()` |
|
|
230
|
+
| `debug.js` | Debug toggle | `runSetDebug()` |
|
|
231
|
+
| `telemetry-cmd.js` | Telemetry commands | `runShowTelemetry()`, `runClearTelemetry()` |
|
|
232
|
+
| `help.js` | Help, AI help, report-issue | `runShowHelp()`, `showStaticHelp()`, `runShowVersion()` |
|
|
233
|
+
|
|
234
|
+
**Utility Modules (`lib/utils/`):**
|
|
235
|
+
|
|
236
|
+
| Module | Purpose | Key Exports |
|
|
237
|
+
| ------------------------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
238
|
+
| `lib/config.js` | Config system | `getConfig()` |
|
|
239
|
+
| `analysis-engine.js` | Shared analysis logic | `buildFileData()`, `buildFilesData()`, `runAnalysis()`, `consolidateResults()`, `hasBlockingIssues()`, `hasAnyIssues()`, `displayResults()`, `displayIssueSummary()` (v2.13.0) |
|
|
240
|
+
| `claude-client.js` | Claude CLI wrapper | `analyzeCode()`, `analyzeCodeParallel()`, `executeClaudeWithRetry()` |
|
|
241
|
+
| `prompt-builder.js` | Prompt construction | `buildAnalysisPrompt()`, `loadPrompt()` |
|
|
242
|
+
| `git-operations.js` | Git abstractions | `getStagedFiles()`, `getUnstagedFiles()`, `getAllTrackedFiles()`, `getDiff()`, `getRepoRoot()`, `getBranchPushStatus()`, `pushBranch()`, `createCommit()`, `fetchRemote()`, `branchExists()`, `getRemoteBranches()`, `resolveBaseBranch()`, `getChangedFilesBetweenRefs()`, `getDiffBetweenRefs()`, `getCommitsBetweenRefs()` |
|
|
243
|
+
| `file-utils.js` | File operations | `ensureDir()`, `ensureOutputDir()`, `writeOutputFile()`, `walkDirectoryTree()` |
|
|
244
|
+
| `pr-metadata-engine.js` | PR metadata generation | `getBranchContext()`, `buildDiffPayload()`, `generatePRMetadata()`, `analyzeBranchForPR()` (v2.14.0) |
|
|
245
|
+
| `git-tag-manager.js` | Git tag operations | `createTag()`, `pushTags()`, `getLocalTags()`, `getRemoteTags()`, `compareLocalAndRemoteTags()`, `tagExists()` (v2.12.0) |
|
|
246
|
+
| `version-manager.js` | Version management | `discoverVersionFiles()`, `getDiscoveryResult()`, `readVersionFromFile()`, `writeVersionToFile()`, `updateVersionFiles()`, `modifySuffix()`, `incrementVersion()`, `parseVersion()`, `validateVersionFormat()`, `compareVersions()`, `validateVersionAlignment()` (v2.15.5) |
|
|
247
|
+
| `changelog-generator.js` | CHANGELOG generation | `generateChangelogEntry()`, `updateChangelogFile()`, `getLastFinalVersionTag()`, `getCommitsSinceTag()`, `discoverChangelogFiles()`, `selectChangelogFile()` (v2.12.0) |
|
|
248
|
+
| `github-api.js` | Octokit integration | `createPullRequest()`, `validateToken()`, `saveGitHubToken()`, `fetchFileContent()`, `fetchDirectoryListing()`, `createIssue()` |
|
|
249
|
+
| `github-client.js` | GitHub helpers | `getReviewersForFiles()`, `parseGitHubRepo()` |
|
|
250
|
+
| `preset-loader.js` | Preset system | `loadPreset()`, `listPresets()` |
|
|
251
|
+
| `task-id.js` | Task ID extraction | `getOrPromptTaskId()`, `formatWithTaskId()` |
|
|
252
|
+
| `logger.js` | Logging system | `info()`, `warning()`, `error()`, `debug()` |
|
|
253
|
+
| `resolution-prompt.js` | Issue resolution | `generateResolutionPrompt()` |
|
|
254
|
+
| `interactive-ui.js` | CLI UI components | `showPRPreview()`, `promptConfirmation()`, `promptMenu()`, `promptToggleList()`, `promptEditField()`, `promptUserConfirmation()` |
|
|
255
|
+
| `telemetry.js` | Local telemetry | `recordEvent()`, `displayStatistics()` |
|
|
256
|
+
|
|
257
|
+
### Design Patterns
|
|
258
|
+
|
|
259
|
+
1. **Command Pattern**: `lib/commands/*.js` - each CLI command is a self-contained module
|
|
260
|
+
2. **Factory Pattern**: `preset-loader.js` loads configurations dynamically per tech-stack
|
|
261
|
+
3. **Template Method**: `prompt-builder.js` builds prompts from markdown templates
|
|
262
|
+
4. **Strategy Pattern**: `claude-client.js` selects between sequential or parallel analysis
|
|
263
|
+
5. **Adapter Pattern**: `git-operations.js` abstracts git commands into JS functions
|
|
264
|
+
6. **Singleton Pattern**: `config.js` loads configuration once per execution
|
|
265
|
+
|
|
266
|
+
### Key Data Flows
|
|
267
|
+
|
|
268
|
+
**Flow 1: Pre-commit with blocking**
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
git commit
|
|
272
|
+
→ hook reads staged files
|
|
273
|
+
→ filters by preset extensions
|
|
274
|
+
→ builds prompt with diff
|
|
275
|
+
→ Claude analyzes → detects SQL injection (CRITICAL)
|
|
276
|
+
→ generates resolution prompt
|
|
277
|
+
→ exit 1 → COMMIT BLOCKED
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Flow 1.5: Interactive analysis command (v2.13.0)**
|
|
281
|
+
|
|
282
|
+
```
|
|
283
|
+
claude-hooks analyze
|
|
284
|
+
→ runs outside git hook context (stdin works)
|
|
285
|
+
→ getStagedFiles() → buildFilesData() → runAnalysis()
|
|
286
|
+
→ displayIssueSummary() → shows all severity levels (or "No issues found")
|
|
287
|
+
→ promptUserConfirmation() → interactive menu:
|
|
288
|
+
→ [y] Continue - executes createCommit('auto', { noVerify: true })
|
|
289
|
+
→ [n] Abort - generates resolution prompt
|
|
290
|
+
→ [v] View - shows detailed issues → returns to menu
|
|
291
|
+
→ on continue: git commit -m "auto" --no-verify
|
|
292
|
+
→ prepare-commit-msg hook generates message via Claude
|
|
293
|
+
→ commit created with auto-generated message
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**Flow 2: Commit with automatic message**
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
git commit -m "auto"
|
|
300
|
+
→ hook extracts task-id from branch (feature/IX-123-add-auth)
|
|
301
|
+
→ Claude generates message → "[IX-123] feat: add user authentication"
|
|
302
|
+
→ writes to .git/COMMIT_EDITMSG
|
|
303
|
+
→ commit proceeds with generated message
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Flow 3: Analyze diff (v2.14.0)**
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
claude-hooks analyze-diff develop
|
|
310
|
+
→ lib/commands/analyze-diff.js (thin wrapper)
|
|
311
|
+
→ analyzeBranchForPR() (pr-metadata-engine.js)
|
|
312
|
+
→ fetchRemote() → resolveBaseBranch() (suggests similar branches if not found)
|
|
313
|
+
→ getChangedFilesBetweenRefs() → getCommitsBetweenRefs()
|
|
314
|
+
→ buildDiffPayload() → tiered reduction (context → proportional → stat-only)
|
|
315
|
+
→ executeClaudeWithRetry() → parses PRMetadata
|
|
316
|
+
→ formats metadata to console
|
|
317
|
+
→ saves to .claude/out/pr-analysis.json
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Flow 4: PR creation (with auto-push v2.11.0, engine v2.14.0)**
|
|
321
|
+
|
|
322
|
+
```
|
|
323
|
+
claude-hooks create-pr develop
|
|
324
|
+
→ checks branch push status (unpublished/unpushed commits)
|
|
325
|
+
→ shows commit preview → prompts for confirmation
|
|
326
|
+
→ pushes branch to remote (if needed)
|
|
327
|
+
→ reads CODEOWNERS → detects reviewers
|
|
328
|
+
→ reads config → applies label rules per preset
|
|
329
|
+
→ analyzeBranchForPR() (pr-metadata-engine.js) → generates metadata
|
|
330
|
+
→ interactive preview → user confirms
|
|
331
|
+
→ Octokit creates PR on GitHub
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**Flow 5: Version bump with per-file editing (v2.16.0)**
|
|
335
|
+
|
|
336
|
+
```
|
|
337
|
+
claude-hooks bump-version patch --interactive
|
|
338
|
+
→ validatePrerequisites() → clean working directory, valid branch, remote
|
|
339
|
+
→ discoverVersionFiles() → recursive scan (max 3 levels)
|
|
340
|
+
→ displayDiscoveryTable() → shows all discovered files with versions
|
|
341
|
+
→ promptFileSelection() → interactive menu:
|
|
342
|
+
→ [a] Update all files - all files get same newVersion
|
|
343
|
+
→ [s] Select files - toggle list to pick subset
|
|
344
|
+
→ [e] Edit per file - promptEditField() per file:
|
|
345
|
+
→ user enters custom version per file (Enter keeps calculated version)
|
|
346
|
+
→ validateVersionFormat() → rejects invalid entries
|
|
347
|
+
→ stores file.targetVersion on each descriptor
|
|
348
|
+
→ [c] Cancel
|
|
349
|
+
→ incrementVersion() / modifySuffix() → calculates newVersion (used for tag + commit)
|
|
350
|
+
→ updateVersionFiles() → uses file.targetVersion || newVersion per file
|
|
351
|
+
→ createTag(newVersion) → tag reflects primary release version
|
|
352
|
+
→ commit message uses newVersion
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Per-file version design**: `VersionFileDescriptor` gains an optional `targetVersion` property at runtime, set only by option 'e'. When present, `updateVersionFiles()` writes `targetVersion` instead of the global `newVersion`. The tag and commit message always use the calculated `newVersion`.
|
|
356
|
+
|
|
357
|
+
## Code Conventions
|
|
358
|
+
|
|
359
|
+
### General Style
|
|
360
|
+
|
|
361
|
+
- **Format**: Prettier (config in `.prettierrc.json`)
|
|
362
|
+
- **Linting**: ESLint 8.57.0 (config in `.eslintrc.json`)
|
|
363
|
+
- **Indentation**: 4 spaces
|
|
364
|
+
- **Quotes**: Single quotes (strings), double quotes (HTML/imports)
|
|
365
|
+
- **Semicolons**: Required
|
|
366
|
+
|
|
367
|
+
### Naming
|
|
368
|
+
|
|
369
|
+
- **Files**: `kebab-case.js` (e.g., `claude-client.js`, `git-operations.js`)
|
|
370
|
+
- **Functions**: `camelCase()` (e.g., `getStagedFiles()`, `buildAnalysisPrompt()`)
|
|
371
|
+
- **Constants**: `UPPER_SNAKE_CASE` (e.g., `MAX_FILE_SIZE`, `ALLOWED_EXTENSIONS`)
|
|
372
|
+
- **Classes**: Not applicable (no classes, only exported functions)
|
|
373
|
+
- **Private variables**: `_` prefix (e.g., `_internalHelper()`)
|
|
374
|
+
|
|
375
|
+
### Exports
|
|
376
|
+
|
|
377
|
+
**Preferred pattern - Named exports:**
|
|
378
|
+
|
|
379
|
+
```javascript
|
|
380
|
+
// lib/utils/example.js
|
|
381
|
+
export function doSomething() { ... }
|
|
382
|
+
export function doOtherThing() { ... }
|
|
383
|
+
|
|
384
|
+
// consumer
|
|
385
|
+
import { doSomething, doOtherThing } from './utils/example.js';
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Avoid default exports** (except in `bin/claude-hooks` per CLI convention).
|
|
389
|
+
|
|
390
|
+
### Error Handling
|
|
391
|
+
|
|
392
|
+
**Standard pattern:**
|
|
393
|
+
|
|
394
|
+
```javascript
|
|
395
|
+
import { error } from './utils/logger.js';
|
|
396
|
+
|
|
397
|
+
try {
|
|
398
|
+
const result = dangerousOperation();
|
|
399
|
+
return result;
|
|
400
|
+
} catch (err) {
|
|
401
|
+
error(`Failed to perform operation: ${err.message}`);
|
|
402
|
+
process.exit(1); // In hooks and CLI commands
|
|
403
|
+
// or throw err; // In library functions
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**Specific errors:**
|
|
408
|
+
|
|
409
|
+
- Git operations → `execSync()` with try-catch, log and exit
|
|
410
|
+
- Claude CLI → retry logic in `claude-client.js`, configurable timeout
|
|
411
|
+
- GitHub API → catch `@octokit/request-error`, user-friendly formatting
|
|
412
|
+
|
|
413
|
+
### Logging
|
|
414
|
+
|
|
415
|
+
```javascript
|
|
416
|
+
import { info, warning, error, debug } from './utils/logger.js';
|
|
417
|
+
|
|
418
|
+
info('✅ Operation completed'); // User-facing messages
|
|
419
|
+
warning('⚠️ Non-blocking issue detected'); // Warnings
|
|
420
|
+
error('❌ Critical failure'); // Errors
|
|
421
|
+
debug('Detailed diagnostic info'); // Only shown when debug=true
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**Debug mode**: Activate with `claude-hooks --debug true` or in `.claude/config.json`.
|
|
425
|
+
|
|
426
|
+
### Async/Await
|
|
427
|
+
|
|
428
|
+
**Prefer async/await over callbacks:**
|
|
429
|
+
|
|
430
|
+
```javascript
|
|
431
|
+
// ✅ GOOD
|
|
432
|
+
async function analyzeCode(prompt) {
|
|
433
|
+
const result = await spawnClaude(prompt);
|
|
434
|
+
return result;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// ❌ BAD
|
|
438
|
+
function analyzeCode(prompt, callback) {
|
|
439
|
+
spawnClaude(prompt, callback);
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### Reusable Modules
|
|
444
|
+
|
|
445
|
+
All modules in `lib/utils/` must:
|
|
446
|
+
|
|
447
|
+
1. Export pure functions (no global side effects)
|
|
448
|
+
2. Include inline JSDoc documentation
|
|
449
|
+
3. Accept configuration via parameters (no globals)
|
|
450
|
+
4. Return structured results (objects or arrays)
|
|
451
|
+
5. Log with `logger.js` (no direct `console.log`)
|
|
452
|
+
|
|
453
|
+
## Workflow
|
|
454
|
+
|
|
455
|
+
### Branching Strategy
|
|
456
|
+
|
|
457
|
+
This repository follows **simplified GitHub Flow**:
|
|
458
|
+
|
|
459
|
+
- **Main branch**: `main` (protected)
|
|
460
|
+
- **Feature branches**: `feature/issue-description` or `feature/TASK-ID-description`
|
|
461
|
+
- **Fix branches**: `fix/issue-description`
|
|
462
|
+
- **Hotfix branches**: `hotfix/urgent-description`
|
|
463
|
+
|
|
464
|
+
**Rules:**
|
|
465
|
+
|
|
466
|
+
1. All changes require PR to `main`
|
|
467
|
+
2. No direct commits to `main`
|
|
468
|
+
3. PRs require review (auto-merge NOT allowed)
|
|
469
|
+
|
|
470
|
+
### Development Process
|
|
471
|
+
|
|
472
|
+
**1. Initial setup (first time)**
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
git clone https://github.com/mscope-S-L/git-hooks.git
|
|
476
|
+
cd git-hooks
|
|
477
|
+
npm install
|
|
478
|
+
npm link # Install globally as symlink for development
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
**2. Create feature branch**
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
git checkout -b feature/new-functionality
|
|
485
|
+
# or with task-id: feature/IX-123-new-functionality
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**3. Iterative development**
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
# Make changes...
|
|
492
|
+
npm run lint # Check linting
|
|
493
|
+
npm run test # Run tests
|
|
494
|
+
git add .
|
|
495
|
+
git commit -m "feat: add new functionality"
|
|
496
|
+
# Hooks execute automatically
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
**4. Local testing**
|
|
500
|
+
|
|
501
|
+
Test changes in a test repository:
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
# In test repo
|
|
505
|
+
cd /path/to/test-repo
|
|
506
|
+
claude-hooks install --force --skip-auth # Reinstall from symlink
|
|
507
|
+
git commit -m "test" # Test hook
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
**5. Create PR**
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
git push -u origin feature/new-functionality
|
|
514
|
+
claude-hooks analyze-diff main # Generate PR metadata
|
|
515
|
+
# or directly:
|
|
516
|
+
claude-hooks create-pr main # Create PR on GitHub (if MCP configured)
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### CI/CD
|
|
520
|
+
|
|
521
|
+
**Currently**: No automated CI/CD (GitHub Actions pending).
|
|
522
|
+
|
|
523
|
+
**Manual verifications before merge:**
|
|
524
|
+
|
|
525
|
+
1. `npm run lint` → passes
|
|
526
|
+
2. `npm run test` → all tests pass
|
|
527
|
+
3. Manual testing in test repo
|
|
528
|
+
4. Peer code review
|
|
529
|
+
5. CHANGELOG.md updated
|
|
530
|
+
|
|
531
|
+
### Versioning
|
|
532
|
+
|
|
533
|
+
We follow **Semantic Versioning** (MAJOR.MINOR.PATCH):
|
|
534
|
+
|
|
535
|
+
- **MAJOR**: Breaking changes (e.g., 1.x → 2.0 with ES6 migration)
|
|
536
|
+
- **MINOR**: New features without breaking changes (e.g., 2.2 → 2.3 with presets)
|
|
537
|
+
- **PATCH**: Bug fixes (e.g., 2.6.0 → 2.6.1 with spawn ENOENT fix)
|
|
538
|
+
|
|
539
|
+
**Update version:**
|
|
540
|
+
|
|
541
|
+
```bash
|
|
542
|
+
npm version patch # 2.6.1 → 2.6.2
|
|
543
|
+
npm version minor # 2.6.1 → 2.7.0
|
|
544
|
+
npm version major # 2.6.1 → 3.0.0
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
**Publish to NPM:**
|
|
548
|
+
|
|
549
|
+
```bash
|
|
550
|
+
npm publish
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### Conventional Commits
|
|
554
|
+
|
|
555
|
+
Format: `<type>(<scope>): <subject>`
|
|
556
|
+
|
|
557
|
+
**Types:**
|
|
558
|
+
|
|
559
|
+
- `feat`: New functionality
|
|
560
|
+
- `fix`: Bug fix
|
|
561
|
+
- `docs`: Documentation only
|
|
562
|
+
- `style`: Formatting (no logic change)
|
|
563
|
+
- `refactor`: Refactoring without functional change
|
|
564
|
+
- `test`: Add or modify tests
|
|
565
|
+
- `chore`: Maintenance (deps, config)
|
|
566
|
+
- `perf`: Performance improvements
|
|
567
|
+
|
|
568
|
+
**Optional scopes:**
|
|
569
|
+
|
|
570
|
+
- `hooks`: Changes in pre-commit or prepare-commit-msg
|
|
571
|
+
- `presets`: Preset system
|
|
572
|
+
- `github`: GitHub integration
|
|
573
|
+
- `cli`: Main CLI commands
|
|
574
|
+
- `config`: Configuration system
|
|
575
|
+
- `windows`: Windows-specific fixes
|
|
576
|
+
|
|
577
|
+
**Examples:**
|
|
578
|
+
|
|
579
|
+
```
|
|
580
|
+
feat(presets): add database preset for SQL analysis
|
|
581
|
+
fix(windows): resolve spawn ENOENT with .cmd files
|
|
582
|
+
docs: update CLAUDE.md with architecture details
|
|
583
|
+
chore(deps): upgrade @octokit/rest to v21
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
## Useful Commands
|
|
587
|
+
|
|
588
|
+
### Development
|
|
589
|
+
|
|
590
|
+
```bash
|
|
591
|
+
# Installation and setup
|
|
592
|
+
npm install # Install dependencies
|
|
593
|
+
npm link # Install globally as symlink
|
|
594
|
+
npm unlink # Uninstall global symlink
|
|
595
|
+
|
|
596
|
+
# Testing
|
|
597
|
+
npm test # Run all tests (Jest)
|
|
598
|
+
npm run test:watch # Tests in watch mode
|
|
599
|
+
npm run test:coverage # Coverage report
|
|
600
|
+
|
|
601
|
+
# Linting and formatting
|
|
602
|
+
npm run lint # Check ESLint
|
|
603
|
+
npm run lint:fix # Auto-fix ESLint issues
|
|
604
|
+
npm run format # Format with Prettier
|
|
605
|
+
|
|
606
|
+
# Versioning
|
|
607
|
+
npm version patch|minor|major # Bump version
|
|
608
|
+
npm publish # Publish to NPM
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### Package CLI
|
|
612
|
+
|
|
613
|
+
```bash
|
|
614
|
+
# Hook installation in a repo
|
|
615
|
+
claude-hooks install # Interactive installation
|
|
616
|
+
claude-hooks install --force # Reinstall without confirmation
|
|
617
|
+
claude-hooks install --skip-auth # Skip Claude verification
|
|
618
|
+
|
|
619
|
+
# Hook management
|
|
620
|
+
claude-hooks status # View current status
|
|
621
|
+
claude-hooks enable [hook] # Enable all or specific hook
|
|
622
|
+
claude-hooks disable [hook] # Disable all or specific hook
|
|
623
|
+
claude-hooks uninstall # Completely uninstall
|
|
624
|
+
|
|
625
|
+
# Presets
|
|
626
|
+
claude-hooks presets # List available presets
|
|
627
|
+
claude-hooks --set-preset backend # Change preset
|
|
628
|
+
claude-hooks preset current # View current preset
|
|
629
|
+
|
|
630
|
+
# Analysis and PRs
|
|
631
|
+
claude-hooks analyze-diff [branch] # Analyze diff for PR
|
|
632
|
+
claude-hooks create-pr [branch] # Create PR on GitHub
|
|
633
|
+
claude-hooks setup-github # Configure GitHub token
|
|
634
|
+
|
|
635
|
+
# Version management
|
|
636
|
+
claude-hooks bump-version patch # Bump version (commits, tags locally)
|
|
637
|
+
claude-hooks bump-version minor --suffix SNAPSHOT # With suffix
|
|
638
|
+
claude-hooks bump-version major --update-changelog # With CHANGELOG
|
|
639
|
+
claude-hooks bump-version patch --push # Push tag immediately
|
|
640
|
+
claude-hooks bump-version patch --no-commit # Manual workflow
|
|
641
|
+
claude-hooks bump-version patch --interactive # Force file selection menu
|
|
642
|
+
claude-hooks generate-changelog # Generate CHANGELOG only
|
|
643
|
+
|
|
644
|
+
# Help and issue reporting
|
|
645
|
+
claude-hooks help "how do presets work?" # AI-powered help (uses CLAUDE.md)
|
|
646
|
+
claude-hooks help --report-issue # Interactive issue creation
|
|
647
|
+
|
|
648
|
+
# Debugging
|
|
649
|
+
claude-hooks --debug true # Enable debug mode
|
|
650
|
+
claude-hooks --debug false # Disable debug mode
|
|
651
|
+
claude-hooks --debug status # View debug status
|
|
652
|
+
|
|
653
|
+
# Auto-update
|
|
654
|
+
claude-hooks update # Update to latest version
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
### Git with Active Hooks
|
|
658
|
+
|
|
659
|
+
```bash
|
|
660
|
+
# Normal commit with analysis
|
|
661
|
+
git commit -m "feat: new functionality"
|
|
662
|
+
|
|
663
|
+
# Commit with automatic message
|
|
664
|
+
git commit -m "auto" # Claude generates the message
|
|
665
|
+
|
|
666
|
+
# Skip analysis (emergencies)
|
|
667
|
+
git commit --no-verify -m "hotfix: urgent"
|
|
668
|
+
|
|
669
|
+
# Amend last commit
|
|
670
|
+
git commit --amend
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
### Local Testing in Test Repo
|
|
674
|
+
|
|
675
|
+
```bash
|
|
676
|
+
# Initial setup
|
|
677
|
+
cd /path/to/test-repo
|
|
678
|
+
claude-hooks install --force --skip-auth
|
|
679
|
+
|
|
680
|
+
# After changes in claude-hooks
|
|
681
|
+
# (npm link is already active, no need to reinstall)
|
|
682
|
+
cd /path/to/test-repo
|
|
683
|
+
git add test.txt
|
|
684
|
+
git commit -m "test: validate changes"
|
|
685
|
+
# Hooks use local version automatically
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
## Testing
|
|
689
|
+
|
|
690
|
+
### Test Framework
|
|
691
|
+
|
|
692
|
+
- **Framework**: Jest with ES6 modules (`--experimental-vm-modules`)
|
|
693
|
+
- **Location**: `test/unit/*.test.js`
|
|
694
|
+
- **Naming**: `{module-name}.test.js` matches `lib/utils/{module-name}.js`
|
|
695
|
+
- **Run**: `npm test` (all), `npm run test:watch` (watch mode)
|
|
696
|
+
|
|
697
|
+
### Test Patterns
|
|
698
|
+
|
|
699
|
+
```javascript
|
|
700
|
+
// test/unit/example.test.js
|
|
701
|
+
import { functionToTest } from '../../lib/utils/example.js';
|
|
702
|
+
|
|
703
|
+
describe('functionToTest', () => {
|
|
704
|
+
it('should handle normal input', () => {
|
|
705
|
+
const result = functionToTest('input');
|
|
706
|
+
expect(result).toBe('expected');
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
it('should throw on invalid input', () => {
|
|
710
|
+
expect(() => functionToTest(null)).toThrow('Invalid input');
|
|
711
|
+
});
|
|
712
|
+
});
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
### Mocking
|
|
716
|
+
|
|
717
|
+
```javascript
|
|
718
|
+
// Mock child_process for git/claude commands
|
|
719
|
+
import { jest } from '@jest/globals';
|
|
720
|
+
import { execSync } from 'child_process';
|
|
721
|
+
|
|
722
|
+
jest.mock('child_process');
|
|
723
|
+
execSync.mockReturnValue('mocked output');
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
### Coverage
|
|
727
|
+
|
|
728
|
+
No enforced threshold. Focus on critical paths:
|
|
729
|
+
|
|
730
|
+
- `claude-client.js` - Claude CLI interaction
|
|
731
|
+
- `git-operations.js` - Git command abstraction
|
|
732
|
+
- `config.js` - Configuration merging
|
|
733
|
+
|
|
734
|
+
## Restrictions
|
|
735
|
+
|
|
736
|
+
### What Claude should NOT do in this repository
|
|
737
|
+
|
|
738
|
+
1. **DO NOT add interactive prompts to git hooks**
|
|
739
|
+
- Git hooks run with stdin redirected from `/dev/null`
|
|
740
|
+
- Readline-based prompts cannot read user input in hook context
|
|
741
|
+
- Works in IDE integrations (VSCode, IntelliJ) but breaks in terminal
|
|
742
|
+
- **Solution**: Use `claude-hooks analyze` command instead (runs outside hook context)
|
|
743
|
+
- **Rationale**: Discovered through manual testing in Issue #20
|
|
744
|
+
|
|
745
|
+
2. **DO NOT modify bash wrappers without corresponding Node.js changes**
|
|
746
|
+
- `templates/pre-commit` and `templates/prepare-commit-msg` are wrappers
|
|
747
|
+
- Real logic is in `lib/hooks/*.js`
|
|
748
|
+
- Changes to bash should be minimal (only Node.js invocation)
|
|
749
|
+
|
|
750
|
+
3. **DO NOT use `shell: true` in `spawn()` calls**
|
|
751
|
+
- Deprecated in Node.js 24 (DEP0190)
|
|
752
|
+
- Use `which-command.js` to resolve executable paths
|
|
753
|
+
- **Exception**: Windows with `.cmd`/`.bat` requires `cmd.exe /c` wrapper
|
|
754
|
+
|
|
755
|
+
4. **DO NOT modify config priority order**
|
|
756
|
+
- Maintain: defaults < user config < preset config
|
|
757
|
+
- Preset always wins (tech-stack specific has priority over user preferences)
|
|
758
|
+
|
|
759
|
+
5. **DO NOT create duplicate config files**
|
|
760
|
+
- Single `.claude/config.json` per repo
|
|
761
|
+
- Presets live in `.claude/presets/{name}/`
|
|
762
|
+
- Do not create `.env` or similar files for configuration
|
|
763
|
+
|
|
764
|
+
6. **DO NOT make breaking changes without MAJOR version bump**
|
|
765
|
+
- Changes in config.json structure → MAJOR
|
|
766
|
+
- Changes in CLI arguments → MAJOR
|
|
767
|
+
- Changes in template format → MINOR if backward compatible, otherwise MAJOR
|
|
768
|
+
|
|
769
|
+
7. **DO NOT hardcode absolute paths**
|
|
770
|
+
- Use `getRepoRoot()` from `git-operations.js`
|
|
771
|
+
- All paths relative to repo root
|
|
772
|
+
- Exception: paths in `PATH` resolved with `which-command.js`
|
|
773
|
+
|
|
774
|
+
8. **DO NOT use `console.log` directly**
|
|
775
|
+
- Always use `logger.js`: `info()`, `warning()`, `error()`, `debug()`
|
|
776
|
+
- Enables centralized output control and debug mode
|
|
777
|
+
|
|
778
|
+
9. **DO NOT execute Claude CLI without timeout**
|
|
779
|
+
- Always configure timeout (default: 150s analysis, 180s commit msg)
|
|
780
|
+
- Timeout configurable in `.claude/config.json`
|
|
781
|
+
|
|
782
|
+
10. **DO NOT ignore platform-specific issues**
|
|
783
|
+
- Test changes on Windows, Linux, and macOS
|
|
784
|
+
- Path separators: use `path.join()` (no hardcoded `/`)
|
|
785
|
+
- Line endings: templates use LF, convert on install if needed
|
|
786
|
+
|
|
787
|
+
11. **DO NOT commit secrets**
|
|
788
|
+
- `.claude/settings.local.json` is in `.gitignore`
|
|
789
|
+
- GitHub tokens should go in settings.local or env vars
|
|
790
|
+
- Never in `.claude/config.json` (tracked)
|
|
791
|
+
|
|
792
|
+
12. **DO NOT modify project `.gitignore` without consultation**
|
|
793
|
+
- `.claude/` is ignored by design (user-specific)
|
|
794
|
+
- `node_modules/` obvious
|
|
795
|
+
- New entries must be justified
|
|
796
|
+
|
|
797
|
+
13. **DO NOT add dependencies without validation**
|
|
798
|
+
- Only 1 runtime dependency currently: `@octokit/rest`
|
|
799
|
+
- New deps must be justified (no built-in alternative?)
|
|
800
|
+
- Dev deps are OK if they improve DX (testing, linting)
|
|
801
|
+
|
|
802
|
+
14. **DO NOT perform git operations add, commit, push unless asked to**
|
|
803
|
+
- Git flow associated with normal development must be left to human user
|
|
804
|
+
|
|
805
|
+
### Technical Limitations
|
|
806
|
+
|
|
807
|
+
1. **Node.js versions**: >=16.9.0 required (ES6 module features)
|
|
808
|
+
2. **Claude CLI**: Must be installed and authenticated externally
|
|
809
|
+
3. **Git**: Requires initialized repo (doesn't work outside git repos)
|
|
810
|
+
4. **Parallel analysis**: Minimum 3 files to activate
|
|
811
|
+
5. **File size**: Default max 1MB per file (configurable)
|
|
812
|
+
6. **Max files**: Default 30 files per commit (configurable)
|
|
813
|
+
7. **GitHub API**: Rate limits apply (5000 req/hour authenticated)
|
|
814
|
+
|
|
815
|
+
### Security Considerations
|
|
816
|
+
|
|
817
|
+
1. **Input sanitization**: Use `sanitize.js` for user inputs in shell commands
|
|
818
|
+
2. **Token storage**: GitHub tokens in settings.local (gitignored) or env vars, NEVER tracked
|
|
819
|
+
3. **Shell injection**: Avoid `shell: true`, use arrays in spawn()
|
|
820
|
+
4. **Path traversal**: Validate relative paths before file operations
|
|
821
|
+
5. **Secrets in diffs**: Hook should NOT prevent commits with secrets (user responsibility)
|