orbital-command 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. package/README.md +67 -42
  2. package/bin/commands/config.js +19 -0
  3. package/bin/commands/events.js +40 -0
  4. package/bin/commands/launch.js +126 -0
  5. package/bin/commands/manifest.js +283 -0
  6. package/bin/commands/registry.js +104 -0
  7. package/bin/commands/update.js +24 -0
  8. package/bin/lib/helpers.js +229 -0
  9. package/bin/orbital.js +147 -319
  10. package/dist/assets/Landing-CfQdHR0N.js +11 -0
  11. package/dist/assets/PrimitivesConfig-DThSipFy.js +32 -0
  12. package/dist/assets/QualityGates-B4kxM5UU.js +26 -0
  13. package/dist/assets/SessionTimeline-Bz1iZnmg.js +1 -0
  14. package/dist/assets/Settings-DLcZwbCT.js +12 -0
  15. package/dist/assets/SourceControl-BMNIz7Lt.js +36 -0
  16. package/dist/assets/WorkflowVisualizer-CxuSBOYu.js +69 -0
  17. package/dist/assets/arrow-down-DVPp6_qp.js +6 -0
  18. package/dist/assets/bot-NFaJBDn_.js +6 -0
  19. package/dist/assets/charts-LGLb8hyU.js +68 -0
  20. package/dist/assets/circle-x-IsFCkBZu.js +6 -0
  21. package/dist/assets/file-text-J1cebZXF.js +6 -0
  22. package/dist/assets/globe-WzeyHsUc.js +6 -0
  23. package/dist/assets/index-BdJ57EhC.css +1 -0
  24. package/dist/assets/index-o4ScMAuR.js +349 -0
  25. package/dist/assets/key-CKR8JJSj.js +6 -0
  26. package/dist/assets/minus-CHBsJyjp.js +6 -0
  27. package/dist/assets/radio-xqZaR-Uk.js +6 -0
  28. package/dist/assets/rocket-D_xvvNG6.js +6 -0
  29. package/dist/assets/shield-TdB1yv_a.js +6 -0
  30. package/dist/assets/ui-BmsSg9jU.js +53 -0
  31. package/dist/assets/useSocketListener-0L5yiN5i.js +1 -0
  32. package/dist/assets/useWorkflowEditor-CqeRWVQX.js +11 -0
  33. package/dist/assets/{vendor-Dzv9lrRc.js → vendor-Bqt8AJn2.js} +1 -1
  34. package/dist/assets/workflow-constants-Rw-GmgHZ.js +6 -0
  35. package/dist/assets/zap-C9wqYMpl.js +6 -0
  36. package/dist/favicon.svg +1 -0
  37. package/dist/index.html +6 -5
  38. package/dist/server/server/__tests__/data-routes.test.js +126 -0
  39. package/dist/server/server/__tests__/helpers/db.js +17 -0
  40. package/dist/server/server/__tests__/helpers/mock-emitter.js +8 -0
  41. package/dist/server/server/__tests__/scope-routes.test.js +138 -0
  42. package/dist/server/server/__tests__/sprint-routes.test.js +102 -0
  43. package/dist/server/server/__tests__/workflow-routes.test.js +107 -0
  44. package/dist/server/server/config-migrator.js +135 -0
  45. package/dist/server/server/config.js +51 -7
  46. package/dist/server/server/database.js +21 -28
  47. package/dist/server/server/global-config.js +143 -0
  48. package/dist/server/server/index.js +118 -276
  49. package/dist/server/server/init.js +243 -225
  50. package/dist/server/server/launch.js +29 -0
  51. package/dist/server/server/manifest-types.js +8 -0
  52. package/dist/server/server/manifest.js +454 -0
  53. package/dist/server/server/migrate-legacy.js +229 -0
  54. package/dist/server/server/parsers/event-parser.js +4 -1
  55. package/dist/server/server/parsers/event-parser.test.js +117 -0
  56. package/dist/server/server/parsers/scope-parser.js +74 -28
  57. package/dist/server/server/parsers/scope-parser.test.js +230 -0
  58. package/dist/server/server/project-context.js +265 -0
  59. package/dist/server/server/project-emitter.js +41 -0
  60. package/dist/server/server/project-manager.js +297 -0
  61. package/dist/server/server/routes/aggregate-routes.js +871 -0
  62. package/dist/server/server/routes/config-routes.js +41 -90
  63. package/dist/server/server/routes/data-routes.js +25 -123
  64. package/dist/server/server/routes/dispatch-routes.js +37 -15
  65. package/dist/server/server/routes/git-routes.js +74 -0
  66. package/dist/server/server/routes/manifest-routes.js +319 -0
  67. package/dist/server/server/routes/scope-routes.js +45 -28
  68. package/dist/server/server/routes/sync-routes.js +134 -0
  69. package/dist/server/server/routes/version-routes.js +1 -15
  70. package/dist/server/server/routes/workflow-routes.js +9 -3
  71. package/dist/server/server/schema.js +3 -0
  72. package/dist/server/server/services/batch-orchestrator.js +41 -17
  73. package/dist/server/server/services/claude-session-service.js +17 -14
  74. package/dist/server/server/services/config-service.js +10 -1
  75. package/dist/server/server/services/deploy-service.test.js +119 -0
  76. package/dist/server/server/services/event-service.js +64 -1
  77. package/dist/server/server/services/event-service.test.js +191 -0
  78. package/dist/server/server/services/gate-service.test.js +105 -0
  79. package/dist/server/server/services/git-service.js +108 -4
  80. package/dist/server/server/services/github-service.js +110 -2
  81. package/dist/server/server/services/readiness-service.test.js +190 -0
  82. package/dist/server/server/services/scope-cache.js +5 -1
  83. package/dist/server/server/services/scope-cache.test.js +142 -0
  84. package/dist/server/server/services/scope-service.js +222 -131
  85. package/dist/server/server/services/scope-service.test.js +137 -0
  86. package/dist/server/server/services/sprint-orchestrator.js +29 -15
  87. package/dist/server/server/services/sprint-service.js +23 -3
  88. package/dist/server/server/services/sprint-service.test.js +238 -0
  89. package/dist/server/server/services/sync-service.js +434 -0
  90. package/dist/server/server/services/sync-types.js +2 -0
  91. package/dist/server/server/services/workflow-service.js +26 -5
  92. package/dist/server/server/services/workflow-service.test.js +159 -0
  93. package/dist/server/server/settings-sync.js +284 -0
  94. package/dist/server/server/uninstall.js +195 -0
  95. package/dist/server/server/update-planner.js +279 -0
  96. package/dist/server/server/update.js +212 -0
  97. package/dist/server/server/utils/cc-hooks-parser.js +3 -0
  98. package/dist/server/server/utils/cc-hooks-parser.test.js +86 -0
  99. package/dist/server/server/utils/dispatch-utils.js +83 -24
  100. package/dist/server/server/utils/dispatch-utils.test.js +182 -0
  101. package/dist/server/server/utils/flag-builder.js +54 -0
  102. package/dist/server/server/utils/json-fields.js +14 -0
  103. package/dist/server/server/utils/json-fields.test.js +73 -0
  104. package/dist/server/server/utils/logger.js +37 -3
  105. package/dist/server/server/utils/package-info.js +30 -0
  106. package/dist/server/server/utils/route-helpers.js +47 -0
  107. package/dist/server/server/utils/route-helpers.test.js +115 -0
  108. package/dist/server/server/utils/terminal-launcher.js +79 -25
  109. package/dist/server/server/utils/worktree-manager.js +13 -4
  110. package/dist/server/server/validator.js +230 -0
  111. package/dist/server/server/watchers/event-watcher.js +28 -13
  112. package/dist/server/server/watchers/global-watcher.js +63 -0
  113. package/dist/server/server/watchers/scope-watcher.js +27 -12
  114. package/dist/server/server/wizard/config-editor.js +237 -0
  115. package/dist/server/server/wizard/detect.js +96 -0
  116. package/dist/server/server/wizard/doctor.js +115 -0
  117. package/dist/server/server/wizard/index.js +340 -0
  118. package/dist/server/server/wizard/phases/confirm.js +39 -0
  119. package/dist/server/server/wizard/phases/project-setup.js +90 -0
  120. package/dist/server/server/wizard/phases/setup-wizard.js +66 -0
  121. package/dist/server/server/wizard/phases/welcome.js +32 -0
  122. package/dist/server/server/wizard/phases/workflow-setup.js +22 -0
  123. package/dist/server/server/wizard/types.js +29 -0
  124. package/dist/server/server/wizard/ui.js +73 -0
  125. package/dist/server/shared/__fixtures__/workflow-configs.js +75 -0
  126. package/dist/server/shared/api-types.js +80 -1
  127. package/dist/server/shared/default-workflow.json +65 -0
  128. package/dist/server/shared/onboarding-tour.test.js +81 -0
  129. package/dist/server/shared/project-colors.js +24 -0
  130. package/dist/server/shared/workflow-config.test.js +84 -0
  131. package/dist/server/shared/workflow-engine.js +1 -1
  132. package/dist/server/shared/workflow-engine.test.js +302 -0
  133. package/dist/server/shared/workflow-normalizer.js +101 -0
  134. package/dist/server/shared/workflow-normalizer.test.js +100 -0
  135. package/dist/server/src/components/onboarding/tour-steps.js +84 -0
  136. package/package.json +34 -29
  137. package/schemas/orbital.config.schema.json +2 -5
  138. package/scripts/postinstall.js +18 -6
  139. package/scripts/release.sh +53 -0
  140. package/server/__tests__/data-routes.test.ts +151 -0
  141. package/server/__tests__/helpers/db.ts +19 -0
  142. package/server/__tests__/helpers/mock-emitter.ts +10 -0
  143. package/server/__tests__/scope-routes.test.ts +158 -0
  144. package/server/__tests__/sprint-routes.test.ts +118 -0
  145. package/server/__tests__/workflow-routes.test.ts +120 -0
  146. package/server/config-migrator.ts +160 -0
  147. package/server/config.ts +64 -12
  148. package/server/database.ts +22 -31
  149. package/server/global-config.ts +204 -0
  150. package/server/index.ts +139 -316
  151. package/server/init.ts +266 -234
  152. package/server/launch.ts +32 -0
  153. package/server/manifest-types.ts +145 -0
  154. package/server/manifest.ts +494 -0
  155. package/server/migrate-legacy.ts +290 -0
  156. package/server/parsers/event-parser.test.ts +135 -0
  157. package/server/parsers/event-parser.ts +4 -1
  158. package/server/parsers/scope-parser.test.ts +270 -0
  159. package/server/parsers/scope-parser.ts +79 -31
  160. package/server/project-context.ts +325 -0
  161. package/server/project-emitter.ts +50 -0
  162. package/server/project-manager.ts +368 -0
  163. package/server/routes/aggregate-routes.ts +968 -0
  164. package/server/routes/config-routes.ts +43 -85
  165. package/server/routes/data-routes.ts +34 -156
  166. package/server/routes/dispatch-routes.ts +46 -17
  167. package/server/routes/git-routes.ts +77 -0
  168. package/server/routes/manifest-routes.ts +388 -0
  169. package/server/routes/scope-routes.ts +39 -30
  170. package/server/routes/sync-routes.ts +175 -0
  171. package/server/routes/version-routes.ts +1 -16
  172. package/server/routes/workflow-routes.ts +9 -3
  173. package/server/schema.ts +3 -0
  174. package/server/services/batch-orchestrator.ts +41 -17
  175. package/server/services/claude-session-service.ts +16 -14
  176. package/server/services/config-service.ts +10 -1
  177. package/server/services/deploy-service.test.ts +145 -0
  178. package/server/services/deploy-service.ts +2 -2
  179. package/server/services/event-service.test.ts +242 -0
  180. package/server/services/event-service.ts +92 -3
  181. package/server/services/gate-service.test.ts +131 -0
  182. package/server/services/gate-service.ts +2 -2
  183. package/server/services/git-service.ts +137 -4
  184. package/server/services/github-service.ts +120 -2
  185. package/server/services/readiness-service.test.ts +217 -0
  186. package/server/services/scope-cache.test.ts +167 -0
  187. package/server/services/scope-cache.ts +4 -1
  188. package/server/services/scope-service.test.ts +169 -0
  189. package/server/services/scope-service.ts +224 -130
  190. package/server/services/sprint-orchestrator.ts +30 -15
  191. package/server/services/sprint-service.test.ts +271 -0
  192. package/server/services/sprint-service.ts +29 -5
  193. package/server/services/sync-service.ts +482 -0
  194. package/server/services/sync-types.ts +77 -0
  195. package/server/services/workflow-service.test.ts +190 -0
  196. package/server/services/workflow-service.ts +29 -9
  197. package/server/settings-sync.ts +359 -0
  198. package/server/uninstall.ts +214 -0
  199. package/server/update-planner.ts +346 -0
  200. package/server/update.ts +263 -0
  201. package/server/utils/cc-hooks-parser.test.ts +96 -0
  202. package/server/utils/cc-hooks-parser.ts +4 -0
  203. package/server/utils/dispatch-utils.test.ts +245 -0
  204. package/server/utils/dispatch-utils.ts +102 -30
  205. package/server/utils/flag-builder.ts +56 -0
  206. package/server/utils/json-fields.test.ts +83 -0
  207. package/server/utils/json-fields.ts +14 -0
  208. package/server/utils/logger.ts +40 -3
  209. package/server/utils/package-info.ts +32 -0
  210. package/server/utils/route-helpers.test.ts +144 -0
  211. package/server/utils/route-helpers.ts +50 -0
  212. package/server/utils/terminal-launcher.ts +85 -25
  213. package/server/utils/worktree-manager.ts +9 -4
  214. package/server/validator.ts +270 -0
  215. package/server/watchers/event-watcher.ts +24 -12
  216. package/server/watchers/global-watcher.ts +77 -0
  217. package/server/watchers/scope-watcher.ts +21 -9
  218. package/server/wizard/config-editor.ts +248 -0
  219. package/server/wizard/detect.ts +104 -0
  220. package/server/wizard/doctor.ts +114 -0
  221. package/server/wizard/index.ts +438 -0
  222. package/server/wizard/phases/confirm.ts +45 -0
  223. package/server/wizard/phases/project-setup.ts +106 -0
  224. package/server/wizard/phases/setup-wizard.ts +78 -0
  225. package/server/wizard/phases/welcome.ts +39 -0
  226. package/server/wizard/phases/workflow-setup.ts +28 -0
  227. package/server/wizard/types.ts +56 -0
  228. package/server/wizard/ui.ts +92 -0
  229. package/shared/__fixtures__/workflow-configs.ts +80 -0
  230. package/shared/api-types.ts +106 -0
  231. package/shared/onboarding-tour.test.ts +94 -0
  232. package/shared/project-colors.ts +24 -0
  233. package/shared/workflow-config.test.ts +111 -0
  234. package/shared/workflow-config.ts +7 -0
  235. package/shared/workflow-engine.test.ts +388 -0
  236. package/shared/workflow-engine.ts +1 -1
  237. package/shared/workflow-normalizer.test.ts +119 -0
  238. package/shared/workflow-normalizer.ts +118 -0
  239. package/templates/agents/QUICK-REFERENCE.md +1 -0
  240. package/templates/agents/README.md +1 -0
  241. package/templates/agents/SKILL-TRIGGERS.md +11 -0
  242. package/templates/agents/green-team/deep-dive.md +361 -0
  243. package/templates/hooks/end-session.sh +4 -1
  244. package/templates/hooks/init-session.sh +1 -0
  245. package/templates/hooks/orbital-emit.sh +2 -2
  246. package/templates/hooks/orbital-report-deploy.sh +4 -4
  247. package/templates/hooks/orbital-report-gates.sh +4 -4
  248. package/templates/hooks/orbital-scope-update.sh +1 -1
  249. package/templates/hooks/scope-commit-logger.sh +2 -2
  250. package/templates/hooks/scope-create-cleanup.sh +2 -2
  251. package/templates/hooks/scope-create-gate.sh +2 -5
  252. package/templates/hooks/scope-gate.sh +4 -6
  253. package/templates/hooks/scope-helpers.sh +28 -1
  254. package/templates/hooks/scope-lifecycle-gate.sh +14 -5
  255. package/templates/hooks/scope-prepare.sh +67 -12
  256. package/templates/hooks/scope-transition.sh +14 -6
  257. package/templates/hooks/time-tracker.sh +2 -5
  258. package/templates/migrations/renames.json +1 -0
  259. package/templates/orbital.config.json +8 -6
  260. package/{shared/default-workflow.json → templates/presets/default.json} +65 -0
  261. package/templates/presets/development.json +4 -4
  262. package/templates/presets/gitflow.json +7 -0
  263. package/templates/prompts/README.md +23 -0
  264. package/templates/prompts/deep-dive-audit.md +94 -0
  265. package/templates/quick/rules.md +56 -5
  266. package/templates/settings-hooks.json +1 -1
  267. package/templates/skills/git-commit/SKILL.md +27 -7
  268. package/templates/skills/git-dev/SKILL.md +13 -4
  269. package/templates/skills/git-main/SKILL.md +13 -3
  270. package/templates/skills/git-production/SKILL.md +9 -2
  271. package/templates/skills/git-staging/SKILL.md +11 -3
  272. package/templates/skills/scope-create/SKILL.md +17 -3
  273. package/templates/skills/scope-fix-review/SKILL.md +14 -7
  274. package/templates/skills/scope-implement/SKILL.md +15 -4
  275. package/templates/skills/scope-post-review/SKILL.md +77 -7
  276. package/templates/skills/scope-pre-review/SKILL.md +11 -4
  277. package/templates/skills/scope-verify/SKILL.md +5 -3
  278. package/templates/skills/test-code-review/SKILL.md +41 -33
  279. package/templates/skills/test-scaffold/SKILL.md +222 -0
  280. package/dist/assets/WorkflowVisualizer-BZ21PIIF.js +0 -84
  281. package/dist/assets/charts-D__PA1zp.js +0 -72
  282. package/dist/assets/index-D1G6i0nS.css +0 -1
  283. package/dist/assets/index-DpItvKpf.js +0 -419
  284. package/dist/assets/ui-BvF022GT.js +0 -53
  285. package/index.html +0 -15
  286. package/postcss.config.js +0 -6
  287. package/src/App.tsx +0 -33
  288. package/src/components/AgentBadge.tsx +0 -40
  289. package/src/components/BatchPreflightModal.tsx +0 -115
  290. package/src/components/CardDisplayToggle.tsx +0 -74
  291. package/src/components/ColumnHeaderActions.tsx +0 -55
  292. package/src/components/ColumnMenu.tsx +0 -99
  293. package/src/components/DeployHistory.tsx +0 -141
  294. package/src/components/DispatchModal.tsx +0 -164
  295. package/src/components/DispatchPopover.tsx +0 -139
  296. package/src/components/DragOverlay.tsx +0 -25
  297. package/src/components/DriftSidebar.tsx +0 -140
  298. package/src/components/EnvironmentStrip.tsx +0 -88
  299. package/src/components/ErrorBoundary.tsx +0 -62
  300. package/src/components/FilterChip.tsx +0 -105
  301. package/src/components/GateIndicator.tsx +0 -33
  302. package/src/components/IdeaDetailModal.tsx +0 -190
  303. package/src/components/IdeaFormDialog.tsx +0 -113
  304. package/src/components/KanbanColumn.tsx +0 -201
  305. package/src/components/MarkdownRenderer.tsx +0 -114
  306. package/src/components/NeonGrid.tsx +0 -128
  307. package/src/components/PromotionQueue.tsx +0 -89
  308. package/src/components/ScopeCard.tsx +0 -234
  309. package/src/components/ScopeDetailModal.tsx +0 -255
  310. package/src/components/ScopeFilterBar.tsx +0 -152
  311. package/src/components/SearchInput.tsx +0 -102
  312. package/src/components/SessionPanel.tsx +0 -335
  313. package/src/components/SprintContainer.tsx +0 -303
  314. package/src/components/SprintDependencyDialog.tsx +0 -78
  315. package/src/components/SprintPreflightModal.tsx +0 -138
  316. package/src/components/StatusBar.tsx +0 -168
  317. package/src/components/SwimCell.tsx +0 -67
  318. package/src/components/SwimLaneRow.tsx +0 -94
  319. package/src/components/SwimlaneBoardView.tsx +0 -108
  320. package/src/components/VersionBadge.tsx +0 -139
  321. package/src/components/ViewModeSelector.tsx +0 -114
  322. package/src/components/config/AgentChip.tsx +0 -53
  323. package/src/components/config/AgentCreateDialog.tsx +0 -321
  324. package/src/components/config/AgentEditor.tsx +0 -175
  325. package/src/components/config/DirectoryTree.tsx +0 -582
  326. package/src/components/config/FileEditor.tsx +0 -550
  327. package/src/components/config/HookChip.tsx +0 -50
  328. package/src/components/config/StageCard.tsx +0 -198
  329. package/src/components/config/TransitionZone.tsx +0 -173
  330. package/src/components/config/UnifiedWorkflowPipeline.tsx +0 -216
  331. package/src/components/config/WorkflowPipeline.tsx +0 -161
  332. package/src/components/source-control/BranchList.tsx +0 -93
  333. package/src/components/source-control/BranchPanel.tsx +0 -105
  334. package/src/components/source-control/CommitLog.tsx +0 -100
  335. package/src/components/source-control/CommitRow.tsx +0 -47
  336. package/src/components/source-control/GitHubPanel.tsx +0 -110
  337. package/src/components/source-control/GitHubSetupGuide.tsx +0 -52
  338. package/src/components/source-control/GitOverviewBar.tsx +0 -101
  339. package/src/components/source-control/PullRequestList.tsx +0 -69
  340. package/src/components/source-control/WorktreeList.tsx +0 -80
  341. package/src/components/ui/badge.tsx +0 -41
  342. package/src/components/ui/button.tsx +0 -55
  343. package/src/components/ui/card.tsx +0 -78
  344. package/src/components/ui/dialog.tsx +0 -94
  345. package/src/components/ui/popover.tsx +0 -33
  346. package/src/components/ui/scroll-area.tsx +0 -54
  347. package/src/components/ui/separator.tsx +0 -28
  348. package/src/components/ui/tabs.tsx +0 -52
  349. package/src/components/ui/toggle-switch.tsx +0 -35
  350. package/src/components/ui/tooltip.tsx +0 -27
  351. package/src/components/workflow/AddEdgeDialog.tsx +0 -217
  352. package/src/components/workflow/AddListDialog.tsx +0 -201
  353. package/src/components/workflow/ChecklistEditor.tsx +0 -239
  354. package/src/components/workflow/CommandPrefixManager.tsx +0 -118
  355. package/src/components/workflow/ConfigSettingsPanel.tsx +0 -189
  356. package/src/components/workflow/DirectionSelector.tsx +0 -133
  357. package/src/components/workflow/DispatchConfigPanel.tsx +0 -180
  358. package/src/components/workflow/EdgeDetailPanel.tsx +0 -236
  359. package/src/components/workflow/EdgePropertyEditor.tsx +0 -251
  360. package/src/components/workflow/EditToolbar.tsx +0 -138
  361. package/src/components/workflow/HookDetailPanel.tsx +0 -250
  362. package/src/components/workflow/HookExecutionLog.tsx +0 -24
  363. package/src/components/workflow/HookSourceModal.tsx +0 -129
  364. package/src/components/workflow/HooksDashboard.tsx +0 -363
  365. package/src/components/workflow/ListPropertyEditor.tsx +0 -251
  366. package/src/components/workflow/MigrationPreviewDialog.tsx +0 -237
  367. package/src/components/workflow/MovementRulesPanel.tsx +0 -188
  368. package/src/components/workflow/NodeDetailPanel.tsx +0 -245
  369. package/src/components/workflow/PresetSelector.tsx +0 -414
  370. package/src/components/workflow/SkillCommandBuilder.tsx +0 -174
  371. package/src/components/workflow/WorkflowEdgeComponent.tsx +0 -145
  372. package/src/components/workflow/WorkflowNode.tsx +0 -147
  373. package/src/components/workflow/graphLayout.ts +0 -186
  374. package/src/components/workflow/mergeHooks.ts +0 -85
  375. package/src/components/workflow/useEditHistory.ts +0 -88
  376. package/src/components/workflow/useWorkflowEditor.ts +0 -262
  377. package/src/components/workflow/validateConfig.ts +0 -70
  378. package/src/hooks/useActiveDispatches.ts +0 -198
  379. package/src/hooks/useBoardSettings.ts +0 -170
  380. package/src/hooks/useCardDisplay.ts +0 -57
  381. package/src/hooks/useCcHooks.ts +0 -24
  382. package/src/hooks/useConfigTree.ts +0 -51
  383. package/src/hooks/useEnforcementRules.ts +0 -46
  384. package/src/hooks/useEvents.ts +0 -59
  385. package/src/hooks/useFileEditor.ts +0 -165
  386. package/src/hooks/useGates.ts +0 -57
  387. package/src/hooks/useIdeaActions.ts +0 -53
  388. package/src/hooks/useKanbanDnd.ts +0 -410
  389. package/src/hooks/useOrbitalConfig.ts +0 -54
  390. package/src/hooks/usePipeline.ts +0 -47
  391. package/src/hooks/usePipelineData.ts +0 -338
  392. package/src/hooks/useReconnect.ts +0 -25
  393. package/src/hooks/useScopeFilters.ts +0 -125
  394. package/src/hooks/useScopeSessions.ts +0 -44
  395. package/src/hooks/useScopes.ts +0 -67
  396. package/src/hooks/useSearch.ts +0 -67
  397. package/src/hooks/useSettings.tsx +0 -187
  398. package/src/hooks/useSocket.ts +0 -25
  399. package/src/hooks/useSourceControl.ts +0 -105
  400. package/src/hooks/useSprintPreflight.ts +0 -55
  401. package/src/hooks/useSprints.ts +0 -154
  402. package/src/hooks/useStatusBarHighlight.ts +0 -18
  403. package/src/hooks/useSwimlaneBoardSettings.ts +0 -104
  404. package/src/hooks/useTheme.ts +0 -9
  405. package/src/hooks/useTransitionReadiness.ts +0 -53
  406. package/src/hooks/useVersion.ts +0 -155
  407. package/src/hooks/useViolations.ts +0 -65
  408. package/src/hooks/useWorkflow.tsx +0 -125
  409. package/src/hooks/useZoomModifier.ts +0 -19
  410. package/src/index.css +0 -797
  411. package/src/layouts/DashboardLayout.tsx +0 -113
  412. package/src/lib/collisionDetection.ts +0 -20
  413. package/src/lib/scope-fields.ts +0 -61
  414. package/src/lib/swimlane.ts +0 -146
  415. package/src/lib/utils.ts +0 -15
  416. package/src/main.tsx +0 -19
  417. package/src/socket.ts +0 -11
  418. package/src/types/index.ts +0 -497
  419. package/src/views/AgentFeed.tsx +0 -339
  420. package/src/views/DeployPipeline.tsx +0 -59
  421. package/src/views/EnforcementView.tsx +0 -378
  422. package/src/views/PrimitivesConfig.tsx +0 -500
  423. package/src/views/QualityGates.tsx +0 -1012
  424. package/src/views/ScopeBoard.tsx +0 -454
  425. package/src/views/SessionTimeline.tsx +0 -516
  426. package/src/views/Settings.tsx +0 -183
  427. package/src/views/SourceControl.tsx +0 -95
  428. package/src/views/WorkflowVisualizer.tsx +0 -382
  429. package/tailwind.config.js +0 -161
  430. package/tsconfig.json +0 -25
  431. package/vite.config.ts +0 -38
