Skip to content

fix(package-manager): restore missing git package deps + pnpm-friendly install flags#6467

Closed
cad0p wants to merge 1 commit into
earendil-works:mainfrom
cad0p:fix/git-package-reinstall-missing-node_modules
Closed

fix(package-manager): restore missing git package deps + pnpm-friendly install flags#6467
cad0p wants to merge 1 commit into
earendil-works:mainfrom
cad0p:fix/git-package-reinstall-missing-node_modules

Conversation

@cad0p

@cad0p cad0p commented Jul 9, 2026

Copy link
Copy Markdown

Problem

A git package whose checkout exists but whose node_modules is missing fails to load with Cannot find module '<dep>'. This hits pnpm users in particular.

Repro (the case I hit): @tintinweb/pi-subagents is installed as git:github.com/cad0p/tintinweb-pi-subagents@master with "npmCommand": ["pnpm"]. After the checkout lost its node_modules (a git clean -fdx during reconcile, a fresh clone by another tool, or a partial state), pi failed at startup:

Error: Failed to load extension ".../tintinweb-pi-subagents/src/index.ts": Failed to load extension: Cannot find module 'croner'
Require stack:
- .../tintinweb-pi-subagents/src/schedule.ts
Hint: Start without extensions using "pi -ne".

Root cause

The package load path (resolvePackageSources) only checks for the git checkout directory, not for node_modules:

if (parsed.type === "git") {
  const installedPath = this.getGitInstallPath(parsed, resolvedScope);
  if (!existsSync(installedPath)) {        // ← checks the dir only
    const installed = await installMissing();
    ...
  } else if (resolvedScope === "temporary" && !parsed.pinned && !isOfflineModeEnabled()) {
    await this.refreshTemporaryGitSource(parsed, resolvedSource);
  }
  metadata.baseDir = installedPath;
  this.collectPackageResources(installedPath, accumulator, filter, metadata);
}

So a checkout that exists but has no node_modules is loaded as-is, and extensions importing third-party packages fail to resolve. The install/reconcile paths (installGit/ensureGitRef) do reinstall after a ref change, but the load path on a plain pi startup does not.

A second, related pnpm issue: getGitDependencyInstallArgs() returns a bare ["install"] when npmCommand is configured. pnpm 11 exits non-zero on unapproved build scripts ([ERR_PNPM_IGNORED_BUILDS]), which would abort install/update/restore even though the dependencies are installed successfully. The npm-package install path (getNpmInstallArgs) already passes --config.strict-dep-builds=false for pnpm; the git path did not.

Fix

Two changes in packages/coding-agent/src/core/package-manager.ts:

  1. ensureGitPackageDependencies() — on resolve, when a git checkout exists but has a package.json with runtime dependencies and no node_modules, reinstall them. No-deps packages are skipped: npm install does not create node_modules for a package with no dependencies, so checking for it would cause spurious reinstalls on every startup for npm users. Respects offline mode.

  2. getGitDependencyInstallArgs() — when the configured package manager is pnpm, return the same pnpm-friendly flags the npm-package path uses (--config.auto-install-peers=false, --config.strict-peer-dependencies=false, --config.strict-dep-builds=false), so [ERR_PNPM_IGNORED_BUILDS] no longer aborts git package installs/updates/restores.

Verification

End-to-end with npmCommand: ["pnpm"] and @tintinweb/pi-subagents (which depends on croner):

$ rm -rf .../tintinweb-pi-subagents/node_modules   # reproduce broken state
$ node packages/coding-agent/dist/cli.js -p "say hi"
+ croner 10.0.1
$ echo $?
0

Before the fix: Cannot find module 'croner' and startup abort. After: deps restored, extension loads, exit 0.

  • npm run check
  • npx vitest run test/package-manager.test.ts — 119 passed (4 new regression tests added)
  • The 2 failures in test/suite/regressions/4167-... are pre-existing on main (verified by stashing this change) and unrelated to package-manager.

Notes

  • Did not edit CHANGELOG.md per CONTRIBUTING.
  • This is a load-path robustness fix; it does not change install/update semantics for healthy checkouts (the node_modules-exists and no-deps cases short-circuit before any install).

…y install flags

The package load path (resolvePackageSources) only checked for a git
checkout's directory, not its node_modules. A checkout that lost its
node_modules (manual git clean -fdx, fresh clone by another tool, or
partial state) was loaded with broken imports, failing with
"Cannot find module '<dep>'" for extensions importing third-party
packages (e.g. croner in @tintinweb/pi-subagents).

Add ensureGitPackageDependencies(): on resolve, when a git checkout
exists but has a package.json with runtime dependencies and no
node_modules, reinstall them. No-deps packages are skipped because
npm install does not create node_modules for them, so checking for
it would cause spurious reinstalls on every startup for npm users.

Also fix getGitDependencyInstallArgs() for pnpm: it returned a bare
["install"], so pnpm 11 exited non-zero on unapproved build scripts
([ERR_PNPM_IGNORED_BUILDS]), aborting install/update/restore even
though dependencies were installed. Mirror the npm-package install flags
(--config.strict-dep-builds=false etc.) so git package installs stay
pnpm-friendly.

Verified end-to-end: removed node_modules from a git package with
npmCommand: ["pnpm"]; pi restored deps (+ croner 10.0.1) and exited 0
with no "Cannot find module" error.
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

This PR was auto-closed. Only contributors approved with lgtm can open PRs. Open an issue first.

Maintainers review auto-closed issues daily. Issues that do not meet the quality bar in CONTRIBUTING.md will not be reopened or receive a reply.

If a maintainer replies lgtmi, your future issues will stay open. If a maintainer replies lgtm, your future issues and PRs will stay open.

See CONTRIBUTING.md.

@github-actions github-actions Bot closed this Jul 9, 2026
@cad0p

cad0p commented Jul 10, 2026

Copy link
Copy Markdown
Author

Sorry for the spam, did not mean to push this

@cad0p cad0p deleted the fix/git-package-reinstall-missing-node_modules branch July 10, 2026 00:08
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.

2 participants