Communitygithub.com

프로젝트 세션 관리자 (PSM)

워크트리 우선 개발 환경 관리자로, 이슈, PR, 기능 작업을 위한 격리된 환경을 제공하며 선택적으로 tmux 세션을 지원합니다.

프로젝트 세션 관리자 (PSM)란 무엇인가요?

프로젝트 세션 관리자(PSM)는 개발자가 여러 작업, 프로젝트 및 저장소에서 병렬로 작업할 수 있도록 git 워크트리와 tmux 세션을 사용하여 격리된 개발 환경을 생성하고 관리하는 AI 에이전트 기술입니다. 'omc teleport' 명령어를 통해 빠르게 이슈/PR/기능 별 워크트리를 생성할 수 있으며, 'review', 'fix', 'feature' 등의 서브커맨드로 전체 세션을 구성할 수 있습니다. GitHub와 Jira 이슈 트래킹을 지원하며, 프로젝트 별칭 설정을 통해 복잡한 저장소 참조를 단순화합니다. PSM은 '--dangerously-skip-permissions' 플래그로 Claude Code를 tmux 세션 내에서 자동 실행하여 반복적인 권한 승인을 건너뛰고 즉시 작업을 시작할 수 있도록 합니다. 주요 기능으로 PR 리뷰 세션, 이슈 수정 세션, 기능 개발 세션 생성 및 관리, 세션 목록 조회, 연결, 종료, 정리 등이 포함되어 있어 개발 워크플로우의 효율성을 크게 향상시킵니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Yeachan-Heo/oh-my-claudecode/tree/main/skills/project-session-manager

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

프로젝트 세션 관리자(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 (기본)ghowner/repo#123, alias#123, GitHub URLreview, fix, feature
JirajiraPROJ-123 (PROJ가 구성된 경우), alias#123fix, 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-123psm_omc_pr-123~/.psm/worktrees/omc/pr-123
이슈 수정omc:issue-42psm_omc_issue-42~/.psm/worktrees/omc/issue-42
기능omc:feat-authpsm_omc_feat-auth~/.psm/worktrees/omc/feat-auth

구현 프로토콜

사용자가 PSM 명령어를 호출하면 다음 프로토콜을 따르세요:

인수 구문 분석

{{ARGUMENTS}}를 구문 분석하여 다음을 결정합니다:

  1. 서브커맨드: review, fix, feature, list, attach, kill, cleanup, status
  2. 참조: project#number, URL 또는 세션 ID
  3. 옵션: --branch, --base, --no-claude, --no-tmux 등

서브커맨드: review <ref>

목적: PR 리뷰 세션 생성

단계:

  1. 참조 확인:

    # 프로젝트 별칭 읽기
    cat ~/.psm/projects.json 2>/dev/null || echo '{"aliases":{}}'
    
    # 참조 형식 구문 분석: alias#num, owner/repo#num, 또는 URL
    # 추출: project_alias, repo (owner/repo), pr_number, local_path
    
  2. PR 정보 가져오기:

    gh pr view <pr_number> --repo <repo> --json number,title,author,headRefName,baseRefName,body,files,url
    
  3. 로컬 저장소 확인:

    # 로컬 경로가 없으면 복제
    if [[ ! -d "$local_path" ]]; then
      git clone "https://github.com/$repo.git" "$local_path"
    fi
    
  4. 워크트리 생성:

    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"
    
  5. 세션 메타데이터 생성:

    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
    
  6. 세션 레지스트리 업데이트:

    # ~/.psm/sessions.json에 추가
    
  7. tmux 세션 생성 (tmux-안전 이름; :/.는 _로 변환됨):

    tmux new-session -d -s "psm_${project_alias}_pr-$pr_number" -c "$worktree_path"
    
  8. 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
    
  9. 세션 정보 출력:

    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>

목적: 이슈 수정 세션 생성

단계:

  1. 참조 확인 (review와 동일)

  2. 이슈 정보 가져오기:

    gh issue view <issue_number> --repo <repo> --json number,title,body,labels,url
    
  3. 기능 브랜치 생성:

    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
    
  4. 워크트리 생성:

    worktree_path="$HOME/.psm/worktrees/$project_alias/issue-$issue_number"
    git worktree add "$worktree_path" "$branch_name"
    
  5. 세션 메타데이터 생성 (review와 유사, type="fix")

  6. 레지스트리 업데이트, 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>

목적: 기능 개발 시작

단계:

  1. 프로젝트 확인 (별칭 또는 경로에서)

  2. 기능 브랜치 생성:

    cd "$local_path"
    git fetch origin main
    branch_name="feature/$feature_name"
    git checkout -b "$branch_name" origin/main
    
  3. 워크트리 생성:

    worktree_path="$HOME/.psm/worktrees/$project_alias/feat-$feature_name"
    git worktree add "$worktree_path" "$branch_name"
    
  4. 세션, 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]

목적: 활성 세션 목록

