@mstar-harness/dsh 3.8.0 → 3.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +142 -194
  3. package/README.zh.md +29 -17
  4. package/bundle/README.md +83 -171
  5. package/dist/client/index.d.ts +17 -8
  6. package/dist/client/panel/MstarPanelTitle.d.ts +13 -0
  7. package/dist/client/panel/PanelView.d.ts +56 -52
  8. package/dist/client/panel/TabNav.d.ts +17 -14
  9. package/dist/client/panel/definition.d.ts +23 -0
  10. package/dist/client/panel/engine-status-client.d.ts +84 -6
  11. package/dist/client/panel/graph/project-graph.d.ts +35 -64
  12. package/dist/client/panel/graph/schema.d.ts +1 -2
  13. package/dist/client/panel/guards.d.ts +41 -1
  14. package/dist/client/panel/locale.d.ts +1 -1
  15. package/dist/client/panel/mstar-glyph.d.ts +22 -0
  16. package/dist/client/panel/pages/AgentListPage.d.ts +71 -0
  17. package/dist/client/panel/pages/EventLogPage.d.ts +7 -4
  18. package/dist/client/panel/pages/IterationInfoSection.d.ts +16 -13
  19. package/dist/client/panel/pages/IterationTaskPage.d.ts +13 -14
  20. package/dist/client/panel/panel-store.d.ts +28 -0
  21. package/dist/client/panel/sidebar.d.ts +13 -7
  22. package/dist/client/panel/state-section.d.ts +25 -3
  23. package/dist/client/panel/use-mstar-engine-status.d.ts +39 -14
  24. package/dist/client/panel/zones/Legend.d.ts +5 -3
  25. package/dist/client/panel/zones/TaskBoard.d.ts +13 -9
  26. package/dist/client.js +1038 -1242
  27. package/dist/engine-status-endpoint.d.ts +85 -8
  28. package/dist/engine-status-store.d.ts +91 -1
  29. package/dist/engine-status-wire.d.ts +9 -0
  30. package/dist/gates/_shared.d.ts +61 -9
  31. package/dist/gates/adapter.d.ts +32 -2
  32. package/dist/gates/agent-flow.d.ts +312 -60
  33. package/dist/gates/catalog.d.ts +59 -38
  34. package/dist/gates/dispatch.d.ts +11 -2
  35. package/dist/gates/goal-bridge.d.ts +10 -130
  36. package/dist/gates/plan-mode-bridge.d.ts +20 -11
  37. package/dist/gates/role-persona.d.ts +16 -0
  38. package/dist/gates/steering.d.ts +41 -0
  39. package/dist/gates/workflow-ledger.d.ts +31 -4
  40. package/dist/gates/workflow-selection.d.ts +41 -20
  41. package/dist/index.js +1208 -394
  42. package/dist/types.d.ts +50 -18
  43. package/harness-commands/amazing-pr-review.md +2 -0
  44. package/harness-commands/codebase-audit.md +2 -0
  45. package/harness-skills/mstar-host/SKILL.md +3 -1
  46. package/harness-skills/mstar-host/references/dsh-workflow-scripts.md +424 -0
  47. package/harness-skills/mstar-host/references/dsh.md +259 -266
  48. package/harness-skills/mstar-roles/references/project-manager.md +2 -0
  49. package/harness-skills/mstar-sdd/SKILL.md +2 -0
  50. package/package.json +66 -64
  51. package/dist/client/panel/pages/AgentCanvasPage.d.ts +0 -345
