project-session-manager について
Project Session Manager(PSM)は、git worktreeとtmuxで隔離された開発セッションを作るスキルです。レビュー、課題修正、機能開発に対応し、GitHubと設定済みのJira参照のほか、`omc teleport`によるworktreeのみの作成も扱います。
主な機能
- 01レビュー・修正・機能開発用worktreeの作成
- 02tmuxによるセッション管理
- 03セッションの一覧・接続・終了・整理
- 04GitHubと設定済みJira参照の解決
- 05`omc teleport`によるworktree作成
活用シーン
- 01隔離されたworktreeでプルリクエストをレビュー
- 02メインのチェックアウトを変えずに課題を修正
- 03独立したセッションで機能開発を開始
- 04開発セッションの一覧表示や整理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yeachan-heo/ oh-my-claudecode --skill project-session-managerインストール後、Claude Code で/project-session-managerを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
psm.shlib/config.shparse.shsession.shtmux.shworktree.shlib/providers/azure-devops.shbitbucket.shgitea.shgithub.shgitlab.shinterface.shjira.shtemplates/feature.mdissue-fix.mdpr-review.mdprojects.jsontests/test-jira-provider.shtest-psm-prompt-injection.sh詳細
プロジェクトセッションマネージャー(PSM)スキル
psm は、この正式なスキルのエントリーポイントに対する互換性エイリアスです。
クイックスタート(worktree 優先): 分離された issue/PR/機能用の worktree を作成してから tmux/セッションのオーケストレーションを追加する場合は、まず
omc teleportを実行してください。omc teleport #123 # issue/PR 用の worktree を作成 omc teleport my-feature # 機能用の worktree を作成 omc teleport list # worktree を一覧表示詳細については、以下のTeleport コマンドを参照してください。
git worktree と tmux セッションを Claude Code と組み合わせて使用し、分離された開発環境を自動化します。複数のタスク、プロジェクト、リポジトリを並行して作業できます。
正式なスラッシュコマンド:/oh-my-claudecode:project-session-manager(エイリアス:/oh-my-claudecode:psm)。
コマンド
| コマンド | 説明 | 例 |
|---|---|---|
review <ref> | PR レビューセッション | /psm review omc#123 |
fix <ref> | issue 修正セッション | /psm fix omc#42 |
feature <proj> <name> | 機能開発 | /psm feature omc add-webhooks |
list [project] | アクティブなセッションを一覧表示 | /psm list |
attach <session> | セッションに接続 | /psm attach omc:pr-123 |
kill <session> | セッションを終了 | /psm kill omc:pr-123 |
cleanup | マージ済み/クローズ済みの項目をクリーンアップ | /psm cleanup |
status | 現在のセッション情報 | /psm status |
プロジェクト参照
サポートされる形式:
- エイリアス:
omc#123(~/.psm/projects.jsonが必要) - フル形式:
owner/repo#123 - URL:
https://github.com/owner/repo/pull/123 - 現在のリポジトリ:
#123(現在のディレクトリのリポジトリを使用)
設定
プロジェクトエイリアス(~/.psm/projects.json)
{
"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
}
}
プロバイダー
PSM は複数の issue トラッキングプロバイダーをサポートしています。
| プロバイダー | 必要な CLI | 参照形式 | コマンド |
|---|---|---|---|
| GitHub(デフォルト) | gh | owner/repo#123、alias#123、GitHub URL | review、fix、feature |
| Jira | jira | PROJ-123(PROJ が設定されている場合)、alias#123 | fix、feature |
Jira の設定
Jira を使用するには、jira_project と provider: "jira" を含むエイリアスを追加します。
{
"aliases": {
"mywork": {
"jira_project": "MYPROJ",
"repo": "mycompany/my-project",
"local": "~/Workspace/my-project",
"default_base": "develop",
"provider": "jira"
}
}
}
重要: git リポジトリをクローンするには、引き続き repo フィールドが必要です。Jira で issue を追跡しますが、作業は git リポジトリで行います。
GitHub 以外のリポジトリでは、代わりに clone_url を使用してください。
{
"aliases": {
"private": {
"jira_project": "PRIV",
"clone_url": "[email protected]:team/repo.git",
"local": "~/Workspace/repo",
"provider": "jira"
}
}
}
Jira 参照の検出
PSM が PROJ-123 形式を Jira として認識するのは、PROJ がエイリアス内で jira_project として明示的に設定されている場合に限られます。これにより、FIX-123 のようなブランチ名を誤認することを防ぎます。
Jira の例
# 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 issues
Jira CLI のセットアップ
Jira CLI をインストールします。
# macOS
brew install ankitpokhrel/jira-cli/jira-cli
# Linux
# See: https://github.com/ankitpokhrel/jira-cli#installation
# Configure (interactive)
jira init
Jira CLI の認証は PSM とは別に処理されます。
ディレクトリ構成
~/.psm/
├── projects.json # Project aliases
├── sessions.json # Active session registry
└── worktrees/ # Worktree storage
└── <project>/
└── <type>-<id>/
セッション名
公開セッション ID(omc:pr-123 のようなコロン形式)は、人が扱う識別子です。sessions.json に保存され、psm attach/psm kill で使用されます。tmux は : と . を session:window.pane ターゲット構文用に予約しており、これらを黙って書き換えるため、実際の tmux セッション名では tmux で安全に使用できる形式を用い、これらの文字を _ に置き換えます(issue #3528)。PSM は tmux とのやり取りのたびに公開 ID を tmux で安全に使用できる名前へ変換します。直接接続する場合は、tmux で安全に使用できる名前を指定してください。
| 種類 | 公開 ID(psm attach/kill) | Tmux セッション(tmux attach -t) | Worktree ディレクトリ |
|---|---|---|---|
| PR レビュー | omc:pr-123 | psm_omc_pr-123 | ~/.psm/worktrees/omc/pr-123 |
| Issue 修正 | omc:issue-42 | psm_omc_issue-42 | ~/.psm/worktrees/omc/issue-42 |
| 機能 | omc:feat-auth | psm_omc_feat-auth | ~/.psm/worktrees/omc/feat-auth |
実装プロトコル
ユーザーが PSM コマンドを実行したら、このプロトコルに従います。
引数を解析する
{{ARGUMENTS}} を解析し、次の項目を特定します。
- サブコマンド:review、fix、feature、list、attach、kill、cleanup、status
- 参照:project#number、URL、またはセッション ID
- オプション:--branch、--base、--no-claude、--no-tmux など
サブコマンド:review <ref>
目的:PR レビューセッションを作成します
手順:
-
参照を解決します:
# 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 -
PR 情報を取得します:
gh pr view <pr_number> --repo <repo> --json number,title,author,headRefName,baseRefName,body,files,url -
ローカルリポジトリが存在することを確認します:
# If local path doesn't exist, clone if [[ ! -d "$local_path" ]]; then git clone "https://github.com/$repo.git" "$local_path" fi -
ワークツリーを作成します:
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" -
セッションメタデータを作成します:
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 -
セッションレジストリを更新します:
# Add to ~/.psm/sessions.json -
tmux セッションを作成します(tmux で安全な名前を使用します。
:/.は_に変換されます):tmux new-session -d -s "psm_${project_alias}_pr-$pr_number" -c "$worktree_path" -
Claude Code を起動します(--no-claude が指定されていない場合):
# --dangerously-skip-permissions prevents the "Do you trust this directory?" prompt # and repeated tool-approval prompts from stalling the session (issue #2508). tmux send-keys -t "psm_${project_alias}_pr-$pr_number" "claude --dangerously-skip-permissions" Enter # After claude boots (PSM_CLAUDE_STARTUP_DELAY, default 5s), deliver the task. # Use -l (literal) so special characters are not misinterpreted by tmux. sleep "${PSM_CLAUDE_STARTUP_DELAY:-5}" tmux send-keys -t "psm_${project_alias}_pr-$pr_number" -l \ "Review PR #$pr_number: \"$pr_title\" by @$pr_author ($head_branch → $base_branch). URL: $pr_url." Enter -
セッション情報を出力します:
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 (or: psm attach omc:pr-123)
サブコマンド:fix <ref>
目的:Issue 修正セッションを作成します
手順:
-
参照を解決します(review と同じです)
-
Issue 情報を取得します:
gh issue view <issue_number> --repo <repo> --json number,title,body,labels,url -
フィーチャーブランチを作成します:
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 -
ワークツリーを作成します:
worktree_path="$HOME/.psm/worktrees/$project_alias/issue-$issue_number" git worktree add "$worktree_path" "$branch_name" -
セッションメタデータを作成します(review と同様に、type="fix" を指定します)
-
レジストリを更新し、tmux を作成して Claude を起動します: review と同様ですが、Issue のコンテキストを初期タスクのプロンプトとして渡します:
tmux send-keys -t "psm_${project_alias}_issue-$issue_number" "claude --dangerously-skip-permissions" Enter # After claude boots, deliver the task (see PSM_CLAUDE_STARTUP_DELAY): tmux send-keys -t "psm_${project_alias}_issue-$issue_number" -l \ "Fix issue #$issue_number: \"$issue_title\". URL: $issue_url. Branch: $branch_name." Enter
サブコマンド:feature <project> <name>
目的:フィーチャー開発を開始します
手順:
-
プロジェクトを解決します(エイリアスまたはパスから)
-
フィーチャーブランチを作成します:
cd "$local_path" git fetch origin main branch_name="feature/$feature_name" git checkout -b "$branch_name" origin/main -
ワークツリーを作成します:
worktree_path="$HOME/.psm/worktrees/$project_alias/feat-$feature_name" git worktree add "$worktree_path" "$branch_name" -
フィーチャーのコンテキストを初期プロンプトとして使用して、セッションと tmux を作成し、Claude を起動します:
tmux send-keys -t "psm_${project_alias}_feat-$feature_name" "claude --dangerously-skip-permissions" Enter tmux send-keys -t "psm_${project_alias}_feat-$feature_name" -l \ "Implement feature \"$feature_name\" for project $project. Branch: $branch_name." Enter
サブコマンド:list [project]
目的:アクティブなセッションを一覧表示します
手順:
-
セッションレジストリを読み込みます:
cat ~/.psm/sessions.json 2>/dev/null || echo '{"sessions":{}}' -
tmux セッションを確認します:
tmux list-sessions -F "#{session_name}" 2>/dev/null | grep "^psm_" -
ワークツリーを確認します:
ls -la ~/.psm/worktrees/*/ 2>/dev/null -
出力を整形します:
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
サブコマンド:attach <session>
目的:既存のセッションに接続します
手順:
-
セッション ID を解析します:
project:type-number -
セッションが存在することを確認します:
tmux has-session -t "psm_${session_id//[.:]/_}" 2>/dev/null # translate public id to tmux-safe name -
接続します:
tmux attach -t "psm_${session_id//[.:]/_}"
サブコマンド:kill <session>
目的:セッションを終了してクリーンアップします
手順:
-
tmux セッションを終了します:
tmux kill-session -t "psm_${session_id//[.:]/_}" 2>/dev/null -
ワークツリーを削除します:
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 -
レジストリを更新します:
# Remove from sessions.json
サブコマンド:cleanup
目的:マージ済み PR とクローズ済み Issue をクリーンアップします
手順:
-
すべてのセッションを読み込みます
-
各 PR セッションについて、マージ済みかどうかを確認します:
gh pr view <pr_number> --repo <repo> --json merged,state -
各 Issue セッションについて、クローズ済みかどうかを確認します:
gh issue view <issue_number> --repo <repo> --json closed,state -
マージ済み/クローズ済みのセッションをクリーンアップします:
- tmux セッションを終了します
- ワークツリーを削除します
- レジストリを更新します
-
結果を報告します:
Cleanup complete: Removed: omc:pr-123 (merged) Removed: omc:issue-42 (closed) Kept: omc:feat-auth (active)
サブコマンド:status
目的:現在のセッション情報を表示します
手順:
-
tmux または cwd から現在のセッションを検出します:
tmux display-message -p "#{session_name}" 2>/dev/null # or check if cwd is inside a worktree -
セッションメタデータを読み込みます:
cat .psm-session.json 2>/dev/null -
ステータスを表示します:
Current Session: omc:pr-123 Type: review PR: #123 - Add webhook support Branch: feature/webhooks Created: 2 hours ago
エラー処理
| エラー | 解決方法 |
|---|---|
| ワークツリーが存在します | 接続、再作成、または中止を選択します |
| PR が見つかりません | URL/番号を確認し、権限を確認します |
| tmux がありません | 警告を表示し、セッションの作成をスキップします |
| gh CLI がありません | インストール手順を示すエラーを表示します |
Teleport コマンド
omc teleport コマンドは、完全な PSM セッションに代わる軽量な方法を提供します。tmux セッション管理を行わずに git ワークツリーを作成するため、手早く分離された開発を行うのに適しています。
使用方法
# 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-feature
オプション
| フラグ | 説明 | デフォルト |
|---|---|---|
--worktree | ワークツリーを作成します(デフォルト。互換性のために保持) | true |
--path <path> | カスタムのワークツリーのルートディレクトリ | ~/Workspace/omc-worktrees/ |
--base <branch> | 作成元のベースブランチ | main |
--json | JSON 形式で出力します | false |
ワークツリーのレイアウト
~/Workspace/omc-worktrees/
├── issue/
│ └── my-repo-123/ # Issue worktrees
├── pr/
│ └── my-repo-456/ # PR review worktrees
└── feat/
└── my-repo-my-feature/ # Feature worktrees
PSM と Teleport の比較
| 機能 | PSM | Teleport |
|---|---|---|
| Git ワークツリー | はい | はい |
| Tmux セッション | はい | いいえ |
| Claude Code の起動 | はい | いいえ |
| セッションレジストリ | はい | いいえ |
| 自動クリーンアップ | はい | いいえ |
| プロジェクトエイリアス | はい | いいえ(現在のリポジトリを使用) |
完全に管理されたセッションには PSM を使用してください。手早くワークツリーを作成するには teleport を使用してください。
要件
必須:
git- バージョン管理(worktree サポート v2.5 以降)jq- JSON 解析tmux- セッション管理(任意ですが、推奨)
任意(プロバイダーごと):
gh- GitHub CLI(GitHub ワークフロー用)jira- Jira CLI(Jira ワークフロー用)
初期化
初回実行時に、デフォルト設定を作成します。
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