pm pls for listing packages and pm cd for jumping to package directories.
Package Listing with pm pls
Thepm pls command displays all workspace packages in a tree structure:
How It Works
Thepls command is remarkably simple:
List workspace packages
The package manager service discovers all workspace packages by reading the workspace configuration (
pnpm-workspace.yaml or package.json workspaces field) and enumerating directories.Format as tree
The
formatWorkspaceTree function groups packages by their parent directory and formats them with box-drawing characters.Tree Formatting Logic
The tree structure is generated by theformatWorkspaceTree function:
- Groups packages by their top-level directory (e.g.,
packages/,apps/) - Uses Unicode box-drawing characters (
├──,└──,│) to create the tree structure - Shows both the directory name and package name for each entry
The same
formatWorkspaceTree function is used in multiple places:pm plsoutput- Root install warnings
- Package not found error messages
Directory Navigation with pm cd
Thepm cd command allows you to jump directly to any workspace package:
Command Implementation
Handle special cases
- If
--completionsflag is present, output all package names for shell completion - If no package name is provided, output the monorepo root directory
Shell Integration Mechanism
Better PM can’t change your shell’s working directory directly (child processes can’t modify parent state). Instead, it uses a shell wrapper function:Activation
Add this to your.zshrc or .bashrc:
The Shell Wrapper
Thepm activate command outputs a shell function that wraps the pm binary:
Intercept pm cd calls
When you run
pm cd <package>, the shell function intercepts it instead of calling the binary directly.Handle flag-only invocations
If the arguments contain flags (like
--completions or --path), pass through to the binary without changing directories.Capture the output path
Execute
command pm cd "$@" and capture the output (the package directory path).Change directory
If the command succeeded and the output is a valid directory, use
builtin cd to change the shell’s working directory.Autocomplete Functionality
Better PM provides shell completion for package names:Zsh Completions
Bash Completions
Detect pm cd context
The completion function checks if the current command is
pm cd and the cursor is on the package name argument.Generate completions
Pass the package names to the shell’s completion system (
compadd for zsh, compgen for bash).Completions Mode
Whenpm cd --completions is called, it outputs one package name per line:
The
--completions flag is hidden from normal help output and is only used by the shell completion functions.Package Discovery
Bothpm pls and pm cd use the same underlying package discovery mechanism:
- Detect package manager - Find the lock file and determine if it’s pnpm, bun, or npm
- Read workspace config - Load workspace globs from
pnpm-workspace.yamlorpackage.json - Enumerate directories - Expand glob patterns and find all package directories
- Read package names - Parse each
package.jsonto get the official package name - Return structured data - Provide an array of
{ name: string; relDir: string }objects
pm cd to any package shown in pm pls.
Fast Navigation
Jump to any package from anywhere in the monorepo without manually typing paths or using fuzzy finders.
Autocomplete Support
Tab completion for package names makes navigation even faster and prevents typos.
Visual Discovery
The tree view in
pm pls helps you understand your monorepo structure at a glance.Error Guidance
If you try to cd to a non-existent package, Better PM shows the full package tree to help you find the right name.