dsh-at-file
FSMargoo/dsh-at-fileCodex 风格的 `@file` 文件引用,输入框里直接搜索并引用工作区文件。
在会话区新增「图谱」Tab,把单个会话的执行过程渲染为可交互 DAG:轮次、LLM 步骤、工具、技能、子代理、代码改动与测试,支持实时状态、重试聚合、关键路径与轨迹双向联动。
中文 | English
An interactive execution-flow graph for a single task in DeepSeek Harness (DSH): see the whole run at a glance —
task start → Agent / Skill / Tool → subtasks → code changes → tests → success / failure / retries— with live execution status and historical replay.
session.jsonl (zstd); nodes keep their Event IDs and link both ways to the raw trajectory.Restrained information visualization blending four sensibilities:
| Influence | In the product |
|---|---|
| Apple restraint | hairline borders, desaturated palette, soft glows instead of heavy shadows, status = tint + dot |
| Linear density | compact toolbars, tabular numerals, dense detail logs, more per screen |
| Vercel precision | global tabular-nums, uppercase micro-labels, pixel-aligned spacing, elevation only on floating surfaces |
| Live agent feel | pulsing RUNNING nodes with per-second timers, animated dash-flow on active edges, breathing LIVE badge |
The UI is glassmorphic: graph / detail / trajectory sit transparent over your skin wallpaper, exactly like the native Conversation/Trajectory tabs. Every card is tinted by node type (task blue · turn indigo · agent cyan · tool slate · skill violet · subagent amber · plan green · code orange · test sky).
The canvas shows only semantically important nodes, so 500-step sessions stay readable:
N steps · N tools · N tok · ↻retries · ✗failures)×N · M files cardClick any key node and the right-hand panel shows what actually happened:
Ctrl/⌘ + wheel zooms at the cursor (bounded 0.3×–2.2× so it never shrinks unreadably); drag to pan, ⤢ fit-to-width, ⇕ collapse-to-turns overview / expand all, type filters, search, focus node, neighborhood highlightRunning sessions refresh incrementally over SSE:
RUNNING nodes pulse and tick per second (18.2s · running, live)PENDING / RUNNING / SUCCESS / FAILED / SKIPPED / CANCELLED / RETRYINGevent_ids / session_id / task_id / timestamps — always answerable: “which Event is this node?”npm run demo # scripted data (includes a live RUNNING task)
npm run demo -- --real # read your real $DSH_HOME sessions
npm run demo -- --port 8123
Open the printed URL; the graph floats over the page and auto-loads a task.
dsh plugin --profile web add github:KevinZhangNothing/dsh-task-graph
dsh plugin runs pnpm and automatically registers packages declaring dsh.bundle into dsh.profile.bundles (verified). Restart the engine (or reload the Web UI) and a third Graph tab appears beside the native Conversation / Trajectory tabs.
Once published to npm:
dsh plugin --profile web add dsh-task-graph. Also searchable in the plugin marketplace (dshmarket).
The Graph tab renders only inside the content area — tab bar, sidebar and every other entry point stay visible. Click back to Conversation / Trajectory or press Esc to return.
dsh plugin --profile web add link:/path/to/dsh-task-graph
# or manually: pnpm add "dsh-task-graph@link:/path/to/dsh-task-graph" inside the profile dir
The server half needs Node ≥ 22.15 (built-in
zlib.zstdDecompressSyncdecodes.zstdsessions — zero native dependencies).
DSH session.jsonl (zstd, multi-frame)
│ lib/sessions.js frame-by-frame decode + cache + incremental tail
▼
lib/graph.js buildGraph(events) ← pure functions, Node/browser shared
│ nodes[] + edges[] + summary
▼
lib/analytics.js criticalPath / performanceProfile
▼
lib/routes.js createApi(store) ← /task-graph/api/* (tasks/graph/events)
│ + startLiveStream (SSE live tail)
├──────────────┬───────────────────────────┐
▼ ▼ ▼
lib/index.js demo/server.mjs lib/client.js
(mounts HTTP (standalone demo (browser UI: SVG rendering,
routes on the server) layouts, detail panel,
DSH webServer) trajectory linkage)
lib/graph.js / lib/analytics.js are pure modules shared by the server, the demo and the unit tests — one build pipeline everywhere.lib/client.js is dependency-free DOM + SVG; loads via DSH's window.__ModuleLoader__ inside the web UI, or as a plain <script> in the demo page.Read-only GET, prefix /task-graph:
| Route | Description |
|---|---|
/task-graph/api/status | health, version, DSH_HOME |
/task-graph/api/tasks?roots=true&q=&limit= | task (session) list + summary stats |
/task-graph/api/task?id=<workspace>/<dir> | full graph (nodes/edges/summary/critical_path) |
/task-graph/api/events?id=…&from= | compact trajectory events (linkage drawer) |
/task-graph/api/event?id=…&seq= | one full event payload |
/task-graph/api/live?id=… | SSE live tail of new events |
Graphs are uniform (see docs/data-model.md):
{
"task_id": "…",
"nodes": [{ "id": "…", "type": "agent", "status": "SUCCESS", "event_ids": [12, 13], "parent_id": "phase-1", "…": "…" }],
"edges": [{ "source": "…", "target": "…", "type": "calls" }]
}
task / phase / agent / tool / skill / subagent / code / test / planPENDING / RUNNING / SUCCESS / FAILED / SKIPPED / CANCELLED / RETRYINGcontains / depends_on / calls / invokes / delegates / consumes / modifies / validates / produces / retriesnpm test # node:test suite (30 cases)
npm run demo # local preview
Layout:
lib/ index.js server entry · sessions.js decoding · graph.js builder ·
analytics.js analysis · routes.js HTTP API · client.js browser UI
demo/ server.mjs · index.html · sample-events.js (scripted data)
test/ node:test suites + fixtures
docs/ data-model.md · trajectory-events.md · spec.md · images/
MIT