@jaimevalasek/aioson 1.4.0 → 1.5.1

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 (199) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/LICENSE +661 -21
  3. package/README.md +3 -1
  4. package/docs/en/squad-dashboard.md +372 -0
  5. package/docs/openclaw-bridge.md +308 -0
  6. package/docs/pt/agentes.md +124 -10
  7. package/docs/pt/cenarios.md +46 -2
  8. package/docs/pt/comandos-cli.md +60 -1
  9. package/docs/pt/inicio-rapido.md +18 -2
  10. package/docs/pt/squad-dashboard.md +373 -0
  11. package/docs/testing/genome-2.0-matrix.md +5 -5
  12. package/docs/testing/genome-2.0-rollout.md +9 -9
  13. package/package.json +2 -2
  14. package/src/backup-local.js +74 -0
  15. package/src/cli.js +98 -0
  16. package/src/commands/backup-local-cmd.js +25 -0
  17. package/src/commands/runtime.js +242 -0
  18. package/src/commands/setup-context.js +7 -2
  19. package/src/commands/squad-daemon.js +209 -0
  20. package/src/commands/squad-dashboard.js +39 -0
  21. package/src/commands/squad-deploy.js +64 -0
  22. package/src/commands/squad-doctor.js +52 -0
  23. package/src/commands/squad-mcp.js +270 -0
  24. package/src/commands/squad-processes.js +56 -0
  25. package/src/commands/squad-recovery.js +42 -0
  26. package/src/commands/squad-roi.js +291 -0
  27. package/src/commands/squad-score.js +250 -0
  28. package/src/commands/squad-status.js +37 -1
  29. package/src/commands/squad-validate.js +62 -1
  30. package/src/commands/squad-webhook.js +160 -0
  31. package/src/commands/squad-worker.js +191 -0
  32. package/src/commands/squad-worktrees.js +75 -0
  33. package/src/commands/web-map.js +70 -0
  34. package/src/commands/web-scrape.js +71 -0
  35. package/src/constants.js +8 -0
  36. package/src/context-writer.js +45 -1
  37. package/src/i18n/messages/en.js +127 -1
  38. package/src/i18n/messages/es.js +117 -0
  39. package/src/i18n/messages/fr.js +117 -0
  40. package/src/i18n/messages/pt-BR.js +126 -1
  41. package/src/lib/webhook-server.js +328 -0
  42. package/src/mcp-connectors/registry.js +602 -0
  43. package/src/runtime-store.js +259 -2
  44. package/src/squad/external-session.js +180 -0
  45. package/src/squad/inter-squad.js +74 -0
  46. package/src/squad/recovery-context.js +201 -0
  47. package/src/squad/worktree-manager.js +114 -0
  48. package/src/squad-daemon.js +490 -0
  49. package/src/squad-dashboard/api.js +223 -0
  50. package/src/squad-dashboard/attachment-handler.js +93 -0
  51. package/src/squad-dashboard/context-monitor.js +157 -0
  52. package/src/squad-dashboard/execution-logs.js +115 -0
  53. package/src/squad-dashboard/hunk-review.js +209 -0
  54. package/src/squad-dashboard/metrics.js +133 -0
  55. package/src/squad-dashboard/process-monitor.js +125 -0
  56. package/src/squad-dashboard/renderer.js +858 -0
  57. package/src/squad-dashboard/server.js +232 -0
  58. package/src/squad-dashboard/styles.js +525 -0
  59. package/src/squad-dashboard/token-tracker.js +99 -0
  60. package/src/web.js +284 -0
  61. package/src/worker-runner.js +339 -0
  62. package/template/.aioson/agents/analyst.md +4 -0
  63. package/template/.aioson/agents/architect.md +4 -0
  64. package/template/.aioson/agents/dev.md +120 -11
  65. package/template/.aioson/agents/deyvin.md +8 -0
  66. package/template/.aioson/agents/neo.md +152 -0
  67. package/template/.aioson/agents/orache.md +17 -0
  68. package/template/.aioson/agents/orchestrator.md +26 -0
  69. package/template/.aioson/agents/product.md +60 -12
  70. package/template/.aioson/agents/qa.md +1 -0
  71. package/template/.aioson/agents/setup.md +63 -19
  72. package/template/.aioson/agents/sheldon.md +603 -0
  73. package/template/.aioson/agents/squad.md +191 -0
  74. package/template/.aioson/agents/tester.md +254 -0
  75. package/template/.aioson/agents/ux-ui.md +12 -0
  76. package/template/.aioson/config.md +6 -0
  77. package/template/.aioson/locales/en/agents/analyst.md +8 -0
  78. package/template/.aioson/locales/en/agents/architect.md +8 -0
  79. package/template/.aioson/locales/en/agents/dev.md +66 -7
  80. package/template/.aioson/locales/en/agents/deyvin.md +8 -0
  81. package/template/.aioson/locales/en/agents/neo.md +8 -0
  82. package/template/.aioson/locales/en/agents/orchestrator.md +26 -0
  83. package/template/.aioson/locales/en/agents/qa.md +49 -0
  84. package/template/.aioson/locales/en/agents/setup.md +2 -1
  85. package/template/.aioson/locales/en/agents/sheldon.md +340 -0
  86. package/template/.aioson/locales/en/agents/ux-ui.md +8 -0
  87. package/template/.aioson/locales/es/agents/analyst.md +8 -0
  88. package/template/.aioson/locales/es/agents/architect.md +8 -0
  89. package/template/.aioson/locales/es/agents/dev.md +66 -7
  90. package/template/.aioson/locales/es/agents/deyvin.md +8 -0
  91. package/template/.aioson/locales/es/agents/neo.md +48 -0
  92. package/template/.aioson/locales/es/agents/orchestrator.md +26 -0
  93. package/template/.aioson/locales/es/agents/qa.md +26 -0
  94. package/template/.aioson/locales/es/agents/setup.md +2 -1
  95. package/template/.aioson/locales/es/agents/sheldon.md +192 -0
  96. package/template/.aioson/locales/es/agents/squad.md +63 -0
  97. package/template/.aioson/locales/es/agents/ux-ui.md +8 -0
  98. package/template/.aioson/locales/fr/agents/analyst.md +8 -0
  99. package/template/.aioson/locales/fr/agents/architect.md +8 -0
  100. package/template/.aioson/locales/fr/agents/dev.md +66 -7
  101. package/template/.aioson/locales/fr/agents/deyvin.md +8 -0
  102. package/template/.aioson/locales/fr/agents/neo.md +48 -0
  103. package/template/.aioson/locales/fr/agents/orchestrator.md +26 -0
  104. package/template/.aioson/locales/fr/agents/qa.md +26 -0
  105. package/template/.aioson/locales/fr/agents/setup.md +2 -1
  106. package/template/.aioson/locales/fr/agents/sheldon.md +192 -0
  107. package/template/.aioson/locales/fr/agents/squad.md +63 -0
  108. package/template/.aioson/locales/fr/agents/ux-ui.md +8 -0
  109. package/template/.aioson/locales/pt-BR/agents/analyst.md +19 -0
  110. package/template/.aioson/locales/pt-BR/agents/architect.md +19 -0
  111. package/template/.aioson/locales/pt-BR/agents/dev.md +75 -12
  112. package/template/.aioson/locales/pt-BR/agents/deyvin.md +8 -0
  113. package/template/.aioson/locales/pt-BR/agents/neo.md +147 -0
  114. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +26 -0
  115. package/template/.aioson/locales/pt-BR/agents/product.md +8 -3
  116. package/template/.aioson/locales/pt-BR/agents/qa.md +60 -0
  117. package/template/.aioson/locales/pt-BR/agents/setup.md +2 -1
  118. package/template/.aioson/locales/pt-BR/agents/sheldon.md +192 -0
  119. package/template/.aioson/locales/pt-BR/agents/squad.md +105 -0
  120. package/template/.aioson/locales/pt-BR/agents/ux-ui.md +8 -0
  121. package/template/.aioson/schemas/squad-blueprint.schema.json +21 -0
  122. package/template/.aioson/schemas/squad-manifest.schema.json +178 -1
  123. package/template/.aioson/skills/design/bold-editorial-ui/SKILL.md +205 -0
  124. package/template/.aioson/skills/design/bold-editorial-ui/references/art-direction.md +338 -0
  125. package/template/.aioson/skills/design/bold-editorial-ui/references/components.md +977 -0
  126. package/template/.aioson/skills/design/bold-editorial-ui/references/dashboards.md +218 -0
  127. package/template/.aioson/skills/design/bold-editorial-ui/references/design-tokens.md +326 -0
  128. package/template/.aioson/skills/design/bold-editorial-ui/references/motion.md +461 -0
  129. package/template/.aioson/skills/design/bold-editorial-ui/references/patterns.md +293 -0
  130. package/template/.aioson/skills/design/bold-editorial-ui/references/websites.md +352 -0
  131. package/template/.aioson/skills/design/clean-saas-ui/SKILL.md +210 -0
  132. package/template/.aioson/skills/design/clean-saas-ui/references/art-direction.md +319 -0
  133. package/template/.aioson/skills/design/clean-saas-ui/references/components.md +365 -0
  134. package/template/.aioson/skills/design/clean-saas-ui/references/dashboards.md +196 -0
  135. package/template/.aioson/skills/design/clean-saas-ui/references/design-tokens.md +244 -0
  136. package/template/.aioson/skills/design/clean-saas-ui/references/motion.md +235 -0
  137. package/template/.aioson/skills/design/clean-saas-ui/references/patterns.md +215 -0
  138. package/template/.aioson/skills/design/clean-saas-ui/references/websites.md +295 -0
  139. package/template/.aioson/skills/design/cognitive-core-ui/SKILL.md +55 -9
  140. package/template/.aioson/skills/design/cognitive-core-ui/references/art-direction.md +339 -0
  141. package/template/.aioson/skills/design/cognitive-core-ui/references/components.md +1 -1
  142. package/template/.aioson/skills/design/cognitive-core-ui/references/dashboards.md +100 -0
  143. package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +43 -9
  144. package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +40 -0
  145. package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +1 -1
  146. package/template/.aioson/skills/design/cognitive-core-ui/references/websites.md +99 -12
  147. package/template/.aioson/skills/design/warm-craft-ui/SKILL.md +209 -0
  148. package/template/.aioson/skills/design/warm-craft-ui/references/art-direction.md +324 -0
  149. package/template/.aioson/skills/design/warm-craft-ui/references/components.md +508 -0
  150. package/template/.aioson/skills/design/warm-craft-ui/references/dashboards.md +223 -0
  151. package/template/.aioson/skills/design/warm-craft-ui/references/design-tokens.md +374 -0
  152. package/template/.aioson/skills/design/warm-craft-ui/references/motion.md +356 -0
  153. package/template/.aioson/skills/design/warm-craft-ui/references/patterns.md +288 -0
  154. package/template/.aioson/skills/design/warm-craft-ui/references/websites.md +289 -0
  155. package/template/.aioson/skills/premium-visual-design/SKILL.md +83 -0
  156. package/template/.aioson/skills/premium-visual-design/components/agent-badge.md +92 -0
  157. package/template/.aioson/skills/premium-visual-design/components/dependency-node.md +102 -0
  158. package/template/.aioson/skills/premium-visual-design/components/mention-autocomplete.md +136 -0
  159. package/template/.aioson/skills/premium-visual-design/components/notification-center.md +136 -0
  160. package/template/.aioson/skills/premium-visual-design/components/review-action-bar.md +188 -0
  161. package/template/.aioson/skills/premium-visual-design/components/team-switcher.md +131 -0
  162. package/template/.aioson/skills/premium-visual-design/patterns/agent-message-thread.md +198 -0
  163. package/template/.aioson/skills/premium-visual-design/patterns/notification-panel.md +275 -0
  164. package/template/.aioson/skills/premium-visual-design/patterns/review-workflow-ui.md +234 -0
  165. package/template/.aioson/skills/premium-visual-design/patterns/task-dependency-graph.md +147 -0
  166. package/template/.aioson/skills/premium-visual-design/tokens/status-extended.md +142 -0
  167. package/template/.aioson/skills/squad/formats/catalog.json +15 -0
  168. package/template/.aioson/skills/squad/formats/content/blog-post.md +47 -0
  169. package/template/.aioson/skills/squad/formats/content/newsletter.md +47 -0
  170. package/template/.aioson/skills/squad/formats/creative/podcast-script.md +43 -0
  171. package/template/.aioson/skills/squad/formats/creative/video-script.md +41 -0
  172. package/template/.aioson/skills/squad/formats/social/instagram-feed.md +42 -0
  173. package/template/.aioson/skills/squad/formats/social/linkedin-post.md +42 -0
  174. package/template/.aioson/skills/squad/formats/social/tiktok.md +39 -0
  175. package/template/.aioson/skills/squad/formats/social/twitter-thread.md +39 -0
  176. package/template/.aioson/skills/squad/formats/social/youtube-long.md +47 -0
  177. package/template/.aioson/skills/squad/formats/social/youtube-shorts.md +39 -0
  178. package/template/.aioson/skills/squad/patterns/multi-platform-pattern.md +108 -0
  179. package/template/.aioson/skills/squad/patterns/persona-based-pattern.md +98 -0
  180. package/template/.aioson/skills/squad/patterns/pipeline-pattern.md +106 -0
  181. package/template/.aioson/skills/squad/patterns/review-loop-pattern.md +81 -0
  182. package/template/.aioson/skills/squad/references/checklist-templates.md +122 -0
  183. package/template/.aioson/skills/squad/references/executor-archetypes.md +123 -0
  184. package/template/.aioson/skills/squad/references/workflow-templates.md +169 -0
  185. package/template/.aioson/skills/static/debugging-protocol.md +42 -0
  186. package/template/.aioson/skills/static/git-worktrees.md +36 -0
  187. package/template/.aioson/tasks/implementation-plan.md +19 -0
  188. package/template/.aioson/tasks/squad-design.md +28 -0
  189. package/template/.aioson/tasks/squad-profile.md +48 -0
  190. package/template/.aioson/tasks/squad-review.md +61 -0
  191. package/template/.aioson/tasks/squad-task-decompose.md +66 -0
  192. package/template/.claude/commands/aioson/agent/neo.md +5 -0
  193. package/template/.claude/commands/aioson/agent/tester.md +5 -0
  194. package/template/.gemini/GEMINI.md +1 -0
  195. package/template/.gemini/commands/aios-neo.toml +4 -0
  196. package/template/.gemini/commands/aios-tester.toml +6 -0
  197. package/template/AGENTS.md +3 -0
  198. package/template/CLAUDE.md +5 -2
  199. package/template/OPENCODE.md +2 -0
