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,339 @@
1
+ import { useState, useMemo } from 'react';
2
+ import { motion } from 'framer-motion';
3
+ import { Bot, Filter } from 'lucide-react';
4
+ import { formatDistanceToNow, format } from 'date-fns';
5
+ import { useEvents } from '@/hooks/useEvents';
6
+ import { useTheme } from '@/hooks/useTheme';
7
+ import { AgentBadge } from '@/components/AgentBadge';
8
+ import { Badge } from '@/components/ui/badge';
9
+ import { Button } from '@/components/ui/button';
10
+ import { Card, CardContent } from '@/components/ui/card';
11
+ import { ScrollArea } from '@/components/ui/scroll-area';
12
+ import { Separator } from '@/components/ui/separator';
13
+ import { cn, formatScopeId } from '@/lib/utils';
14
+ import type { OrbitalEvent } from '@/types';
15
+
16
+ // Agent-related event types
17
+ const AGENT_EVENT_TYPES = [
18
+ 'AGENT_STARTED',
19
+ 'AGENT_FINDING',
20
+ 'AGENT_COMPLETED',
21
+ 'AGENT_CONSENSUS',
22
+ ];
23
+
24
+ const SEVERITY_CONFIG: Record<string, { color: string; label: string }> = {
25
+ blocker: { color: 'text-ask-red bg-[#ff174415]', label: 'BLOCKER' },
26
+ warning: { color: 'text-warning-amber bg-[#ffab0015]', label: 'WARNING' },
27
+ info: { color: 'text-accent-blue bg-[#06b6d415]', label: 'INFO' },
28
+ pass: { color: 'text-bid-green bg-[#00c85315]', label: 'PASS' },
29
+ };
30
+
31
+ const AGENTS = [
32
+ 'all',
33
+ 'attacker',
34
+ 'chaos',
35
+ 'solana-expert',
36
+ 'frontend-designer',
37
+ 'architect',
38
+ 'rules-enforcer',
39
+ ] as const;
40
+
41
+ const rowStagger = {
42
+ show: { transition: { staggerChildren: 0.02 } },
43
+ };
44
+ const rowItem = {
45
+ hidden: { opacity: 0, x: -8 },
46
+ show: { opacity: 1, x: 0, transition: { type: 'spring', stiffness: 400, damping: 30 } },
47
+ };
48
+
49
+ export function AgentFeed() {
50
+ const { events, loading } = useEvents({ limit: 200 });
51
+ const { neonGlass } = useTheme();
52
+ const [agentFilter, setAgentFilter] = useState<string>('all');
53
+ const [showAllEvents, setShowAllEvents] = useState(false);
54
+
55
+ // Filter to agent-related events or show all
56
+ const filteredEvents = useMemo(() => {
57
+ let filtered = events;
58
+
59
+ if (!showAllEvents) {
60
+ filtered = filtered.filter((e) => AGENT_EVENT_TYPES.includes(e.type));
61
+ }
62
+
63
+ if (agentFilter !== 'all') {
64
+ filtered = filtered.filter((e) => e.agent === agentFilter);
65
+ }
66
+
67
+ return filtered;
68
+ }, [events, agentFilter, showAllEvents]);
69
+
70
+ return (
71
+ <div className="flex flex-1 min-h-0 flex-col">
72
+ {/* Header */}
73
+ <div className="mb-4 flex items-center justify-between">
74
+ <div className="flex items-center gap-3">
75
+ <Bot className="h-4 w-4 text-primary" />
76
+ <h1 className="text-xl font-light">Agent Activity</h1>
77
+ {!loading && events.length > 0 && (
78
+ <div className="flex items-center gap-1.5">
79
+ <div className={cn('h-2 w-2 animate-pulse-dot rounded-full bg-bid-green', neonGlass && 'glow-green')} />
80
+ <span className="text-xs text-bid-green">Live</span>
81
+ </div>
82
+ )}
83
+ </div>
84
+ <Button
85
+ variant={showAllEvents ? 'default' : 'outline'}
86
+ size="sm"
87
+ onClick={() => setShowAllEvents(!showAllEvents)}
88
+ >
89
+ <Filter className="mr-1.5 h-3.5 w-3.5" />
90
+ {showAllEvents ? 'All Events' : 'Agent Only'}
91
+ </Button>
92
+ </div>
93
+
94
+ {/* Agent filter chips */}
95
+ <div className="mb-4 flex flex-wrap gap-1.5">
96
+ <button
97
+ key="all"
98
+ onClick={() => setAgentFilter('all')}
99
+ className={cn(
100
+ 'inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xxs font-normal transition-colors cursor-pointer',
101
+ agentFilter === 'all'
102
+ ? 'bg-accent-blue/25 text-accent-blue ring-1 ring-accent-blue/40'
103
+ : 'bg-muted/50 text-muted-foreground hover:bg-muted',
104
+ neonGlass && agentFilter === 'all' && 'glow-blue'
105
+ )}
106
+ >
107
+ All Agents
108
+ </button>
109
+ {AGENTS.filter(a => a !== 'all').map((agent) => (
110
+ <AgentFilterChip
111
+ key={agent}
112
+ agent={agent}
113
+ active={agentFilter === agent}
114
+ onClick={() => setAgentFilter(agent)}
115
+ neonGlass={neonGlass}
116
+ />
117
+ ))}
118
+ </div>
119
+
120
+ <Separator className="mb-4" />
121
+
122
+ {/* Event feed */}
123
+ <ScrollArea className="flex-1">
124
+ {loading ? (
125
+ <div className="flex h-32 items-center justify-center">
126
+ <div className="h-6 w-6 animate-spin rounded-full border-2 border-primary border-t-transparent" />
127
+ </div>
128
+ ) : filteredEvents.length === 0 ? (
129
+ <Card>
130
+ <CardContent className="py-12 text-center">
131
+ <Bot className="mx-auto mb-3 h-10 w-10 text-muted-foreground/50" />
132
+ <p className="text-sm text-muted-foreground">
133
+ No agent activity yet. Events will appear here as agents are triggered.
134
+ </p>
135
+ <p className="mt-1 text-xs text-muted-foreground/60">
136
+ Edit a file matching an agent trigger pattern to see agents in action.
137
+ </p>
138
+ </CardContent>
139
+ </Card>
140
+ ) : neonGlass ? (
141
+ <motion.div
142
+ className="space-y-1 pr-4"
143
+ variants={rowStagger}
144
+ initial="hidden"
145
+ animate="show"
146
+ >
147
+ {filteredEvents.map((event) => (
148
+ <motion.div key={event.id} variants={rowItem}>
149
+ <EventRow event={event} />
150
+ </motion.div>
151
+ ))}
152
+ </motion.div>
153
+ ) : (
154
+ <div className="space-y-1 pr-4">
155
+ {filteredEvents.map((event) => (
156
+ <EventRow key={event.id} event={event} />
157
+ ))}
158
+ </div>
159
+ )}
160
+ </ScrollArea>
161
+ </div>
162
+ );
163
+ }
164
+
165
+ // ─── Event Row ─────────────────────────────────────────────
166
+
167
+ function EventRow({ event }: { event: OrbitalEvent }) {
168
+ const data = event.data as Record<string, unknown>;
169
+ const severity = data.severity as string | undefined;
170
+ const severityConfig = severity ? SEVERITY_CONFIG[severity] : null;
171
+
172
+ return (
173
+ <div className="group flex items-start gap-3 rounded px-2.5 py-1.5 transition-colors hover:bg-surface-light animate-slide-up">
174
+ {/* Timestamp */}
175
+ <span className="mt-0.5 flex-shrink-0 font-mono text-xs text-muted-foreground/60">
176
+ {format(new Date(event.timestamp), 'HH:mm:ss')}
177
+ </span>
178
+
179
+ {/* Agent badge */}
180
+ <div className="flex-shrink-0">
181
+ {event.agent ? (
182
+ <AgentBadge agent={event.agent} showLabel={false} />
183
+ ) : (
184
+ <span className="inline-flex h-6 w-6 items-center justify-center text-xs">
185
+ {getEventIcon(event.type)}
186
+ </span>
187
+ )}
188
+ </div>
189
+
190
+ {/* Content */}
191
+ <div className="min-w-0 flex-1">
192
+ <div className="flex items-center gap-2">
193
+ <span className="text-xs font-normal">
194
+ {formatEventMessage(event)}
195
+ </span>
196
+ {severityConfig && (
197
+ <Badge
198
+ className={cn(
199
+ 'text-[10px] px-1.5 py-0',
200
+ severityConfig.color
201
+ )}
202
+ >
203
+ {severityConfig.label}
204
+ </Badge>
205
+ )}
206
+ </div>
207
+
208
+ {/* Detail message */}
209
+ {'message' in data && data.message != null && (
210
+ <p className="mt-0.5 text-xxs text-muted-foreground line-clamp-2">
211
+ {String(data.message)}
212
+ </p>
213
+ )}
214
+
215
+ {/* File path */}
216
+ {'file' in data && data.file != null && (
217
+ <span className="mt-0.5 inline-block font-mono text-[10px] text-muted-foreground/60">
218
+ {String(data.file)}
219
+ </span>
220
+ )}
221
+
222
+ {/* Scope reference */}
223
+ {event.scope_id && (
224
+ <span className="ml-2 font-mono text-[10px] text-muted-foreground/60">
225
+ scope {formatScopeId(event.scope_id)}
226
+ </span>
227
+ )}
228
+ </div>
229
+
230
+ {/* Relative time */}
231
+ <span className="flex-shrink-0 text-[10px] text-muted-foreground/40 opacity-0 transition-opacity group-hover:opacity-100">
232
+ {formatDistanceToNow(new Date(event.timestamp), { addSuffix: true })}
233
+ </span>
234
+ </div>
235
+ );
236
+ }
237
+
238
+ function formatEventMessage(event: OrbitalEvent): string {
239
+ const data = event.data as Record<string, unknown>;
240
+
241
+ switch (event.type) {
242
+ case 'AGENT_STARTED':
243
+ return `${event.agent ?? 'Agent'} started reviewing`;
244
+ case 'AGENT_FINDING':
245
+ return `${event.agent ?? 'Agent'} found issue`;
246
+ case 'AGENT_COMPLETED':
247
+ return `${event.agent ?? 'Agent'} completed (${data.status ?? 'done'})`;
248
+ case 'AGENT_CONSENSUS':
249
+ return `Consensus: ${data.consensus ?? 'reached'}`;
250
+ case 'SESSION_START':
251
+ return 'Session started';
252
+ case 'SESSION_END':
253
+ return 'Session ended';
254
+ case 'SKILL_INVOKED':
255
+ return `Skill invoked: ${data.skill ?? 'unknown'}`;
256
+ case 'GATE_PASSED':
257
+ return `Gate passed: ${data.gate ?? 'unknown'}`;
258
+ case 'GATE_FAILED':
259
+ return `Gate failed: ${data.gate ?? 'unknown'}`;
260
+ case 'COMMIT_CREATED':
261
+ return `Commit: ${String(data.message ?? data.sha ?? '').slice(0, 50)}`;
262
+ case 'PR_CREATED':
263
+ return `PR #${data.number ?? '?'} created`;
264
+ case 'DEPLOY_STARTED':
265
+ return `Deploying to ${data.environment ?? 'unknown'}`;
266
+ case 'DEPLOY_HEALTHY':
267
+ return `Deploy healthy on ${data.environment ?? 'unknown'}`;
268
+ case 'SCOPE_STATUS_CHANGED':
269
+ return `Scope moved: ${data.from ?? '?'} → ${data.to ?? '?'}`;
270
+ case 'VIOLATION':
271
+ return `Violation: ${data.rule ?? 'unknown rule'} blocked`;
272
+ case 'OVERRIDE':
273
+ return `Override: ${data.rule ?? 'unknown rule'} (${data.reason ?? 'no reason'})`;
274
+ case 'COMMIT':
275
+ return `Scope commit: ${String(data.hash ?? '').slice(0, 7)} ${String(data.message ?? '').slice(0, 40)}`;
276
+ case 'SCOPE_TRANSITION':
277
+ return `Scope ${data.scope_name ?? '?'}: \u2192 ${data.to ?? '?'}`;
278
+ case 'PATTERN_DETECTED':
279
+ return `Pattern detected: ${data.rule ?? '?'} (confidence: ${data.confidence ?? '?'})`;
280
+ case 'RULE_PROPOSED':
281
+ return `Rule proposed: ${String(data.rule_text ?? '').slice(0, 50)}`;
282
+ default:
283
+ return event.type.replace(/_/g, ' ').toLowerCase();
284
+ }
285
+ }
286
+
287
+ // ─── Agent Filter Chip ──────────────────────────────────────
288
+
289
+ const AGENT_CHIP_CONFIG: Record<string, { emoji: string; label: string; color: string; activeColor: string; glowClass: string }> = {
290
+ 'attacker': { emoji: '\u{1F5E1}\u{FE0F}', label: 'Attacker', color: 'text-agent-attacker', activeColor: 'bg-agent-attacker/25 ring-1 ring-agent-attacker/40', glowClass: 'glow-red' },
291
+ 'chaos': { emoji: '\u{1F4A5}', label: 'Chaos', color: 'text-agent-chaos', activeColor: 'bg-agent-chaos/25 ring-1 ring-agent-chaos/40', glowClass: 'glow-amber' },
292
+ 'solana-expert': { emoji: '\u{26D3}\u{FE0F}', label: 'Solana', color: 'text-agent-solana', activeColor: 'bg-agent-solana/25 ring-1 ring-agent-solana/40', glowClass: 'glow-purple' },
293
+ 'frontend-designer': { emoji: '\u{1F3A8}', label: 'Frontend', color: 'text-agent-frontend', activeColor: 'bg-agent-frontend/25 ring-1 ring-agent-frontend/40', glowClass: 'glow-red' },
294
+ 'architect': { emoji: '\u{1F3D7}\u{FE0F}', label: 'Architect', color: 'text-agent-architect', activeColor: 'bg-agent-architect/25 ring-1 ring-agent-architect/40', glowClass: 'glow-blue' },
295
+ 'rules-enforcer': { emoji: '\u{1F4CB}', label: 'Rules', color: 'text-agent-rules', activeColor: 'bg-agent-rules/25 ring-1 ring-agent-rules/40', glowClass: '' },
296
+ };
297
+
298
+ function AgentFilterChip({ agent, active, onClick, neonGlass }: { agent: string; active: boolean; onClick: () => void; neonGlass: boolean }) {
299
+ const config = AGENT_CHIP_CONFIG[agent] ?? { emoji: '\u{1F916}', label: agent, color: 'text-muted-foreground', activeColor: 'bg-muted ring-1 ring-border', glowClass: '' };
300
+ return (
301
+ <button
302
+ onClick={onClick}
303
+ className={cn(
304
+ 'inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xxs font-normal transition-colors cursor-pointer',
305
+ active
306
+ ? cn(config.color, config.activeColor, neonGlass && config.glowClass)
307
+ : cn('bg-muted/50 text-muted-foreground hover:bg-muted')
308
+ )}
309
+ >
310
+ <span>{config.emoji}</span>
311
+ <span>{config.label}</span>
312
+ </button>
313
+ );
314
+ }
315
+
316
+ function getEventIcon(type: string): string {
317
+ const icons: Record<string, string> = {
318
+ SESSION_START: '\u{1F7E2}',
319
+ SESSION_END: '\u{1F534}',
320
+ SKILL_INVOKED: '\u{1F527}',
321
+ GATE_PASSED: '\u2705',
322
+ GATE_FAILED: '\u274C',
323
+ COMMIT_CREATED: '\u{1F4BE}',
324
+ PR_CREATED: '\u{1F517}',
325
+ DEPLOY_STARTED: '\u{1F680}',
326
+ DEPLOY_HEALTHY: '\u{1F49A}',
327
+ DEPLOY_FAILED: '\u{1F4A5}',
328
+ BUILD_COMPLETED: '\u{1F3D7}\u{FE0F}',
329
+ TESTS_COMPLETED: '\u{1F9EA}',
330
+ SCOPE_STATUS_CHANGED: '\u{1F504}',
331
+ VIOLATION: '\u{1F6D1}',
332
+ OVERRIDE: '\u{26A0}\u{FE0F}',
333
+ COMMIT: '\u{1F4DD}',
334
+ SCOPE_TRANSITION: '\u{1F500}',
335
+ PATTERN_DETECTED: '\u{1F50D}',
336
+ RULE_PROPOSED: '\u{1F4CB}',
337
+ };
338
+ return icons[type] ?? '\u{1F4E1}';
339
+ }
@@ -0,0 +1,59 @@
1
+ import { Rocket } from 'lucide-react';
2
+ import { Badge } from '@/components/ui/badge';
3
+ import { usePipeline } from '@/hooks/usePipeline';
4
+ import { EnvironmentStrip } from '@/components/EnvironmentStrip';
5
+ import { PromotionQueue } from '@/components/PromotionQueue';
6
+ import { DriftSidebar } from '@/components/DriftSidebar';
7
+ import { DeployHistory } from '@/components/DeployHistory';
8
+
9
+ export function DeployPipeline() {
10
+ const { drift, frequency, deployments, loading } = usePipeline();
11
+
12
+ if (loading) {
13
+ return (
14
+ <div className="flex h-64 items-center justify-center">
15
+ <div className="h-8 w-8 animate-spin rounded-full border-2 border-primary border-t-transparent" />
16
+ </div>
17
+ );
18
+ }
19
+
20
+ return (
21
+ <div className="flex-1 min-h-0 overflow-y-auto">
22
+ {/* Header */}
23
+ <div className="mb-6 flex items-center gap-3">
24
+ <Rocket className="h-4 w-4 text-primary" />
25
+ <h1 className="text-xl font-light">Deploy Pipeline</h1>
26
+ {deployments.length > 0 && (
27
+ <Badge variant="secondary">
28
+ {deployments.length} deploys
29
+ </Badge>
30
+ )}
31
+ </div>
32
+
33
+ {/* Section 1: Environment Status Strip */}
34
+ {drift && (
35
+ <div className="mb-6">
36
+ <EnvironmentStrip drift={drift} />
37
+ </div>
38
+ )}
39
+
40
+ {/* Section 2 + 3: Promotion Queue + Sidebar */}
41
+ {drift && (
42
+ <div className="mb-6 grid gap-6 lg:grid-cols-3">
43
+ <PromotionQueue
44
+ devToStaging={drift.devToStaging}
45
+ stagingToMain={drift.stagingToMain}
46
+ />
47
+ <DriftSidebar
48
+ drift={drift}
49
+ frequency={frequency}
50
+ deployments={deployments}
51
+ />
52
+ </div>
53
+ )}
54
+
55
+ {/* Section 4: Deployment History */}
56
+ <DeployHistory deployments={deployments} />
57
+ </div>
58
+ );
59
+ }