Skip to content

Releases: youridol/dsh-launcher

v0.5.6

Choose a tag to compare

@github-actions github-actions released this 04 Sep 13:48

修复

  • 开窗探测误判导致弹窗卡"正在打开"30s 超时
    • 根因:web_ready 判定 HTTP 200 才就绪,但实测 dsh web 对带 token 请求返回
      303 See Other(重定向到 / 走会话交换,浏览器跟随后才 200)——裸 HTTP GET
      永远到不了 200 → 探测永不通过 → 前端轮询 30s 超时报"HTTP 未返回 200"。
    • 修复:就绪判据改为 2xx/3xx(200/301/302/303/307 均视为 HTTP server 完整响应、
      路由已挂);404(冷启动路由未挂)/401/5xx/连接失败仍视为未就绪。新增
      http_status_is_success 纯函数 + 单测覆盖。
    • 效果:内嵌与外部浏览器两条路径都能在 dsh 真正可服务后立即打开(不再 30s 卡死)。
  • dsh web 访问地址(token URL)明文写入日志与前端日志流
    • 产品决策(所有者明确要求):用户需从日志复制完整带 token 的访问地址在外部
      浏览器手动打开(裸 URL 会被 dsh 401 "authentication required" 拒绝)。
    • 安全权衡说明:日志仅本机用户可读写(LOCALAPPDATA),不再对 token 打码;
      dsh stdout 落盘文件(dsh-web-stdout.log)本就不打码,此改动使统一日志
      (launcher 侧)与前端日志面板同样可见完整 token。
  • 外部浏览器打开按钮:随就绪探测修复,带 token URL 正常打开(此前同样被探测卡住)。

v0.5.5

Choose a tag to compare

@github-actions github-actions released this 04 Sep 13:23

修复

  • 冷启动弹出内嵌窗口命中 404("找不到此 127.0.0.1 页 / HTTP ERROR 404"),须关闭重开
    • 根因:端口监听/TCP 通 ≠ HTTP 路由就绪。冷启动时 dsh 先监听端口、后挂 SPA 路由,
      期间带 token 请求返回 404;此前"等 token + 固定 1s"是启发式,token 打印瞬间
      HTTP 路由可能仍未挂好 → WebView2 首载命中 404 错误页且不自动恢复。
    • 修复:改为真实 HTTP 就绪探测——新增 Rust core::port::web_ready()(TcpStream
      手写最小 HTTP/1.1 GET,请求带 token 完整 URL,读状态行判定 200)+ IPC 命令
      probe_web_ready
      • 前端 openWithGuide:拿到 token URL 后轮询 probeWebReady 直到 HTTP 200
        (≤30s,700ms 间隔)才开窗;
      • Rust open_web_gui_window(快捷方式/autoOpen 路径):同步轮询 web_ready
        (≤20s)再建窗。
    • 效果:内嵌窗口只在 dsh web 真正可服务(HTTP 200) 后弹出,冷启动首载即成功,
      不再出现 404 需手动重开。

v0.5.4

Choose a tag to compare

@github-actions github-actions released this 04 Sep 13:16

修复

  • 启动后内嵌窗口在 dsh 打印新 token 之前过早弹出(弹窗显示"打开内嵌窗口…"后立即出窗,
    需手动重开):
    • 根因:process.rs start_locked 启动新 dsh 时不清除上一轮的 token 缓存
      (last-web-url 文件)。冷启动/异常退出后重启,旧缓存残留 → 前端 waitForWebUrl
      get_web_url 兜底读到旧 token 秒回 → 不等当前 dsh 输出新 token
      dsh web: http://127.0.0.1:3080/?token=…)窗口就弹出 → 旧 token 无效 → 首载失败。
    • 修复:
      1. start_locked spawn 成功后清空内存 web_url + last-web-url 缓存,前端只能
        轮询到当前进程输出的新 token 才放行;
      2. 前端 waitForWebUrl 增加校验:仅接受token= 的完整 URL 才返回
        (裸 URL / 无 token 值一律继续等,杜绝 401 死窗口)。

v0.5.3

Choose a tag to compare

@github-actions github-actions released this 04 Sep 13:11

