Vibe Coding 遥控器是一个把手机输入体验桥接到电脑当前焦点位置的小工具。
它的核心思路很直接:不再试图重新发明一套电脑端语音输入,而是复用手机上已经很好用的输入法,尤其是语音输入、联想输入和中文输入生态。
这个项目来自一个很具体的痛点。
最近我大量在用 AI 编程工具,例如 Codex、Claude Code 一类产品。用得越多就越明显地感觉到,很多时候表达速度的瓶颈不是想法本身,而是打字。于是我很自然地开始尝试用语音输入代替一部分键盘输入。
但电脑上的语音输入体验一直没有让我满意。豆包电脑版、微信电脑版,还有一些接大模型 API 的第三方工具,我都试过。它们各有优点,但整体上还是有几个共通问题:
- 识别效果不如手机上的输入法稳定
- 一些常用词、技术词、口语语气词处理得不够自然
- 把识别结果真正插入到当前光标位置这件事,成功率并不总是可靠
- 在安静环境里,对着电脑说话也不一定是最舒服的方式
反过来,手机上的输入法,尤其是我常用的手机版豆包输入法,体验明显更好。它的语音输入更顺,低音量下识别也更稳,输入法本身的交互已经被打磨得很成熟。所以这个项目真正想做的是:
把手机上成熟、顺手、自然的输入体验,直接桥接到电脑当前的工作流里。
它不只适合 AI 编程。只要你的场景是“在手机上说话或输入,再把结果落到电脑上”,它都成立。比如:
- 电脑没有麦克风
- 电脑麦克风收音很差
- 你所在的环境更适合对着手机低声说话
- 你更喜欢手机输入法的语音识别效果和交互手感
Vibe Coding 遥控器从一开始追求的就不只是“能用”,而是“顺手”。
目前这套交互重点在于:
- 尽量不打断手机输入法,尤其是连续语音输入
- 让高频操作尽量留在手机键盘附近完成
- 把发送、换行、退格这些动作做成低摩擦的闭环
- 让网页更像输入工具,而不是一个普通表单页
一个典型 AI 编程场景会是这样:
- 手机打开Vibe Coding 遥控器页面,键盘弹出。
- 按住空格开始语音输入。
- 等输入法完成最终整理。
- 点击发送,把文本插到电脑当前光标处。
- 再触发一次电脑上的 Enter,把这段内容真正发给 AI。
整个过程里,手机承担“输入体验”,电脑承担“落点执行”。
- 手机网页输入文本并发送到电脑当前焦点位置
- 复用手机语音输入法,把整理后的文本直接落到电脑
- 发送任意按键、组合键和按键序列到电脑当前焦点位置
- 启动时打印推荐局域网访问地址
- 启动时生成移动端导入配置二维码,方便手机导入 server 地址和 token
- 前端支持:
- 深色 / 浅色 / 跟随系统
- 回车发送 / 回车换行
- Dock 按钮显隐
- 最近发送历史
- 草稿自动保存与恢复
如果你只是想直接使用前端页面,可以先打开:
https://enximi.github.io/vibe-coding-remote/
推荐使用流程:
- 在电脑上下载并运行本地
server - 在手机上打开上面的 GitHub Pages 页面
- 把本地
server的地址和 token 配进页面,或者直接扫码导入 - 先在电脑上把光标放到目标输入框,再开始在手机上输入或语音输入
这条在线地址的意义是:
- 你不需要自己部署前端
- 用户不需要运行 Vite 或下载整个仓库
- 大家只需要拿到前端页面,再单独运行本地
server即可
需要注意:
- 这个在线页面本身是 HTTPS
- 如果本地
server还是纯 HTTP,浏览器通常会拦截跨协议请求 - 所以更稳定的发布方式是:本地
server也提供 HTTPS,或者通过 HTTPS 隧道暴露给手机浏览器
当前“把内容真正输入到桌面焦点位置”这一层仍然是 Windows 优先实现。
原因是桌面输入依赖:
- Win32
SendInput - Windows 焦点窗口输入
- Windows 剪贴板
不过前端已经重构成了 monorepo 结构,当前由同一套 React UI 支撑 Web 壳,后续也方便继续扩展其他客户端。
vibe-coding-remote/
├─ apps/
│ ├─ web/ # Web 壳:Vite dev server + 手机浏览器入口
├─ packages/
│ ├─ app/ # 共享 React UI、状态模型、组件、样式
├─ crates/
│ └─ server/ # Rust 本地服务:API、输入执行、局域网访问地址输出
└─ ...
这套结构的原则是:
packages/app只关心产品 UI 和交互,不关心运行平台apps/web只做“壳”和平台桥接crates/server负责本地 API 与桌面输入执行
cd D:\projects\vibe-coding-remote
pnpm installpnpm run dev:web另开一个终端,再启动本地 Rust 服务:
just dev-server如果要让手机从局域网访问本机 server,可以用:
just dev-server-lan开发时手机访问:
https://你的电脑局域网IP:5173
这时:
- 页面资源来自 Vite
/api由 Vite 代理到 Rust8765- 如果本地不存在
.cert/dev-cert.pem和.cert/dev-key.pem,Vite 会回退为普通 HTTP 开发模式
just build-server这会构建 Rust release 版本地 API 服务。
产物位于:
target/release/vibe-coding-remote.exe
手机浏览器 -> Vite (5173) -> /api -> Rust (8765)
手机浏览器 / App -> 独立部署的前端
-> /api -> Rust (8765)
发布模式下:
server只提供 APIweb需要独立部署server已开启 CORS,允许跨源前端直接访问
仓库已经包含 GitHub Pages workflow:
默认行为是:
- push 到
main - GitHub Actions 自动构建
apps/web - 产物部署到 GitHub Pages
第一次使用时,还需要在 GitHub 仓库设置里把 Pages 的构建来源切到:
Settings -> Pages -> Source -> GitHub Actions
如果仓库地址是:
https://github.com/enximi/vibe-coding-remote
那么默认 Pages 地址会是:
https://enximi.github.io/vibe-coding-remote/
当前 vite.config.ts 会在 GitHub Actions 中自动把 base 设置为仓库名路径,因此项目页模式可以直接工作。
如果以后改成自定义域名,可以在构建时传入:
VITE_BASE_PATH=/
需要注意:
- GitHub Pages 是 HTTPS
- 浏览器通常不允许 HTTPS 页面直接请求 HTTP 的本地 API
- 所以如果前端部署在 Pages,上游
server最好也提供 HTTPS,或者通过 HTTPS 隧道暴露给手机浏览器
server 当前通过统一动作接口接收请求:
POST /api/action受保护接口需要 Bearer token:
Authorization: Bearer <token>把一段文本输入到当前焦点位置。
动作类型为 input-text:
{
"action": {
"type": "input-text",
"text": "你好,世界"
}
}发送任意按键、组合键或连续按键序列。
按键名使用 keyboard-types 的 Code 命名,表示物理键位。
发送一次 Enter:
{
"action": {
"type": "key-sequence",
"sequence": [
{
"keys": ["Enter"]
}
]
}
}发送 Ctrl+V:
{
"action": {
"type": "key-sequence",
"sequence": [
{
"keys": ["ControlLeft", "KeyV"]
}
]
}
}先粘贴,再按 Enter:
{
"action": {
"type": "key-sequence",
"sequence": [
{
"keys": ["ControlLeft", "KeyV"]
},
{
"keys": ["Enter"]
}
]
}
}sequence 的语义是:
- 外层数组按顺序执行
- 每个对象表示同一组同时按下的按键
keys使用keyboard-types的Code命名- 每一组按键会完整执行按下和释放,再进入下一组
健康检查。
返回:
ok
文字输入目前主要走:
剪贴板写入 + 粘贴
流程是:
- 前端调用
/api/action - Rust 收到
input-text动作 - Rust 把文本写入系统剪贴板
- 等待一个很短的时间片
- Rust 模拟一次
Ctrl+V - 文本出现在电脑当前焦点位置
这样通常比逐字模拟键盘输入更稳,尤其适合中文、语音输入和长文本。
按键序列则通过 Win32 SendInput 模拟。协议层使用 keyboard-types 的 Code 表示物理键位,server 在 Windows 上把这些键位映射到实际输入事件。
因为 Vite 开发服务器的资源在内存里。
开发时要看最新页面,请直接访问 5173。apps/web/dist 只有执行构建时才会更新。
因为独立部署后的 Web 页面和本地 server 不再同源,前端必须明确知道目标 server 的 API 地址。
当前最直接的方式是给页面带上 endpoint 参数,例如:
https://你的前端域名/?endpoint=http://192.168.1.23:8765/api/action
常见原因:
- 手机和电脑不在同一个局域网
- Windows 防火墙没有放行 Node / Vite 的入站连接
- 路由器或校园网启用了客户端隔离
- 当前电脑 IP 已经变化
因为普通桌面应用并没有一个统一、稳定、跨应用的“直接写入文本框”系统 API。
更通用的方案通常是:
- 模拟键盘输入
- 或者通过剪贴板 + 粘贴
Vibe Coding 遥控器目前主要选择后者。
后续可以继续扩展的方向包括:
- 补齐移动端客户端体验
- 多端共享更多平台桥接能力
- 设备发现与配对
- WebSocket 实时状态同步
- macOS / Linux 支持
本项目采用 MIT / Apache-2.0 双授权。
你可以任选其一使用:
除非你明确声明否则,提交到本仓库的贡献也将按相同的双授权方式发布。