orbital-command 0.1.4 → 0.3.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 (380) hide show
  1. package/bin/orbital.js +676 -53
  2. package/dist/assets/PrimitivesConfig-CrmQXYh4.js +32 -0
  3. package/dist/assets/QualityGates-BbasOsF3.js +21 -0
  4. package/dist/assets/SessionTimeline-CGeJsVvy.js +1 -0
  5. package/dist/assets/Settings-oiM496mc.js +12 -0
  6. package/dist/assets/SourceControl-B1fP2nJL.js +41 -0
  7. package/dist/assets/WorkflowVisualizer-CWLYf-f0.js +74 -0
  8. package/dist/assets/arrow-down-CPy85_J6.js +6 -0
  9. package/dist/assets/charts-DbDg0Psc.js +68 -0
  10. package/dist/assets/circle-x-Cwz6ZQDV.js +6 -0
  11. package/dist/assets/file-text-C46Xr65c.js +6 -0
  12. package/dist/assets/formatDistanceToNow-BMqsSP44.js +1 -0
  13. package/dist/assets/globe-Cn2yNZUD.js +6 -0
  14. package/dist/assets/index-Aj4sV8Al.css +1 -0
  15. package/dist/assets/index-Bc9dK3MW.js +354 -0
  16. package/dist/assets/key-OPaNTWJ5.js +6 -0
  17. package/dist/assets/minus-GMsbpKym.js +6 -0
  18. package/dist/assets/shield-DwAFkDYI.js +6 -0
  19. package/dist/assets/ui-BmsSg9jU.js +53 -0
  20. package/dist/assets/useWorkflowEditor-BJkTX_NR.js +16 -0
  21. package/dist/assets/{vendor-Dzv9lrRc.js → vendor-Bqt8AJn2.js} +1 -1
  22. package/dist/assets/zap-DfbUoOty.js +11 -0
  23. package/dist/favicon.svg +1 -0
  24. package/dist/index.html +6 -5
  25. package/dist/server/server/__tests__/data-routes.test.js +124 -0
  26. package/dist/server/server/__tests__/helpers/db.js +17 -0
  27. package/dist/server/server/__tests__/helpers/mock-emitter.js +8 -0
  28. package/dist/server/server/__tests__/scope-routes.test.js +137 -0
  29. package/dist/server/server/__tests__/sprint-routes.test.js +102 -0
  30. package/dist/server/server/__tests__/workflow-routes.test.js +107 -0
  31. package/dist/server/server/config-migrator.js +138 -0
  32. package/dist/server/server/config.js +17 -2
  33. package/dist/server/server/database.js +27 -12
  34. package/dist/server/server/global-config.js +143 -0
  35. package/dist/server/server/index.js +882 -252
  36. package/dist/server/server/init.js +579 -194
  37. package/dist/server/server/launch.js +29 -0
  38. package/dist/server/server/manifest-types.js +8 -0
  39. package/dist/server/server/manifest.js +454 -0
  40. package/dist/server/server/migrate-legacy.js +229 -0
  41. package/dist/server/server/parsers/event-parser.test.js +117 -0
  42. package/dist/server/server/parsers/scope-parser.js +74 -28
  43. package/dist/server/server/parsers/scope-parser.test.js +230 -0
  44. package/dist/server/server/project-context.js +255 -0
  45. package/dist/server/server/project-emitter.js +41 -0
  46. package/dist/server/server/project-manager.js +297 -0
  47. package/dist/server/server/routes/config-routes.js +1 -3
  48. package/dist/server/server/routes/data-routes.js +22 -110
  49. package/dist/server/server/routes/dispatch-routes.js +15 -9
  50. package/dist/server/server/routes/git-routes.js +74 -0
  51. package/dist/server/server/routes/manifest-routes.js +319 -0
  52. package/dist/server/server/routes/scope-routes.js +37 -23
  53. package/dist/server/server/routes/sync-routes.js +134 -0
  54. package/dist/server/server/routes/version-routes.js +1 -15
  55. package/dist/server/server/routes/workflow-routes.js +9 -3
  56. package/dist/server/server/schema.js +2 -0
  57. package/dist/server/server/services/batch-orchestrator.js +26 -16
  58. package/dist/server/server/services/claude-session-service.js +17 -14
  59. package/dist/server/server/services/deploy-service.test.js +119 -0
  60. package/dist/server/server/services/event-service.js +64 -1
  61. package/dist/server/server/services/event-service.test.js +191 -0
  62. package/dist/server/server/services/gate-service.test.js +105 -0
  63. package/dist/server/server/services/git-service.js +108 -4
  64. package/dist/server/server/services/github-service.js +110 -2
  65. package/dist/server/server/services/readiness-service.test.js +190 -0
  66. package/dist/server/server/services/scope-cache.js +5 -1
  67. package/dist/server/server/services/scope-cache.test.js +142 -0
  68. package/dist/server/server/services/scope-service.js +217 -126
  69. package/dist/server/server/services/scope-service.test.js +137 -0
  70. package/dist/server/server/services/sprint-orchestrator.js +7 -6
  71. package/dist/server/server/services/sprint-service.js +21 -1
  72. package/dist/server/server/services/sprint-service.test.js +238 -0
  73. package/dist/server/server/services/sync-service.js +434 -0
  74. package/dist/server/server/services/sync-types.js +2 -0
  75. package/dist/server/server/services/telemetry-service.js +143 -0
  76. package/dist/server/server/services/workflow-service.js +26 -5
  77. package/dist/server/server/services/workflow-service.test.js +159 -0
  78. package/dist/server/server/settings-sync.js +284 -0
  79. package/dist/server/server/update-planner.js +279 -0
  80. package/dist/server/server/utils/cc-hooks-parser.js +3 -0
  81. package/dist/server/server/utils/cc-hooks-parser.test.js +86 -0
  82. package/dist/server/server/utils/dispatch-utils.js +77 -20
  83. package/dist/server/server/utils/dispatch-utils.test.js +182 -0
  84. package/dist/server/server/utils/logger.js +37 -3
  85. package/dist/server/server/utils/package-info.js +30 -0
  86. package/dist/server/server/utils/route-helpers.js +10 -0
  87. package/dist/server/server/utils/terminal-launcher.js +79 -25
  88. package/dist/server/server/utils/worktree-manager.js +13 -4
  89. package/dist/server/server/validator.js +230 -0
  90. package/dist/server/server/watchers/global-watcher.js +63 -0
  91. package/dist/server/server/watchers/scope-watcher.js +27 -12
  92. package/dist/server/server/wizard/config-editor.js +237 -0
  93. package/dist/server/server/wizard/detect.js +96 -0
  94. package/dist/server/server/wizard/doctor.js +115 -0
  95. package/dist/server/server/wizard/index.js +155 -0
  96. package/dist/server/server/wizard/phases/confirm.js +39 -0
  97. package/dist/server/server/wizard/phases/project-setup.js +90 -0
  98. package/dist/server/server/wizard/phases/setup-wizard.js +66 -0
  99. package/dist/server/server/wizard/phases/welcome.js +35 -0
  100. package/dist/server/server/wizard/phases/workflow-setup.js +22 -0
  101. package/dist/server/server/wizard/types.js +29 -0
  102. package/dist/server/server/wizard/ui.js +74 -0
  103. package/dist/server/shared/__fixtures__/workflow-configs.js +75 -0
  104. package/dist/server/shared/default-workflow.json +65 -0
  105. package/dist/server/shared/onboarding-tour.test.js +81 -0
  106. package/dist/server/shared/project-colors.js +24 -0
  107. package/dist/server/shared/workflow-config.test.js +84 -0
  108. package/dist/server/shared/workflow-engine.test.js +302 -0
  109. package/dist/server/shared/workflow-normalizer.js +101 -0
  110. package/dist/server/shared/workflow-normalizer.test.js +100 -0
  111. package/dist/server/src/components/onboarding/tour-steps.js +84 -0
  112. package/package.json +20 -15
  113. package/schemas/orbital.config.schema.json +16 -1
  114. package/scripts/postinstall.js +55 -7
  115. package/server/__tests__/data-routes.test.ts +149 -0
  116. package/server/__tests__/helpers/db.ts +19 -0
  117. package/server/__tests__/helpers/mock-emitter.ts +10 -0
  118. package/server/__tests__/scope-routes.test.ts +157 -0
  119. package/server/__tests__/sprint-routes.test.ts +118 -0
  120. package/server/__tests__/workflow-routes.test.ts +120 -0
  121. package/server/config-migrator.ts +163 -0
  122. package/server/config.ts +26 -2
  123. package/server/database.ts +35 -18
  124. package/server/global-config.ts +200 -0
  125. package/server/index.ts +975 -287
  126. package/server/init.ts +625 -182
  127. package/server/launch.ts +32 -0
  128. package/server/manifest-types.ts +145 -0
  129. package/server/manifest.ts +494 -0
  130. package/server/migrate-legacy.ts +290 -0
  131. package/server/parsers/event-parser.test.ts +135 -0
  132. package/server/parsers/scope-parser.test.ts +270 -0
  133. package/server/parsers/scope-parser.ts +79 -31
  134. package/server/project-context.ts +309 -0
  135. package/server/project-emitter.ts +50 -0
  136. package/server/project-manager.ts +369 -0
  137. package/server/routes/config-routes.ts +3 -5
  138. package/server/routes/data-routes.ts +28 -141
  139. package/server/routes/dispatch-routes.ts +19 -11
  140. package/server/routes/git-routes.ts +77 -0
  141. package/server/routes/manifest-routes.ts +388 -0
  142. package/server/routes/scope-routes.ts +29 -25
  143. package/server/routes/sync-routes.ts +175 -0
  144. package/server/routes/version-routes.ts +1 -16
  145. package/server/routes/workflow-routes.ts +9 -3
  146. package/server/schema.ts +2 -0
  147. package/server/services/batch-orchestrator.ts +24 -16
  148. package/server/services/claude-session-service.ts +16 -14
  149. package/server/services/deploy-service.test.ts +145 -0
  150. package/server/services/deploy-service.ts +2 -2
  151. package/server/services/event-service.test.ts +242 -0
  152. package/server/services/event-service.ts +92 -3
  153. package/server/services/gate-service.test.ts +131 -0
  154. package/server/services/gate-service.ts +2 -2
  155. package/server/services/git-service.ts +137 -4
  156. package/server/services/github-service.ts +120 -2
  157. package/server/services/readiness-service.test.ts +217 -0
  158. package/server/services/scope-cache.test.ts +167 -0
  159. package/server/services/scope-cache.ts +4 -1
  160. package/server/services/scope-service.test.ts +169 -0
  161. package/server/services/scope-service.ts +220 -126
  162. package/server/services/sprint-orchestrator.ts +7 -7
  163. package/server/services/sprint-service.test.ts +271 -0
  164. package/server/services/sprint-service.ts +27 -3
  165. package/server/services/sync-service.ts +482 -0
  166. package/server/services/sync-types.ts +77 -0
  167. package/server/services/telemetry-service.ts +195 -0
  168. package/server/services/workflow-service.test.ts +190 -0
  169. package/server/services/workflow-service.ts +29 -9
  170. package/server/settings-sync.ts +359 -0
  171. package/server/update-planner.ts +346 -0
  172. package/server/utils/cc-hooks-parser.test.ts +96 -0
  173. package/server/utils/cc-hooks-parser.ts +4 -0
  174. package/server/utils/dispatch-utils.test.ts +245 -0
  175. package/server/utils/dispatch-utils.ts +97 -27
  176. package/server/utils/logger.ts +40 -3
  177. package/server/utils/package-info.ts +32 -0
  178. package/server/utils/route-helpers.ts +12 -0
  179. package/server/utils/terminal-launcher.ts +85 -25
  180. package/server/utils/worktree-manager.ts +9 -4
  181. package/server/validator.ts +270 -0
  182. package/server/watchers/global-watcher.ts +77 -0
  183. package/server/watchers/scope-watcher.ts +21 -9
  184. package/server/wizard/config-editor.ts +248 -0
  185. package/server/wizard/detect.ts +104 -0
  186. package/server/wizard/doctor.ts +114 -0
  187. package/server/wizard/index.ts +187 -0
  188. package/server/wizard/phases/confirm.ts +45 -0
  189. package/server/wizard/phases/project-setup.ts +106 -0
  190. package/server/wizard/phases/setup-wizard.ts +78 -0
  191. package/server/wizard/phases/welcome.ts +43 -0
  192. package/server/wizard/phases/workflow-setup.ts +28 -0
  193. package/server/wizard/types.ts +56 -0
  194. package/server/wizard/ui.ts +93 -0
  195. package/shared/__fixtures__/workflow-configs.ts +80 -0
  196. package/shared/default-workflow.json +65 -0
  197. package/shared/onboarding-tour.test.ts +94 -0
  198. package/shared/project-colors.ts +24 -0
  199. package/shared/workflow-config.test.ts +111 -0
  200. package/shared/workflow-config.ts +7 -0
  201. package/shared/workflow-engine.test.ts +388 -0
  202. package/shared/workflow-normalizer.test.ts +119 -0
  203. package/shared/workflow-normalizer.ts +118 -0
  204. package/templates/hooks/end-session.sh +3 -1
  205. package/templates/hooks/orbital-emit.sh +2 -2
  206. package/templates/hooks/orbital-report-deploy.sh +4 -4
  207. package/templates/hooks/orbital-report-gates.sh +4 -4
  208. package/templates/hooks/orbital-scope-update.sh +1 -1
  209. package/templates/hooks/scope-create-cleanup.sh +2 -2
  210. package/templates/hooks/scope-create-gate.sh +0 -1
  211. package/templates/hooks/scope-helpers.sh +18 -0
  212. package/templates/hooks/scope-prepare.sh +66 -11
  213. package/templates/migrations/renames.json +1 -0
  214. package/templates/orbital.config.json +7 -2
  215. package/templates/settings-hooks.json +1 -1
  216. package/templates/skills/git-commit/SKILL.md +9 -4
  217. package/templates/skills/git-dev/SKILL.md +8 -3
  218. package/templates/skills/git-main/SKILL.md +8 -2
  219. package/templates/skills/git-production/SKILL.md +6 -2
  220. package/templates/skills/git-staging/SKILL.md +8 -3
  221. package/templates/skills/scope-create/SKILL.md +17 -3
  222. package/templates/skills/scope-fix-review/SKILL.md +6 -3
  223. package/templates/skills/scope-implement/SKILL.md +4 -1
  224. package/templates/skills/scope-post-review/SKILL.md +63 -5
  225. package/templates/skills/scope-pre-review/SKILL.md +5 -2
  226. package/templates/skills/scope-verify/SKILL.md +5 -3
  227. package/templates/skills/test-code-review/SKILL.md +41 -33
  228. package/templates/skills/test-scaffold/SKILL.md +222 -0
  229. package/dist/assets/WorkflowVisualizer-BZ21PIIF.js +0 -84
  230. package/dist/assets/charts-D__PA1zp.js +0 -72
  231. package/dist/assets/index-D1G6i0nS.css +0 -1
  232. package/dist/assets/index-DpItvKpf.js +0 -419
  233. package/dist/assets/ui-BvF022GT.js +0 -53
  234. package/index.html +0 -15
  235. package/postcss.config.js +0 -6
  236. package/src/App.tsx +0 -33
  237. package/src/components/AgentBadge.tsx +0 -40
  238. package/src/components/BatchPreflightModal.tsx +0 -115
  239. package/src/components/CardDisplayToggle.tsx +0 -74
  240. package/src/components/ColumnHeaderActions.tsx +0 -55
  241. package/src/components/ColumnMenu.tsx +0 -99
  242. package/src/components/DeployHistory.tsx +0 -141
  243. package/src/components/DispatchModal.tsx +0 -164
  244. package/src/components/DispatchPopover.tsx +0 -139
  245. package/src/components/DragOverlay.tsx +0 -25
  246. package/src/components/DriftSidebar.tsx +0 -140
  247. package/src/components/EnvironmentStrip.tsx +0 -88
  248. package/src/components/ErrorBoundary.tsx +0 -62
  249. package/src/components/FilterChip.tsx +0 -105
  250. package/src/components/GateIndicator.tsx +0 -33
  251. package/src/components/IdeaDetailModal.tsx +0 -190
  252. package/src/components/IdeaFormDialog.tsx +0 -113
  253. package/src/components/KanbanColumn.tsx +0 -201
  254. package/src/components/MarkdownRenderer.tsx +0 -114
  255. package/src/components/NeonGrid.tsx +0 -128
  256. package/src/components/PromotionQueue.tsx +0 -89
  257. package/src/components/ScopeCard.tsx +0 -234
  258. package/src/components/ScopeDetailModal.tsx +0 -255
  259. package/src/components/ScopeFilterBar.tsx +0 -152
  260. package/src/components/SearchInput.tsx +0 -102
  261. package/src/components/SessionPanel.tsx +0 -335
  262. package/src/components/SprintContainer.tsx +0 -303
  263. package/src/components/SprintDependencyDialog.tsx +0 -78
  264. package/src/components/SprintPreflightModal.tsx +0 -138
  265. package/src/components/StatusBar.tsx +0 -168
  266. package/src/components/SwimCell.tsx +0 -67
  267. package/src/components/SwimLaneRow.tsx +0 -94
  268. package/src/components/SwimlaneBoardView.tsx +0 -108
  269. package/src/components/VersionBadge.tsx +0 -139
  270. package/src/components/ViewModeSelector.tsx +0 -114
  271. package/src/components/config/AgentChip.tsx +0 -53
  272. package/src/components/config/AgentCreateDialog.tsx +0 -321
  273. package/src/components/config/AgentEditor.tsx +0 -175
  274. package/src/components/config/DirectoryTree.tsx +0 -582
  275. package/src/components/config/FileEditor.tsx +0 -550
  276. package/src/components/config/HookChip.tsx +0 -50
  277. package/src/components/config/StageCard.tsx +0 -198
  278. package/src/components/config/TransitionZone.tsx +0 -173
  279. package/src/components/config/UnifiedWorkflowPipeline.tsx +0 -216
  280. package/src/components/config/WorkflowPipeline.tsx +0 -161
  281. package/src/components/source-control/BranchList.tsx +0 -93
  282. package/src/components/source-control/BranchPanel.tsx +0 -105
  283. package/src/components/source-control/CommitLog.tsx +0 -100
  284. package/src/components/source-control/CommitRow.tsx +0 -47
  285. package/src/components/source-control/GitHubPanel.tsx +0 -110
  286. package/src/components/source-control/GitHubSetupGuide.tsx +0 -52
  287. package/src/components/source-control/GitOverviewBar.tsx +0 -101
  288. package/src/components/source-control/PullRequestList.tsx +0 -69
  289. package/src/components/source-control/WorktreeList.tsx +0 -80
  290. package/src/components/ui/badge.tsx +0 -41
  291. package/src/components/ui/button.tsx +0 -55
  292. package/src/components/ui/card.tsx +0 -78
  293. package/src/components/ui/dialog.tsx +0 -94
  294. package/src/components/ui/popover.tsx +0 -33
  295. package/src/components/ui/scroll-area.tsx +0 -54
  296. package/src/components/ui/separator.tsx +0 -28
  297. package/src/components/ui/tabs.tsx +0 -52
  298. package/src/components/ui/toggle-switch.tsx +0 -35
  299. package/src/components/ui/tooltip.tsx +0 -27
  300. package/src/components/workflow/AddEdgeDialog.tsx +0 -217
  301. package/src/components/workflow/AddListDialog.tsx +0 -201
  302. package/src/components/workflow/ChecklistEditor.tsx +0 -239
  303. package/src/components/workflow/CommandPrefixManager.tsx +0 -118
  304. package/src/components/workflow/ConfigSettingsPanel.tsx +0 -189
  305. package/src/components/workflow/DirectionSelector.tsx +0 -133
  306. package/src/components/workflow/DispatchConfigPanel.tsx +0 -180
  307. package/src/components/workflow/EdgeDetailPanel.tsx +0 -236
  308. package/src/components/workflow/EdgePropertyEditor.tsx +0 -251
  309. package/src/components/workflow/EditToolbar.tsx +0 -138
  310. package/src/components/workflow/HookDetailPanel.tsx +0 -250
  311. package/src/components/workflow/HookExecutionLog.tsx +0 -24
  312. package/src/components/workflow/HookSourceModal.tsx +0 -129
  313. package/src/components/workflow/HooksDashboard.tsx +0 -363
  314. package/src/components/workflow/ListPropertyEditor.tsx +0 -251
  315. package/src/components/workflow/MigrationPreviewDialog.tsx +0 -237
  316. package/src/components/workflow/MovementRulesPanel.tsx +0 -188
  317. package/src/components/workflow/NodeDetailPanel.tsx +0 -245
  318. package/src/components/workflow/PresetSelector.tsx +0 -414
  319. package/src/components/workflow/SkillCommandBuilder.tsx +0 -174
  320. package/src/components/workflow/WorkflowEdgeComponent.tsx +0 -145
  321. package/src/components/workflow/WorkflowNode.tsx +0 -147
  322. package/src/components/workflow/graphLayout.ts +0 -186
  323. package/src/components/workflow/mergeHooks.ts +0 -85
  324. package/src/components/workflow/useEditHistory.ts +0 -88
  325. package/src/components/workflow/useWorkflowEditor.ts +0 -262
  326. package/src/components/workflow/validateConfig.ts +0 -70
  327. package/src/hooks/useActiveDispatches.ts +0 -198
  328. package/src/hooks/useBoardSettings.ts +0 -170
  329. package/src/hooks/useCardDisplay.ts +0 -57
  330. package/src/hooks/useCcHooks.ts +0 -24
  331. package/src/hooks/useConfigTree.ts +0 -51
  332. package/src/hooks/useEnforcementRules.ts +0 -46
  333. package/src/hooks/useEvents.ts +0 -59
  334. package/src/hooks/useFileEditor.ts +0 -165
  335. package/src/hooks/useGates.ts +0 -57
  336. package/src/hooks/useIdeaActions.ts +0 -53
  337. package/src/hooks/useKanbanDnd.ts +0 -410
  338. package/src/hooks/useOrbitalConfig.ts +0 -54
  339. package/src/hooks/usePipeline.ts +0 -47
  340. package/src/hooks/usePipelineData.ts +0 -338
  341. package/src/hooks/useReconnect.ts +0 -25
  342. package/src/hooks/useScopeFilters.ts +0 -125
  343. package/src/hooks/useScopeSessions.ts +0 -44
  344. package/src/hooks/useScopes.ts +0 -67
  345. package/src/hooks/useSearch.ts +0 -67
  346. package/src/hooks/useSettings.tsx +0 -187
  347. package/src/hooks/useSocket.ts +0 -25
  348. package/src/hooks/useSourceControl.ts +0 -105
  349. package/src/hooks/useSprintPreflight.ts +0 -55
  350. package/src/hooks/useSprints.ts +0 -154
  351. package/src/hooks/useStatusBarHighlight.ts +0 -18
  352. package/src/hooks/useSwimlaneBoardSettings.ts +0 -104
  353. package/src/hooks/useTheme.ts +0 -9
  354. package/src/hooks/useTransitionReadiness.ts +0 -53
  355. package/src/hooks/useVersion.ts +0 -155
  356. package/src/hooks/useViolations.ts +0 -65
  357. package/src/hooks/useWorkflow.tsx +0 -125
  358. package/src/hooks/useZoomModifier.ts +0 -19
  359. package/src/index.css +0 -797
  360. package/src/layouts/DashboardLayout.tsx +0 -113
  361. package/src/lib/collisionDetection.ts +0 -20
  362. package/src/lib/scope-fields.ts +0 -61
  363. package/src/lib/swimlane.ts +0 -146
  364. package/src/lib/utils.ts +0 -15
  365. package/src/main.tsx +0 -19
  366. package/src/socket.ts +0 -11
  367. package/src/types/index.ts +0 -497
  368. package/src/views/AgentFeed.tsx +0 -339
  369. package/src/views/DeployPipeline.tsx +0 -59
  370. package/src/views/EnforcementView.tsx +0 -378
  371. package/src/views/PrimitivesConfig.tsx +0 -500
  372. package/src/views/QualityGates.tsx +0 -1012
  373. package/src/views/ScopeBoard.tsx +0 -454
  374. package/src/views/SessionTimeline.tsx +0 -516
  375. package/src/views/Settings.tsx +0 -183
  376. package/src/views/SourceControl.tsx +0 -95
  377. package/src/views/WorkflowVisualizer.tsx +0 -382
  378. package/tailwind.config.js +0 -161
  379. package/tsconfig.json +0 -25
  380. package/vite.config.ts +0 -49
