DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

SmileBuild /

SmileBuild/dsh-planchart

Verified

DeepSeek Harness plugin: the agent publishes a project plan as steps in a side panel and a framework diagram in a centre tab, downloadable as SVG or PNG.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@6a2362ef

dsh-planchart

中文

A DeepSeek Harness (dsh) plugin that gives the agent a display surface for project planning. The model calls one tool with the whole plan; the browser renders it in two places:

  • the steps — a panel docked to the right edge of the frame, with phases, status marks and per-step detail;
  • the framework — a "PlanChart" tab beside Chat and Trajectory, holding an auto-laid-out architecture diagram that downloads as SVG or PNG.

Talking to the agent again updates both: every planchart_set call replaces the whole chart, so "mark step 3 done" or "add a cache layer" is an ordinary follow-up message.

The PlanChart tab: the framework diagram in the centre, the steps panel on the right

A framework diagram exported with the PNG button

Install

dsh plugin --profile web add ./dsh-PlanChart

Then restart the profile (dsh web) and hard-reload the browser tab. The plugin declares dsh.bundle.patch, so the installer adds it to the profile's bundle stack automatically; its browser half is discovered through dsh.client and served at /plugins/dsh-planchart/client.js.

The reload is not optional. The client plugin table arrives as window.__DSH_BOOT__, injected into index.html at page load. A tab that was already open when you restarted keeps its old manifest and will never fetch the new bundle — the tools run, the chart is stored, and the browser shows nothing. This is true of every dsh client plugin, not just this one.

To remove it: dsh plugin --profile web remove dsh-planchart.

Tools

Tool What it does
planchart_set Publish the whole chart: title, optional summary, steps[], and a framework graph. Replaces the previous chart wholesale.
planchart_get Read back the chart currently displayed, as text — for revising a chart the model no longer has in context.

There is also a /planchart slash command that prints the current chart.

Step shape

{ "id": "…",            // optional; derived from the title when omitted
  "title": "Build recipe CRUD",
  "status": "pending",  // pending | active | done | blocked
  "detail": "create, edit, publish",   // optional
  "phase": "Build" }                   // optional; consecutive steps group under it

Framework shape

{ "direction": "TB",                       // TB (default) or LR
  "groups": [{ "id": "…", "label": "Client" }],
  "nodes":  [{ "id": "…", "label": "Web app", "kind": "entry",
               "note": "React + Vite", "group": "client" }],
  "edges":  [{ "from": "web-app", "to": "api-gateway",
               "label": "HTTPS", "dashed": false }] }

kind is an accent only: default, entry, core, store, external, output. Ids may be omitted everywhere — one is derived from the label (CJK labels keep their characters), which is what edges then reference.

Layout

Two modes, chosen from the data:

  • Bands — when every node names a declared group, the groups become the rows (or columns under LR) and each is drawn as a labelled band. This is the natural reading of a layered architecture.
  • Layered DAG — otherwise the edges decide the ranks (longest path), ordered by one barycenter sweep.

Both then run the same priority placement so a child sits under its parents rather than under the middle of its row, and edges between siblings in one rank duck through a reserved lane below it instead of cutting across the boxes.

How the chart reaches the browser

The chart rides tool/result.meta — the documented tool-private, replayable payload channel — and a planchart session projection folds it back out:

planchart_set.execute → output.presentationMeta → tool/result.meta (durable log)
                                                          ↓
                                        projection `planchart` (apply/view)
                                                          ↓
                                  session/projection push frame → useProjection

Why not a session event of its own. An out-of-repo event type is absent from this build's KNOWN_SESSION_EVENT_TYPES, and Session.append offers no way to mark an event ignorable. Writing planchart/write would therefore make every session that used the plugin permanently unloadable after a restart — the persistence read path refuses a log containing an unknown, non-ignorable type. Riding meta on an ordinary tool/result adds no vocabulary at all, and replays identically.

Consequences worth knowing:

  • The chart survives restart, resume and fork, because it is derived from the log.
  • Unlike the todo list it is not cleared by the next turn: a published chart is the standing shape of the project.
  • presentationMeta is computed for top-level calls only, so a chart published from inside a subagent does not reach the panels.

Both halves

  • Host (lib/index.js) — the two tools, the projection unit, the system prompt section, the /planchart command. Optional seams (sessionProjections, systemPrompt, commands) are taken through ctx.inject, so a headless composition without them still gets the tools.
  • Browser (lib/client.js) — hand-authored in the lazy-CJS bundle form the client module loader expects (window.__ModuleLoader__.load({ id, factory })), so there is no build step. It registers into conversation.view (the tab) and shell.overlay (the steps panel).

