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.
- package/LICENSE +21 -0
- package/README.md +396 -0
- package/bin/orbital.js +362 -0
- package/dist/assets/WorkflowVisualizer-BZ21PIIF.js +84 -0
- package/dist/assets/WorkflowVisualizer-BZV40eAE.css +1 -0
- package/dist/assets/charts-D__PA1zp.js +72 -0
- package/dist/assets/index-D1G6i0nS.css +1 -0
- package/dist/assets/index-DpItvKpf.js +419 -0
- package/dist/assets/ui-BvF022GT.js +53 -0
- package/dist/assets/vendor-Dzv9lrRc.js +59 -0
- package/dist/index.html +19 -0
- package/dist/scanner-sweep.png +0 -0
- package/dist/server/server/adapters/index.js +34 -0
- package/dist/server/server/adapters/iterm2-adapter.js +29 -0
- package/dist/server/server/adapters/subprocess-adapter.js +21 -0
- package/dist/server/server/adapters/terminal-adapter.js +1 -0
- package/dist/server/server/config.js +156 -0
- package/dist/server/server/database.js +90 -0
- package/dist/server/server/index.js +372 -0
- package/dist/server/server/init.js +811 -0
- package/dist/server/server/parsers/event-parser.js +64 -0
- package/dist/server/server/parsers/scope-parser.js +188 -0
- package/dist/server/server/routes/config-routes.js +163 -0
- package/dist/server/server/routes/data-routes.js +461 -0
- package/dist/server/server/routes/dispatch-routes.js +215 -0
- package/dist/server/server/routes/git-routes.js +92 -0
- package/dist/server/server/routes/scope-routes.js +215 -0
- package/dist/server/server/routes/sprint-routes.js +116 -0
- package/dist/server/server/routes/version-routes.js +130 -0
- package/dist/server/server/routes/workflow-routes.js +185 -0
- package/dist/server/server/schema.js +90 -0
- package/dist/server/server/services/batch-orchestrator.js +253 -0
- package/dist/server/server/services/claude-session-service.js +352 -0
- package/dist/server/server/services/config-service.js +132 -0
- package/dist/server/server/services/deploy-service.js +51 -0
- package/dist/server/server/services/event-service.js +63 -0
- package/dist/server/server/services/gate-service.js +83 -0
- package/dist/server/server/services/git-service.js +309 -0
- package/dist/server/server/services/github-service.js +145 -0
- package/dist/server/server/services/readiness-service.js +184 -0
- package/dist/server/server/services/scope-cache.js +72 -0
- package/dist/server/server/services/scope-service.js +424 -0
- package/dist/server/server/services/sprint-orchestrator.js +312 -0
- package/dist/server/server/services/sprint-service.js +293 -0
- package/dist/server/server/services/workflow-service.js +397 -0
- package/dist/server/server/utils/cc-hooks-parser.js +49 -0
- package/dist/server/server/utils/dispatch-utils.js +305 -0
- package/dist/server/server/utils/logger.js +86 -0
- package/dist/server/server/utils/terminal-launcher.js +388 -0
- package/dist/server/server/utils/worktree-manager.js +98 -0
- package/dist/server/server/watchers/event-watcher.js +81 -0
- package/dist/server/server/watchers/scope-watcher.js +33 -0
- package/dist/server/shared/api-types.js +5 -0
- package/dist/server/shared/default-workflow.json +616 -0
- package/dist/server/shared/workflow-config.js +44 -0
- package/dist/server/shared/workflow-engine.js +353 -0
- package/index.html +15 -0
- package/package.json +110 -0
- package/postcss.config.js +6 -0
- package/schemas/orbital.config.schema.json +83 -0
- package/scripts/postinstall.js +24 -0
- package/scripts/start.sh +20 -0
- package/server/adapters/index.ts +41 -0
- package/server/adapters/iterm2-adapter.ts +37 -0
- package/server/adapters/subprocess-adapter.ts +25 -0
- package/server/adapters/terminal-adapter.ts +24 -0
- package/server/config.ts +234 -0
- package/server/database.ts +107 -0
- package/server/index.ts +452 -0
- package/server/init.ts +891 -0
- package/server/parsers/event-parser.ts +74 -0
- package/server/parsers/scope-parser.ts +240 -0
- package/server/routes/config-routes.ts +182 -0
- package/server/routes/data-routes.ts +548 -0
- package/server/routes/dispatch-routes.ts +275 -0
- package/server/routes/git-routes.ts +112 -0
- package/server/routes/scope-routes.ts +262 -0
- package/server/routes/sprint-routes.ts +142 -0
- package/server/routes/version-routes.ts +156 -0
- package/server/routes/workflow-routes.ts +198 -0
- package/server/schema.ts +90 -0
- package/server/services/batch-orchestrator.ts +286 -0
- package/server/services/claude-session-service.ts +441 -0
- package/server/services/config-service.ts +151 -0
- package/server/services/deploy-service.ts +98 -0
- package/server/services/event-service.ts +98 -0
- package/server/services/gate-service.ts +126 -0
- package/server/services/git-service.ts +391 -0
- package/server/services/github-service.ts +183 -0
- package/server/services/readiness-service.ts +250 -0
- package/server/services/scope-cache.ts +81 -0
- package/server/services/scope-service.ts +476 -0
- package/server/services/sprint-orchestrator.ts +361 -0
- package/server/services/sprint-service.ts +415 -0
- package/server/services/workflow-service.ts +461 -0
- package/server/utils/cc-hooks-parser.ts +70 -0
- package/server/utils/dispatch-utils.ts +395 -0
- package/server/utils/logger.ts +109 -0
- package/server/utils/terminal-launcher.ts +462 -0
- package/server/utils/worktree-manager.ts +104 -0
- package/server/watchers/event-watcher.ts +100 -0
- package/server/watchers/scope-watcher.ts +38 -0
- package/shared/api-types.ts +20 -0
- package/shared/default-workflow.json +616 -0
- package/shared/workflow-config.ts +170 -0
- package/shared/workflow-engine.ts +427 -0
- package/src/App.tsx +33 -0
- package/src/components/AgentBadge.tsx +40 -0
- package/src/components/BatchPreflightModal.tsx +115 -0
- package/src/components/CardDisplayToggle.tsx +74 -0
- package/src/components/ColumnHeaderActions.tsx +55 -0
- package/src/components/ColumnMenu.tsx +99 -0
- package/src/components/DeployHistory.tsx +141 -0
- package/src/components/DispatchModal.tsx +164 -0
- package/src/components/DispatchPopover.tsx +139 -0
- package/src/components/DragOverlay.tsx +25 -0
- package/src/components/DriftSidebar.tsx +140 -0
- package/src/components/EnvironmentStrip.tsx +88 -0
- package/src/components/ErrorBoundary.tsx +62 -0
- package/src/components/FilterChip.tsx +105 -0
- package/src/components/GateIndicator.tsx +33 -0
- package/src/components/IdeaDetailModal.tsx +190 -0
- package/src/components/IdeaFormDialog.tsx +113 -0
- package/src/components/KanbanColumn.tsx +201 -0
- package/src/components/MarkdownRenderer.tsx +114 -0
- package/src/components/NeonGrid.tsx +128 -0
- package/src/components/PromotionQueue.tsx +89 -0
- package/src/components/ScopeCard.tsx +234 -0
- package/src/components/ScopeDetailModal.tsx +255 -0
- package/src/components/ScopeFilterBar.tsx +152 -0
- package/src/components/SearchInput.tsx +102 -0
- package/src/components/SessionPanel.tsx +335 -0
- package/src/components/SprintContainer.tsx +303 -0
- package/src/components/SprintDependencyDialog.tsx +78 -0
- package/src/components/SprintPreflightModal.tsx +138 -0
- package/src/components/StatusBar.tsx +168 -0
- package/src/components/SwimCell.tsx +67 -0
- package/src/components/SwimLaneRow.tsx +94 -0
- package/src/components/SwimlaneBoardView.tsx +108 -0
- package/src/components/VersionBadge.tsx +139 -0
- package/src/components/ViewModeSelector.tsx +114 -0
- package/src/components/config/AgentChip.tsx +53 -0
- package/src/components/config/AgentCreateDialog.tsx +321 -0
- package/src/components/config/AgentEditor.tsx +175 -0
- package/src/components/config/DirectoryTree.tsx +582 -0
- package/src/components/config/FileEditor.tsx +550 -0
- package/src/components/config/HookChip.tsx +50 -0
- package/src/components/config/StageCard.tsx +198 -0
- package/src/components/config/TransitionZone.tsx +173 -0
- package/src/components/config/UnifiedWorkflowPipeline.tsx +216 -0
- package/src/components/config/WorkflowPipeline.tsx +161 -0
- package/src/components/source-control/BranchList.tsx +93 -0
- package/src/components/source-control/BranchPanel.tsx +105 -0
- package/src/components/source-control/CommitLog.tsx +100 -0
- package/src/components/source-control/CommitRow.tsx +47 -0
- package/src/components/source-control/GitHubPanel.tsx +110 -0
- package/src/components/source-control/GitHubSetupGuide.tsx +52 -0
- package/src/components/source-control/GitOverviewBar.tsx +101 -0
- package/src/components/source-control/PullRequestList.tsx +69 -0
- package/src/components/source-control/WorktreeList.tsx +80 -0
- package/src/components/ui/badge.tsx +41 -0
- package/src/components/ui/button.tsx +55 -0
- package/src/components/ui/card.tsx +78 -0
- package/src/components/ui/dialog.tsx +94 -0
- package/src/components/ui/popover.tsx +33 -0
- package/src/components/ui/scroll-area.tsx +54 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/tabs.tsx +52 -0
- package/src/components/ui/toggle-switch.tsx +35 -0
- package/src/components/ui/tooltip.tsx +27 -0
- package/src/components/workflow/AddEdgeDialog.tsx +217 -0
- package/src/components/workflow/AddListDialog.tsx +201 -0
- package/src/components/workflow/ChecklistEditor.tsx +239 -0
- package/src/components/workflow/CommandPrefixManager.tsx +118 -0
- package/src/components/workflow/ConfigSettingsPanel.tsx +189 -0
- package/src/components/workflow/DirectionSelector.tsx +133 -0
- package/src/components/workflow/DispatchConfigPanel.tsx +180 -0
- package/src/components/workflow/EdgeDetailPanel.tsx +236 -0
- package/src/components/workflow/EdgePropertyEditor.tsx +251 -0
- package/src/components/workflow/EditToolbar.tsx +138 -0
- package/src/components/workflow/HookDetailPanel.tsx +250 -0
- package/src/components/workflow/HookExecutionLog.tsx +24 -0
- package/src/components/workflow/HookSourceModal.tsx +129 -0
- package/src/components/workflow/HooksDashboard.tsx +363 -0
- package/src/components/workflow/ListPropertyEditor.tsx +251 -0
- package/src/components/workflow/MigrationPreviewDialog.tsx +237 -0
- package/src/components/workflow/MovementRulesPanel.tsx +188 -0
- package/src/components/workflow/NodeDetailPanel.tsx +245 -0
- package/src/components/workflow/PresetSelector.tsx +414 -0
- package/src/components/workflow/SkillCommandBuilder.tsx +174 -0
- package/src/components/workflow/WorkflowEdgeComponent.tsx +145 -0
- package/src/components/workflow/WorkflowNode.tsx +147 -0
- package/src/components/workflow/graphLayout.ts +186 -0
- package/src/components/workflow/mergeHooks.ts +85 -0
- package/src/components/workflow/useEditHistory.ts +88 -0
- package/src/components/workflow/useWorkflowEditor.ts +262 -0
- package/src/components/workflow/validateConfig.ts +70 -0
- package/src/hooks/useActiveDispatches.ts +198 -0
- package/src/hooks/useBoardSettings.ts +170 -0
- package/src/hooks/useCardDisplay.ts +57 -0
- package/src/hooks/useCcHooks.ts +24 -0
- package/src/hooks/useConfigTree.ts +51 -0
- package/src/hooks/useEnforcementRules.ts +46 -0
- package/src/hooks/useEvents.ts +59 -0
- package/src/hooks/useFileEditor.ts +165 -0
- package/src/hooks/useGates.ts +57 -0
- package/src/hooks/useIdeaActions.ts +53 -0
- package/src/hooks/useKanbanDnd.ts +410 -0
- package/src/hooks/useOrbitalConfig.ts +54 -0
- package/src/hooks/usePipeline.ts +47 -0
- package/src/hooks/usePipelineData.ts +338 -0
- package/src/hooks/useReconnect.ts +25 -0
- package/src/hooks/useScopeFilters.ts +125 -0
- package/src/hooks/useScopeSessions.ts +44 -0
- package/src/hooks/useScopes.ts +67 -0
- package/src/hooks/useSearch.ts +67 -0
- package/src/hooks/useSettings.tsx +187 -0
- package/src/hooks/useSocket.ts +25 -0
- package/src/hooks/useSourceControl.ts +105 -0
- package/src/hooks/useSprintPreflight.ts +55 -0
- package/src/hooks/useSprints.ts +154 -0
- package/src/hooks/useStatusBarHighlight.ts +18 -0
- package/src/hooks/useSwimlaneBoardSettings.ts +104 -0
- package/src/hooks/useTheme.ts +9 -0
- package/src/hooks/useTransitionReadiness.ts +53 -0
- package/src/hooks/useVersion.ts +155 -0
- package/src/hooks/useViolations.ts +65 -0
- package/src/hooks/useWorkflow.tsx +125 -0
- package/src/hooks/useZoomModifier.ts +19 -0
- package/src/index.css +797 -0
- package/src/layouts/DashboardLayout.tsx +113 -0
- package/src/lib/collisionDetection.ts +20 -0
- package/src/lib/scope-fields.ts +61 -0
- package/src/lib/swimlane.ts +146 -0
- package/src/lib/utils.ts +15 -0
- package/src/main.tsx +19 -0
- package/src/socket.ts +11 -0
- package/src/types/index.ts +497 -0
- package/src/views/AgentFeed.tsx +339 -0
- package/src/views/DeployPipeline.tsx +59 -0
- package/src/views/EnforcementView.tsx +378 -0
- package/src/views/PrimitivesConfig.tsx +500 -0
- package/src/views/QualityGates.tsx +1012 -0
- package/src/views/ScopeBoard.tsx +454 -0
- package/src/views/SessionTimeline.tsx +516 -0
- package/src/views/Settings.tsx +183 -0
- package/src/views/SourceControl.tsx +95 -0
- package/src/views/WorkflowVisualizer.tsx +382 -0
- package/tailwind.config.js +161 -0
- package/templates/agents/AUTO-INVOKE.md +180 -0
- package/templates/agents/CONFLICT-RESOLUTION.md +128 -0
- package/templates/agents/QUICK-REFERENCE.md +122 -0
- package/templates/agents/README.md +188 -0
- package/templates/agents/SKILL-TRIGGERS.md +100 -0
- package/templates/agents/blue-team/frontend-designer.md +424 -0
- package/templates/agents/green-team/architect.md +526 -0
- package/templates/agents/green-team/rules-enforcer.md +131 -0
- package/templates/agents/red-team/attacker-learned.md +24 -0
- package/templates/agents/red-team/attacker.md +486 -0
- package/templates/agents/red-team/chaos.md +548 -0
- package/templates/agents/reference/component-registry.md +82 -0
- package/templates/agents/workflows/full-mode.md +218 -0
- package/templates/agents/workflows/quick-mode.md +118 -0
- package/templates/agents/workflows/security-mode.md +283 -0
- package/templates/anti-patterns/dangerous-shortcuts.md +427 -0
- package/templates/config/agent-triggers.json +92 -0
- package/templates/hooks/agent-team-gate.sh +31 -0
- package/templates/hooks/agent-trigger.sh +97 -0
- package/templates/hooks/block-push.sh +66 -0
- package/templates/hooks/block-workarounds.sh +61 -0
- package/templates/hooks/blocker-check.sh +28 -0
- package/templates/hooks/completion-checklist.sh +28 -0
- package/templates/hooks/decision-capture.sh +15 -0
- package/templates/hooks/dependency-check.sh +27 -0
- package/templates/hooks/end-session.sh +31 -0
- package/templates/hooks/exploration-logger.sh +37 -0
- package/templates/hooks/files-changed-summary.sh +37 -0
- package/templates/hooks/get-session-id.sh +49 -0
- package/templates/hooks/git-commit-guard.sh +34 -0
- package/templates/hooks/init-session.sh +93 -0
- package/templates/hooks/orbital-emit.sh +79 -0
- package/templates/hooks/orbital-report-deploy.sh +78 -0
- package/templates/hooks/orbital-report-gates.sh +40 -0
- package/templates/hooks/orbital-report-violation.sh +36 -0
- package/templates/hooks/orbital-scope-update.sh +53 -0
- package/templates/hooks/phase-verify-reminder.sh +26 -0
- package/templates/hooks/review-gate-check.sh +82 -0
- package/templates/hooks/scope-commit-logger.sh +37 -0
- package/templates/hooks/scope-create-cleanup.sh +36 -0
- package/templates/hooks/scope-create-gate.sh +80 -0
- package/templates/hooks/scope-create-tracker.sh +17 -0
- package/templates/hooks/scope-file-sync.sh +53 -0
- package/templates/hooks/scope-gate.sh +35 -0
- package/templates/hooks/scope-helpers.sh +188 -0
- package/templates/hooks/scope-lifecycle-gate.sh +139 -0
- package/templates/hooks/scope-prepare.sh +244 -0
- package/templates/hooks/scope-transition.sh +172 -0
- package/templates/hooks/session-enforcer.sh +143 -0
- package/templates/hooks/time-tracker.sh +33 -0
- package/templates/lessons-learned.md +15 -0
- package/templates/orbital.config.json +35 -0
- package/templates/presets/development.json +42 -0
- package/templates/presets/gitflow.json +712 -0
- package/templates/presets/minimal.json +23 -0
- package/templates/quick/rules.md +218 -0
- package/templates/scopes/_template.md +255 -0
- package/templates/settings-hooks.json +98 -0
- package/templates/skills/git-commit/SKILL.md +85 -0
- package/templates/skills/git-dev/SKILL.md +99 -0
- package/templates/skills/git-hotfix/SKILL.md +223 -0
- package/templates/skills/git-main/SKILL.md +84 -0
- package/templates/skills/git-production/SKILL.md +165 -0
- package/templates/skills/git-staging/SKILL.md +112 -0
- package/templates/skills/scope-create/SKILL.md +81 -0
- package/templates/skills/scope-fix-review/SKILL.md +168 -0
- package/templates/skills/scope-implement/SKILL.md +110 -0
- package/templates/skills/scope-post-review/SKILL.md +144 -0
- package/templates/skills/scope-pre-review/SKILL.md +211 -0
- package/templates/skills/scope-verify/SKILL.md +201 -0
- package/templates/skills/session-init/SKILL.md +62 -0
- package/templates/skills/session-resume/SKILL.md +201 -0
- package/templates/skills/test-checks/SKILL.md +171 -0
- package/templates/skills/test-code-review/SKILL.md +252 -0
- package/tsconfig.json +25 -0
- 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
|