orbital-command 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +396 -0
  3. package/bin/orbital.js +362 -0
  4. package/dist/assets/WorkflowVisualizer-BZ21PIIF.js +84 -0
  5. package/dist/assets/WorkflowVisualizer-BZV40eAE.css +1 -0
  6. package/dist/assets/charts-D__PA1zp.js +72 -0
  7. package/dist/assets/index-D1G6i0nS.css +1 -0
  8. package/dist/assets/index-DpItvKpf.js +419 -0
  9. package/dist/assets/ui-BvF022GT.js +53 -0
  10. package/dist/assets/vendor-Dzv9lrRc.js +59 -0
  11. package/dist/index.html +19 -0
  12. package/dist/scanner-sweep.png +0 -0
  13. package/dist/server/server/adapters/index.js +34 -0
  14. package/dist/server/server/adapters/iterm2-adapter.js +29 -0
  15. package/dist/server/server/adapters/subprocess-adapter.js +21 -0
  16. package/dist/server/server/adapters/terminal-adapter.js +1 -0
  17. package/dist/server/server/config.js +156 -0
  18. package/dist/server/server/database.js +90 -0
  19. package/dist/server/server/index.js +372 -0
  20. package/dist/server/server/init.js +811 -0
  21. package/dist/server/server/parsers/event-parser.js +64 -0
  22. package/dist/server/server/parsers/scope-parser.js +188 -0
  23. package/dist/server/server/routes/config-routes.js +163 -0
  24. package/dist/server/server/routes/data-routes.js +461 -0
  25. package/dist/server/server/routes/dispatch-routes.js +215 -0
  26. package/dist/server/server/routes/git-routes.js +92 -0
  27. package/dist/server/server/routes/scope-routes.js +215 -0
  28. package/dist/server/server/routes/sprint-routes.js +116 -0
  29. package/dist/server/server/routes/version-routes.js +130 -0
  30. package/dist/server/server/routes/workflow-routes.js +185 -0
  31. package/dist/server/server/schema.js +90 -0
  32. package/dist/server/server/services/batch-orchestrator.js +253 -0
  33. package/dist/server/server/services/claude-session-service.js +352 -0
  34. package/dist/server/server/services/config-service.js +132 -0
  35. package/dist/server/server/services/deploy-service.js +51 -0
  36. package/dist/server/server/services/event-service.js +63 -0
  37. package/dist/server/server/services/gate-service.js +83 -0
  38. package/dist/server/server/services/git-service.js +309 -0
  39. package/dist/server/server/services/github-service.js +145 -0
  40. package/dist/server/server/services/readiness-service.js +184 -0
  41. package/dist/server/server/services/scope-cache.js +72 -0
  42. package/dist/server/server/services/scope-service.js +424 -0
  43. package/dist/server/server/services/sprint-orchestrator.js +312 -0
  44. package/dist/server/server/services/sprint-service.js +293 -0
  45. package/dist/server/server/services/workflow-service.js +397 -0
  46. package/dist/server/server/utils/cc-hooks-parser.js +49 -0
  47. package/dist/server/server/utils/dispatch-utils.js +305 -0
  48. package/dist/server/server/utils/logger.js +86 -0
  49. package/dist/server/server/utils/terminal-launcher.js +388 -0
  50. package/dist/server/server/utils/worktree-manager.js +98 -0
  51. package/dist/server/server/watchers/event-watcher.js +81 -0
  52. package/dist/server/server/watchers/scope-watcher.js +33 -0
  53. package/dist/server/shared/api-types.js +5 -0
  54. package/dist/server/shared/default-workflow.json +616 -0
  55. package/dist/server/shared/workflow-config.js +44 -0
  56. package/dist/server/shared/workflow-engine.js +353 -0
  57. package/index.html +15 -0
  58. package/package.json +110 -0
  59. package/postcss.config.js +6 -0
  60. package/schemas/orbital.config.schema.json +83 -0
  61. package/scripts/postinstall.js +24 -0
  62. package/scripts/start.sh +20 -0
  63. package/server/adapters/index.ts +41 -0
  64. package/server/adapters/iterm2-adapter.ts +37 -0
  65. package/server/adapters/subprocess-adapter.ts +25 -0
  66. package/server/adapters/terminal-adapter.ts +24 -0
  67. package/server/config.ts +234 -0
  68. package/server/database.ts +107 -0
  69. package/server/index.ts +452 -0
  70. package/server/init.ts +891 -0
  71. package/server/parsers/event-parser.ts +74 -0
  72. package/server/parsers/scope-parser.ts +240 -0
  73. package/server/routes/config-routes.ts +182 -0
  74. package/server/routes/data-routes.ts +548 -0
  75. package/server/routes/dispatch-routes.ts +275 -0
  76. package/server/routes/git-routes.ts +112 -0
  77. package/server/routes/scope-routes.ts +262 -0
  78. package/server/routes/sprint-routes.ts +142 -0
  79. package/server/routes/version-routes.ts +156 -0
  80. package/server/routes/workflow-routes.ts +198 -0
  81. package/server/schema.ts +90 -0
  82. package/server/services/batch-orchestrator.ts +286 -0
  83. package/server/services/claude-session-service.ts +441 -0
  84. package/server/services/config-service.ts +151 -0
  85. package/server/services/deploy-service.ts +98 -0
  86. package/server/services/event-service.ts +98 -0
  87. package/server/services/gate-service.ts +126 -0
  88. package/server/services/git-service.ts +391 -0
  89. package/server/services/github-service.ts +183 -0
  90. package/server/services/readiness-service.ts +250 -0
  91. package/server/services/scope-cache.ts +81 -0
  92. package/server/services/scope-service.ts +476 -0
  93. package/server/services/sprint-orchestrator.ts +361 -0
  94. package/server/services/sprint-service.ts +415 -0
  95. package/server/services/workflow-service.ts +461 -0
  96. package/server/utils/cc-hooks-parser.ts +70 -0
  97. package/server/utils/dispatch-utils.ts +395 -0
  98. package/server/utils/logger.ts +109 -0
  99. package/server/utils/terminal-launcher.ts +462 -0
  100. package/server/utils/worktree-manager.ts +104 -0
  101. package/server/watchers/event-watcher.ts +100 -0
  102. package/server/watchers/scope-watcher.ts +38 -0
  103. package/shared/api-types.ts +20 -0
  104. package/shared/default-workflow.json +616 -0
  105. package/shared/workflow-config.ts +170 -0
  106. package/shared/workflow-engine.ts +427 -0
  107. package/src/App.tsx +33 -0
  108. package/src/components/AgentBadge.tsx +40 -0
  109. package/src/components/BatchPreflightModal.tsx +115 -0
  110. package/src/components/CardDisplayToggle.tsx +74 -0
  111. package/src/components/ColumnHeaderActions.tsx +55 -0
  112. package/src/components/ColumnMenu.tsx +99 -0
  113. package/src/components/DeployHistory.tsx +141 -0
  114. package/src/components/DispatchModal.tsx +164 -0
  115. package/src/components/DispatchPopover.tsx +139 -0
  116. package/src/components/DragOverlay.tsx +25 -0
  117. package/src/components/DriftSidebar.tsx +140 -0
  118. package/src/components/EnvironmentStrip.tsx +88 -0
  119. package/src/components/ErrorBoundary.tsx +62 -0
  120. package/src/components/FilterChip.tsx +105 -0
  121. package/src/components/GateIndicator.tsx +33 -0
  122. package/src/components/IdeaDetailModal.tsx +190 -0
  123. package/src/components/IdeaFormDialog.tsx +113 -0
  124. package/src/components/KanbanColumn.tsx +201 -0
  125. package/src/components/MarkdownRenderer.tsx +114 -0
  126. package/src/components/NeonGrid.tsx +128 -0
  127. package/src/components/PromotionQueue.tsx +89 -0
  128. package/src/components/ScopeCard.tsx +234 -0
  129. package/src/components/ScopeDetailModal.tsx +255 -0
  130. package/src/components/ScopeFilterBar.tsx +152 -0
  131. package/src/components/SearchInput.tsx +102 -0
  132. package/src/components/SessionPanel.tsx +335 -0
  133. package/src/components/SprintContainer.tsx +303 -0
  134. package/src/components/SprintDependencyDialog.tsx +78 -0
  135. package/src/components/SprintPreflightModal.tsx +138 -0
  136. package/src/components/StatusBar.tsx +168 -0
  137. package/src/components/SwimCell.tsx +67 -0
  138. package/src/components/SwimLaneRow.tsx +94 -0
  139. package/src/components/SwimlaneBoardView.tsx +108 -0
  140. package/src/components/VersionBadge.tsx +139 -0
  141. package/src/components/ViewModeSelector.tsx +114 -0
  142. package/src/components/config/AgentChip.tsx +53 -0
  143. package/src/components/config/AgentCreateDialog.tsx +321 -0
  144. package/src/components/config/AgentEditor.tsx +175 -0
  145. package/src/components/config/DirectoryTree.tsx +582 -0
  146. package/src/components/config/FileEditor.tsx +550 -0
  147. package/src/components/config/HookChip.tsx +50 -0
  148. package/src/components/config/StageCard.tsx +198 -0
  149. package/src/components/config/TransitionZone.tsx +173 -0
  150. package/src/components/config/UnifiedWorkflowPipeline.tsx +216 -0
  151. package/src/components/config/WorkflowPipeline.tsx +161 -0
  152. package/src/components/source-control/BranchList.tsx +93 -0
  153. package/src/components/source-control/BranchPanel.tsx +105 -0
  154. package/src/components/source-control/CommitLog.tsx +100 -0
  155. package/src/components/source-control/CommitRow.tsx +47 -0
  156. package/src/components/source-control/GitHubPanel.tsx +110 -0
  157. package/src/components/source-control/GitHubSetupGuide.tsx +52 -0
  158. package/src/components/source-control/GitOverviewBar.tsx +101 -0
  159. package/src/components/source-control/PullRequestList.tsx +69 -0
  160. package/src/components/source-control/WorktreeList.tsx +80 -0
  161. package/src/components/ui/badge.tsx +41 -0
  162. package/src/components/ui/button.tsx +55 -0
  163. package/src/components/ui/card.tsx +78 -0
  164. package/src/components/ui/dialog.tsx +94 -0
  165. package/src/components/ui/popover.tsx +33 -0
  166. package/src/components/ui/scroll-area.tsx +54 -0
  167. package/src/components/ui/separator.tsx +28 -0
  168. package/src/components/ui/tabs.tsx +52 -0
  169. package/src/components/ui/toggle-switch.tsx +35 -0
  170. package/src/components/ui/tooltip.tsx +27 -0
  171. package/src/components/workflow/AddEdgeDialog.tsx +217 -0
  172. package/src/components/workflow/AddListDialog.tsx +201 -0
  173. package/src/components/workflow/ChecklistEditor.tsx +239 -0
  174. package/src/components/workflow/CommandPrefixManager.tsx +118 -0
  175. package/src/components/workflow/ConfigSettingsPanel.tsx +189 -0
  176. package/src/components/workflow/DirectionSelector.tsx +133 -0
  177. package/src/components/workflow/DispatchConfigPanel.tsx +180 -0
  178. package/src/components/workflow/EdgeDetailPanel.tsx +236 -0
  179. package/src/components/workflow/EdgePropertyEditor.tsx +251 -0
  180. package/src/components/workflow/EditToolbar.tsx +138 -0
  181. package/src/components/workflow/HookDetailPanel.tsx +250 -0
  182. package/src/components/workflow/HookExecutionLog.tsx +24 -0
  183. package/src/components/workflow/HookSourceModal.tsx +129 -0
  184. package/src/components/workflow/HooksDashboard.tsx +363 -0
  185. package/src/components/workflow/ListPropertyEditor.tsx +251 -0
  186. package/src/components/workflow/MigrationPreviewDialog.tsx +237 -0
  187. package/src/components/workflow/MovementRulesPanel.tsx +188 -0
  188. package/src/components/workflow/NodeDetailPanel.tsx +245 -0
  189. package/src/components/workflow/PresetSelector.tsx +414 -0
  190. package/src/components/workflow/SkillCommandBuilder.tsx +174 -0
  191. package/src/components/workflow/WorkflowEdgeComponent.tsx +145 -0
  192. package/src/components/workflow/WorkflowNode.tsx +147 -0
  193. package/src/components/workflow/graphLayout.ts +186 -0
  194. package/src/components/workflow/mergeHooks.ts +85 -0
  195. package/src/components/workflow/useEditHistory.ts +88 -0
  196. package/src/components/workflow/useWorkflowEditor.ts +262 -0
  197. package/src/components/workflow/validateConfig.ts +70 -0
  198. package/src/hooks/useActiveDispatches.ts +198 -0
  199. package/src/hooks/useBoardSettings.ts +170 -0
  200. package/src/hooks/useCardDisplay.ts +57 -0
  201. package/src/hooks/useCcHooks.ts +24 -0
  202. package/src/hooks/useConfigTree.ts +51 -0
  203. package/src/hooks/useEnforcementRules.ts +46 -0
  204. package/src/hooks/useEvents.ts +59 -0
  205. package/src/hooks/useFileEditor.ts +165 -0
  206. package/src/hooks/useGates.ts +57 -0
  207. package/src/hooks/useIdeaActions.ts +53 -0
  208. package/src/hooks/useKanbanDnd.ts +410 -0
  209. package/src/hooks/useOrbitalConfig.ts +54 -0
  210. package/src/hooks/usePipeline.ts +47 -0
  211. package/src/hooks/usePipelineData.ts +338 -0
  212. package/src/hooks/useReconnect.ts +25 -0
  213. package/src/hooks/useScopeFilters.ts +125 -0
  214. package/src/hooks/useScopeSessions.ts +44 -0
  215. package/src/hooks/useScopes.ts +67 -0
  216. package/src/hooks/useSearch.ts +67 -0
  217. package/src/hooks/useSettings.tsx +187 -0
  218. package/src/hooks/useSocket.ts +25 -0
  219. package/src/hooks/useSourceControl.ts +105 -0
  220. package/src/hooks/useSprintPreflight.ts +55 -0
  221. package/src/hooks/useSprints.ts +154 -0
  222. package/src/hooks/useStatusBarHighlight.ts +18 -0
  223. package/src/hooks/useSwimlaneBoardSettings.ts +104 -0
  224. package/src/hooks/useTheme.ts +9 -0
  225. package/src/hooks/useTransitionReadiness.ts +53 -0
  226. package/src/hooks/useVersion.ts +155 -0
  227. package/src/hooks/useViolations.ts +65 -0
  228. package/src/hooks/useWorkflow.tsx +125 -0
  229. package/src/hooks/useZoomModifier.ts +19 -0
  230. package/src/index.css +797 -0
  231. package/src/layouts/DashboardLayout.tsx +113 -0
  232. package/src/lib/collisionDetection.ts +20 -0
  233. package/src/lib/scope-fields.ts +61 -0
  234. package/src/lib/swimlane.ts +146 -0
  235. package/src/lib/utils.ts +15 -0
  236. package/src/main.tsx +19 -0
  237. package/src/socket.ts +11 -0
  238. package/src/types/index.ts +497 -0
  239. package/src/views/AgentFeed.tsx +339 -0
  240. package/src/views/DeployPipeline.tsx +59 -0
  241. package/src/views/EnforcementView.tsx +378 -0
  242. package/src/views/PrimitivesConfig.tsx +500 -0
  243. package/src/views/QualityGates.tsx +1012 -0
  244. package/src/views/ScopeBoard.tsx +454 -0
  245. package/src/views/SessionTimeline.tsx +516 -0
  246. package/src/views/Settings.tsx +183 -0
  247. package/src/views/SourceControl.tsx +95 -0
  248. package/src/views/WorkflowVisualizer.tsx +382 -0
  249. package/tailwind.config.js +161 -0
  250. package/templates/agents/AUTO-INVOKE.md +180 -0
  251. package/templates/agents/CONFLICT-RESOLUTION.md +128 -0
  252. package/templates/agents/QUICK-REFERENCE.md +122 -0
  253. package/templates/agents/README.md +188 -0
  254. package/templates/agents/SKILL-TRIGGERS.md +100 -0
  255. package/templates/agents/blue-team/frontend-designer.md +424 -0
  256. package/templates/agents/green-team/architect.md +526 -0
  257. package/templates/agents/green-team/rules-enforcer.md +131 -0
  258. package/templates/agents/red-team/attacker-learned.md +24 -0
  259. package/templates/agents/red-team/attacker.md +486 -0
  260. package/templates/agents/red-team/chaos.md +548 -0
  261. package/templates/agents/reference/component-registry.md +82 -0
  262. package/templates/agents/workflows/full-mode.md +218 -0
  263. package/templates/agents/workflows/quick-mode.md +118 -0
  264. package/templates/agents/workflows/security-mode.md +283 -0
  265. package/templates/anti-patterns/dangerous-shortcuts.md +427 -0
  266. package/templates/config/agent-triggers.json +92 -0
  267. package/templates/hooks/agent-team-gate.sh +31 -0
  268. package/templates/hooks/agent-trigger.sh +97 -0
  269. package/templates/hooks/block-push.sh +66 -0
  270. package/templates/hooks/block-workarounds.sh +61 -0
  271. package/templates/hooks/blocker-check.sh +28 -0
  272. package/templates/hooks/completion-checklist.sh +28 -0
  273. package/templates/hooks/decision-capture.sh +15 -0
  274. package/templates/hooks/dependency-check.sh +27 -0
  275. package/templates/hooks/end-session.sh +31 -0
  276. package/templates/hooks/exploration-logger.sh +37 -0
  277. package/templates/hooks/files-changed-summary.sh +37 -0
  278. package/templates/hooks/get-session-id.sh +49 -0
  279. package/templates/hooks/git-commit-guard.sh +34 -0
  280. package/templates/hooks/init-session.sh +93 -0
  281. package/templates/hooks/orbital-emit.sh +79 -0
  282. package/templates/hooks/orbital-report-deploy.sh +78 -0
  283. package/templates/hooks/orbital-report-gates.sh +40 -0
  284. package/templates/hooks/orbital-report-violation.sh +36 -0
  285. package/templates/hooks/orbital-scope-update.sh +53 -0
  286. package/templates/hooks/phase-verify-reminder.sh +26 -0
  287. package/templates/hooks/review-gate-check.sh +82 -0
  288. package/templates/hooks/scope-commit-logger.sh +37 -0
  289. package/templates/hooks/scope-create-cleanup.sh +36 -0
  290. package/templates/hooks/scope-create-gate.sh +80 -0
  291. package/templates/hooks/scope-create-tracker.sh +17 -0
  292. package/templates/hooks/scope-file-sync.sh +53 -0
  293. package/templates/hooks/scope-gate.sh +35 -0
  294. package/templates/hooks/scope-helpers.sh +188 -0
  295. package/templates/hooks/scope-lifecycle-gate.sh +139 -0
  296. package/templates/hooks/scope-prepare.sh +244 -0
  297. package/templates/hooks/scope-transition.sh +172 -0
  298. package/templates/hooks/session-enforcer.sh +143 -0
  299. package/templates/hooks/time-tracker.sh +33 -0
  300. package/templates/lessons-learned.md +15 -0
  301. package/templates/orbital.config.json +35 -0
  302. package/templates/presets/development.json +42 -0
  303. package/templates/presets/gitflow.json +712 -0
  304. package/templates/presets/minimal.json +23 -0
  305. package/templates/quick/rules.md +218 -0
  306. package/templates/scopes/_template.md +255 -0
  307. package/templates/settings-hooks.json +98 -0
  308. package/templates/skills/git-commit/SKILL.md +85 -0
  309. package/templates/skills/git-dev/SKILL.md +99 -0
  310. package/templates/skills/git-hotfix/SKILL.md +223 -0
  311. package/templates/skills/git-main/SKILL.md +84 -0
  312. package/templates/skills/git-production/SKILL.md +165 -0
  313. package/templates/skills/git-staging/SKILL.md +112 -0
  314. package/templates/skills/scope-create/SKILL.md +81 -0
  315. package/templates/skills/scope-fix-review/SKILL.md +168 -0
  316. package/templates/skills/scope-implement/SKILL.md +110 -0
  317. package/templates/skills/scope-post-review/SKILL.md +144 -0
  318. package/templates/skills/scope-pre-review/SKILL.md +211 -0
  319. package/templates/skills/scope-verify/SKILL.md +201 -0
  320. package/templates/skills/session-init/SKILL.md +62 -0
  321. package/templates/skills/session-resume/SKILL.md +201 -0
  322. package/templates/skills/test-checks/SKILL.md +171 -0
  323. package/templates/skills/test-code-review/SKILL.md +252 -0
  324. package/tsconfig.json +25 -0
  325. package/vite.config.ts +38 -0