The diagram is drawn with presentational attributes and literal colours — no CSS classes, no var(--dsw-*) — so serializing the live <svg> yields a file that renders standalone once downloaded. It follows the app's light/dark theme by watching data-ds-dark-theme on <body>.

Why the steps panel floats

ui-layout offers four root seats: sidebar, conversation, details and shell.overlay. The right-hand details column is a single slot already occupied by ui-conversation's DetailsPanel, and registering there would replace it and take the tool-details seat with it. shell.overlay is the documented additive seat for a frame-wide surface, so the steps panel lives there: docked right, collapsible to an edge tab, and remembered in localStorage. Being root-scoped it gets no useProjection, so it reads the same per-key observable through ctx.sessions.binding(id).session.projections.faceOf('planchart').

Config

- insert:
    - id: planchart
      name: dsh-planchart
      config:
        promptSection: true   # false keeps the tools but stops advertising them

Tests

npm test                     # host half: registration, the durable round trip, validation
node test/render-preview.mjs # renders the browser half with real React → test/preview.{html,svg}

render-preview.mjs loads lib/client.js through a stub of the client module loader and server-renders both seats, asserting that every node and edge is drawn and that no box escapes the canvas.

Limitations

  • Charts are per session; there is no cross-session library.
  • The steps panel floats over the conversation rather than shrinking it (see above); collapse it to the edge tab when it is in the way.
  • Diagram layout is deterministic but not optimal — heavy graphs (dozens of nodes with many cross-rank edges) will still cross.
  • Caps: 60 steps, 80 nodes, 200 edges, 12 groups. Oversized input is rejected loudly rather than truncated.

中文说明

dsh-planchart 给 agent 增加一块项目规划的展示面板。模型用一个工具发送完整的 规划,浏览器分两处渲染:

  • 步骤 —— 停靠在窗口右侧的面板,带阶段分组、状态标记和每步说明;
  • 框架 —— Chat / Trajectory 旁边的 "PlanChart" 标签页,自动排版的架构图,可以 下载 SVG 或 PNG。

继续对话即可修改:每次 planchart_set 都整体替换当前的图,所以"把第三步标记完成" 或"加一层缓存"就是一句普通的后续消息。

安装

dsh plugin --profile web add ./dsh-PlanChart

然后重启 profile(dsh web),并且硬刷新浏览器页面。插件声明了 dsh.bundle.patch,安装器会自动把它加入 profile 的 bundle 列表;浏览器半边通过 dsh.client 被发现,served 在 /plugins/dsh-planchart/client.js。

刷新这一步不能省。客户端插件表是 window.__DSH_BOOT__,在页面加载时注入 index.html。重启前就开着的标签页会一直用旧的清单,永远不会去取新 bundle —— 结果是工具照常执行、图也存下来了,但界面上什么都不显示。这对所有 dsh 客户端 插件都成立,不只是这个插件。

卸载:dsh plugin --profile web remove dsh-planchart。

工具

  • planchart_set —— 发布整张图:title、可选 summary、steps[]、framework 图。
  • planchart_get —— 把当前显示的图读回成文本,供模型在上下文丢失后再修改。
  • /planchart —— 斜杠命令,打印当前的图。

节点和步骤的 id 都可以省略,会从标题/标签推导(中文标签保留原字符),边再引用它。

数据怎么到浏览器

图挂在 tool/result.meta(工具私有、可重放的载荷通道)上,由 planchart session projection 折叠出来,再通过 session/projection 推给浏览器。

为什么不自定义 session 事件类型:本次构建的 KNOWN_SESSION_EVENT_TYPES 不包含 仓库外的事件类型,而 Session.append 没有提供把事件标记为 ignorable 的入口。写入 planchart/write 会让用过该插件的每个 session 在重启后永久无法加载——持久化读取 路径会拒绝含有未知且非 ignorable 类型的日志。挂在普通 tool/result 的 meta 上不 新增任何事件词汇,重放结果完全一致。

因此:图能跨重启、resume 和 fork 保留;与 todo 列表不同,它不会在下一轮被清空; presentationMeta 只对顶层调用计算,所以子 agent 里发布的图不会出现在面板上。

已知限制

  • 图按 session 保存,没有跨 session 的图库。
  • 步骤面板浮在对话之上,不会挤压中间栏;挡路时可以折叠成右侧边缘的小标签。
  • 排版是确定性的但不是最优的,节点很多且跨层边很密时仍会有交叉。
  • 上限:60 步、80 节点、200 条边、12 个分组,超出会直接报错而不是截断。
—/ 5

No ratings yet

Verified DSH bundle

Commit 6a2362ef392c

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout