omniterm 0.2.5

Web-based tmux terminal manager — one browser tab to watch and drive your AI coding agents
# Claude Code 屏幕检测规则。
# Rules adapted from herdr (https://github.com/ogulcancelik/herdr, Apache-2.0)
# src/detect/manifests/claude.toml — 区域语义精简为 OmniTerm 引擎支持的子集
# (见 src/tmux/agent_detect.rs 顶部注释)。改规则后跑 `cargo test agent_detect`。

[[rules]]
id = "osc_title_working"
state = "working"
priority = 1100
region = "osc_title"
regex = ['^[\x{2800}-\x{28FF}] ']

[[rules]]
id = "transcript_viewer"
state = "unknown"
priority = 1000
region = "bottom_non_empty_lines(3)"
skip_state_update = true
contains = ["showing detailed transcript"]

[[rules]]
id = "live_blocked_form"
state = "blocked"
priority = 980
region = "after_last_horizontal_rule"
contains = ["enter to select", "esc to cancel"]
any = [
  { contains = ["tab/arrow keys to navigate"] },
  { contains = ["arrow keys to navigate"] },
  { contains = ["arrows to navigate"] },
  { contains = ["↑/↓ to navigate"] },
  { contains = ["↑↓ to navigate"] },
]

[[rules]]
id = "live_prompt_box"
state = "idle"
priority = 950
region = "prompt_box_body"
visible_idle = true
line_regex = ['^\s*❯']
not = [
  { contains = ["enter to select"] },
  { contains = ["esc to cancel"] },
  { contains = ["tab/arrow keys"] },
  { contains = ["arrow keys to navigate"] },
  { contains = ["↑/↓ to navigate"] },
  # OmniTerm 补充:权限/选项框体内同样出现 `❯ 1. Yes`,须排除
  { contains = ["do you want to proceed?"] },
  { contains = ["1. yes"] },
]

[[rules]]
id = "model_picker_menu"
state = "unknown"
priority = 900
region = "whole_recent"
skip_state_update = true
contains = ["select model", "enter to set as default", "esc to cancel"]
not = [
  { contains = ["do you want to proceed?"] },
  { contains = ["enter to select"] },
]

[[rules]]
id = "bash_permission_prompt"
state = "blocked"
priority = 850
region = "whole_recent"
contains = ["do you want to proceed?"]
any = [
  { contains = ["bash command"] },
  { contains = ["bash("] },
  { contains = ["contains expansion"] },
  { contains = ["tab to amend"] },
  { contains = ["ctrl+e to explain"] },
]
all = [
  { any = [{ line_regex = ['(?i)^\s*❯?\s*yes\b'] }, { line_regex = ['(?i)^\s*❯?\s*1\.\s*yes\b'] }, { line_regex = ['(?i)^\s*2\.\s*no\b'] }] },
]

[[rules]]
id = "generic_permission_prompt"
state = "blocked"
priority = 840
region = "whole_recent"
contains = ["do you want to proceed?", "esc to cancel"]
all = [
  { any = [
    { line_regex = ['(?i)^\s*❯?\s*1\.\s*yes\b'] },
    { line_regex = ['(?i)^\s*2\.\s*yes\b'] },
    { line_regex = ['(?i)^\s*2\.\s*no\b'] },
    { line_regex = ['(?i)^\s*3\.\s*no\b'] },
  ] },
]

# OmniTerm 补充:Claude 工作中的底部状态行(herdr 依赖 OSC 标题,tmux 下
# pane_title 可能被 shell 覆盖,故加一条屏幕兜底)。
[[rules]]
id = "screen_working_fallback"
state = "working"
priority = 500
region = "bottom_non_empty_lines(6)"
contains = ["esc to interrupt"]
not = [{ contains = ["conversation interrupted"] }]

[[rules]]
id = "legacy_no_prompt_blocker"
state = "blocked"
priority = 300
region = "whole_recent"
any = [
  { contains = ["do you want to"], any = [{ contains = ["yes"] }, { contains = [""] }] },
  { contains = ["would you like to"], any = [{ contains = ["yes"] }, { contains = [""] }] },
  { contains = ["waiting for permission"] },
  { contains = ["do you want to allow this connection?"] },
  { contains = ["tab to amend"] },
  { contains = ["ctrl+e to explain"] },
  { contains = ["do you want to proceed?", "esc to cancel"] },
]
not = [
  { regex = ['(?m)^\s*❯\s*$'] },
]

[[rules]]
id = "osc_title_idle"
state = "idle"
priority = 250
region = "osc_title"
visible_idle = true
regex = ['^\x{2733} ']