# 更新记录

## [0.6.0] — 2026-10-11

**按会话隔离云端任务状态**（用户指出：A 对话发起的云端任务会在 B 对话显示/取回，且不同工作区都会显示云端状态）

- 宿主 `state` 接口支持 `sessionId` 作用域：只返回**属于该会话**的云端任务；设置页不传则给全局视图
- 客户端轮询与展示按会话作用域：某个对话的云朵状态/卡片只反映**本对话**发起的任务，其他对话与工作区不再串显
- 输入区运行中卡片按钮修正：原来的「取消」只是关窗口、容易被误解为终止任务，现改为
  - **终止**：真正停掉云端任务（中止并保留已产出进度，可「回收进度」）
  - **关闭**：仅关闭弹卡
- 「终止」对**云端尚未接单**（本地打包中）的任务同样生效：本地直接废弃该任务

## [0.5.1] — 2026-10-10

- **修复云端项目命名空间创建失败**：`handoff-projects` 原放在 `/srv/dsh-cloud/`（root 属主）下，插件以 `dshcloud` 运行 → `EACCES: permission denied, mkdir`，任务卡在 PENDING；现改到 **DSH_HOME 下**（`/srv/dsh-cloud/home/handoff-projects`，归插件用户所有，任何部署都成立）
- **实测验证隔离与连续**（受控测试，同一工作区发两次任务）：
  - 命名空间按 projectKey 建立，含 `memory/`、`journal.md`、`workspace.json`；任务计数与首末时间正确（jobs=2）
  - 任务结束时插件**自动追加**日志（任务/会话/结论/产出）
  - 第二次任务的云端 agent **确实先读了 `.cloud-project/journal.md`** 并在产出中引用第一次任务的结论 → 跨任务连续成立
- 文档同步：`docs/LIMITATIONS.md` 与 `docs/cloud-host-setup.md` 中的命名空间路径改为 DSH_HOME 下

## [0.5.0] — 2026-10-10

**云端记忆按工作区隔离 + 同工作区连续**（用户边界：不同对话/工作区要隔离，同一工作区要能延续）

- **隔离**：不再把本地记忆写进云端全局 `mnemon/runtime`；改为按工作区建独立命名空间
  `/srv/dsh-cloud/handoff-projects/<projectKey>/`（`projectKey = sha256(本地工作区路径)[:16]`，路径本身不泄露）
  - `memory/` —— 该工作区的持久记忆（本地 `MEMORY.md`/`USER.md` 随包落入此处，其他工作区看不到）
  - `journal.md` —— 历次云端任务日志
  - `workspace.json` —— 本地工作区、任务次数、首末时间
- **连续**：云端会话开工前会先读 `.cloud-project/journal.md`（软链进工作区），知道"这个项目之前做过什么"；任务结束时**插件自动追加**一条日志（任务/结论/产出/越界），无需 agent 操心
- **防串味**：`.cloud-project` 不进工作区快照与回传 diff（`walkFiles` 显式跳过）
- **可见性**（回应"看不到云端怎么编排"）：设置页新增「**云端项目**」卡片，列出每个工作区 ↔ 云端命名空间：任务次数 / 最后一次时间 / 记忆大小（人类可读）
- 清理边界：任务产物照旧确认后清除；**项目记忆与任务日志保留**（这是"越用越懂项目"的载体）

## [0.4.4] — 2026-10-10

- 云议会话清理更彻底：`purgeJob` 改为**按 jobId 删除整个项目会话目录**（原文只按 `sessionId` 删，任务产生的**子智能体会话**会残留）
- 清理云端历史会话残留（4.2MB）

## [0.4.3] — 2026-10-10

- 修复云端清理残留：`purgeJob` 删除会话目录后**未清理变空的项目父目录**（`--srv-dsh-cloud-workspaces-<jobId>--`）；现补 `-empty` 检查并顺手删除
- 实测确认「确认完成」链路：工作区 / 进出包 / job 记录 / 会话副本全部清除（此前仅父目录残留）
- 顺带清理历次测试任务的云端残留（4 个 job 的工作区、进出包、记录与空目录）

## [0.4.2] — 2026-10-10

- 界面：瞬时提示（"✔ 取回完成，云端副本已清理"等）现在**绑定到具体任务**，任务收尾/切换后由 `refresh` 自动清除，不再长期挂在发送卡片上
- 影响范围：仅客户端（刷新页面即可生效，无需重启）

## [0.4.1] — 2026-10-10