@@ -0,0 +1,172 @@
1
+ #!/bin/bash
2
+ # scope-transition.sh — Centralized scope lifecycle transition utility
3
+ #
4
+ # Moves scope files between lifecycle directories and updates frontmatter.
5
+ #
6
+ # Usage:
7
+ # scope-transition.sh <direction|--from STATUS --to STATUS> [--scope ID] [--session UUID]
8
+ #
9
+ # Directions (backward-compat aliases):
10
+ # to-dev — completed → dev (called by /git-dev skill)
11
+ # to-staging — dev → staging (on push/PR to staging)
12
+ # to-production — staging → production (on push/PR to main)
13
+ #
14
+ # Generic form (manifest-driven):
15
+ # --from completed --to dev
16
+ # --from dev --to staging
17
+ #
18
+ # Options:
19
+ # --scope ID — Transition a specific scope by numeric ID
20
+ # --session UUID — Session UUID to record (default: from get-session-id.sh)
21
+ #
22
+ # Exit codes:
23
+ # 0 — Success (or nothing to transition)
24
+ # 1 — Invalid arguments
25
+
26
+ set -euo pipefail
27
+
28
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
29
+ source "$SCRIPT_DIR/scope-helpers.sh"
30
+
31
+ # ─── Parse arguments ───
32
+ DIRECTION=""
33
+ SCOPE_ID=""
34
+ SESSION_UUID=""
35
+ FROM_STATUS=""
36
+ TO_STATUS=""
37
+
38
+ while [ $# -gt 0 ]; do
39
+ case "$1" in
40
+ to-dev|to-staging|to-production) DIRECTION="$1" ;;
41
+ --from) FROM_STATUS="$2"; shift ;;
42
+ --to) TO_STATUS="$2"; shift ;;
43
+ --scope) SCOPE_ID="$2"; shift ;;
44
+ --session) SESSION_UUID="$2"; shift ;;
45
+ *) echo "Unknown argument: $1" >&2; exit 1 ;;
46
+ esac
47
+ shift
48
+ done
49
+
50
+ # ─── Resolve direction alias or --from/--to ───
51
+ if [ -n "$DIRECTION" ]; then
52
+ # Resolve via WORKFLOW_DIRECTION_ALIASES (from manifest or fallback)
53
+ RESOLVED=false
54
+ for alias_entry in "${WORKFLOW_DIRECTION_ALIASES[@]}"; do
55
+ IFS=':' read -r alias_name alias_from alias_to alias_skey <<< "$alias_entry"
56
+ if [ "$alias_name" = "$DIRECTION" ]; then
57
+ SOURCE_STATUS="$alias_from"
58
+ TARGET_STATUS="$alias_to"
59
+ SESSION_KEY="$alias_skey"
60
+ RESOLVED=true
61
+ break
62
+ fi
63
+ done
64
+
65
+ if [ "$RESOLVED" = false ]; then
66
+ VALID_ALIASES=""
67
+ for a in "${WORKFLOW_DIRECTION_ALIASES[@]}"; do
68
+ IFS=':' read -r aname _ _ _ <<< "$a"
69
+ VALID_ALIASES="${VALID_ALIASES:+$VALID_ALIASES, }$aname"
70
+ done
71
+ echo "ERROR: Unknown direction '$DIRECTION'." >&2
72
+ echo " Valid directions: ${VALID_ALIASES:-none (use --from STATUS --to STATUS instead)}" >&2
73
+ echo " Valid statuses: $WORKFLOW_STATUSES" >&2
74
+ exit 1
75
+ fi
76
+ elif [ -n "$FROM_STATUS" ] && [ -n "$TO_STATUS" ]; then
77
+ # Generic --from/--to: look up session key from WORKFLOW_EDGES
78
+ SOURCE_STATUS="$FROM_STATUS"
79
+ TARGET_STATUS="$TO_STATUS"
80
+ SESSION_KEY=""
81
+ for edge_entry in "${WORKFLOW_EDGES[@]}"; do
82
+ IFS=':' read -r edge_from edge_to edge_skey <<< "$edge_entry"
83
+ if [ "$edge_from" = "$SOURCE_STATUS" ] && [ "$edge_to" = "$TARGET_STATUS" ]; then
84
+ SESSION_KEY="$edge_skey"
85
+ break
86
+ fi
87
+ done
88
+ else
89
+ echo "Usage: scope-transition.sh <direction|--from STATUS --to STATUS> [--scope ID] [--session UUID]" >&2
90
+ echo "Directions: to-dev, to-staging, to-production (backward-compat aliases)" >&2
91
+ echo "Generic: --from completed --to dev (manifest-driven)" >&2
92
+ exit 1
93
+ fi
94
+
95
+ # ─── File lock (flock-based, no TOCTOU race) ───
96
+ LOCK_FILE="/tmp/orbital-scope-${SCOPE_ID:-all}.flock"
97
+ exec 200>"$LOCK_FILE"
98
+ if ! flock -n -x 200 2>/dev/null; then
99
+ echo "Scope ${SCOPE_ID:-all} locked by another process" >&2; exit 0
100
+ fi
101
+ trap 'rm -f "$LOCK_FILE" 2>/dev/null' EXIT
102
+
103
+ SOURCE_DIR="$SCOPE_PROJECT_DIR/scopes/$SOURCE_STATUS"
104
+ TARGET_DIR="$SCOPE_PROJECT_DIR/scopes/$TARGET_STATUS"
105
+
106
+ # ─── Resolve session UUID ───
107
+ if [ -z "$SESSION_UUID" ]; then
108
+ SESSION_UUID=$("$SCRIPT_DIR/get-session-id.sh" 2>/dev/null || true)
109
+ fi
110
+
111
+ # ─── Find matching scopes ───
112
+ SCOPES_TO_TRANSITION=""
113
+
114
+ if [ -n "$SCOPE_ID" ]; then
115
+ # Specific scope requested
116
+ SCOPE_FILE=$(find_scope_by_id "$SCOPE_ID")
117
+ if [ -n "$SCOPE_FILE" ]; then
118
+ FILE_STATUS=$(get_frontmatter "$SCOPE_FILE" "status")
119
+ if [ "$FILE_STATUS" = "$SOURCE_STATUS" ]; then
120
+ SCOPES_TO_TRANSITION="$SCOPE_FILE"
121
+ fi
122
+ fi
123
+ else
124
+ # Find all scopes in source directory with matching status
125
+ SCOPES_TO_TRANSITION=$(find_scopes_by_status "$SOURCE_STATUS" "$SOURCE_DIR" 2>/dev/null || true)
126
+ fi
127
+
128
+ if [ -z "$SCOPES_TO_TRANSITION" ]; then
129
+ exit 0
130
+ fi
131
+
132
+ # ─── Transition each scope ───
133
+ mkdir -p "$TARGET_DIR"
134
+ TRANSITIONED=0
135
+ TODAY=$(date +%Y-%m-%d)
136
+
137
+ for scope_file in $SCOPES_TO_TRANSITION; do
138
+ [ -f "$scope_file" ] || continue
139
+ FILENAME=$(basename "$scope_file")
140
+ SCOPE_TITLE=$(get_frontmatter "$scope_file" "title")
141
+ SCOPE_NUM=$(get_frontmatter "$scope_file" "id")
142
+
143
+ # 1. Update status in frontmatter
144
+ set_frontmatter "$scope_file" "status" "$TARGET_STATUS"
145
+
146
+ # 2. Update the date
147
+ set_frontmatter "$scope_file" "updated" "$TODAY"
148
+
149
+ # 2b. Record baseCommit when entering implementing
150
+ if [ "$TARGET_STATUS" = "implementing" ]; then
151
+ BASE_SHA=$(git rev-parse HEAD 2>/dev/null)
152
+ [ -n "$BASE_SHA" ] && set_frontmatter "$scope_file" "baseCommit" "$BASE_SHA"
153
+ fi
154
+
155
+ # 3. Record session UUID if available
156
+ if [ -n "$SESSION_UUID" ] && [ -n "$SESSION_KEY" ]; then
157
+ append_session_uuid "$scope_file" "$SESSION_KEY" "$SESSION_UUID"
158
+ fi
159
+
160
+ # 4. Move file to target directory (scopes are gitignored, use plain mv)
161
+ mv "$scope_file" "$TARGET_DIR/$FILENAME"
162
+
163
+ # 5. Print summary
164
+ echo " Scope $SCOPE_NUM ($FILENAME): $SOURCE_STATUS → $TARGET_STATUS"
165
+ TRANSITIONED=$((TRANSITIONED + 1))
166
+ done
167
+
168
+ if [ "$TRANSITIONED" -gt 0 ]; then
169
+ echo " Transitioned $TRANSITIONED scope(s) $SOURCE_STATUS → $TARGET_STATUS"
170
+ # Invalidate active scope cache since status changed
171
+ invalidate_active_scope_cache
172
+ fi
@@ -0,0 +1,143 @@
1
+ #!/bin/bash
2
+ # session-enforcer.sh — PreToolUse:Edit|Write hook
3
+ #
4
+ # Hard-blocks scope status transitions when the CURRENT session's UUID
5
+ # is not recorded in the scope's sessions.<requiredKey> array.
6
+ #
7
+ # Handles both Edit (old_string/new_string) and Write (full content) tools.
8
+ # Gracefully allows legacy scopes that don't have a sessions: block at all.
9
+ set -e
10
+
11
+ INPUT=$(cat)
12
+ # Validate JSON input
13
+ echo "$INPUT" | jq empty 2>/dev/null || exit 0
14
+
15
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
16
+
17
+ # Extract the file being edited/written
18
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
19
+ [ -z "$FILE_PATH" ] && exit 0
20
+
21
+ # Only enforce on scope files (bash case * matches / in patterns)
22
+ case "$FILE_PATH" in
23
+ */scopes/*.md) ;;
24
+ *) exit 0 ;;
25
+ esac
26
+
27
+ # ─── Determine tool type and extract statuses ───
28
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // "Edit"')
29
+
30
+ if [ "$TOOL_NAME" = "Write" ]; then
31
+ # Write tool: compare existing file on disk vs new content
32
+ if [ ! -f "$FILE_PATH" ]; then
33
+ # New file creation — no status transition to enforce
34
+ exit 0
35
+ fi
36
+ OLD_STATUS=$(sed -n '/^---$/,/^---$/p' "$FILE_PATH" | grep -oE '^status:\s*\S+' | head -1 | sed 's/status:[[:space:]]*//')
37
+ NEW_CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // empty')
38
+ [ -z "$NEW_CONTENT" ] && exit 0
39
+ TARGET_STATUS=$(echo "$NEW_CONTENT" | sed -n '/^---$/,/^---$/p' | grep -oE '^status:\s*\S+' | head -1 | sed 's/status:[[:space:]]*//')
40
+ else
41
+ # Edit tool: compare old_string vs new_string
42
+ NEW_STRING=$(echo "$INPUT" | jq -r '.tool_input.new_string // empty')
43
+ [ -z "$NEW_STRING" ] && exit 0
44
+ TARGET_STATUS=$(echo "$NEW_STRING" | grep -oE 'status:\s*\S+' | head -1 | sed 's/status:[[:space:]]*//')
45
+ OLD_STRING=$(echo "$INPUT" | jq -r '.tool_input.old_string // empty')
46
+ OLD_STATUS=$(echo "$OLD_STRING" | grep -oE 'status:\s*\S+' | head -1 | sed 's/status:[[:space:]]*//')
47
+ fi
48
+
49
+ # No status in the edit/write — not a status transition
50
+ [ -z "$TARGET_STATUS" ] && exit 0
51
+
52
+ # If status isn't changing, allow the edit
53
+ [ "$TARGET_STATUS" = "$OLD_STATUS" ] && exit 0
54
+
55
+ # ─── Map target status to required session key ───
56
+ # This matrix matches WHO actually makes each transition:
57
+ # - createScope: /scope-create → planning
58
+ # - reviewScope: /scope-pre-review → backlog
59
+ # - implementScope: /scope-implement → implementing
60
+ # - verifyScope: /scope-post-review → review (different session required)
61
+ # - commit: /git-commit → completed
62
+ # - prDev: /git-dev → dev
63
+ # - pushToStaging: /git-staging → staging
64
+ # - pushToProduction: /git-production → production
65
+ # ─── Source workflow manifest for edge-based session key lookup ───
66
+ MANIFEST_FILE="${PROJECT_DIR}/.claude/config/workflow-manifest.sh"
67
+ REQUIRED_KEY=""
68
+
69
+ if [ -f "$MANIFEST_FILE" ]; then
70
+ source "$MANIFEST_FILE"
71
+ # Look up session key from WORKFLOW_EDGES: "from:to:sessionKey"
72
+ for edge_entry in "${WORKFLOW_EDGES[@]}"; do
73
+ IFS=':' read -r _from edge_to edge_skey <<< "$edge_entry"
74
+ if [ "$edge_to" = "$TARGET_STATUS" ] && [ -n "$edge_skey" ]; then
75
+ REQUIRED_KEY="$edge_skey"
76
+ break
77
+ fi
78
+ done
79
+ # No session key for this status — not enforced
80
+ [ -z "$REQUIRED_KEY" ] && exit 0
81
+ else
82
+ # Fallback: hardcoded keys (don't silently disable enforcement)
83
+ case "$TARGET_STATUS" in
84
+ planning) REQUIRED_KEY="createScope" ;;
85
+ backlog) REQUIRED_KEY="reviewScope" ;;
86
+ implementing) REQUIRED_KEY="implementScope" ;;
87
+ review) REQUIRED_KEY="reviewGate" ;;
88
+ completed) REQUIRED_KEY="commit" ;;
89
+ dev) REQUIRED_KEY="prDev" ;;
90
+ staging) REQUIRED_KEY="pushToStaging" ;;
91
+ production) REQUIRED_KEY="pushToProduction" ;;
92
+ main) REQUIRED_KEY="pushToMain" ;;
93
+ *) exit 0 ;;
94
+ esac
95
+ fi
96
+
97
+ # Get current session ID from hook stdin
98
+ SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty')
99
+ if [ -z "$SESSION_ID" ]; then
100
+ # If we can't identify the session, allow (graceful degradation)
101
+ exit 0
102
+ fi
103
+
104
+ # ─── Record session UUID on scope for this transition ───
105
+ # This ensures the UUID is present even for direct Edit transitions
106
+ # (scope-lifecycle-gate.sh only records on Bash/git commands)
107
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
108
+ source "$SCRIPT_DIR/scope-helpers.sh" 2>/dev/null || true
109
+ if [ -f "$FILE_PATH" ] && type append_session_uuid &>/dev/null; then
110
+ append_session_uuid "$FILE_PATH" "$REQUIRED_KEY" "$SESSION_ID"
111
+ fi
112
+
113
+ # ─── Read scope file and check sessions block ───
114
+ # For Write tool, check the FILE ON DISK (sessions were written by the
115
+ # scope-lifecycle-gate hook before this call). For Edit tool, also check the file on disk.
116
+ CHECK_FILE="$FILE_PATH"
117
+ if [ ! -f "$CHECK_FILE" ]; then
118
+ exit 0
119
+ fi
120
+
121
+ # Check if sessions: block exists at all in frontmatter
122
+ FRONTMATTER=$(sed -n '/^---$/,/^---$/p' "$CHECK_FILE")
123
+ if ! echo "$FRONTMATTER" | grep -q '^sessions:'; then
124
+ # Legacy scope without sessions field — allow (backwards compatible)
125
+ exit 0
126
+ fi
127
+
128
+ # Look for the specific session key (handles both 2-space and 4-space indent)
129
+ SESSIONS_LINE=$(echo "$FRONTMATTER" | grep "^[[:space:]]*$REQUIRED_KEY:" | head -1)
130
+
131
+ if [ -z "$SESSIONS_LINE" ]; then
132
+ # sessions: block exists but this key is missing — session not recorded
133
+ echo "MUST_BLOCK: Session $SESSION_ID not found in sessions.$REQUIRED_KEY. The scope-lifecycle-gate hook should have recorded this — check .claude/hooks/scope-lifecycle-gate.sh. Format: sessions use inline YAML arrays, e.g. $REQUIRED_KEY: [$SESSION_ID]" >&2
134
+ exit 2
135
+ fi
136
+
137
+ # Check if our UUID appears in the line (fixed-string match, not regex)
138
+ if echo "$SESSIONS_LINE" | grep -qF "$SESSION_ID"; then
139
+ exit 0
140
+ fi
141
+
142
+ echo "MUST_BLOCK: Session $SESSION_ID not found in sessions.$REQUIRED_KEY. The scope-lifecycle-gate hook should have recorded this — check .claude/hooks/scope-lifecycle-gate.sh. Format: sessions use inline YAML arrays — append UUID to existing array, e.g. $REQUIRED_KEY: [existing-uuid, $SESSION_ID]" >&2
143
+ exit 2
@@ -0,0 +1,33 @@
1
+ #!/bin/bash
2
+ # time-tracker.sh — Emit scope status transition events to Orbital dashboard
3
+ # Trigger: PostToolUse:Edit (scope status changes)
4
+ # Nudge-style: always exits 0
5
+ set -e
6
+
7
+ INPUT=$(cat)
8
+ echo "$INPUT" | jq empty 2>/dev/null || exit 0
9
+
10
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
11
+ NEW_STRING=$(echo "$INPUT" | jq -r '.tool_input.new_string // empty')
12
+
13
+ source "$(dirname "$0")/scope-helpers.sh"
14
+ is_scope_file "$FILE_PATH" || exit 0
15
+
16
+ # Detect status transitions
17
+ STATUS=""
18
+ echo "$NEW_STRING" | grep -qiE "status:.*planning" && STATUS="planning"
19
+ echo "$NEW_STRING" | grep -qiE "status:.*backlog" && STATUS="backlog"
20
+ echo "$NEW_STRING" | grep -qiE "status:.*implementing" && STATUS="implementing"
21
+ echo "$NEW_STRING" | grep -qiE "status:.*complete" && STATUS="complete"
22
+ echo "$NEW_STRING" | grep -qiE "🔄.*In Progress" && STATUS="phase_started"
23
+ echo "$NEW_STRING" | grep -qiE "✅.*Done" && STATUS="phase_done"
24
+ [ -z "$STATUS" ] && exit 0
25
+
26
+ SCOPE_NAME=$(basename "$FILE_PATH" .md)
27
+
28
+ # Emit SCOPE_TRANSITION event to Orbital dashboard
29
+ HOOK_DIR="$(dirname "$0")"
30
+ DATA=$(jq -n --arg from "" --arg to "$STATUS" --arg scope_name "$SCOPE_NAME" '{from: $from, to: $to, scope_name: $scope_name}')
31
+ "$HOOK_DIR/orbital-emit.sh" SCOPE_TRANSITION "$DATA"
32
+
33
+ exit 0
@@ -0,0 +1,15 @@
1
+ # Lessons Learned
2
+
3
+ Record insights from debugging sessions, incidents, and post-mortems.
4
+
5
+ ## Format
6
+
7
+ ### YYYY-MM-DD: Title
8
+ **Context**: What happened
9
+ **Root cause**: Why it happened
10
+ **Lesson**: What to do differently
11
+ **Prevention**: How to avoid in future
12
+
13
+ ---
14
+
15
+ <!-- Add entries above this line -->
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "https://orbital-command.dev/schemas/orbital.config.schema.json",
3
+ "projectName": "My Project",
4
+ "scopesDir": "scopes",
5
+ "eventsDir": ".claude/orbital-events",
6
+ "dbDir": ".claude/orbital",
7
+ "configDir": ".claude/config",
8
+ "serverPort": 4444,
9
+ "clientPort": 4445,
10
+ "terminal": {
11
+ "adapter": "auto",
12
+ "profilePrefix": "Orbital"
13
+ },
14
+ "claude": {
15
+ "executable": "claude",
16
+ "flags": ["--dangerously-skip-permissions"]
17
+ },
18
+ "commands": {
19
+ "typeCheck": null,
20
+ "lint": null,
21
+ "build": null,
22
+ "test": null,
23
+ "validateTemplates": null,
24
+ "validateDocs": null,
25
+ "checkRules": null
26
+ },
27
+ "categories": ["feature", "bugfix", "refactor", "infrastructure", "docs"],
28
+ "agents": [
29
+ { "id": "attacker", "label": "Attacker", "emoji": "\ud83d\udde1\ufe0f", "color": "#ff1744" },
30
+ { "id": "chaos", "label": "Chaos", "emoji": "\ud83d\udca5", "color": "#F97316" },
31
+ { "id": "frontend-designer", "label": "Frontend Designer", "emoji": "\ud83c\udfa8", "color": "#EC4899" },
32
+ { "id": "architect", "label": "Architect", "emoji": "\ud83c\udfd7\ufe0f", "color": "#536dfe" },
33
+ { "id": "rules-enforcer", "label": "Rules Enforcer", "emoji": "\ud83d\udccb", "color": "#6B7280" }
34
+ ]
35
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "Development",
3
+ "version": 1,
4
+ "branchingMode": "trunk",
5
+ "lists": [
6
+ { "id": "backlog", "label": "Backlog", "order": 0, "group": "planning", "color": "230 99% 67%", "hex": "#536dfe", "hasDirectory": true, "isEntryPoint": true },
7
+ { "id": "implementing", "label": "Implementing", "order": 1, "group": "development", "color": "40 100% 50%", "hex": "#ffaa00", "hasDirectory": true, "sessionKey": "implementScope", "activeHooks": ["block-commit-implementing"] },
8
+ { "id": "review", "label": "Review", "order": 2, "group": "development", "color": "263 69% 50%", "hex": "#6b26d9", "hasDirectory": true, "sessionKey": "reviewGate" },
9
+ { "id": "completed", "label": "Completed", "order": 3, "group": "development", "color": "174 70% 42%", "hex": "#20b6aa", "hasDirectory": true, "sessionKey": "commit" },
10
+ { "id": "dev", "label": "Dev", "order": 4, "group": "deploy", "color": "197 100% 63%", "hex": "#42c3ff", "hasDirectory": true, "gitBranch": "dev" }
11
+ ],
12
+ "edges": [
13
+ { "from": "backlog", "to": "implementing", "direction": "forward", "command": "/scope-implement {id}", "confirmLevel": "quick", "label": "Start Implementing", "description": "Opens a Claude session running /scope-implement.", "dispatchOnly": true },
14
+ { "from": "implementing", "to": "review", "direction": "forward", "command": "/scope-post-review {id}", "confirmLevel": "full", "label": "Run Review Gate", "description": "Launches formal review gate.", "dispatchOnly": true },
15
+ { "from": "review", "to": "completed", "direction": "forward", "command": "/git-commit", "confirmLevel": "full", "label": "Commit", "description": "Commits scope work to feature branch.", "dispatchOnly": true },
16
+ { "from": "completed", "to": "dev", "direction": "forward", "command": "/git-dev", "confirmLevel": "full", "label": "Merge to Dev", "description": "Merges feature branch into dev.", "dispatchOnly": true },
17
+ { "from": "review", "to": "implementing", "direction": "backward", "command": null, "confirmLevel": "quick", "label": "Back to Implementing", "description": "Re-opens implementation to address review findings.", "dispatchOnly": false },
18
+ { "from": "completed", "to": "implementing", "direction": "backward", "command": null, "confirmLevel": "quick", "label": "Back to Implementing", "description": "Re-opens implementation to fix issues.", "dispatchOnly": false },
19
+ { "from": "implementing", "to": "backlog", "direction": "backward", "command": null, "confirmLevel": "quick", "label": "Back to Backlog", "description": "Returns scope to backlog.", "dispatchOnly": false, "humanOnly": true }
20
+ ],
21
+ "hooks": [
22
+ {
23
+ "id": "block-commit-implementing",
24
+ "label": "Block Commit (Implementing)",
25
+ "timing": "before",
26
+ "type": "shell",
27
+ "target": ".claude/hooks/block-push.sh",
28
+ "blocking": true,
29
+ "description": "Blocks git commit/add during implementing sessions",
30
+ "category": "guard"
31
+ }
32
+ ],
33
+ "groups": [
34
+ { "id": "planning", "label": "Planning", "order": 0 },
35
+ { "id": "development", "label": "Development", "order": 1 },
36
+ { "id": "deploy", "label": "Deploy", "order": 2 }
37
+ ],
38
+ "eventInference": [],
39
+ "allowedCommandPrefixes": ["/scope-", "/git-", "/test-", "/session-"],
40
+ "terminalStatuses": ["dev"],
41
+ "commitBranchPatterns": "^(dev|feat/|fix/|scope/|chore/)"
42
+ }