Skip to content

chore(tooling): adopt Oxlint and Oxfmt - #8930

Merged
cv merged 35 commits into
mainfrom
chore/ultracite-anti-slop
Aug 13, 2026
Merged

chore(tooling): adopt Oxlint and Oxfmt#8930
cv merged 35 commits into
mainfrom
chore/ultracite-anti-slop

Conversation

@cv

@cv cv commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

This change replaces Biome with direct Oxlint and Oxfmt contributor checks. It preserves existing lint boundaries, adds type-aware plugin validation, and formats only added source files to avoid a repository-wide rewrite.

Changes

  • Add Oxlint 1.78.0, Oxfmt 0.63.0, and matching type-aware Oxlint dependencies to the root and plugin projects. Preserve selected ignore patterns and formatter behavior in NemoClaw-owned configuration.
  • Port the existing lint contract to oxlint.config.ts, including SonarJS cognitive-complexity limits and plugin-specific TypeScript rules. Current SonarJS scores preserve existing hotspot limits while rejecting further growth.
  • Add oxlint.type-aware.config.ts so plugin checks enforce typescript/no-floating-promises without adding type-aware cost to the general lint pass.
  • Add an incremental Oxfmt hook for added source files. A repository-wide rewrite would change hundreds of existing files and exceed current test-file budgets.
  • Replace Biome hook commands and suppression directives, refresh the locked npm cache seed, and update contributor guidance and dependency review records.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification: package contracts, plugin coverage, migration-state coverage, locked-cache contracts, normal hook execution, and focused Oxc probes passed.
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: no end-user runtime behavior changed; AGENTS.md, CONTRIBUTING.md, and tools/lint/DEPENDENCY-REVIEW.md document contributor behavior.
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification:
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: Reviewed AGENTS.md, CONTRIBUTING.md, and tools/lint/DEPENDENCY-REVIEW.md. Contributor guidance matches the direct Oxlint and Oxfmt package declarations, hook configuration, NemoClaw-owned Oxc configs, lockfiles, and package contracts. No public docs/ update is needed because supported runtime behavior does not change.
  • Agent: Pi CLI

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit:
  • Station profile/scenario:
  • Result:
  • Supporting evidence:

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run validate:pr passed after refreshing origin/main when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — Clean root and plugin npm ci --ignore-scripts installs passed without Ultracite; npm run lint, npm --prefix nemoclaw run check, and npm run typecheck:cli passed; package contracts passed 406/406; cache seed image contracts passed 13/13; full pre-commit, plugin coverage, normal commit and pre-push hooks passed; npm run docs passed with 0 errors and 2 existing Fern upgrade warnings.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — the combined broad baseline and standalone CLI coverage each exceeded the 300-second host limit; GitHub CI owns the remaining broad result.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Carlos Villela cvillela@nvidia.com

@cv cv self-assigned this Aug 12, 2026
@copy-pr-bot

copy-pr-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6c2e4210-4ecd-4cc9-aed8-59694425cb58

📥 Commits

Reviewing files that changed from the base of the PR and between e6d2b03 and cc94705.

📒 Files selected for processing (1)
  • ci/test-file-size-budget.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • ci/test-file-size-budget.json

📝 Walkthrough

Walkthrough

The repository replaces Biome with Oxfmt and Oxlint, adds added-file formatter and lint scripts, introduces an anti-slop Oxlint plugin, updates documentation and dependencies, and refreshes the npm cache manifest.

Changes

Toolchain migration

