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
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Health diagnostics — `orbital doctor`
3
+ */
4
+ import fs from 'fs';
5
+ import path from 'path';
6
+ import { execFileSync } from 'child_process';
7
+ import pc from 'picocolors';
8
+ export async function runDoctor(projectRoot, packageVersion) {
9
+ console.log(`\n ${pc.bold('Orbital Command')} ${pc.cyan(`v${packageVersion}`)}\n`);
10
+ const checks = [];
11
+ // 1. Check for latest version on npm
12
+ try {
13
+ const latest = execFileSync('npm', ['view', 'orbital-command', 'version'], {
14
+ encoding: 'utf8',
15
+ timeout: 5000,
16
+ }).trim();
17
+ if (latest && latest !== packageVersion) {
18
+ checks.push({ label: 'Latest', status: pc.yellow(`v${latest} available (run \`npm update -g orbital-command\`)`) });
19
+ }
20
+ else {
21
+ checks.push({ label: 'Latest', status: pc.green(`v${packageVersion} (up to date)`) });
22
+ }
23
+ }
24
+ catch {
25
+ checks.push({ label: 'Latest', status: pc.dim('could not check (npm unreachable)') });
26
+ }
27
+ // 2. Node version
28
+ const nodeVersion = process.version;
29
+ const major = parseInt(nodeVersion.slice(1), 10);
30
+ if (major >= 18) {
31
+ checks.push({ label: 'Node', status: pc.green(`${nodeVersion} (supported)`) });
32
+ }
33
+ else {
34
+ checks.push({ label: 'Node', status: pc.red(`${nodeVersion} (requires Node 18+)`) });
35
+ }
36
+ // 3. Global registry
37
+ const homedir = process.env.HOME || process.env.USERPROFILE || '~';
38
+ const registryPath = path.join(homedir, '.orbital', 'config.json');
39
+ if (fs.existsSync(registryPath)) {
40
+ try {
41
+ const registry = JSON.parse(fs.readFileSync(registryPath, 'utf8'));
42
+ const count = (registry.projects || []).length;
43
+ checks.push({ label: 'Global', status: pc.green(`~/.orbital/ exists (${count} project${count !== 1 ? 's' : ''} registered)`) });
44
+ }
45
+ catch {
46
+ checks.push({ label: 'Global', status: pc.yellow('~/.orbital/ exists (registry unreadable)') });
47
+ }
48
+ }
49
+ else {
50
+ checks.push({ label: 'Global', status: pc.dim('~/.orbital/ not found (run `orbital init` to create)') });
51
+ }
52
+ // 4. Project initialization
53
+ const configPath = path.join(projectRoot, '.claude', 'orbital.config.json');
54
+ if (fs.existsSync(configPath)) {
55
+ try {
56
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
57
+ const name = config.projectName || path.basename(projectRoot);
58
+ checks.push({ label: 'Project', status: pc.green(`initialized (${name})`) });
59
+ }
60
+ catch {
61
+ checks.push({ label: 'Project', status: pc.yellow('config exists but unreadable') });
62
+ }
63
+ }
64
+ else {
65
+ checks.push({ label: 'Project', status: pc.dim('not initialized (run `orbital init`)') });
66
+ }
67
+ // 5. Workflow
68
+ const workflowPath = path.join(projectRoot, '.claude', 'config', 'workflow.json');
69
+ if (fs.existsSync(workflowPath)) {
70
+ try {
71
+ const wf = JSON.parse(fs.readFileSync(workflowPath, 'utf8'));
72
+ const listCount = (wf.lists || []).length;
73
+ const mode = wf.branchingMode || 'unknown';
74
+ checks.push({ label: 'Workflow', status: pc.green(`${wf.name || 'Custom'} (${listCount} lists, ${mode})`) });
75
+ }
76
+ catch {
77
+ checks.push({ label: 'Workflow', status: pc.yellow('workflow.json exists but unreadable') });
78
+ }
79
+ }
80
+ else {
81
+ checks.push({ label: 'Workflow', status: pc.dim('no workflow configured') });
82
+ }
83
+ // 6. Database
84
+ const dbPath = path.join(projectRoot, '.claude', 'orbital', 'orbital.db');
85
+ if (fs.existsSync(dbPath)) {
86
+ const stats = fs.statSync(dbPath);
87
+ const sizeMb = (stats.size / (1024 * 1024)).toFixed(1);
88
+ checks.push({ label: 'Database', status: pc.green(`${sizeMb} MB`) });
89
+ }
90
+ else {
91
+ checks.push({ label: 'Database', status: pc.dim('not yet created (starts on first launch)') });
92
+ }
93
+ // 7. Template staleness
94
+ if (fs.existsSync(configPath)) {
95
+ try {
96
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
97
+ if (config.templateVersion && config.templateVersion !== packageVersion) {
98
+ checks.push({ label: 'Templates', status: pc.yellow(`outdated (v${config.templateVersion} → v${packageVersion}, run \`orbital update\`)`) });
99
+ }
100
+ else if (config.templateVersion) {
101
+ checks.push({ label: 'Templates', status: pc.green('synced') });
102
+ }
103
+ else {
104
+ checks.push({ label: 'Templates', status: pc.yellow('no version stamp (run `orbital update`)') });
105
+ }
106
+ }
107
+ catch { /* skip */ }
108
+ }
109
+ // Print all checks
110
+ const maxLabel = Math.max(...checks.map(c => c.label.length));
111
+ for (const check of checks) {
112
+ console.log(` ${pc.dim(check.label.padEnd(maxLabel + 2))} ${check.status}`);
113
+ }
114
+ console.log();
115
+ }
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Interactive CLI wizard — main orchestrator.
3
+ *
4
+ * Entry points:
5
+ * runSetupWizard() — Phase 1: first-time Orbital setup (~/.orbital/)
6
+ * runProjectSetup() — Phase 2: per-project scaffolding (.claude/)
7
+ * runConfigEditor() — interactive config editor (orbital config)
8
+ * runDoctor() — health diagnostics (orbital doctor)
9
+ */
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+ import crypto from 'crypto';
13
+ import * as p from '@clack/prompts';
14
+ import pc from 'picocolors';
15
+ import { buildSetupState, buildProjectState, ORBITAL_HOME } from './detect.js';
16
+ import { phaseSetupWizard } from './phases/setup-wizard.js';
17
+ import { phaseWelcome } from './phases/welcome.js';
18
+ import { phaseProjectSetup } from './phases/project-setup.js';
19
+ import { phaseWorkflowSetup } from './phases/workflow-setup.js';
20
+ import { phaseConfirm, showPostInstall } from './phases/confirm.js';
21
+ import { NOTES } from './ui.js';
22
+ import { runConfigEditor } from './config-editor.js';
23
+ import { runDoctor } from './doctor.js';
24
+ export { runConfigEditor, runDoctor };
25
+ // ─── Phase 1: Setup Wizard ─────────────────────────────────────
26
+ /**
27
+ * First-time setup. Creates ~/.orbital/, seeds primitives,
28
+ * optionally links projects (running Phase 2 for each).
29
+ */
30
+ export async function runSetupWizard(packageVersion) {
31
+ const state = buildSetupState(packageVersion);
32
+ p.intro(`${pc.bgCyan(pc.black(' Orbital Command '))} ${pc.dim(`v${packageVersion}`)}`);
33
+ await phaseSetupWizard(state);
34
+ // If user linked projects, run Phase 2 for each
35
+ for (const projectRoot of state.linkedProjects) {
36
+ p.log.step(`Setting up ${pc.cyan(path.basename(projectRoot))}...`);
37
+ await runProjectSetupInline(projectRoot, packageVersion);
38
+ }
39
+ if (state.linkedProjects.length === 0) {
40
+ p.note(NOTES.setupComplete, 'Done');
41
+ }
42
+ p.outro(state.linkedProjects.length > 0
43
+ ? `Run ${pc.cyan('orbital launch --open')} to open the dashboard.`
44
+ : `Run ${pc.cyan('orbital init')} in a project directory to get started.`);
45
+ }
46
+ // ─── Phase 2: Project Setup ────────────────────────────────────
47
+ /**
48
+ * Per-project setup. Walks through name, commands, workflow, then
49
+ * calls runInit() to scaffold files into .claude/.
50
+ */
51
+ export async function runProjectSetup(projectRoot, packageVersion, args) {
52
+ const state = buildProjectState(projectRoot, packageVersion);
53
+ const force = args.includes('--force');
54
+ p.intro(`${pc.bgCyan(pc.black(' Orbital Command '))} ${pc.dim(`v${packageVersion}`)}`);
55
+ // Welcome gate: detect re-init / reconfigure
56
+ const forceFromWelcome = await phaseWelcome(state);
57
+ const useForce = force || forceFromWelcome;
58
+ await runProjectPhases(state, useForce);
59
+ p.outro(`Run ${pc.cyan('orbital launch --open')} to open the dashboard.`);
60
+ }
61
+ // ─── Shared project phases (used by both flows) ────────────────
62
+ /**
63
+ * Run the project setup phases and install. Used by both
64
+ * standalone runProjectSetup() and inline from runSetupWizard().
65
+ */
66
+ async function runProjectPhases(state, useForce) {
67
+ await phaseProjectSetup(state);
68
+ await phaseWorkflowSetup(state);
69
+ await phaseConfirm(state);
70
+ // Install
71
+ const s = p.spinner();
72
+ s.start('Installing into project...');
73
+ try {
74
+ const { runInit } = await import('../init.js');
75
+ runInit(state.projectRoot, {
76
+ force: useForce,
77
+ quiet: true,
78
+ preset: state.workflowPreset,
79
+ projectName: state.projectName,
80
+ serverPort: state.serverPort,
81
+ clientPort: state.clientPort,
82
+ commands: state.selectedCommands,
83
+ });
84
+ registerProject(state.projectRoot, state.projectName);
85
+ stampTemplateVersion(state.projectRoot, state.packageVersion);
86
+ s.stop('Project ready.');
87
+ }
88
+ catch (err) {
89
+ s.stop('Installation failed.');
90
+ p.log.error(err instanceof Error ? err.message : String(err));
91
+ process.exit(1);
92
+ }
93
+ showPostInstall(state);
94
+ }
95
+ /**
96
+ * Inline project setup — called from Phase 1 when user links a project.
97
+ * Skips intro/outro since the setup wizard already has those.
98
+ */
99
+ async function runProjectSetupInline(projectRoot, packageVersion) {
100
+ const state = buildProjectState(projectRoot, packageVersion);
101
+ // Skip welcome gate for inline — this is a fresh project being linked
102
+ await runProjectPhases(state, false);
103
+ }
104
+ // ─── Registration ──────────────────────────────────────────────
105
+ function registerProject(projectRoot, projectName) {
106
+ const registryPath = path.join(ORBITAL_HOME, 'config.json');
107
+ let registry;
108
+ try {
109
+ registry = fs.existsSync(registryPath)
110
+ ? JSON.parse(fs.readFileSync(registryPath, 'utf8'))
111
+ : { version: 1, projects: [] };
112
+ }
113
+ catch {
114
+ registry = { version: 1, projects: [] };
115
+ }
116
+ if (!registry.projects)
117
+ registry.projects = [];
118
+ if (registry.projects.some((proj) => proj.path === projectRoot))
119
+ return;
120
+ const COLORS = [
121
+ '210 80% 55%', '340 75% 55%', '160 60% 45%', '30 90% 55%',
122
+ '270 65% 55%', '50 85% 50%', '180 55% 45%', '0 70% 55%',
123
+ ];
124
+ const usedColors = registry.projects.map((proj) => proj.color);
125
+ const color = COLORS.find(c => !usedColors.includes(c)) || COLORS[0];
126
+ const name = projectName || path.basename(projectRoot);
127
+ const baseSlug = path.basename(projectRoot).toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '') || 'project';
128
+ const existingIds = registry.projects.map((proj) => proj.id);
129
+ const slug = existingIds.includes(baseSlug)
130
+ ? `${baseSlug}-${crypto.createHash('sha256').update(projectRoot).digest('hex').slice(0, 4)}`
131
+ : baseSlug;
132
+ registry.projects.push({
133
+ id: slug,
134
+ path: projectRoot,
135
+ name,
136
+ color,
137
+ registeredAt: new Date().toISOString(),
138
+ enabled: true,
139
+ });
140
+ fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2), 'utf8');
141
+ }
142
+ // ─── Template Version Stamping ─────────────────────────────────
143
+ function stampTemplateVersion(projectRoot, packageVersion) {
144
+ const configPath = path.join(projectRoot, '.claude', 'orbital.config.json');
145
+ if (!fs.existsSync(configPath))
146
+ return;
147
+ try {
148
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
149
+ if (config.templateVersion !== packageVersion) {
150
+ config.templateVersion = packageVersion;
151
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
152
+ }
153
+ }
154
+ catch { /* ignore malformed config */ }
155
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Phase 3: Confirm choices, run installation, show next steps.
3
+ */
4
+ import fs from 'fs';
5
+ import path from 'path';
6
+ import * as p from '@clack/prompts';
7
+ import { NOTES, formatSummary } from '../ui.js';
8
+ export async function phaseConfirm(state) {
9
+ p.note(formatSummary(state), 'Ready to Initialize');
10
+ const proceed = await p.confirm({
11
+ message: 'Proceed with installation?',
12
+ initialValue: true,
13
+ });
14
+ if (p.isCancel(proceed) || !proceed) {
15
+ p.cancel('Setup cancelled.');
16
+ process.exit(0);
17
+ }
18
+ }
19
+ export function showPostInstall(state) {
20
+ // Count installed artifacts
21
+ const claudeDir = path.join(state.projectRoot, '.claude');
22
+ const counts = {
23
+ hooks: countDir(path.join(claudeDir, 'hooks')),
24
+ skills: countDir(path.join(claudeDir, 'skills')),
25
+ agents: countDir(path.join(claudeDir, 'agents')),
26
+ };
27
+ p.note(NOTES.postInstall(counts), 'Installation Complete');
28
+ p.note(NOTES.nextSteps, 'Getting Started');
29
+ }
30
+ function countDir(dir) {
31
+ if (!fs.existsSync(dir))
32
+ return 0;
33
+ try {
34
+ return fs.readdirSync(dir).filter(f => !f.startsWith('.')).length;
35
+ }
36
+ catch {
37
+ return 0;
38
+ }
39
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Phase 1: Project configuration — name, commands, ports.
3
+ */
4
+ import * as p from '@clack/prompts';
5
+ import { NOTES, formatDetectedCommands } from '../ui.js';
6
+ import { detectProjectName, detectCommands, detectPortConflict } from '../detect.js';
7
+ export async function phaseProjectSetup(state) {
8
+ p.note(NOTES.projectConfig, 'Project Configuration');
9
+ // 1. Project name
10
+ const defaultName = detectProjectName(state.projectRoot);
11
+ const name = await p.text({
12
+ message: 'Project name',
13
+ placeholder: defaultName,
14
+ defaultValue: defaultName,
15
+ });
16
+ if (p.isCancel(name)) {
17
+ p.cancel('Setup cancelled.');
18
+ process.exit(0);
19
+ }
20
+ state.projectName = name;
21
+ // 2. Command detection
22
+ const detected = detectCommands(state.projectRoot);
23
+ state.detectedCommands = detected;
24
+ const detectedCount = Object.values(detected).filter(v => v !== null).length;
25
+ if (detectedCount > 0) {
26
+ p.note(formatDetectedCommands(detected), `Detected ${detectedCount} command(s) from package.json`);
27
+ const useDetected = await p.confirm({
28
+ message: 'Use these detected commands for quality gates?',
29
+ initialValue: true,
30
+ });
31
+ if (p.isCancel(useDetected)) {
32
+ p.cancel('Setup cancelled.');
33
+ process.exit(0);
34
+ }
35
+ if (useDetected) {
36
+ state.selectedCommands = { ...detected };
37
+ }
38
+ else {
39
+ state.selectedCommands = await promptCommands(detected);
40
+ }
41
+ }
42
+ else {
43
+ p.log.info('No build commands detected from package.json. You can configure them later with `orbital config`.');
44
+ state.selectedCommands = detected;
45
+ }
46
+ // 3. Port conflict detection
47
+ const conflict = detectPortConflict(4444);
48
+ if (conflict) {
49
+ p.log.warn(`Port 4444 is already used by "${conflict}".`);
50
+ const serverPort = await p.text({
51
+ message: 'Server port',
52
+ placeholder: '4446',
53
+ defaultValue: '4446',
54
+ validate: (val) => {
55
+ const n = Number(val);
56
+ if (isNaN(n) || n < 1 || n > 65535)
57
+ return 'Must be a valid port (1-65535)';
58
+ return undefined;
59
+ },
60
+ });
61
+ if (p.isCancel(serverPort)) {
62
+ p.cancel('Setup cancelled.');
63
+ process.exit(0);
64
+ }
65
+ state.serverPort = Number(serverPort);
66
+ state.clientPort = state.serverPort + 1;
67
+ }
68
+ }
69
+ async function promptCommands(defaults) {
70
+ const commands = {};
71
+ const labels = {
72
+ typeCheck: 'Type check command',
73
+ lint: 'Lint command',
74
+ build: 'Build command',
75
+ test: 'Test command',
76
+ };
77
+ for (const [key, defaultVal] of Object.entries(defaults)) {
78
+ const val = await p.text({
79
+ message: labels[key] || key,
80
+ placeholder: defaultVal || 'none',
81
+ defaultValue: defaultVal || '',
82
+ });
83
+ if (p.isCancel(val)) {
84
+ p.cancel('Setup cancelled.');
85
+ process.exit(0);
86
+ }
87
+ commands[key] = val || null;
88
+ }
89
+ return commands;
90
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Phase 1: Setup Wizard — runs on first install or when ~/.orbital/ is missing.
3
+ *
4
+ * Creates the Orbital home directory, seeds primitives, and optionally
5
+ * lets the user link projects immediately.
6
+ */
7
+ import fs from 'fs';
8
+ import * as p from '@clack/prompts';
9
+ import pc from 'picocolors';
10
+ import { NOTES } from '../ui.js';
11
+ import { isValidProjectPath, resolveProjectPath, ORBITAL_HOME } from '../detect.js';
12
+ export async function phaseSetupWizard(state) {
13
+ // Welcome and core concepts
14
+ p.note(NOTES.setupWelcome, 'Welcome');
15
+ // Create ~/.orbital/ and seed primitives
16
+ const s = p.spinner();
17
+ s.start('Setting up Orbital Command...');
18
+ try {
19
+ const { ensureOrbitalHome } = await import('../../global-config.js');
20
+ const { seedGlobalPrimitives } = await import('../../init.js');
21
+ ensureOrbitalHome();
22
+ seedGlobalPrimitives();
23
+ // Create empty registry if it doesn't exist
24
+ const registryPath = `${ORBITAL_HOME}/config.json`;
25
+ if (!fs.existsSync(registryPath)) {
26
+ fs.writeFileSync(registryPath, JSON.stringify({ version: 1, projects: [] }, null, 2), 'utf8');
27
+ }
28
+ s.stop('Orbital Command is ready.');
29
+ }
30
+ catch (err) {
31
+ s.stop('Setup failed.');
32
+ p.log.error(err instanceof Error ? err.message : String(err));
33
+ process.exit(1);
34
+ }
35
+ // Offer to link projects
36
+ p.note(NOTES.addProject, 'Projects');
37
+ let addMore = true;
38
+ while (addMore) {
39
+ const wantsProject = await p.confirm({
40
+ message: state.linkedProjects.length === 0
41
+ ? 'Add a project now?'
42
+ : 'Add another project?',
43
+ initialValue: state.linkedProjects.length === 0,
44
+ });
45
+ if (p.isCancel(wantsProject) || !wantsProject) {
46
+ addMore = false;
47
+ break;
48
+ }
49
+ const projectPath = await p.text({
50
+ message: 'Project path',
51
+ placeholder: '~/Code/my-project',
52
+ validate: (val) => {
53
+ if (!val || !val.trim())
54
+ return 'Path is required';
55
+ return isValidProjectPath(val.trim());
56
+ },
57
+ });
58
+ if (p.isCancel(projectPath)) {
59
+ addMore = false;
60
+ break;
61
+ }
62
+ const resolved = resolveProjectPath(projectPath.trim());
63
+ state.linkedProjects.push(resolved);
64
+ p.log.success(`Added: ${pc.cyan(resolved)}`);
65
+ }
66
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Phase 2 welcome gate — project-scoped only.
3
+ *
4
+ * If the project is already initialized, offers re-init or config editor.
5
+ * If not, returns false to continue the project setup flow.
6
+ */
7
+ import * as p from '@clack/prompts';
8
+ import pc from 'picocolors';
9
+ import { NOTES } from '../ui.js';
10
+ import { runConfigEditor } from '../config-editor.js';
11
+ export async function phaseWelcome(state) {
12
+ if (state.isProjectInitialized) {
13
+ p.note(NOTES.reconfigure, pc.yellow('Already Initialized'));
14
+ const action = await p.select({
15
+ message: 'What would you like to do?',
16
+ options: [
17
+ { value: 'reinit', label: 'Re-initialize (--force)', hint: 'reset all templates to defaults' },
18
+ { value: 'configure', label: 'Open config editor', hint: 'modify settings without resetting' },
19
+ { value: 'cancel', label: 'Cancel' },
20
+ ],
21
+ });
22
+ if (p.isCancel(action) || action === 'cancel') {
23
+ p.cancel('Cancelled.');
24
+ process.exit(0);
25
+ }
26
+ if (action === 'configure') {
27
+ await runConfigEditor(state.projectRoot, state.packageVersion, []);
28
+ process.exit(0);
29
+ }
30
+ // Re-init — continue through the full project setup with force
31
+ return true;
32
+ }
33
+ // Not initialized — continue normally
34
+ return false;
35
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Phase 2: Workflow preset selection.
3
+ */
4
+ import * as p from '@clack/prompts';
5
+ import { WORKFLOW_PRESETS } from '../types.js';
6
+ import { NOTES } from '../ui.js';
7
+ export async function phaseWorkflowSetup(state) {
8
+ p.note(NOTES.workflow, 'Workflow Selection');
9
+ const preset = await p.select({
10
+ message: 'Choose a workflow preset',
11
+ options: WORKFLOW_PRESETS.map(p => ({
12
+ value: p.value,
13
+ label: p.label,
14
+ hint: p.hint,
15
+ })),
16
+ });
17
+ if (p.isCancel(preset)) {
18
+ p.cancel('Setup cancelled.');
19
+ process.exit(0);
20
+ }
21
+ state.workflowPreset = preset;
22
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Types for the interactive CLI wizard.
3
+ *
4
+ * Two wizard flows:
5
+ * Phase 1 (SetupState) — first-time Orbital setup, ~/.orbital/ creation
6
+ * Phase 2 (ProjectSetupState) — per-project scaffolding into .claude/
7
+ */
8
+ export const WORKFLOW_PRESETS = [
9
+ {
10
+ value: 'default',
11
+ label: 'Default',
12
+ hint: '7 lists, trunk-based — Icebox → Planning → Backlog → Implementing → Review → Completed → Main',
13
+ },
14
+ {
15
+ value: 'minimal',
16
+ label: 'Minimal',
17
+ hint: '3 lists — To Do → In Progress → Done',
18
+ },
19
+ {
20
+ value: 'development',
21
+ label: 'Development',
22
+ hint: '5 lists, dev branch — Backlog → Implementing → Review → Completed → Dev',
23
+ },
24
+ {
25
+ value: 'gitflow',
26
+ label: 'Gitflow',
27
+ hint: '9 lists, multi-branch — Full pipeline with Dev, Staging, and Production',
28
+ },
29
+ ];
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Shared UI helpers, concept notes, and formatting for the wizard.
3
+ */
4
+ import pc from 'picocolors';
5
+ // ─── Concept Notes ──────────────────────────────────────────────
6
+ export const NOTES = {
7
+ // Phase 1: Setup wizard (runs on install / first use)
8
+ setupWelcome: `Orbital Command is a mission control layer for Claude Code.
9
+
10
+ It gives your projects a real-time dashboard with a Kanban board,
11
+ ${pc.cyan('scopes')} (work items), ${pc.cyan('workflow stages')}, ${pc.cyan('quality gates')},
12
+ ${pc.cyan('dispatches')} (automated Claude sessions), and a ${pc.cyan('sprint orchestrator')}.
13
+
14
+ Everything is driven by config files and hooks inside your project's
15
+ ${pc.cyan('.claude/')} directory — no database or external service required.`,
16
+ setupComplete: `${pc.bold('Setup complete.')}
17
+
18
+ ${pc.cyan('orbital init')} Add a project (run in a project directory)
19
+ ${pc.cyan('orbital launch --open')} Start the dashboard
20
+ ${pc.cyan('orbital doctor')} Health check & version info`,
21
+ addProject: `You can add projects now or later with ${pc.cyan('orbital init')}.
22
+ Each project gets its own workflow, scopes, and quality gates.`,
23
+ // Phase 2: Project setup (runs per-project)
24
+ reconfigure: `This project is already initialized with Orbital Command.
25
+ You can reconfigure settings or run ${pc.cyan('orbital init --force')} to reset.`,
26
+ projectConfig: `${pc.bold('Project Config')} ${pc.dim('(.claude/orbital.config.json)')}
27
+
28
+ Each project gets its own config inside ${pc.cyan('.claude/')}. The project
29
+ config controls the name shown in the dashboard, ports, build commands
30
+ used by quality gates, and agent definitions.`,
31
+ workflow: `${pc.bold('Workflows')} ${pc.dim('(Scopes, Lists, Dispatches)')}
32
+
33
+ Orbital organizes work into ${pc.cyan('scopes')} (cards) that move through
34
+ ${pc.cyan('lists')} (Kanban columns). Transitions between lists can trigger
35
+ commands, quality gates, and Claude Code sessions (${pc.cyan('dispatches')}).
36
+
37
+ Choose a preset to start — you can customize it later from the
38
+ dashboard's workflow editor or by editing ${pc.cyan('.claude/config/workflow.json')}.`,
39
+ postInstall: (counts) => `${pc.bold('What was just created')}
40
+
41
+ ${pc.cyan('Hooks')} (${counts.hooks}) Lifecycle scripts that enforce rules on transitions
42
+ ${pc.cyan('Skills')} (${counts.skills}) Slash commands for Claude (/scope-create, /git-commit, etc.)
43
+ ${pc.cyan('Agents')} (${counts.agents}) Team specifications for code review, architecture, security
44
+ ${pc.cyan('Workflow')} Your selected preset defining lists and transitions
45
+ ${pc.cyan('Quality Gates')} Automated checks (lint, typecheck, tests) before transitions`,
46
+ nextSteps: `${pc.bold('Next Steps')}
47
+
48
+ 1. ${pc.cyan('orbital launch --open')} Open the dashboard
49
+ 2. Create a scope from the board or use ${pc.cyan('/scope-create')}
50
+ 3. Use ${pc.cyan('/scope-implement')} to start working on a scope
51
+
52
+ ${pc.bold('Useful Commands')}
53
+
54
+ ${pc.cyan('orbital status')} See template sync status
55
+ ${pc.cyan('orbital config')} Modify project settings
56
+ ${pc.cyan('orbital update')} Sync to latest templates
57
+ ${pc.cyan('orbital doctor')} Health check & version info`,
58
+ };
59
+ // ─── Formatting Helpers ─────────────────────────────────────────
60
+ export function formatDetectedCommands(commands) {
61
+ const entries = Object.entries(commands).filter(([, v]) => v !== null);
62
+ if (entries.length === 0)
63
+ return pc.dim(' No commands detected');
64
+ return entries
65
+ .map(([key, val]) => ` ${pc.cyan(key.padEnd(12))} ${val}`)
66
+ .join('\n');
67
+ }
68
+ export function formatSummary(state) {
69
+ return [
70
+ ` Project: ${pc.cyan(state.projectName || 'Unknown')}`,
71
+ ` Workflow: ${pc.cyan(state.workflowPreset || 'default')}`,
72
+ ` Ports: ${pc.cyan(String(state.serverPort || 4444))} (server) / ${pc.cyan(String(state.clientPort || 4445))} (client)`,
73
+ ].join('\n');
74
+ }