A powerful command-line project manager inspired by the VS Code Project Manager extension. Easily access your projects, organize them with tags, and auto-detect Git, SVN, and Mercurial repositories.
- Features
- Installation
- Quick Start
- Commands
- Configuration
- Projects File
- Global Flags
- Examples
- Troubleshooting
- Save any folder as a favorite project
- Auto-detect Git, SVN, Mercurial repositories
- Auto-detect VS Code workspaces
- Organize projects with custom tags
- Open projects in your preferred editor (VS Code, Cursor, Vim, etc.)
- Interactive project selection
- Colored output with customizable display
- Cache detected projects for fast access
- Shell completion for bash, zsh, fish, and PowerShell
- Cross-platform support (macOS, Linux, Windows)
brew tap ideaspaper/tap
brew install --cask projector-cligo install github.com/ideaspaper/projector@latestThis will install the binary as projector in your $GOPATH/bin directory. Make sure $GOPATH/bin is in your PATH.
# Clone the repository
git clone https://github.com/ideaspaper/projector.git
cd projector
# Build the binary
make build
# Install to $GOPATH/bin
make install
# Or move to PATH manually
sudo mv projector /usr/local/bin/Requires Go 1.24.4 or later.
go mod download# Add current directory as a project
projector add
# Add a specific directory
projector add ~/projects/myapp
# Add with a custom name
projector add ~/projects/myapp --name "My Application"
# Add with tags
projector add --name "Work API" --tag Work --tag Backend# List all projects
projector list
# List with paths
projector list --path
# List grouped by type
projector list --grouped
# Filter by tag
projector list --tag Work# Open by name
projector open myproject
# Open in new window
projector open myproject --new-window
# Open with a specific editor
projector open myproject --editor vim
# Interactive selection
projector open# Scan for Git repositories
projector scan --git ~/projects
# Scan for all repository types
projector scan --all ~/code
# Scan with custom depth
projector scan --git --depth 5 ~/projectsAdd a folder as a project to your favorites.
projector add [path] [flags]Flags:
| Flag | Short | Description |
|---|---|---|
--name |
-n |
Project name (defaults to folder name) |
--tag |
-t |
Tags for the project (can be repeated) |
--enabled |
Whether the project is enabled (default: true) |
Examples:
# Add current directory
projector add
# Add with custom name
projector add ~/projects/api --name "Backend API"
# Add with multiple tags
projector add --name "Frontend" --tag Work --tag React --tag TypeScriptList all saved and detected projects.
projector list [flags]Aliases: ls
Flags:
| Flag | Short | Description |
|---|---|---|
--tag |
-t |
Filter projects by tag |
--path |
-p |
Show project paths |
--grouped |
-g |
Group projects by type |
--all |
-a |
Include disabled projects |
--favorites |
Show only favorites | |
--git |
Show only Git repositories | |
--svn |
Show only SVN repositories | |
--mercurial |
Show only Mercurial repositories | |
--vscode |
Show only VS Code workspaces | |
--any |
Show only any-folder projects |
Examples:
# List all projects
projector list
# List with full paths
projector list --path
# List grouped by type (Favorites, Git, SVN, etc.)
projector list --grouped
# Filter by tag
projector list --tag Work
# Show only Git repositories
projector list --gitOpen a project in your configured editor.
projector open [project-name] [flags]Flags:
| Flag | Short | Description |
|---|---|---|
--new-window |
-n |
Open in a new window |
--editor |
-e |
Editor to use (overrides config) |
--tag |
-t |
Filter projects by tag |
--grouped |
-g |
Group projects by type (overrides config) |
--favorites |
Show only favorites | |
--git |
Show only Git repositories | |
--svn |
Show only SVN repositories | |
--mercurial |
Show only Mercurial repositories | |
--vscode |
Show only VS Code workspaces | |
--any |
Show only any-folder projects |
Supported Editors:
code/vscode- Visual Studio Codecursor- Cursorsubl/sublime- Sublime Textatom- Atomvim/nvim- Vim / Neovimemacs- Emacsidea/intellij- IntelliJ IDEAwebstorm- WebStormgoland- GoLandpycharm- PyCharmopen- macOS default handlerxdg-open- Linux default handlerexplorer- Windows Explorer
Examples:
# Open by name (fuzzy matching)
projector open myproject
# Open in a new window
projector open myproject -n
# Open with Vim
projector open myproject --editor vim
# Interactive selection (no argument)
projector open
# Filter interactive selection by tag
projector open --tag Work
# Interactive selection with flat list (no grouping)
projector open --grouped=false
# Interactive selection with grouping (overrides config)
projector open -g
# Open only from Git repositories
projector open --git
# Open only from favorites
projector open --favoritesInteractive Selection:
When no project name is provided, an interactive menu is displayed:
Select a project to open:
Favorites
[1] my-app [Work] - /Users/you/projects/my-app
[2] blog - /Users/you/projects/blog
Git Repositories
[3] api - /Users/you/work/api
[4] frontend [React] - /Users/you/work/frontend
Enter project number (or 'q' to quit):
Projects are grouped by type (if groupList is enabled in config), showing tags and truncated paths. Enter the number to open that project.
Remove a project from favorites.
projector remove <project-name>Aliases: rm, delete
Examples:
projector remove myproject
projector rm old-projectEdit a project's properties.
projector edit <project-name> [flags]Flags:
| Flag | Description |
|---|---|
--name |
New project name |
--path |
New project path |
--enabled |
Enable/disable project (true/false) |
--add-tag |
Add a tag to the project (can be repeated) |
--remove-tag |
Remove a tag from the project (can be repeated) |
Examples:
# Rename a project
projector edit myproject --name "New Name"
# Update path
projector edit myproject --path ~/new/location
# Disable a project
projector edit myproject --enabled=false
# Add tags
projector edit myproject --add-tag Work --add-tag Important
# Remove a tag
projector edit myproject --remove-tag Old
# Add and remove tags in one command
projector edit myproject --add-tag Backend --remove-tag FrontendScan directories for repositories and workspaces.
projector scan [paths...] [flags]Flags:
| Flag | Short | Description |
|---|---|---|
--git |
Scan for Git repositories | |
--svn |
Scan for SVN repositories | |
--mercurial |
Scan for Mercurial repositories | |
--vscode |
Scan for VS Code workspaces | |
--any |
Scan for any folder | |
--all |
-a |
Scan for all types |
--depth |
-d |
Maximum scan depth (0 = use config) |
Examples:
# Scan for Git repos in a directory
projector scan --git ~/projects
# Scan for all types in configured base folders
projector scan --all
# Scan multiple directories
projector scan --git ~/work ~/personal
# Limit scan depth
projector scan --git --depth 3 ~/codeSelect a project and output its path to stdout.
projector select [project-name] [flags]If no project name is provided, an interactive selection is shown. This is useful for scripting and shell integration.
Flags:
| Flag | Short | Description |
|---|---|---|
--tag |
-t |
Filter projects by tag |
--grouped |
-g |
Group projects by type (overrides config) |
--favorites |
Show only favorites | |
--git |
Show only Git repositories | |
--svn |
Show only SVN repositories | |
--mercurial |
Show only Mercurial repositories | |
--vscode |
Show only VS Code workspaces | |
--any |
Show only any-folder projects |
Examples:
# Interactive selection
projector select
# Select by name
projector select myproject
# Select by partial name match
projector select my
# Filter interactive selection by tag
projector select --tag Work
# Interactive selection with flat list (no grouping)
projector select --grouped=false
# Interactive selection with grouping (overrides config)
projector select -g
# Select only from Git repositories
projector select --git
# Select only from favorites
projector select --favoritesInteractive Selection:
Similar to open, when no project name is provided, an interactive menu is displayed with 1-based numbering. The selected project's path is output to stdout, making it ideal for shell scripting.
Shell Function for cd:
Add this to your .bashrc or .zshrc to create a pjcd command that selects a project and changes to its directory:
pjcd() {
local dir
dir=$(projector select "$@")
[ -n "$dir" ] && [ -d "$dir" ] && cd "$dir"
}Usage:
# Interactive selection
pjcd
# Direct selection by name
pjcd myprojectList all unique tags currently in use by projects.
projector tagsExamples:
# List all tags in use
projector tagsOutput:
Tags in use:
- Backend
- Frontend
- Go
- Personal
- Work
Clear the cached auto-detected projects.
projector clear-cacheAliases: cc
This command removes the cache file (~/.projector/cache.json) that stores auto-detected repositories (Git, SVN, Mercurial, VS Code workspaces, and any-folder projects).
Note: This does not affect your saved favorites in projects.json. After clearing the cache, run projector scan to re-detect projects.
Examples:
# Clear the project cache
projector clear-cache
# Using the alias
projector cc
# Clear cache and re-scan for Git repositories
projector clear-cache && projector scan --git ~/projectsGenerate shell completion scripts.
projector completion [bash|zsh|fish|powershell]Configuration is stored in ~/.projector/config.json:
{
"sortList": "Name",
"groupList": true,
"showColors": true,
"checkInvalidPathsBeforeListing": true,
"removeCurrentProjectFromList": true,
"cacheProjectsBetweenSessions": true,
"ignoreProjectsWithinProjects": false,
"supportSymlinksOnBaseFolders": false,
"editor": "code",
"openInNewWindow": false,
"gitBaseFolders": ["~/projects", "~/work"],
"gitIgnoredFolders": [
"node_modules",
"out",
"typings",
"test",
".haxelib",
"vendor"
],
"gitMaxDepthRecursion": 4,
"svnBaseFolders": [],
"svnIgnoredFolders": ["node_modules", "out", "typings", "test"],
"svnMaxDepthRecursion": 4,
"hgBaseFolders": [],
"hgIgnoredFolders": ["node_modules", "out", "typings", "test", ".haxelib"],
"hgMaxDepthRecursion": 4,
"vscodeBaseFolders": [],
"vscodeIgnoredFolders": ["node_modules", "out", "typings", "test"],
"vscodeMaxDepthRecursion": 4,
"anyBaseFolders": [],
"anyIgnoredFolders": ["node_modules", "out", "typings", "test"],
"anyMaxDepthRecursion": 4,
"projectsLocation": ""
}| Option | Description | Default |
|---|---|---|
sortList |
Sort order: Name, Path, Saved, Recent |
Name |
groupList |
Group projects by type in list (can be overridden with --grouped flag) |
true |
showColors |
Enable colored output | true |
checkInvalidPathsBeforeListing |
Check if paths exist | true |
editor |
Default editor command | code |
openInNewWindow |
Always open in new window | false |
gitBaseFolders |
Folders to scan for Git repos | [] |
gitIgnoredFolders |
Folders to skip when scanning Git | ["node_modules", ...] |
gitMaxDepthRecursion |
Max depth for Git scanning | 4 |
cacheProjectsBetweenSessions |
Cache detected projects | true |
ignoreProjectsWithinProjects |
Skip nested projects | false |
supportSymlinksOnBaseFolders |
Follow symlinks | false |
projectsLocation |
Custom location for projects.json | "" |
Saved projects are stored in ~/.projector/projects.json:
[
{
"name": "My App",
"rootPath": "~/projects/myapp",
"tags": ["Work", "Go"],
"enabled": true
},
{
"name": "Website",
"rootPath": "~/projects/website",
"tags": ["Personal", "React"],
"enabled": true
}
]You can use ~ or $home in paths - they will be expanded automatically.
| Flag | Short | Description |
|---|---|---|
--no-color |
Disable colored output | |
--verbose |
-v |
Verbose output |
--version |
Show version | |
--help |
-h |
Show help |
# Add some projects
projector add ~/projects/backend --name "Backend API" --tag Work --tag Go
projector add ~/projects/frontend --name "Frontend App" --tag Work --tag React
projector add ~/personal/blog --name "My Blog" --tag Personal
# Configure base folders for scanning
# Edit ~/.projector/config.json and add:
# "gitBaseFolders": ["~/projects", "~/work"]
# Scan for Git repositories
projector scan --git
# List all projects grouped
projector list --grouped --path
# Open a project
projector open backend
# Filter by tag
projector list --tag Work
# Remove a project
projector remove "My Blog"#!/bin/bash
# Open project in tmux session
# Non-interactive: pass project name directly
PROJECT=$(projector select myproject 2>/dev/null)
# Or interactive: let user choose
# PROJECT=$(projector select 2>/dev/null)
if [ -n "$PROJECT" ]; then
SESSION_NAME=$(basename "$PROJECT")
tmux new-session -d -s "$SESSION_NAME" -c "$PROJECT"
tmux attach-session -t "$SESSION_NAME"
fi# Add to your .bashrc or .zshrc
proj() {
local project
project=$(projector list --path | fzf --height 40% --reverse)
if [ -n "$project" ]; then
# Extract path (second line)
path=$(echo "$project" | tail -1 | xargs)
cd "$path" || return
fi
}Create a script that outputs project paths for launcher integration:
#!/bin/bash
projector list --path | while IFS= read -r line; do
if [[ $line == " "* ]]; then
echo "${line:2}" # Path line (indented)
fi
doneError: project 'myproject' not found
- Check project name with
projector list - Names are case-insensitive but must match
- Use partial matching:
projector open mywill matchmyproject
Error: project path does not exist
The project's directory has been moved or deleted. Update it:
projector edit myproject --path ~/new/locationOr remove and re-add:
projector remove myproject
projector add ~/new/location --name myproject- Verify the editor is installed and in PATH
- Check config:
cat ~/.projector/config.json | grep editor - Override with flag:
projector open myproject --editor code
- Ensure base folders are configured in
config.json - Check scan depth (default is 4)
- Verify folders aren't in the ignored list
- Try scanning a specific path:
projector scan --git ~/projects
# Build
make build
# Run tests
make test
# Format code
make fmt
# Lint
make lintprojector/
├── cmd/ # Command implementations
│ ├── root.go # Base command
│ ├── add.go # Add command
│ ├── list.go # List and scan commands
│ ├── open.go # Open command
│ ├── select.go # Select command
│ ├── manage.go # Remove, edit, tag commands
│ └── completion.go # Shell completions
├── pkg/
│ ├── config/ # Configuration
│ ├── models/ # Data structures
│ ├── output/ # Formatted output
│ ├── paths/ # Path utilities
│ ├── scanner/ # Repository detection
│ └── storage/ # JSON persistence
├── main.go
├── go.mod
├── Makefile
└── README.md
MIT License - see LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Inspired by VS Code Project Manager
- Built with Cobra and Viper