orbital-command 0.2.0 → 1.0.0

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 (431) hide show
  1. package/README.md +67 -42
  2. package/bin/commands/config.js +19 -0
  3. package/bin/commands/events.js +40 -0
  4. package/bin/commands/launch.js +126 -0
  5. package/bin/commands/manifest.js +283 -0
  6. package/bin/commands/registry.js +104 -0
  7. package/bin/commands/update.js +24 -0
  8. package/bin/lib/helpers.js +229 -0
  9. package/bin/orbital.js +147 -319
  10. package/dist/assets/Landing-CfQdHR0N.js +11 -0
  11. package/dist/assets/PrimitivesConfig-DThSipFy.js +32 -0
  12. package/dist/assets/QualityGates-B4kxM5UU.js +26 -0
  13. package/dist/assets/SessionTimeline-Bz1iZnmg.js +1 -0
  14. package/dist/assets/Settings-DLcZwbCT.js +12 -0
  15. package/dist/assets/SourceControl-BMNIz7Lt.js +36 -0
  16. package/dist/assets/WorkflowVisualizer-CxuSBOYu.js +69 -0
  17. package/dist/assets/arrow-down-DVPp6_qp.js +6 -0
  18. package/dist/assets/bot-NFaJBDn_.js +6 -0
  19. package/dist/assets/charts-LGLb8hyU.js +68 -0
  20. package/dist/assets/circle-x-IsFCkBZu.js +6 -0
  21. package/dist/assets/file-text-J1cebZXF.js +6 -0
  22. package/dist/assets/globe-WzeyHsUc.js +6 -0
  23. package/dist/assets/index-BdJ57EhC.css +1 -0
  24. package/dist/assets/index-o4ScMAuR.js +349 -0
  25. package/dist/assets/key-CKR8JJSj.js +6 -0
  26. package/dist/assets/minus-CHBsJyjp.js +6 -0
  27. package/dist/assets/radio-xqZaR-Uk.js +6 -0
  28. package/dist/assets/rocket-D_xvvNG6.js +6 -0
  29. package/dist/assets/shield-TdB1yv_a.js +6 -0
  30. package/dist/assets/ui-BmsSg9jU.js +53 -0
  31. package/dist/assets/useSocketListener-0L5yiN5i.js +1 -0
  32. package/dist/assets/useWorkflowEditor-CqeRWVQX.js +11 -0
  33. package/dist/assets/{vendor-Dzv9lrRc.js → vendor-Bqt8AJn2.js} +1 -1
  34. package/dist/assets/workflow-constants-Rw-GmgHZ.js +6 -0
  35. package/dist/assets/zap-C9wqYMpl.js +6 -0
  36. package/dist/favicon.svg +1 -0
  37. package/dist/index.html +6 -5
  38. package/dist/server/server/__tests__/data-routes.test.js +126 -0
  39. package/dist/server/server/__tests__/helpers/db.js +17 -0
  40. package/dist/server/server/__tests__/helpers/mock-emitter.js +8 -0
  41. package/dist/server/server/__tests__/scope-routes.test.js +138 -0
  42. package/dist/server/server/__tests__/sprint-routes.test.js +102 -0
  43. package/dist/server/server/__tests__/workflow-routes.test.js +107 -0
  44. package/dist/server/server/config-migrator.js +135 -0
  45. package/dist/server/server/config.js +51 -7
  46. package/dist/server/server/database.js +21 -28
  47. package/dist/server/server/global-config.js +143 -0
  48. package/dist/server/server/index.js +118 -276
  49. package/dist/server/server/init.js +243 -225
  50. package/dist/server/server/launch.js +29 -0
  51. package/dist/server/server/manifest-types.js +8 -0
  52. package/dist/server/server/manifest.js +454 -0
  53. package/dist/server/server/migrate-legacy.js +229 -0
  54. package/dist/server/server/parsers/event-parser.js +4 -1
  55. package/dist/server/server/parsers/event-parser.test.js +117 -0
  56. package/dist/server/server/parsers/scope-parser.js +74 -28
  57. package/dist/server/server/parsers/scope-parser.test.js +230 -0
  58. package/dist/server/server/project-context.js +265 -0
  59. package/dist/server/server/project-emitter.js +41 -0
  60. package/dist/server/server/project-manager.js +297 -0
  61. package/dist/server/server/routes/aggregate-routes.js +871 -0
  62. package/dist/server/server/routes/config-routes.js +41 -90
  63. package/dist/server/server/routes/data-routes.js +25 -123
  64. package/dist/server/server/routes/dispatch-routes.js +37 -15
  65. package/dist/server/server/routes/git-routes.js +74 -0
  66. package/dist/server/server/routes/manifest-routes.js +319 -0
  67. package/dist/server/server/routes/scope-routes.js +45 -28
  68. package/dist/server/server/routes/sync-routes.js +134 -0
  69. package/dist/server/server/routes/version-routes.js +1 -15
  70. package/dist/server/server/routes/workflow-routes.js +9 -3
  71. package/dist/server/server/schema.js +3 -0
  72. package/dist/server/server/services/batch-orchestrator.js +41 -17
  73. package/dist/server/server/services/claude-session-service.js +17 -14
  74. package/dist/server/server/services/config-service.js +10 -1
  75. package/dist/server/server/services/deploy-service.test.js +119 -0
  76. package/dist/server/server/services/event-service.js +64 -1
  77. package/dist/server/server/services/event-service.test.js +191 -0
  78. package/dist/server/server/services/gate-service.test.js +105 -0
  79. package/dist/server/server/services/git-service.js +108 -4
  80. package/dist/server/server/services/github-service.js +110 -2
  81. package/dist/server/server/services/readiness-service.test.js +190 -0
  82. package/dist/server/server/services/scope-cache.js +5 -1
  83. package/dist/server/server/services/scope-cache.test.js +142 -0
  84. package/dist/server/server/services/scope-service.js +222 -131
  85. package/dist/server/server/services/scope-service.test.js +137 -0
  86. package/dist/server/server/services/sprint-orchestrator.js +29 -15
  87. package/dist/server/server/services/sprint-service.js +23 -3
  88. package/dist/server/server/services/sprint-service.test.js +238 -0
  89. package/dist/server/server/services/sync-service.js +434 -0
  90. package/dist/server/server/services/sync-types.js +2 -0
  91. package/dist/server/server/services/workflow-service.js +26 -5
  92. package/dist/server/server/services/workflow-service.test.js +159 -0
  93. package/dist/server/server/settings-sync.js +284 -0
  94. package/dist/server/server/uninstall.js +195 -0
  95. package/dist/server/server/update-planner.js +279 -0
  96. package/dist/server/server/update.js +212 -0
  97. package/dist/server/server/utils/cc-hooks-parser.js +3 -0
  98. package/dist/server/server/utils/cc-hooks-parser.test.js +86 -0
  99. package/dist/server/server/utils/dispatch-utils.js +83 -24
  100. package/dist/server/server/utils/dispatch-utils.test.js +182 -0
  101. package/dist/server/server/utils/flag-builder.js +54 -0
  102. package/dist/server/server/utils/json-fields.js +14 -0
  103. package/dist/server/server/utils/json-fields.test.js +73 -0
  104. package/dist/server/server/utils/logger.js +37 -3
  105. package/dist/server/server/utils/package-info.js +30 -0
  106. package/dist/server/server/utils/route-helpers.js +47 -0
  107. package/dist/server/server/utils/route-helpers.test.js +115 -0
  108. package/dist/server/server/utils/terminal-launcher.js +79 -25
  109. package/dist/server/server/utils/worktree-manager.js +13 -4
  110. package/dist/server/server/validator.js +230 -0
  111. package/dist/server/server/watchers/event-watcher.js +28 -13
  112. package/dist/server/server/watchers/global-watcher.js +63 -0
  113. package/dist/server/server/watchers/scope-watcher.js +27 -12
  114. package/dist/server/server/wizard/config-editor.js +237 -0
  115. package/dist/server/server/wizard/detect.js +96 -0
  116. package/dist/server/server/wizard/doctor.js +115 -0
  117. package/dist/server/server/wizard/index.js +340 -0
  118. package/dist/server/server/wizard/phases/confirm.js +39 -0
  119. package/dist/server/server/wizard/phases/project-setup.js +90 -0
  120. package/dist/server/server/wizard/phases/setup-wizard.js +66 -0
  121. package/dist/server/server/wizard/phases/welcome.js +32 -0
  122. package/dist/server/server/wizard/phases/workflow-setup.js +22 -0
  123. package/dist/server/server/wizard/types.js +29 -0
  124. package/dist/server/server/wizard/ui.js +73 -0
  125. package/dist/server/shared/__fixtures__/workflow-configs.js +75 -0
  126. package/dist/server/shared/api-types.js +80 -1
  127. package/dist/server/shared/default-workflow.json +65 -0
  128. package/dist/server/shared/onboarding-tour.test.js +81 -0
  129. package/dist/server/shared/project-colors.js +24 -0
  130. package/dist/server/shared/workflow-config.test.js +84 -0
  131. package/dist/server/shared/workflow-engine.js +1 -1
  132. package/dist/server/shared/workflow-engine.test.js +302 -0
  133. package/dist/server/shared/workflow-normalizer.js +101 -0
  134. package/dist/server/shared/workflow-normalizer.test.js +100 -0
  135. package/dist/server/src/components/onboarding/tour-steps.js +84 -0
  136. package/package.json +34 -29
  137. package/schemas/orbital.config.schema.json +2 -5
  138. package/scripts/postinstall.js +18 -6
  139. package/scripts/release.sh +53 -0
  140. package/server/__tests__/data-routes.test.ts +151 -0
  141. package/server/__tests__/helpers/db.ts +19 -0
  142. package/server/__tests__/helpers/mock-emitter.ts +10 -0
  143. package/server/__tests__/scope-routes.test.ts +158 -0
  144. package/server/__tests__/sprint-routes.test.ts +118 -0
  145. package/server/__tests__/workflow-routes.test.ts +120 -0
  146. package/server/config-migrator.ts +160 -0
  147. package/server/config.ts +64 -12
  148. package/server/database.ts +22 -31
  149. package/server/global-config.ts +204 -0
  150. package/server/index.ts +139 -316
  151. package/server/init.ts +266 -234
  152. package/server/launch.ts +32 -0
  153. package/server/manifest-types.ts +145 -0
  154. package/server/manifest.ts +494 -0
  155. package/server/migrate-legacy.ts +290 -0
  156. package/server/parsers/event-parser.test.ts +135 -0
  157. package/server/parsers/event-parser.ts +4 -1
  158. package/server/parsers/scope-parser.test.ts +270 -0
  159. package/server/parsers/scope-parser.ts +79 -31
  160. package/server/project-context.ts +325 -0
  161. package/server/project-emitter.ts +50 -0
  162. package/server/project-manager.ts +368 -0
  163. package/server/routes/aggregate-routes.ts +968 -0
  164. package/server/routes/config-routes.ts +43 -85
  165. package/server/routes/data-routes.ts +34 -156
  166. package/server/routes/dispatch-routes.ts +46 -17
  167. package/server/routes/git-routes.ts +77 -0
  168. package/server/routes/manifest-routes.ts +388 -0
  169. package/server/routes/scope-routes.ts +39 -30
  170. package/server/routes/sync-routes.ts +175 -0
  171. package/server/routes/version-routes.ts +1 -16
  172. package/server/routes/workflow-routes.ts +9 -3
  173. package/server/schema.ts +3 -0
  174. package/server/services/batch-orchestrator.ts +41 -17
  175. package/server/services/claude-session-service.ts +16 -14
  176. package/server/services/config-service.ts +10 -1
  177. package/server/services/deploy-service.test.ts +145 -0
  178. package/server/services/deploy-service.ts +2 -2
  179. package/server/services/event-service.test.ts +242 -0
  180. package/server/services/event-service.ts +92 -3
  181. package/server/services/gate-service.test.ts +131 -0
  182. package/server/services/gate-service.ts +2 -2
  183. package/server/services/git-service.ts +137 -4
  184. package/server/services/github-service.ts +120 -2
  185. package/server/services/readiness-service.test.ts +217 -0
  186. package/server/services/scope-cache.test.ts +167 -0
  187. package/server/services/scope-cache.ts +4 -1
  188. package/server/services/scope-service.test.ts +169 -0
  189. package/server/services/scope-service.ts +224 -130
  190. package/server/services/sprint-orchestrator.ts +30 -15
  191. package/server/services/sprint-service.test.ts +271 -0
  192. package/server/services/sprint-service.ts +29 -5
  193. package/server/services/sync-service.ts +482 -0
  194. package/server/services/sync-types.ts +77 -0
  195. package/server/services/workflow-service.test.ts +190 -0
  196. package/server/services/workflow-service.ts +29 -9
  197. package/server/settings-sync.ts +359 -0
  198. package/server/uninstall.ts +214 -0
  199. package/server/update-planner.ts +346 -0
  200. package/server/update.ts +263 -0
  201. package/server/utils/cc-hooks-parser.test.ts +96 -0
  202. package/server/utils/cc-hooks-parser.ts +4 -0
  203. package/server/utils/dispatch-utils.test.ts +245 -0
  204. package/server/utils/dispatch-utils.ts +102 -30
  205. package/server/utils/flag-builder.ts +56 -0
  206. package/server/utils/json-fields.test.ts +83 -0
  207. package/server/utils/json-fields.ts +14 -0
  208. package/server/utils/logger.ts +40 -3
  209. package/server/utils/package-info.ts +32 -0
  210. package/server/utils/route-helpers.test.ts +144 -0
  211. package/server/utils/route-helpers.ts +50 -0
  212. package/server/utils/terminal-launcher.ts +85 -25
  213. package/server/utils/worktree-manager.ts +9 -4
  214. package/server/validator.ts +270 -0
  215. package/server/watchers/event-watcher.ts +24 -12
  216. package/server/watchers/global-watcher.ts +77 -0
  217. package/server/watchers/scope-watcher.ts +21 -9
  218. package/server/wizard/config-editor.ts +248 -0
  219. package/server/wizard/detect.ts +104 -0
  220. package/server/wizard/doctor.ts +114 -0
  221. package/server/wizard/index.ts +438 -0
  222. package/server/wizard/phases/confirm.ts +45 -0
  223. package/server/wizard/phases/project-setup.ts +106 -0
  224. package/server/wizard/phases/setup-wizard.ts +78 -0
  225. package/server/wizard/phases/welcome.ts +39 -0
  226. package/server/wizard/phases/workflow-setup.ts +28 -0
  227. package/server/wizard/types.ts +56 -0
  228. package/server/wizard/ui.ts +92 -0
  229. package/shared/__fixtures__/workflow-configs.ts +80 -0
  230. package/shared/api-types.ts +106 -0
  231. package/shared/onboarding-tour.test.ts +94 -0
  232. package/shared/project-colors.ts +24 -0
  233. package/shared/workflow-config.test.ts +111 -0
  234. package/shared/workflow-config.ts +7 -0
  235. package/shared/workflow-engine.test.ts +388 -0
  236. package/shared/workflow-engine.ts +1 -1
  237. package/shared/workflow-normalizer.test.ts +119 -0
  238. package/shared/workflow-normalizer.ts +118 -0
  239. package/templates/agents/QUICK-REFERENCE.md +1 -0
  240. package/templates/agents/README.md +1 -0
  241. package/templates/agents/SKILL-TRIGGERS.md +11 -0
  242. package/templates/agents/green-team/deep-dive.md +361 -0
  243. package/templates/hooks/end-session.sh +4 -1
  244. package/templates/hooks/init-session.sh +1 -0
  245. package/templates/hooks/orbital-emit.sh +2 -2
  246. package/templates/hooks/orbital-report-deploy.sh +4 -4
  247. package/templates/hooks/orbital-report-gates.sh +4 -4
  248. package/templates/hooks/orbital-scope-update.sh +1 -1
  249. package/templates/hooks/scope-commit-logger.sh +2 -2
  250. package/templates/hooks/scope-create-cleanup.sh +2 -2
  251. package/templates/hooks/scope-create-gate.sh +2 -5
  252. package/templates/hooks/scope-gate.sh +4 -6
  253. package/templates/hooks/scope-helpers.sh +28 -1
  254. package/templates/hooks/scope-lifecycle-gate.sh +14 -5
  255. package/templates/hooks/scope-prepare.sh +67 -12
  256. package/templates/hooks/scope-transition.sh +14 -6
  257. package/templates/hooks/time-tracker.sh +2 -5
  258. package/templates/migrations/renames.json +1 -0
  259. package/templates/orbital.config.json +8 -6
  260. package/{shared/default-workflow.json → templates/presets/default.json} +65 -0
  261. package/templates/presets/development.json +4 -4
  262. package/templates/presets/gitflow.json +7 -0
  263. package/templates/prompts/README.md +23 -0
  264. package/templates/prompts/deep-dive-audit.md +94 -0
  265. package/templates/quick/rules.md +56 -5
  266. package/templates/settings-hooks.json +1 -1
  267. package/templates/skills/git-commit/SKILL.md +27 -7
  268. package/templates/skills/git-dev/SKILL.md +13 -4
  269. package/templates/skills/git-main/SKILL.md +13 -3
  270. package/templates/skills/git-production/SKILL.md +9 -2
  271. package/templates/skills/git-staging/SKILL.md +11 -3
  272. package/templates/skills/scope-create/SKILL.md +17 -3
  273. package/templates/skills/scope-fix-review/SKILL.md +14 -7
  274. package/templates/skills/scope-implement/SKILL.md +15 -4
  275. package/templates/skills/scope-post-review/SKILL.md +77 -7
  276. package/templates/skills/scope-pre-review/SKILL.md +11 -4
  277. package/templates/skills/scope-verify/SKILL.md +5 -3
  278. package/templates/skills/test-code-review/SKILL.md +41 -33
  279. package/templates/skills/test-scaffold/SKILL.md +222 -0
  280. package/dist/assets/WorkflowVisualizer-BZ21PIIF.js +0 -84
  281. package/dist/assets/charts-D__PA1zp.js +0 -72
  282. package/dist/assets/index-D1G6i0nS.css +0 -1
  283. package/dist/assets/index-DpItvKpf.js +0 -419
  284. package/dist/assets/ui-BvF022GT.js +0 -53
  285. package/index.html +0 -15
  286. package/postcss.config.js +0 -6
  287. package/src/App.tsx +0 -33
  288. package/src/components/AgentBadge.tsx +0 -40
  289. package/src/components/BatchPreflightModal.tsx +0 -115
  290. package/src/components/CardDisplayToggle.tsx +0 -74
  291. package/src/components/ColumnHeaderActions.tsx +0 -55
  292. package/src/components/ColumnMenu.tsx +0 -99
  293. package/src/components/DeployHistory.tsx +0 -141
  294. package/src/components/DispatchModal.tsx +0 -164
  295. package/src/components/DispatchPopover.tsx +0 -139
  296. package/src/components/DragOverlay.tsx +0 -25
  297. package/src/components/DriftSidebar.tsx +0 -140
  298. package/src/components/EnvironmentStrip.tsx +0 -88
  299. package/src/components/ErrorBoundary.tsx +0 -62
  300. package/src/components/FilterChip.tsx +0 -105
  301. package/src/components/GateIndicator.tsx +0 -33
  302. package/src/components/IdeaDetailModal.tsx +0 -190
  303. package/src/components/IdeaFormDialog.tsx +0 -113
  304. package/src/components/KanbanColumn.tsx +0 -201
  305. package/src/components/MarkdownRenderer.tsx +0 -114
  306. package/src/components/NeonGrid.tsx +0 -128
  307. package/src/components/PromotionQueue.tsx +0 -89
  308. package/src/components/ScopeCard.tsx +0 -234
  309. package/src/components/ScopeDetailModal.tsx +0 -255
  310. package/src/components/ScopeFilterBar.tsx +0 -152
  311. package/src/components/SearchInput.tsx +0 -102
  312. package/src/components/SessionPanel.tsx +0 -335
  313. package/src/components/SprintContainer.tsx +0 -303
  314. package/src/components/SprintDependencyDialog.tsx +0 -78
  315. package/src/components/SprintPreflightModal.tsx +0 -138
  316. package/src/components/StatusBar.tsx +0 -168
  317. package/src/components/SwimCell.tsx +0 -67
  318. package/src/components/SwimLaneRow.tsx +0 -94
  319. package/src/components/SwimlaneBoardView.tsx +0 -108
  320. package/src/components/VersionBadge.tsx +0 -139
  321. package/src/components/ViewModeSelector.tsx +0 -114
  322. package/src/components/config/AgentChip.tsx +0 -53
  323. package/src/components/config/AgentCreateDialog.tsx +0 -321
  324. package/src/components/config/AgentEditor.tsx +0 -175
  325. package/src/components/config/DirectoryTree.tsx +0 -582
  326. package/src/components/config/FileEditor.tsx +0 -550
  327. package/src/components/config/HookChip.tsx +0 -50
  328. package/src/components/config/StageCard.tsx +0 -198
  329. package/src/components/config/TransitionZone.tsx +0 -173
  330. package/src/components/config/UnifiedWorkflowPipeline.tsx +0 -216
  331. package/src/components/config/WorkflowPipeline.tsx +0 -161
  332. package/src/components/source-control/BranchList.tsx +0 -93
  333. package/src/components/source-control/BranchPanel.tsx +0 -105
  334. package/src/components/source-control/CommitLog.tsx +0 -100
  335. package/src/components/source-control/CommitRow.tsx +0 -47
  336. package/src/components/source-control/GitHubPanel.tsx +0 -110
  337. package/src/components/source-control/GitHubSetupGuide.tsx +0 -52
  338. package/src/components/source-control/GitOverviewBar.tsx +0 -101
  339. package/src/components/source-control/PullRequestList.tsx +0 -69
  340. package/src/components/source-control/WorktreeList.tsx +0 -80
  341. package/src/components/ui/badge.tsx +0 -41
  342. package/src/components/ui/button.tsx +0 -55
  343. package/src/components/ui/card.tsx +0 -78
  344. package/src/components/ui/dialog.tsx +0 -94
  345. package/src/components/ui/popover.tsx +0 -33
  346. package/src/components/ui/scroll-area.tsx +0 -54
  347. package/src/components/ui/separator.tsx +0 -28
  348. package/src/components/ui/tabs.tsx +0 -52
  349. package/src/components/ui/toggle-switch.tsx +0 -35
  350. package/src/components/ui/tooltip.tsx +0 -27
  351. package/src/components/workflow/AddEdgeDialog.tsx +0 -217
  352. package/src/components/workflow/AddListDialog.tsx +0 -201
  353. package/src/components/workflow/ChecklistEditor.tsx +0 -239
  354. package/src/components/workflow/CommandPrefixManager.tsx +0 -118
  355. package/src/components/workflow/ConfigSettingsPanel.tsx +0 -189
  356. package/src/components/workflow/DirectionSelector.tsx +0 -133
  357. package/src/components/workflow/DispatchConfigPanel.tsx +0 -180
  358. package/src/components/workflow/EdgeDetailPanel.tsx +0 -236
  359. package/src/components/workflow/EdgePropertyEditor.tsx +0 -251
  360. package/src/components/workflow/EditToolbar.tsx +0 -138
  361. package/src/components/workflow/HookDetailPanel.tsx +0 -250
  362. package/src/components/workflow/HookExecutionLog.tsx +0 -24
  363. package/src/components/workflow/HookSourceModal.tsx +0 -129
  364. package/src/components/workflow/HooksDashboard.tsx +0 -363
  365. package/src/components/workflow/ListPropertyEditor.tsx +0 -251
  366. package/src/components/workflow/MigrationPreviewDialog.tsx +0 -237
  367. package/src/components/workflow/MovementRulesPanel.tsx +0 -188
  368. package/src/components/workflow/NodeDetailPanel.tsx +0 -245
  369. package/src/components/workflow/PresetSelector.tsx +0 -414
  370. package/src/components/workflow/SkillCommandBuilder.tsx +0 -174
  371. package/src/components/workflow/WorkflowEdgeComponent.tsx +0 -145
  372. package/src/components/workflow/WorkflowNode.tsx +0 -147
  373. package/src/components/workflow/graphLayout.ts +0 -186
  374. package/src/components/workflow/mergeHooks.ts +0 -85
  375. package/src/components/workflow/useEditHistory.ts +0 -88
  376. package/src/components/workflow/useWorkflowEditor.ts +0 -262
  377. package/src/components/workflow/validateConfig.ts +0 -70
  378. package/src/hooks/useActiveDispatches.ts +0 -198
  379. package/src/hooks/useBoardSettings.ts +0 -170
  380. package/src/hooks/useCardDisplay.ts +0 -57
  381. package/src/hooks/useCcHooks.ts +0 -24
  382. package/src/hooks/useConfigTree.ts +0 -51
  383. package/src/hooks/useEnforcementRules.ts +0 -46
  384. package/src/hooks/useEvents.ts +0 -59
  385. package/src/hooks/useFileEditor.ts +0 -165
  386. package/src/hooks/useGates.ts +0 -57
  387. package/src/hooks/useIdeaActions.ts +0 -53
  388. package/src/hooks/useKanbanDnd.ts +0 -410
  389. package/src/hooks/useOrbitalConfig.ts +0 -54
  390. package/src/hooks/usePipeline.ts +0 -47
  391. package/src/hooks/usePipelineData.ts +0 -338
  392. package/src/hooks/useReconnect.ts +0 -25
  393. package/src/hooks/useScopeFilters.ts +0 -125
  394. package/src/hooks/useScopeSessions.ts +0 -44
  395. package/src/hooks/useScopes.ts +0 -67
  396. package/src/hooks/useSearch.ts +0 -67
  397. package/src/hooks/useSettings.tsx +0 -187
  398. package/src/hooks/useSocket.ts +0 -25
  399. package/src/hooks/useSourceControl.ts +0 -105
  400. package/src/hooks/useSprintPreflight.ts +0 -55
  401. package/src/hooks/useSprints.ts +0 -154
  402. package/src/hooks/useStatusBarHighlight.ts +0 -18
  403. package/src/hooks/useSwimlaneBoardSettings.ts +0 -104
  404. package/src/hooks/useTheme.ts +0 -9
  405. package/src/hooks/useTransitionReadiness.ts +0 -53
  406. package/src/hooks/useVersion.ts +0 -155
  407. package/src/hooks/useViolations.ts +0 -65
  408. package/src/hooks/useWorkflow.tsx +0 -125
  409. package/src/hooks/useZoomModifier.ts +0 -19
  410. package/src/index.css +0 -797
  411. package/src/layouts/DashboardLayout.tsx +0 -113
  412. package/src/lib/collisionDetection.ts +0 -20
  413. package/src/lib/scope-fields.ts +0 -61
  414. package/src/lib/swimlane.ts +0 -146
  415. package/src/lib/utils.ts +0 -15
  416. package/src/main.tsx +0 -19
  417. package/src/socket.ts +0 -11
  418. package/src/types/index.ts +0 -497
  419. package/src/views/AgentFeed.tsx +0 -339
  420. package/src/views/DeployPipeline.tsx +0 -59
  421. package/src/views/EnforcementView.tsx +0 -378
  422. package/src/views/PrimitivesConfig.tsx +0 -500
  423. package/src/views/QualityGates.tsx +0 -1012
  424. package/src/views/ScopeBoard.tsx +0 -454
  425. package/src/views/SessionTimeline.tsx +0 -516
  426. package/src/views/Settings.tsx +0 -183
  427. package/src/views/SourceControl.tsx +0 -95
  428. package/src/views/WorkflowVisualizer.tsx +0 -382
  429. package/tailwind.config.js +0 -161
  430. package/tsconfig.json +0 -25
  431. package/vite.config.ts +0 -38
