dsh-dynamic-island
UI & ExperienceYLifeOnlyOnce/dsh-dynamic-island
A tiny glass companion for DeepSeek Harness: breathes while agent thinks, pulses while working, checks before touching anything. Liquid Glass looks, zero dependencies.
- dsh
- dsh-plugin
- dsh-plugins
- harness
README
π°οΈ DSH Dynamic Island
A tiny glass companion for DeepSeek Harness β it breathes while the agent thinks, pulses while it works, and politely checks with you before touching anything.
π Liquid Glass looks Β· π± zero extra dependencies Β· π always knows what your agent is up to
Status: a high-fidelity design prototype β the place where a Dynamic Island for DeepSeek Harness gets designed, iterated, and proven before it becomes a real plugin. β Star it to keep the island in orbit.
πͺ The island, in the wild
| Chilling over the workspace | Opens when it needs you | Leaves a tiny receipt |
|---|---|---|
The island lives quietly in the corner of your workspace. The moment your agent starts doing something worth knowing about β thinking, running a tool, waiting for your approval, or hitting a snag β it springs to life.
π§ What is this?
dsh-dynamic-island is a high-fidelity, Apple Liquid Glassβinspired Dynamic Island concept for DeepSeek Harness. It turns the agent's inner life β thinking, tool calls, approvals, failures, completion β into a lightweight, readable, slightly companion-like surface that sits on the edge of your screen.
This is not an unrelated desktop pet. Every shape change comes from real Harness state: you always know whether the agent is working, what it's doing, whether it needs your call, and how the task ended.
β¨ Why you'll like it
- π¬ Genuine Liquid Glass β layered transparency, springy shapes, and light that actually moves. All hand-rolled CSS, no UI library.
- π― Status first, always β the companion's face, core light, edge color, and words all tell the same story. No fake animations pretending to be "AI thinking".
- π€« Low-disturbance by design β it stays a quiet dot until something matters. When a task completes it leaves a short receipt, then settles back down.
- π‘οΈ Respectful of your call β approvals mirror the harness's native input area: the island is a second, synchronized place to act, never a rogue state machine.
- βΏ Accessible & polite β respects
prefers-reduced-motion, never relies on color alone, and keeps approval actions as real buttons. - π± Zero runtime dependencies β React and a sprinkle of CSS. Nothing else.
π¨ The five moods
| Mood | The vibe | Tone |
|---|---|---|
| π°οΈ Idle | agent/status: idle β a quiet dot that says "ready when you are" | slate |
| π§ Thinking | Breathing core; capsule shows the current task & step | aqua |
| π οΈ Working | Teal pulse while a tool runs β name and progress on screen | mint |
| π«΅ Approval | Warm coral edge β expands with real ζΉε / ζδΈ buttons | coral |
| β Complete | A soft refractive highlight + a result receipt + a stack of recent wins | lime |
| β οΈ Alert | Orange pause β failure summary and a way back in | amber |
| π Blocked | turn/end {blocked} β the goal paused, waiting for you to unblock | violet |
| βοΈ Max-tokens | turn/end {max-tokens} β output truncated, ask it to continue | rose |
π How it talks to DeepSeek Harness
The concept maps each Harness signal to one island mood β a narrow, versionable client protocol instead of drowning in the raw event stream:
| Island mood | DSH signal |
|---|---|
idle | agent/status: idle |
thinking | agent/status: running, step/start, assistant/chunk (reasoning-delta) |
working | tool/call β the matching tool/result (incl. error / meta) |
approval | a pending approval in the composer |
complete | a successful 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} |
On top of the eight moods, each state also carries payload fields (stream, tool cards, receipt, goal, todos, jobs):
| Island element | DSH signal |
|---|---|
| Streaming preview (reasoning vs. answer tinted) | assistant/chunk (text-delta / reasoning-delta) |
| Tool-command cards (exit code / duration / copy) | tool/call.arguments + tool/result |
| Result receipt (files / checks / tokens / duration) | turn/end.reason + assistant/message.usage |
| Goal progress ring | goal package: roundsStarted / round cap |
| Todo ticker + three-state checklist | todo/write (whole-list snapshot, last-write-wins) |
| Background job chips | jobs package: running | stopping | completed | killed | failed + detail |
| Recent-wins receipt stack | turn/end sequence |
| Model badge | request/context (provider Β· model) |
| Stop / retry / unblock / continue | agent/turn-stopping / agent/request / goal unblock / turn resume |
| Subagent note | subagent/start / subagent/end |
Replay & persistence read
session/event; live interaction readsagent/*. A production plugin still needs to pin down the client slot/connection injection points β and rules for no active session, a dropped stream, parallel sessions, and HMR reloads. That work is tracked on the roadmap.The full "what DSH needs Γ what the signal layer can do Γ how the island shows it" analysis lives in docs/analysis.md.
π Run it
npm install
npm run dev
Open the address Vite prints β the η΅ε¨ε²ζΌη€Ί dock at the bottom flips between the eight moods:
- In approval, hit ζΉε / ζδΈ and watch the island reflect the result instantly;
- Hit ζ₯ηθΏη¨ to expand the in-island activity feed: tool cards with exit code, duration, and a one-click copy of the command;
- Hit ζΈ ε to expand the full three-state task checklist; the goal ring shows goal round progress;
- Retry on alert, unblock when blocked, continue past max-tokens (stop is left to the native Harness UI);
- A model badge shows the model in use (replacing the background-job chips);
- Drag the island from any blank spot to reposition it β the spot is remembered across reloads;
- Press βK (or Ctrl+K) for the command palette β type to filter, ββ to move, β΅ to run;
- Hit βΆ θͺε¨ζΌη€Ί to watch the whole arc β idle β thinking β working β approval (auto-approved) β complete β and press Esc to tuck the island away at any time.
π Integrating into DSH (plugin)
This project is a DSH client plugin β the repo root is the dual-face package, published to npm as dsh-dynamic-island:
# Install straight into Harness (web profile)
dsh plugin --profile web add dsh-dynamic-island
dsh --profile web # restart β the island floats over the GUI, draggable, position remembered
# Or as a regular dependency (dev / referencing the browser half)
npm install dsh-dynamic-island
For local development you can also install from source (npm run build:plugin emits lib/client.js, then dsh plugin --profile web add /path/to/this-repo).
Every mechanism is verified against the DeepSeek Harness source:
- Mount point: the Web GUI's
shell.overlayfloating slot (ui-layout's additive list seat reserved for frame-wide overlays β badges, toasts, status pills β currently with zero registrants). No changes toapps/webare needed. - Shape: dual-face npm package β
dsh.clientdeclaration +exports["./client"]browser half (lib/client.js, built byscripts/build-plugin.mjsas a__ModuleLoader__.loadclosure factory with platform-table externs) + an empty node half (src/index.js). Installed with one command,dsh plugin --profile web add <pkg>. - Data: the browser half subscribes
ctx.sessions.currentProvideInfoβ session snapshot + projections (goal,todos,tokenUsage,contextPressure,permissions) βsrc/plugin/protocol.jsderives the island model β the samesrc/componentsReact tree renders it (demo and plugin share one UI).
In-repo pieces: src/client/ (browser half: index.js, IslandDock.jsx, island-store.js, live-bridge.js, styles.js, locales.js), src/index.js (node half), cordis.patch.yml, src/plugin/protocol.js (protocol adapter). The full blueprint, dev workflow, and honest gaps live in docs/integration.md.
π§± Built with
- React 19 + Vite 8 β plain and fast
- Hand-rolled CSS β every glass panel, orbit, and breathing core is bespoke
- Zero UI frameworks β the point is proving the design, not the stack
πΊοΈ Roadmap
- Eight-state island with Liquid Glass looks (incl. idle / blocked / max-tokens)
- Synchronized approval actions (a mirror of the native input area)
- Streaming output preview (
assistant/chunk, reasoning vs. answer tinted) - Tool-command cards (exit code, duration, copy)
- Result receipts (files, checks, tokens, duration) + recent-wins receipt stack
- Goal progress ring + full task checklist (goal,
todo/write) - Model badge (
request/context, shows the model in use) - βK command palette + auto-play demo
- Integration blueprint + plugin skeleton (repo root is the dual-face client package)
-
build:pluginemits the loader-compliant bundle; smoke-tested (handshake / factory / apply / bridge / verbs) - Real-GUI integration pass (live-bridge on-device check + retry/continue/unblock/approve wired to real remotes) π
π Keep the island in orbit
If this made you smile, hit the β β it's the fuel that turns a design prototype into a real plugin. Issues, ideas, and "why not also support X?" are all welcome.
Built with π«Ά for the DeepSeek Harness community.