Skip to content

feat(view): support searching package.json upward when package name is omitted#11696

Merged
zkochan merged 8 commits into
mainfrom
feat/view-command-support-omitted-package-name
Jun 16, 2026
Merged

feat(view): support searching package.json upward when package name is omitted#11696
zkochan merged 8 commits into
mainfrom
feat/view-command-support-omitted-package-name

Conversation

@btea

@btea btea commented May 17, 2026

Copy link
Copy Markdown
Member

It should behave in accordance with npm view.

replace find-up, refer to https://e18e.dev/docs/replacements/find-up

Summary by CodeRabbit

  • New Features

    • pnpm view now searches upward for the nearest package.json when no package name is provided and uses its name; it errors if that file lacks a name.
  • Tests

    • Added integration tests for upward package.json discovery, nested-directory resolution, and invalid-package-json handling.
  • Chores

    • Improved upward-search implementation and updated workspace dependencies.

Copilot AI review requested due to automatic review settings May 17, 2026 04:01
@btea btea requested a review from zkochan as a code owner May 17, 2026 04:01
@coderabbitai

coderabbitai Bot commented May 17, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Replaces find-up with empathic across workspace manifests and packages, and adds logic to pnpm view to search upward for the nearest package.json and use its name when no package argument is supplied (with validation and tests).

Changes

Dependency Migration and Feature Enhancement

Layer / File(s) Summary
Workspace catalog update
pnpm-workspace.yaml
Added empathic to the pnpm workspace catalog and removed find-up.
Root finder migration to empathic
workspace/root-finder/package.json, workspace/root-finder/src/index.ts
Replaced find-up's findUp with empathic/find's find.any and updated the package dependency.
Projects filter migration to empathic
workspace/projects-filter/package.json, workspace/projects-filter/src/getChangedProjects.ts
Switched .git resolution from awaited findUp calls to find.dir(...) ?? find.file(...) using empathic/find; updated imports and package deps.
View command upward package.json search
deps/inspection/commands/package.json, deps/inspection/commands/src/view/index.ts, deps/inspection/commands/test/view.ts
Added empathic to the view command deps. When no package name is provided, the handler searches upward for package.json, parses it, requires a non-empty name field, throws INVALID_PACKAGE_JSON/MISSING_PACKAGE_NAME as appropriate, updates help text, and adds integration tests for success and error cases.
Changeset documentation
.changeset/view-package-json-upward-search.md
Documented the new pnpm view upward-search behavior and the dependency swap from find-up to empathic.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as pnpm CLI
  participant Handler as view.handler
  participant Finder as empathic/package
  participant FS as node:fs
  CLI->>Handler: invoke `pnpm view` without package arg
  Handler->>Finder: search upward for nearest `package.json`
  Finder->>Handler: return package.json path or nothing
  Handler->>FS: read package.json
  Handler->>Handler: parse & validate `name` -> set packageSpec or throw
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • zkochan

🐰 A rabbit hops through the code with glee,
I sniff out package.json up the tree,
Empathic footsteps guide my way,
Tests and docs help me stay,
Happy hops for tidy dependency! 🥕✨

🚥 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 accurately and concisely describes the main feature change: enabling the view command to search upward for package.json when package name is omitted.
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
  • Commit unit tests in branch feat/view-command-support-omitted-package-name

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.

❤️ Share

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

@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

🧹 Nitpick comments (1)
deps/inspection/commands/test/view.ts (1)

228-244: ⚡ Quick win

Add an explicit parent-directory traversal assertion.

Line 230 places package.json in the same directory as cwd, so this only validates direct lookup. Add a nested cwd case to verify upward search behavior.

Proposed test adjustment
 test('view: uses package.json name when no package name provided', async () => {
   const cwd = process.cwd()
   const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'view-test-'))
   const pkgJsonPath = path.join(tmpDir, 'package.json')