@@ -1,198 +0,0 @@
1
- import { useState } from 'react';
2
- import { useDraggable, useDroppable } from '@dnd-kit/core';
3
- import { ChevronDown, ChevronRight, Star, Zap, Bot, GitBranch, Layers, Timer } from 'lucide-react';
4
- import { Card } from '@/components/ui/card';
5
- import { Badge } from '@/components/ui/badge';
6
- import { HookChip } from './HookChip';
7
- import { AgentChip } from './AgentChip';
8
- import { cn } from '@/lib/utils';
9
- import type { StageData, ConfigPrimitiveType, ResolvedHook } from '@/types';
10
-
11
- /** Wraps a HookChip to make it draggable out of the pipeline */
12
- function DraggableHookChip({ hook, dragId, selected, onClick, onRemove, editable }: {
13
- hook: ResolvedHook;
14
- dragId: string;
15
- selected?: boolean;
16
- onClick?: () => void;
17
- onRemove?: () => void;
18
- editable?: boolean;
19
- }) {
20
- const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
21
- id: dragId,
22
- disabled: !editable,
23
- data: { hookId: hook.id },
24
- });
25
-
26
- return (
27
- <div ref={setNodeRef} className={cn('cursor-pointer', isDragging && 'opacity-40')} onClick={onClick} {...listeners} {...attributes}>
28
- <HookChip hook={hook} selected={selected} onRemove={onRemove} />
29
- </div>
30
- );
31
- }
32
-
33
- interface StageCardProps {
34
- stage: StageData;
35
- selectedPath: string | null;
36
- onSelectItem: (type: ConfigPrimitiveType, path: string) => void;
37
- editable?: boolean;
38
- onRemoveHook?: (listId: string, hookId: string) => void;
39
- }
40
-
41
- export function StageCard({ stage, selectedPath, onSelectItem, editable, onRemoveHook }: StageCardProps) {
42
- const { list, stageHooks, alwaysOnAgents, reviewTeams } = stage;
43
- const [hooksOpen, setHooksOpen] = useState(true);
44
- const [agentsOpen, setAgentsOpen] = useState(true);
45
-
46
- const hasHooks = stageHooks.length > 0;
47
- const hasAgents = alwaysOnAgents.length > 0 || reviewTeams.length > 0;
48
- const showHooksSection = hasHooks || editable;
49
-
50
- const dropId = `drop::stage-hooks::${list.id}`;
51
- const { setNodeRef, isOver } = useDroppable({ id: dropId, disabled: !editable });
52
-
53
- return (
54
- <Card className="overflow-hidden border-border/60">
55
- {/* Header */}
56
- <div className="flex items-center gap-2 px-3 py-2">
57
- <div
58
- className="h-3 w-3 shrink-0 rounded-full"
59
- style={{ backgroundColor: list.hex }}
60
- />
61
- <span className="text-xs font-semibold text-foreground uppercase tracking-wide">
62
- {list.label}
63
- </span>
64
- <span className="text-[10px] text-muted-foreground/40 font-mono">{list.id}</span>
65
-
66
- <div className="ml-auto flex items-center gap-1">
67
- {list.isEntryPoint && (
68
- <Badge variant="outline" className="text-[9px] gap-0.5 px-1 py-0 border-amber-500/30 text-amber-400">
69
- <Star className="h-2.5 w-2.5" /> entry
70
- </Badge>
71
- )}
72
- {list.gitBranch && (
73
- <Badge variant="outline" className="text-[9px] gap-0.5 px-1 py-0 border-green-500/30 text-green-400">
74
- <GitBranch className="h-2.5 w-2.5" /> {list.gitBranch}
75
- </Badge>
76
- )}
77
- {list.supportsBatch && (
78
- <Badge variant="outline" className="text-[9px] gap-0.5 px-1 py-0 border-cyan-500/30 text-cyan-400">
79
- <Layers className="h-2.5 w-2.5" /> batch
80
- </Badge>
81
- )}
82
- {list.supportsSprint && (
83
- <Badge variant="outline" className="text-[9px] gap-0.5 px-1 py-0 border-indigo-500/30 text-indigo-400">
84
- <Timer className="h-2.5 w-2.5" /> sprint
85
- </Badge>
86
- )}
87
- </div>
88
- </div>
89
-
90
- {/* Stage Hooks */}
91
- {showHooksSection && (
92
- <div className="border-t border-border/40">
93
- <button
94
- type="button"
95
- onClick={() => setHooksOpen(!hooksOpen)}
96
- className="flex w-full items-center gap-1.5 px-3 py-1.5 text-[10px] font-medium text-muted-foreground hover:text-foreground transition-colors"
97
- >
98
- {hooksOpen ? <ChevronDown className="h-3 w-3" /> : <ChevronRight className="h-3 w-3" />}
99
- <Zap className="h-3 w-3" />
100
- Stage Hooks
101
- <span className="text-muted-foreground/50">({stageHooks.length})</span>
102
- </button>
103
- {hooksOpen && (
104
- <div
105
- ref={setNodeRef}
106
- className={cn(
107
- 'flex flex-wrap gap-1 px-3 pb-2 min-h-[28px]',
108
- editable && 'border border-dashed border-transparent rounded-md mx-2 mb-1 p-1',
109
- isOver && 'border-accent-blue bg-accent-blue/10',
110
- )}
111
- >
112
- {stageHooks.map(hook => (
113
- <DraggableHookChip
114
- key={hook.id}
115
- hook={hook}
116
- dragId={`pipeline::stage-hook::${list.id}::${hook.id}`}
117
- selected={hook.filePath != null && hook.filePath === selectedPath}
118
- onClick={() => hook.filePath && onSelectItem('hooks', hook.filePath)}
119
- onRemove={editable && onRemoveHook ? () => onRemoveHook(list.id, hook.id) : undefined}
120
- editable={editable}
121
- />
122
- ))}
123
- {editable && stageHooks.length === 0 && (
124
- <span className="text-[9px] text-muted-foreground/40 italic py-0.5">drop hooks here</span>
125
- )}
126
- </div>
127
- )}
128
- </div>
129
- )}
130
-
131
- {/* Agents */}
132
- {hasAgents && (
133
- <div className="border-t border-border/40">
134
- <button
135
- type="button"
136
- onClick={() => setAgentsOpen(!agentsOpen)}
137
- className="flex w-full items-center gap-1.5 px-3 py-1.5 text-[10px] font-medium text-muted-foreground hover:text-foreground transition-colors"
138
- >
139
- {agentsOpen ? <ChevronDown className="h-3 w-3" /> : <ChevronRight className="h-3 w-3" />}
140
- <Bot className="h-3 w-3" />
141
- Agents
142
- <span className="text-muted-foreground/50">
143
- ({alwaysOnAgents.length + reviewTeams.reduce((s, t) => s + t.agents.length, 0)})
144
- </span>
145
- </button>
146
- {agentsOpen && (
147
- <div className="px-3 pb-2 space-y-2">
148
- {/* Always-On */}
149
- {alwaysOnAgents.length > 0 && (
150
- <div>
151
- <div className="text-[9px] uppercase tracking-wider text-muted-foreground/50 mb-1">Always-On</div>
152
- <div className="flex flex-wrap gap-1">
153
- {alwaysOnAgents.map(agent => (
154
- <AgentChip
155
- key={agent.id}
156
- agent={agent}
157
- mode="always-on"
158
- selected={agent.filePath != null && agent.filePath === selectedPath}
159
- onClick={() => agent.filePath && onSelectItem('agents', agent.filePath)}
160
- />
161
- ))}
162
- </div>
163
- </div>
164
- )}
165
-
166
- {/* Review Teams */}
167
- {reviewTeams.map(team => (
168
- <div key={team.skillCommand}>
169
- <div className="flex items-center gap-1 text-[9px] uppercase tracking-wider text-muted-foreground/50 mb-1">
170
- <span>{team.skillCommand} team:</span>
171
- </div>
172
- <div className="flex flex-wrap gap-1">
173
- {team.agents.map(agent => (
174
- <AgentChip
175
- key={agent.id}
176
- agent={agent}
177
- mode="review"
178
- selected={agent.filePath != null && agent.filePath === selectedPath}
179
- onClick={() => agent.filePath && onSelectItem('agents', agent.filePath)}
180
- />
181
- ))}
182
- </div>
183
- </div>
184
- ))}
185
- </div>
186
- )}
187
- </div>
188
- )}
189
-
190
- {/* Empty state */}
191
- {!showHooksSection && !hasAgents && (
192
- <div className="border-t border-border/40 px-3 py-2">
193
- <span className="text-[10px] text-muted-foreground/40 italic">No stage-specific hooks or agents</span>
194
- </div>
195
- )}
196
- </Card>
197
- );
198
- }
@@ -1,173 +0,0 @@
1
- import { useDraggable, useDroppable } from '@dnd-kit/core';
2
- import { ArrowDown, Terminal, Zap } from 'lucide-react';
3
- import { cn } from '@/lib/utils';
4
- import { HookChip } from './HookChip';
5
- import type { EdgeData, ConfigPrimitiveType, ResolvedHook } from '@/types';
6
-
7
- /** Wraps a HookChip to make it draggable out of the pipeline */
8
- function DraggableHookChip({ hook, dragId, selected, onClick, onRemove, editable }: {
9
- hook: ResolvedHook;
10
- dragId: string;
11
- selected?: boolean;
12
- onClick?: () => void;
13
- onRemove?: () => void;
14
- editable?: boolean;
15
- }) {
16
- const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
17
- id: dragId,
18
- disabled: !editable,
19
- data: { hookId: hook.id },
20
- });
21
-
22
- return (
23
- <div ref={setNodeRef} className={cn('cursor-pointer', isDragging && 'opacity-40')} onClick={onClick} {...listeners} {...attributes}>
24
- <HookChip hook={hook} selected={selected} onRemove={onRemove} />
25
- </div>
26
- );
27
- }
28
-
29
- interface TransitionZoneProps {
30
- edges: EdgeData[];
31
- selectedPath: string | null;
32
- onSelectItem: (type: ConfigPrimitiveType, path: string) => void;
33
- editable?: boolean;
34
- onRemoveHook?: (from: string, to: string, hookId: string) => void;
35
- }
36
-
37
- const DIRECTION_STYLE: Record<string, { arrow: string; label: string; border: string; bg: string }> = {
38
- forward: { arrow: 'text-green-500', label: 'text-green-400', border: 'border-green-500/20', bg: 'bg-green-500/5' },
39
- backward: { arrow: 'text-amber-500', label: 'text-amber-400', border: 'border-amber-500/20', bg: 'bg-amber-500/5' },
40
- shortcut: { arrow: 'text-indigo-500', label: 'text-indigo-400', border: 'border-indigo-500/20', bg: 'bg-indigo-500/5' },
41
- };
42
-
43
- function EdgeRow({ edgeData, selectedPath, onSelectItem, editable, onRemoveHook }: {
44
- edgeData: EdgeData;
45
- selectedPath: string | null;
46
- onSelectItem: (type: ConfigPrimitiveType, path: string) => void;
47
- editable?: boolean;
48
- onRemoveHook?: (from: string, to: string, hookId: string) => void;
49
- }) {
50
- const { edge, skillPath, edgeHooks } = edgeData;
51
- const style = DIRECTION_STYLE[edge.direction] ?? DIRECTION_STYLE.forward;
52
-
53
- const skillDropId = `drop::edge-skill::${edge.from}:${edge.to}`;
54
- const { setNodeRef: setSkillRef, isOver: isSkillOver } = useDroppable({ id: skillDropId, disabled: !editable });
55
-
56
- const hooksDropId = `drop::edge-hooks::${edge.from}:${edge.to}`;
57
- const { setNodeRef: setHooksRef, isOver: isHooksOver } = useDroppable({ id: hooksDropId, disabled: !editable });
58
-
59
- const directionLabel = edge.direction === 'shortcut' ? 'SHORTCUT' : 'DEFAULT';
60
-
61
- return (
62
- <div className={cn(
63
- 'flex items-center rounded-lg border overflow-hidden',
64
- style.border, 'bg-card',
65
- )}>
66
- {/* Direction label */}
67
- <div className={cn('shrink-0 self-stretch flex items-center px-2.5', style.bg)}>
68
- <span className={cn('text-[9px] font-semibold uppercase tracking-wider whitespace-nowrap', style.label)}>
69
- {directionLabel}
70
- </span>
71
- </div>
72
-
73
- {/* Skill + Hooks inline */}
74
- <div className="flex items-center flex-1 min-w-0 border-l" style={{ borderColor: 'inherit' }}>
75
- {/* Skill */}
76
- <div
77
- ref={setSkillRef}
78
- className={cn(
79
- 'flex items-center gap-1.5 px-2 py-1 shrink-0',
80
- isSkillOver && 'bg-green-500/10',
81
- )}
82
- >
83
- {edge.command ? (
84
- <button
85
- type="button"
86
- onClick={() => skillPath && onSelectItem('skills', skillPath)}
87
- data-pipeline-path={skillPath ?? undefined}
88
- className={cn(
89
- 'inline-flex items-center gap-1 text-[11px] font-semibold transition-colors whitespace-nowrap rounded-md px-1 -mx-1',
90
- style.label,
91
- skillPath && 'hover:brightness-125 cursor-pointer',
92
- !skillPath && 'cursor-default opacity-60',
93
- skillPath != null && skillPath === selectedPath && 'glow-selected-pulse',
94
- )}
95
- style={skillPath != null && skillPath === selectedPath ? { '--glow-color': '#22c55eA0', '--glow-color-wide': '#22c55e40' } as React.CSSProperties : undefined}
96
- >
97
- <Terminal className="h-3 w-3 shrink-0" />
98
- {edge.command.replace(/\s+\{.*\}$/, '')}
99
- </button>
100
- ) : (
101
- <span className={cn(
102
- 'text-[10px] text-muted-foreground/40 italic whitespace-nowrap',
103
- editable && 'border border-dashed border-muted-foreground/20 rounded px-1.5 py-0.5',
104
- )}>
105
- {editable ? 'drop skill' : 'no skill'}
106
- </span>
107
- )}
108
- </div>
109
-
110
- {/* Divider */}
111
- <div className={cn('w-px self-stretch', style.border.replace('border-', 'bg-'))} />
112
-
113
- {/* Hooks */}
114
- <div
115
- ref={setHooksRef}
116
- className={cn(
117
- 'flex items-center gap-1 px-2 py-1 flex-1 min-w-0',
118
- isHooksOver && 'bg-[#00bcd4]/10',
119
- )}
120
- >
121
- <Zap className="h-3 w-3 shrink-0 text-muted-foreground/30" />
122
- {edgeHooks.map(hook => (
123
- <DraggableHookChip
124
- key={hook.id}
125
- hook={hook}
126
- dragId={`pipeline::edge-hook::${edge.from}:${edge.to}::${hook.id}`}
127
- selected={hook.filePath != null && hook.filePath === selectedPath}
128
- onClick={() => hook.filePath && onSelectItem('hooks', hook.filePath)}
129
- onRemove={editable && onRemoveHook ? () => onRemoveHook(edge.from, edge.to, hook.id) : undefined}
130
- editable={editable}
131
- />
132
- ))}
133
- {edgeHooks.length === 0 && (
134
- <span className={cn(
135
- 'text-[10px] text-muted-foreground/40 italic',
136
- editable && 'border border-dashed border-muted-foreground/20 rounded px-1.5 py-0.5',
137
- )}>
138
- {editable ? 'drop hooks' : 'none'}
139
- </span>
140
- )}
141
- </div>
142
- </div>
143
- </div>
144
- );
145
- }
146
-
147
- export function TransitionZone({ edges, selectedPath, onSelectItem, editable, onRemoveHook }: TransitionZoneProps) {
148
- if (edges.length === 0) return null;
149
-
150
- const arrowStyle = DIRECTION_STYLE.forward.arrow;
151
-
152
- return (
153
- <div className="flex flex-col items-center py-1">
154
- <ArrowDown className={cn('h-7 w-4', arrowStyle)} />
155
-
156
- {/* Edge rows */}
157
- <div className="flex w-full flex-wrap justify-center gap-1 px-1 my-0.5">
158
- {edges.map(edgeData => (
159
- <EdgeRow
160
- key={`${edgeData.edge.from}:${edgeData.edge.to}`}
161
- edgeData={edgeData}
162
- selectedPath={selectedPath}
163
- onSelectItem={onSelectItem}
164
- editable={editable}
165
- onRemoveHook={onRemoveHook}
166
- />
167
- ))}
168
- </div>
169
-
170
- <ArrowDown className={cn('h-7 w-4', arrowStyle)} />
171
- </div>
172
- );
173
- }
@@ -1,216 +0,0 @@
1
- import { useState, useEffect } from 'react';
2
- import { useDraggable } from '@dnd-kit/core';
3
- import { ChevronDown, ChevronRight, CornerDownLeft } from 'lucide-react';
4
- import { Badge } from '@/components/ui/badge';
5
- import { Card } from '@/components/ui/card';
6
- import { ScrollArea } from '@/components/ui/scroll-area';
7
- import { cn } from '@/lib/utils';
8
- import { usePipelineData } from '@/hooks/usePipelineData';
9
- import { HookChip } from './HookChip';
10
- import { StageCard } from './StageCard';
11
- import { TransitionZone } from './TransitionZone';
12
- import type { ConfigPrimitiveType, ResolvedHook } from '@/types';
13
- import type { WorkflowConfig, WorkflowEdge } from '../../../shared/workflow-config';
14
-
15
- function DraggableHookChip({ hook, dragId, selected, onClick, onRemove, editable }: {
16
- hook: ResolvedHook;
17
- dragId: string;
18
- selected?: boolean;
19
- onClick?: () => void;
20
- onRemove?: () => void;
21
- editable?: boolean;
22
- }) {
23
- const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
24
- id: dragId,
25
- disabled: !editable,
26
- data: { hookId: hook.id },
27
- });
28
-
29
- return (
30
- <div ref={setNodeRef} className={cn('cursor-pointer', isDragging && 'opacity-40')} onClick={onClick} {...listeners} {...attributes}>
31
- <HookChip hook={hook} selected={selected} onRemove={onRemove} />
32
- </div>
33
- );
34
- }
35
-
36
- interface UnifiedWorkflowPipelineProps {
37
- selectedPath: string | null;
38
- onSelectItem: (type: ConfigPrimitiveType, path: string) => void;
39
- editConfig?: WorkflowConfig;
40
- editable?: boolean;
41
- onRemoveEdgeHook?: (from: string, to: string, hookId: string) => void;
42
- onRemoveStageHook?: (listId: string, hookId: string) => void;
43
- onRemoveGlobalHook?: (hookId: string) => void;
44
- }
45
-
46
- export function UnifiedWorkflowPipeline({ selectedPath, onSelectItem, editConfig, editable, onRemoveEdgeHook, onRemoveStageHook, onRemoveGlobalHook }: UnifiedWorkflowPipelineProps) {
47
- const data = usePipelineData(editConfig);
48
- const [reworkOpen, setReworkOpen] = useState(false);
49
-
50
- // Scroll selected pipeline item into view
51
- useEffect(() => {
52
- if (!selectedPath) return;
53
- requestAnimationFrame(() => {
54
- const el = document.querySelector(`[data-pipeline-path="${CSS.escape(selectedPath)}"]`);
55
- el?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
56
- });
57
- }, [selectedPath]);
58
-
59
- // Collect all backward edges across stages
60
- const allBackwardEdges: WorkflowEdge[] = data.stages.flatMap(s => s.backwardEdges);
61
-
62
- // Compute stats
63
- const totalHooks = new Set([
64
- ...data.globalHooks.map(h => h.id),
65
- ...data.stages.flatMap(s => s.stageHooks.map(h => h.id)),
66
- ]).size;
67
- const totalSkills = new Set(
68
- data.stages.flatMap(s => s.forwardEdges.filter(e => e.edge.command).map(e => e.edge.command)),
69
- ).size;
70
- const totalAgents = new Set([
71
- ...data.stages.flatMap(s => s.alwaysOnAgents.map(a => a.id)),
72
- ...data.stages.flatMap(s => s.reviewTeams.flatMap(t => t.agents.map(a => a.id))),
73
- ]).size;
74
-
75
- return (
76
- <div className="flex h-full flex-col">
77
- {/* Header */}
78
- <div className="flex items-center justify-between border-b border-border px-3 py-2">
79
- <span className="text-xxs font-medium uppercase tracking-wider text-muted-foreground">
80
- Workflow Pipeline
81
- </span>
82
- <div className="flex items-center gap-1.5">
83
- <Badge variant="secondary" className="text-[10px]">
84
- {data.stages.length} stages
85
- </Badge>
86
- {totalSkills > 0 && (
87
- <Badge variant="secondary" className="text-[10px]">
88
- {totalSkills} skills
89
- </Badge>
90
- )}
91
- {totalHooks > 0 && (
92
- <Badge variant="secondary" className="text-[10px]">
93
- {totalHooks} hooks
94
- </Badge>
95
- )}
96
- {totalAgents > 0 && (
97
- <Badge variant="secondary" className="text-[10px]">
98
- {totalAgents} agents
99
- </Badge>
100
- )}
101
- </div>
102
- </div>
103
-
104
- {/* Pipeline */}
105
- <ScrollArea className="flex-1">
106
- <div className="p-3 space-y-0">
107
- {/* Global Hooks */}
108
- {data.globalHooks.length > 0 && (
109
- <>
110
- <Card className="overflow-hidden border-border/60">
111
- <div className="flex items-center gap-2 px-3 py-2">
112
- <span className="text-sm">🌐</span>
113
- <span className="text-xs font-semibold text-foreground uppercase tracking-wide">
114
- Global Hooks
115
- </span>
116
- <span className="text-[10px] text-muted-foreground/40">active in all stages</span>
117
- </div>
118
- <div className="border-t border-border/40">
119
- <div className="flex flex-wrap gap-1 px-3 py-2">
120
- {data.globalHooks.map(hook => (
121
- <DraggableHookChip
122
- key={hook.id}
123
- hook={hook}
124
- dragId={`pipeline::global-hook::${hook.id}`}
125
- selected={hook.filePath != null && hook.filePath === selectedPath}
126
- onClick={() => hook.filePath && onSelectItem('hooks', hook.filePath)}
127
- onRemove={editable && onRemoveGlobalHook ? () => onRemoveGlobalHook(hook.id) : undefined}
128
- editable={editable}
129
- />
130
- ))}
131
- </div>
132
- </div>
133
- </Card>
134
-
135
- {/* Separator between global hooks and stage cards */}
136
- <div className="flex items-center gap-2 py-2 px-4">
137
- <div className="flex-1 border-t border-border/40" />
138
- <span className="text-[9px] text-muted-foreground/30 uppercase tracking-wider">stages</span>
139
- <div className="flex-1 border-t border-border/40" />
140
- </div>
141
- </>
142
- )}
143
-
144
- {/* Stage cards + transition zones */}
145
- {data.stages.map((stage, i) => (
146
- <div key={stage.list.id}>
147
- <StageCard
148
- stage={stage}
149
- selectedPath={selectedPath}
150
- onSelectItem={onSelectItem}
151
- editable={editable}
152
- onRemoveHook={onRemoveStageHook}
153
- />
154
-
155
- {/* Transition zone: all forward/shortcut edges in a single row */}
156
- {stage.forwardEdges.length > 0 && (
157
- <TransitionZone
158
- edges={stage.forwardEdges}
159
- selectedPath={selectedPath}
160
- onSelectItem={onSelectItem}
161
- editable={editable}
162
- onRemoveHook={onRemoveEdgeHook}
163
- />
164
- )}
165
-
166
- {/* Spacer between stages if no edges (last stage) */}
167
- {stage.forwardEdges.length === 0 && i < data.stages.length - 1 && (
168
- <div className="h-2" />
169
- )}
170
- </div>
171
- ))}
172
-
173
- {/* Backward edges summary */}
174
- {allBackwardEdges.length > 0 && (
175
- <div className="mt-3 border-t border-border/30 pt-2">
176
- <button
177
- type="button"
178
- onClick={() => setReworkOpen(!reworkOpen)}
179
- className="flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-[10px] font-medium text-muted-foreground hover:text-foreground hover:bg-muted/30 transition-colors"
180
- >
181
- {reworkOpen ? <ChevronDown className="h-3 w-3" /> : <ChevronRight className="h-3 w-3" />}
182
- <CornerDownLeft className="h-3 w-3" />
183
- {allBackwardEdges.length} rework paths
184
- </button>
185
- {reworkOpen && (
186
- <div className="space-y-1 px-2 pt-1">
187
- {allBackwardEdges.map(edge => (
188
- <div
189
- key={`${edge.from}:${edge.to}`}
190
- className="flex items-center gap-2 text-[10px] text-muted-foreground/70 py-0.5"
191
- >
192
- <CornerDownLeft className="h-2.5 w-2.5 text-amber-500/50" />
193
- <span className="font-mono">{edge.from}</span>
194
- <span className="text-muted-foreground/30">&rarr;</span>
195
- <span className="font-mono">{edge.to}</span>
196
- <span className="text-muted-foreground/40 truncate">{edge.label}</span>
197
- </div>
198
- ))}
199
- </div>
200
- )}
201
- </div>
202
- )}
203
-
204
- {/* Footer hint */}
205
- <div className="mt-4 px-2 text-center">
206
- <span className="text-[9px] text-muted-foreground/30">
207
- {editable
208
- ? 'Drag items from the tree onto stages or edges'
209
- : 'Click any hook, agent, or skill to open in editor'}
210
- </span>
211
- </div>
212
- </div>
213
- </ScrollArea>
214
- </div>
215
- );
216
- }