@@ -104,6 +104,8 @@ In invoke-based hosts (OpenCode / Cursor Task / Codex with callable multi-agent
104
104
 
105
105
  Host invoke/dispatch details: `mstar-host` → active host reference and `references/parallel-dispatch.md`.
106
106
 
107
+ **dsh:** mstar **stops arming** a goal — dsh progress is the native workflow (workflow snapshot phases + dispatch gates + **subagent settle notifications**), never a `/goal` objective or goal round loop. Phase 2 is a PM-local loop (dispatch → wait for the child's settle notification → next dispatch); a dispatched child owning the critical path means **wait**, not a duplicate work unit. Rule → `mstar-host` → `references/dsh.md`.
108
+
107
109
  Dispatch mechanics and templates:
108
110
  `references/project-manager/dispatch-and-assignment.md`.
109
111
 
@@ -94,6 +94,8 @@ Host mapping → **`mstar-host`** references (`model` / Task field).
94
94
  - **Honest non-convergence**: open findings at wave close → list them in detail and state the disposition — re-feed to the next fix round **or** transfer to residual tracking — never silently close.
95
95
  4. QA gate → **`mstar-harness-core`** Done rules; PM **`mstar-roles/references/project-manager/qa-trigger-matrix.md`**
96
96
 
97
+ > **On dsh:** the plan QC tri MAY run through the native **`workflow`** tool instead of three `subagent` dispatches — take the `script` + `meta` (`meta.name: mstar-qc-tri`) from skill **`mstar-host`** → `references/dsh-workflow-scripts.md` (§ `mstar-qc-tri`); the three seats stay read-only and PM persists `{SDD_DIR}/review/qc1.md`…`qc3.md` from their returned envelopes. Per-task implementers stay **serial `subagent`** — the `workflow` channel is read-only fan-out only; when the tool is unmounted (`ptc` preset) dispatch the three seats as background `subagent` calls (skill **`mstar-host`** → `references/dsh.md`).
98
+
97
99
  ## Progress ledger(Evidence)
98
100
 
99
101
  At start: `cat {SDD_DIR}/progress.md`. Tasks marked complete are DONE — do not re-dispatch after compaction.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mstar-harness/dsh",
3
- "version": "3.8.0",
3
+ "version": "3.8.2",
4
4
  "description": "Morning Star harness dsh (DeepSeek Harness) cordis function plugin — in-process engine gates (status/dispatch/lease) with hard refusal channels.",
5
5
  "keywords": [
6
6
  "dsh",
@@ -48,7 +48,8 @@
48
48
  "@deepseek-ai/dsh-client-store",
49
49
  "@deepseek-ai/dsh-client-ui-conversation",
50
50
  "@deepseek-ai/dsh-client-locale",
51
- "@deepseek-ai/dsh-client-connection"
51
+ "@deepseek-ai/dsh-client-connection",
52
+ "@deepseek-ai/dsh-client-ui-sidebar-right"
52
53
  ],
53
54
  "platform": "web"
54
55
  }
@@ -68,67 +69,68 @@
68
69
  },
