Skip to content
dsh.fish
Bundle

@sleetdrop/dsh-plugin-topology

Plugin dependency graph inspector for DeepSeek Harness: a host service that snapshots the live Cordis plugin fiber tree, a graph.render tool for the model, and a browser panel that renders the plugin/service topology as a zoomable graph with metrics, legend, and unresolved-dependency table.

Source
sleetdrop
License
MIT
Updated
Updated 2 days ago

Readme

# @sleetdrop/dsh-plugin-topology

Plugin dependency graph inspector for DeepSeek Harness. It snapshots the live
Cordis plugin fiber tree into a plugin/service bipartite graph, derives
graph-theory metrics, and renders it as JSON, Graphviz DOT, or SVG.

One installable bundle ships three surfaces:

- **host service** (`@sleetdrop/dsh-plugin-topology`): a `TypertRemoteService`
  exposing `analyze()` and `render()` over the gateway.
- **host tool** (`@sleetdrop/dsh-plugin-topology/tool`): the model-facing
  `graph.render` tool, registering on `ctx.tools`.
- **browser surface** (`dsh.client`): a global panel reachable from the sidebar
  footer that renders the graph, metrics, legend, unresolved-dependency log, and
  pan/zoom + format downloads.

## Install

```sh
# From the npm registry (prebuilt lib/, no build permission needed):
dsh plugin --profile <name> add @sleetdrop/dsh-plugin-topology

# From a local checkout:
git clone https://github.com/sleetdrop/dsh-plugin-topology.git
cd dsh-plugin-topology && pnpm install && pnpm build
dsh plugin --profile <name> add ./dsh-plugin-topology
```

The bundle patch mounts the host service row and the `graph.render` tool row.
The tool row can live in the profile patch instead — a deployment that prefers
per-session placement may remove it from `cordis.patch.yml` and add it to its
agent preset.

## Model Experience

The `graph.render` tool serializes the running instance's plugin dependency
graph as one document:

- `json` — a NetworkX-compatible node-link graph whose nodes carry graph-theory
  metrics (in/out degree, degree/betweenness/eigenvector centrality, page-rank)
  and whose `graph` object carries global metrics (density, strongly connected
  components, `isDag`, diameter).
- `dot` — Graphviz source for layout via any Graphviz tool.
- `svg` — a Graphviz-rendered SVG, with isolated plugins composed beside the
  main graph.

For `dot` or `svg`, write the returned content to a file with the write tool to
produce a shareable artifact. Use `json` to inspect or analyze the assembly.

## Screenshots

The panel opens maximized by default and renders the live plugin/service
topology as a zoomable Graphviz graph, with metrics, a color legend, and an
unresolved-dependency table. The same panel is localized through the harness
locale dictionaries:

- [Chinese (zh_CN)](docs/screenshots/panel-zh_CN.png)
- [English (en_US)](docs/screenshots/panel-en_US.png)

## Browser panel

The trigger sits in `sidebar.footer.action` (a root-scope list slot, above
Settings), visible with or without a selected session — the topology is
runtime-global and needs no session context. The panel opens maximized by
default (the Graphviz canvas needs the space); the header button restores a
centered window. Same-named plugin instances merge into one node; each node's
label carries the instance creation ordinals in brackets (`timer [1,9,23]`),
assigned at startup and meaningful only within that run.

The client injects `remote` (the gateway ClientRemote service) and self-mounts
its own `pluginTopology` Remote contribution, so it does not require editing
the host assembly's contribution list.

## Compatibility

The plugin uses its **own independent semantic version** — it does not mirror
the DeepSeek Harness version. New plugin features and bugfixes bump the plugin
version on their own schedule, independent of which DSH release it targets.
The table below maps each plugin version to the DSH release it was validated
against, so pick the plugin version whose target DSH matches your harness.

Targets DeepSeek Harness `0.1.2-rc.1`; the `peerDependencies` pin the client
packages and `@deepseek-ai/cordis@^4.0.2` the snapshot reads through. The
0.1.2 rc line removed the old `dsh-client-runtime` browser runtime: the client
now runs on the Cordis `Context` augmented by the shell baseline renderer
(`dsh-client-ui-renderer` → `ctx.slots`), `dsh-client-store` (`defineStore`),
`dsh-client-locale` (`ctx.locale`), and `dsh-api-remotes` (`ctx.remote`).
The service reads Cordis internals (`root.registry`, `root.reflect.store`,
fiber fields) that are not part of the stable public API — verify the installed
harness satisfies the peer ranges before enabling the tool or panel.

DSH itself has no beta channel — it publishes `alpha` then `rc` (its `latest`
dist-tag is stale, follow its `next`). This plugin adapts to stable DSH `rc`
releases only and skips the fast-moving `alpha` line.

| Plugin version (Git + npm) | Targets DSH harness | Notes |
| --- | --- | --- |
| `0.1.0` | `0.1.1-rc.2` | Old `dsh-client-runtime` browser model (frozen). |
| `0.2.0` | `0.1.2-rc.1` | Cordis-Context browser model; client-runtime removed. |

## Known Limitations

- A future Cordis that reshapes the internal registry/reflect surfaces breaks
  `snapshot()`; it does not degrade silently.
- The browser panel requires a web profile (the `--patch` overlay covers only
  the node half).
- Same-named instances merge in the display graph; per-instance identity stays
  available in the JSON export and the complete downloadable DOT.

## Development

```sh
pnpm install
pnpm run build      # tsc (node half) + tsdown (client bundle)
pnpm test           # node:test over compiled specs
pnpm run typecheck  # noEmit check
```

The `dsh.client` browser bundle inlines everything except the shell's frozen
platform-module rows (`react`, `@deepseek-ai/cordis`, `dsh-client-store`, and
`dsh-client-ui-slots`), which every 0.1.2-rc.1 harness shell serves.

See [NEXT-STEPS.md](NEXT-STEPS.md) for planned renderer improvements.

## Publishing

The full end-to-end release checklist (version bump → build/test → commit/tag →
headless + browser smoke → publish) is in [`docs/RELEASING.md`](docs/RELEASING.md).
The final publish requires an interactive OTP, so it is run by hand:

```sh
pnpm publish --access public   # prompts for your OTP
```

`prepublishOnly` runs the build and tests. `publishConfig` pins `access:
public` and the `registry.npmjs.org` target (machine-local pnpm may default to
a read-only mirror). If `npm publish` fails with an `EPERM` from the npm cache
(`root-owned files`), either fix the cache once
(`sudo chown -R $(id -u):$(id -g) ~/.npm`) or publish through pnpm, whose
store avoids the npm cache entirely:

```sh
pnpm publish                    # same prepublishOnly gate, pnpm store
```

`files` ships `lib/`, `cordis.patch.yml`, and `overlay.example.yml`; npm adds
README and LICENSE automatically.

## License

[MIT](LICENSE)

Install

dsh plugin --profile web add github:sleetdrop/dsh-plugin-topology

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source