-
Notifications
You must be signed in to change notification settings - Fork 0
Development.zh CN
Crate 使用 Rust edition 2024,并提交 Cargo.lock。先获取 lockfile 指定的 dependency,之后 Makefile 可以离线构建:
cargo fetch --locked
cargo build --release --locked
# Dependency 已缓存后,可以使用项目 target:
make buildmake build 会运行 cargo build --release --offline。Cargo cache 为空的全新 checkout 必须先执行 cargo fetch --locked。
从源代码运行 daemon 前,请先停止已安装的 service,因为两者会绑定相同的 runtime socket:
systemctl --user stop voice-input.service
VOICE_INPUT_ASSET_DIR="$PWD/assets" cargo run --offline -- daemon源代码 daemon 仍会读取常规的用户 config 和 runtime directory。开发完成后请重新启动已安装的 service。
src/
main.rs 初始化 TLS provider 并处理顶层退出
args.rs 手写的 CLI parser/help
app.rs command dispatch,以及 Settings 的激活和启动
daemon.rs control socket、capture service 和 session pipeline
config.rs 公开 TOML schema、默认值和 legacy migration
credentials.rs systemd/environment 解析和基于 stdin 的加密
agent_context.rs 验证和脱敏当前 Pi/Codex session
backend.rs ASR trait、control 和 event
backend/
local_cli.rs /usr/bin/voxtype adapter
qwen_realtime.rs Alibaba WebSocket streaming adapter
qwen_batch.rs Qwen 全音频 compatible-HTTP pass
text.rs 提取 transcript 并执行 OpenCC 转换
llm.rs refinement prompt、共享 deadline 和 fail-open 行为
output.rs 检测 Wayland/XWayland target 并输出文本
state.rs state machine snapshot 和原子持久化
waveform.rs PCM 分析、ASR packetizer 和 Unix socket publisher
wav.rs 临时 PCM16 WAV writer
paths.rs, setup.rs 安装路径和 setup helper
assets/
config.toml 公开示例与默认值参考
voice-input*.service systemd 用户 unit template
quickshell/ 常驻 QML HUD
quickshell-settings/ 按需启动的 FloatingWindow Settings QML
pi/ Pi session-registry extension
omarchy-*.conf/jsonc Hyprland 和 Waybar snippet
.github/workflows/ci.yml CI check
packaging/ 当前为空的 placeholder
contrib/omarchy/ 当前为空的 Hyprland/Waybar placeholder
修改公开字段时,应同步更新 assets/config.toml、Rust 默认值和 Settings 默认值。常驻 HUD 和按需启动的 Settings 是两套生命周期不同的 Quickshell 配置。
运行与 CI 相同的 Rust check:
cargo fmt --all -- --check
cargo check --locked --all-targets
cargo test --lockedCI 还会拒绝已经淘汰的 runtime asset 和 source reference,避免已移除的桌面技术栈意外恢复。Runtime CI 路径不再包含脚本语言 syntax check。
当前 unit test 直接写在各 module 中,覆盖内容包括:
- 当前和 legacy TOML parsing;
- transcript extraction 和 OpenCC 路径选择;
- Qwen event parsing 和 transcript assembly;
- LLM response validation、retry policy、OpenRouter sort 和共享的 1–5 秒预算;这些测试使用本地 mock HTTP server;
- Pi/Codex JSONL extraction、redaction 和 truncation;
- waveform 的 chunk independence、对称性、NDJSON framing,以及 ASR packet preservation;
- Wayland/XWayland effective output mode 和 120 字符 paste threshold;
- credential 的换行清理与 NUL 拒绝,以及 CLI parsing;
- 带版本号的 Settings NDJSON、精确源 revision conflict、完整字段验证、原子保存权限、credential 保留/替换,以及单独报告的重启失败。
测试不会访问真实麦克风、compositor、Alibaba/OpenAI-compatible account、Kitty/Pi/Codex process、Quickshell render/IPC activation,也不会实际验证 clipboard restoration。这些部分需要手动集成测试。
请使用不敏感的测试文本和可丢弃的 clipboard 内容。
- 启动两个用户 service,确认三个 runtime file/socket 都存在。
- 在 terminal 中测试
record start、stop、toggle和cancel。 - 测试计划使用的 Hyprland binding,并确认 modifier release。
- 检查 realtime partial text、Server VAD 波形显示和静音取消。
- 如果启用相关功能,分别验证 final-pass replacement 和
/usr/bin/voxtypefallback。 - 分别测试短 Wayland direct type、长 Wayland paste 和 XWayland target。
- 确认 clipboard 和 Fcitx5 状态能够恢复。
- 移动或重置 HUD,并测试 monitor focus change/hotplug。
- 安装 extension 后重启 Pi,再分别测试 Pi 和 Codex 上下文。
- 连续两次打开 Settings,确认第二次命令会激活现有
FloatingWindow;关闭窗口后,确认按需实例退出。 - 分别测试过期 revision conflict、仅修改配置的保存、credential 保留/替换、使用输入值或 store credential 的 Test LLM,以及单独报告的 daemon 重启失败。
- 把 timing log 和 Settings 诊断信息附加到 report 前,检查其中是否意外包含内容。
- 失败时保留识别文本: LLM failure 不能丢弃有效的 ASR output。
- 单一 refinement deadline: 上下文请求与 fallback 共用最多五秒预算。
- 视觉更新不能产生反压: waveform/HUD client 不能阻塞 capture 或 ASR。
-
明确 backend identity: 本地 fallback 始终是配置的可执行文件,默认
/usr/bin/voxtype。 -
Secret 始终通过 stdin 传递: Settings replacement 依次通过 QML stdin、Rust 和
systemd-credsstdin,不进入 config、argv、环境变量、日志或 response;QML/JavaScript 托管内存中的字段清理只能尽力执行。 -
Rust 独占持久化职责: 验证、
0700/0600权限、原子替换、完整字段保留和精确源 conflict 检查都不能下放到 QML。 - 验证外部上下文: 保留 process/session/path 检查、size limit、redaction 和 prompt isolation。
-
原子 state: 并发 writer 必须继续通过
StateHandle串行更新,并以临时文件替换目标。
packaging/ 当前没有发行版 package recipe;安装由 Makefile 实现。make install 会:
- 把一个 release binary 安装到
$(PREFIX)/bin,默认~/.local/bin; - 把常驻 HUD 和按需启动的 Settings asset 安装到
$(PREFIX)/share/voice-input; - 把 Pi extension 安装到
~/.pi/agent/extensions; - 把 unit template 渲染到
~/.config/systemd/user; - 创建私有 config 与加密 credential directory;
- 仅在 config 不存在时创建示例;
- 可能迁移程序明确识别的旧版 Voxtype config/credential file;
- 更新时删除旧版本遗留的已安装
hud.py和settings.py。
PREFIX 只会改变 binary/share 目标。Service、Pi extension、config 和 credential 位置有各自的 Make variable,并且默认使用用户 home。Packager 应设置所有相关变量,或者明确 staging 每个文件;不能假设 PREFIX 会重定位全部内容。
Service template 包含 @VOICE_INPUT_BIN@、@VOICE_INPUT_ASSET_DIR@ 和 @VOICE_INPUT_QUICKSHELL_DIR@;打包时需要替换为最终绝对路径。Package metadata 应明确列出 /usr/bin/qs 和各项可选外部命令依赖。不要打包本地 config、加密 blob、runtime state、录音、JSONL session 或 log。
- 如果行为会影响隐私、provider protocol 或桌面前提,请先创建 issue 或范围明确的 proposal。
- 创建较小的 topic branch,不要把无关的本地配置加入 patch。
- 为纯逻辑增加或更新 unit test。对于桌面或网络行为,请提供可复现的手动测试步骤。
- 公开行为变化时,同步更新
assets/config.toml、Settings、Rust 默认值、README 和两种 Wiki 语言。 - 运行格式检查、all-target check、测试和 legacy runtime rejection check。
- 检查 diff 中是否存在 credential、用户专属 absolute path、transcript、session file、录音或生成产物。
- 提交 pull request,并说明修改原因、兼容性影响、隐私或数据流变化,以及测试证据。
CI 会在 push 和 pull request 时运行,并且只获得仓库内容的只读权限。它检查 Rust formatting、all target 和 test,并拒绝已经淘汰的桌面 runtime asset/reference。CI 通过后,仍然需要执行上面的 compositor、音频、provider 和 Quickshell 手动检查。
English Home · 简体中文首页 · Source repository · MIT License
Voice Input is an independent community project. HUD and Settings require Quickshell 0.3+. Review Security and Privacy before enabling remote ASR, LLM refinement, pre-roll, agent context, or replacing credentials in Settings.
Voice Input 是独立的社区项目。HUD 和 Settings 需要 Quickshell 0.3 或更高版本。启用远程 ASR、LLM refinement、pre-roll、Agent 上下文,或者在 Settings 中替换 credential 前,请阅读安全与隐私。