Skip to content

ci: add ESLint and tsc type checking for JavaScript files#771

Merged
ericksoa merged 10 commits intoNVIDIA:mainfrom
cv:lint/eslint-js-files
Mar 25, 2026
Merged

ci: add ESLint and tsc type checking for JavaScript files#771
ericksoa merged 10 commits intoNVIDIA:mainfrom
cv:lint/eslint-js-files

Conversation

@cv
Copy link
Copy Markdown
Contributor

@cv cv commented Mar 24, 2026

Summary

  • Add ESLint coverage for all JS files outside the nemoclaw/ TypeScript sub-project (bin/, test/, scripts/, docs/_ext/) with environment-specific configs (CJS, ESM, browser)
  • Add tsc --checkJs via jsconfig.json for type checking JS without requiring migration to TypeScript
  • Wire both into prek hooks (eslint-js at pre-commit, tsc-check-js at pre-push) and add lint/typecheck npm scripts
  • Fix 68 pre-existing ESLint violations and 11 tsc type errors

Test plan

  • npx eslint . passes clean
  • npx tsc -p jsconfig.json passes clean
  • All pre-commit and pre-push hooks pass
  • npx vitest run — all tests pass
  • CI lint + test jobs pass

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores

    • Added ESLint and TypeScript configs plus npm scripts for linting and type-checking.
    • Configured pre-commit and pre-push hooks to run automated linting and type checks.
    • Clarified ignored-error handling and removed unused imports across the codebase.
  • Docs

    • Simplified search-related scripts and adjusted search/filter rendering behavior.
  • Tests

    • Consolidated and updated test imports and annotations.

Add lint and type-check coverage for all JS files outside the nemoclaw/
TypeScript sub-project (bin/, test/, scripts/, docs/_ext/).

- eslint.config.mjs: flat config with environment-specific settings
  (CJS for bin/scripts, ESM for test, browser for docs)
- jsconfig.json: tsc --checkJs with bundler resolution, no strict
- prek hooks: eslint-js (pre-commit, priority 6) and tsc-check-js
  (pre-push, priority 10)
- Fix 68 existing ESLint violations (empty catches, unused vars,
  regex spaces, dead imports, useless try/catch)
- Fix 11 tsc type errors via JSDoc casts and @ts-expect-error pragmas

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f04950d2-052f-4977-8a15-7cafc0fd87ed

📥 Commits

Reviewing files that changed from the base of the PR and between 73a438a and 41ca8af.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (1)
  • .pre-commit-config.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .pre-commit-config.yaml

📝 Walkthrough

Walkthrough

Adds ESLint and JS type-checking configuration plus pre-commit/pre-push hooks; standardizes empty catch blocks to explicit ignored comments; renames unused variables/parameters using an underscore convention; removes some unused imports and small functions; and updates tests and docs search assets accordingly.

Changes

Cohort / File(s) Summary
Tooling & Hooks
\.pre-commit-config.yaml, eslint.config.mjs, jsconfig.json, package.json
Added ESLint flat config, JS/TS typecheck config, new pre-commit local hook (eslint-js) and pre-push hook (tsc-check-js), and npm scripts lint, lint:fix, and typecheck.
Catch Block Standardization
bin/lib/credentials.js, bin/lib/local-inference.js, bin/lib/nim.js, bin/lib/policies.js, bin/lib/registry.js, bin/lib/resolve-openshell.js, bin/nemoclaw.js, scripts/telegram-bridge.js
Replaced empty catch {} blocks with catch { /* ignored */ } to make intent explicit without changing behavior.
Onboard library edits
bin/lib/onboard.js
Removed pythonLiteralJson() and validateAnthropicSelection(), adjusted getSandboxInferenceConfig() initialization, renamed unused parameters (verifyInferenceRoute, startGateway), tightened several regexes in streaming logic, changed spawn error formatting, and removed local shadowing of fs/os.
Unused naming / underscore convention
bin/lib/preflight.js, bin/lib/local-inference.js, docs/_ext/search_assets/main.js, docs/_ext/search_assets/modules/ResultRenderer.js, docs/_ext/search_assets/modules/SearchEngine.js, bin/nemoclaw.js
Renamed unused caught errors/params/locals to _error, _results, _result, _RD, _runCapture etc., and removed/adjusted reliance on caught identifiers.
Search assets & docs changes
docs/_ext/search_assets/main.js, docs/_ext/search_assets/modules/*, docs/_ext/search_assets/modules/SearchPageManager.js
Added global JSDoc annotations, removed generation of some filter option HTML, renamed unused parameters, and simplified error handling; added /* exported SearchPageManager */.
Tests: imports, paths, and annotations
test/runner.test.js, test/onboard.test.js, test/policies.test.js, test/security-binaries-restriction.test.js
Removed duplicate/unused imports, replaced __dirname usage with import.meta.dirname in some tests, added // @ts-expect-error`` for partial mock assignments, and tightened YAML-block regex to require exactly two-space indentation.
Misc. minor edits
bin/lib/policies.js, bin/lib/preflight.js, bin/lib/registry.js, bin/lib/resolve-openshell.js, bin/lib/nim.js, bin/lib/credentials.js, scripts/telegram-bridge.js
Small adjustments such as JSDoc cast for Node error, renaming local variables, and cleanup behavior changes limited to catch-commenting or minor identifier renames.

