orbital-command 0.2.0 → 1.0.0

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