+  const nestedDir = path.join(tmpDir, 'a', 'b')

   try {
     fs.writeFileSync(pkgJsonPath, JSON.stringify({ name: 'is-negative' }))
-    process.chdir(tmpDir)
+    fs.mkdirSync(nestedDir, { recursive: true })
+    process.chdir(nestedDir)

     const result = await view.handler(VIEW_OPTIONS as unknown as Config & ConfigContext, [])
     expect(typeof result).toBe('string')
     expect(result).toContain('is-negative')
🤖 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/test/view.ts` around lines 228 - 244, The test
"view: uses package.json name when no package name provided" currently places
package.json in the same directory as cwd and so only validates direct lookup;
update the test to also assert upward-search behavior by creating a nested
directory (e.g., tmpDir/subdir), writing package.json to tmpDir, chdir into the
nested subdir before calling view.handler (the handler function in view), then
assert the returned string contains the package name; ensure the existing
cleanup still restores cwd and removes tmp files and reuse VIEW_OPTIONS / Config
& ConfigContext as before.
🤖 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/view/index.ts`:
- Around line 59-63: Wrap the JSON.parse of pkgFile in a try/catch and convert
any thrown SyntaxError (or other parse errors) into a PnpmError with code
'INVALID_PACKAGE_JSON'; after parsing, validate that pkgInfo.name is a string
(e.g., typeof pkgInfo.name === 'string') and throw the same
PnpmError('INVALID_PACKAGE_JSON', ...) when it's missing or not a string before
assigning packageSpec = pkgInfo.name so both malformed JSON and non-string name
values are handled consistently (references: pkgInfo, pkgFile, PnpmError,
packageSpec).

---

Nitpick comments:
In `@deps/inspection/commands/test/view.ts`:
- Around line 228-244: The test "view: uses package.json name when no package
name provided" currently places package.json in the same directory as cwd and so
only validates direct lookup; update the test to also assert upward-search
behavior by creating a nested directory (e.g., tmpDir/subdir), writing
package.json to tmpDir, chdir into the nested subdir before calling view.handler
(the handler function in view), then assert the returned string contains the
package name; ensure the existing cleanup still restores cwd and removes tmp
files and reuse VIEW_OPTIONS / Config & ConfigContext as before.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5a8912f6-9548-43fe-bf59-b1924c67112f

📥 Commits

Reviewing files that changed from the base of the PR and between 3ddde2b and 2c673b1.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • .changeset/view-package-json-upward-search.md
  • deps/inspection/commands/package.json
  • deps/inspection/commands/src/view/index.ts
  • deps/inspection/commands/test/view.ts
  • pnpm-workspace.yaml
  • workspace/projects-filter/package.json
  • workspace/projects-filter/src/getChangedProjects.ts
  • workspace/root-finder/package.json
  • workspace/root-finder/src/index.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: ubuntu-latest / Node.js 24 / Test
  • GitHub Check: Agent
  • GitHub Check: Run benchmark on ubuntu-latest
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Use Standard Style with modifications: trailing commas are used, functions are preferred over classes, functions are declared after they are used (hoisting is relied upon).
Functions should have no more than two or three arguments. If a function needs more parameters, use a single options object instead.
Maintain import order: (1) Standard libraries, (2) External dependencies (sorted alphabetically), (3) Relative imports.

Files:

  • deps/inspection/commands/test/view.ts
  • workspace/projects-filter/src/getChangedProjects.ts
  • workspace/root-finder/src/index.ts
  • deps/inspection/commands/src/view/index.ts
🧠 Learnings (2)
📚 Learning: 2026-05-05T23:03:04.286Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11479
File: __utils__/scripts/package.json:6-9
Timestamp: 2026-05-05T23:03:04.286Z
Learning: The pattern cross-env NODE_OPTIONS="$NODE_OPTIONS ..." in package.json scripts is an established convention in the pnpm/pnpm repository and is used across many packages (e.g., fs/hard-link-dir, worker, __utils__/scripts). Do not flag this as a cross-platform issue in individual files; if a change is needed, apply it as a repo-wide change in a separate PR. Scope this guidance to all package.json files in the repo; use the minimatch pattern '**/package.json' to identify relevant files and review changes at the repository level rather than per-file.

Applied to files:

  • workspace/projects-filter/package.json
  • deps/inspection/commands/package.json
  • workspace/root-finder/package.json
📚 Learning: 2026-05-14T09:04:00.133Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11622
File: resolving/npm-resolver/test/publishedBy.test.ts:350-354
Timestamp: 2026-05-14T09:04:00.133Z
Learning: In the pnpm/pnpm repository, ESLint is the authoritative style linter. Do not raise review findings for missing trailing commas in multiline function calls (e.g., `fs.writeFileSync(...)`) when this repo’s ESLint configuration does not report them and lint passes. Prefer deferring to the ESLint results for this specific trailing-comma rule rather than enforcing it manually in code review.

Applied to files:

  • deps/inspection/commands/test/view.ts
  • workspace/projects-filter/src/getChangedProjects.ts
  • workspace/root-finder/src/index.ts
  • deps/inspection/commands/src/view/index.ts
🔇 Additional comments (9)
.changeset/view-package-json-upward-search.md (1)

1-13: LGTM!

pnpm-workspace.yaml (1)

183-183: LGTM!

workspace/root-finder/package.json (1)

35-35: LGTM!

workspace/projects-filter/package.json (1)

39-39: LGTM!

workspace/root-finder/src/index.ts (1)

5-5: LGTM!

Also applies to: 23-23

workspace/projects-filter/src/getChangedProjects.ts (1)

7-7: LGTM!

Also applies to: 24-25

deps/inspection/commands/package.json (1)

61-61: LGTM!

deps/inspection/commands/src/view/index.ts (1)

1-33: LGTM!

Also applies to: 54-58, 64-66

deps/inspection/commands/test/view.ts (1)

1-4: LGTM!

Also applies to: 246-262

Comment thread deps/inspection/commands/src/view/index.ts Outdated

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

This PR updates pnpm view to mimic npm view more closely by allowing the package name to be omitted and then resolving it from the nearest package.json found by searching upward from the working directory. It also standardizes “find up” behavior across a couple of workspace utilities by replacing find-up with empathic.

Changes:

  • pnpm view: if no package name is provided, locate the nearest package.json upward and use its name.
  • Replace find-up with empathic in workspace root-finding and projects filtering utilities.
  • Add tests and a changeset documenting the new pnpm view behavior and dependency swap.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
workspace/root-finder/src/index.ts Switches workspace manifest upward-search from find-up to empathic/find.
workspace/root-finder/package.json Replaces find-up dependency with empathic.
workspace/projects-filter/src/getChangedProjects.ts Switches .git upward-search from find-up to empathic/find.
workspace/projects-filter/package.json Replaces find-up dependency with empathic.
pnpm-workspace.yaml Adds empathic to catalog and removes find-up from catalog.
pnpm-lock.yaml Updates lockfile for the empathic addition and find-up@8 removal.
deps/inspection/commands/src/view/index.ts Implements package-name omission by reading name from nearest package.json found upward.
deps/inspection/commands/package.json Adds empathic dependency (for empathic/package).
deps/inspection/commands/test/view.ts Adds tests covering package-name omission behavior and invalid package.json cases.
.changeset/view-package-json-upward-search.md Declares a minor release for the new view behavior (and documents the dep swap).
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

deps/inspection/commands/src/view/index.ts:63

  • When deriving the package name from the nearest package.json, JSON.parse/readFileSync errors will currently surface as raw Node/SyntaxError exceptions. Consider wrapping the read+parse in try/catch and throwing a PnpmError('INVALID_PACKAGE_JSON', ...) that includes the file path, and also validate that "name" is a non-empty string before assigning it to packageSpec.
    const pkgFile = pkg.up()
    if (pkgFile) {
      const pkgInfo = JSON.parse(fs.readFileSync(pkgFile, 'utf8'))
      if (!pkgInfo.name) {
        throw new PnpmError('INVALID_PACKAGE_JSON', 'Invalid package.json. No "name" field.')
      }
      packageSpec = pkgInfo.name

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

Comment thread deps/inspection/commands/src/view/index.ts Outdated
Comment thread .changeset/view-package-json-upward-search.md
Comment thread deps/inspection/commands/test/view.ts Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 17, 2026 04:05

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 9 out of 10 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (2)

deps/inspection/commands/src/view/index.ts:63

  • Reading and parsing the discovered package.json via fs.readFileSync + JSON.parse can throw raw SyntaxError/IO errors, which will bypass pnpm’s usual error codes/messages for bad manifests. Also, the current check only tests truthiness; it won’t reject non-string name values.

Use an existing manifest reader (e.g. @pnpm/pkg-manifest.reader or readProjectManifestOnly) to parse/normalize and then validate that name is a non-empty string, wrapping failures in a PnpmError with a consistent code and file path.

      const pkgInfo = JSON.parse(fs.readFileSync(pkgFile, 'utf8'))
      if (!pkgInfo.name) {
        throw new PnpmError('INVALID_PACKAGE_JSON', 'Invalid package.json. No "name" field.')
      }
      packageSpec = pkgInfo.name

deps/inspection/commands/src/view/index.ts:66

  • The thrown MISSING_PACKAGE_NAME message still says Usage: pnpm view <package-name>, but help() now documents that the package name is optional (and can be inferred from the nearest package.json). Please update the error message (or add a hint) so it matches the updated command usage/behavior.
    } else {
      throw new PnpmError('MISSING_PACKAGE_NAME', 'Package name is required. Usage: pnpm view <package-name>')
    }

Comment thread deps/inspection/commands/src/view/index.ts Outdated
Comment thread deps/inspection/commands/test/view.ts Outdated
@github-actions

github-actions Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Integrated-Benchmark Report (Linux)

Each scenario has pacquet rows (direct install) and pnpr rows (the same client through the pnpr install accelerator), so pnpr@HEAD vs pacquet@HEAD is the pnpr-vs-direct ratio. Cold-store scenarios wipe the client store between runs (warm server); hot-store scenarios keep it warm. The pacquet@HEAD rows feed the pacquet Bencher testbed; the pnpr@HEAD rows feed the pnpr testbed.

Scenario: Isolated linker: fresh restore, cold cache + cold store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 4.796 ± 0.092 4.724 4.974 2.37 ± 0.13
pacquet@main 4.769 ± 0.038 4.724 4.859 2.36 ± 0.13
pnpr@HEAD 2.024 ± 0.108 1.934 2.301 1.00
pnpr@main 2.025 ± 0.044 1.954 2.089 1.00 ± 0.06
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 4.79645697244,
      "stddev": 0.09151047213947237,
      "median": 4.76154443234,
      "user": 2.3232240400000004,
      "system": 3.749419600000001,
      "min": 4.72398162134,
      "max": 4.97353472234,
      "times": [
        4.79758276134,
        4.81276151134,
        4.94584465734,
        4.76983838434,
        4.72535902534,
        4.73504591434,
        4.72398162134,
        4.72737064634,
        4.97353472234,
        4.75325048034
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 4.768520172740001,
      "stddev": 0.03805235985176815,
      "median": 4.75975765834,
      "user": 2.32074504,
      "system": 3.7418074,
      "min": 4.72350816334,
      "max": 4.85878548634,
      "times": [
        4.78441611234,
        4.75473961634,
        4.74622695734,
        4.74680533134,
        4.85878548634,
        4.73917967134,
        4.79144987734,
        4.77531481134,
        4.72350816334,
        4.76477570034
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 2.0243679253400004,
      "stddev": 0.10841921840001591,
      "median": 1.98061107484,
      "user": 2.55260894,
      "system": 3.2822381999999997,
      "min": 1.9336836853400001,
      "max": 2.30147135234,
      "times": [
        1.96033230734,
        1.9598981103400002,
        2.30147135234,
        2.08811305634,
        1.9775188643400001,
        1.98370328534,
        1.9336836853400001,
        1.96101030234,
        2.04827262134,
        2.02967566834
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 2.02501504734,
      "stddev": 0.0435368159396114,
      "median": 2.01362742234,
      "user": 2.53574074,
      "system": 3.2980364,
      "min": 1.9538879113400003,
      "max": 2.0888788323400003,
      "times": [
        2.01154557934,
        2.06190412334,
        2.08349236434,
        2.03948377534,
        2.0888788323400003,
        2.00459161034,
        1.9538879113400003,
        1.9797726463400003,
        2.01570926534,
        2.01088436534
      ]
    }
  ]
}

Scenario: Isolated linker: fresh restore, hot cache + hot store

Command Mean [ms] Min [ms] Max [ms] Relative
pacquet@HEAD 657.8 ± 31.6 636.1 740.0 1.01 ± 0.06
pacquet@main 648.7 ± 18.4 629.0 683.5 1.00
pnpr@HEAD 666.0 ± 41.2 633.5 775.8 1.03 ± 0.07
pnpr@main 710.6 ± 44.6 648.4 806.6 1.10 ± 0.08
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 0.6577674963600002,
      "stddev": 0.031594509649220184,
      "median": 0.6450403695600001,
      "user": 0.3479935,
      "system": 1.3097192199999999,
      "min": 0.6360831680600001,
      "max": 0.7400004680600001,
      "times": [
        0.7400004680600001,
        0.6678912330600001,
        0.6745211120600001,
        0.6360860690600001,
        0.6484109350600001,
        0.6469636240600001,
        0.6429473550600001,
        0.6431171150600001,
        0.6360831680600001,
        0.6416538840600001
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 0.6486954222600001,
      "stddev": 0.01838080543333596,
      "median": 0.6403374195600001,
      "user": 0.344821,
      "system": 1.30809672,
      "min": 0.62899612006,
      "max": 0.6834822710600001,
      "times": [
        0.6705394060600001,
        0.6339601770600001,
        0.6399225260600001,
        0.6460091230600001,
        0.62899612006,
        0.6363100410600001,
        0.6834822710600001,
        0.6676605190600001,
        0.6407523130600001,
        0.63932172606
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 0.66595607786,
      "stddev": 0.04117827678301331,
      "median": 0.6536848670600002,
      "user": 0.34746299999999997,
      "system": 1.30799472,
      "min": 0.6335087110600001,
      "max": 0.7758429940600001,
      "times": [
        0.7758429940600001,
        0.65937177706,
        0.6631831990600001,
        0.6335087110600001,
        0.6859369250600001,
        0.6477825690600001,
        0.6530729880600001,
        0.6466166190600001,
        0.6542967460600001,
        0.6399482500600001
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 0.7106145981600002,
      "stddev": 0.04455339063065789,
      "median": 0.7086956165600001,
      "user": 0.3477109,
      "system": 1.3057344199999998,
      "min": 0.6483647750600001,
      "max": 0.8066424140600001,
      "times": [
        0.8066424140600001,
        0.6960600710600001,
        0.7289827290600001,
        0.6483647750600001,
        0.7213311620600001,
        0.7365016270600001,
        0.6934963760600001,
        0.72858629906,
        0.6720208510600001,
        0.6741596770600001
      ]
    }
  ]
}

Scenario: Isolated linker: fresh install, cold cache + cold store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 2.114 ± 0.037 2.064 2.197 1.01 ± 0.02
pacquet@main 2.096 ± 0.029 2.056 2.136 1.00
pnpr@HEAD 2.119 ± 0.029 2.067 2.154 1.01 ± 0.02
pnpr@main 2.107 ± 0.015 2.085 2.135 1.01 ± 0.02
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 2.1139616833600003,
      "stddev": 0.03714015288128704,
      "median": 2.1113083357600004,
      "user": 3.3519568800000004,
      "system": 2.9881123,
      "min": 2.0644774062600004,
      "max": 2.19705502526,
      "times": [
        2.13764747526,
        2.1054337702600003,
        2.11601533926,
        2.0644774062600004,
        2.1083568732600004,
        2.1006310962600003,
        2.06874725326,
        2.11425979826,
        2.19705502526,
        2.12699279626
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 2.0955745230600002,
      "stddev": 0.029181950449622625,
      "median": 2.10399078976,
      "user": 3.37394238,
      "system": 2.9512522,
      "min": 2.0556099802600003,
      "max": 2.13607773826,
      "times": [
        2.08316751226,
        2.0588200902600002,
        2.1095974232600003,
        2.12693647726,
        2.06183517326,
        2.0983841562600003,
        2.13607773826,
        2.0556099802600003,
        2.1102486232600004,
        2.11506805626
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 2.11949856986,
      "stddev": 0.029241414231693838,
      "median": 2.1190073642600002,
      "user": 3.3542757800000005,
      "system": 3.0245532999999996,
      "min": 2.0669081842600003,
      "max": 2.15425185126,
      "times": [
        2.15425185126,
        2.1335117512600004,
        2.0669081842600003,
        2.15160420826,
        2.0991561032600004,
        2.14779552726,
        2.0965411312600004,
        2.13658878726,
        2.1041251772600003,
        2.10450297726
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 2.1072926023600003,
      "stddev": 0.0154916682204988,
      "median": 2.1077760847600002,
      "user": 3.34211838,
      "system": 3.0191242,
      "min": 2.08489068726,
      "max": 2.1354406002600004,
      "times": [
        2.10463259526,
        2.0967087652600003,
        2.1354406002600004,
        2.08489068726,
        2.08937225226,
        2.1163397452600003,
        2.11091957426,
        2.09955885926,
        2.1230565452600003,
        2.1120063992600002
      ]
    }
  ]
}

Scenario: Isolated linker: fresh install, hot cache + hot store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 1.229 ± 0.010 1.213 1.245 1.00
pacquet@main 1.257 ± 0.028 1.217 1.310 1.02 ± 0.02
pnpr@HEAD 1.261 ± 0.040 1.205 1.362 1.03 ± 0.03
pnpr@main 1.243 ± 0.030 1.219 1.318 1.01 ± 0.03
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 1.22907706022,
      "stddev": 0.010132575735727518,
      "median": 1.22831736192,
      "user": 1.3471055199999997,
      "system": 1.67793974,
      "min": 1.21317291192,
      "max": 1.2447027919200002,
      "times": [
        1.23424683792,
        1.2274729769200001,
        1.2250662109200001,
        1.21317291192,
        1.22916174692,
        1.2170810219200001,
        1.23047362692,
        1.2254086939200002,
        1.24398378292,
        1.2447027919200002
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 1.2570203759200003,
      "stddev": 0.028051184541660334,
      "median": 1.2517672234200001,
      "user": 1.3582051199999998,
      "system": 1.68012984,
      "min": 1.21721573092,
      "max": 1.31000424292,
      "times": [
        1.2541556359200001,
        1.21721573092,
        1.23631608692,
        1.2838191889200001,
        1.26670631292,
        1.23149049792,
        1.31000424292,
        1.27934753192,
        1.2417697199200002,
        1.2493788109200001
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 1.2610756373200003,
      "stddev": 0.040007694206206,
      "median": 1.2561735814200001,
      "user": 1.36437222,
      "system": 1.6759078399999996,
      "min": 1.20520915092,
      "max": 1.3621602319200001,
      "times": [
        1.20520915092,
        1.2553020439200002,
        1.2342720009200001,
        1.2540925979200002,
        1.24908414992,
        1.27108365792,
        1.3621602319200001,
        1.25704511892,
        1.25958279692,
        1.26292462392
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 1.24269330462,
      "stddev": 0.029992503251653427,
      "median": 1.23051597642,
      "user": 1.33087922,
      "system": 1.68549814,
      "min": 1.21912952292,
      "max": 1.31823483592,
      "times": [
        1.21974783892,
        1.2484577219200002,
        1.2525144029200002,
        1.23345462992,
        1.2578863909200002,
        1.21912952292,
        1.31823483592,
        1.22757732292,
        1.22650672192,
        1.2234236579200002
      ]
    }
  ]
}

Copilot AI review requested due to automatic review settings May 28, 2026 07:14

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 9 out of 10 changed files in this pull request and generated 3 comments.

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

Comment thread deps/inspection/commands/src/view/index.ts Outdated
Comment thread deps/inspection/commands/src/view/index.ts Outdated
Comment thread deps/inspection/commands/src/view/index.ts Outdated
@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

🐰 Bencher Report

Branchpr/11696
Testbedpacquet

🚨 1 Alert

BenchmarkMeasure
Units
ViewBenchmark Result
(Result Δ%)
Upper Boundary
(Limit %)
isolated-linker.fresh-restore.cold-cache.cold-storeLatency
seconds (s)
📈 plot
🚷 threshold
🚨 alert (🔔)
4.80 s
(+91.73%)Baseline: 2.50 s
3.00 s
(159.77%)

Click to view all benchmark results
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
isolated-linker.fresh-install.cold-cache.cold-store📈 view plot
🚷 view threshold
2,113.96 ms
(-7.78%)Baseline: 2,292.30 ms
2,750.76 ms
(76.85%)
isolated-linker.fresh-install.hot-cache.hot-store📈 view plot
🚷 view threshold
1,229.08 ms
(-16.07%)Baseline: 1,464.41 ms
1,757.29 ms
(69.94%)
isolated-linker.fresh-restore.cold-cache.cold-store📈 view plot
🚷 view threshold
🚨 view alert (🔔)
4,796.46 ms
(+91.73%)Baseline: 2,501.70 ms
3,002.04 ms
(159.77%)

isolated-linker.fresh-restore.hot-cache.hot-store📈 view plot
🚷 view threshold
657.77 ms
(+1.34%)Baseline: 649.10 ms
778.92 ms
(84.45%)
🐰 View full continuous benchmarking report in Bencher

…port-omitted-package-name

# Conflicts:
#	pnpm-lock.yaml

@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 (1)
deps/inspection/commands/test/view.ts (1)

311-329: ⚡ Quick win

Consider extracting the temp-dir/chdir scaffolding into a helper.

Tests at lines 237–329 repeat the same mkdtempSyncchdirfinally { chdir(cwd); rmSync(...) } boilerplate. A small helper would reduce duplication and ensure consistent cleanup.

♻️ Example helper
async function withTempCwd (
  setup: (dir: string) => void,
  run: () => Promise<void>
): Promise<void> {
  const cwd = process.cwd()
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'view-test-'))
  try {
    setup(tmpDir)
    await run()
  } finally {
    process.chdir(cwd)
    fs.rmSync(tmpDir, { recursive: true, force: true })
  }
}
🤖 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/test/view.ts` around lines 311 - 329, Extract the
repeated mkdtempSync/chdir/finally cleanup scaffolding used in the tests (e.g.,
the "view: resolves package.json from opts.dir when cwd differs" test) into a
reusable helper (suggested name withTempCwd) that accepts a setup callback and
an async run callback; implement it to capture original cwd, create the temp
dir, call setup(tmpDir) then await run(), and always restore cwd and remove temp
dirs in finally. Replace the duplicated blocks in tests that currently create
tmpDir/otherDir, call process.chdir(otherDir), write package.json, invoke
view.handler({ ...VIEW_OPTIONS, dir: tmpDir } as unknown as Config &
ConfigContext, []), and cleanup with calls to this helper (ensure the helper
supports creating/cleanup of any additional dirs like otherDir or letting setup
create them). Ensure the helper is exported/imported where needed and preserves
existing assertions and error handling.
🤖 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 `@deps/inspection/commands/test/view.ts`:
- Around line 311-329: Extract the repeated mkdtempSync/chdir/finally cleanup
scaffolding used in the tests (e.g., the "view: resolves package.json from
opts.dir when cwd differs" test) into a reusable helper (suggested name
withTempCwd) that accepts a setup callback and an async run callback; implement
it to capture original cwd, create the temp dir, call setup(tmpDir) then await
run(), and always restore cwd and remove temp dirs in finally. Replace the
duplicated blocks in tests that currently create tmpDir/otherDir, call
process.chdir(otherDir), write package.json, invoke view.handler({
...VIEW_OPTIONS, dir: tmpDir } as unknown as Config & ConfigContext, []), and
cleanup with calls to this helper (ensure the helper supports creating/cleanup
of any additional dirs like otherDir or letting setup create them). Ensure the
helper is exported/imported where needed and preserves existing assertions and
error handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ca3bff90-46f3-4370-a26e-a7843f728382

📥 Commits

Reviewing files that changed from the base of the PR and between abaae0a and 5b69835.

📒 Files selected for processing (3)
  • deps/inspection/commands/package.json
  • deps/inspection/commands/src/view/index.ts
  • deps/inspection/commands/test/view.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • deps/inspection/commands/package.json
  • deps/inspection/commands/src/view/index.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Compile & Lint
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Follow Standard Style with trailing commas, preferring functions over classes, and declaring functions after they are used (relying on hoisting)
Use a single options object instead of multiple parameters when a function needs more than two or three arguments
Follow Import Order: Standard libraries first, then external dependencies (alphabetically), then relative imports
Write self-documenting code where function names, parameters, and types explain what a function does without requiring prose comments
Do not write comments that restate what the code already says; refactor via renaming, splitting helpers, or restructuring instead
Do not repeat documentation at call sites that already exists in JSDoc on the callee; update JSDoc once for all call sites to benefit
Use JSDoc only for a function's contract (preconditions, postconditions, edge cases, why the function exists), not for re-narrating the body
Do not record past implementation shape, refactor history, or 'the previous code did X' framing in code; use git log and git blame instead
Write comments only when: the reason for code is non-obvious (hidden invariant, workaround for known bug, deliberate exception), or the right name doesn't fit (temporary technical constraint)

Files:

  • deps/inspection/commands/test/view.ts
🧠 Learnings (1)
📚 Learning: 2026-05-14T09:04:00.133Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11622
File: resolving/npm-resolver/test/publishedBy.test.ts:350-354
Timestamp: 2026-05-14T09:04:00.133Z
Learning: In the pnpm/pnpm repository, ESLint is the authoritative style linter. Do not raise review findings for missing trailing commas in multiline function calls (e.g., `fs.writeFileSync(...)`) when this repo’s ESLint configuration does not report them and lint passes. Prefer deferring to the ESLint results for this specific trailing-comma rule rather than enforcing it manually in code review.

Applied to files:

  • deps/inspection/commands/test/view.ts
🔇 Additional comments (3)
deps/inspection/commands/test/view.ts (3)

8-8: LGTM!


43-56: LGTM!


293-309: LGTM!

Comment thread deps/inspection/commands/src/view/index.ts Outdated
Comment thread deps/inspection/commands/src/view/index.ts Outdated
Comment thread deps/inspection/commands/src/view/index.ts Outdated
Copilot AI review requested due to automatic review settings June 4, 2026 11:57

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 8 out of 9 changed files in this pull request and generated 2 comments.

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

Comment thread deps/inspection/commands/src/view/index.ts
Comment thread .changeset/view-package-json-upward-search.md Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 4, 2026 12:06

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 8 out of 9 changed files in this pull request and generated 1 comment.

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

Comment thread deps/inspection/commands/src/view/index.ts Outdated
@zkochan zkochan merged commit 293921a into main Jun 16, 2026
20 of 21 checks passed
@zkochan zkochan deleted the feat/view-command-support-omitted-package-name branch June 16, 2026 23:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants