Files
openless/openless-all
e1c1be2942 feat(coding-agent): OpenCode CLI 适配器,语音 Agent 可选 OpenCode 后端 (Refs #579) (#638)
* feat(coding-agent): OpenCode CLI 适配器,语音 Agent 可选 OpenCode 后端 (issue #579)

把 OpenCode 当作与 Claude Code 同类的 coding agent CLI 接入,照既有 coding_agent
适配模式(不另造架构),复用同一套 CodingAgentRequest / CodingAgentEvent /
CodingAgentError / 审批护栏链路。

后端:
- coding_agent/opencode.rs(新):detect_opencode(opencode --version)、
  build_opencode_args(opencode run --format json --model --dir
  [--dangerously-skip-permissions],prompt 作为 argv)、parse_opencode_json_line
  (NDJSON:text/tool_use/error;text 块累计,EOF 合成 Completed)、
  run_opencode_agent(取消/超时 kill,护栏经 OPENCODE_CONFIG_CONTENT 注入)。
- coding_agent/args.rs:CodingAgentProvider 枚举(claude-code-cli/opencode-cli,
  未知回落 Claude)+ from_pref/default_exe。
- coding_agent/guard.rs:build_opencode_guard_config —— 把高风险 bash 前缀翻译成
  OpenCode permission.bash deny glob + webfetch deny,审批放行的前缀显式 allow。
- coordinator/dictation_voice_agent: run_less_computer_once 按 coding_agent_provider
  分派 Claude / OpenCode 运行器;两路都 fail-closed(护栏生成失败即中止,不裸跑)。
  审批拦截探测/重跑放行链路 provider 无关,自动复用。
- commands: coding_agent_detect_opencode 命令(已注册 lib.rs)。

前端:
- CodingAgentSection: OpenCode 选项从「即将支持」改为可用 + 选中后探测安装状态并提示。
- ipc: codingAgentDetectOpencode + OpenCodeDetection。
- i18n: opencodeReady / opencodeMissing(5 语言,替换 providerOpenCodeSoon)。

验证:cargo check + cargo test(492 通过)+ npm run build 均通过。

Refs #579
(#579 还含「语音润色模型配置」:prefs 字段已存在但全链路未实现/未接 UI,
转写直接进 agent 未经语音润色模型整理 —— 故用 Refs 不用 Closes。)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(coding-agent): OpenCode 防参数注入 + 可配置 Agent 可执行文件路径 (#638)

注入风险(@H-Chris233 评审):`opencode run` 的 prompt 作为最后位置参数,但之前缺
end-of-options 分隔。以 `-` / `--` 开头的 prompt(语音转写或被 prompt 注入诱导)会被
OpenCode 当作 flag 解析,可绕过护栏(混入 --dangerously-skip-permissions、--dir 改写
工作目录等)。修复:build_opencode_args 末尾追加 `--`,运行器把 prompt 接在其后;新增单测。

可配置路径(@PR-Agent 指出之前 hardcode "opencode"):新增 prefs.coding_agent_exe,
语音 Agent 路径据此取 exe(留空回退默认 claude / opencode),检测命令亦用配置路径;
设置「高级 → Less Computer」新增「可执行文件路径」输入;补 5 语言 i18n。

---------

Co-authored-by: 吕柏青 <lubaiqing9@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
2026-06-24 12:30:12 +08:00
..

OpenLess All-Platform

This is the current cross-platform OpenLess workspace.

App Directory

The runnable Tauri app lives in app/. The macOS build links a vendored C ASR engine (Open-Less/qwen-asr, forked from antirez/qwen-asr) tracked as a git submodule under app/src-tauri/vendor/qwen-asr/, so initialize submodules on first clone.

# First clone only — pull in vendored submodules
git submodule update --init --recursive

cd app
npm ci
npm run tauri dev

macOS Build

Use the project build script instead of calling tauri build directly:

cd app
INSTALL=0 ./scripts/build-mac.sh

Generated macOS artifacts:

  • app/src-tauri/target/release/bundle/macos/OpenLess.app
  • app/src-tauri/target/release/bundle/dmg/OpenLess_1.1.0_aarch64.dmg

For local install during development:

cd app
./scripts/build-mac.sh

Windows Build

The runnable Tauri app is still app/. Windows contributors should run a preflight before building so missing MSVC, Windows SDK, or MinGW tools fail with actionable messages.

cd app
powershell -ExecutionPolicy Bypass -File .\scripts\windows-preflight.ps1

MSVC Route

Use this route when Visual Studio Build Tools and the Windows SDK are installed. Open a Developer PowerShell, or call vcvars64.bat, then run:

cd app
npm ci
npm run tauri -- build

Required Visual Studio Installer components:

  • Microsoft.VisualStudio.Workload.VCTools
  • MSVC v143 x64/x86 build tools
  • Windows 10/11 SDK that provides kernel32.lib

If link.exe or kernel32.lib is missing, rerun:

powershell -ExecutionPolicy Bypass -File .\scripts\windows-preflight.ps1 -Toolchain msvc

GNU / MinGW Route

Use this route when MSVC/Windows SDK is unavailable. The app now lives under the no-space openless-all directory to avoid GNU/MinGW path quoting issues while generating import libraries. Use the helper script to keep the GNU build environment and target setup consistent.

cd app
scoop install rustup mingw
rustup toolchain install stable-x86_64-pc-windows-gnu
rustup target add x86_64-pc-windows-gnu
powershell -ExecutionPolicy Bypass -File .\scripts\windows-preflight.ps1 -Toolchain gnu
powershell -ExecutionPolicy Bypass -File .\scripts\windows-build-gnu.ps1

Generated GNU artifacts:

  • %TEMP%\openless-windows-gnu\src-tauri\target\x86_64-pc-windows-gnu\release\openless.exe
  • %TEMP%\openless-windows-gnu\src-tauri\target\x86_64-pc-windows-gnu\release\bundle\msi\OpenLess_*_x64_en-US.msi
  • %TEMP%\openless-windows-gnu\src-tauri\target\x86_64-pc-windows-gnu\release\bundle\nsis\OpenLess_*_x64-setup.exe

Hotkey Injection Gate

Use this gate before/after Windows hotkey changes when a physical keyboard regression is unavailable. It injects a dev/test-only hotkey click through the coordinator handle_pressed / handle_released path, asserts the log contains [coord] hotkey pressed, and cancels the dry-run session automatically.

cd app
npm run check:hotkey-injection

Windows Runtime Notes

  • Windows does not need the macOS Accessibility permission. Use Settings -> Permissions -> Global hotkey to inspect listener status.
  • Microphone permission is checked by opening a short-lived input stream, so a device-format query alone is not treated as permission granted.
  • Text insertion through Ctrl+V is treated as copy fallback unless the app can confirm insertion.

Release Signing

Tagged releases (v*-tauri) must be Developer ID signed and notarized so users can download and open the macOS app without manually removing quarantine attributes.

Required GitHub secrets:

  • APPLE_CERTIFICATE
  • APPLE_CERTIFICATE_PASSWORD
  • APPLE_ID
  • APPLE_PASSWORD
  • APPLE_TEAM_ID

Optional:

  • APPLE_PROVIDER_SHORT_NAME
  • KEYCHAIN_PASSWORD

Manual workflow runs can still produce ad-hoc signed test builds, but tagged macOS releases fail if signing/notarization secrets are missing.

Ignored Local Output

The following are intentionally local-only:

  • app/node_modules/
  • app/dist/
  • app/src-tauri/target/
  • app/src-tauri/gen/
  • .DS_Store