Sequence Diagram(s)

sequenceDiagram
  participant Dev as Developer
  participant Git as Git (commit/push)
  participant PreCommit as pre-commit
  participant ESLint as ESLint (npx eslint)
  participant TSC as TypeScript (npx tsc)

  Dev->>Git: commit
  Git->>PreCommit: run pre-commit hooks
  PreCommit->>ESLint: run `npx eslint --fix` on staged JS
  ESLint-->>PreCommit: fixes / exit status
  Dev->>Git: push
  Git->>PreCommit: run pre-push hooks
  PreCommit->>TSC: run `npx tsc -p jsconfig.json`
  TSC-->>PreCommit: type-check result
  PreCommit-->>Git: allow or block operation
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰
I hopped through catches, tidy and neat,
Underscores mark the crumbs I eat,
Hooks hum linting, types take a peek,
A little rabbit says: ship it sleek!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately and clearly summarizes the primary objective: adding ESLint and TypeScript type checking for JavaScript files, which aligns with the substantial changes across configuration files, linting setup, and code fixes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@cv cv requested review from ericksoa and kjw3 and removed request for ericksoa March 24, 2026 06:41
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
docs/_ext/search_assets/modules/ResultRenderer.js (1)

132-132: Remove the unused _result binding entirely.

Renaming avoids lint noise, but the variable is still dead code and adds confusion.

