Address repository audit hardening - #61
Conversation
ⓘ You've reached your Qodo monthly free-tier limit. Reviews pause until next month — upgrade your plan to continue now, or link your paid account if you already have one. |
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (11)
📝 WalkthroughWalkthroughThis PR introduces v1.0.0 hardening and feature updates: centralized CLI option parsing with validation, guarded HTTP fetching with origin allowlists and byte limits, mirror path traversal protection, PyPI metadata field validation, preview-by-default wire mode, explicit workspace recommendation execution, lazy VS Code settings path resolution, and resettable in-process GitHub state. Documentation and test coverage are updated accordingly. ChangesV1.0.0 Hardening & Feature Release
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 33 minutes and 42 seconds.Comment |
There was a problem hiding this comment.
Pull request overview
This PR implements post-audit hardening across the CLI lifecycle pipeline: safer mirror writes, guarded external HTTP reads, stricter CLI option parsing, and behavioral tweaks to make mutating operations more explicit—along with regression tests and documentation updates.
Changes:
- Add guarded HTTP utilities (origin allowlists, timeouts, byte limits) and apply them to official-index, GitHub raw reads, and registry metadata fetches.
- Harden filesystem writes for mirrored multi-file artifacts via safe path resolution to prevent traversal outside the raw mirror root.
- Centralize CLI option parsing (reject missing/flag-like values) and adjust lifecycle orchestration (explicit
recommend report, preview-by-default wire intent), with accompanying tests/docs.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib/http.ts | New guarded fetch helpers with allowlists, timeouts, and response size limits. |
| src/lib/cli-options.ts | New shared CLI option parsing helpers with missing-value rejection. |
| src/package-registries.ts | Use guarded JSON fetches and normalize npm/PyPI metadata before use. |
| src/official-index.ts | Use guarded text fetch for official index page summaries with origin allowlist. |
| src/mirror.ts | Prevent mirror artifact path traversal; guarded GitHub raw fetch; summary materialization for *-summary methods. |
| src/discover.ts | Guarded official index fetch; reference-source harvesting changes; utilization reporting refinements. |
| src/pipeline.ts | Workspace pipeline now explicitly runs recommend report; fix install batching completion check. |
| src/wire.ts | Change wire mode default to preview (but see review comment about --apply). |
| src/cli.ts | Reset process-local GitHub state on bootstrap; add doctor alias; simplify top-level error output. |
| src/github.ts | Add clearGitHubState() to reset throttling/health-update state between in-process invocations. |
| src/host-adapters/vscode.ts | Resolve VS Code settings path lazily and thread it through patch/reset flows. |
| src/workspace.ts / src/setup.ts / src/recommend.ts / src/install.ts / src/activate.ts | Adopt shared CLI option parsing helpers and remove local duplicates. |
| src/tests/*.test.ts | Add regression coverage for dotenv parsing, CLI option parsing, mirror path safety, PyPI normalization, and VS Code settings. |
| README.md / Roadmap.md / IMPLEMENTATION-PLAN.md / CHANGELOG.md / package.json | Update docs/metadata to reflect new defaults and hardening behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/wire.ts (1)
61-79:⚠️ Potential issue | 🔴 Critical | ⚡ Quick win
--applyis silently treated as--preview— critical regression.
--applyis included inmodeFlagsfor conflict detection but has no explicitreturn "apply"branch. Before this PR, falling through to the defaultreturn "apply"made it work by coincidence. Now that the default was changed toreturn "preview", any invocation ofwire <host> --applyquietly produces preview-only behaviour: no host settings are mutated, no error is raised, and the caller has no indication that the apply was skipped.🐛 Proposed fix
if (modeFlags[0] === "--preview") { return "preview"; } + if (modeFlags[0] === "--apply") { + return "apply"; + } + return "preview"; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/wire.ts` around lines 61 - 79, The function getWireMode currently detects --apply in modeFlags but lacks an explicit branch, so --apply falls through to the default "preview"; update getWireMode to explicitly handle the "--apply" flag (check modeFlags[0] or use a switch over the detected flag) and return "apply" when present, keeping existing conflict detection and retaining the default behaviour for no flags; reference the getWireMode function and the modeFlags variable when making the fix.
🧹 Nitpick comments (1)
src/cli.ts (1)
98-101: ⚡ Quick winStack trace is suppressed for all
Errorinstances — consider preserving it for unexpected failures.
error instanceof Error ? error.message : errorstrips the stack trace for everyError, including unexpected internal errors (I/O failures, assertion violations, etc.). User-facing CLI errors like "Missing value for '--host'." read fine, but a buggy code path would only surface its message with no location.The existing
console.error(error)call in Node.js already prints the message prominently at the top, followed by the stack — which is the best of both worlds.♻️ Proposed alternatives
Option A — restore full error output (simplest):
- console.error(error instanceof Error ? error.message : error); + console.error(error);Option B — clean output by default, stack on
--debug:- console.error(error instanceof Error ? error.message : error); + const debug = process.argv.includes("--debug"); + console.error(error instanceof Error && !debug ? error.message : error);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cli.ts` around lines 98 - 101, The catch handler in src/cli.ts currently logs only error messages (console.error(error instanceof Error ? error.message : error)), which strips Error stacks; change the handler to pass the original error through to console.error (i.e., log the error object rather than just error.message) so stack traces are preserved for unexpected failures (keep setting process.exitCode = 1), or implement conditional stack printing using the same catch handler (check error instanceof Error and print error.stack when a debug flag/ENV is set).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/discover.ts`:
- Around line 472-490: The per-source status logic now distinguishes
"reference-only" (has catalog entries but no operational entries) from "dormant"
(no entries), but the aggregate dormantSourceCount still counts every
non-operational source; update the dormantSourceCount calculation to match the
per-source status by counting only sources with zero catalog entries (i.e.,
sourceEntries.length === 0) rather than all non-operational ones. Locate the
block that builds sources (the enabledSources.map producing
id/kind/configured/operational/harvestedEntries/operationalEntries/status) and
ensure the dormantSourceCount computation uses the same criteria (check
sourceEntries.length) so that dormantSourceCount only increments when a source's
status === "dormant".
In `@src/lib/http.ts`:
- Around line 17-29: fetchWithTimeout currently overwrites any caller-provided
options.signal, preventing upstream cancellation; modify fetchWithTimeout to
preserve and merge the incoming options.signal with the timeout AbortController
(e.g., create a timeout controller and if options.signal exists use
AbortSignal.any([options.signal, timeoutController.signal]) for the final signal
or attach a listener that aborts the timeout controller when options.signal
fires), pass that merged signal into fetch, and ensure you still clear the
timeout and remove any listeners in the finally block so no leaks occur; update
references in fetchWithTimeout to use the merged signal instead of directly
using controller.signal.
In `@src/package-registries.ts`:
- Around line 120-139: Normalize and validate PyPI URL fields before storing:
when building the returned info object in package-registries (fields
info.home_page and info.project_urls via normalizeStringRecord), parse each URL
string and only keep values that are valid absolute URLs with scheme "http" or
"https" and a non-empty host; otherwise set home_page to undefined and
drop/replace invalid project_urls entries. Update normalizeStringRecord (or its
caller) to perform this filtering/normalization so downstream functions like
extractRepositoryUrlFromPypiMetadata only see bona fide http(s) URLs; apply the
same validation logic to the other similar block that constructs
info.project_urls/info.home_page later in the file (the block referenced in the
review).
---
Outside diff comments:
In `@src/wire.ts`:
- Around line 61-79: The function getWireMode currently detects --apply in
modeFlags but lacks an explicit branch, so --apply falls through to the default
"preview"; update getWireMode to explicitly handle the "--apply" flag (check
modeFlags[0] or use a switch over the detected flag) and return "apply" when
present, keeping existing conflict detection and retaining the default behaviour
for no flags; reference the getWireMode function and the modeFlags variable when
making the fix.
---
Nitpick comments:
In `@src/cli.ts`:
- Around line 98-101: The catch handler in src/cli.ts currently logs only error
messages (console.error(error instanceof Error ? error.message : error)), which
strips Error stacks; change the handler to pass the original error through to
console.error (i.e., log the error object rather than just error.message) so
stack traces are preserved for unexpected failures (keep setting
process.exitCode = 1), or implement conditional stack printing using the same
catch handler (check error instanceof Error and print error.stack when a debug
flag/ENV is set).
🪄 Autofix (Beta)
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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2e08c7aa-d4c8-432d-ab7c-8afea5e36c33
📒 Files selected for processing (25)
CHANGELOG.mdIMPLEMENTATION-PLAN.mdREADME.mdRoadmap.mdpackage.jsonsrc/activate.tssrc/cli.tssrc/discover.tssrc/github.tssrc/host-adapters/vscode.tssrc/install.tssrc/lib/cli-options.tssrc/lib/http.tssrc/mirror.tssrc/official-index.tssrc/package-registries.tssrc/pipeline.tssrc/recommend.tssrc/setup.tssrc/tests/cli-options.test.tssrc/tests/env-file.test.tssrc/tests/security-hardening.test.tssrc/tests/vscode-settings.test.tssrc/wire.tssrc/workspace.ts
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 25 out of 25 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
Addresses the post-merge repository audit with focused hardening, safer defaults, and updated documentation.
Security and runtime hardening
.envloading and runtime config resetLifecycle and CLI behavior
wire <host>default to preview; require explicit--applyor--resetfor mutationsrecommend reportexplicitly in workspace orchestration instead of relying ondiscover selectside effectsdoctorand defaultrecommend reportbehaviorSource utilization and docs
Tests
Validation
npm run typechecknpm run lintnpm run format:checknpm run buildnpm testnpm run smoke:clinpm run benchmark:scannpm run quality:detectionnpm run quality:policynpm run validate:recommendationsgit diff --checknode ./dist/cli.js setup doctor --host --other(fails with the expected missing-value message)node ./dist/cli.js wire cursor(defaults to preview)Summary by CodeRabbit
Release Notes
New Features
--applyor--resetfor mutationsBug Fixes
Documentation & Tests