Layer / File(s) Summary
Toolchain configuration
.pre-commit-config.yaml, package.json, nemoclaw/package.json, oxfmt.config.ts, oxlint*.ts, AGENTS.md, CONTRIBUTING.md, src/lib/..., test/...
Repository scripts, hooks, dependencies, documentation, and formatter suppressions now use Oxfmt and Oxlint.
Added-file formatter and linter
tools/lint/*.sh
The scripts resolve a Git base reference, select added JavaScript and TypeScript files, reject unsafe paths and symlinks, and run Oxfmt or Oxlint.
Anti-slop plugin rules
tools/oxlint/anti-slop/*
The vendored plugin registers rules for type safety, assertions, widening, mocking, reflection, runtime typing, symbol names, and unsafe dictionary contracts.
Dependency cache and maintenance updates
tools/mcp-tool-discovery-runtime/npm-cache-seed/manifest.json, tools/lint/DEPENDENCY-REVIEW.md, ci/test-file-size-budget.json, nemoclaw/src/commands/migration-state.test.ts
The cache manifest adds the new tool archives and updates its lock hash. Related dependency, test-budget, and import maintenance records are updated.

Estimated code review effort: 4 (Complex) | ~45 minutes

Mergeability Score: 🟡 Moderate · up to cc947

The change updates contributor linting and formatting enforcement, but an applicable broad validation gate has not passed because the manual coverage hook exceeded the 300-second host limit. Merge readiness remains moderate until the gate completes successfully or an explicit maintainer waiver is recorded.

Sequence Diagram(s)

sequenceDiagram
  participant PreCommit
  participant AddedFileScripts
  participant OxfmtOxlint
  PreCommit->>AddedFileScripts: run added-file formatter or linter
  AddedFileScripts->>AddedFileScripts: resolve base revision and select files
  AddedFileScripts->>OxfmtOxlint: pass added JavaScript and TypeScript files
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.95% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main tooling change from Biome to Oxlint and Oxfmt.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/ultracite-anti-slop

Comment @coderabbitai help to get the list of available commands.

@github-code-quality

github-code-quality Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 43d263c in the chore/ultracite-anti... branch remains at 96%, unchanged from commit 7aba3cc in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 43d263c in the chore/ultracite-anti... branch remains at 82%, unchanged from commit 7aba3cc in the main branch.

Show a code coverage summary of the most impacted files.
File main 7aba3cc chore/ultracite-anti... 43d263c +/-
src/lib/cua/bounded-file.ts 94% 84% -10%
src/lib/cua/run...ime-manifest.ts 91% 84% -7%
src/lib/cua/contract.ts 87% 80% -7%
src/lib/messagi.../ilink-login.ts 96% 89% -7%
src/lib/onboard...file-builder.ts 95% 91% -4%
src/lib/state/o...d-checkpoint.ts 90% 87% -3%
src/lib/onboard.ts 33% 33% 0%
src/lib/onboard...press-resume.ts 78% 82% +4%
src/lib/agent/dashboard-ui.ts 91% 98% +7%
src/lib/onboard...der/snapshot.ts 75% 83% +8%

Updated August 13, 2026 09:22 UTC

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: Review the warnings below.
Findings: 0 blockers · 1 warning · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · medium confidence · 0 blockers · 1 warning · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Failed after a partial review · low confidence · 0 blockers · 2 warnings · 0 suggestions

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

2 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • established — added file at .pre-commit-config.yaml:116: Keep “added file” for the formatter-selection condition. CONTRIBUTING.md states the base-commit contrast.
  • define — type-aware at .pre-commit-config.yaml:163: Define the term where contributor guidance first names it, as AGENTS.md does, and retain the scope and enforced rule.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite for the commit under review.

Recommended E2E: managed-image-protected-runtime, inference-routing

Manual-only E2E: cloud-onboard, managed-image-multiarch-startup, security-posture, messaging-providers, onboard-repair, onboard-resume, sandbox-operations, skill-agent, token-rotation, channels-add-remove, whatsapp-qr-compact, cloud-inference, network-policy
The manual PR workflow does not run these selectors for the commit under review. Run them from reviewed code on main.

3 optional E2E recommendations
  • rebuild-openclaw
  • sandbox-survival
  • openclaw-tui-chat-correlation
1 warning · 0 suggestions

Warnings

Warnings do not block.

PRA-1 Warning — Add regression coverage for formatter file selection

  • Location: tools/lint/format-added-files.sh:20
  • Category: tests
  • Problem: The new formatter wrapper has no checked-in test for its base-commit selection and rejection paths.
  • Impact: A future change can format modified files, accept an unsafe candidate path, or continue after an unavailable base ref without a focused regression failure.
  • Recommendation: Add a focused wrapper test that stubs Git and Oxfmt. Verify added TypeScript selection, modified-file exclusion, unavailable-base exit status 2, and traversal and symbolic-link rejection.
  • Verification: Inspect the wrapper test and confirm it invokes the script with controlled Git output for each listed path.
  • Test coverage: A deterministic test for tools/lint/format-added-files.sh that verifies added-file selection and the unavailable-base, traversal, and symbolic-link rejection paths.
  • Evidence: tools/lint/format-added-files.sh:20-65 introduces base-ref resolution, candidate validation, added-file selection, and the Oxfmt invocation. The static test inventory lists no test that references format-added-files, Oxfmt, or Oxlint; the nearby cache-seed contract covers archive integrity only.

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

@cv
cv marked this pull request as ready for review August 12, 2026 23:47

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (6)
tools/oxlint/anti-slop/shared/dictionary-types.ts (1)

78-88: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Note the ancestor rescan cost in shouldReportType's caller contract.

shouldReportType (in tools/oxlint/anti-slop/rules/no-unsafe-dictionary-type.ts) calls classifyUnsafeDictionary once per ancestor type node. classifyUnsafeDictionary performs full alias and substitution resolution through this shared module. For deeply nested generic type expressions, the plugin repeats the same resolution work at every nesting level.

This cost is upstream behavior and it is bounded by file size, so it does not block the migration. Record it as a known lint-runtime cost, and measure Oxlint duration on the largest TypeScript files in the repository before enabling these rules repository-wide.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/oxlint/anti-slop/shared/dictionary-types.ts` around lines 78 - 88,
Record the repeated ancestor-rescan cost of shouldReportType calling
classifyUnsafeDictionary as a known lint-runtime limitation, and benchmark
Oxlint duration on the repository’s largest TypeScript files before enabling
these rules repository-wide. Do not change the shared dictionary classification
logic or its current bounded behavior.
tools/oxlint/anti-slop/rules/no-unsafe-dictionary-type.ts (1)

15-57: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

typeNodeKinds duplicates AST knowledge that can drift.

The set enumerates TypeScript type node kinds by hand. isTypeNode uses it, and shouldReportType uses isTypeNode to suppress duplicate reports on nested type nodes. If a future @oxlint/plugins version adds a type node kind, that kind is absent here, suppression stops, and the rule reports the same dictionary at more than one nesting level.

The consequence is duplicate diagnostics, not a crash. This file is vendored, so do not edit it locally. Add the drift risk to the vendored-upgrade checklist in tools/oxlint/anti-slop/UPSTREAM.md.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/oxlint/anti-slop/rules/no-unsafe-dictionary-type.ts` around lines 15 -
57, Add the AST type-node drift risk to the vendored-upgrade checklist in
UPSTREAM.md, noting that manually maintained typeNodeKinds can become incomplete
when `@oxlint/plugins` adds new TypeScript node kinds and cause duplicate
diagnostics through isTypeNode and shouldReportType. Do not modify the vendored
no-unsafe-dictionary-type.ts file.
tools/oxlint/anti-slop/rules/no-known-value-widening.ts (1)

32-43: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

resolveVariable can resolve to an unrelated same-named binding.

The function walks the scope chain and matches on identifier.name from scope.set. It does not use the resolved reference recorded by the scope manager. If an inner scope does not declare the name but an outer scope declares a different variable with the same name, the lookup returns that outer variable.

The sibling rule tools/oxlint/anti-slop/rules/no-widen-then-assert.ts resolves identifiers through scopeManager references instead, which is precise. This file is vendored, so keep it aligned with upstream rather than patching it locally. Track the difference as a known false-positive source for no-known-value-widening.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/oxlint/anti-slop/rules/no-known-value-widening.ts` around lines 32 -
43, Do not modify resolveVariable’s scope-chain lookup in this vendored file.
Record this same-name binding mismatch as a known false-positive source for
no-known-value-widening, and track the fix against upstream by aligning with the
scopeManager-reference resolution used by no-widen-then-assert.ts.
tools/oxlint/anti-slop/rules/no-widen-then-assert.ts (2)

174-192: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Record the linear reference scan as a lint-runtime cost.

resolvedVariableForIdentifier iterates every scope and runs find over each scope's references, matching by source offsets. checkAssertion calls it for every TSAsExpression and TSTypeAssertion, and knownValueEvidence calls it again for each identifier hop. The total work therefore scales with assertions multiplied by references in the file.

Assertion-dense files make this the slowest part of the rule. The file is vendored, so do not optimize it here. Measure Oxlint duration on the largest assertion-heavy TypeScript files before you enable no-widen-then-assert repository-wide, and prefer an offset-keyed lookup map upstream.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/oxlint/anti-slop/rules/no-widen-then-assert.ts` around lines 174 - 192,
Measure Oxlint runtime on the largest assertion-heavy TypeScript files before
enabling no-widen-then-assert repository-wide, accounting for repeated scans in
checkAssertion and knownValueEvidence through resolvedVariableForIdentifier. Do
not optimize the vendored resolvedVariableForIdentifier implementation here;
instead, document or report the measured cost and recommend an upstream
offset-keyed lookup map.

42-85: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Record, Readonly, and PropertyKey are matched by name without a shadowing check.

isBroadRecordKeyType and isBroadRecordType compare the type reference name directly. A file that declares its own Record, Readonly, or PropertyKey type still matches, so the rule can classify a narrow local type as broad and report a false positive.

tools/oxlint/anti-slop/shared/dictionary-types.ts handles this case with shadowedBuiltIns and isBuiltIn. The two rules therefore disagree on the same question. Keep this vendored file aligned with upstream, and raise the inconsistency upstream instead of patching it locally.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/oxlint/anti-slop/rules/no-widen-then-assert.ts` around lines 42 - 85,
Update isBroadRecordKeyType and isBroadRecordType to use the vendored upstream
shadowing-aware built-in detection, including shadowedBuiltIns and isBuiltIn,
before matching PropertyKey, Readonly, or Record. Keep behavior aligned with
tools/oxlint/anti-slop/shared/dictionary-types.ts and do not implement a
local-only workaround; raise the inconsistency upstream instead.
tools/oxlint/anti-slop/UPSTREAM.md (1)

6-10: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the vendored-copy refresh procedure.

Add the commands to update dmmulroy/anti-slop and record the responsible owner. The TypeScript files match the cited commit apart from the SPDX header and its blank separator line.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/oxlint/anti-slop/UPSTREAM.md` around lines 6 - 10, Update the
vendored-copy documentation in UPSTREAM.md to include the commands for
refreshing the dmmulroy/anti-slop sources and identify the responsible owner.
Preserve the stated commit, SPDX-header exception, blank separator line, and
upstream license details.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@oxlint.config.ts`:
- Around line 161-162: Update the lint configuration around
typescript/no-floating-promises so it is either backed by compatible type-aware
linting with oxlint-tsgolint pinned in the lockfile, or remove the rule when
type-aware support is not available; ensure the final configuration does not
retain an unsupported type-aware rule.

In `@tools/lint/format-added-files.sh`:
- Around line 7-15: Update the mode-parsing logic in the script before the
existing shift so it only evaluates and removes the first argument when at least
one argument was provided. Preserve the --check/--write validation and default
mode behavior, while allowing no-argument execution to continue to candidate
discovery without triggering shift failure.
- Around line 17-20: Update the base-ref resolution in the format-added-files
script to fail closed when the configured ref cannot be resolved, rather than
falling back to HEAD and producing an empty diff. Ensure the script exits with a
clear error unless it can resolve a valid base or merge base, and add a
regression test covering a clean PR checkout where origin/main is unavailable.
- Around line 33-43: Update the candidate filtering loop around candidates and
added_files to resolve each file against the repository root, reject absolute or
traversal paths that escape that root, and only then perform the file-type and
git cat-file checks. Preserve valid repository-relative formatter paths and
continue excluding unsupported extensions.

In `@tools/oxlint/anti-slop/rules/no-conditional-empty-object-spread.ts`:
- Around line 15-24: Update isConditionalEmptyObjectSpread to unwrapParentheses
on both conditional.consequent and conditional.alternate before passing them to
isEmptyObjectExpression, so parenthesized empty-object branches are detected.
Add a RuleTester case covering condition ? value : ({}).

---

Nitpick comments:
In `@tools/oxlint/anti-slop/rules/no-known-value-widening.ts`:
- Around line 32-43: Do not modify resolveVariable’s scope-chain lookup in this
vendored file. Record this same-name binding mismatch as a known false-positive
source for no-known-value-widening, and track the fix against upstream by
aligning with the scopeManager-reference resolution used by
no-widen-then-assert.ts.

In `@tools/oxlint/anti-slop/rules/no-unsafe-dictionary-type.ts`:
- Around line 15-57: Add the AST type-node drift risk to the vendored-upgrade
checklist in UPSTREAM.md, noting that manually maintained typeNodeKinds can
become incomplete when `@oxlint/plugins` adds new TypeScript node kinds and cause
duplicate diagnostics through isTypeNode and shouldReportType. Do not modify the
vendored no-unsafe-dictionary-type.ts file.

In `@tools/oxlint/anti-slop/rules/no-widen-then-assert.ts`:
- Around line 174-192: Measure Oxlint runtime on the largest assertion-heavy
TypeScript files before enabling no-widen-then-assert repository-wide,
accounting for repeated scans in checkAssertion and knownValueEvidence through
resolvedVariableForIdentifier. Do not optimize the vendored
resolvedVariableForIdentifier implementation here; instead, document or report
the measured cost and recommend an upstream offset-keyed lookup map.
- Around line 42-85: Update isBroadRecordKeyType and isBroadRecordType to use
the vendored upstream shadowing-aware built-in detection, including
shadowedBuiltIns and isBuiltIn, before matching PropertyKey, Readonly, or
Record. Keep behavior aligned with
tools/oxlint/anti-slop/shared/dictionary-types.ts and do not implement a
local-only workaround; raise the inconsistency upstream instead.

In `@tools/oxlint/anti-slop/shared/dictionary-types.ts`:
- Around line 78-88: Record the repeated ancestor-rescan cost of
shouldReportType calling classifyUnsafeDictionary as a known lint-runtime
limitation, and benchmark Oxlint duration on the repository’s largest TypeScript
files before enabling these rules repository-wide. Do not change the shared
dictionary classification logic or its current bounded behavior.

In `@tools/oxlint/anti-slop/UPSTREAM.md`:
- Around line 6-10: Update the vendored-copy documentation in UPSTREAM.md to
include the commands for refreshing the dmmulroy/anti-slop sources and identify
the responsible owner. Preserve the stated commit, SPDX-header exception, blank
separator line, and upstream license details.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 440573cb-0d1f-4618-b0b1-ff51098a3f98

📥 Commits

Reviewing files that changed from the base of the PR and between 9584e94 and 337b002.

⛔ Files ignored due to path filters (2)
  • nemoclaw/package-lock.json is excluded by !**/package-lock.json
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (142)
  • .pre-commit-config.yaml
  • AGENTS.md
  • CONTRIBUTING.md
  • biome.json
  • ci/test-file-size-budget.json
  • nemoclaw/package.json
  • nemoclaw/src/commands/migration-state.test.ts
  • oxfmt.config.ts
  • oxlint.anti-slop.config.ts
  • oxlint.config.ts
  • package.json
  • scripts/checks/run.mts
  • src/lib/onboard.ts
  • src/lib/onboard/credential-navigation.ts
  • test/anti-slop-rules.test.ts
  • test/format-added-files.test.ts
  • test/mcp-tool-discovery-image-contract.test.ts
  • test/nemoclaw-start-extra-placeholder-breadcrumb-helpers.ts
  • test/onboard-inference-reconciliation.test.ts
  • test/onboard-messaging.test.ts
  • tools/e2e/hermes-gpu-startup-workflow-boundary.mts
  • tools/lint/format-added-files.sh
  • tools/lint/lint-added-files.sh
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/acorn-8.18.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/ansi-escapes-7.3.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/ansi-regex-6.3.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/ansi-styles-6.2.3.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/binding-linux-x64-gnu-0.63.0.tgz.part-000
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/binding-linux-x64-gnu-0.63.0.tgz.part-001
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/binding-linux-x64-gnu-1.78.0.tgz.part-000
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/binding-linux-x64-gnu-1.78.0.tgz.part-001
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/binding-linux-x64-gnu-1.78.0.tgz.part-002
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/binding-linux-x64-gnu-1.78.0.tgz.part-003
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/biome-2.4.14.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/braces-3.0.3.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/citty-0.2.2.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-cursor-5.0.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-2.4.14.tgz.part-000
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-2.4.14.tgz.part-001
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-2.4.14.tgz.part-002
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-2.4.14.tgz.part-003
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-2.4.14.tgz.part-004
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-2.4.14.tgz.part-005
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-2.4.14.tgz.part-006
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-2.4.14.tgz.part-007
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-2.4.14.tgz.part-008
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-2.4.14.tgz.part-009
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-2.4.14.tgz.part-010
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-musl-2.4.14.tgz.part-000
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-musl-2.4.14.tgz.part-001
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-musl-2.4.14.tgz.part-002
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-musl-2.4.14.tgz.part-003
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-musl-2.4.14.tgz.part-004
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-musl-2.4.14.tgz.part-005
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-musl-2.4.14.tgz.part-006
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-musl-2.4.14.tgz.part-007
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-musl-2.4.14.tgz.part-008
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-musl-2.4.14.tgz.part-009
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-linux-x64-musl-2.4.14.tgz.part-010
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/cli-truncate-6.1.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/commander-15.0.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/confbox-0.1.8.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/core-1.4.3.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/deepmerge-4.3.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/empathic-2.0.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/environment-1.1.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/execa-10.0.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/fast-glob-3.3.3.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/fast-string-truncated-width-3.0.3.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/fast-string-width-3.0.2.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/fast-wrap-ansi-0.2.2.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/fastq-1.20.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/fill-range-7.1.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/find-workspaces-0.3.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/fs.scandir-2.1.5.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/fs.stat-2.0.5.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/fs.walk-1.2.8.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/get-east-asian-width-1.6.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/glob-parent-5.1.2.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/helper-string-parser-7.29.7.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/helper-validator-identifier-7.29.7.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/is-extglob-2.1.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/is-fullwidth-code-point-5.1.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/is-glob-4.0.3.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/is-number-7.0.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/jsonc-parser-3.3.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/log-update-8.0.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/magicast-0.5.4.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/manifest.json
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/merge2-1.4.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/micromatch-4.0.8.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/mimic-function-5.0.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/mlly-1.8.2.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/nypm-0.6.9.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/onetime-7.0.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/oxfmt-0.63.0.tgz.part-000
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/oxfmt-0.63.0.tgz.part-001
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/oxlint-1.78.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/parser-7.29.8.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/picomatch-2.3.2.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/pkg-types-1.3.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/prompts-1.7.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/queue-microtask-1.2.3.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/resolve.exports-2.0.3.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/restore-cursor-5.1.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/reusify-1.1.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/run-parallel-1.2.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/sisteransi-1.0.5.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/slice-ansi-9.0.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/string-width-8.2.2.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/strip-ansi-7.2.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/tinyexec-1.0.4.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/tinyexec-1.3.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/tinypool-2.1.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/to-regex-range-5.0.1.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/types-7.29.8.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/ufo-1.6.4.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/ultracite-7.10.3.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/which-command-0.1.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/wrap-ansi-10.0.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/yaml-2.9.0.tgz
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/zod-4.4.3.tgz
  • tools/oxlint/anti-slop/LICENSE
  • tools/oxlint/anti-slop/UPSTREAM.md
  • tools/oxlint/anti-slop/index.ts
  • tools/oxlint/anti-slop/rules/no-chained-type-assertions.ts
  • tools/oxlint/anti-slop/rules/no-conditional-empty-object-spread.ts
  • tools/oxlint/anti-slop/rules/no-known-value-widening.ts
  • tools/oxlint/anti-slop/rules/no-module-mocking.ts
  • tools/oxlint/anti-slop/rules/no-object-parameters.ts
  • tools/oxlint/anti-slop/rules/no-reflect-apply.ts
  • tools/oxlint/anti-slop/rules/no-reflect-get.ts
  • tools/oxlint/anti-slop/rules/no-runtime-typeof.ts
  • tools/oxlint/anti-slop/rules/no-shape-in-symbol-names.ts
  • tools/oxlint/anti-slop/rules/no-unknown-parameters.ts
  • tools/oxlint/anti-slop/rules/no-unknown-returns.ts
  • tools/oxlint/anti-slop/rules/no-unknown-type-aliases.ts
  • tools/oxlint/anti-slop/rules/no-unsafe-dictionary-type.ts
  • tools/oxlint/anti-slop/rules/no-widen-then-assert.ts
  • tools/oxlint/anti-slop/rules/require-safety-comment-for-type-assertion.ts
  • tools/oxlint/anti-slop/shared/dictionary-types.ts
  • tools/oxlint/anti-slop/shared/reflect-method.ts