Proposed cleanup
-    bindResultEvents(container, results) {
-        container.querySelectorAll('.search-result-item').forEach((item, index) => {
-            const _result = results[index];
+    bindResultEvents(container) {
+        container.querySelectorAll('.search-result-item').forEach((item) => {
-        this.bindResultEvents(container, results);
+        this.bindResultEvents(container);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/_ext/search_assets/modules/ResultRenderer.js` at line 132, Remove the
dead binding "_result" created by "const _result = results[index];" — delete
that entire declaration so there is no unused variable; if the intention was to
reference the item later, instead use "results[index]" inline where needed or
rename the existing usage to a used variable, but do not keep "_result" as an
unused binding.
bin/lib/nim.js (1)

149-149: Pre-existing dead code: _interval is never used.

The variable is declared but the sleep call on line 164 uses a hardcoded "5" instead of _interval / 1000. The underscore prefix acknowledges this, but consider either using the variable or removing it entirely to avoid confusion.

♻️ Option: Use the interval constant or remove it
-  const _interval = 5000;
+  const intervalSec = 5;
   const safePort = Number(port);
   console.log(`  Waiting for NIM health on port ${safePort} (timeout: ${timeout}s)...`);

   while ((Date.now() - start) / 1000 < timeout) {
     ...
     // Synchronous sleep via spawnSync
-    require("child_process").spawnSync("sleep", ["5"]);
+    require("child_process").spawnSync("sleep", [String(intervalSec)]);
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/nim.js` at line 149, The code declares a constant named _interval but
never uses it; update the sleep invocation (the call currently using the
hardcoded "5") to use _interval by converting milliseconds to seconds (e.g., use
_interval / 1000) or remove the unused _interval constant entirely—ensure you
update or delete the _interval declaration and replace the hardcoded sleep
argument so there is no leftover dead variable.
docs/_ext/search_assets/main.js (1)

161-164: Consider removing unused parameters entirely or documenting the interface contract.

The renderResults method ignores both parameters and returns an empty string. If this is a public API placeholder for future implementation, consider adding a JSDoc comment explaining the interface contract. If it's truly dead code, consider removing it.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/_ext/search_assets/main.js` around lines 161 - 164, The
renderResults(_results, _query) method currently ignores its parameters and
returns an empty string; either remove the unused parameters and delete the
method if it is dead code, or add a JSDoc describing the interface contract and
intended behavior (including expected types for results and query and that it
returns an HTML string) so callers know it’s a placeholder for future
implementation; update any references to SearchPageManager.renderResults to
match the chosen approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bin/lib/onboard.js`:
- Around line 540-542: Remove the unused destructured import _mkdtempSync and
the redundant local os require: delete the line that does const { mkdtempSync:
_mkdtempSync } = require("fs") and the line const os = require("os"), and keep
using the module-level fs and os imports so buildCtx =
fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-build-")) continues to work
unchanged; verify there are no other local references to _mkdtempSync or the
local os after removal.

In `@docs/_ext/search_assets/modules/SearchPageManager.js`:
- Around line 136-143: The computed variables _audienceOptions and
_difficultyOptions are dead code because their option HTML is never inserted
into the template; either remove them or render dropdowns and wire them into the
filter grid. Fix by updating the render/template method that builds the filter
grid to include select elements for audience and difficulty (using the existing
_audienceOptions and _difficultyOptions), ensure their select IDs/classes match
the event handler selectors referenced in the change handler, and reuse
escapeHtml, formatPersonaName, and formatDifficultyName when populating the
options; alternatively, delete the declarations of _audienceOptions and
_difficultyOptions and remove any related null-checked DOM references in the
event handling code to eliminate the unused variables.

---

Nitpick comments:
In `@bin/lib/nim.js`:
- Line 149: The code declares a constant named _interval but never uses it;
update the sleep invocation (the call currently using the hardcoded "5") to use
_interval by converting milliseconds to seconds (e.g., use _interval / 1000) or
remove the unused _interval constant entirely—ensure you update or delete the
_interval declaration and replace the hardcoded sleep argument so there is no
leftover dead variable.

In `@docs/_ext/search_assets/main.js`:
- Around line 161-164: The renderResults(_results, _query) method currently
ignores its parameters and returns an empty string; either remove the unused
parameters and delete the method if it is dead code, or add a JSDoc describing
the interface contract and intended behavior (including expected types for
results and query and that it returns an HTML string) so callers know it’s a
placeholder for future implementation; update any references to
SearchPageManager.renderResults to match the chosen approach.

In `@docs/_ext/search_assets/modules/ResultRenderer.js`:
- Line 132: Remove the dead binding "_result" created by "const _result =
results[index];" — delete that entire declaration so there is no unused
variable; if the intention was to reference the item later, instead use
"results[index]" inline where needed or rename the existing usage to a used
variable, but do not keep "_result" as an unused binding.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f4add669-0c02-44a5-af3f-8b8142371814

📥 Commits

Reviewing files that changed from the base of the PR and between 6e1208c and 0358e5a.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (21)
  • .pre-commit-config.yaml
  • bin/lib/credentials.js
  • bin/lib/local-inference.js
  • bin/lib/nim.js
  • bin/lib/onboard.js
  • bin/lib/policies.js
  • bin/lib/preflight.js
  • bin/lib/registry.js
  • bin/lib/resolve-openshell.js
  • bin/nemoclaw.js
  • docs/_ext/search_assets/main.js
  • docs/_ext/search_assets/modules/ResultRenderer.js
  • docs/_ext/search_assets/modules/SearchEngine.js
  • docs/_ext/search_assets/modules/SearchPageManager.js
  • eslint.config.mjs
  • jsconfig.json
  • package.json
  • scripts/telegram-bridge.js
  • test/policies.test.js
  • test/preflight.test.js
  • test/runner.test.js
💤 Files with no reviewable changes (1)
  • test/policies.test.js

- bin/lib/onboard.js: remove redundant fs/os requires (already imported
  at module level)
- docs/_ext/search_assets/modules/SearchPageManager.js: remove unused
  audienceOptions and difficultyOptions (never wired into template)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@wscurran wscurran added CI/CD Use this label to identify issues with NemoClaw CI/CD pipeline or GitHub Actions. enhancement: testing Use this label to identify requests to improve NemoClaw test coverage. labels Mar 24, 2026
cv and others added 5 commits March 24, 2026 16:10
# Conflicts:
#	bin/lib/onboard.js
#	bin/lib/preflight.js
#	package.json
#	test/preflight.test.js
- Fix duplicate imports in onboard.test.js
- Remove unused imports (createSandbox, pruneStaleSandboxEntry, runCaptureOpenshell)
- Add JSDoc type annotation for err.code in preflight.js probe

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@ericksoa ericksoa left a comment

Choose a reason for hiding this comment

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

LGTM. Clean separation of ESLint configs by environment (CJS for bin/scripts, ESM for test, browser for docs). The _ prefix convention for intentionally unused vars is consistent with the TS sub-project. Good that strict and noImplicitAny are off in jsconfig — pragmatic for a JS codebase that isn't migrating wholesale to TS.

@ericksoa
Copy link
Copy Markdown
Contributor

@cv This has merge conflicts with main — can you merge main into your branch? The "Update branch" button should work if GitHub shows it for fork PRs, otherwise a local merge.

cv and others added 3 commits March 24, 2026 18:14
The nemoclaw-blueprint Python modules were converted to TypeScript in
PR #772, so the pyright pre-push hook is no longer needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The root eslint.config.mjs imports @eslint/js but it was missing from
package.json, causing the eslint-js pre-push hook to fail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ericksoa ericksoa merged commit 6964d78 into NVIDIA:main Mar 25, 2026
7 checks passed
@cv cv deleted the lint/eslint-js-files branch March 25, 2026 04:46
temrjan pushed a commit to temrjan/NemoClaw that referenced this pull request Mar 25, 2026
* ci: add ESLint and tsc type checking for JavaScript files

Add lint and type-check coverage for all JS files outside the nemoclaw/
TypeScript sub-project (bin/, test/, scripts/, docs/_ext/).

- eslint.config.mjs: flat config with environment-specific settings
  (CJS for bin/scripts, ESM for test, browser for docs)
- jsconfig.json: tsc --checkJs with bundler resolution, no strict
- prek hooks: eslint-js (pre-commit, priority 6) and tsc-check-js
  (pre-push, priority 10)
- Fix 68 existing ESLint violations (empty catches, unused vars,
  regex spaces, dead imports, useless try/catch)
- Fix 11 tsc type errors via JSDoc casts and @ts-expect-error pragmas

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove dead code flagged in review

- bin/lib/onboard.js: remove redundant fs/os requires (already imported
  at module level)
- docs/_ext/search_assets/modules/SearchPageManager.js: remove unused
  audienceOptions and difficultyOptions (never wired into template)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve lint errors from main merge

- Fix duplicate imports in onboard.test.js
- Remove unused imports (createSandbox, pruneStaleSandboxEntry, runCaptureOpenshell)
- Add JSDoc type annotation for err.code in preflight.js probe

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: apply eslint autofix to security test regex

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove dead functions pythonLiteralJson and validateAnthropicSelection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add @eslint/js as dev dependency

The root eslint.config.mjs imports @eslint/js but it was missing from
package.json, causing the eslint-js pre-push hook to fail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Aaron Erickson 🦞 <aerickson@nvidia.com>
lakamsani pushed a commit to lakamsani/NemoClaw that referenced this pull request Apr 4, 2026
* ci: add ESLint and tsc type checking for JavaScript files

Add lint and type-check coverage for all JS files outside the nemoclaw/
TypeScript sub-project (bin/, test/, scripts/, docs/_ext/).

- eslint.config.mjs: flat config with environment-specific settings
  (CJS for bin/scripts, ESM for test, browser for docs)
- jsconfig.json: tsc --checkJs with bundler resolution, no strict
- prek hooks: eslint-js (pre-commit, priority 6) and tsc-check-js
  (pre-push, priority 10)
- Fix 68 existing ESLint violations (empty catches, unused vars,
  regex spaces, dead imports, useless try/catch)
- Fix 11 tsc type errors via JSDoc casts and @ts-expect-error pragmas

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove dead code flagged in review

- bin/lib/onboard.js: remove redundant fs/os requires (already imported
  at module level)
- docs/_ext/search_assets/modules/SearchPageManager.js: remove unused
  audienceOptions and difficultyOptions (never wired into template)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve lint errors from main merge

- Fix duplicate imports in onboard.test.js
- Remove unused imports (createSandbox, pruneStaleSandboxEntry, runCaptureOpenshell)
- Add JSDoc type annotation for err.code in preflight.js probe

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: apply eslint autofix to security test regex

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove dead functions pythonLiteralJson and validateAnthropicSelection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add @eslint/js as dev dependency

The root eslint.config.mjs imports @eslint/js but it was missing from
package.json, causing the eslint-js pre-push hook to fail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Aaron Erickson 🦞 <aerickson@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/CD Use this label to identify issues with NemoClaw CI/CD pipeline or GitHub Actions. enhancement: testing Use this label to identify requests to improve NemoClaw test coverage.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants