cli-anything-iterm2 应用层控制实战:Workspace 快照定位、上下文持久化、App 级变量、模态对话框与文件面板全解析
cli-anything-iterm2 应用层控制实战Workspace 快照定位、上下文持久化、App 级变量、模态对话框与文件面板全解析【免费下载链接】CLI-AnythingCLI-Anything: Making ALL Software Agent-Native -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anythingcli-anything-iterm2是 CLI-Anything 生态中面向 iTerm2 的状态化命令行 harness它通过 iTerm2 Python APIWebSocket接管正在运行的 iTerm2 实例。本文聚焦其中面向「应用App层」的一组能力——工作区快照与状态盘点、会话上下文管理、App 级变量读写以及 macOS 原生模态对话框与文件打开/保存面板——结合本仓库源码逐条拆解每个命令的参数语义、底层调用链与--json返回结构帮助你或你的 Agent在一整屏跑满进程的既有工作区中快速定位每一个 pane、记住我正在操作谁并在需要人工确认时优雅地弹出原生 UI。文章对应的原始参考文档位于 app-context.md所属技能说明见 SKILL.md。一、前置准备让 App 层命令可运行在调用任何app子命令前需要满足 SKILL.md 中列出的三条前置条件macOS iTerm2 正在运行brew install --cask iterm2本组命令全部基于 live iTerm2 进程不会自启应用启用 Python APIiTerm2 → Preferences → General → Magic →Enable Python API。CLI 需要它通过 WebSocket 建立会话入口见main.py实际连接封装在utils/iterm2_backend.py安装 harnesspip install cli-anything-iterm2或从源码pip install -e .。命令统一语法为cli-anything-iterm2 [--json] group command [OPTIONS] [ARGS]Agent 场景务必加--json在 iterm2_ctl_cli.py 中可以看到启用后结果统一以json.dumps(..., indent2)输出未启用时则走_print_data的人类可读缩进打印便于肉眼观察。二、Workspace 定位从app status到app snapshot2.1app status—— 轻量级清点app status返回窗口—标签页—会话三级结构只含 ID 与名称适合快速了解有多少东西在跑cli-anything-iterm2 --json app status从其源码iterm2_ctl_cli.py可以看出命令内部遍历app.windows→w.tabs→t.sessions为每个会话收集session_id与name最后以window_count汇总。JSON 返回示例{ window_count: 2, windows: [ { window_id: W0, tabs: [ {tab_id: W0T0, sessions: [{session_id: W0T0P0, name: api-server}]} ] } ] }2.2app snapshot—— 主推的富快照定位命令app status只能告诉你有什么 pane却回答不了每个 pane 在干什么。这正是 app-context.md 反复强调的app snapshot的用武之地它是降落既有工作区时的首选 orientation 命令cli-anything-iterm2 --json app snapshot单次调用即可拿到所有窗口下每个会话的session_id、name、window_id、tab_id、path当前工作目录、pid、process前台进程名、roleuser.role会话变量标签、last_line屏幕上最后一行非空可见输出。该命令的底层实现位于 core/session.py 的workspace_snapshot()其数据来源很有价值path、pid直接取自 iTerm2 内建会话变量async_get_variable(path)/async_get_variable(pid)process通过ps -p pid -o comm反查得到_get_process_name见同一文件 L301-L314role读取自定义会话变量user.role未设置时为Nonelast_line从async_get_screen_contents()倒序扫描跳过空行取第一个非空行。这意味着 Agent 只需一条命令就能在不动任何 pane、不读全屏滚动区的情况下完成全局态势感知——TEST.md 中的Automation audit工作流正是这一思路先app status盘点再逐个session screen深读。2.3 用user.role给 pane 打语义标签snapshot只有在你预先给会话打上role标签时才有角色化视图否则role字段为空。建工作区时随手打标即可cli-anything-iterm2 session set-var user.role api-server cli-anything-iterm2 session set-var user.role log-tail cli-anything-iterm2 session set-var user.role editor之后每次app snapshot输出都会带上这些语义标签形成进程 路径 角色 最后输出的完整画像。角色变量的读写语义内建只读、user.前缀可读写在 session-control.md 中有完整说明。三、上下文管理让后续命令不再每次手写--session-idiTerm2 的窗口、标签页、会话 ID 是随运行时长存的动态标识每次都手敲既繁琐又易错。cli-anything-iterm2用**持久化的上下文context**解决这个问题上下文保存了当前 window/tab/session 三级 ID设置后session send、session screen、session scrollback等命令都可以省略--session-id。3.1 四件套命令cli-anything-iterm2 --json app status # 盘点所有窗口/标签页/会话 cli-anything-iterm2 app current # 聚焦当前活动会话 → 保存为上下文 cli-anything-iterm2 app context # 查看已保存的上下文 cli-anything-iterm2 app set-context --session-id id # 手动指定上下文也可带 --window-id/--tab-id cli-anything-iterm2 app clear-context # 清空上下文3.2 状态持久化原理上下文并非存放在内存而是落盘持久化状态文件位于~/.cli-anything-iterm2/session.json实现见 core/session_state.py。SessionState数据类仅含window_id、tab_id、session_id与notes四个字段save_state()在写入时通过fcntl.flock加独占锁L88-L102避免多个 CLI 进程并发写坏状态文件——这解释了为什么命令是有状态的每次app current/set-context写入后换一个新终端进程再执行session send依然生效。CLI 层的串联逻辑在 iterm2_ctl_cli.pyapp current调用win_mod.get_current_window拿到焦点窗口随即把三级 ID 写入 stateapp set-context支持--window-id、--tab-id、--session-id三个可选参数按传入项更新各命令取上下文时统一走get_state().session_id缺省时提示Use --session-id or set context with app current。3.3 组合出的典型 Agent 工作流把定位与上下文串起来就是 SKILL.md 展示的标准工作流# 1. 定位——一次拿到全部会话的角色/路径/进程/最后输出 cli-anything-iterm2 --json app snapshot # 2. 建立上下文保存 window/tab/session ID供后续命令复用 cli-anything-iterm2 app current # 3. 交互——设置上下文后无需再写 --session-id cli-anything-iterm2 session send git status cli-anything-iterm2 --json session scrollback --tail 200 --strip # 4. 扩成多 pane 工作区——新 pane 直接设为上下文打上角色标签 cli-anything-iterm2 session split --vertical --use-as-context cli-anything-iterm2 session send python3 -m http.server 8000 cli-anything-iterm2 session set-var user.role http-server注意第 4 步中session split --use-as-context会在创建后把新 pane 写入上下文见 iterm2_ctl_cli.py随后发送命令无需再指定--session-id非常适合新建即接管的自动布局场景。这一整套app current → session split → session set-var role的流程同样出现在 TEST.md 的 Workflow 1: Agent workspace setup 验证场景中。四、App 级变量跨会话共享元数据与会话级变量见session set-var user.role作用域限于单个 pane不同app组提供的是应用级变量——挂在整个 iTerm2 App 对象上跨窗口、标签、会话共享cli-anything-iterm2 app get-var hostname cli-anything-iterm2 app set-var user.myvar hello内置变量如hostname只读可直接get-var自定义变量必须使用user.前缀命名空间例如user.myvar写后可通过get-var user.myvar读回。底层实现见 iterm2_ctl_cli.pyget-var通过iterm2.async_get_app()拿到 App 后调用a.async_get_variable(name)set-var调用a.async_set_variable(name, value)均返回{variable: ..., value: ...}结构。它的典型用途包括记录当前正在编排哪个项目目录部署环境是 staging 还是 production等与单个 pane 无关的工作区级状态。五、模态对话框让 Agent 能向人类要确认、要输入自动化并不总意味着无人值守。app组通过 iTerm2 的原生对话框 API让 CLI/Agent 在关键步骤把控制权交还给坐在屏幕前的人。相关协程封装在 core/dialogs.pyCLI 入口在 iterm2_ctl_cli.py。5.1app alert—— 消息 自定义按钮cli-anything-iterm2 app alert Title Message # 仅一个 OK 按钮 cli-anything-iterm2 app alert Deploy? Push? --button Yes --button No必填两个位置参数TITLE加粗标题与SUBTITLE正文可多行--button可重复传入添加多个按钮标签返回用户点击的按钮标签。返回值按按钮出现顺序从 1000 起编号1000 对应第一个按钮json-tmux-app.md 给出了规范示例{button_index: 1000, button_label: OK} {button_index: 1000, button_label: Yes} // --button Yes --button No 时 1001 No底层show_alert()dialogs.py通过iterm2.Alert(title, subtitle, window_id...)构造未传按钮时默认仅一个 OKasync_run()返回的 1000-based 索引会被换算回 0-based 以正确映射buttons列表取标签。--window-id可将对话框挂到指定窗口而非全局模态CLI 层默认回退到当前上下文的window_id见 L277。5.2app text-input—— 带输入框的对话框cli-anything-iterm2 app text-input Rename Enter name: --default myapp--placeholder输入框中的灰色占位提示文本默认空--default预填文本CLI 层内部变量为default_value默认空返回用户输入或cancelled标记。对应show_text_input()dialogs.py构造iterm2.TextInputAlert(title, subtitle, placeholder, default_value, window_id...)取消时async_run返回None结果统一为{cancelled: false, text: hello world} {cancelled: true, text: null}一个典型的自动化交互闭环是Agent 想重命名服务先text-input Rename Enter new name: --default $current再从返回的text读取确认值最后执行session set-name/session set-var user.role落库——把人类决策与机器执行干净地切开。六、文件面板弹出 macOS 原生 Open / Save 对话框当自动化需要用户从文件系统挑选目标文件或指定保存路径时纯文本输入既难用又易错。app组直接封装了 macOS 原生文件面板对应 iTerm2 Python API 的OpenPanel/SavePanel。6.1app file-panel—— 打开文件可多选、可过滤扩展名、可选目录cli-anything-iterm2 app file-panel # macOS open picker cli-anything-iterm2 app file-panel --ext py --ext txt --multi # 过滤扩展名 多选 cli-anything-iterm2 app file-panel --dirs --multi # 允许选目录 多选CLI 层iterm2_ctl_cli.py暴露的选项与底层show_open_panel()dialogs.py一一对应CLI 选项语义底层映射--title TEXT面板标题/提示文案默认Openpanel.message title--path DIR初始目录panel.path path--ext EXT可重复只允许选择指定扩展名如--ext py --ext txtpanel.extensions [..]--dirs允许选择目录options 追加CAN_CHOOSE_DIRECTORIES--multi允许多选options 追加ALLOWS_MULTIPLE_SELECTION默认始终附加CAN_CHOOSE_FILES全部选择路径通过result.files列表返回{cancelled: false, files: [/Users/alex/foo.py, /Users/alex/bar.py]} {cancelled: true, files: []}6.2app save-panel—— 保存文件对话框cli-anything-iterm2 app save-panel --filename output.txt # 预填文件名 cli-anything-iterm2 app save-panel --path ~/Desktop --filename output.txt对应show_save_panel()dialogs.py支持--path初始目录与--filename预填文件名返回用户确认的保存路径{cancelled: false, file: /Users/alex/output.txt} {cancelled: true, file: null}6.3 面板取消时的错误处理约定所有对话框/面板取消都不算异常CLI 层只打印Cancelled.如text-input、file-panel、save-panel各命令在cancelled分支的处理JSON 模式下返回cancelled: true结构而非报错Agent 可根据该字段自行决定放弃还是重试。真正的连接性错误则统一由handle_iterm2_error装饰器iterm2_ctl_cli.py捕获以{error: ...}形式输出并以退出码 1 结束。七、把 App 层串成完整的 Agent 编排闭环将以上能力组合起来一个定位 → 建上下文 → 自动执行 → 人工兜底的编排闭环可以这样落地# 阶段 1全局定位 人工圈定工作目标 cli-anything-iterm2 --json app snapshot cli-anything-iterm2 app set-context --session-id target_pane_id # 阶段 2在上下文中自动推进 cli-anything-iterm2 session send python3 build.py --env staging # 阶段 3关键决策点弹窗征求人类意见 cli-anything-iterm2 app alert Deploy Build passed. Push to staging? \ --button Yes, deploy --button No, keep local # 阶段 4需要资源时让用户从原生面板挑选 cli-anything-iterm2 app file-panel --ext png --ext jpg --multi cli-anything-iterm2 app save-panel --filename artifact.json快照/上下文解决Agent 进入陌生工作区不知道从哪下手的问题一条app snapshot附带user.role标签即可区分 api-server、log-tail、editor对话框解决无人确认的破坏性操作问题app alert的返回值button_label能直接被 Agent 分支判断文件面板解决路径输入不可靠问题让 macOS 原生 UI 保证路径真实存在。需要再次说明的是以上命令面向正在运行中的 iTerm2 实例且依赖会话内的 Shell Integration如需wait-prompt、get-prompt等流程控制能力相关基础在 SKILL.md 与配套参考文档中均有更细的说明。八、相关参考文档与源码索引围绕 App 层主题仓库内可按需深入以下路径app-context.md本文主题的原始参考文档命令速查SKILL.md技能总览、前置条件、命令分组表、标准 Agent 工作流与 REPL 模式json-tmux-app.mdapp对话框/面板相关命令的--json返回结构规范与错误格式session-control.md会话级变量与user.前缀命名约定iterm2_ctl_cli.pyapp命令组的全部 Click 实现status/current/context/set-context/clear-context/get-var/set-var/alert/text-input/file-panel/save-panel/snapshotcore/session_state.py上下文状态文件的持久化与文件锁实现core/dialogs.pyAlert / TextInputAlert / OpenPanel / SavePanel 四个异步协程的封装core/session.pyworkspace_snapshotsnapshot 数据源实现TEST.md包含app current、app status在内的真实工作流验证场景与 CLI 子进程测试清单。【免费下载链接】CLI-AnythingCLI-Anything: Making ALL Software Agent-Native -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考