#!/usr/bin/env node import { copyFileSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync, } from "node:fs"; import os from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const pluginDir = path.resolve(__dirname, ".."); const homeDir = process.env.HOME || os.homedir(); function readVersion() { const packageJson = JSON.parse( readFileSync(path.join(pluginDir, "package.json"), "utf8"), ); if (!packageJson.version) { throw new Error("Failed to read version from package.json"); } return packageJson.version; } function installCommands(version) { const commandDir = path.join(homeDir, ".claude", "commands"); const sentinel = path.join(commandDir, `.brooks-lint-v${version}`); try { readFileSync(sentinel, "utf8"); return; } catch { // Sentinel does not exist yet. } mkdirSync(commandDir, { recursive: true }); 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)); } } for (const entry of readdirSync(commandDir)) { if (entry === ".brooks-lint-installed" || entry.startsWith(".brooks-lint-v")) { rmSync(path.join(commandDir, entry), { force: true }); } } writeFileSync(sentinel, ""); } function buildContext() { return [ "You have the brooks-lint plugin installed. It provides six independent skills - load the relevant one via the Skill tool:", " brooks-lint:brooks-review -> PR code review", " brooks-lint:brooks-audit -> Architecture audit", " brooks-lint:brooks-debt -> Tech debt assessment", " brooks-lint:brooks-test -> Test quality review", " brooks-lint:brooks-health -> Codebase health dashboard", " brooks-lint:brooks-sweep -> Full sweep: analyse all dimensions and auto-fix findings", "", "Triggers when the user asks to review code, discuss architecture, assess tech debt, or discuss test quality. Also triggers when the user mentions: Brooks's Law / Mythical Man-Month / conceptual integrity / second system effect / Hyrum's Law / deep modules / tactical programming / code smells / refactoring / clean architecture / DDD.", ].join("\n"); } function buildOutput(context) { if (process.env.CLAUDE_PLUGIN_ROOT) { return { hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: context, }, }; } return { additional_context: context, }; } try { installCommands(readVersion()); process.stdout.write(`${JSON.stringify(buildOutput(buildContext()), null, 2)}\n`); } catch (error) { process.stderr.write(`${error.message}\n`); process.exit(1); }