dsh-goal-gantt: Visualize long task progress in DSH sessions

Foreword

It is very easy to lose progress when running long tasks: the conversation window scrolls through dozens of rounds, and you only know it is still working, not what chapter it is on, how much is left, or what was produced in each chapter. dsh-goal-gantt is the client plugin that solves this. It breaks a goal into several phases, giving you a phase-level progress dashboard directly at the top of the session: the current phase, four key numbers, a Gantt timeline, and a collapsible phase list. The maintainer is 123David-yang, and the repository is tagged with the dsh-plugin topic, so it can be installed via the plugin market or CLI.

Below, I introduce what it is, how to install it, how to use it, and a few things to note.

I. What is this

One-sentence positioning: It is DeepSeek Harness’s goal phase-level progress dashboard; it does not record the trajectory of individual tool calls.

It answers three questions:

  1. What chapter is this goal currently on?
  2. What was done in each chapter, what was produced, and what remains?
  3. How far away from the goal is it (in phases / rounds / estimated time)?

The dashboard has both Chinese and English interfaces, automatically switching based on system language, or can be forced with ?lang=zh / ?lang=en.

II. Core Features

Three things in one screen. The top is “Goal + Session + Total Progress”. The current phase is dominant as a large title plus a one-sentence summary, along with four key numbers: progress, used, checks, remaining phases. Other metrics are pushed down to the phase list, expanded as needed.

Gantt Timeline. Planned bars use dashed lines, actual bars use solid lines, both displayed overlaid. Scales automatically switch between 15 min / 1 hour / 6 hours / 1 day based on span. Zoom levels have four gears: Focus Now / 6h / 24h / All. “Focus Now” takes a window sized to the duration of the active phase; when approaching the edge, it automatically re-centers, staying within view.

Phases are Reusable. Writing multiple configurations with the same id merges them into one lane, drawing a bar for each segment separately. Suitable for recurring work like “intermittent optimization”.

Hero Current Phase. Automatically locates the active phase, showing the phase name, one-sentence summary, and four key numbers.

Phase List & Grouping. One line per phase. Summary, checks, and deliverables are only visible when expanded. By default, only the active one is expanded. Can filter by All / Active / Incomplete. Search box matches by id, title, summary; pressing / focuses search. Groups are Active / Not Started / Completed; Completed is collapsed by default.

Filtering is Shareable. Filter conditions and search terms are written into the URL (?q=P3&f=active), and “Copy Link” includes them. The “Copy Link” in the top-right corner of Hero can also generate direct addresses like #P3, which opens and locates to that phase and expands it.

Copy Summary & Export CSV. One-click copy current progress to Markdown (status icons + phase list + remaining time), ready to paste into issues or IMs. Phase table can be exported to CSV (id / title / status / progress / planned & actual time / duration / checks / summary) with BOM, ready to open in Excel.

Interaction Details. Clicking a Gantt bar or phase row scrolls to the corresponding phase and highlights it; keyboard Enter/Space works too. Gantt bars and phase rows are focusable via Tab, with aria-label / aria-controls. When scrolling, the pinned progress ring and session selector remain visible. Relative time shows “5 hours ago” / “2h36m done”. Expanded state and grouping state are saved in localStorage.

Theme & Fallback. Light theme follows system prefers-color-scheme and supports prefers-reduced-motion. Contrast between body text and auxiliary text is above 4.5:1.

Stability. When the content signature (hash) doesn’t change, only the time cursor moves; the DOM is not rebuilt. Sessions without a goal show an empty state hint; phases are not fabricated based on conversation rounds. Polling pauses when the tab is hidden. Bad configurations (illegal times, missing id, phases not an array, progress out of bounds) are handled gracefully, preventing NaN or negative width bars.

III. Installation and Activation

Method 1: Plugin Market: The repository has the dsh-plugin topic, so it enters the market index automatically. Search for goal-board in the DSH Web GUI plugin page and install with one click.

Method 2: CLI:

dsh plugin add github:123David-yang/dsh-goal-gantt

Method 3: Manual script, suitable for environments where the market cannot be installed:

# Windows
pwsh -File scripts/install.ps1

The script locates $env:DSH_HOME/profiles/web (or ~/.dsh/profiles/web), copies the plugin into node_modules, and registers cordis.patch.yml.

After installation, restart DSH once. A “Dashboard” tab will appear at the top of the session.

IV. Typical Usage

After installation, there are two entry points. One is the “Dashboard” tab at the top of the session, next to “Chat / Trajectory”. Clicking it displays within the current session, no jump, no new page, and automatically follows when switching sessions. Rendering uses Shadow DOM for style isolation from the host. The other is an independent page:

http://127.0.0.1:3080/goal-gantt

The page pulls /api/goal-gantt automatically every 10 seconds, reflecting phase status changes in real-time.