@@ -0,0 +1,275 @@
1
+ # Notification Panel Pattern
2
+
3
+ Full notification list with filter tabs, grouping by squad, and mark-all-read. Used inside the notification-center component's dropdown.
4
+
5
+ ## Anatomy
6
+
7
+ ```
8
+ ┌─ Notifications ─────────────────── [Mark all read] ┐
9
+ │ [All] [Unread ③] [Mentions] [Errors] │
10
+ ├─────────────────────────────────────────────────────┤
11
+ │ ● merge_conflict alpha-squad/dev 2m ago ● │ ← unread dot
12
+ │ Branch aioson/alpha/writer has conflicts │
13
+ ├─────────────────────────────────────────────────────┤
14
+ │ ✓ task_completed bravo-squad/planner 5m ago │
15
+ │ PRD v2 delivered to output port │
16
+ ├─────────────────────────────────────────────────────┤
17
+ │ ⚠ context_warning alpha-squad/writer 8m ago ● │
18
+ │ Context window at 87% — approaching limit │
19
+ └─────────────────────────────────────────────────────┘
20
+ ```
21
+
22
+ ## HTML Structure
23
+
24
+ ```html
25
+ <div class="notif-panel">
26
+
27
+ <!-- Header -->
28
+ <div class="notif-header">
29
+ <span class="notif-title">Notifications</span>
30
+ <button class="notif-mark-all">Mark all read</button>
31
+ </div>
32
+
33
+ <!-- Filter tabs -->
34
+ <div class="notif-filters">
35
+ <button class="notif-filter active">All</button>
36
+ <button class="notif-filter">
37
+ Unread <span class="notif-filter-badge">3</span>
38
+ </button>
39
+ <button class="notif-filter">Mentions</button>
40
+ <button class="notif-filter">Errors</button>
41
+ </div>
42
+
43
+ <!-- Notification list -->
44
+ <div class="notif-list">
45
+
46
+ <!-- Unread item -->
47
+ <div class="notif-item unread" data-id="n1" data-type="merge_conflict">
48
+ <div class="notif-type-dot" style="background:#c084fc" title="merge_conflict"></div>
49
+ <div class="notif-body">
50
+ <div class="notif-meta">merge_conflict &nbsp;·&nbsp; alpha-squad/dev</div>
51
+ <div class="notif-summary">Branch aioson/alpha/writer has conflicts</div>
52
+ </div>
53
+ <div class="notif-right">
54
+ <span class="notif-time">2m ago</span>
55
+ <span class="notif-unread-dot"></span>
56
+ </div>
57
+ </div>
58
+
59
+ <!-- Read item -->
60
+ <div class="notif-item" data-id="n2" data-type="task_completed">
61
+ <div class="notif-type-dot" style="background:#4ade80" title="task_completed"></div>
62
+ <div class="notif-body">
63
+ <div class="notif-meta">task_completed &nbsp;·&nbsp; bravo-squad/planner</div>
64
+ <div class="notif-summary">PRD v2 delivered to output port</div>
65
+ </div>
66
+ <div class="notif-right">
67
+ <span class="notif-time">5m ago</span>
68
+ </div>
69
+ </div>
70
+
71
+ <!-- Squad group (when > 5 items from same squad) -->
72
+ <div class="notif-group">
73
+ <div class="notif-group-header" data-group="gamma-squad">
74
+ <span class="notif-group-name">gamma-squad</span>
75
+ <span class="notif-group-count">6 notifications</span>
76
+ <button class="notif-group-toggle">▼</button>
77
+ </div>
78
+ <div class="notif-group-items">
79
+ <!-- items... -->
80
+ </div>
81
+ </div>
82
+
83
+ </div>
84
+
85
+ <!-- Empty state -->
86
+ <div class="notif-empty" hidden>
87
+ <div class="notif-empty-icon">🔔</div>
88
+ <div>No notifications</div>
89
+ </div>
90
+
91
+ </div>
92
+ ```
93
+
94
+ ## CSS
95
+
96
+ ```css
97
+ .notif-panel {
98
+ background: var(--bg-card);
99
+ border: 1px solid var(--border);
100
+ border-radius: 8px;
101
+ width: 380px;
102
+ max-height: 480px;
103
+ display: flex;
104
+ flex-direction: column;
105
+ overflow: hidden;
106
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
107
+ }
108
+
109
+ .notif-header {
110
+ display: flex;
111
+ justify-content: space-between;
112
+ align-items: center;
113
+ padding: 12px 16px;
114
+ border-bottom: 1px solid var(--border);
115
+ flex-shrink: 0;
116
+ }
117
+
118
+ .notif-title { font-size: 13px; font-weight: 600; }
119
+
120
+ .notif-mark-all {
121
+ font-size: 11px;
122
+ color: var(--accent);
123
+ background: none;
124
+ border: none;
125
+ cursor: pointer;
126
+ }
127
+
128
+ .notif-mark-all:hover { text-decoration: underline; }
129
+
130
+ /* Filter tabs */
131
+ .notif-filters {
132
+ display: flex;
133
+ gap: 4px;
134
+ padding: 8px 12px;
135
+ border-bottom: 1px solid var(--border);
136
+ flex-shrink: 0;
137
+ flex-wrap: wrap;
138
+ }
139
+
140
+ .notif-filter {
141
+ padding: 3px 10px;
142
+ border-radius: 12px;
143
+ font-size: 11px;
144
+ cursor: pointer;
145
+ background: none;
146
+ border: 1px solid transparent;
147
+ color: var(--text-muted);
148
+ transition: all 0.12s;
149
+ display: flex;
150
+ align-items: center;
151
+ gap: 4px;
152
+ }
153
+
154
+ .notif-filter:hover { color: var(--text); border-color: var(--border); }
155
+
156
+ .notif-filter.active {
157
+ background: var(--accent-dim);
158
+ color: var(--accent);
159
+ border-color: var(--accent);
160
+ }
161
+
162
+ .notif-filter-badge {
163
+ background: var(--accent);
164
+ color: #fff;
165
+ border-radius: 8px;
166
+ font-size: 9px;
167
+ padding: 0 5px;
168
+ font-weight: 700;
169
+ line-height: 14px;
170
+ }
171
+
172
+ /* Notification list */
173
+ .notif-list {
174
+ overflow-y: auto;
175
+ flex: 1;
176
+ }
177
+
178
+ .notif-item {
179
+ display: flex;
180
+ gap: 10px;
181
+ padding: 10px 16px;
182
+ border-bottom: 1px solid var(--border);
183
+ cursor: pointer;
184
+ transition: background 0.12s;
185
+ align-items: flex-start;
186
+ }
187
+
188
+ .notif-item:hover { background: var(--bg-hover); }
189
+ .notif-item:last-child { border-bottom: none; }
190
+
191
+ .notif-type-dot {
192
+ width: 8px;
193
+ height: 8px;
194
+ border-radius: 50%;
195
+ flex-shrink: 0;
196
+ margin-top: 4px;
197
+ }
198
+
199
+ .notif-body { flex: 1; min-width: 0; }
200
+
201
+ .notif-meta {
202
+ font-size: 11px;
203
+ color: var(--text-muted);
204
+ margin-bottom: 2px;
205
+ white-space: nowrap;
206
+ overflow: hidden;
207
+ text-overflow: ellipsis;
208
+ }
209
+
210
+ .notif-summary {
211
+ font-size: 12px;
212
+ line-height: 1.4;
213
+ color: var(--text);
214
+ }
215
+
216
+ .notif-right {
217
+ display: flex;
218
+ flex-direction: column;
219
+ align-items: flex-end;
220
+ gap: 4px;
221
+ flex-shrink: 0;
222
+ }
223
+
224
+ .notif-time {
225
+ font-size: 10px;
226
+ color: var(--text-muted);
227
+ white-space: nowrap;
228
+ }
229
+
230
+ .notif-unread-dot {
231
+ width: 6px;
232
+ height: 6px;
233
+ border-radius: 50%;
234
+ background: var(--accent);
235
+ }
236
+
237
+ /* Grouping */
238
+ .notif-group-header {
239
+ display: flex;
240
+ align-items: center;
241
+ gap: 8px;
242
+ padding: 8px 16px;
243
+ background: var(--bg-hover);
244
+ font-size: 12px;
245
+ cursor: pointer;
246
+ }
247
+
248
+ .notif-group-name { font-weight: 500; flex: 1; }
249
+ .notif-group-count { font-size: 11px; color: var(--text-muted); }
250
+ .notif-group-toggle { background: none; border: none; color: var(--text-muted); cursor: pointer; }
251
+ .notif-group-items { display: none; }
252
+ .notif-group.open .notif-group-items { display: block; }
253
+ .notif-group.open .notif-group-toggle { transform: rotate(180deg); }
254
+
255
+ /* Empty state */
256
+ .notif-empty {
257
+ display: flex;
258
+ flex-direction: column;
259
+ align-items: center;
260
+ padding: 32px 16px;
261
+ color: var(--text-muted);
262
+ font-size: 13px;
263
+ gap: 8px;
264
+ }
265
+
266
+ .notif-empty-icon { font-size: 28px; }
267
+ ```
268
+
269
+ ## Interaction notes
270
+
271
+ - Filter `Unread` shows only items with `.unread` class. Clicking any item marks it read.
272
+ - Filter `Mentions` shows items whose summary contains a `@{currentAgent}` pattern.
273
+ - Filter `Errors` shows items with type `error`, `merge_conflict`, or `context_critical`.
274
+ - Groups collapse/expand on header click. Groups auto-form when ≥ 5 items share the same `squadSlug`.
275
+ - Mark all read: removes `.unread` and `.notif-unread-dot` from all items, resets unread count in notification-center badge.
@@ -0,0 +1,234 @@
1
+ # Review Workflow UI Pattern
2
+
3
+ Full hunk-level code review layout for the Squad Dashboard. Diff viewer + per-hunk approve/reject sidebar.
4
+
5
+ ## Layout
6
+
7
+ Split view: diff on the left (70%), hunk status sidebar on the right (30%).
8
+
9
+ ```
10
+ ┌──────────────────────────────────────────┬─────────────────────┐
11
+ │ DIFF VIEWER │ HUNK STATUS │
12
+ │ │ │
13
+ │ ─── Hunk 1/4 [● pending] ────────────── │ 1/4 hunks reviewed │
14
+ │ @@ -12,8 +12,10 @@ │ ──────────────────── │
15
+ │ context line │ ✓ Hunk 1 approved │
16
+ │ - removed line │ ● Hunk 2 pending │
17
+ │ + added line │ ✗ Hunk 3 rejected │
18
+ │ [✓ Approve] [✗ Reject] [💬] │ ● Hunk 4 pending │
19
+ │ │ │
20
+ │ ─── Hunk 2/4 [● pending] ────────────── │ ──────────────────── │
21
+ │ @@ -45,7 +45,9 @@ │ [Submit Review] │
22
+ │ ... │ │
23
+ └──────────────────────────────────────────┴─────────────────────┘
24
+ ```
25
+
26
+ ## HTML Structure
27
+
28
+ ```html
29
+ <div class="review-layout">
30
+
31
+ <!-- Progress bar at top -->
32
+ <div class="review-progress">
33
+ <span class="review-progress-label">1 / 4 hunks reviewed</span>
34
+ <div class="review-progress-bar">
35
+ <div class="review-progress-fill" style="width: 25%"></div>
36
+ </div>
37
+ </div>
38
+
39
+ <div class="review-split">
40
+
41
+ <!-- Left: Diff viewer -->
42
+ <div class="review-diff-panel">
43
+
44
+ <!-- Hunk 1 — approved -->
45
+ <div class="diff-hunk approved" data-hunk="1" data-status="approved">
46
+ <div class="diff-hunk-header">
47
+ <span class="diff-hunk-title">Hunk 1/4</span>
48
+ <code class="diff-hunk-range">@@ -12,8 +12,10 @@</code>
49
+ <span class="diff-hunk-status-badge status-approved">✓ approved</span>
50
+ </div>
51
+ <div class="diff-lines">
52
+ <div class="diff-line diff-context"> context line</div>
53
+ <div class="diff-line diff-remove">- removed line</div>
54
+ <div class="diff-line diff-add">+ added line</div>
55
+ </div>
56
+ <!-- action bar from review-action-bar.md -->
57
+ </div>
58
+
59
+ <!-- Hunk 2 — pending -->
60
+ <div class="diff-hunk" data-hunk="2" data-status="pending">
61
+ <!-- ... -->
62
+ </div>
63
+
64
+ </div>
65
+
66
+ <!-- Right: Status sidebar -->
67
+ <div class="review-sidebar">
68
+ <div class="review-sidebar-header">Hunks</div>
69
+ <div class="review-hunk-list">
70
+ <div class="review-hunk-item approved" data-hunk="1">
71
+ <span class="review-hunk-icon">✓</span>
72
+ <span class="review-hunk-label">Hunk 1</span>
73
+ <span class="review-hunk-status">approved</span>
74
+ </div>
75
+ <div class="review-hunk-item pending active" data-hunk="2">
76
+ <span class="review-hunk-icon">●</span>
77
+ <span class="review-hunk-label">Hunk 2</span>
78
+ <span class="review-hunk-status">pending</span>
79
+ </div>
80
+ <div class="review-hunk-item rejected" data-hunk="3">
81
+ <span class="review-hunk-icon">✗</span>
82
+ <span class="review-hunk-label">Hunk 3</span>
83
+ <span class="review-hunk-status">rejected</span>
84
+ </div>
85
+ </div>
86
+ <div class="review-sidebar-footer">
87
+ <button class="review-submit-btn" disabled>Submit Review</button>
88
+ <div class="review-submit-hint">Review all hunks to submit</div>
89
+ </div>
90
+ </div>
91
+
92
+ </div>
93
+ </div>
94
+ ```
95
+
96
+ ## CSS
97
+
98
+ ```css
99
+ /* Layout */
100
+ .review-layout { display: flex; flex-direction: column; gap: 16px; }
101
+
102
+ .review-split {
103
+ display: grid;
104
+ grid-template-columns: 1fr 280px;
105
+ gap: 16px;
106
+ align-items: flex-start;
107
+ }
108
+
109
+ /* Progress bar */
110
+ .review-progress { display: flex; align-items: center; gap: 12px; }
111
+ .review-progress-label { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
112
+ .review-progress-bar { flex: 1; height: 4px; background: var(--bg-hover); border-radius: 2px; }
113
+ .review-progress-fill { height: 100%; background: var(--accent); border-radius: 2px; transition: width 0.3s; }
114
+
115
+ /* Diff panel */
116
+ .diff-hunk {
117
+ border: 1px solid var(--border);
118
+ border-radius: 6px;
119
+ margin-bottom: 12px;
120
+ overflow: hidden;
121
+ }
122
+
123
+ .diff-hunk.approved {
124
+ border-color: var(--success);
125
+ background: rgba(74, 222, 128, 0.04);
126
+ }
127
+
128
+ .diff-hunk.rejected {
129
+ border-color: var(--danger);
130
+ background: rgba(248, 113, 113, 0.04);
131
+ }
132
+
133
+ .diff-hunk.revised {
134
+ border-color: var(--warning);
135
+ background: rgba(251, 191, 36, 0.04);
136
+ }
137
+
138
+ .diff-hunk-header {
139
+ display: flex;
140
+ align-items: center;
141
+ gap: 10px;
142
+ padding: 8px 12px;
143
+ background: var(--bg-hover);
144
+ font-size: 12px;
145
+ }
146
+
147
+ .diff-hunk-title { font-weight: 600; }
148
+ .diff-hunk-range { font-family: monospace; color: var(--text-muted); flex: 1; }
149
+
150
+ .diff-hunk-status-badge {
151
+ font-size: 11px;
152
+ padding: 1px 8px;
153
+ border-radius: 10px;
154
+ }
155
+
156
+ .diff-hunk-status-badge.status-approved { background: rgba(74,222,128,0.15); color: var(--success); }
157
+ .diff-hunk-status-badge.status-rejected { background: rgba(248,113,113,0.15); color: var(--danger); }
158
+ .diff-hunk-status-badge.status-pending { background: var(--bg-hover); color: var(--text-muted); }
159
+
160
+ .diff-lines { overflow-x: auto; }
161
+ .diff-line { font-family: monospace; font-size: 12px; padding: 1px 12px; line-height: 1.6; }
162
+ .diff-add { background: rgba(74, 222, 128, 0.10); color: var(--success); }
163
+ .diff-remove { background: rgba(248, 113, 113, 0.10); color: var(--danger); }
164
+ .diff-context { color: var(--text-muted); }
165
+
166
+ /* Sidebar */
167
+ .review-sidebar {
168
+ background: var(--bg-card);
169
+ border: 1px solid var(--border);
170
+ border-radius: 8px;
171
+ padding: 12px;
172
+ position: sticky;
173
+ top: 16px;
174
+ }
175
+
176
+ .review-sidebar-header {
177
+ font-size: 11px;
178
+ text-transform: uppercase;
179
+ color: var(--text-muted);
180
+ letter-spacing: 0.4px;
181
+ margin-bottom: 10px;
182
+ }
183
+
184
+ .review-hunk-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
185
+
186
+ .review-hunk-item {
187
+ display: flex;
188
+ align-items: center;
189
+ gap: 8px;
190
+ padding: 6px 8px;
191
+ border-radius: 4px;
192
+ font-size: 12px;
193
+ cursor: pointer;
194
+ }
195
+
196
+ .review-hunk-item:hover { background: var(--bg-hover); }
197
+ .review-hunk-item.active { background: var(--accent-dim); }
198
+
199
+ .review-hunk-icon { font-size: 13px; flex-shrink: 0; }
200
+ .review-hunk-label { flex: 1; }
201
+ .review-hunk-status { font-size: 11px; color: var(--text-muted); }
202
+
203
+ .review-hunk-item.approved .review-hunk-icon { color: var(--success); }
204
+ .review-hunk-item.rejected .review-hunk-icon { color: var(--danger); }
205
+
206
+ .review-sidebar-footer { border-top: 1px solid var(--border); padding-top: 12px; }
207
+
208
+ .review-submit-btn {
209
+ width: 100%;
210
+ padding: 8px;
211
+ border-radius: 6px;
212
+ background: var(--accent);
213
+ color: #fff;
214
+ border: none;
215
+ cursor: pointer;
216
+ font-size: 13px;
217
+ font-weight: 500;
218
+ }
219
+
220
+ .review-submit-btn:disabled {
221
+ background: var(--bg-hover);
222
+ color: var(--text-muted);
223
+ cursor: not-allowed;
224
+ }
225
+
226
+ .review-submit-hint { font-size: 11px; color: var(--text-muted); text-align: center; margin-top: 6px; }
227
+ ```
228
+
229
+ ## Interaction notes
230
+
231
+ - Clicking a hunk in the sidebar scrolls the diff panel to that hunk.
232
+ - Submit becomes enabled only when all hunks have a status (approved/rejected/revised).
233
+ - If any hunks are rejected, submit posts a `task_needs_revision` event with the list of rejected hunk IDs.
234
+ - If all hunks are approved, submit posts a `task_done` event.
@@ -0,0 +1,147 @@
1
+ # Task Dependency Graph Pattern
2
+
3
+ SVG-based DAG (Directed Acyclic Graph) visualization for task dependencies. Zero external dependencies — pure SVG + DOM.
4
+
5
+ ## Example Layout (5 nodes, 3 layers)
6
+
7
+ ```
8
+ Layer 1 Layer 2 Layer 3
9
+ ───────── ───────── ─────────
10
+ ┌──────────┐
11
+ │ research │ ──→ ┌──────────┐
12
+ └──────────┘ │ analyze │ ──→ ┌──────────┐
13
+ └──────────┘ │ write │
14
+ ┌──────────┐ ┌──────────┐ ──→ └──────────┘
15
+ │ gather │ ──→ │ review │
16
+ └──────────┘ └──────────┘
17
+
18
+ x=0 x=160 x=320
19
+ ```
20
+
21
+ Nodes: 120×44px. Column spacing: 160px. Row spacing: 60px.
22
+
23
+ ## SVG Container
24
+
25
+ ```html
26
+ <div class="dep-graph-wrap">
27
+ <svg class="dep-graph-svg"
28
+ width="560" height="240"
29
+ viewBox="0 0 560 240"
30
+ xmlns="http://www.w3.org/2000/svg">
31
+
32
+ <!-- Arrow marker definition -->
33
+ <defs>
34
+ <marker id="dep-arrow" markerWidth="8" markerHeight="8"
35
+ refX="6" refY="3" orient="auto">
36
+ <path d="M0,0 L0,6 L8,3 z" fill="#2a2e3a"/>
37
+ </marker>
38
+ </defs>
39
+
40
+ <!-- Edges (draw before nodes so nodes render on top) -->
41
+ <path class="dep-edge" d="M120,22 C140,22 140,82 160,82"
42
+ stroke="#2a2e3a" stroke-width="1.5" fill="none"
43
+ marker-end="url(#dep-arrow)"/>
44
+
45
+ <!-- Nodes (use dep-node component) -->
46
+ <g transform="translate(0, 0)">
47
+ <!-- dep-node component for "research" -->
48
+ </g>
49
+ <g transform="translate(160, 60)">
50
+ <!-- dep-node component for "analyze" -->
51
+ </g>
52
+
53
+ </svg>
54
+ </div>
55
+ ```
56
+
57
+ ## Edge Types
58
+
59
+ | Type | Stroke | Style |
60
+ |------|--------|-------|
61
+ | `dependency` (normal) | `--border` (#2a2e3a) | Solid, 1.5px |
62
+ | `blocking` | `--danger` (#f87171) | Solid, 2px |
63
+ | `soft` (optional dep) | `--text-muted` | Dashed 4,3 |
64
+
65
+ ```svg
66
+ <!-- Blocking edge -->
67
+ <path class="dep-edge dep-edge-blocking" d="..."
68
+ stroke="#f87171" stroke-width="2" fill="none"
69
+ marker-end="url(#dep-arrow-danger)"/>
70
+
71
+ <!-- Soft/optional edge -->
72
+ <path class="dep-edge dep-edge-soft" d="..."
73
+ stroke="#8b8fa3" stroke-width="1" stroke-dasharray="4,3"
74
+ fill="none" marker-end="url(#dep-arrow-muted)"/>
75
+ ```
76
+
77
+ ## Layout Algorithm (spec)
78
+
79
+ 1. **Topological sort** — group nodes by their earliest possible layer (depth from source).
80
+ 2. **Column assignment** — layer N is at `x = N * 160`.
81
+ 3. **Row stacking** — within each layer, nodes stacked at `y = index * 60`.
82
+ 4. **Edge routing** — cubic bezier from right port of source to left port of target:
83
+ - `C1 = (srcX + dx*0.5, srcY)` — horizontal pull at source
84
+ - `C2 = (tgtX - dx*0.5, tgtY)` — horizontal pull at target
85
+ - Where `dx = tgtX - srcX` (always positive for left→right edges)
86
+
87
+ ```
88
+ path d="M{sx},{sy} C{c1x},{c1y} {c2x},{c2y} {tx},{ty}"
89
+ ```
90
+
91
+ 5. **SVG sizing** — `width = (maxLayer + 1) * 160 + 40`. `height = maxNodesInLayer * 60 + 20`.
92
+
93
+ ## CSS
94
+
95
+ ```css
96
+ .dep-graph-wrap {
97
+ overflow: auto;
98
+ background: var(--bg-card);
99
+ border: 1px solid var(--border);
100
+ border-radius: 8px;
101
+ padding: 16px;
102
+ }
103
+
104
+ .dep-graph-svg {
105
+ display: block;
106
+ }
107
+
108
+ .dep-edge {
109
+ transition: stroke 0.15s;
110
+ }
111
+
112
+ .dep-edge:hover {
113
+ stroke: var(--accent);
114
+ }
115
+ ```
116
+
117
+ ## Interaction
118
+
119
+ - **Click node**: Show task detail panel or tooltip with status, agent, blockers.
120
+ - **Hover node**: Highlight all edges connected to that node (add `.highlighted` class, dim others).
121
+ - **Pan**: Drag the SVG container when graph is wider than viewport.
122
+
123
+ ## Tooltip on hover
124
+
125
+ ```html
126
+ <div class="dep-tooltip" style="position:absolute; display:none;">
127
+ <div class="dep-tooltip-title">write-prd</div>
128
+ <div class="dep-tooltip-row">Agent: <strong>planner</strong></div>
129
+ <div class="dep-tooltip-row">Status: <strong class="state-running">running</strong></div>
130
+ <div class="dep-tooltip-row">Blocked by: <em>none</em></div>
131
+ </div>
132
+ ```
133
+
134
+ ```css
135
+ .dep-tooltip {
136
+ background: var(--bg-card);
137
+ border: 1px solid var(--border);
138
+ border-radius: 6px;
139
+ padding: 8px 12px;
140
+ font-size: 12px;
141
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
142
+ pointer-events: none;
143
+ z-index: 100;
144
+ }
145
+ .dep-tooltip-title { font-weight: 600; margin-bottom: 4px; }
146
+ .dep-tooltip-row { color: var(--text-muted); line-height: 1.8; }
147
+ ```