Skip to content

feat: isolated global packages#10697

Merged
zkochan merged 29 commits into
mainfrom
new-global-dir
Mar 1, 2026
Merged

feat: isolated global packages#10697
zkochan merged 29 commits into
mainfrom
new-global-dir

Conversation

@zkochan

@zkochan zkochan commented Feb 26, 2026

Copy link
Copy Markdown
Member

TLDR: Global packages in pnpm v10 are annoying and slow because they all are installed to a single global package. Instead, we will now use a system that is similar to the one used by "pnpm dlx" (aka "pnpx").

Each globally installed package (or group of packages installed together) now gets its own isolated installation directory with its own package.json, node_modules, and lockfile. This prevents global packages from interfering with each other through peer dependency conflicts or version resolution shifts.

Changes

  • Add @pnpm/global-packages shared utilities package for scanning, hashing, and managing isolated global installs
  • pnpm add -g creates isolated installs in {pnpmHomeDir}/global/v11/{hash}/
  • pnpm remove -g removes the entire installation group containing the package
  • pnpm update -g re-installs into new isolated directories and swaps symlinks
  • pnpm list -g scans isolated directories to show installed global packages
  • pnpm outdated -g checks each isolated installation for outdated dependencies
  • pnpm store prune cleans up orphaned global installation directories

Breaking changes

  • pnpm install -g (no args) is no longer supported — use pnpm add -g <pkg>
  • pnpm link <pkg-name> no longer resolves packages from the global store — only relative or absolute paths are accepted
  • pnpm link --global is removed — use pnpm add -g . to register a local package's bins globally

zkochan and others added 17 commits February 26, 2026 02:49
Each globally installed package (or group of packages installed together)
now gets its own isolated installation directory with its own package.json,
node_modules, and lockfile. This prevents global packages from interfering
with each other through peer dependency conflicts or version resolution shifts.

- Add @pnpm/global-packages shared utilities package
- Extract createCacheKey from dlx to shared package
- pnpm add -g creates isolated installs in {pnpmHomeDir}/global/{hash}/
- pnpm remove -g removes entire installation group containing the package
- pnpm update -g re-installs in new isolated directories
- pnpm list -g scans isolated directories
- pnpm install -g (no args) is no longer supported
- pnpm link resolves packages from isolated global directories
…file

- Rename global packages directory from `global` to `.global` to avoid
  collisions with bin shims in PNPM_HOME root
- Read resolved aliases from installed package.json instead of parsing
  them from CLI params, removing the parseWantedDependency dependency
- Replace JSON.parse(fs.readFileSync(...)) with loadJsonFileSync from
  load-json-file for consistency with the rest of the codebase
- Use lexCompare instead of localeCompare in cacheKey.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…cleanup

