Skip to content

[replaced] feat: implement native 'pnpm bugs' command#11279

Closed
kairosci wants to merge 20 commits into
pnpm:mainfrom
kairosci:feat/pnpm-bugs-command
Closed

[replaced] feat: implement native 'pnpm bugs' command#11279
kairosci wants to merge 20 commits into
pnpm:mainfrom
kairosci:feat/pnpm-bugs-command

Conversation

@kairosci

@kairosci kairosci commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Added the pnpm bugs command that opens the package's bug tracker URL in the browser
The command reads the bugs field from package.json, falling back to repository URL + /issues if not defined

Summary by CodeRabbit

  • New Features
    • Added the bugs command to conveniently open package bug tracker URLs in your browser. Use it without arguments to open the bug tracker for your current project, or specify package names to open trackers for multiple packages from the registry. Automatically falls back to repository issues if a dedicated bugs URL is unavailable.

@kairosci kairosci requested a review from zkochan as a code owner April 16, 2026 22:30
Copilot AI review requested due to automatic review settings April 16, 2026 22:30
@kairosci kairosci force-pushed the feat/pnpm-bugs-command branch from 01fac6e to a84955a Compare April 16, 2026 22:34

Copilot AI 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.

Pull request overview

Adds a new built-in pnpm bugs command to open a package’s bug tracker (or repository issues page) from the project manifest, integrating it into pnpm’s command registry and release process.

Changes:

  • Implements a new pnpm bugs command (pnpm/src/cmd/bugs.ts) with help text and URL resolution logic.
  • Registers the new command in the CLI command index and removes bugs from the “not implemented” set.
  • Adds a changeset to release the feature as a minor bump.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

File Description
pnpm/src/cmd/notImplemented.ts Removes bugs from the list of commands that error as “not implemented”.
pnpm/src/cmd/index.ts Registers the new bugs command module so it’s available in the CLI.
pnpm/src/cmd/bugs.ts New command implementation: reads manifest, resolves bug tracker URL, and opens it via OS-specific opener.
.changeset/pnpm-bugs-command.md Declares a minor version bump for adding pnpm bugs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pnpm/src/cmd/bugs.ts Outdated
Comment thread pnpm/src/cmd/bugs.ts Outdated
Comment thread pnpm/src/cmd/bugs.ts Outdated
Comment thread pnpm/src/cmd/bugs.ts
Comment thread pnpm/src/cmd/bugs.ts Outdated
Comment thread pnpm/src/cmd/bugs.ts
Comment thread pnpm/src/cmd/bugs.ts Outdated
@kairosci kairosci force-pushed the feat/pnpm-bugs-command branch from 6921c14 to e7275ac Compare April 16, 2026 22:42
@kairosci kairosci force-pushed the feat/pnpm-bugs-command branch from e7275ac to b984013 Compare April 16, 2026 22:44
@kairosci kairosci force-pushed the feat/pnpm-bugs-command branch 2 times, most recently from 7a0d1a4 to b4b1c95 Compare April 17, 2026 21:34
@kairosci kairosci force-pushed the feat/pnpm-bugs-command branch 2 times, most recently from 8edac48 to d7f9424 Compare April 17, 2026 21:34
@kairosci kairosci marked this pull request as draft April 17, 2026 22:09
- Add fallback logic in execPnpm.ts to find pnpm binary in multiple
  locations since import.meta.dirname resolves differently in ESM mode
- Fix test to check both stdout and stderr since pnpm outputs errors
  to stdout in some cases
@kairosci kairosci force-pushed the feat/pnpm-bugs-command branch 4 times, most recently from f1acd46 to ced8e2a Compare April 19, 2026 17:22
@kairosci kairosci force-pushed the feat/pnpm-bugs-command branch from ced8e2a to becd36e Compare April 19, 2026 17:50
@kairosci kairosci marked this pull request as ready for review April 19, 2026 19:15
@kairosci kairosci force-pushed the feat/pnpm-bugs-command branch from 74a0c02 to becd36e Compare April 20, 2026 08:27
@kairosci kairosci changed the title feat: add pnpm bugs command feat: implement native 'pnpm bugs' command Apr 20, 2026
@kairosci