@@ -1,183 +0,0 @@
1
- import { useEffect } from 'react';
2
- import { Settings as SettingsIcon, Minus, Plus } from 'lucide-react';
3
- import { ScrollArea } from '@/components/ui/scroll-area';
4
- import { Separator } from '@/components/ui/separator';
5
- import { ToggleSwitch } from '@/components/ui/toggle-switch';
6
- import { useSettings, FONT_CATALOG, preloadFontPreviews, type FontCategory } from '@/hooks/useSettings';
7
- import { cn } from '@/lib/utils';
8
-
9
- const CATEGORY_LABELS: Record<FontCategory, string> = {
10
- 'monospace': 'Monospace',
11
- 'sans-serif': 'Sans-Serif',
12
- 'display': 'Display',
13
- };
14
-
15
- const CATEGORY_ORDER: FontCategory[] = ['monospace', 'sans-serif', 'display'];
16
-
17
- export function Settings() {
18
- const { settings, updateSetting } = useSettings();
19
-
20
- useEffect(() => { preloadFontPreviews(); }, []);
21
-
22
- const decrementScale = () => {
23
- const next = Math.max(0.8, Math.round((settings.fontScale - 0.05) * 100) / 100);
24
- updateSetting('fontScale', next);
25
- };
26
-
27
- const incrementScale = () => {
28
- const next = Math.min(1.3, Math.round((settings.fontScale + 0.05) * 100) / 100);
29
- updateSetting('fontScale', next);
30
- };
31
-
32
- return (
33
- <div className="flex h-full flex-col">
34
- {/* Header */}
35
- <div className="flex items-center gap-3 px-2 pb-4">
36
- <SettingsIcon className="h-5 w-5 text-muted-foreground" />
37
- <h1 className="text-lg font-medium tracking-wide">Settings</h1>
38
- </div>
39
-
40
- <ScrollArea className="flex-1">
41
- <div className="flex flex-col gap-6 pr-4 pb-8">
42
-
43
- {/* ── Appearance ── */}
44
- <section className="card-glass rounded-xl p-5">
45
- <h2 className="text-sm font-medium uppercase tracking-wider text-muted-foreground mb-5">
46
- Appearance
47
- </h2>
48
-
49
- {/* Font Family */}
50
- <div className="mb-5">
51
- <label className="text-xs text-muted-foreground mb-3 block">Font Family</label>
52
- {CATEGORY_ORDER.map(category => {
53
- const fonts = FONT_CATALOG.filter(f => f.category === category);
54
- return (
55
- <div key={category} className="mb-4 last:mb-0">
56
- <span className="text-xxs uppercase tracking-widest text-muted-foreground/60 mb-2 block">
57
- {CATEGORY_LABELS[category]}
58
- </span>
59
- <div className="grid grid-cols-2 gap-2 xl:grid-cols-3">
60
- {fonts.map(font => (
61
- <button
62
- key={font.family}
63
- onClick={() => updateSetting('fontFamily', font.family)}
64
- className={cn(
65
- 'group relative flex flex-col items-start rounded-lg border px-3 py-2.5 text-left transition-all duration-200',
66
- settings.fontFamily === font.family
67
- ? 'border-[rgba(0,188,212,0.5)] bg-[rgba(0,188,212,0.08)] shadow-[0_0_12px_rgba(0,188,212,0.15)]'
68
- : 'border-[rgba(255,255,255,0.06)] bg-[rgba(255,255,255,0.02)] hover:border-[rgba(255,255,255,0.12)] hover:bg-[rgba(255,255,255,0.04)]'
69
- )}
70
- >
71
- <span
72
- className="text-sm text-foreground truncate w-full"
73
- style={{ fontFamily: `'${font.family}', ${category === 'monospace' ? 'monospace' : 'sans-serif'}` }}
74
- >
75
- {font.label}
76
- </span>
77
- <span
78
- className="text-xs text-muted-foreground/50 mt-0.5"
79
- style={{ fontFamily: `'${font.family}', ${category === 'monospace' ? 'monospace' : 'sans-serif'}` }}
80
- >
81
- Aa Bb 0123
82
- </span>
83
- </button>
84
- ))}
85
- </div>
86
- </div>
87
- );
88
- })}
89
- </div>
90
-
91
- <Separator className="my-4" />
92
-
93
- {/* Font Size Scale */}
94
- <SettingRow label="Font Size" description="Scale text across the dashboard">
95
- <div className="flex items-center gap-2">
96
- <button
97
- onClick={decrementScale}
98
- disabled={settings.fontScale <= 0.8}
99
- className="flex h-7 w-7 items-center justify-center rounded-md border border-[rgba(255,255,255,0.08)] bg-[rgba(255,255,255,0.03)] text-muted-foreground transition-colors hover:border-[rgba(0,188,212,0.3)] hover:text-foreground disabled:opacity-30 disabled:cursor-not-allowed"
100
- >
101
- <Minus className="h-3.5 w-3.5" />
102
- </button>
103
- <span className="w-12 text-center text-sm tabular-nums">
104
- {Math.round(settings.fontScale * 100)}%
105
- </span>
106
- <button
107
- onClick={incrementScale}
108
- disabled={settings.fontScale >= 1.3}
109
- className="flex h-7 w-7 items-center justify-center rounded-md border border-[rgba(255,255,255,0.08)] bg-[rgba(255,255,255,0.03)] text-muted-foreground transition-colors hover:border-[rgba(0,188,212,0.3)] hover:text-foreground disabled:opacity-30 disabled:cursor-not-allowed"
110
- >
111
- <Plus className="h-3.5 w-3.5" />
112
- </button>
113
- </div>
114
- </SettingRow>
115
-
116
- <Separator className="my-4" />
117
-
118
- {/* Reduce Motion */}
119
- <SettingRow label="Reduce Motion" description="Disable animations and transitions">
120
- <ToggleSwitch
121
- checked={settings.reduceMotion}
122
- onCheckedChange={v => updateSetting('reduceMotion', v)}
123
- />
124
- </SettingRow>
125
-
126
- <Separator className="my-4" />
127
-
128
- {/* Background Effects */}
129
- <SettingRow label="Background Effects" description="Animated orbs and grid overlay">
130
- <ToggleSwitch
131
- checked={settings.showBackgroundEffects}
132
- onCheckedChange={v => updateSetting('showBackgroundEffects', v)}
133
- />
134
- </SettingRow>
135
- </section>
136
-
137
- {/* ── Display ── */}
138
- <section className="card-glass rounded-xl p-5">
139
- <h2 className="text-sm font-medium uppercase tracking-wider text-muted-foreground mb-5">
140
- Display
141
- </h2>
142
-
143
- <SettingRow label="Status Bar" description="Scope progress bar at bottom">
144
- <ToggleSwitch
145
- checked={settings.showStatusBar}
146
- onCheckedChange={v => updateSetting('showStatusBar', v)}
147
- />
148
- </SettingRow>
149
-
150
- <Separator className="my-4" />
151
-
152
- <SettingRow label="Compact Mode" description="Reduce spacing for denser layout">
153
- <ToggleSwitch
154
- checked={settings.compactMode}
155
- onCheckedChange={v => updateSetting('compactMode', v)}
156
- />
157
- </SettingRow>
158
- </section>
159
- </div>
160
- </ScrollArea>
161
- </div>
162
- );
163
- }
164
-
165
- function SettingRow({
166
- label,
167
- description,
168
- children,
169
- }: {
170
- label: string;
171
- description: string;
172
- children: React.ReactNode;
173
- }) {
174
- return (
175
- <div className="flex items-center justify-between gap-4">
176
- <div className="min-w-0">
177
- <div className="text-sm text-foreground">{label}</div>
178
- <div className="text-xs text-muted-foreground/60">{description}</div>
179
- </div>
180
- <div className="flex-shrink-0">{children}</div>
181
- </div>
182
- );
183
- }
@@ -1,95 +0,0 @@
1
- import { useState } from 'react';
2
- import { GitFork, ChevronDown, ChevronRight, Rocket } from 'lucide-react';
3
- import { Badge } from '@/components/ui/badge';
4
- import { Card, CardHeader, CardTitle } from '@/components/ui/card';
5
- import { useSourceControl } from '@/hooks/useSourceControl';
6
- import { usePipeline } from '@/hooks/usePipeline';
7
- import { GitOverviewBar } from '@/components/source-control/GitOverviewBar';
8
- import { CommitLog } from '@/components/source-control/CommitLog';
9
- import { BranchPanel } from '@/components/source-control/BranchPanel';
10
- import { GitHubPanel } from '@/components/source-control/GitHubPanel';
11
- import { DeployHistory } from '@/components/DeployHistory';
12
-
13
- export function SourceControl() {
14
- const { overview, commits, branches, worktrees, github, drift, loading, loadMoreCommits, hasMoreCommits } = useSourceControl();
15
- const { deployments } = usePipeline();
16
- const [deployExpanded, setDeployExpanded] = useState(true);
17
-
18
- if (loading) {
19
- return (
20
- <div className="flex h-64 items-center justify-center">
21
- <div className="h-8 w-8 animate-spin rounded-full border-2 border-primary border-t-transparent" />
22
- </div>
23
- );
24
- }
25
-
26
- return (
27
- <div className="flex-1 min-h-0 overflow-y-auto">
28
- {/* Header */}
29
- <div className="mb-6 flex items-center gap-3">
30
- <GitFork className="h-4 w-4 text-primary" />
31
- <h1 className="text-xl font-light">Repo</h1>
32
- {overview && (
33
- <Badge variant="secondary">
34
- {overview.currentBranch}
35
- </Badge>
36
- )}
37
- </div>
38
-
39
- {/* Section A: Git Overview Bar */}
40
- {overview && <GitOverviewBar overview={overview} github={github} />}
41
-
42
- {/* Section B + C: Commit Log + Branch Panel */}
43
- <div className="grid gap-6 lg:grid-cols-3">
44
- <CommitLog
45
- commits={commits}
46
- branches={branches}
47
- hasMore={hasMoreCommits}
48
- onLoadMore={loadMoreCommits}
49
- />
50
- <BranchPanel
51
- branches={branches}
52
- worktrees={worktrees}
53
- drift={drift}
54
- branchingMode={overview?.branchingMode ?? 'trunk'}
55
- />
56
- </div>
57
-
58
- {/* Section D: GitHub Panel (collapsible) */}
59
- <GitHubPanel github={github} />
60
-
61
- {/* Section E: Deploy History (collapsible) */}
62
- {deployments.length > 0 && (
63
- <div className="mt-6">
64
- {!deployExpanded ? (
65
- <Card
66
- className="cursor-pointer select-none"
67
- onClick={() => setDeployExpanded(true)}
68
- >
69
- <CardHeader>
70
- <CardTitle className="flex items-center gap-2 text-base">
71
- <ChevronRight className="h-4 w-4 text-muted-foreground" />
72
- <Rocket className="h-4 w-4 text-primary" />
73
- Deploy History
74
- <Badge variant="secondary">{deployments.length}</Badge>
75
- </CardTitle>
76
- </CardHeader>
77
- </Card>
78
- ) : (
79
- <div>
80
- <button
81
- onClick={() => setDeployExpanded(false)}
82
- className="mb-2 flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors"
83
- >
84
- <ChevronDown className="h-4 w-4" />
85
- <Rocket className="h-4 w-4" />
86
- Deploy History
87
- </button>
88
- <DeployHistory deployments={deployments} />
89
- </div>
90
- )}
91
- </div>
92
- )}
93
- </div>
94
- );
95
- }
@@ -1,382 +0,0 @@
1
- import { useState, useMemo, useCallback, useEffect } from 'react';
2
- import {
3
- ReactFlow,
4
- Background,
5
- Controls,
6
- useNodesState,
7
- useEdgesState,
8
- BackgroundVariant,
9
- } from '@xyflow/react';
10
- import type { NodeMouseHandler, EdgeMouseHandler } from '@xyflow/react';
11
- import '@xyflow/react/dist/style.css';
12
-
13
- import { Workflow, Zap, Pencil, LayoutGrid } from 'lucide-react';
14
- import type { WorkflowHook, UnifiedHook } from '../../shared/workflow-config';
15
- import { useWorkflow } from '@/hooks/useWorkflow';
16
- import { useScopes } from '@/hooks/useScopes';
17
- import { useCcHooks } from '@/hooks/useCcHooks';
18
- import { WorkflowNode } from '@/components/workflow/WorkflowNode';
19
- import type { WorkflowNodeType } from '@/components/workflow/WorkflowNode';
20
- import { WorkflowEdgeComponent } from '@/components/workflow/WorkflowEdgeComponent';
21
- import type { WorkflowEdgeType } from '@/components/workflow/WorkflowEdgeComponent';
22
- import { NodeDetailPanel } from '@/components/workflow/NodeDetailPanel';
23
- import { EdgeDetailPanel } from '@/components/workflow/EdgeDetailPanel';
24
- import { PresetSelector } from '@/components/workflow/PresetSelector';
25
- import { HookSourceModal } from '@/components/workflow/HookSourceModal';
26
- import { HooksDashboard } from '@/components/workflow/HooksDashboard';
27
- import { HookDetailPanel } from '@/components/workflow/HookDetailPanel';
28
- import { ListPropertyEditor } from '@/components/workflow/ListPropertyEditor';
29
- import { EdgePropertyEditor } from '@/components/workflow/EdgePropertyEditor';
30
- import { EditToolbar } from '@/components/workflow/EditToolbar';
31
- import { AddListDialog } from '@/components/workflow/AddListDialog';
32
- import { AddEdgeDialog } from '@/components/workflow/AddEdgeDialog';
33
- import { MigrationPreviewDialog } from '@/components/workflow/MigrationPreviewDialog';
34
- import { ConfigSettingsPanel } from '@/components/workflow/ConfigSettingsPanel';
35
- import { useWorkflowEditor } from '@/components/workflow/useWorkflowEditor';
36
- import { computeLayout, computeEdges, computeActiveHandles } from '@/components/workflow/graphLayout';
37
- import { mergeHooks } from '@/components/workflow/mergeHooks';
38
-
39
- // ─── Constants ──────────────────────────────────────────
40
-
41
- const NODE_TYPES = { workflow: WorkflowNode } as const;
42
- const EDGE_TYPES = { workflow: WorkflowEdgeComponent } as const;
43
-
44
- // ─── Detail Panel State ─────────────────────────────────
45
-
46
- type DetailState =
47
- | { type: 'none' }
48
- | { type: 'node'; listId: string }
49
- | { type: 'edge'; from: string; to: string };
50
-
51
- type ActiveTab = 'graph' | 'hooks';
52
-
53
- // ─── Component ──────────────────────────────────────────
54
-
55
- export default function WorkflowVisualizer() {
56
- const { engine } = useWorkflow();
57
- const { scopes } = useScopes();
58
- const { ccHooks } = useCcHooks();
59
- const config = engine.getConfig();
60
- const editor = useWorkflowEditor(config);
61
-
62
- // The config to display: either the edit draft or the live config
63
- const displayConfig = editor.editMode ? editor.editConfig : config;
64
- const displayLists = useMemo(() => [...displayConfig.lists].sort((a, b) => a.order - b.order), [displayConfig.lists]);
65
- const displayEdges = displayConfig.edges;
66
- const displayHooks = displayConfig.hooks ?? [];
67
-
68
- // Unified hooks: workflow + CC merged
69
- const unifiedHooks = useMemo(() => mergeHooks(displayHooks, ccHooks), [displayHooks, ccHooks]);
70
-
71
- // Tab state
72
- const [activeTab, setActiveTab] = useState<ActiveTab>('graph');
73
-
74
- // Source modal (shared across tabs)
75
- const [sourceModalHook, setSourceModalHook] = useState<UnifiedHook | null>(null);
76
-
77
- // Hooks tab: selected hook for detail panel
78
- const [selectedHookForDetail, setSelectedHookForDetail] = useState<UnifiedHook | null>(null);
79
-
80
- // Adapter: convert WorkflowHook click from Edge/NodeDetailPanel to source modal
81
- const handleWorkflowHookClick = useCallback((wfHook: WorkflowHook) => {
82
- const unified = unifiedHooks.find((u) => u.id === wfHook.id);
83
- if (unified) setSourceModalHook(unified);
84
- }, [unifiedHooks]);
85
-
86
- // Cross-tab: navigate from HookDetailPanel edge click to Graph tab
87
- const handleNavigateToEdge = useCallback((from: string, to: string) => {
88
- setSelectedHookForDetail(null);
89
- setActiveTab('graph');
90
- setDetail({ type: 'edge', from, to });
91
- }, []);
92
-
93
- // Scope counts
94
- const scopeCounts = useMemo(() => {
95
- const counts = new Map<string, number>();
96
- for (const scope of scopes) {
97
- counts.set(scope.status, (counts.get(scope.status) ?? 0) + 1);
98
- }
99
- return counts;
100
- }, [scopes]);
101
-
102
- // Build graph data from display config
103
- const activeHandles = useMemo(
104
- () => computeActiveHandles(displayEdges, displayLists),
105
- [displayEdges, displayLists],
106
- );
107
- const graphNodes = useMemo(
108
- () => computeLayout(displayLists, displayConfig.groups ?? [], scopeCounts, displayEdges).map((node) => ({
109
- ...node,
110
- data: { ...node.data, activeHandles: activeHandles.get(node.id) },
111
- })),
112
- [displayLists, displayConfig.groups, scopeCounts, displayEdges, activeHandles],
113
- );
114
- const graphEdges = useMemo(
115
- () => computeEdges(displayEdges, displayLists, displayHooks, false),
116
- [displayEdges, displayLists, displayHooks],
117
- );
118
-
119
- const [nodes, setNodes, onNodesChange] = useNodesState(graphNodes);
120
- const [edges, setEdges, onEdgesChange] = useEdgesState(graphEdges);
121
-
122
- // Sync React Flow state when the computed graph data changes (e.g. preset switch)
123
- useEffect(() => { setNodes(graphNodes); }, [graphNodes, setNodes]);
124
- useEffect(() => { setEdges(graphEdges); }, [graphEdges, setEdges]);
125
-
126
- // Detail panel (graph tab)
127
- const [detail, setDetail] = useState<DetailState>({ type: 'none' });
128
-
129
- const onNodeClick: NodeMouseHandler<WorkflowNodeType> = useCallback((_event, node) => {
130
- setDetail({ type: 'node', listId: node.id });
131
- }, []);
132
-
133
- const onEdgeClick: EdgeMouseHandler<WorkflowEdgeType> = useCallback((_event, edge) => {
134
- const [from, to] = edge.id.split(':');
135
- setDetail({ type: 'edge', from, to });
136
- }, []);
137
-
138
- const onPaneClick = useCallback(() => setDetail({ type: 'none' }), []);
139
-
140
- // Resolve selected items from display config
141
- const selectedList = detail.type === 'node'
142
- ? displayConfig.lists.find((l) => l.id === detail.listId) ?? null
143
- : null;
144
- const selectedEdge = detail.type === 'edge'
145
- ? displayEdges.find((e) => e.from === detail.from && e.to === detail.to) ?? null
146
- : null;
147
-
148
- const nodeHooks = useMemo(() => {
149
- if (!selectedList) return [];
150
- const relevant = displayEdges.filter((e) => e.from === selectedList.id || e.to === selectedList.id);
151
- const hookIds = new Set(relevant.flatMap((e) => e.hooks ?? []));
152
- return displayHooks.filter((h) => hookIds.has(h.id));
153
- }, [selectedList, displayEdges, displayHooks]);
154
-
155
- const nodeConnectedEdges = useMemo(() => {
156
- if (!selectedList) return [];
157
- return displayEdges.filter((e) => e.from === selectedList.id || e.to === selectedList.id);
158
- }, [selectedList, displayEdges]);
159
-
160
- const edgeHooks = useMemo(() => {
161
- if (!selectedEdge) return [];
162
- return (selectedEdge.hooks ?? [])
163
- .map((id) => displayHooks.find((h) => h.id === id))
164
- .filter((h): h is NonNullable<typeof h> => h !== undefined);
165
- }, [selectedEdge, displayHooks]);
166
-
167
- return (
168
- <div className="flex flex-1 min-h-0 flex-col">
169
- {/* Header */}
170
- <div className="mb-4 flex items-center justify-between">
171
- <div className="flex items-center gap-3">
172
- <Workflow className="h-4 w-4 text-primary" />
173
- <h1 className="text-xl font-light">Workflow</h1>
174
- {editor.editMode && (
175
- <span className="rounded bg-cyan-500/20 px-2 py-0.5 text-[10px] font-semibold text-cyan-400">
176
- EDIT MODE
177
- </span>
178
- )}
179
-
180
- {/* Tab navigation */}
181
- {!editor.editMode && (
182
- <div className="ml-4 flex rounded-lg border border-zinc-800 bg-zinc-900/50 p-0.5">
183
- <TabButton
184
- active={activeTab === 'graph'}
185
- onClick={() => setActiveTab('graph')}
186
- icon={<LayoutGrid className="h-3 w-3" />}
187
- label="Graph"
188
- />
189
- <TabButton
190
- active={activeTab === 'hooks'}
191
- onClick={() => setActiveTab('hooks')}
192
- icon={<Zap className="h-3 w-3" />}
193
- label="Hooks"
194
- count={unifiedHooks.length}
195
- />
196
- </div>
197
- )}
198
- </div>
199
- <div className="flex items-center gap-2">
200
- {!editor.editMode && (
201
- <button
202
- onClick={editor.enterEditMode}
203
- className="flex items-center gap-1.5 rounded border border-zinc-800 px-3 py-1.5 text-xs text-zinc-400 transition-colors hover:border-cyan-500/40 hover:text-cyan-400"
204
- >
205
- <Pencil className="h-3.5 w-3.5" />
206
- Edit
207
- </button>
208
- )}
209
- {!editor.editMode && <PresetSelector activeConfigName={config.name} />}
210
- </div>
211
- </div>
212
-
213
- {/* Edit Toolbar */}
214
- {editor.editMode && (
215
- <div className="mb-3">
216
- <EditToolbar
217
- canUndo={editor.canUndo}
218
- canRedo={editor.canRedo}
219
- changeCount={editor.changeCount}
220
- validation={editor.validation}
221
- saving={editor.saving}
222
- onAddList={() => editor.setShowAddList(true)}
223
- onAddEdge={() => editor.setShowAddEdge(true)}
224
- onConfigSettings={() => { editor.setShowConfigSettings(true); setDetail({ type: 'none' }); }}
225
- onUndo={editor.undo}
226
- onRedo={editor.redo}
227
- onSave={editor.save}
228
- onDiscard={editor.discard}
229
- onPreview={editor.preview}
230
- />
231
- </div>
232
- )}
233
-
234
- {/* ─── Graph Tab ────────────────────────────────── */}
235
- {(activeTab === 'graph' || editor.editMode) && (
236
- <div className="flex min-h-0 flex-1 gap-3">
237
- {/* React Flow Canvas */}
238
- <div
239
- className="min-h-0 flex-1 rounded-lg border bg-transparent"
240
- style={{ borderColor: editor.editMode ? '#3b82f640' : '#27272a' }}
241
- >
242
- <ReactFlow
243
- nodes={nodes}
244
- edges={edges}
245
- onNodesChange={onNodesChange}
246
- onEdgesChange={onEdgesChange}
247
- nodeTypes={NODE_TYPES}
248
- edgeTypes={EDGE_TYPES}
249
- onNodeClick={onNodeClick}
250
- onEdgeClick={onEdgeClick}
251
- onPaneClick={onPaneClick}
252
- fitView
253
- fitViewOptions={{ padding: 0.08 }}
254
- minZoom={0.3}
255
- maxZoom={2}
256
- proOptions={{ hideAttribution: true }}
257
- >
258
- <Background variant={BackgroundVariant.Dots} gap={20} size={1} color="#27272a" />
259
- <Controls className="!border-zinc-800 !bg-zinc-900 [&>button]:!border-zinc-800 [&>button]:!bg-zinc-900 [&>button]:!fill-zinc-400 [&>button:hover]:!bg-zinc-800" />
260
- </ReactFlow>
261
- </div>
262
-
263
- {/* Edit mode panels */}
264
- {editor.editMode && detail.type === 'node' && selectedList && (
265
- <ListPropertyEditor
266
- key={selectedList.id}
267
- list={selectedList}
268
- config={editor.editConfig}
269
- onSave={(updated) => { editor.updateList(selectedList, updated); setDetail({ type: 'none' }); }}
270
- onDelete={() => { editor.deleteList(selectedList.id); setDetail({ type: 'none' }); }}
271
- onClose={() => setDetail({ type: 'none' })}
272
- />
273
- )}
274
- {editor.editMode && detail.type === 'edge' && selectedEdge && (
275
- <EdgePropertyEditor
276
- key={`${selectedEdge.from}:${selectedEdge.to}`}
277
- edge={selectedEdge}
278
- config={editor.editConfig}
279
- onSave={(updated) => { editor.updateEdge(selectedEdge, updated); setDetail({ type: 'none' }); }}
280
- onDelete={() => { editor.deleteEdge(selectedEdge.from, selectedEdge.to); setDetail({ type: 'none' }); }}
281
- onClose={() => setDetail({ type: 'none' })}
282
- />
283
- )}
284
- {editor.editMode && editor.showConfigSettings && detail.type === 'none' && (
285
- <ConfigSettingsPanel
286
- config={editor.editConfig}
287
- onUpdate={editor.updateConfig}
288
- onClose={() => editor.setShowConfigSettings(false)}
289
- />
290
- )}
291
-
292
- {/* Read-only panels (graph tab only, not edit mode) */}
293
- {!editor.editMode && detail.type === 'node' && (
294
- <NodeDetailPanel list={selectedList} hooks={nodeHooks} connectedEdges={nodeConnectedEdges} onClose={() => setDetail({ type: 'none' })} onHookClick={handleWorkflowHookClick} />
295
- )}
296
- {!editor.editMode && detail.type === 'edge' && (
297
- <EdgeDetailPanel edge={selectedEdge} hooks={edgeHooks} onClose={() => setDetail({ type: 'none' })} onHookClick={handleWorkflowHookClick} />
298
- )}
299
- </div>
300
- )}
301
-
302
- {/* ─── Hooks Tab ────────────────────────────────── */}
303
- {activeTab === 'hooks' && !editor.editMode && (
304
- <div className="flex min-h-0 flex-1 gap-3">
305
- <HooksDashboard
306
- hooks={unifiedHooks}
307
- edges={displayEdges}
308
- onHookClick={setSelectedHookForDetail}
309
- />
310
- {selectedHookForDetail && (
311
- <HookDetailPanel
312
- hook={selectedHookForDetail}
313
- edges={displayEdges}
314
- onClose={() => setSelectedHookForDetail(null)}
315
- onViewSource={setSourceModalHook}
316
- onNavigateToEdge={handleNavigateToEdge}
317
- />
318
- )}
319
- </div>
320
- )}
321
-
322
- {/* Dialogs */}
323
- <AddListDialog
324
- open={editor.showAddList}
325
- onOpenChange={editor.setShowAddList}
326
- config={editor.editConfig}
327
- onAdd={editor.addList}
328
- />
329
- <AddEdgeDialog
330
- open={editor.showAddEdge}
331
- onOpenChange={editor.setShowAddEdge}
332
- config={editor.editConfig}
333
- onAdd={editor.addEdge}
334
- />
335
- <MigrationPreviewDialog
336
- open={editor.showPreview}
337
- onOpenChange={editor.setShowPreview}
338
- config={editor.editConfig}
339
- plan={editor.previewPlan}
340
- loading={editor.previewLoading}
341
- error={editor.previewError}
342
- onApply={editor.applyMigration}
343
- />
344
- <HookSourceModal
345
- hook={sourceModalHook}
346
- open={sourceModalHook !== null}
347
- onClose={() => setSourceModalHook(null)}
348
- />
349
- </div>
350
- );
351
- }
352
-
353
- // ─── Sub-components ─────────────────────────────────────
354
-
355
- function TabButton({ active, onClick, icon, label, count }: {
356
- active: boolean; onClick: () => void; icon: React.ReactNode; label: string; count?: number;
357
- }) {
358
- return (
359
- <button
360
- onClick={onClick}
361
- className="flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors"
362
- style={{
363
- backgroundColor: active ? '#27272a' : 'transparent',
364
- color: active ? '#e4e4e7' : '#71717a',
365
- }}
366
- >
367
- {icon}
368
- {label}
369
- {count !== undefined && count > 0 && (
370
- <span
371
- className="rounded-full px-1.5 py-0.5 text-[9px] font-semibold leading-none"
372
- style={{
373
- backgroundColor: active ? '#f9731630' : '#27272a',
374
- color: active ? '#f97316' : '#71717a',
375
- }}
376
- >
377
- {count}
378
- </span>
379
- )}
380
- </button>
381
- );
382
- }