* feat(ci): review agent on Sonnet 5 with structured, linked reviews Bump the pinned review model from claude-sonnet-4-5-20250929 to claude-sonnet-5 (verified against the pinned Claude Code 2.1.214 with subscription auth and --json-schema structured output). Restructure the published review body: verdict-first summary, findings ordered by severity, fixed section order, and every file or symbol reference as a GitHub permalink pinned to the analyzed head SHA (or the merge-base SHA for deleted and rename-old paths) instead of bare path:line text, so references are clickable and render inline previews. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * feat(ci): review agent runs as a coordinated reviewer swarm Implement the review skill's expert-lens section in CI: the main agent spawns four trusted lanes in parallel via the Task tool — correctness, security, blast-radius, and coverage — each a purpose-built persona restricted to Read/Glob/Grep plus the read-only graph MCP tools. Personas live in the canonical skill tree (mirrored to all shipped copies) and are installed into the reviewer's user-scope agents dir from the exact control SHA, so a hostile PR head can never define a lane. Lane reports are treated as unverified claims: the main agent re-anchors findings before publishing, and the publisher's context-evidence gate still requires the main conversation's own successful context call. Bash and the newer Agent tool remain disallowed for every context; the analyze timeout gets swarm headroom (45 -> 60 minutes). The workflow contract test now pins the swarm posture. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * fix(ci): sidechain tool calls can no longer satisfy the evidence gate The review agent's own review of this PR found that proveGraphReview() walked the flat transcript without reading parent_tool_use_id, so a spawned lane's context call could satisfy the publisher's graph-evidence gate the prompt reserves for the orchestrator. Entries with a non-null parent_tool_use_id are still strictly validated (malformed linkage fails the transcript) but are excluded from both candidate context calls and qualifying results; a new fixture proves sidechain-only evidence is rejected while mainline evidence beside sidechain turns still passes. Also gives the orchestrator turn headroom for the four dispatched lanes (--max-turns 100 -> 150), addressing the review's LOW finding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * refactor(skills): swarm-lane dispatch belongs to the review skill Move the lane orchestration out of the workflow prompt and into the gitnexus-review skill itself: a new "Swarm lanes" section names the four ci-persona lanes, defines when and how to dispatch them (parallel, one message, per-lane context and file slices), and owns the verification contract (lane reports are unverified claims; re-anchor, dedup, drop unanchored findings; lanes structure the work but never gate it). Any runner of the skill — the CI workflow or a local harness — now triggers the lanes from one canonical definition. The workflow prompt keeps only its CI-specific deltas: the lanes' trusted-control-SHA install provenance, the Task-tool dispatch surface, and the publisher's orchestrator-only context-evidence gate. Mirrors synced; 122 contract tests pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * feat(skills): add adversarial finder lane and critic gate to the swarm ci-adversarial-lens joins the parallel finder wave: it assumes the change is broken and constructs reachable failure scenarios — interleavings, hostile inputs, state corruption, abuse of newly exposed surfaces — each verified to a concrete entry point before it may be reported. ci-critic-lens runs last as a gate on the orchestrator's finished draft: it audits anchoring, concreteness, severity calibration, format conformance, and honesty, returning PASS or a numbered defect list with the smallest repair per item. The skill bounds it to two passes and the critic hardens the review without ever blocking it; the workflow inherits both lanes automatically through the wholesale ci-personas install. Mirrors synced across all three shipped trees; 122 contract tests pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * refactor(ci): workflow defers the whole swarm contract to the skill Now that the skill's Swarm lanes section owns dispatch, verification, the critic gate, and the fallbacks, the workflow prompt stops restating any of it. It contributes only what CI alone knows: the lanes' control-SHA install provenance, the concrete environment mapping for lane inputs (diff, manifest, head and merge-base checkouts, exact SHAs), and the one CI override — the publisher's context-evidence gate remains orchestrator-only. Analyze timeout gains headroom for the critic's sequential rounds (60 -> 75 minutes). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * fix(ci): dispatch swarm lanes via the Agent tool, not the renamed Task alias On the pinned Claude Code 2.1.214 the subagent-dispatch tool is `Agent` (`Task` was renamed to `Agent` in 2.1.63 and is now a legacy alias), and permission rules evaluate deny before allow. The workflow allowed `Task` and denied `Agent`, so the orchestrator could never dispatch a lane and every review silently fell back to the inline single-agent path while the text-only tests certified the broken config. Use `Agent` consistently: add it to --tools, allow it scoped to the six ci-personas (`Agent(ci-correctness-lens,...,ci-critic-lens)`), remove it from --disallowedTools, and update the prompt. Tests now match the scoped allowlist on the raw string (commas inside Agent(...) break a split) and assert Agent is no longer bare-denied. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * fix(ci): harden swarm permissions — allow Glob/Grep + merge-base reads, quarantine PR-head agents Three permission-hygiene gaps around the swarm dispatch: - Glob/Grep were in --tools but had no allow rule, so the lanes' declared tools could manufacture denied-tool errors; allow them (read-only, sandboxed by cwd + add-dir). - The prompt hands lanes the merge-base source checkout for deleted / rename-old symbols, but no Read rule covered it; add a scoped Read() allow (which grants access without triggering --add-dir agent discovery). - The --add-dir PR-head copy is scanned for spawnable agent definitions and the pinned runtime has no suppression env, so a PR could ship its own .claude/agents/*.md. Drop that subtree from the materialized copy after checkout-index (skills left intact), so only the trusted control-SHA personas can ever be dispatched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * test(ci): pin the Agent allowlist to the ci-personas; require a dispatch canary A text-only assertion cannot prove the pinned CLI actually dispatches the lanes (print mode silently ignores invalid settings and does not validate Agent(type) content at parse time) — that is what let the original Task/Agent inversion pass CI. Two mitigations for the class: - A cross-consistency test asserts the six names in the Agent(...) allowlist equal the six ci-personas filenames and each persona's frontmatter name, so a rename or typo in any of the three fails without auth. - The activation checklist now requires the post-merge canary to prove a positive dispatch AND an unlisted-type refusal before enabling the trigger. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * fix(ci): bound swarm transcript volume with per-persona maxTurns The six lanes stream into the single execution transcript the publisher validates, but the personas carried no turn budget, so a large-PR swarm run could overflow the (hard-throw) transcript caps and brick a valid review. Bound each lane deterministically — finders maxTurns 12, the critic maxTurns 6 — which keeps the worst case (~2×(150+5×12+2×6) ≈ 444 messages) under the unchanged 1_000 cap, so no cap needs raising. A new test encodes that invariant: it fails if a persona's maxTurns is bumped without revisiting the cap. Applied byte-identically across all four shipped skill trees. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * test(ci): independently pin both sidechain evidence-gate guards The sidechain-exclusion guards at candidate registration and result acceptance were mutually redundant on realistic transcripts (a real sidechain turn carries parent_tool_use_id on both its call and result), so deleting either guard alone still passed the whole suite. Add two asymmetric cross-wired fixtures — a mainline call with a sidechain result (pins the acceptance guard) and a sidechain call with a mainline result (pins the registration guard), both expecting missing_graph_evidence. Mutation-verified: deleting either guard alone now reddens the suite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * docs(skills): require own evidence before dispatch; document critic fail-open and swarm naming Strengthen the gitnexus-review "Swarm lanes" contract (all four mirrors): - The orchestrator must make its own graph context call on a changed symbol before dispatching any lane, so a fully-delegated run cannot leave the publisher's evidence gate unsatisfied (mirrored into the workflow prompt, with a test pinning the ordering phrase). - Document that the critic's fail-open is deliberate (bounded to two passes, cannot deadlock, review still gated by evidence + schema), and distinguish it from the hard lane-7 gate in the separate gitnexus-pr-swarm-review skill. - Give a concrete local-harness registration pointer for ci-personas. - Add a reciprocal cross-reference in gitnexus-pr-swarm-review (single path — that skill is not part of the mirrored family). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * docs: record the review-agent swarm capability (AGENTS.md, CLAUDE.md, reviewer-swarm README) Reflect the shipped swarm in the standing docs: bump AGENTS.md to 1.14.0 and CLAUDE.md to 1.8.0 with changelog rows, extend the gitnexus-review description to mention the ci-personas swarm lanes, and refresh the reviewer-swarm README so its differentiator names the real distinction (interactive on-demand swarm vs the CI review agent's in-workflow lanes) now that both run swarms. No CHANGELOG.md edit (feature-PR rule). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * fix(ci): close pre-push review findings on the swarm permission change Adversarial review of the fix diff caught two issues introduced by the permission-hygiene commit: - Bare Glob/Grep in --allowedTools are separate tools that the Read()-scoped path denies (/proc, github.workspace, ...) do not cover, opening an undenied read path to the raw checkouts and host paths via a prompt- injected lane. Drop the bare allow — under dontAsk they stay denied by omission; lanes read via the scoped Read() rules and the graph MCP. - The agents quarantine removed only the add-dir root's .claude/agents; make it recursive so a nested (e.g. monorepo subpackage) .claude/agents cannot survive and be discovered. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ * feat(ci): post an "in progress" marker while the review swarm runs Swarm reviews can take up to 75 minutes, and until now the PR showed no sign a review was running. Add a dedicated write-scoped `acknowledge` job that, under the same authorization gate as analyze, upserts a per-PR "🔄 GitNexus review in progress" sticky comment linking to the live run (and reacts 👀 to the trigger comment); the publisher removes that marker when the review — or a clean failure — posts. The marker lives in its own job so the model-facing analyze job stays secretless and read-only: it cannot post to the PR, so per-lane live progress isn't exposed there — the marker is a binary "running" state with a link to the Actions run where lane-by-lane progress is visible. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
13 KiB
Last reviewed: 2026-07-16
Project: GitNexus · Environment: dev · Maintainer: repository maintainers (see GitHub)
Scope
| Boundary | Rule |
|---|---|
| Reads | gitnexus/, gitnexus-web/, eval/, plugin packages, .github/, .gitnexus/, docs. |
| Writes | Only paths required for the change; keep diffs minimal. Update lockfiles when deps change. |
| Executes | npm, npx, node under gitnexus/ and gitnexus-web/; uv run for Python under eval/; documented CI/dev workflows. |
| Off-limits | Real .env / secrets, production credentials, unrelated repos, destructive git ops without confirmation. |
Model Configuration
- Primary: Use a named model (e.g. Claude Sonnet 4.x). Avoid
Autoor unversionedlatestwhen reproducibility matters. - Notes: The GitNexus CLI indexer does not call an LLM.
Execution Sequence (complex tasks)
For multi-step work, state up front:
- Which rules in this file and GUARDRAILS.md apply (and any relevant Signs).
- Current Scope boundaries.
- Which validation commands you will run (
cd gitnexus && npm test,npx tsc --noEmit).
On long threads, "Remember: apply all AGENTS.md rules" re-weights these instructions against context dilution.
Claude Code hooks
PreToolUse hooks can block tools (e.g. git_commit) until checks pass. Adapt to this repo: cd gitnexus && npm test before commit.
Context budget
Commands and gotchas live under Repo reference below and in CONTRIBUTING.md. If always-on rules grow, split into .cursor/rules/*.mdc (globs). Cursor: project-wide rules in .cursor/index.mdc. Claude Code: load STANDARDS.md only when needed.
Reference docs
- ARCHITECTURE.md, CONTRIBUTING.md, GUARDRAILS.md
- Call & inheritance resolution (RFC #909 Ring 3): See ARCHITECTURE.md § Scope-Resolution Pipeline. All languages resolve calls and inheritance through the scope-resolution pipeline (
Registry.lookup,preEmitInheritanceEdges,emitHeritageEdges,buildMro→MethodDispatchIndex). Shared code ingitnexus/src/core/ingestion/must not name languages — plug language behavior in viaLanguageProvider/ScopeResolverhooks. A language plugs in by implementingScopeResolver(scope-resolution/contract/scope-resolver.ts) and registering it inSCOPE_RESOLVERS. (The legacy call-resolution DAG +@heritagecapture path were removed in RING4-1 #942.) - Cursor:
.cursor/index.mdc(always-on);.cursor/rules/*.mdc(glob-scoped). Legacy.cursorrulesdeprecated. - GitNexus: standard skills in
.claude/skills/gitnexus-*/; MCP rules ingitnexus:startblock below.
PR Swarm Review (cross-CLI)
To run a production-readiness review of a GitNexus pull request from any AI CLI, follow
the canonical, CLI-neutral spec pr-swarm-review/orchestration.md
(seven read-only review personas under pr-swarm-review/personas/). It defines two
execution modes with the same output contract: Swarm mode (parallel subagents, e.g.
Claude Code) and Solo mode (one agent runs all lanes sequentially — Codex, Gemini,
Cursor, Copilot, or any agent reading this file). Per-CLI entrypoints are thin wrappers
listed in pr-swarm-review/README.md; edit review logic only
in the canonical files, never in the wrappers. The review is read-only — it never edits,
commits, or posts.
Engineering planning & execution (/gitnexus-plan · /gitnexus-work · /gitnexus-review · /gitnexus-lfg)
Four canonical, CLI-neutral skill specs under .claude/skills/ (Claude Code invokes
them as slash commands; Codex or any other agent reading this file should read the
named SKILL.md and follow it directly — user-level Codex prompts are documented in the
plan/work/lfg skill READMEs):
gitnexus-plan/SKILL.md— deep, implementation-ready plan for a code change: GitNexus graph intelligence for navigation, statement-level PDG slices for behavioral constraints, targeted source reads for verification. Output lands indocs/plans/with a reusable implementation context pack (section 11). Planning-only — it never edits code (index freshness refreshes viaanalyze --index-onlyare the one permitted state change). Interactive runs ask up front how deep to go (quick / standard / deep); Deepen mode strengthens an existing plan in place.gitnexus-work/SKILL.md— executes a gitnexus-plan as verified atomic commits: drift-checks the plan's evidence pin against HEAD,impactbefore every symbol edit, tests from the plan's scenarios,detect_changesbefore every commit.gitnexus-review/SKILL.md— read-only GitNexus review of a PR URL/number, branch or commit range, or local staged/unstaged/untracked changes. It pins exact SHAs, aligns the graph and checkout, runs a PDG-backed taint pass on trust-boundary diffs, scales to per-domain expert lenses from the graph's clusters (dispatched as parallel swarm lanes —ci-personas/— when the CI review agent runs it), and reports evidence-backed findings.gitnexus-lfg/SKILL.md— pipeline orchestrator: plan (depth asked up front) → blocking user gate (proceed or stop) → work →gitnexus-review.
The family ships with the npm package (gitnexus/skills/, installed to editor targets
by gitnexus setup) and the Claude Code plugin; review also has a standalone Cursor
mirror. gitnexus/test/unit/shipped-skills-sync.test.ts guards the copies. Token savings of the workflow are measurable with
eval/workflow_bench/ (real headless CLI runs, free-model routing supported — see its README).
Changelog
| Date | Version | Change |
|---|---|---|
| 2026-07-20 | 1.14.0 | gitnexus-review gains a coordinated swarm: six ci-personas/ lanes the CI review agent dispatches as subagents (via the Agent tool), with a bounded critic gate and sidechain-excluded evidence. |
| 2026-07-16 | 1.13.0 | gitnexus-plan asks plan depth up front (quick/standard/deep) in interactive runs; gitnexus-lfg gate slimmed to proceed/stop (Deepen stays as the route-back mechanism). |
| 2026-07-16 | 1.12.0 | Renamed gitnexus-pr-review to gitnexus-review; added PR URL/number, branch/range, and local-change targets plus install migration (setup warns on a legacy gitnexus-pr-review dir and leaves it in place; uninstall removes it). |
| 2026-07-11 | 1.11.0 | Skill family shipped via npm skills/ + plugin (sync-guarded); added eval/workflow_bench token-savings benchmark. |
| 2026-07-11 | 1.10.0 | Added gitnexus-work (plan executor) and gitnexus-lfg (plan → deepen/work gate → review pipeline) skills; section renamed to Engineering planning & execution. |
| 2026-07-11 | 1.9.0 | Added Engineering planning (/gitnexus-plan) section; registered the gitnexus-plan skill (.claude/skills/gitnexus-plan/). |
| 2026-05-22 | 1.8.0 | Kotlin added to MIGRATED_LANGUAGES (registry-primary call resolution by default). Closes #1756 (companion-vs-instance dispatch) and #1757 (lambda scopes); refs #1746. RFC §6.4 corpus criterion waived (corpus-mode wiring is #927-scope); fixture criterion met. |
| 2026-04-23 | 1.7.0 | TypeScript added to MIGRATED_LANGUAGES (registry-primary call resolution by default). |
| 2026-04-20 | 1.6.0 | Added scope-resolution pipeline pointer (RFC #909 Ring 3); Python migrated to registry-primary. |
| 2026-04-19 | 1.5.0 | Cross-repo impact (#794): impact/query/context accept repo: "@<group>" + service. Removed group_query/group_contracts/group_status MCP tools; added gitnexus://group/{name}/contracts and gitnexus://group/{name}/status resources. |
| 2026-04-16 | 1.4.0 | Fixed: web UI description, pre-commit behavior, MCP tools (7->16), added gitnexus-shared, removed stale vite-plugin-wasm gotcha. |
| 2026-04-13 | 1.3.0 | Updated GitNexus index stats after DAG refactor. |
| 2026-03-24 | 1.2.0 | Fixed gitnexus:start block duplication. |
| 2026-03-23 | 1.1.0 | Updated agent instructions, references, Cursor layout. |
| 2026-03-22 | 1.0.0 | Initial structured header and changelog. |
GitNexus — Code Intelligence
This project is indexed by GitNexus as GitNexus (20319 symbols, 54304 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
Index stale? Run
node .gitnexus/run.cjs analyzefrom the project root — it auto-selects an available runner. No.gitnexus/run.cjsyet?npx gitnexus analyze(npm 11 crash →npm i -g gitnexus; #1939).
Always Do
- MUST run impact analysis before editing any symbol. Before modifying a function, class, or method, run
impact({target: "symbolName", direction: "upstream"})and report the blast radius (direct callers, affected processes, risk level) to the user. - MUST run
detect_changes()before committing to verify your changes only affect expected symbols and execution flows. For regression review, compare against the default branch:detect_changes({scope: "compare", base_ref: "main"}). - MUST warn the user if impact analysis returns HIGH or CRITICAL risk before proceeding with edits.
- When exploring unfamiliar code, use
query({search_query: "concept"})to find execution flows instead of grepping. It returns process-grouped results ranked by relevance. - When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use
context({name: "symbolName"}). - For security review,
explain({target: "fileOrSymbol"})lists taint findings (source→sink flows; needsanalyze --pdg).
Never Do
- NEVER edit a function, class, or method without first running
impacton it. - NEVER ignore HIGH or CRITICAL risk warnings from impact analysis.
- NEVER rename symbols with find-and-replace — use
renamewhich understands the call graph. - NEVER commit changes without running
detect_changes()to check affected scope.
Resources
| Resource | Use for |
|---|---|
gitnexus://repo/GitNexus/context |
Codebase overview, check index freshness |
gitnexus://repo/GitNexus/clusters |
All functional areas |
gitnexus://repo/GitNexus/processes |
All execution flows |
gitnexus://repo/GitNexus/process/{name} |
Step-by-step execution trace |
CLI
| Task | Read this skill file |
|---|---|
| Understand architecture / "How does X work?" | .claude/skills/gitnexus-exploring/SKILL.md |
| Blast radius / "What breaks if I change X?" | .claude/skills/gitnexus-impact-analysis/SKILL.md |
| Trace bugs / "Why is X failing?" | .claude/skills/gitnexus-debugging/SKILL.md |
| Rename / extract / split / refactor | .claude/skills/gitnexus-refactoring/SKILL.md |
| Tools, resources, schema reference | .claude/skills/gitnexus-guide/SKILL.md |
| Index, status, clean, wiki CLI commands | .claude/skills/gitnexus-cli/SKILL.md |
Repo reference
Packages
| Package | Path | Purpose |
|---|---|---|
| CLI/Core | gitnexus/ |
TypeScript CLI, indexing pipeline, MCP server. Published to npm. |
| Web UI | gitnexus-web/ |
React/Vite thin client. All queries via gitnexus serve HTTP API. |
| Shared | gitnexus-shared/ |
Shared TypeScript types and constants. |
| Claude Plugin | gitnexus-claude-plugin/ |
Static config for Claude marketplace. |
| Cursor Integration | gitnexus-cursor-integration/ |
Static config for Cursor editor. |
| Eval | eval/ |
Python evaluation harness (Docker + LLM API keys). |
Running services
cd gitnexus && npm run dev # CLI: tsx watch mode
cd gitnexus-web && npm run dev # Web UI: Vite on port 5173
npx gitnexus serve # HTTP API on port 4747 (from any indexed repo)
Testing
CLI / Core (gitnexus/)
npm test— full vitest suite (~2000 tests)npm run test:unit— unit tests onlynpm run test:integration— integration (~1850 tests). LadybugDB file-locking tests may fail in containers (known env issue).npx tsc --noEmit— typecheck
Web UI (gitnexus-web/)
npm test— vitest (~200 tests)npm run test:e2e— Playwright (7 spec files; requiresgitnexus serve+npm run dev)npx tsc -b --noEmit— typecheck
Pre-commit hook (.husky/pre-commit): formatting (prettier via lint-staged) + typecheck for staged packages. Tests do not run in pre-commit — CI only.
Gotchas
npm installingitnexus/triggersprepare(builds viatsc) andpostinstall(materializes the vendored grammars intonode_modules/, then prefers a committed prebuild per platform-arch and only source-builds when none matches). A C/C++ toolchain (python3,make,g++) is needed only for that source-build fallback.- The vendored grammars
tree-sitter-{c,dart,proto,swift,kotlin}are handled uniformly: c is required; dart/proto/swift/kotlin are optional and skippable viaGITNEXUS_SKIP_OPTIONAL_GRAMMARS=1. Install warnings appear only when no prebuild matches the platform-arch and no toolchain is present, and are non-fatal — only that language's parsing is unavailable. - ESLint configured via
eslint.config.mjs(TS, React Hooks, unused-imports). Nonpm run lintscript; usenpx eslint .. Prettier runs via lint-staged. CI checks both inci-quality.yml.