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
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bidirectional settings hook sync.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the old additive-only mergeSettingsHooks(). The key improvement:
|
|
5
|
+
* when a hook is removed from the template between versions, it's also
|
|
6
|
+
* removed from settings.local.json — preventing stale registrations
|
|
7
|
+
* pointing to deleted scripts.
|
|
8
|
+
*/
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import { hashFile } from './manifest.js';
|
|
12
|
+
import { createLogger } from './utils/logger.js';
|
|
13
|
+
const log = createLogger('sync');
|
|
14
|
+
// ─── Public API ─────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Sync settings.local.json hooks with the current settings-hooks.json template.
|
|
17
|
+
*
|
|
18
|
+
* - Adds new _orbital hooks from the template
|
|
19
|
+
* - Removes _orbital hooks that are no longer in the template
|
|
20
|
+
* - Updates _orbital hooks that have changed (e.g., renamed command paths)
|
|
21
|
+
* - Never touches user hooks (those without _orbital: true)
|
|
22
|
+
*
|
|
23
|
+
* @param settingsPath - Path to .claude/settings.local.json
|
|
24
|
+
* @param templatePath - Path to templates/settings-hooks.json
|
|
25
|
+
* @param previousChecksum - Hash of the template last time sync was run (from manifest)
|
|
26
|
+
* @param renameMap - Optional map of old command paths to new ones
|
|
27
|
+
* @returns Sync result with counts of changes made
|
|
28
|
+
*/
|
|
29
|
+
export function syncSettingsHooks(settingsPath, templatePath, previousChecksum, renameMap) {
|
|
30
|
+
if (!fs.existsSync(templatePath)) {
|
|
31
|
+
return { added: 0, removed: 0, updated: 0, skipped: true };
|
|
32
|
+
}
|
|
33
|
+
// Check if template has changed since last sync
|
|
34
|
+
const currentChecksum = hashFile(templatePath);
|
|
35
|
+
if (currentChecksum === previousChecksum) {
|
|
36
|
+
return { added: 0, removed: 0, updated: 0, skipped: true };
|
|
37
|
+
}
|
|
38
|
+
// Load current settings
|
|
39
|
+
let settings = {};
|
|
40
|
+
if (fs.existsSync(settingsPath)) {
|
|
41
|
+
try {
|
|
42
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
log.warn('Malformed settings file, starting fresh', { path: settingsPath });
|
|
46
|
+
settings = {};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Load template
|
|
50
|
+
const template = JSON.parse(fs.readFileSync(templatePath, 'utf-8'));
|
|
51
|
+
const templateHooks = template.hooks || {};
|
|
52
|
+
// Collect all _orbital commands currently in settings
|
|
53
|
+
const currentOrbitalCommands = collectOrbitalCommands(settings.hooks || {});
|
|
54
|
+
// Collect all commands from the template
|
|
55
|
+
const templateCommands = collectAllCommands(templateHooks);
|
|
56
|
+
// Build rename map for command paths (from file rename map)
|
|
57
|
+
const commandRenameMap = buildCommandRenameMap(renameMap);
|
|
58
|
+
let added = 0;
|
|
59
|
+
let removed = 0;
|
|
60
|
+
let updated = 0;
|
|
61
|
+
// Phase 1: Handle renames in existing _orbital hooks
|
|
62
|
+
if (settings.hooks && commandRenameMap.size > 0) {
|
|
63
|
+
updated += applyCommandRenames(settings.hooks, commandRenameMap);
|
|
64
|
+
}
|
|
65
|
+
// Phase 2: Remove _orbital hooks that are no longer in the template
|
|
66
|
+
if (settings.hooks) {
|
|
67
|
+
removed += removeStaleHooks(settings.hooks, templateCommands);
|
|
68
|
+
}
|
|
69
|
+
// Phase 3: Add new hooks from the template
|
|
70
|
+
if (!settings.hooks)
|
|
71
|
+
settings.hooks = {};
|
|
72
|
+
added += addNewHooks(settings.hooks, templateHooks, currentOrbitalCommands);
|
|
73
|
+
// Phase 4: Clean up empty groups and events
|
|
74
|
+
cleanupEmptyEntries(settings.hooks);
|
|
75
|
+
if (Object.keys(settings.hooks).length === 0) {
|
|
76
|
+
delete settings.hooks;
|
|
77
|
+
}
|
|
78
|
+
// Write back
|
|
79
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
80
|
+
return { added, removed, updated, skipped: false };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Remove all _orbital hooks from settings.local.json.
|
|
84
|
+
* Used during uninstall.
|
|
85
|
+
*/
|
|
86
|
+
export function removeAllOrbitalHooks(settingsPath) {
|
|
87
|
+
if (!fs.existsSync(settingsPath))
|
|
88
|
+
return 0;
|
|
89
|
+
let settings;
|
|
90
|
+
try {
|
|
91
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
log.debug('Settings unreadable during cleanup', { path: settingsPath });
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
if (!settings.hooks)
|
|
98
|
+
return 0;
|
|
99
|
+
let removed = 0;
|
|
100
|
+
for (const groups of Object.values(settings.hooks)) {
|
|
101
|
+
for (const group of groups) {
|
|
102
|
+
if (!group.hooks)
|
|
103
|
+
continue;
|
|
104
|
+
const before = group.hooks.length;
|
|
105
|
+
group.hooks = group.hooks.filter(h => !h._orbital);
|
|
106
|
+
removed += before - group.hooks.length;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
cleanupEmptyEntries(settings.hooks);
|
|
110
|
+
if (Object.keys(settings.hooks).length === 0) {
|
|
111
|
+
delete settings.hooks;
|
|
112
|
+
}
|
|
113
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
114
|
+
return removed;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get the current checksum of the settings-hooks.json template.
|
|
118
|
+
*/
|
|
119
|
+
export function getTemplateChecksum(templatePath) {
|
|
120
|
+
if (!fs.existsSync(templatePath))
|
|
121
|
+
return '';
|
|
122
|
+
return hashFile(templatePath);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Validate that every _orbital hook in settings.local.json points to a file
|
|
126
|
+
* that exists on disk. Returns list of broken command paths.
|
|
127
|
+
*/
|
|
128
|
+
export function validateHookPaths(settingsPath, projectRoot) {
|
|
129
|
+
if (!fs.existsSync(settingsPath))
|
|
130
|
+
return [];
|
|
131
|
+
let settings;
|
|
132
|
+
try {
|
|
133
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
if (!settings.hooks)
|
|
139
|
+
return [];
|
|
140
|
+
const broken = [];
|
|
141
|
+
for (const groups of Object.values(settings.hooks)) {
|
|
142
|
+
for (const group of groups) {
|
|
143
|
+
for (const hook of group.hooks || []) {
|
|
144
|
+
if (!hook._orbital)
|
|
145
|
+
continue;
|
|
146
|
+
// Resolve command path — handle $CLAUDE_PROJECT_DIR variable
|
|
147
|
+
const commandPath = hook.command
|
|
148
|
+
.replace(/^"?\$CLAUDE_PROJECT_DIR"?\//, '')
|
|
149
|
+
.replace(/^"/, '')
|
|
150
|
+
.replace(/"$/, '');
|
|
151
|
+
const absPath = path.join(projectRoot, commandPath);
|
|
152
|
+
if (!fs.existsSync(absPath)) {
|
|
153
|
+
broken.push(hook.command);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return broken;
|
|
159
|
+
}
|
|
160
|
+
// ─── Internal Helpers ───────────────────────────────────────
|
|
161
|
+
/** Collect all command strings from _orbital hooks in settings. */
|
|
162
|
+
function collectOrbitalCommands(hooks) {
|
|
163
|
+
const commands = new Set();
|
|
164
|
+
for (const groups of Object.values(hooks)) {
|
|
165
|
+
for (const group of groups) {
|
|
166
|
+
for (const hook of group.hooks || []) {
|
|
167
|
+
if (hook._orbital)
|
|
168
|
+
commands.add(hook.command);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return commands;
|
|
173
|
+
}
|
|
174
|
+
/** Collect all command strings from a hooks template. */
|
|
175
|
+
function collectAllCommands(hooks) {
|
|
176
|
+
const commands = new Set();
|
|
177
|
+
for (const groups of Object.values(hooks)) {
|
|
178
|
+
for (const group of groups) {
|
|
179
|
+
for (const hook of group.hooks || []) {
|
|
180
|
+
if (hook.command)
|
|
181
|
+
commands.add(hook.command);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return commands;
|
|
186
|
+
}
|
|
187
|
+
/** Build a command-level rename map from a file-level rename map. */
|
|
188
|
+
function buildCommandRenameMap(fileRenameMap) {
|
|
189
|
+
const commandMap = new Map();
|
|
190
|
+
if (!fileRenameMap)
|
|
191
|
+
return commandMap;
|
|
192
|
+
for (const [oldFile, newFile] of fileRenameMap) {
|
|
193
|
+
// Hook commands use paths like: "$CLAUDE_PROJECT_DIR"/.claude/hooks/foo.sh
|
|
194
|
+
// We need to detect when oldFile appears in a command and replace with newFile
|
|
195
|
+
if (oldFile.startsWith('hooks/') || oldFile.startsWith('skills/')) {
|
|
196
|
+
const oldSuffix = `.claude/${oldFile}`;
|
|
197
|
+
const newSuffix = `.claude/${newFile}`;
|
|
198
|
+
commandMap.set(oldSuffix, newSuffix);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return commandMap;
|
|
202
|
+
}
|
|
203
|
+
/** Apply command path renames to existing _orbital hooks. Returns count of updates. */
|
|
204
|
+
function applyCommandRenames(hooks, commandRenameMap) {
|
|
205
|
+
let updated = 0;
|
|
206
|
+
for (const groups of Object.values(hooks)) {
|
|
207
|
+
for (const group of groups) {
|
|
208
|
+
for (const hook of group.hooks || []) {
|
|
209
|
+
if (!hook._orbital)
|
|
210
|
+
continue;
|
|
211
|
+
for (const [oldSuffix, newSuffix] of commandRenameMap) {
|
|
212
|
+
if (hook.command.includes(oldSuffix)) {
|
|
213
|
+
hook.command = hook.command.replace(oldSuffix, newSuffix);
|
|
214
|
+
updated++;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return updated;
|
|
222
|
+
}
|
|
223
|
+
/** Remove _orbital hooks whose commands are not in the template. Returns count removed. */
|
|
224
|
+
function removeStaleHooks(hooks, templateCommands) {
|
|
225
|
+
let removed = 0;
|
|
226
|
+
for (const groups of Object.values(hooks)) {
|
|
227
|
+
for (const group of groups) {
|
|
228
|
+
if (!group.hooks)
|
|
229
|
+
continue;
|
|
230
|
+
const before = group.hooks.length;
|
|
231
|
+
group.hooks = group.hooks.filter(hook => {
|
|
232
|
+
if (!hook._orbital)
|
|
233
|
+
return true; // Keep user hooks
|
|
234
|
+
return templateCommands.has(hook.command); // Keep if still in template
|
|
235
|
+
});
|
|
236
|
+
removed += before - group.hooks.length;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return removed;
|
|
240
|
+
}
|
|
241
|
+
/** Add hooks from template that aren't already in settings. Returns count added. */
|
|
242
|
+
function addNewHooks(settingsHooks, templateHooks, existingOrbitalCommands) {
|
|
243
|
+
let added = 0;
|
|
244
|
+
for (const [event, templateGroups] of Object.entries(templateHooks)) {
|
|
245
|
+
if (!settingsHooks[event]) {
|
|
246
|
+
settingsHooks[event] = [];
|
|
247
|
+
}
|
|
248
|
+
for (const templateGroup of templateGroups) {
|
|
249
|
+
const matcher = templateGroup.matcher || '__none__';
|
|
250
|
+
// Find matching group in settings
|
|
251
|
+
let targetGroup = settingsHooks[event].find(g => (g.matcher || '__none__') === matcher);
|
|
252
|
+
if (!targetGroup) {
|
|
253
|
+
// Create the group with all hooks tagged
|
|
254
|
+
targetGroup = {
|
|
255
|
+
...(templateGroup.matcher ? { matcher: templateGroup.matcher } : {}),
|
|
256
|
+
hooks: [],
|
|
257
|
+
};
|
|
258
|
+
settingsHooks[event].push(targetGroup);
|
|
259
|
+
}
|
|
260
|
+
if (!targetGroup.hooks)
|
|
261
|
+
targetGroup.hooks = [];
|
|
262
|
+
for (const hook of templateGroup.hooks || []) {
|
|
263
|
+
if (existingOrbitalCommands.has(hook.command))
|
|
264
|
+
continue;
|
|
265
|
+
// Also check if command already exists (de-dup)
|
|
266
|
+
const alreadyPresent = targetGroup.hooks.some(h => h.command === hook.command);
|
|
267
|
+
if (alreadyPresent)
|
|
268
|
+
continue;
|
|
269
|
+
targetGroup.hooks.push({ ...hook, _orbital: true });
|
|
270
|
+
added++;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return added;
|
|
275
|
+
}
|
|
276
|
+
/** Remove empty hook groups and empty event entries. */
|
|
277
|
+
function cleanupEmptyEntries(hooks) {
|
|
278
|
+
for (const [event, groups] of Object.entries(hooks)) {
|
|
279
|
+
hooks[event] = groups.filter(g => g.hooks && g.hooks.length > 0);
|
|
280
|
+
if (hooks[event].length === 0) {
|
|
281
|
+
delete hooks[event];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Uninstall logic — extracted from init.ts for focused maintainability.
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { loadManifest } from './manifest.js';
|
|
7
|
+
import { removeAllOrbitalHooks } from './settings-sync.js';
|
|
8
|
+
import { unregisterProject } from './global-config.js';
|
|
9
|
+
import { TEMPLATES_DIR, cleanEmptyDirs, listTemplateFiles, } from './init.js';
|
|
10
|
+
export function runUninstall(projectRoot, options = {}) {
|
|
11
|
+
const { dryRun = false, keepConfig = false } = options;
|
|
12
|
+
const claudeDir = path.join(projectRoot, '.claude');
|
|
13
|
+
console.log(`\nOrbital Command — uninstall${dryRun ? ' (dry run)' : ''}`);
|
|
14
|
+
console.log(`Project root: ${projectRoot}\n`);
|
|
15
|
+
const manifest = loadManifest(projectRoot);
|
|
16
|
+
// Fall back to legacy uninstall if no manifest
|
|
17
|
+
if (!manifest) {
|
|
18
|
+
console.log(' No manifest found — falling back to legacy uninstall.');
|
|
19
|
+
runLegacyUninstall(projectRoot);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// Compute what to remove vs preserve
|
|
23
|
+
const toRemove = [];
|
|
24
|
+
const toPreserve = [];
|
|
25
|
+
for (const [filePath, record] of Object.entries(manifest.files)) {
|
|
26
|
+
if (record.origin === 'user') {
|
|
27
|
+
toPreserve.push(filePath);
|
|
28
|
+
}
|
|
29
|
+
else if (record.status === 'modified' || record.status === 'outdated') {
|
|
30
|
+
toPreserve.push(filePath);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
toRemove.push(filePath);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (dryRun) {
|
|
37
|
+
console.log(' Files to REMOVE:');
|
|
38
|
+
for (const f of toRemove)
|
|
39
|
+
console.log(` ${f}`);
|
|
40
|
+
if (toPreserve.length > 0) {
|
|
41
|
+
console.log(' Files to PRESERVE:');
|
|
42
|
+
for (const f of toPreserve)
|
|
43
|
+
console.log(` ${f} (${manifest.files[f].origin}/${manifest.files[f].status})`);
|
|
44
|
+
}
|
|
45
|
+
console.log(`\n Would also remove: settings hooks, generated artifacts, config files, gitignore entries`);
|
|
46
|
+
console.log(` No changes made. Run without --dry-run to apply.`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// 1. Remove _orbital hooks from settings.local.json
|
|
50
|
+
const settingsPath = path.join(claudeDir, 'settings.local.json');
|
|
51
|
+
const removedHooks = removeAllOrbitalHooks(settingsPath);
|
|
52
|
+
console.log(` Removed ${removedHooks} orbital hook registrations`);
|
|
53
|
+
// 2. Delete template files (synced + pinned, not modified or user-owned)
|
|
54
|
+
let filesRemoved = 0;
|
|
55
|
+
for (const filePath of toRemove) {
|
|
56
|
+
const absPath = path.join(claudeDir, filePath);
|
|
57
|
+
if (fs.existsSync(absPath)) {
|
|
58
|
+
fs.unlinkSync(absPath);
|
|
59
|
+
filesRemoved++;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
console.log(` Removed ${filesRemoved} template files`);
|
|
63
|
+
if (toPreserve.length > 0) {
|
|
64
|
+
console.log(` Preserved ${toPreserve.length} user/modified files`);
|
|
65
|
+
}
|
|
66
|
+
// 3. Clean up empty directories
|
|
67
|
+
for (const dir of ['hooks', 'skills', 'agents', 'config/workflows', 'quick', 'anti-patterns']) {
|
|
68
|
+
const dirPath = path.join(claudeDir, dir);
|
|
69
|
+
if (fs.existsSync(dirPath))
|
|
70
|
+
cleanEmptyDirs(dirPath);
|
|
71
|
+
}
|
|
72
|
+
// 4. Remove generated artifacts
|
|
73
|
+
for (const artifact of manifest.generatedArtifacts) {
|
|
74
|
+
const artifactPath = path.join(claudeDir, artifact);
|
|
75
|
+
if (fs.existsSync(artifactPath)) {
|
|
76
|
+
fs.unlinkSync(artifactPath);
|
|
77
|
+
console.log(` Removed .claude/${artifact}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// 5. Remove template-sourced config files
|
|
81
|
+
const configFiles = [
|
|
82
|
+
'config/agent-triggers.json',
|
|
83
|
+
'config/workflow.json',
|
|
84
|
+
'lessons-learned.md',
|
|
85
|
+
];
|
|
86
|
+
for (const file of configFiles) {
|
|
87
|
+
const filePath = path.join(claudeDir, file);
|
|
88
|
+
if (fs.existsSync(filePath)) {
|
|
89
|
+
fs.unlinkSync(filePath);
|
|
90
|
+
console.log(` Removed .claude/${file}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Remove config/workflows/ directory entirely
|
|
94
|
+
const workflowsDir = path.join(claudeDir, 'config', 'workflows');
|
|
95
|
+
if (fs.existsSync(workflowsDir)) {
|
|
96
|
+
fs.rmSync(workflowsDir, { recursive: true, force: true });
|
|
97
|
+
console.log(` Removed .claude/config/workflows/`);
|
|
98
|
+
}
|
|
99
|
+
// 6. Remove gitignore entries
|
|
100
|
+
removeGitignoreEntries(projectRoot, manifest.gitignoreEntries);
|
|
101
|
+
console.log(` Cleaned .gitignore`);
|
|
102
|
+
// 7. Deregister from global registry
|
|
103
|
+
if (unregisterProject(projectRoot)) {
|
|
104
|
+
console.log(` Removed project from ~/.orbital/config.json`);
|
|
105
|
+
}
|
|
106
|
+
// 8. Remove orbital config and manifest (unless --keep-config)
|
|
107
|
+
if (!keepConfig) {
|
|
108
|
+
const toClean = ['orbital.config.json', 'orbital-manifest.json', 'orbital-sync.json'];
|
|
109
|
+
for (const file of toClean) {
|
|
110
|
+
const filePath = path.join(claudeDir, file);
|
|
111
|
+
if (fs.existsSync(filePath))
|
|
112
|
+
fs.unlinkSync(filePath);
|
|
113
|
+
}
|
|
114
|
+
// Remove backups directory
|
|
115
|
+
const backupsDir = path.join(claudeDir, '.orbital-backups');
|
|
116
|
+
if (fs.existsSync(backupsDir))
|
|
117
|
+
fs.rmSync(backupsDir, { recursive: true, force: true });
|
|
118
|
+
console.log(` Removed orbital config and manifest`);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// Still remove the manifest — it's invalid after uninstall
|
|
122
|
+
const manifestPath = path.join(claudeDir, 'orbital-manifest.json');
|
|
123
|
+
if (fs.existsSync(manifestPath))
|
|
124
|
+
fs.unlinkSync(manifestPath);
|
|
125
|
+
console.log(` Kept orbital.config.json (--keep-config)`);
|
|
126
|
+
}
|
|
127
|
+
// Clean up remaining empty directories
|
|
128
|
+
for (const dir of ['config', 'quick', 'anti-patterns', 'review-verdicts']) {
|
|
129
|
+
const dirPath = path.join(claudeDir, dir);
|
|
130
|
+
if (fs.existsSync(dirPath))
|
|
131
|
+
cleanEmptyDirs(dirPath);
|
|
132
|
+
}
|
|
133
|
+
const total = removedHooks + filesRemoved;
|
|
134
|
+
console.log(`\nUninstall complete. ${total} items removed.`);
|
|
135
|
+
if (toPreserve.length > 0) {
|
|
136
|
+
console.log(`Note: ${toPreserve.length} user/modified files were preserved.`);
|
|
137
|
+
}
|
|
138
|
+
console.log(`Note: scopes/ and .claude/orbital-events/ were preserved.\n`);
|
|
139
|
+
}
|
|
140
|
+
// ─── Helpers ────────────────────────────────────────────────
|
|
141
|
+
/** Legacy uninstall for projects without a manifest (backward compat). */
|
|
142
|
+
function runLegacyUninstall(projectRoot) {
|
|
143
|
+
const claudeDir = path.join(projectRoot, '.claude');
|
|
144
|
+
// Remove orbital hooks from settings.local.json
|
|
145
|
+
const settingsPath = path.join(claudeDir, 'settings.local.json');
|
|
146
|
+
const removedHooks = removeAllOrbitalHooks(settingsPath);
|
|
147
|
+
console.log(` Removed ${removedHooks} orbital hook registrations`);
|
|
148
|
+
// Delete hooks/skills/agents that match template files
|
|
149
|
+
for (const dir of ['hooks', 'skills', 'agents']) {
|
|
150
|
+
const templateDir = listTemplateFiles(path.join(TEMPLATES_DIR, dir), path.join(claudeDir, dir));
|
|
151
|
+
let removed = 0;
|
|
152
|
+
for (const f of templateDir) {
|
|
153
|
+
if (fs.existsSync(f)) {
|
|
154
|
+
fs.unlinkSync(f);
|
|
155
|
+
removed++;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const dirPath = path.join(claudeDir, dir);
|
|
159
|
+
if (fs.existsSync(dirPath))
|
|
160
|
+
cleanEmptyDirs(dirPath);
|
|
161
|
+
console.log(` Removed ${removed} ${dir} files`);
|
|
162
|
+
}
|
|
163
|
+
console.log(`\nLegacy uninstall complete.`);
|
|
164
|
+
console.log(`Note: scopes/ and .claude/orbital-events/ were preserved.\n`);
|
|
165
|
+
}
|
|
166
|
+
/** Remove Orbital-added entries from .gitignore. */
|
|
167
|
+
function removeGitignoreEntries(projectRoot, entries) {
|
|
168
|
+
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
169
|
+
if (!fs.existsSync(gitignorePath))
|
|
170
|
+
return;
|
|
171
|
+
let content = fs.readFileSync(gitignorePath, 'utf-8');
|
|
172
|
+
const marker = '# Orbital Command';
|
|
173
|
+
const markerIdx = content.indexOf(marker);
|
|
174
|
+
if (markerIdx !== -1) {
|
|
175
|
+
const before = content.slice(0, markerIdx).replace(/\n+$/, '');
|
|
176
|
+
const after = content.slice(markerIdx);
|
|
177
|
+
const lines = after.split('\n');
|
|
178
|
+
let endIdx = 0;
|
|
179
|
+
for (let i = 0; i < lines.length; i++) {
|
|
180
|
+
const line = lines[i].trim();
|
|
181
|
+
if (i === 0) {
|
|
182
|
+
endIdx = i + 1;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (line === '' || entries.includes(line)) {
|
|
186
|
+
endIdx = i + 1;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
const remaining = lines.slice(endIdx).join('\n');
|
|
192
|
+
content = before + (remaining ? '\n' + remaining : '') + '\n';
|
|
193
|
+
fs.writeFileSync(gitignorePath, content, 'utf-8');
|
|
194
|
+
}
|
|
195
|
+
}
|