69
70
  "peerDependencies": {
70
71
  "@deepseek-ai/cordis": "^4.0.2",
71
- "@deepseek-ai/dsh-agent": "^0.1.5-rc.1",
72
- "@deepseek-ai/dsh-agent-default-model": "^0.1.5-rc.1",
73
- "@deepseek-ai/dsh-agent-presets": "^0.1.5-rc.1",
74
- "@deepseek-ai/dsh-api-gateway": "^0.1.5-rc.1",
75
- "@deepseek-ai/dsh-api-remotes": "^0.1.5-rc.1",
76
- "@deepseek-ai/dsh-api-session-controller": "^0.1.5-rc.1",
77
- "@deepseek-ai/dsh-atomic-write": "^0.1.5-rc.1",
78
- "@deepseek-ai/dsh-attachment": "^0.1.5-rc.1",
79
- "@deepseek-ai/dsh-brand": "^0.1.5-rc.1",
80
- "@deepseek-ai/dsh-chunked-list": "^0.1.5-rc.1",
81
- "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.1",
82
- "@deepseek-ai/dsh-client-file-upload": "^0.1.5-rc.1",
83
- "@deepseek-ai/dsh-client-locale": "^0.1.5-rc.1",
84
- "@deepseek-ai/dsh-client-store": "^0.1.5-rc.1",
85
- "@deepseek-ai/dsh-client-ui-chat": "^0.1.5-rc.1",
86
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.1",
87
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-rc.1",
88
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-rc.1",
89
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.5-rc.1",
90
- "@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.5-rc.1",
91
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-rc.1",
92
- "@deepseek-ai/dsh-code-runtime": "^0.1.5-rc.1",
93
- "@deepseek-ai/dsh-commands": "^0.1.5-rc.1",
94
- "@deepseek-ai/dsh-credentials": "^0.1.5-rc.1",
95
- "@deepseek-ai/dsh-deque": "^0.1.5-rc.1",
96
- "@deepseek-ai/dsh-file-reference": "^0.1.5-rc.1",
97
- "@deepseek-ai/dsh-fs": "^0.1.5-rc.1",
98
- "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.1",
99
- "@deepseek-ai/dsh-invariants": "^0.1.5-rc.1",
100
- "@deepseek-ai/dsh-jobs": "^0.1.5-rc.1",
101
- "@deepseek-ai/dsh-llm": "^0.1.5-rc.1",
102
- "@deepseek-ai/dsh-llm-retry": "^0.1.5-rc.1",
103
- "@deepseek-ai/dsh-native-command": "^0.1.5-rc.1",
104
- "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.1",
105
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.1",
106
- "@deepseek-ai/dsh-scope": "^0.1.5-rc.1",
107
- "@deepseek-ai/dsh-session": "^0.1.5-rc.1",
108
- "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.1",
109
- "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.1",
110
- "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-rc.1",
111
- "@deepseek-ai/dsh-session-query": "^0.1.5-rc.1",
112
- "@deepseek-ai/dsh-session-title": "^0.1.5-rc.1",
113
- "@deepseek-ai/dsh-settings": "^0.1.5-rc.1",
114
- "@deepseek-ai/dsh-skill": "^0.1.5-rc.1",
115
- "@deepseek-ai/dsh-skill-filesystem": "^0.1.5-rc.1",
116
- "@deepseek-ai/dsh-storage": "^0.1.5-rc.1",
117
- "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.1",
118
- "@deepseek-ai/dsh-subagent": "^0.1.5-rc.1",
119
- "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.1",
120
- "@deepseek-ai/dsh-timeout": "^0.1.5-rc.1",
121
- "@deepseek-ai/dsh-tool-subagent": "^0.1.5-rc.1",
122
- "@deepseek-ai/dsh-tool-todo": "^0.1.5-rc.1",
123
- "@deepseek-ai/dsh-tools": "^0.1.5-rc.1",
124
- "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.1",
125
- "@deepseek-ai/dsh-typert-registry": "^0.1.5-rc.1",
126
- "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.1",
127
- "@deepseek-ai/dsh-util-crypto": "^0.1.5-rc.1",
128
- "@deepseek-ai/dsh-util-time": "^0.1.5-rc.1",
129
- "@deepseek-ai/dsh-util-values": "^0.1.5-rc.1",
130
- "@deepseek-ai/dsh-util-workspace-path": "^0.1.5-rc.1",
131
- "@deepseek-ai/dsh-workspace": "^0.1.5-rc.1",
72
+ "@deepseek-ai/dsh-agent": "^0.1.5-rc.2",
73
+ "@deepseek-ai/dsh-agent-default-model": "^0.1.5-rc.2",
74
+ "@deepseek-ai/dsh-agent-presets": "^0.1.5-rc.2",
75
+ "@deepseek-ai/dsh-api-gateway": "^0.1.5-rc.2",
76
+ "@deepseek-ai/dsh-api-remotes": "^0.1.5-rc.2",
77
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.5-rc.2",
78
+ "@deepseek-ai/dsh-atomic-write": "^0.1.5-rc.2",
79
+ "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2",
80
+ "@deepseek-ai/dsh-brand": "^0.1.5-rc.2",
81
+ "@deepseek-ai/dsh-chunked-list": "^0.1.5-rc.2",
82
+ "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2",
83
+ "@deepseek-ai/dsh-client-file-upload": "^0.1.5-rc.2",
84
+ "@deepseek-ai/dsh-client-locale": "^0.1.5-rc.2",
85
+ "@deepseek-ai/dsh-client-store": "^0.1.5-rc.2",
86
+ "@deepseek-ai/dsh-client-ui-chat": "^0.1.5-rc.2",
87
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.2",
88
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-rc.2",
89
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-rc.2",
90
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.5-rc.2",
91
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.5-rc.2",
92
+ "@deepseek-ai/dsh-client-ui-sidebar-right": "^0.1.5-rc.2",
93
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-rc.2",
94
+ "@deepseek-ai/dsh-code-runtime": "^0.1.5-rc.2",
95
+ "@deepseek-ai/dsh-commands": "^0.1.5-rc.2",
96
+ "@deepseek-ai/dsh-credentials": "^0.1.5-rc.2",
97
+ "@deepseek-ai/dsh-deque": "^0.1.5-rc.2",
98
+ "@deepseek-ai/dsh-file-reference": "^0.1.5-rc.2",
99
+ "@deepseek-ai/dsh-fs": "^0.1.5-rc.2",
100
+ "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2",
101
+ "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2",
102
+ "@deepseek-ai/dsh-jobs": "^0.1.5-rc.2",
103
+ "@deepseek-ai/dsh-llm": "^0.1.5-rc.2",
104
+ "@deepseek-ai/dsh-llm-retry": "^0.1.5-rc.2",
105
+ "@deepseek-ai/dsh-native-command": "^0.1.5-rc.2",
106
+ "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2",
107
+ "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2",
108
+ "@deepseek-ai/dsh-scope": "^0.1.5-rc.2",
109
+ "@deepseek-ai/dsh-session": "^0.1.5-rc.2",
110
+ "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2",
111
+ "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2",
112
+ "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-rc.2",
113
+ "@deepseek-ai/dsh-session-query": "^0.1.5-rc.2",
114
+ "@deepseek-ai/dsh-session-title": "^0.1.5-rc.2",
115
+ "@deepseek-ai/dsh-settings": "^0.1.5-rc.2",
116
+ "@deepseek-ai/dsh-skill": "^0.1.5-rc.2",
117
+ "@deepseek-ai/dsh-skill-filesystem": "^0.1.5-rc.2",
118
+ "@deepseek-ai/dsh-storage": "^0.1.5-rc.2",
119
+ "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2",
120
+ "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2",
121
+ "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2",
122
+ "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2",
123
+ "@deepseek-ai/dsh-tool-subagent": "^0.1.5-rc.2",
124
+ "@deepseek-ai/dsh-tool-todo": "^0.1.5-rc.2",
125
+ "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
126
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2",
127
+ "@deepseek-ai/dsh-typert-registry": "^0.1.5-rc.2",
128
+ "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.2",
129
+ "@deepseek-ai/dsh-util-crypto": "^0.1.5-rc.2",
130
+ "@deepseek-ai/dsh-util-time": "^0.1.5-rc.2",
131
+ "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2",
132
+ "@deepseek-ai/dsh-util-workspace-path": "^0.1.5-rc.2",
133
+ "@deepseek-ai/dsh-workspace": "^0.1.5-rc.2",
132
134
  "@deepseek-ai/schemastery": "^3.18.1"
133
135
  },
