📦 deps(thirdparty): update snapshots
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
{
|
||||
"name": "brooks-lint",
|
||||
"description": "AI code reviews grounded in twelve classic engineering books — decay risk diagnostics with book citations, severity labels, and six analysis modes (PR review, architecture audit, tech debt, test quality, health dashboard, full-sweep auto-fix)",
|
||||
"version": "1.4.0",
|
||||
"version": "1.4.1",
|
||||
"source": "./",
|
||||
"author": {
|
||||
"name": "hyhmrright",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "brooks-lint",
|
||||
"description": "AI code reviews grounded in twelve classic engineering books — decay risk diagnostics with book citations, severity labels, and six analysis modes (PR review, architecture audit, tech debt, test quality, health dashboard, full-sweep auto-fix)",
|
||||
"version": "1.4.0",
|
||||
"version": "1.4.1",
|
||||
"author": {
|
||||
"name": "hyhmrright",
|
||||
"email": "hyhmrright@gmail.com"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "brooks-lint",
|
||||
"version": "1.4.0",
|
||||
"version": "1.4.1",
|
||||
"description": "AI code reviews grounded in twelve classic engineering books — decay risk diagnostics with book citations, severity labels, and six analysis modes (PR review, architecture audit, tech debt, test quality, health dashboard, full-sweep auto-fix)",
|
||||
"author": {
|
||||
"name": "hyhmrright",
|
||||
|
||||
+12
-2
@@ -16,11 +16,21 @@ jobs:
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [20, 22, 24]
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- name: Set up Node.js
|
||||
- name: Set up Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Validate repository consistency
|
||||
run: node scripts/validate-repo.mjs
|
||||
- name: Unit tests
|
||||
run: npm test
|
||||
- name: Parser benchmark (frozen corpus)
|
||||
run: npm run benchmark
|
||||
- name: Structural eval suite
|
||||
run: npm run evals
|
||||
|
||||
@@ -4,6 +4,27 @@ All notable changes to brooks-lint are documented here.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.4.1] - 2026-07-18
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Infinite Skill-invocation loop on model-invoked commands** ([#21]) — the
|
||||
`commands/brooks-*.md` wrappers were purely self-referential ("Use the Skill
|
||||
tool to invoke `brooks-lint:brooks-review`"). Combined with an upstream Claude
|
||||
Code bug ([anthropics/claude-code#54535], closed NOT_PLANNED) that re-injects a
|
||||
command body without its `<command-name>` tag after a model-invoked Skill call,
|
||||
the model could loop: call Skill → body re-injected → call Skill again, never
|
||||
running the skill. Each wrapper now **reads its skill's `SKILL.md` directly**
|
||||
instead of calling the Skill tool, so the re-injection path is never triggered
|
||||
and the skill runs once. The session-start hook bakes the absolute
|
||||
`${CLAUDE_PLUGIN_ROOT}` path into the installed short forms, since that variable
|
||||
does not expand in user commands under `~/.claude/commands/`. Cross-platform
|
||||
safe: `commands/` is still consumed as-is by the Gemini extension, and Codex is
|
||||
unaffected (it loads `skills/` only).
|
||||
|
||||
[#21]: https://github.com/hyhmrright/brooks-lint/issues/21
|
||||
[anthropics/claude-code#54535]: https://github.com/anthropics/claude-code/issues/54535
|
||||
|
||||
## [1.4.0] - 2026-06-19
|
||||
|
||||
### Added
|
||||
|
||||
@@ -31,7 +31,7 @@ Guidance for Claude Code when modifying this repository. For repo layout, instal
|
||||
- **SKILL.md trigger descriptions:** Every `description:` field MUST include a "Do NOT trigger for:" clause. Without it, false triggering occurs (e.g. `brooks-debt` firing on HTTP `/health` questions).
|
||||
- **Book count is derived, never hardcoded:** `validate-repo.mjs` reads `source-coverage.md` frontmatter and derives `sourceCount` from it. Adding a book = update the frontmatter list + add the corresponding section; the validator auto-adapts.
|
||||
- **`package.json` is ESM:** `"type": "module"` enables ESM for everything in `scripts/`. Skills are plain markdown — no bundling.
|
||||
- **Slash commands:** Plugin skills register as `/brooks-lint:brooks-review`. Short forms (`/brooks-review`, `/brooks-audit`, `/brooks-debt`, `/brooks-test`, `/brooks-health`, `/brooks-sweep`) are auto-installed to `~/.claude/commands/` by the session-start hook — they are thin wrappers, not separate definitions.
|
||||
- **Slash commands:** Plugin skills register as `/brooks-lint:brooks-review`. Short forms (`/brooks-review`, `/brooks-audit`, `/brooks-debt`, `/brooks-test`, `/brooks-health`, `/brooks-sweep`) are auto-installed to `~/.claude/commands/` by the session-start hook — they are thin wrappers, not separate definitions. Each wrapper body must **`Read` its skill's `SKILL.md` directly**, NOT "use the Skill tool to invoke …" — a purely self-referential body loops forever when the skill is model-invoked (upstream re-injects the body without the `<command-name>` tag; issue #21 / `anthropics/claude-code#54535`). The hook substitutes `${CLAUDE_PLUGIN_ROOT}` → the absolute plugin path when installing short forms, because that variable does not expand in user commands. `commands/*.md` is shared: the Gemini extension (`gemini-extension.json`) consumes it as-is; Codex loads `skills/` only.
|
||||
- **GitHub Action cache:** `.github/actions/brooks-lint/action.yml` uses `actions/cache@v4` with built-in cache-hit guard — do NOT add a manual directory check.
|
||||
- **Custom risks:** Teams add project-specific risk codes via `custom-risks-guide.md` in their project root. Template lives at `skills/_shared/custom-risks-guide.md`.
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ Como el parser es determinista y el corpus está congelado, `npm run benchmark`
|
||||
|
||||
Los comandos en forma corta (`/brooks-review`) se instalan automáticamente al iniciar la primera sesión. Para instalarlos manualmente:
|
||||
```bash
|
||||
cp commands/*.md ~/.claude/commands/
|
||||
bash hooks/session-start
|
||||
```
|
||||
|
||||
#### Instalación manual
|
||||
|
||||
@@ -266,7 +266,7 @@ graph TD
|
||||
|
||||
短縮形コマンド(`/brooks-review`)は、最初のセッション開始時に自動インストールされます。手動でインストールするには:
|
||||
```bash
|
||||
cp commands/*.md ~/.claude/commands/
|
||||
bash hooks/session-start
|
||||
```
|
||||
|
||||
#### 手動インストール
|
||||
|
||||
@@ -266,7 +266,7 @@ graph TD
|
||||
|
||||
단축 명령(`/brooks-review`)은 첫 세션 시작 시 자동으로 설치됩니다. 수동으로 설치하려면:
|
||||
```bash
|
||||
cp commands/*.md ~/.claude/commands/
|
||||
bash hooks/session-start
|
||||
```
|
||||
|
||||
#### 수동 설치
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/version-1.4.0-blue.svg" alt="Version">
|
||||
<img src="https://img.shields.io/badge/version-1.4.1-blue.svg" alt="Version">
|
||||
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="MIT License">
|
||||
<img src="https://img.shields.io/badge/Claude_Code-Plugin-blueviolet.svg" alt="Claude Code Plugin">
|
||||
<img src="https://img.shields.io/badge/Codex_CLI-Skill-orange.svg" alt="Codex CLI Skill">
|
||||
@@ -266,7 +266,7 @@ Because the parser is deterministic and the corpus is frozen, `npm run benchmark
|
||||
|
||||
Short-form commands (`/brooks-review`) are auto-installed on first session start. To install manually:
|
||||
```bash
|
||||
cp commands/*.md ~/.claude/commands/
|
||||
bash hooks/session-start
|
||||
```
|
||||
|
||||
#### Manual Install
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/version-1.4.0-blue.svg" alt="Version">
|
||||
<img src="https://img.shields.io/badge/version-1.4.1-blue.svg" alt="Version">
|
||||
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="MIT License">
|
||||
<img src="https://img.shields.io/badge/Claude_Code-Plugin-blueviolet.svg" alt="Claude Code Plugin">
|
||||
<img src="https://img.shields.io/badge/Codex_CLI-Skill-orange.svg" alt="Codex CLI Skill">
|
||||
@@ -266,7 +266,7 @@ graph TD
|
||||
|
||||
短命令(`/brooks-review`)会在首次会话启动时自动安装。手动安装:
|
||||
```bash
|
||||
cp commands/*.md ~/.claude/commands/
|
||||
bash hooks/session-start
|
||||
```
|
||||
|
||||
#### 手动安装
|
||||
|
||||
@@ -266,7 +266,7 @@ graph TD
|
||||
|
||||
短命令(`/brooks-review`)會在首次工作階段啟動時自動安裝。手動安裝:
|
||||
```bash
|
||||
cp commands/*.md ~/.claude/commands/
|
||||
bash hooks/session-start
|
||||
```
|
||||
|
||||
#### 手動安裝
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Source
|
||||
|
||||
- Repo: https://github.com/hyhmrright/brooks-lint
|
||||
- Ref: 821487f9249e8838b01e493585afdabefbf3a066
|
||||
- Ref: 141f45ebb70bfa5a67e0dc8ee33b56e40067836d
|
||||
- Remove-Paths:
|
||||
- Snapshot: 2026-07-02
|
||||
- Snapshot: 2026-07-18
|
||||
- Sync-Mode: copy_skill_dirs
|
||||
- Notes: vendored into playbook branch thirdparty/skill
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
description: Run a Brooks-Lint architecture audit
|
||||
allowed-tools: Skill
|
||||
---
|
||||
|
||||
Use the Skill tool to invoke the `brooks-lint:brooks-audit` skill, then follow its instructions exactly.
|
||||
Read `${CLAUDE_PLUGIN_ROOT}/skills/brooks-audit/SKILL.md` and follow its instructions exactly. If that file cannot be found, locate the `brooks-audit` skill's `SKILL.md` in this plugin and follow it.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
description: Run a Brooks-Lint tech debt assessment
|
||||
allowed-tools: Skill
|
||||
---
|
||||
|
||||
Use the Skill tool to invoke the `brooks-lint:brooks-debt` skill, then follow its instructions exactly.
|
||||
Read `${CLAUDE_PLUGIN_ROOT}/skills/brooks-debt/SKILL.md` and follow its instructions exactly. If that file cannot be found, locate the `brooks-debt` skill's `SKILL.md` in this plugin and follow it.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
description: Run a Brooks-Lint codebase health dashboard across all four dimensions
|
||||
allowed-tools: Skill
|
||||
---
|
||||
|
||||
Use the Skill tool to invoke the `brooks-lint:brooks-health` skill, then follow its instructions exactly.
|
||||
Read `${CLAUDE_PLUGIN_ROOT}/skills/brooks-health/SKILL.md` and follow its instructions exactly. If that file cannot be found, locate the `brooks-health` skill's `SKILL.md` in this plugin and follow it.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
description: Run a Brooks-Lint PR code review
|
||||
allowed-tools: Skill
|
||||
---
|
||||
|
||||
Use the Skill tool to invoke the `brooks-lint:brooks-review` skill, then follow its instructions exactly.
|
||||
Read `${CLAUDE_PLUGIN_ROOT}/skills/brooks-review/SKILL.md` and follow its instructions exactly. If that file cannot be found, locate the `brooks-review` skill's `SKILL.md` in this plugin and follow it.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
description: Run all Brooks-Lint analyses in one pass, auto-fix safe findings, confirm risky ones
|
||||
allowed-tools: Skill
|
||||
---
|
||||
|
||||
Use the Skill tool to invoke the `brooks-lint:brooks-sweep` skill, then follow its instructions exactly.
|
||||
Read `${CLAUDE_PLUGIN_ROOT}/skills/brooks-sweep/SKILL.md` and follow its instructions exactly. If that file cannot be found, locate the `brooks-sweep` skill's `SKILL.md` in this plugin and follow it.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
description: Run a Brooks-Lint test quality review
|
||||
allowed-tools: Skill
|
||||
---
|
||||
|
||||
Use the Skill tool to invoke the `brooks-lint:brooks-test` skill, then follow its instructions exactly.
|
||||
Read `${CLAUDE_PLUGIN_ROOT}/skills/brooks-test/SKILL.md` and follow its instructions exactly. If that file cannot be found, locate the `brooks-test` skill's `SKILL.md` in this plugin and follow it.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "brooks-lint",
|
||||
"version": "1.4.0",
|
||||
"version": "1.4.1",
|
||||
"description": "AI code reviews grounded in twelve classic engineering books — decay risk diagnostics with book citations, severity labels, and six analysis modes (PR review, architecture audit, tech debt, test quality, health dashboard, full-sweep auto-fix)",
|
||||
"author": "hyhmrright",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import {
|
||||
copyFileSync,
|
||||
mkdirSync,
|
||||
readFileSync,
|
||||
readdirSync,
|
||||
@@ -42,7 +41,14 @@ function installCommands(version) {
|
||||
const commandsDir = path.join(pluginDir, "commands");
|
||||
for (const entry of readdirSync(commandsDir)) {
|
||||
if (/^brooks-.*\.md$/.test(entry)) {
|
||||
copyFileSync(path.join(commandsDir, entry), path.join(commandDir, entry));
|
||||
// Short forms live in ~/.claude/commands/ (user commands), where
|
||||
// ${CLAUDE_PLUGIN_ROOT} does not expand — bake in the absolute path so
|
||||
// the wrapper can still locate its SKILL.md.
|
||||
const body = readFileSync(path.join(commandsDir, entry), "utf8").replaceAll(
|
||||
"${CLAUDE_PLUGIN_ROOT}",
|
||||
pluginDir,
|
||||
);
|
||||
writeFileSync(path.join(commandDir, entry), body);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "brooks-lint",
|
||||
"version": "1.4.0",
|
||||
"version": "1.4.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"bump": "node scripts/bump-version.mjs",
|
||||
|
||||
@@ -44,8 +44,12 @@ const EMOJI_SEVERITY = { "🔴": "critical", "🟡": "warning", "🟢": "suggest
|
||||
// A path with a directory separator, or a bare filename with a known source
|
||||
// extension — optionally followed by `:line`. The extension allowlist keeps
|
||||
// prose like "e.g." or "i.e." from being mistaken for a file reference.
|
||||
// Within a shared prefix the longer extension must come first (`exs` before
|
||||
// `ex`, `cljs` before `clj`) so JS alternation doesn't stop at the short one;
|
||||
// the newer extensions lead the list so a bare `c`/`h`/`m` can't shadow `cr`/
|
||||
// `hs`/`ml`.
|
||||
const LOCATION_RE =
|
||||
/([\w.-]*\/[\w./-]*\.\w+|[\w.-]+\.(?:ts|tsx|js|jsx|mjs|cjs|py|java|go|rb|rs|cc|cpp|cxx|c|h|hpp|cs|php|kt|kts|swift|scala|vue|sql|rsx|m|mm))(?::(\d+))?/;
|
||||
/([\w.-]*\/[\w./-]*\.\w+|[\w.-]+\.(?:astro|cljc|cljs|clj|cr|dart|elm|erl|exs|ex|fsx|fs|gradle|groovy|hs|jl|lua|mli|ml|nim|pl|pm|proto|sol|svelte|tf|zig|ts|tsx|js|jsx|mjs|cjs|py|java|go|rb|rs|cc|cpp|cxx|c|h|hpp|cs|php|kt|kts|swift|scala|vue|sql|rsx|m|mm))(?::(\d+))?/;
|
||||
|
||||
function splitTitle(bold) {
|
||||
// Dash is the template separator; a colon is a common LLM variant. `.match`
|
||||
|
||||
@@ -659,6 +659,21 @@ test("does not mistake prose for a file reference", () => {
|
||||
assert.deepEqual(extractLocation("see line 3 (i.e. nowhere)"), { file: null, line: null });
|
||||
});
|
||||
|
||||
// Bare filenames (no `/`) exercise the extension allowlist; a path with a
|
||||
// slash would match the first branch's generic `.\w+` regardless of the list.
|
||||
test("captures newer-language extensions from bare filenames", () => {
|
||||
assert.deepEqual(extractLocation("bug in user.ex:42"), { file: "user.ex", line: 42 });
|
||||
assert.deepEqual(extractLocation("see main.dart"), { file: "main.dart", line: null });
|
||||
assert.deepEqual(extractLocation("main.tf drifts"), { file: "main.tf", line: null });
|
||||
});
|
||||
|
||||
test("prefers the longer of two prefix-sharing extensions", () => {
|
||||
// A bare `ex`/`clj`/`ml` must not truncate `.exs`/`.cljs`/`.mli`.
|
||||
assert.equal(extractLocation("runtime.exs boots the app").file, "runtime.exs");
|
||||
assert.equal(extractLocation("core.cljs mounts").file, "core.cljs");
|
||||
assert.equal(extractLocation("parser.mli exports").file, "parser.mli");
|
||||
});
|
||||
|
||||
// ── sarif: reportToSarif ───────────────────────────────────────────────────
|
||||
|
||||
console.log("\nreportToSarif");
|
||||
|
||||
Reference in New Issue
Block a user