-
Notifications
You must be signed in to change notification settings - Fork 0
Development.zh CN
Crate 使用 Rust edition 2024,并提交 Cargo.lock。项目的构建和验证 target 都会强制使用 lockfile:
cargo build --release --locked
# 等价的项目 target:
make build从源码运行 daemon 前必须先停止已安装的 service,因为两者会使用相同的 runtime socket:
systemctl --user stop voice-input.service
VOICE_INPUT_ASSET_DIR="$PWD/assets" cargo run --locked -- daemon源码 daemon 仍会读取常规用户配置和 runtime directory。测试结束后请重新启动已安装的 service。
src/
main.rs TLS 设置与顶层退出处理
args.rs 手写 CLI 解析与帮助信息
app.rs 命令分发、diagnostics、Settings 启动
daemon.rs control socket、采集、session/finalization pipeline
config.rs TOML schema、默认值、验证与迁移
diagnostics.rs schema 4 隐私安全支持数据
credentials.rs systemd/environment credential 解析与加密
focused_window.rs 有边界的 Hyprland/Kitty 目标探测
agent_context.rs 开始时创建的 Pi/Codex 术语快照
backend.rs ASR trait、control 与 event
backend/
local_cli.rs /usr/bin/voxtype adapter 与 process 边界
qwen_realtime.rs Qwen Realtime WebSocket adapter
qwen_batch.rs compatible 完整音频 HTTP pass
qwen_audio3/
streaming.rs 实验性 Streaming protocol 与重连
native.rs 实验性 Native 完整音频 pass
text.rs transcript 提取与 OpenCC 转换
http_client.rs 有边界且清理错误的 HTTP helper
llm.rs 目标感知 refinement 与共享 deadline
output.rs Wayland/XWayland clipboard 投递及 helper
settings_backend.rs 带版本的 Settings NDJSON 与持久化
state.rs 状态机和私有原子持久化
waveform.rs PCM 分析与 Unix socket publisher
wav.rs 有边界的临时 PCM16 WAV 处理
paths.rs, setup.rs 安装路径与 setup helper
assets/
config.toml 规范的公开 sample/default reference
voice-input*.service systemd 用户 unit template
quickshell/ 常驻 HUD QML 与 shader source
quickshell-settings/ 按需启动的 Settings QML
pi/ Pi session-registry extension
omarchy-*.conf/jsonc Hyprland 与 Waybar snippet
docs/ Audio3 决策/评估与实验记录
.github/workflows/ci.yml CI 验证
公开行为变化时,应同步更新 assets/config.toml、Rust 默认值和迁移、Settings 默认值/UI、两份 README,以及两种 Wiki 语言。常驻 HUD 与按需启动的 Settings 是生命周期不同的两套 Quickshell 配置。
运行全部标准本地检查:
make validate
make hud-shaders QSB=/usr/lib/qt6/bin/qsb
/usr/lib/qt6/bin/qsb --dump target/quickshell/shaders/wavy-halo.frag.qsb
git diff --checkmake validate 会运行 import-aware qmllint、Rust 格式检查、all-target check、测试,以及将 warning 视为错误的默认 Clippy lint。Qt 工具位于其他路径时,请设置 QMLLINT 或 QSB。
CI 还会使用 Qt 6.8.3 qmlformat 解析每个 QML asset;该语法检查是本地 qmllint 的补充,不能替代后者。Shader job 要求 QSB 精确包含六个 target:SPIR-V 100、GLSL 100 es、GLSL 120、GLSL 150、HLSL 50 和 MSL 12;同时验证 reflection 中 uniform block buf 位于 binding 0,qt_Matrix 是 offset 0、大小 64 byte 的 mat4,qt_Opacity 是 offset 64、大小 4 byte 的 float。
Rust 测试覆盖的边界包括:
- 当前/旧版 TOML、Audio3 endpoint 与 final-pass 迁移、preset、vocabulary 限制和字段验证;
- CLI 解析、control 命令/响应上限、连接准入、过期 idle generation 和 restart 语义;
- Qwen Realtime 与 Audio3 event 解析、transcript assembly、重连/重放 policy、timestamp metadata、Native 选择和结果优先级;
- schema 4 diagnostics allowlist、聚合上限和已清理的 provider identifier;
- LLM response 验证、目标 prompt、去除术语的重试、OpenRouter sorting,以及共享的 1–30 秒 deadline;
- Pi/Codex session 验证、脱敏、分词、低频排序、consumer 上限和本地技术术语归一化;
- PCM16 fragmentation(包括奇数字节读取)、波形 chunk independence、可复用输出 buffer、对称性、NDJSON framing 和 publisher backpressure;
- 本地 ASR 与输出 child process 的 timeout、process-group termination、并行 stdout/stderr 排空、输出上限、可执行文件探测、clipboard-only 路由和错误清理;
- 私有/原子 state 持久化,以及带版本 Settings request、精确源 revision conflict、完整字段验证、credential keep/replace 和 restart failure 报告。
测试不会使用真实麦克风、compositor、远程 provider account、Kitty/Pi/Codex process、Quickshell rendering、clipboard manager 或完整 systemd credential lifecycle。QML 会经过 lint 和 parse,但 malformed-frame recovery、多显示器 rendering 等行为仍需要人工集成验证。
请使用不敏感的音频/文本、可丢弃的剪贴板内容,以及允许产生远程测试费用的账号。
- 启动两个用户 service;只检查
control.sock、state.json和waveform.sock的 metadata,不打印 state,然后运行voice-input diagnostics。 - 测试
record start、stop、toggle、cancel和restart;确认 idle 时 restart 被忽略,只有 active session 会启动 replacement。 - 测试随附的 F8/F9/F10 Hyprland binding,以及 hold mode 的
bind/bindr配对,包括 modifier release 和 finalization 期间排队的 control。 - 验证 arming、实时 partial text、waveform 可见性、350 ms no-speech grace、最终空结果,以及达到
audio.max_duration_secs后自动停止。 - 分别验证 Qwen Realtime 正常完成、一次受控重建、delivery overload、完整音频 final pass 和本地 fallback。
- 对实验性 Audio3,验证 Regional/Custom 路由、区域 credential、preset、language hint、heartbeat、vocabulary、一次 4× 重放重连,以及 Streaming-only/Adaptive/Always Native policy。
- 使用
voice-input asr stream-test --file …与voice-input asr test --file …隔离 Audio3 API;这些命令会发送远程请求,并可能产生费用。 - 验证原生 Wayland 与 XWayland 粘贴目标、兼容 clipboard manager 下的 sensitive Wayland payload、可丢弃剪贴板内容的恢复、helper timeout 行为和 Fcitx5 恢复。
- 移动/重置 HUD;测试焦点变化、多显示器、热插拔/重连、只重启 daemon、只重启 HUD,以及 malformed/stale state 或 waveform input 不会替换上一份有效 UI state。
- 安装 extension 后重启/reload Pi。在 Pi/Codex 中开始 dictation,并在停止前改变焦点,确认开始时术语与停止时目标风格相互独立。
- 连续打开两次 Settings,确认只激活一个窗口。测试只保存配置、credential keep/replace、Test LLM、过期 revision conflict、部分 restart failure、request timeout、backend crash、malformed/oversized/wrong-ID response、有限自动重启和手动 Reload 恢复。
- 确认
voice-input diagnostics --format json不包含 transcript、endpoint、model、credential、vocabulary term、Agent source 或 provider message。绝不附加 status 输出或未经检查的 journal。
- 失败时保留识别文本: LLM failure 不得丢弃有效 ASR 输出。
- 一份 refinement deadline: prompt/context 工作与纯 transcript 重试共用一份最多 30 秒的预算;预算至少为 10 秒时,为恢复保留五秒。
-
采集不承受 backpressure: capture 不得等待远程 ASR 或 HUD client。音频 control queue 和 waveform queue 有界且非阻塞;overload 转向完整缓冲音频恢复。ASR event channel 当前仍是标准无界 Rust
mpsc,在单独完成架构重构前,不得把它记录或假设为有界。 - 所有外部边界都有限制: command、response、file、network message、process output、recording、retry 和 wait 都需要明确上限,并定义 timeout、disconnect 与 partial-data 行为。
- 清理错误内容: 面向用户的 error 和常规日志不得暴露 provider body、child stderr、transcript、clipboard 内容、credential、术语或 session 数据。
- 冻结单次操作上下文: 开始时术语不可变,并与停止时目标分类相互独立。保留验证、脱敏、各 consumer 上限和 prompt isolation。
-
Secret 只通过 stdin: Settings replacement 采用 QML stdin → Rust →
systemd-credsstdin,不进入 TOML/argv/environment/log/response。QML 托管 string 的清理仍只能尽力执行。 - 持久化由 Rust 负责: schema 验证、私有权限、原子替换、locking、完整字段保留和精确源 conflict 不得移入 QML。
- 把 QML 输入视为不可信: 共享 Process/Socket/Timer 位于 screen variant 之外;完整 protocol/state/waveform frame 通过验证后才能一次原子赋值;保留上一份有效值,并限制 backend restart。
- 保留 clipboard 隐私语义: 所有输出继续使用 clipboard paste;Wayland transcript 与恢复 payload 使用 sensitive hint,XWayland 不提供同等保证。
-
保留 Qt 6 shader ABI: 编译
.qsb,遵循 Qt uniform block/reflection layout,输出 premultiplied alpha,并保留全部 CI target。
packaging/ 目前没有发行版 package recipe;安装由 Makefile 实现。make install 会:
- 把 release binary 安装到
$(PREFIX)/bin; - 编译并安装 HUD shader、QML asset、Settings 和内置 font 到
$(PREFIX)/share/voice-input; - 把 Pi extension 安装到
~/.pi/agent/extensions; - 生成用户 service template 并安装桌面 snippet;
- 创建私有 config 和加密 credential directory;
- 仅在用户配置不存在时创建配置,并可能迁移已识别的旧文件;
- 删除旧版 GTK/Python 安装 asset。
PREFIX 不会重定位所有用户路径。Packager 必须设置 SYSTEMD_USER_DIR、PI_EXTENSIONS_DIR、CONFIG_HOME 等变量,或者明确 staging 文件。不要打包本地 config、credential、runtime state、recording、clipboard backup、session JSONL、log 或生成的 build output。
仓库贡献指南定义了 Rust、QML、Quickshell、shader、资源边界和验证标准。
- 使用范围明确的 topic branch,不要把无关本地配置加入 patch。
- 为解析和不变量增加 unit test;对于 compositor、audio、provider 或 QML 行为,记录可复现的人工检查。
- 公开行为变化时,同步更新全部公开 schema surface 和两种文档语言。
- 运行上文完整验证与 shader 命令;检查 QSB target/reflection,并运行
git diff --check。 - 检查 patch 中是否包含 credential、用户绝对路径、transcript、术语、clipboard backup、session file、recording 或生成 artifact。
- 在 pull request 中说明兼容性、迁移、隐私/data flow、资源限制和测试证据。
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 前,请阅读安全与隐私。