Commit Graph
336 Commits
Author SHA1 Message Date
Atlas Zeng 5d2d6e5801 Merge pull request #88 from omdsh-dev/feat/title-bar-compat
feat: 侧边栏新增位置兼容模式(v0.12.2)
2026-08-15 15:53:35 +08:00
Atlas Zeng 30d0b103f6 Merge pull request #72 from NolanHo/feat/dev
fix: 终端 Tab 使用账户 login shell 并以 login 模式启动
2026-08-15 15:53:26 +08:00
Menghuan1918 8ad1766390 feat: 位置兼容模式支持自定义下移距离(齿轮弹窗数字输入)
titleBarStripPx 新偏好(0–120px,默认 40):侧边栏按钮与内容的下移量改为
CSS 变量 --dsh-title-bar-strip 驱动,Sidebar shell 随 prefs 写入。设置页
「常规」的位置兼容模式行在开启时显示齿轮小图标,弹窗内用数字行设置下移
距离(复用 FeatureSettingsRows 行控件与提交钳制)。
2026-08-15 15:46:56 +08:00
Menghuan1918 648ff27b5f chore: 版本号升至 v0.12.2(位置兼容模式随本次发布) 2026-08-15 15:37:31 +08:00
Menghuan1918 1e7c72ccbe feat: 侧边栏新增位置兼容模式,为 Windows 原生标题栏预留顶部空间
新增 SidebarPrefs.titleBarCompat 设置项(默认关闭):开启后 toggle cluster
下移 40px、右侧面板内容从标题栏条带下方开始,避免被 Windows 无边框窗口
右上角的原生标题栏遮挡。底部面板不受影响。设置页「常规」新增一行开关,
zh/en 双语,读写下穿既有 settings 路由。测试覆盖 parsePrefs 回退、schema
默认值、设置页渲染与开关状态。
2026-08-15 15:37:31 +08:00
Menghuan1918 5c27882995 docs: 仓库硬约束新增「代码改动必须走 PR,仅文档类改动可直推 main」 2026-08-15 15:36:12 +08:00
Menghuan1918 ad787ab22d Revert "feat: 侧边栏新增位置兼容模式,为 Windows 原生标题栏预留顶部空间"
This reverts commit ae71aecb83.
2026-08-15 15:36:12 +08:00
Menghuan1918 ae71aecb83 feat: 侧边栏新增位置兼容模式,为 Windows 原生标题栏预留顶部空间
新增 SidebarPrefs.titleBarCompat 设置项(默认关闭):开启后 toggle cluster
下移 40px、右侧面板内容从标题栏条带下方开始,避免被 Windows 无边框窗口
右上角的原生标题栏遮挡。底部面板不受影响。设置页「常规」新增一行开关,
zh/en 双语,读写下穿既有 settings 路由。测试覆盖 parsePrefs 回退、schema
默认值、设置页渲染与开关状态。
2026-08-15 15:24:46 +08:00
Atlas Zeng 1a0d530711 Merge pull request #74 from NolanHo/feat/link-interception-toggle
feat: 服务化 API 新增 urlTarget 外链认领 + 浏览器 HTTP/HTTPS 二级设置开关
2026-08-15 15:20:23 +08:00
Menghuan1918 29f162dac0 feat: 服务化 API 新增 urlTarget 外链认领 + 浏览器 HTTP/HTTPS 二级设置开关
基于 PR #74 的颗粒度讨论向前兼容拓展服务化 API:
- TabDescriptor 新增可选 urlTarget(url) 谓词:聊天/界面外链被拦截时按注册
  顺序路由到第一个命中的插件 tab 类型(openTab({ type, url, title })),
  内置 browser 退居隐式兜底;SIDEBAR_FEATURES 追加 'urlTarget'
- 浏览器链接设置改为二级菜单(齿轮弹窗):新增 browserInterceptHttp
  (默认开)+ browserInterceptHttps(默认关);browserInterceptLinks
  保留为总闸(默认开,旧文档零迁移)
- 拦截管线:registerLinkInterception 的 takeoverEnabled 改收解析后的
  URL,协议/同源纯判定(shouldInterceptLink)签名不变
