# ✦ dsh-constellation **A live, self-organizing constellation map of your DeepSeek Harness plugin universe.** DeepSeek Harness runs on the idea that *everything is a plugin* — but once your profile carries a hundred fibers, nothing tells you what your agent is actually made of. Which fiber is stuck pending? Who provides `llm`? What does `dsh-session-title-first-prompt-llm` even do? Constellation answers all three: a floating ✦ button in the DSH Web UI opens a real-time map of every plugin and service fiber in your running profile — organized into balanced capability domains, labeled in plain language, searchable, and operable. [English](README.md) | [中文](README.zh.md) ![overview](docs/overview-en.png) ## Features ### 🌌 Graph — your plugin universe, at three zoom levels The map starts **collapsed**: one pill per capability domain, sized by member count, with aggregated dependency edges between domains. - **Click a domain** to expand its member plugins in a radial layout around the pill, inside a dashed territory boundary — click again to collapse - **Big domains cluster first**: domains beyond 12 members show service clusters (`llm ×8`) — click a cluster to see just those plugins - **Hover or select a plugin** to reveal its live dependency edges (providers → it → consumers) while the rest of the map dims — the on-demand "internal logic" of your composition - **Search anything**: press `/` and type a plugin name, service, keyword, or domain — results ranked, keyboard-navigable, and clicking one flies the camera to the node with a pulse highlight - Nodes are colored by fiber phase (active / pending / failed / disabled…); the legend doubles as a phase filter ![domain](docs/domain-en.png) ![deps](docs/deps-en.png) ### ✦ AI-native organization Plugin ecosystems grow faster than any hand-written category list. When your profile has an LLM configured, Constellation puts it to work: - **AI taxonomy** — the model proposes a *balanced* capability taxonomy (no 34-member mega-domain, no singleton domains) with bilingual labels, then assigns every plugin and writes it a short human label: `dsh-session-title-first-prompt-llm` becomes *标题生成 / Session title LLM* - **AI descriptions** — plugins whose package ships no description get a one-line summary written by the profile's own model - **One-click re-run** — the ✦ *AI classify* button re-organizes the map whenever your plugin set changes Everything is cached under `$DSH_HOME/storages/` — one classification pass survives restarts. Profiles without an LLM simply fall back to the built-in heuristic classifier; the graph never depends on model access. ### 🗂 Detail drawer — inspect and operate Every plugin opens a side drawer with its label, description, phase, and provided/consumed services, plus **live entry operations**: - **Enable / Disable** — flips the entry through the cordis-plugin-loader tree API and persists to the profile (no restart needed) - **Remove** — stops the entry and removes it from the loader tree (confirmation required) ![detail](docs/detail-en.png) ### 📋 Inventory — every entry at a glance Cards grouped by capability domain: phase, label, description, and services. Click a card for the detail drawer. ### 🩺 Doctor — the plugin physician Automatic diagnostics over the live snapshot (click a finding to inspect): - ⏳ **Stuck pending** — a fiber waiting on a service no active plugin provides (names the missing service) - ❌ **Failed fibers** — plugins that crashed on load - 🧟 **Zombie entries** — enabled entries whose fiber is disposed - ⚠️ **Duplicate providers** — two plugins providing the same service; only the last one wins ### 🌏 Bilingual UI The whole interface speaks **Chinese and English** with a one-click switch — a natural fit for a harness whose plugin names are English but whose users often aren't. ![search](docs/search-en.png) ## Install ```bash dsh plugin --profile web add dsh-constellation ``` Then start the Web UI (`dsh --profile web`) and click the ✦ button in the bottom-right corner. ## How it works ``` ┌─ Browser ──────────────────────────────────────┐ │ client bundle (React, ~90 KB) │ │ body-portal panel · canvas constellation map │ │ polls GET /constellation/graph │ └───────────────────┬────────────────────────────┘ │ same-origin, loopback-fenced ┌───────────────────┴────────────────────────────┐ │ host half (Node) │ │ walks ctx.loader.entries() per request: │ │ fiber.inject keys → consumed services │ │ fiber.store keys → provided services │ │ fiber.state → phase │ │ optional llm sub-fiber: taxonomy + labels │ └────────────────────────────────────────────────┘ ``` The graph projection reads the same runtime records the cordis context proxy consults — no kernel-internal APIs, so it survives minor version drift. Data never leaves localhost: routes reject non-loopback Host headers, and the LLM calls go through the profile's own configured model. ## Requirements - DeepSeek Harness `>= 0.1.0-rc.8` with a Web composition (e.g. the `web` profile) - Node `>= 20` - *(optional)* a configured default model, for the AI taxonomy / labels / descriptions ## Development ```bash npm install npm run build # tsc (types) + tsdown (lib/index.js + lib/client.js) ``` The client bundle follows the official DSH client-bundle preset: a CJS closure factory registered through `window.__ModuleLoader__`, with React / react-dom kept external against the shell's module table. ## License MIT