变更

  • 启动后打开内嵌窗口增加 1 秒就绪缓冲
    • 前端(StatusCard openWithGuide)与 Rust(open_web_gui_window)两条路径统一:
      拿到带 token 完整 URL(dsh 打印 dsh web: http://127.0.0.1:<port>/?token=…)后
      再等 1 秒才创建内嵌窗口。
    • 原因:token 刚输出的瞬间 dsh web 服务/前端资源可能仍在预热(首屏资源、插件
      serve 未完),立刻开窗会首载失败/白屏,需手动重开一遍;1 秒缓冲后首载即成功。
    • 前端 waitForWebUrl 已保证等 token 出现(≤40s),Rust 路径等 token ≤10s,两者
      之后统一 +1 秒缓冲,与"完全启动后 1 秒弹出"的用户预期一致。

v0.5.2

Choose a tag to compare

@github-actions github-actions released this 04 Sep 13:06

修复

  • 内嵌 Web GUI 白屏 + 所有窗口无法关闭(需任务管理器强杀)——主线程死锁
    • 根因:create_web_gui_window 命令在 async 运行时线程执行同步 fn,内部
      run_on_main_thread(建窗) + std::sync::mpsc::recv() 阻塞等待主线程建窗结果
      当主线程正被 WebView2 的同步窗口消息占用(内嵌 dsh UI 页面加载/交互时常见,
      Windows 窗口消息模型下主线程处理 WebView 消息期间不会让出给 run_on_main_thread
      排队的闭包)→ 主线程与等待它的命令线程交叉死锁 → 内嵌窗口停在白屏、主窗口
      及所有窗口事件循环卡死、无法关闭。
    • 修复:命令改为 async fn,把建窗调度到主线程后立即返回(fire-and-forget),
      不跨线程阻塞等待
      ;窗口创建仍在主线程完成(Tauri 要求),创建失败由内部日志
      记录。前端不再依赖返回的窗口 label(图标在创建时已同步设置)。
  • 移除 create_web_gui_window 返回 label 的契约(前端 lib/tauri.ts createWebGuiWindow
    签名不变,仅不再消费返回值)。
  • 内嵌窗口偶发创建失败("the underlying handle is not available")apply_window_icon
    在 build() 后立即取 hwnd 的竞态失败不再阻断窗口创建(恢复 0.4.14 语义:失败仅记警告,
    窗口照常打开)。此前 ? 传播会把已建成的窗口整体判失败 → 不开窗。
  • 日志全域化(不允许丢失任何日志)
    • 新增全局 panic hook:任何线程 panic 落盘 logs/crash.log + 经 Logger 记录
      (release 无控制台时 panic 此前完全不可见 → 静默崩溃无痕)。
    • 关键路径 eprintln!(主窗口图标失败、外链打开失败、Tauri 启动失败)改经 Logger
      落盘,release 下不再丢失。
    • dsh stdout/stderr 已实时落盘 dsh-web-stdout/stderr.log 并逐行进日志流;崩溃
      尾部不完整行有 flush 兜底,保证 dsh 侧日志不丢。

v0.4.14

Choose a tag to compare

@github-actions github-actions released this 04 Sep 08:27

修复

  • 修复内嵌 Web GUI(deepseek-harness Web UI)无法打开会话中的超链接
    • 根因(三层):
      1. dsh Web UI 将 markdown 中的 http/https 外链渲染为 target="_blank" 锚点(dsh 侧源码行为,本启动器不改 dsh)。
      2. launcher 注册的 opener 插件(tauri_plugin_opener::init(),默认 open_js_links_on_click: true)向每个 WebView 注入点击拦截脚本:左键点击 _blank 外链会 preventDefault() 并改走 plugin:opener|open_url IPC。
      3. 该 IPC 受 Tauri 2 ACL 管控:原 capabilities/default.json 仅授予 main 窗口 opener:default,内嵌 dsh-web-gui-* 窗口没有任何 capabilityopen_url 被静默拒绝(release 下 "not allowed by ACL"),点击无任何反应。
    • 修复:
      • 新增 src-tauri/capabilities/dsh-web-gui.json:对 dsh-web-gui-* 窗口放行 opener:defaultremote.urls 覆盖 http(s)://127.0.0.1:*http(s)://localhost:*(dsh Web GUI 的 loopback 服务地址;缺省组件自动补全配符,见 tauri URLPattern 语义)。除 opener 外不授予任何本地文件/系统命令权限
      • lib.rs 内嵌窗口 builder 增加 Rust 兜底:.on_navigation(|_| true) 显式放行一切导航(窗口只作 dsh Web UI 载体);.on_new_window() 收到 WebView2 原生新窗口请求(window.open 等)时用系统默认浏览器打开目标 URL 并 Deny,杜绝进程内游离 WebView2 子窗口。
    • 效果:点击会话内 http/https 超链接 → 系统默认浏览器(Edge/Chrome 等)打开新标签;ctrl/shift 点击与 window.open 类请求一致处理。
    • 验证:tsc / vite build / cargo check --all-targets(0 警告)。

v0.4.13

Choose a tag to compare

@github-actions github-actions released this 03 Sep 16:43

变更

  • 全链路审计修复(依据 AUDIT_REPORT §2–§5)
    • 进程安全:收养/停止/端口清剿前校验监听进程确为 dsh(命令行特征),不再强杀占用同端口的无关进程。
    • 假功能修复:npm registry 镜像真正生效(npm view / npm install -g / pnpm install 注入 --registry);GitHub tag 列表改 semver 数值排序(0.9<0.10、rc.9<rc.10);工具链检测产出 mismatch(Node 22.19+/24+、Git 2.26+、Python 3.10+ 门槛比较)。
    • 凭据安全:GitHub Token 落盘 DPAPI 加密(Windows)、不再回传前端明文、git 认证改环境变量注入(不进命令行);dsh web token 不再明文进日志/日志流(日志打码 + 独立缓存文件)。
    • 可靠性:子进程/网络操作全部加超时与强杀(查询/下载/安装/UAC 分档 60s~20min,流式命令 30min 看门狗);配置读写加互斥与原子写;Logger/托盘构建失败降级不再 panic;新增后端每 5s 状态对账(收养实例退出收敛/外部启动自动接管);monitor 收尾按 pid 归属复位,防覆盖重启新实例。
    • 前端:面板宽度与对侧开关联动重算(reclamp 接线);日志流增量格式化消除 O(n²);贴顶滚动不再打断阅读;进度清理定时器登记、打开流程取消令牌下渗;版本平局比较按 semver 数值化(rc.9<rc.10);开关/token 表单陈旧闭包与明文回显修正。
    • 构建/CI/发布tsc -p tsconfig.node.json --noEmit 纳入(vite.config.ts 首获类型检查,补 @types/node);cargo check --all-targets;补离线集成测试,网络测试 #[ignore];release 流程 bump 后显式打 tag、决策前同步远端 master、skip-release 不再自动递增;构建期依赖归入 devDependencies;清理死代码/重复实现与注释/文档漂移(AGENTS.md 悬空引用等)。
    • 验证:tsc / vite build / cargo check --all-targets(0 警告)/ cargo test --lib 35 通过 / 6 个离线集成测试通过。

v0.4.12

Choose a tag to compare

@github-actions github-actions released this 03 Sep 13:44

变更

  • 移除版本管理面板通道按钮上的版本数角标
    • 原按钮组(GitHub 通道 / npm 通道)右侧显示通道可用版本总数角标(如 GitHub 10、
      npm 15)。该数字为远端拉取到的全部版本数,而列表只展示最新 8 个 → 与所见不一致
      易误导。移除角标,按钮仅保留通道名称,干净无歧义。
    • 版本 0.4.12。

v0.4.11

Choose a tag to compare

@github-actions github-actions released this 03 Sep 11:57

变更

  • 优化内嵌打开逻辑:自动拉起 dsh 并等待就绪后才开窗 + 进度小弹窗
    • 此前点击“内嵌打开/外部浏览器”时若 dsh 未运行,直接 toast 报错要求手动先点“启动”
      ——流程割裂;若 dsh 冷启动中则静默轮询无感知。
    • 现在(components/StatusCard.tsx):点击后弹出进度引导弹窗,阶段化展示
      (检查状态 → 启动 dsh → 等待就绪(端口监听) → 获取访问地址 → 打开窗口),
      每阶段推进度条与文案;dsh 未运行/出错时自动调用 startDsh 拉起(含端口校验、
      端口占用由 Rust 端报错),停止中则等待停止完成后自动重启;就绪后拿到带 token 的
      完整 URL 才创建内嵌窗口/打开外部浏览器(杜绝 401/拒绝连接死窗口)。
    • 弹窗含取消、失败重试按钮(重试走 force 重开流程);用流程序号(useRef)防竞态——
      取消/重开后旧流程异步回调不再污染状态;未安装 dsh 时弹窗明确提示先安装。
    • 验证:tsc / vite / cargo release / NSIS 构建通过。版本 0.4.11。

v0.4.10

Choose a tag to compare

@github-actions github-actions released this 03 Sep 11:33

修复

  • 卸载 Git / Python 失败:“Start-Process : 系统找不到指定的文件”(真实客户机
    192.168.3.122 实测复现 + 验证):
    • 现象:点卸载 Git / Python → 日志报 Start-Process -FilePath 'C:\Program'
      -ArgumentList 'Files\Git\unins00...'(路径在第一个空格处截断)→
      “系统找不到指定的文件”。
    • 根因:注册表 UninstallString 是整体引号包裹的路径,如
      "C:\Program Files\Git\unins000.exe"
      "C:\Users\...\Package Cache\{...}\python-3.14.0-amd64.exe" /uninstall
      core/toolchain.rs 的 find_uninstall_entry 在收集候选时执行
      trim_matches('"') 提前剥掉首尾引号 → 返回值变成无引号含空格的裸路径
      → split_uninstall_cmd 按“无引号:第一个空白前为 exe”切分 → exe 截断为
      C:\Program / C:\Users\Administrator\AppData\Local\Package
      Start-Process 找不到该“文件”。
    • 修复:find_uninstall_entry 保留原始 UninstallString(含引号),引号解析统一
      交给已正确支持引号路径的 split_uninstall_cmd(对 Git 整体引号、Python 引号+
      参数两种真实格式均正确解析)。
    • 验证:测试机 192.168.3.122 实测——旧逻辑 exe=C:\Program(不存在)复现报错;
      修复后 exe=C:\Program Files\Git\unins000.exe 与完整 Python 缓存路径均解析正确
      且文件存在;新增 test_split_uninstall_cmd_real_registry_values 回归测试
      (真实注册表值 Git/Python)。版本 0.4.10。