단계:

  1. 세션 레지스트리 읽기:

    cat ~/.psm/sessions.json 2>/dev/null || echo '{"sessions":{}}'
    
  2. tmux 세션 확인:

    tmux list-sessions -F "#{session_name}" 2>/dev/null | grep "^psm_"
    
  3. 워크트리 확인:

    ls -la ~/.psm/worktrees/*/ 2>/dev/null
    
  4. 출력 형식:

    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>

목적: 기존 세션에 연결

단계:

  1. 세션 ID 구문 분석: project:type-number

  2. 세션 존재 확인:

    tmux has-session -t "psm_${session_id//[.:]/_}" 2>/dev/null   # 공개 ID를 tmux-안전 이름으로 변환
    
  3. 연결:

    tmux attach -t "psm_${session_id//[.:]/_}"
    

서브커맨드: kill <session>

목적: 세션 종료 및 정리

단계:

  1. tmux 세션 종료:

    tmux kill-session -t "psm_${session_id//[.:]/_}" 2>/dev/null
    
  2. 워크트리 제거:

    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
    
  3. 레지스트리 업데이트:

    # sessions.json에서 제거
    

서브커맨드: cleanup

목적: 병합된 PR 및 종료된 이슈 정리

단계:

  1. 모든 세션 읽기

  2. 각 PR 세션에 대해 병합 여부 확인:

    gh pr view <pr_number> --repo <repo> --json merged,state
    
  3. 각 이슈 세션에 대해 종료 여부 확인:

    gh issue view <issue_number> --repo <repo> --json closed,state
    
  4. 병합/종료된 세션 정리:

    • tmux 세션 종료
    • 워크트리 제거
    • 레지스트리 업데이트
  5. 보고:

    Cleanup complete:
      Removed: omc:pr-123 (merged)
      Removed: omc:issue-42 (closed)
      Kept: omc:feat-auth (active)
    

서브커맨드: status

목적: 현재 세션 정보 표시

단계:

  1. tmux 또는 cwd에서 현재 세션 감지:

    tmux display-message -p "#{session_name}" 2>/dev/null
    # 또는 cwd가 워크트리 내부에 있는지 확인
    
  2. 세션 메타데이터 읽기:

    cat .psm-session.json 2>/dev/null
    
  3. 상태 표시:

    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>가 호출되면:

  1. 참조 확인 및 프로젝트 별칭 확인 (~/.psm/projects.json)
  2. 필요한 경우 로컬 저장소 복제
  3. 기준 브랜치 가져오기
  4. 적절한 브랜치 생성: 이슈/PR의 경우 issue/<name>-<num> 또는 pr-<num>, 기능의 경우 feat/<name>
  5. ~/.psm/worktrees/<project>/<type>-<name>/에 워크트리 추가
  6. 워크트리로 cd

전역 옵션

옵션설명기본값
--no-tmuxtmux 세션 생성 안 함tmux 사용
--no-claudeClaude Code 자동 실행 안 함claude 실행
--base <branch>기준 브랜치 지정프로젝트 기본값
--branch <name>작업 브랜치 이름 지정자동 생성됨
PSM_CLAUDE_STARTUP_DELAYclaude 부팅 대기 시간(초)5

환경 변수

변수설명기본값
PSM_CLAUDE_STARTUP_DELAYclaude 실행 후 작업 명령 전 대기 시간(초)5
PSM_DANGEROUSLY_SKIP_PERM--dangerously-skip-permissions 플래그 사용 안 함1 (사용)
PSM_TMUX_ENABLEDtmux 세션 생성 전역 활성화/비활성화true

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

agent-doc-discipline

Writing-time discipline for documents agents consume (the five surfaces, specs, tickets, .omc/skills/) — every rule checkable and carrying a why, steps before reference, one meaning in one home, no restating what the environment already says. Mandatory at drydock seed generation and the launch C5 sediment pass; opt-in for any other agent-facing doc edit. The companion of minimal-code-discipline: that one disciplines code, this one disciplines papers.

ai-slop-cleaner

Clean AI-generated code slop with a regression-safe, deletion-first workflow and optional reviewer-only mode

ask

Process-first advisor routing for Claude, Codex, Gemini, Antigravity, Grok, or Cursor via `omc ask`, with artifact capture and no raw CLI assembly

ask-navigator

Shipyard

autopilot

Full autonomous execution from idea to working code

autoresearch

Stateful single-mission improvement loop with strict evaluator contract, markdown decision logs, and max-runtime stop behavior

cancel

Cancel any active OMC mode (autopilot, ralph, ultragoal, swarm, ultrapilot, pipeline, team) and clean up retired legacy state

configure-notifications

Configure notification integrations (Telegram, Discord, Slack) via natural language

debug

Diagnose the current OMC session or repo state using logs, traces, state, and focused reproduction

deepinit

Deep codebase initialization with hierarchical AGENTS.md documentation

deep-interview

Socratic deep interview with mathematical ambiguity gating before explicit execution approval

drydock

Lay the keel of the shipyard harness in any repo — the 4-pillar shared environment (Context, Rules, Tools, Standards) across 5 surfaces (CLAUDE.md, skills, design-system, mcp/cli, shared context) so that every human and agent inherits the same design language and anyone can ship. Run once per repo; re-run with --check to audit drift.

execute

Carry an approved task through to working, verified code

external-context

Invoke parallel document-specialist agents for external web searches and documentation lookup

graph

Deterministic orchestration graph runtime - declarative DAG pipelines with journal-based crash recovery

harbor

Harbor intake for external work — the captain only handles unresolved decisions. Sweeps incoming issues and PRs, verifies every claim before disposition, reuses every decision already made, and hands the maintainer a docket whose pending items each carry one question with options, recommendation, impact and evidence. Agent-autonomous for facts and for actions covered by standing authorization; signed for every new judgment. Never merges.

hud

Configure HUD display options (layout, presets, display elements)

launch

Shipyard

loft

Loft the shape before cutting steel — answer a design question that prose cannot settle by building a throwaway artifact: a pure logic module in a clickable shell, or structurally different UI variants behind one route. The captain reacts to the artifact; the answer folds into the decision; the artifact never docks. Use when a design question stalls in words, when a navigator map carries a loft ticket, or when a spec discussion reaches

minimal-code-discipline

YAGNI-ladder coding discipline for writing changes — existence-first, reuse before writing, dependency ladder, shortest correct diff, with non-negotiables that must never be minimized away

관련 스킬