claude-git-hooks 2.66.1 → 2.68.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/CHANGELOG.md +117 -8
- package/README.md +34 -0
- package/bin/claude-hooks +19 -0
- package/lib/commands/analyze-diff.js +26 -23
- package/lib/commands/analyze.js +3 -1
- package/lib/commands/back-merge.js +39 -33
- package/lib/commands/bump-version.js +20 -15
- package/lib/commands/close-release.js +25 -19
- package/lib/commands/create-pr.js +30 -1
- package/lib/commands/create-release.js +19 -13
- package/lib/commands/install.js +9 -19
- package/lib/commands/update.js +14 -28
- package/lib/defaults.json +9 -0
- package/lib/hooks/pre-commit.js +112 -32
- package/lib/utils/analysis-engine.js +7 -3
- package/lib/utils/auto-update.js +198 -0
- package/lib/utils/config-registry.js +1 -0
- package/lib/utils/library-resolver.js +50 -0
- package/lib/utils/prompt-builder.js +15 -0
- package/lib/utils/skill-registry/catalogue.js +74 -0
- package/lib/utils/skill-registry/feedback-writer.js +196 -0
- package/lib/utils/skill-registry/index.js +254 -0
- package/lib/utils/skill-registry/parser.js +311 -0
- package/lib/utils/skill-registry/resume.js +81 -0
- package/lib/utils/skill-registry/runner.js +265 -0
- package/lib/utils/version-manager.js +9 -3
- package/package.json +84 -85
- package/templates/CLAUDE_ANALYSIS_PROMPT.md +2 -1
- package/templates/config.advanced.example.json +42 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,21 +5,112 @@ Todos los cambios notables en este proyecto se documentarán en este archivo.
|
|
|
5
5
|
El formato está basado en [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.68.0] - 2026-06-12
|
|
9
|
+
|
|
10
|
+
### ✨ Added
|
|
11
|
+
- Silent, throttled pre-command auto-update guard that checks for newer versions before running commands and self-updates automatically (#196)
|
|
12
|
+
- New `autoUpdate` configuration section with `enabled` (default: true) and `intervalHours` (default: 24) settings to control automatic update behavior
|
|
13
|
+
- Centralized `lib/utils/auto-update.js` module providing shared update logic (`getUpdateStatus`, `performUpdate`, `shouldAutoCheck`, `maybeAutoUpdate`) for all update paths
|
|
14
|
+
|
|
15
|
+
### 🔧 Changed
|
|
16
|
+
- Refactored `update` command into a thin wrapper over the shared auto-update module, eliminating duplicated version-check and npm-install logic
|
|
17
|
+
- Refactored install-time update prompt to use shared `getUpdateStatus()` and `performUpdate()` instead of inline implementation
|
|
18
|
+
- Auto-update is fully fail-open and skipped in `--headless` mode — never blocks the real command on failure
|
|
19
|
+
- Excluded fast/offline commands (`update`, `install`, `uninstall`, `help`, `version`, `migrate-config`) from the pre-command auto-update check to avoid recursion and unnecessary latency
|
|
20
|
+
|
|
21
|
+
### 🐛 Fixed
|
|
22
|
+
- Fixed install-time update prompt incorrectly offering to "update" dev builds that are ahead of the latest published npm version
|
|
23
|
+
|
|
24
|
+
### 🗑️ Removed
|
|
25
|
+
- Removed `check-version.sh` template installation from the install command (replaced by the integrated auto-update guard)
|
|
26
|
+
- Removed inline `npm install -g` and `runInstall(['--force'])` calls from `update.js` and `install.js` in favor of centralized `performUpdate()`
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## [2.67.3] - 2026-06-12
|
|
30
|
+
|
|
31
|
+
### ✨ Added
|
|
32
|
+
- Upfront CLI availability probe in gotcha solicitation — checks once per run instead of discovering failures per-book (#195)
|
|
33
|
+
- New `llm.js` shared CLI wrapper for the librarian pipeline, using the developer's `claude` login session
|
|
34
|
+
|
|
35
|
+
### 🔧 Changed
|
|
36
|
+
- Replaced Anthropic SDK (`@anthropic-ai/sdk`) with CLI wrapper (`llm.js`) in the librarian's candidate-text-generator (#195)
|
|
37
|
+
- Default model identifier simplified from `claude-sonnet-4-6` to `sonnet` shorthand
|
|
38
|
+
- Gotcha solicitation skips per-book candidate generation entirely when CLI is unavailable, showing a single message instead of one warning per book
|
|
39
|
+
- Tests updated to mock the CLI wrapper instead of the Anthropic SDK
|
|
40
|
+
|
|
41
|
+
### 🐛 Fixed
|
|
42
|
+
- Resolved library pipeline resolver issues when Anthropic API key is unavailable — librarian now works with just a `claude` CLI login (#195)
|
|
43
|
+
|
|
44
|
+
### 🗑️ Removed
|
|
45
|
+
- Removed `_classifyError()` helper and all SDK-specific error classification logic from candidate-text-generator
|
|
46
|
+
- Removed direct dependency on `@anthropic-ai/sdk` in the librarian pipeline
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
## [2.67.2] - 2026-06-11
|
|
50
|
+
|
|
51
|
+
### 🔧 Changed
|
|
52
|
+
- Centralized `.library/` resolution into a dedicated `library-resolver.js` module — all commands now resolve Library paths from the repo root via `libraryModuleUrl()` instead of fragile relative imports
|
|
53
|
+
- Library pipeline steps (staleness checks, verification gates, co-change pipeline) now gracefully skip with a debug log when the working repo has no `.library/` directory
|
|
54
|
+
|
|
55
|
+
### 🐛 Fixed
|
|
56
|
+
- Commands no longer produce misleading warnings or errors when the tool is installed as a dependency in repos that have no `.library/` (#194)
|
|
57
|
+
- Sanitized version output at source (#194)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## [2.67.1] - 2026-06-11
|
|
61
|
+
|
|
62
|
+
### 🐛 Fixed
|
|
63
|
+
- Sanitized non-semver versions at discovery source in version-manager, preventing invalid version strings from propagating through the bump-version pipeline
|
|
64
|
+
|
|
65
|
+
### 🗑️ Removed
|
|
66
|
+
- Removed unused `test:full` npm script from package.json
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
## [2.67.0] - 2026-06-10
|
|
70
|
+
|
|
71
|
+
### ✨ Added
|
|
72
|
+
|
|
73
|
+
- Integrated the `@mscope/automation-skills` rule registry into the pre-commit hook: deterministic JBE/UIK rule checks run against staged files and surface findings alongside lint + AI output, with optional severity gating via `skillRegistry.blockOn` (Options A + G)
|
|
74
|
+
- Injected the mscope rule catalogue into the Claude analysis prompt; findings Claude cannot classify against the catalogue are appended as `[skill-gap]` candidates to the skill repo's `skill-feedback.md`, fingerprint-deduplicated and reviewed via `automation-skills retro` — never auto-merged (Option E2)
|
|
75
|
+
- Lessons-learned capture on `create-pr`: a new knowledge-capture step hands control to `automation-skills resume` before tags are pushed, recording branch lessons to the skill repo's `implementation-history.md` (supersedes the draft `finish-branch` command; gated by `skillRegistry.resumeOnCreatePr`, skipped in headless mode)
|
|
76
|
+
- `skillRegistry` configuration section (`enabled`, `blockOn`, `resumeOnCreatePr`) registered in package defaults, overridable remotely and per-repo, documented in `config.advanced.example.json`
|
|
77
|
+
- Unit tests for the skill-registry: parser, runner, catalogue, feedback-writer, facade, and resume modules
|
|
78
|
+
|
|
79
|
+
### 🔧 Changed
|
|
80
|
+
|
|
81
|
+
- Skill-registry consumption is decoupled behind a facade (`runSkillChecks`, `getCatalogueSection`, `recordSkillGaps`) with a memoized registry load; the catalogue reaches the analysis prompt as a plain parameter threaded through `analysis-engine` → `prompt-builder`, which have no skill-registry knowledge
|
|
82
|
+
- `analyze` command injects the same rule catalogue into its analysis prompt for parity with pre-commit
|
|
83
|
+
- `CLAUDE_ANALYSIS_PROMPT.md` now instructs Claude to classify each finding against the injected catalogue via `details[].rule`
|
|
84
|
+
- Library extractor cross-references now resolve through books' frontmatter `source_files` instead of source-file basenames, so books not named after their source (e.g. `skill-registry-parser.md`) survive regeneration with correct references
|
|
85
|
+
|
|
86
|
+
### 🐛 Fixed
|
|
87
|
+
|
|
88
|
+
- Resolved the `automation-skills` sibling skill repo relative to the working repo (env vars → sibling-of-working-repo) instead of guessing under the user's home directory, making registry loading reliable across machines
|
|
89
|
+
- Fixed catalogue injection never activating in the canonical sibling layout — the registry was loaded without the working repo root, so resolution silently failed unless an env var was set
|
|
90
|
+
- Repaired skill-registry text injections that were being corrupted by suggestion-click commits
|
|
91
|
+
- Skill-gap writer failures during pre-commit are now logged as warnings instead of silently discarded (the commit is never blocked either way)
|
|
92
|
+
|
|
93
|
+
### 🗑️ Removed
|
|
94
|
+
|
|
95
|
+
- Removed the legacy `mscope-automation--claude-skills` sibling skill-repo name from registry resolution, leaving only the current `automation-skills` name
|
|
96
|
+
|
|
8
97
|
## [2.66.1] - 2026-06-10
|
|
9
98
|
|
|
10
99
|
### 🐛 Fixed
|
|
11
|
-
- Normalized path separators to forward slashes in staleness checker for cross-platform compatibility
|
|
12
100
|
|
|
101
|
+
- Normalized path separators to forward slashes in staleness checker for cross-platform compatibility
|
|
13
102
|
|
|
14
103
|
## [2.66.0] - 2026-06-10
|
|
15
104
|
|
|
16
105
|
### ✨ Added
|
|
106
|
+
|
|
17
107
|
- Multi-language extractor registry with pluggable per-language architecture [AUT-3742]
|
|
18
108
|
- End-to-end SDLC stability check test suite
|
|
19
109
|
- Version alignment validation now scoped to base branch tags (#185)
|
|
20
110
|
- Extractor notes template for documenting per-language extractors
|
|
21
111
|
|
|
22
112
|
### 🔧 Changed
|
|
113
|
+
|
|
23
114
|
- Moved arrow-function extraction from monolithic extractor to pluggable extractor module [AUT-3742]
|
|
24
115
|
- Decoupled `lib/` from `.library/` static imports with ESLint enforcement rule [AUT-3742]
|
|
25
116
|
- Library maintenance pipeline now runs before tag push in `create-pr`, ensuring library books are included in tagged commits
|
|
@@ -27,6 +118,7 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
27
118
|
- Tags are force-repointed to HEAD after library commit so tagged version includes regenerated books
|
|
28
119
|
|
|
29
120
|
### 🐛 Fixed
|
|
121
|
+
|
|
30
122
|
- Fixed `create-pr` gotcha solicitation receiving empty file paths instead of actual book content (#190)
|
|
31
123
|
- Fixed `create-pr` tag comparison using global tag list instead of base branch scope
|
|
32
124
|
- Fixed `create-pr` library pipeline leaking host-repo paths into foreign repositories (#186)
|
|
@@ -35,12 +127,13 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
35
127
|
- Fixed stale git worktree leftovers causing integration test failures
|
|
36
128
|
|
|
37
129
|
### 🗑️ Removed
|
|
38
|
-
- Removed per-file custom version entry option (`promptEditField`) from `bump-version` interactive selection
|
|
39
130
|
|
|
131
|
+
- Removed per-file custom version entry option (`promptEditField`) from `bump-version` interactive selection
|
|
40
132
|
|
|
41
133
|
## [2.65.0] - 2026-06-08
|
|
42
134
|
|
|
43
135
|
### ✨ Added
|
|
136
|
+
|
|
44
137
|
- Multi-language extractor registry with pluggable per-language extractors (AUT-3742)
|
|
45
138
|
- Extractor interface contract and runtime validator for language extractor plugins (AUT-3742)
|
|
46
139
|
- JS extractor notes template for documenting new extractors (AUT-3742)
|
|
@@ -48,6 +141,7 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
48
141
|
- Version alignment now scoped to base branch tags instead of global tag lookup
|
|
49
142
|
|
|
50
143
|
### 🔧 Changed
|
|
144
|
+
|
|
51
145
|
- Arrow-function extraction moved from monolithic extract.js to pluggable JS extractor module (AUT-3742)
|
|
52
146
|
- Decoupled lib/ from .library/ static imports with ESLint enforcement — lib/ must use dynamic import() for Library integration (AUT-3742)
|
|
53
147
|
- Library maintenance pipeline in create-pr now runs before tag push so tags include regenerated books
|
|
@@ -56,6 +150,7 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
56
150
|
- bump-version interactive file selection simplified — goes directly to toggle list, non-semver files pre-deselected
|
|
57
151
|
|
|
58
152
|
### 🐛 Fixed
|
|
153
|
+
|
|
59
154
|
- Fixed create-pr library pipeline running incorrectly in foreign repos by deriving paths from resolver config (#186)
|
|
60
155
|
- Fixed bump-version crash when non-semver files (e.g., Maven `${revision}`) reached version parser (#187)
|
|
61
156
|
- Fixed create-pr comparing tags against global scope instead of base branch (#185, #189)
|
|
@@ -63,13 +158,14 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
63
158
|
- Fixed local tag lookup not scoped to HEAD branch, causing cross-branch version mismatches
|
|
64
159
|
|
|
65
160
|
### 🗑️ Removed
|
|
161
|
+
|
|
66
162
|
- Removed per-file custom version editing (option `e`) from bump-version interactive selection
|
|
67
163
|
- Removed `promptMenu` and `promptEditField` usage from bump-version flow
|
|
68
164
|
|
|
69
|
-
|
|
70
165
|
## [2.64.4] - 2026-06-08
|
|
71
166
|
|
|
72
167
|
### ✨ Added
|
|
168
|
+
|
|
73
169
|
- Added multi-language extractor registry with pluggable architecture and runtime interface validation (AUT-3742, #184)
|
|
74
170
|
- Added JS extractor as first pluggable extractor with dedicated test harness and fixtures (AUT-3742)
|
|
75
171
|
- Added extractor notes template for documenting per-language extractors (AUT-3742)
|
|
@@ -77,6 +173,7 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
77
173
|
- Added branch-scoped version alignment validation in `create-pr` (#185)
|
|
78
174
|
|
|
79
175
|
### 🔧 Changed
|
|
176
|
+
|
|
80
177
|
- Decoupled `lib/` from `.library/` static imports with ESLint restricted-imports guard (AUT-3742)
|
|
81
178
|
- Moved arrow-function extraction from monolithic extractor into pluggable JS extractor module (AUT-3742)
|
|
82
179
|
- Simplified `bump-version` interactive file selection — removed menu, goes directly to toggle list with non-semver files pre-deselected (#187)
|
|
@@ -84,18 +181,20 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
84
181
|
- Reordered `create-pr` steps so library pipeline runs before tag push, then re-points unpushed tags to HEAD to include library commits
|
|
85
182
|
|
|
86
183
|
### 🐛 Fixed
|
|
184
|
+
|
|
87
185
|
- Fixed `bump-version` crash when non-semver files (e.g., Maven `${revision}`) were included in version resolution (#187)
|
|
88
186
|
- Fixed `create-pr` library pipeline using hardcoded paths that broke in foreign repositories (#186)
|
|
89
187
|
- Fixed version alignment and tag lookup returning results from unrelated branches instead of scoping to base branch (#185)
|
|
90
188
|
- Fixed `create-pr` tag becoming stale after library book regeneration by running the pipeline before tag push and re-pointing tags
|
|
91
189
|
|
|
92
190
|
### 🗑️ Removed
|
|
93
|
-
- Removed `promptMenu` and `promptEditField` options from `bump-version` interactive file selection (#187)
|
|
94
191
|
|
|
192
|
+
- Removed `promptMenu` and `promptEditField` options from `bump-version` interactive file selection (#187)
|
|
95
193
|
|
|
96
194
|
## [2.64.3] - 2026-06-08
|
|
97
195
|
|
|
98
196
|
### ✨ Added
|
|
197
|
+
|
|
99
198
|
- Added multi-language extractor registry with pluggable interface, including JS extractor and notes template (AUT-3742)
|
|
100
199
|
- Added library maintenance pipeline step in create-pr that regenerates books before tag push
|
|
101
200
|
- Added branch-scoped tag lookup functions (`getLatestLocalTagOnBranch`, `getLatestRemoteTagOnBranch`) to git-tag-manager
|
|
@@ -103,6 +202,7 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
103
202
|
- Added extractor test harness with JS fixtures (AUT-3742)
|
|
104
203
|
|
|
105
204
|
### 🔧 Changed
|
|
205
|
+
|
|
106
206
|
- Moved arrow-function extraction from monolithic `extract.js` into pluggable extractor under `librarian/extractors/registered/js/` (AUT-3742)
|
|
107
207
|
- Scoped version alignment validation to base branch tags instead of global tag lookup
|
|
108
208
|
- Simplified bump-version interactive file selection — goes directly to toggle list, non-semver files pre-deselected
|
|
@@ -110,19 +210,21 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
110
210
|
- Unpushed tags are force-repointed to HEAD after library commit so tags include regenerated books
|
|
111
211
|
|
|
112
212
|
### 🐛 Fixed
|
|
213
|
+
|
|
113
214
|
- Fixed create-pr using stale tag for comparison after library regeneration created a new commit
|
|
114
215
|
- Fixed create-pr running library pipeline in foreign repos where `.library/` paths were invalid (#186)
|
|
115
216
|
- Fixed bump-version crashing on non-semver version files (e.g., Maven `${revision}`) by excluding them from version resolution (#187)
|
|
116
217
|
- Fixed local tag lookup scanning tags from all branches instead of only the current HEAD branch (#185)
|
|
117
218
|
|
|
118
219
|
### 🗑️ Removed
|
|
220
|
+
|
|
119
221
|
- Removed per-file custom version editing (`promptEditField` option) from bump-version interactive selection
|
|
120
222
|
- Removed `promptMenu` four-option flow from bump-version in favor of direct toggle list
|
|
121
223
|
|
|
122
|
-
|
|
123
224
|
## [2.64.2] - 2026-06-08
|
|
124
225
|
|
|
125
226
|
### ✨ Added
|
|
227
|
+
|
|
126
228
|
- Multi-language extractor registry with pluggable extractor interface and JS extractor (AUT-3742, #184)
|
|
127
229
|
- Extractor notes template and per-extractor documentation standard (AUT-3742)
|
|
128
230
|
- Test harness for extractors with JS fixtures (AUT-3742)
|
|
@@ -131,6 +233,7 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
131
233
|
- Library maintenance pipeline step in create-pr to regenerate books before tagging (#187)
|
|
132
234
|
|
|
133
235
|
### 🔧 Changed
|
|
236
|
+
|
|
134
237
|
- Moved arrow-function extraction from monolithic extractor to pluggable JS extractor module (AUT-3742)
|
|
135
238
|
- Decoupled lib/ from .library/ imports — library integration now uses dynamic import with graceful degradation (AUT-3742)
|
|
136
239
|
- Library pipeline in create-pr derives paths from resolver.yaml config instead of hardcoded values (#186)
|
|
@@ -138,42 +241,47 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
138
241
|
- Tags are re-pointed to HEAD after library commit so tagged releases include regenerated books (#187)
|
|
139
242
|
|
|
140
243
|
### 🐛 Fixed
|
|
244
|
+
|
|
141
245
|
- Fixed bump-version crashing on non-semver version files (e.g., Maven `${revision}`) by excluding them from version resolution (#187)
|
|
142
246
|
- Fixed create-pr library pipeline leaking git-hooks paths into foreign repos (#186)
|
|
143
247
|
- Fixed local tag lookup scanning all branches instead of scoping to HEAD branch (#185)
|
|
144
248
|
- Fixed stale tags in create-pr when library pipeline generates a new commit after tag creation (#187)
|
|
145
249
|
|
|
146
250
|
### 🗑️ Removed
|
|
147
|
-
- Removed per-file custom version editing (option `e`) from bump-version interactive selection (#187)
|
|
148
251
|
|
|
252
|
+
- Removed per-file custom version editing (option `e`) from bump-version interactive selection (#187)
|
|
149
253
|
|
|
150
254
|
## [2.64.1] - 2026-06-08
|
|
151
255
|
|
|
152
256
|
### ✨ Added
|
|
257
|
+
|
|
153
258
|
- Multi-language extractor registry with pluggable architecture for Library book generation [AUT-3742] (#184)
|
|
154
259
|
- JS extractor as first pluggable extractor with Tree-sitter parsing, extractor notes template, and test harness [AUT-3742] (#184)
|
|
155
260
|
- ESLint rule preventing `lib/` from statically importing `.library/` modules [AUT-3742] (#184)
|
|
156
261
|
- Branch-scoped tag lookup functions `getLatestLocalTagOnBranch()` and `getLatestRemoteTagOnBranch()` in git-tag-manager (#185)
|
|
157
262
|
|
|
158
263
|
### 🔧 Changed
|
|
264
|
+
|
|
159
265
|
- Library pipeline (`createPrPipeline`) now derives `booksDir`/`sourceDir` from overridden `repoRoot`, preventing git-hooks paths from leaking into foreign repos (#186)
|
|
160
266
|
- Version alignment scoped to base branch tags instead of global tag list (#185)
|
|
161
267
|
- Bump-version interactive file selection simplified to direct toggle list with non-semver files pre-deselected
|
|
162
268
|
- Moved arrow-function extraction from monolithic `extract.js` to pluggable extractor module [AUT-3742]
|
|
163
269
|
|
|
164
270
|
### 🐛 Fixed
|
|
271
|
+
|
|
165
272
|
- Excluded non-semver files (e.g., Maven `${revision}`) from version resolution in bump-version command, preventing `parseVersion()` failures
|
|
166
273
|
- Fixed library pipeline using hardcoded git-hooks paths when running in foreign repos (#186)
|
|
167
274
|
- Scoped local tag lookup to HEAD branch to avoid cross-branch version pollution (#185)
|
|
168
275
|
|
|
169
276
|
### 🗑️ Removed
|
|
277
|
+
|
|
170
278
|
- Removed menu-based file selection (all/select/edit/cancel) from bump-version in favor of direct toggle list
|
|
171
279
|
- Removed per-file custom version entry (`targetVersion`) from interactive file selection
|
|
172
280
|
|
|
173
|
-
|
|
174
281
|
## [2.64.0] - 2026-06-08
|
|
175
282
|
|
|
176
283
|
### ✨ Added
|
|
284
|
+
|
|
177
285
|
- Multi-language extractor registry with pluggable interface and JS extractor (AUT-3742)
|
|
178
286
|
- Extractor notes template for documenting per-language extractors (AUT-3742)
|
|
179
287
|
- Test harness with JS fixtures for extractor validation (AUT-3742)
|
|
@@ -181,15 +289,16 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|
|
181
289
|
- ESLint `no-restricted-imports` rule preventing `lib/` from statically importing `.library/` modules (AUT-3742)
|
|
182
290
|
|
|
183
291
|
### 🔧 Changed
|
|
292
|
+
|
|
184
293
|
- Moved arrow-function extraction from monolithic `extract.js` to pluggable extractor module under `librarian/extractors/registered/js/` (AUT-3742)
|
|
185
294
|
- `validateVersionAlignment()` now accepts a `baseBranch` parameter, scoping version checks to the relevant branch tags instead of all tags
|
|
186
295
|
- Library pipeline (`createPrPipeline`) now derives `booksDir`/`sourceDir` from resolver config when `repoRoot` is overridden, preventing path leakage into foreign repos
|
|
187
296
|
|
|
188
297
|
### 🐛 Fixed
|
|
298
|
+
|
|
189
299
|
- Fixed local tag lookup returning tags from unrelated branches instead of scoping to HEAD branch
|
|
190
300
|
- Fixed library pipeline leaking git-hooks internal paths into foreign repos during PR creation (#185)
|
|
191
301
|
|
|
192
|
-
|
|
193
302
|
## [2.63.1] - 2026-06-03
|
|
194
303
|
|
|
195
304
|
### ✨ Added
|
package/README.md
CHANGED
|
@@ -308,6 +308,39 @@ claude-hooks batch-info
|
|
|
308
308
|
# Shows: per-model average analysis time and orchestration overhead (from telemetry)
|
|
309
309
|
```
|
|
310
310
|
|
|
311
|
+
### mscope Skill-Registry Integration (automation-skills)
|
|
312
|
+
|
|
313
|
+
Connects the hooks to the `@mscope/automation-skills` rule registry. No new commands — the integration runs inside `pre-commit` and `create-pr`.
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
# Setup (one of):
|
|
317
|
+
git clone https://github.com/mscope-S-L/automation-skills ../automation-skills # sibling of your repo
|
|
318
|
+
export CLAUDE_HOOKS_SKILL_REPO=/path/to/automation-skills # or explicit path
|
|
319
|
+
|
|
320
|
+
# Optional — enables freshness checks and lessons-learned capture:
|
|
321
|
+
npm install -g github:mscope-S-L/automation-skills
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**What it does on every commit:**
|
|
325
|
+
|
|
326
|
+
- Runs the registry's deterministic JBE/UIK rule checks against staged files and shows findings alongside lint + AI output (warn-only by default)
|
|
327
|
+
- Injects the rule catalogue into the Claude analysis prompt so AI findings are classified against rule IDs
|
|
328
|
+
- Findings the AI cannot classify are appended as `[skill-gap]` candidates to the **sibling skill repo's** `skill-feedback.md` (a cross-repo write — uncommitted, fingerprint-deduplicated, reviewed later via `automation-skills retro`, never auto-merged into the registry)
|
|
329
|
+
|
|
330
|
+
**What it does on `create-pr`:**
|
|
331
|
+
|
|
332
|
+
- Hands control to `automation-skills resume` (interactive) to record the branch's lessons-learned before tags are pushed. Skipped in headless mode or when the CLI is not installed.
|
|
333
|
+
|
|
334
|
+
**Configuration** (`.claude/config.json` overrides):
|
|
335
|
+
|
|
336
|
+
| Key | Default | Effect |
|
|
337
|
+
| --- | --- | --- |
|
|
338
|
+
| `skillRegistry.enabled` | `true` | Master switch for the whole integration |
|
|
339
|
+
| `skillRegistry.blockOn` | `"never"` | Block commits at/above a severity: `critical`, `high`, `medium`, `low` |
|
|
340
|
+
| `skillRegistry.resumeOnCreatePr` | `true` | Lessons-learned capture during `create-pr` |
|
|
341
|
+
|
|
342
|
+
**Use case:** team-wide antipattern enforcement with a feedback loop — the registry teaches the hooks, and unrecognized findings feed back into the registry. Everything silently no-ops when the skill repo isn't found; the integration is value-add, never a hard dependency.
|
|
343
|
+
|
|
311
344
|
### Other Commands
|
|
312
345
|
|
|
313
346
|
```bash
|
|
@@ -574,6 +607,7 @@ claude-hooks batch-info # Shows config + per-model avg speed from telemetry
|
|
|
574
607
|
- Max files per commit: 30
|
|
575
608
|
- Orchestrator threshold: 3 files
|
|
576
609
|
- Orchestrator model: opus (internal, not configurable)
|
|
610
|
+
- Skill registry: enabled, `blockOn: never` (warn-only), `resumeOnCreatePr: true` — silently inactive when the automation-skills repo isn't found
|
|
577
611
|
|
|
578
612
|
---
|
|
579
613
|
|
package/bin/claude-hooks
CHANGED
|
@@ -131,6 +131,25 @@ async function main() {
|
|
|
131
131
|
logger.debug('bin - main', 'Authorization guard bypassed (--headless)', { command: entry.name });
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
// --- Pre-command auto-update guard (silent, throttled) ---
|
|
135
|
+
// Single choke-point: every command flows through here, so auto-update is added
|
|
136
|
+
// once instead of in each command file. Mirrors the authorization guard above.
|
|
137
|
+
// Fully fail-open — never blocks the real command.
|
|
138
|
+
if (!isHeadless) {
|
|
139
|
+
try {
|
|
140
|
+
const { maybeAutoUpdate } = await import('../lib/utils/auto-update.js');
|
|
141
|
+
const updated = await maybeAutoUpdate(entry.name);
|
|
142
|
+
if (updated) {
|
|
143
|
+
// The running binary was just replaced; user must re-run their command.
|
|
144
|
+
process.exit(0);
|
|
145
|
+
}
|
|
146
|
+
} catch (err) {
|
|
147
|
+
logger.debug('bin - main', 'Pre-command auto-update skipped (non-fatal)', {
|
|
148
|
+
error: err.message
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
134
153
|
// --- Commands with special argument handling ---
|
|
135
154
|
|
|
136
155
|
// analyze: translate flags to options object
|
|
@@ -7,6 +7,7 @@ import fs from 'fs';
|
|
|
7
7
|
import { analyzeBranchForPR } from '../utils/pr-metadata-engine.js';
|
|
8
8
|
import { getConfig } from '../config.js';
|
|
9
9
|
import logger from '../utils/logger.js';
|
|
10
|
+
import { libraryModuleUrl, hasLibrary } from '../utils/library-resolver.js';
|
|
10
11
|
import { colors, error, info, checkGitRepo } from './helpers.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -93,31 +94,33 @@ export async function runAnalyzeDiff(args) {
|
|
|
93
94
|
console.log(result.testingNotes);
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
// Library staleness section
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
stalenessResult.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
97
|
+
// Library staleness section (only when the working repo has its own .library/)
|
|
98
|
+
if (hasLibrary()) {
|
|
99
|
+
try {
|
|
100
|
+
const { runAll } = await import(libraryModuleUrl('tools/staleness.js'));
|
|
101
|
+
const { getSourceDir, getBooksDir } = await import(libraryModuleUrl('paths.js'));
|
|
102
|
+
const { getRepoRoot } = await import('../utils/git-operations.js');
|
|
103
|
+
const stalenessResult = await runAll(getBooksDir(), getSourceDir(), getRepoRoot(), false);
|
|
104
|
+
const staleCount = stalenessResult.stale.length +
|
|
105
|
+
stalenessResult.orphan_books.length +
|
|
106
|
+
stalenessResult.unbooked_sources.length;
|
|
107
|
+
if (staleCount > 0) {
|
|
108
|
+
console.log('');
|
|
109
|
+
console.log(`📚 ${colors.yellow}Library Staleness:${colors.reset} ${staleCount} book(s) need attention`);
|
|
110
|
+
for (const item of stalenessResult.stale) {
|
|
111
|
+
console.log(` └─ stale: ${item.book}`);
|
|
112
|
+
}
|
|
113
|
+
for (const item of stalenessResult.orphan_books) {
|
|
114
|
+
console.log(` └─ orphan: ${item.book}`);
|
|
115
|
+
}
|
|
116
|
+
for (const src of stalenessResult.unbooked_sources) {
|
|
117
|
+
console.log(` └─ unbooked: ${src}`);
|
|
118
|
+
}
|
|
119
|
+
console.log(' Run: npm run library:regenerate');
|
|
110
120
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
for (const src of stalenessResult.unbooked_sources) {
|
|
115
|
-
console.log(` └─ unbooked: ${src}`);
|
|
116
|
-
}
|
|
117
|
-
console.log(' Run: npm run library:regenerate');
|
|
121
|
+
} catch {
|
|
122
|
+
logger.warning('📚 Library staleness check unavailable — .library/ tools not found');
|
|
118
123
|
}
|
|
119
|
-
} catch {
|
|
120
|
-
logger.warning('📚 Library staleness check unavailable — .library/ tools not found');
|
|
121
124
|
}
|
|
122
125
|
|
|
123
126
|
// Save the results in a file with context
|
package/lib/commands/analyze.js
CHANGED
|
@@ -43,6 +43,7 @@ import { generateResolutionPrompt } from '../utils/resolution-prompt.js';
|
|
|
43
43
|
import { getConfig } from '../config.js';
|
|
44
44
|
import { loadPreset } from '../utils/preset-loader.js';
|
|
45
45
|
import { CostTracker } from '../utils/cost-tracker.js';
|
|
46
|
+
import { getCatalogueSection } from '../utils/skill-registry/index.js';
|
|
46
47
|
import { getVersion } from '../utils/package-info.js';
|
|
47
48
|
import logger from '../utils/logger.js';
|
|
48
49
|
import { error, success, info } from './helpers.js';
|
|
@@ -219,7 +220,8 @@ export const runAnalyze = async (options = {}) => {
|
|
|
219
220
|
const result = await runAnalysis(filesData, config, {
|
|
220
221
|
hook: 'analyze',
|
|
221
222
|
headless,
|
|
222
|
-
costTracker
|
|
223
|
+
costTracker,
|
|
224
|
+
catalogueSection: getCatalogueSection({ repoRoot: getRepoRoot() })
|
|
223
225
|
});
|
|
224
226
|
|
|
225
227
|
// Write hooks-verified marker when analysis completes without critical/blocker issues.
|
|
@@ -58,6 +58,7 @@ import {
|
|
|
58
58
|
promptConfirmation
|
|
59
59
|
} from '../utils/interactive-ui.js';
|
|
60
60
|
import logger from '../utils/logger.js';
|
|
61
|
+
import { libraryModuleUrl, hasLibrary } from '../utils/library-resolver.js';
|
|
61
62
|
import { colors, error, checkGitRepo } from './helpers.js';
|
|
62
63
|
|
|
63
64
|
/** Default source branch for back-merge */
|
|
@@ -652,50 +653,55 @@ export async function runBackMerge(args) {
|
|
|
652
653
|
console.log('');
|
|
653
654
|
|
|
654
655
|
// 14b. Co-change correlation pipeline (AUT-3777)
|
|
656
|
+
// Only runs when the working repo has its own .library/ (the tool ships without one).
|
|
655
657
|
let coChangeReport = null;
|
|
656
|
-
|
|
657
|
-
|
|
658
|
+
if (!hasLibrary()) {
|
|
659
|
+
logger.debug('back-merge', 'No .library/ in current repo — skipping co-change pipeline');
|
|
660
|
+
} else {
|
|
661
|
+
try {
|
|
662
|
+
const { coChangePipeline } = await import(libraryModuleUrl('librarian/index.js'));
|
|
658
663
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
664
|
+
showInfo('Running co-change correlation pipeline...');
|
|
665
|
+
const summary = coChangePipeline({ repoCtx: {} });
|
|
666
|
+
const { modifiedFiles, perStep, report, warnings, mode } = summary;
|
|
662
667
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
668
|
+
// Surface summary to stdout
|
|
669
|
+
showInfo(
|
|
670
|
+
`Co-change: mode=${mode}, detected=${perStep.detection.modifications}, ` +
|
|
671
|
+
`injected=${perStep.injection.modifications}, warnings=${warnings.length}`
|
|
672
|
+
);
|
|
673
|
+
for (const w of warnings) {
|
|
674
|
+
showWarning(w);
|
|
675
|
+
}
|
|
671
676
|
|
|
672
|
-
|
|
673
|
-
|
|
677
|
+
// Save report for PR body attachment after push
|
|
678
|
+
coChangeReport = report;
|
|
674
679
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
} else {
|
|
678
|
-
const root = getRepoRoot();
|
|
679
|
-
const absFiles = modifiedFiles.map(f => path.isAbsolute(f) ? f : path.join(root, f));
|
|
680
|
-
const stageResult = stageFiles(absFiles);
|
|
681
|
-
|
|
682
|
-
if (!stageResult.success) {
|
|
683
|
-
showWarning(`Failed to stage co-change files: ${stageResult.error}`);
|
|
680
|
+
if (modifiedFiles.length === 0) {
|
|
681
|
+
showInfo('Co-change pipeline produced no Library changes');
|
|
684
682
|
} else {
|
|
685
|
-
const
|
|
686
|
-
const
|
|
687
|
-
const
|
|
683
|
+
const root = getRepoRoot();
|
|
684
|
+
const absFiles = modifiedFiles.map(f => path.isAbsolute(f) ? f : path.join(root, f));
|
|
685
|
+
const stageResult = stageFiles(absFiles);
|
|
688
686
|
|
|
689
|
-
if (!
|
|
690
|
-
showWarning(`Failed to
|
|
687
|
+
if (!stageResult.success) {
|
|
688
|
+
showWarning(`Failed to stage co-change files: ${stageResult.error}`);
|
|
691
689
|
} else {
|
|
692
|
-
|
|
690
|
+
const windowDesc = tagName ? `${tagName}..HEAD` : 'full history';
|
|
691
|
+
const libCommitMsg = `chore(library): co-change correlations for ${windowDesc}`;
|
|
692
|
+
const libCommit = createCommit(libCommitMsg);
|
|
693
|
+
|
|
694
|
+
if (!libCommit.success) {
|
|
695
|
+
showWarning(`Failed to commit co-change files: ${libCommit.error}`);
|
|
696
|
+
} else {
|
|
697
|
+
showSuccess(`Co-change committed: ${libCommitMsg} (${modifiedFiles.length} file(s))`);
|
|
698
|
+
}
|
|
693
699
|
}
|
|
694
700
|
}
|
|
701
|
+
} catch (err) {
|
|
702
|
+
logger.warning(`co-change pipeline skipped: ${err.message}`);
|
|
703
|
+
logger.debug('back-merge', 'Co-change pipeline skipped', { error: err.message });
|
|
695
704
|
}
|
|
696
|
-
} catch (err) {
|
|
697
|
-
logger.warning(`co-change pipeline skipped: ${err.message}`);
|
|
698
|
-
logger.debug('back-merge', 'Co-change pipeline skipped', { error: err.message });
|
|
699
705
|
}
|
|
700
706
|
|
|
701
707
|
// 15. Verify sync
|
|
@@ -24,8 +24,7 @@ import {
|
|
|
24
24
|
discoverVersionFiles,
|
|
25
25
|
incrementVersion,
|
|
26
26
|
modifySuffix,
|
|
27
|
-
updateVersionFiles
|
|
28
|
-
validateVersionFormat
|
|
27
|
+
updateVersionFiles
|
|
29
28
|
} from '../utils/version-manager.js';
|
|
30
29
|
import { createTag, pushTags, tagExists, formatTagName } from '../utils/git-tag-manager.js';
|
|
31
30
|
import {
|
|
@@ -51,6 +50,7 @@ import {
|
|
|
51
50
|
promptToggleList
|
|
52
51
|
} from '../utils/interactive-ui.js';
|
|
53
52
|
import logger from '../utils/logger.js';
|
|
53
|
+
import { libraryModuleUrl, hasLibrary } from '../utils/library-resolver.js';
|
|
54
54
|
import { colors, error, checkGitRepo } from './helpers.js';
|
|
55
55
|
import {
|
|
56
56
|
CONSOLE_WARNING_TEMPLATE,
|
|
@@ -414,20 +414,25 @@ export async function runBumpVersion(args) {
|
|
|
414
414
|
|
|
415
415
|
showSuccess('Prerequisites validated');
|
|
416
416
|
|
|
417
|
-
// Library verification gate — silent on clean, loud-warn on stale, never-hard-fail
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
417
|
+
// Library verification gate — silent on clean, loud-warn on stale, never-hard-fail.
|
|
418
|
+
// Only runs when the working repo has its own .library/ (the tool ships without one).
|
|
419
|
+
if (!hasLibrary()) {
|
|
420
|
+
logger.debug('bump-version', 'No .library/ in current repo — skipping Library verification gate');
|
|
421
|
+
} else {
|
|
422
|
+
logger.debug('bump-version', 'Running Library verification gate');
|
|
423
|
+
try {
|
|
424
|
+
const { verify } = await import(libraryModuleUrl('librarian/index.js'));
|
|
425
|
+
const verifyResult = await verify();
|
|
422
426
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
+
if (verifyResult.clean) {
|
|
428
|
+
logger.debug('bump-version', 'Library is clean — no warning needed');
|
|
429
|
+
} else {
|
|
430
|
+
_emitLibraryWarning(verifyResult);
|
|
431
|
+
}
|
|
432
|
+
} catch (verifyErr) {
|
|
433
|
+
const msg = `\n${colors.yellow} ${LIBRARY_VERIFY_SKIPPED_WARNING} ${verifyErr.message}${colors.reset}\n\n`;
|
|
434
|
+
process.stderr.write(msg);
|
|
427
435
|
}
|
|
428
|
-
} catch (verifyErr) {
|
|
429
|
-
const msg = `\n${colors.yellow} ${LIBRARY_VERIFY_SKIPPED_WARNING} ${verifyErr.message}${colors.reset}\n\n`;
|
|
430
|
-
process.stderr.write(msg);
|
|
431
436
|
}
|
|
432
437
|
|
|
433
438
|
// Step 2: Discover all version files
|
|
@@ -478,7 +483,7 @@ export async function runBumpVersion(args) {
|
|
|
478
483
|
? uniqueSelected[0]
|
|
479
484
|
: discovery.resolvedVersion;
|
|
480
485
|
|
|
481
|
-
if (!currentVersion
|
|
486
|
+
if (!currentVersion) {
|
|
482
487
|
showError('Could not determine a valid semver version from selected files');
|
|
483
488
|
process.exit(1);
|
|
484
489
|
}
|