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,237 +0,0 @@
1
- import { useState, useMemo, useCallback } from 'react';
2
- import * as Dialog from '@radix-ui/react-dialog';
3
- import { X, AlertTriangle, ArrowRight, CheckCircle2, Loader2 } from 'lucide-react';
4
- import type { WorkflowConfig } from '../../../shared/workflow-config';
5
-
6
- // ─── Types ──────────────────────────────────────────────
7
-
8
- interface MigrationPlan {
9
- valid: boolean;
10
- validationErrors: string[];
11
- removedLists: string[];
12
- addedLists: string[];
13
- dirsToCreate: string[];
14
- dirsToRemove: string[];
15
- orphanedScopes: Array<{ listId: string; scopeFiles: string[] }>;
16
- lostEdges: Array<{ from: string; to: string }>;
17
- suggestedMappings: Record<string, string>;
18
- impactSummary: string;
19
- }
20
-
21
- interface MigrationPreviewDialogProps {
22
- open: boolean;
23
- onOpenChange: (open: boolean) => void;
24
- config: WorkflowConfig;
25
- plan: MigrationPlan | null;
26
- loading: boolean;
27
- error: string | null;
28
- onApply: (orphanMappings: Record<string, string>) => void;
29
- }
30
-
31
- // ─── Component ──────────────────────────────────────────
32
-
33
- export function MigrationPreviewDialog({
34
- open,
35
- onOpenChange,
36
- config,
37
- plan,
38
- loading,
39
- error,
40
- onApply,
41
- }: MigrationPreviewDialogProps) {
42
- const [orphanMappings, setOrphanMappings] = useState<Record<string, string>>({});
43
-
44
- // Initialize mappings from suggestions when plan changes
45
- useMemo(() => {
46
- if (plan?.suggestedMappings) {
47
- setOrphanMappings({ ...plan.suggestedMappings });
48
- }
49
- }, [plan?.suggestedMappings]);
50
-
51
- const listIds = useMemo(() => config.lists.map((l) => l.id), [config.lists]);
52
-
53
- const allOrphansMapped = useMemo(() => {
54
- if (!plan) return true;
55
- return plan.orphanedScopes.every((o) => orphanMappings[o.listId]);
56
- }, [plan, orphanMappings]);
57
-
58
- const handleApply = useCallback(() => {
59
- if (!allOrphansMapped) return;
60
- onApply(orphanMappings);
61
- }, [allOrphansMapped, orphanMappings, onApply]);
62
-
63
- return (
64
- <Dialog.Root open={open} onOpenChange={onOpenChange}>
65
- <Dialog.Portal>
66
- <Dialog.Overlay className="fixed inset-0 z-40 bg-black/60 backdrop-blur-sm" />
67
- <Dialog.Content className="fixed left-1/2 top-1/2 z-50 max-h-[80vh] w-[520px] -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900 shadow-xl">
68
- {/* Header */}
69
- <div className="flex items-center justify-between border-b border-zinc-800 px-5 py-4">
70
- <Dialog.Title className="flex items-center gap-2 text-sm font-medium text-zinc-100">
71
- <AlertTriangle className="h-4 w-4 text-amber-400" />
72
- Migration Preview
73
- </Dialog.Title>
74
- <Dialog.Close className="rounded p-1 text-zinc-500 hover:bg-zinc-800 hover:text-zinc-300">
75
- <X className="h-4 w-4" />
76
- </Dialog.Close>
77
- </div>
78
-
79
- {/* Content */}
80
- <div className="max-h-[60vh] overflow-y-auto p-5 text-xs">
81
- {loading && (
82
- <div className="flex items-center justify-center gap-2 py-8 text-zinc-500">
83
- <Loader2 className="h-4 w-4 animate-spin" />
84
- <span>Computing migration impact...</span>
85
- </div>
86
- )}
87
-
88
- {error && (
89
- <div className="rounded border border-red-500/30 bg-red-500/10 p-3 text-red-400">
90
- {error}
91
- </div>
92
- )}
93
-
94
- {plan && !loading && (
95
- <div className="space-y-4">
96
- {/* Validation errors */}
97
- {!plan.valid && (
98
- <div className="rounded border border-red-500/30 bg-red-500/10 p-3">
99
- <p className="mb-2 font-semibold text-red-400">Validation Errors</p>
100
- {plan.validationErrors.map((e) => (
101
- <p key={e} className="text-red-400">{e}</p>
102
- ))}
103
- </div>
104
- )}
105
-
106
- {plan.valid && (
107
- <>
108
- {/* Summary */}
109
- <div className="rounded border border-zinc-800 bg-zinc-950/50 p-3">
110
- <p className="text-zinc-300">{plan.impactSummary}</p>
111
- </div>
112
-
113
- {/* Added lists */}
114
- {plan.addedLists.length > 0 && (
115
- <Section title={`Added Lists (${plan.addedLists.length})`}>
116
- <div className="flex flex-wrap gap-1.5">
117
- {plan.addedLists.map((id) => (
118
- <span key={id} className="rounded bg-emerald-500/15 px-2 py-1 font-mono text-emerald-400">
119
- + {id}
120
- </span>
121
- ))}
122
- </div>
123
- </Section>
124
- )}
125
-
126
- {/* Removed lists */}
127
- {plan.removedLists.length > 0 && (
128
- <Section title={`Removed Lists (${plan.removedLists.length})`}>
129
- <div className="flex flex-wrap gap-1.5">
130
- {plan.removedLists.map((id) => (
131
- <span key={id} className="rounded bg-red-500/15 px-2 py-1 font-mono text-red-400">
132
- - {id}
133
- </span>
134
- ))}
135
- </div>
136
- </Section>
137
- )}
138
-
139
- {/* Lost edges */}
140
- {plan.lostEdges.length > 0 && (
141
- <Section title={`Lost Edges (${plan.lostEdges.length})`}>
142
- <div className="space-y-1">
143
- {plan.lostEdges.map((e) => (
144
- <div key={`${e.from}:${e.to}`} className="flex items-center gap-2 text-zinc-400">
145
- <span className="font-mono">{e.from}</span>
146
- <ArrowRight className="h-3 w-3 text-zinc-600" />
147
- <span className="font-mono">{e.to}</span>
148
- </div>
149
- ))}
150
- </div>
151
- </Section>
152
- )}
153
-
154
- {/* Orphaned scopes */}
155
- {plan.orphanedScopes.length > 0 && (
156
- <Section title="Orphaned Scopes — Reassignment Required">
157
- <div className="space-y-3">
158
- {plan.orphanedScopes.map((o) => (
159
- <div key={o.listId} className="rounded border border-amber-500/30 bg-amber-500/5 p-3">
160
- <div className="flex items-center justify-between">
161
- <span className="font-mono text-amber-400">{o.listId}</span>
162
- <span className="text-zinc-500">{o.scopeFiles.length} scope(s)</span>
163
- </div>
164
- <div className="mt-2 flex items-center gap-2">
165
- <span className="text-zinc-500">Move to:</span>
166
- <select
167
- value={orphanMappings[o.listId] ?? ''}
168
- onChange={(e) => setOrphanMappings((prev) => ({ ...prev, [o.listId]: e.target.value }))}
169
- className="flex-1 rounded border border-zinc-700 bg-zinc-800 px-2 py-1.5 text-zinc-200 outline-none focus:border-zinc-500"
170
- >
171
- <option value="">Select destination...</option>
172
- {listIds.map((id) => (
173
- <option key={id} value={id}>{id}</option>
174
- ))}
175
- </select>
176
- </div>
177
- {o.scopeFiles.length <= 5 && (
178
- <div className="mt-2 space-y-0.5">
179
- {o.scopeFiles.map((f) => (
180
- <p key={f} className="font-mono text-[10px] text-zinc-500">{f}</p>
181
- ))}
182
- </div>
183
- )}
184
- </div>
185
- ))}
186
- </div>
187
- </Section>
188
- )}
189
-
190
- {/* No impact */}
191
- {plan.removedLists.length === 0 &&
192
- plan.addedLists.length === 0 &&
193
- plan.lostEdges.length === 0 &&
194
- plan.orphanedScopes.length === 0 && (
195
- <div className="flex items-center gap-2 rounded border border-emerald-500/30 bg-emerald-500/10 p-3 text-emerald-400">
196
- <CheckCircle2 className="h-4 w-4" />
197
- <span>No migration needed — configs are compatible</span>
198
- </div>
199
- )}
200
- </>
201
- )}
202
- </div>
203
- )}
204
- </div>
205
-
206
- {/* Footer */}
207
- <div className="flex items-center justify-end gap-2 border-t border-zinc-800 px-5 py-4">
208
- <Dialog.Close className="rounded px-3 py-1.5 text-xs text-zinc-400 hover:bg-zinc-800 hover:text-zinc-200">
209
- Cancel
210
- </Dialog.Close>
211
- {plan?.valid && (
212
- <button
213
- onClick={handleApply}
214
- disabled={!allOrphansMapped}
215
- className="flex items-center gap-1.5 rounded bg-emerald-600 px-4 py-1.5 text-xs font-medium text-white hover:bg-emerald-500 disabled:opacity-40"
216
- >
217
- <CheckCircle2 className="h-3.5 w-3.5" />
218
- Apply Migration
219
- </button>
220
- )}
221
- </div>
222
- </Dialog.Content>
223
- </Dialog.Portal>
224
- </Dialog.Root>
225
- );
226
- }
227
-
228
- // ─── Sub-components ─────────────────────────────────────
229
-
230
- function Section({ title, children }: { title: string; children: React.ReactNode }) {
231
- return (
232
- <div>
233
- <h4 className="mb-2 text-[10px] font-semibold uppercase tracking-wider text-zinc-500">{title}</h4>
234
- {children}
235
- </div>
236
- );
237
- }
@@ -1,188 +0,0 @@
1
- import { useMemo } from 'react';
2
- import { ArrowRight, ArrowLeft, CornerRightDown, Info } from 'lucide-react';
3
- import type { WorkflowEdge, WorkflowList } from '../../../shared/workflow-config';
4
-
5
- // ─── Types ──────────────────────────────────────────────
6
-
7
- interface MovementRulesPanelProps {
8
- edge: WorkflowEdge;
9
- lists: WorkflowList[];
10
- }
11
-
12
- // ─── Component ──────────────────────────────────────────
13
-
14
- export function MovementRulesPanel({ edge, lists }: MovementRulesPanelProps) {
15
- const sortedLists = useMemo(
16
- () => [...lists].sort((a, b) => a.order - b.order),
17
- [lists],
18
- );
19
-
20
- const fromList = lists.find((l) => l.id === edge.from);
21
- const toList = lists.find((l) => l.id === edge.to);
22
- const fromOrder = fromList?.order ?? -1;
23
- const toOrder = toList?.order ?? -1;
24
-
25
- if (edge.direction === 'shortcut') {
26
- return <ShortcutRules sortedLists={sortedLists} fromOrder={fromOrder} toOrder={toOrder} edge={edge} />;
27
- }
28
-
29
- if (edge.direction === 'backward') {
30
- return <BackwardRules edge={edge} fromLabel={fromList?.label ?? edge.from} toLabel={toList?.label ?? edge.to} />;
31
- }
32
-
33
- return <ForwardRules edge={edge} fromLabel={fromList?.label ?? edge.from} toLabel={toList?.label ?? edge.to} />;
34
- }
35
-
36
- // ─── Sub-panels ─────────────────────────────────────────
37
-
38
- function ShortcutRules({ sortedLists, fromOrder, toOrder, edge }: {
39
- sortedLists: WorkflowList[];
40
- fromOrder: number;
41
- toOrder: number;
42
- edge: WorkflowEdge;
43
- }) {
44
- const skippedLists = sortedLists.filter(
45
- (l) => l.order > Math.min(fromOrder, toOrder) && l.order < Math.max(fromOrder, toOrder),
46
- );
47
-
48
- return (
49
- <div className="space-y-2">
50
- <RuleHeader icon={CornerRightDown} color="#6366f1" label="Shortcut — Skip Rules" />
51
- {/* Mini diagram */}
52
- <div className="flex items-center gap-1 rounded border border-zinc-800 bg-zinc-950/50 px-2.5 py-2 overflow-x-auto">
53
- {sortedLists.map((list, i) => {
54
- const isFrom = list.id === edge.from;
55
- const isTo = list.id === edge.to;
56
- const isSkipped = skippedLists.some((s) => s.id === list.id);
57
- return (
58
- <div key={list.id} className="flex items-center gap-1">
59
- <span
60
- className="rounded px-1.5 py-0.5 text-[8px] font-medium whitespace-nowrap"
61
- style={{
62
- backgroundColor: isFrom || isTo ? '#6366f120' : isSkipped ? '#27272a' : '#18181b',
63
- color: isFrom || isTo ? '#818cf8' : isSkipped ? '#52525b' : '#71717a',
64
- border: isFrom || isTo ? '1px solid #6366f140' : '1px solid transparent',
65
- textDecoration: isSkipped ? 'line-through' : 'none',
66
- }}
67
- >
68
- {list.label}
69
- </span>
70
- {i < sortedLists.length - 1 && (
71
- <span className="text-[8px] text-zinc-700">›</span>
72
- )}
73
- </div>
74
- );
75
- })}
76
- </div>
77
- {skippedLists.length > 0 ? (
78
- <p className="text-[9px] text-zinc-500">
79
- <span className="text-indigo-400">{edge.from}</span>
80
- {' → '}
81
- <span className="text-indigo-400">{edge.to}</span>
82
- {' skips '}
83
- <span className="text-zinc-400">{skippedLists.map((l) => l.label).join(', ')}</span>
84
- </p>
85
- ) : (
86
- <p className="text-[9px] text-zinc-500">No intermediate lists are skipped.</p>
87
- )}
88
- </div>
89
- );
90
- }
91
-
92
- function BackwardRules({ edge, fromLabel, toLabel }: {
93
- edge: WorkflowEdge;
94
- fromLabel: string;
95
- toLabel: string;
96
- }) {
97
- const suggestedItems = [
98
- 'Issue documented',
99
- 'Fix scope created',
100
- 'Root cause identified',
101
- ];
102
-
103
- return (
104
- <div className="space-y-2">
105
- <RuleHeader icon={ArrowLeft} color="#f59e0b" label="Backward — Revert Rules" />
106
- <div className="flex items-center gap-2 rounded border border-amber-500/20 bg-amber-500/5 px-2.5 py-2">
107
- <span className="rounded bg-amber-500/20 px-1.5 py-0.5 text-[9px] font-medium text-amber-400">
108
- {fromLabel}
109
- </span>
110
- <svg width="24" height="12" viewBox="0 0 24 12" className="shrink-0">
111
- <line x1="20" y1="6" x2="4" y2="6" stroke="#f59e0b" strokeWidth="1.5" strokeDasharray="2 2" />
112
- <polygon points="4,6 8,3 8,9" fill="#f59e0b" />
113
- </svg>
114
- <span className="rounded bg-amber-500/20 px-1.5 py-0.5 text-[9px] font-medium text-amber-400">
115
- {toLabel}
116
- </span>
117
- <span className="ml-auto rounded bg-amber-500/15 px-1.5 py-0.5 text-[8px] font-semibold text-amber-400">
118
- REPAIR
119
- </span>
120
- </div>
121
- <p className="text-[9px] text-zinc-500">
122
- {fromLabel} → {toLabel} is a <span className="text-amber-400">repair</span> operation.
123
- Scopes move backward for rework.
124
- </p>
125
- {/* Suggested checklist items */}
126
- {(!edge.checklist || edge.checklist.length === 0) && (
127
- <div className="rounded border border-zinc-800 bg-zinc-950/50 p-2">
128
- <div className="flex items-center gap-1 mb-1.5">
129
- <Info className="h-3 w-3 text-zinc-600" />
130
- <span className="text-[9px] font-medium text-zinc-500">Suggested checklist items</span>
131
- </div>
132
- <ul className="space-y-0.5">
133
- {suggestedItems.map((item) => (
134
- <li key={item} className="text-[9px] text-zinc-600 flex items-center gap-1.5">
135
- <span className="h-1 w-1 rounded-full bg-zinc-700 shrink-0" />
136
- {item}
137
- </li>
138
- ))}
139
- </ul>
140
- </div>
141
- )}
142
- </div>
143
- );
144
- }
145
-
146
- function ForwardRules({ edge, fromLabel, toLabel }: {
147
- edge: WorkflowEdge;
148
- fromLabel: string;
149
- toLabel: string;
150
- }) {
151
- return (
152
- <div className="space-y-2">
153
- <RuleHeader icon={ArrowRight} color="#22c55e" label="Forward — Progression" />
154
- <div className="flex items-center gap-2 rounded border border-emerald-500/20 bg-emerald-500/5 px-2.5 py-2">
155
- <span className="rounded bg-emerald-500/20 px-1.5 py-0.5 text-[9px] font-medium text-emerald-400">
156
- {fromLabel}
157
- </span>
158
- <svg width="24" height="12" viewBox="0 0 24 12" className="shrink-0">
159
- <line x1="4" y1="6" x2="20" y2="6" stroke="#22c55e" strokeWidth="1.5" />
160
- <polygon points="20,6 16,3 16,9" fill="#22c55e" />
161
- </svg>
162
- <span className="rounded bg-emerald-500/20 px-1.5 py-0.5 text-[9px] font-medium text-emerald-400">
163
- {toLabel}
164
- </span>
165
- </div>
166
- {edge.dispatchOnly && (
167
- <p className="text-[9px] text-zinc-500">
168
- This transition requires a <span className="text-cyan-400">skill command</span> to trigger.
169
- </p>
170
- )}
171
- </div>
172
- );
173
- }
174
-
175
- // ─── Shared ─────────────────────────────────────────────
176
-
177
- function RuleHeader({ icon: Icon, color, label }: {
178
- icon: React.ComponentType<{ className?: string; style?: React.CSSProperties }>;
179
- color: string;
180
- label: string;
181
- }) {
182
- return (
183
- <div className="flex items-center gap-1.5">
184
- <Icon className="h-3 w-3" style={{ color }} />
185
- <span className="text-[10px] font-semibold" style={{ color }}>{label}</span>
186
- </div>
187
- );
188
- }
@@ -1,245 +0,0 @@
1
- import { useMemo } from 'react';
2
- import { X, Star, Package, Zap, GitBranch, Key, Shield, Terminal, Radio, Globe, ShieldCheck, AlertTriangle, Cog, Eye } from 'lucide-react';
3
- import type { WorkflowList, WorkflowHook, WorkflowEdge, HookCategory, HookEnforcement } from '../../../shared/workflow-config';
4
- import { getHookEnforcement } from '../../../shared/workflow-config';
5
-
6
- interface NodeDetailPanelProps {
7
- list: WorkflowList | null;
8
- hooks: WorkflowHook[];
9
- connectedEdges: WorkflowEdge[];
10
- onClose: () => void;
11
- onHookClick?: (hook: WorkflowHook) => void;
12
- }
13
-
14
- const CATEGORY_CONFIG: Record<HookCategory, { icon: typeof Shield; color: string; label: string }> = {
15
- guard: { icon: ShieldCheck, color: '#ef4444', label: 'Guards' },
16
- gate: { icon: AlertTriangle, color: '#f59e0b', label: 'Gates' },
17
- lifecycle: { icon: Cog, color: '#3b82f6', label: 'Lifecycle' },
18
- observer: { icon: Eye, color: '#6b7280', label: 'Observers' },
19
- };
20
-
21
- const CATEGORY_ORDER: HookCategory[] = ['guard', 'gate', 'lifecycle', 'observer'];
22
-
23
- const ENFORCEMENT_COLORS: Record<HookEnforcement, string> = {
24
- blocker: '#ef4444',
25
- advisor: '#f59e0b',
26
- operator: '#3b82f6',
27
- silent: '#6b7280',
28
- };
29
-
30
- export function NodeDetailPanel({ list, hooks, connectedEdges, onClose, onHookClick }: NodeDetailPanelProps) {
31
- if (!list) return null;
32
-
33
- const inbound = connectedEdges.filter((e) => e.to === list.id);
34
- const outbound = connectedEdges.filter((e) => e.from === list.id);
35
-
36
- // Group hooks by category
37
- const grouped = useMemo(() => {
38
- const groups = new Map<HookCategory, WorkflowHook[]>();
39
- for (const hook of hooks) {
40
- const existing = groups.get(hook.category);
41
- if (existing) existing.push(hook);
42
- else groups.set(hook.category, [hook]);
43
- }
44
- return groups;
45
- }, [hooks]);
46
-
47
- return (
48
- <div className="flex h-full w-80 shrink-0 flex-col rounded-lg border border-zinc-800 bg-zinc-900/95 backdrop-blur">
49
- {/* Header */}
50
- <div className="flex items-center justify-between border-b border-zinc-800 px-4 py-3">
51
- <div className="flex items-center gap-2">
52
- <div className="h-3 w-3 rounded-full" style={{ backgroundColor: list.hex }} />
53
- <span className="text-sm font-medium">{list.label}</span>
54
- </div>
55
- <button onClick={onClose} className="rounded p-1 text-zinc-500 hover:bg-zinc-800 hover:text-zinc-300">
56
- <X className="h-4 w-4" />
57
- </button>
58
- </div>
59
-
60
- {/* Content */}
61
- <div className="flex-1 space-y-4 overflow-y-auto p-4 text-xs">
62
- {/* Properties */}
63
- <Section title="Properties">
64
- <PropRow label="ID" value={list.id} />
65
- <PropRow label="Order" value={String(list.order)} />
66
- {list.group && <PropRow label="Group" value={list.group} />}
67
- <PropRow label="Color" value={list.hex} />
68
- </Section>
69
-
70
- {/* Flags */}
71
- <Section title="Flags">
72
- <div className="flex flex-wrap gap-2">
73
- {list.isEntryPoint && <FlagBadge icon={Star} label="Entry Point" color={list.hex} />}
74
- {list.supportsBatch && <FlagBadge icon={Package} label="Batch" color="#22c55e" />}
75
- {list.supportsSprint && <FlagBadge icon={Zap} label="Sprint" color="#6366f1" />}
76
- {list.gitBranch && <FlagBadge icon={GitBranch} label={list.gitBranch} color="#f59e0b" />}
77
- {list.sessionKey && <FlagBadge icon={Key} label={list.sessionKey} color="#8b5cf6" />}
78
- </div>
79
- {!list.isEntryPoint && !list.supportsBatch && !list.supportsSprint && !list.gitBranch && !list.sessionKey && (
80
- <span className="text-zinc-600">None</span>
81
- )}
82
- </Section>
83
-
84
- {/* Inbound edges */}
85
- <Section title={`Inbound (${inbound.length})`}>
86
- {inbound.length === 0 ? (
87
- <span className="text-zinc-600">None</span>
88
- ) : (
89
- inbound.map((e) => <EdgeRow key={`${e.from}:${e.to}`} edge={e} showField="from" />)
90
- )}
91
- </Section>
92
-
93
- {/* Outbound edges */}
94
- <Section title={`Outbound (${outbound.length})`}>
95
- {outbound.length === 0 ? (
96
- <span className="text-zinc-600">None</span>
97
- ) : (
98
- outbound.map((e) => <EdgeRow key={`${e.from}:${e.to}`} edge={e} showField="to" />)
99
- )}
100
- </Section>
101
-
102
- {/* Hooks grouped by category */}
103
- {hooks.length > 0 && (
104
- <Section title={`Hooks (${hooks.length})`}>
105
- <div className="space-y-3">
106
- {CATEGORY_ORDER.map((cat) => {
107
- const catHooks = grouped.get(cat);
108
- if (!catHooks?.length) return null;
109
- const config = CATEGORY_CONFIG[cat];
110
- const CatIcon = config.icon;
111
- return (
112
- <div key={cat}>
113
- <div className="mb-1.5 flex items-center gap-1.5">
114
- <CatIcon className="h-2.5 w-2.5" style={{ color: config.color }} />
115
- <span className="text-[9px] font-semibold uppercase tracking-wider" style={{ color: config.color }}>
116
- {config.label}
117
- </span>
118
- </div>
119
- {catHooks.map((h) => (
120
- <NodeHookDetail key={h.id} hook={h} onClick={onHookClick} />
121
- ))}
122
- </div>
123
- );
124
- })}
125
- </div>
126
- </Section>
127
- )}
128
- </div>
129
- </div>
130
- );
131
- }
132
-
133
- // ─── Sub-components ─────────────────────────────────────
134
-
135
- function Section({ title, children }: { title: string; children: React.ReactNode }) {
136
- return (
137
- <div>
138
- <h4 className="mb-2 text-[10px] font-semibold uppercase tracking-wider text-zinc-500">{title}</h4>
139
- <div className="space-y-1.5">{children}</div>
140
- </div>
141
- );
142
- }
143
-
144
- function PropRow({ label, value }: { label: string; value: string }) {
145
- return (
146
- <div className="flex items-center justify-between">
147
- <span className="text-zinc-500">{label}</span>
148
- <span className="font-mono text-zinc-300">{value}</span>
149
- </div>
150
- );
151
- }
152
-
153
- function FlagBadge({ icon: Icon, label, color }: { icon: React.ComponentType<{ className?: string }>; label: string; color: string }) {
154
- return (
155
- <span className="flex items-center gap-1 rounded px-1.5 py-0.5 text-[10px]" style={{ backgroundColor: `${color}15`, color }}>
156
- <Icon className="h-3 w-3" />
157
- {label}
158
- </span>
159
- );
160
- }
161
-
162
- const TIMING_COLORS: Record<string, string> = {
163
- before: '#eab308',
164
- after: '#3b82f6',
165
- };
166
-
167
- const TYPE_COLORS: Record<string, string> = {
168
- shell: '#22c55e',
169
- event: '#a855f7',
170
- webhook: '#f97316',
171
- };
172
-
173
- const TYPE_ICONS: Record<string, typeof Terminal> = {
174
- shell: Terminal,
175
- event: Radio,
176
- webhook: Globe,
177
- };
178
-
179
- function NodeHookDetail({ hook, onClick }: { hook: WorkflowHook; onClick?: (hook: WorkflowHook) => void }) {
180
- const timingColor = TIMING_COLORS[hook.timing] ?? '#3b82f6';
181
- const typeColor = TYPE_COLORS[hook.type] ?? '#22c55e';
182
- const TypeIcon = TYPE_ICONS[hook.type] ?? Terminal;
183
- const enforcement = getHookEnforcement(hook);
184
- const enforcementColor = ENFORCEMENT_COLORS[enforcement];
185
- const catConfig = CATEGORY_CONFIG[hook.category];
186
- const CatIcon = catConfig.icon;
187
-
188
- return (
189
- <button
190
- onClick={() => onClick?.(hook)}
191
- className="w-full rounded border bg-zinc-950/50 p-2 text-left transition-colors hover:border-zinc-600 hover:bg-zinc-900/70"
192
- style={{ borderColor: hook.blocking ? '#ef444466' : '#27272a' }}
193
- >
194
- <div className="flex items-center gap-2">
195
- <CatIcon className="h-2.5 w-2.5" style={{ color: catConfig.color }} />
196
- <span className="text-zinc-300">{hook.label}</span>
197
- <span
198
- className="ml-auto rounded px-1 py-0.5 text-[8px] font-bold uppercase"
199
- style={{ backgroundColor: `${enforcementColor}20`, color: enforcementColor }}
200
- >
201
- {enforcement}
202
- </span>
203
- </div>
204
- <div className="mt-1.5 flex flex-wrap items-center gap-1">
205
- <span
206
- className="rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase"
207
- style={{ backgroundColor: `${timingColor}20`, color: timingColor }}
208
- >
209
- {hook.timing}
210
- </span>
211
- <span
212
- className="flex items-center gap-0.5 rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase"
213
- style={{ backgroundColor: `${typeColor}20`, color: typeColor }}
214
- >
215
- <TypeIcon className="h-2.5 w-2.5" />
216
- {hook.type}
217
- </span>
218
- </div>
219
- <div className="mt-1.5 flex items-center gap-1.5 rounded border border-zinc-800 bg-zinc-900 px-2 py-1 font-mono text-[10px] text-zinc-400">
220
- <TypeIcon className="h-3 w-3 shrink-0 text-zinc-600" />
221
- <span className="truncate">{hook.target}</span>
222
- </div>
223
- {hook.description && <p className="mt-1 text-zinc-500">{hook.description}</p>}
224
- </button>
225
- );
226
- }
227
-
228
- const DIRECTION_COLORS: Record<string, string> = {
229
- forward: '#22c55e',
230
- backward: '#f59e0b',
231
- shortcut: '#6366f1',
232
- };
233
-
234
- function EdgeRow({ edge, showField }: { edge: WorkflowEdge; showField: 'from' | 'to' }) {
235
- const color = DIRECTION_COLORS[edge.direction] ?? '#22c55e';
236
- return (
237
- <div className="flex items-center gap-2 rounded border border-zinc-800/50 bg-zinc-950/30 px-2 py-1.5">
238
- <span className="rounded px-1 py-0.5 text-[9px] uppercase" style={{ backgroundColor: `${color}20`, color }}>
239
- {edge.direction}
240
- </span>
241
- <span className="text-zinc-400">{showField === 'from' ? edge.from : edge.to}</span>
242
- <span className="ml-auto text-zinc-600">{edge.label}</span>
243
- </div>
244
- );
245
- }