跳转至

从终端控制运行中的应用

Agent or terminal                                  // control.cli; every OS
├── One tree and protocol over the local API's POST /control on every OS;
│   OS can't do it -> unsupported at runtime, exit 1
├── hex status [--json] -> Listener, capture, meeting, model, features,
│   permissions, window, update, version, pid, memory
│   └── Hex not running -> exit 3, "Hex is not running; run `hex start`"
├── hex start -> Already running: nothing | else open Hex.app (Linux and
│   Windows: a detached `hex app --hidden`), wait ≤ 20 s
│   └── The caller's HEX_* variables -> open --env (values never logged)
├── hex quit | restart [--force]
│   ├── Meeting or dictation in progress, no --force -> refused, exit 1
│   ├── Listener didn't answer, no --force -> busy (it might be recording)
│   └── restart -> reopens with the running Hex's HEX_* variables (macOS);
│       Linux unit -> systemctl restart; else waits for the drain, then start
├── hex dictation start|stop|toggle|cancel
│   ├── Same shortcut state machine as the hotkey; start locks the capture
│   ├── start -> intentional at once: tone once the mic is open, recording
│   │   behavior, live stream
│   ├── stop -> done only when the clip went to transcription;
│   │   no audio yet or silent -> discarded, nothing transcribing
│   ├── cancel -> discards the recording in any mode, nothing pasted or saved;
│   │   jobs already transcribing finish; idle -> unchanged
│   ├── Repeat a command -> unchanged, exit 0
│   └── dictation stop --print -> stops at once, then waits ≤ 60 s and prints
│       the transcript (processed as a paste) instead of pasting it
│       ├── No speech -> no-speech, exit 4, prints nothing
│       ├── Not recording -> not-recording, exit 1
│       ├── Failure or timeout -> exit 1, prints nothing, never pastes
│       └── History keeps it as Printed; Paste Last skips it (also on Linux)
│   └── dictation start|toggle --raw -> the dictation it starts pastes the
│       transcript as heard (Dictate without processing); History keeps it as Raw;
│       --raw with stop -> usage error, exit 2
├── hex paste-last -> pastes the last dictation
│   ├── Setup gates the listener -> not-ready
│   └── Recording or shortcut gesture in progress -> busy (menu bar: nothing)
├── hex meetings record [--title] | stop | copy-last
│   ├── Meetings off -> feature-off; recording shows in the menu bar and HUD
│   │   exactly like a menu-bar recording
│   └── No meetings cancel: Hex cannot discard a recording
├── hex settings list | get <key|prefix> | set <key> <value>
│   ├── The window's save, then ReloadSettings -> live, no restart
│   ├── Unknown key, bad value, read-only key -> refused, nothing written
│   ├── Shortcut conflict -> refused, as the window's recorder would
│   └── apply <file|-> -> a JSON object of key: value, all or none
│       ├── Undeclared settings keep their values; dependent keys in any order
│       ├── transcription.model / .language -> selected, never downloaded
│       ├── Hex running -> SettingsApply: saved and adopted live, like set
│       └── Hex stopped -> written to settings.json under the service lock
│           (Linux); a Hex holding it is waited for (≤ 35 s) instead
├── hex model list | use <id> | install [id] | cancel
│   ├── use -> installed models only; never downloads or repairs; keeps the
│   │   model's remembered language and hints (--language overrides)
│   └── Linux/Windows: install with Hex stopped downloads here; status,
│       devices, check, transcribe run here (macOS: unsupported)
├── hex window show [pane] | hide
│   ├── settings -> the General pane (status window.pane stays "settings")
│   ├── meetings pane with Meetings off -> the pane's opt-in card
│   └── story <story> [--variant V] [--play] -> a playground story, as a
│       hex://story link opens (labs.md); playground off -> feature-off
├── hex history clear --yes -> without --yes refused before Hex is asked
├── hex check-for-updates -> The updater checks now
├── hex launch-at-login [on|off] -> SMAppService (changes need Hex.app);
│   Windows Run key; Linux XDG autostart entry
└── hex logs [--process] [-n N] [-f] -> local tail; works with Hex stopped

