프로젝트 세션 관리자(PSM) 스킬
psm은 이 정식 스킬 진입점의 호환성 별칭입니다.
빠른 시작 (워크트리 우선): tmux/세션 오케스트레이션을 추가하기 전에 격리된 이슈/PR/기능 워크트리를 원할 때
omc teleport로 시작하세요:omc teleport #123 # 이슈/PR을 위한 워크트리 생성 omc teleport my-feature # 기능을 위한 워크트리 생성 omc teleport list # 워크트리 목록 보기자세한 내용은 아래 텔레포트 명령어를 참조하세요.
Claude Code와 함께 git 워크트리와 tmux 세션을 사용하여 격리된 개발 환경을 자동화합니다. 여러 작업, 프로젝트 및 저장소에서 병렬 작업을 가능하게 합니다.
정식 슬래시 명령어: /oh-my-claudecode:project-session-manager (별칭: /oh-my-claudecode:psm).
명령어
| 명령어 | 설명 | 예시 |
|---|---|---|
review <ref> | PR 리뷰 세션 | /psm review omc#123 |
fix <ref> | 이슈 수정 세션 | /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은 여러 이슈 트래킹 제공자를 지원합니다:
| 제공자 | 필요한 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"
}
}
}
중요: repo 필드는 git 저장소를 복제하는 데 여전히 필요합니다. Jira는 이슈를 추적하지만, 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_project로 명시적으로 구성된 PROJ가 있을 때만 Jira로 인식합니다. 이는 FIX-123과 같은 브랜치 이름에서 발생하는 오탐을 방지합니다.
Jira 예시
# Jira 이슈 수정 (MYPROJ가 구성되어 있어야 함)
psm fix MYPROJ-123
# 별칭을 사용하여 수정 (권장)
psm fix mywork#123
# 기능 개발 (GitHub와 동일하게 작동)
psm feature mywork add-webhooks
# 참고: 'psm review'는 Jira에서 지원되지 않습니다 (PR 개념 없음)
# Jira 이슈에는 'psm fix'를 사용하세요
Jira CLI 설정
Jira CLI를 설치하세요:
# macOS
brew install ankitpokhrel/jira-cli/jira-cli
# Linux
# 참조: https://github.com/ankitpokhrel/jira-cli#installation
# 구성 (대화형)
jira init
Jira CLI는 PSM과 별도로 인증을 처리합니다.
디렉토리 구조
~/.psm/
├── projects.json # 프로젝트 별칭
├── sessions.json # 활성 세션 레지스트리
└── worktrees/ # 워크트리 저장소
└── <project>/
└── <type>-<id>/
세션 이름 지정
공개 세션 ID (콜론 형식, 예: omc:pr-123)는 sessions.json에 저장되고 psm attach/psm kill과 함께 사용되는 사람용 식별자입니다. tmux는 :와 .를 session:window.pane 대상 구문용으로 예약하고 자동으로 다시 작성하므로, 실제 tmux 세션 이름은 해당 문자가 _가 되는 tmux-안전 형식을 사용합니다 (이슈 #3528). PSM은 모든 tmux 경계에서 공개 ID를 tmux-안전 이름으로 변환합니다. tmux-안전 이름으로 직접 연결하세요.
| 유형 | 공개 ID (psm attach/kill) | Tmux 세션 (tmux attach -t) | 워크트리 디렉토리 |
|---|---|---|---|
| PR 리뷰 | omc:pr-123 | psm_omc_pr-123 | ~/.psm/worktrees/omc/pr-123 |
| 이슈 수정 | 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 리뷰 세션 생성
단계:
-
참조 확인:
# 프로젝트 별칭 읽기 cat ~/.psm/projects.json 2>/dev/null || echo '{"aliases":{}}' # 참조 형식 구문 분석: alias#num, owner/repo#num, 또는 URL # 추출: 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 [[ ! -d "$local_path" ]]; then git clone "https://github.com/$repo.git" "$local_path" fi -
워크트리 생성:
worktree_path="$HOME/.psm/worktrees/$project_alias/pr-$pr_number" # PR 브랜치 가져오기 cd "$local_path" git fetch origin "pull/$pr_number/head:pr-$pr_number-review" # 워크트리 생성 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 -
세션 레지스트리 업데이트:
# ~/.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는 "이 디렉토리를 신뢰하시겠습니까?" 프롬프트와 # 반복적인 도구 승인 프롬프트가 세션을 지연시키는 것을 방지합니다 (이슈 #2508). tmux send-keys -t "psm_${project_alias}_pr-$pr_number" "claude --dangerously-skip-permissions" Enter # claude가 부팅된 후 (PSM_CLAUDE_STARTUP_DELAY, 기본 5초), 작업을 전달합니다. # -l (리터럴)을 사용하여 특수 문자가 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>
목적: 이슈 수정 세션 생성
단계:
-
참조 확인 (review와 동일)
-
이슈 정보 가져오기:
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와 동일하지만 이슈 컨텍스트를 초기 작업 프롬프트로 전달:
tmux send-keys -t "psm_${project_alias}_issue-$issue_number" "claude --dangerously-skip-permissions" Enter # claude가 부팅된 후, 작업 전달 (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 # 공개 ID를 tmux-안전 이름으로 변환 -
연결:
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 -
레지스트리 업데이트:
# sessions.json에서 제거
서브커맨드: cleanup
목적: 병합된 PR 및 종료된 이슈 정리
단계:
-
모든 세션 읽기
-
각 PR 세션에 대해 병합 여부 확인:
gh pr view <pr_number> --repo <repo> --json merged,state -
각 이슈 세션에 대해 종료 여부 확인:
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 # 또는 cwd가 워크트리 내부에 있는지 확인 -
세션 메타데이터 읽기:
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 없음 | 설치 안내와 함께 오류 메시지 출력 |
텔레포트 명령어
omc teleport 명령어는 전체 PSM 세션에 대한 가벼운 대안을 제공합니다. tmux 세션 관리 없이 git 워크트리를 생성합니다. 빠르고 격리된 개발에 이상적입니다.
사용법
# 이슈 또는 PR을 위한 워크트리 생성
omc teleport #123
omc teleport owner/repo#123
omc teleport https://github.com/owner/repo/issues/42
# 기능을 위한 워크트리 생성
omc teleport my-feature
# 기존 워크트리 목록
omc teleport list
# 워크트리 제거
omc teleport remove issue/my-repo-123
omc teleport remove --force feat/my-repo-my-feature
옵션
| 플래그 | 설명 | 기본값 |
|---|---|---|
--worktree-root <path> | 워크트리 루트 디렉토리 | ~/.psm/worktrees |
--base <branch> | 기준 브랜치 | 프로젝트 구성 참조 |
--no-fetch | 원격에서 가져오지 않음 | 가져오기 수행 |
-f, --force | 제거 시 강제 실행 | false |
동작
omc teleport <reference>가 호출되면:
- 참조 확인 및 프로젝트 별칭 확인 (
~/.psm/projects.json) - 필요한 경우 로컬 저장소 복제
- 기준 브랜치 가져오기
- 적절한 브랜치 생성: 이슈/PR의 경우
issue/<name>-<num>또는pr-<num>, 기능의 경우feat/<name> ~/.psm/worktrees/<project>/<type>-<name>/에 워크트리 추가- 워크트리로
cd
전역 옵션
| 옵션 | 설명 | 기본값 |
|---|---|---|
--no-tmux | tmux 세션 생성 안 함 | tmux 사용 |
--no-claude | Claude Code 자동 실행 안 함 | claude 실행 |
--base <branch> | 기준 브랜치 지정 | 프로젝트 기본값 |
--branch <name> | 작업 브랜치 이름 지정 | 자동 생성됨 |
PSM_CLAUDE_STARTUP_DELAY | claude 부팅 대기 시간(초) | 5 |
환경 변수
| 변수 | 설명 | 기본값 |
|---|---|---|
PSM_CLAUDE_STARTUP_DELAY | claude 실행 후 작업 명령 전 대기 시간(초) | 5 |
PSM_DANGEROUSLY_SKIP_PERM | --dangerously-skip-permissions 플래그 사용 안 함 | 1 (사용) |
PSM_TMUX_ENABLED | tmux 세션 생성 전역 활성화/비활성화 | true |