claude-git-hooks 2.61.2 → 2.67.3

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 CHANGED
@@ -5,45 +5,371 @@ 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.67.3] - 2026-06-12
9
+
10
+ ### ✨ Added
11
+ - Upfront CLI availability probe in gotcha solicitation — checks once per run instead of discovering failures per-book (#195)
12
+ - New `llm.js` shared CLI wrapper for the librarian pipeline, using the developer's `claude` login session
13
+
14
+ ### 🔧 Changed
15
+ - Replaced Anthropic SDK (`@anthropic-ai/sdk`) with CLI wrapper (`llm.js`) in the librarian's candidate-text-generator (#195)
16
+ - Default model identifier simplified from `claude-sonnet-4-6` to `sonnet` shorthand
17
+ - Gotcha solicitation skips per-book candidate generation entirely when CLI is unavailable, showing a single message instead of one warning per book
18
+ - Tests updated to mock the CLI wrapper instead of the Anthropic SDK
19
+
20
+ ### 🐛 Fixed
21
+ - Resolved library pipeline resolver issues when Anthropic API key is unavailable — librarian now works with just a `claude` CLI login (#195)
22
+
23
+ ### 🗑️ Removed
24
+ - Removed `_classifyError()` helper and all SDK-specific error classification logic from candidate-text-generator
25
+ - Removed direct dependency on `@anthropic-ai/sdk` in the librarian pipeline
26
+
27
+
28
+ ## [2.67.2] - 2026-06-11
29
+
30
+ ### 🔧 Changed
31
+ - 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
32
+ - 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
33
+
34
+ ### 🐛 Fixed
35
+ - Commands no longer produce misleading warnings or errors when the tool is installed as a dependency in repos that have no `.library/` (#194)
36
+ - Sanitized version output at source (#194)
37
+
38
+
39
+ ## [2.67.1] - 2026-06-11
40
+
41
+ ### 🐛 Fixed
42
+ - Sanitized non-semver versions at discovery source in version-manager, preventing invalid version strings from propagating through the bump-version pipeline
43
+
44
+ ### 🗑️ Removed
45
+ - Removed unused `test:full` npm script from package.json
46
+
47
+
48
+ ## [2.67.0] - 2026-06-10
49
+
50
+ ### ✨ Added
51
+
52
+ - 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)
53
+ - 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)
54
+ - 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)
55
+ - `skillRegistry` configuration section (`enabled`, `blockOn`, `resumeOnCreatePr`) registered in package defaults, overridable remotely and per-repo, documented in `config.advanced.example.json`
56
+ - Unit tests for the skill-registry: parser, runner, catalogue, feedback-writer, facade, and resume modules
57
+
58
+ ### 🔧 Changed
59
+
60
+ - 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
61
+ - `analyze` command injects the same rule catalogue into its analysis prompt for parity with pre-commit
62
+ - `CLAUDE_ANALYSIS_PROMPT.md` now instructs Claude to classify each finding against the injected catalogue via `details[].rule`
63
+ - 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
64
+
65
+ ### 🐛 Fixed
66
+
67
+ - 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
68
+ - 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
69
+ - Repaired skill-registry text injections that were being corrupted by suggestion-click commits
70
+ - Skill-gap writer failures during pre-commit are now logged as warnings instead of silently discarded (the commit is never blocked either way)
71
+
72
+ ### 🗑️ Removed
73
+
74
+ - Removed the legacy `mscope-automation--claude-skills` sibling skill-repo name from registry resolution, leaving only the current `automation-skills` name
75
+
76
+ ## [2.66.1] - 2026-06-10
77
+
78
+ ### 🐛 Fixed
79
+
80
+ - Normalized path separators to forward slashes in staleness checker for cross-platform compatibility
81
+
82
+ ## [2.66.0] - 2026-06-10
83
+
84
+ ### ✨ Added
85
+
86
+ - Multi-language extractor registry with pluggable per-language architecture [AUT-3742]
87
+ - End-to-end SDLC stability check test suite
88
+ - Version alignment validation now scoped to base branch tags (#185)
89
+ - Extractor notes template for documenting per-language extractors
90
+
91
+ ### 🔧 Changed
92
+
93
+ - Moved arrow-function extraction from monolithic extractor to pluggable extractor module [AUT-3742]
94
+ - Decoupled `lib/` from `.library/` static imports with ESLint enforcement rule [AUT-3742]
95
+ - Library maintenance pipeline now runs before tag push in `create-pr`, ensuring library books are included in tagged commits
96
+ - Simplified `bump-version` interactive file selection to direct toggle list, removing multi-choice menu
97
+ - Tags are force-repointed to HEAD after library commit so tagged version includes regenerated books
98
+
99
+ ### 🐛 Fixed
100
+
101
+ - Fixed `create-pr` gotcha solicitation receiving empty file paths instead of actual book content (#190)
102
+ - Fixed `create-pr` tag comparison using global tag list instead of base branch scope
103
+ - Fixed `create-pr` library pipeline leaking host-repo paths into foreign repositories (#186)
104
+ - Fixed `bump-version` crashing on non-semver version files such as Maven `${revision}` placeholders (#187)
105
+ - Fixed version tag lookup scanning all branches instead of only the HEAD branch (#185)
106
+ - Fixed stale git worktree leftovers causing integration test failures
107
+
108
+ ### 🗑️ Removed
109
+
110
+ - Removed per-file custom version entry option (`promptEditField`) from `bump-version` interactive selection
111
+
112
+ ## [2.65.0] - 2026-06-08
113
+
114
+ ### ✨ Added
115
+
116
+ - Multi-language extractor registry with pluggable per-language extractors (AUT-3742)
117
+ - Extractor interface contract and runtime validator for language extractor plugins (AUT-3742)
118
+ - JS extractor notes template for documenting new extractors (AUT-3742)
119
+ - Test harness with JS fixtures for extractor validation (AUT-3742)
120
+ - Version alignment now scoped to base branch tags instead of global tag lookup
121
+
122
+ ### 🔧 Changed
123
+
124
+ - Arrow-function extraction moved from monolithic extract.js to pluggable JS extractor module (AUT-3742)
125
+ - Decoupled lib/ from .library/ static imports with ESLint enforcement — lib/ must use dynamic import() for Library integration (AUT-3742)
126
+ - Library maintenance pipeline in create-pr now runs before tag push so tags include regenerated books
127
+ - Unpushed tags are force-repointed to HEAD after library commit to include book changes
128
+ - Gotcha solicitation now receives full book content instead of just file paths
129
+ - bump-version interactive file selection simplified — goes directly to toggle list, non-semver files pre-deselected
130
+
131
+ ### 🐛 Fixed
132
+
133
+ - Fixed create-pr library pipeline running incorrectly in foreign repos by deriving paths from resolver config (#186)
134
+ - Fixed bump-version crash when non-semver files (e.g., Maven `${revision}`) reached version parser (#187)
135
+ - Fixed create-pr comparing tags against global scope instead of base branch (#185, #189)
136
+ - Fixed create-pr using stale tag reference after library pipeline commit
137
+ - Fixed local tag lookup not scoped to HEAD branch, causing cross-branch version mismatches
138
+
139
+ ### 🗑️ Removed
140
+
141
+ - Removed per-file custom version editing (option `e`) from bump-version interactive selection
142
+ - Removed `promptMenu` and `promptEditField` usage from bump-version flow
143
+
144
+ ## [2.64.4] - 2026-06-08
145
+
146
+ ### ✨ Added
147
+
148
+ - Added multi-language extractor registry with pluggable architecture and runtime interface validation (AUT-3742, #184)
149
+ - Added JS extractor as first pluggable extractor with dedicated test harness and fixtures (AUT-3742)
150
+ - Added extractor notes template for documenting per-language extractors (AUT-3742)
151
+ - Added branch-scoped tag lookup functions `getLatestLocalTagOnBranch()` and `getLatestRemoteTagOnBranch()` to git-tag-manager (#185)
152
+ - Added branch-scoped version alignment validation in `create-pr` (#185)
153
+
154
+ ### 🔧 Changed
155
+
156
+ - Decoupled `lib/` from `.library/` static imports with ESLint restricted-imports guard (AUT-3742)
157
+ - Moved arrow-function extraction from monolithic extractor into pluggable JS extractor module (AUT-3742)
158
+ - Simplified `bump-version` interactive file selection — removed menu, goes directly to toggle list with non-semver files pre-deselected (#187)
159
+ - Library pipeline in `create-pr` now derives paths from resolver config, preventing git-hooks paths from leaking into foreign repos (#186)
160
+ - Reordered `create-pr` steps so library pipeline runs before tag push, then re-points unpushed tags to HEAD to include library commits
161
+
162
+ ### 🐛 Fixed
163
+
164
+ - Fixed `bump-version` crash when non-semver files (e.g., Maven `${revision}`) were included in version resolution (#187)
165
+ - Fixed `create-pr` library pipeline using hardcoded paths that broke in foreign repositories (#186)
166
+ - Fixed version alignment and tag lookup returning results from unrelated branches instead of scoping to base branch (#185)
167
+ - Fixed `create-pr` tag becoming stale after library book regeneration by running the pipeline before tag push and re-pointing tags
168
+
169
+ ### 🗑️ Removed
170
+
171
+ - Removed `promptMenu` and `promptEditField` options from `bump-version` interactive file selection (#187)
172
+
173
+ ## [2.64.3] - 2026-06-08
174
+
175
+ ### ✨ Added
176
+
177
+ - Added multi-language extractor registry with pluggable interface, including JS extractor and notes template (AUT-3742)
178
+ - Added library maintenance pipeline step in create-pr that regenerates books before tag push
179
+ - Added branch-scoped tag lookup functions (`getLatestLocalTagOnBranch`, `getLatestRemoteTagOnBranch`) to git-tag-manager
180
+ - Added ESLint rule preventing `lib/` from statically importing `.library/` modules (AUT-3742)
181
+ - Added extractor test harness with JS fixtures (AUT-3742)
182
+
183
+ ### 🔧 Changed
184
+
185
+ - Moved arrow-function extraction from monolithic `extract.js` into pluggable extractor under `librarian/extractors/registered/js/` (AUT-3742)
186
+ - Scoped version alignment validation to base branch tags instead of global tag lookup
187
+ - Simplified bump-version interactive file selection — goes directly to toggle list, non-semver files pre-deselected
188
+ - Library pipeline now derives booksDir/sourceDir from resolver config when repoRoot is overridden, preventing path leakage into foreign repos
189
+ - Unpushed tags are force-repointed to HEAD after library commit so tags include regenerated books
190
+
191
+ ### 🐛 Fixed
192
+
193
+ - Fixed create-pr using stale tag for comparison after library regeneration created a new commit
194
+ - Fixed create-pr running library pipeline in foreign repos where `.library/` paths were invalid (#186)
195
+ - Fixed bump-version crashing on non-semver version files (e.g., Maven `${revision}`) by excluding them from version resolution (#187)
196
+ - Fixed local tag lookup scanning tags from all branches instead of only the current HEAD branch (#185)
197
+
198
+ ### 🗑️ Removed
199
+
200
+ - Removed per-file custom version editing (`promptEditField` option) from bump-version interactive selection
201
+ - Removed `promptMenu` four-option flow from bump-version in favor of direct toggle list
202
+
203
+ ## [2.64.2] - 2026-06-08
204
+
205
+ ### ✨ Added
206
+
207
+ - Multi-language extractor registry with pluggable extractor interface and JS extractor (AUT-3742, #184)
208
+ - Extractor notes template and per-extractor documentation standard (AUT-3742)
209
+ - Test harness for extractors with JS fixtures (AUT-3742)
210
+ - ESLint rule preventing lib/ from statically importing .library/ modules (AUT-3742)
211
+ - Version alignment now scoped to base branch tags for accurate cross-branch comparisons (#185)
212
+ - Library maintenance pipeline step in create-pr to regenerate books before tagging (#187)
213
+
214
+ ### 🔧 Changed
215
+
216
+ - Moved arrow-function extraction from monolithic extractor to pluggable JS extractor module (AUT-3742)
217
+ - Decoupled lib/ from .library/ imports — library integration now uses dynamic import with graceful degradation (AUT-3742)
218
+ - Library pipeline in create-pr derives paths from resolver.yaml config instead of hardcoded values (#186)
219
+ - Simplified bump-version interactive file selection to use toggle list directly, removing menu options (a/s/e/c) (#187)
220
+ - Tags are re-pointed to HEAD after library commit so tagged releases include regenerated books (#187)
221
+
222
+ ### 🐛 Fixed
223
+
224
+ - Fixed bump-version crashing on non-semver version files (e.g., Maven `${revision}`) by excluding them from version resolution (#187)
225
+ - Fixed create-pr library pipeline leaking git-hooks paths into foreign repos (#186)
226
+ - Fixed local tag lookup scanning all branches instead of scoping to HEAD branch (#185)
227
+ - Fixed stale tags in create-pr when library pipeline generates a new commit after tag creation (#187)
228
+
229
+ ### 🗑️ Removed
230
+
231
+ - Removed per-file custom version editing (option `e`) from bump-version interactive selection (#187)
232
+
233
+ ## [2.64.1] - 2026-06-08
234
+
235
+ ### ✨ Added
236
+
237
+ - Multi-language extractor registry with pluggable architecture for Library book generation [AUT-3742] (#184)
238
+ - JS extractor as first pluggable extractor with Tree-sitter parsing, extractor notes template, and test harness [AUT-3742] (#184)
239
+ - ESLint rule preventing `lib/` from statically importing `.library/` modules [AUT-3742] (#184)
240
+ - Branch-scoped tag lookup functions `getLatestLocalTagOnBranch()` and `getLatestRemoteTagOnBranch()` in git-tag-manager (#185)
241
+
242
+ ### 🔧 Changed
243
+
244
+ - Library pipeline (`createPrPipeline`) now derives `booksDir`/`sourceDir` from overridden `repoRoot`, preventing git-hooks paths from leaking into foreign repos (#186)
245
+ - Version alignment scoped to base branch tags instead of global tag list (#185)
246
+ - Bump-version interactive file selection simplified to direct toggle list with non-semver files pre-deselected
247
+ - Moved arrow-function extraction from monolithic `extract.js` to pluggable extractor module [AUT-3742]
248
+
249
+ ### 🐛 Fixed
250
+
251
+ - Excluded non-semver files (e.g., Maven `${revision}`) from version resolution in bump-version command, preventing `parseVersion()` failures
252
+ - Fixed library pipeline using hardcoded git-hooks paths when running in foreign repos (#186)
253
+ - Scoped local tag lookup to HEAD branch to avoid cross-branch version pollution (#185)
254
+
255
+ ### 🗑️ Removed
256
+
257
+ - Removed menu-based file selection (all/select/edit/cancel) from bump-version in favor of direct toggle list
258
+ - Removed per-file custom version entry (`targetVersion`) from interactive file selection
259
+
260
+ ## [2.64.0] - 2026-06-08
261
+
262
+ ### ✨ Added
263
+
264
+ - Multi-language extractor registry with pluggable interface and JS extractor (AUT-3742)
265
+ - Extractor notes template for documenting per-language extractors (AUT-3742)
266
+ - Test harness with JS fixtures for extractor validation (AUT-3742)
267
+ - Branch-scoped tag lookup methods `getLatestLocalTagOnBranch()` and `getLatestRemoteTagOnBranch()` in git-tag-manager
268
+ - ESLint `no-restricted-imports` rule preventing `lib/` from statically importing `.library/` modules (AUT-3742)
269
+
270
+ ### 🔧 Changed
271
+
272
+ - Moved arrow-function extraction from monolithic `extract.js` to pluggable extractor module under `librarian/extractors/registered/js/` (AUT-3742)
273
+ - `validateVersionAlignment()` now accepts a `baseBranch` parameter, scoping version checks to the relevant branch tags instead of all tags
274
+ - Library pipeline (`createPrPipeline`) now derives `booksDir`/`sourceDir` from resolver config when `repoRoot` is overridden, preventing path leakage into foreign repos
275
+
276
+ ### 🐛 Fixed
277
+
278
+ - Fixed local tag lookup returning tags from unrelated branches instead of scoping to HEAD branch
279
+ - Fixed library pipeline leaking git-hooks internal paths into foreign repos during PR creation (#185)
280
+
281
+ ## [2.63.1] - 2026-06-03
282
+
283
+ ### ✨ Added
284
+
285
+ - Multi-language extractor registry with pluggable interface and runtime validation (AUT-3742, #184)
286
+ - JS extractor as first pluggable extractor with full EXTRACTOR_NOTES documentation (AUT-3742)
287
+ - Extractor notes template for documenting new language extractors (AUT-3742)
288
+ - Test harness with JS fixtures for extractor validation (AUT-3742)
289
+ - Version alignment scoped to base branch tags for accurate cross-branch versioning
290
+
291
+ ### 🔧 Changed
292
+
293
+ - Decoupled lib/ from .library/ imports with ESLint no-restricted-imports rule to enforce package boundary (AUT-3742)
294
+ - Refactored arrow-function extraction from monolithic extract.js into pluggable JS extractor module (AUT-3742)
295
+
296
+ ### 🐛 Fixed
297
+
298
+ - Scoped local tag lookup to HEAD branch to prevent cross-branch version conflicts
299
+
300
+ ## [2.63.0] - 2026-06-03
301
+
302
+ ### ✨ Added
303
+
304
+ - Added multi-language extractor registry with convention-driven loader, priority-based lookup, and warn-and-skip error handling (AUT-3742)
305
+ - Added Extractor interface definition with JSDoc types and runtime validator for pluggable per-language extractors (AUT-3742)
306
+ - Added JS/ESM pluggable extractor conforming to the new Extractor interface (AUT-3742)
307
+ - Added extractor notes template and canonical JS extractor documentation covering supported constructs, known limitations, and test fixtures (AUT-3742)
308
+ - Added ESLint `no-restricted-imports` rule preventing `lib/` from statically importing `.library/` modules (AUT-3742)
309
+ - Added extractor test harness with JS fixtures for eight construct categories (AUT-3742)
310
+
311
+ ### 🔧 Changed
312
+
313
+ - Refactored arrow-function extraction from monolithic `extract.js` into standalone pluggable extractor module under `librarian/extractors/registered/js/` (AUT-3742)
314
+ - Decoupled `lib/` source code from `.library/` imports — runtime integration now requires dynamic `import()` with graceful degradation (AUT-3742)
315
+
316
+ ## [2.62.0] - 2026-06-02
317
+
318
+ ### ✨ Added
319
+
320
+ - Added structure detector pipeline for Library bootstrap — 3-stage detection (filesystem scan → Haiku inference → interactive console) that generates `.library/structure.yaml` config (AUT-3741)
321
+ - Added deterministic filesystem scanner with configurable depth/child limits, BOM file detection, and language-by-layer counting (AUT-3741)
322
+ - Added Haiku-based structure inference with exponential-backoff retry, scanner-detected language reconciliation, and graceful degradation to stub config on API failure (AUT-3741)
323
+ - Added interactive 3-option console flow (Accept / Reject / Retry) with re-run safety supporting Keep / Overwrite / Merge of existing configs (AUT-3741)
324
+ - Added structure detector documentation to Library README including sequence diagram, consumer contract, config format, and worked example (AUT-3741)
325
+
326
+ ### 🐛 Fixed
327
+
328
+ - Fixed tag staleness during Library regeneration (#179)
329
+
8
330
  ## [2.61.2] - 2026-06-01
9
331
 
10
332
  ### 🐛 Fixed
11
- - Fixed incorrect import path for gotcha solicitation in PR pipeline
12
333
 
334
+ - Fixed incorrect import path for gotcha solicitation in PR pipeline
13
335
 
14
336
  ## [2.61.1] - 2026-06-01
15
337
 
16
338
  ### ✨ Added
339
+
17
340
  - Auto-regeneration of stale Library books during `create-release` — stale books are now regenerated before the release is tagged, keeping the tag accurate (#178, AUT-3738)
18
341
 
19
342
  ### 🔧 Changed
343
+
20
344
  - Staleness warning templates are now context-aware: `CONSOLE_WARNING_TEMPLATE` and `PR_BODY_SECTION_TEMPLATE` accept an `autoRegen` option to tailor messaging per consumer (`will-run` for create-release, `deferred` for bump-version, `completed`/`failed` in PR body)
21
345
  - PR body staleness section now reflects the actual auto-regeneration outcome instead of always listing remediation scripts
22
346
  - Console staleness warning in `bump-version` now tells the user that Library will be auto-regenerated when they run `create-pr`
23
347
 
24
348
  ### 🗑️ Removed
25
- - Removed static recommended-scripts list from console staleness warnings (replaced by context-aware auto-regeneration messages)
26
349
 
350
+ - Removed static recommended-scripts list from console staleness warnings (replaced by context-aware auto-regeneration messages)
27
351
 
28
352
  ## [2.61.0] - 2026-06-01
29
353
 
30
354
  ### ✨ Added
355
+
31
356
  - Added canonical staleness-warning templates (`CONSOLE_WARNING_TEMPLATE`, `PR_BODY_SECTION_TEMPLATE`, `PR_TAG_VALUE`) for consistent Library staleness messaging across all consumer commands (AUT-3738)
32
357
  - Added non-blocking Library staleness verification gate to the `create-release` workflow — warns operators when Library books are out of date without blocking the release (AUT-3738)
33
358
  - Added automatic release PR creation step in `create-release` with idempotency check, staleness section in PR body wrapped in marker comments, and `library-stale` label when applicable (AUT-3738)
34
359
  - Added `LIBRARY_VERIFY_SKIPPED_WARNING_RELEASE` constant for release-specific Library verification skip messaging (AUT-3738)
35
360
 
36
361
  ### 🔧 Changed
362
+
37
363
  - Refactored `bump-version` Library warning to use the canonical `CONSOLE_WARNING_TEMPLATE` instead of inline formatting (AUT-3738)
38
364
  - Changed `create-release` Library staleness gate from blocking (exit on stale) to non-blocking (warn and continue), using the librarian `verify()` API instead of raw staleness tools (AUT-3738)
39
365
  - Refactored `library-warnings.js` to re-export canonical wording from the librarian messages module instead of defining constants inline (AUT-3738)
40
366
  - Updated Library books for `create-release`, `bump-version`, and `library-warnings` to reflect new dependencies and exports (AUT-3738)
41
367
 
42
368
  ### 🗑️ Removed
369
+
43
370
  - Removed blocking Library staleness check from `create-release` that imported `.library/tools/staleness.js` directly and aborted on drift (AUT-3738)
44
371
  - Removed `LIBRARY_STALE_WARNING` constant from `library-warnings.js`, replaced by canonical `CONSOLE_WARNING_TEMPLATE` (AUT-3738)
45
372
 
46
-
47
373
  ## [2.61.0] - 2026-05-29
48
374
 
49
375
  ### ✨ 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
 
@@ -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
- try {
98
- const { runAll } = await import('../../.library/tools/staleness.js');
99
- const { getSourceDir, getBooksDir } = await import('../../.library/paths.js');
100
- const { getRepoRoot } = await import('../utils/git-operations.js');
101
- const stalenessResult = await runAll(getBooksDir(), getSourceDir(), getRepoRoot(), false);
102
- const staleCount = stalenessResult.stale.length +
103
- stalenessResult.orphan_books.length +
104
- stalenessResult.unbooked_sources.length;
105
- if (staleCount > 0) {
106
- console.log('');
107
- console.log(`📚 ${colors.yellow}Library Staleness:${colors.reset} ${staleCount} book(s) need attention`);
108
- for (const item of stalenessResult.stale) {
109
- console.log(` └─ stale: ${item.book}`);
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
- for (const item of stalenessResult.orphan_books) {
112
- console.log(` └─ orphan: ${item.book}`);
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
@@ -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
- try {
657
- const { coChangePipeline } = await import('../../.library/librarian/index.js');
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
- showInfo('Running co-change correlation pipeline...');
660
- const summary = coChangePipeline({ repoCtx: {} });
661
- const { modifiedFiles, perStep, report, warnings, mode } = summary;
664
+ showInfo('Running co-change correlation pipeline...');
665
+ const summary = coChangePipeline({ repoCtx: {} });
666
+ const { modifiedFiles, perStep, report, warnings, mode } = summary;
662
667
 
663
- // Surface summary to stdout
664
- showInfo(
665
- `Co-change: mode=${mode}, detected=${perStep.detection.modifications}, ` +
666
- `injected=${perStep.injection.modifications}, warnings=${warnings.length}`
667
- );
668
- for (const w of warnings) {
669
- showWarning(w);
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
- // Save report for PR body attachment after push
673
- coChangeReport = report;
677
+ // Save report for PR body attachment after push
678
+ coChangeReport = report;
674
679
 
675
- if (modifiedFiles.length === 0) {
676
- showInfo('Co-change pipeline produced no Library changes');
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 windowDesc = tagName ? `${tagName}..HEAD` : 'full history';
686
- const libCommitMsg = `chore(library): co-change correlations for ${windowDesc}`;
687
- const libCommit = createCommit(libCommitMsg);
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 (!libCommit.success) {
690
- showWarning(`Failed to commit co-change files: ${libCommit.error}`);
687
+ if (!stageResult.success) {
688
+ showWarning(`Failed to stage co-change files: ${stageResult.error}`);
691
689
  } else {
692
- showSuccess(`Co-change committed: ${libCommitMsg} (${modifiedFiles.length} file(s))`);
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