除 start、restart、logs、settings apply 和只读命令之外,每条命令都只与正在运行的 Hex 通信;它们都不会启动 Hex。每个 OS 都通过本地 API 的仅所有者可访问的发现文件以及 Bearer 令牌认证的 POST /control 路由来访问它。命令在日志记录和实例锁之前完成分发,因此在任何 OS 上都不会与正在运行的应用竞争其文件。需要选择加入的功能始终是显式设置:没有任何命令会作为副作用打开 Meetings。

在 Linux 和 Windows 上,control::host::answer 通过操作系统的适配器(linux::app::LinuxControl、windows::rune::WindowsControl)执行每条命令:听写命令和 paste-last 命令会进入监听器自身的队列(Windows:与热键循环相同,就像按下了切换键一样);设置的保存与重新加载与窗口一致;settings set 会拒绝操作系统缺少相应能力的键(settings list 会将其标记为“not on this OS”)。meetings record|stop|copy-last 与托盘菜单项一样进入会议记录器(meeting/runtime);window story 返回 unsupported;Windows 会将每条 annotate 命令发送给正在运行的 Hex。hex history、hex meetings list|show|search 和 hex mcp 在每个 OS 上都会读取文件。

来源:control.rs(协议、状态、退出规则)、control/host.rs(Linux 和 Windows 主机)、control/settings.rs(设置注册表)、control/cli.rs 和 control/cli/human.rs(clap、输出、退出码、启动、日志)、macos_rune/control.rs(macOS 主机)、local_api.rs 中的 /control 路由,以及 main.rs 中的早期分发。命令与 JSON 契约 记录了标志、退出码和 schema。

检查:control::tests 对每条命令和回复进行往返测试(包括 a_printing_stop_answers_through_its_reply_channel),拒绝其他协议版本,并覆盖退出规则(未应答的监听器会拒绝退出)和 model_selection(记住的提示、通配符语言验证);control::settings::tests 包括 every_persisted_setting_has_a_cli_key、值解析、快捷键冲突和零音量;control::cli::tests 固定退出码、输出以及 hex start 的 open 参数;desktop::onboarding::tests::relaunch_forwards_only_the_hex_environment 固定 restart 的行为;macos_rune::control::tests 检查 model use 是否只准备其确切选择的已安装项;dictation::audio::tests::marked_captures_are_intentional_without_a_hold 覆盖即时流和 ReadyIntentional;recognition::tests 覆盖停止回复和“粘贴上一条”的拒绝;control::tests::cancel_parses_and_takes_no_flags 覆盖 cancel 及其标志;本地 API 的 control_requests_are_authenticated_versioned_and_typed 覆盖身份验证、边界和错误码;tests::control_commands_parse_beside_the_read_commands 覆盖与 history 和 meetings 并存的解析;control::host::tests 覆盖退出拒绝、打印停止和运行时 unsupported 回复;linux::tests 解析与 Linux 自身命令并列的共享命令树;rune_ui::platform::parity_tests 在某项能力跨不同 OS 存在差异且没有记录原因时失败;settings_name_real_capabilities_and_keys 检查设置到能力的映射表。

观察到(10月30日,apollo,使用隔离的数据根目录以及无显示器的 hex service):status、settings get/set(以及 show_dock_icon 被拒绝)、vocabulary add/list/remove、model list/use/status、history clear、window hide、check-for-updates、commands check、quit、start 和 restart 都按文档所述得到响应。Windows 版本已用 cargo xwin clippy 编译(仅 x64;ARM64 交叉构建在 rquickjs-sys 的构建脚本中失败,与此无关);尚未在 Windows PC 上运行。

缺口:没有命令在真实应用上运行过;单元检查代替了宿主环境。控制循环的启动/停止接线(提示音时序、录音行为)没有端到端测试。CLI 的音量更改不会像窗口那样预览提示音。引导过程中的权限提示、日历连接以及会议删除或重命名都没有对应命令。在 Linux 和 Windows 上通过 CLI 进行听写还没有配合麦克风运行过;在 Linux 或 Windows 上通过 CLI 进行会议录制也还没有运行过。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 hex19/hex