Skip to content

feat: detect package manager automatically with the vscode command#76

Merged
9romise merged 4 commits intomainfrom
packageManager
Mar 13, 2026
Merged

feat: detect package manager automatically with the vscode command#76
9romise merged 4 commits intomainfrom
packageManager

Conversation

@9romise
Copy link
Copy Markdown
Member

@9romise 9romise commented Mar 12, 2026

No description provided.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 12, 2026

📝 Walkthrough

Walkthrough

Adds a mapping workspaceFileMapping for non-npm managers and a new getPackageManager that queries the VS Code npm.packageManager command (falls back to npm on error and shows an error). Removes the prior detectPackageManager from src/utils/package-manager.ts. Updates src/core/workspace.ts to use getPackageManager, conditionally load non-npm workspace catalog files using the mapping only if the workspace file exists, and adjust catalog promise usage and error handling. Several workspace fixture package manifests and the package-manager test were removed.

Possibly related PRs

  • npmx-dev/vscode-npmx PR 74: Modifies src/core/workspace.ts and workspace catalog/loading logic, overlapping changes to workspace catalog loading and related functions.
🚥 Pre-merge checks | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is empty with no author-provided context, making it impossible to assess whether it relates to the changeset. Add a meaningful pull request description explaining the changes, rationale, and how they address the stated objective of detecting package managers automatically via the VS Code command.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch packageManager
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

CodeRabbit can generate a title for your PR based on the changes with custom instructions.

Set the reviews.auto_title_instructions setting to generate a title for your PR based on the changes in the PR with custom instructions.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/core/workspace.ts (1)

54-69: ⚠️ Potential issue | 🔴 Critical

Always initialise #catalogs before loading manifests.

For npm workspaces this branch leaves #catalogs unset, but Line 128 later does this.#catalogs!.promise unconditionally. Opening any package.json in an npm repo will therefore throw before dependency resolution runs.

Possible fix
  async loadWorkspace() {
-    this.#catalogs = undefined
+    this.#catalogs = Promise.withResolvers<CatalogsInfo | undefined>()
     this.packageManager = await getPackageManager(this.folder.uri)

     logger.info(`[workspace-context] detect package manager: ${this.packageManager}`)

     if (this.packageManager !== 'npm') {
-      this.#catalogs = Promise.withResolvers()
       const workspaceFilename = workspaceFileMapping[this.packageManager]
       const workspaceFile = Uri.joinPath(this.folder.uri, workspaceFilename)
       this.#catalogs.resolve(
         await accessOk(workspaceFile)
           ? (await this.loadWorkspaceCatalogInfo(workspaceFile))?.catalogs
           : undefined,
       )
+    } else {
+      this.#catalogs.resolve(undefined)
     }
   }
🧹 Nitpick comments (1)
src/core/workspace.ts (1)

22-25: Keep workspace filename rules in one place.

workspaceFileMapping is now the obvious canonical source, but src/utils/file.ts Lines 27-30 still hardcode the same pnpm/yarn basenames in isWorkspaceFilePath(). That duplication will drift the next time a manager or filename changes.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b5e19b11-35cc-46ec-a8c3-e2ad6b3ff2e4

📥 Commits

Reviewing files that changed from the base of the PR and between b5cacf5 and 705f407.

📒 Files selected for processing (17)
  • src/core/workspace.ts
  • src/utils/package-manager.ts
  • tests/fixtures/workspace/dirty-doc/package.json
  • tests/fixtures/workspace/dirty-doc/packages/app/package.json
  • tests/fixtures/workspace/minimal/package.json
  • tests/fixtures/workspace/package-manager-npm/.yarnrc.yml
  • tests/fixtures/workspace/package-manager-npm/package.json
  • tests/fixtures/workspace/package-manager-npm/pnpm-workspace.yaml
  • tests/fixtures/workspace/package-manager-pnpm/package.json
  • tests/fixtures/workspace/package-manager-pnpm/pnpm-workspace.yaml
  • tests/fixtures/workspace/package-manager-yarn/.yarnrc.yml
  • tests/fixtures/workspace/package-manager-yarn/package.json
  • tests/fixtures/workspace/pnpm-workspace/package.json
  • tests/fixtures/workspace/pnpm-workspace/packages/app/package.json
  • tests/fixtures/workspace/pnpm-workspace/packages/core/package.json
  • tests/fixtures/workspace/pnpm-workspace/pnpm-workspace.yaml
  • tests/utils/package-manager.test.ts
