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/README.md CHANGED
@@ -24,52 +24,32 @@ Think of it as the control tower that turns a collection of AI-assisted coding s
24
24
 
25
25
  - **Node.js >= 18**
26
26
  - **Claude Code** installed and available as `claude` on your PATH
27
+ - **iTerm2** (macOS, recommended) — sprint dispatch and batch orchestration use iTerm2 tabs to run parallel Claude Code sessions. Without it, sessions fall back to basic subprocess mode. The setup wizard will prompt you to install it.
27
28
  - **C++ compiler** for the `better-sqlite3` native module:
28
29
  - macOS: Xcode Command Line Tools (`xcode-select --install`)
29
30
  - Linux: `build-essential` (`apt install build-essential`)
30
31
 
31
- ## Installation
32
-
33
- **Global install (recommended for regular use):**
34
-
35
- ```bash
36
- npm install -g github:SakaraLabs/orbital-command
37
- ```
38
-
39
- This registers the `orbital` command globally. Then in any project:
40
-
41
- ```bash
42
- orbital init
43
- orbital dev
44
- ```
45
-
46
- **Without global install:**
47
-
48
- ```bash
49
- npx github:SakaraLabs/orbital-command init
50
- npx github:SakaraLabs/orbital-command dev
51
- ```
52
-
53
32
  ## Quick Start
54
33
 
55
34
  ```bash
56
- # 1. Navigate to your project
35
+ npm install orbital-command
57
36
  cd my-project
37
+ orbital
38
+ ```
58
39
 
59
- # 2. Scaffold Orbital Command (hooks, skills, agents, config)
60
- orbital init
40
+ That's it. The `orbital` command detects your context and guides you through everything:
61
41
 
62
- # 3. Launch the dashboard
63
- orbital dev
64
- ```
42
+ 1. **First run** — setup wizard configures Orbital globally
43
+ 2. **New project** — project setup wizard scaffolds hooks, skills, agents, and workflow config
44
+ 3. **Existing project** — hub menu lets you launch the dashboard, edit config, run diagnostics, or update templates
65
45
 
66
- Open [http://localhost:4445](http://localhost:4445) in your browser. The API server runs on port 4444.
46
+ On macOS, the wizard will recommend installing [iTerm2](https://iterm2.com) for the full dispatch experience it polls for the install automatically so you can continue once it's ready.
67
47
 
68
- The `init` command is non-destructive — it skips files that already exist. Pass `--force` to overwrite everything with the latest templates.
48
+ Open [http://localhost:4444](http://localhost:4444) after launching.
69
49
 
70
50
  ## What Gets Installed
71
51
 
72
- After `orbital init`, your project receives:
52
+ After setup, your project receives:
73
53
 
74
54
  ```
75
55
  .claude/
@@ -111,15 +91,26 @@ scopes/
111
91
 
112
92
  ## CLI Reference
113
93
 
94
+ The bare `orbital` command is the primary entry point — it detects context and shows the right options. All subcommands below are also available directly for scripting or when you know what you want.
95
+
114
96
  | Command | Description |
115
97
  |---------|-------------|
116
- | `orbital init` | Scaffold hooks, skills, agents, and config into the current project |
117
- | `orbital init --force` | Re-scaffold, overwriting all existing files with latest templates |
118
- | `orbital dev` | Start the API server and Vite dev server concurrently |
119
- | `orbital build` | Production build of the dashboard frontend |
98
+ | `orbital` | Context-aware hub menu (setup, init, launch, config, etc.) |
99
+ | `orbital` | Context-aware hub menu (setup, launch, config, doctor, etc.) |
100
+ | `orbital config` | Modify project settings interactively |
101
+ | `orbital doctor` | Health check and version diagnostics |
102
+ | `orbital update` | Sync templates and apply migrations |
103
+ | `orbital status` | Show template sync status |
120
104
  | `orbital emit <TYPE> [JSON]` | Emit an event to the file-based event bus |