- 测试:matchUrlTarget(注册顺序/抛错吞掉/browser 永不命中)、jsdom
  点击接管门控、parsePrefs 新字段默认值;全默认字面量同步
- 文档:设计文档 + AGENTS.md(字段/示例/设置键)+ README(外链分流)
2026-08-15 15:05:06 +08:00
Atlas Zeng 5bd961f7f1 Merge pull request #76 from ChenRuoT/add-dsh-sidebar-qa
feat: 推荐插件目录收录 dsh-sidebar-qa (Tab 注册)
2026-08-15 11:23:20 +08:00
Menghuan1918 f842fa0029 docs: 友情链接收录 DeepSeek Harness Desktop(issue #78) 2026-08-15 10:47:30 +08:00
ChenRuoT 0b5405117d feat: 推荐插件目录收录 dsh-sidebar-qa (Tab 注册)
plugins-tabs.ts 收录 dsh-sidebar-qa (划选提问tab)
install 拼接官方一键命令
2026-08-15 02:28:57 +08:00
Atlas Zeng 2bace68af8 Merge pull request #71 from omdsh-dev/ci/mount-smoke
ci: 新增插件挂载冒烟门禁(npm 打包 → 真实挂载 DSH → 无头渲染防 crash)
2026-08-15 01:55:39 +08:00
Menghuan1918 f903ac77d6 test(e2e): 落实 Codex 审查意见 — 强制覆盖 editor 懒加载 chunk + 缺失内置 tab 即失败
- seed hello.txt,经 Explorer 打开文件并等待 /sidebar/bundle/editor.js 响应,
  缺失/损坏的 editor chunk 会令门禁变红(已实测:删 chunk → 错误条被检出)
- + 菜单缺失内置 tab 由跳过改为 toHaveCount(1) 硬失败,防深扫悄悄缩水
- AGENTS.md CI 冒烟说明同步
2026-08-15 01:52:54 +08:00
trinhthiminh650-tech 8014255541 feat(browser): loopback allowlist with same-origin for local dev servers
Add a side-card preference 'browserAllowedLoopback' (comma-separated
host or host:port entries) that lets the sidebar browser navigate to
explicitly trusted loopback addresses. Bare hosts (localhost,
127.0.0.1) match every port; host:port entries match exactly.

Allowlisted local addresses additionally get the 'allow-same-origin'
sandbox token in the iframe: local dev servers (Vite etc.) need a real
origin for their module/HMR/fetch pipeline and would otherwise render
blank in the opaque-origin sandbox. The page stays cross-origin to the
GUI and to every other site.

The server-side browser.probe route mirrors the same allowlist so
probed local servers are not rejected as 'local addresses are not
probed'.
2026-08-15 01:37:39 +08:00
Atlas Zeng 33ee02e747 Update README.md (#70) 2026-08-15 01:26:56 +08:00
Menghuan1918 7ee0b457a3 feat: CI 挂载冒烟门禁 — npm 打包 → 真实挂载 DSH → 无头渲染防 crash
新增 plugin-mount job(pnpm test:mount):
- scripts/e2e-mount.sh:scratch profile 引导(allowBuilds/minimumReleaseAgeExclude 预写)→ 官方
  dsh plugin --profile web add file:<tarball> 挂载(dsh.profile.bundles 协调校验)→ keyless
  dsh web --port 0 → Playwright 无头渲染 → trap 清理
- tests/e2e/mount.e2e.ts:seed 工作区+会话(宿主 RPC)→ 断言 #root 与 [data-dsh-better-sidebar]
  挂载、无崩溃标记(错误条/pageerror/插件 console 错误)→ + 菜单逐个打开内置 tab 深扫
- playwright.config.ts:chromium headless、单 worker、retries 0、失败留 trace/截图/HTML 报告
- vitest exclude 与 *.e2e.ts 命名双保险隔离;exclude 整体替换默认值,须保留默认排除项
- CI 钉住 @deepseek-ai/dsh@0.1.0-rc.6;DSH_TELEMETRY_DISABLED=1;workflow_dispatch + PR 并发取消

已验证:本地端到端全绿;人为注入 tab 组件 crash → 门禁变红(错误条检出),还原后变绿;
typecheck/vitest 全绿;CI 同款 npm 安装 CLI 路径实测通过
2026-08-15 01:21:21 +08:00
Menghuan1918 d478780e43 docs: README 语气专业化并放大最近更新截图
- Hero 特性标签新增 <code>插件接入</code>(Plugin integration),以 code 标签承载插件注册接入能力
- 移除口语化表达(吃自己的狗粮 / 把自己当用户),改用中性措辞
- 「我们的态度」改为「核心理念」,表述更正式
- 最近更新截图放大(320 → 480)
- 同步英文 README
2026-08-15 01:18:58 +08:00
NolanHo 76fa7df264 fix: resolve the account login shell and spawn terminals as login shells
Terminal tabs resolved the shell from the dsh process environment only,
falling back to a hardcoded /bin/bash — service-managed launches without
SHELL therefore ignored the account's login shell (e.g. zsh). They also
spawned with an empty argv, so even a resolved zsh ran as a non-login
shell and skipped ~/.zprofile.

defaultShell() now falls back to the account's login shell (passwd) after
$SHELL, and both registries spawn POSIX shells with -l so the tab behaves
like a terminal emulator (loads ~/.profile / ~/.zprofile). Windows keeps
powershell.exe with no login flag.

Fixes omdsh-dev/DSH-better-sidebar#68
2026-08-14 10:15:34 -07:00
Atlas Zeng acd4a8313c Update README.md 2026-08-15 01:14:29 +08:00
Menghuan1918 cb6f2cdc8f docs: README 服务化定位前置、精简功能一览并修正内置 viewer 计数
- 开头(Hero)声明服务化框架定位:ctx.betterSidebar 服务 + registerTab/registerFileViewer,内置 tab/viewer 与外部插件走同一套服务
- Hero 附 GitHub topic dsh-better-sidebar,说明生态位插件
- 修复展示视频(裸 URL → <video> 内嵌)与截图排版
- 功能一览 15 条精简为 10 条,突出重点;新增「我们的态度」引言
- 最近更新保留截图列,整理为可点击缩略图
- 修正内置 viewer 计数 9 → 6(Office 预览已迁至推荐插件)
- 同步英文 README
2026-08-15 01:09:42 +08:00
trinhthiminh650-tech 6f092a6b1a fix(browser): probe embed signals via GET fallback when HEAD omits them
Some servers (e.g. aliyun consoles) answer HEAD without the
X-Frame-Options / Content-Security-Policy headers that only their
GET response carries. The embeddability probe then wrongly reported
the site as embeddable, leaving the plain iframe to surface the
browser's misleading "refused to connect" error (the site actually
forbids framing via frame-ancestors).

Retry once as GET when both embed signals are absent (the body is
discarded — only headers matter), mirroring the existing 405/501
HEAD fallback. The client then shows the friendly embed-refusal
panel with an "open in browser" action instead of the misleading
connection error.
2026-08-15 01:02:35 +08:00
Atlas Zeng 3825fced25 Update README.md 2026-08-15 00:49:59 +08:00
Menghuan1918 4e275aa321 chore: v0.12.1(0.12.0 被 npm 判定已发布过无法复用,正式版改用 0.12.1;README 版本号同步) v0.12.1 2026-08-15 00:36:09 +08:00
Menghuan1918 ef8a707da8 chore: v0.12.0(正式版) 2026-08-15 00:33:26 +08:00
Menghuan1918 83a658efd4 chore: v0.12.0-beta.1(版本三处同步,api-surface 测试放行预发布版本号) 2026-08-15 00:28:59 +08:00
Menghuan1918 cba7e77896 docs: README 精简,最近更新改为表格(v0.12.0),版本号 0.11.0→0.12.0 2026-08-14 23:33:40 +08:00
Atlas Zeng e484556c1e Merge pull request #63 from omdsh-dev/feat/recommend-sentinel
feat: 推荐插件目录收录 dsh-sentinel(Tab 注册)
2026-08-14 23:09:57 +08:00
Menghuan1918 7d524724ae feat: 推荐插件目录收录 dsh-sentinel(Tab 注册)
- plugins-tabs.ts 收录 dsh-sentinel(条件驱动的 agent 唤醒系统,注册 dsh-sentinel:watches Tab)
- install 拼接官方一键命令:cd ~/.dsh && dsh plugin --profile web add "github:fuhefei/dsh-sentinel#v0.7.0"
- 新增 pluginSentinelDesc 文案(zh/en);测试同步(tab 目录不再为空态)
2026-08-14 23:04:25 +08:00
Menghuan1918 c0aeefc936 fix: 回应审查保留意见 — 测试钉住跨站分支、删死接口、修正注释措辞
- tests/trusted-hosts.spec.ts:用例 4 改为受信 origin + cross-site marker
  以隔离拒绝分支(原同时踩 marker 与 origin 两条路径,删除 marker 检查
  测试依旧通过——变异验证现仅该用例失败);接受侧断言从 not.toBe(403)
  收紧为 toBe(200),请求体补 sessionId(session.cwd 的真实契约)
- src/context-types.ts:删除已无引用的 SidebarLoader/SidebarLoaderEntry
  死接口(loader 成员移除后残留)
- src/index.ts:修正 "same list / 无需重启" 过承诺注释,改为与 /api 网关
  同源的准确表述(boot 采样快照 + --trusted-host 权威,读 live 服务值)
2026-08-14 23:03:26 +08:00
Rookie_Zoe ea250c9e87 fix: /sidebar 信任栅栏改用 webRuntime.trustedHosts,修复远程访问全部 403
根因:trustedHostsOf 按 entry.options.name === 'connection' 查找 connection
行,但该行 name 是模块标识符(@deepseek-ai/dsh-client-connection,id 才是
connection),查找永远落空 → trustedHosts 为空 → 栅栏只放行回环 Host → 通过
域名或局域网 IP 访问时 /sidebar/bundle chunk 加载失败、资源管理器/代码管理器
全部 403 forbidden(/api 不受影响,它读的是 apply 时已求值的配置)。

修复(按 review 建议):host half 直接注入 webRuntime 服务,栅栏每请求实时
读取 ctx.webRuntime.trustedHosts —— 与 /api 网关同一信任列表(启动时采样的
LAN IP 字面量 + --trusted-host 权威),不再依赖 Loader entry / fiber /
!!js 节点求值;自定义信任域名由 dsh web --trusted-host 提供。

新增 tests/trusted-hosts.spec.ts 回归:域名/局域网放行、空列表仅回环、
跨站标记拒绝、每请求实时读取;plugin-shape 断言同步更新。
2026-08-14 23:03:26 +08:00
feifei 9b87c1da16 docs: register dsh-sentinel as the first real consumer integration (#58) 2026-08-14 23:03:20 +08:00
Atlas Zeng 001e86b1e1 feat: 标签页栏支持鼠标滚轮横向滚动 (#61)
普通鼠标滚轮只产生垂直 delta,overflow-x 的横向滚动容器不会消费它,
事件会冒泡导致页面滚动。给 TabBar 的滚动容器绑定原生非 passive wheel
监听(React 的 onWheel 在根节点是 passive,preventDefault 无效),
在标签条溢出时把 deltaY(含 deltaX、deltaMode 归一化)转为 scrollLeft:

- 未溢出时完全不拦截,页面正常滚动(空 pane 亦然)
- 按住 Shift/Ctrl/Cmd/Alt 时放行,保留浏览器原生横滚/缩放
- 每个 pane 的 TabBar 独立监听,只滚动悬停的标签条

新增 tests/tab-bar-wheel.spec.tsx(jsdom 挂载,7 个用例)。
2026-08-14 22:59:19 +08:00
Atlas Zeng 277e7d3b40 Merge pull request #59 from omdsh-dev/feat/plugin-api-v012
feat: 设置页「添加插件」推荐目录 + 复制安装命令;移除内置 Office 预览
2026-08-14 22:56:24 +08:00
Menghuan1918 58999c2f3b fix: 回应 Codex review——复制反馈仅在写入成功时显示;插件名改为 window.open 按钮
- copy 现在 await writeClipboard 的布尔结果,剪贴板被拒时不再显示「已复制」(避免误导用户粘贴从未写入的命令)
- 插件名由 <a target=_blank> 改为 <button>,与「跳转」按钮同走 window.open——锚点会被 document capture 的链接接管拦截(忽略 target=_blank)开进侧边栏浏览器,按钮形态绕过
- 测试:新增剪贴板拒绝用例 + 名字/跳转双按钮 window.open 断言
2026-08-14 22:53:14 +08:00
Menghuan1918 2bcfdfce87 chore: 移除 Office 预览相关依赖与产物声明
- dependencies 删除 @aiden0z/pptx-renderer / @univerjs/preset-sheets-core / @univerjs/presets / docx-preview / xlsx
- files 删除已废弃的 lib/client-docx|xlsx|pptx.js 声明
- pnpm-lock.yaml 同步更新
2026-08-14 22:37:23 +08:00
Menghuan1918 cbc28473a0 feat: 设置页「添加插件」推荐目录 + 复制安装命令;移除内置 Office 预览
- 设置页侧边栏内容/文件预览两个网格末尾各增虚线卡片,弹出对应 kind 的插件弹窗
- 弹窗:GitHub topic 按钮(新标签页)+ 推荐插件目录(plugins-tabs.ts / plugins-viewers.ts)
- 每条目「跳转」(window.open 新标签页直达仓库)与「复制」(writeClipboard + 已复制反馈)
- 不做终端预填流:不关闭弹窗、不打开终端、无失败路径(install/installNotice/installError* 文案删除)
- 内置 Office 预览(docx/xlsx/pptx)整体移除,chunk 白名单 5→2(terminal/editor)
- 文案「内置插件」→「推荐插件」;AGENTS.md/README/设计文档同步
2026-08-14 22:30:34 +08:00
Atlas Zeng 1b0b382edc Merge pull request #54 from omdsh-dev/feat/plugin-api-v012
feat: 公共 API 基座化(v0.12.0,纯增量)
2026-08-14 22:02:14 +08:00
Menghuan1918 0995a58454 fix: 回应独立 CR 的 P2/P3 意见(0×P1)
- P2-1 onOpen 收到真正落地的 tab:url 新建场景从 landed 态按 id 反查
  (补丁后对象),回调不再拿到未打 url 的 tab
- P2-2 插件设置行显式取值源:FeatureSettingsRows 新增 valueSource prop,
  插件行读自己的 pluginSettings blob——插件键与宿主 pref 同名时不再
  静默读宿主值(原投影合并有读宿主写插件的读写不对称);prop 命名避开
  Object.prototype.valueOf 冲突
- P2-3 consumer 类型检查接入工程:package.json 新增 check:consumer-types
  脚本 + CI 在 build 后执行;脚本补 lib/types 存在性前置检查(防假绿)
- P3-1 url seed 只在新建时应用:dedupe 聚焦的 tab 不再被覆写 path
- P3-2 closeTab/activateTab 未知 id 严格 no-op:store.reduce 对同引用
  结果短路(不 notify、不重写 localStorage),根因修复 + 回归测试
- P3-3 closeTab/activateTab 增加可选 scope(cwd 随回调传递),Sidebar
  双树激活/关闭路径传入 { sessionId, cwd }
- P3-4 定向打开不再自动展开不可见 session 的面板
- P3-5 Sidebar 终端 pty 释放查找覆盖双树(底部面板终端不再漏掉 HTTP
  兜底)
- P3-6/P3-7 与 Nits:AGENTS.md/指南文档化(dedupeKey 纯函数、meta 用
  null 清除、回调 scope 的 cwd 语义);consumer fixture 补常量导出覆盖

测试 +6(url 落地保真 / url 不覆写聚焦 / 未知 id 无 notify / 定向打开
不展开 / scope 随回调 / valueSource 键隔离),464 全绿;typecheck、
build、consumer 校验全部通过。
2026-08-14 21:28:41 +08:00
Menghuan1918 319d34ed09 fix: 回应 Codex 审查的 4 条意见(2×P1 + 2×P2)
- P1 state.ts reduceFor:恢复共享 uid 计数器到调用前水平(目标 session 的
  max 可能低于激活 session 已用 id,否则下次 mint 撞 id 损坏布局);
  回归测试实证:无修复时 split 产生重复 pane id
- P1 service.ts 生命周期分类:dedupe 聚焦判定改为基于输入态的存在性
  (dedupeKey 匹配或 id 匹配都算聚焦)——按 path 去重 + 新 id 打开时
  不再对从未插入的幽灵 tab 触发 onOpen(资源泄漏源)
- P2 SideCardSection:乐观 prefs ref(optimisticRef)驱动嵌套 map 合并
  (tabsEnabled/viewersEnabled/pluginSettings),同 tick 多次写入不再
  互相丢弃;mergePluginSetting 抽纯函数 + 单测
- P2 state.ts schedulePersist:每 session 独立防抖定时器(persistTimers
  Map),定向打开不再取消其他 session 的待写;单测验证双写都落盘
2026-08-14 21:13:53 +08:00
Menghuan1918 ced3a1eade docs: README 指向外部插件指南与 AGENTS.md,设计文档补 v0.12.0 扩展记录
- README/README_EN:服务化小节与特性清单同时链接 AGENTS.md 与
  docs/external-plugin-guide.md;安装示例版本 0.10.3 → 0.11.0(npm 最新已发布版)
- docs/plans/2026-08-11-service-registry-design.md:追加 §18 v0.12.0
  基座化扩展记录(类型导出/零 Node 依赖/新方法/新字段/设置 seam/load signal/测试)
- docs/plans/2026-08-11-declarative-sidebar-settings-design.md:追加 §8
  设置 seam 开放记录(pluginSettings 持久化/pluginToggles/render/SettingsBody)
- docs/external-plugin-guide.md:修正纯度门交叉引用(§9 → §10)
2026-08-14 20:49:00 +08:00
Menghuan1918 82a69546d2 feat: 公共 API 基座化(v0.12.0,纯增量)— 类型/能力/设置 seam 全面补齐
- 类型生态:service 模块 re-export SidebarTab/SidebarState/SidebarStore/
  SidebarSnapshot/SidebarDiffRef/TabType/SessionScope/SidebarPrefs 等公共
  状态词汇(此前 TS2459 无法命名);context-types 去 Node 依赖(结构镜像
  SidebarHttpRequest/Response/UpgradeSocket/Head),client 可达声明图零
  node:* 引用,外部消费者无 @types/node + skipLibCheck:false 可编译
  (scripts/check-consumer-types.sh 守护)
- 服务能力:version/features 版本与能力探测(单调只增)、getSnapshot/
  subscribeState 状态订阅、updateTab(title/path/meta)、activateTab、
  openFile(路径派生 id 与内置拦截一致)、openTab(seed, scope?) 定向到
  指定 session(store.reduceFor 不扰动 UI)
- TabDescriptor:badge 角标(99+ 封顶,抛错吞掉)、onOpen/onActivate/
  onClose 生命周期回调(service 路径派发,dedupe 聚焦触发 onActivate
  而非 onOpen,抛错不打断流程);SidebarTab.meta JSON 可序列化跨刷新
  持久化(sanitize 宽松保留)
- 设置 seam 开放:PrefsSchema 增 pluginSettings 开放嵌套 map(z.dict),
  settings.pluginToggles(插件自有行,同 switch/text/number 控件)与
  settings.render(自定义面板,含 store/service/prefs/updatePluginSetting/
  close props);viewer 卡片 v0.12.0 起也有齿轮设置弹窗
- FileViewerDescriptor.load 增第三参 AbortSignal(EditorHost 生命周期中止)
- UI 接线:tab 激活/关闭改走 service(跨树激活修复 + 回调触发)、+ 菜单
  传 scope、TabBar badge pill 渲染;active-session scope 走原 reduce 路径
  保证 notify
- 测试 +23:生命周期/定向打开/updateTab/activateTab/openFile/meta 持久化/
  reduceFor/能力常量(与 package.json 锁步)、consumer-types.ts 编译门、
  api-surface.spec.ts(client 图零 node 依赖守护);既有 430 测试全绿
- 文档:AGENTS.md 修 available 三参示例并补全部新 API;external-plugin-
  guide.md 刷新至 v0.12.0(7 tab + 9 viewer、设置 seam 开放、类型导入
  路径建议);README×2 服务化小节同步

未发版 npm(用户决定);分支 feat/plugin-api-v012。
2026-08-14 20:44:43 +08:00
Atlas Zeng 288a499c7f Merge pull request #51 from omdsh-dev/fix/issue-42-auto-terminal-regression
test: issue #42 底部面板首展自动终端触发链回归测试 + 诊断文档
2026-08-14 20:20:35 +08:00
Menghuan1918 c70d868c58 test: issue #42 触发链回归测试 + 诊断文档(底部面板首展自动终端)
#42 的根因与 #25 同源(零尺寸容器同步 open xterm → 渲染器未创建 →
.dimensions/.handleResize 崩溃),已在 v0.11.0 修复(openWhenSized);
「整个面板空白」放大器已由 #31 修复(per-tab 崩溃隔离)消除。
本次无代码改动,补齐缺失的覆盖:

- tests/bottom-auto-terminal.spec.tsx:钉住 #42 触发链(首展自动开终端
  恰好一个 tab 落在底部工作树、bottomOpenedOnce 原子置位、pref / 类型
  禁用双门控、面板完整存活),此前该 effect 零测试覆盖;
- docs/plans/2026-08-14-issue-42-verify-design.md:诊断证据链、
  修复覆盖路径、AttachConsole(node-pty 上游限制,仅文档化)、
  issue 回复草稿。

验证:pnpm test 34 文件 / 430 例全绿;typecheck、build 通过。
2026-08-14 20:17:27 +08:00
Atlas Zeng 61e31321d6 Merge pull request #48 from omdsh-dev/fix/issue-31-sidebar-crash
fix: sidebar crash #31 — layout-push leak + per-tab error containment
2026-08-14 20:02:16 +08:00
Menghuan1918 9aeb0464ce fix: sidebar crash #31 — layout-push CSS-variable leak + per-tab error containment
Two failure modes of a sidebar render crash, fixed together:

1. Layout-push leak (root cause): the layout-push effect wrote
   --dsh-sidebar-width/--dsh-sidebar-height on document.documentElement
   without a cleanup, so ANY unmount of the Sidebar (error-boundary swap,
   plugin disable, HMR) left the variables behind and layout.css kept
   squeezing #root with a stale margin — "the sidebar cannot be hidden"
   until a full reload. The effect now removes both properties on cleanup
   (the CSS fallback 0px restores the layout).

2. Crash containment (UX): the root error boundary previously replaced the
   WHOLE sidebar — toggle cluster included — with an error strip on any tab
   crash. A new shared RenderBoundary (src/client/RenderBoundary.tsx) now
   scopes containment per tab: a crashing viewer/editor shows a dismissible
   strip inside its own pane while the toggle cluster, the other tabs, and
   the panel stay alive. The descriptor is rendered as a real element
   (createElement) so even top-level component throws land in the boundary,
   not in TabContent's own render. The root boundary remains as the last
   resort for Workbench/shell errors.

Tests (tests/sidebar-crash.spec.tsx, jsdom + real Sidebar/store harness):
- unmount clears both CSS variables (red before the fix: 307px leaked)
- a crashing tab is contained: strip in-pane, collapse button alive,
  layout push still live
- the retry button recovers a tab whose crash has since been fixed

Full suite: 425 tests pass; tsc --noEmit clean.
2026-08-14 18:29:31 +08:00
Atlas Zeng dff1595e77 Merge pull request #43 from ma15803216102/fix/html-preview-windows-drive-path
fix(html): Windows 盘符路径解码去掉前导斜杠,修复 html 预览被 isWithin 拒绝
2026-08-14 18:26:40 +08:00
Cora cd737a7f3f fix(installer):修复 PowerShell 安装入口和版本校验 2026-08-14 18:10:41 +08:00
Atlas Zeng 28d20a46c0 Merge pull request #35 from omdsh-dev/ci/github-actions
ci: add GitHub Actions workflow (tests + type/build checks)
2026-08-14 17:53:07 +08:00