instrlint 0.1.10 → 0.2.2

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/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js","../src/cli.ts","../src/commands/run-command.ts","../src/core/scanner.ts","../src/adapters/claude-code.ts","../src/core/parser.ts","../src/detectors/token-estimator.ts","../src/adapters/codex.ts","../src/adapters/cursor.ts","../src/adapters/dispatch.ts","../src/analyzers/budget.ts","../src/detectors/config-overlap.ts","../src/utils/text.ts","../src/detectors/duplicate.ts","../src/analyzers/dead-rules.ts","../src/detectors/contradiction.ts","../src/detectors/stale-refs.ts","../src/detectors/scope-classifier.ts","../src/analyzers/structure.ts","../src/core/scorer.ts","../src/core/reporter.ts","../src/commands/budget-command.ts","../src/i18n/en.json","../src/i18n/zh-TW.json","../src/i18n/index.ts","../src/fixers/line-remover.ts","../src/fixers/remove-dead.ts","../src/fixers/remove-stale.ts","../src/fixers/deduplicate.ts","../src/fixers/structure-suggestions.ts","../src/utils/skill-version.ts","../src/verifiers/candidates.ts","../src/verifiers/policy.ts","../src/verifiers/verdicts.ts","../src/commands/install-command.ts","../src/commands/deadrules-command.ts","../src/commands/structure-command.ts","../src/commands/ci-command.ts","../src/reporters/sarif.ts","../src/commands/init-ci-command.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { runAll } from \"./commands/run-command.js\";\nimport { runBudget } from \"./commands/budget-command.js\";\nimport { runDeadRules } from \"./commands/deadrules-command.js\";\nimport { runStructure } from \"./commands/structure-command.js\";\nimport { runCi } from \"./commands/ci-command.js\";\nimport { runInitCi } from \"./commands/init-ci-command.js\";\nimport { runInstall } from \"./commands/install-command.js\";\nimport { initLocale } from \"./i18n/index.js\";\nimport { CURRENT_VERSION } from \"./utils/skill-version.js\";\nimport type { FailOn } from \"./commands/ci-command.js\";\n\nconst program = new Command();\n\nprogram\n .enablePositionalOptions()\n .name(\"instrlint\")\n .description(\n \"Lint and optimize your CLAUDE.md / AGENTS.md — find dead rules, token waste, and structural issues\",\n )\n .version(CURRENT_VERSION)\n .option(\n \"--format <type>\",\n \"output format (terminal|json|markdown)\",\n \"terminal\",\n )\n .option(\"--lang <locale>\", \"output language (en|zh-TW)\", \"en\")\n .option(\"--tool <name>\", \"force tool detection (claude-code|codex|cursor)\")\n .option(\"--fix\", \"auto-fix safe issues (dead rules, stale refs, dupes)\")\n .option(\"--force\", \"skip git clean check when using --fix\")\n .option(\n \"--emit-candidates <path>\",\n \"write low-confidence findings as candidates JSON for host LLM verification\",\n )\n .option(\n \"--apply-verdicts <path>\",\n \"apply host LLM verdicts from JSON file to the report\",\n )\n .option(\n \"--skip-report\",\n \"suppress terminal output (use with --emit-candidates)\",\n )\n .action(async function (this: Command) {\n const opts = this.opts<{\n format: string;\n lang?: string;\n tool?: string;\n fix?: boolean;\n force?: boolean;\n emitCandidates?: string;\n applyVerdicts?: string;\n skipReport?: boolean;\n }>();\n const result = await runAll(opts);\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"budget\")\n .description(\"Token budget analysis only\")\n .option(\n \"--format <type>\",\n \"output format (terminal|json|markdown)\",\n \"terminal\",\n )\n .option(\"--lang <locale>\", \"output language (en|zh-TW)\")\n .option(\"--tool <name>\", \"force tool detection (claude-code|codex|cursor)\")\n .action(async function (this: Command) {\n const opts = this.opts<{ format: string; lang?: string; tool?: string }>();\n const lang = opts.lang ?? this.parent?.opts<{ lang?: string }>()?.lang;\n const result = await runBudget({\n ...opts,\n ...(lang !== undefined && { lang }),\n });\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"deadrules\")\n .description(\"Dead rule detection only\")\n .option(\"--format <type>\", \"output format (terminal|json)\", \"terminal\")\n .option(\"--lang <locale>\", \"output language (en|zh-TW)\")\n .option(\"--tool <name>\", \"force tool detection (claude-code|codex|cursor)\")\n .action(async function (this: Command) {\n const opts = this.opts<{ format: string; lang?: string; tool?: string }>();\n const lang = opts.lang ?? this.parent?.opts<{ lang?: string }>()?.lang;\n const result = await runDeadRules({\n ...opts,\n ...(lang !== undefined && { lang }),\n });\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"structure\")\n .description(\"Structural analysis only\")\n .option(\"--format <type>\", \"output format (terminal|json)\", \"terminal\")\n .option(\"--lang <locale>\", \"output language (en|zh-TW)\")\n .option(\"--tool <name>\", \"force tool detection (claude-code|codex|cursor)\")\n .action(async function (this: Command) {\n const opts = this.opts<{ format: string; lang?: string; tool?: string }>();\n const lang = opts.lang ?? this.parent?.opts<{ lang?: string }>()?.lang;\n const result = await runStructure({\n ...opts,\n ...(lang !== undefined && { lang }),\n });\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"ci\")\n .description(\n \"CI mode: run full analysis and exit 1 if findings exceed threshold\",\n )\n .option(\n \"--fail-on <level>\",\n \"failure threshold (critical|warning|info)\",\n \"critical\",\n )\n .option(\"--format <type>\", \"output format (json|markdown|sarif)\", \"json\")\n .option(\"--output <file>\", \"write output to file instead of stdout\")\n .option(\"--tool <name>\", \"force tool detection (claude-code|codex|cursor)\")\n .action(async function (this: Command) {\n const opts = this.opts<{\n failOn: string;\n format: string;\n output?: string;\n tool?: string;\n }>();\n const lang = this.parent?.opts<{ lang?: string }>()?.lang;\n initLocale(lang);\n const result = await runCi({\n failOn: opts.failOn as FailOn,\n format: opts.format,\n ...(opts.output !== undefined && { output: opts.output }),\n ...(opts.tool !== undefined && { tool: opts.tool }),\n ...(lang !== undefined && { lang }),\n });\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"init-ci\")\n .description(\"Generate CI configuration for instrlint\")\n .option(\"--github\", \"Generate GitHub Actions workflow\")\n .option(\"--gitlab\", \"Generate GitLab CI snippet (prints to stdout)\")\n .option(\"--force\", \"overwrite existing files\")\n .action(function (this: Command) {\n const opts = this.opts<{\n github?: boolean;\n gitlab?: boolean;\n force?: boolean;\n }>();\n const result = runInitCi(opts);\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"install\")\n .description(\"Install instrlint as a skill\")\n .option(\"--claude-code\", \"Install as Claude Code skill\")\n .option(\"--codex\", \"Install as Codex skill\")\n .option(\"--project\", \"Install into current project (instead of global)\")\n .option(\"--force\", \"overwrite existing skill file\")\n .action(function (this: Command) {\n const opts = this.opts<{\n claudeCode?: boolean;\n codex?: boolean;\n project?: boolean;\n force?: boolean;\n }>();\n const result = runInstall(opts);\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram.parse();\n","import { execSync } from \"child_process\";\nimport { writeFileSync } from \"fs\";\nimport { createInterface } from \"readline\";\nimport { basename, resolve, relative } from \"path\";\nimport chalk from \"chalk\";\nimport { scanProject } from \"../core/scanner.js\";\nimport { loadProject } from \"../adapters/dispatch.js\";\nimport { ensureInitialized } from \"../detectors/token-estimator.js\";\nimport { analyzeBudget } from \"../analyzers/budget.js\";\nimport { analyzeDeadRules } from \"../analyzers/dead-rules.js\";\nimport { analyzeStructure } from \"../analyzers/structure.js\";\nimport { calculateScore, buildActionPlan } from \"../core/scorer.js\";\nimport {\n printCombinedTerminal,\n reportJson,\n reportMarkdown,\n} from \"../core/reporter.js\";\nimport { removeDeadRules } from \"../fixers/remove-dead.js\";\nimport { removeStaleRefs } from \"../fixers/remove-stale.js\";\nimport { deduplicateRules } from \"../fixers/deduplicate.js\";\nimport {\n buildStructureSuggestions,\n printStructureSuggestions,\n markdownStructureSuggestions,\n} from \"../fixers/structure-suggestions.js\";\nimport { t, plural, initLocale, getLocale } from \"../i18n/index.js\";\nimport { checkSkillUpdate } from \"../utils/skill-version.js\";\nimport {\n buildCandidates,\n applyVerdicts,\n loadVerdictsFile,\n} from \"../verifiers/index.js\";\nimport type { ApplyVerdictsResult } from \"../verifiers/index.js\";\nimport { runInstall } from \"./install-command.js\";\nimport type { HealthReport } from \"../types.js\";\n\n// ─── Git helpers ───────────────────────────────────────────────────────────────\n\nfunction isGitClean(cwd: string): boolean {\n try {\n const out = execSync(\"git status --porcelain\", { cwd, encoding: \"utf8\" });\n return out.trim().length === 0;\n } catch {\n // Not a git repo or git unavailable — proceed without blocking\n return true;\n }\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface RunCommandOpts {\n format: string;\n tool?: string;\n lang?: string;\n fix?: boolean;\n force?: boolean;\n projectRoot?: string;\n emitCandidates?: string;\n applyVerdicts?: string;\n skipReport?: boolean;\n}\n\nexport interface RunCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\n// ─── Core logic ───────────────────────────────────────────────────────────────\n\nexport async function runAll(\n opts: RunCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): Promise<RunCommandResult> {\n initLocale(opts.lang);\n await ensureInitialized();\n\n const projectRoot = opts.projectRoot ?? process.cwd();\n const scan = scanProject(projectRoot, opts.tool);\n\n if (scan.tool === \"unknown\") {\n output.error(t(\"error.unknownTool\"));\n return { exitCode: 1, errorMessage: \"unknown tool\" };\n }\n\n if (scan.rootFilePath === null) {\n output.error(t(\"error.missingRootFile\", { tool: scan.tool }));\n return { exitCode: 1, errorMessage: \"missing root file\" };\n }\n\n // --fix and --emit-candidates are mutually exclusive\n if (opts.fix && opts.emitCandidates) {\n output.error(\"--fix and --emit-candidates cannot be used together\");\n return {\n exitCode: 1,\n errorMessage: \"--fix and --emit-candidates conflict\",\n };\n }\n\n // --fix: require clean working tree unless --force is set\n if (opts.fix && !opts.force && !isGitClean(projectRoot)) {\n output.error(t(\"error.dirtyWorkingTree\"));\n return { exitCode: 1, errorMessage: \"dirty working tree\" };\n }\n\n // --emit-candidates: validate output path stays within project root\n if (opts.emitCandidates) {\n const resolved = resolve(opts.emitCandidates);\n const rel = relative(projectRoot, resolved);\n if (rel.startsWith(\"..\")) {\n output.error(\n `--emit-candidates path must be within the project directory: ${opts.emitCandidates}`,\n );\n return {\n exitCode: 1,\n errorMessage: \"emit-candidates path outside project\",\n };\n }\n }\n\n const instructions = loadProject(projectRoot, scan.tool);\n\n const { findings: budgetFindings, summary } = analyzeBudget(instructions);\n const { findings: deadRuleFindings } = analyzeDeadRules(\n instructions,\n projectRoot,\n );\n const { findings: structureFindings } = analyzeStructure(\n instructions,\n projectRoot,\n );\n\n let allFindings = [\n ...budgetFindings,\n ...deadRuleFindings,\n ...structureFindings,\n ];\n\n // ── Emit candidates for host LLM verification ────────────────────────────────\n if (opts.emitCandidates) {\n const candidatesFile = buildCandidates(\n allFindings,\n instructions,\n projectRoot,\n getLocale(),\n );\n writeFileSync(opts.emitCandidates, JSON.stringify(candidatesFile, null, 2));\n if (opts.skipReport) return { exitCode: 0 };\n }\n\n // ── Apply host LLM verdicts ──────────────────────────────────────────────────\n let rejectedByVerification: number | undefined;\n if (opts.applyVerdicts) {\n try {\n const verdictsFile = loadVerdictsFile(opts.applyVerdicts);\n const result: ApplyVerdictsResult = applyVerdicts(\n allFindings,\n verdictsFile,\n );\n allFindings = result.findings;\n rejectedByVerification =\n result.rejectedCount > 0 ? result.rejectedCount : undefined;\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n return { exitCode: 1, errorMessage: \"failed to apply verdicts\" };\n }\n }\n\n const { score, grade } = calculateScore(allFindings, summary);\n const actionPlan = buildActionPlan(allFindings);\n\n const report: HealthReport = {\n project: basename(projectRoot),\n tool: instructions.tool,\n score,\n grade,\n locale: getLocale(),\n tokenMethod: summary.tokenMethod,\n findings: allFindings,\n budget: summary,\n actionPlan,\n ...(rejectedByVerification !== undefined ? { rejectedByVerification } : {}),\n };\n\n // ── Apply fixes ──────────────────────────────────────────────────────────────\n if (opts.fix) {\n // Build suggestions BEFORE modifying files, so line numbers are still accurate\n const suggestions = buildStructureSuggestions(allFindings);\n\n const deadFixed = removeDeadRules(allFindings);\n const staleFixed = removeStaleRefs(allFindings);\n const dupeFixed = deduplicateRules(allFindings);\n const total = deadFixed + staleFixed + dupeFixed;\n\n if (total === 0) {\n output.log(chalk.green(` ${t(\"status.noAutoFixable\")}`));\n } else {\n output.log(\"\");\n output.log(chalk.bold.white(` ${t(\"label.fixSummary\")}`));\n output.log(chalk.gray(\" ─\".repeat(30)));\n if (deadFixed > 0)\n output.log(\n ` ${chalk.yellow(\"⚠\")} ${t(\"fix.removedDeadRules\", { count: String(deadFixed), s: plural(deadFixed) })}`,\n );\n if (staleFixed > 0)\n output.log(\n ` ${chalk.yellow(\"⚠\")} ${t(\"fix.removedStaleRefs\", { count: String(staleFixed), s: plural(staleFixed) })}`,\n );\n if (dupeFixed > 0)\n output.log(\n ` ${chalk.yellow(\"⚠\")} ${t(\"fix.removedDuplicates\", { count: String(dupeFixed), s: plural(dupeFixed) })}`,\n );\n output.log(chalk.gray(\" ─\".repeat(30)));\n output.log(\n chalk.green(\n ` ${t(\"status.fixedIssues\", { count: String(total), s: plural(total) })}`,\n ),\n );\n output.log(\"\");\n }\n\n // Print actionable suggestions for non-auto-fixable structure findings\n printStructureSuggestions(suggestions, projectRoot, output);\n\n return { exitCode: 0 };\n }\n\n // ── Skill update notice ──────────────────────────────────────────────────────\n const skillUpdate = checkSkillUpdate(projectRoot);\n\n // ── Format output ────────────────────────────────────────────────────────────\n if (opts.format === \"json\") {\n output.log(reportJson(report));\n return { exitCode: 0 };\n }\n\n if (opts.format === \"markdown\") {\n const mdSuggestions = buildStructureSuggestions(allFindings);\n const mdExtra = markdownStructureSuggestions(mdSuggestions, projectRoot);\n const updateSection = skillUpdate\n ? [\n \"\",\n `> ⚠️ **${t(\"install.outdatedTitle\")}** (${t(\"install.outdatedVersions\", { installed: skillUpdate.installedVersion, current: skillUpdate.currentVersion })})`,\n `> \\`${t(\"install.updateCmd\", { flag: skillUpdate.isProject ? \"--claude-code --project\" : \"--claude-code\" })}\\``,\n ]\n : [];\n output.log(reportMarkdown(report, [...mdExtra, ...updateSection]));\n return { exitCode: 0 };\n }\n\n printCombinedTerminal(report, output);\n\n if (skillUpdate && process.stdout.isTTY) {\n output.log(\"\");\n output.log(\n ` ${chalk.yellow(\"⚠\")} ${chalk.bold(t(\"install.outdatedTitle\"))} (${t(\"install.outdatedVersions\", { installed: skillUpdate.installedVersion, current: skillUpdate.currentVersion })})`,\n );\n const confirmed = await promptYesNo(` ${t(\"install.updatePrompt\")}`);\n if (confirmed) {\n const installResult = runInstall(\n {\n claudeCode: true,\n project: skillUpdate.isProject,\n force: true,\n projectRoot,\n },\n output,\n );\n if (installResult.exitCode !== 0) {\n output.error?.(\n `Update failed: ${installResult.errorMessage ?? \"unknown error\"}`,\n );\n }\n }\n output.log(\"\");\n }\n\n return { exitCode: 0 };\n}\n\nfunction promptYesNo(question: string): Promise<boolean> {\n return new Promise((resolve) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question(`${question} ${chalk.gray(\"[Y/n]\")} `, (answer) => {\n rl.close();\n const trimmed = answer.trim().toLowerCase();\n resolve(trimmed === \"\" || trimmed === \"y\");\n });\n });\n}\n","import { existsSync } from 'fs';\nimport { join } from 'path';\nimport type { ToolType } from '../types.js';\n\nexport type ScanConfidence = 'high' | 'low' | 'ambiguous';\n\nexport interface ScanResult {\n tool: ToolType;\n /** Absolute path to the root instruction file (e.g. CLAUDE.md or AGENTS.md) */\n rootFilePath: string | null;\n /** Absolute path to the config directory (e.g. .claude/, .agents/) */\n configDir: string | null;\n confidence: ScanConfidence;\n}\n\ninterface Detection {\n tool: ToolType;\n rootFilePath: string | null;\n configDir: string | null;\n}\n\nfunction detectAll(projectRoot: string): Detection[] {\n const detections: Detection[] = [];\n\n // Claude Code: .claude/ directory\n const claudeDir = join(projectRoot, '.claude');\n if (existsSync(claudeDir)) {\n const rootInDir = join(claudeDir, 'CLAUDE.md');\n const rootAtRoot = join(projectRoot, 'CLAUDE.md');\n detections.push({\n tool: 'claude-code',\n rootFilePath: existsSync(rootInDir)\n ? rootInDir\n : existsSync(rootAtRoot)\n ? rootAtRoot\n : null,\n configDir: claudeDir,\n });\n }\n\n // Codex: .agents/ directory\n const agentsDir = join(projectRoot, '.agents');\n if (existsSync(agentsDir)) {\n const agentsMd = join(projectRoot, 'AGENTS.md');\n detections.push({\n tool: 'codex',\n rootFilePath: existsSync(agentsMd) ? agentsMd : null,\n configDir: agentsDir,\n });\n }\n\n // Codex: .codex/ directory (alternative)\n const codexDir = join(projectRoot, '.codex');\n if (existsSync(codexDir) && !detections.some((d) => d.tool === 'codex')) {\n const agentsMd = join(projectRoot, 'AGENTS.md');\n detections.push({\n tool: 'codex',\n rootFilePath: existsSync(agentsMd) ? agentsMd : null,\n configDir: codexDir,\n });\n }\n\n // Cursor: .cursor/ directory or .cursorrules file\n const cursorDir = join(projectRoot, '.cursor');\n const cursorRules = join(projectRoot, '.cursorrules');\n if (existsSync(cursorDir) || existsSync(cursorRules)) {\n detections.push({\n tool: 'cursor',\n rootFilePath: existsSync(cursorRules) ? cursorRules : null,\n configDir: existsSync(cursorDir) ? cursorDir : null,\n });\n }\n\n return detections;\n}\n\nfunction detectByRootFile(projectRoot: string): Detection | null {\n const claudeMd = join(projectRoot, 'CLAUDE.md');\n if (existsSync(claudeMd)) {\n return { tool: 'claude-code', rootFilePath: claudeMd, configDir: null };\n }\n\n const agentsMd = join(projectRoot, 'AGENTS.md');\n if (existsSync(agentsMd)) {\n return { tool: 'codex', rootFilePath: agentsMd, configDir: null };\n }\n\n return null;\n}\n\nexport function scanProject(projectRoot: string, forceTool?: string): ScanResult {\n if (!existsSync(projectRoot)) {\n throw new Error(`Project root does not exist: ${projectRoot}`);\n }\n\n // --tool flag overrides everything\n if (forceTool != null) {\n const valid: ToolType[] = ['claude-code', 'codex', 'cursor'];\n if (!valid.includes(forceTool as ToolType)) {\n throw new Error(\n `Invalid tool: \"${forceTool}\". Must be one of: ${valid.join(', ')}`\n );\n }\n const tool = forceTool as ToolType;\n // Still try to find the root file for this tool\n const detections = detectAll(projectRoot);\n const match = detections.find((d) => d.tool === tool);\n return {\n tool,\n rootFilePath: match?.rootFilePath ?? null,\n configDir: match?.configDir ?? null,\n confidence: 'high',\n };\n }\n\n const detections = detectAll(projectRoot);\n\n if (detections.length === 0) {\n // Fall back to checking for bare root files\n const byFile = detectByRootFile(projectRoot);\n if (byFile != null) {\n return { ...byFile, confidence: 'low' };\n }\n return { tool: 'unknown', rootFilePath: null, configDir: null, confidence: 'low' };\n }\n\n if (detections.length === 1) {\n const d = detections[0]!;\n return { tool: d.tool, rootFilePath: d.rootFilePath, configDir: d.configDir, confidence: 'high' };\n }\n\n // Multiple detections — use the first match, mark ambiguous\n const first = detections[0]!;\n return {\n tool: first.tool,\n rootFilePath: first.rootFilePath,\n configDir: first.configDir,\n confidence: 'ambiguous',\n };\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from \"fs\";\nimport { basename, dirname, join, relative } from \"path\";\nimport { parseInstructionFile, parseYamlFrontmatter } from \"../core/parser.js\";\nimport {\n countTokens,\n estimateMcpTokens,\n} from \"../detectors/token-estimator.js\";\nimport type {\n InstructionFile,\n McpServerConfig,\n ParsedInstructions,\n RuleFile,\n SkillFile,\n} from \"../types.js\";\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction withTokens(file: InstructionFile): InstructionFile {\n const raw = (() => {\n try {\n return readFileSync(file.path, \"utf8\");\n } catch {\n return \"\";\n }\n })();\n const { count, method } = countTokens(raw);\n return { ...file, tokenCount: count, tokenMethod: method };\n}\n\nfunction safeParseFile(filePath: string): InstructionFile | null {\n try {\n const file = parseInstructionFile(filePath);\n return withTokens(file);\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not read ${filePath}, skipping\\n`,\n );\n return null;\n }\n}\n\n// ─── Root file discovery ───────────────────────────────────────────────────\n\nfunction findRootFile(projectRoot: string): string | null {\n const candidates = [\n join(projectRoot, \"CLAUDE.md\"),\n join(projectRoot, \".claude\", \"CLAUDE.md\"),\n ];\n return candidates.find(existsSync) ?? null;\n}\n\n// ─── Rules ────────────────────────────────────────────────────────────────\n\nfunction loadRules(projectRoot: string): RuleFile[] {\n const rulesDir = join(projectRoot, \".claude\", \"rules\");\n if (!existsSync(rulesDir)) return [];\n\n const rules: RuleFile[] = [];\n let entries: string[] = [];\n try {\n entries = readdirSync(rulesDir).filter((f) => f.endsWith(\".md\"));\n } catch {\n return [];\n }\n\n for (const filename of entries) {\n const filePath = join(rulesDir, filename);\n try {\n const raw = readFileSync(filePath, \"utf8\");\n const { paths, globs, body } = parseYamlFrontmatter(raw);\n const baseFile = parseInstructionFile(filePath);\n const { count, method } = countTokens(body);\n rules.push({\n ...baseFile,\n tokenCount: count,\n tokenMethod: method,\n ...(paths != null ? { paths } : {}),\n ...(globs != null ? { globs } : {}),\n });\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not parse rule ${filePath}, skipping\\n`,\n );\n }\n }\n\n return rules;\n}\n\n// ─── Skills ───────────────────────────────────────────────────────────────\n\nfunction loadSkills(projectRoot: string): SkillFile[] {\n const skillsDir = join(projectRoot, \".claude\", \"skills\");\n if (!existsSync(skillsDir)) return [];\n\n const skills: SkillFile[] = [];\n let entries: string[] = [];\n try {\n entries = readdirSync(skillsDir);\n } catch {\n return [];\n }\n\n for (const skillName of entries) {\n const skillFile = join(skillsDir, skillName, \"SKILL.md\");\n if (!existsSync(skillFile)) continue;\n\n const parsed = safeParseFile(skillFile);\n if (parsed != null) {\n skills.push({ ...parsed, skillName });\n }\n }\n\n return skills;\n}\n\n// ─── Sub-directory CLAUDE.md files ────────────────────────────────────────\n\nconst SKIP_DIRS = new Set([\n \"node_modules\",\n \"dist\",\n \".git\",\n \".claude\",\n \".turbo\",\n \"coverage\",\n \"tests\",\n \"test\",\n \"__tests__\",\n \"spec\",\n]);\n\nfunction findSubClaudeFiles(\n dir: string,\n projectRoot: string,\n depth = 0,\n): InstructionFile[] {\n if (depth > 10) return []; // guard against infinite recursion\n const results: InstructionFile[] = [];\n\n let entries: string[] = [];\n try {\n entries = readdirSync(dir);\n } catch {\n return [];\n }\n\n for (const entry of entries) {\n if (SKIP_DIRS.has(entry)) continue;\n const full = join(dir, entry);\n\n try {\n const stat = statSync(full);\n if (stat.isDirectory()) {\n results.push(...findSubClaudeFiles(full, projectRoot, depth + 1));\n } else if (entry === \"CLAUDE.md\") {\n // Skip the project root CLAUDE.md itself\n if (relative(projectRoot, full) === \"CLAUDE.md\") continue;\n const parsed = safeParseFile(full);\n if (parsed != null) results.push(parsed);\n }\n } catch {\n // skip inaccessible entries\n }\n }\n\n return results;\n}\n\n// ─── MCP servers ──────────────────────────────────────────────────────────\n\ninterface McpServerEntry {\n command?: string;\n args?: string[];\n tools?: unknown[];\n}\n\nfunction parseMcpServers(projectRoot: string): McpServerConfig[] {\n const candidates = [\n join(projectRoot, \".claude\", \"settings.json\"),\n join(projectRoot, \".claude\", \"settings.local.json\"),\n ];\n\n const servers: McpServerConfig[] = [];\n\n for (const settingsPath of candidates) {\n if (!existsSync(settingsPath)) continue;\n try {\n const raw = readFileSync(settingsPath, \"utf8\");\n const parsed: unknown = JSON.parse(raw);\n if (\n parsed == null ||\n typeof parsed !== \"object\" ||\n !(\"mcpServers\" in parsed)\n ) {\n continue;\n }\n const mcpServers = (\n parsed as { mcpServers: Record<string, McpServerEntry> }\n ).mcpServers;\n for (const [name, entry] of Object.entries(mcpServers)) {\n const toolCount = Array.isArray(entry.tools)\n ? entry.tools.length\n : undefined;\n const config: McpServerConfig = {\n name,\n estimatedTokens: 0,\n ...(toolCount !== undefined ? { toolCount } : {}),\n };\n const { count } = estimateMcpTokens(config);\n servers.push({ ...config, estimatedTokens: count });\n }\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not parse MCP config in ${settingsPath}, skipping\\n`,\n );\n }\n }\n\n return servers;\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport function loadClaudeCodeProject(projectRoot: string): ParsedInstructions {\n // Root file\n const rootFilePath = findRootFile(projectRoot);\n const rootFile: InstructionFile =\n rootFilePath != null\n ? (safeParseFile(rootFilePath) ?? emptyFile(rootFilePath))\n : emptyFile(join(projectRoot, \"CLAUDE.md\"));\n\n // Rule files\n const rules = loadRules(projectRoot);\n\n // Skill files\n const skills = loadSkills(projectRoot);\n\n // Sub-directory CLAUDE.md files (skip root)\n const subFiles = findSubClaudeFiles(projectRoot, projectRoot);\n\n // MCP servers\n const mcpServers = parseMcpServers(projectRoot);\n\n return {\n tool: \"claude-code\",\n rootFile,\n rules,\n skills,\n subFiles,\n mcpServers,\n };\n}\n\nfunction emptyFile(path: string): InstructionFile {\n return {\n path,\n lines: [],\n lineCount: 0,\n tokenCount: 0,\n tokenMethod: \"estimated\",\n };\n}\n","import { readFileSync } from \"fs\";\nimport type { InstructionFile, ParsedLine } from \"../types.js\";\n\n// ─── Keyword dictionary ────────────────────────────────────────────────────\n\nconst KNOWN_KEYWORDS = new Set([\n \"typescript\",\n \"javascript\",\n \"eslint\",\n \"prettier\",\n \"biome\",\n \"react\",\n \"vue\",\n \"svelte\",\n \"angular\",\n \"next\",\n \"nextjs\",\n \"nuxt\",\n \"jest\",\n \"vitest\",\n \"mocha\",\n \"jasmine\",\n \"playwright\",\n \"cypress\",\n \"postgresql\",\n \"postgres\",\n \"mysql\",\n \"sqlite\",\n \"mongodb\",\n \"redis\",\n \"docker\",\n \"kubernetes\",\n \"k8s\",\n \"terraform\",\n \"git\",\n \"github\",\n \"gitlab\",\n \"npm\",\n \"pnpm\",\n \"yarn\",\n \"bun\",\n \"node\",\n \"nodejs\",\n \"deno\",\n \"webpack\",\n \"vite\",\n \"esbuild\",\n \"tsup\",\n \"rollup\",\n \"zod\",\n \"prisma\",\n \"drizzle\",\n \"openai\",\n \"anthropic\",\n \"claude\",\n \"commitlint\",\n \"husky\",\n \"lint-staged\",\n]);\n\nconst KEYWORD_REGEX = new RegExp(\n `\\\\b(${[...KNOWN_KEYWORDS].join(\"|\")})\\\\b`,\n \"gi\",\n);\n\n// ─── Path extraction ───────────────────────────────────────────────────────\n\n// Matches path-like strings: starts with src/, tests/, ./, ../, or contains /\n// but NOT URLs (http:// https://)\nconst PATH_REGEX =\n /(?<!\\w)(?:\\.{1,2}\\/|(?:src|tests?|dist|lib|docs?|config|scripts?|packages?)\\/)[^\\s,;`'\")\\]>]+/g;\n\n// ─── Rule classification signals ──────────────────────────────────────────\n\nconst RULE_IMPERATIVE_WORDS =\n /\\b(must|should|never|always|prefer|avoid|ensure|require|forbid|use|do not|don't)\\b/i;\n\nconst RULE_NEGATION_PATTERN = /\\b(not|don't|do not)\\s+\\w+/i;\n\n// Strong imperatives for non-list lines (must match at sentence start or be prominent)\nconst STRONG_IMPERATIVE = /\\b(must|shall|always|never)\\b/i;\n\n// ─── YAML frontmatter parsing ──────────────────────────────────────────────\n\nexport interface FrontmatterResult {\n paths?: string[];\n globs?: string[];\n body: string;\n}\n\nexport function parseYamlFrontmatter(content: string): FrontmatterResult {\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/m.exec(content);\n if (match == null) {\n return { body: content };\n }\n\n const yaml = match[1] ?? \"\";\n const body = match[2] ?? \"\";\n\n const paths = extractYamlStringArray(yaml, \"paths\");\n const globs = extractYamlStringArray(yaml, \"globs\");\n\n return {\n ...(paths != null ? { paths } : {}),\n ...(globs != null ? { globs } : {}),\n body,\n };\n}\n\nfunction extractYamlStringArray(\n yaml: string,\n key: string,\n): string[] | undefined {\n // Match \"key:\\n - value\\n - value\" style\n const blockMatch = new RegExp(\n `^${key}:\\\\s*\\\\n((?:\\\\s+-\\\\s+.+\\\\n?)*)`,\n \"m\",\n ).exec(yaml);\n if (blockMatch != null) {\n return (blockMatch[1] ?? \"\")\n .split(\"\\n\")\n .map((l) =>\n l\n .replace(/^\\s+-\\s+/, \"\")\n .replace(/[\"']/g, \"\")\n .trim(),\n )\n .filter((l) => l.length > 0);\n }\n\n // Match \"key: [value, value]\" inline style\n const inlineMatch = new RegExp(`^${key}:\\\\s*\\\\[(.+)\\\\]`, \"m\").exec(yaml);\n if (inlineMatch != null) {\n return (inlineMatch[1] ?? \"\")\n .split(\",\")\n .map((s) => s.replace(/[\"']/g, \"\").trim())\n .filter((s) => s.length > 0);\n }\n\n return undefined;\n}\n\n// ─── Line classifier ───────────────────────────────────────────────────────\n\nfunction classifyLine(\n text: string,\n inCodeBlock: boolean,\n inHtmlComment: boolean,\n): ParsedLine[\"type\"] {\n if (inCodeBlock) return \"code\";\n if (inHtmlComment) return \"comment\";\n\n const trimmed = text.trim();\n\n if (trimmed.length === 0) return \"blank\";\n if (/^#{1,6}\\s/.test(trimmed)) return \"heading\";\n if (trimmed.startsWith(\"```\")) return \"code\";\n\n // Inline HTML comment (whole line)\n if (/^<!--[\\s\\S]*-->$/.test(trimmed)) return \"comment\";\n // Opening HTML comment\n if (trimmed.startsWith(\"<!--\")) return \"comment\";\n\n if (isRule(trimmed)) return \"rule\";\n return \"other\";\n}\n\nfunction isRule(text: string): boolean {\n const isList = text.startsWith(\"- \");\n const body = isList ? text.slice(2) : text;\n\n if (isList) {\n if (RULE_IMPERATIVE_WORDS.test(body)) return true;\n if (RULE_NEGATION_PATTERN.test(body)) return true;\n } else {\n // Non-list lines: require strong imperative AND sentence-like structure\n if (STRONG_IMPERATIVE.test(body) && /^[A-Z]/.test(body)) return true;\n // Also catch imperative sentences starting with a verb (capitalised)\n if (RULE_IMPERATIVE_WORDS.test(body) && /^[A-Z][a-z]/.test(body))\n return true;\n }\n\n return false;\n}\n\nfunction extractKeywords(text: string): string[] {\n const matches = text.matchAll(KEYWORD_REGEX);\n const found = new Set<string>();\n for (const m of matches) {\n found.add(m[0].toLowerCase());\n }\n return [...found];\n}\n\nfunction extractPaths(text: string): string[] {\n const matches = text.matchAll(PATH_REGEX);\n const found: string[] = [];\n for (const m of matches) {\n // Strip trailing punctuation\n const cleaned = m[0].replace(/[.,;)>\\]'\"]+$/, \"\");\n if (cleaned.length > 1) found.push(cleaned);\n }\n return [...new Set(found)];\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport function parseInstructionFile(filePath: string): InstructionFile {\n const raw = readFileSync(filePath, \"utf8\");\n const rawLines = raw.split(/\\r?\\n/);\n\n // Strip the single trailing empty string produced by a final newline.\n // Most text files end with \\n, which splits into [..., ''] — this is not a real line.\n if (rawLines.length > 0 && rawLines[rawLines.length - 1] === \"\") {\n rawLines.pop();\n }\n\n let inCodeBlock = false;\n let inHtmlComment = false;\n const lines: ParsedLine[] = [];\n\n for (let i = 0; i < rawLines.length; i++) {\n const text = rawLines[i] ?? \"\";\n const trimmed = text.trim();\n\n // Classify using current state (before updating)\n const type = classifyLine(text, inCodeBlock, inHtmlComment);\n\n // Update code block state AFTER classifying the fence line itself\n if (!inHtmlComment && trimmed.startsWith(\"```\")) {\n inCodeBlock = !inCodeBlock;\n }\n\n // Update HTML comment state AFTER classifying the current line:\n // - opening line (<!-- ... without -->): set true after this line\n // - closing line (contains -->): set false after this line\n // - lines inside: state remains true\n if (!inCodeBlock) {\n if (inHtmlComment) {\n if (trimmed.includes(\"-->\")) inHtmlComment = false;\n } else if (trimmed.startsWith(\"<!--\") && !trimmed.includes(\"-->\")) {\n inHtmlComment = true;\n }\n }\n\n lines.push({\n lineNumber: i + 1,\n text,\n type,\n keywords: extractKeywords(text),\n referencedPaths: extractPaths(text),\n });\n }\n\n return {\n path: filePath,\n lines,\n lineCount: lines.length,\n // tokenCount and tokenMethod will be filled by the adapter/estimator\n tokenCount: 0,\n tokenMethod: \"estimated\",\n };\n}\n","import type { McpServerConfig, TokenMethod } from \"../types.js\";\n\n// ─── Tiktoken singleton ────────────────────────────────────────────────────\n\ninterface TiktokenEncoder {\n encode(text: string): ArrayLike<number>;\n}\n\nlet encoder: TiktokenEncoder | null = null;\n\n// Single shared Promise — all callers await the same resolution.\n// Setting initialized = true before the await was a race: ensureInitialized()\n// would see the flag and return while encoder was still null.\nconst initPromise: Promise<void> = (async () => {\n try {\n const { getEncoding } = await import(\"js-tiktoken\");\n encoder = getEncoding(\"cl100k_base\");\n } catch {\n process.stderr.write(\n \"[instrlint] Warning: js-tiktoken failed to load — falling back to character estimation\\n\",\n );\n encoder = null;\n }\n})();\n\nexport async function ensureInitialized(): Promise<void> {\n await initPromise;\n}\n\n// ─── CJK character detection ───────────────────────────────────────────────\n\nconst CJK_REGEX = /[\\u3000-\\u9fff\\uac00-\\ud7af\\uf900-\\ufaff]/g;\n\nfunction cjkRatio(text: string): number {\n if (text.length === 0) return 0;\n const matches = text.match(CJK_REGEX);\n return (matches?.length ?? 0) / text.length;\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport interface TokenCount {\n count: number;\n method: TokenMethod;\n}\n\nexport function countTokens(text: string): TokenCount {\n if (text.length === 0) return { count: 0, method: \"measured\" };\n\n if (encoder != null) {\n try {\n return { count: encoder.encode(text).length, method: \"measured\" };\n } catch {\n // Fall through to estimation\n }\n }\n\n return estimateFallback(text);\n}\n\nexport function estimateFallback(text: string): TokenCount {\n const ratio = cjkRatio(text);\n const charsPerToken = 4 * (1 - ratio) + 2 * ratio;\n return {\n count: Math.ceil(text.length / charsPerToken),\n method: \"estimated\",\n };\n}\n\nexport function estimateMcpTokens(config: McpServerConfig): {\n count: number;\n method: \"estimated\";\n} {\n if (config.toolCount != null) {\n return { count: config.toolCount * 400, method: \"estimated\" };\n }\n // Default: assume a small server (~2500 tokens)\n return { count: 2500, method: \"estimated\" };\n}\n","import { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { parseInstructionFile } from \"../core/parser.js\";\nimport {\n countTokens,\n estimateMcpTokens,\n} from \"../detectors/token-estimator.js\";\nimport type {\n InstructionFile,\n McpServerConfig,\n ParsedInstructions,\n SkillFile,\n} from \"../types.js\";\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction safeParseFile(filePath: string): InstructionFile | null {\n try {\n const raw = readFileSync(filePath, \"utf8\");\n const file = parseInstructionFile(filePath);\n const { count, method } = countTokens(raw);\n return { ...file, tokenCount: count, tokenMethod: method };\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not read ${filePath}, skipping\\n`,\n );\n return null;\n }\n}\n\nfunction emptyFile(path: string): InstructionFile {\n return {\n path,\n lines: [],\n lineCount: 0,\n tokenCount: 0,\n tokenMethod: \"estimated\",\n };\n}\n\n// ─── Skills ───────────────────────────────────────────────────────────────\n\nfunction loadSkills(projectRoot: string): SkillFile[] {\n const skillsDir = join(projectRoot, \".agents\", \"skills\");\n if (!existsSync(skillsDir)) return [];\n\n const skills: SkillFile[] = [];\n let entries: string[] = [];\n try {\n entries = readdirSync(skillsDir);\n } catch {\n return [];\n }\n\n for (const skillName of entries) {\n const skillFile = join(skillsDir, skillName, \"SKILL.md\");\n if (!existsSync(skillFile)) continue;\n const parsed = safeParseFile(skillFile);\n if (parsed != null) {\n skills.push({ ...parsed, skillName });\n }\n }\n\n return skills;\n}\n\n// ─── MCP servers from .codex/config.toml ─────────────────────────────────\n\n/**\n * Minimal TOML parser targeting only [mcp_servers.<name>] sections.\n * Handles simple key = \"value\" and key = [\"array\"] under those sections.\n */\nfunction parseMcpFromToml(toml: string): McpServerConfig[] {\n const servers: McpServerConfig[] = [];\n const sectionRe = /^\\[mcp_servers\\.([^\\]]+)\\]/;\n const keyValueRe = /^(\\w+)\\s*=\\s*(.+)$/;\n\n let currentName: string | null = null;\n let currentTools: string[] | undefined;\n\n const flush = () => {\n if (currentName != null) {\n const config: McpServerConfig = {\n name: currentName,\n estimatedTokens: 0,\n ...(currentTools !== undefined ? { toolCount: currentTools.length } : {}),\n };\n const { count } = estimateMcpTokens(config);\n servers.push({ ...config, estimatedTokens: count });\n }\n currentName = null;\n currentTools = undefined;\n };\n\n for (const line of toml.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"#\") || trimmed === \"\") continue;\n\n const sectionMatch = sectionRe.exec(trimmed);\n if (sectionMatch != null) {\n flush();\n currentName = sectionMatch[1]!;\n continue;\n }\n\n if (currentName == null) continue;\n\n const kvMatch = keyValueRe.exec(trimmed);\n if (kvMatch == null) continue;\n\n const key = kvMatch[1]!;\n const raw = kvMatch[2]!.trim();\n\n if (key === \"tools\") {\n // Parse inline array: [\"tool1\", \"tool2\"]\n const items = raw.match(/\"([^\"]+)\"/g);\n currentTools = items != null ? items.map((s) => s.slice(1, -1)) : [];\n }\n }\n\n flush();\n return servers;\n}\n\nfunction loadMcpServers(projectRoot: string): McpServerConfig[] {\n const tomlPath = join(projectRoot, \".codex\", \"config.toml\");\n if (!existsSync(tomlPath)) return [];\n\n try {\n const raw = readFileSync(tomlPath, \"utf8\");\n return parseMcpFromToml(raw);\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not parse MCP config in ${tomlPath}, skipping\\n`,\n );\n return [];\n }\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport function loadCodexProject(projectRoot: string): ParsedInstructions {\n const rootFilePath = join(projectRoot, \"AGENTS.md\");\n const rootFile: InstructionFile = existsSync(rootFilePath)\n ? (safeParseFile(rootFilePath) ?? emptyFile(rootFilePath))\n : emptyFile(rootFilePath);\n\n const skills = loadSkills(projectRoot);\n const mcpServers = loadMcpServers(projectRoot);\n\n return {\n tool: \"codex\",\n rootFile,\n rules: [],\n skills,\n subFiles: [],\n mcpServers,\n };\n}\n","import { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { parseInstructionFile, parseYamlFrontmatter } from \"../core/parser.js\";\nimport {\n countTokens,\n estimateMcpTokens,\n} from \"../detectors/token-estimator.js\";\nimport type {\n InstructionFile,\n McpServerConfig,\n ParsedInstructions,\n RuleFile,\n} from \"../types.js\";\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction safeParseFile(filePath: string): InstructionFile | null {\n try {\n const raw = readFileSync(filePath, \"utf8\");\n const file = parseInstructionFile(filePath);\n const { count, method } = countTokens(raw);\n return { ...file, tokenCount: count, tokenMethod: method };\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not read ${filePath}, skipping\\n`,\n );\n return null;\n }\n}\n\nfunction emptyFile(path: string): InstructionFile {\n return {\n path,\n lines: [],\n lineCount: 0,\n tokenCount: 0,\n tokenMethod: \"estimated\",\n };\n}\n\n// ─── Root file ─────────────────────────────────────────────────────────────\n\nfunction findRootFile(projectRoot: string): string | null {\n const cursorRules = join(projectRoot, \".cursorrules\");\n if (existsSync(cursorRules)) return cursorRules;\n return null;\n}\n\n// ─── Rules from .cursor/rules/*.md ────────────────────────────────────────\n\nfunction loadRules(projectRoot: string): RuleFile[] {\n const rulesDir = join(projectRoot, \".cursor\", \"rules\");\n if (!existsSync(rulesDir)) return [];\n\n const rules: RuleFile[] = [];\n let entries: string[] = [];\n try {\n entries = readdirSync(rulesDir).filter((f) => f.endsWith(\".md\"));\n } catch {\n return [];\n }\n\n for (const filename of entries) {\n const filePath = join(rulesDir, filename);\n try {\n const raw = readFileSync(filePath, \"utf8\");\n // Cursor uses globs: in frontmatter (not paths:)\n const { globs, body } = parseYamlFrontmatter(raw);\n const baseFile = parseInstructionFile(filePath);\n const { count, method } = countTokens(body);\n rules.push({\n ...baseFile,\n tokenCount: count,\n tokenMethod: method,\n ...(globs != null ? { globs } : {}),\n });\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not parse rule ${filePath}, skipping\\n`,\n );\n }\n }\n\n return rules;\n}\n\n// ─── MCP servers from .cursor/mcp.json ────────────────────────────────────\n\ninterface CursorMcpEntry {\n command?: string;\n args?: string[];\n tools?: unknown[];\n}\n\nfunction loadMcpServers(projectRoot: string): McpServerConfig[] {\n const mcpPath = join(projectRoot, \".cursor\", \"mcp.json\");\n if (!existsSync(mcpPath)) return [];\n\n try {\n const raw = readFileSync(mcpPath, \"utf8\");\n const parsed: unknown = JSON.parse(raw);\n if (\n parsed == null ||\n typeof parsed !== \"object\" ||\n !(\"mcpServers\" in parsed)\n ) {\n return [];\n }\n const mcpServers = (\n parsed as { mcpServers: Record<string, CursorMcpEntry> }\n ).mcpServers;\n return Object.entries(mcpServers).map(([name, entry]) => {\n const toolCount = Array.isArray(entry.tools) ? entry.tools.length : undefined;\n const config: McpServerConfig = {\n name,\n estimatedTokens: 0,\n ...(toolCount !== undefined ? { toolCount } : {}),\n };\n const { count } = estimateMcpTokens(config);\n return { ...config, estimatedTokens: count };\n });\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not parse MCP config in ${mcpPath}, skipping\\n`,\n );\n return [];\n }\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport function loadCursorProject(projectRoot: string): ParsedInstructions {\n const rootFilePath = findRootFile(projectRoot);\n const rootFile: InstructionFile =\n rootFilePath != null\n ? (safeParseFile(rootFilePath) ?? emptyFile(rootFilePath))\n : emptyFile(join(projectRoot, \".cursorrules\"));\n\n const rules = loadRules(projectRoot);\n const mcpServers = loadMcpServers(projectRoot);\n\n return {\n tool: \"cursor\",\n rootFile,\n rules,\n skills: [],\n subFiles: [],\n mcpServers,\n };\n}\n","import { loadClaudeCodeProject } from \"./claude-code.js\";\nimport { loadCodexProject } from \"./codex.js\";\nimport { loadCursorProject } from \"./cursor.js\";\nimport type { ParsedInstructions, ToolType } from \"../types.js\";\n\nexport function loadProject(\n projectRoot: string,\n tool: ToolType,\n): ParsedInstructions {\n switch (tool) {\n case \"claude-code\":\n return loadClaudeCodeProject(projectRoot);\n case \"codex\":\n return loadCodexProject(projectRoot);\n case \"cursor\":\n return loadCursorProject(projectRoot);\n default:\n return loadClaudeCodeProject(projectRoot);\n }\n}\n","import type {\n BudgetSummary,\n FileTokenEntry,\n Finding,\n ParsedInstructions,\n TokenMethod,\n} from \"../types.js\";\n\nconst CONTEXT_WINDOW = 200_000;\nconst SYSTEM_PROMPT_TOKENS = 12_000;\nconst WARN_LINE_THRESHOLD = 200;\nconst CRITICAL_LINE_THRESHOLD = 400;\nconst WARN_BASELINE_PCT = 0.25; // 25% = 50K\nconst MCP_INFO_THRESHOLD = 10_000;\n\nfunction sumTokens(\n items: Array<{ tokenCount: number; tokenMethod: TokenMethod }>,\n): { tokens: number; method: TokenMethod } {\n if (items.length === 0) return { tokens: 0, method: \"measured\" };\n const tokens = items.reduce((acc, f) => acc + f.tokenCount, 0);\n const method: TokenMethod = items.every((f) => f.tokenMethod === \"measured\")\n ? \"measured\"\n : \"estimated\";\n return { tokens, method };\n}\n\nexport interface BudgetResult {\n findings: Finding[];\n summary: BudgetSummary;\n}\n\nexport function analyzeBudget(instructions: ParsedInstructions): BudgetResult {\n const findings: Finding[] = [];\n\n // ── Root file ────────────────────────────────────────────────────────────\n const rootFileTokens = instructions.rootFile.tokenCount;\n const rootFileMethod = instructions.rootFile.tokenMethod;\n const rootLines = instructions.rootFile.lineCount;\n\n if (rootLines > CRITICAL_LINE_THRESHOLD) {\n findings.push({\n severity: \"critical\",\n category: \"budget\",\n file: instructions.rootFile.path,\n messageKey: \"budget.rootFileCritical\",\n messageParams: { lines: String(rootLines) },\n suggestion: `Root instruction file is ${rootLines} lines — agent compliance drops significantly above 200 lines`,\n autoFixable: false,\n });\n } else if (rootLines > WARN_LINE_THRESHOLD) {\n findings.push({\n severity: \"warning\",\n category: \"budget\",\n file: instructions.rootFile.path,\n messageKey: \"budget.rootFileWarning\",\n messageParams: { lines: String(rootLines) },\n suggestion: `Root instruction file is ${rootLines} lines (recommended: < 200)`,\n autoFixable: false,\n });\n }\n\n // ── Rules ─────────────────────────────────────────────────────────────────\n const { tokens: rulesTokens, method: rulesMethod } = sumTokens(\n instructions.rules,\n );\n\n // ── Skills ────────────────────────────────────────────────────────────────\n const { tokens: skillsTokens, method: skillsMethod } = sumTokens(\n instructions.skills,\n );\n\n // ── Sub-files ─────────────────────────────────────────────────────────────\n const { tokens: subFilesTokens, method: subFilesMethod } = sumTokens(\n instructions.subFiles,\n );\n\n // ── MCP servers ───────────────────────────────────────────────────────────\n const mcpTokens = instructions.mcpServers.reduce(\n (acc, s) => acc + s.estimatedTokens,\n 0,\n );\n\n for (const server of instructions.mcpServers) {\n if (server.estimatedTokens > MCP_INFO_THRESHOLD) {\n findings.push({\n severity: \"info\",\n category: \"budget\",\n file: \".claude/settings.json\",\n messageKey: \"budget.mcpLargeServer\",\n messageParams: {\n name: server.name,\n tokens: server.estimatedTokens.toLocaleString(\"en\"),\n },\n suggestion: `MCP server '${server.name}' consumes ~${server.estimatedTokens.toLocaleString(\"en\")} tokens`,\n autoFixable: false,\n });\n }\n }\n\n // ── Totals ────────────────────────────────────────────────────────────────\n const totalBaseline =\n SYSTEM_PROMPT_TOKENS +\n rootFileTokens +\n rulesTokens +\n skillsTokens +\n subFilesTokens +\n mcpTokens;\n\n const availableTokens = CONTEXT_WINDOW - totalBaseline;\n\n const pct = totalBaseline / CONTEXT_WINDOW;\n if (pct > WARN_BASELINE_PCT) {\n findings.push({\n severity: \"warning\",\n category: \"budget\",\n file: instructions.rootFile.path,\n messageKey: \"budget.baselineHigh\",\n messageParams: { pct: Math.round(pct * 100).toString() },\n suggestion: `Baseline context consumption is ${Math.round(pct * 100)}% of window`,\n autoFixable: false,\n });\n }\n\n // Overall method: measured only if all file groups are measured\n const tokenMethod: TokenMethod = [\n rootFileMethod,\n rulesMethod,\n skillsMethod,\n subFilesMethod,\n ].every((m) => m === \"measured\")\n ? \"measured\"\n : \"estimated\";\n\n // File breakdown\n const fileBreakdown: FileTokenEntry[] = [\n {\n path: instructions.rootFile.path,\n tokenCount: rootFileTokens,\n tokenMethod: rootFileMethod,\n },\n ...instructions.rules.map((r) => ({\n path: r.path,\n tokenCount: r.tokenCount,\n tokenMethod: r.tokenMethod,\n })),\n ...instructions.skills.map((s) => ({\n path: s.path,\n tokenCount: s.tokenCount,\n tokenMethod: s.tokenMethod,\n })),\n ...instructions.subFiles.map((f) => ({\n path: f.path,\n tokenCount: f.tokenCount,\n tokenMethod: f.tokenMethod,\n })),\n ];\n\n const summary: BudgetSummary = {\n systemPromptTokens: SYSTEM_PROMPT_TOKENS,\n rootFileTokens,\n rootFileLines: rootLines,\n rootFileMethod,\n rulesTokens,\n rulesMethod,\n skillsTokens,\n skillsMethod,\n subFilesTokens,\n subFilesMethod,\n mcpTokens,\n totalBaseline,\n availableTokens,\n fileBreakdown,\n tokenMethod,\n };\n\n return { findings, summary };\n}\n","import { readFileSync, existsSync } from \"fs\";\nimport { join } from \"path\";\nimport type { Finding, ParsedInstructions, ParsedLine } from \"../types.js\";\n\n// ─── Config reading helpers ───────────────────────────────────────────────────\n\nfunction readJsonFile(projectRoot: string, filename: string): unknown | null {\n try {\n const content = readFileSync(join(projectRoot, filename), \"utf8\");\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nfunction readTextFile(projectRoot: string, filename: string): string | null {\n try {\n return readFileSync(join(projectRoot, filename), \"utf8\");\n } catch {\n return null;\n }\n}\n\nfunction checkEditorConfig(projectRoot: string, key: string): boolean {\n const content = readTextFile(projectRoot, \".editorconfig\");\n if (!content) return false;\n return new RegExp(`^${key}\\\\s*=\\\\s*.+`, \"m\").test(content);\n}\n\nfunction checkPrettierConfig(projectRoot: string, field: string): boolean {\n // Try .prettierrc and .prettierrc.json\n for (const filename of [\".prettierrc\", \".prettierrc.json\"]) {\n const parsed = readJsonFile(projectRoot, filename);\n if (parsed !== null && typeof parsed === \"object\" && parsed !== null) {\n if (field in (parsed as Record<string, unknown>)) return true;\n }\n }\n return false;\n}\n\nfunction getPrettierField(projectRoot: string, field: string): unknown {\n for (const filename of [\".prettierrc\", \".prettierrc.json\"]) {\n const parsed = readJsonFile(projectRoot, filename);\n if (parsed !== null && typeof parsed === \"object\") {\n const obj = parsed as Record<string, unknown>;\n if (field in obj) return obj[field];\n }\n }\n return undefined;\n}\n\nfunction checkEslintRule(projectRoot: string, ruleName: string): boolean {\n const parsed = readJsonFile(projectRoot, \".eslintrc.json\");\n if (!parsed || typeof parsed !== \"object\") return false;\n const rules = (parsed as Record<string, unknown>)[\"rules\"];\n if (!rules || typeof rules !== \"object\") return false;\n const val = (rules as Record<string, unknown>)[ruleName];\n if (val === undefined) return false;\n if (val === \"off\" || val === 0) return false;\n if (Array.isArray(val) && (val[0] === \"off\" || val[0] === 0)) return false;\n return true;\n}\n\n// ─── Overlap patterns ─────────────────────────────────────────────────────────\n\ninterface OverlapPattern {\n id: string;\n rulePattern: RegExp;\n configCheck: (projectRoot: string) => boolean;\n configName: string;\n}\n\nconst PATTERNS: OverlapPattern[] = [\n {\n id: \"ts-strict\",\n rulePattern: /\\b(typescript|ts)\\b.*\\bstrict\\b|\\bstrict\\s*(mode|typing)/i,\n configCheck: (root) => {\n const tsconfig = readJsonFile(root, \"tsconfig.json\");\n if (!tsconfig || typeof tsconfig !== \"object\") return false;\n const opts = (tsconfig as Record<string, unknown>)[\"compilerOptions\"];\n if (!opts || typeof opts !== \"object\") return false;\n return (opts as Record<string, unknown>)[\"strict\"] === true;\n },\n configName: \"tsconfig.json (compilerOptions.strict: true)\",\n },\n {\n id: \"indent-spaces\",\n rulePattern: /\\b(2|two|4|four)\\s*(-?\\s*)space\\s*indent/i,\n configCheck: (root) =>\n checkEditorConfig(root, \"indent_size\") ||\n checkPrettierConfig(root, \"tabWidth\"),\n configName: \".editorconfig / .prettierrc (indentation)\",\n },\n {\n id: \"import-order\",\n rulePattern: /import\\s*(order|sort)|sort\\s*import/i,\n configCheck: (root) => {\n const pkg = readJsonFile(root, \"package.json\");\n if (!pkg || typeof pkg !== \"object\") return false;\n const devDeps = (pkg as Record<string, unknown>)[\"devDependencies\"];\n const hasPlugin =\n devDeps &&\n typeof devDeps === \"object\" &&\n \"eslint-plugin-import\" in devDeps;\n return hasPlugin === true && checkEslintRule(root, \"import/order\");\n },\n configName: \"eslint-plugin-import (import/order)\",\n },\n {\n id: \"conventional-commit\",\n rulePattern: /conventional\\s*commit/i,\n configCheck: (root) => {\n // Check commitlint key in package.json\n const pkg = readJsonFile(root, \"package.json\");\n if (pkg && typeof pkg === \"object\" && \"commitlint\" in (pkg as object))\n return true;\n // Check commitlint config files\n const configFiles = [\n \"commitlint.config.js\",\n \"commitlint.config.cjs\",\n \"commitlint.config.ts\",\n \".commitlintrc\",\n \".commitlintrc.json\",\n \".commitlintrc.yaml\",\n \".commitlintrc.yml\",\n ];\n return configFiles.some((f) => existsSync(join(root, f)));\n },\n configName: \"commitlint config\",\n },\n {\n id: \"semicolons\",\n rulePattern: /\\b(semicolons?|always\\s*use\\s*;|semi\\s*colon)/i,\n configCheck: (root) => checkPrettierConfig(root, \"semi\"),\n configName: \".prettierrc (semi)\",\n },\n {\n id: \"single-quote\",\n rulePattern: /single\\s*quotes?|prefer\\s*'|use\\s*'/i,\n configCheck: (root) => getPrettierField(root, \"singleQuote\") === true,\n configName: \".prettierrc (singleQuote: true)\",\n },\n {\n id: \"trailing-comma\",\n rulePattern: /trailing\\s*comma/i,\n configCheck: (root) => checkPrettierConfig(root, \"trailingComma\"),\n configName: \".prettierrc (trailingComma)\",\n },\n {\n id: \"max-line-length\",\n rulePattern:\n /\\b(max|maximum)\\s*(line\\s*)?(length|width|chars?)\\b|\\bprint\\s*width\\b/i,\n configCheck: (root) => checkPrettierConfig(root, \"printWidth\"),\n configName: \".prettierrc (printWidth)\",\n },\n {\n id: \"no-console\",\n rulePattern: /\\b(no|avoid|remove)\\b.*\\bconsole\\.(log|warn|error)/i,\n configCheck: (root) => checkEslintRule(root, \"no-console\"),\n configName: \"eslint (no-console)\",\n },\n {\n id: \"no-unused-vars\",\n rulePattern: /\\b(no|remove|avoid)\\s*(unused|dead)\\s*(var|variable|import)/i,\n configCheck: (root) => {\n const tsconfig = readJsonFile(root, \"tsconfig.json\");\n if (tsconfig && typeof tsconfig === \"object\") {\n const opts = (tsconfig as Record<string, unknown>)[\"compilerOptions\"];\n if (opts && typeof opts === \"object\") {\n const o = opts as Record<string, unknown>;\n if (o[\"noUnusedLocals\"] === true || o[\"noUnusedParameters\"] === true)\n return true;\n }\n }\n return (\n checkEslintRule(root, \"no-unused-vars\") ||\n checkEslintRule(root, \"@typescript-eslint/no-unused-vars\")\n );\n },\n configName: \"tsconfig / eslint (no-unused-vars)\",\n },\n {\n id: \"test-framework\",\n rulePattern: /\\b(use|prefer)\\s*(jest|vitest|mocha|jasmine)\\b/i,\n configCheck: (root) => {\n const configs = [\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"jest.config.ts\",\n \"jest.config.js\",\n \"jest.config.cjs\",\n \".mocharc.js\",\n \".mocharc.json\",\n \".mocharc.yaml\",\n ];\n if (configs.some((f) => existsSync(join(root, f)))) return true;\n const pkg = readJsonFile(root, \"package.json\");\n if (!pkg || typeof pkg !== \"object\") return false;\n const devDeps = (pkg as Record<string, unknown>)[\"devDependencies\"] ?? {};\n return [\"jest\", \"vitest\", \"mocha\", \"jasmine\"].some(\n (fw) => typeof devDeps === \"object\" && fw in (devDeps as object),\n );\n },\n configName: \"test framework config file\",\n },\n {\n id: \"formatter\",\n rulePattern: /\\b(format|prettier|biome)\\s*(code|files|on\\s*save)/i,\n configCheck: (root) => {\n const prettierFiles = [\n \".prettierrc\",\n \".prettierrc.json\",\n \".prettierrc.yaml\",\n \".prettierrc.yml\",\n ];\n if (prettierFiles.some((f) => existsSync(join(root, f)))) return true;\n return existsSync(join(root, \"biome.json\"));\n },\n configName: \"prettier / biome config file\",\n },\n {\n id: \"end-of-line\",\n rulePattern: /\\b(line\\s*ending|eol|crlf|lf)\\b/i,\n configCheck: (root) =>\n checkEditorConfig(root, \"end_of_line\") ||\n checkPrettierConfig(root, \"endOfLine\"),\n configName: \".editorconfig / .prettierrc (endOfLine)\",\n },\n {\n id: \"tab-width\",\n rulePattern: /\\btab\\s*(width|size)\\b/i,\n configCheck: (root) =>\n checkEditorConfig(root, \"tab_width\") ||\n checkEditorConfig(root, \"indent_size\") ||\n checkPrettierConfig(root, \"tabWidth\"),\n configName: \".editorconfig / .prettierrc (tabWidth)\",\n },\n {\n id: \"no-default-export\",\n rulePattern: /\\b(no|avoid|prefer\\s*named)\\s*(default\\s*export)/i,\n configCheck: (root) =>\n checkEslintRule(root, \"import/no-default-export\") ||\n checkEslintRule(root, \"no-restricted-exports\"),\n configName: \"eslint-plugin-import (no-default-export)\",\n },\n];\n\n// ─── Detector ─────────────────────────────────────────────────────────────────\n\nfunction collectRuleLines(\n instructions: ParsedInstructions,\n): Array<{ line: ParsedLine; file: string }> {\n const result: Array<{ line: ParsedLine; file: string }> = [];\n for (const l of instructions.rootFile.lines) {\n if (l.type === \"rule\")\n result.push({ line: l, file: instructions.rootFile.path });\n }\n for (const sub of instructions.subFiles) {\n for (const l of sub.lines) {\n if (l.type === \"rule\") result.push({ line: l, file: sub.path });\n }\n }\n for (const rule of instructions.rules) {\n for (const l of rule.lines) {\n if (l.type === \"rule\") result.push({ line: l, file: rule.path });\n }\n }\n return result;\n}\n\nexport function detectConfigOverlaps(\n instructions: ParsedInstructions,\n projectRoot: string,\n): Finding[] {\n const findings: Finding[] = [];\n const ruleLines = collectRuleLines(instructions);\n\n for (const { line, file } of ruleLines) {\n for (const pattern of PATTERNS) {\n if (\n pattern.rulePattern.test(line.text) &&\n pattern.configCheck(projectRoot)\n ) {\n const ruleText = line.text.trim();\n const short =\n ruleText.length > 60 ? ruleText.slice(0, 60) + \"…\" : ruleText;\n findings.push({\n severity: \"warning\",\n category: \"dead-rule\",\n file,\n line: line.lineNumber,\n messageKey: \"deadRule.configOverlap\",\n messageParams: {\n rule: ruleText.slice(0, 80),\n config: pattern.configName,\n },\n suggestion: `Rule \"${short}\" is already enforced by ${pattern.configName}`,\n autoFixable: true,\n });\n break; // one pattern match per line is enough\n }\n }\n }\n\n return findings;\n}\n","const STOP_WORDS = new Set([\n 'the', 'a', 'an', 'is', 'are', 'to', 'for', 'and', 'or', 'in', 'of', 'with', 'that', 'this',\n]);\n\nexport function tokenizeWords(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((w) => w.length > 1);\n}\n\nexport function removeStopWords(words: string[]): string[] {\n return words.filter((w) => !STOP_WORDS.has(w));\n}\n\nexport function jaccardSimilarity(setA: string[], setB: string[]): number {\n if (setA.length === 0 && setB.length === 0) return 0;\n const a = new Set(setA);\n const b = new Set(setB);\n let intersection = 0;\n for (const word of a) {\n if (b.has(word)) intersection++;\n }\n const union = new Set([...a, ...b]).size;\n return union === 0 ? 0 : intersection / union;\n}\n","import type { Finding, ParsedInstructions, ParsedLine } from '../types.js';\nimport { jaccardSimilarity, removeStopWords, tokenizeWords } from '../utils/text.js';\n\nconst SIMILARITY_THRESHOLD = 0.7;\nconst MIN_WORDS_AFTER_STOP = 4;\n\ninterface RuleLine {\n line: ParsedLine;\n file: string;\n words: string[];\n}\n\nfunction collectRuleLines(instructions: ParsedInstructions): RuleLine[] {\n const result: RuleLine[] = [];\n\n const add = (lines: ParsedLine[], file: string) => {\n for (const l of lines) {\n if (l.type !== 'rule') continue;\n const words = removeStopWords(tokenizeWords(l.text));\n if (words.length < MIN_WORDS_AFTER_STOP) continue;\n result.push({ line: l, file, words });\n }\n };\n\n add(instructions.rootFile.lines, instructions.rootFile.path);\n for (const sub of instructions.subFiles) add(sub.lines, sub.path);\n for (const rule of instructions.rules) add(rule.lines, rule.path);\n\n return result;\n}\n\nexport function detectDuplicates(instructions: ParsedInstructions): Finding[] {\n const findings: Finding[] = [];\n const ruleLines = collectRuleLines(instructions);\n const reported = new Set<string>();\n\n for (let i = 0; i < ruleLines.length; i++) {\n for (let j = i + 1; j < ruleLines.length; j++) {\n const a = ruleLines[i]!;\n const b = ruleLines[j]!;\n const pairKey = `${a.file}:${a.line.lineNumber}|${b.file}:${b.line.lineNumber}`;\n if (reported.has(pairKey)) continue;\n\n const sim = jaccardSimilarity(a.words, b.words);\n if (sim < SIMILARITY_THRESHOLD) continue;\n\n reported.add(pairKey);\n\n const isExact = sim >= 1.0;\n const simPct = `${Math.round(sim * 100)}`;\n\n findings.push({\n severity: isExact ? 'warning' : 'info',\n category: 'duplicate',\n file: b.file,\n line: b.line.lineNumber,\n messageKey: isExact ? 'deadRule.exactDuplicate' : 'deadRule.nearDuplicate',\n messageParams: {\n otherFile: a.file,\n otherLine: String(a.line.lineNumber),\n similarity: simPct,\n },\n suggestion: isExact\n ? `Exact duplicate of line ${a.line.lineNumber} in ${a.file}`\n : `Very similar to line ${a.line.lineNumber} in ${a.file} (${simPct}% similar)`,\n autoFixable: isExact,\n });\n }\n }\n\n return findings;\n}\n","import { detectConfigOverlaps } from '../detectors/config-overlap.js';\nimport { detectDuplicates } from '../detectors/duplicate.js';\nimport type { Finding, ParsedInstructions } from '../types.js';\n\nexport interface DeadRulesResult {\n findings: Finding[];\n}\n\nexport function analyzeDeadRules(\n instructions: ParsedInstructions,\n projectRoot: string,\n): DeadRulesResult {\n return {\n findings: [\n ...detectConfigOverlaps(instructions, projectRoot),\n ...detectDuplicates(instructions),\n ],\n };\n}\n","import { removeStopWords, tokenizeWords } from \"../utils/text.js\";\nimport type {\n Finding,\n InstructionFile,\n ParsedInstructions,\n ParsedLine,\n} from \"../types.js\";\n\n// ─── Negation detection ────────────────────────────────────────────────────────\n\nconst NEGATION_WORDS = [\"never\", \"don't\", \"avoid\", \"forbid\"];\n\n/**\n * Returns true if `word` is negated within a single sentence of `text`.\n * Checks each sentence independently to avoid cross-sentence false positives.\n *\n * Possessive forms (\"not Claude's …\") are excluded: when the word immediately\n * follows \"not\" but is itself in possessive form, the negation targets the\n * whole noun phrase, not the word itself.\n */\nfunction isNegated(text: string, word: string): boolean {\n // Split into sentences to prevent cross-sentence false positives\n const sentences = text.split(/[.!?]+\\s+/);\n const escapedWord = word.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const wordPresent = new RegExp(`\\\\b${escapedWord}\\\\b`, \"i\");\n\n for (const sentence of sentences) {\n if (!wordPresent.test(sentence)) continue;\n const lower = sentence.toLowerCase();\n\n for (const neg of NEGATION_WORDS) {\n // Window of 1: negation must be within 1 intervening word of the target.\n // Exclude possessive: \"never Claude's X\" negates the NP, not \"Claude\".\n const pattern = new RegExp(\n `\\\\b${neg}\\\\b(?:\\\\s+\\\\w+){0,1}\\\\s+\\\\b${escapedWord}\\\\b(?!['\\\\u2019]s\\\\b)`,\n \"i\",\n );\n if (pattern.test(lower)) return true;\n }\n\n // \"do not\" / \"not\" before word (within 1 token), same possessive exclusion\n const notPattern = new RegExp(\n `\\\\b(?:do\\\\s+)?not\\\\b(?:\\\\s+\\\\w+){0,1}\\\\s+\\\\b${escapedWord}\\\\b(?!['\\\\u2019]s\\\\b)`,\n \"i\",\n );\n if (notPattern.test(lower)) return true;\n }\n\n return false;\n}\n\n// ─── Helpers ───────────────────────────────────────────────────────────────────\n\n/**\n * Extra stop words specific to contradiction detection.\n * These are polarity markers and generic imperatives/modals that appear across\n * many rule lines and would generate false-positive shared-word matches.\n */\nconst POLARITY_STOP_WORDS = new Set([\n // Polarity / negation markers (meta-level, not domain content)\n \"never\",\n \"always\",\n \"avoid\",\n \"not\",\n // Generic imperative verbs (describe HOW to comply, not WHAT topic)\n \"use\",\n \"ensure\",\n \"require\",\n \"prefer\",\n \"follow\",\n \"keep\",\n \"calls\",\n \"run\",\n \"runs\",\n // Common modals and auxiliaries\n \"must\",\n \"should\",\n \"can\",\n \"will\",\n \"may\",\n // Generic quantifiers\n \"all\",\n \"every\",\n \"each\",\n \"any\",\n // Pronouns and copulas — appear in any sentence regardless of topic;\n // their negation carries no semantic domain information\n \"it\",\n \"its\",\n \"be\",\n \"by\",\n \"own\",\n \"on\",\n]);\n\ninterface AnnotatedLine {\n line: ParsedLine;\n words: string[];\n file: string;\n}\n\nfunction collectRuleLines(instructions: ParsedInstructions): AnnotatedLine[] {\n const sources: InstructionFile[] = [\n instructions.rootFile,\n ...instructions.subFiles,\n ...instructions.rules,\n ];\n\n const annotated: AnnotatedLine[] = [];\n for (const file of sources) {\n for (const line of file.lines) {\n if (line.type !== \"rule\") continue;\n const words = removeStopWords(tokenizeWords(line.text)).filter(\n (w) => !POLARITY_STOP_WORDS.has(w),\n );\n if (words.length < 3) continue;\n annotated.push({ line, words, file: file.path });\n }\n }\n return annotated;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport function detectContradictions(\n instructions: ParsedInstructions,\n): Finding[] {\n const lines = collectRuleLines(instructions);\n const findings: Finding[] = [];\n const reportedPairs = new Set<string>();\n\n for (let i = 0; i < lines.length; i++) {\n for (let j = i + 1; j < lines.length; j++) {\n const a = lines[i]!;\n const b = lines[j]!;\n\n // Find unique shared content words (Set-based to avoid duplicate counting)\n const setA = new Set(a.words);\n const setB = new Set(b.words);\n const shared = [...setB].filter((w) => setA.has(w));\n\n if (shared.length < 3) continue;\n\n // Check if any shared word has opposite polarity in the two lines\n const hasContradiction = shared.some(\n (word) => isNegated(a.line.text, word) !== isNegated(b.line.text, word),\n );\n\n if (!hasContradiction) continue;\n\n const pairKey = `${a.file}:${a.line.lineNumber}|${b.file}:${b.line.lineNumber}`;\n if (reportedPairs.has(pairKey)) continue;\n reportedPairs.add(pairKey);\n\n const snippet =\n a.line.text.length > 60\n ? `${a.line.text.slice(0, 60)}...`\n : a.line.text;\n\n findings.push({\n severity: \"critical\",\n category: \"contradiction\",\n file: b.file,\n line: b.line.lineNumber,\n messageKey: \"structure.contradiction\",\n messageParams: {\n snippet,\n lineA: String(a.line.lineNumber),\n lineB: String(b.line.lineNumber),\n fileA: a.file,\n },\n suggestion: `Contradicting rules: \"${snippet}\" (${a.file} line ${a.line.lineNumber}) conflicts with line ${b.line.lineNumber}.`,\n autoFixable: false,\n });\n }\n }\n\n return findings;\n}\n","import { existsSync } from 'fs';\nimport { join } from 'path';\nimport type { Finding, InstructionFile, ParsedInstructions, ParsedLine } from '../types.js';\n\n// ─── Helpers ───────────────────────────────────────────────────────────────────\n\ninterface AnnotatedLine {\n line: ParsedLine;\n file: string;\n}\n\nfunction collectLines(instructions: ParsedInstructions): AnnotatedLine[] {\n const sources: InstructionFile[] = [\n instructions.rootFile,\n ...instructions.subFiles,\n ...instructions.rules,\n ];\n\n const result: AnnotatedLine[] = [];\n for (const file of sources) {\n for (const line of file.lines) {\n if (line.type === 'blank' || line.type === 'code') continue;\n if (line.referencedPaths.length === 0) continue;\n result.push({ line, file: file.path });\n }\n }\n return result;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport function detectStaleRefs(\n instructions: ParsedInstructions,\n projectRoot: string,\n): Finding[] {\n const findings: Finding[] = [];\n\n for (const { line, file } of collectLines(instructions)) {\n for (const refPath of line.referencedPaths) {\n // Skip directory refs (trailing slash) and glob patterns\n if (refPath.endsWith('/') || refPath.includes('*')) continue;\n\n const absolutePath = join(projectRoot, refPath);\n if (!existsSync(absolutePath)) {\n findings.push({\n severity: 'warning',\n category: 'stale-ref',\n file,\n line: line.lineNumber,\n messageKey: 'structure.staleRef',\n messageParams: { path: refPath },\n suggestion: `Stale reference: \"${refPath}\" does not exist.`,\n autoFixable: true,\n });\n }\n }\n }\n\n return findings;\n}\n","import type { Finding, ParsedInstructions } from \"../types.js\";\n\n// ─── Patterns ─────────────────────────────────────────────────────────────────\n\n/** Rule references a specific source directory → suggest a path-scoped rule file */\nconst PATH_REF_PATTERN = /\\b(?:src|tests?|lib|dist)\\//i;\n\n/** Rule forbids a git workflow action → suggest a git hook instead */\nconst HOOK_PATTERN =\n /\\b(?:never|don't|do\\s+not|forbid)\\b.*\\b(?:commit|push|merge|build|run)\\b/i;\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport function classifyScope(instructions: ParsedInstructions): Finding[] {\n const findings: Finding[] = [];\n const rootFile = instructions.rootFile;\n\n for (const line of rootFile.lines) {\n if (line.type !== \"rule\") continue;\n\n if (HOOK_PATTERN.test(line.text)) {\n const snippet =\n line.text.length > 60 ? `${line.text.slice(0, 60)}...` : line.text;\n findings.push({\n severity: \"info\",\n category: \"structure\",\n file: rootFile.path,\n line: line.lineNumber,\n messageKey: \"structure.scopeHook\",\n messageParams: { line: String(line.lineNumber), snippet },\n suggestion: `Rule at line ${line.lineNumber} could be a git hook: \"${snippet}\"`,\n autoFixable: false,\n });\n // Don't also emit path-scoped suggestion for the same line\n continue;\n }\n\n if (PATH_REF_PATTERN.test(line.text)) {\n const snippet =\n line.text.length > 60 ? `${line.text.slice(0, 60)}...` : line.text;\n findings.push({\n severity: \"info\",\n category: \"structure\",\n file: rootFile.path,\n line: line.lineNumber,\n messageKey: \"structure.scopePathScoped\",\n messageParams: { line: String(line.lineNumber), snippet },\n suggestion: `Rule at line ${line.lineNumber} references a specific path — consider a path-scoped rule file: \"${snippet}\"`,\n autoFixable: false,\n });\n }\n }\n\n return findings;\n}\n","import { detectContradictions } from '../detectors/contradiction.js';\nimport { detectStaleRefs } from '../detectors/stale-refs.js';\nimport { classifyScope } from '../detectors/scope-classifier.js';\nimport type { Finding, ParsedInstructions } from '../types.js';\n\nexport interface StructureResult {\n findings: Finding[];\n}\n\nexport function analyzeStructure(\n instructions: ParsedInstructions,\n projectRoot: string,\n): StructureResult {\n return {\n findings: [\n ...detectContradictions(instructions),\n ...detectStaleRefs(instructions, projectRoot),\n ...classifyScope(instructions),\n ],\n };\n}\n","import type { ActionItem, BudgetSummary, Finding } from \"../types.js\";\n\nexport type Grade = \"A\" | \"B\" | \"C\" | \"D\" | \"F\";\n\nconst CONTEXT_WINDOW = 200_000;\n\n// ─── Scoring weights ───────────────────────────────────────────────────────────\n\nconst CRITICAL_DEDUCTION = 10;\nconst WARNING_DEDUCTION = 5;\nconst INFO_DEDUCTION = 1;\n\nconst MAX_CRITICAL_DEDUCTION = 40;\nconst MAX_WARNING_DEDUCTION = 30;\nconst MAX_INFO_DEDUCTION = 10;\nconst MAX_ROOT_FILE_PENALTY = 30;\nconst MAX_BUDGET_DEDUCTION = 30;\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport function gradeFromScore(score: number): Grade {\n if (score >= 90) return \"A\";\n if (score >= 80) return \"B\";\n if (score >= 70) return \"C\";\n if (score >= 60) return \"D\";\n return \"F\";\n}\n\nexport function calculateScore(\n findings: Finding[],\n budget: BudgetSummary,\n): { score: number; grade: Grade } {\n const criticals = findings.filter((f) => f.severity === \"critical\").length;\n const warnings = findings.filter((f) => f.severity === \"warning\").length;\n const infos = findings.filter((f) => f.severity === \"info\").length;\n\n const criticalDeduction = Math.min(\n criticals * CRITICAL_DEDUCTION,\n MAX_CRITICAL_DEDUCTION,\n );\n const warningDeduction = Math.min(\n warnings * WARNING_DEDUCTION,\n MAX_WARNING_DEDUCTION,\n );\n const infoDeduction = Math.min(infos * INFO_DEDUCTION, MAX_INFO_DEDUCTION);\n\n // Root file length penalty — proportional beyond each threshold\n // 201-300: -5, 301-400: -8, 401-500: -10, 501-600: -15, 601-700: -20, ...\n const rootLines = budget.rootFileLines;\n let rootFilePenalty = 0;\n if (rootLines > 400) {\n rootFilePenalty = 10 + Math.floor((rootLines - 400) / 100) * 5;\n } else if (rootLines > 200) {\n rootFilePenalty = 5 + Math.floor((rootLines - 200) / 100) * 3;\n }\n rootFilePenalty = Math.min(rootFilePenalty, MAX_ROOT_FILE_PENALTY);\n\n // Budget penalty — continuous beyond 25% of context window\n // 25%: -5, 50%: -15, 75%: -25, capped at 30\n const baselinePct = budget.totalBaseline / CONTEXT_WINDOW;\n let budgetDeduction = 0;\n if (baselinePct > 0.25) {\n budgetDeduction = 5 + Math.floor((baselinePct - 0.25) * 40);\n }\n budgetDeduction = Math.min(budgetDeduction, MAX_BUDGET_DEDUCTION);\n\n const score = Math.max(\n 0,\n 100 -\n criticalDeduction -\n warningDeduction -\n infoDeduction -\n rootFilePenalty -\n budgetDeduction,\n );\n return { score, grade: gradeFromScore(score) };\n}\n\nexport function buildActionPlan(findings: Finding[]): ActionItem[] {\n const priorityOf = (f: Finding): number => {\n if (f.severity === \"critical\") return 1;\n if (f.severity === \"warning\") return 2;\n return 3;\n };\n\n const seen = new Set<string>();\n return findings\n .filter((f) => {\n if (seen.has(f.suggestion)) return false;\n seen.add(f.suggestion);\n return true;\n })\n .map((f) => ({\n priority: priorityOf(f),\n description: f.suggestion,\n category: f.category,\n }))\n .sort((a, b) => a.priority - b.priority);\n}\n","import chalk from \"chalk\";\nimport type { BudgetSummary, Finding, HealthReport } from \"../types.js\";\nimport { bar } from \"../commands/budget-command.js\";\nimport { t, plural, getLocale } from \"../i18n/index.js\";\n\n// ─── Visual helpers ───────────────────────────────────────────────────────────\n\nconst BOX_W = 50;\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\n\nfunction visLen(s: string): number {\n return s.replace(ANSI_RE, \"\").length;\n}\n\nfunction padR(s: string, w: number): string {\n return s + \" \".repeat(Math.max(0, w - visLen(s)));\n}\n\nfunction gradeColor(grade: string): (s: string) => string {\n if (grade === \"A\") return chalk.green;\n if (grade === \"B\") return chalk.cyan;\n if (grade === \"C\") return chalk.yellow;\n if (grade === \"D\") return chalk.magenta;\n return chalk.red;\n}\n\nfunction gradeBadge(grade: string): string {\n // Light backgrounds (A/B/C) need dark text; dark backgrounds (D/F) need white text\n if (grade === \"A\") return chalk.bgGreen(chalk.bold.black(` ${grade} `));\n if (grade === \"B\") return chalk.bgCyan(chalk.bold.black(` ${grade} `));\n if (grade === \"C\") return chalk.bgYellow(chalk.bold.black(` ${grade} `));\n if (grade === \"D\") return chalk.bgMagenta(chalk.bold.white(` ${grade} `));\n return chalk.bgRed(chalk.bold.white(` ${grade} `));\n}\n\nfunction scoreBar(score: number, grade: string, width = 30): string {\n const filled = Math.round((score / 100) * width);\n const empty = width - filled;\n return gradeColor(grade)(\"█\".repeat(filled)) + chalk.gray(\"░\".repeat(empty));\n}\n\nfunction sectionHeader(title: string, width = BOX_W): string {\n const inner = ` ${title} `;\n const remaining = Math.max(0, width - 2 - inner.length);\n return chalk.gray(` ──${chalk.bold.white(inner)}${\"─\".repeat(remaining)}──`);\n}\n\n// ─── Compact helpers ───────────────────────────────────────────────────────────\n\nfunction printCompactBudget(\n summary: BudgetSummary,\n output: { log: typeof console.log },\n): void {\n const total = summary.totalBaseline;\n const window = total + summary.availableTokens;\n const fraction = total / window;\n const fmt = new Intl.NumberFormat(getLocale());\n const usedPrefix = summary.tokenMethod === \"estimated\" ? \"~\" : \"\";\n const budgetLine = t(\"compact.budgetLine\", {\n used: `${usedPrefix}${fmt.format(total)}`,\n window: fmt.format(window),\n pct: String(Math.round(fraction * 100)),\n });\n output.log(` ${chalk.yellow(budgetLine)} ${bar(fraction, 14)}`);\n}\n\nconst SEVERITY_ORDER: Record<string, number> = {\n critical: 0,\n warning: 1,\n info: 2,\n};\n\nfunction printFindingsTable(\n findings: Finding[],\n output: { log: typeof console.log },\n): void {\n const categories: Array<{ key: string; label: string }> = [\n { key: \"contradiction\", label: t(\"compact.contradictions\") },\n { key: \"budget\", label: t(\"compact.budget\") },\n { key: \"dead-rule\", label: t(\"compact.deadRules\") },\n { key: \"duplicate\", label: t(\"compact.duplicates\") },\n { key: \"stale-ref\", label: t(\"compact.staleRefs\") },\n { key: \"structure\", label: t(\"compact.structure\") },\n ];\n\n const rows = categories\n .map(({ key, label }) => {\n const group = findings.filter((f) => f.category === key);\n return {\n label,\n critical: group.filter((f) => f.severity === \"critical\").length,\n warning: group.filter((f) => f.severity === \"warning\").length,\n info: group.filter((f) => f.severity === \"info\").length,\n };\n })\n .filter((r) => r.critical + r.warning + r.info > 0);\n\n if (rows.length === 0) return;\n\n output.log(sectionHeader(t(\"label.findings\")));\n for (const row of rows) {\n const parts: string[] = [];\n if (row.critical > 0) parts.push(chalk.red(`✖ ${row.critical}`));\n if (row.warning > 0) parts.push(chalk.yellow(`⚠ ${row.warning}`));\n if (row.info > 0) parts.push(chalk.blue(`ℹ ${row.info}`));\n output.log(\n ` ${chalk.whiteBright(row.label.padEnd(18))}${parts.join(\" \")}`,\n );\n }\n}\n\nfunction printTopIssues(\n findings: Finding[],\n output: { log: typeof console.log },\n): void {\n if (findings.length === 0) return;\n\n const sorted = [...findings].sort(\n (a, b) =>\n (SEVERITY_ORDER[a.severity] ?? 3) - (SEVERITY_ORDER[b.severity] ?? 3),\n );\n const top = sorted.slice(0, 5);\n\n output.log(\"\");\n output.log(sectionHeader(t(\"label.topIssues\")));\n for (let i = 0; i < top.length; i++) {\n const f = top[i]!;\n const icon =\n f.severity === \"critical\"\n ? chalk.red(\"✖\")\n : f.severity === \"warning\"\n ? chalk.yellow(\"⚠\")\n : chalk.blue(\"ℹ\");\n const msg = t(f.messageKey, f.messageParams);\n const truncated = msg.length > 68 ? `${msg.slice(0, 68)}…` : msg;\n const verifyBadge =\n f.verification?.verdict === \"confirmed\"\n ? chalk.green(` ✓ ${t(\"verification.confirmed\")}`)\n : f.verification?.verdict === \"uncertain\"\n ? chalk.yellow(` ❓ ${t(\"verification.uncertain\")}`)\n : \"\";\n output.log(\n ` ${chalk.white(`${i + 1}.`)} ${icon} ${truncated}${verifyBadge}`,\n );\n }\n if (sorted.length > 5) {\n output.log(\n chalk.white(\n ` ${t(\"compact.andMore\", { count: String(sorted.length - 5) })}`,\n ),\n );\n }\n}\n\n// ─── Terminal reporter ─────────────────────────────────────────────────────────\n\nexport function printCombinedTerminal(\n report: HealthReport,\n output: { log: typeof console.log } = console,\n): void {\n const { project, tool, score, grade, tokenMethod } = report;\n const border = \"─\".repeat(BOX_W);\n\n // ─── Header box ─────────────────────────────────────────────────────────────\n output.log(\"\");\n const B = chalk.green; // box border colour — use consistently\n output.log(B(` ╭${border}╮`));\n const line1 = ` ${chalk.bold.white(\"instrlint\")} ${B(\"─\")} ${chalk.cyan(project)}`;\n output.log(` ${B(\"│\")}${padR(line1, BOX_W)}${B(\"│\")}`);\n const line2 = ` ${chalk.white(tool)} ${B(\"·\")} ${chalk.white(tokenMethod)}`;\n output.log(` ${B(\"│\")}${padR(line2, BOX_W)}${B(\"│\")}`);\n output.log(B(` ├${border}┤`));\n const scoreLine = ` ${scoreBar(score, grade)} ${chalk.bold.white(String(score))}/100 ${gradeBadge(grade)}`;\n output.log(` ${B(\"│\")}${padR(scoreLine, BOX_W)}${B(\"│\")}`);\n output.log(B(` ╰${border}╯`));\n\n // ─── Budget ─────────────────────────────────────────────────────────────────\n output.log(\"\");\n output.log(sectionHeader(t(\"label.budget\")));\n printCompactBudget(report.budget, output);\n\n // ─── Findings ───────────────────────────────────────────────────────────────\n if (report.findings.length > 0) {\n output.log(\"\");\n printFindingsTable(report.findings, output);\n printTopIssues(report.findings, output);\n }\n\n // ─── Footer ─────────────────────────────────────────────────────────────────\n output.log(\"\");\n if (report.findings.length === 0) {\n output.log(chalk.green(` ${t(\"status.perfectScore\")}`));\n } else {\n const criticals = report.findings.filter(\n (f) => f.severity === \"critical\",\n ).length;\n const warnings = report.findings.filter(\n (f) => f.severity === \"warning\",\n ).length;\n const infos = report.findings.filter((f) => f.severity === \"info\").length;\n const parts: string[] = [];\n if (criticals > 0)\n parts.push(\n chalk.red(t(\"severity.critical\", { count: String(criticals) })),\n );\n if (warnings > 0)\n parts.push(\n chalk.yellow(\n t(\"severity.warnings\", {\n count: String(warnings),\n s: plural(warnings),\n }),\n ),\n );\n if (infos > 0)\n parts.push(\n chalk.blue(\n t(\"severity.suggestions\", { count: String(infos), s: plural(infos) }),\n ),\n );\n const summary = parts.join(chalk.gray(\" · \"));\n const summaryVisible = summary.replace(ANSI_RE, \"\");\n const pad = Math.max(0, BOX_W - 2 - summaryVisible.length);\n output.log(\n chalk.gray(` ──`) + ` ${summary} ` + chalk.gray(\"─\".repeat(pad)),\n );\n }\n if (report.rejectedByVerification) {\n output.log(\n chalk.gray(\n ` ${t(\"verification.filteredCount\", { count: String(report.rejectedByVerification), s: plural(report.rejectedByVerification) })}`,\n ),\n );\n }\n output.log(\"\");\n}\n\n// ─── JSON reporter ─────────────────────────────────────────────────────────────\n\nexport function reportJson(report: HealthReport): string {\n return JSON.stringify(report, null, 2);\n}\n\n// ─── Markdown reporter ─────────────────────────────────────────────────────────\n\nfunction mdSeverityIcon(f: Finding): string {\n if (f.severity === \"critical\") return \"🔴\";\n if (f.severity === \"warning\") return \"🟡\";\n return \"ℹ️\";\n}\n\nfunction mdBar(fraction: number, width = 20): string {\n const filled = Math.round(Math.min(1, Math.max(0, fraction)) * width);\n const empty = width - filled;\n return \"`\" + \"█\".repeat(filled) + \"░\".repeat(empty) + \"`\";\n}\n\nfunction mdFormatTokens(\n count: number,\n method: \"measured\" | \"estimated\",\n): string {\n const fmt = new Intl.NumberFormat(getLocale());\n return method === \"estimated\" ? `~${fmt.format(count)}` : fmt.format(count);\n}\n\nexport function reportMarkdown(\n report: HealthReport,\n extraSections: string[] = [],\n): string {\n const { project, tool, score, grade, findings, budget } = report;\n const criticals = findings.filter((f) => f.severity === \"critical\").length;\n const warnings = findings.filter((f) => f.severity === \"warning\").length;\n const infos = findings.filter((f) => f.severity === \"info\").length;\n const gradeEmoji =\n grade === \"A\"\n ? \"🟢\"\n : grade === \"B\"\n ? \"🔵\"\n : grade === \"C\"\n ? \"🟡\"\n : grade === \"D\"\n ? \"🟠\"\n : \"🔴\";\n\n const lines: string[] = [\n `# ${t(\"markdown.title\", { project })}`,\n \"\",\n `${gradeEmoji} **${score}/100 (${grade})** ${mdBar(score / 100, 25)} · \\`${tool}\\``,\n \"\",\n t(\"markdown.summary\"),\n \"\",\n `| ${t(\"markdown.severity\")} | ${t(\"markdown.count\")} |`,\n \"|----------|-------|\",\n `| ${t(\"markdown.critical\")} | ${criticals} |`,\n `| ${t(\"markdown.warning\")} | ${warnings} |`,\n `| ${t(\"markdown.info\")} | ${infos} |`,\n ...(report.rejectedByVerification\n ? [\n `| ${t(\"verification.filteredCount\", { count: String(report.rejectedByVerification), s: plural(report.rejectedByVerification) })} | |`,\n ]\n : []),\n \"\",\n ];\n\n // ── Budget breakdown ─────────────────────────────────────────────────────\n const window = budget.totalBaseline + budget.availableTokens;\n const budgetRows: Array<{\n labelKey: string;\n tokens: number;\n method: \"measured\" | \"estimated\";\n }> = [\n {\n labelKey: \"label.systemPrompt\",\n tokens: budget.systemPromptTokens,\n method: \"estimated\" as const,\n },\n {\n labelKey: \"label.rootFile\",\n tokens: budget.rootFileTokens,\n method: budget.rootFileMethod,\n },\n {\n labelKey: \"label.ruleFiles\",\n tokens: budget.rulesTokens,\n method: budget.rulesMethod,\n },\n {\n labelKey: \"label.skillFiles\",\n tokens: budget.skillsTokens,\n method: budget.skillsMethod,\n },\n {\n labelKey: \"label.subDirFiles\",\n tokens: budget.subFilesTokens,\n method: budget.subFilesMethod,\n },\n {\n labelKey: \"label.mcpServers\",\n tokens: budget.mcpTokens,\n method: \"estimated\" as const,\n },\n ].filter((r) => r.tokens > 0);\n\n lines.push(`## ${t(\"label.tokenBudget\")}`, \"\");\n lines.push(\n `| ${t(\"markdown.budgetCategory\")} | ${t(\"markdown.budgetTokens\")} | % | |`,\n \"|------|--------|---|---|\",\n );\n for (const row of budgetRows) {\n const pctVal = Math.round((row.tokens / window) * 100);\n lines.push(\n `| ${t(row.labelKey)} | ${mdFormatTokens(row.tokens, row.method)} | ${pctVal}% | ${mdBar(row.tokens / window, 12)} |`,\n );\n }\n const baselinePct = Math.round((budget.totalBaseline / window) * 100);\n lines.push(\n `| **${t(\"label.baselineTotal\")}** | **${mdFormatTokens(budget.totalBaseline, budget.tokenMethod)}** | **${baselinePct}%** | ${mdBar(budget.totalBaseline / window, 12)} |`,\n );\n lines.push(\n `| ${t(\"label.available\")} | ${mdFormatTokens(budget.availableTokens, \"estimated\")} | ${100 - baselinePct}% | |`,\n );\n lines.push(\"\");\n\n // Findings grouped by category\n const categories: Array<{\n labelKey: string;\n filter: (f: Finding) => boolean;\n }> = [\n {\n labelKey: \"markdown.contradictions\",\n filter: (f) => f.category === \"contradiction\",\n },\n {\n labelKey: \"markdown.staleReferences\",\n filter: (f) => f.category === \"stale-ref\",\n },\n {\n labelKey: \"markdown.deadRules\",\n filter: (f) => f.category === \"dead-rule\",\n },\n {\n labelKey: \"markdown.duplicateRules\",\n filter: (f) => f.category === \"duplicate\",\n },\n {\n labelKey: \"markdown.budgetIssues\",\n filter: (f) => f.category === \"budget\",\n },\n {\n labelKey: \"markdown.refactoringOpportunities\",\n filter: (f) => f.category === \"structure\",\n },\n ];\n\n for (const { labelKey, filter } of categories) {\n const group = findings.filter(filter);\n if (group.length === 0) continue;\n lines.push(`## ${t(labelKey)}`, \"\");\n for (const f of group) {\n const loc =\n f.line != null\n ? ` ${t(\"markdown.lineRef\", { line: String(f.line) })}`\n : \"\";\n const verifyBadge =\n f.verification?.verdict === \"confirmed\"\n ? ` ✓ *${t(\"verification.confirmed\")}*: ${f.verification.reason}`\n : f.verification?.verdict === \"uncertain\"\n ? ` ❓ *${t(\"verification.uncertain\")}*: ${f.verification.reason}`\n : \"\";\n lines.push(\n `- ${mdSeverityIcon(f)} ${t(f.messageKey, f.messageParams)}${loc}${verifyBadge}`,\n );\n }\n lines.push(\"\");\n }\n\n // Action plan\n if (report.actionPlan.length > 0) {\n lines.push(t(\"markdown.actionPlan\"), \"\");\n for (let i = 0; i < Math.min(report.actionPlan.length, 10); i++) {\n const item = report.actionPlan[i]!;\n lines.push(`${i + 1}. ${item.description}`);\n }\n lines.push(\"\");\n }\n\n // Extra sections (e.g. actionable structure suggestions)\n if (extraSections.length > 0) {\n lines.push(...extraSections);\n }\n\n lines.push(\"---\", t(\"markdown.attribution\"));\n return lines.join(\"\\n\");\n}\n","import chalk from \"chalk\";\nimport { scanProject } from \"../core/scanner.js\";\nimport { loadProject } from \"../adapters/dispatch.js\";\nimport { ensureInitialized } from \"../detectors/token-estimator.js\";\nimport { analyzeBudget } from \"../analyzers/budget.js\";\nimport { t, plural, initLocale, getLocale } from \"../i18n/index.js\";\nimport type { BudgetSummary, Finding, TokenMethod } from \"../types.js\";\n\n// ─── Formatting helpers ────────────────────────────────────────────────────\n\nfunction getFmt(): Intl.NumberFormat {\n return new Intl.NumberFormat(getLocale());\n}\n\nexport function formatTokens(count: number, method: TokenMethod): string {\n const formatted = getFmt().format(count);\n if (method === \"measured\") return t(\"tokens.measured\", { count: formatted });\n return t(\"tokens.estimated\", { count: formatted });\n}\n\nexport function bar(fraction: number, width = 24): string {\n const filled = Math.round(Math.min(1, Math.max(0, fraction)) * width);\n const empty = width - filled;\n return chalk.cyan(\"█\".repeat(filled)) + chalk.gray(\"░\".repeat(empty));\n}\n\nexport function pct(fraction: number): string {\n return `${Math.round(fraction * 100)}%`;\n}\n\n// ─── Budget terminal output ────────────────────────────────────────────────\n\nexport function printBudgetTerminal(\n summary: BudgetSummary,\n findings: Finding[],\n output: { log: typeof console.log } = console,\n): void {\n const total = summary.totalBaseline;\n const window = total + summary.availableTokens;\n\n output.log(\"\");\n output.log(chalk.bold.white(` ${t(\"label.tokenBudget\")}`));\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n const rows: Array<{ labelKey: string; tokens: number; method: TokenMethod }> =\n [\n {\n labelKey: \"label.systemPrompt\",\n tokens: summary.systemPromptTokens,\n method: \"estimated\",\n },\n {\n labelKey: \"label.rootFile\",\n tokens: summary.rootFileTokens,\n method: summary.rootFileMethod,\n },\n {\n labelKey: \"label.ruleFiles\",\n tokens: summary.rulesTokens,\n method: summary.rulesMethod,\n },\n {\n labelKey: \"label.skillFiles\",\n tokens: summary.skillsTokens,\n method: summary.skillsMethod,\n },\n {\n labelKey: \"label.subDirFiles\",\n tokens: summary.subFilesTokens,\n method: summary.subFilesMethod,\n },\n {\n labelKey: \"label.mcpServers\",\n tokens: summary.mcpTokens,\n method: \"estimated\",\n },\n ];\n\n for (const row of rows) {\n if (row.tokens === 0) continue;\n const fraction = row.tokens / window;\n const label = t(row.labelKey).padEnd(14);\n const tokenStr = formatTokens(row.tokens, row.method).padStart(28);\n output.log(\n ` ${chalk.white(label)} ${bar(fraction)} ${chalk.yellow(tokenStr)}`,\n );\n }\n\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n const baselineFraction = total / window;\n const baselineStr = formatTokens(total, summary.tokenMethod).padStart(28);\n output.log(\n ` ${t(\"label.baselineTotal\").padEnd(14)} ${bar(baselineFraction)} ${chalk.bold.yellow(baselineStr)} ${chalk.gray(pct(baselineFraction))}`,\n );\n\n const availStr = formatTokens(summary.availableTokens, \"estimated\").padStart(\n 28,\n );\n output.log(\n ` ${t(\"label.available\").padEnd(14)} ${\"\".padEnd(26)} ${chalk.green(availStr)}`,\n );\n output.log(\"\");\n\n if (findings.length === 0) {\n output.log(chalk.green(` ${t(\"status.noBudgetIssues\")}`));\n } else {\n for (const f of findings) {\n const icon =\n f.severity === \"critical\"\n ? chalk.red(\" ✖\")\n : f.severity === \"warning\"\n ? chalk.yellow(\" ⚠\")\n : chalk.blue(\" ℹ\");\n output.log(`${icon} ${t(f.messageKey, f.messageParams)}`);\n }\n }\n output.log(\"\");\n}\n\n// ─── Core run logic (testable) ─────────────────────────────────────────────\n\nexport interface BudgetCommandOpts {\n format: string;\n tool?: string;\n lang?: string;\n projectRoot?: string;\n}\n\nexport interface BudgetCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\nexport async function runBudget(\n opts: BudgetCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): Promise<BudgetCommandResult> {\n initLocale(opts.lang);\n await ensureInitialized();\n\n const projectRoot = opts.projectRoot ?? process.cwd();\n const scan = scanProject(projectRoot, opts.tool);\n\n if (scan.tool === \"unknown\") {\n output.error(t(\"error.unknownTool\"));\n return { exitCode: 1, errorMessage: \"unknown tool\" };\n }\n\n if (scan.rootFilePath === null) {\n output.error(t(\"error.missingRootFile\", { tool: scan.tool }));\n return { exitCode: 1, errorMessage: \"missing root file\" };\n }\n\n const instructions = loadProject(projectRoot, scan.tool);\n const { findings, summary } = analyzeBudget(instructions);\n\n if (opts.format === \"json\") {\n output.log(JSON.stringify({ findings, summary }, null, 2));\n return { exitCode: 0 };\n }\n\n printBudgetTerminal(summary, findings, output);\n return { exitCode: 0 };\n}\n","{\n \"label.tokenBudget\": \"TOKEN BUDGET\",\n \"label.deadRules\": \"DEAD RULES\",\n \"label.structure\": \"STRUCTURE\",\n \"label.actionPlan\": \"ACTION PLAN\",\n \"label.fixSummary\": \"FIX SUMMARY\",\n \"label.systemPrompt\": \"System prompt\",\n \"label.rootFile\": \"Root file\",\n \"label.ruleFiles\": \"Rule files\",\n \"label.skillFiles\": \"Skill files\",\n \"label.subDirFiles\": \"Sub-dir files\",\n \"label.mcpServers\": \"MCP servers\",\n \"label.baselineTotal\": \"Baseline total\",\n \"label.available\": \"Available\",\n \"label.redundantByConfig\": \"Redundant (enforced by config)\",\n \"label.duplicates\": \"Duplicates\",\n \"label.contradictions\": \"Contradictions\",\n \"label.staleReferences\": \"Stale References\",\n \"label.refactoringOpportunities\": \"Refactoring Opportunities\",\n \"label.tool\": \"Tool:\",\n \"label.score\": \"Score:\",\n\n \"status.noBudgetIssues\": \"✓ No budget issues found\",\n \"status.noDeadRules\": \"✓ No dead rules found\",\n \"status.noStructuralIssues\": \"✓ No structural issues found\",\n \"status.noAutoFixable\": \"✓ No auto-fixable issues found\",\n \"status.perfectScore\": \"✓ Perfect score — no issues found\",\n \"status.fixedIssues\": \"✓ Fixed {{count}} issue{{s}} — run `git diff` to review changes\",\n\n \"error.unknownTool\": \"No agent instruction files found. Run this command in a project that uses Claude Code, Codex, or Cursor.\",\n \"error.missingRootFile\": \"Found {{tool}} configuration but no root instruction file.\",\n \"error.dirtyWorkingTree\": \"Working tree is dirty. Commit or stash your changes before running --fix, or use --force to skip this check.\",\n\n \"fix.removedDeadRules\": \"Removed {{count}} redundant rule{{s}}\",\n \"fix.removedStaleRefs\": \"Removed {{count}} stale reference{{s}}\",\n \"fix.removedDuplicates\": \"Removed {{count}} exact duplicate{{s}}\",\n\n \"summary.redundantRules\": \"{{count}} redundant rule{{s}}\",\n \"summary.duplicates\": \"{{count}} duplicate{{s}}\",\n \"summary.contradictions\": \"{{count}} contradiction{{s}}\",\n \"summary.staleRefs\": \"{{count}} stale ref{{s}}\",\n \"summary.refactoringSuggestions\": \"{{count}} refactoring suggestion{{s}}\",\n \"summary.found\": \"{{parts}} found\",\n\n \"tokens.measured\": \"{{count}} tokens\",\n \"tokens.estimated\": \"~{{count}} tokens (estimated)\",\n\n \"actionPlan.andMore\": \"… and {{count}} more\",\n\n \"severity.critical\": \"{{count}} critical\",\n \"severity.warnings\": \"{{count}} warning{{s}}\",\n \"severity.suggestions\": \"{{count}} suggestion{{s}}\",\n\n \"budget.rootFileCritical\": \"Root instruction file is {{lines}} lines — agent compliance drops significantly above 200 lines\",\n \"budget.rootFileWarning\": \"Root instruction file is {{lines}} lines (recommended: < 200)\",\n \"budget.mcpLargeServer\": \"MCP server '{{name}}' consumes ~{{tokens}} tokens\",\n \"budget.baselineHigh\": \"Baseline context consumption is {{pct}}% of window\",\n\n \"deadRule.configOverlap\": \"Rule \\\"{{rule}}\\\" is already enforced by {{config}}\",\n \"deadRule.exactDuplicate\": \"Exact duplicate of line {{otherLine}} in {{otherFile}}\",\n \"deadRule.nearDuplicate\": \"Very similar to line {{otherLine}} in {{otherFile}} ({{similarity}}% similar)\",\n\n \"structure.contradiction\": \"Contradicting rules: \\\"{{snippet}}\\\" ({{fileA}} line {{lineA}}) conflicts with line {{lineB}}.\",\n \"structure.staleRef\": \"Stale reference: \\\"{{path}}\\\" does not exist.\",\n \"structure.scopeHook\": \"Rule at line {{line}} could be a git hook: \\\"{{snippet}}\\\"\",\n \"structure.scopePathScoped\": \"Rule at line {{line}} references a specific path — consider a path-scoped rule file: \\\"{{snippet}}\\\"\",\n\n \"label.budget\": \"BUDGET\",\n \"label.findings\": \"FINDINGS\",\n \"label.topIssues\": \"TOP ISSUES\",\n \"label.category\": \"Category\",\n\n \"compact.budgetLine\": \"{{used}} / {{window}} tokens ({{pct}}%)\",\n \"compact.andMore\": \"… and {{count}} more (run instrlint <command> for details)\",\n \"compact.budget\": \"Budget\",\n \"compact.deadRules\": \"Dead rules\",\n \"compact.duplicates\": \"Duplicates\",\n \"compact.contradictions\": \"Contradictions\",\n \"compact.staleRefs\": \"Stale refs\",\n \"compact.structure\": \"Structure\",\n\n \"markdown.title\": \"instrlint Health Report — {{project}}\",\n \"markdown.scoreLine\": \"**Score: {{score}}/100 ({{grade}})** · Tool: `{{tool}}`\",\n \"markdown.summary\": \"## Summary\",\n \"markdown.severity\": \"Severity\",\n \"markdown.count\": \"Count\",\n \"markdown.critical\": \"🔴 Critical\",\n \"markdown.warning\": \"🟡 Warning\",\n \"markdown.info\": \"ℹ️ Info\",\n \"markdown.contradictions\": \"Contradictions\",\n \"markdown.staleReferences\": \"Stale References\",\n \"markdown.deadRules\": \"Dead Rules\",\n \"markdown.duplicateRules\": \"Duplicates\",\n \"markdown.budgetIssues\": \"Budget Issues\",\n \"markdown.refactoringOpportunities\": \"Refactoring Opportunities\",\n \"markdown.lineRef\": \"(line {{line}})\",\n \"markdown.budgetCategory\": \"Category\",\n \"markdown.budgetTokens\": \"Tokens\",\n \"markdown.actionPlan\": \"## Action Plan\",\n \"markdown.attribution\": \"*Generated by [instrlint](https://github.com/jed1978/instrlint)*\",\n\n \"ci.passed\": \"✓ instrlint passed score={{score}} grade={{grade}}\",\n \"ci.failed\": \"✖ instrlint failed score={{score}} grade={{grade}}\",\n \"ci.writtenTo\": \"→ written to {{file}}\",\n\n \"initCi.created\": \"✓ Created {{path}}\",\n \"initCi.alreadyExists\": \"{{path}} already exists. Use --force to overwrite.\",\n\n \"install.installed\": \"✓ Installed to {{path}}\\n → Restart Claude Code to activate /instrlint\",\n \"install.alreadyExists\": \"{{path}} already exists. Use --force to overwrite.\",\n \"install.unknownTarget\": \"Specify --claude-code or --codex\",\n \"install.outdatedTitle\": \"instrlint skill is outdated\",\n \"install.outdatedVersions\": \"installed: {{installed}} → current: {{current}}\",\n \"install.updateCmd\": \"npx instrlint install {{flag}} --force\",\n \"install.updatePrompt\": \"Update skill now?\",\n\n \"verification.confirmed\": \"LLM confirmed\",\n \"verification.uncertain\": \"LLM uncertain\",\n \"verification.filteredCount\": \"⊘ {{count}} false positive{{s}} filtered by LLM\",\n\n \"fix.manualActions\": \"MANUAL ACTIONS NEEDED\",\n \"fix.hookCreate\": \"Add to .claude/settings.json:\",\n \"fix.hookWarning\": \"⚠ Hook executes shell commands — review carefully before adding\",\n \"fix.pathScopedCreate\": \"Create {{path}}:\",\n \"fix.thenRemoveLine\": \"Then remove line {{line}} from {{file}}\"\n}\n","{\n \"label.tokenBudget\": \"TOKEN 預算\",\n \"label.deadRules\": \"冗餘規則\",\n \"label.structure\": \"結構分析\",\n \"label.actionPlan\": \"行動計畫\",\n \"label.fixSummary\": \"修復摘要\",\n \"label.systemPrompt\": \"系統提示\",\n \"label.rootFile\": \"根指令檔\",\n \"label.ruleFiles\": \"規則檔\",\n \"label.skillFiles\": \"技能檔\",\n \"label.subDirFiles\": \"子目錄檔\",\n \"label.mcpServers\": \"MCP 伺服器\",\n \"label.baselineTotal\": \"初始總量\",\n \"label.available\": \"可用\",\n \"label.redundantByConfig\": \"冗餘(已由配置強制執行)\",\n \"label.duplicates\": \"重複項目\",\n \"label.contradictions\": \"規則矛盾\",\n \"label.staleReferences\": \"過時參照\",\n \"label.refactoringOpportunities\": \"重構建議\",\n \"label.tool\": \"工具:\",\n \"label.score\": \"分數:\",\n\n \"status.noBudgetIssues\": \"✓ 無 Token 預算問題\",\n \"status.noDeadRules\": \"✓ 無冗餘規則\",\n \"status.noStructuralIssues\": \"✓ 無結構性問題\",\n \"status.noAutoFixable\": \"✓ 無可自動修復的問題\",\n \"status.perfectScore\": \"✓ 滿分 — 無任何問題\",\n \"status.fixedIssues\": \"✓ 已修復 {{count}} 個問題 — 執行 `git diff` 查看變更\",\n\n \"error.unknownTool\": \"找不到代理指令檔。請在使用 Claude Code、Codex 或 Cursor 的專案中執行此指令。\",\n \"error.missingRootFile\": \"找到 {{tool}} 配置,但找不到根指令檔。\",\n \"error.dirtyWorkingTree\": \"工作目錄有未提交的變更。請先提交或儲藏變更再執行 --fix,或使用 --force 跳過此檢查。\",\n\n \"fix.removedDeadRules\": \"已移除 {{count}} 個冗餘規則\",\n \"fix.removedStaleRefs\": \"已移除 {{count}} 個過時參照\",\n \"fix.removedDuplicates\": \"已移除 {{count}} 個重複項目\",\n\n \"summary.redundantRules\": \"{{count}} 個冗餘規則\",\n \"summary.duplicates\": \"{{count}} 個重複項目\",\n \"summary.contradictions\": \"{{count}} 個規則矛盾\",\n \"summary.staleRefs\": \"{{count}} 個過時參照\",\n \"summary.refactoringSuggestions\": \"{{count}} 個重構建議\",\n \"summary.found\": \"發現 {{parts}}\",\n\n \"tokens.measured\": \"{{count}} tokens\",\n \"tokens.estimated\": \"~{{count}} tokens(估計值)\",\n\n \"actionPlan.andMore\": \"… 還有 {{count}} 個\",\n\n \"severity.critical\": \"{{count}} 個嚴重問題\",\n \"severity.warnings\": \"{{count}} 個警告\",\n \"severity.suggestions\": \"{{count}} 個建議\",\n\n \"budget.rootFileCritical\": \"根指令檔有 {{lines}} 行 — 超過 200 行後代理遵循率顯著下降\",\n \"budget.rootFileWarning\": \"根指令檔有 {{lines}} 行(建議:< 200 行)\",\n \"budget.mcpLargeServer\": \"MCP 伺服器「{{name}}」消耗約 {{tokens}} tokens\",\n \"budget.baselineHigh\": \"基線情境消耗佔視窗 {{pct}}%\",\n\n \"deadRule.configOverlap\": \"規則「{{rule}}」已由 {{config}} 強制執行\",\n \"deadRule.exactDuplicate\": \"與 {{otherFile}} 第 {{otherLine}} 行完全重複\",\n \"deadRule.nearDuplicate\": \"與 {{otherFile}} 第 {{otherLine}} 行高度相似({{similarity}}% 相似度)\",\n\n \"structure.contradiction\": \"規則矛盾:「{{snippet}}」({{fileA}} 第 {{lineA}} 行)與第 {{lineB}} 行衝突。\",\n \"structure.staleRef\": \"過時參照:「{{path}}」不存在。\",\n \"structure.scopeHook\": \"第 {{line}} 行的規則適合做成 git hook:「{{snippet}}」\",\n \"structure.scopePathScoped\": \"第 {{line}} 行的規則參照了特定路徑 — 建議建立路徑範圍的規則檔:「{{snippet}}」\",\n\n \"label.budget\": \"預算\",\n \"label.findings\": \"問題總覽\",\n \"label.topIssues\": \"首要問題\",\n \"label.category\": \"Category\",\n\n \"compact.budgetLine\": \"{{used}} / {{window}} tokens ({{pct}}%)\",\n \"compact.andMore\": \"… 還有 {{count}} 個(執行 instrlint <command> 查看詳情)\",\n \"compact.budget\": \"Budget\",\n \"compact.deadRules\": \"Dead rules\",\n \"compact.duplicates\": \"Duplicates\",\n \"compact.contradictions\": \"Contradictions\",\n \"compact.staleRefs\": \"Stale refs\",\n \"compact.structure\": \"Structure\",\n\n \"markdown.title\": \"instrlint 健康報告 — {{project}}\",\n \"markdown.scoreLine\": \"**分數:{{score}}/100 ({{grade}})** · 工具:`{{tool}}`\",\n \"markdown.summary\": \"## 摘要\",\n \"markdown.severity\": \"嚴重程度\",\n \"markdown.count\": \"數量\",\n \"markdown.critical\": \"🔴 嚴重\",\n \"markdown.warning\": \"🟡 警告\",\n \"markdown.info\": \"ℹ️ 資訊\",\n \"markdown.contradictions\": \"規則矛盾\",\n \"markdown.staleReferences\": \"過時參照\",\n \"markdown.deadRules\": \"冗餘規則\",\n \"markdown.duplicateRules\": \"重複項目\",\n \"markdown.budgetIssues\": \"Token 預算問題\",\n \"markdown.refactoringOpportunities\": \"重構建議\",\n \"markdown.lineRef\": \"(第 {{line}} 行)\",\n \"markdown.budgetCategory\": \"類別\",\n \"markdown.budgetTokens\": \"Token 數\",\n \"markdown.actionPlan\": \"## 行動計畫\",\n \"markdown.attribution\": \"*由 [instrlint](https://github.com/jed1978/instrlint) 生成*\",\n\n \"ci.passed\": \"✓ instrlint 通過 分數={{score}} 等級={{grade}}\",\n \"ci.failed\": \"✖ instrlint 未通過 分數={{score}} 等級={{grade}}\",\n \"ci.writtenTo\": \"→ 已寫入 {{file}}\",\n\n \"initCi.created\": \"✓ 已建立 {{path}}\",\n \"initCi.alreadyExists\": \"{{path}} 已存在。使用 --force 覆蓋。\",\n\n \"install.installed\": \"✓ 已安裝至 {{path}}\\n → 重新啟動 Claude Code 後即可使用 /instrlint\",\n \"install.alreadyExists\": \"{{path}} 已存在。使用 --force 覆蓋。\",\n \"install.unknownTarget\": \"請指定 --claude-code 或 --codex\",\n \"install.outdatedTitle\": \"instrlint skill 版本過舊\",\n \"install.outdatedVersions\": \"已安裝:{{installed}} → 最新:{{current}}\",\n \"install.updateCmd\": \"npx instrlint install {{flag}} --force\",\n \"install.updatePrompt\": \"是否立即更新?\",\n\n \"verification.confirmed\": \"LLM 已確認\",\n \"verification.uncertain\": \"LLM 不確定\",\n \"verification.filteredCount\": \"⊘ 已過濾 {{count}} 個{{s}} false positive(由 LLM 判斷)\",\n\n \"fix.manualActions\": \"需要手動操作\",\n \"fix.hookCreate\": \"加入 .claude/settings.json:\",\n \"fix.hookWarning\": \"⚠ Hook 會執行 shell command,請仔細確認後再加入\",\n \"fix.pathScopedCreate\": \"建立 {{path}}:\",\n \"fix.thenRemoveLine\": \"搬移後請從 {{file}} 第 {{line}} 行刪除原規則\"\n}\n","import enMessages from \"./en.json\";\nimport zhTWMessages from \"./zh-TW.json\";\n\ntype Locale = \"en\" | \"zh-TW\";\n\nconst LOCALE_MAP: Record<Locale, Record<string, string>> = {\n en: enMessages as Record<string, string>,\n \"zh-TW\": zhTWMessages as Record<string, string>,\n};\n\nlet _locale: Locale = \"en\";\nlet _messages: Record<string, string> = LOCALE_MAP[\"en\"];\n\n/** Detect locale from environment / system, falling back to 'en'. */\nexport function detectLocale(): Locale {\n const env = process.env[\"INSTRLINT_LANG\"];\n if (env === \"zh-TW\" || env === \"en\") return env;\n try {\n const sys = Intl.DateTimeFormat().resolvedOptions().locale;\n // Any zh-* locale (zh-CN, zh-HK, etc.) maps to zh-TW — it's the only CJK locale we support\n if (sys.startsWith(\"zh\")) return \"zh-TW\";\n } catch {\n // ignore\n }\n return \"en\";\n}\n\n/**\n * Set the active locale. Call once at CLI startup with the --lang value.\n * Falls back to detectLocale() if lang is unrecognised or omitted.\n */\nexport function initLocale(lang?: string): void {\n const valid: Locale[] = [\"en\", \"zh-TW\"];\n const resolved: Locale = valid.includes(lang as Locale)\n ? (lang as Locale)\n : detectLocale();\n _locale = resolved;\n _messages = LOCALE_MAP[resolved];\n}\n\n/** Return current active locale. */\nexport function getLocale(): Locale {\n return _locale;\n}\n\n/**\n * Look up a translation key and interpolate {{param}} placeholders.\n * Returns the key itself when no translation is found.\n */\nexport function t(key: string, params?: Record<string, string>): string {\n const template = _messages[key] ?? key;\n if (!params) return template;\n return template.replace(\n /\\{\\{(\\w+)\\}\\}/g,\n (_, k: string) => params[k] ?? `{{${k}}}`,\n );\n}\n\n/** Plural suffix helper: returns 's' for count !== 1, '' otherwise. */\nexport function plural(count: number): string {\n return count === 1 ? \"\" : \"s\";\n}\n","import { readFileSync, writeFileSync } from 'fs';\nimport type { Finding, FindingCategory } from '../types.js';\n\n/**\n * Removes lines from files based on findings of the specified categories.\n * Only removes lines where `autoFixable === true` and `line` is set.\n * Processes removals from bottom to top within each file to avoid line-offset shifts.\n *\n * @returns total number of lines removed across all files\n */\nexport function removeLines(findings: Finding[], categories: FindingCategory[]): number {\n const catSet = new Set<FindingCategory>(categories);\n const fixable = findings.filter(\n (f) => catSet.has(f.category) && f.autoFixable && f.line != null,\n );\n\n // Group by file path\n const byFile = new Map<string, number[]>();\n for (const f of fixable) {\n const arr = byFile.get(f.file) ?? [];\n arr.push(f.line!);\n byFile.set(f.file, arr);\n }\n\n let totalFixed = 0;\n\n for (const [filePath, lineNumbers] of byFile) {\n // Deduplicate and sort descending so we remove from the bottom up\n const uniqueSorted = [...new Set(lineNumbers)].sort((a, b) => b - a);\n\n const content = readFileSync(filePath, 'utf8');\n // Preserve trailing newline behaviour: if file ends with \\n, the last element after split is ''\n const lines = content.split('\\n');\n\n for (const lineNum of uniqueSorted) {\n const idx = lineNum - 1; // convert 1-based to 0-indexed\n if (idx >= 0 && idx < lines.length) {\n lines.splice(idx, 1);\n }\n }\n\n writeFileSync(filePath, lines.join('\\n'));\n totalFixed += uniqueSorted.length;\n }\n\n return totalFixed;\n}\n","import { removeLines } from './line-remover.js';\nimport type { Finding } from '../types.js';\n\n/**\n * Removes rules that are provably redundant — already enforced by project config.\n * Only removes lines flagged as `category: 'dead-rule'` and `autoFixable: true`.\n *\n * @returns number of lines removed\n */\nexport function removeDeadRules(findings: Finding[]): number {\n return removeLines(findings, ['dead-rule']);\n}\n","import { removeLines } from './line-remover.js';\nimport type { Finding } from '../types.js';\n\n/**\n * Removes lines that contain references to non-existent files.\n * Only removes lines flagged as `category: 'stale-ref'` and `autoFixable: true`.\n *\n * @returns number of lines removed\n */\nexport function removeStaleRefs(findings: Finding[]): number {\n return removeLines(findings, ['stale-ref']);\n}\n","import { removeLines } from './line-remover.js';\nimport type { Finding } from '../types.js';\n\n/**\n * Removes exact duplicate rule lines (keeps the first occurrence, removes later ones).\n * Only removes lines flagged as `category: 'duplicate'` and `autoFixable: true`.\n * Near-duplicates (autoFixable: false) are left untouched.\n *\n * @returns number of lines removed\n */\nexport function deduplicateRules(findings: Finding[]): number {\n return removeLines(findings, ['duplicate']);\n}\n","import { readFileSync } from \"fs\";\nimport { relative } from \"path\";\nimport chalk from \"chalk\";\nimport { t } from \"../i18n/index.js\";\nimport type { Finding } from \"../types.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface StructureSuggestion {\n finding: Finding;\n /** Full rule text from the source file (falls back to snippet) */\n ruleText: string;\n type: \"hook\" | \"path-scoped\";\n /** For path-scoped: the extracted directory name (e.g. 'src') */\n pathDir?: string;\n}\n\n// ─── File helpers ─────────────────────────────────────────────────────────────\n\nfunction readFileLine(filePath: string, lineNumber: number): string {\n try {\n const content = readFileSync(filePath, \"utf8\");\n return content.split(\"\\n\")[lineNumber - 1]?.trim() ?? \"\";\n } catch {\n return \"\";\n }\n}\n\n// ─── Path extraction ──────────────────────────────────────────────────────────\n\nconst PATH_DIR_RE = /\\b(src|tests?|lib|dist)\\//i;\n\nfunction extractPathDir(text: string): string | undefined {\n const m = PATH_DIR_RE.exec(text);\n return m?.[1]?.toLowerCase();\n}\n\n// ─── Code generators ──────────────────────────────────────────────────────────\n\nexport function buildHookSnippet(ruleText: string): string {\n const comment =\n ruleText.length > 80 ? `${ruleText.slice(0, 80)}…` : ruleText;\n return JSON.stringify(\n {\n hooks: {\n PreToolUse: [\n {\n matcher: \"Bash\",\n hooks: [\n {\n type: \"command\",\n command: `# TODO: implement enforcement of:\\n# ${comment}`,\n },\n ],\n },\n ],\n },\n },\n null,\n 2,\n );\n}\n\nexport function buildPathScopedFile(\n pathDir: string,\n ruleText: string,\n): { filePath: string; content: string } {\n const filePath = `.claude/rules/${pathDir}.md`;\n const content = `---\\nglobs:\\n - \"${pathDir}/**\"\\n---\\n\\n${ruleText}\\n`;\n return { filePath, content };\n}\n\n// ─── Builder ──────────────────────────────────────────────────────────────────\n\nexport function buildStructureSuggestions(\n findings: Finding[],\n): StructureSuggestion[] {\n const suggestions: StructureSuggestion[] = [];\n\n for (const finding of findings) {\n if (finding.category !== \"structure\") continue;\n if (\n finding.messageKey !== \"structure.scopeHook\" &&\n finding.messageKey !== \"structure.scopePathScoped\"\n ) {\n continue;\n }\n\n const ruleText =\n finding.line != null && finding.line > 0\n ? (readFileLine(finding.file, finding.line) ||\n (finding.messageParams?.snippet ?? \"\"))\n : (finding.messageParams?.snippet ?? \"\");\n\n if (finding.messageKey === \"structure.scopeHook\") {\n suggestions.push({ finding, ruleText, type: \"hook\" });\n } else {\n const pathDir =\n extractPathDir(ruleText) ||\n extractPathDir(finding.messageParams?.snippet ?? \"\") ||\n \"src\";\n suggestions.push({ finding, ruleText, type: \"path-scoped\", pathDir });\n }\n }\n\n return suggestions;\n}\n\n// ─── Terminal renderer ────────────────────────────────────────────────────────\n\nfunction terminalCodeBlock(code: string, output: { log: typeof console.log }): void {\n const lines = code.split(\"\\n\");\n output.log(chalk.gray(\" ┌\" + \"─\".repeat(62)));\n for (const line of lines) {\n output.log(` ${chalk.gray(\"│\")} ${chalk.white(line)}`);\n }\n output.log(chalk.gray(\" └\" + \"─\".repeat(62)));\n}\n\nexport function printStructureSuggestions(\n suggestions: StructureSuggestion[],\n projectRoot: string,\n output: { log: typeof console.log },\n): void {\n if (suggestions.length === 0) return;\n\n output.log(\"\");\n output.log(chalk.bold.white(` ${t(\"fix.manualActions\")}`));\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n for (const s of suggestions) {\n const relFile = relative(projectRoot, s.finding.file);\n const lineNum = s.finding.line ?? 0;\n\n output.log(\"\");\n output.log(\n ` ${chalk.blue(\"ℹ\")} ${chalk.white(t(s.finding.messageKey, s.finding.messageParams))}`,\n );\n output.log(\"\");\n\n if (s.type === \"hook\") {\n output.log(` ${chalk.cyan(t(\"fix.hookCreate\"))}`);\n terminalCodeBlock(buildHookSnippet(s.ruleText), output);\n output.log(` ${chalk.yellow(t(\"fix.hookWarning\"))}`);\n if (lineNum > 0) {\n output.log(\n ` ${chalk.gray(t(\"fix.thenRemoveLine\", { line: String(lineNum), file: relFile }))}`,\n );\n }\n } else {\n const dir = s.pathDir ?? \"src\";\n const { filePath, content } = buildPathScopedFile(dir, s.ruleText);\n output.log(` ${chalk.cyan(t(\"fix.pathScopedCreate\", { path: filePath }))}`);\n terminalCodeBlock(content, output);\n if (lineNum > 0) {\n output.log(\n ` ${chalk.gray(t(\"fix.thenRemoveLine\", { line: String(lineNum), file: relFile }))}`,\n );\n }\n }\n }\n\n output.log(\"\");\n}\n\n// ─── Markdown renderer ────────────────────────────────────────────────────────\n\nexport function markdownStructureSuggestions(\n suggestions: StructureSuggestion[],\n projectRoot: string,\n): string[] {\n if (suggestions.length === 0) return [];\n\n const lines: string[] = [`## ${t(\"fix.manualActions\")}`, \"\"];\n\n for (const s of suggestions) {\n const relFile = relative(projectRoot, s.finding.file);\n const lineNum = s.finding.line ?? 0;\n const icon =\n s.finding.severity === \"critical\"\n ? \"🔴\"\n : s.finding.severity === \"warning\"\n ? \"🟡\"\n : \"ℹ️\";\n\n lines.push(\n `### ${icon} ${t(s.finding.messageKey, s.finding.messageParams)}`,\n \"\",\n );\n\n if (s.type === \"hook\") {\n lines.push(t(\"fix.hookCreate\"), \"\", \"```json\", buildHookSnippet(s.ruleText), \"```\", \"\");\n lines.push(`> ${t(\"fix.hookWarning\")}`, \"\");\n if (lineNum > 0) {\n lines.push(\n `_${t(\"fix.thenRemoveLine\", { line: String(lineNum), file: relFile })}_`,\n \"\",\n );\n }\n } else {\n const dir = s.pathDir ?? \"src\";\n const { filePath, content } = buildPathScopedFile(dir, s.ruleText);\n lines.push(t(\"fix.pathScopedCreate\", { path: filePath }), \"\");\n lines.push(\"```markdown\", content, \"```\", \"\");\n if (lineNum > 0) {\n lines.push(\n `_${t(\"fix.thenRemoveLine\", { line: String(lineNum), file: relFile })}_`,\n \"\",\n );\n }\n }\n }\n\n return lines;\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport { fileURLToPath } from \"url\";\n\nfunction readPackageVersion(): string {\n const thisFile = fileURLToPath(import.meta.url);\n // bundled: dist/cli.js → 2 levels up = package root\n // dev/test: src/utils/skill-version.ts → 3 levels up = package root\n for (const levels of [2, 3]) {\n const pkgPath = join(thisFile, ...Array(levels).fill(\"..\"), \"package.json\");\n if (existsSync(pkgPath)) {\n const raw: unknown = JSON.parse(readFileSync(pkgPath, \"utf8\"));\n if (\n typeof raw === \"object\" &&\n raw !== null &&\n \"version\" in raw &&\n typeof (raw as { version: unknown }).version === \"string\"\n ) {\n return (raw as { version: string }).version;\n }\n }\n }\n return \"0.0.0\";\n}\n\nexport const CURRENT_VERSION: string = readPackageVersion();\n\nconst VERSION_RE = /^instrlint-version:\\s*(.+)$/m;\n\nfunction extractVersion(content: string): string | null {\n const m = VERSION_RE.exec(content);\n return m ? m[1]!.trim() : null;\n}\n\nfunction readInstalledVersion(path: string): string | null {\n if (!existsSync(path)) return null;\n try {\n return extractVersion(readFileSync(path, \"utf8\"));\n } catch {\n return null;\n }\n}\n\nexport interface SkillUpdateInfo {\n installedVersion: string;\n currentVersion: string;\n installPath: string;\n isProject: boolean;\n}\n\nexport function checkSkillUpdate(projectRoot: string): SkillUpdateInfo | null {\n const candidates: Array<{ path: string; isProject: boolean }> = [\n {\n path: join(projectRoot, \".claude\", \"commands\", \"instrlint.md\"),\n isProject: true,\n },\n {\n path: join(homedir(), \".claude\", \"commands\", \"instrlint.md\"),\n isProject: false,\n },\n ];\n\n for (const { path, isProject } of candidates) {\n const installed = readInstalledVersion(path);\n if (installed !== null && installed !== CURRENT_VERSION) {\n return {\n installedVersion: installed,\n currentVersion: CURRENT_VERSION,\n installPath: path,\n isProject,\n };\n }\n }\n return null;\n}\n\nexport function injectVersion(content: string, version: string): string {\n // Replace existing instrlint-version line (idempotent)\n if (/^instrlint-version:/m.test(content)) {\n return content.replace(\n /^instrlint-version:.*$/m,\n `instrlint-version: ${version}`,\n );\n }\n // Insert before closing --- of frontmatter\n const updated = content.replace(\n /^(---\\n[\\s\\S]*?)(---)$/m,\n `$1instrlint-version: ${version}\\n$2`,\n );\n if (updated === content) {\n throw new Error(\"injectVersion: no YAML frontmatter found in skill file\");\n }\n return updated;\n}\n","import { createHash } from \"crypto\";\nimport { relative } from \"path\";\nimport type { Finding, ParsedInstructions, InstructionFile } from \"../types.js\";\nimport type {\n Candidate,\n CandidatesFile,\n CandidateContext,\n RuleRef,\n} from \"./schema.js\";\nimport { shouldVerify } from \"./policy.js\";\n\n// ─── Line lookup ──────────────────────────────────────────────────────────────\n\nfunction findLineText(\n parsed: ParsedInstructions,\n filePath: string,\n lineNumber: number,\n): string {\n const sources: InstructionFile[] = [\n parsed.rootFile,\n ...parsed.subFiles,\n ...parsed.rules,\n ];\n const file = sources.find((f) => f.path === filePath);\n if (!file) return \"\";\n const line = file.lines.find((l) => l.lineNumber === lineNumber);\n return line?.text.trim() ?? \"\";\n}\n\nfunction ruleRef(\n parsed: ParsedInstructions,\n filePath: string,\n lineNumber: number,\n projectRoot: string,\n): RuleRef {\n return {\n file: toRelative(filePath, projectRoot),\n line: lineNumber,\n text: findLineText(parsed, filePath, lineNumber),\n };\n}\n\n// ─── Context builders ─────────────────────────────────────────────────────────\n\nfunction buildContext(\n finding: Finding,\n parsed: ParsedInstructions,\n projectRoot: string,\n): CandidateContext | null {\n if (finding.category === \"contradiction\") {\n const { fileA, lineA } = finding.messageParams ?? {};\n if (!fileA || !lineA) return null;\n return {\n type: \"contradiction\",\n ruleA: ruleRef(parsed, fileA, Number(lineA), projectRoot),\n ruleB: ruleRef(parsed, finding.file, finding.line ?? 0, projectRoot),\n };\n }\n\n if (finding.category === \"duplicate\") {\n const { otherFile, otherLine } = finding.messageParams ?? {};\n if (!otherFile || !otherLine) return null;\n return {\n type: \"duplicate\",\n ruleA: ruleRef(parsed, otherFile, Number(otherLine), projectRoot),\n ruleB: ruleRef(parsed, finding.file, finding.line ?? 0, projectRoot),\n };\n }\n\n return null;\n}\n\n// ─── Stable ID ────────────────────────────────────────────────────────────────\n\n/**\n * Hash over category + file + line so the same finding always gets the same ID\n * across instrlint runs, enabling verdict caching by the host agent.\n */\nexport function hashFinding(finding: Finding): string {\n const key = `${finding.category}:${finding.file}:${finding.line ?? 0}:${finding.messageKey}`;\n return createHash(\"sha256\").update(key).digest(\"hex\").slice(0, 12);\n}\n\n// ─── Question text ────────────────────────────────────────────────────────────\n\nconst QUESTIONS: Record<string, Record<string, string>> = {\n contradiction: {\n en: 'Do rules A and B actually contradict each other in practice? A real contradiction means a developer following both rules would be forced to violate one of them. Respond with JSON only: {\"verdict\":\"confirmed\"|\"rejected\"|\"uncertain\",\"reason\":\"<≤20 words>\"}',\n \"zh-TW\":\n '規則 A 和規則 B 在實際開發中真的相互矛盾嗎?真正的矛盾是指:同時遵守兩條規則在某些情境下是不可能的。僅用 JSON 回答:{\"verdict\":\"confirmed\"|\"rejected\"|\"uncertain\",\"reason\":\"<20 字以內>\"}',\n },\n duplicate: {\n en: 'Are rules A and B true semantic duplicates — do they say the same thing in different words, such that keeping both adds no value? Respond with JSON only: {\"verdict\":\"confirmed\"|\"rejected\"|\"uncertain\",\"reason\":\"<≤20 words>\"}',\n \"zh-TW\":\n '規則 A 和規則 B 在語意上真的是重複的嗎——用不同的措辭說同一件事,保留兩條毫無額外價值?僅用 JSON 回答:{\"verdict\":\"confirmed\"|\"rejected\"|\"uncertain\",\"reason\":\"<20 字以內>\"}',\n },\n};\n\nfunction questionFor(category: string, locale: string): string {\n const lang = locale === \"zh-TW\" ? \"zh-TW\" : \"en\";\n const question = QUESTIONS[category]?.[lang] ?? QUESTIONS[category]?.[\"en\"];\n if (!question) {\n process.stderr.write(\n `[instrlint] Warning: no verification question for category \"${category}\", skipping\\n`,\n );\n return \"\";\n }\n return question;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/** Normalize an absolute path to project-relative for safe serialization. */\nfunction toRelative(filePath: string, projectRoot: string): string {\n const rel = relative(projectRoot, filePath);\n // If the path escaped the project root, keep as-is (safety: don't strip info)\n return rel.startsWith(\"..\") ? filePath : rel;\n}\n\n/** Return a copy of the finding with all file paths made project-relative. */\nfunction normalizeFilePaths(finding: Finding, projectRoot: string): Finding {\n const normalized: Finding = {\n ...finding,\n file: toRelative(finding.file, projectRoot),\n };\n if (normalized.messageParams) {\n const params = { ...normalized.messageParams };\n if (params[\"fileA\"])\n params[\"fileA\"] = toRelative(params[\"fileA\"], projectRoot);\n if (params[\"otherFile\"])\n params[\"otherFile\"] = toRelative(params[\"otherFile\"], projectRoot);\n normalized.messageParams = params;\n }\n return normalized;\n}\n\nexport function buildCandidates(\n findings: Finding[],\n parsed: ParsedInstructions,\n projectRoot: string,\n locale: string,\n): CandidatesFile {\n const candidates: Candidate[] = [];\n\n for (const finding of findings) {\n if (!shouldVerify(finding)) continue;\n const context = buildContext(finding, parsed, projectRoot);\n if (!context) continue;\n\n candidates.push({\n id: hashFinding(finding),\n category: finding.category,\n question: questionFor(finding.category, locale),\n context,\n originalFinding: normalizeFilePaths(finding, projectRoot),\n });\n }\n\n return {\n version: 1,\n generatedAt: new Date().toISOString(),\n projectRoot,\n candidates,\n };\n}\n","import type { Finding } from \"../types.js\";\n\n/**\n * Returns true for findings that benefit from LLM verification — those with\n * high false-positive rates from the deterministic detectors.\n *\n * High-confidence findings are excluded because they use deterministic checks\n * (filesystem existence, exact config field matching) where LLM review adds\n * no value and would waste the user's session tokens.\n */\nexport function shouldVerify(finding: Finding): boolean {\n // Exact filesystem check — deterministic, skip verification\n if (finding.category === \"stale-ref\") return false;\n\n // Math-based budget checks — deterministic, skip\n if (finding.category === \"budget\") return false;\n\n // Structure suggestions are informational, not findings to confirm\n if (finding.category === \"structure\") return false;\n\n // Config-overlap dead rules use hard-coded patterns — conservative by design,\n // but auto-fixable ones are safe; non-auto-fixable may have false positives\n if (finding.category === \"dead-rule\") return !finding.autoFixable;\n\n // Contradictions have high false-positive rate — always verify\n if (finding.category === \"contradiction\") return true;\n\n // Near-duplicates (warning) are ambiguous; exact dupes (info + autoFixable)\n // are deterministic and don't need LLM review\n if (finding.category === \"duplicate\") {\n return finding.severity === \"warning\" && !finding.autoFixable;\n }\n\n return false;\n}\n","import { readFileSync } from \"fs\";\nimport type { Finding } from \"../types.js\";\nimport type { VerdictsFile } from \"./schema.js\";\nimport { hashFinding } from \"./candidates.js\";\n\n/**\n * Reads verdicts.json written by the host agent and merges verdicts back into\n * the findings array.\n *\n * - `rejected` findings are removed entirely (they were false positives).\n * - `confirmed` and `uncertain` findings get a `verification` field attached.\n * - Findings with no matching verdict are returned unchanged.\n * - Unknown IDs in verdicts are silently ignored (forward-compatible).\n */\nexport interface ApplyVerdictsResult {\n findings: Finding[];\n rejectedCount: number;\n}\n\nexport function applyVerdicts(\n findings: Finding[],\n verdictsFile: VerdictsFile,\n): ApplyVerdictsResult {\n const verdictMap = new Map(verdictsFile.verdicts.map((v) => [v.id, v]));\n\n const withVerdicts = findings.map((f): Finding => {\n const verdict = verdictMap.get(hashFinding(f));\n if (!verdict) return f;\n return {\n ...f,\n verification: { verdict: verdict.verdict, reason: verdict.reason },\n };\n });\n\n const kept = withVerdicts.filter(\n (f) => f.verification?.verdict !== \"rejected\",\n );\n const rejectedCount = withVerdicts.length - kept.length;\n\n return { findings: kept, rejectedCount };\n}\n\n/**\n * Loads and parses a verdicts.json file from disk.\n * Throws with a descriptive message if the file is missing or malformed.\n */\nexport function loadVerdictsFile(filePath: string): VerdictsFile {\n let raw: string;\n try {\n raw = readFileSync(filePath, \"utf8\");\n } catch {\n throw new Error(\n `Cannot read verdicts file: ${filePath}\\nRun instrlint --emit-candidates first, then ask the host LLM to write verdicts.`,\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw) as unknown;\n } catch {\n throw new Error(`verdicts.json is not valid JSON: ${filePath}`);\n }\n\n const obj = parsed as Record<string, unknown>;\n\n if (\n typeof parsed !== \"object\" ||\n parsed === null ||\n obj[\"version\"] !== 1 ||\n !Array.isArray(obj[\"verdicts\"])\n ) {\n throw new Error(\n `verdicts.json has unexpected format (expected {version:1, verdicts:[...]}): ${filePath}`,\n );\n }\n\n const VALID_VERDICTS = new Set([\"confirmed\", \"rejected\", \"uncertain\"]);\n const MAX_REASON_LENGTH = 500;\n\n for (const v of obj[\"verdicts\"] as unknown[]) {\n if (typeof v !== \"object\" || v === null) {\n throw new Error(`verdicts.json: each verdict must be an object`);\n }\n const item = v as Record<string, unknown>;\n if (typeof item[\"id\"] !== \"string\" || item[\"id\"].length === 0) {\n throw new Error(`verdicts.json: verdict missing string \"id\"`);\n }\n if (!VALID_VERDICTS.has(item[\"verdict\"] as string)) {\n throw new Error(\n `verdicts.json: invalid verdict \"${item[\"verdict\"]}\" for id \"${item[\"id\"]}\" (must be confirmed|rejected|uncertain)`,\n );\n }\n if (typeof item[\"reason\"] !== \"string\") {\n throw new Error(\n `verdicts.json: verdict \"${item[\"id\"]}\" missing string \"reason\"`,\n );\n }\n if ((item[\"reason\"] as string).length > MAX_REASON_LENGTH) {\n throw new Error(\n `verdicts.json: verdict \"${item[\"id\"]}\" reason exceeds ${MAX_REASON_LENGTH} characters`,\n );\n }\n }\n\n return parsed as VerdictsFile;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport { fileURLToPath } from \"url\";\nimport { t } from \"../i18n/index.js\";\nimport { injectVersion, CURRENT_VERSION } from \"../utils/skill-version.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface InstallCommandOpts {\n claudeCode?: boolean;\n codex?: boolean;\n project?: boolean;\n force?: boolean;\n projectRoot?: string;\n}\n\nexport interface InstallCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\n// ─── File resolution ──────────────────────────────────────────────────────────\n\nfunction resolveSkillFile(target: \"claude-code\" | \"codex\"): string {\n const thisFile = fileURLToPath(import.meta.url);\n const subDir = target === \"claude-code\" ? \"claude-code\" : \"codex\";\n\n // tsup bundles into dist/cli.js (2 levels up = package root).\n // In dev/test, file is at src/commands/install-command.ts (3 levels up = package root).\n // Try both, use whichever has the skills directory.\n for (const levels of [2, 3]) {\n const parts = Array(levels).fill(\"..\");\n const candidate = join(thisFile, ...parts, \"skills\", subDir, \"SKILL.md\");\n if (existsSync(candidate)) return candidate;\n }\n\n // Fallback: return the 2-level path so the error message shows a useful path\n return join(thisFile, \"..\", \"..\", \"skills\", subDir, \"SKILL.md\");\n}\n\nfunction readSkillContent(target: \"claude-code\" | \"codex\"): string {\n const skillPath = resolveSkillFile(target);\n try {\n const raw = readFileSync(skillPath, \"utf8\");\n return injectVersion(raw, CURRENT_VERSION);\n } catch {\n throw new Error(\n `Could not read skill file at ${skillPath}. Make sure the package is properly installed.`,\n );\n }\n}\n\n// ─── Install targets ──────────────────────────────────────────────────────────\n\nfunction installClaudeCode(\n content: string,\n projectRoot: string,\n isProject: boolean,\n force: boolean,\n output: { log: typeof console.log; error: typeof console.error },\n): InstallCommandResult {\n const targetDir = isProject\n ? join(projectRoot, \".claude\", \"commands\")\n : join(homedir(), \".claude\", \"commands\");\n\n const targetPath = join(targetDir, \"instrlint.md\");\n\n if (existsSync(targetPath) && !force) {\n output.error(t(\"install.alreadyExists\", { path: targetPath }));\n return { exitCode: 1, errorMessage: \"file already exists\" };\n }\n\n mkdirSync(targetDir, { recursive: true });\n writeFileSync(targetPath, content, \"utf8\");\n output.log(t(\"install.installed\", { path: targetPath }));\n return { exitCode: 0 };\n}\n\nfunction installCodex(\n content: string,\n projectRoot: string,\n force: boolean,\n output: { log: typeof console.log; error: typeof console.error },\n): InstallCommandResult {\n const targetDir = join(projectRoot, \".agents\", \"skills\", \"instrlint\");\n const targetPath = join(targetDir, \"SKILL.md\");\n\n if (existsSync(targetPath) && !force) {\n output.error(t(\"install.alreadyExists\", { path: targetPath }));\n return { exitCode: 1, errorMessage: \"file already exists\" };\n }\n\n mkdirSync(targetDir, { recursive: true });\n writeFileSync(targetPath, content, \"utf8\");\n output.log(t(\"install.installed\", { path: targetPath }));\n return { exitCode: 0 };\n}\n\n// ─── Core logic ───────────────────────────────────────────────────────────────\n\nexport function runInstall(\n opts: InstallCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): InstallCommandResult {\n const projectRoot = opts.projectRoot ?? process.cwd();\n const force = opts.force ?? false;\n\n if (opts.claudeCode) {\n let content: string;\n try {\n content = readSkillContent(\"claude-code\");\n } catch (err) {\n output.error(String(err));\n return { exitCode: 1, errorMessage: String(err) };\n }\n return installClaudeCode(\n content,\n projectRoot,\n opts.project ?? false,\n force,\n output,\n );\n }\n\n if (opts.codex) {\n let content: string;\n try {\n content = readSkillContent(\"codex\");\n } catch (err) {\n output.error(String(err));\n return { exitCode: 1, errorMessage: String(err) };\n }\n return installCodex(content, projectRoot, force, output);\n }\n\n output.error(t(\"install.unknownTarget\"));\n return { exitCode: 1, errorMessage: \"no target specified\" };\n}\n","import chalk from \"chalk\";\nimport { analyzeDeadRules } from \"../analyzers/dead-rules.js\";\nimport { loadProject } from \"../adapters/dispatch.js\";\nimport { ensureInitialized } from \"../detectors/token-estimator.js\";\nimport { scanProject } from \"../core/scanner.js\";\nimport { t, plural, initLocale, getLocale } from \"../i18n/index.js\";\nimport type { Finding } from \"../types.js\";\n\n// ─── Terminal output ──────────────────────────────────────────────────────────\n\nexport function printDeadRulesTerminal(\n findings: Finding[],\n output: { log: typeof console.log } = console,\n): void {\n const overlaps = findings.filter((f) => f.category === \"dead-rule\");\n const duplicates = findings.filter((f) => f.category === \"duplicate\");\n\n output.log(\"\");\n output.log(chalk.bold.white(` ${t(\"label.deadRules\")}`));\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n if (overlaps.length > 0) {\n output.log(chalk.bold(` ${t(\"label.redundantByConfig\")}`));\n for (const f of overlaps) {\n output.log(` ${chalk.yellow(\"⚠\")} ${t(f.messageKey, f.messageParams)}`);\n }\n output.log(\"\");\n }\n\n if (duplicates.length > 0) {\n output.log(chalk.bold(` ${t(\"label.duplicates\")}`));\n for (const f of duplicates) {\n const icon =\n f.severity === \"warning\" ? chalk.yellow(\"⚠\") : chalk.blue(\"ℹ\");\n output.log(` ${icon} ${t(f.messageKey, f.messageParams)}`);\n }\n output.log(\"\");\n }\n\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n if (findings.length === 0) {\n output.log(chalk.green(` ${t(\"status.noDeadRules\")}`));\n } else {\n const sep = getLocale() === \"zh-TW\" ? \"、\" : \", \";\n const parts: string[] = [];\n if (overlaps.length > 0)\n parts.push(\n t(\"summary.redundantRules\", {\n count: String(overlaps.length),\n s: plural(overlaps.length),\n }),\n );\n if (duplicates.length > 0)\n parts.push(\n t(\"summary.duplicates\", {\n count: String(duplicates.length),\n s: plural(duplicates.length),\n }),\n );\n output.log(\n chalk.yellow(` ${t(\"summary.found\", { parts: parts.join(sep) })}`),\n );\n }\n output.log(\"\");\n}\n\n// ─── Core run logic ───────────────────────────────────────────────────────────\n\nexport interface DeadRulesCommandOpts {\n format: string;\n tool?: string;\n lang?: string;\n projectRoot?: string;\n}\n\nexport interface DeadRulesCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\nexport async function runDeadRules(\n opts: DeadRulesCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): Promise<DeadRulesCommandResult> {\n initLocale(opts.lang);\n await ensureInitialized();\n\n const projectRoot = opts.projectRoot ?? process.cwd();\n const scan = scanProject(projectRoot, opts.tool);\n\n if (scan.tool === \"unknown\") {\n output.error(t(\"error.unknownTool\"));\n return { exitCode: 1, errorMessage: \"unknown tool\" };\n }\n\n if (scan.rootFilePath === null) {\n output.error(t(\"error.missingRootFile\", { tool: scan.tool }));\n return { exitCode: 1, errorMessage: \"missing root file\" };\n }\n\n const instructions = loadProject(projectRoot, scan.tool);\n const { findings } = analyzeDeadRules(instructions, projectRoot);\n\n if (opts.format === \"json\") {\n output.log(JSON.stringify({ findings }, null, 2));\n return { exitCode: 0 };\n }\n\n printDeadRulesTerminal(findings, output);\n return { exitCode: 0 };\n}\n","import chalk from \"chalk\";\nimport { analyzeStructure } from \"../analyzers/structure.js\";\nimport { loadProject } from \"../adapters/dispatch.js\";\nimport { ensureInitialized } from \"../detectors/token-estimator.js\";\nimport { scanProject } from \"../core/scanner.js\";\nimport { t, plural, initLocale, getLocale } from \"../i18n/index.js\";\nimport type { Finding } from \"../types.js\";\n\n// ─── Terminal output ──────────────────────────────────────────────────────────\n\nfunction printStructureTerminal(\n findings: Finding[],\n output: { log: typeof console.log } = console,\n): void {\n const contradictions = findings.filter((f) => f.category === \"contradiction\");\n const staleRefs = findings.filter((f) => f.category === \"stale-ref\");\n const scoped = findings.filter((f) => f.category === \"structure\");\n\n output.log(\"\");\n output.log(chalk.bold.white(` ${t(\"label.structure\")}`));\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n if (contradictions.length > 0) {\n output.log(chalk.bold(` ${t(\"label.contradictions\")}`));\n for (const f of contradictions) {\n output.log(` ${chalk.red(\"✖\")} ${t(f.messageKey, f.messageParams)}`);\n }\n output.log(\"\");\n }\n\n if (staleRefs.length > 0) {\n output.log(chalk.bold(` ${t(\"label.staleReferences\")}`));\n for (const f of staleRefs) {\n output.log(` ${chalk.yellow(\"⚠\")} ${t(f.messageKey, f.messageParams)}`);\n }\n output.log(\"\");\n }\n\n if (scoped.length > 0) {\n output.log(chalk.bold(` ${t(\"label.refactoringOpportunities\")}`));\n for (const f of scoped) {\n output.log(` ${chalk.blue(\"ℹ\")} ${t(f.messageKey, f.messageParams)}`);\n }\n output.log(\"\");\n }\n\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n if (findings.length === 0) {\n output.log(chalk.green(` ${t(\"status.noStructuralIssues\")}`));\n } else {\n const sep = getLocale() === \"zh-TW\" ? \"、\" : \", \";\n const parts: string[] = [];\n if (contradictions.length > 0)\n parts.push(\n t(\"summary.contradictions\", {\n count: String(contradictions.length),\n s: plural(contradictions.length),\n }),\n );\n if (staleRefs.length > 0)\n parts.push(\n t(\"summary.staleRefs\", {\n count: String(staleRefs.length),\n s: plural(staleRefs.length),\n }),\n );\n if (scoped.length > 0)\n parts.push(\n t(\"summary.refactoringSuggestions\", {\n count: String(scoped.length),\n s: plural(scoped.length),\n }),\n );\n output.log(\n chalk.yellow(` ${t(\"summary.found\", { parts: parts.join(sep) })}`),\n );\n }\n output.log(\"\");\n}\n\n// ─── Core run logic ───────────────────────────────────────────────────────────\n\nexport interface StructureCommandOpts {\n format: string;\n tool?: string;\n lang?: string;\n projectRoot?: string;\n}\n\nexport interface StructureCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\nexport async function runStructure(\n opts: StructureCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): Promise<StructureCommandResult> {\n initLocale(opts.lang);\n await ensureInitialized();\n\n const projectRoot = opts.projectRoot ?? process.cwd();\n const scan = scanProject(projectRoot, opts.tool);\n\n if (scan.tool === \"unknown\") {\n output.error(t(\"error.unknownTool\"));\n return { exitCode: 1, errorMessage: \"unknown tool\" };\n }\n\n if (scan.rootFilePath === null) {\n output.error(t(\"error.missingRootFile\", { tool: scan.tool }));\n return { exitCode: 1, errorMessage: \"missing root file\" };\n }\n\n const instructions = loadProject(projectRoot, scan.tool);\n const { findings } = analyzeStructure(instructions, projectRoot);\n\n if (opts.format === \"json\") {\n output.log(JSON.stringify({ findings }, null, 2));\n return { exitCode: 0 };\n }\n\n printStructureTerminal(findings, output);\n return { exitCode: 0 };\n}\n","import { writeFileSync } from \"fs\";\nimport { basename } from \"path\";\nimport { scanProject } from \"../core/scanner.js\";\nimport { loadProject } from \"../adapters/dispatch.js\";\nimport { ensureInitialized } from \"../detectors/token-estimator.js\";\nimport { analyzeBudget } from \"../analyzers/budget.js\";\nimport { analyzeDeadRules } from \"../analyzers/dead-rules.js\";\nimport { analyzeStructure } from \"../analyzers/structure.js\";\nimport { calculateScore, buildActionPlan } from \"../core/scorer.js\";\nimport { reportJson, reportMarkdown } from \"../core/reporter.js\";\nimport { reportSarif } from \"../reporters/sarif.js\";\nimport { t, initLocale, getLocale } from \"../i18n/index.js\";\nimport type { Finding, HealthReport } from \"../types.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type FailOn = \"critical\" | \"warning\" | \"info\";\n\nexport interface CiCommandOpts {\n format?: string;\n tool?: string;\n lang?: string;\n failOn?: FailOn;\n output?: string;\n projectRoot?: string;\n}\n\nexport interface CiCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\n// ─── Threshold helpers ────────────────────────────────────────────────────────\n\nfunction shouldFail(findings: Finding[], failOn: FailOn): boolean {\n if (failOn === \"info\") return findings.length > 0;\n if (failOn === \"warning\")\n return findings.some(\n (f) => f.severity === \"critical\" || f.severity === \"warning\",\n );\n // default: critical\n return findings.some((f) => f.severity === \"critical\");\n}\n\n// ─── Core logic ───────────────────────────────────────────────────────────────\n\nexport async function runCi(\n opts: CiCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): Promise<CiCommandResult> {\n initLocale(opts.lang);\n await ensureInitialized();\n\n const projectRoot = opts.projectRoot ?? process.cwd();\n const failOn: FailOn = opts.failOn ?? \"critical\";\n const format = opts.format ?? \"terminal\";\n\n const scan = scanProject(projectRoot, opts.tool);\n\n if (scan.tool === \"unknown\") {\n output.error(t(\"error.unknownTool\"));\n return { exitCode: 1, errorMessage: \"unknown tool\" };\n }\n\n if (scan.rootFilePath === null) {\n output.error(t(\"error.missingRootFile\", { tool: scan.tool }));\n return { exitCode: 1, errorMessage: \"missing root file\" };\n }\n\n const instructions = loadProject(projectRoot, scan.tool);\n\n const { findings: budgetFindings, summary } = analyzeBudget(instructions);\n const { findings: deadRuleFindings } = analyzeDeadRules(\n instructions,\n projectRoot,\n );\n const { findings: structureFindings } = analyzeStructure(\n instructions,\n projectRoot,\n );\n\n const allFindings = [\n ...budgetFindings,\n ...deadRuleFindings,\n ...structureFindings,\n ];\n const { score, grade } = calculateScore(allFindings, summary);\n const actionPlan = buildActionPlan(allFindings);\n\n const report: HealthReport = {\n project: basename(projectRoot),\n tool: instructions.tool,\n score,\n grade,\n locale: getLocale(),\n tokenMethod: summary.tokenMethod,\n findings: allFindings,\n budget: summary,\n actionPlan,\n };\n\n // ── Format output ─────────────────────────────────────────────────────────\n let formatted: string;\n if (format === \"sarif\") {\n formatted = reportSarif(report);\n } else if (format === \"json\") {\n formatted = reportJson(report);\n } else if (format === \"markdown\") {\n formatted = reportMarkdown(report);\n } else {\n formatted = reportJson(report);\n }\n\n if (opts.output != null) {\n writeFileSync(opts.output, formatted, \"utf8\");\n const pass = !shouldFail(allFindings, failOn);\n const statusKey = pass ? \"ci.passed\" : \"ci.failed\";\n output.error(\n `${t(statusKey, { score: String(score), grade })} ${t(\"ci.writtenTo\", { file: opts.output })}`,\n );\n } else {\n output.log(formatted);\n }\n\n const failed = shouldFail(allFindings, failOn);\n return { exitCode: failed ? 1 : 0 };\n}\n","import type { Finding, HealthReport } from \"../types.js\";\n\n// ─── SARIF v2.1.0 types ────────────────────────────────────────────────────\n\ninterface SarifArtifactLocation {\n uri: string;\n uriBaseId?: string;\n}\n\ninterface SarifRegion {\n startLine: number;\n}\n\ninterface SarifPhysicalLocation {\n artifactLocation: SarifArtifactLocation;\n region?: SarifRegion;\n}\n\ninterface SarifLocation {\n physicalLocation: SarifPhysicalLocation;\n}\n\ninterface SarifMessage {\n text: string;\n}\n\ninterface SarifResult {\n ruleId: string;\n level: \"error\" | \"warning\" | \"note\";\n message: SarifMessage;\n locations: SarifLocation[];\n}\n\ninterface SarifRule {\n id: string;\n name: string;\n shortDescription: SarifMessage;\n}\n\ninterface SarifDriver {\n name: string;\n version: string;\n informationUri: string;\n rules: SarifRule[];\n}\n\ninterface SarifTool {\n driver: SarifDriver;\n}\n\ninterface SarifRun {\n tool: SarifTool;\n results: SarifResult[];\n}\n\ninterface SarifLog {\n $schema: string;\n version: \"2.1.0\";\n runs: SarifRun[];\n}\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction severityToLevel(\n severity: Finding[\"severity\"],\n): \"error\" | \"warning\" | \"note\" {\n if (severity === \"critical\") return \"error\";\n if (severity === \"warning\") return \"warning\";\n return \"note\";\n}\n\nfunction findingToRuleId(f: Finding): string {\n return `instrlint/${f.category}/${f.messageKey.replace(/\\./g, \"/\")}`;\n}\n\nfunction buildRules(findings: Finding[]): SarifRule[] {\n const seen = new Set<string>();\n const rules: SarifRule[] = [];\n for (const f of findings) {\n const id = findingToRuleId(f);\n if (seen.has(id)) continue;\n seen.add(id);\n rules.push({\n id,\n name: f.messageKey,\n shortDescription: { text: `${f.category}: ${f.messageKey}` },\n });\n }\n return rules;\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport function reportSarif(report: HealthReport): string {\n const rules = buildRules(report.findings);\n\n const results: SarifResult[] = report.findings.map((f) => ({\n ruleId: findingToRuleId(f),\n level: severityToLevel(f.severity),\n message: { text: f.suggestion },\n locations: [\n {\n physicalLocation: {\n artifactLocation: {\n uri: f.file.replace(/\\\\/g, \"/\"),\n uriBaseId: \"%SRCROOT%\",\n },\n ...(f.line != null ? { region: { startLine: f.line } } : {}),\n },\n },\n ],\n }));\n\n const log: SarifLog = {\n $schema:\n \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json\",\n version: \"2.1.0\",\n runs: [\n {\n tool: {\n driver: {\n name: \"instrlint\",\n version: \"0.1.0\",\n informationUri: \"https://github.com/jed1978/instrlint\",\n rules,\n },\n },\n results,\n },\n ],\n };\n\n return JSON.stringify(log, null, 2);\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { t } from \"../i18n/index.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface InitCiCommandOpts {\n github?: boolean;\n gitlab?: boolean;\n force?: boolean;\n projectRoot?: string;\n}\n\nexport interface InitCiCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\n// ─── GitHub Actions workflow template ────────────────────────────────────────\n\nfunction githubWorkflow(): string {\n return `name: instrlint\n\non:\n push:\n paths:\n - 'CLAUDE.md'\n - '.claude/**'\n - 'AGENTS.md'\n - '.agents/**'\n - '.cursorrules'\n - '.cursor/**'\n pull_request:\n paths:\n - 'CLAUDE.md'\n - '.claude/**'\n - 'AGENTS.md'\n - '.agents/**'\n - '.cursorrules'\n - '.cursor/**'\n\njobs:\n instrlint:\n name: Lint instruction files\n runs-on: ubuntu-latest\n permissions:\n contents: read\n security-events: write\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: actions/setup-node@v4\n with:\n node-version: '20'\n\n - name: Run instrlint\n run: npx instrlint@latest ci --fail-on warning --format sarif --output instrlint.sarif\n\n - name: Upload SARIF\n if: always()\n uses: github/codeql-action/upload-sarif@v3\n with:\n sarif_file: instrlint.sarif\n category: instrlint\n`;\n}\n\n// ─── GitLab CI snippet template ───────────────────────────────────────────────\n\nfunction gitlabSnippet(): string {\n return `# Add this to your .gitlab-ci.yml\ninstrlint:\n image: node:20\n stage: test\n rules:\n - changes:\n - CLAUDE.md\n - .claude/**/*\n - AGENTS.md\n - .agents/**/*\n - .cursorrules\n - .cursor/**/*\n script:\n - npx instrlint@latest ci --fail-on warning --format json\n allow_failure: false\n`;\n}\n\n// ─── Core logic ───────────────────────────────────────────────────────────────\n\nexport function runInitCi(\n opts: InitCiCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): InitCiCommandResult {\n const projectRoot = opts.projectRoot ?? process.cwd();\n\n if (opts.github) {\n const workflowDir = join(projectRoot, \".github\", \"workflows\");\n const workflowPath = join(workflowDir, \"instrlint.yml\");\n\n if (existsSync(workflowPath) && !opts.force) {\n output.error(t(\"initCi.alreadyExists\", { path: workflowPath }));\n return { exitCode: 1, errorMessage: \"file already exists\" };\n }\n\n mkdirSync(workflowDir, { recursive: true });\n writeFileSync(workflowPath, githubWorkflow(), \"utf8\");\n output.log(t(\"initCi.created\", { path: workflowPath }));\n return { exitCode: 0 };\n }\n\n if (opts.gitlab) {\n output.log(gitlabSnippet());\n return { exitCode: 0 };\n }\n\n output.error(\"init-ci: specify --github or --gitlab\");\n return { exitCode: 1, errorMessage: \"no target specified\" };\n}\n"],"mappings":"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","names":["import_fs","import_path","import_chalk","detections","import_fs","import_path","import_fs","import_fs","import_path","safeParseFile","emptyFile","loadSkills","import_fs","import_path","safeParseFile","emptyFile","findRootFile","loadRules","loadMcpServers","pct","import_fs","import_path","collectRuleLines","collectRuleLines","import_fs","import_path","CONTEXT_WINDOW","import_chalk","chalk","chalk","import_fs","import_fs","import_path","import_chalk","chalk","import_fs","import_path","import_path","import_fs","import_fs","import_path","import_os","import_url","chalk","resolve","import_chalk","chalk","import_chalk","chalk","import_fs","import_path","import_fs","import_path"]}
1
+ {"version":3,"sources":["../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js","../src/cli.ts","../src/commands/run-command.ts","../src/core/scanner.ts","../src/adapters/claude-code.ts","../src/core/parser.ts","../src/detectors/token-estimator.ts","../src/adapters/codex.ts","../src/adapters/cursor.ts","../src/adapters/dispatch.ts","../src/analyzers/budget.ts","../src/detectors/config-overlap.ts","../src/utils/text.ts","../src/detectors/duplicate.ts","../src/analyzers/dead-rules.ts","../src/detectors/contradiction.ts","../src/detectors/stale-refs.ts","../src/detectors/scope-classifier.ts","../src/analyzers/structure.ts","../src/core/scorer.ts","../src/core/reporter.ts","../src/commands/budget-command.ts","../src/i18n/en.json","../src/i18n/zh-TW.json","../src/i18n/index.ts","../src/fixers/line-remover.ts","../src/fixers/remove-dead.ts","../src/fixers/remove-stale.ts","../src/fixers/deduplicate.ts","../src/fixers/structure-suggestions.ts","../src/utils/skill-version.ts","../src/verifiers/candidates.ts","../src/verifiers/policy.ts","../src/verifiers/verdicts.ts","../src/commands/install-command.ts","../src/commands/deadrules-command.ts","../src/commands/structure-command.ts","../src/commands/ci-command.ts","../src/reporters/sarif.ts","../src/commands/init-ci-command.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { runAll } from \"./commands/run-command.js\";\nimport { runBudget } from \"./commands/budget-command.js\";\nimport { runDeadRules } from \"./commands/deadrules-command.js\";\nimport { runStructure } from \"./commands/structure-command.js\";\nimport { runCi } from \"./commands/ci-command.js\";\nimport { runInitCi } from \"./commands/init-ci-command.js\";\nimport { runInstall } from \"./commands/install-command.js\";\nimport { initLocale } from \"./i18n/index.js\";\nimport { CURRENT_VERSION } from \"./utils/skill-version.js\";\nimport type { FailOn } from \"./commands/ci-command.js\";\n\nconst program = new Command();\n\nprogram\n .enablePositionalOptions()\n .name(\"instrlint\")\n .description(\n \"Lint and optimize your CLAUDE.md / AGENTS.md — find dead rules, token waste, and structural issues\",\n )\n .version(CURRENT_VERSION)\n .option(\n \"--format <type>\",\n \"output format (terminal|json|markdown)\",\n \"terminal\",\n )\n .option(\"--lang <locale>\", \"output language (en|zh-TW)\", \"en\")\n .option(\"--tool <name>\", \"force tool detection (claude-code|codex|cursor)\")\n .option(\"--fix\", \"auto-fix safe issues (dead rules, stale refs, dupes)\")\n .option(\"--force\", \"skip git clean check when using --fix\")\n .option(\n \"--emit-candidates <path>\",\n \"write low-confidence findings as candidates JSON for host LLM verification\",\n )\n .option(\n \"--apply-verdicts <path>\",\n \"apply host LLM verdicts from JSON file to the report\",\n )\n .option(\n \"--skip-report\",\n \"suppress terminal output (use with --emit-candidates)\",\n )\n .action(async function (this: Command) {\n const opts = this.opts<{\n format: string;\n lang?: string;\n tool?: string;\n fix?: boolean;\n force?: boolean;\n emitCandidates?: string;\n applyVerdicts?: string;\n skipReport?: boolean;\n }>();\n const result = await runAll(opts);\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"budget\")\n .description(\"Token budget analysis only\")\n .option(\n \"--format <type>\",\n \"output format (terminal|json|markdown)\",\n \"terminal\",\n )\n .option(\"--lang <locale>\", \"output language (en|zh-TW)\")\n .option(\"--tool <name>\", \"force tool detection (claude-code|codex|cursor)\")\n .action(async function (this: Command) {\n const opts = this.opts<{ format: string; lang?: string; tool?: string }>();\n const lang = opts.lang ?? this.parent?.opts<{ lang?: string }>()?.lang;\n const result = await runBudget({\n ...opts,\n ...(lang !== undefined && { lang }),\n });\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"deadrules\")\n .description(\"Dead rule detection only\")\n .option(\"--format <type>\", \"output format (terminal|json)\", \"terminal\")\n .option(\"--lang <locale>\", \"output language (en|zh-TW)\")\n .option(\"--tool <name>\", \"force tool detection (claude-code|codex|cursor)\")\n .action(async function (this: Command) {\n const opts = this.opts<{ format: string; lang?: string; tool?: string }>();\n const lang = opts.lang ?? this.parent?.opts<{ lang?: string }>()?.lang;\n const result = await runDeadRules({\n ...opts,\n ...(lang !== undefined && { lang }),\n });\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"structure\")\n .description(\"Structural analysis only\")\n .option(\"--format <type>\", \"output format (terminal|json)\", \"terminal\")\n .option(\"--lang <locale>\", \"output language (en|zh-TW)\")\n .option(\"--tool <name>\", \"force tool detection (claude-code|codex|cursor)\")\n .action(async function (this: Command) {\n const opts = this.opts<{ format: string; lang?: string; tool?: string }>();\n const lang = opts.lang ?? this.parent?.opts<{ lang?: string }>()?.lang;\n const result = await runStructure({\n ...opts,\n ...(lang !== undefined && { lang }),\n });\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"ci\")\n .description(\n \"CI mode: run full analysis and exit 1 if findings exceed threshold\",\n )\n .option(\n \"--fail-on <level>\",\n \"failure threshold (critical|warning|info)\",\n \"critical\",\n )\n .option(\"--format <type>\", \"output format (json|markdown|sarif)\", \"json\")\n .option(\"--output <file>\", \"write output to file instead of stdout\")\n .option(\"--tool <name>\", \"force tool detection (claude-code|codex|cursor)\")\n .action(async function (this: Command) {\n const opts = this.opts<{\n failOn: string;\n format: string;\n output?: string;\n tool?: string;\n }>();\n const lang = this.parent?.opts<{ lang?: string }>()?.lang;\n initLocale(lang);\n const result = await runCi({\n failOn: opts.failOn as FailOn,\n format: opts.format,\n ...(opts.output !== undefined && { output: opts.output }),\n ...(opts.tool !== undefined && { tool: opts.tool }),\n ...(lang !== undefined && { lang }),\n });\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"init-ci\")\n .description(\"Generate CI configuration for instrlint\")\n .option(\"--github\", \"Generate GitHub Actions workflow\")\n .option(\"--gitlab\", \"Generate GitLab CI snippet (prints to stdout)\")\n .option(\"--force\", \"overwrite existing files\")\n .action(function (this: Command) {\n const opts = this.opts<{\n github?: boolean;\n gitlab?: boolean;\n force?: boolean;\n }>();\n const result = runInitCi(opts);\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram\n .command(\"install\")\n .description(\"Install instrlint as a skill\")\n .option(\"--claude-code\", \"Install as Claude Code skill\")\n .option(\"--codex\", \"Install as Codex skill\")\n .option(\"--project\", \"Install into current project (instead of global)\")\n .option(\"--force\", \"overwrite existing skill file\")\n .action(function (this: Command) {\n const opts = this.opts<{\n claudeCode?: boolean;\n codex?: boolean;\n project?: boolean;\n force?: boolean;\n }>();\n const result = runInstall(opts);\n if (result.exitCode !== 0) process.exit(result.exitCode);\n });\n\nprogram.parse();\n","import { execSync } from \"child_process\";\nimport { writeFileSync } from \"fs\";\nimport { createInterface } from \"readline\";\nimport { basename, resolve, relative } from \"path\";\nimport chalk from \"chalk\";\nimport { scanProject } from \"../core/scanner.js\";\nimport { loadProject } from \"../adapters/dispatch.js\";\nimport { ensureInitialized } from \"../detectors/token-estimator.js\";\nimport { analyzeBudget } from \"../analyzers/budget.js\";\nimport { analyzeDeadRules } from \"../analyzers/dead-rules.js\";\nimport { analyzeStructure } from \"../analyzers/structure.js\";\nimport { calculateScore, buildActionPlan } from \"../core/scorer.js\";\nimport {\n printCombinedTerminal,\n reportJson,\n reportMarkdown,\n} from \"../core/reporter.js\";\nimport { removeDeadRules } from \"../fixers/remove-dead.js\";\nimport { removeStaleRefs } from \"../fixers/remove-stale.js\";\nimport { deduplicateRules } from \"../fixers/deduplicate.js\";\nimport {\n buildStructureSuggestions,\n printStructureSuggestions,\n markdownStructureSuggestions,\n} from \"../fixers/structure-suggestions.js\";\nimport { t, plural, initLocale, getLocale } from \"../i18n/index.js\";\nimport { checkSkillUpdate } from \"../utils/skill-version.js\";\nimport {\n buildCandidates,\n applyVerdicts,\n loadVerdictsFile,\n} from \"../verifiers/index.js\";\nimport type { ApplyVerdictsResult } from \"../verifiers/index.js\";\nimport { runInstall } from \"./install-command.js\";\nimport type { HealthReport } from \"../types.js\";\n\n// ─── Git helpers ───────────────────────────────────────────────────────────────\n\nfunction isGitClean(cwd: string): boolean {\n try {\n const out = execSync(\"git status --porcelain\", { cwd, encoding: \"utf8\" });\n return out.trim().length === 0;\n } catch {\n // Not a git repo or git unavailable — proceed without blocking\n return true;\n }\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface RunCommandOpts {\n format: string;\n tool?: string;\n lang?: string;\n fix?: boolean;\n force?: boolean;\n projectRoot?: string;\n emitCandidates?: string;\n applyVerdicts?: string;\n skipReport?: boolean;\n}\n\nexport interface RunCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\n// ─── Core logic ───────────────────────────────────────────────────────────────\n\nexport async function runAll(\n opts: RunCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): Promise<RunCommandResult> {\n initLocale(opts.lang);\n await ensureInitialized();\n\n const projectRoot = opts.projectRoot ?? process.cwd();\n const scan = scanProject(projectRoot, opts.tool);\n\n if (scan.tool === \"unknown\") {\n output.error(t(\"error.unknownTool\"));\n return { exitCode: 1, errorMessage: \"unknown tool\" };\n }\n\n if (scan.rootFilePath === null) {\n output.error(t(\"error.missingRootFile\", { tool: scan.tool }));\n return { exitCode: 1, errorMessage: \"missing root file\" };\n }\n\n // --fix and --emit-candidates are mutually exclusive\n if (opts.fix && opts.emitCandidates) {\n output.error(\"--fix and --emit-candidates cannot be used together\");\n return {\n exitCode: 1,\n errorMessage: \"--fix and --emit-candidates conflict\",\n };\n }\n\n // --fix: require clean working tree unless --force is set\n if (opts.fix && !opts.force && !isGitClean(projectRoot)) {\n output.error(t(\"error.dirtyWorkingTree\"));\n return { exitCode: 1, errorMessage: \"dirty working tree\" };\n }\n\n // --emit-candidates: validate output path stays within project root\n if (opts.emitCandidates) {\n const resolved = resolve(opts.emitCandidates);\n const rel = relative(projectRoot, resolved);\n if (rel.startsWith(\"..\")) {\n output.error(\n `--emit-candidates path must be within the project directory: ${opts.emitCandidates}`,\n );\n return {\n exitCode: 1,\n errorMessage: \"emit-candidates path outside project\",\n };\n }\n }\n\n const instructions = loadProject(projectRoot, scan.tool);\n\n const { findings: budgetFindings, summary } = analyzeBudget(instructions);\n const { findings: deadRuleFindings } = analyzeDeadRules(\n instructions,\n projectRoot,\n );\n const { findings: structureFindings } = analyzeStructure(\n instructions,\n projectRoot,\n );\n\n let allFindings = [\n ...budgetFindings,\n ...deadRuleFindings,\n ...structureFindings,\n ];\n\n // ── Emit candidates for host LLM verification ────────────────────────────────\n if (opts.emitCandidates) {\n const candidatesFile = buildCandidates(\n allFindings,\n instructions,\n projectRoot,\n getLocale(),\n );\n writeFileSync(opts.emitCandidates, JSON.stringify(candidatesFile, null, 2));\n if (opts.skipReport) return { exitCode: 0 };\n }\n\n // ── Apply host LLM verdicts ──────────────────────────────────────────────────\n let rejectedByVerification: number | undefined;\n if (opts.applyVerdicts) {\n try {\n const verdictsFile = loadVerdictsFile(opts.applyVerdicts);\n const result: ApplyVerdictsResult = applyVerdicts(\n allFindings,\n verdictsFile,\n );\n allFindings = result.findings;\n rejectedByVerification =\n result.rejectedCount > 0 ? result.rejectedCount : undefined;\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n return { exitCode: 1, errorMessage: \"failed to apply verdicts\" };\n }\n }\n\n const { score, grade } = calculateScore(allFindings, summary);\n const actionPlan = buildActionPlan(allFindings);\n\n const report: HealthReport = {\n project: basename(projectRoot),\n tool: instructions.tool,\n score,\n grade,\n locale: getLocale(),\n tokenMethod: summary.tokenMethod,\n findings: allFindings,\n budget: summary,\n actionPlan,\n ...(rejectedByVerification !== undefined ? { rejectedByVerification } : {}),\n };\n\n // ── Apply fixes ──────────────────────────────────────────────────────────────\n if (opts.fix) {\n // Build suggestions BEFORE modifying files, so line numbers are still accurate\n const suggestions = buildStructureSuggestions(allFindings);\n\n const deadFixed = removeDeadRules(allFindings);\n const staleFixed = removeStaleRefs(allFindings);\n const dupeFixed = deduplicateRules(allFindings);\n const total = deadFixed + staleFixed + dupeFixed;\n\n if (total === 0) {\n output.log(chalk.green(` ${t(\"status.noAutoFixable\")}`));\n } else {\n output.log(\"\");\n output.log(chalk.bold.white(` ${t(\"label.fixSummary\")}`));\n output.log(chalk.gray(\" ─\".repeat(30)));\n if (deadFixed > 0)\n output.log(\n ` ${chalk.yellow(\"⚠\")} ${t(\"fix.removedDeadRules\", { count: String(deadFixed), s: plural(deadFixed) })}`,\n );\n if (staleFixed > 0)\n output.log(\n ` ${chalk.yellow(\"⚠\")} ${t(\"fix.removedStaleRefs\", { count: String(staleFixed), s: plural(staleFixed) })}`,\n );\n if (dupeFixed > 0)\n output.log(\n ` ${chalk.yellow(\"⚠\")} ${t(\"fix.removedDuplicates\", { count: String(dupeFixed), s: plural(dupeFixed) })}`,\n );\n output.log(chalk.gray(\" ─\".repeat(30)));\n output.log(\n chalk.green(\n ` ${t(\"status.fixedIssues\", { count: String(total), s: plural(total) })}`,\n ),\n );\n output.log(\"\");\n }\n\n // Print actionable suggestions for non-auto-fixable structure findings\n printStructureSuggestions(suggestions, projectRoot, output);\n\n return { exitCode: 0 };\n }\n\n // ── Skill update notice ──────────────────────────────────────────────────────\n const skillUpdate = checkSkillUpdate(projectRoot);\n\n // ── Format output ────────────────────────────────────────────────────────────\n if (opts.format === \"json\") {\n output.log(reportJson(report));\n return { exitCode: 0 };\n }\n\n if (opts.format === \"markdown\") {\n const mdSuggestions = buildStructureSuggestions(allFindings);\n const mdExtra = markdownStructureSuggestions(mdSuggestions, projectRoot);\n const updateSection = skillUpdate\n ? [\n \"\",\n `> ⚠️ **${t(\"install.outdatedTitle\")}** (${t(\"install.outdatedVersions\", { installed: skillUpdate.installedVersion, current: skillUpdate.currentVersion })})`,\n `> \\`${t(\"install.updateCmd\", { flag: skillUpdate.isProject ? \"--claude-code --project\" : \"--claude-code\" })}\\``,\n ]\n : [];\n output.log(reportMarkdown(report, [...mdExtra, ...updateSection]));\n return { exitCode: 0 };\n }\n\n printCombinedTerminal(report, output);\n\n if (skillUpdate && process.stdout.isTTY) {\n output.log(\"\");\n output.log(\n ` ${chalk.yellow(\"⚠\")} ${chalk.bold(t(\"install.outdatedTitle\"))} (${t(\"install.outdatedVersions\", { installed: skillUpdate.installedVersion, current: skillUpdate.currentVersion })})`,\n );\n const confirmed = await promptYesNo(` ${t(\"install.updatePrompt\")}`);\n if (confirmed) {\n const installResult = runInstall(\n {\n claudeCode: true,\n project: skillUpdate.isProject,\n force: true,\n projectRoot,\n },\n output,\n );\n if (installResult.exitCode !== 0) {\n output.error?.(\n `Update failed: ${installResult.errorMessage ?? \"unknown error\"}`,\n );\n }\n }\n output.log(\"\");\n }\n\n return { exitCode: 0 };\n}\n\nfunction promptYesNo(question: string): Promise<boolean> {\n return new Promise((resolve) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question(`${question} ${chalk.gray(\"[Y/n]\")} `, (answer) => {\n rl.close();\n const trimmed = answer.trim().toLowerCase();\n resolve(trimmed === \"\" || trimmed === \"y\");\n });\n });\n}\n","import { existsSync } from 'fs';\nimport { join } from 'path';\nimport type { ToolType } from '../types.js';\n\nexport type ScanConfidence = 'high' | 'low' | 'ambiguous';\n\nexport interface ScanResult {\n tool: ToolType;\n /** Absolute path to the root instruction file (e.g. CLAUDE.md or AGENTS.md) */\n rootFilePath: string | null;\n /** Absolute path to the config directory (e.g. .claude/, .agents/) */\n configDir: string | null;\n confidence: ScanConfidence;\n}\n\ninterface Detection {\n tool: ToolType;\n rootFilePath: string | null;\n configDir: string | null;\n}\n\nfunction detectAll(projectRoot: string): Detection[] {\n const detections: Detection[] = [];\n\n // Claude Code: .claude/ directory\n const claudeDir = join(projectRoot, '.claude');\n if (existsSync(claudeDir)) {\n const rootInDir = join(claudeDir, 'CLAUDE.md');\n const rootAtRoot = join(projectRoot, 'CLAUDE.md');\n detections.push({\n tool: 'claude-code',\n rootFilePath: existsSync(rootInDir)\n ? rootInDir\n : existsSync(rootAtRoot)\n ? rootAtRoot\n : null,\n configDir: claudeDir,\n });\n }\n\n // Codex: .agents/ directory\n const agentsDir = join(projectRoot, '.agents');\n if (existsSync(agentsDir)) {\n const agentsMd = join(projectRoot, 'AGENTS.md');\n detections.push({\n tool: 'codex',\n rootFilePath: existsSync(agentsMd) ? agentsMd : null,\n configDir: agentsDir,\n });\n }\n\n // Codex: .codex/ directory (alternative)\n const codexDir = join(projectRoot, '.codex');\n if (existsSync(codexDir) && !detections.some((d) => d.tool === 'codex')) {\n const agentsMd = join(projectRoot, 'AGENTS.md');\n detections.push({\n tool: 'codex',\n rootFilePath: existsSync(agentsMd) ? agentsMd : null,\n configDir: codexDir,\n });\n }\n\n // Cursor: .cursor/ directory or .cursorrules file\n const cursorDir = join(projectRoot, '.cursor');\n const cursorRules = join(projectRoot, '.cursorrules');\n if (existsSync(cursorDir) || existsSync(cursorRules)) {\n detections.push({\n tool: 'cursor',\n rootFilePath: existsSync(cursorRules) ? cursorRules : null,\n configDir: existsSync(cursorDir) ? cursorDir : null,\n });\n }\n\n return detections;\n}\n\nfunction detectByRootFile(projectRoot: string): Detection | null {\n const claudeMd = join(projectRoot, 'CLAUDE.md');\n if (existsSync(claudeMd)) {\n return { tool: 'claude-code', rootFilePath: claudeMd, configDir: null };\n }\n\n const agentsMd = join(projectRoot, 'AGENTS.md');\n if (existsSync(agentsMd)) {\n return { tool: 'codex', rootFilePath: agentsMd, configDir: null };\n }\n\n return null;\n}\n\nexport function scanProject(projectRoot: string, forceTool?: string): ScanResult {\n if (!existsSync(projectRoot)) {\n throw new Error(`Project root does not exist: ${projectRoot}`);\n }\n\n // --tool flag overrides everything\n if (forceTool != null) {\n const valid: ToolType[] = ['claude-code', 'codex', 'cursor'];\n if (!valid.includes(forceTool as ToolType)) {\n throw new Error(\n `Invalid tool: \"${forceTool}\". Must be one of: ${valid.join(', ')}`\n );\n }\n const tool = forceTool as ToolType;\n // Still try to find the root file for this tool\n const detections = detectAll(projectRoot);\n const match = detections.find((d) => d.tool === tool);\n return {\n tool,\n rootFilePath: match?.rootFilePath ?? null,\n configDir: match?.configDir ?? null,\n confidence: 'high',\n };\n }\n\n const detections = detectAll(projectRoot);\n\n if (detections.length === 0) {\n // Fall back to checking for bare root files\n const byFile = detectByRootFile(projectRoot);\n if (byFile != null) {\n return { ...byFile, confidence: 'low' };\n }\n return { tool: 'unknown', rootFilePath: null, configDir: null, confidence: 'low' };\n }\n\n if (detections.length === 1) {\n const d = detections[0]!;\n return { tool: d.tool, rootFilePath: d.rootFilePath, configDir: d.configDir, confidence: 'high' };\n }\n\n // Multiple detections — use the first match, mark ambiguous\n const first = detections[0]!;\n return {\n tool: first.tool,\n rootFilePath: first.rootFilePath,\n configDir: first.configDir,\n confidence: 'ambiguous',\n };\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from \"fs\";\nimport { basename, dirname, join, relative } from \"path\";\nimport { parseInstructionFile, parseYamlFrontmatter } from \"../core/parser.js\";\nimport {\n countTokens,\n estimateMcpTokens,\n} from \"../detectors/token-estimator.js\";\nimport type {\n InstructionFile,\n McpServerConfig,\n ParsedInstructions,\n RuleFile,\n SkillFile,\n} from \"../types.js\";\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction withTokens(file: InstructionFile): InstructionFile {\n const raw = (() => {\n try {\n return readFileSync(file.path, \"utf8\");\n } catch {\n return \"\";\n }\n })();\n const { count, method } = countTokens(raw);\n return { ...file, tokenCount: count, tokenMethod: method };\n}\n\nfunction safeParseFile(filePath: string): InstructionFile | null {\n try {\n const file = parseInstructionFile(filePath);\n return withTokens(file);\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not read ${filePath}, skipping\\n`,\n );\n return null;\n }\n}\n\n// ─── Root file discovery ───────────────────────────────────────────────────\n\nfunction findRootFile(projectRoot: string): string | null {\n const candidates = [\n join(projectRoot, \"CLAUDE.md\"),\n join(projectRoot, \".claude\", \"CLAUDE.md\"),\n ];\n return candidates.find(existsSync) ?? null;\n}\n\n// ─── Rules ────────────────────────────────────────────────────────────────\n\nfunction loadRules(projectRoot: string): RuleFile[] {\n const rulesDir = join(projectRoot, \".claude\", \"rules\");\n if (!existsSync(rulesDir)) return [];\n\n const rules: RuleFile[] = [];\n let entries: string[] = [];\n try {\n entries = readdirSync(rulesDir).filter((f) => f.endsWith(\".md\"));\n } catch {\n return [];\n }\n\n for (const filename of entries) {\n const filePath = join(rulesDir, filename);\n try {\n const raw = readFileSync(filePath, \"utf8\");\n const { paths, globs, body } = parseYamlFrontmatter(raw);\n const baseFile = parseInstructionFile(filePath);\n const { count, method } = countTokens(body);\n rules.push({\n ...baseFile,\n tokenCount: count,\n tokenMethod: method,\n ...(paths != null ? { paths } : {}),\n ...(globs != null ? { globs } : {}),\n });\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not parse rule ${filePath}, skipping\\n`,\n );\n }\n }\n\n return rules;\n}\n\n// ─── Skills ───────────────────────────────────────────────────────────────\n\nfunction loadSkills(projectRoot: string): SkillFile[] {\n const skillsDir = join(projectRoot, \".claude\", \"skills\");\n if (!existsSync(skillsDir)) return [];\n\n const skills: SkillFile[] = [];\n let entries: string[] = [];\n try {\n entries = readdirSync(skillsDir);\n } catch {\n return [];\n }\n\n for (const skillName of entries) {\n const skillFile = join(skillsDir, skillName, \"SKILL.md\");\n if (!existsSync(skillFile)) continue;\n\n const parsed = safeParseFile(skillFile);\n if (parsed != null) {\n skills.push({ ...parsed, skillName });\n }\n }\n\n return skills;\n}\n\n// ─── Sub-directory CLAUDE.md files ────────────────────────────────────────\n\nconst SKIP_DIRS = new Set([\n \"node_modules\",\n \"dist\",\n \".git\",\n \".claude\",\n \".turbo\",\n \"coverage\",\n \"tests\",\n \"test\",\n \"__tests__\",\n \"spec\",\n]);\n\nfunction findSubClaudeFiles(\n dir: string,\n projectRoot: string,\n depth = 0,\n): InstructionFile[] {\n if (depth > 10) return []; // guard against infinite recursion\n const results: InstructionFile[] = [];\n\n let entries: string[] = [];\n try {\n entries = readdirSync(dir);\n } catch {\n return [];\n }\n\n for (const entry of entries) {\n if (SKIP_DIRS.has(entry)) continue;\n const full = join(dir, entry);\n\n try {\n const stat = statSync(full);\n if (stat.isDirectory()) {\n results.push(...findSubClaudeFiles(full, projectRoot, depth + 1));\n } else if (entry === \"CLAUDE.md\") {\n // Skip the project root CLAUDE.md itself\n if (relative(projectRoot, full) === \"CLAUDE.md\") continue;\n const parsed = safeParseFile(full);\n if (parsed != null) results.push(parsed);\n }\n } catch {\n // skip inaccessible entries\n }\n }\n\n return results;\n}\n\n// ─── MCP servers ──────────────────────────────────────────────────────────\n\ninterface McpServerEntry {\n command?: string;\n args?: string[];\n tools?: unknown[];\n}\n\nfunction parseMcpServers(projectRoot: string): McpServerConfig[] {\n const candidates = [\n join(projectRoot, \".claude\", \"settings.json\"),\n join(projectRoot, \".claude\", \"settings.local.json\"),\n ];\n\n const servers: McpServerConfig[] = [];\n\n for (const settingsPath of candidates) {\n if (!existsSync(settingsPath)) continue;\n try {\n const raw = readFileSync(settingsPath, \"utf8\");\n const parsed: unknown = JSON.parse(raw);\n if (\n parsed == null ||\n typeof parsed !== \"object\" ||\n !(\"mcpServers\" in parsed)\n ) {\n continue;\n }\n const mcpServers = (\n parsed as { mcpServers: Record<string, McpServerEntry> }\n ).mcpServers;\n for (const [name, entry] of Object.entries(mcpServers)) {\n const toolCount = Array.isArray(entry.tools)\n ? entry.tools.length\n : undefined;\n const config: McpServerConfig = {\n name,\n estimatedTokens: 0,\n ...(toolCount !== undefined ? { toolCount } : {}),\n };\n const { count } = estimateMcpTokens(config);\n servers.push({ ...config, estimatedTokens: count });\n }\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not parse MCP config in ${settingsPath}, skipping\\n`,\n );\n }\n }\n\n return servers;\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport function loadClaudeCodeProject(projectRoot: string): ParsedInstructions {\n // Root file\n const rootFilePath = findRootFile(projectRoot);\n const rootFile: InstructionFile =\n rootFilePath != null\n ? (safeParseFile(rootFilePath) ?? emptyFile(rootFilePath))\n : emptyFile(join(projectRoot, \"CLAUDE.md\"));\n\n // Rule files\n const rules = loadRules(projectRoot);\n\n // Skill files\n const skills = loadSkills(projectRoot);\n\n // Sub-directory CLAUDE.md files (skip root)\n const subFiles = findSubClaudeFiles(projectRoot, projectRoot);\n\n // MCP servers\n const mcpServers = parseMcpServers(projectRoot);\n\n return {\n tool: \"claude-code\",\n rootFile,\n rules,\n skills,\n subFiles,\n mcpServers,\n };\n}\n\nfunction emptyFile(path: string): InstructionFile {\n return {\n path,\n lines: [],\n lineCount: 0,\n tokenCount: 0,\n tokenMethod: \"estimated\",\n };\n}\n","import { readFileSync } from \"fs\";\nimport type { InstructionFile, ParsedLine } from \"../types.js\";\n\n// ─── Keyword dictionary ────────────────────────────────────────────────────\n\nconst KNOWN_KEYWORDS = new Set([\n \"typescript\",\n \"javascript\",\n \"eslint\",\n \"prettier\",\n \"biome\",\n \"react\",\n \"vue\",\n \"svelte\",\n \"angular\",\n \"next\",\n \"nextjs\",\n \"nuxt\",\n \"jest\",\n \"vitest\",\n \"mocha\",\n \"jasmine\",\n \"playwright\",\n \"cypress\",\n \"postgresql\",\n \"postgres\",\n \"mysql\",\n \"sqlite\",\n \"mongodb\",\n \"redis\",\n \"docker\",\n \"kubernetes\",\n \"k8s\",\n \"terraform\",\n \"git\",\n \"github\",\n \"gitlab\",\n \"npm\",\n \"pnpm\",\n \"yarn\",\n \"bun\",\n \"node\",\n \"nodejs\",\n \"deno\",\n \"webpack\",\n \"vite\",\n \"esbuild\",\n \"tsup\",\n \"rollup\",\n \"zod\",\n \"prisma\",\n \"drizzle\",\n \"openai\",\n \"anthropic\",\n \"claude\",\n \"commitlint\",\n \"husky\",\n \"lint-staged\",\n]);\n\nconst KEYWORD_REGEX = new RegExp(\n `\\\\b(${[...KNOWN_KEYWORDS].join(\"|\")})\\\\b`,\n \"gi\",\n);\n\n// ─── Path extraction ───────────────────────────────────────────────────────\n\n// Matches path-like strings: starts with src/, tests/, ./, ../, or contains /\n// but NOT URLs (http:// https://)\nconst PATH_REGEX =\n /(?<!\\w)(?:\\.{1,2}\\/|(?:src|tests?|dist|lib|docs?|config|scripts?|packages?)\\/)[^\\s,;`'\")\\]>]+/g;\n\n// Matches @file references: @path/to/file.md (or .txt, .json, .yaml, .yml)\n// Negative lookbehind: not after word char (avoids emails like user@example.com)\n// Capture group 1: the path, WITHOUT the leading @\nconst AT_REF_REGEX =\n /(?<![a-zA-Z0-9_])@((?:\\.\\.?\\/)?[\\w./-]+\\.(?:md|txt|json|yaml|yml))\\b/g;\n\n// ─── Rule classification signals ──────────────────────────────────────────\n\nconst RULE_IMPERATIVE_WORDS =\n /\\b(must|should|never|always|prefer|avoid|ensure|require|forbid|use|do not|don't)\\b|必須|應該|應當|永遠|總是|禁止|不要|不可|不得|避免|請使用|優先使用|請勿/i;\n\nconst RULE_NEGATION_PATTERN = /\\b(not|don't|do not)\\s+\\w+/i;\n\n// Strong imperatives for non-list lines (must match at sentence start or be prominent)\nconst STRONG_IMPERATIVE = /\\b(must|shall|always|never)\\b/i;\n\n// ─── YAML frontmatter parsing ──────────────────────────────────────────────\n\nexport interface FrontmatterResult {\n paths?: string[];\n globs?: string[];\n body: string;\n}\n\nexport function parseYamlFrontmatter(content: string): FrontmatterResult {\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/m.exec(content);\n if (match == null) {\n return { body: content };\n }\n\n const yaml = match[1] ?? \"\";\n const body = match[2] ?? \"\";\n\n const paths = extractYamlStringArray(yaml, \"paths\");\n const globs = extractYamlStringArray(yaml, \"globs\");\n\n return {\n ...(paths != null ? { paths } : {}),\n ...(globs != null ? { globs } : {}),\n body,\n };\n}\n\nfunction extractYamlStringArray(\n yaml: string,\n key: string,\n): string[] | undefined {\n // Match \"key:\\n - value\\n - value\" style\n const blockMatch = new RegExp(\n `^${key}:\\\\s*\\\\n((?:\\\\s+-\\\\s+.+\\\\n?)*)`,\n \"m\",\n ).exec(yaml);\n if (blockMatch != null) {\n return (blockMatch[1] ?? \"\")\n .split(\"\\n\")\n .map((l) =>\n l\n .replace(/^\\s+-\\s+/, \"\")\n .replace(/[\"']/g, \"\")\n .trim(),\n )\n .filter((l) => l.length > 0);\n }\n\n // Match \"key: [value, value]\" inline style\n const inlineMatch = new RegExp(`^${key}:\\\\s*\\\\[(.+)\\\\]`, \"m\").exec(yaml);\n if (inlineMatch != null) {\n return (inlineMatch[1] ?? \"\")\n .split(\",\")\n .map((s) => s.replace(/[\"']/g, \"\").trim())\n .filter((s) => s.length > 0);\n }\n\n return undefined;\n}\n\n// ─── Line classifier ───────────────────────────────────────────────────────\n\nfunction classifyLine(\n text: string,\n inCodeBlock: boolean,\n inHtmlComment: boolean,\n): ParsedLine[\"type\"] {\n if (inCodeBlock) return \"code\";\n if (inHtmlComment) return \"comment\";\n\n const trimmed = text.trim();\n\n if (trimmed.length === 0) return \"blank\";\n if (/^#{1,6}\\s/.test(trimmed)) return \"heading\";\n if (trimmed.startsWith(\"```\")) return \"code\";\n\n // Inline HTML comment (whole line)\n if (/^<!--[\\s\\S]*-->$/.test(trimmed)) return \"comment\";\n // Opening HTML comment\n if (trimmed.startsWith(\"<!--\")) return \"comment\";\n\n if (isRule(trimmed)) return \"rule\";\n return \"other\";\n}\n\nfunction isRule(text: string): boolean {\n const isList = text.startsWith(\"- \");\n const body = isList ? text.slice(2) : text;\n\n if (isList) {\n if (RULE_IMPERATIVE_WORDS.test(body)) return true;\n if (RULE_NEGATION_PATTERN.test(body)) return true;\n } else {\n // Non-list lines: require strong imperative AND sentence-like structure\n if (STRONG_IMPERATIVE.test(body) && /^[A-Z]/.test(body)) return true;\n // Also catch imperative sentences starting with a verb (capitalised)\n if (RULE_IMPERATIVE_WORDS.test(body) && /^[A-Z][a-z]/.test(body))\n return true;\n // CJK lines: classify as rule if they start with a CJK character and contain an imperative word\n if (\n RULE_IMPERATIVE_WORDS.test(body) &&\n /^[\\u4e00-\\u9fff\\u3400-\\u4dbf]/.test(body)\n )\n return true;\n }\n\n return false;\n}\n\nfunction extractKeywords(text: string): string[] {\n const matches = text.matchAll(KEYWORD_REGEX);\n const found = new Set<string>();\n for (const m of matches) {\n found.add(m[0].toLowerCase());\n }\n return [...found];\n}\n\nfunction extractPaths(text: string): string[] {\n const found: string[] = [];\n\n // Existing path patterns (src/, tests/, ./, ../, etc.)\n for (const m of text.matchAll(PATH_REGEX)) {\n const cleaned = m[0].replace(/[.,;)>\\]'\"]+$/, \"\");\n if (cleaned.length > 1) found.push(cleaned);\n }\n\n // @file references: strip the @ and keep just the path\n for (const m of text.matchAll(AT_REF_REGEX)) {\n const cleaned = (m[1] ?? \"\").replace(/[.,;)>\\]'\"]+$/, \"\");\n if (cleaned.length > 0) found.push(cleaned);\n }\n\n return [...new Set(found)];\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport function parseInstructionFile(filePath: string): InstructionFile {\n const raw = readFileSync(filePath, \"utf8\");\n const rawLines = raw.split(/\\r?\\n/);\n\n // Strip the single trailing empty string produced by a final newline.\n // Most text files end with \\n, which splits into [..., ''] — this is not a real line.\n if (rawLines.length > 0 && rawLines[rawLines.length - 1] === \"\") {\n rawLines.pop();\n }\n\n let inCodeBlock = false;\n let inHtmlComment = false;\n const lines: ParsedLine[] = [];\n\n for (let i = 0; i < rawLines.length; i++) {\n const text = rawLines[i] ?? \"\";\n const trimmed = text.trim();\n\n // Classify using current state (before updating)\n const type = classifyLine(text, inCodeBlock, inHtmlComment);\n\n // Update code block state AFTER classifying the fence line itself\n if (!inHtmlComment && trimmed.startsWith(\"```\")) {\n inCodeBlock = !inCodeBlock;\n }\n\n // Update HTML comment state AFTER classifying the current line:\n // - opening line (<!-- ... without -->): set true after this line\n // - closing line (contains -->): set false after this line\n // - lines inside: state remains true\n if (!inCodeBlock) {\n if (inHtmlComment) {\n if (trimmed.includes(\"-->\")) inHtmlComment = false;\n } else if (trimmed.startsWith(\"<!--\") && !trimmed.includes(\"-->\")) {\n inHtmlComment = true;\n }\n }\n\n lines.push({\n lineNumber: i + 1,\n text,\n type,\n keywords: extractKeywords(text),\n referencedPaths: extractPaths(text),\n });\n }\n\n return {\n path: filePath,\n lines,\n lineCount: lines.length,\n // tokenCount and tokenMethod will be filled by the adapter/estimator\n tokenCount: 0,\n tokenMethod: \"estimated\",\n };\n}\n","import type { McpServerConfig, TokenMethod } from \"../types.js\";\n\n// ─── Tiktoken singleton ────────────────────────────────────────────────────\n\ninterface TiktokenEncoder {\n encode(text: string): ArrayLike<number>;\n}\n\nlet encoder: TiktokenEncoder | null = null;\n\n// Single shared Promise — all callers await the same resolution.\n// Setting initialized = true before the await was a race: ensureInitialized()\n// would see the flag and return while encoder was still null.\nconst initPromise: Promise<void> = (async () => {\n try {\n const { getEncoding } = await import(\"js-tiktoken\");\n encoder = getEncoding(\"cl100k_base\");\n } catch {\n process.stderr.write(\n \"[instrlint] Warning: js-tiktoken failed to load — falling back to character estimation\\n\",\n );\n encoder = null;\n }\n})();\n\nexport async function ensureInitialized(): Promise<void> {\n await initPromise;\n}\n\n// ─── CJK character detection ───────────────────────────────────────────────\n\nconst CJK_REGEX = /[\\u3000-\\u9fff\\uac00-\\ud7af\\uf900-\\ufaff]/g;\n\nfunction cjkRatio(text: string): number {\n if (text.length === 0) return 0;\n const matches = text.match(CJK_REGEX);\n return (matches?.length ?? 0) / text.length;\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport interface TokenCount {\n count: number;\n method: TokenMethod;\n}\n\nexport function countTokens(text: string): TokenCount {\n if (text.length === 0) return { count: 0, method: \"measured\" };\n\n if (encoder != null) {\n try {\n return { count: encoder.encode(text).length, method: \"measured\" };\n } catch {\n // Fall through to estimation\n }\n }\n\n return estimateFallback(text);\n}\n\nexport function estimateFallback(text: string): TokenCount {\n const ratio = cjkRatio(text);\n const charsPerToken = 4 * (1 - ratio) + 2 * ratio;\n return {\n count: Math.ceil(text.length / charsPerToken),\n method: \"estimated\",\n };\n}\n\nexport function estimateMcpTokens(config: McpServerConfig): {\n count: number;\n method: \"estimated\";\n} {\n if (config.toolCount != null) {\n return { count: config.toolCount * 400, method: \"estimated\" };\n }\n // Default: assume a small server (~2500 tokens)\n return { count: 2500, method: \"estimated\" };\n}\n","import { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { parseInstructionFile } from \"../core/parser.js\";\nimport {\n countTokens,\n estimateMcpTokens,\n} from \"../detectors/token-estimator.js\";\nimport type {\n InstructionFile,\n McpServerConfig,\n ParsedInstructions,\n SkillFile,\n} from \"../types.js\";\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction safeParseFile(filePath: string): InstructionFile | null {\n try {\n const raw = readFileSync(filePath, \"utf8\");\n const file = parseInstructionFile(filePath);\n const { count, method } = countTokens(raw);\n return { ...file, tokenCount: count, tokenMethod: method };\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not read ${filePath}, skipping\\n`,\n );\n return null;\n }\n}\n\nfunction emptyFile(path: string): InstructionFile {\n return {\n path,\n lines: [],\n lineCount: 0,\n tokenCount: 0,\n tokenMethod: \"estimated\",\n };\n}\n\n// ─── Skills ───────────────────────────────────────────────────────────────\n\nfunction loadSkills(projectRoot: string): SkillFile[] {\n const skillsDir = join(projectRoot, \".agents\", \"skills\");\n if (!existsSync(skillsDir)) return [];\n\n const skills: SkillFile[] = [];\n let entries: string[] = [];\n try {\n entries = readdirSync(skillsDir);\n } catch {\n return [];\n }\n\n for (const skillName of entries) {\n const skillFile = join(skillsDir, skillName, \"SKILL.md\");\n if (!existsSync(skillFile)) continue;\n const parsed = safeParseFile(skillFile);\n if (parsed != null) {\n skills.push({ ...parsed, skillName });\n }\n }\n\n return skills;\n}\n\n// ─── MCP servers from .codex/config.toml ─────────────────────────────────\n\n/**\n * Minimal TOML parser targeting only [mcp_servers.<name>] sections.\n * Handles simple key = \"value\" and key = [\"array\"] under those sections.\n */\nfunction parseMcpFromToml(toml: string): McpServerConfig[] {\n const servers: McpServerConfig[] = [];\n const sectionRe = /^\\[mcp_servers\\.([^\\]]+)\\]/;\n const keyValueRe = /^(\\w+)\\s*=\\s*(.+)$/;\n\n let currentName: string | null = null;\n let currentTools: string[] | undefined;\n\n const flush = () => {\n if (currentName != null) {\n const config: McpServerConfig = {\n name: currentName,\n estimatedTokens: 0,\n ...(currentTools !== undefined ? { toolCount: currentTools.length } : {}),\n };\n const { count } = estimateMcpTokens(config);\n servers.push({ ...config, estimatedTokens: count });\n }\n currentName = null;\n currentTools = undefined;\n };\n\n for (const line of toml.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"#\") || trimmed === \"\") continue;\n\n const sectionMatch = sectionRe.exec(trimmed);\n if (sectionMatch != null) {\n flush();\n currentName = sectionMatch[1]!;\n continue;\n }\n\n if (currentName == null) continue;\n\n const kvMatch = keyValueRe.exec(trimmed);\n if (kvMatch == null) continue;\n\n const key = kvMatch[1]!;\n const raw = kvMatch[2]!.trim();\n\n if (key === \"tools\") {\n // Parse inline array: [\"tool1\", \"tool2\"]\n const items = raw.match(/\"([^\"]+)\"/g);\n currentTools = items != null ? items.map((s) => s.slice(1, -1)) : [];\n }\n }\n\n flush();\n return servers;\n}\n\nfunction loadMcpServers(projectRoot: string): McpServerConfig[] {\n const tomlPath = join(projectRoot, \".codex\", \"config.toml\");\n if (!existsSync(tomlPath)) return [];\n\n try {\n const raw = readFileSync(tomlPath, \"utf8\");\n return parseMcpFromToml(raw);\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not parse MCP config in ${tomlPath}, skipping\\n`,\n );\n return [];\n }\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport function loadCodexProject(projectRoot: string): ParsedInstructions {\n const rootFilePath = join(projectRoot, \"AGENTS.md\");\n const rootFile: InstructionFile = existsSync(rootFilePath)\n ? (safeParseFile(rootFilePath) ?? emptyFile(rootFilePath))\n : emptyFile(rootFilePath);\n\n const skills = loadSkills(projectRoot);\n const mcpServers = loadMcpServers(projectRoot);\n\n return {\n tool: \"codex\",\n rootFile,\n rules: [],\n skills,\n subFiles: [],\n mcpServers,\n };\n}\n","import { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { parseInstructionFile, parseYamlFrontmatter } from \"../core/parser.js\";\nimport {\n countTokens,\n estimateMcpTokens,\n} from \"../detectors/token-estimator.js\";\nimport type {\n InstructionFile,\n McpServerConfig,\n ParsedInstructions,\n RuleFile,\n} from \"../types.js\";\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction safeParseFile(filePath: string): InstructionFile | null {\n try {\n const raw = readFileSync(filePath, \"utf8\");\n const file = parseInstructionFile(filePath);\n const { count, method } = countTokens(raw);\n return { ...file, tokenCount: count, tokenMethod: method };\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not read ${filePath}, skipping\\n`,\n );\n return null;\n }\n}\n\nfunction emptyFile(path: string): InstructionFile {\n return {\n path,\n lines: [],\n lineCount: 0,\n tokenCount: 0,\n tokenMethod: \"estimated\",\n };\n}\n\n// ─── Root file ─────────────────────────────────────────────────────────────\n\nfunction findRootFile(projectRoot: string): string | null {\n const cursorRules = join(projectRoot, \".cursorrules\");\n if (existsSync(cursorRules)) return cursorRules;\n return null;\n}\n\n// ─── Rules from .cursor/rules/*.md ────────────────────────────────────────\n\nfunction loadRules(projectRoot: string): RuleFile[] {\n const rulesDir = join(projectRoot, \".cursor\", \"rules\");\n if (!existsSync(rulesDir)) return [];\n\n const rules: RuleFile[] = [];\n let entries: string[] = [];\n try {\n entries = readdirSync(rulesDir).filter((f) => f.endsWith(\".md\"));\n } catch {\n return [];\n }\n\n for (const filename of entries) {\n const filePath = join(rulesDir, filename);\n try {\n const raw = readFileSync(filePath, \"utf8\");\n // Cursor uses globs: in frontmatter (not paths:)\n const { globs, body } = parseYamlFrontmatter(raw);\n const baseFile = parseInstructionFile(filePath);\n const { count, method } = countTokens(body);\n rules.push({\n ...baseFile,\n tokenCount: count,\n tokenMethod: method,\n ...(globs != null ? { globs } : {}),\n });\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not parse rule ${filePath}, skipping\\n`,\n );\n }\n }\n\n return rules;\n}\n\n// ─── MCP servers from .cursor/mcp.json ────────────────────────────────────\n\ninterface CursorMcpEntry {\n command?: string;\n args?: string[];\n tools?: unknown[];\n}\n\nfunction loadMcpServers(projectRoot: string): McpServerConfig[] {\n const mcpPath = join(projectRoot, \".cursor\", \"mcp.json\");\n if (!existsSync(mcpPath)) return [];\n\n try {\n const raw = readFileSync(mcpPath, \"utf8\");\n const parsed: unknown = JSON.parse(raw);\n if (\n parsed == null ||\n typeof parsed !== \"object\" ||\n !(\"mcpServers\" in parsed)\n ) {\n return [];\n }\n const mcpServers = (\n parsed as { mcpServers: Record<string, CursorMcpEntry> }\n ).mcpServers;\n return Object.entries(mcpServers).map(([name, entry]) => {\n const toolCount = Array.isArray(entry.tools) ? entry.tools.length : undefined;\n const config: McpServerConfig = {\n name,\n estimatedTokens: 0,\n ...(toolCount !== undefined ? { toolCount } : {}),\n };\n const { count } = estimateMcpTokens(config);\n return { ...config, estimatedTokens: count };\n });\n } catch {\n process.stderr.write(\n `[instrlint] Warning: could not parse MCP config in ${mcpPath}, skipping\\n`,\n );\n return [];\n }\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport function loadCursorProject(projectRoot: string): ParsedInstructions {\n const rootFilePath = findRootFile(projectRoot);\n const rootFile: InstructionFile =\n rootFilePath != null\n ? (safeParseFile(rootFilePath) ?? emptyFile(rootFilePath))\n : emptyFile(join(projectRoot, \".cursorrules\"));\n\n const rules = loadRules(projectRoot);\n const mcpServers = loadMcpServers(projectRoot);\n\n return {\n tool: \"cursor\",\n rootFile,\n rules,\n skills: [],\n subFiles: [],\n mcpServers,\n };\n}\n","import { loadClaudeCodeProject } from \"./claude-code.js\";\nimport { loadCodexProject } from \"./codex.js\";\nimport { loadCursorProject } from \"./cursor.js\";\nimport type { ParsedInstructions, ToolType } from \"../types.js\";\n\nexport function loadProject(\n projectRoot: string,\n tool: ToolType,\n): ParsedInstructions {\n switch (tool) {\n case \"claude-code\":\n return loadClaudeCodeProject(projectRoot);\n case \"codex\":\n return loadCodexProject(projectRoot);\n case \"cursor\":\n return loadCursorProject(projectRoot);\n default:\n return loadClaudeCodeProject(projectRoot);\n }\n}\n","import type {\n BudgetSummary,\n FileTokenEntry,\n Finding,\n ParsedInstructions,\n TokenMethod,\n} from \"../types.js\";\n\nconst CONTEXT_WINDOW = 200_000;\nconst SYSTEM_PROMPT_TOKENS = 12_000;\nconst WARN_LINE_THRESHOLD = 200;\nconst CRITICAL_LINE_THRESHOLD = 400;\nconst WARN_BASELINE_PCT = 0.25; // 25% = 50K\nconst MCP_INFO_THRESHOLD = 10_000;\n\nfunction sumTokens(\n items: Array<{ tokenCount: number; tokenMethod: TokenMethod }>,\n): { tokens: number; method: TokenMethod } {\n if (items.length === 0) return { tokens: 0, method: \"measured\" };\n const tokens = items.reduce((acc, f) => acc + f.tokenCount, 0);\n const method: TokenMethod = items.every((f) => f.tokenMethod === \"measured\")\n ? \"measured\"\n : \"estimated\";\n return { tokens, method };\n}\n\nexport interface BudgetResult {\n findings: Finding[];\n summary: BudgetSummary;\n}\n\nexport function analyzeBudget(instructions: ParsedInstructions): BudgetResult {\n const findings: Finding[] = [];\n\n // ── Root file ────────────────────────────────────────────────────────────\n const rootFileTokens = instructions.rootFile.tokenCount;\n const rootFileMethod = instructions.rootFile.tokenMethod;\n const rootLines = instructions.rootFile.lineCount;\n\n if (rootLines > CRITICAL_LINE_THRESHOLD) {\n findings.push({\n severity: \"critical\",\n category: \"budget\",\n file: instructions.rootFile.path,\n messageKey: \"budget.rootFileCritical\",\n messageParams: { lines: String(rootLines) },\n suggestion: `Root instruction file is ${rootLines} lines — agent compliance drops significantly above 200 lines`,\n autoFixable: false,\n });\n } else if (rootLines > WARN_LINE_THRESHOLD) {\n findings.push({\n severity: \"warning\",\n category: \"budget\",\n file: instructions.rootFile.path,\n messageKey: \"budget.rootFileWarning\",\n messageParams: { lines: String(rootLines) },\n suggestion: `Root instruction file is ${rootLines} lines (recommended: < 200)`,\n autoFixable: false,\n });\n }\n\n // ── Rules ─────────────────────────────────────────────────────────────────\n const { tokens: rulesTokens, method: rulesMethod } = sumTokens(\n instructions.rules,\n );\n\n // ── Skills ────────────────────────────────────────────────────────────────\n const { tokens: skillsTokens, method: skillsMethod } = sumTokens(\n instructions.skills,\n );\n\n // ── Sub-files ─────────────────────────────────────────────────────────────\n const { tokens: subFilesTokens, method: subFilesMethod } = sumTokens(\n instructions.subFiles,\n );\n\n // ── MCP servers ───────────────────────────────────────────────────────────\n const mcpTokens = instructions.mcpServers.reduce(\n (acc, s) => acc + s.estimatedTokens,\n 0,\n );\n\n for (const server of instructions.mcpServers) {\n if (server.estimatedTokens > MCP_INFO_THRESHOLD) {\n findings.push({\n severity: \"info\",\n category: \"budget\",\n file: \".claude/settings.json\",\n messageKey: \"budget.mcpLargeServer\",\n messageParams: {\n name: server.name,\n tokens: server.estimatedTokens.toLocaleString(\"en\"),\n },\n suggestion: `MCP server '${server.name}' consumes ~${server.estimatedTokens.toLocaleString(\"en\")} tokens`,\n autoFixable: false,\n });\n }\n }\n\n // ── Totals ────────────────────────────────────────────────────────────────\n const totalBaseline =\n SYSTEM_PROMPT_TOKENS +\n rootFileTokens +\n rulesTokens +\n skillsTokens +\n subFilesTokens +\n mcpTokens;\n\n const availableTokens = CONTEXT_WINDOW - totalBaseline;\n\n const pct = totalBaseline / CONTEXT_WINDOW;\n if (pct > WARN_BASELINE_PCT) {\n findings.push({\n severity: \"warning\",\n category: \"budget\",\n file: instructions.rootFile.path,\n messageKey: \"budget.baselineHigh\",\n messageParams: { pct: Math.round(pct * 100).toString() },\n suggestion: `Baseline context consumption is ${Math.round(pct * 100)}% of window`,\n autoFixable: false,\n });\n }\n\n // Overall method: measured only if all file groups are measured\n const tokenMethod: TokenMethod = [\n rootFileMethod,\n rulesMethod,\n skillsMethod,\n subFilesMethod,\n ].every((m) => m === \"measured\")\n ? \"measured\"\n : \"estimated\";\n\n // File breakdown\n const fileBreakdown: FileTokenEntry[] = [\n {\n path: instructions.rootFile.path,\n tokenCount: rootFileTokens,\n tokenMethod: rootFileMethod,\n },\n ...instructions.rules.map((r) => ({\n path: r.path,\n tokenCount: r.tokenCount,\n tokenMethod: r.tokenMethod,\n })),\n ...instructions.skills.map((s) => ({\n path: s.path,\n tokenCount: s.tokenCount,\n tokenMethod: s.tokenMethod,\n })),\n ...instructions.subFiles.map((f) => ({\n path: f.path,\n tokenCount: f.tokenCount,\n tokenMethod: f.tokenMethod,\n })),\n ];\n\n const summary: BudgetSummary = {\n systemPromptTokens: SYSTEM_PROMPT_TOKENS,\n rootFileTokens,\n rootFileLines: rootLines,\n rootFileMethod,\n rulesTokens,\n rulesMethod,\n skillsTokens,\n skillsMethod,\n subFilesTokens,\n subFilesMethod,\n mcpTokens,\n totalBaseline,\n availableTokens,\n fileBreakdown,\n tokenMethod,\n };\n\n return { findings, summary };\n}\n","import { readFileSync, existsSync, readdirSync } from \"fs\";\nimport { join } from \"path\";\nimport type { Finding, ParsedInstructions, ParsedLine } from \"../types.js\";\n\n// ─── Config reading helpers ───────────────────────────────────────────────────\n\nfunction readJsonFile(projectRoot: string, filename: string): unknown | null {\n try {\n const content = readFileSync(join(projectRoot, filename), \"utf8\");\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nfunction readTextFile(projectRoot: string, filename: string): string | null {\n try {\n return readFileSync(join(projectRoot, filename), \"utf8\");\n } catch {\n return null;\n }\n}\n\nfunction checkEditorConfig(projectRoot: string, key: string): boolean {\n const content = readTextFile(projectRoot, \".editorconfig\");\n if (!content) return false;\n return new RegExp(`^${key}\\\\s*=\\\\s*.+`, \"m\").test(content);\n}\n\nfunction checkPrettierConfig(projectRoot: string, field: string): boolean {\n // Try .prettierrc and .prettierrc.json\n for (const filename of [\".prettierrc\", \".prettierrc.json\"]) {\n const parsed = readJsonFile(projectRoot, filename);\n if (parsed !== null && typeof parsed === \"object\" && parsed !== null) {\n if (field in (parsed as Record<string, unknown>)) return true;\n }\n }\n return false;\n}\n\nfunction getPrettierField(projectRoot: string, field: string): unknown {\n for (const filename of [\".prettierrc\", \".prettierrc.json\"]) {\n const parsed = readJsonFile(projectRoot, filename);\n if (parsed !== null && typeof parsed === \"object\") {\n const obj = parsed as Record<string, unknown>;\n if (field in obj) return obj[field];\n }\n }\n return undefined;\n}\n\n// ─── C# helpers ──────────────────────────────────────────────────────────────\n\nfunction readCsprojContent(projectRoot: string): string | null {\n // Directory.Build.props takes precedence (applies to all projects in tree)\n const buildProps = readTextFile(projectRoot, \"Directory.Build.props\");\n if (buildProps) return buildProps;\n try {\n const files = readdirSync(projectRoot);\n for (const f of files) {\n if (f.endsWith(\".csproj\") || f.endsWith(\".fsproj\")) {\n const content = readTextFile(projectRoot, f);\n if (content) return content;\n }\n }\n } catch {\n // directory not readable\n }\n return null;\n}\n\n/** Check if a .csproj / Directory.Build.props contains <Tag>value</Tag> (case-insensitive). */\nfunction checkCsprojProperty(\n projectRoot: string,\n tag: string,\n value: string,\n): boolean {\n const content = readCsprojContent(projectRoot);\n if (!content) return false;\n return new RegExp(`<${tag}>\\\\s*${value}\\\\s*</${tag}>`, \"i\").test(content);\n}\n\n/** Check if .editorconfig contains a line matching the given regex. */\nfunction checkEditorConfigPattern(\n projectRoot: string,\n pattern: RegExp,\n): boolean {\n const content = readTextFile(projectRoot, \".editorconfig\");\n if (!content) return false;\n return pattern.test(content);\n}\n\nfunction checkEslintRule(projectRoot: string, ruleName: string): boolean {\n const parsed = readJsonFile(projectRoot, \".eslintrc.json\");\n if (!parsed || typeof parsed !== \"object\") return false;\n const rules = (parsed as Record<string, unknown>)[\"rules\"];\n if (!rules || typeof rules !== \"object\") return false;\n const val = (rules as Record<string, unknown>)[ruleName];\n if (val === undefined) return false;\n if (val === \"off\" || val === 0) return false;\n if (Array.isArray(val) && (val[0] === \"off\" || val[0] === 0)) return false;\n return true;\n}\n\n// ─── Overlap patterns ─────────────────────────────────────────────────────────\n\ninterface OverlapPattern {\n id: string;\n rulePattern: RegExp;\n configCheck: (projectRoot: string) => boolean;\n configName: string;\n}\n\nconst PATTERNS: OverlapPattern[] = [\n {\n id: \"ts-strict\",\n rulePattern: /\\b(typescript|ts)\\b.*\\bstrict\\b|\\bstrict\\s*(mode|typing)/i,\n configCheck: (root) => {\n const tsconfig = readJsonFile(root, \"tsconfig.json\");\n if (!tsconfig || typeof tsconfig !== \"object\") return false;\n const opts = (tsconfig as Record<string, unknown>)[\"compilerOptions\"];\n if (!opts || typeof opts !== \"object\") return false;\n return (opts as Record<string, unknown>)[\"strict\"] === true;\n },\n configName: \"tsconfig.json (compilerOptions.strict: true)\",\n },\n {\n id: \"indent-spaces\",\n rulePattern: /\\b(2|two|4|four)\\s*(-?\\s*)space\\s*indent/i,\n configCheck: (root) =>\n checkEditorConfig(root, \"indent_size\") ||\n checkPrettierConfig(root, \"tabWidth\"),\n configName: \".editorconfig / .prettierrc (indentation)\",\n },\n {\n id: \"import-order\",\n rulePattern: /import\\s*(order|sort)|sort\\s*import/i,\n configCheck: (root) => {\n const pkg = readJsonFile(root, \"package.json\");\n if (!pkg || typeof pkg !== \"object\") return false;\n const devDeps = (pkg as Record<string, unknown>)[\"devDependencies\"];\n const hasPlugin =\n devDeps &&\n typeof devDeps === \"object\" &&\n \"eslint-plugin-import\" in devDeps;\n return hasPlugin === true && checkEslintRule(root, \"import/order\");\n },\n configName: \"eslint-plugin-import (import/order)\",\n },\n {\n id: \"conventional-commit\",\n rulePattern: /conventional\\s*commit/i,\n configCheck: (root) => {\n // Check commitlint key in package.json\n const pkg = readJsonFile(root, \"package.json\");\n if (pkg && typeof pkg === \"object\" && \"commitlint\" in (pkg as object))\n return true;\n // Check commitlint config files\n const configFiles = [\n \"commitlint.config.js\",\n \"commitlint.config.cjs\",\n \"commitlint.config.ts\",\n \".commitlintrc\",\n \".commitlintrc.json\",\n \".commitlintrc.yaml\",\n \".commitlintrc.yml\",\n ];\n return configFiles.some((f) => existsSync(join(root, f)));\n },\n configName: \"commitlint config\",\n },\n {\n id: \"semicolons\",\n rulePattern: /\\b(semicolons?|always\\s*use\\s*;|semi\\s*colon)/i,\n configCheck: (root) => checkPrettierConfig(root, \"semi\"),\n configName: \".prettierrc (semi)\",\n },\n {\n id: \"single-quote\",\n rulePattern: /single\\s*quotes?|prefer\\s*'|use\\s*'/i,\n configCheck: (root) => getPrettierField(root, \"singleQuote\") === true,\n configName: \".prettierrc (singleQuote: true)\",\n },\n {\n id: \"trailing-comma\",\n rulePattern: /trailing\\s*comma/i,\n configCheck: (root) => checkPrettierConfig(root, \"trailingComma\"),\n configName: \".prettierrc (trailingComma)\",\n },\n {\n id: \"max-line-length\",\n rulePattern:\n /\\b(max|maximum)\\s*(line\\s*)?(length|width|chars?)\\b|\\bprint\\s*width\\b/i,\n configCheck: (root) => checkPrettierConfig(root, \"printWidth\"),\n configName: \".prettierrc (printWidth)\",\n },\n {\n id: \"no-console\",\n rulePattern: /\\b(no|avoid|remove)\\b.*\\bconsole\\.(log|warn|error)/i,\n configCheck: (root) => checkEslintRule(root, \"no-console\"),\n configName: \"eslint (no-console)\",\n },\n {\n id: \"no-unused-vars\",\n rulePattern: /\\b(no|remove|avoid)\\s*(unused|dead)\\s*(var|variable|import)/i,\n configCheck: (root) => {\n const tsconfig = readJsonFile(root, \"tsconfig.json\");\n if (tsconfig && typeof tsconfig === \"object\") {\n const opts = (tsconfig as Record<string, unknown>)[\"compilerOptions\"];\n if (opts && typeof opts === \"object\") {\n const o = opts as Record<string, unknown>;\n if (o[\"noUnusedLocals\"] === true || o[\"noUnusedParameters\"] === true)\n return true;\n }\n }\n return (\n checkEslintRule(root, \"no-unused-vars\") ||\n checkEslintRule(root, \"@typescript-eslint/no-unused-vars\")\n );\n },\n configName: \"tsconfig / eslint (no-unused-vars)\",\n },\n {\n id: \"test-framework\",\n rulePattern: /\\b(use|prefer)\\s*(jest|vitest|mocha|jasmine)\\b/i,\n configCheck: (root) => {\n const configs = [\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"jest.config.ts\",\n \"jest.config.js\",\n \"jest.config.cjs\",\n \".mocharc.js\",\n \".mocharc.json\",\n \".mocharc.yaml\",\n ];\n if (configs.some((f) => existsSync(join(root, f)))) return true;\n const pkg = readJsonFile(root, \"package.json\");\n if (!pkg || typeof pkg !== \"object\") return false;\n const devDeps = (pkg as Record<string, unknown>)[\"devDependencies\"] ?? {};\n return [\"jest\", \"vitest\", \"mocha\", \"jasmine\"].some(\n (fw) => typeof devDeps === \"object\" && fw in (devDeps as object),\n );\n },\n configName: \"test framework config file\",\n },\n {\n id: \"formatter\",\n rulePattern: /\\b(format|prettier|biome)\\s*(code|files|on\\s*save)/i,\n configCheck: (root) => {\n const prettierFiles = [\n \".prettierrc\",\n \".prettierrc.json\",\n \".prettierrc.yaml\",\n \".prettierrc.yml\",\n ];\n if (prettierFiles.some((f) => existsSync(join(root, f)))) return true;\n return existsSync(join(root, \"biome.json\"));\n },\n configName: \"prettier / biome config file\",\n },\n {\n id: \"end-of-line\",\n rulePattern: /\\b(line\\s*ending|eol|crlf|lf)\\b/i,\n configCheck: (root) =>\n checkEditorConfig(root, \"end_of_line\") ||\n checkPrettierConfig(root, \"endOfLine\"),\n configName: \".editorconfig / .prettierrc (endOfLine)\",\n },\n {\n id: \"tab-width\",\n rulePattern: /\\btab\\s*(width|size)\\b/i,\n configCheck: (root) =>\n checkEditorConfig(root, \"tab_width\") ||\n checkEditorConfig(root, \"indent_size\") ||\n checkPrettierConfig(root, \"tabWidth\"),\n configName: \".editorconfig / .prettierrc (tabWidth)\",\n },\n {\n id: \"no-default-export\",\n rulePattern: /\\b(no|avoid|prefer\\s*named)\\s*(default\\s*export)/i,\n configCheck: (root) =>\n checkEslintRule(root, \"import/no-default-export\") ||\n checkEslintRule(root, \"no-restricted-exports\"),\n configName: \"eslint-plugin-import (no-default-export)\",\n },\n\n // ─── C# patterns ─────────────────────────────────────────────────────────\n\n {\n id: \"csharp-nullable\",\n rulePattern:\n /\\b(nullable\\s*reference\\s*type|#nullable\\s*enable|enable\\s*nullable|null\\s*reference\\s*exception)\\b/i,\n configCheck: (root) =>\n checkCsprojProperty(root, \"Nullable\", \"enable\") ||\n checkCsprojProperty(root, \"Nullable\", \"annotations\") ||\n checkCsprojProperty(root, \"Nullable\", \"warnings\"),\n configName: \".csproj (<Nullable>enable</Nullable>)\",\n },\n {\n id: \"csharp-implicit-usings\",\n rulePattern: /\\b(global\\s*usings?|implicit\\s*usings?)\\b/i,\n configCheck: (root) =>\n checkCsprojProperty(root, \"ImplicitUsings\", \"enable\"),\n configName: \".csproj (<ImplicitUsings>enable</ImplicitUsings>)\",\n },\n {\n id: \"csharp-test-framework\",\n rulePattern: /\\b(xunit|nunit|mstest|microsoft\\.testing\\.framework)\\b/i,\n configCheck: (root) => {\n const content = readCsprojContent(root);\n if (!content) return false;\n return /PackageReference\\s+Include=\"(xunit|NUnit|MSTest|Microsoft\\.Testing)/i.test(\n content,\n );\n },\n configName: \".csproj (PackageReference xUnit / NUnit / MSTest)\",\n },\n {\n id: \"csharp-formatter\",\n rulePattern: /\\bdotnet\\s*format\\b/i,\n configCheck: (root) =>\n checkEditorConfigPattern(root, /^\\[.*\\.cs\\]/m) &&\n checkEditorConfigPattern(root, /^csharp_/m),\n configName: \".editorconfig ([*.cs] csharp_style_* settings)\",\n },\n {\n id: \"csharp-naming\",\n rulePattern:\n /\\bdotnet_naming\\b|PascalCase\\s+for\\s+(all\\s+)?(public|class|method|property|type)\\b/i,\n configCheck: (root) =>\n checkEditorConfigPattern(root, /^dotnet_naming_rule\\./m),\n configName: \".editorconfig (dotnet_naming_rule.*)\",\n },\n {\n id: \"csharp-unused\",\n rulePattern:\n /\\b(IDE0059|CS0168|CS0219|dead\\s*code|unused.*IDE|roslyn.*unused)\\b/i,\n configCheck: (root) =>\n checkEditorConfigPattern(\n root,\n /^dotnet_diagnostic\\.(IDE0059|CS0168|CS0219)/m,\n ),\n configName: \".editorconfig (dotnet_diagnostic.IDE0059 / CS0168)\",\n },\n];\n\n// ─── Detector ─────────────────────────────────────────────────────────────────\n\nfunction collectRuleLines(\n instructions: ParsedInstructions,\n): Array<{ line: ParsedLine; file: string }> {\n const result: Array<{ line: ParsedLine; file: string }> = [];\n for (const l of instructions.rootFile.lines) {\n if (l.type === \"rule\")\n result.push({ line: l, file: instructions.rootFile.path });\n }\n for (const sub of instructions.subFiles) {\n for (const l of sub.lines) {\n if (l.type === \"rule\") result.push({ line: l, file: sub.path });\n }\n }\n for (const rule of instructions.rules) {\n for (const l of rule.lines) {\n if (l.type === \"rule\") result.push({ line: l, file: rule.path });\n }\n }\n return result;\n}\n\nexport function detectConfigOverlaps(\n instructions: ParsedInstructions,\n projectRoot: string,\n): Finding[] {\n const findings: Finding[] = [];\n const ruleLines = collectRuleLines(instructions);\n\n for (const { line, file } of ruleLines) {\n for (const pattern of PATTERNS) {\n if (\n pattern.rulePattern.test(line.text) &&\n pattern.configCheck(projectRoot)\n ) {\n const ruleText = line.text.trim();\n const short =\n ruleText.length > 60 ? ruleText.slice(0, 60) + \"…\" : ruleText;\n findings.push({\n severity: \"warning\",\n category: \"dead-rule\",\n file,\n line: line.lineNumber,\n messageKey: \"deadRule.configOverlap\",\n messageParams: {\n rule: ruleText.slice(0, 80),\n config: pattern.configName,\n },\n suggestion: `Rule \"${short}\" is already enforced by ${pattern.configName}`,\n autoFixable: true,\n });\n break; // one pattern match per line is enough\n }\n }\n }\n\n return findings;\n}\n","const STOP_WORDS = new Set([\n // English grammatical function words\n \"the\",\n \"a\",\n \"an\",\n \"is\",\n \"are\",\n \"to\",\n \"for\",\n \"and\",\n \"or\",\n \"in\",\n \"of\",\n \"with\",\n \"that\",\n \"this\",\n // Chinese filler bigrams (grammatical / no topic content)\n \"的時\",\n \"時候\",\n \"一個\",\n \"所有\",\n \"每個\",\n]);\n\n// Matches a contiguous run of CJK Unified Ideographs (BMP + Extension A)\nconst CJK_RUN = /[\\u4e00-\\u9fff\\u3400-\\u4dbf]+/g;\nconst ASCII_WORD = /[a-z0-9]+/g;\n\nexport function tokenizeWords(text: string): string[] {\n const words: string[] = [];\n const lower = text.toLowerCase();\n\n // English alphanumeric tokens — same behaviour as before (length > 1)\n for (const m of lower.matchAll(ASCII_WORD)) {\n if (m[0].length > 1) words.push(m[0]);\n }\n\n // CJK char-bigrams: slide a 2-char window over each contiguous CJK run.\n // Single-char runs are skipped (analogous to the length > 1 filter for ASCII).\n for (const m of text.matchAll(CJK_RUN)) {\n const run = m[0];\n if (run.length < 2) continue;\n for (let i = 0; i < run.length - 1; i++) {\n words.push(run.slice(i, i + 2));\n }\n }\n\n return words;\n}\n\nexport function removeStopWords(words: string[]): string[] {\n return words.filter((w) => !STOP_WORDS.has(w));\n}\n\nexport function jaccardSimilarity(setA: string[], setB: string[]): number {\n if (setA.length === 0 && setB.length === 0) return 0;\n const a = new Set(setA);\n const b = new Set(setB);\n let intersection = 0;\n for (const word of a) {\n if (b.has(word)) intersection++;\n }\n const union = new Set([...a, ...b]).size;\n return union === 0 ? 0 : intersection / union;\n}\n","import type { Finding, ParsedInstructions, ParsedLine } from '../types.js';\nimport { jaccardSimilarity, removeStopWords, tokenizeWords } from '../utils/text.js';\n\nconst SIMILARITY_THRESHOLD = 0.7;\nconst MIN_WORDS_AFTER_STOP = 4;\n\ninterface RuleLine {\n line: ParsedLine;\n file: string;\n words: string[];\n}\n\nfunction collectRuleLines(instructions: ParsedInstructions): RuleLine[] {\n const result: RuleLine[] = [];\n\n const add = (lines: ParsedLine[], file: string) => {\n for (const l of lines) {\n if (l.type !== 'rule') continue;\n const words = removeStopWords(tokenizeWords(l.text));\n if (words.length < MIN_WORDS_AFTER_STOP) continue;\n result.push({ line: l, file, words });\n }\n };\n\n add(instructions.rootFile.lines, instructions.rootFile.path);\n for (const sub of instructions.subFiles) add(sub.lines, sub.path);\n for (const rule of instructions.rules) add(rule.lines, rule.path);\n\n return result;\n}\n\nexport function detectDuplicates(instructions: ParsedInstructions): Finding[] {\n const findings: Finding[] = [];\n const ruleLines = collectRuleLines(instructions);\n const reported = new Set<string>();\n\n for (let i = 0; i < ruleLines.length; i++) {\n for (let j = i + 1; j < ruleLines.length; j++) {\n const a = ruleLines[i]!;\n const b = ruleLines[j]!;\n const pairKey = `${a.file}:${a.line.lineNumber}|${b.file}:${b.line.lineNumber}`;\n if (reported.has(pairKey)) continue;\n\n const sim = jaccardSimilarity(a.words, b.words);\n if (sim < SIMILARITY_THRESHOLD) continue;\n\n reported.add(pairKey);\n\n const isExact = sim >= 1.0;\n const simPct = `${Math.round(sim * 100)}`;\n\n findings.push({\n severity: isExact ? 'warning' : 'info',\n category: 'duplicate',\n file: b.file,\n line: b.line.lineNumber,\n messageKey: isExact ? 'deadRule.exactDuplicate' : 'deadRule.nearDuplicate',\n messageParams: {\n otherFile: a.file,\n otherLine: String(a.line.lineNumber),\n similarity: simPct,\n },\n suggestion: isExact\n ? `Exact duplicate of line ${a.line.lineNumber} in ${a.file}`\n : `Very similar to line ${a.line.lineNumber} in ${a.file} (${simPct}% similar)`,\n autoFixable: isExact,\n });\n }\n }\n\n return findings;\n}\n","import { detectConfigOverlaps } from '../detectors/config-overlap.js';\nimport { detectDuplicates } from '../detectors/duplicate.js';\nimport type { Finding, ParsedInstructions } from '../types.js';\n\nexport interface DeadRulesResult {\n findings: Finding[];\n}\n\nexport function analyzeDeadRules(\n instructions: ParsedInstructions,\n projectRoot: string,\n): DeadRulesResult {\n return {\n findings: [\n ...detectConfigOverlaps(instructions, projectRoot),\n ...detectDuplicates(instructions),\n ],\n };\n}\n","import { removeStopWords, tokenizeWords } from \"../utils/text.js\";\nimport type {\n Finding,\n InstructionFile,\n ParsedInstructions,\n ParsedLine,\n} from \"../types.js\";\n\n// ─── Negation detection ────────────────────────────────────────────────────────\n\nconst NEGATION_WORDS = [\"never\", \"don't\", \"avoid\", \"forbid\"];\n\n// CJK negation words that negate the whole clause they appear in\nconst CJK_NEGATIONS = [\"禁止\", \"不要\", \"不可\", \"不得\", \"避免\", \"請勿\", \"勿\"];\n\n// Matches CJK-only strings (no ASCII)\nconst CJK_ONLY_RE = /^[\\u4e00-\\u9fff\\u3400-\\u4dbf]+$/;\n\n/**\n * Returns true if `word` is negated within a single sentence of `text`.\n * Checks each sentence independently to avoid cross-sentence false positives.\n *\n * Possessive forms (\"not Claude's …\") are excluded: when the word immediately\n * follows \"not\" but is itself in possessive form, the negation targets the\n * whole noun phrase, not the word itself.\n */\nfunction isNegated(text: string, word: string): boolean {\n // Split into sentences — supports both English (.!?) and Chinese (。!?) punctuation\n const sentences = text.split(/[.!?。!?]+\\s*/);\n const escapedWord = word.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const wordPresent = new RegExp(`\\\\b${escapedWord}\\\\b`, \"i\");\n\n for (const sentence of sentences) {\n if (!wordPresent.test(sentence)) continue;\n const lower = sentence.toLowerCase();\n\n for (const neg of NEGATION_WORDS) {\n // Window of 1: negation must be within 1 intervening word of the target.\n // Exclude possessive: \"never Claude's X\" negates the NP, not \"Claude\".\n const pattern = new RegExp(\n `\\\\b${neg}\\\\b(?:\\\\s+\\\\w+){0,1}\\\\s+\\\\b${escapedWord}\\\\b(?!['\\\\u2019]s\\\\b)`,\n \"i\",\n );\n if (pattern.test(lower)) return true;\n }\n\n // \"do not\" / \"not\" before word (within 1 token), same possessive exclusion\n const notPattern = new RegExp(\n `\\\\b(?:do\\\\s+)?not\\\\b(?:\\\\s+\\\\w+){0,1}\\\\s+\\\\b${escapedWord}\\\\b(?!['\\\\u2019]s\\\\b)`,\n \"i\",\n );\n if (notPattern.test(lower)) return true;\n }\n\n // CJK path: whole-sentence negation.\n // Chinese imperatives (禁止/不要/…) typically appear sentence-initially and\n // negate the entire clause — no word-boundary or window needed.\n if (CJK_ONLY_RE.test(word)) {\n for (const sentence of sentences) {\n if (!sentence.includes(word)) continue;\n for (const neg of CJK_NEGATIONS) {\n if (sentence.includes(neg)) return true;\n }\n }\n }\n\n return false;\n}\n\n// ─── Helpers ───────────────────────────────────────────────────────────────────\n\n/**\n * Extra stop words specific to contradiction detection.\n * These are polarity markers and generic imperatives/modals that appear across\n * many rule lines and would generate false-positive shared-word matches.\n */\nconst POLARITY_STOP_WORDS = new Set([\n // Polarity / negation markers (meta-level, not domain content)\n \"never\",\n \"always\",\n \"avoid\",\n \"not\",\n // Generic imperative verbs (describe HOW to comply, not WHAT topic)\n \"use\",\n \"ensure\",\n \"require\",\n \"prefer\",\n \"follow\",\n \"keep\",\n \"calls\",\n \"run\",\n \"runs\",\n // Common modals and auxiliaries\n \"must\",\n \"should\",\n \"can\",\n \"will\",\n \"may\",\n // Generic quantifiers\n \"all\",\n \"every\",\n \"each\",\n \"any\",\n // Pronouns and copulas — appear in any sentence regardless of topic;\n // their negation carries no semantic domain information\n \"it\",\n \"its\",\n \"be\",\n \"by\",\n \"own\",\n \"on\",\n // Chinese polarity / imperative bigrams (analogues of English never/always/use/must)\n \"永遠\",\n \"總是\",\n \"禁止\",\n \"不要\",\n \"不可\",\n \"不得\",\n \"避免\",\n \"請勿\",\n \"必須\",\n \"應該\",\n \"應當\",\n // Chinese generic verb bigrams (HOW to comply, not WHAT topic)\n \"使用\",\n \"採用\",\n \"執行\",\n \"進行\",\n \"可以\",\n \"需要\",\n]);\n\ninterface AnnotatedLine {\n line: ParsedLine;\n words: string[];\n file: string;\n}\n\nfunction collectRuleLines(instructions: ParsedInstructions): AnnotatedLine[] {\n const sources: InstructionFile[] = [\n instructions.rootFile,\n ...instructions.subFiles,\n ...instructions.rules,\n ];\n\n const annotated: AnnotatedLine[] = [];\n for (const file of sources) {\n for (const line of file.lines) {\n if (line.type !== \"rule\") continue;\n const words = removeStopWords(tokenizeWords(line.text)).filter(\n (w) => !POLARITY_STOP_WORDS.has(w),\n );\n if (words.length < 3) continue;\n annotated.push({ line, words, file: file.path });\n }\n }\n return annotated;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport function detectContradictions(\n instructions: ParsedInstructions,\n): Finding[] {\n const lines = collectRuleLines(instructions);\n const findings: Finding[] = [];\n const reportedPairs = new Set<string>();\n\n for (let i = 0; i < lines.length; i++) {\n for (let j = i + 1; j < lines.length; j++) {\n const a = lines[i]!;\n const b = lines[j]!;\n\n // Find unique shared content words (Set-based to avoid duplicate counting)\n const setA = new Set(a.words);\n const setB = new Set(b.words);\n const shared = [...setB].filter((w) => setA.has(w));\n\n if (shared.length < 3) continue;\n\n // Check if any shared word has opposite polarity in the two lines\n const hasContradiction = shared.some(\n (word) => isNegated(a.line.text, word) !== isNegated(b.line.text, word),\n );\n\n if (!hasContradiction) continue;\n\n const pairKey = `${a.file}:${a.line.lineNumber}|${b.file}:${b.line.lineNumber}`;\n if (reportedPairs.has(pairKey)) continue;\n reportedPairs.add(pairKey);\n\n const snippet =\n a.line.text.length > 60\n ? `${a.line.text.slice(0, 60)}...`\n : a.line.text;\n\n findings.push({\n severity: \"critical\",\n category: \"contradiction\",\n file: b.file,\n line: b.line.lineNumber,\n messageKey: \"structure.contradiction\",\n messageParams: {\n snippet,\n lineA: String(a.line.lineNumber),\n lineB: String(b.line.lineNumber),\n fileA: a.file,\n },\n suggestion: `Contradicting rules: \"${snippet}\" (${a.file} line ${a.line.lineNumber}) conflicts with line ${b.line.lineNumber}.`,\n autoFixable: false,\n });\n }\n }\n\n return findings;\n}\n","import { existsSync } from 'fs';\nimport { join } from 'path';\nimport type { Finding, InstructionFile, ParsedInstructions, ParsedLine } from '../types.js';\n\n// ─── Helpers ───────────────────────────────────────────────────────────────────\n\ninterface AnnotatedLine {\n line: ParsedLine;\n file: string;\n}\n\nfunction collectLines(instructions: ParsedInstructions): AnnotatedLine[] {\n const sources: InstructionFile[] = [\n instructions.rootFile,\n ...instructions.subFiles,\n ...instructions.rules,\n ];\n\n const result: AnnotatedLine[] = [];\n for (const file of sources) {\n for (const line of file.lines) {\n if (line.type === 'blank' || line.type === 'code') continue;\n if (line.referencedPaths.length === 0) continue;\n result.push({ line, file: file.path });\n }\n }\n return result;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport function detectStaleRefs(\n instructions: ParsedInstructions,\n projectRoot: string,\n): Finding[] {\n const findings: Finding[] = [];\n\n for (const { line, file } of collectLines(instructions)) {\n for (const refPath of line.referencedPaths) {\n // Skip directory refs (trailing slash) and glob patterns\n if (refPath.endsWith('/') || refPath.includes('*')) continue;\n\n const absolutePath = join(projectRoot, refPath);\n if (!existsSync(absolutePath)) {\n findings.push({\n severity: 'warning',\n category: 'stale-ref',\n file,\n line: line.lineNumber,\n messageKey: 'structure.staleRef',\n messageParams: { path: refPath },\n suggestion: `Stale reference: \"${refPath}\" does not exist.`,\n autoFixable: true,\n });\n }\n }\n }\n\n return findings;\n}\n","import type { Finding, ParsedInstructions } from \"../types.js\";\n\n// ─── Patterns ─────────────────────────────────────────────────────────────────\n\n/** Rule references a specific source directory → suggest a path-scoped rule file */\nconst PATH_REF_PATTERN = /\\b(?:src|tests?|lib|dist)\\//i;\n\n/** Rule forbids a git workflow action → suggest a git hook instead */\nconst HOOK_PATTERN =\n /\\b(?:never|don't|do\\s+not|forbid)\\b(?:\\s+\\w+){0,3}\\s+\\b(?:commit|push|merge|rebase|tag|checkout|amend)\\b/i;\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport function classifyScope(instructions: ParsedInstructions): Finding[] {\n const findings: Finding[] = [];\n const rootFile = instructions.rootFile;\n\n for (const line of rootFile.lines) {\n if (line.type !== \"rule\") continue;\n\n if (HOOK_PATTERN.test(line.text)) {\n const snippet =\n line.text.length > 60 ? `${line.text.slice(0, 60)}...` : line.text;\n findings.push({\n severity: \"info\",\n category: \"structure\",\n file: rootFile.path,\n line: line.lineNumber,\n messageKey: \"structure.scopeHook\",\n messageParams: { line: String(line.lineNumber), snippet },\n suggestion: `Rule at line ${line.lineNumber} could be a git hook: \"${snippet}\"`,\n autoFixable: false,\n });\n // Don't also emit path-scoped suggestion for the same line\n continue;\n }\n\n if (PATH_REF_PATTERN.test(line.text)) {\n const snippet =\n line.text.length > 60 ? `${line.text.slice(0, 60)}...` : line.text;\n findings.push({\n severity: \"info\",\n category: \"structure\",\n file: rootFile.path,\n line: line.lineNumber,\n messageKey: \"structure.scopePathScoped\",\n messageParams: { line: String(line.lineNumber), snippet },\n suggestion: `Rule at line ${line.lineNumber} references a specific path — consider a path-scoped rule file: \"${snippet}\"`,\n autoFixable: false,\n });\n }\n }\n\n return findings;\n}\n","import { detectContradictions } from '../detectors/contradiction.js';\nimport { detectStaleRefs } from '../detectors/stale-refs.js';\nimport { classifyScope } from '../detectors/scope-classifier.js';\nimport type { Finding, ParsedInstructions } from '../types.js';\n\nexport interface StructureResult {\n findings: Finding[];\n}\n\nexport function analyzeStructure(\n instructions: ParsedInstructions,\n projectRoot: string,\n): StructureResult {\n return {\n findings: [\n ...detectContradictions(instructions),\n ...detectStaleRefs(instructions, projectRoot),\n ...classifyScope(instructions),\n ],\n };\n}\n","import type { ActionItem, BudgetSummary, Finding } from \"../types.js\";\n\nexport type Grade = \"A\" | \"B\" | \"C\" | \"D\" | \"F\";\n\nconst CONTEXT_WINDOW = 200_000;\n\n// ─── Scoring weights ───────────────────────────────────────────────────────────\n\nconst CRITICAL_DEDUCTION = 10;\nconst WARNING_DEDUCTION = 5;\nconst INFO_DEDUCTION = 1;\n\nconst MAX_CRITICAL_DEDUCTION = 40;\nconst MAX_WARNING_DEDUCTION = 30;\nconst MAX_INFO_DEDUCTION = 10;\nconst MAX_ROOT_FILE_PENALTY = 30;\nconst MAX_BUDGET_DEDUCTION = 30;\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport function gradeFromScore(score: number): Grade {\n if (score >= 90) return \"A\";\n if (score >= 80) return \"B\";\n if (score >= 70) return \"C\";\n if (score >= 60) return \"D\";\n return \"F\";\n}\n\nexport function calculateScore(\n findings: Finding[],\n budget: BudgetSummary,\n): { score: number; grade: Grade } {\n const criticals = findings.filter((f) => f.severity === \"critical\").length;\n const warnings = findings.filter((f) => f.severity === \"warning\").length;\n const infos = findings.filter((f) => f.severity === \"info\").length;\n\n const criticalDeduction = Math.min(\n criticals * CRITICAL_DEDUCTION,\n MAX_CRITICAL_DEDUCTION,\n );\n const warningDeduction = Math.min(\n warnings * WARNING_DEDUCTION,\n MAX_WARNING_DEDUCTION,\n );\n const infoDeduction = Math.min(infos * INFO_DEDUCTION, MAX_INFO_DEDUCTION);\n\n // Root file length penalty — proportional beyond each threshold\n // 201-300: -5, 301-400: -8, 401-500: -10, 501-600: -15, 601-700: -20, ...\n const rootLines = budget.rootFileLines;\n let rootFilePenalty = 0;\n if (rootLines > 400) {\n rootFilePenalty = 10 + Math.floor((rootLines - 400) / 100) * 5;\n } else if (rootLines > 200) {\n rootFilePenalty = 5 + Math.floor((rootLines - 200) / 100) * 3;\n }\n rootFilePenalty = Math.min(rootFilePenalty, MAX_ROOT_FILE_PENALTY);\n\n // Budget penalty — continuous beyond 25% of context window\n // 25%: -5, 50%: -15, 75%: -25, capped at 30\n const baselinePct = budget.totalBaseline / CONTEXT_WINDOW;\n let budgetDeduction = 0;\n if (baselinePct > 0.25) {\n budgetDeduction = 5 + Math.floor((baselinePct - 0.25) * 40);\n }\n budgetDeduction = Math.min(budgetDeduction, MAX_BUDGET_DEDUCTION);\n\n const score = Math.max(\n 0,\n 100 -\n criticalDeduction -\n warningDeduction -\n infoDeduction -\n rootFilePenalty -\n budgetDeduction,\n );\n return { score, grade: gradeFromScore(score) };\n}\n\nexport function buildActionPlan(findings: Finding[]): ActionItem[] {\n const priorityOf = (f: Finding): number => {\n if (f.severity === \"critical\") return 1;\n if (f.severity === \"warning\") return 2;\n return 3;\n };\n\n const seen = new Set<string>();\n return findings\n .filter((f) => {\n if (seen.has(f.suggestion)) return false;\n seen.add(f.suggestion);\n return true;\n })\n .map((f) => ({\n priority: priorityOf(f),\n description: f.suggestion,\n category: f.category,\n }))\n .sort((a, b) => a.priority - b.priority);\n}\n","import chalk from \"chalk\";\nimport type { BudgetSummary, Finding, HealthReport } from \"../types.js\";\nimport { bar } from \"../commands/budget-command.js\";\nimport { t, plural, getLocale } from \"../i18n/index.js\";\n\n// ─── Visual helpers ───────────────────────────────────────────────────────────\n\nconst BOX_W = 50;\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\n\nfunction visLen(s: string): number {\n return s.replace(ANSI_RE, \"\").length;\n}\n\nfunction padR(s: string, w: number): string {\n return s + \" \".repeat(Math.max(0, w - visLen(s)));\n}\n\nfunction gradeColor(grade: string): (s: string) => string {\n if (grade === \"A\") return chalk.green;\n if (grade === \"B\") return chalk.cyan;\n if (grade === \"C\") return chalk.yellow;\n if (grade === \"D\") return chalk.magenta;\n return chalk.red;\n}\n\nfunction gradeBadge(grade: string): string {\n // Light backgrounds (A/B/C) need dark text; dark backgrounds (D/F) need white text\n if (grade === \"A\") return chalk.bgGreen(chalk.bold.black(` ${grade} `));\n if (grade === \"B\") return chalk.bgCyan(chalk.bold.black(` ${grade} `));\n if (grade === \"C\") return chalk.bgYellow(chalk.bold.black(` ${grade} `));\n if (grade === \"D\") return chalk.bgMagenta(chalk.bold.white(` ${grade} `));\n return chalk.bgRed(chalk.bold.white(` ${grade} `));\n}\n\nfunction scoreBar(score: number, grade: string, width = 30): string {\n const filled = Math.round((score / 100) * width);\n const empty = width - filled;\n return gradeColor(grade)(\"█\".repeat(filled)) + chalk.gray(\"░\".repeat(empty));\n}\n\nfunction sectionHeader(title: string, width = BOX_W): string {\n const inner = ` ${title} `;\n const remaining = Math.max(0, width - 2 - inner.length);\n return chalk.gray(` ──${chalk.bold.white(inner)}${\"─\".repeat(remaining)}──`);\n}\n\n// ─── Compact helpers ───────────────────────────────────────────────────────────\n\nfunction printCompactBudget(\n summary: BudgetSummary,\n output: { log: typeof console.log },\n): void {\n const total = summary.totalBaseline;\n const window = total + summary.availableTokens;\n const fraction = total / window;\n const fmt = new Intl.NumberFormat(getLocale());\n const usedPrefix = summary.tokenMethod === \"estimated\" ? \"~\" : \"\";\n const budgetLine = t(\"compact.budgetLine\", {\n used: `${usedPrefix}${fmt.format(total)}`,\n window: fmt.format(window),\n pct: String(Math.round(fraction * 100)),\n });\n output.log(` ${chalk.yellow(budgetLine)} ${bar(fraction, 14)}`);\n}\n\nconst SEVERITY_ORDER: Record<string, number> = {\n critical: 0,\n warning: 1,\n info: 2,\n};\n\nfunction printFindingsTable(\n findings: Finding[],\n output: { log: typeof console.log },\n): void {\n const categories: Array<{ key: string; label: string }> = [\n { key: \"contradiction\", label: t(\"compact.contradictions\") },\n { key: \"budget\", label: t(\"compact.budget\") },\n { key: \"dead-rule\", label: t(\"compact.deadRules\") },\n { key: \"duplicate\", label: t(\"compact.duplicates\") },\n { key: \"stale-ref\", label: t(\"compact.staleRefs\") },\n { key: \"structure\", label: t(\"compact.structure\") },\n ];\n\n const rows = categories\n .map(({ key, label }) => {\n const group = findings.filter((f) => f.category === key);\n return {\n label,\n critical: group.filter((f) => f.severity === \"critical\").length,\n warning: group.filter((f) => f.severity === \"warning\").length,\n info: group.filter((f) => f.severity === \"info\").length,\n };\n })\n .filter((r) => r.critical + r.warning + r.info > 0);\n\n if (rows.length === 0) return;\n\n output.log(sectionHeader(t(\"label.findings\")));\n for (const row of rows) {\n const parts: string[] = [];\n if (row.critical > 0) parts.push(chalk.red(`✖ ${row.critical}`));\n if (row.warning > 0) parts.push(chalk.yellow(`⚠ ${row.warning}`));\n if (row.info > 0) parts.push(chalk.blue(`ℹ ${row.info}`));\n output.log(\n ` ${chalk.whiteBright(row.label.padEnd(18))}${parts.join(\" \")}`,\n );\n }\n}\n\nfunction printTopIssues(\n findings: Finding[],\n output: { log: typeof console.log },\n): void {\n if (findings.length === 0) return;\n\n const sorted = [...findings].sort(\n (a, b) =>\n (SEVERITY_ORDER[a.severity] ?? 3) - (SEVERITY_ORDER[b.severity] ?? 3),\n );\n const top = sorted.slice(0, 5);\n\n output.log(\"\");\n output.log(sectionHeader(t(\"label.topIssues\")));\n for (let i = 0; i < top.length; i++) {\n const f = top[i]!;\n const icon =\n f.severity === \"critical\"\n ? chalk.red(\"✖\")\n : f.severity === \"warning\"\n ? chalk.yellow(\"⚠\")\n : chalk.blue(\"ℹ\");\n const msg = t(f.messageKey, f.messageParams);\n const truncated = msg.length > 68 ? `${msg.slice(0, 68)}…` : msg;\n const verifyBadge =\n f.verification?.verdict === \"confirmed\"\n ? chalk.green(` ✓ ${t(\"verification.confirmed\")}`)\n : f.verification?.verdict === \"uncertain\"\n ? chalk.yellow(` ❓ ${t(\"verification.uncertain\")}`)\n : \"\";\n output.log(\n ` ${chalk.white(`${i + 1}.`)} ${icon} ${truncated}${verifyBadge}`,\n );\n }\n if (sorted.length > 5) {\n output.log(\n chalk.white(\n ` ${t(\"compact.andMore\", { count: String(sorted.length - 5) })}`,\n ),\n );\n }\n}\n\n// ─── Terminal reporter ─────────────────────────────────────────────────────────\n\nexport function printCombinedTerminal(\n report: HealthReport,\n output: { log: typeof console.log } = console,\n): void {\n const { project, tool, score, grade, tokenMethod } = report;\n const border = \"─\".repeat(BOX_W);\n\n // ─── Header box ─────────────────────────────────────────────────────────────\n output.log(\"\");\n const B = chalk.green; // box border colour — use consistently\n output.log(B(` ╭${border}╮`));\n const line1 = ` ${chalk.bold.white(\"instrlint\")} ${B(\"─\")} ${chalk.cyan(project)}`;\n output.log(` ${B(\"│\")}${padR(line1, BOX_W)}${B(\"│\")}`);\n const line2 = ` ${chalk.white(tool)} ${B(\"·\")} ${chalk.white(tokenMethod)}`;\n output.log(` ${B(\"│\")}${padR(line2, BOX_W)}${B(\"│\")}`);\n output.log(B(` ├${border}┤`));\n const scoreLine = ` ${scoreBar(score, grade)} ${chalk.bold.white(String(score))}/100 ${gradeBadge(grade)}`;\n output.log(` ${B(\"│\")}${padR(scoreLine, BOX_W)}${B(\"│\")}`);\n output.log(B(` ╰${border}╯`));\n\n // ─── Budget ─────────────────────────────────────────────────────────────────\n output.log(\"\");\n output.log(sectionHeader(t(\"label.budget\")));\n printCompactBudget(report.budget, output);\n\n // ─── Findings ───────────────────────────────────────────────────────────────\n if (report.findings.length > 0) {\n output.log(\"\");\n printFindingsTable(report.findings, output);\n printTopIssues(report.findings, output);\n }\n\n // ─── Footer ─────────────────────────────────────────────────────────────────\n output.log(\"\");\n if (report.findings.length === 0) {\n output.log(chalk.green(` ${t(\"status.perfectScore\")}`));\n } else {\n const criticals = report.findings.filter(\n (f) => f.severity === \"critical\",\n ).length;\n const warnings = report.findings.filter(\n (f) => f.severity === \"warning\",\n ).length;\n const infos = report.findings.filter((f) => f.severity === \"info\").length;\n const parts: string[] = [];\n if (criticals > 0)\n parts.push(\n chalk.red(t(\"severity.critical\", { count: String(criticals) })),\n );\n if (warnings > 0)\n parts.push(\n chalk.yellow(\n t(\"severity.warnings\", {\n count: String(warnings),\n s: plural(warnings),\n }),\n ),\n );\n if (infos > 0)\n parts.push(\n chalk.blue(\n t(\"severity.suggestions\", { count: String(infos), s: plural(infos) }),\n ),\n );\n const summary = parts.join(chalk.gray(\" · \"));\n const summaryVisible = summary.replace(ANSI_RE, \"\");\n const pad = Math.max(0, BOX_W - 2 - summaryVisible.length);\n output.log(\n chalk.gray(` ──`) + ` ${summary} ` + chalk.gray(\"─\".repeat(pad)),\n );\n }\n if (report.rejectedByVerification) {\n output.log(\n chalk.gray(\n ` ${t(\"verification.filteredCount\", { count: String(report.rejectedByVerification), s: plural(report.rejectedByVerification) })}`,\n ),\n );\n }\n output.log(\"\");\n}\n\n// ─── JSON reporter ─────────────────────────────────────────────────────────────\n\nexport function reportJson(report: HealthReport): string {\n return JSON.stringify(report, null, 2);\n}\n\n// ─── Markdown reporter ─────────────────────────────────────────────────────────\n\nfunction mdSeverityIcon(f: Finding): string {\n if (f.severity === \"critical\") return \"🔴\";\n if (f.severity === \"warning\") return \"🟡\";\n return \"ℹ️\";\n}\n\nfunction mdBar(fraction: number, width = 20): string {\n const filled = Math.round(Math.min(1, Math.max(0, fraction)) * width);\n const empty = width - filled;\n return \"`\" + \"█\".repeat(filled) + \"░\".repeat(empty) + \"`\";\n}\n\nfunction mdFormatTokens(\n count: number,\n method: \"measured\" | \"estimated\",\n): string {\n const fmt = new Intl.NumberFormat(getLocale());\n return method === \"estimated\" ? `~${fmt.format(count)}` : fmt.format(count);\n}\n\nexport function reportMarkdown(\n report: HealthReport,\n extraSections: string[] = [],\n): string {\n const { project, tool, score, grade, findings, budget } = report;\n const criticals = findings.filter((f) => f.severity === \"critical\").length;\n const warnings = findings.filter((f) => f.severity === \"warning\").length;\n const infos = findings.filter((f) => f.severity === \"info\").length;\n const gradeEmoji =\n grade === \"A\"\n ? \"🟢\"\n : grade === \"B\"\n ? \"🔵\"\n : grade === \"C\"\n ? \"🟡\"\n : grade === \"D\"\n ? \"🟠\"\n : \"🔴\";\n\n const lines: string[] = [\n `# ${t(\"markdown.title\", { project })}`,\n \"\",\n `${gradeEmoji} **${score}/100 (${grade})** ${mdBar(score / 100, 25)} · \\`${tool}\\``,\n \"\",\n t(\"markdown.summary\"),\n \"\",\n `| ${t(\"markdown.severity\")} | ${t(\"markdown.count\")} |`,\n \"|----------|-------|\",\n `| ${t(\"markdown.critical\")} | ${criticals} |`,\n `| ${t(\"markdown.warning\")} | ${warnings} |`,\n `| ${t(\"markdown.info\")} | ${infos} |`,\n ...(report.rejectedByVerification\n ? [\n `| ${t(\"verification.filteredCount\", { count: String(report.rejectedByVerification), s: plural(report.rejectedByVerification) })} | |`,\n ]\n : []),\n \"\",\n ];\n\n // ── Budget breakdown ─────────────────────────────────────────────────────\n const window = budget.totalBaseline + budget.availableTokens;\n const budgetRows: Array<{\n labelKey: string;\n tokens: number;\n method: \"measured\" | \"estimated\";\n }> = [\n {\n labelKey: \"label.systemPrompt\",\n tokens: budget.systemPromptTokens,\n method: \"estimated\" as const,\n },\n {\n labelKey: \"label.rootFile\",\n tokens: budget.rootFileTokens,\n method: budget.rootFileMethod,\n },\n {\n labelKey: \"label.ruleFiles\",\n tokens: budget.rulesTokens,\n method: budget.rulesMethod,\n },\n {\n labelKey: \"label.skillFiles\",\n tokens: budget.skillsTokens,\n method: budget.skillsMethod,\n },\n {\n labelKey: \"label.subDirFiles\",\n tokens: budget.subFilesTokens,\n method: budget.subFilesMethod,\n },\n {\n labelKey: \"label.mcpServers\",\n tokens: budget.mcpTokens,\n method: \"estimated\" as const,\n },\n ].filter((r) => r.tokens > 0);\n\n lines.push(`## ${t(\"label.tokenBudget\")}`, \"\");\n lines.push(\n `| ${t(\"markdown.budgetCategory\")} | ${t(\"markdown.budgetTokens\")} | % | |`,\n \"|------|--------|---|---|\",\n );\n for (const row of budgetRows) {\n const pctVal = Math.round((row.tokens / window) * 100);\n lines.push(\n `| ${t(row.labelKey)} | ${mdFormatTokens(row.tokens, row.method)} | ${pctVal}% | ${mdBar(row.tokens / window, 12)} |`,\n );\n }\n const baselinePct = Math.round((budget.totalBaseline / window) * 100);\n lines.push(\n `| **${t(\"label.baselineTotal\")}** | **${mdFormatTokens(budget.totalBaseline, budget.tokenMethod)}** | **${baselinePct}%** | ${mdBar(budget.totalBaseline / window, 12)} |`,\n );\n lines.push(\n `| ${t(\"label.available\")} | ${mdFormatTokens(budget.availableTokens, \"estimated\")} | ${100 - baselinePct}% | |`,\n );\n lines.push(\"\");\n\n // Findings grouped by category\n const categories: Array<{\n labelKey: string;\n filter: (f: Finding) => boolean;\n }> = [\n {\n labelKey: \"markdown.contradictions\",\n filter: (f) => f.category === \"contradiction\",\n },\n {\n labelKey: \"markdown.staleReferences\",\n filter: (f) => f.category === \"stale-ref\",\n },\n {\n labelKey: \"markdown.deadRules\",\n filter: (f) => f.category === \"dead-rule\",\n },\n {\n labelKey: \"markdown.duplicateRules\",\n filter: (f) => f.category === \"duplicate\",\n },\n {\n labelKey: \"markdown.budgetIssues\",\n filter: (f) => f.category === \"budget\",\n },\n {\n labelKey: \"markdown.refactoringOpportunities\",\n filter: (f) => f.category === \"structure\",\n },\n ];\n\n for (const { labelKey, filter } of categories) {\n const group = findings.filter(filter);\n if (group.length === 0) continue;\n lines.push(`## ${t(labelKey)}`, \"\");\n for (const f of group) {\n const loc =\n f.line != null\n ? ` ${t(\"markdown.lineRef\", { line: String(f.line) })}`\n : \"\";\n const verifyBadge =\n f.verification?.verdict === \"confirmed\"\n ? ` ✓ *${t(\"verification.confirmed\")}*: ${f.verification.reason}`\n : f.verification?.verdict === \"uncertain\"\n ? ` ❓ *${t(\"verification.uncertain\")}*: ${f.verification.reason}`\n : \"\";\n lines.push(\n `- ${mdSeverityIcon(f)} ${t(f.messageKey, f.messageParams)}${loc}${verifyBadge}`,\n );\n }\n lines.push(\"\");\n }\n\n // Action plan\n if (report.actionPlan.length > 0) {\n lines.push(t(\"markdown.actionPlan\"), \"\");\n for (let i = 0; i < Math.min(report.actionPlan.length, 10); i++) {\n const item = report.actionPlan[i]!;\n lines.push(`${i + 1}. ${item.description}`);\n }\n lines.push(\"\");\n }\n\n // Extra sections (e.g. actionable structure suggestions)\n if (extraSections.length > 0) {\n lines.push(...extraSections);\n }\n\n lines.push(\"---\", t(\"markdown.attribution\"));\n return lines.join(\"\\n\");\n}\n","import chalk from \"chalk\";\nimport { scanProject } from \"../core/scanner.js\";\nimport { loadProject } from \"../adapters/dispatch.js\";\nimport { ensureInitialized } from \"../detectors/token-estimator.js\";\nimport { analyzeBudget } from \"../analyzers/budget.js\";\nimport { t, plural, initLocale, getLocale } from \"../i18n/index.js\";\nimport type { BudgetSummary, Finding, TokenMethod } from \"../types.js\";\n\n// ─── Formatting helpers ────────────────────────────────────────────────────\n\nfunction getFmt(): Intl.NumberFormat {\n return new Intl.NumberFormat(getLocale());\n}\n\nexport function formatTokens(count: number, method: TokenMethod): string {\n const formatted = getFmt().format(count);\n if (method === \"measured\") return t(\"tokens.measured\", { count: formatted });\n return t(\"tokens.estimated\", { count: formatted });\n}\n\nexport function bar(fraction: number, width = 24): string {\n const filled = Math.round(Math.min(1, Math.max(0, fraction)) * width);\n const empty = width - filled;\n return chalk.cyan(\"█\".repeat(filled)) + chalk.gray(\"░\".repeat(empty));\n}\n\nexport function pct(fraction: number): string {\n return `${Math.round(fraction * 100)}%`;\n}\n\n// ─── Budget terminal output ────────────────────────────────────────────────\n\nexport function printBudgetTerminal(\n summary: BudgetSummary,\n findings: Finding[],\n output: { log: typeof console.log } = console,\n): void {\n const total = summary.totalBaseline;\n const window = total + summary.availableTokens;\n\n output.log(\"\");\n output.log(chalk.bold.white(` ${t(\"label.tokenBudget\")}`));\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n const rows: Array<{ labelKey: string; tokens: number; method: TokenMethod }> =\n [\n {\n labelKey: \"label.systemPrompt\",\n tokens: summary.systemPromptTokens,\n method: \"estimated\",\n },\n {\n labelKey: \"label.rootFile\",\n tokens: summary.rootFileTokens,\n method: summary.rootFileMethod,\n },\n {\n labelKey: \"label.ruleFiles\",\n tokens: summary.rulesTokens,\n method: summary.rulesMethod,\n },\n {\n labelKey: \"label.skillFiles\",\n tokens: summary.skillsTokens,\n method: summary.skillsMethod,\n },\n {\n labelKey: \"label.subDirFiles\",\n tokens: summary.subFilesTokens,\n method: summary.subFilesMethod,\n },\n {\n labelKey: \"label.mcpServers\",\n tokens: summary.mcpTokens,\n method: \"estimated\",\n },\n ];\n\n for (const row of rows) {\n if (row.tokens === 0) continue;\n const fraction = row.tokens / window;\n const label = t(row.labelKey).padEnd(14);\n const tokenStr = formatTokens(row.tokens, row.method).padStart(28);\n output.log(\n ` ${chalk.white(label)} ${bar(fraction)} ${chalk.yellow(tokenStr)}`,\n );\n }\n\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n const baselineFraction = total / window;\n const baselineStr = formatTokens(total, summary.tokenMethod).padStart(28);\n output.log(\n ` ${t(\"label.baselineTotal\").padEnd(14)} ${bar(baselineFraction)} ${chalk.bold.yellow(baselineStr)} ${chalk.gray(pct(baselineFraction))}`,\n );\n\n const availStr = formatTokens(summary.availableTokens, \"estimated\").padStart(\n 28,\n );\n output.log(\n ` ${t(\"label.available\").padEnd(14)} ${\"\".padEnd(26)} ${chalk.green(availStr)}`,\n );\n output.log(\"\");\n\n if (findings.length === 0) {\n output.log(chalk.green(` ${t(\"status.noBudgetIssues\")}`));\n } else {\n for (const f of findings) {\n const icon =\n f.severity === \"critical\"\n ? chalk.red(\" ✖\")\n : f.severity === \"warning\"\n ? chalk.yellow(\" ⚠\")\n : chalk.blue(\" ℹ\");\n output.log(`${icon} ${t(f.messageKey, f.messageParams)}`);\n }\n }\n output.log(\"\");\n}\n\n// ─── Core run logic (testable) ─────────────────────────────────────────────\n\nexport interface BudgetCommandOpts {\n format: string;\n tool?: string;\n lang?: string;\n projectRoot?: string;\n}\n\nexport interface BudgetCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\nexport async function runBudget(\n opts: BudgetCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): Promise<BudgetCommandResult> {\n initLocale(opts.lang);\n await ensureInitialized();\n\n const projectRoot = opts.projectRoot ?? process.cwd();\n const scan = scanProject(projectRoot, opts.tool);\n\n if (scan.tool === \"unknown\") {\n output.error(t(\"error.unknownTool\"));\n return { exitCode: 1, errorMessage: \"unknown tool\" };\n }\n\n if (scan.rootFilePath === null) {\n output.error(t(\"error.missingRootFile\", { tool: scan.tool }));\n return { exitCode: 1, errorMessage: \"missing root file\" };\n }\n\n const instructions = loadProject(projectRoot, scan.tool);\n const { findings, summary } = analyzeBudget(instructions);\n\n if (opts.format === \"json\") {\n output.log(JSON.stringify({ findings, summary }, null, 2));\n return { exitCode: 0 };\n }\n\n printBudgetTerminal(summary, findings, output);\n return { exitCode: 0 };\n}\n","{\n \"label.tokenBudget\": \"TOKEN BUDGET\",\n \"label.deadRules\": \"DEAD RULES\",\n \"label.structure\": \"STRUCTURE\",\n \"label.actionPlan\": \"ACTION PLAN\",\n \"label.fixSummary\": \"FIX SUMMARY\",\n \"label.systemPrompt\": \"System prompt\",\n \"label.rootFile\": \"Root file\",\n \"label.ruleFiles\": \"Rule files\",\n \"label.skillFiles\": \"Skill files\",\n \"label.subDirFiles\": \"Sub-dir files\",\n \"label.mcpServers\": \"MCP servers\",\n \"label.baselineTotal\": \"Baseline total\",\n \"label.available\": \"Available\",\n \"label.redundantByConfig\": \"Redundant (enforced by config)\",\n \"label.duplicates\": \"Duplicates\",\n \"label.contradictions\": \"Contradictions\",\n \"label.staleReferences\": \"Stale References\",\n \"label.refactoringOpportunities\": \"Refactoring Opportunities\",\n \"label.tool\": \"Tool:\",\n \"label.score\": \"Score:\",\n\n \"status.noBudgetIssues\": \"✓ No budget issues found\",\n \"status.noDeadRules\": \"✓ No dead rules found\",\n \"status.noStructuralIssues\": \"✓ No structural issues found\",\n \"status.noAutoFixable\": \"✓ No auto-fixable issues found\",\n \"status.perfectScore\": \"✓ Perfect score — no issues found\",\n \"status.fixedIssues\": \"✓ Fixed {{count}} issue{{s}} — run `git diff` to review changes\",\n\n \"error.unknownTool\": \"No agent instruction files found. Run this command in a project that uses Claude Code, Codex, or Cursor.\",\n \"error.missingRootFile\": \"Found {{tool}} configuration but no root instruction file.\",\n \"error.dirtyWorkingTree\": \"Working tree is dirty. Commit or stash your changes before running --fix, or use --force to skip this check.\",\n\n \"fix.removedDeadRules\": \"Removed {{count}} redundant rule{{s}}\",\n \"fix.removedStaleRefs\": \"Removed {{count}} stale reference{{s}}\",\n \"fix.removedDuplicates\": \"Removed {{count}} exact duplicate{{s}}\",\n\n \"summary.redundantRules\": \"{{count}} redundant rule{{s}}\",\n \"summary.duplicates\": \"{{count}} duplicate{{s}}\",\n \"summary.contradictions\": \"{{count}} contradiction{{s}}\",\n \"summary.staleRefs\": \"{{count}} stale ref{{s}}\",\n \"summary.refactoringSuggestions\": \"{{count}} refactoring suggestion{{s}}\",\n \"summary.found\": \"{{parts}} found\",\n\n \"tokens.measured\": \"{{count}} tokens\",\n \"tokens.estimated\": \"~{{count}} tokens (estimated)\",\n\n \"actionPlan.andMore\": \"… and {{count}} more\",\n\n \"severity.critical\": \"{{count}} critical\",\n \"severity.warnings\": \"{{count}} warning{{s}}\",\n \"severity.suggestions\": \"{{count}} suggestion{{s}}\",\n\n \"budget.rootFileCritical\": \"Root instruction file is {{lines}} lines — agent compliance drops significantly above 200 lines\",\n \"budget.rootFileWarning\": \"Root instruction file is {{lines}} lines (recommended: < 200)\",\n \"budget.mcpLargeServer\": \"MCP server '{{name}}' consumes ~{{tokens}} tokens\",\n \"budget.baselineHigh\": \"Baseline context consumption is {{pct}}% of window\",\n\n \"deadRule.configOverlap\": \"Rule \\\"{{rule}}\\\" is already enforced by {{config}}\",\n \"deadRule.exactDuplicate\": \"Exact duplicate of line {{otherLine}} in {{otherFile}}\",\n \"deadRule.nearDuplicate\": \"Very similar to line {{otherLine}} in {{otherFile}} ({{similarity}}% similar)\",\n\n \"structure.contradiction\": \"Contradicting rules: \\\"{{snippet}}\\\" ({{fileA}} line {{lineA}}) conflicts with line {{lineB}}.\",\n \"structure.staleRef\": \"Stale reference: \\\"{{path}}\\\" does not exist.\",\n \"structure.scopeHook\": \"Rule at line {{line}} could be a git hook: \\\"{{snippet}}\\\"\",\n \"structure.scopePathScoped\": \"Rule at line {{line}} references a specific path — consider a path-scoped rule file: \\\"{{snippet}}\\\"\",\n\n \"label.budget\": \"BUDGET\",\n \"label.findings\": \"FINDINGS\",\n \"label.topIssues\": \"TOP ISSUES\",\n \"label.category\": \"Category\",\n\n \"compact.budgetLine\": \"{{used}} / {{window}} tokens ({{pct}}%)\",\n \"compact.andMore\": \"… and {{count}} more (run instrlint <command> for details)\",\n \"compact.budget\": \"Budget\",\n \"compact.deadRules\": \"Dead rules\",\n \"compact.duplicates\": \"Duplicates\",\n \"compact.contradictions\": \"Contradictions\",\n \"compact.staleRefs\": \"Stale refs\",\n \"compact.structure\": \"Structure\",\n\n \"markdown.title\": \"instrlint Health Report — {{project}}\",\n \"markdown.scoreLine\": \"**Score: {{score}}/100 ({{grade}})** · Tool: `{{tool}}`\",\n \"markdown.summary\": \"## Summary\",\n \"markdown.severity\": \"Severity\",\n \"markdown.count\": \"Count\",\n \"markdown.critical\": \"🔴 Critical\",\n \"markdown.warning\": \"🟡 Warning\",\n \"markdown.info\": \"ℹ️ Info\",\n \"markdown.contradictions\": \"Contradictions\",\n \"markdown.staleReferences\": \"Stale References\",\n \"markdown.deadRules\": \"Dead Rules\",\n \"markdown.duplicateRules\": \"Duplicates\",\n \"markdown.budgetIssues\": \"Budget Issues\",\n \"markdown.refactoringOpportunities\": \"Refactoring Opportunities\",\n \"markdown.lineRef\": \"(line {{line}})\",\n \"markdown.budgetCategory\": \"Category\",\n \"markdown.budgetTokens\": \"Tokens\",\n \"markdown.actionPlan\": \"## Action Plan\",\n \"markdown.attribution\": \"*Generated by [instrlint](https://github.com/jed1978/instrlint)*\",\n\n \"ci.passed\": \"✓ instrlint passed score={{score}} grade={{grade}}\",\n \"ci.failed\": \"✖ instrlint failed score={{score}} grade={{grade}}\",\n \"ci.writtenTo\": \"→ written to {{file}}\",\n\n \"initCi.created\": \"✓ Created {{path}}\",\n \"initCi.alreadyExists\": \"{{path}} already exists. Use --force to overwrite.\",\n\n \"install.installed\": \"✓ Installed to {{path}}\\n → Restart Claude Code to activate /instrlint\",\n \"install.alreadyExists\": \"{{path}} already exists. Use --force to overwrite.\",\n \"install.unknownTarget\": \"Specify --claude-code or --codex\",\n \"install.outdatedTitle\": \"instrlint skill is outdated\",\n \"install.outdatedVersions\": \"installed: {{installed}} → current: {{current}}\",\n \"install.updateCmd\": \"npx instrlint install {{flag}} --force\",\n \"install.updatePrompt\": \"Update skill now?\",\n\n \"verification.confirmed\": \"LLM confirmed\",\n \"verification.uncertain\": \"LLM uncertain\",\n \"verification.filteredCount\": \"⊘ {{count}} false positive{{s}} filtered by LLM\",\n\n \"fix.manualActions\": \"MANUAL ACTIONS NEEDED\",\n \"fix.hookCreate\": \"Add to .claude/settings.json:\",\n \"fix.hookWarning\": \"⚠ Hook executes shell commands — review carefully before adding\",\n \"fix.pathScopedCreate\": \"Create {{path}}:\",\n \"fix.thenRemoveLine\": \"Then remove line {{line}} from {{file}}\"\n}\n","{\n \"label.tokenBudget\": \"TOKEN 預算\",\n \"label.deadRules\": \"冗餘規則\",\n \"label.structure\": \"結構分析\",\n \"label.actionPlan\": \"行動計畫\",\n \"label.fixSummary\": \"修復摘要\",\n \"label.systemPrompt\": \"系統提示\",\n \"label.rootFile\": \"根指令檔\",\n \"label.ruleFiles\": \"規則檔\",\n \"label.skillFiles\": \"技能檔\",\n \"label.subDirFiles\": \"子目錄檔\",\n \"label.mcpServers\": \"MCP 伺服器\",\n \"label.baselineTotal\": \"初始總量\",\n \"label.available\": \"可用\",\n \"label.redundantByConfig\": \"冗餘(已由配置強制執行)\",\n \"label.duplicates\": \"重複項目\",\n \"label.contradictions\": \"規則矛盾\",\n \"label.staleReferences\": \"過時參照\",\n \"label.refactoringOpportunities\": \"重構建議\",\n \"label.tool\": \"工具:\",\n \"label.score\": \"分數:\",\n\n \"status.noBudgetIssues\": \"✓ 無 Token 預算問題\",\n \"status.noDeadRules\": \"✓ 無冗餘規則\",\n \"status.noStructuralIssues\": \"✓ 無結構性問題\",\n \"status.noAutoFixable\": \"✓ 無可自動修復的問題\",\n \"status.perfectScore\": \"✓ 滿分 — 無任何問題\",\n \"status.fixedIssues\": \"✓ 已修復 {{count}} 個問題 — 執行 `git diff` 查看變更\",\n\n \"error.unknownTool\": \"找不到代理指令檔。請在使用 Claude Code、Codex 或 Cursor 的專案中執行此指令。\",\n \"error.missingRootFile\": \"找到 {{tool}} 配置,但找不到根指令檔。\",\n \"error.dirtyWorkingTree\": \"工作目錄有未提交的變更。請先提交或儲藏變更再執行 --fix,或使用 --force 跳過此檢查。\",\n\n \"fix.removedDeadRules\": \"已移除 {{count}} 個冗餘規則\",\n \"fix.removedStaleRefs\": \"已移除 {{count}} 個過時參照\",\n \"fix.removedDuplicates\": \"已移除 {{count}} 個重複項目\",\n\n \"summary.redundantRules\": \"{{count}} 個冗餘規則\",\n \"summary.duplicates\": \"{{count}} 個重複項目\",\n \"summary.contradictions\": \"{{count}} 個規則矛盾\",\n \"summary.staleRefs\": \"{{count}} 個過時參照\",\n \"summary.refactoringSuggestions\": \"{{count}} 個重構建議\",\n \"summary.found\": \"發現 {{parts}}\",\n\n \"tokens.measured\": \"{{count}} tokens\",\n \"tokens.estimated\": \"~{{count}} tokens(估計值)\",\n\n \"actionPlan.andMore\": \"… 還有 {{count}} 個\",\n\n \"severity.critical\": \"{{count}} 個嚴重問題\",\n \"severity.warnings\": \"{{count}} 個警告\",\n \"severity.suggestions\": \"{{count}} 個建議\",\n\n \"budget.rootFileCritical\": \"根指令檔有 {{lines}} 行 — 超過 200 行後代理遵循率顯著下降\",\n \"budget.rootFileWarning\": \"根指令檔有 {{lines}} 行(建議:< 200 行)\",\n \"budget.mcpLargeServer\": \"MCP 伺服器「{{name}}」消耗約 {{tokens}} tokens\",\n \"budget.baselineHigh\": \"基線情境消耗佔視窗 {{pct}}%\",\n\n \"deadRule.configOverlap\": \"規則「{{rule}}」已由 {{config}} 強制執行\",\n \"deadRule.exactDuplicate\": \"與 {{otherFile}} 第 {{otherLine}} 行完全重複\",\n \"deadRule.nearDuplicate\": \"與 {{otherFile}} 第 {{otherLine}} 行高度相似({{similarity}}% 相似度)\",\n\n \"structure.contradiction\": \"規則矛盾:「{{snippet}}」({{fileA}} 第 {{lineA}} 行)與第 {{lineB}} 行衝突。\",\n \"structure.staleRef\": \"過時參照:「{{path}}」不存在。\",\n \"structure.scopeHook\": \"第 {{line}} 行的規則適合做成 git hook:「{{snippet}}」\",\n \"structure.scopePathScoped\": \"第 {{line}} 行的規則參照了特定路徑 — 建議建立路徑範圍的規則檔:「{{snippet}}」\",\n\n \"label.budget\": \"預算\",\n \"label.findings\": \"問題總覽\",\n \"label.topIssues\": \"首要問題\",\n \"label.category\": \"Category\",\n\n \"compact.budgetLine\": \"{{used}} / {{window}} tokens ({{pct}}%)\",\n \"compact.andMore\": \"… 還有 {{count}} 個(執行 instrlint <command> 查看詳情)\",\n \"compact.budget\": \"Budget\",\n \"compact.deadRules\": \"Dead rules\",\n \"compact.duplicates\": \"Duplicates\",\n \"compact.contradictions\": \"Contradictions\",\n \"compact.staleRefs\": \"Stale refs\",\n \"compact.structure\": \"Structure\",\n\n \"markdown.title\": \"instrlint 健康報告 — {{project}}\",\n \"markdown.scoreLine\": \"**分數:{{score}}/100 ({{grade}})** · 工具:`{{tool}}`\",\n \"markdown.summary\": \"## 摘要\",\n \"markdown.severity\": \"嚴重程度\",\n \"markdown.count\": \"數量\",\n \"markdown.critical\": \"🔴 嚴重\",\n \"markdown.warning\": \"🟡 警告\",\n \"markdown.info\": \"ℹ️ 資訊\",\n \"markdown.contradictions\": \"規則矛盾\",\n \"markdown.staleReferences\": \"過時參照\",\n \"markdown.deadRules\": \"冗餘規則\",\n \"markdown.duplicateRules\": \"重複項目\",\n \"markdown.budgetIssues\": \"Token 預算問題\",\n \"markdown.refactoringOpportunities\": \"重構建議\",\n \"markdown.lineRef\": \"(第 {{line}} 行)\",\n \"markdown.budgetCategory\": \"類別\",\n \"markdown.budgetTokens\": \"Token 數\",\n \"markdown.actionPlan\": \"## 行動計畫\",\n \"markdown.attribution\": \"*由 [instrlint](https://github.com/jed1978/instrlint) 生成*\",\n\n \"ci.passed\": \"✓ instrlint 通過 分數={{score}} 等級={{grade}}\",\n \"ci.failed\": \"✖ instrlint 未通過 分數={{score}} 等級={{grade}}\",\n \"ci.writtenTo\": \"→ 已寫入 {{file}}\",\n\n \"initCi.created\": \"✓ 已建立 {{path}}\",\n \"initCi.alreadyExists\": \"{{path}} 已存在。使用 --force 覆蓋。\",\n\n \"install.installed\": \"✓ 已安裝至 {{path}}\\n → 重新啟動 Claude Code 後即可使用 /instrlint\",\n \"install.alreadyExists\": \"{{path}} 已存在。使用 --force 覆蓋。\",\n \"install.unknownTarget\": \"請指定 --claude-code 或 --codex\",\n \"install.outdatedTitle\": \"instrlint skill 版本過舊\",\n \"install.outdatedVersions\": \"已安裝:{{installed}} → 最新:{{current}}\",\n \"install.updateCmd\": \"npx instrlint install {{flag}} --force\",\n \"install.updatePrompt\": \"是否立即更新?\",\n\n \"verification.confirmed\": \"LLM 已確認\",\n \"verification.uncertain\": \"LLM 不確定\",\n \"verification.filteredCount\": \"⊘ 已過濾 {{count}} 個{{s}} false positive(由 LLM 判斷)\",\n\n \"fix.manualActions\": \"需要手動操作\",\n \"fix.hookCreate\": \"加入 .claude/settings.json:\",\n \"fix.hookWarning\": \"⚠ Hook 會執行 shell command,請仔細確認後再加入\",\n \"fix.pathScopedCreate\": \"建立 {{path}}:\",\n \"fix.thenRemoveLine\": \"搬移後請從 {{file}} 第 {{line}} 行刪除原規則\"\n}\n","import enMessages from \"./en.json\";\nimport zhTWMessages from \"./zh-TW.json\";\n\ntype Locale = \"en\" | \"zh-TW\";\n\nconst LOCALE_MAP: Record<Locale, Record<string, string>> = {\n en: enMessages as Record<string, string>,\n \"zh-TW\": zhTWMessages as Record<string, string>,\n};\n\nlet _locale: Locale = \"en\";\nlet _messages: Record<string, string> = LOCALE_MAP[\"en\"];\n\n/** Detect locale from environment / system, falling back to 'en'. */\nexport function detectLocale(): Locale {\n const env = process.env[\"INSTRLINT_LANG\"];\n if (env === \"zh-TW\" || env === \"en\") return env;\n try {\n const sys = Intl.DateTimeFormat().resolvedOptions().locale;\n // Any zh-* locale (zh-CN, zh-HK, etc.) maps to zh-TW — it's the only CJK locale we support\n if (sys.startsWith(\"zh\")) return \"zh-TW\";\n } catch {\n // ignore\n }\n return \"en\";\n}\n\n/**\n * Set the active locale. Call once at CLI startup with the --lang value.\n * Falls back to detectLocale() if lang is unrecognised or omitted.\n */\nexport function initLocale(lang?: string): void {\n const valid: Locale[] = [\"en\", \"zh-TW\"];\n const resolved: Locale = valid.includes(lang as Locale)\n ? (lang as Locale)\n : detectLocale();\n _locale = resolved;\n _messages = LOCALE_MAP[resolved];\n}\n\n/** Return current active locale. */\nexport function getLocale(): Locale {\n return _locale;\n}\n\n/**\n * Look up a translation key and interpolate {{param}} placeholders.\n * Returns the key itself when no translation is found.\n */\nexport function t(key: string, params?: Record<string, string>): string {\n const template = _messages[key] ?? key;\n if (!params) return template;\n return template.replace(\n /\\{\\{(\\w+)\\}\\}/g,\n (_, k: string) => params[k] ?? `{{${k}}}`,\n );\n}\n\n/** Plural suffix helper: returns 's' for count !== 1, '' otherwise. */\nexport function plural(count: number): string {\n return count === 1 ? \"\" : \"s\";\n}\n","import { readFileSync, writeFileSync } from 'fs';\nimport type { Finding, FindingCategory } from '../types.js';\n\n/**\n * Removes lines from files based on findings of the specified categories.\n * Only removes lines where `autoFixable === true` and `line` is set.\n * Processes removals from bottom to top within each file to avoid line-offset shifts.\n *\n * @returns total number of lines removed across all files\n */\nexport function removeLines(findings: Finding[], categories: FindingCategory[]): number {\n const catSet = new Set<FindingCategory>(categories);\n const fixable = findings.filter(\n (f) => catSet.has(f.category) && f.autoFixable && f.line != null,\n );\n\n // Group by file path\n const byFile = new Map<string, number[]>();\n for (const f of fixable) {\n const arr = byFile.get(f.file) ?? [];\n arr.push(f.line!);\n byFile.set(f.file, arr);\n }\n\n let totalFixed = 0;\n\n for (const [filePath, lineNumbers] of byFile) {\n // Deduplicate and sort descending so we remove from the bottom up\n const uniqueSorted = [...new Set(lineNumbers)].sort((a, b) => b - a);\n\n const content = readFileSync(filePath, 'utf8');\n // Preserve trailing newline behaviour: if file ends with \\n, the last element after split is ''\n const lines = content.split('\\n');\n\n for (const lineNum of uniqueSorted) {\n const idx = lineNum - 1; // convert 1-based to 0-indexed\n if (idx >= 0 && idx < lines.length) {\n lines.splice(idx, 1);\n }\n }\n\n writeFileSync(filePath, lines.join('\\n'));\n totalFixed += uniqueSorted.length;\n }\n\n return totalFixed;\n}\n","import { removeLines } from './line-remover.js';\nimport type { Finding } from '../types.js';\n\n/**\n * Removes rules that are provably redundant — already enforced by project config.\n * Only removes lines flagged as `category: 'dead-rule'` and `autoFixable: true`.\n *\n * @returns number of lines removed\n */\nexport function removeDeadRules(findings: Finding[]): number {\n return removeLines(findings, ['dead-rule']);\n}\n","import { removeLines } from './line-remover.js';\nimport type { Finding } from '../types.js';\n\n/**\n * Removes lines that contain references to non-existent files.\n * Only removes lines flagged as `category: 'stale-ref'` and `autoFixable: true`.\n *\n * @returns number of lines removed\n */\nexport function removeStaleRefs(findings: Finding[]): number {\n return removeLines(findings, ['stale-ref']);\n}\n","import { removeLines } from './line-remover.js';\nimport type { Finding } from '../types.js';\n\n/**\n * Removes exact duplicate rule lines (keeps the first occurrence, removes later ones).\n * Only removes lines flagged as `category: 'duplicate'` and `autoFixable: true`.\n * Near-duplicates (autoFixable: false) are left untouched.\n *\n * @returns number of lines removed\n */\nexport function deduplicateRules(findings: Finding[]): number {\n return removeLines(findings, ['duplicate']);\n}\n","import { readFileSync } from \"fs\";\nimport { relative } from \"path\";\nimport chalk from \"chalk\";\nimport { t } from \"../i18n/index.js\";\nimport type { Finding } from \"../types.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface StructureSuggestion {\n finding: Finding;\n /** Full rule text from the source file (falls back to snippet) */\n ruleText: string;\n type: \"hook\" | \"path-scoped\";\n /** For path-scoped: the extracted directory name (e.g. 'src') */\n pathDir?: string;\n}\n\n// ─── File helpers ─────────────────────────────────────────────────────────────\n\nfunction readFileLine(filePath: string, lineNumber: number): string {\n try {\n const content = readFileSync(filePath, \"utf8\");\n return content.split(\"\\n\")[lineNumber - 1]?.trim() ?? \"\";\n } catch {\n return \"\";\n }\n}\n\n// ─── Path extraction ──────────────────────────────────────────────────────────\n\nconst PATH_DIR_RE = /\\b(src|tests?|lib|dist)\\//i;\n\nfunction extractPathDir(text: string): string | undefined {\n const m = PATH_DIR_RE.exec(text);\n return m?.[1]?.toLowerCase();\n}\n\n// ─── Code generators ──────────────────────────────────────────────────────────\n\nexport function buildHookSnippet(ruleText: string): string {\n const comment =\n ruleText.length > 80 ? `${ruleText.slice(0, 80)}…` : ruleText;\n return JSON.stringify(\n {\n hooks: {\n PreToolUse: [\n {\n matcher: \"Bash\",\n hooks: [\n {\n type: \"command\",\n command: `# TODO: implement enforcement of:\\n# ${comment}`,\n },\n ],\n },\n ],\n },\n },\n null,\n 2,\n );\n}\n\nexport function buildPathScopedFile(\n pathDir: string,\n ruleText: string,\n): { filePath: string; content: string } {\n const filePath = `.claude/rules/${pathDir}.md`;\n const content = `---\\nglobs:\\n - \"${pathDir}/**\"\\n---\\n\\n${ruleText}\\n`;\n return { filePath, content };\n}\n\n// ─── Builder ──────────────────────────────────────────────────────────────────\n\nexport function buildStructureSuggestions(\n findings: Finding[],\n): StructureSuggestion[] {\n const suggestions: StructureSuggestion[] = [];\n\n for (const finding of findings) {\n if (finding.category !== \"structure\") continue;\n if (\n finding.messageKey !== \"structure.scopeHook\" &&\n finding.messageKey !== \"structure.scopePathScoped\"\n ) {\n continue;\n }\n\n const ruleText =\n finding.line != null && finding.line > 0\n ? (readFileLine(finding.file, finding.line) ||\n (finding.messageParams?.snippet ?? \"\"))\n : (finding.messageParams?.snippet ?? \"\");\n\n if (finding.messageKey === \"structure.scopeHook\") {\n suggestions.push({ finding, ruleText, type: \"hook\" });\n } else {\n const pathDir =\n extractPathDir(ruleText) ||\n extractPathDir(finding.messageParams?.snippet ?? \"\") ||\n \"src\";\n suggestions.push({ finding, ruleText, type: \"path-scoped\", pathDir });\n }\n }\n\n return suggestions;\n}\n\n// ─── Terminal renderer ────────────────────────────────────────────────────────\n\nfunction terminalCodeBlock(code: string, output: { log: typeof console.log }): void {\n const lines = code.split(\"\\n\");\n output.log(chalk.gray(\" ┌\" + \"─\".repeat(62)));\n for (const line of lines) {\n output.log(` ${chalk.gray(\"│\")} ${chalk.white(line)}`);\n }\n output.log(chalk.gray(\" └\" + \"─\".repeat(62)));\n}\n\nexport function printStructureSuggestions(\n suggestions: StructureSuggestion[],\n projectRoot: string,\n output: { log: typeof console.log },\n): void {\n if (suggestions.length === 0) return;\n\n output.log(\"\");\n output.log(chalk.bold.white(` ${t(\"fix.manualActions\")}`));\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n for (const s of suggestions) {\n const relFile = relative(projectRoot, s.finding.file);\n const lineNum = s.finding.line ?? 0;\n\n output.log(\"\");\n output.log(\n ` ${chalk.blue(\"ℹ\")} ${chalk.white(t(s.finding.messageKey, s.finding.messageParams))}`,\n );\n output.log(\"\");\n\n if (s.type === \"hook\") {\n output.log(` ${chalk.cyan(t(\"fix.hookCreate\"))}`);\n terminalCodeBlock(buildHookSnippet(s.ruleText), output);\n output.log(` ${chalk.yellow(t(\"fix.hookWarning\"))}`);\n if (lineNum > 0) {\n output.log(\n ` ${chalk.gray(t(\"fix.thenRemoveLine\", { line: String(lineNum), file: relFile }))}`,\n );\n }\n } else {\n const dir = s.pathDir ?? \"src\";\n const { filePath, content } = buildPathScopedFile(dir, s.ruleText);\n output.log(` ${chalk.cyan(t(\"fix.pathScopedCreate\", { path: filePath }))}`);\n terminalCodeBlock(content, output);\n if (lineNum > 0) {\n output.log(\n ` ${chalk.gray(t(\"fix.thenRemoveLine\", { line: String(lineNum), file: relFile }))}`,\n );\n }\n }\n }\n\n output.log(\"\");\n}\n\n// ─── Markdown renderer ────────────────────────────────────────────────────────\n\nexport function markdownStructureSuggestions(\n suggestions: StructureSuggestion[],\n projectRoot: string,\n): string[] {\n if (suggestions.length === 0) return [];\n\n const lines: string[] = [`## ${t(\"fix.manualActions\")}`, \"\"];\n\n for (const s of suggestions) {\n const relFile = relative(projectRoot, s.finding.file);\n const lineNum = s.finding.line ?? 0;\n const icon =\n s.finding.severity === \"critical\"\n ? \"🔴\"\n : s.finding.severity === \"warning\"\n ? \"🟡\"\n : \"ℹ️\";\n\n lines.push(\n `### ${icon} ${t(s.finding.messageKey, s.finding.messageParams)}`,\n \"\",\n );\n\n if (s.type === \"hook\") {\n lines.push(t(\"fix.hookCreate\"), \"\", \"```json\", buildHookSnippet(s.ruleText), \"```\", \"\");\n lines.push(`> ${t(\"fix.hookWarning\")}`, \"\");\n if (lineNum > 0) {\n lines.push(\n `_${t(\"fix.thenRemoveLine\", { line: String(lineNum), file: relFile })}_`,\n \"\",\n );\n }\n } else {\n const dir = s.pathDir ?? \"src\";\n const { filePath, content } = buildPathScopedFile(dir, s.ruleText);\n lines.push(t(\"fix.pathScopedCreate\", { path: filePath }), \"\");\n lines.push(\"```markdown\", content, \"```\", \"\");\n if (lineNum > 0) {\n lines.push(\n `_${t(\"fix.thenRemoveLine\", { line: String(lineNum), file: relFile })}_`,\n \"\",\n );\n }\n }\n }\n\n return lines;\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport { fileURLToPath } from \"url\";\n\nfunction readPackageVersion(): string {\n const thisFile = fileURLToPath(import.meta.url);\n // bundled: dist/cli.js → 2 levels up = package root\n // dev/test: src/utils/skill-version.ts → 3 levels up = package root\n for (const levels of [2, 3]) {\n const pkgPath = join(thisFile, ...Array(levels).fill(\"..\"), \"package.json\");\n if (existsSync(pkgPath)) {\n const raw: unknown = JSON.parse(readFileSync(pkgPath, \"utf8\"));\n if (\n typeof raw === \"object\" &&\n raw !== null &&\n \"version\" in raw &&\n typeof (raw as { version: unknown }).version === \"string\"\n ) {\n return (raw as { version: string }).version;\n }\n }\n }\n return \"0.0.0\";\n}\n\nexport const CURRENT_VERSION: string = readPackageVersion();\n\nconst VERSION_RE = /^instrlint-version:\\s*(.+)$/m;\n\nfunction extractVersion(content: string): string | null {\n const m = VERSION_RE.exec(content);\n return m ? m[1]!.trim() : null;\n}\n\nfunction readInstalledVersion(path: string): string | null {\n if (!existsSync(path)) return null;\n try {\n return extractVersion(readFileSync(path, \"utf8\"));\n } catch {\n return null;\n }\n}\n\nexport interface SkillUpdateInfo {\n installedVersion: string;\n currentVersion: string;\n installPath: string;\n isProject: boolean;\n}\n\nexport function checkSkillUpdate(\n projectRoot: string,\n globalRoot?: string,\n): SkillUpdateInfo | null {\n const resolvedGlobal = globalRoot ?? homedir();\n const candidates: Array<{ path: string; isProject: boolean }> = [\n {\n path: join(projectRoot, \".claude\", \"commands\", \"instrlint.md\"),\n isProject: true,\n },\n {\n path: join(resolvedGlobal, \".claude\", \"commands\", \"instrlint.md\"),\n isProject: false,\n },\n ];\n\n for (const { path, isProject } of candidates) {\n const installed = readInstalledVersion(path);\n if (installed !== null && installed !== CURRENT_VERSION) {\n return {\n installedVersion: installed,\n currentVersion: CURRENT_VERSION,\n installPath: path,\n isProject,\n };\n }\n }\n return null;\n}\n\nexport function injectVersion(content: string, version: string): string {\n // Replace existing instrlint-version line (idempotent)\n if (/^instrlint-version:/m.test(content)) {\n return content.replace(\n /^instrlint-version:.*$/m,\n `instrlint-version: ${version}`,\n );\n }\n // Insert before closing --- of frontmatter\n const updated = content.replace(\n /^(---\\n[\\s\\S]*?)(---)$/m,\n `$1instrlint-version: ${version}\\n$2`,\n );\n if (updated === content) {\n throw new Error(\"injectVersion: no YAML frontmatter found in skill file\");\n }\n return updated;\n}\n","import { createHash } from \"crypto\";\nimport { relative } from \"path\";\nimport type { Finding, ParsedInstructions, InstructionFile } from \"../types.js\";\nimport type {\n Candidate,\n CandidatesFile,\n CandidateContext,\n RuleRef,\n} from \"./schema.js\";\nimport { shouldVerify } from \"./policy.js\";\n\n// ─── Line lookup ──────────────────────────────────────────────────────────────\n\nfunction findLineText(\n parsed: ParsedInstructions,\n filePath: string,\n lineNumber: number,\n): string {\n const sources: InstructionFile[] = [\n parsed.rootFile,\n ...parsed.subFiles,\n ...parsed.rules,\n ];\n const file = sources.find((f) => f.path === filePath);\n if (!file) return \"\";\n const line = file.lines.find((l) => l.lineNumber === lineNumber);\n return line?.text.trim() ?? \"\";\n}\n\nfunction ruleRef(\n parsed: ParsedInstructions,\n filePath: string,\n lineNumber: number,\n projectRoot: string,\n): RuleRef {\n return {\n file: toRelative(filePath, projectRoot),\n line: lineNumber,\n text: findLineText(parsed, filePath, lineNumber),\n };\n}\n\n// ─── Context builders ─────────────────────────────────────────────────────────\n\nfunction buildContext(\n finding: Finding,\n parsed: ParsedInstructions,\n projectRoot: string,\n): CandidateContext | null {\n if (finding.category === \"contradiction\") {\n const { fileA, lineA } = finding.messageParams ?? {};\n if (!fileA || !lineA) return null;\n return {\n type: \"contradiction\",\n ruleA: ruleRef(parsed, fileA, Number(lineA), projectRoot),\n ruleB: ruleRef(parsed, finding.file, finding.line ?? 0, projectRoot),\n };\n }\n\n if (finding.category === \"duplicate\") {\n const { otherFile, otherLine } = finding.messageParams ?? {};\n if (!otherFile || !otherLine) return null;\n return {\n type: \"duplicate\",\n ruleA: ruleRef(parsed, otherFile, Number(otherLine), projectRoot),\n ruleB: ruleRef(parsed, finding.file, finding.line ?? 0, projectRoot),\n };\n }\n\n if (finding.category === \"structure\") {\n return {\n type: \"structure\",\n rule: ruleRef(parsed, finding.file, finding.line ?? 0, projectRoot),\n suggestion: finding.suggestion,\n };\n }\n\n return null;\n}\n\n// ─── Stable ID ────────────────────────────────────────────────────────────────\n\n/**\n * Hash over category + file + line so the same finding always gets the same ID\n * across instrlint runs, enabling verdict caching by the host agent.\n */\nexport function hashFinding(finding: Finding): string {\n const key = `${finding.category}:${finding.file}:${finding.line ?? 0}:${finding.messageKey}`;\n return createHash(\"sha256\").update(key).digest(\"hex\").slice(0, 12);\n}\n\n// ─── Question text ────────────────────────────────────────────────────────────\n\nconst QUESTIONS: Record<string, Record<string, string>> = {\n contradiction: {\n en: 'Do rules A and B actually contradict each other in practice? A real contradiction means a developer following both rules would be forced to violate one of them. Respond with JSON only: {\"verdict\":\"confirmed\"|\"rejected\"|\"uncertain\",\"reason\":\"<≤20 words>\"}',\n \"zh-TW\":\n '規則 A 和規則 B 在實際開發中真的相互矛盾嗎?真正的矛盾是指:同時遵守兩條規則在某些情境下是不可能的。僅用 JSON 回答:{\"verdict\":\"confirmed\"|\"rejected\"|\"uncertain\",\"reason\":\"<20 字以內>\"}',\n },\n duplicate: {\n en: 'Are rules A and B true semantic duplicates — do they say the same thing in different words, such that keeping both adds no value? Respond with JSON only: {\"verdict\":\"confirmed\"|\"rejected\"|\"uncertain\",\"reason\":\"<≤20 words>\"}',\n \"zh-TW\":\n '規則 A 和規則 B 在語意上真的是重複的嗎——用不同的措辭說同一件事,保留兩條毫無額外價值?僅用 JSON 回答:{\"verdict\":\"confirmed\"|\"rejected\"|\"uncertain\",\"reason\":\"<20 字以內>\"}',\n },\n structure: {\n en: 'Is this structural suggestion accurate? Should this rule truly move to a git hook or path-scoped rule file, or is it an architectural principle / general guidance that belongs in CLAUDE.md? Respond with JSON only: {\"verdict\":\"confirmed\"|\"rejected\"|\"uncertain\",\"reason\":\"<≤20 words>\"}',\n \"zh-TW\":\n '這條結構建議是否準確?這條規則真的更適合移到 git hook 或 path-scoped rule file 中,還是它是架構說明 / 一般原則,應留在 CLAUDE.md 中?僅用 JSON 回答:{\"verdict\":\"confirmed\"|\"rejected\"|\"uncertain\",\"reason\":\"<20 字以內>\"}',\n },\n};\n\nfunction questionFor(category: string, locale: string): string {\n const lang = locale === \"zh-TW\" ? \"zh-TW\" : \"en\";\n const question = QUESTIONS[category]?.[lang] ?? QUESTIONS[category]?.[\"en\"];\n if (!question) {\n process.stderr.write(\n `[instrlint] Warning: no verification question for category \"${category}\", skipping\\n`,\n );\n return \"\";\n }\n return question;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/** Normalize an absolute path to project-relative for safe serialization. */\nfunction toRelative(filePath: string, projectRoot: string): string {\n const rel = relative(projectRoot, filePath);\n // If the path escaped the project root, keep as-is (safety: don't strip info)\n return rel.startsWith(\"..\") ? filePath : rel;\n}\n\n/** Return a copy of the finding with all file paths made project-relative. */\nfunction normalizeFilePaths(finding: Finding, projectRoot: string): Finding {\n const normalized: Finding = {\n ...finding,\n file: toRelative(finding.file, projectRoot),\n };\n if (normalized.messageParams) {\n const params = { ...normalized.messageParams };\n if (params[\"fileA\"])\n params[\"fileA\"] = toRelative(params[\"fileA\"], projectRoot);\n if (params[\"otherFile\"])\n params[\"otherFile\"] = toRelative(params[\"otherFile\"], projectRoot);\n normalized.messageParams = params;\n }\n return normalized;\n}\n\nexport function buildCandidates(\n findings: Finding[],\n parsed: ParsedInstructions,\n projectRoot: string,\n locale: string,\n): CandidatesFile {\n const candidates: Candidate[] = [];\n\n for (const finding of findings) {\n if (!shouldVerify(finding)) continue;\n const context = buildContext(finding, parsed, projectRoot);\n if (!context) continue;\n\n candidates.push({\n id: hashFinding(finding),\n category: finding.category,\n question: questionFor(finding.category, locale),\n context,\n originalFinding: normalizeFilePaths(finding, projectRoot),\n });\n }\n\n return {\n version: 1,\n generatedAt: new Date().toISOString(),\n projectRoot,\n candidates,\n };\n}\n","import type { Finding } from \"../types.js\";\n\n/**\n * Returns true for findings that benefit from LLM verification — those with\n * high false-positive rates from the deterministic detectors.\n *\n * High-confidence findings are excluded because they use deterministic checks\n * (filesystem existence, exact config field matching) where LLM review adds\n * no value and would waste the user's session tokens.\n */\nexport function shouldVerify(finding: Finding): boolean {\n // Exact filesystem check — deterministic, skip verification\n if (finding.category === \"stale-ref\") return false;\n\n // Math-based budget checks — deterministic, skip\n if (finding.category === \"budget\") return false;\n\n // Structure suggestions are informational, not findings to confirm\n if (finding.category === \"structure\") return true;\n\n // Config-overlap dead rules use hard-coded patterns — conservative by design,\n // but auto-fixable ones are safe; non-auto-fixable may have false positives\n if (finding.category === \"dead-rule\") return !finding.autoFixable;\n\n // Contradictions have high false-positive rate — always verify\n if (finding.category === \"contradiction\") return true;\n\n // Near-duplicates (warning) are ambiguous; exact dupes (info + autoFixable)\n // are deterministic and don't need LLM review\n if (finding.category === \"duplicate\") {\n return finding.severity === \"warning\" && !finding.autoFixable;\n }\n\n return false;\n}\n","import { readFileSync } from \"fs\";\nimport type { Finding } from \"../types.js\";\nimport type { VerdictsFile } from \"./schema.js\";\nimport { hashFinding } from \"./candidates.js\";\n\n/**\n * Reads verdicts.json written by the host agent and merges verdicts back into\n * the findings array.\n *\n * - `rejected` findings are removed entirely (they were false positives).\n * - `confirmed` and `uncertain` findings get a `verification` field attached.\n * - Findings with no matching verdict are returned unchanged.\n * - Unknown IDs in verdicts are silently ignored (forward-compatible).\n */\nexport interface ApplyVerdictsResult {\n findings: Finding[];\n rejectedCount: number;\n}\n\nexport function applyVerdicts(\n findings: Finding[],\n verdictsFile: VerdictsFile,\n): ApplyVerdictsResult {\n const verdictMap = new Map(verdictsFile.verdicts.map((v) => [v.id, v]));\n\n const withVerdicts = findings.map((f): Finding => {\n const verdict = verdictMap.get(hashFinding(f));\n if (!verdict) return f;\n return {\n ...f,\n verification: { verdict: verdict.verdict, reason: verdict.reason },\n };\n });\n\n const kept = withVerdicts.filter(\n (f) => f.verification?.verdict !== \"rejected\",\n );\n const rejectedCount = withVerdicts.length - kept.length;\n\n return { findings: kept, rejectedCount };\n}\n\n/**\n * Loads and parses a verdicts.json file from disk.\n * Throws with a descriptive message if the file is missing or malformed.\n */\nexport function loadVerdictsFile(filePath: string): VerdictsFile {\n let raw: string;\n try {\n raw = readFileSync(filePath, \"utf8\");\n } catch {\n throw new Error(\n `Cannot read verdicts file: ${filePath}\\nRun instrlint --emit-candidates first, then ask the host LLM to write verdicts.`,\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw) as unknown;\n } catch {\n throw new Error(`verdicts.json is not valid JSON: ${filePath}`);\n }\n\n const obj = parsed as Record<string, unknown>;\n\n if (\n typeof parsed !== \"object\" ||\n parsed === null ||\n obj[\"version\"] !== 1 ||\n !Array.isArray(obj[\"verdicts\"])\n ) {\n throw new Error(\n `verdicts.json has unexpected format (expected {version:1, verdicts:[...]}): ${filePath}`,\n );\n }\n\n const VALID_VERDICTS = new Set([\"confirmed\", \"rejected\", \"uncertain\"]);\n const MAX_REASON_LENGTH = 500;\n\n for (const v of obj[\"verdicts\"] as unknown[]) {\n if (typeof v !== \"object\" || v === null) {\n throw new Error(`verdicts.json: each verdict must be an object`);\n }\n const item = v as Record<string, unknown>;\n if (typeof item[\"id\"] !== \"string\" || item[\"id\"].length === 0) {\n throw new Error(`verdicts.json: verdict missing string \"id\"`);\n }\n if (!VALID_VERDICTS.has(item[\"verdict\"] as string)) {\n throw new Error(\n `verdicts.json: invalid verdict \"${item[\"verdict\"]}\" for id \"${item[\"id\"]}\" (must be confirmed|rejected|uncertain)`,\n );\n }\n if (typeof item[\"reason\"] !== \"string\") {\n throw new Error(\n `verdicts.json: verdict \"${item[\"id\"]}\" missing string \"reason\"`,\n );\n }\n if ((item[\"reason\"] as string).length > MAX_REASON_LENGTH) {\n throw new Error(\n `verdicts.json: verdict \"${item[\"id\"]}\" reason exceeds ${MAX_REASON_LENGTH} characters`,\n );\n }\n }\n\n return parsed as VerdictsFile;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport { fileURLToPath } from \"url\";\nimport { t } from \"../i18n/index.js\";\nimport { injectVersion, CURRENT_VERSION } from \"../utils/skill-version.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface InstallCommandOpts {\n claudeCode?: boolean;\n codex?: boolean;\n project?: boolean;\n force?: boolean;\n projectRoot?: string;\n}\n\nexport interface InstallCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\n// ─── File resolution ──────────────────────────────────────────────────────────\n\nfunction resolveSkillFile(target: \"claude-code\" | \"codex\"): string {\n const thisFile = fileURLToPath(import.meta.url);\n const subDir = target === \"claude-code\" ? \"claude-code\" : \"codex\";\n\n // tsup bundles into dist/cli.js (2 levels up = package root).\n // In dev/test, file is at src/commands/install-command.ts (3 levels up = package root).\n // Try both, use whichever has the skills directory.\n for (const levels of [2, 3]) {\n const parts = Array(levels).fill(\"..\");\n const candidate = join(thisFile, ...parts, \"skills\", subDir, \"SKILL.md\");\n if (existsSync(candidate)) return candidate;\n }\n\n // Fallback: return the 2-level path so the error message shows a useful path\n return join(thisFile, \"..\", \"..\", \"skills\", subDir, \"SKILL.md\");\n}\n\nfunction readSkillContent(target: \"claude-code\" | \"codex\"): string {\n const skillPath = resolveSkillFile(target);\n try {\n const raw = readFileSync(skillPath, \"utf8\");\n return injectVersion(raw, CURRENT_VERSION);\n } catch {\n throw new Error(\n `Could not read skill file at ${skillPath}. Make sure the package is properly installed.`,\n );\n }\n}\n\n// ─── Install targets ──────────────────────────────────────────────────────────\n\nfunction installClaudeCode(\n content: string,\n projectRoot: string,\n isProject: boolean,\n force: boolean,\n output: { log: typeof console.log; error: typeof console.error },\n): InstallCommandResult {\n const targetDir = isProject\n ? join(projectRoot, \".claude\", \"commands\")\n : join(homedir(), \".claude\", \"commands\");\n\n const targetPath = join(targetDir, \"instrlint.md\");\n\n if (existsSync(targetPath) && !force) {\n output.error(t(\"install.alreadyExists\", { path: targetPath }));\n return { exitCode: 1, errorMessage: \"file already exists\" };\n }\n\n mkdirSync(targetDir, { recursive: true });\n writeFileSync(targetPath, content, \"utf8\");\n output.log(t(\"install.installed\", { path: targetPath }));\n return { exitCode: 0 };\n}\n\nfunction installCodex(\n content: string,\n projectRoot: string,\n force: boolean,\n output: { log: typeof console.log; error: typeof console.error },\n): InstallCommandResult {\n const targetDir = join(projectRoot, \".agents\", \"skills\", \"instrlint\");\n const targetPath = join(targetDir, \"SKILL.md\");\n\n if (existsSync(targetPath) && !force) {\n output.error(t(\"install.alreadyExists\", { path: targetPath }));\n return { exitCode: 1, errorMessage: \"file already exists\" };\n }\n\n mkdirSync(targetDir, { recursive: true });\n writeFileSync(targetPath, content, \"utf8\");\n output.log(t(\"install.installed\", { path: targetPath }));\n return { exitCode: 0 };\n}\n\n// ─── Core logic ───────────────────────────────────────────────────────────────\n\nexport function runInstall(\n opts: InstallCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): InstallCommandResult {\n const projectRoot = opts.projectRoot ?? process.cwd();\n const force = opts.force ?? false;\n\n if (opts.claudeCode) {\n let content: string;\n try {\n content = readSkillContent(\"claude-code\");\n } catch (err) {\n output.error(String(err));\n return { exitCode: 1, errorMessage: String(err) };\n }\n return installClaudeCode(\n content,\n projectRoot,\n opts.project ?? false,\n force,\n output,\n );\n }\n\n if (opts.codex) {\n let content: string;\n try {\n content = readSkillContent(\"codex\");\n } catch (err) {\n output.error(String(err));\n return { exitCode: 1, errorMessage: String(err) };\n }\n return installCodex(content, projectRoot, force, output);\n }\n\n output.error(t(\"install.unknownTarget\"));\n return { exitCode: 1, errorMessage: \"no target specified\" };\n}\n","import chalk from \"chalk\";\nimport { analyzeDeadRules } from \"../analyzers/dead-rules.js\";\nimport { loadProject } from \"../adapters/dispatch.js\";\nimport { ensureInitialized } from \"../detectors/token-estimator.js\";\nimport { scanProject } from \"../core/scanner.js\";\nimport { t, plural, initLocale, getLocale } from \"../i18n/index.js\";\nimport type { Finding } from \"../types.js\";\n\n// ─── Terminal output ──────────────────────────────────────────────────────────\n\nexport function printDeadRulesTerminal(\n findings: Finding[],\n output: { log: typeof console.log } = console,\n): void {\n const overlaps = findings.filter((f) => f.category === \"dead-rule\");\n const duplicates = findings.filter((f) => f.category === \"duplicate\");\n\n output.log(\"\");\n output.log(chalk.bold.white(` ${t(\"label.deadRules\")}`));\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n if (overlaps.length > 0) {\n output.log(chalk.bold(` ${t(\"label.redundantByConfig\")}`));\n for (const f of overlaps) {\n output.log(` ${chalk.yellow(\"⚠\")} ${t(f.messageKey, f.messageParams)}`);\n }\n output.log(\"\");\n }\n\n if (duplicates.length > 0) {\n output.log(chalk.bold(` ${t(\"label.duplicates\")}`));\n for (const f of duplicates) {\n const icon =\n f.severity === \"warning\" ? chalk.yellow(\"⚠\") : chalk.blue(\"ℹ\");\n output.log(` ${icon} ${t(f.messageKey, f.messageParams)}`);\n }\n output.log(\"\");\n }\n\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n if (findings.length === 0) {\n output.log(chalk.green(` ${t(\"status.noDeadRules\")}`));\n } else {\n const sep = getLocale() === \"zh-TW\" ? \"、\" : \", \";\n const parts: string[] = [];\n if (overlaps.length > 0)\n parts.push(\n t(\"summary.redundantRules\", {\n count: String(overlaps.length),\n s: plural(overlaps.length),\n }),\n );\n if (duplicates.length > 0)\n parts.push(\n t(\"summary.duplicates\", {\n count: String(duplicates.length),\n s: plural(duplicates.length),\n }),\n );\n output.log(\n chalk.yellow(` ${t(\"summary.found\", { parts: parts.join(sep) })}`),\n );\n }\n output.log(\"\");\n}\n\n// ─── Core run logic ───────────────────────────────────────────────────────────\n\nexport interface DeadRulesCommandOpts {\n format: string;\n tool?: string;\n lang?: string;\n projectRoot?: string;\n}\n\nexport interface DeadRulesCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\nexport async function runDeadRules(\n opts: DeadRulesCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): Promise<DeadRulesCommandResult> {\n initLocale(opts.lang);\n await ensureInitialized();\n\n const projectRoot = opts.projectRoot ?? process.cwd();\n const scan = scanProject(projectRoot, opts.tool);\n\n if (scan.tool === \"unknown\") {\n output.error(t(\"error.unknownTool\"));\n return { exitCode: 1, errorMessage: \"unknown tool\" };\n }\n\n if (scan.rootFilePath === null) {\n output.error(t(\"error.missingRootFile\", { tool: scan.tool }));\n return { exitCode: 1, errorMessage: \"missing root file\" };\n }\n\n const instructions = loadProject(projectRoot, scan.tool);\n const { findings } = analyzeDeadRules(instructions, projectRoot);\n\n if (opts.format === \"json\") {\n output.log(JSON.stringify({ findings }, null, 2));\n return { exitCode: 0 };\n }\n\n printDeadRulesTerminal(findings, output);\n return { exitCode: 0 };\n}\n","import chalk from \"chalk\";\nimport { analyzeStructure } from \"../analyzers/structure.js\";\nimport { loadProject } from \"../adapters/dispatch.js\";\nimport { ensureInitialized } from \"../detectors/token-estimator.js\";\nimport { scanProject } from \"../core/scanner.js\";\nimport { t, plural, initLocale, getLocale } from \"../i18n/index.js\";\nimport type { Finding } from \"../types.js\";\n\n// ─── Terminal output ──────────────────────────────────────────────────────────\n\nfunction printStructureTerminal(\n findings: Finding[],\n output: { log: typeof console.log } = console,\n): void {\n const contradictions = findings.filter((f) => f.category === \"contradiction\");\n const staleRefs = findings.filter((f) => f.category === \"stale-ref\");\n const scoped = findings.filter((f) => f.category === \"structure\");\n\n output.log(\"\");\n output.log(chalk.bold.white(` ${t(\"label.structure\")}`));\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n if (contradictions.length > 0) {\n output.log(chalk.bold(` ${t(\"label.contradictions\")}`));\n for (const f of contradictions) {\n output.log(` ${chalk.red(\"✖\")} ${t(f.messageKey, f.messageParams)}`);\n }\n output.log(\"\");\n }\n\n if (staleRefs.length > 0) {\n output.log(chalk.bold(` ${t(\"label.staleReferences\")}`));\n for (const f of staleRefs) {\n output.log(` ${chalk.yellow(\"⚠\")} ${t(f.messageKey, f.messageParams)}`);\n }\n output.log(\"\");\n }\n\n if (scoped.length > 0) {\n output.log(chalk.bold(` ${t(\"label.refactoringOpportunities\")}`));\n for (const f of scoped) {\n output.log(` ${chalk.blue(\"ℹ\")} ${t(f.messageKey, f.messageParams)}`);\n }\n output.log(\"\");\n }\n\n output.log(chalk.gray(\" ─\".repeat(30)));\n\n if (findings.length === 0) {\n output.log(chalk.green(` ${t(\"status.noStructuralIssues\")}`));\n } else {\n const sep = getLocale() === \"zh-TW\" ? \"、\" : \", \";\n const parts: string[] = [];\n if (contradictions.length > 0)\n parts.push(\n t(\"summary.contradictions\", {\n count: String(contradictions.length),\n s: plural(contradictions.length),\n }),\n );\n if (staleRefs.length > 0)\n parts.push(\n t(\"summary.staleRefs\", {\n count: String(staleRefs.length),\n s: plural(staleRefs.length),\n }),\n );\n if (scoped.length > 0)\n parts.push(\n t(\"summary.refactoringSuggestions\", {\n count: String(scoped.length),\n s: plural(scoped.length),\n }),\n );\n output.log(\n chalk.yellow(` ${t(\"summary.found\", { parts: parts.join(sep) })}`),\n );\n }\n output.log(\"\");\n}\n\n// ─── Core run logic ───────────────────────────────────────────────────────────\n\nexport interface StructureCommandOpts {\n format: string;\n tool?: string;\n lang?: string;\n projectRoot?: string;\n}\n\nexport interface StructureCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\nexport async function runStructure(\n opts: StructureCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): Promise<StructureCommandResult> {\n initLocale(opts.lang);\n await ensureInitialized();\n\n const projectRoot = opts.projectRoot ?? process.cwd();\n const scan = scanProject(projectRoot, opts.tool);\n\n if (scan.tool === \"unknown\") {\n output.error(t(\"error.unknownTool\"));\n return { exitCode: 1, errorMessage: \"unknown tool\" };\n }\n\n if (scan.rootFilePath === null) {\n output.error(t(\"error.missingRootFile\", { tool: scan.tool }));\n return { exitCode: 1, errorMessage: \"missing root file\" };\n }\n\n const instructions = loadProject(projectRoot, scan.tool);\n const { findings } = analyzeStructure(instructions, projectRoot);\n\n if (opts.format === \"json\") {\n output.log(JSON.stringify({ findings }, null, 2));\n return { exitCode: 0 };\n }\n\n printStructureTerminal(findings, output);\n return { exitCode: 0 };\n}\n","import { writeFileSync } from \"fs\";\nimport { basename } from \"path\";\nimport { scanProject } from \"../core/scanner.js\";\nimport { loadProject } from \"../adapters/dispatch.js\";\nimport { ensureInitialized } from \"../detectors/token-estimator.js\";\nimport { analyzeBudget } from \"../analyzers/budget.js\";\nimport { analyzeDeadRules } from \"../analyzers/dead-rules.js\";\nimport { analyzeStructure } from \"../analyzers/structure.js\";\nimport { calculateScore, buildActionPlan } from \"../core/scorer.js\";\nimport { reportJson, reportMarkdown } from \"../core/reporter.js\";\nimport { reportSarif } from \"../reporters/sarif.js\";\nimport { t, initLocale, getLocale } from \"../i18n/index.js\";\nimport type { Finding, HealthReport } from \"../types.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type FailOn = \"critical\" | \"warning\" | \"info\";\n\nexport interface CiCommandOpts {\n format?: string;\n tool?: string;\n lang?: string;\n failOn?: FailOn;\n output?: string;\n projectRoot?: string;\n}\n\nexport interface CiCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\n// ─── Threshold helpers ────────────────────────────────────────────────────────\n\nfunction shouldFail(findings: Finding[], failOn: FailOn): boolean {\n if (failOn === \"info\") return findings.length > 0;\n if (failOn === \"warning\")\n return findings.some(\n (f) => f.severity === \"critical\" || f.severity === \"warning\",\n );\n // default: critical\n return findings.some((f) => f.severity === \"critical\");\n}\n\n// ─── Core logic ───────────────────────────────────────────────────────────────\n\nexport async function runCi(\n opts: CiCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): Promise<CiCommandResult> {\n initLocale(opts.lang);\n await ensureInitialized();\n\n const projectRoot = opts.projectRoot ?? process.cwd();\n const failOn: FailOn = opts.failOn ?? \"critical\";\n const format = opts.format ?? \"terminal\";\n\n const scan = scanProject(projectRoot, opts.tool);\n\n if (scan.tool === \"unknown\") {\n output.error(t(\"error.unknownTool\"));\n return { exitCode: 1, errorMessage: \"unknown tool\" };\n }\n\n if (scan.rootFilePath === null) {\n output.error(t(\"error.missingRootFile\", { tool: scan.tool }));\n return { exitCode: 1, errorMessage: \"missing root file\" };\n }\n\n const instructions = loadProject(projectRoot, scan.tool);\n\n const { findings: budgetFindings, summary } = analyzeBudget(instructions);\n const { findings: deadRuleFindings } = analyzeDeadRules(\n instructions,\n projectRoot,\n );\n const { findings: structureFindings } = analyzeStructure(\n instructions,\n projectRoot,\n );\n\n const allFindings = [\n ...budgetFindings,\n ...deadRuleFindings,\n ...structureFindings,\n ];\n const { score, grade } = calculateScore(allFindings, summary);\n const actionPlan = buildActionPlan(allFindings);\n\n const report: HealthReport = {\n project: basename(projectRoot),\n tool: instructions.tool,\n score,\n grade,\n locale: getLocale(),\n tokenMethod: summary.tokenMethod,\n findings: allFindings,\n budget: summary,\n actionPlan,\n };\n\n // ── Format output ─────────────────────────────────────────────────────────\n let formatted: string;\n if (format === \"sarif\") {\n formatted = reportSarif(report);\n } else if (format === \"json\") {\n formatted = reportJson(report);\n } else if (format === \"markdown\") {\n formatted = reportMarkdown(report);\n } else {\n formatted = reportJson(report);\n }\n\n if (opts.output != null) {\n writeFileSync(opts.output, formatted, \"utf8\");\n const pass = !shouldFail(allFindings, failOn);\n const statusKey = pass ? \"ci.passed\" : \"ci.failed\";\n output.error(\n `${t(statusKey, { score: String(score), grade })} ${t(\"ci.writtenTo\", { file: opts.output })}`,\n );\n } else {\n output.log(formatted);\n }\n\n const failed = shouldFail(allFindings, failOn);\n return { exitCode: failed ? 1 : 0 };\n}\n","import type { Finding, HealthReport } from \"../types.js\";\n\n// ─── SARIF v2.1.0 types ────────────────────────────────────────────────────\n\ninterface SarifArtifactLocation {\n uri: string;\n uriBaseId?: string;\n}\n\ninterface SarifRegion {\n startLine: number;\n}\n\ninterface SarifPhysicalLocation {\n artifactLocation: SarifArtifactLocation;\n region?: SarifRegion;\n}\n\ninterface SarifLocation {\n physicalLocation: SarifPhysicalLocation;\n}\n\ninterface SarifMessage {\n text: string;\n}\n\ninterface SarifResult {\n ruleId: string;\n level: \"error\" | \"warning\" | \"note\";\n message: SarifMessage;\n locations: SarifLocation[];\n}\n\ninterface SarifRule {\n id: string;\n name: string;\n shortDescription: SarifMessage;\n}\n\ninterface SarifDriver {\n name: string;\n version: string;\n informationUri: string;\n rules: SarifRule[];\n}\n\ninterface SarifTool {\n driver: SarifDriver;\n}\n\ninterface SarifRun {\n tool: SarifTool;\n results: SarifResult[];\n}\n\ninterface SarifLog {\n $schema: string;\n version: \"2.1.0\";\n runs: SarifRun[];\n}\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction severityToLevel(\n severity: Finding[\"severity\"],\n): \"error\" | \"warning\" | \"note\" {\n if (severity === \"critical\") return \"error\";\n if (severity === \"warning\") return \"warning\";\n return \"note\";\n}\n\nfunction findingToRuleId(f: Finding): string {\n return `instrlint/${f.category}/${f.messageKey.replace(/\\./g, \"/\")}`;\n}\n\nfunction buildRules(findings: Finding[]): SarifRule[] {\n const seen = new Set<string>();\n const rules: SarifRule[] = [];\n for (const f of findings) {\n const id = findingToRuleId(f);\n if (seen.has(id)) continue;\n seen.add(id);\n rules.push({\n id,\n name: f.messageKey,\n shortDescription: { text: `${f.category}: ${f.messageKey}` },\n });\n }\n return rules;\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\nexport function reportSarif(report: HealthReport): string {\n const rules = buildRules(report.findings);\n\n const results: SarifResult[] = report.findings.map((f) => ({\n ruleId: findingToRuleId(f),\n level: severityToLevel(f.severity),\n message: { text: f.suggestion },\n locations: [\n {\n physicalLocation: {\n artifactLocation: {\n uri: f.file.replace(/\\\\/g, \"/\"),\n uriBaseId: \"%SRCROOT%\",\n },\n ...(f.line != null ? { region: { startLine: f.line } } : {}),\n },\n },\n ],\n }));\n\n const log: SarifLog = {\n $schema:\n \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json\",\n version: \"2.1.0\",\n runs: [\n {\n tool: {\n driver: {\n name: \"instrlint\",\n version: \"0.1.0\",\n informationUri: \"https://github.com/jed1978/instrlint\",\n rules,\n },\n },\n results,\n },\n ],\n };\n\n return JSON.stringify(log, null, 2);\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { t } from \"../i18n/index.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface InitCiCommandOpts {\n github?: boolean;\n gitlab?: boolean;\n force?: boolean;\n projectRoot?: string;\n}\n\nexport interface InitCiCommandResult {\n exitCode: number;\n errorMessage?: string;\n}\n\n// ─── GitHub Actions workflow template ────────────────────────────────────────\n\nfunction githubWorkflow(): string {\n return `name: instrlint\n\non:\n push:\n paths:\n - 'CLAUDE.md'\n - '.claude/**'\n - 'AGENTS.md'\n - '.agents/**'\n - '.cursorrules'\n - '.cursor/**'\n pull_request:\n paths:\n - 'CLAUDE.md'\n - '.claude/**'\n - 'AGENTS.md'\n - '.agents/**'\n - '.cursorrules'\n - '.cursor/**'\n\njobs:\n instrlint:\n name: Lint instruction files\n runs-on: ubuntu-latest\n permissions:\n contents: read\n security-events: write\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: actions/setup-node@v4\n with:\n node-version: '20'\n\n - name: Run instrlint\n run: npx instrlint@latest ci --fail-on warning --format sarif --output instrlint.sarif\n\n - name: Upload SARIF\n if: always()\n uses: github/codeql-action/upload-sarif@v3\n with:\n sarif_file: instrlint.sarif\n category: instrlint\n`;\n}\n\n// ─── GitLab CI snippet template ───────────────────────────────────────────────\n\nfunction gitlabSnippet(): string {\n return `# Add this to your .gitlab-ci.yml\ninstrlint:\n image: node:20\n stage: test\n rules:\n - changes:\n - CLAUDE.md\n - .claude/**/*\n - AGENTS.md\n - .agents/**/*\n - .cursorrules\n - .cursor/**/*\n script:\n - npx instrlint@latest ci --fail-on warning --format json\n allow_failure: false\n`;\n}\n\n// ─── Core logic ───────────────────────────────────────────────────────────────\n\nexport function runInitCi(\n opts: InitCiCommandOpts,\n output: { log: typeof console.log; error: typeof console.error } = console,\n): InitCiCommandResult {\n const projectRoot = opts.projectRoot ?? process.cwd();\n\n if (opts.github) {\n const workflowDir = join(projectRoot, \".github\", \"workflows\");\n const workflowPath = join(workflowDir, \"instrlint.yml\");\n\n if (existsSync(workflowPath) && !opts.force) {\n output.error(t(\"initCi.alreadyExists\", { path: workflowPath }));\n return { exitCode: 1, errorMessage: \"file already exists\" };\n }\n\n mkdirSync(workflowDir, { recursive: true });\n writeFileSync(workflowPath, githubWorkflow(), \"utf8\");\n output.log(t(\"initCi.created\", { path: workflowPath }));\n return { exitCode: 0 };\n }\n\n if (opts.gitlab) {\n output.log(gitlabSnippet());\n return { exitCode: 0 };\n }\n\n output.error(\"init-ci: specify --github or --gitlab\");\n return { exitCode: 1, errorMessage: \"no target specified\" };\n}\n"],"mappings":"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","names":["import_fs","import_path","import_chalk","detections","import_fs","import_path","import_fs","import_fs","import_path","safeParseFile","emptyFile","loadSkills","import_fs","import_path","safeParseFile","emptyFile","findRootFile","loadRules","loadMcpServers","pct","import_fs","import_path","collectRuleLines","collectRuleLines","import_fs","import_path","CONTEXT_WINDOW","import_chalk","chalk","chalk","import_fs","import_fs","import_path","import_chalk","chalk","import_fs","import_path","import_path","import_fs","import_fs","import_path","import_os","import_url","chalk","resolve","import_chalk","chalk","import_chalk","chalk","import_fs","import_path","import_fs","import_path"]}