chore(blueprint): add pyright strict type checking#523
Conversation
Adds a dedicated lint job that runs `make check` on every PR, covering ESLint, Prettier, tsc --noEmit (TypeScript) and ruff (Python). Previously, lint failures were only caught locally — now they block merge. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds pyright in strict mode to the Python nemoclaw-blueprint package, integrated into `make check`. This catches type errors locally and in CI, which is especially important for AI-agent-authored contributions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a repository-wide lint job to the PR GitHub Actions workflow, integrates Pyright into Makefile checks with strict Python 3.11 settings, tightens ESLint test-file exceptions, and applies non-functional TypeScript formatting/rewrites. Changes
Sequence Diagram(s)sequenceDiagram
participant GH as GitHub Actions Runner
participant Node as Node.js v22
participant Py as Python 3.11
participant UV as uv
participant NPM as npm (nemoclaw)
participant Make as make check
GH->>Node: Provision Node.js v22
GH->>Py: Provision Python 3.11
GH->>UV: Install uv
UV->>Py: uv installs ruff
GH->>NPM: Run `npm install` in `nemoclaw`
GH->>Make: Run `make check` (ruff, pyright, format checks)
Make-->>GH: Linting results
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/workflows/pr.yaml (1)
28-29: npm cache may require a lockfile.The
cache: npmoption typically requirespackage-lock.jsonto exist in the repository root (or the directory specified bycache-dependency-path). If the lockfile is innemoclaw/instead, consider addingcache-dependency-path: nemoclaw/package-lock.json.Proposed fix
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "22" cache: npm + cache-dependency-path: nemoclaw/package-lock.json🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/pr.yaml around lines 28 - 29, The GitHub Actions workflow currently uses "cache: npm" but doesn't point to the repository's lockfile; update the workflow to add the cache-dependency-path key referencing the lockfile location (e.g. set cache-dependency-path: "nemoclaw/package-lock.json") or move the package-lock.json to the repo root so the existing cache: npm works; modify the workflow's node-version/cache block to include the cache-dependency-path entry so the npm cache is keyed correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.github/workflows/pr.yaml:
- Around line 28-29: The GitHub Actions workflow currently uses "cache: npm" but
doesn't point to the repository's lockfile; update the workflow to add the
cache-dependency-path key referencing the lockfile location (e.g. set
cache-dependency-path: "nemoclaw/package-lock.json") or move the
package-lock.json to the repo root so the existing cache: npm works; modify the
workflow's node-version/cache block to include the cache-dependency-path entry
so the npm cache is keyed correctly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 704e03f2-e288-4c0f-8b4d-15a66e2d2c58
📒 Files selected for processing (3)
.github/workflows/pr.yamlnemoclaw-blueprint/Makefilenemoclaw-blueprint/pyproject.toml
- Remove async from functions without await in fetch.ts, use Promise.reject/resolve instead - Add braces to void arrow expression in logs.ts - Configure allowDefaultProject for test files excluded from tsconfig - Relax no-unsafe-assignment/member-access rules for test files - Fix unused variable in status.test.ts - Apply prettier formatting to all source files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
nemoclaw/src/blueprint/fetch.ts (1)
49-60:⚠️ Potential issue | 🟠 MajorSynchronous throw breaks the Promise contract in non-async function.
The
downloadAndCachefunction at line 58 throws synchronously despite returning aPromise. Callers using promise chaining (.catch(),.then()) will not catch this error. Change toreturn Promise.reject(...)to match the Promise return type and align with the pattern used elsewhere in the file (fetchBlueprintandresolveLatestVersion).Proposed fix
export function downloadAndCache( registry: string, version: string, ): Promise<{ localPath: string; manifest: BlueprintManifest }> { // Future: HTTP fetch + tar extract + manifest parse void registry; const localPath = getCachedBlueprintPath(version); const manifest = readCachedManifest(version); if (!manifest) { - throw new Error(`Failed to read manifest after download for version ${version}`); + return Promise.reject( + new Error(`Failed to read manifest after download for version ${version}`), + ); } return Promise.resolve({ localPath, manifest }); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@nemoclaw/src/blueprint/fetch.ts` around lines 49 - 60, downloadAndCache currently throws synchronously when readCachedManifest(version) returns falsy, breaking the Promise contract; instead return a rejected Promise so callers can catch it. In the downloadAndCache function (which uses getCachedBlueprintPath and readCachedManifest), replace the synchronous throw with returning Promise.reject(new Error(...)) and keep the same error message so the function always returns a Promise that rejects on failure.
🧹 Nitpick comments (1)
nemoclaw/eslint.config.mjs (1)
11-13: Consider aligningallowDefaultProjectpattern with the test override scope for consistency.Line 12 uses
src/*/*.test.tswhile line 33 usessrc/**/*.test.ts. While current test files atsrc/commands/status.test.tsare covered by both patterns, aligning them would prevent inconsistency if tests are added at deeper nesting levels.Suggested change
projectService: { - allowDefaultProject: ["src/**/*.test.ts"], + allowDefaultProject: ["src/**/*.test.ts"], },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@nemoclaw/eslint.config.mjs` around lines 11 - 13, The projectService configuration uses allowDefaultProject: ["src/*/*.test.ts"] which is narrower than the test override pattern; update allowDefaultProject in the projectService block to the recursive pattern "src/**/*.test.ts" to match the test override scope so deeper-nested tests (and files like src/commands/status.test.ts) remain consistently covered; modify the allowDefaultProject value within the projectService object accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@nemoclaw/src/blueprint/fetch.ts`:
- Around line 49-60: downloadAndCache currently throws synchronously when
readCachedManifest(version) returns falsy, breaking the Promise contract;
instead return a rejected Promise so callers can catch it. In the
downloadAndCache function (which uses getCachedBlueprintPath and
readCachedManifest), replace the synchronous throw with returning
Promise.reject(new Error(...)) and keep the same error message so the function
always returns a Promise that rejects on failure.
---
Nitpick comments:
In `@nemoclaw/eslint.config.mjs`:
- Around line 11-13: The projectService configuration uses allowDefaultProject:
["src/*/*.test.ts"] which is narrower than the test override pattern; update
allowDefaultProject in the projectService block to the recursive pattern
"src/**/*.test.ts" to match the test override scope so deeper-nested tests (and
files like src/commands/status.test.ts) remain consistently covered; modify the
allowDefaultProject value within the projectService object accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8ff0f99a-d5f2-4353-9a40-2b5b0d6fc4e3
📒 Files selected for processing (10)
nemoclaw/eslint.config.mjsnemoclaw/src/blueprint/fetch.tsnemoclaw/src/cli.tsnemoclaw/src/commands/logs.tsnemoclaw/src/commands/migrate.tsnemoclaw/src/commands/migration-state.tsnemoclaw/src/commands/onboard.tsnemoclaw/src/commands/status.test.tsnemoclaw/src/commands/status.tsnemoclaw/src/index.ts
✅ Files skipped from review due to trivial changes (8)
- nemoclaw/src/commands/status.ts
- nemoclaw/src/commands/logs.ts
- nemoclaw/src/index.ts
- nemoclaw/src/commands/onboard.ts
- nemoclaw/src/commands/migration-state.ts
- nemoclaw/src/commands/status.test.ts
- nemoclaw/src/cli.ts
- nemoclaw/src/commands/migrate.ts
# Conflicts: # nemoclaw/src/blueprint/fetch.ts # nemoclaw/src/cli.ts # nemoclaw/src/commands/logs.ts # nemoclaw/src/commands/migrate.ts # nemoclaw/src/commands/onboard.ts # nemoclaw/src/commands/status.test.ts # nemoclaw/src/commands/status.ts
…iles The glob `src/*/*.test.ts` missed files like `src/register.test.ts`. Changed to `src/**/*.test.ts` to cover test files at any depth. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
typescript-eslint disallows ** in allowDefaultProject globs for performance reasons. Use explicit single-level patterns instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ericksoa
left a comment
There was a problem hiding this comment.
Clean setup — pyright strict mode via ephemeral uv run is elegant (no permanent dep), and the new CI lint job closes the gap between local and CI linting. ESLint test-file relaxations are reasonable.
* ci: add lint job to PR workflow Adds a dedicated lint job that runs `make check` on every PR, covering ESLint, Prettier, tsc --noEmit (TypeScript) and ruff (Python). Previously, lint failures were only caught locally — now they block merge. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(blueprint): add pyright strict type checking Adds pyright in strict mode to the Python nemoclaw-blueprint package, integrated into `make check`. This catches type errors locally and in CI, which is especially important for AI-agent-authored contributions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(lint): resolve ESLint errors and format issues - Remove async from functions without await in fetch.ts, use Promise.reject/resolve instead - Add braces to void arrow expression in logs.ts - Configure allowDefaultProject for test files excluded from tsconfig - Relax no-unsafe-assignment/member-access rules for test files - Fix unused variable in status.test.ts - Apply prettier formatting to all source files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ci: trigger workflow re-run * fix(lint): update allowDefaultProject glob to match root-level test files The glob `src/*/*.test.ts` missed files like `src/register.test.ts`. Changed to `src/**/*.test.ts` to cover test files at any depth. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(lint): use single-level globs in allowDefaultProject typescript-eslint disallows ** in allowDefaultProject globs for performance reasons. Use explicit single-level patterns instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: format register.test.ts with prettier Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ci: add lint job to PR workflow Adds a dedicated lint job that runs `make check` on every PR, covering ESLint, Prettier, tsc --noEmit (TypeScript) and ruff (Python). Previously, lint failures were only caught locally — now they block merge. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(blueprint): add pyright strict type checking Adds pyright in strict mode to the Python nemoclaw-blueprint package, integrated into `make check`. This catches type errors locally and in CI, which is especially important for AI-agent-authored contributions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(lint): resolve ESLint errors and format issues - Remove async from functions without await in fetch.ts, use Promise.reject/resolve instead - Add braces to void arrow expression in logs.ts - Configure allowDefaultProject for test files excluded from tsconfig - Relax no-unsafe-assignment/member-access rules for test files - Fix unused variable in status.test.ts - Apply prettier formatting to all source files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ci: trigger workflow re-run * fix(lint): update allowDefaultProject glob to match root-level test files The glob `src/*/*.test.ts` missed files like `src/register.test.ts`. Changed to `src/**/*.test.ts` to cover test files at any depth. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(lint): use single-level globs in allowDefaultProject typescript-eslint disallows ** in allowDefaultProject globs for performance reasons. Use explicit single-level patterns instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: format register.test.ts with prettier Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
nemoclaw-blueprint/Python codemake checkviauv run --with pyright pyright .Motivation
AI agents contributing to this repo can introduce subtle type errors in Python code. Unlike TypeScript (which already has
tsc --strict), the Python side had no type checker. This closes that gap.Test plan
cd nemoclaw-blueprint && make checkpasses (ruff + pyright)make checkfrom root still works🤖 Generated with Claude Code
Summary by CodeRabbit