121
- | `orbital update` | Re-copy hooks, skills, agents, and presets (overwrites). Pass `--include-examples` to include domain-specific example agents |
122
- | `orbital uninstall` | Remove all Orbital artifacts from the project. Preserves `scopes/` and event history |
105
+ | `orbital validate` | Check cross-references and consistency |
106
+ | `orbital register [path]` | Register a project with the dashboard |
107
+ | `orbital unregister <id>` | Remove a project from the dashboard |
108
+ | `orbital projects` | List all registered projects |
109
+ | `orbital pin <path>` | Lock a file from template updates |
110
+ | `orbital unpin <path>` | Unlock a pinned file |
111
+ | `orbital diff <path>` | Show diff between template and local file |
112
+ | `orbital reset <path>` | Restore a file from the current template |
113
+ | `orbital uninstall` | Remove all Orbital artifacts from the project |
123
114
 
124
115
  ## Workflow Presets
125
116
 
@@ -351,7 +342,7 @@ When you dispatch a scope from the dashboard, Orbital:
351
342
  No. Orbital Command is purpose-built for Claude Code. The hooks, skills, agents, and session tracking all depend on Claude Code's lifecycle events and CLI.
352
343
 
353
344
  ### Do I need to keep the dashboard running?
354
- No. The file-based event bus means hooks write events as JSON files regardless of whether the server is running. Events queue up and get ingested when you next run `orbital dev`.
345
+ No. The file-based event bus means hooks write events as JSON files regardless of whether the server is running. Events queue up and get ingested when you next launch the dashboard.
355
346
 
356
347
  ### How do I customize the workflow columns?
357
348
  Open the Workflow Visualizer (`/workflow` in the dashboard). You can add/remove columns, create transitions, attach hooks, and set confirmation levels. Or edit `.claude/config/workflow.json` directly. Changes take effect immediately.
@@ -370,7 +361,7 @@ Sprints group multiple scopes for batch execution. The orchestrator resolves dep
370
361
  ### How do I reset everything?
371
362
  ```bash
372
363
  orbital uninstall # Remove all Orbital artifacts
373
- orbital init --force # Re-scaffold from scratch
364
+ # Then run `orbital` and select "Reset to defaults"
374
365
  ```
375
366
 
376
367
  This preserves your `scopes/` directory and event history.
@@ -382,14 +373,48 @@ Yes. Set `terminal.adapter` in your config:
382
373
  - `"subprocess"` — Generic subprocess spawning (works everywhere)
383
374
  - `"none"` — Disable terminal dispatch
384
375
 
376
+ ## Development
377
+
378
+ ```bash
379
+ # Install dependencies (includes all build/frontend packages as devDependencies)
380
+ npm install
381
+
382
+ # Start dev server with hot-reload
383
+ npm run dev:local
384
+
385
+ # Run the full validation pipeline (typecheck → test → build → build:server)
386
+ npm run validate
387
+ ```
388
+
389
+ | Script | Purpose |
390
+ |--------|---------|
391
+ | `npm run dev:local` | Express API + Vite dev server with hot-reload |
392
+ | `npm run dev:server` | Express API only (tsx watch) |
393
+ | `npm run dev:client` | Vite dev server only |
394
+ | `npm run typecheck` | Type check client + server tsconfigs |
395
+ | `npm run test` | Run all tests |
396
+ | `npm run build` | Vite production build (frontend) |
397
+ | `npm run build:server` | TypeScript compile server to dist/server |
398
+ | `npm run validate` | Full pipeline: typecheck → test → build → build:server |
399
+
400
+ ### Releasing
401
+
402
+ ```bash
403
+ npm run release # patch bump (0.3.0 → 0.3.1)
404
+ npm run release -- minor # minor bump (0.3.0 → 0.4.0)
405
+ npm run release -- major # major bump (0.3.0 → 1.0.0)
406
+ ```
407
+
408
+ This validates the full pipeline, bumps the version, creates a git tag, and pushes. The tag push triggers the publish workflow which validates again and publishes to npm with provenance.
409
+
385
410
  ## Contributing