💤 Files with no reviewable changes (16)
  • tests/utils/package-manager.test.ts
  • tests/fixtures/workspace/dirty-doc/package.json
  • src/utils/package-manager.ts
  • tests/fixtures/workspace/package-manager-npm/package.json
  • tests/fixtures/workspace/package-manager-yarn/package.json
  • tests/fixtures/workspace/package-manager-npm/.yarnrc.yml
  • tests/fixtures/workspace/package-manager-pnpm/package.json
  • tests/fixtures/workspace/minimal/package.json
  • tests/fixtures/workspace/dirty-doc/packages/app/package.json
  • tests/fixtures/workspace/pnpm-workspace/packages/core/package.json
  • tests/fixtures/workspace/pnpm-workspace/package.json
  • tests/fixtures/workspace/pnpm-workspace/packages/app/package.json
  • tests/fixtures/workspace/package-manager-pnpm/pnpm-workspace.yaml
  • tests/fixtures/workspace/package-manager-yarn/.yarnrc.yml
  • tests/fixtures/workspace/pnpm-workspace/pnpm-workspace.yaml
  • tests/fixtures/workspace/package-manager-npm/pnpm-workspace.yaml

@9romise 9romise changed the title refactor: detect package manager automatically with the vscode command feat: detect package manager automatically with the vscode command Mar 12, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/core/workspace.ts (1)

55-70: ⚠️ Potential issue | 🔴 Critical

Critical: #catalogs is never initialised for npm, causing runtime crash.

When packageManager is 'npm', #catalogs remains undefined (set at line 56, never reassigned). However, loadPackageManifestInfo at line 129 accesses this.#catalogs!.promise, which will throw TypeError: Cannot read properties of undefined.

🐛 Proposed fix: always initialise `#catalogs`
   async loadWorkspace() {
-    this.#catalogs = undefined
-    this.packageManager = await getPackageManager(this.folder.uri)
-
-    logger.info(`[workspace-context] detect package manager: ${this.packageManager}`)
-
-    if (this.packageManager !== 'npm') {
-      this.#catalogs = Promise.withResolvers()
-      const workspaceFilename = workspaceFileMapping[this.packageManager]
-      const workspaceFile = Uri.joinPath(this.folder.uri, workspaceFilename)
-      this.#catalogs.resolve(
-        await accessOk(workspaceFile)
-          ? (await this.loadWorkspaceCatalogInfo(workspaceFile))?.catalogs
-          : undefined,
-      )
-    }
+    this.#catalogs = Promise.withResolvers()
+    this.packageManager = await getPackageManager(this.folder.uri)
+
+    logger.info(`[workspace-context] detect package manager: ${this.packageManager}`)
+
+    if (this.packageManager === 'npm') {
+      this.#catalogs.resolve(undefined)
+    } else {
+      const workspaceFilename = workspaceFileMapping[this.packageManager]
+      const workspaceFile = Uri.joinPath(this.folder.uri, workspaceFilename)
+      this.#catalogs.resolve(
+        await accessOk(workspaceFile)
+          ? (await this.loadWorkspaceCatalogInfo(workspaceFile))?.catalogs
+          : undefined,
+      )
+    }
   }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d3236b8a-ba1e-4a24-a6e6-d69c8e03d47c

📥 Commits

Reviewing files that changed from the base of the PR and between 705f407 and 72d8d4d.

📒 Files selected for processing (1)
  • src/core/workspace.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/core/workspace.ts (1)

27-36: Consider handling falsy results more explicitly.

Line 30 silently falls back to 'npm' when the command returns a falsy value (e.g., undefined or null), whereas line 33 only notifies the user when the command throws. If the command succeeds but returns nothing, the user won't be informed of the fallback.

💡 Optional: Add logging for falsy result fallback
 async function getPackageManager(uri: Uri): Promise<PackageManager> {
   try {
     const result = await commands.executeCommand<PackageManager>('npm.packageManager', uri)
+    if (!result) {
+      logger.info('[workspace-context] npm.packageManager returned no result, defaulting to npm')
+    }
     return result || 'npm'
   } catch (error) {
     console.error('Error getting package manager:', error)
     window.showErrorMessage('Failed to detect package manager. Defaulting to npm.')
     return 'npm'
   }
 }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2881ec6f-f795-4e67-be70-e1c219ea7ed5

📥 Commits

Reviewing files that changed from the base of the PR and between 72d8d4d and 2e52557.

📒 Files selected for processing (1)
  • src/core/workspace.ts

@9romise 9romise enabled auto-merge March 13, 2026 03:19
@9romise 9romise disabled auto-merge March 13, 2026 03:21
@9romise 9romise added this pull request to the merge queue Mar 13, 2026
Merged via the queue into main with commit 6b4b794 Mar 13, 2026
11 checks passed
@9romise 9romise deleted the packageManager branch March 13, 2026 03:21
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.

1 participant