2026-08-16 23:34:22 +08:00
|
|
|
|
# 2026-08-16 dsh-worktable v2:PRD §10 定案并实现
|
|
|
|
|
|
|
|
|
|
|
|
> 日期 / 主题 / 状态:2026-08-16 · 工作台 v2(管理/添加/卡片规范 v2/排序埋点/i18n) · 代码完成,待重启后 GUI 验收
|
|
|
|
|
|
|
|
|
|
|
|
## 任务目标
|
|
|
|
|
|
|
|
|
|
|
|
按 PRD §10 与用户逐项讨论定案后实现:①管理视图(编辑模式)②添加(+) 真实逻辑 ③卡片规范 v2
|
|
|
|
|
|
(渐进上报协议)④分类(取消)⑤i18n 接入 dsh-client-locale;并升级 dsh-travelatlas 卡片协议。
|
|
|
|
|
|
|
|
|
|
|
|
## 定案记录(与用户问答确认)
|
|
|
|
|
|
|
|
|
|
|
|
1. **管理功能**:☰ 菜单「管理项目…」→ 区块内编辑模式(改名/隐藏/拖拽+↑↓排序),全存 localStorage;不做独立路由页;不做真正插件启停(宿主职责)。
|
|
|
|
|
|
2. **添加(+)**:接入指引面板(注册即入驻说明 + 市场外链)+ 本地快捷方式条目(名称/图标/链接,点击新标签打开,标「本地」角标)。
|
|
|
|
|
|
3. **卡片规范 v2**:owner props 扩展(query/wide/order/hidden/nameOverrides/managing/reportMeta/reportUsed),全部可选;v1 卡片零改动兼容(按注册序排最前)。
|
|
|
|
|
|
4. **分类**:取消(用户定案:每项目占一行、自成工作台,无需分组);视图菜单只留「排序:手动/最近」;旧 groupBy 状态忽略。
|
|
|
|
|
|
5. **i18n**:NS worktable zh/en 词典,ctx.locale.register + package.json 声明 dsh-client-locale;宿主缺席回退 zh。
|
|
|
|
|
|
6. **市场外链**:https://github.com/hikariming/dshfind(已核实可访问;dshfind.com 未验证,不链死链)。
|
|
|
|
|
|
|
|
|
|
|
|
## 实际改动
|
|
|
|
|
|
|
|
|
|
|
|
- 工作台 `01_content/src/client/locales.ts`(新增):zh/en 词典(31 键)+ NS + 类型声明。
|
|
|
|
|
|
- 工作台 `01_content/src/client/index.tsx`(重构):
|
|
|
|
|
|
- 视图菜单去分组,只留排序(手动/最近)+「管理项目…」;
|
|
|
|
|
|
- 管理面板:改名/隐藏/拖拽(HTML5 drag)/↑↓ 排序/恢复默认;编辑态弱化卡片区;
|
|
|
|
|
|
- 添加面板:接入指引 + 市场外链 + 快捷方式表单(http/https 校验);
|
|
|
|
|
|
- 排序:effectiveOrder(手动=持久化序+注册序补齐;最近=lastUsed 降序+其余手动序);
|
|
|
|
|
|
- 协议回调 reportMeta/reportUsed(useCallback 稳定引用)+ 模块级注册 id 跟踪
|
|
|
|
|
|
(ctx.slots.subscribe + entries);
|
|
|
|
|
|
- 持久化 loadView/loadProjects 显式挑字段(旧 groupBy 忽略)。
|
|
|
|
|
|
- 工作台 `01_content/src/client/styles.ts`:新增菜单分隔/添加面板/管理面板/快捷方式/编辑弱化样式;移除旧 tip 规则。
|
|
|
|
|
|
- 工作台 `01_content/package.json`:dsh.client.inject + peerDependencies 增加 @deepseek-ai/dsh-client-locale。
|
|
|
|
|
|
- travelatlas `src/client/index.tsx`:WorktableCard 升级协议 v2(WORKTABLE_CARD_ID、reportMeta、
|
|
|
|
|
|
reportUsed、hidden/order/nameOverrides 消费,约 20 行);浮层/降级回退/站点未动。
|
|
|
|
|
|
- 构建:两插件 npm run build + node --check 全部通过。
|
|
|
|
|
|
- 健康检查:/api/worktable/health 200(旧进程)。
|
|
|
|
|
|
|
|
|
|
|
|
## 完成状态
|
|
|
|
|
|
|
|
|
|
|
|
代码实现完成;GUI 验收待重启后进行(bundle 层启动时组合)。
|
|
|
|
|
|
|
|
|
|
|
|
## 验证方式与结果
|
|
|
|
|
|
|
|
|
|
|
|
- 工作台、travelatlas 均 npm run build + node --check 通过;
|
|
|
|
|
|
- /api/worktable/health 200;
|
|
|
|
|
|
- 机制预核实(读宿主源码):列表座位渲染器 display:contents 锚点 + 错误边界无 DOM 包裹
|
|
|
|
|
|
→ 卡片根节点为 .dsh-wt_projects 直接 flex 子项,CSS order 排序可行;
|
|
|
|
|
|
- 待验证:重启后 GUI 验收清单(PRD §9 v2 项)。
|
|
|
|
|
|
|
|
|
|
|
|
## 尚未验证 / 待续事项
|
|
|
|
|
|
|
|
|
|
|
|
- 重启后的 GUI 验收(排序/编辑模式/添加面板/i18n/隐藏);
|
|
|
|
|
|
- 未上报 v1 卡片的兼容展示(当前 profile 无此类卡片,需造测试插件验证);
|
|
|
|
|
|
- 管理面板 HTML5 拖拽在侧边栏内的交互体验;
|
|
|
|
|
|
- 宿主无插件清单 API(/api/plugins 等已探测 404),「自动发现已装项目」本版不可行——PRD §10 已知边界。
|
|
|
|
|
|
|
|
|
|
|
|
## 后续待办
|
|
|
|
|
|
|
|
|
|
|
|
- 重启 dsh web(schedule-restart.ps1 已安排)后按 PRD §9 v2 清单验收;
|
|
|
|
|
|
- 观察 travelatlas 降级回退是否正常(卸载工作台场景)。
|
|
|
|
|
|
|
|
|
|
|
|
## 涉及文件清单
|
|
|
|
|
|
|
|
|
|
|
|
| 文件 | 操作 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| dsh-worktable/01_content/src/client/locales.ts | 新增 |
|
|
|
|
|
|
| dsh-worktable/01_content/src/client/index.tsx | 重构 |
|
|
|
|
|
|
| dsh-worktable/01_content/src/client/styles.ts | 增删样式 |
|
|
|
|
|
|
| dsh-worktable/01_content/package.json | 声明 locale 依赖 |
|
|
|
|
|
|
| dsh-worktable/02_process/PRD.md | §3/§5/§6/§9/§10/§11 同步 |
|
|
|
|
|
|
| dsh-travelatlas/src/client/index.tsx | 卡片协议 v2(最小 diff) |
|
|
|
|
|
|
| 本文件 | 新增工作记录 |
|
|
|
|
|
|
|
|
|
|
|
|
## 补记(22:30 左右,重启验收阶段)
|
|
|
|
|
|
|
|
|
|
|
|
- 22:22 计划任务杀掉旧 dsh web 后,用户手动重启(22:22:59 起的新服务);工作台 v2 bundle
|
|
|
|
|
|
经字节级验证已在服务器生效,用户硬刷新后确认 GUI 正常(☰ 菜单/添加面板均为 v2)。
|
|
|
|
|
|
- **travelatlas 并行重写冲突**:22:10:44 其 src/client/index.tsx 被重写为 conversation.view
|
|
|
|
|
|
会话标签页架构(旧全屏浮层废弃),覆盖了本窗口早前应用在旧卡片上的 v2 协议改动。
|
|
|
|
|
|
- 处理:经用户确认后,把 v2 协议重新应用到新卡片(WorktableCard 约 20 行,不动 conversation.view
|
|
|
|
|
|
逻辑),重新构建并通过 node --check;验证服务器实时下发新 bundle(served len=9933、
|
|
|
|
|
|
含 WORKTABLE_CARD_ID/reportMeta),无需再次重启。
|
|
|
|
|
|
- **偶发排版错乱(已自愈)**:用户反馈界面排版乱、随后自行恢复。排查确认宿主资源未变、
|
|
|
|
|
|
travelatlas 样式为局部类、3080 仅一台服务器(npx 与 bin.js 为父子进程)。推断为页面刷新时
|
|
|
|
|
|
恰逢 travelatlas bundle 重建落盘(22:33:17)的写入竞争或重启后页面半载状态;无需代码修复。
|
|
|
|
|
|
教训:对外交付前应避免「用户可刷新的时间窗」内重打包插件。
|
|
|
|
|
|
|
|
|
|
|
|
## 补记(拖动与折叠体验修正)
|
|
|
|
|
|
|
|
|
|
|
|
- 需求(用户反馈):① 侧边栏折叠再展开、以及快速拖动越界松手时,不应重置到 footer,
|
|
|
|
|
|
而应回归上一次位置;② 折叠态不应显示「≡」,应显示一个框框收纳所有项目 emoji,
|
|
|
|
|
|
框框位置与展开前一致。
|
|
|
|
|
|
- 实现:① 移除 wide 变化时的 dock 重置(折叠/展开保持原停靠;仅窗口 resize 仍回弹 footer);
|
|
|
|
|
|
拖动新增越界判定(超出底部/顶部/侧边 24/24/80px 即「无有效落点」),松手回归拖前位置且不持久化;
|
|
|
|
|
|
② 折叠态渲染 .dsh-wt_railBox:项目 emoji(无报到卡片回退 📦)+ 快捷方式图标;
|
|
|
|
|
|
浮动态先以文档流实测折叠列几何(useLayoutEffect),再 fixed 定位到拖前高度;无项目时显示「≡」。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(served len=38441,含 railBox/overshoot 标记),
|
|
|
|
|
|
无需重启,用户刷新后实测。
|
|
|
|
|
|
|
|
|
|
|
|
## 补记(与 dsh-usage 余额 dock 的共存修正)
|
|
|
|
|
|
|
|
|
|
|
|
- 问题(用户反馈):侧边栏新出现 dsh-usage 的余额悬浮面板(.u_dock:position:fixed、
|
|
|
|
|
|
bottom:72px、z-index:30,覆盖在侧边栏底部),遮挡了工作台停靠区与 ≡ 手柄,导致无法拖动。
|
|
|
|
|
|
- 实现:① 停靠态自动避让——扫描侧边栏列内贴底(距底 <300px、left<80px)的 fixed 面板,
|
|
|
|
|
|
与区块自然位置重叠时以 margin-bottom 把区块抬到面板上方(上限 340px,含多重面板取最大值);
|
|
|
|
|
|
停靠期间每 2s 轮询跟随面板自身移动;浮动态不避让(z-index 70 天然在上)。
|
|
|
|
|
|
② 标题文字也作为拖拽手柄(≡ 与标题均可拖、双击复位),加大抓取面积。
|
|
|
|
|
|
③ 检测为通用算法(不硬编码 .u_dock 类名),不依赖 dsh-usage 内部结构。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(served len=40909,含 bottomInset/
|
|
|
|
|
|
measureBottomOverlay 标记),无需重启,用户刷新后实测。
|
|
|
|
|
|
|
|
|
|
|
|
## 补记(拖动无法落位的根因修复)
|
|
|
|
|
|
|
|
|
|
|
|
- 问题(用户反馈):能拖动,但松手必回原位。
|
|
|
|
|
|
- 根因:避让让位后停靠位置低于「固定 380px 估算的浮动上限 maxTop」,旧越界闩锁把起始位置
|
|
|
|
|
|
本身判定为越界 → 每次松手都触发「回归拖前位置」。
|
|
|
|
|
|
- 修复:① 浮动上限改为按区块实际高度计算(window.innerHeight - startRect.height - 12),
|
|
|
|
|
|
停靠位紧邻浮动范围下沿;② 取消拖动过程越界闩锁,改为「松手瞬间按指针位置判定落点」——
|
|
|
|
|
|
指针在有效落点区内则落位,越出(底/顶 24px、侧边 80px)才回归拖前位置。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(served len=40969),无需重启。
|
|
|
|
|
|
|
|
|
|
|
|
## 补记(折叠态图标框水平偏移修复)
|
|
|
|
|
|
|
|
|
|
|
|
- 问题(用户反馈):侧边栏收起后 emoji 图标框偏右,不在窄栏中间。
|
|
|
|
|
|
- 根因:折叠瞬间在过渡帧上测得「展开态」的列宽/left,fixed 定位用旧几何 → 图标按旧宽度居中而偏位。
|
|
|
|
|
|
- 修复:改为折叠动画结束后(320ms + 750ms 双次重测取收敛值)再测量并定位;测量带收敛守卫
|
|
|
|
|
|
(差值 <1px 不重复 setState)。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(served len=41341,含 measureRailRect),无需重启。
|
|
|
|
|
|
|
|
|
|
|
|
## 补记(悬浮窗宽度与 sidebar 联动)
|
|
|
|
|
|
|
|
|
|
|
|
- 需求(用户规格):悬浮窗只做宽度与水平定位的联动(高度仍由拖拽决定):
|
|
|
|
|
|
dockWidth = sidebar 宽 − paddingLeft − paddingRight − 40px(每边内缩 20px);
|
|
|
|
|
|
left = sidebar 左边缘视口坐标 + paddingLeft + 20px;
|
|
|
|
|
|
用 ResizeObserver 监听 sidebar(拖宽/折叠/窗口缩放实时跟随);
|
|
|
|
|
|
sidebar 识别 = 从挂载点向上遍历父链,className 含 SidebarRoot/sidebar 或标签 aside/nav,到 body 为止;
|
|
|
|
|
|
降级:找不到 sidebar 或宽度 ≤0 → left 固定 14px,宽度不设内联(CSS min-width:176px/max-width:264px)。
|
|
|
|
|
|
- 实现:FloatRect 精简为 { top }(left/width 全部由派生几何提供);新增 findSidebar 帮助函数、
|
|
|
|
|
|
floatGeo 状态与 measureFloatGeo(getBoundingClientRect + getComputedStyle 取 padding,取整);
|
|
|
|
|
|
useLayoutEffect 挂载首测 + ResizeObserver 订阅 + 卸载 disconnect,无轮询;
|
|
|
|
|
|
拖动仅更新 top,落点/回弹逻辑不变;.dsh-wt_float 增加 min/max 宽度兜底。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(served len=42718,含 findSidebar/ResizeObserver)。
|
|
|
|
|
|
|
|
|
|
|
|
## 补记(折叠图标放大 + 项目 emoji 定案 🌏)
|
|
|
|
|
|
|
|
|
|
|
|
- 需求(用户反馈):① 折叠态图标框里的 emoji 太小 → 放大(12px → 17px,行高 16 → 22px);
|
|
|
|
|
|
② 旅行 Atlas 的 emoji 不是用户给的 → 经询问定案为 🌏(地球·亚洲,U+1F30F);
|
|
|
|
|
|
③ 后续所有项目按各自上报的 emoji 展示(协议 reportMeta.icon 已支持,无需改工作台)。
|
|
|
|
|
|
- 改动:travelatlas src/client/index.tsx 全部图标统一 🌏(卡片/报到/降级入口/分栏标题),
|
|
|
|
|
|
重建并通过检查;worktable styles .dsh-wt_railIcon 放大。
|
|
|
|
|
|
- 备注 1:23:21:58 dsh web 被重启过一次(非本窗口发起,疑并行窗口操作),打断了我的一步验证,
|
|
|
|
|
|
服务恢复后健康检查正常。
|
|
|
|
|
|
- 备注 2:travelatlas 客户端在本窗口期间被并行重写两次(会话标签页版 → 分栏模式版),
|
|
|
|
|
|
每次重写都会覆盖 v2 协议与 emoji;本窗口已两次重新应用。
|
|
|
|
|
|
- 备注 3(验证教训):esbuild 默认 ascii charset,非 ASCII 字符在 bundle 里以 \u{...} 转义
|
|
|
|
|
|
输出,且 pwsh Get-Content/IWR 按 ANSI 解码 UTF-8——校验 emoji 需用 read 工具读 UTF-8
|
|
|
|
|
|
或直接查转义序列(如 1F30F)。
|
2026-08-16 23:55:38 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(checkpoint + GitHub 推送)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户确认效果稳定,执行 checkpoint:dsh-worktable 建 git 仓库(branch main),
|
|
|
|
|
|
本地身份 Aisland <eechaoserebus@gmail.com>,首次提交 d58cbc5(20 文件;
|
|
|
|
|
|
node_modules/lib/03_local/日志按根 .gitignore 排除);README「当前状态」段同步为 v2。
|
|
|
|
|
|
- 推送到 GitHub 私有仓库 https://github.com/Aisland-SJL/dsh-worktable:
|
|
|
|
|
|
安装 gh CLI(winget,v2.97.0);设备授权流程首次因网络超时失败——根因为系统代理
|
|
|
|
|
|
(127.0.0.1:7890)只作用于 WinINET,gh CLI 需显式 HTTPS_PROXY 环境变量;
|
|
|
|
|
|
带上代理重试成功,账号为 Aisland-SJL,创建私有仓库并推送 main=d58cbc5,已验证同步。
|
|
|
|
|
|
- 遗留:lib/ 未入库(clone 后需 npm install && npm run build);
|
|
|
|
|
|
01_content 内缺 README.md/LICENSE(开源独立发布前补);版本号仍 0.1.0(开源前升 0.2.0)。
|
|
|
|
|
|
|
|
|
|
|
|
## 补记(多项目分栏框架设计定案)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户规划后续项目:建筑审图工作台(图纸+规范+对话 3 栏)、网页动画生成工作台(4+ 栏)、
|
|
|
|
|
|
机器人工作台(2 栏)等,均以「内容栏并置 + 右侧对话」形式入驻工作台。
|
|
|
|
|
|
- 讨论结论(用户确认):路线 B——工作台内置「声明式多栏」分栏框架(openSplit(spec) 回调),
|
|
|
|
|
|
框架管几何(会话根探测/挤右栏/拖分隔线/Esc/宽度持久化),项目管声明(panes 数组 + iframe URL
|
|
|
|
|
|
为主、component 预留位);路线 A(项目自带 overlay)作为逃生舱并存。
|
|
|
|
|
|
- 落地:PRD §12 写入设计规格(SplitSpec/框架职责/实施时机),代码待第一个新项目开工时实现;
|
|
|
|
|
|
§11 状态表同步;本窗口暂不写代码(用户选择「先落设计」)。
|
2026-08-17 00:28:30 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(travelatlas 分栏「切会话不关闭」补丁)
|
|
|
|
|
|
|
|
|
|
|
|
- 需求(用户):分栏模式下切换不同对话时,左侧旅行网页保持不消失;仅 ✕ / 再点工作台卡片 /
|
|
|
|
|
|
Esc / 无任何活动会话时关闭。
|
|
|
|
|
|
- 实现(travelatlas src/client/index.tsx,store 层):
|
|
|
|
|
|
① 新增 syncAnchor:会话根失效时找新根重新锚定(恢复旧视图区 margin、更新 root/header/viewArea、
|
|
|
|
|
|
RO 改观察新根、几何重算),左侧 iframe 组件保持挂载不卸载不刷新;
|
|
|
|
|
|
② findConversationRoot 优先 phase=active(避免过渡期命中旧根);
|
|
|
|
|
|
③ 新增 body 级 MutationObserver 兜底(attributeFilter data-phase + childList),
|
|
|
|
|
|
覆盖「旧根被替换后 RO 不再回调」与 phase 过渡态;close 时一并断开;
|
|
|
|
|
|
④ 关闭条件收敛为:无任何会话根 / 结构无法识别 / ✕ / Esc / 再点卡片。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(served len=17083,含 syncAnchor/MutationObserver);
|
|
|
|
|
|
待用户刷新后实测「切会话左侧保持、点 ✕/卡片才关闭」。
|
|
|
|
|
|
- 该行为已同步写入 PRD §12.4 框架规格(所有未来项目默认继承)。
|
|
|
|
|
|
|
|
|
|
|
|
## 补记(分隔线向左范围放开)
|
|
|
|
|
|
|
|
|
|
|
|
- 需求(用户):分栏分隔线向右可移、向左有上限(聊天栏最大 480px 且图鉴保留 260px),
|
|
|
|
|
|
希望对话框更大、分隔线能再往左。
|
|
|
|
|
|
- 实现(travelatlas):删除 MAX_CHAT_W=480 固定上限;新增 MIN_ATLAS_W=160,
|
|
|
|
|
|
聊天栏钳制改为 [240, max(240, 列宽−160)]——左侧图鉴最小保留 160px,其余全给聊天栏。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(served len=17070,含 MIN_ATLAS_W)。
|
|
|
|
|
|
- PRD §12.4 对话栏宽度语义同步(上限=列宽−内容最小宽,不再固定 480)。
|
|
|
|
|
|
|
|
|
|
|
|
## 补记(乐高式工作区构想 → PRD §13 设计定稿)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户构想:把工作台做成「乐高基座」——「+」新建工作区时提供 2/3/4 窗拓扑预设
|
|
|
|
|
|
(左右/上下/3 横排/上一下二/井字/3+1),其中一窗恒为聊天窗(继承全部会话、切会话不消失),
|
|
|
|
|
|
其余窗放置内容插件(浏览器/资源管理器/源代码管理/任务管理/终端/自定义 vibe 生成)。
|
|
|
|
|
|
- 评估结论(已与用户确认):可行;核心 = 分割树 tiling 引擎 + PaneProvider 内容插件协议;
|
|
|
|
|
|
硬约束 = 聊天窗必须贴右/下边缘(margin 挤法的能力边界);内容窗可行性分级记录(浏览器✅、
|
|
|
|
|
|
资源管理器/终端/任务管理🔶待调研、SCM⚠️受限、自定义✅闭环)。
|
|
|
|
|
|
- 落地:PRD §13 设计定稿(13.1–13.9:目标/硬约束/分割树/内容协议/+面板改版/持久化/
|
|
|
|
|
|
可行性记录/里程碑 M1-M3/协议关系);§12 并入 §13 引擎;§11 状态表同步;
|
|
|
|
|
|
代码按用户选择暂不实现。
|
2026-08-17 00:37:39 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(M1 布局引擎实现 + dsh-planreview 测试车)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户指令:不动 travelatlas;新建「建筑审图」项目作为 M1 测试车,开始实现。
|
|
|
|
|
|
- 新建 dsh-planreview(E:\AI_Workspace\DeepseekHarness\Projects\dsh-planreview):
|
|
|
|
|
|
工作台项目模板结构(00_index/01_content/02_process/03_local/04_test + AGENTS/README/.gitignore);
|
|
|
|
|
|
服务端托管 /planreview/drawing/ 与 /planreview/spec/ 占位页 + /api/planreview/health;
|
|
|
|
|
|
客户端工作台卡片(协议 v2:📐 报到/埋点/隐藏/排序/改名)+ openSplit 三窗声明
|
|
|
|
|
|
(main=[图纸,规范] + 聊天,chatWidth 240–600)+ 工作台缺席降级提示入口。
|
|
|
|
|
|
- 工作台 M1 引擎:新增 01_content/src/client/split.tsx(splitStore + SplitWorkspace)——
|
|
|
|
|
|
布局模型 = 标题栏 + 顶部通栏行(可选) + 主行内容窗 + 右下聊天窗;聊天窗 = marginLeft+marginTop
|
|
|
|
|
|
组合挤法(官方会话视图区整体);会话切换重锚定不关闭(复用 §12.4 方案);
|
|
|
|
|
|
chat/top/pane/topPane 四类分隔线拖拽;dsh.worktable.split.v1 按 layoutId 持久化各宽度;
|
|
|
|
|
|
Esc/✕ 退出。owner props 新增 openSplit(spec);shell.overlay 注册 dsh-worktable-split。
|
|
|
|
|
|
- 构建与注册:两插件构建 + node --check 通过;profile packages.json 增加
|
|
|
|
|
|
dsh-planreview(link + bundles,位于 worktable 之后 travelatlas 之前);
|
|
|
|
|
|
node_modules/dsh-planreview junction 已建;服务端已实时下发新 worktable bundle
|
|
|
|
|
|
(served len=59982,含 SplitWorkspace/splitStore/openSplit)。
|
|
|
|
|
|
- 待验证:重启 dsh web 后 GUI 验收(见 dsh-planreview PRD §4 清单)。
|
2026-08-17 00:46:06 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(反选 + 项目互斥规则)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:① 建筑审图卡片没有反选(再点应关闭,travelatlas 有);② 项目间应互斥——
|
|
|
|
|
|
选 B 关 A,网页窗口同一时刻只容纳一个项目;多项目并行应靠多开浏览器窗口。
|
|
|
|
|
|
- 实现(工作台 split.tsx,不动 travelatlas):
|
|
|
|
|
|
① 反选:open(spec) 若同 id 已激活 → close 并返回;
|
|
|
|
|
|
② 替换:开前先关旧(引擎内天然互斥);
|
|
|
|
|
|
③ 共享协议:打开时广播 window CustomEvent 'dsh:split-claim',并监听让位(其他接入
|
|
|
|
|
|
协议的分栏引擎据此互斥——未来项目默认继承);
|
|
|
|
|
|
④ 未接入协议的引擎兼容:打开前运行时点击 .ta_splitClose 关闭 travelatlas 分栏
|
|
|
|
|
|
(不改其代码,迁入引擎后移除);另设让位观察器——视图区 margin 被外部改写即关闭自身
|
|
|
|
|
|
(覆盖「先开审图再点旅行」的反向场景)。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(含 split-claim/yieldObserver/ta_splitClose
|
|
|
|
|
|
标记);待用户刷新后实测两个方向与反选。
|
2026-08-17 00:50:36 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(卡片选中效果 + 埋点收敛)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:① 建筑审图打开后卡片无「选中」效果(旅行 Atlas 有);② 「最近」排序下每次点击
|
|
|
|
|
|
都置顶,体验差——应只在工作区真正打开(有改动)时计一次使用。
|
|
|
|
|
|
- 实现:
|
|
|
|
|
|
① owner props 新增 activeSplitId(工作台订阅 splitStore 激活态下发);planreview 卡片
|
|
|
|
|
|
data-on=active 高亮(蓝边 + 名称高亮),样式与旅行 Atlas 同类;
|
|
|
|
|
|
② 埋点收敛(worktable reportUsed 过滤):引擎项目(调用过 openSplit 的 id)仅在本次点击
|
|
|
|
|
|
导致工作区打开时计使用,关闭/重复点击不计;遗留自带分栏的项目(travelatlas,不改其代码)
|
|
|
|
|
|
用 15s 冷却去重;无判定依据的普通项目保持原行为;
|
|
|
|
|
|
③ planreview 无需改埋点逻辑(引擎内统一过滤)。
|
|
|
|
|
|
- 验证:两插件构建 + node --check 通过;服务端实时下发(含 activeSplitId/
|
|
|
|
|
|
LEGACY_BUMP_COOLDOWN 标记);待用户刷新实测。
|
2026-08-17 00:56:33 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(排序默认改为「手动」)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:最近排序下点击仍有反复置顶,体验差 → 定案:默认「手动」排序,
|
|
|
|
|
|
喜欢「最近」的用户自行切换。
|
|
|
|
|
|
- 实现:loadView 一次性迁移(sortMigratedV2 标记)——旧存「最近」自动回落「手动」;
|
|
|
|
|
|
用户此后手动选择「最近」会写入标记并被尊重;persistView 统一写入标记。
|
|
|
|
|
|
fresh 状态默认本就 manual(DEFAULTS.orderBy='manual')。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(含 sortMigratedV2);待用户刷新确认。
|
2026-08-17 01:01:08 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(「+」新建工作区:拓扑预设 + 布局条目)
|
|
|
|
|
|
|
|
|
|
|
|
- 完成 M1 剩余项(PRD §13.5/§13.8):
|
|
|
|
|
|
① 「+」面板新增「新建工作区」区:四个拓扑预设(左右两栏/三栏横排/上一下二/井字四栏,
|
|
|
|
|
|
聊天窗恒贴右)+ 布局名称 + 各内容窗 URL(校验 / 或 http(s) 开头)→ 保存并直接打开;
|
|
|
|
|
|
② 布局条目 = 一等公民:进入项目区(🧱 卡片 + 布局角标 + N 窗描述),参与搜索/隐藏/改名/
|
|
|
|
|
|
↑↓ 与拖拽排序/「最近」排序(打开计使用)/选中态(activeSplitId)/折叠图标框;管理条内可删除;
|
|
|
|
|
|
③ 持久化进 dsh.worktable.projects.v1.layouts(LayoutSpec 数组)。
|
|
|
|
|
|
- 词典新增 12 键(zh/en);样式新增预设按钮与布局卡片。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(含 PRESET_DEFS/saveLayout/dsh-wt_layout);
|
|
|
|
|
|
待用户刷新实测。
|
2026-08-17 01:19:03 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(+ 面板改版:可视化布局选择 + 窗内 6 选 1 + 聊天左右切换)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户定案(参照 better-sidebar 交互):
|
|
|
|
|
|
① + 面板移除「接入新项目」说明,第一步 = 可视化布局缩略图选择(画出来的窗格示意,
|
|
|
|
|
|
聊天窗蓝色 💬);② 选完只填一个布局名称即可进入,不再填内容地址;
|
|
|
|
|
|
③ 进入后每个窗内 6 选 1 内容(浏览器/资源管理器/源代码管理/任务管理/终端 + 自定义;
|
|
|
|
|
|
better-sidebar 是 5 项,我们多一个自定义);④ 窗位可调整(标题栏拖拽换位),
|
|
|
|
|
|
聊天窗可切左下/右下。
|
|
|
|
|
|
- 实现(工作台 split.tsx 重写 + index.tsx/locales/styles):
|
|
|
|
|
|
① LayoutSpec 增加 chatSide('left'|'right');聊天居左 = marginRight 挤法(新),
|
|
|
|
|
|
居右 = marginLeft(原有);工具栏 ⇄ 翻转按钮;
|
|
|
|
|
|
② SplitContent 三态扩展:null(未指派)/iframe/builtin(browser|explorer|scm|tasks|terminal);
|
|
|
|
|
|
未指派窗渲染 6 选 1 网格;浏览器内置窗带地址栏;其余内置窗显示「开发中」占位;自定义 = URL 输入;
|
|
|
|
|
|
③ swapPanes 拖拽换位(同行交换 + 跨行互换,宽度跟随);setPaneContent/setChatSide/
|
|
|
|
|
|
swapPanes 变更经 splitStore.onSpecMutated 回调回写 projects.v1.layouts(持久化);
|
|
|
|
|
|
④ + 面板:缩略图预设(presetThumb 纯 CSS 窗格图)+ 名称输入 +「进入工作区」;
|
|
|
|
|
|
⑤ 引擎 UI 文案经 setSplitT 注入 locale(zh/en 新增 15 键)。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(含 presetThumb/PanePicker/setChatSide/swapPanes);
|
|
|
|
|
|
待用户刷新实测。
|
2026-08-17 01:23:29 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(+ 面板改为右侧弹出悬浮窗)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户要求:+ 点击后向右弹出窗口(非展开下拉),窗口比例适配内容;不安排自动重启(其他窗口仍在工作)。
|
|
|
|
|
|
- 实现:addOpen 时渲染透明全屏遮罩(点击关闭)+ fixed 弹出面板:宽 320px、
|
|
|
|
|
|
left = sidebar 右边缘 + 8(视口内钳制,sidebar 右边缘由既有 ResizeObserver 测量维护)、
|
|
|
|
|
|
top = 工作台区块顶部(钳制 56..视口-540);内容不变(布局缩略图 → 名称 → 进入 /
|
|
|
|
|
|
快捷方式表单);样式 .dsh-wt_pop 限高滚动 + 阴影。
|
|
|
|
|
|
- 构建 + node --check 通过;服务端实时下发(含 popBackdrop/dsh-wt_pop),无需重启,用户刷新生效。
|
2026-08-17 11:32:45 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(+ 弹窗精简 + 布局扩为 6 个 + 左列布局引擎支持)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户定案:① + 弹窗去掉「本地快捷方式」表单(只留布局选择 + 名称;存量快捷方式条目仍保留);
|
|
|
|
|
|
② 布局扩为 6 个:新增「左一右二」(左侧一个整高窗,右侧竖排两个,右下为聊天)与
|
|
|
|
|
|
「上一下三」(上面一个通栏,下面横分三个,最右为聊天);6 个布局 2 行 × 3 列排布。
|
|
|
|
|
|
- 引擎(split.tsx):LayoutSpec 新增 left(左列整高内容窗,可选)+ leftWidth;左列布局下
|
|
|
|
|
|
聊天固定右下(marginLeft=leftW + marginTop 组合挤法),⇄ 翻转按钮隐藏;新增 setLeftW 与
|
|
|
|
|
|
'left' 分隔线(左/右列边界拖拽);setPaneContent/swapPanes 泛化支持 left 行;leftW 持久化。
|
|
|
|
|
|
- 预设与 UI(index.tsx/locales/styles):PRESET_DEFS 增 leftCount 字段与 l2/t3 两项;
|
|
|
|
|
|
缩略图新增左列样式(thumbCols/thumbCol);预设网格 3 列;弹窗移除快捷方式表单及对应状态/函数
|
|
|
|
|
|
(removeShortcut 保留);词典新增 preset.l2/preset.t3。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(含 preset.l2/leftWidth/setLeftW);
|
|
|
|
|
|
待用户刷新实测。
|
2026-08-17 11:37:46 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(第 6 个布局改为「左品右聊」)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户定案:上一下三 改为——左侧品字形(上一个、下两个内容窗)+ 右侧聊天窗通高整列。
|
|
|
|
|
|
- 引擎:LayoutSpec 新增 chatFullHeight(聊天通高:marginTop 不再被 top 行下推、
|
|
|
|
|
|
top 行排入内容区一侧、聊天分隔线全高、工具栏宽度取内容区宽);
|
|
|
|
|
|
该布局支持 ⇄ 翻转(聊天通高贴左时内容区在右)。
|
|
|
|
|
|
- 预设:t3 的 chatFull=true;缩略图改为左品字 + 右通高聊天;词典 preset.t3 改名「左品右聊 / Pin + chat」。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;服务端实时下发(含 chatFullHeight);待用户刷新实测。
|
2026-08-17 11:47:35 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(5 个功能窗照搬 better-sidebar 架构,第一版实现)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户要求:参照已安装的 dsh-better-sidebar,把前 5 个内容窗(浏览器/资源管理器/
|
|
|
|
|
|
源代码管理/任务管理/终端)做成真正生效的,自定义暂缓。
|
|
|
|
|
|
- 调研结论(better-sidebar 架构):内容窗能力 = 它自己服务端的路由(fs 列表、git 命令、
|
|
|
|
|
|
node-pty + WebSocket 升级路由、任务回放)+ 客户端 xterm/iframe;注册 Upgrade 走
|
|
|
|
|
|
ctx.webServer.registerUpgrade。
|
|
|
|
|
|
- 实现(dsh-worktable):
|
|
|
|
|
|
① 服务端重写(src/index.ts):POST /api/worktable/fs(readdir 目录优先排序、上限 500)、
|
|
|
|
|
|
POST /api/worktable/git(status porcelain v1 -z + 分支)、WS /api/worktable/term
|
|
|
|
|
|
(node-pty 生成 shell + resize 协议;node-pty/ws 缺失时路由不注册、终端窗降级提示);
|
|
|
|
|
|
build.mjs 服务端 external 增加 ws/node-pty(运行时从宿主 node_modules 解析,
|
|
|
|
|
|
better-sidebar 已带)。
|
|
|
|
|
|
② 客户端(split.tsx):ExplorerPane(面包屑路径/上一级/后退/刷新/目录进入)、
|
|
|
|
|
|
GitPane(分支 + 变更清单,XY 着色)、JobsPane(sessions 快照 jobsBySession 列表、
|
|
|
|
|
|
状态圆点、2s 刷新)、TerminalPane(xterm + WS + ResizeObserver fit/resize);
|
|
|
|
|
|
新增 SplitEnv(setSplitEnv 注入 getScope/getJobs),工作台从 useSessions 快照取
|
|
|
|
|
|
当前会话与 cwd、jobsBySession。
|
|
|
|
|
|
③ 依赖:devDependencies 增加 xterm ^5.3.0(已 npm install,打包进 client.js)。
|
|
|
|
|
|
- 注意:服务端路由改动需**重启 dsh web 后生效**(bundle 启动时组合;客户端已实时下发)。
|
|
|
|
|
|
未安排自动重启(用户要求,其他窗口仍在工作)。
|
|
|
|
|
|
- 待后续:文件打开/编辑、SCM diff/暂存/提交、终端 cwd 信任客户端(better-sidebar 用
|
|
|
|
|
|
服务端 header.cwd,后续对齐)、jobs 输出回放。
|
2026-08-17 12:10:34 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(重启后工作台消失:useSessions 崩溃排查与修复)
|
|
|
|
|
|
|
|
|
|
|
|
- 现象:用户重启 dsh web 后侧边栏工作台与各项目卡片全部消失(服务端正常、bundle 正常下发)。
|
|
|
|
|
|
- 排查:opencli 绑定用户标签页失败(被另一 Chrome 扩展占用调试通道);改用
|
|
|
|
|
|
Node + headless Chrome + CDP 自建诊断(04_test/headless-diag.cjs),在真实浏览器引擎
|
|
|
|
|
|
中复现并捕获到根因:`slot entry crashed in 'sidebar.footer.action':
|
|
|
|
|
|
TypeError: w is not a function`(宿主 useSyncExternalStore 包装层)——触发点是
|
|
|
|
|
|
WorktableSection 调用 `props.useSessions()`(GlobalStandardProps 的 selector hook
|
|
|
|
|
|
在该宿主版本的 footer.action 座位里崩坏)。
|
|
|
|
|
|
- 修复:不再使用 props.useSessions;改为 apply() 里订阅 `ctx.sessions.list`
|
|
|
|
|
|
(ObservableSnapshot.getSnapshot/subscribe,client inject 增加 'sessions'),
|
|
|
|
|
|
写入模块级 sessionScopeStore;组件与分栏引擎(setSplitEnv getScope/getJobs)直接读该快照。
|
|
|
|
|
|
- 回归验证:headless Chrome 重跑——wtSection/railBox 渲染正常、ERRORS_COUNT=0;
|
|
|
|
|
|
用户刷新即恢复(客户端实时下发,无需重启)。
|
|
|
|
|
|
- 工具沉淀:04_test/headless-diag.cjs(headless Chrome + CDP 页面诊断,可复用)。
|
2026-08-17 12:19:08 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(功能窗标签页模型 + 数据层修复)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:① 窗口内容一旦选定就无法更换/回退;② 资源管理器、后台任务没有内容;
|
|
|
|
|
|
③ 交互形态与 better-sidebar 差异大、不可用。
|
|
|
|
|
|
- 实现:
|
|
|
|
|
|
① 标签页模型(split.tsx):SplitPane 增加 tabs[]/active(兼容旧 content 字段,打开时
|
|
|
|
|
|
归一化为单标签);openTab/closeTab/setActiveTab 三个变更方法;窗内标签栏(多标签可切换、
|
|
|
|
|
|
✕ 关闭;关完回到 6 选 1 选择器);标签标题 = 内置类型名或 URL 主机名;变更经
|
|
|
|
|
|
onSpecMutated 回写持久化。
|
|
|
|
|
|
② 数据层(服务端):inject 增加 'sessions'(better-sidebar 同款),serverCwd 解析 =
|
|
|
|
|
|
header.cwd → 客户端 cwd → process.cwd();fs/git/term 三路由全部走该解析;
|
|
|
|
|
|
客户端请求带 sessionId。解决「资源管理器没有内容」(此前仅依赖客户端列表 cwd,缺失时空白)。
|
|
|
|
|
|
③ 任务窗数据源不变(jobsBySession,无后台任务时显示空态文案)。
|
|
|
|
|
|
- 验证:构建 + node --check 通过;headless Chrome 回归零报错、区块正常渲染。
|
|
|
|
|
|
- 注意:服务端 cwd 解析需**重启 dsh web 后生效**;标签页模型为客户端改动、刷新即生效。
|
2026-08-17 12:28:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(对照 better-sidebar 源码重做:树形资源管理器 / 子代理任务窗 / 终端依赖解析)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:① 资源管理器刷新/后退按钮失效(只有上一级能用);② 终端空白;③ 任务窗
|
|
|
|
|
|
没有 Agent 情况;④ 要求对照 better-sidebar 源码重做(树形展开 + 重绘图标)。
|
|
|
|
|
|
- 调研:better-sidebar 客户端 16px 描边 SVG 图标 + 子代理树(aria-expanded、缩进、当前高亮);
|
|
|
|
|
|
服务端 inject ['webServer','sessions','webRuntime','tools']。
|
|
|
|
|
|
- 实现:
|
|
|
|
|
|
① 资源管理器重写为树形:懒加载子目录(缓存 + 展开集)、▸/▾ 旋转箭头、重绘文件夹/文件
|
|
|
|
|
|
SVG 图标、缩进层级;刷新(清缓存重载根)与上一级(根上移)修复可用(旧版在 setState
|
|
|
|
|
|
更新器里做副作用导致按钮失效,已避免)。
|
|
|
|
|
|
② 任务窗增加「子代理」区(sessions 快照 subagentsByParent[current],防御式取数,
|
|
|
|
|
|
状态圆点 + 缩进),与后台任务并列。
|
|
|
|
|
|
③ 终端空白根因:服务端 import('node-pty')/import('ws') 失败——本包经 junction 链接,
|
|
|
|
|
|
模块真实路径在工作区,向上找不到 profile 级依赖。修复:loadPkg 沿「junction 路径 +
|
|
|
|
|
|
realpath」两条祖先链 createRequire 查找并加载;已本地验证 junction 路径可解析
|
|
|
|
|
|
node-pty/ws。**需重启 dsh web 后终端路由才注册。**
|
|
|
|
|
|
- 验证:构建 + node --check 通过;headless Chrome 回归零报错;依赖解析测试通过。
|
|
|
|
|
|
- 差距(M3 待续):文件打开/编辑器、SCM diff/暂存/提交、任务输出回放。
|
2026-08-17 12:49:27 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(内容窗收敛为 4 项 + 终端修复验证 + 标签跨窗拖动)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户定案:内容窗收敛为 4 项(浏览器/资源管理器/终端/自定义),源代码管理与任务管理
|
|
|
|
|
|
暂砍(非重点);重点修终端并验证浏览器。
|
|
|
|
|
|
- 实现:
|
|
|
|
|
|
① 选择器砍为 4 项(SCM/Tasks 移除);
|
|
|
|
|
|
② 终端修复:loadPkg 沿「junction 路径 + realpath + ~/.dsh/profiles/*/node_modules」
|
|
|
|
|
|
三链解析 ws/node-pty(此前 import 直接失败);修 readdir 误用(回调版→readdirSync);
|
|
|
|
|
|
新增 04_test/term-e2e.cjs 端到端测试(模拟宿主经 junction 加载 bundle,真实 ws 客户端 +
|
|
|
|
|
|
真实 node-pty shell)→ **RESULT: PASS(echo 回显正常)**;
|
|
|
|
|
|
③ 资源管理器点击 .html/.htm → 自动开浏览器标签(/api/worktable/file 服务端文件路由,
|
|
|
|
|
|
内容类型按扩展名,20MB 上限);
|
|
|
|
|
|
④ 标签跨窗拖动:标签 draggable + 窗容器接收(dragOver/drop)+ 吸附动画
|
|
|
|
|
|
(data-drop-hover 边框辉光 + scale 过渡)+ moveTab(源移除/目标追加/激活末位/持久化);
|
|
|
|
|
|
⑤ 调试出口 window.__dshWorktable={splitStore} + 04_test/functional-diag.cjs
|
|
|
|
|
|
(headless Chrome 分步自动化:打开布局→2 选择器×4 选项→开浏览器/资源管理器标签→
|
|
|
|
|
|
跨窗移动标签→关闭)→ **全绿、零报错**。
|
|
|
|
|
|
- 注意:服务端改动(file 路由 + 终端 loadPkg)需**重启 dsh web 生效**;
|
|
|
|
|
|
客户端改动(4 选项/HTML 点击开标签/拖动吸附)刷新即生效。
|
2026-08-17 12:54:40 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(fs 500 与终端无响应修复)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户重启后反馈:① 资源管理器 Error: HTTP 500;② 终端无法敲命令(pwd 无响应);
|
|
|
|
|
|
③ 标签拖拽吸附好评。
|
|
|
|
|
|
- 根因:
|
|
|
|
|
|
① fs 路由 ReferenceError: resolve is not defined——改 import 时将 resolve 重命名
|
|
|
|
|
|
pathResolve,函数体仍用旧名(探活服务端拿到的真实报错);
|
|
|
|
|
|
② 终端 ws 路由是异步注册(await import 之后才 registerUpgrade),宿主错过晚注册的
|
|
|
|
|
|
升级路由 → 握手失败、终端空白。
|
|
|
|
|
|
- 修复:① resolve → pathResolve(listDirectory 与 file 路由两处);
|
|
|
|
|
|
② setupTerminal 改同步(只用同步 loadPkg 解析 ws/node-pty)+ 注册包进 ctx.effect
|
|
|
|
|
|
(better-sidebar 同款生命周期)。
|
|
|
|
|
|
- 验证(04_test/term-e2e.cjs 扩展):fs handler 直调 200 + 真实条目;终端 E2E
|
|
|
|
|
|
RESULT: PASS(真实 cmd.exe shell,pwd 回显正常)。**需再重启一次 dsh web 生效。**
|
2026-08-17 20:45:29 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(浏览器 file 路由 readFile 坑 + 终端实机验证 + 客户端焦点)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:① 浏览器打不开(错误 JSON = file 路由抛
|
|
|
|
|
|
ERR_INVALID_ARG_TYPE cb must be function——readFile 用了 node:fs 回调版,
|
|
|
|
|
|
与 readdir 同一类坑);② 终端仍无法敲命令。
|
|
|
|
|
|
- 处理:
|
|
|
|
|
|
① readFile 改 node:fs/promises(file 路由本地直调 200 + README 内容,已验证);
|
|
|
|
|
|
② 终端**实机验证**:直接对用户运行中的服务器(20:40:44 启动)跑 ws + pwd →
|
|
|
|
|
|
RESULT: PASS(cmd.exe 真实回显 E:\AI_Workspace)——服务端已通!用户侧「敲不了」
|
|
|
|
|
|
定位为客户端焦点问题:TerminalPane 增加 open 后自动 focus + 点击聚焦 + ws.onopen 聚焦;
|
|
|
|
|
|
③ 客户端焦点修复实时下发(F5 生效);file 路由修复需再重启一次。
|
2026-08-17 20:48:13 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(终端 shell 换 PowerShell + 浏览器默认页 + 标记回显验证)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:终端报 'pwd' is not recognized(说明终端已通,但 shell 是 cmd.exe——
|
|
|
|
|
|
pwd/ls 是 PowerShell/bash 命令);浏览器标签页打不开。
|
|
|
|
|
|
- 处理:① 服务端 spawnShell Windows 改 powershell.exe -NoLogo(pwd/ls 等可用);
|
|
|
|
|
|
② 浏览器默认页 bing.com → example.com(bing 带 X-Frame-Options 禁止 iframe 嵌入,
|
|
|
|
|
|
是「打不开」的另一半原因);③ E2E 改为 marker echo 验证(此前 PASS 被 shell banner
|
|
|
|
|
|
误判);④ 实机验证:对运行中服务器 echo 回显 OK(输入链路确认通)。
|
|
|
|
|
|
- 验证:harness(PowerShell 壳)marker 回显 PASS(含 PSReadLine 着色码,确认 PowerShell);
|
|
|
|
|
|
实机 cmd 壳 marker 回显 PASS;file 路由直调 200。
|
|
|
|
|
|
- 生效:终端 shell 与 file 路由 = 服务端,**需重启 dsh web**;浏览器默认页 = 客户端,F5 即生效。
|
2026-08-17 21:04:17 +08:00
|
|
|
|
## 补记(6 预设默认比例均衡化 + 窗内 4 按钮居中自适应)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:① 6 个布局预设默认窗格比例失衡(最后一个窗吃掉全部余量,其余全贴 min);
|
|
|
|
|
|
② 空窗里的 4 个内容选项(浏览器/资源管理器/终端/自定义)贴顶部且按钮拉伸,要求:
|
|
|
|
|
|
按钮固定大小、整体居中,并按窗位形状自适应排列(宽窗横排 / 方窗 2×2 / 竖窗竖排)。
|
|
|
|
|
|
- 处理:
|
|
|
|
|
|
① 均衡默认(split.tsx open()):无存档尺寸时不再 panes.map(p => p.min),
|
|
|
|
|
|
而是按当前几何均分:内容窗宽度均分、顶行均分、左列 38%、顶行高 35%、聊天 30%
|
|
|
|
|
|
(全部按各自 min/max 夹取)。根因是 allocate() 最后一个窗拿余量的退化模型。
|
|
|
|
|
|
② 持久化键 dsh.worktable.split.v1 → v2:旧存档里全是失衡宽度,升级键位让新默认生效
|
|
|
|
|
|
(用户手调过的宽度一次性重置,属预期)。
|
|
|
|
|
|
③ Picker 自适应(split.tsx PanePicker + styles.ts):容器 flex 居中,
|
|
|
|
|
|
ResizeObserver 按宽高比切换三态:aspect>1.4 → row(横排)/ 0.72~1.4 → grid(2×2)/
|
|
|
|
|
|
<0.72 → col(竖排);按钮固定 92×78 圆角卡片(图标 22px + 标签),不再拉伸铺满;
|
|
|
|
|
|
自定义表单同步居中(max-width 320px)。
|
|
|
|
|
|
- 验证(04_test/functional-diag.cjs 扩展断言):STEP1 paneWs=[228,228] 均分
|
|
|
|
|
|
(旧逻辑为 [200,262]);STEP2 pickerModes 均为 -col(无头视口竖窗)+ pickSize
|
|
|
|
|
|
{w:92,h:78};STEP3-5 回归不变;ERRORS_COUNT: 0。bundle-eval 补桩
|
|
|
|
|
|
(navigator.userAgent/platform、canvas getContext)后 PASS。
|
|
|
|
|
|
- 备注:本次为纯客户端改动,F5 即生效,无需重启 dsh web。
|
2026-08-17 21:22:20 +08:00
|
|
|
|
## 补记(项目卡片统一加框 + 小字精简 + 图标可选 + 新建布局唯一性互斥)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈(四条命令合并执行):
|
|
|
|
|
|
① 加号新建的项目侧栏卡片有框、两个入驻项目(建筑审图/旅行 Atlas)没框 → 统一加框;
|
|
|
|
|
|
② 新建布局与旅行 Atlas 可同时打开 → 全部项目共用唯一互斥(开一个关前一个);
|
|
|
|
|
|
③ 项目标签只留名字一行,去掉描述小字(建筑审图/旅行 Atlas);
|
|
|
|
|
|
④ 左侧 emoji 要能点开一套完整图标列表换选(新项目一直是砖墙 🧱 换不了)。
|
|
|
|
|
|
- 处理(不改动 travelatlas/building-agent 代码,全部在本插件侧):
|
|
|
|
|
|
① styles.ts:.dsh-wt_projects 内 .ta_card/.pr_card 静止态常显边框+底色(与布局卡同款),
|
|
|
|
|
|
静止态带框 + hover 高亮;同时 .ta_cardDesc/.pr_cardDesc display:none(小字去掉);
|
|
|
|
|
|
② split.tsx:新增 MutationObserver——.ta_split 浮层(travelatlas 引擎打开)出现即 close() 本引擎;
|
|
|
|
|
|
反向(本引擎打开 → 点旅行 Atlas)沿用既有 .ta_splitClose 桥;互斥全项目(含 + 新建布局)成立;
|
|
|
|
|
|
③ EMOJI_SET 18 项图标集(🧱🏠🎓🚗✈️🌍🏥📚✏️⚙️🎨🎮🌏📐🧪🤖📦💬);
|
|
|
|
|
|
布局卡/管理行/快捷方式的图标都变可点(stopPropagation,不触发卡片本身),
|
|
|
|
|
|
弹固定定位图标选择器(6 列网格、当前项高亮);选中持久化到 projects.v1(LayoutSpec 加 icon 字段;
|
|
|
|
|
|
快捷方式复用 icon 字段);rail 图标同步使用所选 emoji;locale 加 icons.title/icons.change。
|
|
|
|
|
|
- 验证(04_test/functional-diag.cjs 扩展:--window-size=1440,900 + dsf=1 + 新 Chrome profile +
|
|
|
|
|
|
Page.addScriptToEvaluateOnNewDocument 种子测试布局 + 点击展开侧栏):
|
|
|
|
|
|
STEP6 图标链路:icon0=🧱 → 点图标 popup=true(18 cells) → 点🏠 → icon1=🏠 且 projects.v1
|
|
|
|
|
|
saved=🏠;ta/pr 边框色 rgba(255,255,255,.06)(非 transparent)+ desc display:none;
|
|
|
|
|
|
STEP7 互斥:本引擎打开时合成挂 .ta_split → engineClosedByFakeTa=true(观察器关闭引擎)。
|
|
|
|
|
|
(travelatlas 在无会话 headless 页面不自开分栏,taSplitPresent=false 属预期,改合成验证。)
|
|
|
|
|
|
STEP1-5 回归不变(paneWs 均分、picker 自适应、拖标签);ERRORS_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效,无需重启 dsh web。
|
2026-08-17 21:34:42 +08:00
|
|
|
|
## 补记(常驻项目图标可换 + 新建布局卡单行化 + 头部按钮对齐官方图标)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈(三条):
|
|
|
|
|
|
① 常驻项目(建筑审图/旅行 Atlas)也纳入图标可换范围(🌏📐 已含在 18 项图标集里);
|
|
|
|
|
|
② 新建布局卡片要与常驻项目展示完全一致:标题单行,去掉第二行描述与右侧「布局」小字;
|
|
|
|
|
|
③ 工作台右上角 3 按钮(搜索/视图选项/添加)完全照抄官方工作区头部 icon。
|
|
|
|
|
|
- 处理:
|
|
|
|
|
|
① 常驻项目图标(DOM 层,不改动 travelatlas/planreview 代码):projects.v1 新增
|
|
|
|
|
|
iconOverrides 字段并传给卡片 ownerProps;effect 把 override 写到卡片 icon 元素的
|
|
|
|
|
|
data-wt-icon 属性,CSS 用 attr() 换显示(原字符字号压 0);文档捕获阶段委托点击
|
|
|
|
|
|
.ta_cardIcon/.pr_cardIcon → 打开图标选择器(kind: project,stopPropagation 阻止卡片
|
|
|
|
|
|
自身打开);管理行插件图标、rail 图标同步可换。图标选择器支持三类:layout/shortcut/project。
|
|
|
|
|
|
② 布局卡单行化:去掉 .dsh-wt_layoutDesc 与 .dsh-wt_layoutBadge 渲染及样式、
|
|
|
|
|
|
locale 的 layout.desc/layout.badge 键;卡片 = 图标 + 名称 + ›,与 ta_card/pr_card 一致。
|
|
|
|
|
|
③ 头部按钮换官方 SVG:用 CDP 探针从运行中的 DSH Web GUI 工作区面板取样三枚图标
|
|
|
|
|
|
(Search sessions 放大镜 / View options 滑块 / Add workspace 文档加号,fill=currentColor),
|
|
|
|
|
|
内联为 ICON_SEARCH/ICON_VIEW_OPTIONS/ICON_ADD 常量替换原 🔍/☰/+ 文本。
|
|
|
|
|
|
- 验证(functional-diag STEP6 扩展):layoutDesc=0、layoutBadge=0、headerSvgs=3;
|
|
|
|
|
|
ta_cardIcon 点击 → popup → 选 ✈️ → taIconAttr=✈️ + projects.v1.iconOverrides.travelatlas=✈️;
|
|
|
|
|
|
既有图标链路(🧱→🏠)+ ta/pr 统一框 + 小字隐藏 + STEP7 互斥全部保持;ERRORS_COUNT: 0。
|
|
|
|
|
|
bundle-eval 补 jsxs 桩后 PASS(模块级 JSX 常量引入)。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效,无需重启 dsh web。
|
2026-08-17 21:39:08 +08:00
|
|
|
|
## 补记(头部间距与抓手微调)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:头部 3 按钮间距比官方小,左侧拖动抓手偏小。
|
|
|
|
|
|
- 处理:.dsh-wt_actions gap 2px → 7px;.dsh-wt_handle 22×22/13px → 25×25/15px。
|
|
|
|
|
|
- 验证:functional-diag 全 STEP 回归 PASS,ERRORS_COUNT: 0(纯 CSS 改动,F5 生效)。
|
2026-08-17 21:41:25 +08:00
|
|
|
|
## 补记(视图选项改右侧弹窗)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:视图选项(排序/管理菜单)不要下方内联展开,要和 + 新建一样从右侧弹出。
|
|
|
|
|
|
- 处理:viewOptionsOpen 复用 popLeft/popTop(锚定侧栏右缘 + 区块顶部),
|
|
|
|
|
|
dsh-wt_menu dsh-wt_pop fixed 定位 width 200 + 透明遮罩点击关闭;与 + 弹窗互斥不变。
|
|
|
|
|
|
- 验证:functional-diag STEP8 menuPos=fixed、menuLeft=288(侧栏右缘+8)、
|
|
|
|
|
|
遮罩点击关闭 PASS;全 STEP 回归 ERROR_COUNT: 0。纯客户端改动,F5 生效。
|
2026-08-17 21:50:55 +08:00
|
|
|
|
## 补记(管理项目改右侧弹窗展开)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:点「管理项目…」后,管理面板应从新弹出的界面(同锚点)往下展开,
|
|
|
|
|
|
而不是从工作台原位内联展开。
|
|
|
|
|
|
- 处理:managing 时 dsh-wt_manage 加 dsh-wt_pop + fixed 定位(popLeft/popTop 与视图选项
|
|
|
|
|
|
弹窗同一锚点,宽 316),加透明遮罩点击关闭;完成按钮关闭不变;
|
|
|
|
|
|
项目卡区 data-managing 弱化保持。
|
|
|
|
|
|
- 验证:functional-diag STEP9 managePos=fixed、manageLeft=288(同弹窗锚点)、rows=3、
|
|
|
|
|
|
遮罩关闭 PASS;全 STEP 回归 ERROR_COUNT: 0。纯客户端改动,F5 生效。
|
2026-08-17 21:59:18 +08:00
|
|
|
|
## 补记(删除二次确认 + 常驻项目可删 + 字号/字重统一)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈(四条):① 常驻两项目也要删除 ✕;② 删除(常驻/新建/快捷方式)都要二次确认警告弹窗;
|
|
|
|
|
|
③ 常驻项目 emoji 字号与新建项目不一致;④ 所有项目名改为不加粗。
|
|
|
|
|
|
- 处理:
|
|
|
|
|
|
① projects.v1 新增 removed 列表:删除常驻项目 = 移出工作台(插件不卸载),
|
|
|
|
|
|
卡片/管理行/rail 全部隐藏(ownerProps.hidden 并入 removed);「恢复默认」清空 removed/iconOverrides 找回;
|
|
|
|
|
|
管理面板全部行(常驻/布局/快捷方式)都有 ✕。
|
|
|
|
|
|
② 删除统一走 askDelete → fixed 居中警告弹窗(⚠️ 标题 + 按类型文案 + 取消/红色删除),
|
|
|
|
|
|
遮罩 81/弹窗 82 压在管理弹窗之上;取消不动、确认执行(布局删条目/常驻进 removed)。
|
|
|
|
|
|
③ 常驻卡片 emoji 统一 13px(含 data-wt-icon ::before 15px→13px);
|
|
|
|
|
|
④ ta/pr 卡片名 font-weight 400,.dsh-wt_layoutName 600→400。
|
|
|
|
|
|
- 验证(functional-diag STEP10):prIconSize=13px、taIconBeforeSize=13px、taNameWeight/laNameWeight=400;
|
|
|
|
|
|
管理行 ✕ → confirmShown=true → 取消(卡片仍在)→ 再 ✕ 删除 → cardsAfter pr:0 + removed=['planreview'];
|
|
|
|
|
|
布局 ✕ 确认后 layoutsLeft=0;rowsAfterDelete=2;全 STEP 回归 ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效,无需重启 dsh web。
|
2026-08-17 22:03:38 +08:00
|
|
|
|
## 补记(图标统一放大 15px + 四类卡片竖向高度统一)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:① 项目 emoji 放大到 15;② 现有四个项目卡片框的竖向高度不一致,统一;
|
|
|
|
|
|
③ 后续新建的项目也要继承统一高度。
|
|
|
|
|
|
- 处理:
|
|
|
|
|
|
① 全部项目图标 15px:布局卡/快捷方式/常驻卡(含 data-wt-icon ::before 覆盖)/管理行(20px 盒);
|
|
|
|
|
|
顺带修掉 .dsh-wt_iconPick 的 font:inherit 简写(会把字号重置回父级 12px,覆盖 15px 设置)。
|
|
|
|
|
|
② 四类卡片统一 height:34px + box-sizing:border-box:.ta_card/.pr_card/.dsh-wt_layout/.dsh-wt_shortcut;
|
|
|
|
|
|
按类名生效,新建条目自动继承。
|
|
|
|
|
|
- 验证(functional-diag STEP10 扩展 + 种子加 1 条快捷方式):heights ta/pr/layout/shortcut 全 34px;
|
|
|
|
|
|
四类图标 computed 全 15px;删除确认等既有断言不变;ERRORS_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效,无需重启 dsh web。
|
2026-08-17 22:07:29 +08:00
|
|
|
|
## 补记(窗间竖向分隔线居中修正)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:窗口之间的竖向可拖动分隔线偏右,不在两个窗口缝隙的正中。
|
|
|
|
|
|
- 根因:窗格 border-box、allocate 留 6px 缝;分隔线定位写成了「窗右缘 + DIVIDER/2」
|
|
|
|
|
|
(左 = 缝右半起点),6px 线右半压进下一个窗口 → 视觉偏右 3px。
|
|
|
|
|
|
- 处理:主行与顶部行内垂直分隔线 left 去掉 + DIVIDER/2,直接对齐窗右缘([缝左, 缝左+6]),
|
|
|
|
|
|
中心 = 缝中心。聊天/左列/上下水平分隔线本就骑缝居中,不动。
|
|
|
|
|
|
- 验证(functional-diag STEP2 dividerAlign):paneRight=514、divLeft=514、divWidth=6、
|
|
|
|
|
|
centerOffset=0(修复前 +3);全 STEP 回归 ERROR_COUNT: 0。纯客户端改动,F5 生效。
|
2026-08-17 22:14:01 +08:00
|
|
|
|
## 里程碑 checkpoint(开始自定义开发前)
|
|
|
|
|
|
|
|
|
|
|
|
- 时间:2026-08-17。工作树干净,全部历史已推送。
|
|
|
|
|
|
- 打点:git tag checkpoint-2026-08-17-pre-fileviewer(已推远端,b22cd6b)。
|
|
|
|
|
|
- 状态:工作台 UI/交互(卡片统一、图标、弹窗、删除确认、互斥、预设均衡、picker 自适应、
|
|
|
|
|
|
分隔线居中)全部完成并验证;下一个大块 = 文件预览(MD/TXT/PDF 等自定义开发)。
|
2026-08-17 22:21:13 +08:00
|
|
|
|
## 补记(文件预览 MD/TXT/PDF/图片 + 预设三改左二右一)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户确认默认方案开工 + 第 3 个预设(左一右二)改为「左边两个 + 右边一个对话」。
|
|
|
|
|
|
- 文件预览实现:
|
|
|
|
|
|
① SplitContent 新增 kind:'file'(path);tabTitleOf 取 basename;openTab 去重
|
|
|
|
|
|
(同内容已有标签 → 直接激活,sameContent 判定);
|
|
|
|
|
|
② FileViewer:pdf → iframe 原生渲染(服务端 MIME application/pdf);图片 → 居中 img;
|
|
|
|
|
|
md/markdown → markdown-it(打进 client.js,linkify 开、内嵌 HTML 关闭,链接点击新标签外开);
|
|
|
|
|
|
其余 → 等宽 <pre> 纯文本;fetch 失败/加载中文案(file.fail/file.loading);
|
|
|
|
|
|
③ 资源管理器点击 .md/.markdown/.mdown/.txt/.log/.pdf/图片 开预览标签(.html 行为不变,
|
|
|
|
|
|
其他类型提示不支持);服务端 file 路由 MIME 补 pdf/markdown/log/bmp/ico;
|
|
|
|
|
|
④ 全套暗色 MD 排版样式(标题/代码块/引用/表格/列表/分割线)。
|
|
|
|
|
|
- 预设 l2 改造:PRESET_DEFS l2 → {top:1, content:1, chatFull:true}(左列上下两内容窗 + 右列通高聊天),
|
|
|
|
|
|
缩略图改为左 2 右 1;PRD §13 预设说明同步更新。
|
|
|
|
|
|
- 验证(functional-diag STEP11):openTab kind:file PRD.md → 标签名 PRD.md、.dsh-wt_md 渲染出
|
|
|
|
|
|
PRD 开头文本;同路径再开 tabsAfterDup=1(去重);package.json → .dsh-wt_txt 展示;
|
|
|
|
|
|
全 STEP 回归 ERROR_COUNT: 0。bundle-eval 补 atob/btoa 桩后 PASS(markdown-it 引入)。
|
|
|
|
|
|
- 备注:客户端改动 F5 生效;服务端 pdf MIME 需手动重启 dsh web 一次后 PDF 预览才生效。
|
2026-08-17 22:50:14 +08:00
|
|
|
|
## 补记(PDF 自绘阅读器:抓手/空格拖拽/H 切换/缩放)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户需求:PDF 阅读器加抓手工具——顶部 ✋ 按钮;按住空格期间鼠标变抓手、左键拖动平移、
|
|
|
|
|
|
松开空格取消;快捷键 H 一键切换抓手;抓手态下拖动即可移动页面。
|
|
|
|
|
|
- 关键决策:原生 Chrome PDF 视图(iframe)内部无法拦截鼠标 → 改用 pdf.js 自绘渲染
|
|
|
|
|
|
(画布多页纵向 + 视口按需渲染 + DPR≤2)。
|
|
|
|
|
|
- 实现:
|
|
|
|
|
|
① PdfViewer 组件:工具栏 [✋抓手][−][百分比][+][⤢适应宽度];缩放 0.2~5;
|
|
|
|
|
|
抓手三入口——空格按住(输入框不劫持、松开取消)/ H 常开切换 / 顶部按钮;
|
|
|
|
|
|
抓手态 cursor grab/grabbing,pointer 捕获拖拽改 scrollLeft/Top;
|
|
|
|
|
|
② worker 零服务端依赖:build.mjs 改 esbuild JS API,把 pdf.worker.min.mjs 源码以
|
|
|
|
|
|
__WT_PDF_WORKER__ 字符串注入 client banner(bundle 2.6MB),运行时 Blob URL 起 module worker;
|
|
|
|
|
|
失败自动回退原生 iframe(服务端 MIME 已补 application/pdf 备用);
|
|
|
|
|
|
③ 服务端 file 路由 MIME 补 pdf/markdown/log/bmp/ico。
|
|
|
|
|
|
- 验证(functional-diag STEP12 + 04_test/fixture.pdf 夹具):canvasW=439 自绘渲染;
|
|
|
|
|
|
空格按住 panClass=true/松开 false;H 开/关正确;放大至 281% 溢出后合成指针拖拽
|
|
|
|
|
|
scrollTopAfterDrag=140(平移生效);全 STEP 回归 ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:全部客户端改动,F5 即生效,无需重启 dsh web。
|
2026-08-17 23:00:55 +08:00
|
|
|
|
## 补记(PDF 回退原生阅读器 + 设置面板合并 + 变更视图)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:① 自绘 PDF 阅读器不要了,回退之前的原生 Chrome PDF 浏览器(其无法加抓手:
|
|
|
|
|
|
原生视图内部是浏览器扩展页,插件注入不了按钮、拦不到鼠标,也驱动不了内部滚动——
|
|
|
|
|
|
向用户如实说明后按指示回退);② 视图选项改名「设置」,点开直接内嵌「排序方式 + 管理项目
|
|
|
|
|
|
展开列表」,不再二次点击;③ 管理项目里给现有项目加「变更视图」:换预设拓扑,
|
2026-08-18 12:41:53 +08:00
|
|
|
|
## 补记(文件夹分组标题视觉区分加强)
|
2026-08-17 23:15:13 +08:00
|
|
|
|
|
2026-08-18 12:41:53 +08:00
|
|
|
|
- 用户反馈:文件夹名与下方对话区分度不够。
|
|
|
|
|
|
- 处理:分组标题与选项同字号(12px)、加粗(600)、左侧 2px 蓝色竖条 + 微底色背景块,
|
|
|
|
|
|
文字用次级灰(不用全蓝,避免怪感);行间距拉开(选项 padding 6px、分隔线 margin 6px)。
|
|
|
|
|
|
- 验证(STEP20 断言):groupFontSize=12px、groupWeight=600、groupBorderLeft=2px;
|
|
|
|
|
|
全 20 STEP ERROR_COUNT: 0。
|
2026-08-18 12:37:40 +08:00
|
|
|
|
- 备注:纯客户端改动,F5 即生效。
|
2026-08-18 22:26:44 +08:00
|
|
|
|
|
|
|
|
|
|
## 补记(自定义窗口发送后右侧对话窗自动切换 — 实测验证)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户要求:自定义窗口「新建会话」或「发送到会话」点发送后,右侧对话窗自动切到选定会话。
|
|
|
|
|
|
- 结论:功能代码此前已实现——createCustomSession / sendCustomToSession 成功后均调用
|
|
|
|
|
|
b.sessions.open(sessionId)(宿主 manager.select)。本次为实测验证 + 加诊断钩子。
|
|
|
|
|
|
- 调试钩子:apply 里新增 window.__dshOpenSession(id) / window.__dshSessions(try/catch 包住,
|
|
|
|
|
|
与既有 __dshWorktable 调试导出一致),供无头探针复用。
|
|
|
|
|
|
- 新增 04_test/chatswitch-probe.cjs:无头 Chrome 读 ctx.sessions.list.getSnapshot() 快照 →
|
|
|
|
|
|
切到另一会话 → 校验 current 变更 + 右侧出现目标标题 → 切回原会话(非破坏性)。
|
|
|
|
|
|
- 验证结果:idsCount=16,switched=true,domTitleRight=true(主区 x=300 标题精确匹配),
|
|
|
|
|
|
restoredOk=true;functional-diag 全 20 STEP ERROR_COUNT: 0。
|
|
|
|
|
|
- 教训:构建必须在 01_content 目录下执行(node build.mjs);误在仓库根目录跑会把 lib 写到
|
|
|
|
|
|
仓库根的 lib/,宿主仍加载 01_content/lib 旧 bundle,出现「改完不生效」假象(已删误产物)。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效,无需重启 dsh web。
|
|
|
|
|
|
|
2026-08-18 23:10:50 +08:00
|
|
|
|
## 补记(修复「发送到会话」失败:conversation.send requires a session scope)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户实测报错:创建对话失败:Error: conversation.send requires a session scope — address one via
|
|
|
|
|
|
ctx.sessions.scope(id).conversation。
|
|
|
|
|
|
- 根因:① conversation.sendSession(session, text, images, mode) 第一参数是「会话面」对象而非 id
|
|
|
|
|
|
字符串,旧代码传 id → 静默失败;② 回退的 conversation.send 按插件自身 ctx 解析作用域,
|
|
|
|
|
|
而 dsh-worktable 是根级插件,无会话标签 → 宿主报 requires a session scope。
|
|
|
|
|
|
- 探针实测(读宿主 dsh-client-runtime / dsh-client-ui-conversation 源码 + 页面验证):
|
|
|
|
|
|
scope(id).conversation 属性访问被 inject 代理拦截;scope(id).get('conversation') 可用;
|
|
|
|
|
|
sessions.binding(id).session.prompt([{type:'text',text}], 'queue') 是宿主 sendSession 同款路径。
|
|
|
|
|
|
- 修复:新增 promptIntoSession(sessionId, text)——binding 解析重试 2s → 宿主
|
|
|
|
|
|
conversation.sendSession(会话面, text, [], 'queue') → 直连 session.prompt → scope(id).get
|
|
|
|
|
|
('conversation').send 三级降级;createCustomSession / sendCustomToSession 统一走该函数,
|
|
|
|
|
|
open(会话) 后发送(右侧对话窗仍自动切换)。
|
|
|
|
|
|
- 验证:send-self-test.cjs 端到端自测(新建一次性会话 session-91a6adea,promptOk=true、
|
|
|
|
|
|
listEntry running=true 轮次启动);functional-diag 全 20 STEP ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效;自测留下的一次性会话请用户手动删除。
|
|
|
|
|
|
|
2026-08-18 23:27:16 +08:00
|
|
|
|
## 补记(新建对话加分组选项:加入现有组 / 新建一个组)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:新建对话只能落在未分组,无法加进已有项目组(如 Projects),也没法顺手建新组。
|
|
|
|
|
|
- 宿主能力勘察:sessions.create({workspaceId}) 指定分组建会话;ctx.workspaces 服务提供
|
|
|
|
|
|
list/create({path})/rename/delete/archiveSession 等;本机目录选择器为 native 模式,
|
|
|
|
|
|
createDirectory 需 browse 能力不可用 → 建组目录改走插件服务端 mkdir 路由。
|
|
|
|
|
|
- 实现:① 插件 inject 增 'workspaces',桥接 ctx.workspaces;② 新建模式加「分组」三态选择
|
|
|
|
|
|
(未分组 / 现有组列表 / +新建分组),新建组显示父目录+名称两个输入框;③ 默认分组 =
|
|
|
|
|
|
当前会话所在工作区(体验:新会话直接落在你正在用的组里);④ 服务端新增
|
|
|
|
|
|
POST /api/worktable/mkdir(父目录必须已存在,防误建深层目录),客户端 create 前调用兜底;
|
|
|
|
|
|
⑤ createCustomSession 按分组解析 workspaceId 后 sessions.create({workspaceId})。
|
|
|
|
|
|
- 验证:STEP20 扩展断言全过——newSelectCount=2、groupDefaultValue=Projects▾(自动选中当前组)、
|
|
|
|
|
|
groupItemCount=4、groupHasNone/groupHasNew=true、newGroupInputs=2、sendDisabledNewGroup=true、
|
|
|
|
|
|
groupInputsAfterNone=0;ERRORS_COUNT: 0。
|
|
|
|
|
|
- 待办:mkdir 为服务端路由,需用户重启 dsh web 后跑 group-cycle-test.cjs 全周期自测
|
|
|
|
|
|
(建目录→注册分组→按组建会话→验证→归档会话+删分组+清目录,无残留)。
|
|
|
|
|
|
- 备注:加入现有组纯客户端(重启前即可用);新建组依赖 mkdir 路由(重启后可用)。
|
|
|
|
|
|
|
2026-08-19 00:06:03 +08:00
|
|
|
|
## 补记(布局预设重排 + 新增 5 视窗预设)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户要求:① 删「上一下二」(第二行第一个,与左品右聊重叠);② 其后两个预设左移一位、
|
|
|
|
|
|
末尾空出;③ 末尾新增 5 视窗预设——左侧上下结构:上 1 通栏大窗 + 下 3 小窗并排,右侧对话整列;
|
|
|
|
|
|
④ 已确认「原来的第4个」= 上一下二本身(只删一个)。
|
|
|
|
|
|
- 实现:PRESET_DEFS 新序 [2h, 3h, l2, grid, t3, l13];l13 = topCount 1 + contentCount 3 +
|
|
|
|
|
|
chatFull true + topHeightDefault 420(上大下小在宽高上都明显,可拖动微调);缩略图新增 l13
|
|
|
|
|
|
分支(左列 1+3、右列对话,共 5 格),删除 t2 分支与定义;buildLayout 支持按预设定制
|
|
|
|
|
|
topHeight 默认值。
|
|
|
|
|
|
- 验证(preset-l13-probe.cjs):presetCount=6、thumbCells=[2,3,3,4,4,5](t2 已去、l13 末尾
|
|
|
|
|
|
5 格);保存布局 savedTop=1/savedMain=3/chatFull=true/topDefault=420;打开后 paneCount=4
|
|
|
|
|
|
(4 内容窗 + 对话 = 5 视窗)、topW=797 通栏 vs botW=262×3 三小窗、topOnTop=true;
|
|
|
|
|
|
functional-diag 全 20 STEP ERROR_COUNT: 0(STEP9 点第 3 个仍为 l2,断言不变)。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效;存量已保存布局不受影响(存的是完整 spec,非预设 id)。
|
|
|
|
|
|
|
2026-08-19 00:19:14 +08:00
|
|
|
|
## 补记(用户重启后补跑分组全周期自测 — 通过)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户重启 dsh web(mkdir 路由生效)后补跑 group-cycle-test.cjs(已改为走服务端 mkdir 路由,
|
|
|
|
|
|
与客户端同款路径):
|
|
|
|
|
|
mkdirOk=true → 注册工作区 workspaceTitle=wt-grouptest-* → sessions.create({workspaceId}) →
|
|
|
|
|
|
wsInList=true / sessionInWs=true(会话正确落进新分组)/ sessionCwd=新目录 →
|
|
|
|
|
|
清理 archived=true / wsDeleted=true / wsGone=true,测试空目录已 rm。
|
|
|
|
|
|
- 重启后 functional-diag 全 20 STEP 复跑 ERROR_COUNT: 0(site/write/workspaces 路由全部就绪)。
|
|
|
|
|
|
- 备注:之前 send-self-test 遗留的一次性会话 session-91a6adea 用户未删,STEP20 itemCount 13→14
|
|
|
|
|
|
即该测试会话;再次提醒用户删除即可,不影响功能。
|
2026-08-19 01:55:36 +08:00
|
|
|
|
## 补记(动画窗类型 + 绑定按钮改版 + 自动绑定规则 + 会话硬删除)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户要求:① 删掉归档的一次性会话 session-91a6adea;② 新增「动画」窗类型(iframe 壳 + 地址栏,
|
|
|
|
|
|
独立 🎬 图标,站内自带控件);③ 绑定按钮重画:竖向对齐 + ○○(未绑定)/●●(已绑定)双圆单色图标;
|
|
|
|
|
|
④ 绑定弹窗改版:未绑定显示「未绑定对话」,已绑定显示「📂文件夹 | [对话名框]」,去掉照抄项目名的
|
|
|
|
|
|
第二行;⑤ 自动绑定规则:子窗口新建/发送到会话且当前项目未绑定 → 自动绑定该会话;已绑定 → 永不
|
|
|
|
|
|
自动改绑;⑥ 资深 PM 式 hover 提示。
|
|
|
|
|
|
- 实现:① 会话目录 + workspace.json 引用删除(备份后清理,宿主已采纳);② BuiltinType 增 'anim'、
|
|
|
|
|
|
BUILTIN_ICONS 🎬、AnimPane(浏览器窗同款壳、默认 about:blank)、选择器第 2 位;③ 绑定按钮改为
|
|
|
|
|
|
绝对定位 right:26px/top:50% 统一对齐(布局卡与入驻卡一致),图标由 CSS 双圆绘制(::before/::after,
|
|
|
|
|
|
data-bound 切换空心/实心、单色 currentColor);④ 弹窗状态行(bindInfoOf 查文件夹+标题,对话名带框)
|
|
|
|
|
|
+ 提示文案「一个项目只能绑定一个对话…」;⑤ custom env 增 autoBind('auto'/'kept'/'none'),
|
|
|
|
|
|
createCustomSession 返回会话 id,CustomPane 完成页显示自动绑定/未改绑提示。
|
|
|
|
|
|
- 验证(probe-batch5/autobind-mini):pickCount=5、tabType=anim、地址栏+iframe ✓;3 个绑定按钮
|
|
|
|
|
|
全部 absolute/delta=0 对齐、8px 空心圆 ✓;弹窗未绑定态「未绑定对话」无对话框 ✓,绑定后
|
|
|
|
|
|
📂未分组 | [dsh-usage] 带框 ✓;autoBind 未绑定→'auto'+写入、再调→'kept'+不变 ✓;functional-diag
|
|
|
|
|
|
全 20 STEP ERROR_COUNT: 0。
|
|
|
|
|
|
- 事故与修复:删除会话时用 PowerShell Set-Content 重写 workspace.json 带上了 UTF-8 BOM,宿主路由
|
|
|
|
|
|
JSON.parse 抛错 → /api/worktable/workspaces 404、会话分组退化为平铺(STEP20 groupHeaders 0)。
|
|
|
|
|
|
已去 BOM 修复,并在服务端路由加 BOM 容忍(下次重启生效)。
|
|
|
|
|
|
- 备注:动画窗/绑定按钮纯客户端,F5 即生效;服务端 BOM 容忍改动需下次重启 dsh web 后生效。
|
|
|
|
|
|
|
2026-08-19 02:07:46 +08:00
|
|
|
|
## 补记(绑定图标微调:更小 + 黑白单色 + hover 气泡)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:图标太大;颜色要黑白克制(不要蓝色强调);hover 要有自身按钮区域效果 +
|
|
|
|
|
|
直接显示「已绑定对话:xxx」,不必点击。
|
|
|
|
|
|
- 实现:按钮 18×14 → 16×12、圆 8px → 6px;未绑定 = 次级灰空心圆(rgb 207,211,214),
|
|
|
|
|
|
已绑定 = 主色实心圆(rgb 249,250,251),移除 accent 蓝;hover 自身 4px 圆角底色
|
|
|
|
|
|
+ ::after 气泡(content:attr(data-tip),显示「未绑定对话:点击选择要跟随的对话」/
|
|
|
|
|
|
「已绑定对话:{name}」,name 由 boundSessionTitle 同步读会话快照取 displayTitle)。
|
|
|
|
|
|
- 验证(bindicon-mini.cjs):16×12 / 6px 圆 ✓;绑定态 color=主色非 accent、实心 ✓;
|
|
|
|
|
|
data-tip 解析「已绑定对话:Projects」✓;functional-diag ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效。
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-08-19 01:14:13 +08:00
|
|
|
|
## 补记(第 7/8 布局 + +自定义磁贴 + 窗口改名 + 对话绑定)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户要求:① 新增第 7 个预设「田字格」——右聊天通高整列、左侧 2×2 四窗默认等大,横向贯通、
|
|
|
|
|
|
竖向两段分隔条独立可拖;② 第 8 个预设「上2下3」——左列上排 2 窗 + 下排 3 窗宽度均分,右聊天;
|
|
|
|
|
|
③ 第 9 格为「+」磁贴(永远最后):点开右侧弹窗,上半描述布局、下半按钮把「用户需求 + 上下文
|
|
|
|
|
|
提示词」复制进剪贴板并弹 Toast,提示词含引擎规则与现有预设清单,可发给任意 dsh 实现;
|
|
|
|
|
|
④ 窗格改名「内容N」→「窗口N」,并把窗口编号映射写进 AGENTS.md/PRD(左栏→顶行→主行);
|
|
|
|
|
|
⑤ 对话绑定:每张项目卡中间偏右加 🔗 按钮 → 会话分组列表弹窗(与发送到会话同源)→ 绑定后
|
|
|
|
|
|
打开项目自动 sessions.open 切换右侧对话;解绑/未绑定不切换。
|
|
|
|
|
|
- 引擎修正:① topHeightRatio 字段(首次打开顶行占比,(rowH-BAR)*ratio;0.5=等分,缺省 0.35);
|
|
|
|
|
|
② chatFull 布局顶行默认宽扣除聊天列(此前 2 窗顶行一宽一窄)。
|
|
|
|
|
|
- 剪贴板降级:navigator.clipboard 失败时改用临时隐藏 textarea 全选提示词后 execCommand('copy')
|
|
|
|
|
|
(此前误选输入框原文)。
|
|
|
|
|
|
- 验证(probe-batch4.cjs):tileCount=9、thumbCells=[2,3,3,4,4,5,5,6,0]、plusTileLast=true;
|
|
|
|
|
|
g4 保存 top2/main2/ratio0.5/窗口1-4;打开后四窗 rect 388×388 等大(宽度差 ≤ 分隔条宽)、
|
|
|
|
|
|
g4TopAbove=true;l23 top2/main3;+磁贴弹窗 promptLen=1059 含需求+PRESET_DEFS+g4+topHeightRatio
|
|
|
|
|
|
+现有清单且需求落在「用户需求」段后;绑定全流程 boundSaved/boundIsSession/switchedToBound/
|
|
|
|
|
|
unbindShown/bindingsAfterUnbind=null/restored 全过,入驻卡注入 2 个 🔗;functional-diag
|
|
|
|
|
|
全 20 STEP ERROR_COUNT: 0(STEP9 presetCount 9)。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效;动画生成窗(iframe 壳)按用户指示未实现,仅给方案。
|
|
|
|
|
|
|
2026-08-19 02:21:09 +08:00
|
|
|
|
## 补记(绑定气泡最终方案:body 级气泡向右伸出)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:向左弹出盖住项目名;要向右伸(参照「添加项目」原生 title 气泡——溢出侧栏也显示正常)。
|
|
|
|
|
|
- 根因(两处):① 此前 CSS ::after 气泡画在侧栏层叠上下文内,向右必被右侧对话浮层压住;
|
|
|
|
|
|
② 首次尝试的 body 级气泡函数被误插进 WorktableSection 组件内部,apply 的 effect 引用
|
|
|
|
|
|
模块级同名函数 → 运行时 ReferenceError,hover 无任何反应(esbuild 改名 showBindTip2 暴露)。
|
|
|
|
|
|
- 方案:事件委托(mouseover/mouseout/scroll/click,捕获阶段)→ body 级 .dsh-wt_bindTip 独立元素,
|
|
|
|
|
|
z-index 1200(> 分栏浮层 68),定位在按钮右侧 8px、垂直居中,右侧放不下才翻左。
|
|
|
|
|
|
- 验证(bindtip-portal.cjs):tipShown ✓、tipText=已绑定对话:Projects、parent=body、z=1200>
|
|
|
|
|
|
overlay 68、tipLeft 249 > btnRight 241(向右伸出)✓、mouseout 隐藏 ✓;functional-diag
|
|
|
|
|
|
ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效。
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-08-19 02:11:58 +08:00
|
|
|
|
## 补记(绑定按钮 hover 修复:气泡改向左伸出 + hover 区加大)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:已绑定对话的 hover 气泡被右侧对话窗挡住(怀疑堆叠顺序);hover 底色框太小,
|
|
|
|
|
|
要圆角矩形、大小与原 🔗 按钮相当。
|
|
|
|
|
|
- 处理:气泡定位从「按钮上方居中」改为「按钮左侧、垂直居中」(right: calc(100%+8px))——
|
|
|
|
|
|
整个气泡留在侧栏内,不再跨到右侧对话区,堆叠顺序不再是问题;hover 区域 16×12 → 22×22、
|
|
|
|
|
|
border-radius 6px(与原 🔗 按钮同尺寸),6px 双圆图标居中不变、单色不变。
|
|
|
|
|
|
- 验证(bindicon-mini.cjs):按钮 22×22 / radius 6px;气泡 right=30px、left=-204px(向左伸出
|
|
|
|
|
|
侧栏内)✓;未绑定/已绑定颜色与实心空心不变;functional-diag ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效。
|
|
|
|
|
|
|
2026-08-19 20:56:35 +08:00
|
|
|
|
## 补记(绑定图标两点间距加大)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:○○/●● 两个点挨得太近,分开一点(实心空心一起改)。
|
|
|
|
|
|
- 处理:圆点定位 left 0 / 7px → 0 / 11px,圆 6px 不变 → 间距 1px → 5px;容器 14px → 17px
|
|
|
|
|
|
(22×22 按钮底内居中不变)。
|
|
|
|
|
|
- 验证(bindicon-mini.cjs):circleLeft=0px / circle2Left=11px / gap=5,空心与实心两态一致;
|
|
|
|
|
|
functional-diag ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效。
|
|
|
|
|
|
|
2026-08-19 21:00:22 +08:00
|
|
|
|
## 补记(圆点间距 4px + 布局卡箭头垂直对齐)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:① ○○/●● 间距再收一点(5px → 4px);② 布局卡右侧 › 箭头纵坐标偏下,
|
|
|
|
|
|
要对齐项目标签栏中心。
|
|
|
|
|
|
- 处理:圆点 second circle left 11px → 10px;箭头由 line-height 20px 裸文本改为
|
|
|
|
|
|
inline-flex + align-items:center + height/line-height 18px(与项目名同高),
|
|
|
|
|
|
去掉字形下沉带来的下偏(先试 translateY(-1px) 过矫 1.5px 偏高,去掉后误差 -0.5px)。
|
|
|
|
|
|
- 验证(arrow-mini.cjs):gap=4 ✓;箭头字面中心 531.5 vs 卡片/项目名中心 532(偏差 -0.5px,
|
|
|
|
|
|
亚像素级);functional-diag ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效。
|
|
|
|
|
|
|
2026-08-19 21:03:01 +08:00
|
|
|
|
## 补记(箭头视觉居中再调:整体上移 1px)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:› 箭头还是有点靠下、不在正中间。
|
|
|
|
|
|
- 处理:字形墨迹在字面框内偏下——字面框几何居中仍显下偏;改为 inline-flex 居中基础上
|
|
|
|
|
|
整体 translateY(-1px)(实测字面框中心高于项目名中心 1.5px,视觉墨迹落正)。
|
|
|
|
|
|
- 验证:functional-diag ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效。
|
|
|
|
|
|
|
2026-08-19 21:07:20 +08:00
|
|
|
|
## 补记(箭头对齐正主:入驻项目卡自带箭头)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:箭头两次改动「没动」——原因:用户看的是入驻项目卡(旅行 Atlas / 建筑审图)
|
|
|
|
|
|
自己的 › 箭头(.ta_cardArrow / .pr_cardArrow),此前两轮改的是布局卡 .dsh-wt_layoutArrow。
|
|
|
|
|
|
- 处理:桥注入时给入驻卡文本为 › 的 span 子元素加 .dsh-wt_resArrow 类(通用,不限具体卡片),
|
|
|
|
|
|
CSS:button[data-wt-id] > .dsh-wt_resArrow = 18px 行高 + inline-flex 居中 + translateY(-1px)
|
|
|
|
|
|
(字面框偏下补偿,与布局卡同款)。
|
|
|
|
|
|
- 验证(carddom-mini.cjs):ta/pr 箭头均注入 dsh-wt_resArrow、h=20→18px、字面中心高于
|
|
|
|
|
|
卡片中心 1.5px(墨迹视觉居中);functional-diag ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效;代理已恢复,积压提交已全部推送。
|
|
|
|
|
|
|
2026-08-19 21:29:44 +08:00
|
|
|
|
## 补记(项目文件夹强制绑定 + 项目×对话联动 + 窗口提示词升级)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户要求三项:① 所有项目绑定工作文件夹——新建时强制填写(父目录+名称,保存建目录),
|
|
|
|
|
|
绑定面板里「绑定对话」上方可改;项目产出文件尽可能都进该文件夹;② 项目×对话联动——项目
|
|
|
|
|
|
打开期间切到其他对话 = 自动关项目(保留新对话);✕/反选关项目 = 自动回切「打开前会话」;
|
|
|
|
|
|
③ 自定义窗口提示词带窗口身份(项目+窗口N)+ 更多注入(插件知识包),解决接收会话
|
|
|
|
|
|
从头侦察插件源码导致的响应过慢。
|
|
|
|
|
|
- 实现:① projects.v1.folders(项目id→绝对路径);saveLayout 强制父目录 + mkdir 建目录;
|
|
|
|
|
|
绑定弹窗加「📁 项目文件夹」区(显示/更改/保存);新建对话未选分组时 sessions.create({cwd:
|
|
|
|
|
|
项目文件夹});② 模块级 projectAttachRef/suppressRestoreRef + syncSessionScope 检测「切到非
|
|
|
|
|
|
归属会话 → splitStore.close()」+ splitStore 订阅「关闭 → sessions.open(打开前会话)」;
|
|
|
|
|
|
③ buildWindowTaskText 统一组装(窗口身份+文件夹+KNOWLEDGE_PACK「不要重新侦察插件源码」),
|
|
|
|
|
|
两模式共用;CustomPane 经 PaneBody 传入窗格标题(窗口N)。
|
|
|
|
|
|
- 验证(probe-batch6.cjs):提示词含窗口2/项目/文件夹/知识包 ✓;新建面板 3 输入、folders 持久化
|
|
|
|
|
|
+ 目录真实创建 ✓;绑定面板文件夹区(未设置态/表单/保存)✓;联动:切会话→projectAutoClosed+
|
|
|
|
|
|
keptNewSession ✓、st.close→restoredToPrev ✓;functional-diag 全 20 STEP ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效;测试目录已清理。用户贴的接收会话记录(glob 超时/反复 Read
|
|
|
|
|
|
插件源码)即知识包要解决的痛点。
|
|
|
|
|
|
|
2026-08-19 21:48:32 +08:00
|
|
|
|
## 补记(自定义窗默认模式对调 + 文件夹弹窗选择)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:① 自定义窗默认应为「发送到会话」且排第一,「新建对话」第二;② 项目文件夹的
|
|
|
|
|
|
父目录+名称双输入太麻烦——要像 DSH 加工作区那样弹资源管理器式位置选择窗。
|
|
|
|
|
|
- 实现:① CustomPane 默认 mode='existing'、按钮顺序对调(发送到会话在前);② 文件夹选择
|
|
|
|
|
|
改用宿主 ctx.workspaces.pickDirectory()(本机为原生 IFileDialog,真实 Windows 文件夹选择窗,
|
|
|
|
|
|
与 DSH 加工作区同款):新建项目面板 = 路径显示 + 「选择位置…」按钮(必选,留空不可保存);
|
|
|
|
|
|
绑定弹窗「更改」= 直接弹窗选择、选中路径即项目文件夹;取消手输表单与 mkdir 依赖。
|
|
|
|
|
|
- 验证(probe-batch7.cjs,桩 pickDirectory):默认模式按钮0=发送到会话且选中、会话行默认可见、
|
|
|
|
|
|
分组行默认隐藏 ✓;新建面板路径显示+选择按钮、桩返回路径回填、保存后 folders 持久化 ✓;
|
|
|
|
|
|
绑定弹窗「更改」写入选中路径 ✓;functional-diag 全 20 STEP(STEP20 按新顺序重写)
|
|
|
|
|
|
ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效;无头环境 pickDirectory 不弹真实对话框(挂起),真实 GUI 中
|
|
|
|
|
|
由用户手势触发原生 Windows 文件夹选择窗。
|
|
|
|
|
|
|
2026-08-19 22:00:45 +08:00
|
|
|
|
## 补记(修复:新建对话后项目被误关 + 未自动绑定)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:自定义窗「新建对话」发送后,项目界面自动关闭跳到新对话;且项目未自动绑定新对话
|
|
|
|
|
|
(项目当时无绑定)——两处都不对:用户要继续在项目里跟新对话沟通,且按规则应自动绑定。
|
|
|
|
|
|
- 根因:createCustomSession 里 sessions.open(新会话) 触发「项目打开期间切到非归属会话 →
|
|
|
|
|
|
自动关项目」联动;项目一关,CustomPane 的 autoBind 拿不到 splitStore.spec.id → 绑定失败。
|
|
|
|
|
|
- 修复:pluginOpenedSessionsRef + markPluginSessionOpen——插件自身发起的会话切换(新建/发送)
|
|
|
|
|
|
在联动检测中被消费豁免,不关项目;autoBind 随即可正常执行(项目仍打开)。
|
|
|
|
|
|
- 验证(probe-batch8.cjs,真实发送一条消息后归档):projectStillOpen=true ✓、
|
|
|
|
|
|
binding=新会话且 boundToNew=true ✓、完成页提示「已自动把这个项目绑定到这个对话…」✓;
|
|
|
|
|
|
functional-diag 全 20 STEP ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效。
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-08-19 21:54:50 +08:00
|
|
|
|
## 补记(提示词零泄漏硬约束)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户提醒:新建对话的分组下拉里出现的个人分组(Projects / DeepseekHarness 等)绝不能写进
|
|
|
|
|
|
对外生成的提示词(尤其「+自定义」剪贴板提示词——会发给别人的 DSH)。
|
|
|
|
|
|
- 核查:buildCustomLayoutPrompt 只含插件通用知识(预设列表/字段/构建方式,无任何个人路径与
|
|
|
|
|
|
分组名)✓;buildWindowTaskText 含项目名/窗口N/项目文件夹(仅发用户自己的会话)✓;分组
|
|
|
|
|
|
下拉选择只用于 sessions.create 的 workspaceId,不进任何文本 ✓。
|
|
|
|
|
|
- 固化:AGENTS.md「提示词零泄漏(硬约束)」+ PRD §13 条目 + buildCustomLayoutPrompt 代码注释。
|
|
|
|
|
|
- 备注:本次无行为改动,仅规则固化与文档;重建后提交。
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-08-19 21:48:32 +08:00
|
|
|
|
|
2026-08-19 21:29:44 +08:00
|
|
|
|
|
2026-08-19 21:10:39 +08:00
|
|
|
|
## 补记(箭头再上移 0.5px)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:入驻卡箭头还是有点偏下,再往上一点点。
|
|
|
|
|
|
- 处理:.dsh-wt_resArrow 与 .dsh-wt_layoutArrow 的 translateY(-1px) → -1.5px(两处同款保持
|
|
|
|
|
|
一致)。
|
|
|
|
|
|
- 验证(carddom-mini.cjs):ta/pr 箭头字面中心高于卡片中心 2px(墨迹视觉居中);functional-diag
|
|
|
|
|
|
ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效。
|
|
|
|
|
|
|
2026-08-19 22:05:56 +08:00
|
|
|
|
## 补记(未分组会话入列表 + 新建面板文件夹行左对齐)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:① 新建布局面板「项目文件夹」行左侧有空隙、地址栏太短;② 绑定对话与发送到会话
|
|
|
|
|
|
的列表里都没有「未分组」的对话。
|
|
|
|
|
|
- 处理:① 文件夹行标签去掉 86px 右对齐固定宽(width:auto/text-align:left,与名称输入框左缘
|
|
|
|
|
|
对齐),地址显示条 flex:1 拉长,面板 320 → 360 宽;② fetchSessionGroups 增「未分组」组——
|
|
|
|
|
|
收集所有工作区已归属会话后,把 snap.ids 中不属于任何工作区(且非 archived/子代理)的会话
|
|
|
|
|
|
归入「📁 未分组」组,排在列表最前。绑定弹窗与发送到会话共用该函数,一处修复两处生效。
|
|
|
|
|
|
- 验证(probe-batch9.cjs):期望未分组 5 个 → 组标题 [📁 未分组, 📁 Projects, 📁 DeepseekHarness]、
|
|
|
|
|
|
列表 19 项(14+5)✓;文件夹行 text-align=left、标签左缘 304 ≈ 行左缘 302、与名称输入框对齐 ✓;
|
|
|
|
|
|
functional-diag 全 20 STEP(groupHeaders 3 / itemCount 19)ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效。
|
|
|
|
|
|
|
2026-08-19 22:30:25 +08:00
|
|
|
|
## 补记(任务完成/待决提醒镜像到项目卡)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户要求:绑定对话出现原生小绿点(任务完成)/小黄点(需要判断)时,项目卡上的两个圆点
|
|
|
|
|
|
同步变绿/变黄并发光;点一下项目恢复常态实心。
|
|
|
|
|
|
- 实现:syncSessionScope 额外把完整会话快照写入 sessionsSnapshotStore 并通知监听;
|
|
|
|
|
|
组件按 bindings × byId.completed/pendingInteraction(含 notifyAck.v1 ack 过滤)算出
|
|
|
|
|
|
bindNotifyMap;卡片 data-bound 扩展 done/need 两态(CSS 绿 #3fb950 / 黄 #d29922 + 实心 +
|
|
|
|
|
|
drop-shadow 发光);点开项目(openSplit / DOM 桥)ack 当前状态恢复实心;hover 气泡追加
|
|
|
|
|
|
「任务已完成,点击项目查看」「需要你的决定,点击项目处理」。
|
|
|
|
|
|
- 验证(probe-batch10.cjs,桩注入快照状态):completed→data-bound=done、色 rgb(63,185,80)、
|
|
|
|
|
|
实心、drop-shadow 发光、tip 含「已完成」✓;点项目→ack=done、恢复 data-bound=true ✓;
|
|
|
|
|
|
pendingInteraction→need、黄 rgb(210,153,34)、发光、tip 含「决定」✓;functional-diag
|
|
|
|
|
|
全 20 STEP ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效。
|
|
|
|
|
|
|
2026-08-19 22:47:44 +08:00
|
|
|
|
## 补记(窗口任务提示词按任务分形式)
|
|
|
|
|
|
|
|
|
|
|
|
- 用户反馈:几乎所有自定义窗口都用 HTML 实现,质疑是否该有更合适的形式。
|
|
|
|
|
|
- 处理:buildWindowTaskText 第 4 条改为「产出形式请按任务类型选择(不要一律用 HTML)」表——
|
|
|
|
|
|
交互小工具/看板/表单/图表→单文件 HTML;文档/演示→.pptx/.md/.xlsx 真实文件;视频/动画→
|
|
|
|
|
|
.mp4/.gif/Lottie;已有内置能力→建议改用内置窗,不要重复造轮子;知识包装载方式同步中性化。
|
|
|
|
|
|
- 验证(promptform-mini.cjs):hasTable/hasPptx/hasMp4/hasBuiltinAdvice/noPriorityHtml/
|
|
|
|
|
|
knowledgeNeutral/stillHasHtmlForTools 全 true;functional-diag 全 20 STEP ERROR_COUNT: 0。
|
|
|
|
|
|
- 备注:纯客户端改动,F5 即生效;组件窗(配置驱动)方向另行讨论。
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-08-19 22:30:25 +08:00
|
|
|
|
|
2026-08-19 22:05:56 +08:00
|
|
|
|
|
2026-08-19 21:10:39 +08:00
|
|
|
|
|
2026-08-19 21:07:20 +08:00
|
|
|
|
|
2026-08-19 21:03:01 +08:00
|
|
|
|
|
2026-08-19 21:00:22 +08:00
|
|
|
|
|
2026-08-19 20:56:35 +08:00
|
|
|
|
|
2026-08-19 02:11:58 +08:00
|
|
|
|
|
2026-08-19 00:19:14 +08:00
|
|
|
|
|
2026-08-19 00:06:03 +08:00
|
|
|
|
|
2026-08-18 23:27:16 +08:00
|
|
|
|
|