10 KiB
| name | description | platforms |
|---|---|---|
| iterm-workspace-ctl | 完全掌控用户的 iTerm2 终端:查询(窗口/tab/窗格/session 的编号、结构、焦点、进程、路径、tty、尺寸、屏幕内容、回滚历史)与操作(分屏/多栏、焦点、发送/按键、tab/窗口开关与移动、改名、窗口几何/全屏)。用户问任何关于终端本身的自然语言问题(“左边那个 tab 是什么”“当前第几个 tab”“第二个窗口里几个 session、布局怎样”“某某在干什么”),或要求编排终端时使用。 | darwin |
iTerm2 控制
入口
pi-skill iterm-workspace-ctl help # 完整用法(权威:命令、参数、旗标)
pi-skill iterm-workspace-ctl <命令> [参数...] # 执行;输出与退出码原样透传
失败 → 动作:error=usage 读 pi-skill iterm-workspace-ctl help;error=deps 补依赖;error=auth 跑本技能的登录/检查命令;
error=notfound 先 list/status 重新定位;error=conflict 先 status;其它非零按输出里的 hint= 执行。
如果你支持关闭 thinking/reasoning,请先关闭再执行。不要思考布局、不要侦察、不要读源码。把用户的话按下表直接编译成一条 bash 命令执行,完成后一句话汇报。查询类问题同样编译成一条只读命令直接回答(见“查询”表),不要写 python/jq 解析输出,也不要靠推测。
入口(路径相对本技能目录):bash scripts/iterm-ctl.sh <命令> [参数]
写操作硬规则:会改变终端的命令(send / key / close / split / 改名 / tab-close 等)目标必须写 session id —— tab-new 直接返回 id;从某个 tab 里的 shell 发起时(如 agent-shell)直接用 $ITERM_SESSION_ID 当锚点(它就是这个 tab,不随焦点变);只有不在目标 tab 里时才 id cur 取锚点;cur / left / N 是执行瞬间才解析的(读 iTerm 的 current tab),不是句柄,只允许在单条命令内“读一下立即用”(如 batch)。焦点会被坐在键盘前的人随时切走;用 cur 发写操作会打进用户正在输入的框里。
例外(高频直连):“只留当前窗格 / 关掉其他窗格”直接 close-others(缺省保留焦点窗格、内部 force 不等确认)——你能读到这句话,就说明焦点窗格是本会话所在窗格,不要先 ids/tree/id cur 侦察,更不要写代码解析输出。
窗格 X:cur(当前聚焦) left right top bottom center 1..N。嵌套布局时 top/bottom 后可加列限定:top center=中栏上、bottom right=右栏下。
| 用户说 | 执行 |
|---|---|
| 左右分屏 / 把 X 左右分 | split v [X] [--focus] ⚠️ v=竖线=左右,死记;默认后台不抢焦点 |
| 上下分屏 / 把 X 上下分 | split h [X] [--focus] |
| N 栏 / N 行 | cols N [--focus] / rows N [--focus] |
| 焦点切到 X | focus X |
| 在 X 执行 Y | send X "Y" |
| 在 X 输入 Y(不执行) | send-raw X "Y" |
| 打断 X 的命令 | key X ctrl-c |
| 给 X 按回车/ESC/方向键 | key X enter esc up down left right |
| 关掉 X 窗格 | close X |
| 只留 X 窗格(缺省=当前) | close-others [X] |
| 新开/切换/关 tab | tab-new [--profile P] [--command C] [--focus] / tab-select N / tab-close [N] |
| tab 独立成窗口 | tab-detach N |
| 新开/关窗口 | win-new [--profile P] [--command C] / win-close [n|id] |
| 切窗口 / 把 iTerm 前置 | win-select <n|id> / app-activate |
| 看 X 的输出 / 看历史 | capture X [N] / capture X N --scrollback |
| 等 X 出现"词" | wait X "词" |
| 等 X 手里的活干完再跟它说句话 | send-when-idle start X "话"(后台守候;send-when-idle status / logs <id> / stop <id|--all> 管) |
| 等 X 空闲再动手(前台阻塞,可组合) | wait-idle X [--when auto|prompt|quiet],可加 --send "话" 一次做完 |
| X 现在忙不忙 | idle-state X(job / prompt / 屏幕指纹) |
| 看所有 session id | ids |
| 拿住 X 备用(锚定) | id X |
| 按 id 操作(与焦点无关) | send-id <id> "Y" / key-id <id> ... / capture-id <id> [N] / wait-id <id> "词" / close-id <id> / split-id <id> v|h |
| 改名 / 标题 | title <pane|id> "文字" / tab-title N "文字" / win-title [n|id] "文字" |
| 窗口几何 / 全屏 | frame [n|id] [x y w h] / fullscreen <n|id> on|off |
| 回滚缓冲(iTerm2 设置,新开会话生效) | scrollback list / scrollback unlimited / scrollback set 1000 [--profile P] |
| 按键扩展 | key X backspace delete home end pageup pagedown F1..F12 ctrl-a..z ctrl-enter(ctrl-enter 走 kitty 协议 CSI u,用于 copilot CLI 这类需要 Ctrl+Enter 排队提交的 TUI) |
| 等它干完再交代下一件事 | wait-idle / send-when-idle(判定=回 shell 提示符或屏幕连续静止;不要用 sleep 猜时间,语义与边界见 REFERENCE.md) |
| 多步组合 / 复杂任务 | batch(从 stdin 一次连接执行;默认用它) |
查询:任何终端问题 → 一条命令(禁止写代码解析)
硬规则:回答任何问题都用下表命令直接读,一条 bash 调用拿到现成可读的输出;不要写 python/jq 解析,不要把一条问题拆成多步侦察。
| 用户问 | 执行 |
|---|---|
| 我在哪?当前是第几个 tab/窗格? | where |
| 当前窗口有哪些 tab?左边/右边的 tab 是什么? | tab-list(输出带 current-2 / current-1 / current / current+1 标记,直接读取) |
| 第几个 tab、first/last 在干什么? | capture-tab first|last|N [行数];看历史加 --scrollback |
| 某个 tab 有几个 session、布局怎样、什么进程? | tab-show first|last|N |
| 有几个窗口?某个窗口在哪、什么尺寸、全屏吗? | win-list / win-show first|last|N |
| 全部结构(窗口/tab/窗格/进程/路径/尺寸) | tree(机器处理才用 tree --json) |
| 某 session 的 cwd/进程/tty/任意变量 | tab-show/tree 已含 job/path/tty;或 var <pane|id> <名字> |
| 有哪些 profile | profiles |
| 窗口位置/大小/是否全屏 | frame [n|id] / fullscreen <n|id> on|off(不传 on/off 只读) |
| 给某个 tab 发命令/按键(不用先查 id) | send-tab first|last|N "命令" / key-tab first|last|N ctrl-c |
- 编号(window/tab/pane)会随增删变化:回答时以本次输出为准。
- “在干什么”看
tab-show的 job/path,“细节/最新输出”用capture-tab;不要臆测。 - 用户说“窗口”= iTerm 顶层 window;一个 window 里有多个 tab。
锚定规则(跨调用必遵守):left/right/cur 是相对当前聚焦 tab 实时解析的,用户切 tab/窗口后同一条命令会落到别的窗格。凡是要跨多次 bash 调用或多轮对话连续操作的窗格,先 id <pane>(或 ids)拿到 session id,之后一律用 *-id 命令,与前台焦点完全无关。同一时刻连续动作(如 split v && send right "pi")可以直接用方位。
焦点规则(默认不抢):split / split-id / cols / rows / tab-new 一律在后台创建,保持用户当前焦点不动;只有用户明确说"切过去 / 打开给我看 / 我要看着它"时才加 --focus。发送、按键、读屏、关闭等 *-id 操作全程不动焦点。绝不主动 focus/focus-id,除非用户明确要求。
批量规则(默认合并执行):多步任务默认写成 batch heredoc,一次连接全部执行完;只有用户明确说"一步步来 / 我要看着它执行 / 每步分开做"时才拆成单条命令逐步执行。batch 内遇错即停,行首 # 为注释。支持纯赋值 A=$ITERM_SESSION_ID;$VAR 没在 batch 里捕获过时退回环境变量($ITERM_SESSION_ID 可直接用,w0t1p0: 前缀各 *-id 命令都认)。
组合:多个动作按语序用 && 串成一条 bash 调用。"等它跑起来" = sleep 2。分屏后新窗格在下/右:split h center && send top "htop" && send bottom "x" = 中栏上跑 htop、中栏下跑 x。
例:
- 左右分屏右边开 pi →
split v && send right "pi" - 三栏各开 pi →
cols 3 && send left "pi" && send center "pi" && send right "pi" - 打断右边再关掉 →
key right ctrl-c && close right
配方(多步组合,一律 id 锚定、不抢焦点;默认用 batch):
- 新 tab + 左右分屏 + 左 pi / 右 proxy→codex:
pi-skill iterm-workspace-ctl batch <<'EOF' T=$(tab-new) # 后台新 tab;输出左窗格 id,焦点不变 R=$(split-id "$T" v) # 原 session 在左、新窗格在右;输出右窗格 id send-id "$T" "pi" send-id "$R" "proxy" sleep 2 send-id "$R" "codex" EOF - 新 tab + 多栏各自起工具:batch 里
T=$(tab-new)→ 逐个R=$(split-id "$T" v)收集 id → 对每个 idsend-id <id> "命令"。 - 等启动完成:用
wait-id <id> "词" [秒]代替盲目 sleep;读结果capture-id <id> [行数];结束清理close-id <id>。 - 在已有后台 tab 里增减窗格:直接 batch 里
split-id <该 tab 内任一 session id> v|h,不会切用户焦点。
⚠️ close/close-others 会杀窗格里的进程,别关到用户自己正在用的窗格。
复杂流程(>3 步)机械处理:先在配方表里找相同组合,命中就直接照抄;没命中就切小段查映射表,每段单独编译,用 && 串成一条。跨调用的每一步必须带 *-id。不要规划状态转移,不要推演“执行后窗格变成什么样”。
生成命令后、执行前,机械核对(不要思考,只对照):
□ 查询类问题是否用了“查询”表的直接命令(tab-list/tab-show/win-show/capture-tab/where)且没写代码解析?
□ 命令里每个词都在映射表里出现过?
□ 没有 info/capture/grep/ls 等侦察命令?
□ 是一条 bash 调用(多步用 && 串)?
□ 跨调用操作是否已用 id/ids 锚定,并改用 *-id?
□ 创建类是否默认不抢焦点(没自作主张加 --focus)?
全部打勾 → 立即执行。任何一项没打勾 → 重查映射表,不要自己想。
只有命令报错或缺库时,才读 REFERENCE.md(安装、排查、AppleScript 退回方案)。