package/server/init.ts CHANGED
@@ -1,11 +1,25 @@
1
1
  /**
2
- * Shared init logic — used by both the CLI (`orbital init`) and
3
- * programmatic callers (e.g. tests).
2
+ * Shared init logic — used by the wizard and
3
+ * programmatic callers (e.g. tests, API routes).
4
4
  */
5
5
 
6
6
  import fs from 'fs';
7
7
  import path from 'path';
8
8
  import { fileURLToPath } from 'url';
9
+ import { GLOBAL_PRIMITIVES_DIR, ensureOrbitalHome } from './global-config.js';
10
+ import {
11
+ saveManifest,
12
+ createManifest,
13
+ hashFile,
14
+ buildTemplateInventory,
15
+ templateFileRecord,
16
+ userFileRecord,
17
+ isSelfHosting,
18
+ getSymlinkTarget,
19
+ } from './manifest.js';
20
+ import type { OrbitalManifest } from './manifest-types.js';
21
+ import { getTemplateChecksum } from './settings-sync.js';
22
+ import { getPackageVersion as _getPackageVersionUtil } from './utils/package-info.js';
9
23
 
10
24
  const __filename = fileURLToPath(import.meta.url);
11
25
  const __dirname = path.dirname(__filename);
@@ -228,7 +242,8 @@ function generateManifest(config: Record<string, unknown>): string {
228
242
  lines.push('');
229
243
 
230
244
  lines.push('# ─── Entry point status ───');
231
- lines.push(`WORKFLOW_ENTRY_STATUS="${(config.entryPoint as string) || (lists[0]?.id as string) || 'todo'}"`);
245
+ const entryPointId = (lists.find((l) => l.isEntryPoint)?.id as string) || (lists[0]?.id as string) || 'todo';
246
+ lines.push(`WORKFLOW_ENTRY_STATUS="${entryPointId}"`);
232
247
  lines.push('');
233
248
 
234
249
  const listMap = new Map(lists.map((l) => [l.id, l]));
@@ -255,6 +270,25 @@ function generateManifest(config: Record<string, unknown>): string {
255
270
  lines.push(')');
256
271
  lines.push('');
257
272
 
273
+ lines.push('# ─── Commit session branch patterns (regex) ───');
274
+ lines.push(`WORKFLOW_COMMIT_BRANCHES="${(config.commitBranchPatterns as string) ?? ''}"`);
275
+ lines.push('');
276
+
277
+ lines.push('# ─── Backward-compat direction aliases (alias:from:to:sessionKey) ───');
278
+ lines.push('WORKFLOW_DIRECTION_ALIASES=(');
279
+ for (const edge of (config.edges as Array<Record<string, unknown>>) || []) {
280
+ if (edge.direction !== 'forward' || !edge.dispatchOnly) continue;
281
+ const targetList = listMap.get(edge.to as string);
282
+ if (!targetList) continue;
283
+ const group = targetList.group as string | undefined;
284
+ if (group?.startsWith('deploy')) {
285
+ const sessionKey = (targetList.sessionKey as string) ?? '';
286
+ lines.push(` "to-${edge.to as string}:${edge.from as string}:${edge.to as string}:${sessionKey}"`);
287
+ }
288
+ }
289
+ lines.push(')');
290
+ lines.push('');
291
+
258
292
  lines.push('# ─── Helper functions ──────────────────────────────');
259
293
  lines.push('');
260
294
  lines.push('status_to_dir() {');
@@ -489,20 +523,151 @@ function cleanEmptyDirs(dir: string): void {
489
523
  }
490
524
  }
491
525
 
526
+ // ─── Manifest Building ──────────────────────────────────────
527
+
528
+ /** Build a manifest by scanning .claude/ and classifying files against templates. */
529
+ function buildInitManifest(
530
+ projectRoot: string,
531
+ claudeDir: string,
532
+ preset: string,
533
+ ): OrbitalManifest {
534
+ const selfHosting = isSelfHosting(projectRoot);
535
+ const templateInventory = buildTemplateInventory(TEMPLATES_DIR);
536
+ const pkg = getPackageVersion();
537
+
538
+ const manifest = createManifest(pkg, preset);
539
+
540
+ // Classify all template files
541
+ for (const [relPath, templateHash] of templateInventory) {
542
+ const absPath = path.join(claudeDir, relPath);
543
+
544
+ if (selfHosting) {
545
+ const symlinkTarget = getSymlinkTarget(claudeDir, relPath);
546
+ if (symlinkTarget) {
547
+ manifest.files[relPath] = templateFileRecord(templateHash, symlinkTarget);
548
+ continue;
549
+ }
550
+ }
551
+
552
+ if (fs.existsSync(absPath)) {
553
+ const fileHash = hashFile(absPath);
554
+ if (fileHash === templateHash) {
555
+ manifest.files[relPath] = templateFileRecord(templateHash);
556
+ } else {
557
+ // File exists but doesn't match template — classify as outdated
558
+ // (no prior install to compare against, so we can't know if user edited it)
559
+ manifest.files[relPath] = {
560
+ origin: 'template',
561
+ status: 'outdated',
562
+ templateHash,
563
+ installedHash: fileHash,
564
+ };
565
+ }
566
+ }
567
+ // File doesn't exist — it may not have been copied (e.g. skipped on non-force init)
568
+ }
569
+
570
+ // Scan managed directories for user-created files
571
+ for (const dir of ['hooks', 'skills', 'agents']) {
572
+ const dirPath = path.join(claudeDir, dir);
573
+ if (!fs.existsSync(dirPath)) continue;
574
+
575
+ walkDirForManifest(dirPath, dir, (relPath, absPath) => {
576
+ if (manifest.files[relPath]) return; // Already classified
577
+ const fileHash = hashFile(absPath);
578
+ manifest.files[relPath] = userFileRecord(fileHash);
579
+ });
580
+ }
581
+
582
+ // Record settings hooks checksum
583
+ const settingsHooksPath = path.join(TEMPLATES_DIR, 'settings-hooks.json');
584
+ if (fs.existsSync(settingsHooksPath)) {
585
+ manifest.settingsHooksChecksum = getTemplateChecksum(settingsHooksPath);
586
+ }
587
+
588
+ // Record gitignore entries
589
+ manifest.gitignoreEntries = [
590
+ 'scopes/',
591
+ '.claude/orbital/',
592
+ '.claude/orbital-events/',
593
+ '.claude/config/workflow-manifest.sh',
594
+ ];
595
+
596
+ return manifest;
597
+ }
598
+
599
+ function getPackageVersion(): string {
600
+ return _getPackageVersionUtil(PACKAGE_ROOT);
601
+ }
602
+
603
+ /** Recursively walk a directory for manifest building. */
604
+ function walkDirForManifest(
605
+ dirPath: string,
606
+ prefix: string,
607
+ fn: (relPath: string, absPath: string) => void,
608
+ ): void {
609
+ if (!fs.existsSync(dirPath)) return;
610
+ for (const entry of fs.readdirSync(dirPath, { withFileTypes: true })) {
611
+ if (entry.name.startsWith('.')) continue;
612
+ const absPath = path.join(dirPath, entry.name);
613
+ const relPath = `${prefix}/${entry.name}`;
614
+ // Follow symlinks: use stat() to check if target is a directory
615
+ const stat = fs.statSync(absPath);
616
+ if (stat.isDirectory()) {
617
+ walkDirForManifest(absPath, relPath, fn);
618
+ } else {
619
+ fn(relPath, absPath);
620
+ }
621
+ }
622
+ }
623
+
492
624
  // ─── Exports ─────────────────────────────────────────────────
493
625
 
494
- export { TEMPLATES_DIR, ensureDir };
626
+ /** Seed ~/.orbital/primitives/ from package templates. Called by init, update, and server startup. */
627
+ export function seedGlobalPrimitives(): void {
628
+ ensureOrbitalHome();
629
+ for (const type of ['hooks', 'skills', 'agents'] as const) {
630
+ const src = path.join(TEMPLATES_DIR, type);
631
+ const dest = path.join(GLOBAL_PRIMITIVES_DIR, type);
632
+ if (fs.existsSync(src)) {
633
+ copyDirSync(src, dest, { overwrite: true });
634
+ }
635
+ }
636
+ }
637
+
638
+ export { TEMPLATES_DIR, ensureDir, cleanEmptyDirs, chmodScripts, listTemplateFiles, writeManifest, generateIndexMd, getPackageVersion };
639
+
640
+ // Re-export manifest utilities for CLI access via loadSharedModule()
641
+ export { loadManifest, saveManifest, hashFile, buildTemplateInventory, refreshFileStatuses, summarizeManifest } from './manifest.js';
642
+ export { validate, formatValidationReport } from './validator.js';
643
+
644
+ // Re-export update and uninstall from their new homes (backward compat for loadSharedModule)
645
+ export { runUpdate, type UpdateOptions } from './update.js';
646
+ export { runUninstall, type UninstallOptions } from './uninstall.js';
495
647
 
496
648
  export interface InitOptions {
497
649
  force?: boolean;
650
+ quiet?: boolean; // suppress console output (used by wizard)
651
+ preset?: string; // workflow preset name (default: 'default')
652
+ projectName?: string; // override auto-detected project name
653
+ serverPort?: number; // override default server port
654
+ clientPort?: number; // override default client port
655
+ commands?: Partial<Record<string, string | null>>; // override detected commands
498
656
  }
499
657
 
500
658
  export function runInit(projectRoot: string, options: InitOptions = {}): void {
501
659
  const force = options.force ?? false;
660
+ const quiet = options.quiet ?? false;
661
+ const selectedPreset = options.preset || 'default';
502
662
  const claudeDir = path.join(projectRoot, '.claude');
503
663
 
504
- console.log(`\nOrbital Command — init`);
505
- console.log(`Project root: ${projectRoot}\n`);
664
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
665
+ const log = quiet ? (..._args: unknown[]) => {} : console.log.bind(console);
666
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
667
+ const warn = quiet ? (..._args: unknown[]) => {} : console.warn.bind(console);
668
+
669
+ log(`\nOrbital Command — init`);
670
+ log(`Project root: ${projectRoot}\n`);
506
671
 
507
672
  // 1. Create directories
508
673
  const dirs = [
@@ -513,24 +678,26 @@ export function runInit(projectRoot: string, options: InitOptions = {}): void {
513
678
  ];
514
679
  for (const dir of dirs) {
515
680
  const wasCreated = ensureDir(dir);
516
- console.log(` ${wasCreated ? 'Created' : 'Exists '} ${path.relative(projectRoot, dir)}/`);
681
+ log(` ${wasCreated ? 'Created' : 'Exists '} ${path.relative(projectRoot, dir)}/`);
517
682
  }
518
683
 
519
- // 1b. Create scopes/ subdirectories from the default workflow preset
684
+ // 1b. Create scopes/ subdirectories from the selected workflow preset
685
+ const selectedPresetPath = path.join(TEMPLATES_DIR, 'presets', `${selectedPreset}.json`);
520
686
  const defaultPresetPath = path.join(TEMPLATES_DIR, 'presets', 'default.json');
687
+ const presetPath = fs.existsSync(selectedPresetPath) ? selectedPresetPath : defaultPresetPath;
521
688
  let scopeDirs = ['icebox'];
522
689
  try {
523
- const preset = JSON.parse(fs.readFileSync(defaultPresetPath, 'utf8'));
690
+ const preset = JSON.parse(fs.readFileSync(presetPath, 'utf8'));
524
691
  if (preset.lists && Array.isArray(preset.lists)) {
525
692
  scopeDirs = preset.lists.filter((l: Record<string, unknown>) => l.hasDirectory).map((l: Record<string, unknown>) => l.id as string);
526
693
  }
527
694
  } catch {
528
- console.warn(' Warning: could not load default preset, creating scopes/icebox/ only');
695
+ warn(' Warning: could not load preset, creating scopes/icebox/ only');
529
696
  }
530
697
  for (const dirId of scopeDirs) {
531
698
  const scopeDir = path.join(projectRoot, 'scopes', dirId);
532
699
  const wasCreated = ensureDir(scopeDir);
533
- console.log(` ${wasCreated ? 'Created' : 'Exists '} scopes/${dirId}/`);
700
+ log(` ${wasCreated ? 'Created' : 'Exists '} scopes/${dirId}/`);
534
701
  }
535
702
 
536
703
  // 1c. Copy scope template
@@ -539,9 +706,9 @@ export function runInit(projectRoot: string, options: InitOptions = {}): void {
539
706
  if (fs.existsSync(scopeTemplateSrc)) {
540
707
  if (force || !fs.existsSync(scopeTemplateDest)) {
541
708
  fs.copyFileSync(scopeTemplateSrc, scopeTemplateDest);
542
- console.log(` ${force ? 'Reset ' : 'Created'} scopes/_template.md`);
709
+ log(` ${force ? 'Reset ' : 'Created'} scopes/_template.md`);
543
710
  } else {
544
- console.log(` Exists scopes/_template.md`);
711
+ log(` Exists scopes/_template.md`);
545
712
  }
546
713
  }
547
714
 
@@ -552,75 +719,97 @@ export function runInit(projectRoot: string, options: InitOptions = {}): void {
552
719
  if (configIsNew) {
553
720
  if (fs.existsSync(configSrc)) {
554
721
  fs.copyFileSync(configSrc, configDest);
555
- console.log(` Created .claude/orbital.config.json`);
722
+ // Apply wizard-collected or auto-detected values
723
+ try {
724
+ const config = JSON.parse(fs.readFileSync(configDest, 'utf8'));
725
+ config.projectName = options.projectName || path.basename(projectRoot)
726
+ .replace(/[-_]+/g, ' ')
727
+ .replace(/\b\w/g, c => c.toUpperCase());
728
+ if (options.serverPort) config.serverPort = options.serverPort;
729
+ if (options.clientPort) config.clientPort = options.clientPort;
730
+ fs.writeFileSync(configDest, JSON.stringify(config, null, 2) + '\n', 'utf8');
731
+ } catch { /* leave template default */ }
732
+ log(` Created .claude/orbital.config.json`);
556
733
  } else {
557
734
  const defaultConfig = {
558
- serverPort: 4444,
559
- clientPort: 4445,
560
- projectName: path.basename(projectRoot),
735
+ serverPort: options.serverPort || 4444,
736
+ clientPort: options.clientPort || 4445,
737
+ projectName: options.projectName || path.basename(projectRoot),
561
738
  };
562
739
  fs.writeFileSync(configDest, JSON.stringify(defaultConfig, null, 2) + '\n', 'utf8');
563
- console.log(` Created .claude/orbital.config.json (default)`);
740
+ log(` Created .claude/orbital.config.json (default)`);
564
741
  }
565
742
 
566
- // Auto-detect project commands from package.json
567
- const pkgJsonPath = path.join(projectRoot, 'package.json');
568
- if (fs.existsSync(pkgJsonPath)) {
743
+ // Apply wizard-provided commands or auto-detect from package.json
744
+ if (options.commands) {
569
745
  try {
570
- const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
571
- const scripts = pkg.scripts || {};
572
746
  const config = JSON.parse(fs.readFileSync(configDest, 'utf8'));
573
747
  if (!config.commands) config.commands = {};
574
- let detected = 0;
575
-
576
- if (scripts.typecheck || scripts['type-check']) {
577
- config.commands.typeCheck = `npm run ${scripts.typecheck ? 'typecheck' : 'type-check'}`;
578
- detected++;
579
- }
580
- if (scripts.lint) { config.commands.lint = 'npm run lint'; detected++; }
581
- if (scripts.build) { config.commands.build = 'npm run build'; detected++; }
582
- if (scripts.test) { config.commands.test = 'npm run test'; detected++; }
583
-
584
- if (detected > 0) {
585
- fs.writeFileSync(configDest, JSON.stringify(config, null, 2) + '\n', 'utf8');
586
- console.log(` Detected ${detected} project command(s) from package.json`);
587
- }
748
+ Object.assign(config.commands, options.commands);
749
+ const commandCount = Object.values(options.commands).filter(v => v !== null).length;
750
+ fs.writeFileSync(configDest, JSON.stringify(config, null, 2) + '\n', 'utf8');
751
+ if (commandCount > 0) log(` Applied ${commandCount} project command(s)`);
588
752
  } catch { /* leave defaults */ }
753
+ } else {
754
+ // Auto-detect project commands from package.json
755
+ const pkgJsonPath = path.join(projectRoot, 'package.json');
756
+ if (fs.existsSync(pkgJsonPath)) {
757
+ try {
758
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
759
+ const scripts = pkg.scripts || {};
760
+ const config = JSON.parse(fs.readFileSync(configDest, 'utf8'));
761
+ if (!config.commands) config.commands = {};
762
+ let detected = 0;
763
+
764
+ if (scripts.typecheck || scripts['type-check']) {
765
+ config.commands.typeCheck = `npm run ${scripts.typecheck ? 'typecheck' : 'type-check'}`;
766
+ detected++;
767
+ }
768
+ if (scripts.lint) { config.commands.lint = 'npm run lint'; detected++; }
769
+ if (scripts.build) { config.commands.build = 'npm run build'; detected++; }
770
+ if (scripts.test) { config.commands.test = 'npm run test'; detected++; }
771
+
772
+ if (detected > 0) {
773
+ fs.writeFileSync(configDest, JSON.stringify(config, null, 2) + '\n', 'utf8');
774
+ log(` Detected ${detected} project command(s) from package.json`);
775
+ }
776
+ } catch { /* leave defaults */ }
777
+ }
589
778
  }
590
779
  } else {
591
- console.log(` Exists .claude/orbital.config.json`);
780
+ log(` Exists .claude/orbital.config.json`);
592
781
  }
593
782
 
594
783
  // 3. Copy hooks
595
- console.log('');
784
+ log('');
596
785
  const hooksSrc = path.join(TEMPLATES_DIR, 'hooks');
597
786
  const hooksDest = path.join(claudeDir, 'hooks');
598
787
  if (force) {
599
788
  const pruned = pruneStaleEntries(hooksSrc, hooksDest);
600
- if (pruned > 0) console.log(` Pruned ${pruned} stale hook entries`);
789
+ if (pruned > 0) log(` Pruned ${pruned} stale hook entries`);
601
790
  }
602
791
  const hooksResult = copyDirSync(hooksSrc, hooksDest, { overwrite: force });
603
- console.log(` Hooks ${hooksResult.created.length} copied, ${hooksResult.skipped.length} skipped`);
792
+ log(` Hooks ${hooksResult.created.length} copied, ${hooksResult.skipped.length} skipped`);
604
793
 
605
794
  // 4. Copy skills
606
795
  const skillsSrc = path.join(TEMPLATES_DIR, 'skills');
607
796
  const skillsDest = path.join(claudeDir, 'skills');
608
797
  if (force) {
609
798
  const pruned = pruneStaleEntries(skillsSrc, skillsDest);
610
- if (pruned > 0) console.log(` Pruned ${pruned} stale skill entries`);
799
+ if (pruned > 0) log(` Pruned ${pruned} stale skill entries`);
611
800
  }
612
801
  const skillsResult = copyDirSync(skillsSrc, skillsDest, { overwrite: force });
613
- console.log(` Skills ${skillsResult.created.length} copied, ${skillsResult.skipped.length} skipped`);
802
+ log(` Skills ${skillsResult.created.length} copied, ${skillsResult.skipped.length} skipped`);
614
803
 
615
804
  // 5. Copy agents
616
805
  const agentsSrc = path.join(TEMPLATES_DIR, 'agents');
617
806
  const agentsDest = path.join(claudeDir, 'agents');
618
807
  if (force) {
619
808
  const pruned = pruneStaleEntries(agentsSrc, agentsDest);
620
- if (pruned > 0) console.log(` Pruned ${pruned} stale agent entries`);
809
+ if (pruned > 0) log(` Pruned ${pruned} stale agent entries`);
621
810
  }
622
811
  const agentsResult = copyDirSync(agentsSrc, agentsDest, { overwrite: force });
623
- console.log(` Agents ${agentsResult.created.length} copied, ${agentsResult.skipped.length} skipped`);
812
+ log(` Agents ${agentsResult.created.length} copied, ${agentsResult.skipped.length} skipped`);
624
813
 
625
814
  // 6. Copy workflow presets
626
815
  const presetsSrc = path.join(TEMPLATES_DIR, 'presets');
@@ -628,22 +817,22 @@ export function runInit(projectRoot: string, options: InitOptions = {}): void {
628
817
  if (fs.existsSync(presetsSrc) && fs.readdirSync(presetsSrc).length > 0) {
629
818
  if (force) {
630
819
  const pruned = pruneStaleEntries(presetsSrc, presetsDest);
631
- if (pruned > 0) console.log(` Pruned ${pruned} stale preset entries`);
820
+ if (pruned > 0) log(` Pruned ${pruned} stale preset entries`);
632
821
  }
633
822
  const presetsResult = copyDirSync(presetsSrc, presetsDest, { overwrite: force });
634
- console.log(` Presets ${presetsResult.created.length} copied, ${presetsResult.skipped.length} skipped`);
823
+ log(` Presets ${presetsResult.created.length} copied, ${presetsResult.skipped.length} skipped`);
635
824
  }
636
825
 
637
826
  // 6b. Reset active workflow config when --force, or create if missing
638
827
  const activeWorkflowDest = path.join(claudeDir, 'config', 'workflow.json');
639
828
  if (force) {
640
- fs.copyFileSync(defaultPresetPath, activeWorkflowDest);
641
- console.log(` Reset .claude/config/workflow.json (default workflow)`);
829
+ fs.copyFileSync(presetPath, activeWorkflowDest);
830
+ log(` Reset .claude/config/workflow.json (${selectedPreset} workflow)`);
642
831
  } else if (!fs.existsSync(activeWorkflowDest)) {
643
- fs.copyFileSync(defaultPresetPath, activeWorkflowDest);
644
- console.log(` Created .claude/config/workflow.json`);
832
+ fs.copyFileSync(presetPath, activeWorkflowDest);
833
+ log(` Created .claude/config/workflow.json (${selectedPreset})`);
645
834
  } else {
646
- console.log(` Exists .claude/config/workflow.json`);
835
+ log(` Exists .claude/config/workflow.json`);
647
836
  }
648
837
 
649
838
  // 7. Copy agent-triggers.json
@@ -652,9 +841,9 @@ export function runInit(projectRoot: string, options: InitOptions = {}): void {
652
841
  if (fs.existsSync(triggersSrc)) {
653
842
  if (force || !fs.existsSync(triggersDest)) {
654
843
  fs.copyFileSync(triggersSrc, triggersDest);
655
- console.log(` Created .claude/config/agent-triggers.json`);
844
+ log(` Created .claude/config/agent-triggers.json`);
656
845
  } else {
657
- console.log(` Exists .claude/config/agent-triggers.json`);
846
+ log(` Exists .claude/config/agent-triggers.json`);
658
847
  }
659
848
  }
660
849
 
@@ -663,7 +852,7 @@ export function runInit(projectRoot: string, options: InitOptions = {}): void {
663
852
  const quickDest = path.join(claudeDir, 'quick');
664
853
  if (fs.existsSync(quickSrc)) {
665
854
  const quickResult = copyDirSync(quickSrc, quickDest, { overwrite: force });
666
- console.log(` Quick ${quickResult.created.length} copied, ${quickResult.skipped.length} skipped`);
855
+ log(` Quick ${quickResult.created.length} copied, ${quickResult.skipped.length} skipped`);
667
856
  }
668
857
 
669
858
  // 7c. Copy anti-patterns/ templates
@@ -671,7 +860,7 @@ export function runInit(projectRoot: string, options: InitOptions = {}): void {
671
860
  const antiDest = path.join(claudeDir, 'anti-patterns');
672
861
  if (fs.existsSync(antiSrc)) {
673
862
  const antiResult = copyDirSync(antiSrc, antiDest, { overwrite: force });
674
- console.log(` Anti-pat ${antiResult.created.length} copied, ${antiResult.skipped.length} skipped`);
863
+ log(` Anti-pat ${antiResult.created.length} copied, ${antiResult.skipped.length} skipped`);
675
864
  }
676
865
 
677
866
  // 7d. Copy lessons-learned.md
@@ -680,212 +869,55 @@ export function runInit(projectRoot: string, options: InitOptions = {}): void {
680
869
  if (fs.existsSync(lessonsSrc)) {
681
870
  if (force || !fs.existsSync(lessonsDest)) {
682
871
  fs.copyFileSync(lessonsSrc, lessonsDest);
683
- console.log(` Created .claude/lessons-learned.md`);
872
+ log(` Created .claude/lessons-learned.md`);
684
873
  } else {
685
- console.log(` Exists .claude/lessons-learned.md`);
874
+ log(` Exists .claude/lessons-learned.md`);
686
875
  }
687
876
  }
688
877
 
689
878
  // 7e. Generate workflow manifest
690
879
  const manifestOk = writeManifest(claudeDir);
691
- console.log(` ${manifestOk ? 'Created' : 'Skipped'} .claude/config/workflow-manifest.sh`);
880
+ log(` ${manifestOk ? 'Created' : 'Skipped'} .claude/config/workflow-manifest.sh`);
692
881
 
693
882
  // 7f. Generate INDEX.md
694
883
  const indexDest = path.join(claudeDir, 'INDEX.md');
695
884
  if (force || !fs.existsSync(indexDest)) {
696
885
  const indexContent = generateIndexMd(projectRoot, claudeDir);
697
886
  fs.writeFileSync(indexDest, indexContent, 'utf8');
698
- console.log(` ${force ? 'Reset ' : 'Created'} .claude/INDEX.md`);
887
+ log(` ${force ? 'Reset ' : 'Created'} .claude/INDEX.md`);
699
888
  } else {
700
- console.log(` Exists .claude/INDEX.md`);
889
+ log(` Exists .claude/INDEX.md`);
701
890
  }
702
891
 
703
892
  // 8. Merge hook registrations into settings.local.json
704
- console.log('');
893
+ log('');
705
894
  const settingsTarget = path.join(claudeDir, 'settings.local.json');
706
895
  const settingsSrc = path.join(TEMPLATES_DIR, 'settings-hooks.json');
707
896
  mergeSettingsHooks(settingsTarget, settingsSrc);
708
- console.log(` Merged hook registrations into .claude/settings.local.json`);
897
+ log(` Merged hook registrations into .claude/settings.local.json`);
709
898
 
710
899
  // 9. Update .gitignore
711
900
  const gitignoreUpdated = updateGitignore(projectRoot);
712
- console.log(` ${gitignoreUpdated ? 'Updated' : 'Exists '} .gitignore (Orbital patterns)`);
901
+ log(` ${gitignoreUpdated ? 'Updated' : 'Exists '} .gitignore (Orbital patterns)`);
713
902
 
714
903
  // 10. Make hook scripts executable
715
904
  chmodScripts(hooksDest);
716
- console.log(` chmod hook scripts set to executable`);
905
+ log(` chmod hook scripts set to executable`);
906
+
907
+ // 11. Seed global primitives from package templates
908
+ seedGlobalPrimitives();
909
+ log(` Seeded global primitives (~/.orbital/primitives/)`);
910
+
911
+ // 12. Build and save manifest
912
+ const manifest = buildInitManifest(projectRoot, claudeDir, selectedPreset);
913
+ saveManifest(projectRoot, manifest);
914
+ log(` Created .claude/orbital-manifest.json (${Object.keys(manifest.files).length} files tracked)`);
717
915
 
718
916
  // Summary
719
917
  const totalCreated = hooksResult.created.length + skillsResult.created.length + agentsResult.created.length;
720
918
  const totalSkipped = hooksResult.skipped.length + skillsResult.skipped.length + agentsResult.skipped.length;
721
- console.log(`\nDone. ${totalCreated} files installed, ${totalSkipped} skipped (use --force to overwrite).`);
722
- }
723
-
724
- export function runUpdate(projectRoot: string): void {
725
- const claudeDir = path.join(projectRoot, '.claude');
726
-
727
- console.log(`\nOrbital Command — update`);
728
- console.log(`Project root: ${projectRoot}\n`);
729
-
730
- // 1. Copy hooks (overwrite) — prune stale entries first
731
- const hooksSrc = path.join(TEMPLATES_DIR, 'hooks');
732
- const hooksDest = path.join(claudeDir, 'hooks');
733
- const hooksPruned = pruneStaleEntries(hooksSrc, hooksDest);
734
- if (hooksPruned > 0) console.log(` Pruned ${hooksPruned} stale hook entries`);
735
- const hooksResult = copyDirSync(hooksSrc, hooksDest, { overwrite: true });
736
- console.log(` Hooks ${hooksResult.created.length} updated`);
737
-
738
- // 2. Copy skills (overwrite) — prune stale entries first
739
- const skillsSrc = path.join(TEMPLATES_DIR, 'skills');
740
- const skillsDest = path.join(claudeDir, 'skills');
741
- const skillsPruned = pruneStaleEntries(skillsSrc, skillsDest);
742
- if (skillsPruned > 0) console.log(` Pruned ${skillsPruned} stale skill entries`);
743
- const skillsResult = copyDirSync(skillsSrc, skillsDest, { overwrite: true });
744
- console.log(` Skills ${skillsResult.created.length} updated`);
745
-
746
- // 3. Copy agents (overwrite) — prune stale entries first
747
- const agentsSrc = path.join(TEMPLATES_DIR, 'agents');
748
- const agentsDest = path.join(claudeDir, 'agents');
749
- const agentsPruned = pruneStaleEntries(agentsSrc, agentsDest);
750
- if (agentsPruned > 0) console.log(` Pruned ${agentsPruned} stale agent entries`);
751
- const agentsResult = copyDirSync(agentsSrc, agentsDest, { overwrite: true });
752
- console.log(` Agents ${agentsResult.created.length} updated`);
753
-
754
- // 4. Update workflow presets — prune stale entries first
755
- const presetsSrc = path.join(TEMPLATES_DIR, 'presets');
756
- const presetsDest = path.join(claudeDir, 'config', 'workflows');
757
- if (fs.existsSync(presetsSrc) && fs.readdirSync(presetsSrc).length > 0) {
758
- const presetsPruned = pruneStaleEntries(presetsSrc, presetsDest);
759
- if (presetsPruned > 0) console.log(` Pruned ${presetsPruned} stale preset entries`);
760
- const presetsResult = copyDirSync(presetsSrc, presetsDest, { overwrite: true });
761
- console.log(` Presets ${presetsResult.created.length} updated`);
762
- }
763
-
764
- // 5. Update quick/, anti-patterns/, lessons-learned, scope template
765
- const quickSrc = path.join(TEMPLATES_DIR, 'quick');
766
- const quickDest = path.join(claudeDir, 'quick');
767
- if (fs.existsSync(quickSrc)) {
768
- const quickResult = copyDirSync(quickSrc, quickDest, { overwrite: true });
769
- console.log(` Quick ${quickResult.created.length} updated`);
770
- }
771
-
772
- const antiSrc = path.join(TEMPLATES_DIR, 'anti-patterns');
773
- const antiDest = path.join(claudeDir, 'anti-patterns');
774
- if (fs.existsSync(antiSrc)) {
775
- const antiResult = copyDirSync(antiSrc, antiDest, { overwrite: true });
776
- console.log(` Anti-pat ${antiResult.created.length} updated`);
777
- }
778
-
779
- const lessonsSrc = path.join(TEMPLATES_DIR, 'lessons-learned.md');
780
- const lessonsDest = path.join(claudeDir, 'lessons-learned.md');
781
- if (fs.existsSync(lessonsSrc) && !fs.existsSync(lessonsDest)) {
782
- fs.copyFileSync(lessonsSrc, lessonsDest);
783
- console.log(` Created .claude/lessons-learned.md`);
784
- }
785
-
786
- const scopeTemplateSrc = path.join(TEMPLATES_DIR, 'scopes', '_template.md');
787
- const scopeTemplateDest = path.join(projectRoot, 'scopes', '_template.md');
788
- if (fs.existsSync(scopeTemplateSrc)) {
789
- ensureDir(path.join(projectRoot, 'scopes'));
790
- fs.copyFileSync(scopeTemplateSrc, scopeTemplateDest);
791
- console.log(` Updated scopes/_template.md`);
792
- }
793
-
794
- // 5b. Regenerate workflow manifest
795
- const manifestOk = writeManifest(claudeDir);
796
- console.log(` ${manifestOk ? 'Updated' : 'Skipped'} .claude/config/workflow-manifest.sh`);
797
-
798
- // 6. Re-merge settings hooks
799
- const settingsTarget = path.join(claudeDir, 'settings.local.json');
800
- const settingsSrc = path.join(TEMPLATES_DIR, 'settings-hooks.json');
801
- mergeSettingsHooks(settingsTarget, settingsSrc);
802
- console.log(` Merged hook registrations into .claude/settings.local.json`);
803
-
804
- // 7. Make hook scripts executable
805
- chmodScripts(hooksDest);
806
- console.log(` chmod hook scripts set to executable`);
807
-
808
- console.log(`\nUpdate complete.\n`);
919
+ log(`\nDone. ${totalCreated} files installed, ${totalSkipped} skipped (use --force to overwrite).`);
809
920
  }
810
921
 
811
- export function runUninstall(projectRoot: string): void {
812
- const claudeDir = path.join(projectRoot, '.claude');
813
-
814
- console.log(`\nOrbital Command — uninstall`);
815
- console.log(`Project root: ${projectRoot}\n`);
816
-
817
- let removedCount = 0;
818
-
819
- // 1. Remove orbital hooks from settings.local.json
820
- const settingsPath = path.join(claudeDir, 'settings.local.json');
821
- if (fs.existsSync(settingsPath)) {
822
- try {
823
- const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
824
- if (settings.hooks) {
825
- for (const [event] of Object.entries(settings.hooks)) {
826
- for (const group of settings.hooks[event]) {
827
- if (group.hooks) {
828
- const before = group.hooks.length;
829
- group.hooks = group.hooks.filter((h: HookEntry) => !h._orbital);
830
- removedCount += before - group.hooks.length;
831
- }
832
- }
833
- settings.hooks[event] = settings.hooks[event].filter(
834
- (g: HookGroup) => g.hooks && g.hooks.length > 0
835
- );
836
- if (settings.hooks[event].length === 0) {
837
- delete settings.hooks[event];
838
- }
839
- }
840
- if (Object.keys(settings.hooks).length === 0) {
841
- delete settings.hooks;
842
- }
843
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
844
- console.log(` Removed ${removedCount} orbital hook registrations from settings.local.json`);
845
- }
846
- } catch {
847
- console.warn(' Warning: could not parse settings.local.json');
848
- }
849
- }
850
-
851
- // 2. Delete hooks that came from templates
852
- const hookFiles = listTemplateFiles(path.join(TEMPLATES_DIR, 'hooks'), path.join(claudeDir, 'hooks'));
853
- let hooksRemoved = 0;
854
- for (const f of hookFiles) {
855
- if (fs.existsSync(f)) {
856
- fs.unlinkSync(f);
857
- hooksRemoved++;
858
- }
859
- }
860
- console.log(` Removed ${hooksRemoved} hook scripts`);
861
-
862
- // 3. Delete skills that came from templates
863
- const skillFiles = listTemplateFiles(path.join(TEMPLATES_DIR, 'skills'), path.join(claudeDir, 'skills'));
864
- let skillsRemoved = 0;
865
- for (const f of skillFiles) {
866
- if (fs.existsSync(f)) {
867
- fs.unlinkSync(f);
868
- skillsRemoved++;
869
- }
870
- }
871
- const skillsDest = path.join(claudeDir, 'skills');
872
- if (fs.existsSync(skillsDest)) cleanEmptyDirs(skillsDest);
873
- console.log(` Removed ${skillsRemoved} skill files`);
874
-
875
- // 4. Delete agents that came from templates
876
- const agentFiles = listTemplateFiles(path.join(TEMPLATES_DIR, 'agents'), path.join(claudeDir, 'agents'));
877
- let agentsRemoved = 0;
878
- for (const f of agentFiles) {
879
- if (fs.existsSync(f)) {
880
- fs.unlinkSync(f);
881
- agentsRemoved++;
882
- }
883
- }
884
- const agentsDest = path.join(claudeDir, 'agents');
885
- if (fs.existsSync(agentsDest)) cleanEmptyDirs(agentsDest);
886
- console.log(` Removed ${agentsRemoved} agent files`);
887
-
888
- const total = removedCount + hooksRemoved + skillsRemoved + agentsRemoved;
889
- console.log(`\nUninstall complete. ${total} items removed.`);
890
- console.log(`Note: scopes/ and .claude/orbital-events/ were preserved.\n`);
891
- }
922
+ // runUpdate and runUninstall have been extracted to update.ts and uninstall.ts
923
+ // and are re-exported above for backward compatibility.