- 修复 v0.4.0 遗漏：客户端已有「查看报告」按钮，但**宿主缺少 `open-report` 路由**（补丁在锚点处失败后重试时漏加），点击报 `unknown method: open-report`
- `open-report` 实现：从回传包解出 Markdown 报告 → 复制到 `~/.dsh/dsh-cloud-handoff/work/reports/<jobId>/` → 调系统默认应用打开（macOS `open` / Linux `xdg-open`）；找不到研究报告时回退到包内任意 `.md`
- 实测：用真实回传包（job f1398386）验证解包与报告定位成功

## [0.4.0] — 2026-10-10

**云端定位固化为「研究模式」**（用户明确边界：云端只做研究/验证/方案，绝不直接改本地项目代码）：

- **云端只允许在研究目录内产出**（`cloudResearchDir`，默认 `cloud-research/`）：
  - `<主题>-复盘.md` 主交付物（固定结构：背景/结论/方案与权衡/范例代码/验证过程/风险/给本地 agent 的实施建议）
  - `examples/` 范例代码片段、`evidence/` 验证实验脚本与输出
- **深度研究为默认方法**：先列假设 → 逐条验证 → 复盘（区分已验证/推断）→ 方案与权衡
- **回传范围过滤 + 越界告警**：只回传研究目录内的变更；云端若触碰目录外文件，一律拦截不回传，本地卡片红字警告（`outOfScope`/`deletedOut`）
- **界面**：移除「机械应用」按钮；取回卡片新增「**查看报告**」——一键用系统默认 .md 应用打开云端复盘报告，看完再决定是否交给本地会话落盘
- 取回指令改为研究语义：本地 agent 先读报告（`dsh_cloud_apply_result mode=report`）→ 结合本地完整代码库制定实施计划 → 再落盘；范例代码仅供参考
- 新增 `classifyResearchScope` 纯函数与单测（10/10 通过）

## [0.3.6] — 2026-10-09

- **修复真实发送失败**：`buildTaskBrief` 返回 `{brief}` 而打包器读 `brief.text` → 每次真实发送都报「缺少任务简报」而失败（此前的干跑测试手工构造了 `{text}` 所以没暴露）
- 统一字段为 `text`，并新增 **简报→打包 集成测试**（造真实会话日志 → 生成简报 → 打包），防止同类字段错位再次发生

## [0.3.5] — 2026-10-09

- 任务输入框加大：3 行 → **6 行（132px 起，可拖高至 45vh）**，面板宽度 288px → 360px；提示语改为"本地 agent 会据此整理成完整简报"，明确无需用户写长篇
- 说明：自 v0.3.1 起用户只需一两句话即可，细节由本地 agent 总结成简报

## [0.3.4] — 2026-10-09

- **发送改为异步**：点击发送立即返回（不再阻塞 1~2 分钟导致工具调用超时/界面像卡住），打包与上传在后台进行
- **迁移阶段可见**：卡片实时显示 `准备任务简报 → 生成任务简报 → 打包工作区（简报 X KB）→ 上传到云端 → 云端接单中 → 云端执行中`
- 失败阶段明确落库（传输失败 / 云端接单失败 / 迁移异常），操作记录同步写入

## [0.3.3] — 2026-10-09

- 修复 v0.3.0 载荷改造遗漏：`packBundle` 仍在读已移除的 `sessionLogs`，导致点击发送即报 `Cannot read properties of undefined (reading 'find')`
- 新增打包干跑单测，防止同类回归
- 冒烟验证：简报式迁移 + 云端新建会话 + API Key 通道**全链路跑通**（云端建目标 → 读简报 → 产出文件 → `dsh_cloud_finish` → receipt `changed` 正确）

## [0.3.2] — 2026-10-09

**实测云端载荷上限，据此定简报预算（不再拍脑袋）**

实测（api.deepseek.com/anthropic，deepseek-v4-pro）：

| 请求体 | 结果 |
|---|---|
| 2 MB | 200 OK（4.3s） |
| 8 MB | 200 OK（83s） |
| 16 MB | 400：1,398,191 tokens > 上下文上限 1,048,576 |
| 32 MB | 400：2,796,291 tokens |

结论：**硬限制是模型上下文窗口 1M tokens**，不是请求字节数；上传速度约 100KB/s（越大越慢）。

据此：
- 简报预算 `briefBudgetBytes` 默认 **300KB**（≈5~7 万 tokens，占窗口 5~7%，上传 <1s），可用插件配置调整
- 细节保留度大幅提高：用户要求最多 150 条（每条 ≤3000 字）、助手结论 80 条（每条 ≤4000 字）、约束与注意事项 40 条、文件线索 200 条、发起方补充上下文 ≤120KB
- 实测本会话（18.3MB 日志 / 5895 事件）→ 简报 **35.1KB**，未触发截断，信息密度远高于此前 10KB 版本

