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,78 @@
1
+ #!/bin/bash
2
+ # orbital-report-deploy.sh — Report deployment events to Orbital dashboard
3
+ #
4
+ # Usage:
5
+ # orbital-report-deploy.sh <environment> <status> [commit_sha] [branch] [pr_number]
6
+ #
7
+ # Actions:
8
+ # New deployment: orbital-report-deploy.sh staging deploying abc1234 feature/x 42
9
+ # Update status: ORBITAL_DEPLOY_ID=5 orbital-report-deploy.sh staging healthy
10
+ #
11
+ # Environment variables:
12
+ # ORBITAL_DEPLOY_ID — existing deployment ID to update (PATCH instead of POST)
13
+ # ORBITAL_URL — base URL (default: http://localhost:4444)
14
+ #
15
+ # Health check URLs are read from .claude/orbital.config.json under "healthChecks".
16
+ # If not configured, the health check step is skipped.
17
+ #
18
+ # Fails silently if the Orbital server is not running.
19
+ set -e
20
+
21
+ ENVIRONMENT="${1:?Usage: orbital-report-deploy.sh <environment> <status> [commit_sha] [branch] [pr_number]}"
22
+ STATUS="${2:?Usage: orbital-report-deploy.sh <environment> <status> [commit_sha] [branch] [pr_number]}"
23
+ COMMIT_SHA="${3:-}"
24
+ BRANCH="${4:-}"
25
+ PR_NUMBER="${5:-}"
26
+
27
+ ORBITAL_URL="${ORBITAL_URL:-http://localhost:4444}"
28
+
29
+ # Find project root for config lookup
30
+ if [ -n "$CLAUDE_PROJECT_DIR" ]; then
31
+ PROJECT_ROOT="$CLAUDE_PROJECT_DIR"
32
+ else
33
+ PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo ".")
34
+ fi
35
+
36
+ if [ -n "$ORBITAL_DEPLOY_ID" ]; then
37
+ # Update existing deployment — build payload with jq
38
+ JQ_ARGS=(--arg status "$STATUS")
39
+ JQ_EXPR='{status: $status}'
40
+ [ -n "$COMMIT_SHA" ] && JQ_ARGS+=(--arg details "$COMMIT_SHA") && JQ_EXPR='{status: $status, details: $details}'
41
+ PAYLOAD=$(jq -n "${JQ_ARGS[@]}" "$JQ_EXPR")
42
+
43
+ curl --fail --silent --max-time 2 \
44
+ -X PATCH \
45
+ -H "Content-Type: application/json" \
46
+ -d "$PAYLOAD" \
47
+ "$ORBITAL_URL/api/orbital/deployments/$ORBITAL_DEPLOY_ID" > /dev/null 2>&1 || true
48
+ else
49
+ # Create new deployment record — build payload with jq
50
+ JQ_ARGS=(--arg environment "$ENVIRONMENT" --arg status "$STATUS")
51
+ JQ_EXPR='{environment: $environment, status: $status}'
52
+
53
+ [ -n "$COMMIT_SHA" ] && JQ_ARGS+=(--arg commit_sha "$COMMIT_SHA") && JQ_EXPR=$(echo "$JQ_EXPR" | sed 's/}$/, commit_sha: $commit_sha}/')
54
+ [ -n "$BRANCH" ] && JQ_ARGS+=(--arg branch "$BRANCH") && JQ_EXPR=$(echo "$JQ_EXPR" | sed 's/}$/, branch: $branch}/')
55
+ [ -n "$PR_NUMBER" ] && JQ_ARGS+=(--argjson pr_number "$PR_NUMBER") && JQ_EXPR=$(echo "$JQ_EXPR" | sed 's/}$/, pr_number: $pr_number}/')
56
+
57
+ # Read health check URL from orbital.config.json if configured
58
+ HEALTH_URL=""
59
+ if command -v jq >/dev/null 2>&1 && [ -f "$PROJECT_ROOT/.claude/orbital.config.json" ]; then
60
+ HEALTH_URL=$(jq -r ".healthChecks[\"$ENVIRONMENT\"] // empty" "$PROJECT_ROOT/.claude/orbital.config.json" 2>/dev/null)
61
+ fi
62
+ [ -n "$HEALTH_URL" ] && JQ_ARGS+=(--arg health_check_url "$HEALTH_URL") && JQ_EXPR=$(echo "$JQ_EXPR" | sed 's/}$/, health_check_url: $health_check_url}/')
63
+
64
+ PAYLOAD=$(jq -n "${JQ_ARGS[@]}" "$JQ_EXPR")
65
+
66
+ # POST and capture the response to extract deployment ID
67
+ RESPONSE=$(curl --fail --silent --max-time 2 \
68
+ -X POST \
69
+ -H "Content-Type: application/json" \
70
+ -d "$PAYLOAD" \
71
+ "$ORBITAL_URL/api/orbital/deployments" 2>/dev/null) || true
72
+
73
+ # Print the deployment ID for callers to capture
74
+ if [ -n "$RESPONSE" ]; then
75
+ DEPLOY_ID=$(echo "$RESPONSE" | jq -r '.id // empty' 2>/dev/null)
76
+ [ -n "$DEPLOY_ID" ] && echo "$DEPLOY_ID"
77
+ fi
78
+ fi
@@ -0,0 +1,40 @@
1
+ #!/bin/bash
2
+ # orbital-report-gates.sh — Report quality gate results to Orbital dashboard
3
+ #
4
+ # Usage:
5
+ # orbital-report-gates.sh <gate_name> <pass|fail> [duration_ms] [details]
6
+ #
7
+ # Environment variables:
8
+ # ORBITAL_GATE_COMMIT_SHA — commit SHA to tag the run (auto-detected if not set)
9
+ # ORBITAL_GATE_SCOPE_ID — scope ID to associate with (optional)
10
+ # ORBITAL_URL — base URL (default: http://localhost:4444)
11
+ #
12
+ # Fails silently if the Orbital server is not running.
13
+ set -e
14
+
15
+ GATE_NAME="${1:?Usage: orbital-report-gates.sh <gate_name> <pass|fail> [duration_ms] [details]}"
16
+ STATUS="${2:?Usage: orbital-report-gates.sh <gate_name> <pass|fail> [duration_ms] [details]}"
17
+ DURATION_MS="${3:-null}"
18
+ DETAILS="${4:-}"
19
+
20
+ ORBITAL_URL="${ORBITAL_URL:-http://localhost:4444}"
21
+ COMMIT_SHA="${ORBITAL_GATE_COMMIT_SHA:-$(git rev-parse --short HEAD 2>/dev/null || echo "")}"
22
+ SCOPE_ID="${ORBITAL_GATE_SCOPE_ID:-null}"
23
+
24
+ # Build JSON payload using jq for safe escaping
25
+ JQ_ARGS=(--arg gate_name "$GATE_NAME" --arg status "$STATUS")
26
+ JQ_EXPR='{gate_name: $gate_name, status: $status}'
27
+
28
+ [ "$SCOPE_ID" != "null" ] && JQ_ARGS+=(--argjson scope_id "$SCOPE_ID") && JQ_EXPR=$(echo "$JQ_EXPR" | sed 's/}$/, scope_id: $scope_id}/')
29
+ [ "$DURATION_MS" != "null" ] && JQ_ARGS+=(--argjson duration_ms "$DURATION_MS") && JQ_EXPR=$(echo "$JQ_EXPR" | sed 's/}$/, duration_ms: $duration_ms}/')
30
+ [ -n "$COMMIT_SHA" ] && JQ_ARGS+=(--arg commit_sha "$COMMIT_SHA") && JQ_EXPR=$(echo "$JQ_EXPR" | sed 's/}$/, commit_sha: $commit_sha}/')
31
+ [ -n "$DETAILS" ] && JQ_ARGS+=(--arg details "$DETAILS") && JQ_EXPR=$(echo "$JQ_EXPR" | sed 's/}$/, details: $details}/')
32
+
33
+ PAYLOAD=$(jq -n "${JQ_ARGS[@]}" "$JQ_EXPR")
34
+
35
+ # POST to Orbital server — silent fail if not running
36
+ curl --fail --silent --max-time 2 \
37
+ -X POST \
38
+ -H "Content-Type: application/json" \
39
+ -d "$PAYLOAD" \
40
+ "$ORBITAL_URL/api/orbital/gates" > /dev/null 2>&1 || true
@@ -0,0 +1,36 @@
1
+ #!/bin/bash
2
+ # orbital-report-violation.sh — Emit a VIOLATION event to Orbital dashboard
3
+ #
4
+ # Usage:
5
+ # orbital-report-violation.sh <rule_name> [file] [details]
6
+ #
7
+ # Examples:
8
+ # orbital-report-violation.sh "no-any" "src/services/foo.ts" "Found ': any' on line 42"
9
+ # orbital-report-violation.sh "file-size" "src/big.ts" "452 lines (limit 400)"
10
+ # orbital-report-violation.sh "no-console" "" "3 console.log found"
11
+ #
12
+ # Delegates to orbital-emit.sh for file-based event delivery.
13
+ set -e
14
+
15
+ RULE="${1:?Usage: orbital-report-violation.sh <rule_name> [file] [details]}"
16
+ FILE="${2:-}"
17
+ DETAILS="${3:-}"
18
+
19
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
20
+
21
+ # Build JSON data payload using jq for safe escaping
22
+ JQ_ARGS=(--arg rule "$RULE" --arg outcome "detected")
23
+ JQ_EXPR='{rule: $rule, outcome: $outcome}'
24
+
25
+ if [ -n "$FILE" ]; then
26
+ JQ_ARGS+=(--arg file "$FILE")
27
+ JQ_EXPR='{rule: $rule, outcome: $outcome, file: $file}'
28
+ fi
29
+ if [ -n "$DETAILS" ]; then
30
+ JQ_ARGS+=(--arg details "$DETAILS")
31
+ JQ_EXPR=$(echo "$JQ_EXPR" | sed 's/}$/, details: $details}/')
32
+ fi
33
+
34
+ DATA=$(jq -n "${JQ_ARGS[@]}" "$JQ_EXPR")
35
+
36
+ "$HOOK_DIR/orbital-emit.sh" VIOLATION "$DATA"
@@ -0,0 +1,53 @@
1
+ #!/bin/bash
2
+ # orbital-scope-update.sh — Update scope status on the Orbital dashboard
3
+ #
4
+ # Usage:
5
+ # orbital-scope-update SCOPE_ID STATUS
6
+ # orbital-scope-update 78 implementing
7
+ # orbital-scope-update 35,66,70 implementing # bulk update
8
+ #
9
+ # Valid statuses: backlog, team-review, blockers, implementing,
10
+ # testing, gates, code-review, pr-ci, staging, production, done
11
+ #
12
+ # Falls back to file-based event if Orbital server isn't reachable.
13
+ set -e
14
+
15
+ SCOPE_IDS="${1:?Usage: orbital-scope-update SCOPE_ID[,SCOPE_ID,...] STATUS}"
16
+ STATUS="${2:?Usage: orbital-scope-update SCOPE_ID STATUS}"
17
+
18
+ ORBITAL_API="http://localhost:4444/api/orbital"
19
+
20
+ # Try the REST API first (fastest, real-time)
21
+ if command -v curl &>/dev/null; then
22
+ # Check if it's a bulk update (comma-separated IDs)
23
+ if [[ "$SCOPE_IDS" == *","* ]]; then
24
+ # Build bulk JSON payload using jq for safe escaping
25
+ IFS=',' read -ra IDS <<< "$SCOPE_IDS"
26
+ SCOPES_JSON=$(printf '%s\n' "${IDS[@]}" | tr -d ' ' | jq -R 'tonumber' | jq -s --arg status "$STATUS" '[.[] | {id: ., status: $status}]')
27
+ PAYLOAD=$(jq -n --argjson scopes "$SCOPES_JSON" '{scopes: $scopes}')
28
+
29
+ HTTP_CODE=$(curl -s -o /dev/null -w '%{http_code}' -X PATCH \
30
+ -H 'Content-Type: application/json' \
31
+ -d "$PAYLOAD" \
32
+ "$ORBITAL_API/scopes/bulk/status" 2>/dev/null) || true
33
+ else
34
+ PAYLOAD=$(jq -n --arg status "$STATUS" '{status: $status}')
35
+ HTTP_CODE=$(curl -s -o /dev/null -w '%{http_code}' -X PATCH \
36
+ -H 'Content-Type: application/json' \
37
+ -d "$PAYLOAD" \
38
+ "$ORBITAL_API/scopes/$SCOPE_IDS" 2>/dev/null) || true
39
+ fi
40
+
41
+ if [ "$HTTP_CODE" = "200" ]; then
42
+ exit 0
43
+ fi
44
+ fi
45
+
46
+ # Fallback: emit SCOPE_STATUS_CHANGED event via file bus
47
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
48
+ IFS=',' read -ra IDS <<< "$SCOPE_IDS"
49
+ for id in "${IDS[@]}"; do
50
+ id=$(echo "$id" | tr -d ' ')
51
+ DATA=$(jq -n --arg to "$STATUS" '{to: $to}')
52
+ "$SCRIPT_DIR/orbital-emit.sh" SCOPE_STATUS_CHANGED "$DATA" --scope "$id" 2>/dev/null &
53
+ done
@@ -0,0 +1,26 @@
1
+ #!/bin/bash
2
+ # phase-verify-reminder.sh — Remind to verify before marking phase done
3
+ # Trigger: PreToolUse:Edit (scope file with completion marker)
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
+ # Only trigger on scope files
14
+ source "$(dirname "$0")/scope-helpers.sh"
15
+ is_scope_file "$FILE_PATH" || exit 0
16
+
17
+ # Only trigger when marking something as done
18
+ echo "$NEW_STRING" | grep -qE "✅|Done" || exit 0
19
+
20
+ echo ""
21
+ echo "✅ Marking phase done — verify first:"
22
+ echo " □ npm run type-check && npm run build"
23
+ echo " □ Changes tested or reviewed"
24
+ echo ""
25
+
26
+ exit 0
@@ -0,0 +1,82 @@
1
+ #!/bin/bash
2
+ # review-gate-check.sh — PreToolUse:Edit hook
3
+ #
4
+ # Blocks scope completion (status → completed) unless a valid review verdict
5
+ # exists with PASS verdict and session separation.
6
+ #
7
+ # Exit codes:
8
+ # 0 — Allow the edit
9
+ # 2 — Block (no verdict, failed verdict, or session separation violation)
10
+ set -euo pipefail
11
+
12
+ INPUT=$(cat)
13
+ echo "$INPUT" | jq empty 2>/dev/null || exit 0
14
+
15
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
16
+ NEW_STRING=$(echo "$INPUT" | jq -r '.tool_input.new_string // empty')
17
+
18
+ # Only enforce on scope files
19
+ source "$(dirname "$0")/scope-helpers.sh"
20
+ is_scope_file "$FILE_PATH" || exit 0
21
+
22
+ # Only enforce when status is being set to completed
23
+ echo "$NEW_STRING" | grep -qiE "status:.*completed" || exit 0
24
+
25
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
26
+ VERDICTS_DIR="$PROJECT_DIR/.claude/review-verdicts"
27
+
28
+ # ─── Extract scope number from filename ───
29
+ FILENAME=$(basename "$FILE_PATH" .md)
30
+ # Handle patterns: 083-platform-fees, 047a-critical-fixes
31
+ SCOPE_NUM=$(echo "$FILENAME" | grep -oE '^[0-9]+' | head -1)
32
+
33
+ if [ -z "$SCOPE_NUM" ]; then
34
+ # Can't determine scope number — allow (template files, etc.)
35
+ exit 0
36
+ fi
37
+
38
+ # Pad to 3 digits for verdict file lookup (force base-10 to avoid octal)
39
+ SCOPE_NUM_CLEAN=$((10#${SCOPE_NUM}))
40
+ PADDED=$(printf '%03d' "$SCOPE_NUM_CLEAN")
41
+ VERDICT_FILE="$VERDICTS_DIR/${PADDED}.json"
42
+
43
+ # ─── Check verdict file exists ───
44
+ if [ ! -f "$VERDICT_FILE" ]; then
45
+ echo "" >&2
46
+ echo "MUST_BLOCK: No review verdict found for scope $PADDED." >&2
47
+ echo " Run: /scope-post-review $PADDED" >&2
48
+ echo " The review gate must pass before a scope can be completed." >&2
49
+ echo " Verdict file expected at: .claude/review-verdicts/${PADDED}.json" >&2
50
+ echo " Format: {\"verdict\": \"PASS\", \"reviewSession\": \"uuid\", \"implementSession\": \"uuid\"}" >&2
51
+ echo "" >&2
52
+ exit 2
53
+ fi
54
+
55
+ # ─── Validate verdict is PASS ───
56
+ VERDICT=$(jq -r '.verdict // empty' "$VERDICT_FILE")
57
+ if [ "$VERDICT" != "PASS" ]; then
58
+ echo "" >&2
59
+ echo "MUST_BLOCK: Review verdict for scope $PADDED is '$VERDICT', not PASS." >&2
60
+ echo " Fix the failing criteria and re-run: /scope-post-review $PADDED" >&2
61
+ echo " Verdict file: .claude/review-verdicts/${PADDED}.json" >&2
62
+ echo "" >&2
63
+ exit 2
64
+ fi
65
+
66
+ # ─── Validate session separation ───
67
+ REVIEW_SESSION=$(jq -r '.reviewSession // empty' "$VERDICT_FILE")
68
+ IMPLEMENT_SESSION=$(jq -r '.implementSession // empty' "$VERDICT_FILE")
69
+
70
+ if [ -n "$REVIEW_SESSION" ] && [ -n "$IMPLEMENT_SESSION" ]; then
71
+ if [ "$REVIEW_SESSION" = "$IMPLEMENT_SESSION" ]; then
72
+ echo "" >&2
73
+ echo "MUST_BLOCK: Session separation violation in verdict for scope $PADDED." >&2
74
+ echo " The review session ($REVIEW_SESSION) matches the implement session." >&2
75
+ echo " A different Claude Code session must run /scope-post-review (the user starts a new session)." >&2
76
+ echo "" >&2
77
+ exit 2
78
+ fi
79
+ fi
80
+
81
+ # All checks passed
82
+ exit 0
@@ -0,0 +1,37 @@
1
+ #!/bin/bash
2
+ # scope-commit-logger.sh — Suggest Implementation Log entry after commits
3
+ # Trigger: PostToolUse:Bash (git commit detected)
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
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
11
+ echo "$COMMAND" | grep -qE "git commit" || exit 0
12
+
13
+ # Check commit succeeded
14
+ EXIT_CODE=$(echo "$INPUT" | jq -r '.tool_result.exitCode // .tool_result.exit_code // "0"')
15
+ [ "$EXIT_CODE" != "0" ] && exit 0
16
+
17
+ source "$(dirname "$0")/scope-helpers.sh"
18
+ SCOPE=$(find_active_scope) || exit 0
19
+
20
+ COMMIT_HASH=$(cd "$SCOPE_PROJECT_DIR" && git rev-parse --short HEAD 2>/dev/null || true)
21
+ COMMIT_MSG=$(cd "$SCOPE_PROJECT_DIR" && git log -1 --pretty=format:%s 2>/dev/null || true)
22
+ SCOPE_ID=$(echo "$(basename "$SCOPE")" | grep -oE '[0-9]+' | head -1)
23
+
24
+ # Emit COMMIT event to Orbital dashboard
25
+ HOOK_DIR="$(dirname "$0")"
26
+ COMMIT_DATA=$(jq -n --arg hash "$COMMIT_HASH" --arg message "$COMMIT_MSG" '{hash: $hash, message: $message}')
27
+ AGENT_DATA=$(jq -n --arg outcome "committed" --arg commit_hash "$COMMIT_HASH" '{outcome: $outcome, commit_hash: $commit_hash}')
28
+ "$HOOK_DIR/orbital-emit.sh" COMMIT "$COMMIT_DATA" --scope "$SCOPE_ID"
29
+ "$HOOK_DIR/orbital-emit.sh" AGENT_COMPLETED "$AGENT_DATA" --scope "$SCOPE_ID" &
30
+
31
+ echo ""
32
+ echo "📝 Consider updating Implementation Log in $(basename "$SCOPE"):"
33
+ echo " Commit: $COMMIT_HASH"
34
+ echo " Add: phase, what changed, issues encountered"
35
+ echo ""
36
+
37
+ exit 0
@@ -0,0 +1,36 @@
1
+ #!/bin/bash
2
+ #
3
+ # scope-create-cleanup.sh — PostToolUse:Write cleanup
4
+ #
5
+ # After a successful Write, checks if the written file is a scope document.
6
+ # If so, removes the .scope-create-session marker to lift the write gate.
7
+ #
8
+ set -e
9
+
10
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
11
+ MARKER="$PROJECT_DIR/.claude/metrics/.scope-create-session"
12
+
13
+ # Fast exit: no marker = nothing to clean
14
+ [ -f "$MARKER" ] || exit 0
15
+
16
+ # Extract file_path from tool input
17
+ INPUT=$(cat)
18
+ echo "$INPUT" | jq empty 2>/dev/null || exit 0
19
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
20
+ [ -z "$FILE_PATH" ] && exit 0
21
+
22
+ # Check if written file is a scope document in planning/
23
+ case "$FILE_PATH" in
24
+ */scopes/planning/*.md)
25
+ rm -f "$MARKER"
26
+ HOOK_DIR="$(dirname "$0")"
27
+ GATE_DATA=$(jq -n --arg scope_file "$FILE_PATH" '{scope_file: $scope_file}')
28
+ "$HOOK_DIR/orbital-emit.sh" SCOPE_GATE_LIFTED "$GATE_DATA" 2>/dev/null &
29
+ echo ""
30
+ echo "Scope document written. Write gate lifted."
31
+ echo "Remember: STOP here. Implementation is a separate session:"
32
+ echo " /scope-implement NNN"
33
+ ;;
34
+ esac
35
+
36
+ exit 0
@@ -0,0 +1,80 @@
1
+ #!/bin/bash
2
+ #
3
+ # scope-create-gate.sh — PreToolUse:Write|Edit blocker
4
+ #
5
+ # Blocks writes to non-scope files while a /scope create session is active.
6
+ # The marker (.scope-create-session) is set by scope-create-tracker.sh and
7
+ # removed by scope-create-cleanup.sh after the scope document is written.
8
+ #
9
+ # Exit codes: 0 = allow, 2 = block
10
+ set -e
11
+
12
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
13
+ MARKER="$PROJECT_DIR/.claude/metrics/.scope-create-session"
14
+
15
+ # Fast exit: no marker = no gate
16
+ [ -f "$MARKER" ] || exit 0
17
+
18
+ # Optional: auto-expire stale markers (older than 2 hours)
19
+ if [ "$(uname)" = "Darwin" ]; then
20
+ MARKER_AGE=$(( $(date +%s) - $(stat -f %m "$MARKER") ))
21
+ else
22
+ MARKER_AGE=$(( $(date +%s) - $(stat -c %Y "$MARKER") ))
23
+ fi
24
+ if [ "$MARKER_AGE" -gt 900 ]; then
25
+ rm -f "$MARKER"
26
+ exit 0
27
+ fi
28
+
29
+ # Extract file_path from tool input
30
+ INPUT=$(cat)
31
+ echo "$INPUT" | jq empty 2>/dev/null || exit 0
32
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
33
+
34
+ # If no file_path found, allow (defensive — don't break unknown tool shapes)
35
+ [ -z "$FILE_PATH" ] && exit 0
36
+
37
+ # ─── Allowlisted paths ───
38
+ # 1. Scope files
39
+ case "$FILE_PATH" in
40
+ */scopes/*) exit 0 ;;
41
+ esac
42
+
43
+ # 2. Plan files (both project-local and home directory)
44
+ case "$FILE_PATH" in
45
+ */.claude/plans/*) exit 0 ;;
46
+ esac
47
+
48
+ # 3. Claude project config files
49
+ case "$FILE_PATH" in
50
+ "$PROJECT_DIR"/.claude/*) exit 0 ;;
51
+ esac
52
+
53
+ # 4. Home-directory Claude plans
54
+ HOME_DIR="${HOME:-/Users/$(whoami)}"
55
+ case "$FILE_PATH" in
56
+ "$HOME_DIR"/.claude/plans/*) exit 0 ;;
57
+ esac
58
+
59
+ # ─── Block everything else ───
60
+ HOOK_DIR="$(dirname "$0")"
61
+ VIOLATION_DATA=$(jq -n --arg rule "scope-create-gate" --arg file "$FILE_PATH" --arg outcome "blocked" '{rule: $rule, file: $file, outcome: $outcome}')
62
+ "$HOOK_DIR/orbital-emit.sh" VIOLATION "$VIOLATION_DATA" 2>/dev/null &
63
+
64
+ # Resolve entry status from workflow manifest
65
+ HOOK_DIR="$(dirname "$0")"
66
+ source "$HOOK_DIR/scope-helpers.sh" 2>/dev/null || true
67
+ ENTRY="${WORKFLOW_ENTRY_STATUS:-planning}"
68
+
69
+ echo "BLOCKED: Write to non-scope file during /scope create"
70
+ echo ""
71
+ echo " File: $FILE_PATH"
72
+ echo ""
73
+ echo " You must write the scope document first:"
74
+ echo " 1. Find next scope number (highest NNN in scopes/**/*.md + 1, zero-padded to 3 digits)"
75
+ echo " 2. Copy template from scopes/_template.md"
76
+ echo " 3. Write to scopes/$ENTRY/NNN-short-description.md"
77
+ echo ""
78
+ echo " After the scope document is written, the gate lifts automatically."
79
+ echo " To abandon: delete .claude/metrics/.scope-create-session"
80
+ exit 2
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ # scope-create-tracker.sh — Track when /scope create is invoked
3
+ # Trigger: PostToolUse:Skill
4
+ set -e
5
+
6
+ INPUT=$(cat)
7
+ echo "$INPUT" | jq empty 2>/dev/null || exit 0
8
+ SKILL=$(echo "$INPUT" | jq -r '.tool_input.skill // empty')
9
+
10
+ # Only track scope create invocations
11
+ [[ "$SKILL" == "scope-create" ]] || exit 0
12
+
13
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
14
+ mkdir -p "$PROJECT_DIR/.claude/metrics"
15
+ echo "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$PROJECT_DIR/.claude/metrics/.scope-create-session"
16
+
17
+ exit 0
@@ -0,0 +1,53 @@
1
+ #!/bin/bash
2
+ # scope-file-sync.sh — Flag out-of-scope files before commits
3
+ # Trigger: PreToolUse:Bash (git commit detected)
4
+ # Nudge-style: always exits 0
5
+ set -e
6
+
7
+ INPUT=$(cat)
8
+ echo "$INPUT" | jq empty 2>/dev/null || exit 0
9
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
10
+ echo "$COMMAND" | grep -qE "git commit" || exit 0
11
+
12
+ source "$(dirname "$0")/scope-helpers.sh"
13
+ SCOPE=$(find_active_scope) || exit 0
14
+
15
+ # Get staged files
16
+ STAGED=$(cd "$SCOPE_PROJECT_DIR" && git diff --cached --name-only 2>/dev/null)
17
+ [ -z "$STAGED" ] && exit 0
18
+
19
+ # Get file references from scope's Files Summary table
20
+ SCOPE_FILES=$(grep -oE '`[^`]+\.(ts|tsx|js|jsx|md|json|sh|css)`' "$SCOPE" | tr -d '`' | sort -u)
21
+ [ -z "$SCOPE_FILES" ] && exit 0
22
+
23
+ # Build a patterns file for grep -Ff matching (O(n) instead of O(n²))
24
+ SCOPE_PATTERNS_FILE=$(mktemp)
25
+ trap "rm -f '$SCOPE_PATTERNS_FILE'" EXIT
26
+ # Add both full paths and basenames as patterns
27
+ echo "$SCOPE_FILES" > "$SCOPE_PATTERNS_FILE"
28
+ echo "$SCOPE_FILES" | xargs -I{} basename {} >> "$SCOPE_PATTERNS_FILE"
29
+
30
+ OUT_OF_SCOPE=""
31
+ for staged_file in $STAGED; do
32
+ # Skip non-code and meta files
33
+ [[ "$staged_file" == *.lock ]] && continue
34
+ [[ "$staged_file" == *"node_modules"* ]] && continue
35
+ [[ "$staged_file" == *".claude/"* ]] && continue
36
+ [[ "$staged_file" == *"scopes/"* ]] && continue
37
+
38
+ # Check if staged file or its basename matches any scope file pattern
39
+ if ! echo "$staged_file" | grep -qFf "$SCOPE_PATTERNS_FILE" && \
40
+ ! basename "$staged_file" | grep -qFf "$SCOPE_PATTERNS_FILE"; then
41
+ OUT_OF_SCOPE="$OUT_OF_SCOPE - $staged_file\n"
42
+ fi
43
+ done
44
+
45
+ if [ -n "$OUT_OF_SCOPE" ]; then
46
+ echo ""
47
+ echo "⚠️ Files outside scope ($(basename "$SCOPE")):"
48
+ echo -e "$OUT_OF_SCOPE"
49
+ echo " If intentional, document in PROCESS > Deviations from Spec"
50
+ echo ""
51
+ fi
52
+
53
+ exit 0
@@ -0,0 +1,35 @@
1
+ #!/bin/bash
2
+ # scope-gate.sh — After plan approval, instruct agent to write scope doc
3
+ # Trigger: PostToolUse:ExitPlanMode
4
+ # Only fires when /scope create was invoked this session
5
+ set -euo pipefail
6
+
7
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
8
+ MARKER="$PROJECT_DIR/.claude/metrics/.scope-create-session"
9
+
10
+ # Only act if /scope create was invoked this session
11
+ [ -f "$MARKER" ] || exit 0
12
+
13
+ # NOTE: Marker is NOT deleted here — scope-create-gate.sh (PreToolUse)
14
+ # blocks non-scope writes until the scope document is created.
15
+ # scope-create-cleanup.sh (PostToolUse) removes the marker after the scope is written.
16
+
17
+ echo ""
18
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
19
+ echo " SCOPE DOCUMENT REQUIRED"
20
+ echo ""
21
+ echo " Write the scope document now using your plan."
22
+ echo " Follow the create skill steps:"
23
+ echo " 1. Find next scope number"
24
+ echo " 2. Copy template from scopes/_template.md"
25
+ echo " 3. Fill SPECIFICATION from your plan"
26
+ echo " 4. Set status: planning, spec_locked: true"
27
+ echo ""
28
+ echo " ⛔ Writes to non-scope files are BLOCKED until"
29
+ echo " the scope document is written."
30
+ echo ""
31
+ echo " Then STOP. Implementation is a separate session:"
32
+ echo " /scope-implement NNN"
33
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
34
+
35
+ exit 0