Hash entries in .global/ are now symlinks pointing directly to .tmp-* install
dirs, removing the unnecessary intermediate directory + pkg symlink layer.
Added cleanOrphanedInstallDirs() to remove .tmp-* dirs not referenced by any
symlink, called from handleGlobalAdd, handleGlobalUpdate, and storePrune.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Install directories are permanent, not temporary. Renamed
createTmpInstallDir to createInstallDir and removed the .tmp- prefix.
Updated cleanOrphanedInstallDirs to clean any unreferenced directory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removed getGlobalDir from @pnpm/global-packages. The global packages
directory is now resolved in the config package as global/v11 (respecting
the user's --global-dir setting) and passed through as globalPkgDir to
all command handlers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
createCacheKey is dlx-specific (hashes resolved package IDs), not
related to global packages. Only createGlobalCacheKey (which hashes
alias names) belongs in @pnpm/global-packages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On Windows, os.devNull is '\\.\nul', which git cannot open as a config
file path (fatal: unable to access '\\.\nul': Invalid argument).
Git for Windows translates the literal '/dev/null' correctly via its
MSYS2 layer, fixing patch-commit on Windows.
…mandOptions

globalPkgDir is only needed for global operations, so it should not be
required in option types used by non-global tests and callers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…kages

Add a non-normalizing package.json reader to @pnpm/read-package-json
and use it in scanGlobalPackages, globalAdd, and globalUpdate instead
of importing load-json-file directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ackage[]

Remove GlobalPackageDetail wrapper type. getGlobalPackageDetails now
returns the installed packages array directly instead of spreading
the info object the caller already has.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Minimize dlx.ts diff vs main (only localeCompare → lexCompare)
- Remove unnecessary realpath in cleanOrphanedInstallDirs
- Remove unused pnpmHomeDir from UpdateCommandOptions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pnpm link no longer resolves packages from the global store by name.
Only relative or absolute paths are accepted. The --global flag is
removed; use "pnpm add -g ." to register a local package's bins
globally instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use scanGlobalPackages to discover all isolated global package groups
and check each one for outdated dependencies.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@zkochan zkochan marked this pull request as ready for review February 28, 2026 19:35
@zkochan zkochan requested a review from gluxon as a code owner February 28, 2026 19:35
Copilot AI review requested due to automatic review settings February 28, 2026 19:35
@zkochan zkochan added this to the v11.0 milestone Feb 28, 2026

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 introduces an isolated global package installation layout, where each global install group lives in its own directory (with its own package.json, lockfile, and node_modules) to prevent cross-package dependency/peer resolution interference.

Changes:

  • Adds new @pnpm/global-packages workspace package to manage scanning/cleanup, hashing, and install-dir handling for global installs.
  • Updates global-related commands (add -g, remove -g, update -g, list -g, outdated -g, store prune) to work with isolated global install directories.
  • Updates tests and changesets to reflect new global layout and breaking CLI behavior (notably pnpm link and pnpm install -g).

Reviewed changes

Copilot reviewed 39 out of 40 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
store/plugin-commands-store/tsconfig.json Adds TS project reference to new global-packages utilities.
store/plugin-commands-store/src/storePrune.ts Invokes orphaned global install-dir cleanup during store prune when configured.
store/plugin-commands-store/src/store.ts Extends store command options to include globalPkgDir.
store/plugin-commands-store/package.json Adds dependency on @pnpm/global-packages.
reviewing/plugin-commands-outdated/tsconfig.json Adds TS project reference to global-packages.
reviewing/plugin-commands-outdated/test/index.ts Adds tests for pnpm outdated -g using isolated global layout.
reviewing/plugin-commands-outdated/src/outdated.ts Implements outdated -g by scanning isolated global install groups.
reviewing/plugin-commands-outdated/package.json Adds dependency on @pnpm/global-packages.
reviewing/plugin-commands-listing/tsconfig.json Adds TS project reference to global-packages.
reviewing/plugin-commands-listing/src/list.ts Implements list -g by scanning isolated global install groups.
reviewing/plugin-commands-listing/package.json Adds dependency on @pnpm/global-packages.
pnpm/test/root.ts Updates pnpm root -g expectation to new layout path.
pnpm/test/link.ts Updates link-related global prefix expectations to new layout path.
pnpm/test/install/global.ts Refactors global install tests to work with isolated install directories.
pnpm-lock.yaml Adds lock entries for new @pnpm/global-packages and related deps.
pkg-manifest/read-package-json/src/index.ts Adds sync “raw” read helper for package.json with improved error wrapping.
pkg-manager/plugin-commands-installation/tsconfig.json Adds TS refs for global-packages, link-bins, remove-bins.
pkg-manager/plugin-commands-installation/test/link.ts Removes/adjusts tests tied to deprecated global link behaviors.
pkg-manager/plugin-commands-installation/src/update/index.ts Routes pnpm update -g to new global update handler.
pkg-manager/plugin-commands-installation/src/remove.ts Routes pnpm remove -g to new global remove handler.
pkg-manager/plugin-commands-installation/src/link.ts Removes linking-by-package-name/global link mode; enforces path-only linking.
pkg-manager/plugin-commands-installation/src/install.ts Rejects pnpm install -g (unless invoked internally from link).
pkg-manager/plugin-commands-installation/src/globalUpdate.ts Implements global update by reinstalling into new isolated dirs and swapping hash links.
pkg-manager/plugin-commands-installation/src/globalRemove.ts Implements global remove by deleting whole install groups + bins.
pkg-manager/plugin-commands-installation/src/globalAdd.ts Implements global add into isolated dirs, de-duping existing installs and relinking bins.
pkg-manager/plugin-commands-installation/src/add.ts Delegates global adds to handleGlobalAdd.
pkg-manager/plugin-commands-installation/package.json Adds deps needed for global isolation (global-packages, link-bins, remove-bins, symlink-dir).
patching/plugin-commands-patching/src/patchCommit.ts Makes git global config redirection Windows-safe by using /dev/null.
packages/global-packages/tsconfig.lint.json Adds lint tsconfig for the new workspace package.
packages/global-packages/tsconfig.json Adds build tsconfig and project references for the new workspace package.
packages/global-packages/src/scanGlobalPackages.ts Adds scanning, lookup, orphan cleanup, and bin discovery for isolated global installs.
packages/global-packages/src/index.ts Exports new global-packages utilities.
packages/global-packages/src/globalPackageDir.ts Adds helpers for hash links, resolving install dirs, and creating install dirs.
packages/global-packages/src/cacheKey.ts Adds cache key generator for global install groups.
packages/global-packages/package.json Introduces the new @pnpm/global-packages workspace package.
exec/plugin-commands-script-runners/src/dlx.ts Uses lexCompare for stable cache key sorting.
config/config/src/parseAuthInfo.ts Removes an unnecessary eslint suppression.
config/config/src/index.ts Sets globalPkgDir layout to .../global/v11 for isolated global installs.
.changeset/link-breaking-changes.md Documents breaking changes to pnpm link.
.changeset/isolated-global-packages.md Documents isolated global packages behavior and related breaking changes.
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 pkg-manager/plugin-commands-installation/src/remove.ts
Comment thread packages/global-packages/src/scanGlobalPackages.ts Outdated
Comment thread global/packages/package.json
Comment thread config/config/src/index.ts Outdated
Comment thread pnpm/test/link.ts Outdated
Comment thread pnpm/test/install/global.ts Outdated
Comment thread reviewing/plugin-commands-outdated/test/index.ts
Comment thread reviewing/plugin-commands-listing/src/list.ts Outdated
Comment thread pnpm/test/root.ts Outdated
Comment thread pkg-manager/plugin-commands-installation/src/update/index.ts
- Add NO_GLOBAL_BIN_DIR validation to `pnpm remove -g` and `pnpm update -g`
- Add GLOBAL_LAYOUT_VERSION constant, use it in config and tests
- Use symlink-dir in outdated test for Windows compatibility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

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 40 out of 41 changed files in this pull request and generated 10 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 packages/global-packages/src/scanGlobalPackages.ts Outdated
Comment thread reviewing/plugin-commands-listing/src/list.ts Outdated
Comment thread pkg-manager/plugin-commands-installation/src/globalUpdate.ts Outdated
Comment thread global/commands/src/globalAdd.ts
Comment thread .changeset/isolated-global-packages.md Outdated
Comment thread pkg-manager/plugin-commands-installation/src/globalUpdate.ts Outdated
Comment thread pkg-manager/plugin-commands-installation/src/globalRemove.ts Outdated
Comment thread packages/global-packages/src/scanGlobalPackages.ts Outdated
Comment thread global/commands/src/globalRemove.ts
Comment thread global/packages/src/scanGlobalPackages.ts
- Fix shared mutation in getGlobalPackageDetails and getInstalledBinNames
- Sort pnpm list -g output using lexCompare for deterministic results
- Add isSubdir safety checks before deleting install dirs
- Remove stale bins in globalUpdate before swapping symlink
- Remove stale pnpm link bullet from changeset
- Use is-subdir package instead of custom isSubdir function

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

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

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

pkg-manager/plugin-commands-installation/src/link.ts:131

  • When pnpm link is run with no params, the error message just says "You must provide a parameter". Since this PR removes global-name linking and narrows link usage, consider making the error point to the supported forms (e.g. pnpm link <dir>) and/or the replacement for global registration (pnpm add -g .).
  if ((params == null) || (params.length === 0)) {
    const cwd = process.cwd()
    if (path.relative(linkOpts.dir, cwd) === '') {
      throw new PnpmError('LINK_BAD_PARAMS', 'You must provide a parameter')
    }

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

Comment thread global/packages/package.json
Comment thread reviewing/plugin-commands-listing/src/list.ts
Comment thread .changeset/isolated-global-packages.md Outdated
zkochan and others added 2 commits March 1, 2026 01:51
When installing or updating a global package, check if its binaries
would conflict with binaries from other globally installed packages.
If a conflict is found, refuse the installation and suggest removing
the conflicting package first.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a test verifying that old bins are removed when re-adding a global
package whose bin names have changed. Also skip recently-created dirs
in cleanOrphanedInstallDirs to avoid racing with concurrent installs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

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 41 out of 42 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 (1)

pkg-manager/plugin-commands-installation/src/link.ts:130

  • The PR declares pnpm link --global removed, but handler() doesn’t explicitly reject global mode (opts.global / opts.cliOptions?.global). As-is, running pnpm link -g may still proceed (and _calledFromLink bypasses the new install -g guard). Add an explicit error for global link usage with guidance to use pnpm add -g ..
  // pnpm link (no params, no --global)
  if ((params == null) || (params.length === 0)) {
    const cwd = process.cwd()
    if (path.relative(linkOpts.dir, cwd) === '') {
      throw new PnpmError('LINK_BAD_PARAMS', 'You must provide a parameter')

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

Comment thread pkg-manager/plugin-commands-installation/src/link.ts
Comment thread global/packages/src/scanGlobalPackages.ts
zkochan and others added 2 commits March 1, 2026 02:17
Use safeReadPackageJsonFromDir for missing/corrupted package.json

Use Math.max(birthtimeMs, ctimeMs) for orphaned install dir garbage collection
Remove `pnpm link` (no arguments), which required `-C` to specify the
target project. Use `pnpm link <dir>` with an explicit path instead.
Also resolve globalDir in cleanOrphanedInstallDirs to fix path
comparison with realpaths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Verify that removing one package from a globally installed group
deletes the entire group's install directory, hash symlink, and
all bin shims.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

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 41 out of 42 changed files in this pull request and generated 2 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 global/packages/src/scanGlobalPackages.ts
Comment thread reviewing/plugin-commands-listing/src/list.ts Outdated
zkochan and others added 2 commits March 1, 2026 11:27
Use @pnpm/matcher for pnpm ls -g filtering so glob patterns like
babel-* work consistently with non-global listing. Remove e2e tests
for pnpm link --global and pnpm link (no args) which are no longer
supported.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move global-related command handlers out of plugin-commands-installation
into a new @pnpm/global.commands package under global/commands/. Also
rename @pnpm/global-packages to @pnpm/global.packages and move it to
global/packages/ to establish a global/ domain directory.

The key architectural change is replacing the 450-line installDeps()
dependency with a focused ~30-line installGlobalPackages() function
that directly calls mutateModulesInSingleProject from @pnpm/core.

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 51 out of 52 changed files in this pull request and generated 2 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 on lines +111 to +113
if (opts.global && opts.globalPkgDir) {
return listGlobalPackages(opts.globalPkgDir, params)
}

Copilot AI Mar 1, 2026

Copy link

Choose a reason for hiding this comment

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

The global fast-path (if (opts.global && opts.globalPkgDir) return listGlobalPackages(...)) bypasses the existing list rendering logic and ignores supported list output options like --json, --parseable, --long, --depth, and --lockfile-only that are part of this command’s API.

Either (a) adapt global listing to reuse the existing list/listForPackages rendering (so flags behave consistently), or (b) explicitly reject/handle incompatible flags in global mode and document it as a breaking change.

Copilot uses AI. Check for mistakes.
Comment on lines 130 to +135
const [pkgPaths, pkgNames] = partition((inp) => isFilespec.test(inp), params)

pkgNames.forEach((pkgName) => pkgPaths.push(path.join(opts.globalPkgDir, 'node_modules', pkgName)))
if (pkgNames.length > 0) {
throw new PnpmError('LINK_BAD_PARAMS',
`Cannot link by package name. Use a relative or absolute path instead, e.g. "pnpm link ./${pkgNames[0]}"`)
}

Copilot AI Mar 1, 2026

Copy link

Choose a reason for hiding this comment

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

partition((inp) => isFilespec.test(inp), params) is too strict for detecting directory paths. A relative directory like packages/foo (no leading ./) is a valid path but will be classified as a “package name” and rejected. This makes pnpm link packages/foo fail even though the command now requires linking by path.

Consider treating an argument as a path if it resolves to an existing filesystem entry (e.g. fs.existsSync(path.resolve(inp))), or at least if it contains a path separator, rather than requiring ./, ../, /, ~/, or a drive prefix.

Copilot uses AI. Check for mistakes.
zkochan and others added 3 commits March 1, 2026 14:31
- Make `pnpm approve-builds -g` throw an error since it doesn't work
  with isolated global packages (no single .modules.yaml to scan)
- After `pnpm add -g` / `pnpm update -g`, if packages have ignored
  builds, reuse the `approve-builds` interactive flow (enquirer
  multiselect + rebuild) instead of re-installing from scratch
- `installGlobalPackages` now returns `ignoredBuilds` from
  `mutateModulesInSingleProject` to avoid reading .modules.yaml
With isolated global packages, the global package directory itself is
the root — there is no top-level node_modules directory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-commands

The cycle was: global/commands → exec/build-commands →
plugin-commands-installation → global/commands.

The exec/build-commands → plugin-commands-installation reference was
only needed for tests (import of install.handler). Replace the
programmatic install.handler() calls with running the pnpm CLI via
execa, matching the pattern used in plugin-commands-store tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

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 56 out of 57 changed files in this pull request and generated no new 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.

@zkochan zkochan merged commit fd511e4 into main Mar 1, 2026
17 checks passed
@zkochan zkochan deleted the new-global-dir branch March 1, 2026 14:49
zkochan added a commit that referenced this pull request May 4, 2026
Restores `--json` / `--parseable` / `--long` support on `pnpm -g ls` and tightens `--depth>0` semantics around isolated global installs. Closes #11440.

- **`--json` / `--parseable` (the regression):** aggregate global packages from all isolated install dirs into a single synthesized `PackageDependencyHierarchy` and dispatch to the existing `renderJson` / `renderParseable` / `renderTree`. Output shape matches pnpm 10 (`result[0].dependencies[name].version`), so tools like `npm-check-updates` work again.
- **`--depth>0`:** the v11 architecture installs each global package into its own isolated dir with its own lockfile, so merging transitive trees across installs would be incoherent. New behavior:
  - One global install dir total → fast-path delegate to the regular `list` flow with `params` unchanged, so `listForPackages` can match top-level *or* transitive packages.
  - Multiple installs, params narrow to one install dir (top-level alias match) → drop the params and render that install dir's full tree.
  - Multiple installs, params don't narrow → throw `ERR_PNPM_GLOBAL_LS_DEPTH_NOT_SUPPORTED` with a message asking the user to filter to a single global package or omit `--depth`.

The regression was introduced by the isolated global packages refactor (#10697), which added a custom `listGlobalPackages` shortcut that always returned plain text and ignored format flags.
zkochan added a commit that referenced this pull request May 4, 2026
Restores `--json` / `--parseable` / `--long` support on `pnpm -g ls` and tightens `--depth>0` semantics around isolated global installs. Closes #11440.

- **`--json` / `--parseable` (the regression):** aggregate global packages from all isolated install dirs into a single synthesized `PackageDependencyHierarchy` and dispatch to the existing `renderJson` / `renderParseable` / `renderTree`. Output shape matches pnpm 10 (`result[0].dependencies[name].version`), so tools like `npm-check-updates` work again.
- **`--depth>0`:** the v11 architecture installs each global package into its own isolated dir with its own lockfile, so merging transitive trees across installs would be incoherent. New behavior:
  - One global install dir total → fast-path delegate to the regular `list` flow with `params` unchanged, so `listForPackages` can match top-level *or* transitive packages.
  - Multiple installs, params narrow to one install dir (top-level alias match) → drop the params and render that install dir's full tree.
  - Multiple installs, params don't narrow → throw `ERR_PNPM_GLOBAL_LS_DEPTH_NOT_SUPPORTED` with a message asking the user to filter to a single global package or omit `--depth`.

The regression was introduced by the isolated global packages refactor (#10697), which added a custom `listGlobalPackages` shortcut that always returned plain text and ignored format flags.
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.

2 participants