## [0.3.1] — 2026-10-09

**发送流程改为「先总结、再迁移」**（用户明确要求）：
- 点发送后不直接打包，而是先交给**本地 agent**：
  1. 把用户的意图总结成清晰、可独立执行的**子任务**；
  2. 围绕该子任务挑出相关的**主任务状态 / 依赖 / 前置条件 / 约束与注意事项**；
  3. 调用 `dsh_cloud_send(taskSummary=…, briefOverride=…)` 真正迁移。
- 云端收到的是「总结后的子任务 + 前情简报」，**不是原始对话**；确定性简报仍作为兜底基础。
- 发送卡片提示语同步更新，明确告知"先总结、再迁移"。

## [0.3.0] — 2026-10-09

**迁移载荷重做：不再打包整段会话历史，改为「任务简报」**（用户指出：整段对话不可能发上去）

- 本地发送前自动生成**分支任务交接简报**：主任务背景与当前状态 → 依赖与注意事项（从你的约束里提炼）→ 云端环境事实 → 交给云端的子任务 → 关键文件线索；体积上限 40KB（实测 18.3MB 会话 → 10.3KB）
- 云端不再导入旧会话，而是**新建干净会话**下发简报，并把模型固定为 API Key 通道（`cloudProvider`/`cloudModel`）
- 彻底消除因上下文过大导致的云端调用失败（此前 16.9MB 会话 → 请求超限 → `transport failed`）
- 发送工具支持 `briefOverride`：发起任务的 agent 可补写依赖/约束/注意事项
- 附带上一版未发布的界面调整：运行中卡片直接显示「云端正在运行，请稍后（已跑 X 分钟）」+ 任务简述；**只有云端完成后才出现「取回结果」按钮**；云端一结束后台自动下载（只下载不落盘）

## [0.2.7] — 2026-10-09

- **云端固定走 API Key 通道**（根因修复）：云端是无头机器、没有账号登录态，导入会话时把 `model/selection` 的 provider 改写为 `deepseek-official`（可配置 `cloudProvider`），模型 id 保持不变；此前云端每次调用模型都 `DeepSeek Messages transport failed`
- **记录每一次用户操作**：新增 `operations.json`（最近 200 条）与任务 `history`，覆盖发送/取回/机械应用/交给会话落盘/确认完成/丢弃/中止/接入；设置页新增「最近操作」卡片，含人类可读时间
- 修复提示重复：`emit` 之前只做浅合并，旧 `result` 与新 `error` 会同时显示（出现两行重复提示）
- 「云端正在执行」不再显示为红色错误，改为信息态提示（含已跑时长与事件数）

## [0.2.6] — 2026-10-09

修复**云端任务永久卡在「云端仍在执行」**的真实缺陷（首次实际使用即踩到）：
- 根因：云端 agent 的会话回合异常结束（如 DeepSeek API 传输失败）后没来得及调用 `dsh_cloud_finish`，任务状态永远停在 `RUNNING`，本地"取回"被判定为"云端仍在执行"而永久拒绝
- 修复：云端新增**回合结束收敛**——日志静默 ≥90 秒且最后事件是 `turn/end` 时，自动打包回传并置为 `STOPPED`（本地/云端均有 60 秒与查询时的惰性检查）
- 本地「待取回」卡片对 `STOPPED` 明确提示「云端未正常完成（会话回合中断），以下是中断前的产出」

## [0.2.5] — 2026-10-08

发布流程升级为 **npm Trusted Publishing（OIDC 受信发布）**：
- 打 tag 即由 GitHub Actions 自动发布到 npm，**无需 token、无需 2FA 交互**
- 自动附带 **provenance 签名**（用户可验证包确实由本仓库构建）
- 发布前强制校验 `tag` 与 `package.json` 版本一致

## [0.2.4] — 2026-10-08

R3 真机验证修复（Debian 12 / Ubuntu 24.04 全新机器实测）+ 仓库开源化（README/LICENSE/CHANGELOG/CI）。

一键脚本在**全新云镜像**上跑出来的真实问题，全部已修：
- **插件未被云端加载**：`dsh plugin link/add` 只写 `dependencies`，不写 `dsh.profile.bundles`，插件装上却不会加载；脚本现在显式注册 bundle，并校验「依赖 + bundle」两项
- **失败被静默吞掉**：插件链接失败时原来被 `|| true` 掩盖（用户会看到"对接成功"但云端无反应）；现在关键步骤失败即报错退出
- **属主混乱**：stage 5 以 root 跑 pnpm 导致 profile 属主为 root，dshcloud 后续无权操作；现在统一属主并以 dshcloud 身份执行
- **apt 撞锁**：全新镜像首次开机 cloud-init/unattended-upgrades 长时间占用 apt；现在等 cloud-init 结束 + `DPkg::Lock::Timeout=900` 让 apt 排队
- **端口漂移**：重跑脚本每次生成新端口会破坏已配对客户端；端口现在持久化到云端 config 并沿用
- **启动自检**：改为轮询 90 秒（DSH 冷启动约 20~30 秒），自检失败会明确警告
- **不再安装代理软件**：删除 mihomo 部署；新增 `--mirror cn`（apt 换清华 TUNA + npm 换 npmmirror）
- **发行版门禁**：仅支持 Debian 12/13 与 Ubuntu 22.04/24.04（其它发行版直接提示退出）；Ubuntu 增加 needrestart 非交互与 dpkg 配置冲突策略

验证记录：Ubuntu 24.04 与 Debian 12 全新机器上，脚本自检均在第 10 秒通过；用对接码完成配对（SSH 免密 + 云端 RPC 在线）、跑通真实任务（云端执行 → 下载待取回 → 不落盘 → 确认完成 → 云端工作区/进出包/会话副本/job 记录全部清空）。

## [0.2.3] — 2026-10-08

真机全链路验收后的修复：
- 取回指令改为**直接落盘**（用户在审阅卡已确认，不再二次询问）；子智能体职责明确：逐文件读取 → 按 `localStatus` 写入 → 冲突/二进制走 `.cloud-<jobId>` 副本 → 落盘后校验
- 审阅卡补**变更文件清单**（原来只有计数）
- 「确认完成」同时清理本地回传包与解包缓存

## [0.2.2] — 2026-10-08

开源对接能力（R2）：
- 一键脚本通用化：随机端口、预生成 Token、打印**对接码** `DSHCP1:…`、SSH 公钥引导、x86_64/arm64 自动选型、发行版探测、`--registry cn`、`--repo` 自动克隆
- 插件新增 **云端接入向导**（设置页）：粘贴对接码 → 解析 → 测试连通 → 保存（`pairing.apply` RPC）

## [0.2.1] — 2026-10-08

兼容性重构（R1）：
- **tar-over-ssh 替代 rsync**：本机只需系统自带 `ssh`/`tar`，Windows 亦可（实验性）
- `findChildLogs` 去掉 zstd CLI 依赖，改用 `node:zlib`
- 声明 `engines.dsh`

## [0.2.0] — 2026-10-08

取回三段式（P2–P4）：
- 下载不落盘：云端完成 → 只下载回传包 → 状态 `RETURNED`（云端已完成·待取回）
- 落盘两条路径：**子智能体取回**（默认，`dsh_cloud_apply_result` 工具消费回传包）与**机械应用**（兜底）
- 回传包 v2：新增被改文件的**迁移前基线**（`base.tar.zst`，三路合并用）与完整 receipt
- 云端 `/ack` 确认清理 + **保留期清扫**（默认 7 天，可配）
- 云端会话**永不拼回**本地会话（规避 seq 撞号）；jobs.json 保留最近 20 条
- 状态机新增 `RETURNED` / `DISCARDED`

## [0.1.6] — 2026-10-08

- **非 git 目录也能上云**：工作区遍历模式 + 排除表（node_modules/.git/缓存/凭据/.DS_Store）
- 发送前**预检**：工作区不可打包时不打断当前轮
- 真实工作区实测：321 文件 / 68.6MB / 跳过 10 项缓存

## [0.1.5] — 2026-10-08

- 云朵图标下移 2px 对齐基线

## [0.1.4] — 2026-10-08

- 让底部信息栏收窄到内容宽度，云朵图标紧贴上下文圆环

## [0.1.3] — 2026-10-07

- 输入区改为**无边框云朵图标**（对齐底部控件行），点击弹出任务说明卡片（发送/取消）
- 中止后回传真实 diff + 会话尾部（原为占位）
- 同会话二次迁移：`SESSION_LIVE` 检测 → 自动重启云端服务 → 同 jobId 重试

## [0.1.2] — 2026-10-07

- 中止（abort）路径修复：状态 `ABORTED` 保留 active 供回收
- 冲突文件保留 `.cloud-<jobId>` 副本

## [0.1.0] — 2026-10-07

首个可用版本：会话日志帧级迁移（cwd 重写）、`resolveAgent + followup` 续跑、工作区 tar 快照、云端完成回传、启动钩子同步。
