project-session-manager
Original:🇺🇸 English
Translated
13 scriptsChecked / no sensitive code detected
Manage isolated dev environments with git worktrees and tmux sessions
3installs
Added on
NPX Install
npx skill4agent add yeachan-heo/oh-my-claudecode project-session-managerTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Project Session Manager (PSM) Skill
Quick Start: For simple worktree creation without tmux sessions, use:omc teleportbashomc teleport #123 # Create worktree for issue/PR omc teleport my-feature # Create worktree for feature omc teleport list # List worktreesSee Teleport Command below for details.
Automate isolated development environments using git worktrees and tmux sessions with Claude Code. Enables parallel work across multiple tasks, projects, and repositories.
Commands
| Command | Description | Example |
|---|---|---|
| PR review session | |
| Issue fix session | |
| Feature development | |
| List active sessions | |
| Attach to session | |
| Kill session | |
| Clean merged/closed | |
| Current session info | |
Project References
Supported formats:
- Alias: (requires
omc#123)~/.psm/projects.json - Full:
owner/repo#123 - URL:
https://github.com/owner/repo/pull/123 - Current: (uses current directory's repo)
#123
Configuration
Project Aliases (~/.psm/projects.json
)
~/.psm/projects.jsonjson
{
"aliases": {
"omc": {
"repo": "Yeachan-Heo/oh-my-claudecode",
"local": "~/Workspace/oh-my-claudecode",
"default_base": "main"
}
},
"defaults": {
"worktree_root": "~/.psm/worktrees",
"cleanup_after_days": 14
}
}Providers
PSM supports multiple issue tracking providers:
| Provider | CLI Required | Reference Formats | Commands |
|---|---|---|---|
| GitHub (default) | | | review, fix, feature |
| Jira | | | fix, feature |
Jira Configuration
To use Jira, add an alias with and :
jira_projectprovider: "jira"json
{
"aliases": {
"mywork": {
"jira_project": "MYPROJ",
"repo": "mycompany/my-project",
"local": "~/Workspace/my-project",
"default_base": "develop",
"provider": "jira"
}
}
}Important: The field is still required for cloning the git repository. Jira tracks issues, but you work in a git repo.
repoFor non-GitHub repos, use instead:
clone_urljson
{
"aliases": {
"private": {
"jira_project": "PRIV",
"clone_url": "git@gitlab.internal:team/repo.git",
"local": "~/Workspace/repo",
"provider": "jira"
}
}
}Jira Reference Detection
PSM only recognizes format as Jira when is explicitly configured as a in your aliases. This prevents false positives from branch names like .
PROJ-123PROJjira_projectFIX-123Jira Examples
bash
# Fix a Jira issue (MYPROJ must be configured)
psm fix MYPROJ-123
# Fix using alias (recommended)
psm fix mywork#123
# Feature development (works same as GitHub)
psm feature mywork add-webhooks
# Note: 'psm review' is not supported for Jira (no PR concept)
# Use 'psm fix' for Jira issuesJira CLI Setup
Install the Jira CLI:
bash
# macOS
brew install ankitpokhrel/jira-cli/jira-cli
# Linux
# See: https://github.com/ankitpokhrel/jira-cli#installation
# Configure (interactive)
jira initThe Jira CLI handles authentication separately from PSM.
Directory Structure
~/.psm/
├── projects.json # Project aliases
├── sessions.json # Active session registry
└── worktrees/ # Worktree storage
└── <project>/
└── <type>-<id>/Session Naming
| Type | Tmux Session | Worktree Dir |
|---|---|---|
| PR Review | | |
| Issue Fix | | |
| Feature | | |
Implementation Protocol
When the user invokes a PSM command, follow this protocol:
Parse Arguments
Parse to determine:
{{ARGUMENTS}}- Subcommand: review, fix, feature, list, attach, kill, cleanup, status
- Reference: project#number, URL, or session ID
- Options: --branch, --base, --no-claude, --no-tmux, etc.
Subcommand: review <ref>
review <ref>Purpose: Create PR review session
Steps:
-
Resolve reference:bash
# Read project aliases cat ~/.psm/projects.json 2>/dev/null || echo '{"aliases":{}}' # Parse ref format: alias#num, owner/repo#num, or URL # Extract: project_alias, repo (owner/repo), pr_number, local_path -
Fetch PR info:bash
gh pr view <pr_number> --repo <repo> --json number,title,author,headRefName,baseRefName,body,files,url -
Ensure local repo exists:bash
# If local path doesn't exist, clone if [[ ! -d "$local_path" ]]; then git clone "https://github.com/$repo.git" "$local_path" fi -
Create worktree:bash
worktree_path="$HOME/.psm/worktrees/$project_alias/pr-$pr_number" # Fetch PR branch cd "$local_path" git fetch origin "pull/$pr_number/head:pr-$pr_number-review" # Create worktree git worktree add "$worktree_path" "pr-$pr_number-review" -
Create session metadata:bash
cat > "$worktree_path/.psm-session.json" << EOF { "id": "$project_alias:pr-$pr_number", "type": "review", "project": "$project_alias", "ref": "pr-$pr_number", "branch": "<head_branch>", "base": "<base_branch>", "created_at": "$(date -Iseconds)", "tmux_session": "psm:$project_alias:pr-$pr_number", "worktree_path": "$worktree_path", "source_repo": "$local_path", "github": { "pr_number": $pr_number, "pr_title": "<title>", "pr_author": "<author>", "pr_url": "<url>" }, "state": "active" } EOF -
Update sessions registry:bash
# Add to ~/.psm/sessions.json -
Create tmux session:bash
tmux new-session -d -s "psm:$project_alias:pr-$pr_number" -c "$worktree_path" -
Launch Claude Code (unless --no-claude):bash
tmux send-keys -t "psm:$project_alias:pr-$pr_number" "claude" Enter -
Output session info:
Session ready! ID: omc:pr-123 Worktree: ~/.psm/worktrees/omc/pr-123 Tmux: psm:omc:pr-123 To attach: tmux attach -t psm:omc:pr-123
Subcommand: fix <ref>
fix <ref>Purpose: Create issue fix session
Steps:
-
Resolve reference (same as review)
-
Fetch issue info:bash
gh issue view <issue_number> --repo <repo> --json number,title,body,labels,url -
Create feature branch:bash
cd "$local_path" git fetch origin main branch_name="fix/$issue_number-$(echo "$title" | tr ' ' '-' | tr '[:upper:]' '[:lower:]' | head -c 30)" git checkout -b "$branch_name" origin/main -
Create worktree:bash
worktree_path="$HOME/.psm/worktrees/$project_alias/issue-$issue_number" git worktree add "$worktree_path" "$branch_name" -
Create session metadata (similar to review, type="fix")
-
Update registry, create tmux, launch claude (same as review)
Subcommand: feature <project> <name>
feature <project> <name>Purpose: Start feature development
Steps:
-
Resolve project (from alias or path)
-
Create feature branch:bash
cd "$local_path" git fetch origin main branch_name="feature/$feature_name" git checkout -b "$branch_name" origin/main -
Create worktree:bash
worktree_path="$HOME/.psm/worktrees/$project_alias/feat-$feature_name" git worktree add "$worktree_path" "$branch_name" -
Create session, tmux, launch claude (same pattern)
Subcommand: list [project]
list [project]Purpose: List active sessions
Steps:
-
Read sessions registry:bash
cat ~/.psm/sessions.json 2>/dev/null || echo '{"sessions":{}}' -
Check tmux sessions:bash
tmux list-sessions -F "#{session_name}" 2>/dev/null | grep "^psm:" -
Check worktrees:bash
ls -la ~/.psm/worktrees/*/ 2>/dev/null -
Format output:
Active PSM Sessions: ID | Type | Status | Worktree -------------------|---------|----------|--------------------------- omc:pr-123 | review | active | ~/.psm/worktrees/omc/pr-123 omc:issue-42 | fix | detached | ~/.psm/worktrees/omc/issue-42
Subcommand: attach <session>
attach <session>Purpose: Attach to existing session
Steps:
-
Parse session ID:
project:type-number -
Verify session exists:bash
tmux has-session -t "psm:$session_id" 2>/dev/null -
Attach:bash
tmux attach -t "psm:$session_id"
Subcommand: kill <session>
kill <session>Purpose: Kill session and cleanup
Steps:
-
Kill tmux session:bash
tmux kill-session -t "psm:$session_id" 2>/dev/null -
Remove worktree:bash
worktree_path=$(jq -r ".sessions[\"$session_id\"].worktree" ~/.psm/sessions.json) source_repo=$(jq -r ".sessions[\"$session_id\"].source_repo" ~/.psm/sessions.json) cd "$source_repo" git worktree remove "$worktree_path" --force -
Update registry:bash
# Remove from sessions.json
Subcommand: cleanup
cleanupPurpose: Clean up merged PRs and closed issues
Steps:
-
Read all sessions
-
For each PR session, check if merged:bash
gh pr view <pr_number> --repo <repo> --json merged,state -
For each issue session, check if closed:bash
gh issue view <issue_number> --repo <repo> --json closed,state -
Clean up merged/closed sessions:
- Kill tmux session
- Remove worktree
- Update registry
-
Report:
Cleanup complete: Removed: omc:pr-123 (merged) Removed: omc:issue-42 (closed) Kept: omc:feat-auth (active)
Subcommand: status
statusPurpose: Show current session info
Steps:
-
Detect current session from tmux or cwd:bash
tmux display-message -p "#{session_name}" 2>/dev/null # or check if cwd is inside a worktree -
Read session metadata:bash
cat .psm-session.json 2>/dev/null -
Show status:
Current Session: omc:pr-123 Type: review PR: #123 - Add webhook support Branch: feature/webhooks Created: 2 hours ago
Error Handling
| Error | Resolution |
|---|---|
| Worktree exists | Offer: attach, recreate, or abort |
| PR not found | Verify URL/number, check permissions |
| No tmux | Warn and skip session creation |
| No gh CLI | Error with install instructions |
Teleport Command
The command provides a lightweight alternative to full PSM sessions. It creates git worktrees without tmux session management — ideal for quick, isolated development.
omc teleportUsage
bash
# Create worktree for an issue or PR
omc teleport #123
omc teleport owner/repo#123
omc teleport https://github.com/owner/repo/issues/42
# Create worktree for a feature
omc teleport my-feature
# List existing worktrees
omc teleport list
# Remove a worktree
omc teleport remove issue/my-repo-123
omc teleport remove --force feat/my-repo-my-featureOptions
| Flag | Description | Default |
|---|---|---|
| Create worktree (default, kept for compatibility) | |
| Custom worktree root directory | |
| Base branch to create from | |
| Output as JSON | |
Worktree Layout
~/Workspace/omc-worktrees/
├── issue/
│ └── my-repo-123/ # Issue worktrees
├── pr/
│ └── my-repo-456/ # PR review worktrees
└── feat/
└── my-repo-my-feature/ # Feature worktreesPSM vs Teleport
| Feature | PSM | Teleport |
|---|---|---|
| Git worktree | Yes | Yes |
| Tmux session | Yes | No |
| Claude Code launch | Yes | No |
| Session registry | Yes | No |
| Auto-cleanup | Yes | No |
| Project aliases | Yes | No (uses current repo) |
Use PSM for full managed sessions. Use teleport for quick worktree creation.
Requirements
Required:
- - Version control (with worktree support v2.5+)
git - - JSON parsing
jq - - Session management (optional, but recommended)
tmux
Optional (per provider):
- - GitHub CLI (for GitHub workflows)
gh - - Jira CLI (for Jira workflows)
jira
Initialization
On first run, create default config:
bash
mkdir -p ~/.psm/worktrees ~/.psm/logs
# Create default projects.json if not exists
if [[ ! -f ~/.psm/projects.json ]]; then
cat > ~/.psm/projects.json << 'EOF'
{
"aliases": {
"omc": {
"repo": "Yeachan-Heo/oh-my-claudecode",
"local": "~/Workspace/oh-my-claudecode",
"default_base": "main"
}
},
"defaults": {
"worktree_root": "~/.psm/worktrees",
"cleanup_after_days": 14,
"auto_cleanup_merged": true
}
}
EOF
fi
# Create sessions.json if not exists
if [[ ! -f ~/.psm/sessions.json ]]; then
echo '{"version":1,"sessions":{},"stats":{"total_created":0,"total_cleaned":0}}' > ~/.psm/sessions.json
fi