pm activate
Set up shell integration and completions
Overview
The pm activate command generates shell integration code that enables advanced features like actual directory changes with pm cd and intelligent tab completions for workspace packages.
Syntax
pm activate <shell>
Arguments
shell string required
Your shell type: zsh or bash
Installation
Add to your shell configuration file:
# Add this line to ~/.zshrc
eval "$(pm activate zsh)"# Add this line to ~/.bashrc
eval "$(pm activate bash)"Then reload your shell:
# For zsh
source ~/.zshrc
# For bash
source ~/.bashrc
What It Enables
1. Actual Directory Changes
Without activation, pm cd only prints the path:
# Without activation
pm cd @myapp/web
/path/to/monorepo/apps/web
# (you're still in the same directory)
With activation, it actually changes directories:
# With activation
pm cd @myapp/web
# (now in /path/to/monorepo/apps/web)
2. Tab Completions
Complete package names with Tab:
pm cd <TAB>
# Shows all workspace packages
@myapp/api @myapp/core @myapp/web @myapp/utils
pm cd @myapp/<TAB>
# Completes package names
3. Command Completions
Complete all pm commands and flags:
pm <TAB>
add cd i install link ls
pls remove run unlink up why x
pm add -<TAB>
-D # (shows dev dependency flag)
How It Works
Shell Wrapper Function
The activation creates a wrapper function that intercepts pm cd commands:
From src/commands/activate.ts:6-22:
pm() {
if [ "$1" = "cd" ]; then
shift;
# Check if any flags are present
for arg in "$@"; do
case "$arg" in
-*) command pm cd "$@"; return;;
esac;
done;
# Get the directory path
local dir;
dir=$(command pm cd "$@");
# If successful and path exists, cd to it
if [ $? -eq 0 ] && [ -d "$dir" ]; then
builtin cd "$dir";
fi;
else
command pm "$@";
fi;
};
This wrapper:
- Intercepts
pm cdcalls - Handles flags by passing through to the command
- Gets the directory path from
pm cd - Uses shell’s builtin
cdto actually change directory - Passes all other commands through normally
Completion Functions
For zsh, from src/commands/activate.ts:24-34:
eval "$(command pm --completions zsh)";
if (( $+functions[_pm_zsh_completions] )); then
functions[_pm_zsh_completions_base]=$functions[_pm_zsh_completions];
_pm_zsh_completions() {
if [[ $words[2] == cd ]] && (( CURRENT == 3 )); then
compadd -- ${(f)"$(command pm cd --completions 2>/dev/null)"};
else
_pm_zsh_completions_base "$@";
fi;
};
fi;
This:
- Loads base completions from
pm --completions zsh - Wraps the completion function
- For
pm cd <TAB>, gets package names frompm cd --completions - For other commands, uses base completions
Testing Activation
Verify Installation
Check if the function exists:
type pm
pm is a shell function from /Users/you/.zshrc
pm is /usr/local/bin/pm
Test Directory Change
pwd
# /path/to/monorepo
pm cd @myapp/web
pwd
# /path/to/monorepo/apps/web
Test Completions
pm cd <TAB>
# Should show package names
Manual Setup
If you prefer not to use eval, save the output:
pm activate zsh > ~/.pm-integration.zsh
Then source it in ~/.zshrc:
source ~/.pm-integration.zsh
Troubleshooting
Completions Not Working
-
Reload shell:
source ~/.zshrc # or ~/.bashrc -
Check function is loaded:
type pm -
Verify activation line:
grep "pm activate" ~/.zshrc
Directory Changes Not Working
-
Verify shell integration:
type pm # Should show "pm is a shell function" -
Test without cd:
pm --version # Should still work -
Check package exists:
pm pls # Verify package name is correct
Conflicts with Existing Function
If you have another pm function:
# Rename the wrapper
eval "$(pm activate zsh | sed 's/^pm()/better_pm()/')"
# Then use:
better_pm cd @myapp/web
Shell Support
| Shell | Supported | Completions | cd Integration |
|---|---|---|---|
| zsh | ✅ Yes | ✅ Yes | ✅ Yes |
| bash | ✅ Yes | ✅ Yes | ✅ Yes |
| fish | ⚠️ Partial | ❌ No | ❌ No |
| other | ⚠️ Basic | ❌ No | ❌ No |
What Gets Activated
Shell Wrapper
Function that intercepts pm cd and uses builtin cd
Base Completions
Tab completion for all pm commands and flags
Package Completions
Tab completion for workspace package names in pm cd
Smart Filtering
Completions filter based on what you’ve typed
Advanced Usage
Lazy Loading
For faster shell startup, lazy load activation:
# Only load when pm is used
pm() {
unfunction pm
eval "$(command pm activate zsh)"
pm "$@"
}
Custom Wrapper
Extend the wrapper with your own logic:
eval "$(pm activate zsh)"
# Save the original function
functions[_pm_original]=$functions[pm]
# Override with custom logic
pm() {
echo "Running pm $@"
_pm_original "$@"
}