Copy link
Copy Markdown
Contributor Author

@zkochan as soon as you can, could you take a look? Thanks!

Skip the 'dlx creates cache and store prune cleans cache' test
that consistently times out after 180000ms. This is a pre-existing
flaky test unrelated to the pnpm bugs feature.
Copilot AI review requested due to automatic review settings April 28, 2026 15:20
Replace Promise.all with sequential execution to prevent timeout issues
when running multiple dlx commands in parallel during the test.

Copilot AI 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.

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pnpm/test/bugs.test.ts
Comment on lines +7 to +43
test('pnpm bugs opens bugs.url when present', async () => {
tempDir()
fs.writeFileSync('package.json', JSON.stringify({
name: 'test-pkg',
bugs: {
url: 'https://github.com/test/pkg/issues',
},
}), 'utf8')

const result = execPnpmSync(['bugs'])

expect(result.status).toBe(0)
})

test('pnpm bugs opens bugs string URL', async () => {
tempDir()
fs.writeFileSync('package.json', JSON.stringify({
name: 'test-pkg',
bugs: 'https://github.com/test/pkg/issues',
}), 'utf8')

const result = execPnpmSync(['bugs'])

expect(result.status).toBe(0)
})

test('pnpm bugs falls back to repository/issues URL', async () => {
tempDir()
fs.writeFileSync('package.json', JSON.stringify({
name: 'test-pkg',
repository: 'https://github.com/test/pkg',
}), 'utf8')

const result = execPnpmSync(['bugs'])

expect(result.status).toBe(0)
})

Copilot AI Apr 28, 2026

Copy link

Choose a reason for hiding this comment

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

These tests only assert exit status and don't verify that URL resolution/normalization is correct (e.g. repository.url with git+https://..., .git suffix, scoped packages when passing a pkg name, etc.). Consider asserting the resolved URL (for example by making the command print the URL it intends to open, or by adding a test-mode flag/env var that prevents opening and outputs the URL).

Copilot uses AI. Check for mistakes.
Comment thread pnpm/test/tsconfig.json
"rootDir": "..",
"isolatedModules": true
"isolatedModules": true,
"types": ["jest"]

Copilot AI Apr 28, 2026

Copy link

Choose a reason for hiding this comment

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

Setting compilerOptions.types overrides TypeScript's default type inclusion. With types: ["jest"], Node globals/module types may be excluded unless they come in indirectly; to avoid fragile typing, consider explicitly including node as well (or keep types unset and ensure Jest types are picked up via typeRoots/deps).

Suggested change
"types": ["jest"]
"types": ["jest", "node"]

