Repository navigation
feat(route): legacy ladder and per-linter custom-rule counts - #577
theCodeDrift wants to merge 2 commits into
Conversation
Adds the legacy-linter-recipes OpenSpec change and the customRules count detect reports for eslint, biome, pylint, flake8, and ruff.
route v7 checks for a rule the linter ships before anything else, gates a new custom rule on five of the repository's own, and renders a paragraph per linter detect found. create-legacy-rule v2 and onboard v7 follow it.
|
@claude /review |
|
Claude finished @theCodeDrift's task in 5m 47s —— View job Review completeReview mode: incremental — read 0 prior review thread(s) before reviewing.
SummaryThe implementation lines up well with the OpenSpec proposal/design/spec deltas: the Two inline findings, both [New]:
Nothing else stood out as incorrect — the ESLint "unknown" vs. counted-threshold logic, the Biome nested-config summation, the pylint |
| */ | ||
| function countRuleDirectory(path: string): number { | ||
| let count = 0; | ||
| for (const entry of readdirSync(path)) { |
There was a problem hiding this comment.
[New] readdirSync(path) here isn't wrapped in a try/catch, unlike every other filesystem read in this module (readText catches, and the statSync two lines below is already wrapped). If eslint-rules/eslint-local-rules/tools/eslint-rules exists but is unreadable (e.g. EACCES), this throws synchronously inside countEslint → countCustomRules → detectRepository, and neither detect.ts nor agent.ts wraps that call in a try/catch. The top-level handler in src/index.ts catches it, but only prints error.message to stderr and sets exitCode = 1 — under detect --json that means no JSON is written to stdout at all, not even the INTERNAL_ERROR envelope that schema-validation failures get.
This conflicts with this file's own module doc ("derived from files on disk without executing anything") and the existing invariant in scan.ts that "unreadable or malformed files are skipped rather than failing the scan." Worth wrapping the readdirSync call the same way statSync is, so an unreadable rule directory degrades to "not counted" instead of failing the whole scan.
| // --- ESLint ------------------------------------------------------------------ | ||
|
|
||
| /** House directories that hold one ESLint rule per entry. */ | ||
| const ESLINT_RULE_DIRECTORIES = [ |
There was a problem hiding this comment.
[New] Minor duplication: this list (eslint-rules, eslint-local-rules, tools/eslint-rules) is also hardcoded in scan.ts's detectRuleStyles (the loop building ruleStyles). Not a bug, but the two lists can drift if one is updated without the other — might be worth having one reference the other's constant.
Stack (root → tip):
First of two PRs for the
legacy-linter-recipesOpenSpec change. For a linter the repository already runs, the agent now uses a rule that linter already ships instead of working out each tool's dialect from scratch. It writes a new custom rule there only when the repository's own rules give it something to copy.The legacy ladder.
route(topic v8) takes these in order:sgorvalerule.routeno longer asks the user to choose between a linter rule and a Taskless rule: the order decides. It also renders a paragraph for each linterdetectfound, saying what that tool always checks first.detect --jsonreportscustomRulesfor ESLint, Biome, pylint, flake8, and Ruff: a count of the rules the repository wrote itself for that linter, and where they are.pluginsentries.load-pluginsmodules that exist in the repository.[flake8:local-plugins]entries and published entry points.ESLint's count is
"unknown"when the config defines rules inline or imports a plugin from a local file, because counting those would mean running JavaScript. The recipes treat"unknown"as below the threshold.Recipes.
create-legacy-rulev3 looks for a shipped rule first and asks before adding a plugin the repository does not have. During onboarding (v11), the agent only enables rules from packages already installed: it writes no custom rules and adds no dependencies.Safe to merge on its own. The
routeparagraphs name onlycreate-legacy-rulehere; #578 adds--tool.Typecheck, lint, and the full test suite pass. The changeset is in this PR, and #578 extends it.