💤 Files with no reviewable changes (2)
  • biome.json
  • nemoclaw/src/commands/migration-state.test.ts

Comment thread oxlint.config.ts Outdated
Comment thread tools/lint/format-added-files.sh Outdated
Comment thread tools/lint/format-added-files.sh Outdated
Comment thread tools/lint/format-added-files.sh
Comment thread tools/oxlint/anti-slop/rules/no-conditional-empty-object-spread.ts Outdated
Comment thread test/anti-slop-rules.test.ts Outdated
Comment thread test/format-added-files.test.ts Outdated
Comment thread test/nemoclaw-start-extra-placeholder-breadcrumb-helpers.ts Outdated
Comment thread src/lib/onboard.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
tools/lint/format-added-files.sh (1)

47-50: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Reject candidates whose ancestors are symbolic links.

[[ -L "${file}" ]] checks only the final component. If linked-dir is a symlink, linked-dir/outside.ts passes [[ -f "${file}" ]] and is added to the Oxfmt or Oxlint command. Resolve each existing candidate to a canonical path and reject it unless it is contained by the canonical repository root. Add a regression test for a symlinked directory that targets a file outside the repository.

  • tools/lint/format-added-files.sh#L47-L50
  • tools/lint/lint-added-files.sh#L24-L27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/lint/format-added-files.sh` around lines 47 - 50, Update the candidate