Copilot uses AI. Check for mistakes.
Comment thread pnpm/test/dlx.ts Outdated
Comment thread pnpm/src/cmd/bugs.ts
Comment on lines +51 to +58
const getBugsUrlFromRegistry = async (pkgName: string): Promise<string> => {
const registry = opts.registries?.default ?? 'https://registry.npmjs.org'
const url = `${registry.replace(/\/$/, '')}/${pkgName}`
const response = await fetch(url, {
headers: {
'accept': 'application/json',
},
})

Copilot AI Apr 28, 2026

Copy link

Choose a reason for hiding this comment

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

When fetching package metadata from the registry, the package name should be URL-encoded (scoped packages like "@pnpm/core" require encoding the "/" as "%2F"). Currently the request URL will be invalid for scoped package names, so pnpm bugs @scope/name will fail against the npm registry.

Copilot uses AI. Check for mistakes.
Replace Promise.all with sequential execution to prevent timeout.
Add eslint-disable comment for no-await-in-loop as sequential
execution is required here to avoid overwhelming the system.
Replace Promise.all with sequential execution to prevent timeout.
Add eslint-disable comment for no-await-in-loop rule.
@kairosci kairosci requested a review from zkochan May 1, 2026 17:49
@kairosci

kairosci commented May 4, 2026

Copy link
Copy Markdown
Contributor Author

@zkochan could you take a look at it? Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why was a change in this file needed?

Comment thread .changeset/pnpm-bugs-command.md Outdated

Added the `pnpm bugs` command that opens the package's bug tracker URL in the browser.

Fix the `bins.linker` tests to use `process.execPath` for `spawnSync` to avoid empty stdout.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

don't create one changeset for two unrelated changes. Create separate changeset files.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

how are these changes related to the pnpm bugs command?

Comment thread bins/linker/test/index.ts

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

how is this related at all to pnpm bugs command?

Comment thread pnpm/src/cmd/bugs.ts
Comment on lines +51 to +58
const getBugsUrlFromRegistry = async (pkgName: string): Promise<string> => {
const registry = opts.registries?.default ?? 'https://registry.npmjs.org'
const url = `${registry.replace(/\/$/, '')}/${pkgName}`
const response = await fetch(url, {
headers: {
'accept': 'application/json',
},
})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why wasn't this addressed?

- Normalize repository URLs by stripping git+ prefix and converting git:// to https://
- Encode scoped package names for registry API requests
- Differentiate registry error responses (404, 401/403, other)
- Propagate execFile errors instead of silently resolving
- Remove @pnpm/bins.linker from changeset
Copilot AI review requested due to automatic review settings May 6, 2026 11:15
@zkochan zkochan force-pushed the feat/pnpm-bugs-command branch from 2e02f0d to a505ff6 Compare May 6, 2026 11:15
@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR introduces a new pnpm bugs command that opens package bug tracker URLs from either the current project manifest or fetched registry metadata. Supporting changes include command registration, comprehensive test coverage, and test infrastructure improvements.

Changes

pnpm bugs Command

Layer / File(s) Summary
Core Command Implementation
pnpm/src/cmd/bugs.ts
Implements the bugs command handler with logic to open package bug tracker URLs. Supports two modes: reading bugs from local manifest or fetching from registry. Includes URL normalization, manifest parsing, and platform-specific URL opening.
Command Registration
pnpm/src/cmd/index.ts, pnpm/src/cmd/notImplemented.ts
Wires the bugs command into the CLI by importing and adding it to the commands array, and removes it from the not-implemented commands list.
Changeset Documentation
.changeset/pnpm-bugs-command.md
Documents the minor version bump and new bugs command behavior.
Tests & Test Utilities
pnpm/test/bugs.test.ts, pnpm/test/utils/execPnpm.ts, pnpm/test/tsconfig.json
Adds four test cases covering bugs URL extraction from object, string, and repository fallback formats, plus error handling. Updates test utilities with dynamic bin location discovery and adds Jest type definitions.

Test Infrastructure Improvements

Layer / File(s) Summary
Jest Registry Setup
__utils__/jest-config/with-registry/globalSetup.js
Introduces forceExit flag and SIGTERM handler to distinguish intentional shutdown from crashes, preventing spurious process exits during server closure.
Test Execution Sequencing
pnpm/test/dlx.ts
Converts parallel Promise.all execution to sequential for-of loop with awaits for dlx invocations, ensuring deterministic test execution.
Test Harness Updates
bins/linker/test/index.ts, fetching/pick-fetcher/test/customFetch.ts
Updates linker test to invoke bins via Node interpreter rather than direct spawn. Adds new test for custom fetcher delegating to gitHostedTarball for Git URLs.

Sequence Diagrams

sequenceDiagram
    actor User
    participant CLI as pnpm bugs
    participant Manifest as Local Manifest
    participant Registry as Package Registry
    participant URLHandler as URL Handler
    
    Note over User,URLHandler: Mode 1: No Arguments
    User->>CLI: pnpm bugs
    CLI->>Manifest: read package.json
    Manifest-->>CLI: manifest with bugs/repo
    CLI->>URLHandler: normalize & extract bugs URL
    URLHandler->>URLHandler: derive from bugs or repository
    URLHandler-->>CLI: validated URL
    CLI->>URLHandler: open URL
    URLHandler-->>User: browser opens
    
    Note over User,URLHandler: Mode 2: Package Names
    User->>CLI: pnpm bugs pkg1 pkg2
    CLI->>Registry: fetch pkg1 metadata
    Registry-->>CLI: manifest
    CLI->>URLHandler: extract bugs URL
    URLHandler->>URLHandler: normalize & validate
    URLHandler-->>CLI: URL
    CLI->>Registry: fetch pkg2 metadata
    Registry-->>CLI: manifest
    CLI->>URLHandler: extract bugs URL
    URLHandler-->>CLI: URL
    CLI->>URLHandler: open all URLs
    URLHandler-->>User: browsers open
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • zkochan

Poem

🐰 A clever command hops to life,
bugs tracked with nary a strife,
URLs fetched from registry deep,
or local manifests to keep,
open browsers with speed supreme!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: implement native pnpm bugs command' clearly and specifically describes the primary change: adding a new pnpm CLI command for viewing package bug trackers. It is concise, uses appropriate conventional commit formatting, and accurately reflects the main changeset.
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.

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

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

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment on lines +44 to +50
throw new PnpmError('NO_MANIFEST_FOUND', `No package.json was found in "${dir}"`)
}
const url = pickBugsUrl({ bugs: manifest.bugs, repository: manifest.repository })
if (!url) {
throw new PnpmError(
'NO_BUGS_URL',
'The package.json does not have a bug tracker URL. Add a "bugs" or "repository" field to your package.json.'
Comment on lines +75 to +92
if (manifest.repository) {
const repoUrl = typeof manifest.repository === 'string' ? manifest.repository : manifest.repository.url
if (repoUrl) {
const normalized = normalizeRepositoryUrl(repoUrl)
if (normalized && isHttpUrl(normalized)) return `${normalized}/issues`
}
}
return undefined
}

function normalizeRepositoryUrl (url: string): string | undefined {
let normalized = url.replace(/^git\+/, '').replace(/\.git$/, '')
if (normalized.startsWith('git://')) {
normalized = `https://${normalized.slice('git://'.length)}`
} else if (normalized.startsWith('git@github.com:')) {
normalized = `https://github.com/${normalized.slice('git@github.com:'.length)}`
}
return normalized

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 `@deps/inspection/commands/src/bugs/index.ts`:
- Around line 85-91: The normalization currently only converts git@github.com:
URLs; update normalizeRepositoryUrl to recognize SSH URLs of the form
git@HOST:PATH (e.g. /^git@([^:]+):(.+)$/) instead of the hardcoded
'git@github.com:' check and rewrite them to https://HOST/PATH (stripping any
trailing '.git' already handled); keep the existing git:// -> https://
conversion and ensure the function returns the normalized string for these
generalized SSH cases (use the captured host and path to build the replacement).
🪄 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 Plus

Run ID: 7296328f-b8dc-45ad-99a6-26d46690188a

📥 Commits

Reviewing files that changed from the base of the PR and between 29c2e7a and a505ff6.

📒 Files selected for processing (6)
  • .changeset/pnpm-bugs-command.md
  • deps/inspection/commands/src/bugs/index.ts
  • deps/inspection/commands/src/index.ts
  • deps/inspection/commands/test/bugs.ts
  • pnpm/src/cmd/index.ts
  • pnpm/src/cmd/notImplemented.ts
💤 Files with no reviewable changes (1)
  • pnpm/src/cmd/notImplemented.ts

Comment on lines +85 to +91
function normalizeRepositoryUrl (url: string): string | undefined {
let normalized = url.replace(/^git\+/, '').replace(/\.git$/, '')
if (normalized.startsWith('git://')) {
normalized = `https://${normalized.slice('git://'.length)}`
} else if (normalized.startsWith('git@github.com:')) {
normalized = `https://github.com/${normalized.slice('git@github.com:'.length)}`
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Generalize SSH repository normalization beyond GitHub.

Line 89 only handles git@github.com:. Repos like git@gitlab.com:group/pkg.git won’t normalize, so fallback incorrectly throws ERR_PNPM_NO_BUGS_URL.

Proposed fix
 function normalizeRepositoryUrl (url: string): string | undefined {
   let normalized = url.replace(/^git\+/, '').replace(/\.git$/, '')
   if (normalized.startsWith('git://')) {
     normalized = `https://${normalized.slice('git://'.length)}`
-  } else if (normalized.startsWith('git@github.com:')) {
-    normalized = `https://github.com/${normalized.slice('git@github.com:'.length)}`
+  } else {
+    const scpLike = normalized.match(/^git@([^:]+):(.+)$/)
+    if (scpLike) {
+      normalized = `https://${scpLike[1]}/${scpLike[2]}`
+    }
   }
   return normalized
 }
🤖 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 `@deps/inspection/commands/src/bugs/index.ts` around lines 85 - 91, The
normalization currently only converts git@github.com: URLs; update
normalizeRepositoryUrl to recognize SSH URLs of the form git@HOST:PATH (e.g.
/^git@([^:]+):(.+)$/) instead of the hardcoded 'git@github.com:' check and
rewrite them to https://HOST/PATH (stripping any trailing '.git' already
handled); keep the existing git:// -> https:// conversion and ensure the
function returns the normalized string for these generalized SSH cases (use the
captured host and path to build the replacement).

@kairosci kairosci force-pushed the feat/pnpm-bugs-command branch from a505ff6 to efb5440 Compare May 6, 2026 11:49
@zkochan

zkochan commented May 6, 2026

Copy link
Copy Markdown
Member

you are pushing a lot of unrelated changes to this PR. It won't be accepted this way.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
pnpm/src/cmd/bugs.ts (1)

146-159: 💤 Low value

Consider adding a timeout to prevent indefinite blocking.

While open, xdg-open, and start typically return immediately, edge cases (e.g., a custom handler that blocks) could cause the command to hang indefinitely.

🔧 Optional: Add timeout to execFile
   const { execFile } = await import('node:child_process')
   await new Promise<void>((resolve, reject) => {
-    execFile(cmd, args, (err) => {
+    execFile(cmd, args, { timeout: 30000 }, (err) => {
       if (err) {
         const errorDetails = [err.code, err.message].filter(Boolean).join(': ')
         reject(new PnpmError(
🤖 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 `@pnpm/src/cmd/bugs.ts` around lines 146 - 159, The execFile invocation that
runs cmd with args can hang; update the execFile usage in the Promise
(referencing execFile, cmd, args, canonicalUrl, and PnpmError) to enforce a
timeout: either pass a timeout option to execFile or capture the returned
ChildProcess, start a setTimeout (e.g. 5s), and on timeout kill the child and
reject the promise with a PnpmError (use a clear error id like
'OPEN_BUGS_URL_TIMEOUT' and include canonicalUrl and cmd in the message); ensure
the timeout is cleared on success or error to avoid leaks.
pnpm/test/bugs.test.ts (1)

7-43: 🏗️ Heavy lift

Strengthen success-path assertions to validate the resolved URL.

These tests currently verify only exit code. They can still pass if the command opens an incorrect URL. Please assert the actual URL chosen (e.g., by stubbing/capturing opener invocation, or by unit-testing the URL-resolution helper directly).

🤖 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 `@pnpm/test/bugs.test.ts` around lines 7 - 43, Update the three tests (pnpm
bugs opens bugs.url when present, pnpm bugs opens bugs string URL, pnpm bugs
falls back to repository/issues URL) to assert the actual URL opened instead of
only the exit code: stub or spy the module that launches the browser (the opener
used by the CLI) before calling execPnpmSync(['bugs']), capture the URL argument
passed to that opener, and add expect assertions verifying it equals the
resolved URL (e.g., 'https://github.com/test/pkg/issues' for the first two tests
and 'https://github.com/test/pkg/issues' for the repository fallback). If there
is a URL-resolution helper function used by the command, alternatively test that
helper directly by calling it with the same package.json shapes and asserting
the returned URL. Ensure you restore the stub/spy after each test.
🤖 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.

Nitpick comments:
In `@pnpm/src/cmd/bugs.ts`:
- Around line 146-159: The execFile invocation that runs cmd with args can hang;
update the execFile usage in the Promise (referencing execFile, cmd, args,
canonicalUrl, and PnpmError) to enforce a timeout: either pass a timeout option
to execFile or capture the returned ChildProcess, start a setTimeout (e.g. 5s),
and on timeout kill the child and reject the promise with a PnpmError (use a
clear error id like 'OPEN_BUGS_URL_TIMEOUT' and include canonicalUrl and cmd in
the message); ensure the timeout is cleared on success or error to avoid leaks.

In `@pnpm/test/bugs.test.ts`:
- Around line 7-43: Update the three tests (pnpm bugs opens bugs.url when
present, pnpm bugs opens bugs string URL, pnpm bugs falls back to
repository/issues URL) to assert the actual URL opened instead of only the exit
code: stub or spy the module that launches the browser (the opener used by the
CLI) before calling execPnpmSync(['bugs']), capture the URL argument passed to
that opener, and add expect assertions verifying it equals the resolved URL
(e.g., 'https://github.com/test/pkg/issues' for the first two tests and
'https://github.com/test/pkg/issues' for the repository fallback). If there is a
URL-resolution helper function used by the command, alternatively test that
helper directly by calling it with the same package.json shapes and asserting
the returned URL. Ensure you restore the stub/spy after each test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 71bc15c2-d541-4cd7-9175-dc964a144171

📥 Commits

Reviewing files that changed from the base of the PR and between a505ff6 and efb5440.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • .changeset/pnpm-bugs-command.md
  • __utils__/jest-config/with-registry/globalSetup.js
  • bins/linker/test/index.ts
  • fetching/pick-fetcher/test/customFetch.ts
  • pnpm/src/cmd/bugs.ts
  • pnpm/src/cmd/index.ts
  • pnpm/src/cmd/notImplemented.ts
  • pnpm/test/bugs.test.ts
  • pnpm/test/dlx.ts
  • pnpm/test/tsconfig.json
  • pnpm/test/utils/execPnpm.ts
💤 Files with no reviewable changes (1)
  • pnpm/src/cmd/notImplemented.ts

zkochan added a commit that referenced this pull request May 6, 2026
@kairosci kairosci closed this May 6, 2026
@kairosci kairosci changed the title feat: implement native 'pnpm bugs' command [replaced] feat: implement native 'pnpm bugs' command May 6, 2026
@kairosci

kairosci commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

My wrong, I'm experimenting several conflicts, I'm going to close it.

zkochan added a commit that referenced this pull request May 6, 2026
Adds a native `pnpm bugs` command (npm-compatible) that opens a package's bug tracker URL in the browser.

- With no arguments, reads `bugs` / `repository` from the current project's `package.json`.
- With one or more package names, fetches each package's metadata from the registry (via `fetchPackageInfo`, so auth, scoped names, and proxies are handled) and opens its bug tracker.
- Falls back to `<repository>/issues` when `bugs` is missing, normalizing `git+`, `.git`, `git://`, and `git@github.com:` forms first.
- Implemented in `@pnpm/deps.inspection.commands` alongside `docs`, reusing the `open` package for cross-platform browser launching.

Picked up from #11279 (kairosci's branch) and reworked per @zkochan's review:
- moved out of `pnpm/src/cmd/` into the inspection commands package
- supports `pnpm bugs [<pkgname> [<pkgname> ...]]` per npm
- proper scoped-name encoding via the npm resolver
- changeset split (no more `bins.linker` bump)
- dropped unrelated test/build noise

Closes #11279.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants