<div align="center">
<img src="public/favicon.svg" width="72" alt="DSH 灵动岛 logo" />
🛰️ DSH 灵动岛
给 DeepSeek Harness 的一只小玻璃伙伴——Agent 思考时它轻轻呼吸,干活时它微微脉动,要动你的东西之前,它还会先礼貌地问你一声。
🍎 Liquid Glass 质感 · 🌱 零额外依赖 · 👀 时刻知道你的 Agent 在干嘛
English · [MIT](LICENSE)
</div>
---
> 状态:高保真设计原型 —— 为 DeepSeek Harness 设计、打磨、验证灵动岛形态的地方,之后才会变成真正的插件。⭐ 点个 Star,让这座小岛留在你的轨道上。
---
🪟 岛在工作区里的样子
| 安静地趴在角落 | 需要你时弹开 | 完成后留张小收据 |
|---|---|---|
| <img src="public/screens/island-1.png" width="320" alt="工作区上的灵动岛" /> | <img src="public/screens/island-2.png" width="320" alt="展开的灵动岛" /> | <img src="public/screens/island-3.png" width="320" alt="任务完成后的灵动岛" /> |
小岛平时安静地待在工作区角落。一旦你的 Agent 开始做值得你知道的事——思考、跑工具、等你批准、或者碰了钉子——它就立刻活过来。
🧭 这是什么?
dsh-dynamic-island 是为 DeepSeek Harness 打造的苹果 Liquid Glass 风格灵动岛概念原型:把 Agent 的内心活动——思考、工具调用、审批、异常、完成——变成一块轻量、可读、带一点点陪伴感的小屏幕,趴在你屏幕的边缘。
它不是一只和任务无关的桌宠。每一次形态变化都来自真实的 Harness 状态:你永远知道 Agent 有没有在干活、在干什么、要不要你拍板、任务最后怎么样了。
✨ 你会喜欢它的理由
- 🍬 货真价实的 Liquid Glass —— 层层通透、带弹性的形态、会动的光。全部手写 CSS,不用任何 UI 库。
- 🎯 状态优先,始终如一 —— 小伙伴的表情、核心光源、边缘色和文字说的是同一件事。绝不用假动画假装"AI 在思考"。
- 🤫 低打扰设计 —— 没事就缩成一个小点。任务完成时留下一张小收据,然后安静回去。
- 🛡️ 尊重你的决定 —— 审批镜像 Harness 原生输入区:灵动岛只是第二个同步操作入口,绝不会自己替 Harness 做决定。
- ♿ 无障碍、有礼貌 —— 尊重
prefers-reduced-motion,不单靠颜色表达状态,审批按钮永远是真实可点的按钮。 - 🌱 零运行时依赖 —— React + 一点点 CSS,仅此而已。
🎨 八种心情
| 心情 | 感觉 | 色调 |
|---|---|---|
| 🛰️ 待命 | agent/status: idle 时的安静小点——「随时吩咐」 | slate |
| 🧠 思考 | 核心轻轻呼吸;胶囊显示当前任务和步骤 | aqua |
| 🛠️ 执行 | 青绿脉冲——工具名和进度实时显示 | mint |
| 🫵 确认 | 暖珊瑚边缘——展开真实的「批准 / 暂不」按钮 | coral |
| ✅ 完成 | 一抹柔和的折射高光 + 结果小票 + 最近完成堆 | lime |
| ⚠️ 异常 | 橙色停顿——失败摘要和回到正轨的入口 | amber |
| 🔒 阻塞 | turn/end {blocked}——目标暂停,等你解除 | violet |
| ✂️ 上限 | turn/end {max-tokens}——输出被截断,可续跑 | rose |
🔌 它怎么和 DeepSeek Harness 对话
概念上把每一条 Harness 信号映射成一种岛的心情——一个窄的、可版本化的客户端状态协议,而不是一头扎进原始事件流:
| 岛的心情 | DSH 信号 |
|---|---|
idle | agent/status: idle |
thinking | agent/status: running、step/start、assistant/chunk(reasoning-delta) |
working | tool/call → 对应的 tool/result(含 error / meta) |
approval | 输入区有待处理的审批 |
complete | turn/end 成功结束 + assistant/message.usage |
alert | tool/result error、agent/request-error、turn/end {error} |
blocked | turn/end {blocked} |
max-tokens | turn/end {max-tokens} |
八态之上,每个心情还带载荷字段(流式预览、工具卡、小票、目标、清单、后台任务):
| 岛上元素 | DSH 信号 | |---|---| | 流式预览行(思考/正文分色) | assistant/chunk(text-delta / reasoning-delta) | | 工具命令卡(退出码 / 耗时 / 复制) | tool/call.arguments + tool/result | | 结果小票(文件 / 检查 / tokens / 用时) | turn/end.reason + assistant/message.usage | | 目标进度环 | goal 包:roundsStarted / 轮次上限 | | 任务清单点 + 三态清单 | todo/write(整表快照,last-write-wins) | | 后台任务胶囊 | jobs 包:running \| stopping \| completed \| killed \| failed + detail | | 小票堆(最近完成) | turn/end 序列 | | 模型徽章 | request/context(provider · model) | | 停止 / 重试 / 解除阻塞 / 续跑 | agent/turn-stopping / agent/request / goal 解除 / turn 续跑 | | 子代理注记 | subagent/start / subagent/end |
> 回放与持久化读 session/event;实时交互读 agent/*。正式插件还需要敲定当前版本允许的 client slot/connection 注入点——以及没有活动会话、事件流断开、多会话并行、HMR 重载这些边角规则。这些都在[路线图](#-路线图)上。 > > 完整的「DSH 需要什么 × 信号层能不能做到 × 岛怎么呈现」分析见 [docs/analysis.md](docs/analysis.md)。
🚀 跑起来
npm install
npm run dev打开 Vite 打印的地址——底部 灵动岛演示 栏可以切换八种心情:
- 确认状态点「批准 / 暂不」,看小岛瞬间同步反映结果;
- 点「查看过程」展开岛内活动流:工具卡带退出码、耗时,还能一键复制命令;
- 点「清单」展开完整任务清单(三态勾选);目标进度环显示 goal 轮次;
- 异常态可点「重试」,阻塞态可点「解除阻塞」,上限态可点「继续」;(停止交给 Harness 原生界面)
- 模型徽章显示当前使用的模型(替代后台任务胶囊);
- 按住岛任意空白处可拖拽到任意位置(位置会记住,刷新后仍在);
- 按 ⌘K(或 Ctrl+K)打开命令面板,输入过滤、↑↓ 选择、↵ 执行;
- 点「▶ 自动演示」完整看一遍 待命 → 思考 → 执行 → 确认(自动批准)→ 完成 的弧线,按 Esc 随时收起。
🔌 集成进 DSH(插件化)
这个项目就是一枚 DSH 客户端插件 —— 仓库根即双面包插件包,已在 npm 发布(dsh-dynamic-island):
# 直接装进 Harness(web profile)
dsh plugin --profile web add dsh-dynamic-island
dsh --profile web # 重启 → 岛浮现在 GUI 右上角,可拖拽、位置记忆
# 或作为普通依赖(开发/引用浏览器半场)
npm install dsh-dynamic-island本地开发时也可以从源码装(npm run build:plugin 产出 lib/client.js 后, dsh plugin --profile web add /path/to/this-repo)。
机制已全部对照 DeepSeek Harness 源码核实:
- 注入点:Web GUI 的
shell.overlay浮层槽(ui-layout 专门为全屏浮层预留的
加性 list 槽,目前零注册者),无需修改 apps/web 源码;
- 形态:双面包 npm 包 ——
dsh.client声明 +exports["./client"]浏览器半场
(lib/client.js,scripts/build-plugin.mjs 产出 __ModuleLoader__.load 闭包工厂 + 平台模块表 extern)+ 空 node 半场(src/index.js),dsh plugin --profile web add <pkg> 一条命令安装;
- 数据:浏览器半场订阅
ctx.sessions.currentProvideInfo→ 会话快照 + 投影
(goal、todos、tokenUsage、contextPressure、permissions)→ src/plugin/protocol.js 派生成岛模型 → 同一套 src/components React 组件渲染(demo 与插件共用一份 UI)。
仓库内已就位:src/client/(浏览器半场:index / IslandDock / island-store / live-bridge / styles / locales)、src/index.js(node 半场)、cordis.patch.yml、 src/plugin/protocol.js(协议适配层)。完整方案、开发工作流与已知缺口见 [docs/integration.md](docs/integration.md)。
🧱 技术栈
- React 19 + Vite 8 —— 简洁快速
- 纯手写 CSS —— 每一块玻璃、每一条轨道、每一次呼吸都是定制的
- 零 UI 框架 —— 重点是验证设计,不是炫技
🗺️ 路线图
- [x] 八种状态的 Liquid Glass 灵动岛(含待命 / 阻塞 / 上限)
- [x] 同步的审批操作(原生输入区的镜像)
- [x] 流式输出预览(
assistant/chunk,思考/正文分色) - [x] 工具命令卡片(退出码、耗时、复制)
- [x] 结果收据(文件、检查、tokens、用时)+ 最近完成小票堆
- [x] 目标进度环 + 完整任务清单(goal、
todo/write) - [x] 模型徽章(
request/context,显示当前使用的模型) - [x] ⌘K 命令面板 + 自动演示
- [x] 集成方案与插件骨架(仓库根即双面包客户端插件)
- [x]
build:plugin产出 loader 合规 bundle,冒烟通过(握手 / 工厂 / apply / 桥派生 / 动作面) - [ ] 真实 GUI 联调(桥实机核对 + retry/continue/unblock/approve 接上真实远端)🚀
💛 让小岛留在轨道上
如果它让你会心一笑,点个 ⭐ —— 这是把设计原型变成真正插件的燃料。Issues、想法、"为什么还不支持 XXX" 统统欢迎。
为 DeepSeek Harness 社区,用 🫶 建造。