386
411
 
412
+ Open an issue first for large changes or new features.
413
+
387
414
  1. Fork the repository and clone locally
388
415
  2. Install dependencies: `npm install`
389
416
  3. Start development: `npm run dev:local`
390
- 4. Typecheck: `npm run typecheck`
391
-
392
- Open an issue first for large changes or new features.
417
+ 4. Validate before submitting: `npm run validate`
393
418
 
394
419
  ## License
395
420
 
@@ -0,0 +1,19 @@
1
+ import {
2
+ detectProjectRoot,
3
+ getPackageVersion,
4
+ loadWizardModule,
5
+ } from '../lib/helpers.js';
6
+
7
+ export async function cmdConfig(args) {
8
+ const { runConfigEditor } = await loadWizardModule();
9
+ const projectRoot = detectProjectRoot();
10
+ const version = getPackageVersion();
11
+ await runConfigEditor(projectRoot, version, args);
12
+ }
13
+
14
+ export async function cmdDoctor() {
15
+ const { runDoctor } = await loadWizardModule();
16
+ const projectRoot = detectProjectRoot();
17
+ const version = getPackageVersion();
18
+ await runDoctor(projectRoot, version);
19
+ }
@@ -0,0 +1,40 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import crypto from 'crypto';
4
+ import { detectProjectRoot } from '../lib/helpers.js';
5
+
6
+ export function cmdEmit(args) {
7
+ const type = args[0];
8
+ const jsonStr = args.slice(1).join(' ');
9
+
10
+ if (!type) {
11
+ console.error('Usage: orbital emit <TYPE> <JSON>');
12
+ process.exit(1);
13
+ }
14
+
15
+ const projectRoot = detectProjectRoot();
16
+ const eventsDir = path.join(projectRoot, '.claude', 'orbital-events');
17
+ if (!fs.existsSync(eventsDir)) fs.mkdirSync(eventsDir, { recursive: true });
18
+
19
+ let payload;
20
+ try {
21
+ payload = jsonStr ? JSON.parse(jsonStr) : {};
22
+ } catch (err) {
23
+ console.error(`Invalid JSON: ${err.message}`);
24
+ process.exit(1);
25
+ }
26
+
27
+ const eventId = crypto.randomUUID();
28
+ const event = {
29
+ ...payload,
30
+ id: eventId,
31
+ type,
32
+ timestamp: new Date().toISOString(),
33
+ };
34
+
35
+ const filePath = path.join(eventsDir, `${eventId}.json`);
36
+ fs.writeFileSync(filePath, JSON.stringify(event, null, 2) + '\n', 'utf8');
37
+
38
+ console.log(`Event emitted: ${type} (${eventId})`);
39
+ console.log(` File: ${path.relative(projectRoot, filePath)}`);
40
+ }
@@ -0,0 +1,126 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { spawn } from 'child_process';
4
+ import {
5
+ PACKAGE_ROOT,
6
+ resolveBin,
7
+ detectProjectRoot,
8
+ loadConfig,
9
+ openBrowser,
10
+ } from '../lib/helpers.js';
11
+
12
+ export function cmdLaunchOrDev(forceViteFlag) {
13
+ const shouldOpen = process.argv.includes('--open');
14
+ const forceVite = forceViteFlag || process.argv.includes('--vite');
15
+ const projectRoot = detectProjectRoot();
16
+ const config = loadConfig(projectRoot);
17
+ const serverPort = config.serverPort || 4444;
18
+ const clientPort = config.clientPort || 4445;
19
+
20
+ // Detect packaged mode: dist/index.html exists -> serve pre-built frontend
21
+ const hasPrebuiltFrontend = fs.existsSync(path.join(PACKAGE_ROOT, 'dist', 'index.html'));
22
+ const useVite = forceVite || !hasPrebuiltFrontend;
23
+
24
+ // Detect compiled server: dist/server/server/launch.js exists -> run with node
25
+ const compiledServer = path.join(PACKAGE_ROOT, 'dist', 'server', 'server', 'launch.js');
26
+ const hasCompiledServer = fs.existsSync(compiledServer);
27
+ const useCompiledServer = hasCompiledServer && !useVite;
28
+
29
+ console.log(`\nOrbital Command — ${useVite ? 'dev' : 'launch'}`);
30
+ console.log(`Project root: ${projectRoot}`);
31
+ if (useVite) {
32
+ console.log(`Server: http://localhost:${serverPort}`);
33
+ console.log(`Client: http://localhost:${clientPort} (Vite dev server)\n`);
34
+ } else {
35
+ console.log(`Dashboard: http://localhost:${serverPort}\n`);
36
+ }
37
+
38
+ const env = {
39
+ ...process.env,
40
+ ORBITAL_LAUNCH_MODE: 'central',
41
+ ORBITAL_AUTO_REGISTER: projectRoot,
42
+ ORBITAL_SERVER_PORT: String(serverPort),
43
+ };
44
+
45
+ let serverProcess;
46
+
47
+ if (useCompiledServer) {
48
+ serverProcess = spawn(process.execPath, [compiledServer],
49
+ { stdio: 'inherit', env, cwd: PACKAGE_ROOT });
50
+ } else {
51
+ const tsxBin = resolveBin('tsx');
52
+ const serverScript = path.join(PACKAGE_ROOT, 'server', 'launch.ts');
53
+ if (tsxBin) {
54
+ serverProcess = spawn(tsxBin, ['watch', serverScript],
55
+ { stdio: 'inherit', env, cwd: PACKAGE_ROOT });
56
+ } else {
57
+ console.error('Error: tsx not found. Install it with: npm install tsx');
58
+ process.exit(1);
59
+ }
60
+ }
61
+
62
+ let viteProcess = null;
63
+
64
+ if (useVite) {
65
+ const viteBin = resolveBin('vite');
66
+ if (!viteBin) {
67
+ console.error('Error: vite not found. Install it with: npm install vite');
68
+ process.exit(1);
69
+ }
70
+ viteProcess = spawn(viteBin, ['--config', path.join(PACKAGE_ROOT, 'vite.config.ts'), '--port', String(clientPort)],
71
+ { stdio: 'inherit', env, cwd: PACKAGE_ROOT });
72
+ }
73
+
74
+ const dashboardUrl = useVite
75
+ ? `http://localhost:${clientPort}`
76
+ : `http://localhost:${serverPort}`;
77
+
78
+ if (shouldOpen) {
79
+ setTimeout(() => openBrowser(dashboardUrl), 2000);
80
+ }
81
+
82
+ let exiting = false;
83
+
84
+ function cleanup() {
85
+ if (exiting) return;
86
+ exiting = true;
87
+ serverProcess.kill();
88
+ if (viteProcess) viteProcess.kill();
89
+ process.exit(0);
90
+ }
91
+ process.on('SIGINT', cleanup);
92
+ process.on('SIGTERM', cleanup);
93
+
94
+ serverProcess.on('exit', (code) => {
95
+ if (exiting) return;
96
+ exiting = true;
97
+ console.log(`Server exited with code ${code}`);
98
+ if (viteProcess) viteProcess.kill();
99
+ process.exit(code || 0);
100
+ });
101
+ if (viteProcess) {
102
+ viteProcess.on('exit', (code) => {
103
+ if (exiting) return;
104
+ exiting = true;
105
+ console.log(`Vite exited with code ${code}`);
106
+ serverProcess.kill();
107
+ process.exit(code || 0);
108
+ });
109
+ }
110
+ }
111
+
112
+ export function cmdBuild() {
113
+ console.log(`\nOrbital Command — build\n`);
114
+
115
+ const viteBin = resolveBin('vite');
116
+ if (!viteBin) {
117
+ console.error('Error: vite not found. Install it with: npm install vite');
118
+ process.exit(1);
119
+ }
120
+ const buildProcess = spawn(viteBin, ['build', '--config', path.join(PACKAGE_ROOT, 'vite.config.ts')],
121
+ { stdio: 'inherit', cwd: PACKAGE_ROOT });
122
+
123
+ buildProcess.on('exit', (code) => {
124
+ process.exit(code || 0);
125
+ });
126
+ }
@@ -0,0 +1,283 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { execFileSync } from 'child_process';
4
+ import {
5
+ PACKAGE_ROOT,
6
+ detectProjectRoot,
7
+ getPackageVersion,
8
+ loadSharedModule,
9
+ } from '../lib/helpers.js';
10
+
11
+ export async function cmdStatus() {
12
+ const projectRoot = detectProjectRoot();
13
+
14
+ const mod = await loadSharedModule();
15
+ const manifest = mod.loadManifest(projectRoot);
16
+
17
+ if (!manifest) {
18
+ console.log('\nNo manifest found. Run `orbital` to set up this project.\n');
19
+ return;
20
+ }
21
+
22
+ const claudeDir = path.join(projectRoot, '.claude');
23
+ mod.refreshFileStatuses(manifest, claudeDir);
24
+
25
+ const summary = mod.summarizeManifest(manifest);
26
+ const packageVersion = getPackageVersion();
27
+ const needsUpdate = manifest.packageVersion !== packageVersion;
28
+
29
+ console.log(`\nOrbital Command v${packageVersion}${needsUpdate ? ` (installed: ${manifest.packageVersion} → needs update)` : ''}\n`);
30
+
31
+ for (const [type, counts] of Object.entries(summary.byType)) {
32
+ const parts = [];
33
+ if (counts.synced) parts.push(`${counts.synced} synced`);
34
+ if (counts.outdated) parts.push(`${counts.outdated} outdated`);
35
+ if (counts.modified) parts.push(`${counts.modified} modified`);
36
+ if (counts.pinned) parts.push(`${counts.pinned} pinned`);
37
+ if (counts.userOwned) parts.push(`${counts.userOwned} user-owned`);
38
+ console.log(` ${type.padEnd(16)} ${parts.join(', ')}`);
39
+ }
40
+
41
+ const outdated = Object.entries(manifest.files)
42
+ .filter(([, r]) => r.status === 'outdated');
43
+ if (outdated.length > 0) {
44
+ console.log('\n Outdated files (safe to update):');
45
+ for (const [file] of outdated) {
46
+ console.log(` ${file}`);
47
+ }
48
+ }
49
+
50
+ const modified = Object.entries(manifest.files)
51
+ .filter(([, r]) => r.status === 'modified');
52
+ if (modified.length > 0) {
53
+ console.log('\n Modified files (user edited):');
54
+ for (const [file] of modified) {
55
+ console.log(` ${file} (run 'orbital diff ${file}')`);
56
+ }
57
+ }
58
+
59
+ const pinned = Object.entries(manifest.files)
60
+ .filter(([, r]) => r.status === 'pinned');
61
+ if (pinned.length > 0) {
62
+ console.log('\n Pinned files:');
63
+ for (const [file, record] of pinned) {
64
+ const reason = record.pinnedReason ? `"${record.pinnedReason}"` : '';
65
+ console.log(` ${file} ${reason}`);
66
+ }
67
+ }
68
+
69
+ console.log();
70
+ }
71
+
72
+ export async function cmdValidate() {
73
+ const projectRoot = detectProjectRoot();
74
+
75
+ const mod = await loadSharedModule();
76
+ const report = mod.validate(projectRoot, getPackageVersion());
77
+ console.log(mod.formatValidationReport(report));
78
+ process.exit(report.errors > 0 ? 1 : 0);
79
+ }
80
+
81
+ export async function cmdPin(args) {
82
+ const projectRoot = detectProjectRoot();
83
+ const filePath = args.find(a => !a.startsWith('--'));
84
+ const reasonIdx = args.indexOf('--reason');
85
+ const reason = reasonIdx !== -1 ? args[reasonIdx + 1] : undefined;
86
+
87
+ if (!filePath) {
88
+ console.error('Usage: orbital pin <relative-path> [--reason "..."]');
89
+ process.exit(1);
90
+ }
91
+
92
+ const mod = await loadSharedModule();
93
+ const manifest = mod.loadManifest(projectRoot);
94
+ if (!manifest) {
95
+ console.error('No manifest found. Run `orbital` first.');
96
+ process.exit(1);
97
+ }
98
+
99
+ const record = manifest.files[filePath];
100
+ if (!record) {
101
+ console.error(`File not tracked: ${filePath}`);
102
+ process.exit(1);
103
+ }
104
+ if (record.origin === 'user') {
105
+ console.error(`Cannot pin user-owned file: ${filePath}`);
106
+ process.exit(1);
107
+ }
108
+
109
+ record.status = 'pinned';
110
+ record.pinnedAt = new Date().toISOString();
111
+ if (reason) record.pinnedReason = reason;
112
+
113
+ mod.saveManifest(projectRoot, manifest);
114
+ console.log(`Pinned: ${filePath}${reason ? ` (${reason})` : ''}`);
115
+ }
116
+
117
+ export async function cmdUnpin(args) {
118
+ const projectRoot = detectProjectRoot();
119
+ const filePath = args[0];
120
+
121
+ if (!filePath) {
122
+ console.error('Usage: orbital unpin <relative-path>');
123
+ process.exit(1);
124
+ }
125
+
126
+ const mod = await loadSharedModule();
127
+ const manifest = mod.loadManifest(projectRoot);
128
+ if (!manifest) {
129
+ console.error('No manifest found. Run `orbital` first.');
130
+ process.exit(1);
131
+ }
132
+
133
+ const record = manifest.files[filePath];
134
+ if (!record || record.status !== 'pinned') {
135
+ console.error(`File is not pinned: ${filePath}`);
136
+ process.exit(1);
137
+ }
138
+
139
+ record.status = 'synced';
140
+ delete record.pinnedAt;
141
+ delete record.pinnedReason;
142
+
143
+ const absPath = path.join(projectRoot, '.claude', filePath);
144
+ if (fs.existsSync(absPath)) {
145
+ const currentHash = mod.hashFile(absPath);
146
+ record.status = mod.computeFileStatus(record, currentHash);
147
+ } else {
148
+ record.status = 'synced';
149
+ }
150
+
151
+ mod.saveManifest(projectRoot, manifest);
152
+ console.log(`Unpinned: ${filePath} (now ${record.status})`);
153
+ }
154
+
155
+ export async function cmdPins() {
156
+ const projectRoot = detectProjectRoot();
157
+
158
+ const mod = await loadSharedModule();
159
+ const manifest = mod.loadManifest(projectRoot);
160
+ if (!manifest) {
161
+ console.error('No manifest found. Run `orbital` first.');
162
+ process.exit(1);
163
+ }
164
+
165
+ const pinned = Object.entries(manifest.files)
166
+ .filter(([, r]) => r.status === 'pinned');
167
+
168
+ if (pinned.length === 0) {
169
+ console.log('No pinned files.');
170
+ return;
171
+ }
172
+
173
+ console.log(`\n Pinned files:\n`);
174
+ for (const [file, record] of pinned) {
175
+ const reason = record.pinnedReason || '(no reason)';
176
+ const date = record.pinnedAt ? new Date(record.pinnedAt).toLocaleDateString() : '';
177
+ console.log(` ${file}`);
178
+ console.log(` Reason: ${reason} Pinned: ${date}`);
179
+ if (record.templateHash !== record.installedHash) {
180
+ console.log(` Template has changed since pin — run 'orbital diff ${file}' to compare`);
181
+ }
182
+ }
183
+ console.log();
184
+ }
185
+
186
+ export async function cmdDiff(args) {
187
+ const projectRoot = detectProjectRoot();
188
+ const filePath = args[0];
189
+
190
+ if (!filePath) {
191
+ console.error('Usage: orbital diff <relative-path>');
192
+ process.exit(1);
193
+ }
194
+
195
+ const mod = await loadSharedModule();
196
+ const manifest = mod.loadManifest(projectRoot);
197
+ if (!manifest) {
198
+ console.error('No manifest found. Run `orbital` first.');
199
+ process.exit(1);
200
+ }
201
+
202
+ const record = manifest.files[filePath];
203
+ if (!record || record.origin !== 'template') {
204
+ console.error(`Not a template file: ${filePath}`);
205
+ process.exit(1);
206
+ }
207
+
208
+ let templateRelPath = filePath;
209
+ if (filePath.startsWith('config/workflows/')) {
210
+ templateRelPath = filePath.replace('config/workflows/', 'presets/');
211
+ }
212
+
213
+ const templatePath = path.join(PACKAGE_ROOT, 'templates', templateRelPath);
214
+ const localPath = path.join(projectRoot, '.claude', filePath);
215
+
216
+ if (!fs.existsSync(templatePath)) {
217
+ console.error(`Template file not found: ${templateRelPath}`);
218
+ process.exit(1);
219
+ }
220
+ if (!fs.existsSync(localPath)) {
221
+ console.log('Local file does not exist. Template content:');
222
+ console.log(fs.readFileSync(templatePath, 'utf-8'));
223
+ return;
224
+ }
225
+
226
+ try {
227
+ const output = execFileSync(
228
+ 'git', ['diff', '--no-index', '--color', '--', templatePath, localPath],
229
+ { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }
230
+ );
231
+ console.log(output);
232
+ } catch (e) {
233
+ if (e.stdout) console.log(e.stdout);
234
+ else console.log('Files differ but git diff is unavailable.');
235
+ }
236
+ }
237
+
238
+ export async function cmdReset(args) {
239
+ const projectRoot = detectProjectRoot();
240
+ const filePath = args[0];
241
+
242
+ if (!filePath) {
243
+ console.error('Usage: orbital reset <relative-path>');
244
+ process.exit(1);
245
+ }
246
+
247
+ const mod = await loadSharedModule();
248
+ const manifest = mod.loadManifest(projectRoot);
249
+ if (!manifest) {
250
+ console.error('No manifest found. Run `orbital` first.');
251
+ process.exit(1);
252
+ }
253
+
254
+ const record = manifest.files[filePath];
255
+ if (!record || record.origin !== 'template') {
256
+ console.error(`Not a template file: ${filePath}`);
257
+ process.exit(1);
258
+ }
259
+
260
+ let templateRelPath = filePath;
261
+ if (filePath.startsWith('config/workflows/')) {
262
+ templateRelPath = filePath.replace('config/workflows/', 'presets/');
263
+ }
264
+
265
+ const templatePath = path.join(PACKAGE_ROOT, 'templates', templateRelPath);
266
+ const localPath = path.join(projectRoot, '.claude', filePath);
267
+
268
+ if (!fs.existsSync(templatePath)) {
269
+ console.error(`Template file not found: ${templateRelPath}`);
270
+ process.exit(1);
271
+ }
272
+
273
+ fs.copyFileSync(templatePath, localPath);
274
+ const newHash = mod.hashFile(localPath);
275
+ record.status = 'synced';
276
+ record.templateHash = newHash;
277
+ record.installedHash = newHash;
278
+ delete record.pinnedAt;
279
+ delete record.pinnedReason;
280
+
281
+ mod.saveManifest(projectRoot, manifest);
282
+ console.log(`Reset: ${filePath} → synced with template`);
283
+ }