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.
- package/README.md +67 -42
- package/bin/commands/config.js +19 -0
- package/bin/commands/events.js +40 -0
- package/bin/commands/launch.js +126 -0
- package/bin/commands/manifest.js +283 -0
- package/bin/commands/registry.js +104 -0
- package/bin/commands/update.js +24 -0
- package/bin/lib/helpers.js +229 -0
- package/bin/orbital.js +147 -319
- package/dist/assets/Landing-CfQdHR0N.js +11 -0
- package/dist/assets/PrimitivesConfig-DThSipFy.js +32 -0
- package/dist/assets/QualityGates-B4kxM5UU.js +26 -0
- package/dist/assets/SessionTimeline-Bz1iZnmg.js +1 -0
- package/dist/assets/Settings-DLcZwbCT.js +12 -0
- package/dist/assets/SourceControl-BMNIz7Lt.js +36 -0
- package/dist/assets/WorkflowVisualizer-CxuSBOYu.js +69 -0
- package/dist/assets/arrow-down-DVPp6_qp.js +6 -0
- package/dist/assets/bot-NFaJBDn_.js +6 -0
- package/dist/assets/charts-LGLb8hyU.js +68 -0
- package/dist/assets/circle-x-IsFCkBZu.js +6 -0
- package/dist/assets/file-text-J1cebZXF.js +6 -0
- package/dist/assets/globe-WzeyHsUc.js +6 -0
- package/dist/assets/index-BdJ57EhC.css +1 -0
- package/dist/assets/index-o4ScMAuR.js +349 -0
- package/dist/assets/key-CKR8JJSj.js +6 -0
- package/dist/assets/minus-CHBsJyjp.js +6 -0
- package/dist/assets/radio-xqZaR-Uk.js +6 -0
- package/dist/assets/rocket-D_xvvNG6.js +6 -0
- package/dist/assets/shield-TdB1yv_a.js +6 -0
- package/dist/assets/ui-BmsSg9jU.js +53 -0
- package/dist/assets/useSocketListener-0L5yiN5i.js +1 -0
- package/dist/assets/useWorkflowEditor-CqeRWVQX.js +11 -0
- package/dist/assets/{vendor-Dzv9lrRc.js → vendor-Bqt8AJn2.js} +1 -1
- package/dist/assets/workflow-constants-Rw-GmgHZ.js +6 -0
- package/dist/assets/zap-C9wqYMpl.js +6 -0
- package/dist/favicon.svg +1 -0
- package/dist/index.html +6 -5
- package/dist/server/server/__tests__/data-routes.test.js +126 -0
- package/dist/server/server/__tests__/helpers/db.js +17 -0
- package/dist/server/server/__tests__/helpers/mock-emitter.js +8 -0
- package/dist/server/server/__tests__/scope-routes.test.js +138 -0
- package/dist/server/server/__tests__/sprint-routes.test.js +102 -0
- package/dist/server/server/__tests__/workflow-routes.test.js +107 -0
- package/dist/server/server/config-migrator.js +135 -0
- package/dist/server/server/config.js +51 -7
- package/dist/server/server/database.js +21 -28
- package/dist/server/server/global-config.js +143 -0
- package/dist/server/server/index.js +118 -276
- package/dist/server/server/init.js +243 -225
- package/dist/server/server/launch.js +29 -0
- package/dist/server/server/manifest-types.js +8 -0
- package/dist/server/server/manifest.js +454 -0
- package/dist/server/server/migrate-legacy.js +229 -0
- package/dist/server/server/parsers/event-parser.js +4 -1
- package/dist/server/server/parsers/event-parser.test.js +117 -0
- package/dist/server/server/parsers/scope-parser.js +74 -28
- package/dist/server/server/parsers/scope-parser.test.js +230 -0
- package/dist/server/server/project-context.js +265 -0
- package/dist/server/server/project-emitter.js +41 -0
- package/dist/server/server/project-manager.js +297 -0
- package/dist/server/server/routes/aggregate-routes.js +871 -0
- package/dist/server/server/routes/config-routes.js +41 -90
- package/dist/server/server/routes/data-routes.js +25 -123
- package/dist/server/server/routes/dispatch-routes.js +37 -15
- package/dist/server/server/routes/git-routes.js +74 -0
- package/dist/server/server/routes/manifest-routes.js +319 -0
- package/dist/server/server/routes/scope-routes.js +45 -28
- package/dist/server/server/routes/sync-routes.js +134 -0
- package/dist/server/server/routes/version-routes.js +1 -15
- package/dist/server/server/routes/workflow-routes.js +9 -3
- package/dist/server/server/schema.js +3 -0
- package/dist/server/server/services/batch-orchestrator.js +41 -17
- package/dist/server/server/services/claude-session-service.js +17 -14
- package/dist/server/server/services/config-service.js +10 -1
- package/dist/server/server/services/deploy-service.test.js +119 -0
- package/dist/server/server/services/event-service.js +64 -1
- package/dist/server/server/services/event-service.test.js +191 -0
- package/dist/server/server/services/gate-service.test.js +105 -0
- package/dist/server/server/services/git-service.js +108 -4
- package/dist/server/server/services/github-service.js +110 -2
- package/dist/server/server/services/readiness-service.test.js +190 -0
- package/dist/server/server/services/scope-cache.js +5 -1
- package/dist/server/server/services/scope-cache.test.js +142 -0
- package/dist/server/server/services/scope-service.js +222 -131
- package/dist/server/server/services/scope-service.test.js +137 -0
- package/dist/server/server/services/sprint-orchestrator.js +29 -15
- package/dist/server/server/services/sprint-service.js +23 -3
- package/dist/server/server/services/sprint-service.test.js +238 -0
- package/dist/server/server/services/sync-service.js +434 -0
- package/dist/server/server/services/sync-types.js +2 -0
- package/dist/server/server/services/workflow-service.js +26 -5
- package/dist/server/server/services/workflow-service.test.js +159 -0
- package/dist/server/server/settings-sync.js +284 -0
- package/dist/server/server/uninstall.js +195 -0
- package/dist/server/server/update-planner.js +279 -0
- package/dist/server/server/update.js +212 -0
- package/dist/server/server/utils/cc-hooks-parser.js +3 -0
- package/dist/server/server/utils/cc-hooks-parser.test.js +86 -0
- package/dist/server/server/utils/dispatch-utils.js +83 -24
- package/dist/server/server/utils/dispatch-utils.test.js +182 -0
- package/dist/server/server/utils/flag-builder.js +54 -0
- package/dist/server/server/utils/json-fields.js +14 -0
- package/dist/server/server/utils/json-fields.test.js +73 -0
- package/dist/server/server/utils/logger.js +37 -3
- package/dist/server/server/utils/package-info.js +30 -0
- package/dist/server/server/utils/route-helpers.js +47 -0
- package/dist/server/server/utils/route-helpers.test.js +115 -0
- package/dist/server/server/utils/terminal-launcher.js +79 -25
- package/dist/server/server/utils/worktree-manager.js +13 -4
- package/dist/server/server/validator.js +230 -0
- package/dist/server/server/watchers/event-watcher.js +28 -13
- package/dist/server/server/watchers/global-watcher.js +63 -0
- package/dist/server/server/watchers/scope-watcher.js +27 -12
- package/dist/server/server/wizard/config-editor.js +237 -0
- package/dist/server/server/wizard/detect.js +96 -0
- package/dist/server/server/wizard/doctor.js +115 -0
- package/dist/server/server/wizard/index.js +340 -0
- package/dist/server/server/wizard/phases/confirm.js +39 -0
- package/dist/server/server/wizard/phases/project-setup.js +90 -0
- package/dist/server/server/wizard/phases/setup-wizard.js +66 -0
- package/dist/server/server/wizard/phases/welcome.js +32 -0
- package/dist/server/server/wizard/phases/workflow-setup.js +22 -0
- package/dist/server/server/wizard/types.js +29 -0
- package/dist/server/server/wizard/ui.js +73 -0
- package/dist/server/shared/__fixtures__/workflow-configs.js +75 -0
- package/dist/server/shared/api-types.js +80 -1
- package/dist/server/shared/default-workflow.json +65 -0
- package/dist/server/shared/onboarding-tour.test.js +81 -0
- package/dist/server/shared/project-colors.js +24 -0
- package/dist/server/shared/workflow-config.test.js +84 -0
- package/dist/server/shared/workflow-engine.js +1 -1
- package/dist/server/shared/workflow-engine.test.js +302 -0
- package/dist/server/shared/workflow-normalizer.js +101 -0
- package/dist/server/shared/workflow-normalizer.test.js +100 -0
- package/dist/server/src/components/onboarding/tour-steps.js +84 -0
- package/package.json +34 -29
- package/schemas/orbital.config.schema.json +2 -5
- package/scripts/postinstall.js +18 -6
- package/scripts/release.sh +53 -0
- package/server/__tests__/data-routes.test.ts +151 -0
- package/server/__tests__/helpers/db.ts +19 -0
- package/server/__tests__/helpers/mock-emitter.ts +10 -0
- package/server/__tests__/scope-routes.test.ts +158 -0
- package/server/__tests__/sprint-routes.test.ts +118 -0
- package/server/__tests__/workflow-routes.test.ts +120 -0
- package/server/config-migrator.ts +160 -0
- package/server/config.ts +64 -12
- package/server/database.ts +22 -31
- package/server/global-config.ts +204 -0
- package/server/index.ts +139 -316
- package/server/init.ts +266 -234
- package/server/launch.ts +32 -0
- package/server/manifest-types.ts +145 -0
- package/server/manifest.ts +494 -0
- package/server/migrate-legacy.ts +290 -0
- package/server/parsers/event-parser.test.ts +135 -0
- package/server/parsers/event-parser.ts +4 -1
- package/server/parsers/scope-parser.test.ts +270 -0
- package/server/parsers/scope-parser.ts +79 -31
- package/server/project-context.ts +325 -0
- package/server/project-emitter.ts +50 -0
- package/server/project-manager.ts +368 -0
- package/server/routes/aggregate-routes.ts +968 -0
- package/server/routes/config-routes.ts +43 -85
- package/server/routes/data-routes.ts +34 -156
- package/server/routes/dispatch-routes.ts +46 -17
- package/server/routes/git-routes.ts +77 -0
- package/server/routes/manifest-routes.ts +388 -0
- package/server/routes/scope-routes.ts +39 -30
- package/server/routes/sync-routes.ts +175 -0
- package/server/routes/version-routes.ts +1 -16
- package/server/routes/workflow-routes.ts +9 -3
- package/server/schema.ts +3 -0
- package/server/services/batch-orchestrator.ts +41 -17
- package/server/services/claude-session-service.ts +16 -14
- package/server/services/config-service.ts +10 -1
- package/server/services/deploy-service.test.ts +145 -0
- package/server/services/deploy-service.ts +2 -2
- package/server/services/event-service.test.ts +242 -0
- package/server/services/event-service.ts +92 -3
- package/server/services/gate-service.test.ts +131 -0
- package/server/services/gate-service.ts +2 -2
- package/server/services/git-service.ts +137 -4
- package/server/services/github-service.ts +120 -2
- package/server/services/readiness-service.test.ts +217 -0
- package/server/services/scope-cache.test.ts +167 -0
- package/server/services/scope-cache.ts +4 -1
- package/server/services/scope-service.test.ts +169 -0
- package/server/services/scope-service.ts +224 -130
- package/server/services/sprint-orchestrator.ts +30 -15
- package/server/services/sprint-service.test.ts +271 -0
- package/server/services/sprint-service.ts +29 -5
- package/server/services/sync-service.ts +482 -0
- package/server/services/sync-types.ts +77 -0
- package/server/services/workflow-service.test.ts +190 -0
- package/server/services/workflow-service.ts +29 -9
- package/server/settings-sync.ts +359 -0
- package/server/uninstall.ts +214 -0
- package/server/update-planner.ts +346 -0
- package/server/update.ts +263 -0
- package/server/utils/cc-hooks-parser.test.ts +96 -0
- package/server/utils/cc-hooks-parser.ts +4 -0
- package/server/utils/dispatch-utils.test.ts +245 -0
- package/server/utils/dispatch-utils.ts +102 -30
- package/server/utils/flag-builder.ts +56 -0
- package/server/utils/json-fields.test.ts +83 -0
- package/server/utils/json-fields.ts +14 -0
- package/server/utils/logger.ts +40 -3
- package/server/utils/package-info.ts +32 -0
- package/server/utils/route-helpers.test.ts +144 -0
- package/server/utils/route-helpers.ts +50 -0
- package/server/utils/terminal-launcher.ts +85 -25
- package/server/utils/worktree-manager.ts +9 -4
- package/server/validator.ts +270 -0
- package/server/watchers/event-watcher.ts +24 -12
- package/server/watchers/global-watcher.ts +77 -0
- package/server/watchers/scope-watcher.ts +21 -9
- package/server/wizard/config-editor.ts +248 -0
- package/server/wizard/detect.ts +104 -0
- package/server/wizard/doctor.ts +114 -0
- package/server/wizard/index.ts +438 -0
- package/server/wizard/phases/confirm.ts +45 -0
- package/server/wizard/phases/project-setup.ts +106 -0
- package/server/wizard/phases/setup-wizard.ts +78 -0
- package/server/wizard/phases/welcome.ts +39 -0
- package/server/wizard/phases/workflow-setup.ts +28 -0
- package/server/wizard/types.ts +56 -0
- package/server/wizard/ui.ts +92 -0
- package/shared/__fixtures__/workflow-configs.ts +80 -0
- package/shared/api-types.ts +106 -0
- package/shared/onboarding-tour.test.ts +94 -0
- package/shared/project-colors.ts +24 -0
- package/shared/workflow-config.test.ts +111 -0
- package/shared/workflow-config.ts +7 -0
- package/shared/workflow-engine.test.ts +388 -0
- package/shared/workflow-engine.ts +1 -1
- package/shared/workflow-normalizer.test.ts +119 -0
- package/shared/workflow-normalizer.ts +118 -0
- package/templates/agents/QUICK-REFERENCE.md +1 -0
- package/templates/agents/README.md +1 -0
- package/templates/agents/SKILL-TRIGGERS.md +11 -0
- package/templates/agents/green-team/deep-dive.md +361 -0
- package/templates/hooks/end-session.sh +4 -1
- package/templates/hooks/init-session.sh +1 -0
- package/templates/hooks/orbital-emit.sh +2 -2
- package/templates/hooks/orbital-report-deploy.sh +4 -4
- package/templates/hooks/orbital-report-gates.sh +4 -4
- package/templates/hooks/orbital-scope-update.sh +1 -1
- package/templates/hooks/scope-commit-logger.sh +2 -2
- package/templates/hooks/scope-create-cleanup.sh +2 -2
- package/templates/hooks/scope-create-gate.sh +2 -5
- package/templates/hooks/scope-gate.sh +4 -6
- package/templates/hooks/scope-helpers.sh +28 -1
- package/templates/hooks/scope-lifecycle-gate.sh +14 -5
- package/templates/hooks/scope-prepare.sh +67 -12
- package/templates/hooks/scope-transition.sh +14 -6
- package/templates/hooks/time-tracker.sh +2 -5
- package/templates/migrations/renames.json +1 -0
- package/templates/orbital.config.json +8 -6
- package/{shared/default-workflow.json → templates/presets/default.json} +65 -0
- package/templates/presets/development.json +4 -4
- package/templates/presets/gitflow.json +7 -0
- package/templates/prompts/README.md +23 -0
- package/templates/prompts/deep-dive-audit.md +94 -0
- package/templates/quick/rules.md +56 -5
- package/templates/settings-hooks.json +1 -1
- package/templates/skills/git-commit/SKILL.md +27 -7
- package/templates/skills/git-dev/SKILL.md +13 -4
- package/templates/skills/git-main/SKILL.md +13 -3
- package/templates/skills/git-production/SKILL.md +9 -2
- package/templates/skills/git-staging/SKILL.md +11 -3
- package/templates/skills/scope-create/SKILL.md +17 -3
- package/templates/skills/scope-fix-review/SKILL.md +14 -7
- package/templates/skills/scope-implement/SKILL.md +15 -4
- package/templates/skills/scope-post-review/SKILL.md +77 -7
- package/templates/skills/scope-pre-review/SKILL.md +11 -4
- package/templates/skills/scope-verify/SKILL.md +5 -3
- package/templates/skills/test-code-review/SKILL.md +41 -33
- package/templates/skills/test-scaffold/SKILL.md +222 -0
- package/dist/assets/WorkflowVisualizer-BZ21PIIF.js +0 -84
- package/dist/assets/charts-D__PA1zp.js +0 -72
- package/dist/assets/index-D1G6i0nS.css +0 -1
- package/dist/assets/index-DpItvKpf.js +0 -419
- package/dist/assets/ui-BvF022GT.js +0 -53
- package/index.html +0 -15
- package/postcss.config.js +0 -6
- package/src/App.tsx +0 -33
- package/src/components/AgentBadge.tsx +0 -40
- package/src/components/BatchPreflightModal.tsx +0 -115
- package/src/components/CardDisplayToggle.tsx +0 -74
- package/src/components/ColumnHeaderActions.tsx +0 -55
- package/src/components/ColumnMenu.tsx +0 -99
- package/src/components/DeployHistory.tsx +0 -141
- package/src/components/DispatchModal.tsx +0 -164
- package/src/components/DispatchPopover.tsx +0 -139
- package/src/components/DragOverlay.tsx +0 -25
- package/src/components/DriftSidebar.tsx +0 -140
- package/src/components/EnvironmentStrip.tsx +0 -88
- package/src/components/ErrorBoundary.tsx +0 -62
- package/src/components/FilterChip.tsx +0 -105
- package/src/components/GateIndicator.tsx +0 -33
- package/src/components/IdeaDetailModal.tsx +0 -190
- package/src/components/IdeaFormDialog.tsx +0 -113
- package/src/components/KanbanColumn.tsx +0 -201
- package/src/components/MarkdownRenderer.tsx +0 -114
- package/src/components/NeonGrid.tsx +0 -128
- package/src/components/PromotionQueue.tsx +0 -89
- package/src/components/ScopeCard.tsx +0 -234
- package/src/components/ScopeDetailModal.tsx +0 -255
- package/src/components/ScopeFilterBar.tsx +0 -152
- package/src/components/SearchInput.tsx +0 -102
- package/src/components/SessionPanel.tsx +0 -335
- package/src/components/SprintContainer.tsx +0 -303
- package/src/components/SprintDependencyDialog.tsx +0 -78
- package/src/components/SprintPreflightModal.tsx +0 -138
- package/src/components/StatusBar.tsx +0 -168
- package/src/components/SwimCell.tsx +0 -67
- package/src/components/SwimLaneRow.tsx +0 -94
- package/src/components/SwimlaneBoardView.tsx +0 -108
- package/src/components/VersionBadge.tsx +0 -139
- package/src/components/ViewModeSelector.tsx +0 -114
- package/src/components/config/AgentChip.tsx +0 -53
- package/src/components/config/AgentCreateDialog.tsx +0 -321
- package/src/components/config/AgentEditor.tsx +0 -175
- package/src/components/config/DirectoryTree.tsx +0 -582
- package/src/components/config/FileEditor.tsx +0 -550
- package/src/components/config/HookChip.tsx +0 -50
- package/src/components/config/StageCard.tsx +0 -198
- package/src/components/config/TransitionZone.tsx +0 -173
- package/src/components/config/UnifiedWorkflowPipeline.tsx +0 -216
- package/src/components/config/WorkflowPipeline.tsx +0 -161
- package/src/components/source-control/BranchList.tsx +0 -93
- package/src/components/source-control/BranchPanel.tsx +0 -105
- package/src/components/source-control/CommitLog.tsx +0 -100
- package/src/components/source-control/CommitRow.tsx +0 -47
- package/src/components/source-control/GitHubPanel.tsx +0 -110
- package/src/components/source-control/GitHubSetupGuide.tsx +0 -52
- package/src/components/source-control/GitOverviewBar.tsx +0 -101
- package/src/components/source-control/PullRequestList.tsx +0 -69
- package/src/components/source-control/WorktreeList.tsx +0 -80
- package/src/components/ui/badge.tsx +0 -41
- package/src/components/ui/button.tsx +0 -55
- package/src/components/ui/card.tsx +0 -78
- package/src/components/ui/dialog.tsx +0 -94
- package/src/components/ui/popover.tsx +0 -33
- package/src/components/ui/scroll-area.tsx +0 -54
- package/src/components/ui/separator.tsx +0 -28
- package/src/components/ui/tabs.tsx +0 -52
- package/src/components/ui/toggle-switch.tsx +0 -35
- package/src/components/ui/tooltip.tsx +0 -27
- package/src/components/workflow/AddEdgeDialog.tsx +0 -217
- package/src/components/workflow/AddListDialog.tsx +0 -201
- package/src/components/workflow/ChecklistEditor.tsx +0 -239
- package/src/components/workflow/CommandPrefixManager.tsx +0 -118
- package/src/components/workflow/ConfigSettingsPanel.tsx +0 -189
- package/src/components/workflow/DirectionSelector.tsx +0 -133
- package/src/components/workflow/DispatchConfigPanel.tsx +0 -180
- package/src/components/workflow/EdgeDetailPanel.tsx +0 -236
- package/src/components/workflow/EdgePropertyEditor.tsx +0 -251
- package/src/components/workflow/EditToolbar.tsx +0 -138
- package/src/components/workflow/HookDetailPanel.tsx +0 -250
- package/src/components/workflow/HookExecutionLog.tsx +0 -24
- package/src/components/workflow/HookSourceModal.tsx +0 -129
- package/src/components/workflow/HooksDashboard.tsx +0 -363
- package/src/components/workflow/ListPropertyEditor.tsx +0 -251
- package/src/components/workflow/MigrationPreviewDialog.tsx +0 -237
- package/src/components/workflow/MovementRulesPanel.tsx +0 -188
- package/src/components/workflow/NodeDetailPanel.tsx +0 -245
- package/src/components/workflow/PresetSelector.tsx +0 -414
- package/src/components/workflow/SkillCommandBuilder.tsx +0 -174
- package/src/components/workflow/WorkflowEdgeComponent.tsx +0 -145
- package/src/components/workflow/WorkflowNode.tsx +0 -147
- package/src/components/workflow/graphLayout.ts +0 -186
- package/src/components/workflow/mergeHooks.ts +0 -85
- package/src/components/workflow/useEditHistory.ts +0 -88
- package/src/components/workflow/useWorkflowEditor.ts +0 -262
- package/src/components/workflow/validateConfig.ts +0 -70
- package/src/hooks/useActiveDispatches.ts +0 -198
- package/src/hooks/useBoardSettings.ts +0 -170
- package/src/hooks/useCardDisplay.ts +0 -57
- package/src/hooks/useCcHooks.ts +0 -24
- package/src/hooks/useConfigTree.ts +0 -51
- package/src/hooks/useEnforcementRules.ts +0 -46
- package/src/hooks/useEvents.ts +0 -59
- package/src/hooks/useFileEditor.ts +0 -165
- package/src/hooks/useGates.ts +0 -57
- package/src/hooks/useIdeaActions.ts +0 -53
- package/src/hooks/useKanbanDnd.ts +0 -410
- package/src/hooks/useOrbitalConfig.ts +0 -54
- package/src/hooks/usePipeline.ts +0 -47
- package/src/hooks/usePipelineData.ts +0 -338
- package/src/hooks/useReconnect.ts +0 -25
- package/src/hooks/useScopeFilters.ts +0 -125
- package/src/hooks/useScopeSessions.ts +0 -44
- package/src/hooks/useScopes.ts +0 -67
- package/src/hooks/useSearch.ts +0 -67
- package/src/hooks/useSettings.tsx +0 -187
- package/src/hooks/useSocket.ts +0 -25
- package/src/hooks/useSourceControl.ts +0 -105
- package/src/hooks/useSprintPreflight.ts +0 -55
- package/src/hooks/useSprints.ts +0 -154
- package/src/hooks/useStatusBarHighlight.ts +0 -18
- package/src/hooks/useSwimlaneBoardSettings.ts +0 -104
- package/src/hooks/useTheme.ts +0 -9
- package/src/hooks/useTransitionReadiness.ts +0 -53
- package/src/hooks/useVersion.ts +0 -155
- package/src/hooks/useViolations.ts +0 -65
- package/src/hooks/useWorkflow.tsx +0 -125
- package/src/hooks/useZoomModifier.ts +0 -19
- package/src/index.css +0 -797
- package/src/layouts/DashboardLayout.tsx +0 -113
- package/src/lib/collisionDetection.ts +0 -20
- package/src/lib/scope-fields.ts +0 -61
- package/src/lib/swimlane.ts +0 -146
- package/src/lib/utils.ts +0 -15
- package/src/main.tsx +0 -19
- package/src/socket.ts +0 -11
- package/src/types/index.ts +0 -497
- package/src/views/AgentFeed.tsx +0 -339
- package/src/views/DeployPipeline.tsx +0 -59
- package/src/views/EnforcementView.tsx +0 -378
- package/src/views/PrimitivesConfig.tsx +0 -500
- package/src/views/QualityGates.tsx +0 -1012
- package/src/views/ScopeBoard.tsx +0 -454
- package/src/views/SessionTimeline.tsx +0 -516
- package/src/views/Settings.tsx +0 -183
- package/src/views/SourceControl.tsx +0 -95
- package/src/views/WorkflowVisualizer.tsx +0 -382
- package/tailwind.config.js +0 -161
- package/tsconfig.json +0 -25
- 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
|
-
|
|
35
|
+
npm install orbital-command
|
|
57
36
|
cd my-project
|
|
37
|
+
orbital
|
|
38
|
+
```
|
|
58
39
|
|
|
59
|
-
|
|
60
|
-
orbital init
|
|
40
|
+
That's it. The `orbital` command detects your context and guides you through everything:
|
|
61
41
|
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
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
|
-
|
|
48
|
+
Open [http://localhost:4444](http://localhost:4444) after launching.
|
|
69
49
|
|
|
70
50
|
## What Gets Installed
|
|
71
51
|
|
|
72
|
-
After
|
|
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
|
|
117
|
-
| `orbital
|
|
118
|
-
| `orbital
|
|
119
|
-
| `orbital
|
|
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
|
|
122
|
-
| `orbital
|
|
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
|
|
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
|
|
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.
|
|
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
|
+
}
|