Phase data is primarily read from goal-board/board.config.json in the workspace:

{
  "title": "GOAL 甘特看板",
  "phases": [
    {
      "id": "P1",
      "title": "数据采集层",
      "desc": "一句话说明这一章干什么",
      "status": "done",                        // done | active | pending | blocked
      "plannedStart": "2026-11-05T00:05:00+08:00",
      "plannedEnd":   "2026-11-05T00:14:00+08:00",
      "startedAt":    "2026-11-05T00:05:40+08:00",
      "endedAt":      "2026-11-05T00:13:30+08:00",
      "summary": "这一章实际做了什么(显示在总结卡上)",
      "checks": [{ "label": "子任务", "done": true }],
      "deliverables": [{ "label": "文件", "path": "relative/or/absolute/path" }]
    }
  ]
}

Configuration defaults to only applying to sessions that are “in the same workspace and currently have a goal”; it can also be precisely bound using sessionId or goalId. When no config file exists, it falls back automatically: first by goal_round rounds, then by conversation rounds. Phase progress equals the completion ratio of checks; when there are no checks, it’s estimated by status (done=100 / active=40 / pending=0).

Reusing phases is simply writing multiple entries with the same id:

{ "id": "P8", "title": "时间轴优化", "status": "done",   "startedAt": "...", "endedAt": "..." },
{ "id": "P9", "title": "文档",       "status": "done",   "startedAt": "...", "endedAt": "..." },
{ "id": "P8", "title": "时间轴优化", "status": "active", "startedAt": "..." }

On the Gantt chart, P8 will be one row with two bars.

V. Sessions without a goal: Conversation as Project

When there is no goal, it’s not just an empty state. The plugin abstracts the conversation itself into a project: segmented by idle intervals (default 20 minutes of silence counts as a new segment). The four numbers change to duration of this segment, number of phases, total span, active duration. Segment titles are taken from the first user message in that segment. Each segment extracts a sentence of “what was accomplished” from the last assistant reply (pure extraction, no model call). Top mark “Auto-generated”, no fake progress percentage. Zero tokens throughout, using only event types and tool names for rule-based judgment, no model calls. Empty state only appears when there are “no events at all”.

VI. Performance, Data Sources, and Privacy

In terms of performance, parsing only uses relevant events (turn/start, tool/call, messages, goal changes). The largest tool/result is filtered by text before entering JSON.parse. Projection cache and logs are cached by mtime + size. Author’s benchmark (node test/perf.test.mjs): 9.5 MB / 20k events session, cold start ~25 ms, hot call < 1 ms, integrated into CI. Groups with over 40 items only render the first 40; the rest are folded into “Show More”.

Data Sources:

Data Location
goal status, rounds, tokens, round outlines $DSH_HOME/storages/session_projcache/sessions/*.json
Precise event timeline (turn / tool / goal changes) $DSH_HOME/sessions/<cwd>/<session>/session.v4.jsonl.zstd

Session logs are zstd concatenations of multiple frames (written one frame at a time). Node’s native zstdDecompressSync only decompresses the first frame. The plugin decompresses frame by frame by magic number 28 B5 2F FD before merging – this section in the README is marked as the most critical compatibility logic.

Privacy: Read-only by default, does not write to sessions or modify existing configs; the only write operation is “Write Example Config” in the empty state, which only creates <workspace>/goal-board/board.config.json, rejecting if the file exists. Runs offline, no network requests, no telemetry. Parsing results are cached in memory for 1 second by mtime. Routes are protected by DSH’s connection.requestRejection trust fence (Host/Origin + Login cookie).

VII. Applicable Scenarios and Notes

Suitable for developers running multi-phase long tasks, needing to sync progress externally, and wanting to view the Gantt directly in DSH without switching to external tools.

A few notes:

  • The plugin runs with the permissions of the current DSH process, able to read workspace and session data it can see. Before installing, open the repo to verify source code and license (MIT) and ensure it meets your security agreements.
  • Compatibility scope is DSH Web profile, @deepseek-ai/dsh 0.2.x, Node.js >= 22 (depends on zlib.zstdDecompressSync; lower versions degrade to read-only projection cache, log events unavailable). Windows / macOS / Linux are supported; Windows is the main development environment.
  • The per-frame zstd decompression of session logs is version-sensitive logic. If DSH log format changes cause missing phase events, this can help locate the issue.
  • It is read-only, fully offline, which is a plus for teams that don’t want to send session content externally.

Short conclusion: If you are already using DSH to run long tasks, the value of this plugin lies in integrating the “phase progress” signal into the session interface, rather than setting up a separate tracking system. It won’t define your goals for you; it simply lays out an existing goal or conversation structure into a readable progress board.

Catalog Page: https://www.skillhub.cn/plugins/123David-yang/dsh-goal-gantt

GitHub: https://github.com/123David-yang/dsh-goal-gantt

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye