feat(pacquet): implement bugs command#12687
Conversation
|
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 ChangesBugs command and supporting infrastructure
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
✨ 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. Comment |
PR Summary by QodoAdd Description
Diagram
High-Level Assessment
Files changed (4)
|
Code Review by Qodo
Context used✅ Tickets:
🎫 Rust Roadmap 1. Hardcoded hook PATH
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@pacquet/crates/cli/src/cli_args/bugs.rs`:
- Around line 309-317: The Windows-specific URL launcher in open_url_in_browser
is vulnerable because cmd /c start re-parses attacker-controlled URLs and can
interpret shell metacharacters. Replace this shell-based launch path with a safe
launcher approach that does not invoke cmd.exe on Windows, or add strict
validation to reject URLs containing shell metacharacters before opening them.
Update the bugs/repository URL flow around pick_bugs_url and open_url_in_browser
so the launch path is safe for attacker-controlled manifest data.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 434d4a82-08c0-442e-b200-6fbb09a75ae9
📒 Files selected for processing (4)
pacquet/crates/cli/src/cli_args.rspacquet/crates/cli/src/cli_args/bugs.rspacquet/crates/cli/src/cli_args/bugs/tests.rspacquet/crates/cli/tests/bugs.rs
|
Code review by qodo was updated up to the latest commit 3821e4b |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #12687 +/- ##
==========================================
+ Coverage 85.24% 85.27% +0.03%
==========================================
Files 407 409 +2
Lines 61864 62079 +215
==========================================
+ Hits 52734 52940 +206
- Misses 9130 9139 +9 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Integrated-Benchmark Report (Linux)Commit: Each scenario reports direct installs and pnpr installs. Bencher consumes pacquet@HEAD and pnpr@HEAD. Scenario: Isolated linker: fresh restore, cold cache + cold store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 3.81350806086,
"stddev": 0.16380215586094632,
"median": 3.73844986806,
"user": 3.5699700799999987,
"system": 3.3819558,
"min": 3.60512047256,
"max": 4.06881038656,
"times": [
3.76045224656,
3.7164474895599997,
3.7157980085599998,
4.06881038656,
3.9619634485599997,
3.88642570756,
3.71604831756,
4.0407848585599995,
3.60512047256,
3.66322967256
]
},
{
"command": "pacquet@main",
"mean": 3.78059420516,
"stddev": 0.11699261389367892,
"median": 3.80623871756,
"user": 3.6188499800000002,
"system": 3.3910711,
"min": 3.6164225645599997,
"max": 3.94366819656,
"times": [
3.6248205885599996,
3.84206772956,
3.68010905856,
3.70727433256,
3.89932634956,
3.78534713256,
3.94366819656,
3.8797757965599997,
3.6164225645599997,
3.8271303025599996
]
},
{
"command": "pnpr@HEAD",
"mean": 2.16281494996,
"stddev": 0.14004088485357083,
"median": 2.10048199656,
"user": 2.65190278,
"system": 3.0421213000000003,
"min": 2.01005050656,
"max": 2.37151868456,
"times": [
2.3538790495599997,
2.27787883156,
2.26799844456,
2.01005050656,
2.0295854045599997,
2.0354890485599997,
2.08747333456,
2.11349065856,
2.0807855365599996,
2.37151868456
]
},
{
"command": "pnpr@main",
"mean": 2.13933156326,
"stddev": 0.10961432000078361,
"median": 2.11598733606,
"user": 2.6640449799999995,
"system": 3.0230268,
"min": 2.02083420556,
"max": 2.3516355185599997,
"times": [
2.2110584365599997,
2.27297496056,
2.1262707765599997,
2.1057038955599996,
2.09283832156,
2.14549708856,
2.02083420556,
2.03094069956,
2.3516355185599997,
2.03556172956
]
}
]
}Scenario: Isolated linker: fresh restore, hot cache + hot store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 0.6402141846,
"stddev": 0.015967133098974677,
"median": 0.6400935205,
"user": 0.3722578999999999,
"system": 1.3172068399999997,
"min": 0.6193850575,
"max": 0.6763016015,
"times": [
0.6346770245,
0.6193850575,
0.6462890365,
0.6241854565,
0.6288798995,
0.6763016015,
0.6441932244999999,
0.6471373845,
0.6450993445,
0.6359938165
]
},
{
"command": "pacquet@main",
"mean": 0.6577384018,
"stddev": 0.05436424615023598,
"median": 0.642605436,
"user": 0.37803829999999994,
"system": 1.3218886399999998,
"min": 0.6172070335,
"max": 0.8081182705,
"times": [
0.6400653685,
0.6509001605,
0.6172070335,
0.6302607765,
0.6331569355,
0.6474248244999999,
0.6408326805,
0.6443781915,
0.8081182705,
0.6650397765
]
},
{
"command": "pnpr@HEAD",
"mean": 0.6842714945,
"stddev": 0.018073770945984884,
"median": 0.682817982,
"user": 0.3855723,
"system": 1.34986464,
"min": 0.6626243695,
"max": 0.7181832164999999,
"times": [
0.6877076995,
0.6958635925,
0.6658521945,
0.6695640905,
0.6917850395,
0.6706029065,
0.6626243695,
0.6779282645,
0.7181832164999999,
0.7026035715
]
},
{
"command": "pnpr@main",
"mean": 0.7079979106,
"stddev": 0.015167146466108101,
"median": 0.7043126555,
"user": 0.40685529999999986,
"system": 1.3576191399999997,
"min": 0.6867400225,
"max": 0.7362584605,
"times": [
0.7139788415,
0.7362584605,
0.7288694314999999,
0.7030169475,
0.7021496205,
0.7089475135,
0.6867400225,
0.6922133335,
0.7021965715,
0.7056083635
]
}
]
}Scenario: Isolated linker: fresh install, cold cache + cold store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 4.319302100879999,
"stddev": 0.09013012036849323,
"median": 4.30235567828,
"user": 3.8102215999999993,
"system": 3.3944811199999996,
"min": 4.23649976728,
"max": 4.537222701279999,
"times": [
4.537222701279999,
4.28822928228,
4.2660305982799995,
4.32089747428,
4.24150932328,
4.23649976728,
4.25780623728,
4.31648207428,
4.387532310279999,
4.34081124028
]
},
{
"command": "pacquet@main",
"mean": 4.35067842588,
"stddev": 0.04001742771238971,
"median": 4.35123037978,
"user": 3.8423939999999996,
"system": 3.43118852,
"min": 4.27148645628,
"max": 4.40122125028,
"times": [
4.33496805028,
4.3334170172799995,
4.35990594028,
4.342554819279999,
4.36492665828,
4.40122125028,
4.27148645628,
4.392466241279999,
4.391203506279999,
4.31463431928
]
},
{
"command": "pnpr@HEAD",
"mean": 2.2062672702800006,
"stddev": 0.11338319565302123,
"median": 2.1881260197800003,
"user": 2.4922007,
"system": 2.9325475199999995,
"min": 2.07080202628,
"max": 2.3778372022800003,
"times": [
2.35479707628,
2.12368376428,
2.3778372022800003,
2.23478496428,
2.11909621128,
2.07080202628,
2.27425623828,
2.28474529928,
2.08120284528,
2.14146707528
]
},
{
"command": "pnpr@main",
"mean": 2.20359535028,
"stddev": 0.1309031283226149,
"median": 2.2108884812800005,
"user": 2.5005597,
"system": 2.8974872199999995,
"min": 2.0006100242800002,
"max": 2.45893850528,
"times": [
2.2107909282800002,
2.23137701928,
2.33292223028,
2.2109860342800003,
2.0006100242800002,
2.06321765328,
2.1147357652800003,
2.24223254728,
2.17014279528,
2.45893850528
]
}
]
}Scenario: Isolated linker: fresh install, hot cache + hot store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 1.3321333901799999,
"stddev": 0.012813470319940599,
"median": 1.32977847678,
"user": 1.3126988799999997,
"system": 1.67261822,
"min": 1.31393610128,
"max": 1.35395563028,
"times": [
1.35395563028,
1.33176017928,
1.31393610128,
1.32160576928,
1.33568874628,
1.34928463428,
1.31999187328,
1.3400473962800001,
1.32726679728,
1.3277967742799999
]
},
{
"command": "pacquet@main",
"mean": 1.3448455895799998,
"stddev": 0.01849315646046127,
"median": 1.3417195562800002,
"user": 1.3093647800000001,
"system": 1.7019837199999999,
"min": 1.32003940428,
"max": 1.37691452628,
"times": [
1.32629450728,
1.35720671928,
1.35353850628,
1.3380027272800001,
1.32003940428,
1.37691452628,
1.3366612362799999,
1.34543638528,
1.32798933128,
1.36637255228
]
},
{
"command": "pnpr@HEAD",
"mean": 0.6631252705799999,
"stddev": 0.016012520487786674,
"median": 0.66247784978,
"user": 0.33393628,
"system": 1.2782676199999998,
"min": 0.64136919728,
"max": 0.7011127742800001,
"times": [
0.67211229328,
0.66185380328,
0.65201965428,
0.7011127742800001,
0.6560496892800001,
0.66488692628,
0.66659088328,
0.64136919728,
0.65215558828,
0.66310189628
]
},
{
"command": "pnpr@main",
"mean": 0.6638804689800001,
"stddev": 0.006823029653986641,
"median": 0.6643770842800001,
"user": 0.34051408,
"system": 1.2796596199999999,
"min": 0.65130784528,
"max": 0.67304866628,
"times": [
0.66015855128,
0.65130784528,
0.65646157928,
0.66213273328,
0.67304866628,
0.67292010628,
0.6681541212800001,
0.66388143428,
0.66487273428,
0.66586691828
]
}
]
}Scenario: Isolated linker: fresh install, cold cache + hot store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 3.02317627436,
"stddev": 0.02677740062711613,
"median": 3.01978199706,
"user": 1.7854871000000003,
"system": 1.9497360999999995,
"min": 2.98812697006,
"max": 3.08176152706,
"times": [
3.01185618006,
3.01863876406,
3.02092523006,
3.03795495306,
2.99934879506,
3.08176152706,
3.00364506106,
3.02467478806,
2.98812697006,
3.04483047506
]
},
{
"command": "pacquet@main",
"mean": 3.05116537126,
"stddev": 0.047333562437288666,
"median": 3.0386896115599997,
"user": 1.8143661999999998,
"system": 1.9751954,
"min": 3.00345705406,
"max": 3.16808712206,
"times": [
3.05463203506,
3.0327630550599998,
3.00345705406,
3.03314010406,
3.0442391190599998,
3.00792260206,
3.02576794706,
3.16808712206,
3.06067071706,
3.08097395706
]
},
{
"command": "pnpr@HEAD",
"mean": 0.6702514885599999,
"stddev": 0.012409238512558367,
"median": 0.66904578756,
"user": 0.34744169999999996,
"system": 1.2952583,
"min": 0.64962153706,
"max": 0.6939376700600001,
"times": [
0.67191029106,
0.6939376700600001,
0.6697500940600001,
0.66471220606,
0.68682794006,
0.66500462106,
0.66987015206,
0.66253889306,
0.64962153706,
0.66834148106
]
},
{
"command": "pnpr@main",
"mean": 0.69083325406,
"stddev": 0.04742514800084136,
"median": 0.67539160356,
"user": 0.3438021,
"system": 1.2768428,
"min": 0.6664340590600001,
"max": 0.8246905950600001,
"times": [
0.6853382570600001,
0.6664340590600001,
0.68043845906,
0.6721094010600001,
0.68471696606,
0.6775635170600001,
0.67321969006,
0.67241719006,
0.8246905950600001,
0.6714044060600001
]
}
]
}Scenario: Isolated linker: fresh restore, cold cache + cold store + cold pnpr
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 7.19276034978,
"stddev": 0.18387492344659243,
"median": 7.18753150838,
"user": 3.8366562,
"system": 3.68135374,
"min": 6.9920549458800005,
"max": 7.60462500488,
"times": [
7.60462500488,
6.99874689688,
7.04286941188,
7.14440006388,
6.9920549458800005,
7.09299669388,
7.23066295288,
7.26650932288,
7.29714176188,
7.257596442880001
]
},
{
"command": "pacquet@main",
"mean": 7.648297078480001,
"stddev": 1.3789775894670975,
"median": 7.21830719188,
"user": 3.997076,
"system": 3.9085173399999995,
"min": 7.146354365880001,
"max": 11.56911746288,
"times": [
7.146354365880001,
7.181204864880001,
7.1480342428800006,
7.31862717288,
7.29864704688,
11.56911746288,
7.238013399880001,
7.21842669088,
7.21818769288,
7.14635784488
]
},
{
"command": "pnpr@HEAD",
"mean": 5.604801475980001,
"stddev": 0.10912320303667473,
"median": 5.595071171880001,
"user": 2.7712118,
"system": 3.23614604,
"min": 5.45466044788,
"max": 5.78407632888,
"times": [
5.60323311788,
5.55276051888,
5.58690922588,
5.639202789880001,
5.554887267880001,
5.7672304078800005,
5.46905578588,
5.78407632888,
5.45466044788,
5.635998868880001
]
},
{
"command": "pnpr@main",
"mean": 5.62800770348,
"stddev": 0.08420500193727867,
"median": 5.59950935038,
"user": 2.8018721999999996,
"system": 3.26697294,
"min": 5.537848593880001,
"max": 5.780682785880001,
"times": [
5.62422918388,
5.69006261988,
5.5595296778800005,
5.56776330088,
5.780682785880001,
5.57478951688,
5.71647569188,
5.537848593880001,
5.68202475888,
5.54667090488
]
}
]
} |
|
| Branch | pr/12687 |
| Testbed | pnpr |
⚠️ WARNING: No Threshold found!Without a Threshold, no Alerts will ever be generated.
Click here to create a new Threshold
For more information, see the Threshold documentation.
To only post results if a Threshold exists, set the--ci-only-thresholdsflag.
Click to view all benchmark results
| Benchmark | Latency | milliseconds (ms) |
|---|---|---|
| isolated-linker.fresh-install.cold-cache.cold-store | 📈 view plot | 2,206.27 ms |
| isolated-linker.fresh-install.cold-cache.hot-store | 📈 view plot | 670.25 ms |
| isolated-linker.fresh-install.hot-cache.hot-store | 📈 view plot | 663.13 ms |
| isolated-linker.fresh-restore.cold-cache.cold-store | 📈 view plot | 2,162.81 ms |
| isolated-linker.fresh-restore.cold-cache.cold-store.cold-pnpr | 📈 view plot | 5,604.80 ms |
| isolated-linker.fresh-restore.hot-cache.hot-store | 📈 view plot | 684.27 ms |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
pacquet/crates/cli/src/cli_args/audit/signatures.rs (1)
519-519: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMove this
useto the top with the other imports.The new
use crate::cli_args::package_name::encode_package_name;is placed at the bottom of the file, detached from the rest of the import block. rustfmt won't relocate it, so it stays an outlier. Merge it into the top crate-local imports for consistency.As per path instructions (pacquet/CODE_STYLE_GUIDE.md: "keep imports merged by crate").
🤖 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 `@pacquet/crates/cli/src/cli_args/audit/signatures.rs` at line 519, The new crate-local import for encode_package_name is isolated at the bottom of signatures.rs instead of being merged with the existing import block. Move it into the top grouped imports near the other crate imports in the audit/signatures module so the import layout stays consistent and rustfmt won’t leave it as an outlier.
🤖 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 `@pacquet/crates/cli/src/cli_args/patch_remove/tests.rs`:
- Around line 86-88: The patch-remove cancellation test is currently skipping
itself under a TTY, which removes the PatchRemoveError::Canceled assertion
instead of enforcing the required non-interactive stdin setup. Update the test
in tests.rs to keep the cancellation behavior verified by either making
non-interactive stdin a hard precondition or using a test harness/helper that
explicitly supplies non-interactive input, so the test still asserts the
canceled error path rather than returning early.
In `@pacquet/crates/cli/src/cli_args/patch/tests.rs`:
- Around line 70-71: The stdin TTY guard in the patch cancellation tests is
causing them to return early and stop verifying the PatchError::Canceled
regression locally. Remove the silent skip in these tests, or refactor the
stdin-dependent behavior behind a seam/harness so the dialoguer path can be
forced even when stdin is interactive. Keep the assertions in the existing test
cases in tests.rs focused on the cancel contract rather than bypassing the test
body.
---
Nitpick comments:
In `@pacquet/crates/cli/src/cli_args/audit/signatures.rs`:
- Line 519: The new crate-local import for encode_package_name is isolated at
the bottom of signatures.rs instead of being merged with the existing import
block. Move it into the top grouped imports near the other crate imports in the
audit/signatures module so the import layout stays consistent and rustfmt won’t
leave it as an outlier.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 1ea5ec12-bb8a-4ca5-a85d-791cb9e856c9
📒 Files selected for processing (8)
pacquet/crates/cli/src/cli_args.rspacquet/crates/cli/src/cli_args/audit/signatures.rspacquet/crates/cli/src/cli_args/bugs.rspacquet/crates/cli/src/cli_args/bugs/tests.rspacquet/crates/cli/src/cli_args/package_name.rspacquet/crates/cli/src/cli_args/patch/tests.rspacquet/crates/cli/src/cli_args/patch_remove/tests.rspacquet/crates/cli/tests/bugs.rs
✅ Files skipped from review due to trivial changes (1)
- pacquet/crates/cli/src/cli_args/package_name.rs
🚧 Files skipped from review as they are similar to previous changes (4)
- pacquet/crates/cli/src/cli_args.rs
- pacquet/crates/cli/tests/bugs.rs
- pacquet/crates/cli/src/cli_args/bugs.rs
- pacquet/crates/cli/src/cli_args/bugs/tests.rs
|
Code review by qodo was updated up to the latest commit b8d08c4 |
|
Code review by qodo was updated up to the latest commit b8d08c4 |
|
Code review by qodo was updated up to the latest commit 7e0edd5 |
| fn open_url(url: &str) { | ||
| println!("{url}"); | ||
| let result = open_url_in_browser(url); | ||
| if let Err(err) = result { | ||
| tracing::debug!(target: "pacquet_cli", %err, "could not open browser"); | ||
| } |
There was a problem hiding this comment.
1. Bugs url credential leak 🐞 Bug ⛨ Security
open_url() prints the derived bugs URL verbatim, so inline user:pass@ credentials coming from package.json or registry metadata can be leaked into terminal output/CI logs. The URL is then also passed through to the browser launcher without redaction/stripping.
Agent Prompt
### Issue description
`pacquet bugs` prints the bugs URL to stdout via `println!("{url}")`. If the URL contains embedded basic-auth (`https://user:pass@host/...`), those credentials are leaked into terminal output and CI logs.
### Issue Context
The repo already has a dedicated credential redaction utility (`pacquet_network::redact_url_credentials`) and uses it before printing untrusted URLs in other commands (e.g. `ping`).
### Fix Focus Areas
- pacquet/crates/cli/src/cli_args/bugs.rs[282-287]
- pacquet/crates/cli/src/cli_args/bugs.rs[141-165]
### Expected fix
- Redact credentials before printing (at minimum).
- Prefer also stripping userinfo before launching the browser (parse with `url::Url`, clear username/password, and open the cleaned URL), since bug tracker URLs should not require embedded credentials.
- Reuse the existing redaction helper (`pacquet_network::redact_url_credentials`) to match established repo behavior.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
Code review by qodo was updated up to the latest commit 7e0edd5 |
Port the `pnpm bugs` command from TypeScript to Rust, opening the package's bug report URL in the default browser (or printing it). Extracts `encode_package_name` / `encode_uri_component` into a shared `package_name` module, replacing private copies in `audit/signatures` and `self_update/verify_engine`. Review feedback applied: - dylint import-granularity (merged two `use crate::cli_args::...` lines) - dylint bare-url (wrapped bare https:// in comment with backticks) - CodeRabbitAI security: `rundll32.exe` uses absolute path from `%SystemRoot%` instead of bare executable name Ref pnpm#12687
|
Code review by qodo was updated up to the latest commit cd59e46 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@pacquet/crates/cli/src/cli_args/self_update/verify_engine.rs`:
- Around line 467-480: The packument fetch in verify_engine currently uses
response.text().await, which buffers the entire body before the size check and
can still exhaust memory. Update the packument reading logic to stream the
response incrementally inside the same trust-critical path, enforcing
MAX_PACKUMENT_BYTES as chunks are read rather than after full buffering. Keep
the existing oversized-response handling and error reporting around display_url
and redact_url_credentials, but move the cap enforcement into the streaming read
flow.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 59d7283f-d7cb-4271-b0d8-99365a97f16a
📒 Files selected for processing (10)
pacquet/crates/cli/src/cli_args.rspacquet/crates/cli/src/cli_args/audit/signatures.rspacquet/crates/cli/src/cli_args/bugs.rspacquet/crates/cli/src/cli_args/bugs/tests.rspacquet/crates/cli/src/cli_args/cli_command.rspacquet/crates/cli/src/cli_args/dispatch.rspacquet/crates/cli/src/cli_args/dispatch_query.rspacquet/crates/cli/src/cli_args/package_name.rspacquet/crates/cli/src/cli_args/self_update/verify_engine.rspacquet/crates/cli/tests/bugs.rs
✅ Files skipped from review due to trivial changes (1)
- pacquet/crates/cli/src/cli_args/bugs/tests.rs
🚧 Files skipped from review as they are similar to previous changes (4)
- pacquet/crates/cli/src/cli_args/package_name.rs
- pacquet/crates/cli/tests/bugs.rs
- pacquet/crates/cli/src/cli_args/audit/signatures.rs
- pacquet/crates/cli/src/cli_args/bugs.rs
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 1
🤖 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 `@pacquet/crates/cli/src/cli_args/self_update/verify_engine.rs`:
- Around line 467-480: The packument fetch in verify_engine currently uses
response.text().await, which buffers the entire body before the size check and
can still exhaust memory. Update the packument reading logic to stream the
response incrementally inside the same trust-critical path, enforcing
MAX_PACKUMENT_BYTES as chunks are read rather than after full buffering. Keep
the existing oversized-response handling and error reporting around display_url
and redact_url_credentials, but move the cap enforcement into the streaming read
flow.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 59d7283f-d7cb-4271-b0d8-99365a97f16a
📒 Files selected for processing (10)
pacquet/crates/cli/src/cli_args.rspacquet/crates/cli/src/cli_args/audit/signatures.rspacquet/crates/cli/src/cli_args/bugs.rspacquet/crates/cli/src/cli_args/bugs/tests.rspacquet/crates/cli/src/cli_args/cli_command.rspacquet/crates/cli/src/cli_args/dispatch.rspacquet/crates/cli/src/cli_args/dispatch_query.rspacquet/crates/cli/src/cli_args/package_name.rspacquet/crates/cli/src/cli_args/self_update/verify_engine.rspacquet/crates/cli/tests/bugs.rs
✅ Files skipped from review due to trivial changes (1)
- pacquet/crates/cli/src/cli_args/bugs/tests.rs
🚧 Files skipped from review as they are similar to previous changes (4)
- pacquet/crates/cli/src/cli_args/package_name.rs
- pacquet/crates/cli/tests/bugs.rs
- pacquet/crates/cli/src/cli_args/audit/signatures.rs
- pacquet/crates/cli/src/cli_args/bugs.rs
🛑 Comments failed to post (1)
pacquet/crates/cli/src/cli_args/self_update/verify_engine.rs (1)
467-480: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Read the packument incrementally before applying the size cap.
response.text().awaitbuffers the entire response first, so a chunked or incorrectContent-Lengthcan still exhaust memory on this trust-critical path.🤖 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 `@pacquet/crates/cli/src/cli_args/self_update/verify_engine.rs` around lines 467 - 480, The packument fetch in verify_engine currently uses response.text().await, which buffers the entire body before the size check and can still exhaust memory. Update the packument reading logic to stream the response incrementally inside the same trust-critical path, enforcing MAX_PACKUMENT_BYTES as chunks are read rather than after full buffering. Keep the existing oversized-response handling and error reporting around display_url and redact_url_credentials, but move the cap enforcement into the streaming read flow.
|
Code review by qodo was updated up to the latest commit cd59e46 |
There was a problem hiding this comment.
Pull request overview
Adds the pacquet bugs CLI command (parity feature with pnpm bugs) and supporting URL/registry plumbing so pacquet can derive and open a package’s bug tracker URL from either the local package.json or the registry.
Changes:
- Introduces
pacquet bugs(aliasissues) with URL derivation frombugs/repositoryfields and browser launch, plus unit + integration tests. - Centralizes JS-compatible URL encoding (
encodeURIComponent+ pnpm-style scoped package encoding) inpacquet_networkand updates registry callers to use it (including holding throttling permits across body consumption). - Updates
pnprserver routing to correctly serve/<encoded-scoped-name>/<tag>requests where%2Fis decoded into/.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpr/crates/pnpr/src/server.rs | Route fix for encoded scoped package name + tag paths. |
| pacquet/crates/resolving-git-resolver/src/hosted_git.rs | Switch to shared URL-encoding helper. |
| pacquet/crates/registry/src/package.rs | Encode package name in registry URLs; hold throttling guard across request+body. |
| pacquet/crates/registry/src/package_version.rs | Encode package name + tag segment in version-manifest URLs; hold throttling guard. |
| pacquet/crates/registry/src/package_tag.rs | Add tag support + registry path-segment helper for tags/versions. |
| pacquet/crates/package-manager/src/add/tests.rs | Update mocks for encoded scoped package paths. |
| pacquet/crates/network/src/url_encoding.rs | New shared URL encoding helpers (encode_uri_component, encode_package_name). |
| pacquet/crates/network/src/lib.rs | Re-export URL encoding helpers and wire in new module. |
| pacquet/crates/cli/tests/bugs.rs | New integration tests for pacquet bugs behavior (local + registry). |
| pacquet/crates/cli/src/cli_args/self_update/verify_engine.rs | Use shared package-name encoding; stream response with size cap. |
| pacquet/crates/cli/src/cli_args/dist_tag.rs | Use shared URI-component encoding (dedupe local implementation). |
| pacquet/crates/cli/src/cli_args/dispatch.rs | Wire Bugs command into dispatch. |
| pacquet/crates/cli/src/cli_args/dispatch_query.rs | Add bugs dispatcher entrypoint. |
| pacquet/crates/cli/src/cli_args/cli_command.rs | Define bugs/issues CLI command and help text. |
| pacquet/crates/cli/src/cli_args/bugs/tests.rs | New unit tests for URL derivation + spec parsing. |
| pacquet/crates/cli/src/cli_args/bugs.rs | New bugs command implementation (manifest + registry lookup + open). |
| pacquet/crates/cli/src/cli_args/audit/signatures/tests.rs | Update imports to shared package-name encoding. |
| pacquet/crates/cli/src/cli_args/audit/signatures.rs | Use shared package-name encoding (dedupe local implementation). |
| pacquet/crates/cli/src/cli_args.rs | Export the new bugs module. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Code review by qodo was updated up to the latest commit 84cc28d |
|
Code review by qodo was updated up to the latest commit 7dfa6d7 |
|
Code review by qodo was updated up to the latest commit 84cc28d |
Drop logout's private encode_uri_component (and its hex_upper helper) in favor of pacquet_network::encode_uri_component. The two produce identical output (uppercase two-digit hex, same unreserved set), so this removes a duplicate. Left dist_tag's escaped_package_name as-is: its lowercase %2f matches npm-package-arg's escapedName for the dist-tags endpoint, which is intentionally distinct from encode_package_name's uppercase %2F toUri encoding for packument URLs.
|
Code review by qodo was updated up to the latest commit e713c5b |
1 similar comment
|
Code review by qodo was updated up to the latest commit e713c5b |
|
Code review by qodo was updated up to the latest commit 2613f5a |
|
@zkochan I don't know if it's on purpose or not, but you forgot to enable auto-merge |
registry_path_segment claimed to return a URL-encoded segment but the Version branch returned the raw semver string. Route it through encode_uri_component too so build metadata (the '+' in e.g. 1.2.3+build) cannot corrupt the request path. Add a unit test covering all variants.
|
Code review by qodo was updated up to the latest commit 4ce8a6b |
1 similar comment
|
Code review by qodo was updated up to the latest commit 4ce8a6b |

Port the
pnpm bugscommand from the TypeScript CLI to pacquet (Rust). The command opens the bug tracker URL of a package in the default browser. When called with no arguments, it reads the current project'spackage.jsonand derives the URL from thebugsorrepositoryfield. When called with package names, it fetches each package's latest version from the registry and derives the URL from the published manifest.The implementation follows the same structure as the pnpm handler:
pickBugsUrlprefersbugs(string or{url}) then falls back torepositorywithrepositoryToIssuesUrlnormalization. Hosted git shorthands (GitHub, GitLab, Bitbucket),git+https:///SCP-style SSH, and self-hosted git server URLs are all handled. The URL is printed to stdout and the browser is launched viaxdg-open/open/start with output suppressed.Related to #11633.
This change is pacquet-only; the TypeScript implementation already exists in
pnpm11/deps/inspection/commands/src/bugs/.pacquet/port, or the description notes what still needs porting.Summary by CodeRabbit
New Features
bugsCLI command to open project or package issue pages in your browser.Bug Fixes
Tests