名称: psm 描述: 项目会话管理器 — 使用git worktrees和tmux的隔离开发环境 参数提示: “review <ref> | fix <ref> | feature <name> | list | attach <session> | kill <session> | cleanup | status” 别名: [session, worktree-session] 禁用模型调用: true
项目会话管理器 (/psm)
使用git worktrees和tmux管理隔离的开发会话。
所有PSM状态存储在~/.maestro-psm/下。
用户命令
$ARGUMENTS
支持的子命令
| 模式 | 操作 |
|---|---|
review <ref> |
创建PR审查会话 |
fix <ref> |
创建问题修复会话 |
feature <name> |
从main创建功能会话 |
list |
列出状态和tmux中的会话 |
attach <session> |
显示会话的附加命令 |
kill <session> |
杀死tmux + 移除工作树 + 删除状态 |
cleanup |
自动清理已合并的PR / 已关闭的问题会话 |
status |
显示当前会话上下文 |
初始化(始终首先运行)
STATE_DIR="$HOME/.maestro-psm"
WORKTREE_ROOT="$STATE_DIR/worktrees"
LOG_DIR="$STATE_DIR/logs"
SESSIONS_FILE="$STATE_DIR/sessions.json"
mkdir -p "$WORKTREE_ROOT" "$LOG_DIR"
if [[ ! -f "$SESSIONS_FILE" ]]; then
cat > "$SESSIONS_FILE" <<'EOF'
{"version": 1, "sessions": {}}
EOF
fi
规则:
- 使用
$HOME(扩展为~)进行文件系统操作。 - 在写入文件或创建工作树之前创建父目录。
- 当先决条件缺失时,快速失败并显示清晰错误信息。
共享解析规则
GitHub引用格式
为review和fix支持以下形式:
#123→ 当前仓库owner/repo#123→ 显式仓库https://github.com/owner/repo/pull/123→ PR URLhttps://github.com/owner/repo/issues/123→ 问题URL
解析结果
将解析数据规范化为:
repo:owner/reponumber: 数字引用(123)kind:pull或issue
验证
review <ref>仅接受PR格式(#、owner/repo#或/pull/)。fix <ref>仅接受问题格式(#、owner/repo#或/issues/)。- 如果使用
#123,则使用gh repo view --json nameWithOwner从当前目录解析仓库。 - 如果解析失败,停止并显示接受的示例。
共享会话模型
在~/.maestro-psm/sessions.json中使用此一致会话元数据模型:
{
"version": 1,
"sessions": {
"project:pr-123": {
"id": "project:pr-123",
"type": "review",
"repo": "owner/repo",
"number": 123,
"ref": "#123",
"title": "添加webhook支持",
"branch": "pr-123-review",
"base": "main",
"worktree": "/Users/me/.maestro-psm/worktrees/project/pr-123",
"tmux": "maestro:project:pr-123",
"createdAt": "2026-02-09T00:00:00Z",
"url": "https://github.com/owner/repo/pull/123"
}
}
}
会话命名:
- 会话ID:
<alias>:<ref-id> - Tmux会话:
maestro:<session-id> - 别名默认值:仓库名称(来自
owner/repo)
子命令工作流
1) review <ref>
目标:从PR头部分支创建PR审查工作区。
- 将
<ref>解析为repo+pr_number。 - 获取PR元数据:
gh pr view <num> --repo <repo> --json number,title,headRefName,baseRefName,url - 解析本地仓库根目录:
- 当远程匹配
<repo>时,优先当前git仓库。 - 否则使用专用本地克隆,位于
~/.maestro-psm/repos/<owner>__<repo>下。
- 当远程匹配
- 创建/更新审查分支 + 工作树:
其中git -C <repo_root> fetch origin pull/<num>/head:pr-<num>-review git -C <repo_root> worktree add <worktree_path> pr-<num>-reviewworktree_path=~/.maestro-psm/worktrees/<alias>/pr-<num>。 - 在后台创建tmux会话:
tmux new-session -d -s maestro:<alias>:pr-<num> -c <worktree_path> - 使用会话元数据更新
~/.maestro-psm/sessions.json。 - 打印会话准备就绪报告,包括附加命令。
2) fix <ref>
目标:从main创建问题修复分支,加上隔离工作树 + tmux。
- 将
<ref>解析为repo+issue_number。 - 通过
gh issue view获取问题元数据。 - 从
main创建分支:
其中git -C <repo_root> fetch origin main git -C <repo_root> worktree add -b fix/<num>-<slug> <worktree_path> origin/mainworktree_path=~/.maestro-psm/worktrees/<alias>/issue-<num>。 - 创建tmux会话:
tmux new-session -d -s maestro:<alias>:issue-<num> -c <worktree_path> - 更新sessions.json。
- 打印会话准备就绪报告,包括附加命令。
3) feature <name>
目标:在隔离会话中从main创建功能分支。
- 解析当前仓库(
gh repo view --json nameWithOwner)。 - 将
<name>转换为分支安全命名(slugify)。 - 创建分支 + 工作树:
其中git -C <repo_root> fetch origin main git -C <repo_root> worktree add -b feature/<slug> <worktree_path> origin/mainworktree_path=~/.maestro-psm/worktrees/<alias>/feat-<slug>。 - 创建tmux会话:
tmux new-session -d -s maestro:<alias>:feat-<slug> -c <worktree_path> - 更新sessions.json。
- 打印会话准备就绪报告,包括附加命令。
4) list
目标:显示持久化会话以及tmux是否存活。
- 读取
~/.maestro-psm/sessions.json。 - 获取存活tmux会话:
tmux list-sessions -F "#{session_name}" 2>/dev/null - 交叉参考每个会话的
tmux值。 - 显示表格:
- 会话ID
- 类型
- 引用
- 分支
- 状态(如果tmux存在则为
active,否则为dead)
5) attach <session>
目标:提供确切的附加命令。
- 构建tmux名称:
maestro:<session>。 - 验证会话是否存在:
tmux has-session -t maestro:<session> - 如果找到,打印:
tmux attach -t maestro:<session> - 如果缺失,显示清晰错误并建议
/psm list。
6) kill <session>
目标:完全移除一个会话。
- 从sessions.json解析会话记录。
- 杀死tmux会话:
tmux kill-session -t maestro:<session> - 移除工作树:
git -C <repo_root> worktree remove <worktree_path> --force - 从sessions.json删除会话。
- 报告移除的tmux/工作树/状态条目。
7) cleanup
目标:自动清理已完成的审查/修复会话。
对于sessions.json中的每个会话:
-
如果
type=review,检查合并状态:gh pr view <num> --repo <repo> --json merged如果已合并,移除会话(同
kill步骤)。 -
如果
type=fix,检查关闭状态:gh issue view <num> --repo <repo> --json closed如果已关闭,移除会话(同
kill步骤)。 -
如果
type=feature,除非显式请求,否则跳过自动清理。
输出摘要:
- 已清理的会话
- 跳过的会话
- 任何失败及原因
8) status
目标:显示当前环境的会话上下文。
检测顺序:
- 如果在tmux内部,读取当前会话名称(
tmux display-message -p '#S')。 - 否则将当前工作目录与sessions.json中存储的工作树路径匹配。
- 如果找到匹配,打印完整会话详情:
- ID
- 类型
- 仓库/引用
- 分支
- 工作树
- Tmux名称
- 附加命令
- 如果无匹配,报告:“当前不在管理的PSM会话中。”
会话报告格式
创建会话时使用此确切结构:
会话准备就绪!
ID: project:pr-123
类型: review
PR: #123 - 添加webhook支持
工作树: ~/.maestro-psm/worktrees/project/pr-123
Tmux: maestro:project:pr-123
命令:
附加: tmux attach -t maestro:project:pr-123
杀死: /psm kill project:pr-123
清理: /psm cleanup
对于问题/修复或功能会话,将PR行替换为相关引用标签。
重要说明
- 对所有GitHub操作使用
ghCLI(认证 + 仓库上下文)。 - 对所有状态使用
~/.maestro-psm/(绝不用~/.psm/,绝不用.maestro/)。 - 在实际命令执行中将
~扩展为$HOME。 - 在文件系统操作之前创建父目录。
- Tmux会话在后台启动;用户保持在当前终端。
- 始终告知用户如何附加(
tmux attach -t maestro:<session>)。 - 使用清晰、可操作的错误信息(无效引用、缺失gh认证、缺失tmux会话、git工作树错误)。