134
136
  "publishConfig": {
@@ -143,7 +145,7 @@
143
145
  "anser": "^2.3.5",
144
146
  "bun-types": "^1.2.17",
145
147
  "clsx": "^2.0.0",
146
- "dsh-llm-fallbacks": "0.4.1",
148
+ "dsh-llm-fallbacks": "0.5.2",
147
149
  "immer": "^10.1.1",
148
150
  "js-yaml": "^4.1.0",
149
151
  "katex": "^0.16.47",
@@ -1,345 +0,0 @@
1
- /**
2
- * AgentCanvasPage (spec panel-tabs §4/§6.2
3
- * — the 代理执行 tab: a DRAGGABLE agent canvas. Replaces the muted
4
- * placeholder page and the stage-column AgentFlowZone
5
- * (deleted by this plan — the free canvas supersedes it).
6
- *
7
- * Canvas contract (spec §6.2 — zero third-party deps):
8
- * - pan ONLY (translate, no zoom / pinch / rotate) via native pointer events
9
- * (pointerdown / pointermove / pointerup + setPointerCapture) on the
10
- * viewport; `touch-action: none` + `preventDefault` on pointerdown stop
11
- * native scroll / text selection; during capture the entity cards never
12
- * receive the pointer (no click-through); no pan bounds (free pan).
13
- * - forced capture loss (window blur / alt-tab / element removal mid-gesture)
14
- * fires `lostpointercapture` without pointerup — it binds the same end
15
- * handler so `dragRef` never goes stale (review S-002).
16
- * - the content layer carries `data-canvas-pan` and exposes the pan state as
17
- * `transform: translate(xpx, ypx)`; the grid background moves WITH the
18
- * content. Pan is instant (no animation), so `prefers-reduced-motion`
19
- * needs no pan-specific handling; the next-edge dash flow and the running
20
- * card pulse are CSS animations killed by the panel root's reduced-motion
21
- * rule (`* { animation: none !important }`).
22
- * - pan state `{ x, y }` is LOCAL useState; the drag math is extracted into
23
- * the exported pure helpers (`panDragStart` / `panDragMove` / `panTransform`)
24
- * so the pointer-event sequence is unit-testable without a DOM.
25
- *
26
- * Entities (spec §4/§6.2): every KNOWN_AGENTS roster member renders a card —
27
- * title = the AGENT NAME (role id, or displayName for idle cards via
28
- * `entity.name`); the session id / task tag are AUXILIARY record fields on
29
- * `data-agent-record` (never the title). Idle (no dispatch evidence) cards
30
- * are muted (`data-agent-idle`); lit cards follow the projection's status
31
- * priority (running/settled/error/denied/advisory). Settled cards get a
32
- * standalone GREEN DONE FRAME + green ✓ (
33
- * `data-agent-done="true"`, the frame is a full-strength success ring on the
34
- * rounded card body) ONLY when `emphasis !== 'off'` — an off-tier role
35
- * (already-passed / stage-less on-demand + general) never shows the
36
- * completion marker (the v3 leak: the ✓ survived the off-tier low
37
- * transparency).
38
- *
39
- * Shared iteration section : the page renders the
40
- * SAME `IterationInfoSection` the tasks tab uses, from the SAME
41
- * `view.iteration` data — 两个 tab 显示同一迭代信息块.
42
- *
43
- * Edges (spec §4 — the
44
- * finalized 2026-08-12 line semantics, design doc §2): ONLY the actual
45
- * handoffs (business entity→entity — role-keyed, general endpoints
46
- * filtered, one edge per pair) and the supervise line (plan
47
- * Task 2 — the static bidirectional
48
- * implementor ↔ sdd-reviewer sub-bucket line inside the `sdd-implement`
49
- * column, dim dashed by default, lit business when the projected
50
- * `evidenced` flag is true — never a fabricated activation) — all drawn as
51
- * SVG bezier `C` paths (design doc §2.6) over the layout computed by the
52
- * exported pure `layoutAgents`. The `expected` stage skeleton and the
53
- * animated `next` edge are REMOVED ( — the column order
54
- * implies the flow, the running card glow + status point carry the
55
- * position). Every line anchors to a CARD PORT (4 fixed edge-midpoint
56
- * ports, design doc §2.5 — hover-visible dots, static-invisible) or the
57
- * supervise side-gap anchors (card right edge + 18px); the arrow tip sits
58
- * at the STANDOFF point 10px off the target port (arrow along the endpoint
59
- * tangent — H1) and no line crosses text (H2: standoff + side-gap routing
60
- * for caption-crossing same-column flows + column-gap crossings). Col-skip
61
- * cross-column edges reroute via a multi-`L` side-gap DETOUR below the
62
- * intermediate card band instead of a direct bezier through the card bodies
63
- * (H1).
64
- *
65
- * Layout : deterministic columns per EXPECTED_ROLE_FLOW stage
66
- * (review-edit-chain → sdd-implement → qc-tri → qa-gate) — FOUR columns
67
- * total (: the standalone rightmost UNKNOWN
68
- * column is REMOVED; `zone: 'general'` entities render in an "unknown /
69
- * 未匹配角色" SUB-PARTITION at the bottom of the LAST column,
70
- * `data-sub-bucket="unknown"`), laid out in TWO SIDE-BY-SIDE PHASE GROUPS
71
- * — the
72
- * Phase 1 group LEFTMOST (review-edit-chain — the sequential Review & Edit
73
- * chain: product-manager → architect → writing-specialist) and the Phase 2
74
- * group to its RIGHT (sdd-implement → qc-tri → qa-gate — the iterative plan
75
- * loop, annotated with the current `activePlanId` from the projected
76
- * `state.plans[]` InProgress rows), top-aligned on ONE label row, each with
77
- * its group label (`data-canvas-group`). The
78
- * `sdd-implement` column is split into sub-buckets by the PROJECTED
79
- * `entity.bucket` (never a render guess): the implementor partition above —
80
- * flow roles in the stage's original order, then the on-demand roles
81
- * (ops-engineer / prompt-engineer, carrying the on-demand badge) — and the
82
- * reviewer partition (code-reviewer, idle included) below, with the
83
- * implementor / sdd-reviewer caption labels. `zone: 'on-demand'` entities
84
- * have NO standalone column anymore — they live in the implementor
85
- * partition. The former "general sinks to the bottom of
86
- * the sdd-implement column" placement is superseded, as is the
87
- * rightmost unknown column; the former
88
- * sdd-implement → general SDD loop back-edge stays REMOVED (the render
89
- * draws no loop branch).
90
- *
91
- * Degradation (spec §8 — never throws / never orange): the projection always
92
- * yields the full idle roster, so the canvas renders it with the muted
93
- * `data-canvas-note` (degraded = ledger missing; empty = no events;
94
- * settle-only = events but no dispatch rows — review T2-Imp-2 restored the
95
- * old zone's distinct settle-only anchor; the empty/settle-only note
96
- * is PROJECTED metadata, never inferred from the entity list). The Legend
97
- * (idle / collaboration swatches) sits BELOW the viewport.
98
- * `initialPan` is a deterministic SSR/test seed — the live page starts at the
99
- * origin.
100
- */
101
- import * as React from 'react';
102
- import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
103
- import type { AgentEdge, ZoneView } from '../graph/project-graph.ts';
104
- import { type PhaseId } from '../graph/schema.ts';
105
- export interface AgentCanvasPageProps {
106
- /** The projected agents zone (spec §6.2 — `ZoneView['agents']`). */
107
- view: ZoneView['agents'];
108
- /** The projected iteration zone (spec §3) — the SHARED iteration info
109
- * block : BOTH the tasks tab and this page render the SAME
110
- * `IterationInfoSection` from the SAME `view.iteration` data. */
111
- iteration: ZoneView['iteration'];
112
- t: TranslateNS<'mstar-panel'>;
113
- /** Deterministic initial pan seed (SSR/tests); the live page starts at the origin. */
114
- initialPan?: PanState;
115
- }
116
- /** Pan state: the content-layer translate (spec §6.2 — free pan, no bounds). */
117
- export interface PanState {
118
- x: number;
119
- y: number;
120
- }
121
- /** A live drag gesture: the pan at pointerdown + the pointer start position. */
122
- export interface PanDrag {
123
- originX: number;
124
- originY: number;
125
- startX: number;
126
- startY: number;
127
- }
128
- export declare const PAN_ORIGIN: PanState;
129
- /** Open a drag gesture: remember the pan at pointerdown and the pointer seat. */
130
- export declare function panDragStart(pan: PanState, x: number, y: number): PanDrag;
131
- /** Follow the pointer: pan = origin + (current − start) — free pan (spec §6.2). */
132
- export declare function panDragMove(drag: PanDrag, x: number, y: number): PanState;
133
- /** The `data-canvas-pan` transform string (spec §6.2 — translate only). */
134
- export declare function panTransform(pan: PanState): string;
135
- /** One positioned box in the canvas coordinate space. */
136
- export interface CanvasBox {
137
- x: number;
138
- y: number;
139
- w: number;
140
- h: number;
141
- }
142
- /** One stage column track (expected/next edge anchors + the column label). */
143
- export interface CanvasColumn extends CanvasBox {
144
- id: string;
145
- }
146
- /**
147
- * One PHASE group of the canvas : the stage columns split into two SIDE-BY-SIDE groups by iteration
148
- * phase — **Phase 1** (review-edit-chain, the sequential Review & Edit
149
- * chain: product-manager → architect → writing-specialist) LEFTMOST,
150
- * **Phase 2** (sdd-implement → qc-tri → qa-gate, the iterative plan loop) to
151
- * its RIGHT — every group label row TOP-ALIGNED at PAD_Y; the Phase-2 row
152
- * additionally annotates the CURRENT PLAN (the projected `activePlanId` —
153
- * the first InProgress `state.plans[]` row, design doc §1.2). Group order =
154
- * first occurrence in the projected stage order (PHASE_IDS-aligned) —
155
- * derived, never literal, so a phase/stage rename can never orphan the
156
- * groups.
157
- */
158
- export interface CanvasGroup {
159
- /** The group's iteration phase id. */
160
- phase: PhaseId;
161
- /** 1-based group ordinal in stage order (Phase 1 = 1, Phase 2 = 2). */
162
- index: number;
163
- /** The group label row seat (canvas coordinates; width = the group's
164
- * content width — the Phase-2 current-plan chip rides the same row). */
165
- label: {
166
- x: number;
167
- y: number;
168
- w: number;
169
- h: number;
170
- };
171
- /** The stage column ids of this group, stage order. */
172
- columnIds: readonly string[];
173
- /** Current-plan annotation host (design doc §1.2 —):
174
- * true for the `autonomous-execute` phase group (the iterative plan loop)
175
- * only. */
176
- planNote: boolean;
177
- }
178
- /** The deterministic canvas geometry: stage columns + per-entity card boxes. */
179
- export interface CanvasLayout {
180
- width: number;
181
- height: number;
182
- columns: readonly CanvasColumn[];
183
- cards: ReadonlyMap<string, CanvasBox>;
184
- /** Sub-bucket geometry per column id (the supervise line anchors to the band edges (the
185
- * inter-partition gap; QC W-001).
186
- * Columns without sub-buckets are absent from the map. */
187
- subBuckets: ReadonlyMap<string, SubBucketGeometry>;
188
- /** The unknown sub-partition at the bottom of the LAST column (plan
189
- * Task 5 —:
190
- * `zone: 'general'` entities sink into a qa-gate-column-bottom sub-partition
191
- * instead of a standalone fifth column). The caption seat + card band;
192
- * null when the layout has no columns (total function — never a throw). */
193
- unknown: UnknownSubPartition | null;
194
- /** The Phase groups (user
195
- * 2026-08-12 feedback #2; plan
196
- * Phase 1 leftmost /
197
- * Phase 2 right, top-aligned, each with its label seat; empty when the
198
- * layout has no columns. */
199
- groups: readonly CanvasGroup[];
200
- }
201
- /** The unknown sub-partition id : `zone: 'general'` entities render in a bottom
202
- * sub-partition of the LAST column titled「unknown / 未匹配角色」and marked
203
- * `data-sub-bucket="unknown"`. The former standalone rightmost UNKNOWN column
204
- * is REMOVED — the constant
205
- * value survives as the sub-partition bucket id. */
206
- export declare const UNKNOWN_COLUMN = "unknown";
207
- /** One sub-bucket partition inside the `sdd-implement` column (plan
208
- * the caption seat + the cards'
209
- * band — the supervise line anchors to the band's edge (implementor:
210
- * bottom edge; reviewer: top edge — the inter-partition gap; QC W-001). */
211
- export interface SubBucketPartition {
212
- /** The caption row's top-left seat (canvas coordinates; width = the card
213
- * row width so the dashed rule fills the row). */
214
- label: {
215
- x: number;
216
- y: number;
217
- w: number;
218
- };
219
- /** The bucket's card bounding band (canvas coordinates); null when the
220
- * partition has no cards (total function — the caption and the supervise
221
- * line skip). */
222
- band: CanvasBox | null;
223
- }
224
- /** The sub-bucket geometry of one column : implementor +
225
- * reviewer partitions. Present ONLY for the `sdd-implement` column — the
226
- * supervise anchors read the bands. */
227
- export interface SubBucketGeometry {
228
- implementor: SubBucketPartition;
229
- reviewer: SubBucketPartition;
230
- }
231
- /** The unknown sub-partition of the LAST column : the caption seat + the general cards' band. The
232
- * caption row (SUB_LABEL_H) sits ROW_GAP below the last flow card; the
233
- * general cards follow SUB_GAP below it. */
234
- export interface UnknownSubPartition {
235
- /** The caption row's top-left seat (canvas coordinates; width = the card
236
- * row width so the dashed rule fills the row). */
237
- label: {
238
- x: number;
239
- y: number;
240
- w: number;
241
- };
242
- /** The unknown partition's card bounding band; null when the partition has
243
- * no general card (total function — the caption renders only with cards). */
244
- band: CanvasBox | null;
245
- }
246
- /**
247
- * Deterministic canvas layout (spec §4
248
- * + Task 8 + plan
249
- * Task 2 — the F5 rework + the
250
- * left-right rework): one column per EXPECTED_ROLE_FLOW stage (view order:
251
- * review-edit-chain → sdd-implement → qc-tri → qa-gate) — FOUR columns
252
- * total, laid out in TWO SIDE-BY-SIDE PHASE GROUPS (the **Phase 1 group
253
- * LEFTMOST** (review-edit-chain — the sequential Review & Edit chain:
254
- * product-manager → architect → writing-specialist) and the **Phase 2 group
255
- * to its RIGHT** (sdd-implement → qc-tri → qa-gate — the iterative plan
256
- * loop, annotated with the current `activePlanId`), every group label row
257
- * TOP-ALIGNED at PAD_Y (design doc §1.2; the standalone rightmost unknown
258
- * column is REMOVED ). The `sdd-implement` column
259
- * is split into sub-buckets by the
260
- * PROJECTED `entity.bucket` (never a render-side guess): the implementor
261
- * partition above — flow roles in the stage's original EXPECTED_ROLE_FLOW
262
- * order, then the on-demand roles (ops-engineer / prompt-engineer — the
263
- * standalone on-demand column is REMOVED) — and the reviewer partition
264
- * (code-reviewer) below, with the implementor / sdd-reviewer caption seats +
265
- * card bands recorded in `subBuckets` (the supervise-line anchors).
266
- * `zone: 'general'` entities (the general bucket — unmatched / anonymous
267
- * dispatches) render in the "unknown / 未匹配角色" SUB-PARTITION at the
268
- * bottom of the LAST column (`layout.unknown` — design doc §1.2: caption row
269
- * ROW_GAP below the last flow card, general cards SUB_GAP below it). The
270
- * column bucket comes from the PROJECTED `entity.zone`: 'flow' → the
271
- * entity's stage column, 'on-demand' → the sdd-implement column's implementor
272
- * partition, 'general' → the last column's unknown partition. Total function —
273
- * every entity gets a box; absent sdd-implement stage → on-demand falls back
274
- * to the LAST column; unknown column ids fall back to the same sink; no
275
- * stages → empty groups/columns; never a throw.
276
- */
277
- export declare function layoutAgents(view: ZoneView['agents']): CanvasLayout;
278
- /** The fixed port points of a card box (design doc §2.5 — 4 edge-midpoint
279
- * ports, no new tokens). */
280
- export type PortId = 'north' | 'south' | 'west' | 'east';
281
- /** One edge's bezier geometry (design doc §2.6): the `d` path + the
282
- * endpoint coordinates (start = the source port, end = the target STANDOFF
283
- * point — the arrow tip lands there, 10px off the card border H1). Null
284
- * when an anchor is missing (total function). */
285
- export interface EdgeGeometry {
286
- /** The SVG path `d` — a single `C` cubic-bezier command for the standard
287
- * curves, or the multi-command `M … L … L … L … L … L …` side-gap detour
288
- * polyline for col-skip cross-column edges . The render
289
- * passes `d` through verbatim; `marker-end orient="auto"` follows the
290
- * FINAL segment, so the arrow always rides the endpoint tangent (H1). */
291
- d: string;
292
- x1: number;
293
- y1: number;
294
- x2: number;
295
- y2: number;
296
- }
297
- /**
298
- * One edge's SVG bezier geometry ; null when an anchor is missing (total
299
- * function).
300
- *
301
- * Port selection (design doc §2.5 — lines connect ports only, never through
302
- * a card): forward (source column < target column) → source EAST → target
303
- * WEST; reverse (source column > target column) → source WEST → target
304
- * EAST; same column → the vertical flow (direction-aware. The
305
- * path END stands off STANDOFF px from the target port along the endpoint
306
- * tangent (arrow tip off the card, H1); the source starts AT its port (no
307
- * arrow there).
308
- *
309
- * Direction-aware vertical endpoints : a same-column
310
- * (or side-gap) flow whose SOURCE sits BELOW the target — the implement →
311
- * review → rework cycle collapses to `code-reviewer → fullstack-dev` (the
312
- * projection pair-dedupe keeps the LATEST direction) — must approach the
313
- * target's SOUTH port, not its north: the arrow tip lands `standoff` below
314
- * the target's bottom edge pointing UP into it. The old code put the tip
315
- * above the target (pointing AWAY) and the center-x line ran through both
316
- * card bodies (H1/H2 violations). Forward (source above) keeps source SOUTH
317
- * → target NORTH. The reverse side-gap detour below is direction-aware by
318
- * construction (it enters the target from its RIGHT side gap and lands 10px
319
- * off the EAST edge, tip pointing LEFT into the card).
320
- *
321
- * Same-column flows whose center-x vertical line would cross a sub-bucket
322
- * CAPTION row (the implementor↔reviewer flow crosses the "sdd-reviewer"
323
- * caption, the qa-gate↔unknown flow crosses the「unknown / 未匹配角色」
324
- * caption) OR another CARD body (a handoff between non-adjacent cards, e.g.
325
- * fullstack-dev → frontend-dev skips the idle fullstack-dev-2 — the
326
- * 2026-08-13 "线穿过卡片" report) route in the column's LEFT side gap instead
327
- * (design doc §2.0 绕行策略 ② — 同列关系线移到卡片列外侧的间隙带): the vertical
328
- * bezier hangs at `card left edge − SIDE_GAP`, clear of every text (H2) and
329
- * every card body (H1).
330
- *
331
- * Inter-phase flows : a Phase 1 → Phase 2 handoff (e.g. writing-specialist →
332
- * fullstack-dev — a real same-plan Review&Edit→implement transfer) is a
333
- * normal FORWARD horizontal bezier (source east → target west) — the groups
334
- * sit side-by-side at one top-aligned y band, so no label row lies between
335
- * the cards. The CARD-AWARE guard : a
336
- * cross-column edge whose columns SKIP an intermediate column (e.g.
337
- * writing-specialist → qc-specialist — a real docs-only / inline / QA-gate
338
- * ledger chain) would run its direct horizontal bezier THROUGH the
339
- * intermediate column's card bodies; when the direct bbox intersects ANY
340
- * card box other than the source/target cards, the edge reroutes via the
341
- * side-gap DETOUR (see `sideGapDetour`) — a polyline below the intermediate
342
- * band, clear of every card (H1) and text seat (H2).
343
- */
344
- export declare function edgePath(edge: AgentEdge, layout: CanvasLayout): EdgeGeometry | null;
345
- export declare function AgentCanvasPage({ view, iteration, t, initialPan }: AgentCanvasPageProps): React.JSX.Element;