3DS Store › Apps › DSSH

DSSH changelog

v1.3.0 · Aug 13, 2026

DSSH 的第一个社区贡献版本 🎉 本次合并了 @hedykan 和 @cadl 两位贡献者的全部功能 PR(#5、#6、#7),感谢你们!

新功能

SELECT 键断线重连(#5,by @hedykan)

合盖休眠会冻结 TCP 导致 SSH 硬断开,以前只能退出重进。现在按 SELECT 即可原地重连、秒回原来的 tmux 会话。

蟹蟹吉祥物 6 个新状态(#5,by @hedykan)

重连中张望、成功欢呼、失败沮丧、录音、思考、打字——蟹蟹现在会跟着应用状态卖萌了。

语音打字机流式输出(#5,by @hedykan)

语音转写文本改为逐字流式回传(延迟自适应),不再一次性整段 dump。

macOS Keychain 自动解锁(#6,by @cadl)

连接 macOS 时自动解锁登录 Keychain,Claude Code 可以直接复用已有登录凭据,不用每次重新 login。在 config.ini 中配置:

macos_keychain_password = "你的 macOS 登录密码"

⚠️ 密码以明文保存在 SD 卡上,默认关闭,请自行评估风险。

fish / Kitty 键盘协议渲染修复(#6,by @cadl)

修复了 fish 等 shell 下输入一直卡在屏幕第一行、内容错乱的问题;补充了终端查询响应和正确的初始 PTY 尺寸。

原生 Tailscale 支持(#7,by @cadl)

3DS 可以直接加入你的 tailnet,通过 Tailscale IPv4 或 MagicDNS 名称连接 SSH。传输层由 libts3ds 提供(实验性)。在 config.ini 中配置 tailscale_auth_key 即可启用。

安装

  • .3dsx:放到 SD 卡 /3ds/ 目录,用 Homebrew Launcher 启动
  • DSSH.cia:用 FBI 安装
  • 私钥仍需 ssh-keygen -m PEM 格式(mbedtls 2.28 限制)

致谢

  • @hedykan — SELECT 重连、吉祥物状态、语音打字机
  • @cadl — Keychain 解锁、fish 渲染修复、Tailscale 支持及 libts3ds

两位的功能均经过各自真机验证;合并后的组合构建通过了全部主机端回归测试(config / terminal / IME)。

v1.2.0 · May 31, 2026

两个小但都很有用的改动:终端 Shift+Tab 在软键盘上能打出来了,语音识别从 Whisper 换到 Qwen3-ASR-Flash 解决稳定性 + 中文标点更地道。

⇥ Shift+Tab on the soft keyboard

按住物理 L(Shift)同时点软键盘 tab → 输出 \x1b[Z(CSI Z,terminal 标准的"光标后退一个 tab")。普通点 tab 仍然是 \t 不变。

实用场景:

  • vim/zsh 补全候选反向走:补全菜单里前一项
  • tmux Ctrl-B q 后窗口编号反向切
  • lazyvim 的部分 plugin 用 Shift+Tab 退出嵌套菜单

修改面:source/softkb.c 的 KIND_SEQ dispatch 加 4 行——只对 \t 特判,其他 KIND_SEQ binding 不受影响。

🎙️ ASR 从 Whisper → Qwen3-ASR-Flash

OPENROUTER_AUDIO_MODEL 常量从 openai/whisper-large-v3-turbo 切到 qwen/qwen3-asr-flash-2026-02-10。

为什么换:

  • 稳定性:OpenRouter 的 Whisper Turbo provider 偶尔对某些 IP 段限速 / 阻断,同一段音频走 Qwen 始终成功
  • 中文标点更地道:
  • Whisper:你好世界,今天天气不错
  • Qwen3:你好,世界。今天天气不错。
  • 没有协议改动:OpenRouter 的 /v1/audio/transcriptions endpoint 对 Whisper 和 Qwen3 用完全相同的 JSON 请求 / 响应格式——服务器端 shim 改一个常量就完事,3DS 端代码 0 修改

代价:

  • 单价从 ~\$0.067/音频小时 → ~\$0.13/音频小时(约 2 倍)。个人用一个月仍是几美分级别,可忽略

升级方式:

OpenRouter API key 不变(同一把 key 同时能调 Whisper 和 Qwen)。重跑 install 脚本或者手动 \git pull\ 即可:

cd ~/dssh-repo && git pull
bash tools/install_whisper_api.sh   # 已有 key 不会再问,只刷新 shim

📦 安装 / 升级

| 想要的 | 下载 |
|---|---|
| Homebrew Launcher 启动 | \`3dssh.3dsx\` |
| HOME 菜单图标启动(推荐)| \`DSSH.cia\` |
| 完整 1m42s 演示视频(v1.0 拼音 IME 录的,v1.2 兼容)| \`demo.mp4\` |

从 v1.1 升级

  • 3DS:装新 \.cia\ 即可(覆盖安装)。Shift+Tab 立刻生效
  • 服务器:\cd ~/dssh-repo && git pull && bash tools/install_whisper_api.sh\——shim 会刷新成 Qwen3 版本。下次按 START 自动用新模型

新用户从零安装

按 README 的语音输入章节走 OpenRouter + DeepSeek 两把 key 的一键安装,全套服务器端 ~30 KB、~1 分钟搞定。

v1.1.0 · May 7, 2026

v1.0 把语音输入做完了;v1.1 加了一条与 SSH 平行的语音 AI 问答通道——按住 L+START 说一句问题,底屏弹出问答 modal,DeepSeek 答案直接出现,不打扰顶屏正在跑的 yazi / vim / tmux / claude-code。

🎤 → 🤖 Voice AI ask(v1.1 新增)

[L + START] 录音 32 秒上限
   │
   ▼ 16 kHz PCM → 服务器 shim --ask
[Whisper Turbo] 转写
   │
   ▼ 转出来的中文 → DeepSeek-Chat(带 history)
[DeepSeek] 回答(6-15 句,markdown)
   │
   ▼ JSON 返回 3DS
[底屏 modal 0.5s 淡入]
   │
   ├─ A 关闭 + 保留 history(追问)
   └─ B / 触屏 关闭 + 清空 history(新对话)

用户体验:

  • 顶屏 SSH 完全不动——问 AI 不打断 yazi / vim 状态
  • Markdown 渲染:# 标题 黄色、` code 青色、- 列表 → • 列表、bold` 隐式 strip 不丢内容
  • History 追问:A 关 modal 时保留当前 Q&A,下次 L+START 接续;B 重置开新对话;上限 5 轮 FIFO
  • 录音上限从 8 秒升到 32 秒——多句话问题也塞得下
  • 触发手势:L+START(区别于普通 START 的语音 IME)

服务器端配置——还是一条命令

需要两把 API key(OpenRouter + DeepSeek,均有免费额度):

git clone https://github.com/Fishason/DSSH.git ~/dssh-repo
bash ~/dssh-repo/tools/install_whisper_api.sh
# ↑ 交互式提示输入两把 key

或者非交互式:

OPENROUTER_API_KEY="sk-or-v1-..." \
DEEPSEEK_API_KEY="sk-..." \
bash ~/dssh-repo/tools/install_whisper_api.sh

| Key | 申请地址 | 用途 | 必需性 |
|---|---|---|---|
| OpenRouter | openrouter.ai/settings/keys | Whisper Turbo(语音→文字)| 必需 |
| DeepSeek | platform.deepseek.com/api_keys | DeepSeek-Chat(AI 回答)| L+START 必需,纯语音 IME 不需要 |

费用:Whisper Turbo \\$0.04/音频小时\ + DeepSeek \~\$0.0001/次问答\,个人用月成本几美分。

详细安装文档见 README — 语音输入。

🛠 其它改动(自 v1.0)

  • modal 渲染 z-order 修复:之前 \renderer_draw_text_px\ 内部硬编码 z=0.5,比 modal bg z=0.51 低,文字被背景覆盖看不见。新增 \renderer_draw_text_px_z(x, y, z, text, rgba)\ API 让 modal 用 z=0.62 画文字稳压 bg
  • Aux channel drain loop:voice.c phase 2 改成单帧内 drain 完所有 readable bytes 再判 EOF,避免分包到达时 EOF 早判导致 JSON 截断
  • shim --ask 模式:每条 error path 都走兜底 JSON 输出,3DS 永不收到完全空 reply
  • 诊断日志:\/tmp/dssh-ai-debug.log\ 记录每次 L+START 的 PCM 长度 / 转写文本 / DeepSeek 回答 / 输出 JSON,调试一目了然

📦 安装

| 想要的 | 下载 |
|---|---|
| Homebrew Launcher 启动 | \`3dssh.3dsx\` |
| HOME 菜单图标启动(推荐) | \`DSSH.cia\` |
| v1.0 拼音 IME 演示视频(v1.1 兼容)| \`demo.mp4\` |

🔄 从 v1.0 升级

3DS 端:直接用新 \.cia\ 覆盖。

服务器端:

\\\`bash
cd ~/dssh-repo && git pull
bash tools/install_whisper_api.sh

已有 OpenRouter key 不会再问;新提示输入 DeepSeek key

\\\`

旧的纯语音 IME 仍然可用,只是 L+START 多了一个 AI 问答路径。如果不想用,跳过 DeepSeek key 就行——L+START 会优雅 fail(modal 显示 \"no API key\" 错误)。

🐛 已知边界

  • modal 答案区约 14 行 × 50 字符;超长答案末尾自动 \...\ 截断
  • \**bold**\ 在 6×12 像素字体下没法做加粗效果——syntax 隐去、内容仍显示,但没有视觉强调

v1.0.0 · May 7, 2026

v1.0 是 DSSH 的"功能完整"里程碑——上屏 ANSI 终端、下屏拼音 IME、物理键
完整映射、语音输入全部跑通了。从 v0.4.0 以来唯一的核心新增是 语音输入,
但这是个把 3DS 从"能打字" → "能开口说"的质变功能。

🎤 语音输入(v1.0 新增)

按 START → 说一句中文 → 再按 START → 转写文字直接进 SSH 终端。
端到端约 1-2 秒。

3DS 麦克风 ─ 16 kHz PCM ─► libssh2 第二 channel ─► dssh-whisper-shim
                                                    │
                                                    ▼
                                           OpenRouter Whisper Turbo
                                          (或自部署 whisper.cpp)
                                                    │
                                                    ▼
                                          返回 UTF-8 中文 → SSH 终端
  • 零新端口、零新认证:复用现有 SSH session 开第二个 libssh2 channel
  • 默认走云端 OpenRouter Whisper Large V3 Turbo:~1-2 秒响应、$0.04/小时
  • 可切自部署 whisper.cpp:装 dual track 后一行 dssh-whisper switch local
  • 状态指示:软键盘左上角 红 \"REC\" 脉冲 → 青色 Braille 旋转 → 完成上屏

详见 README 中的 语音输入 章节。

快速开始

到 openrouter.ai/settings/keys
拿一个 API key,然后在服务器:

git clone https://github.com/Fishason/DSSH.git ~/dssh-repo
bash ~/dssh-repo/tools/install_whisper_api.sh
# 按提示粘贴 API key

然后把新版 DSSH.cia 装到 3DS,连上 SSH,按 START 说话即可。

dssh-whisper CLI

dssh-whisper status     # 当前 track + key 是否在
dssh-whisper switch     # toggle api ↔ local
dssh-whisper start      # 启动本地 daemon(双轨装态)
dssh-whisper stop       # 停 daemon(也叫 close)
dssh-whisper logs -f    # tail 日志
dssh-whisper uninstall  # 全卸

两种安装方式对比

| | API 轨(推荐)| 双轨 |
|---|---|---|
| 推理位置 | OpenRouter 云端 | 云端默认 + 本地 fallback |
| 服务器占用 | ~30 KB | ~600 MB(含 small.zh 模型)|
| 4 秒音频延迟 | ~1-2 秒 | API: ~1-2s · 本地 2-30s |
| 费用 | $0.04/音频小时 | 按 track 算 |
| 隐私 | 音频上云 | 本地轨音频不出服务器 |

🛠 其它 polish(自 v0.4.0)

  • font_atlas.c fallback_alias() 扩展 ~30 条 emoji 等价映射:✅→✔ ❌→✖ 🟢🔵🔴→● 🚀→↗ 等。Lazy.nvim / Mason / lspstatus 用 emoji 标注 状态时不再显示 ?。
  • 3DS 顶屏 banner 更新:去掉残留的 \"M7\" milestone 文字,改成 \"DSSH ● pinyin IME (R toggle) ● voice (START to record)\"。
  • 物理键 START 重绑定:原本是 \"退出程序\",由于 3DS HOME 按钮已可 退出任何 homebrew,START 退出冗余;现在 START 是语音输入开关。
  • 新增 ssh_client aux channel API:libssh2 多 channel 包装,未来 其它\"通过 SSH 调远端命令\"的功能(文件浏览、剪贴板同步等)可直接复用。

📦 安装

| 想要的 | 下载 |
|---|---|
| Homebrew Launcher 启动 | \`3dssh.3dsx\` |
| HOME 菜单图标启动(推荐)| \`DSSH.cia\`(用 FBI 安装)|
| 完整演示视频(v0.3 拼音 IME,v1.0 也兼容)| \`demo.mp4\` |

SD 卡部署:私钥 \id_rsa\ 和 \config.ini\ 放 \/3ds/3dssh/\(详见 README)。

🔄 从 v0.4.0 升级

3DS 端:直接用新 \.cia\ 覆盖安装。

服务器端(如果想用语音输入):

git clone https://github.com/Fishason/DSSH.git ~/dssh-repo
bash ~/dssh-repo/tools/install_whisper_api.sh

不想用语音也完全不影响——v1.0 客户端可以连任何标准 SSH 服务器,
START 键不按就什么都不做。

🐛 已知边界

  • 单次录音上限 ~7 秒(受 256 KB mic buffer 限制)。再长可以拆两次。
  • 服务器需要外网出口才能用 API 轨;如果服务器在内网/无外网环境, 装 dual track 即可全离线运行。
  • OpenRouter audio API 计费有 10 秒下限(4 秒音频也按 10 秒收费), 但单价就 $0.000111,完全不影响个人使用。

v0.4.0 · May 6, 2026

本轮针对 v0.3.0 实机使用反馈的体验问题做集中 polish:终端配色与 nvim 对齐、LazyVim 图标无问号、软键盘按住连发、tab/翻页键尺寸优化。

✨ 改动一览

终端配色:Tokyo Night Storm

  • 默认主题从 Catppuccin Mocha 切到 Tokyo Night Storm(LazyVim 默认 colorscheme),nvim 的 truecolor 输出与终端无缝衔接。
  • 默认背景 #1e1e2e → #1a1b26、默认前景 #cdd6f4 → #c0caf5,ANSI 16 色全表替换。
  • 早期的"色彩增益"已移除——尝试过对所有颜色做 (v+12)*1.10 的统一抬升,但会让深蓝背景偏淡、亮蓝代码近白。现在 rgba_to_c2d 是无修改的 raw 直通,nvim 给什么颜色就显示什么颜色。

LazyVim / Nerd Font 图标全集

  • 用 fontTools 直接枚举 SymbolsNerdFontMono 的完整 cmap,把所有 PUA 码位一次性塞进 atlas——新增 8,558 个码位。
  • 覆盖 Devicons、Codicons、Material Design v3 (含 supplementary plane U+F0001+)、Font Awesome、Octicons、Powerline 全集。
  • LazyVim 侧栏文件类型、Lazy.nvim 面板、lualine、tmux 主题中的 ? 图标几乎全部消失。

软键盘 hold 连发

  • 按住任意字符键、tab、空格不放 → 持续重复输出。节奏与物理 D-pad 一致:250ms 初始延迟 → 12/秒 → 30/秒 → 60/秒(三段加速)。[123]/[abc] 翻页键不会反复翻页。
  • IME 候选条点击、调试模式徽章双击仍是单触发(不会被 hold 误触)。

软键盘 row 3 布局优化

  • 字母页:[123](w=2) | tab(w=2) | space(w=6)
  • 符号页:[abc](w=2) | ...| space(w=4) | \\(w=1)
  • [123] 和 [abc] 都是 col 0 起始、宽度 w=2 —— 位置 AND 尺寸都对齐,切页指肌记忆 100% 一致。
  • tab 从 w=1 升到 w=2,触屏命中区翻倍。

底层(无可见行为,但为未来铺路)

  • 字体 atlas 改为 3 层灰度 AA 存储(full / half / quarter alpha)。位图字体(Terminus、Zpix)零成本;future-proof 给将来可能换上的窄宽 TTF(如 Iosevka Term)保留接入点。
  • 实验性的 Liberation Mono ASCII AA 路径试过但已回退——所有 12pt 等宽 TTF 字体(Liberation / DejaVu / FreeMono / Noto / Hack)advance 都是 7-8 px,硬塞 6 px cell 必然右边裁切;唯一原生贴 6×12 的就是 Terminus。

📦 安装

| 想要的 | 下载 |
|---|---|
| Homebrew Launcher 启动 | \`3dssh.3dsx\` |
| HOME 菜单图标启动(推荐) | \`DSSH.cia\`(用 FBI 安装) |

SD 卡部署:把私钥 id_rsa 和 config.ini 放到 /3ds/3dssh/(详见 README)。

🐛 已知问题

  • 6×12 cell 是 3DS 顶屏的硬约束(400÷6≈66 列),现代抗锯齿 TTF 字体(Cascadia Code / Fira Code 等)原生设计宽度都超过 6 px,因此目前无法在不裁切的前提下切到"VS Code 风现代字体"。如果用户愿意接受 cell 升 8×16 + 屏上 50 列 × 15 行(vim 内可见内容显著变少),未来可做这条路径。

v0.3.0 · May 3, 2026

v0.2.0 之后的实机使用反馈,五个改动一起合在 M10 polish 里发布。

改动

  • IME 选词游标 wrap-around — D-pad 左在最左候选 → 跳到本页最右;右在最右 → 跳到最左。不用绕开页边再回来。
  • 新版螃蟹 — 从红色高拱型改成 Anthropic 风的粉色矮宽形(参考截图),4 帧步行循环(休息→抬左 1+3 腿→休息→抬右 2+4 腿)。
  • 网络异常检测 — 启用 libssh2 keepalive 每 10s 一次;25s 内没收到任何 SSH 字节(数据或 keepalive ack)→ 螃蟹切到 ALERT 状态:停步 + 头顶举一个红色 ✕ 来回轻晃。网络恢复后自动收起 ✕ 复走路。
  • 字典更新:
  • 屏蔽 \三国群英传\
  • 新增 ~80 条 2024-2025 现代词(大语言模型 / 提示词 / 思维链 / 内卷 / 躺平 / 云原生 / Devops 一类)
  • \dyymx\ → 大语言模型 首位
  • yazi 图标支持 — 把 Symbols Only Nerd Font 加进 atlas,覆盖 yazi 默认 theme 用到的 282 个 codepoint(Devicons/Codicons/MDI v3 全段,含补充平面 U+F0001+)。yazi 的文件 / 文件夹图标不再显示 \?\。

安装升级

下 \DSSH.cia\ 直接装,会覆盖旧 v0.2.0(同 title-id)。SD 卡 \/3ds/3dssh/\ 的 config.ini + id_rsa 不动,无需重配。

完整 commit history:v0.2.0…v0.3.0

v0.2.0 · May 3, 2026

关键改动 — 全部基于 v0.1.0 后的实机使用反馈(commit ed0fb6c)。

新功能

  • A 键 IME→英文逃生:CN 模式下不小心打了英文(比如 cd /etc)?按 A 把拼音 buffer 当 ASCII 直接发到 SSH 并清空,不用退格 + 切模式 + 重打。Space 现在是唯一的"提交候选"键。
  • L + Circle Pad → 切右窗格滚动:tmux vertical-split 里默认 Circle Pad 永远滚左窗格;现在按住 L 同时滚动会发到右/下窗格的坐标,让 tmux 路由到对的窗格。
  • Shift + . → 。:字母页快速打中文句号 U+3002,跟 sogou/搜狗的习惯一致。EN/CN 模式都生效。
  • 符号页加 ?:之前 row 2 漏了问号,现在 10 键无 stagger 跟 row 1 对齐:- + = [ ] ; : ' / ?。

改进

  • Debug 页面的物理键说明同步更新(双击右上 ENG/CHN 进入)
  • README 加了「tmux 分屏滚动」「误打英文逃生」两个专门小节
  • 内部 out_buf 16→64 字节,确保 IME buffer 满 31 字符也能完整 dump

安装

下载 \DSSH.cia\ (~14 MB) 拷到 SD → FBI 安装。或者下 \3dssh.3dsx\ 通过 Homebrew Launcher 跑。SD 卡 \/3ds/3dssh/\ 需要有 \config.ini\ 和 \id_rsa\,详见 README。

升级

如果你已经装了 v0.1.0:直接装 v0.2.0 的 .cia 就会覆盖旧版(title-id 一样)。SD 卡的 config.ini + id_rsa 不动,无需重配。

完整 commit history:v0.1.0…v0.2.0

v0.1.0 · May 1, 2026

First public release of DSSH — Nintendo 3DS SSH client with Chinese IME.

安装

下载 \DSSH.cia\ (~14 MB) → 拷到 SD → FBI install → HOME 菜单出现橙色 DSSH 图标。

或者下 \3dssh.3dsx\ 直接通过 Homebrew Launcher 启动。

启动前需要在 SD 卡 \sdmc:/3ds/3dssh/\ 放好 \config.ini\ 和 \id_rsa\,详见 README。

已实现功能(M0 → M9 全部完成)

  • libssh2 + mbedTLS 跑 RSA-4096 公钥认证
  • citro2d 上屏 ANSI/VT100 终端,21k+ CJK 汉字 + ASCII 字体 atlas
  • 自绘软键盘(iOS 风圆角 + 平滑下沉动画)
  • 拼音 IME:rime-ice 30 万词典 + 缩写匹配 (\nh\→你好) + 前缀回退
  • 修饰键 hold-style + D-pad 候选导航 + 候选条触屏选词
  • Anthropic 红螃蟹吉祥物
  • 隐藏 debug 页面(双击右上 ENG/CHN)

测试环境

  • 旧 3DS / New 3DS(破解)+ Homebrew Launcher / FBI
  • 服务器侧:Ubuntu OpenSSH 8.x,OpenSSH RSA-SHA2 兼容