validation in tools/lint/format-added-files.sh at lines 47-50 and
tools/lint/lint-added-files.sh at lines 24-27 to canonicalize each existing
candidate, reject any resolved path outside the canonical repository root, and
retain rejection of symlink candidates. Add a regression test covering a
symlinked directory whose target file is outside the repository; apply the same
containment behavior to both formatting and linting flows.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@tools/lint/format-added-files.sh`:
- Around line 47-50: Update the candidate validation in
tools/lint/format-added-files.sh at lines 47-50 and
tools/lint/lint-added-files.sh at lines 24-27 to canonicalize each existing
candidate, reject any resolved path outside the canonical repository root, and
retain rejection of symlink candidates. Add a regression test covering a
symlinked directory whose target file is outside the repository; apply the same
containment behavior to both formatting and linting flows.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e9df05e8-29c2-406a-84c2-8016ee928b9b

📥 Commits

Reviewing files that changed from the base of the PR and between 993e87b and 444bfbc.

⛔ Files ignored due to path filters (2)
  • nemoclaw/package-lock.json is excluded by !**/package-lock.json
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (27)
  • .pre-commit-config.yaml
  • AGENTS.md
  • CONTRIBUTING.md
  • ci/test-file-size-budget.json
  • nemoclaw/package.json
  • oxlint.config.ts
  • oxlint.type-aware.config.ts
  • package.json
  • src/lib/onboard.ts
  • src/lib/onboard/credential-navigation.ts
  • test/mcp-tool-discovery-image-contract.test.ts
  • test/nemoclaw-start-extra-placeholder-breadcrumb-helpers.ts
  • test/onboard-inference-reconciliation.test.ts
  • test/onboard-messaging.test.ts
  • tools/e2e/hermes-gpu-startup-workflow-boundary.mts
  • tools/lint/format-added-files.sh
  • tools/lint/lint-added-files.sh
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/linux-x64-7.0.2001.tgz.part-000
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/linux-x64-7.0.2001.tgz.part-001
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/linux-x64-7.0.2001.tgz.part-002
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/linux-x64-7.0.2001.tgz.part-003
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/linux-x64-7.0.2001.tgz.part-004
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/manifest.json
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/oxlint-tsgolint-7.0.2001.tgz
  • tools/oxlint/anti-slop/UPSTREAM.md
  • tools/oxlint/anti-slop/rules/no-conditional-empty-object-spread.ts
  • tools/oxlint/anti-slop/rules/no-runtime-typeof.ts
💤 Files with no reviewable changes (6)
  • test/onboard-inference-reconciliation.test.ts
  • src/lib/onboard/credential-navigation.ts
  • tools/e2e/hermes-gpu-startup-workflow-boundary.mts
  • test/nemoclaw-start-extra-placeholder-breadcrumb-helpers.ts
  • test/onboard-messaging.test.ts
  • src/lib/onboard.ts
🚧 Files skipped from review as they are similar to previous changes (11)
  • test/mcp-tool-discovery-image-contract.test.ts
  • CONTRIBUTING.md
  • .pre-commit-config.yaml
  • tools/oxlint/anti-slop/rules/no-runtime-typeof.ts
  • ci/test-file-size-budget.json
  • package.json
  • tools/oxlint/anti-slop/rules/no-conditional-empty-object-spread.ts
  • nemoclaw/package.json
  • oxlint.config.ts
  • tools/mcp-tool-discovery-runtime/npm-cache-seed/manifest.json
  • AGENTS.md

@cv

cv commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author

Advisor warning dispositions for e6d2b030f:

  • SonarJS license evidence: addressed in tools/lint/DEPENDENCY-REVIEW.md. The record pins version 4.2.0 and its registry integrity, records LGPL-3.0-only, limits execution to contributor and CI lint checks, confirms exclusion from published package code and the plugin cache seed, and names every re-review condition.
  • Lint-hook path tests: not added because the maintainer explicitly requested removal of both new tooling test files in this review cycle. Focused manual probes verified absolute-path rejection, traversal and dot-segment rejection, symbolic-link rejection, missing-base status 2 before tool execution, and -- handling for a hyphen-prefixed filename.

All review threads are resolved. The independent documentation review passed on this commit.

@copy-pr-bot

copy-pr-bot Bot commented Aug 13, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@cv cv changed the title chore(tooling): adopt ultracite and anti-slop chore(tooling): adopt Oxlint and Oxfmt Aug 13, 2026
@cv

cv commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author

Advisor warning disposition for PRA-1 on 115692bcb:

  • Result: false positive.
  • src/lib/actions/sandbox/process-recovery.ts is unchanged between the PR base and latest PR commit.
  • The previous Biome configuration applied a limit of 149 and passed this unchanged file.
  • SonarJS reports a different numeric score of 297 for the same file. oxlint.config.ts pins that measured score, so the next complexity increase fails.
  • Setting the SonarJS limit to 149 would reject unchanged main code and turn this tooling migration into a source refactor.

The tools' numeric scores are not interchangeable. Rule tightening remains separate from this migration.

@cv

cv commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author

Advisor warning disposition for PRA-1 on 43d263c0b:

  • Result: deferred non-blocking follow-up.
  • The maintainer previously requested removal of the two new tooling test files in this review cycle; that disposition and the focused path probes are recorded above.
  • This PR keeps the formatter wrapper unchanged while replacing its dependency and configuration ownership.
  • Full pre-commit, direct lint and format checks, clean locked installs, package contracts, and cache-seed contracts pass.
  • Additional formatter-wrapper checks and stricter lint rules remain scoped to the agreed follow-up PR.

No change is required in this review cycle.

@cv
cv merged commit 14c6d77 into main Aug 13, 2026
86 of 90 checks passed
@cv
cv deleted the chore/ultracite-anti-slop branch August 13, 2026 10:40
@wscurran wscurran added the chore Build, CI, dependency, or tooling maintenance label Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Build, CI, dependency, or tooling maintenance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants