code-coordinator 0.5.46__py3-none-any.whl

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 (295) hide show
  1. code_coordinator-0.5.46.dist-info/METADATA +625 -0
  2. code_coordinator-0.5.46.dist-info/RECORD +295 -0
  3. code_coordinator-0.5.46.dist-info/WHEEL +5 -0
  4. code_coordinator-0.5.46.dist-info/entry_points.txt +2 -0
  5. code_coordinator-0.5.46.dist-info/licenses/LICENSE +110 -0
  6. code_coordinator-0.5.46.dist-info/top_level.txt +1 -0
  7. coord/__init__.py +176 -0
  8. coord/_board_mapping.py +229 -0
  9. coord/acceptance.py +468 -0
  10. coord/acceptance_drivers.py +632 -0
  11. coord/agent.py +7517 -0
  12. coord/agent_app.py +1555 -0
  13. coord/agent_update.py +417 -0
  14. coord/agents/opencode/.gitignore +13 -0
  15. coord/agents/opencode/agents/work.md +129 -0
  16. coord/agents/opencode/routing.jsonc +49 -0
  17. coord/audit.py +301 -0
  18. coord/auto_loop.py +1440 -0
  19. coord/board_bool_guard.py +72 -0
  20. coord/board_service.py +141 -0
  21. coord/board_wire.py +309 -0
  22. coord/brain.py +581 -0
  23. coord/branch_model.py +214 -0
  24. coord/cargo_cache.py +258 -0
  25. coord/ci_github.py +386 -0
  26. coord/ci_store.py +560 -0
  27. coord/claim.py +353 -0
  28. coord/cli.py +454 -0
  29. coord/client.py +610 -0
  30. coord/commands/__init__.py +1 -0
  31. coord/commands/_common.py +329 -0
  32. coord/commands/acceptance.py +916 -0
  33. coord/commands/agent_ops.py +1339 -0
  34. coord/commands/audit.py +131 -0
  35. coord/commands/chat.py +320 -0
  36. coord/commands/dispatch.py +1780 -0
  37. coord/commands/dispatch_workers.py +4894 -0
  38. coord/commands/drive.py +616 -0
  39. coord/commands/drive_queue.py +1203 -0
  40. coord/commands/gate_a.py +217 -0
  41. coord/commands/gates.py +89 -0
  42. coord/commands/issues.py +681 -0
  43. coord/commands/lifecycle.py +513 -0
  44. coord/commands/merge.py +1900 -0
  45. coord/commands/milestone.py +2081 -0
  46. coord/commands/plan_followup.py +1243 -0
  47. coord/commands/plans.py +156 -0
  48. coord/commands/release.py +2232 -0
  49. coord/commands/report.py +341 -0
  50. coord/commands/review.py +1523 -0
  51. coord/commands/scorecard.py +252 -0
  52. coord/commands/sessions.py +1930 -0
  53. coord/commands/setup.py +576 -0
  54. coord/commands/status.py +2089 -0
  55. coord/commands/terminal.py +385 -0
  56. coord/commands/test_gate.py +775 -0
  57. coord/commands/tui.py +288 -0
  58. coord/comments.py +718 -0
  59. coord/config.py +3032 -0
  60. coord/conflict_fix.py +633 -0
  61. coord/dao.py +483 -0
  62. coord/dashboard/__init__.py +0 -0
  63. coord/dashboard/fixture.py +376 -0
  64. coord/dashboard/index.html +658 -0
  65. coord/dashboard/server.py +1894 -0
  66. coord/dashboard/terminal.py +382 -0
  67. coord/dashboard/webapp/.gitignore +9 -0
  68. coord/dashboard/webapp/components.json +17 -0
  69. coord/dashboard/webapp/dist/assets/Gallery-da3qNiIw.js +71 -0
  70. coord/dashboard/webapp/dist/assets/Terminal-9CEnUXvW.css +32 -0
  71. coord/dashboard/webapp/dist/assets/Terminal-skVFCxPU.js +63 -0
  72. coord/dashboard/webapp/dist/assets/index-DltfZR5f.js +184 -0
  73. coord/dashboard/webapp/dist/assets/index-Dq4kwTdw.css +1 -0
  74. coord/dashboard/webapp/dist/assets/workbox-window.prod.es5-BqEJf4Xk.js +2 -0
  75. coord/dashboard/webapp/dist/icons/icon-192.png +0 -0
  76. coord/dashboard/webapp/dist/icons/icon-512.png +0 -0
  77. coord/dashboard/webapp/dist/icons/icon.svg +5 -0
  78. coord/dashboard/webapp/dist/index.html +38 -0
  79. coord/dashboard/webapp/dist/manifest.webmanifest +1 -0
  80. coord/dashboard/webapp/dist/sw.js +1 -0
  81. coord/dashboard/webapp/dist/workbox-e4022e15.js +1 -0
  82. coord/dashboard/webapp/e2e/available-gates-terminal.spec.ts +75 -0
  83. coord/dashboard/webapp/e2e/deep-link.spec.ts +172 -0
  84. coord/dashboard/webapp/e2e/fixtureServer.ts +155 -0
  85. coord/dashboard/webapp/e2e/live-update-fixture.spec.ts +113 -0
  86. coord/dashboard/webapp/e2e/realtime.spec.ts +238 -0
  87. coord/dashboard/webapp/e2e/shell.spec.ts +309 -0
  88. coord/dashboard/webapp/e2e/smoke.spec.ts +191 -0
  89. coord/dashboard/webapp/e2e/terminal.spec.ts +420 -0
  90. coord/dashboard/webapp/e2e/theme.spec.ts +138 -0
  91. coord/dashboard/webapp/eslint.config.js +20 -0
  92. coord/dashboard/webapp/index.html +37 -0
  93. coord/dashboard/webapp/node_modules/flatted/python/flatted.py +144 -0
  94. coord/dashboard/webapp/package-lock.json +10584 -0
  95. coord/dashboard/webapp/package.json +63 -0
  96. coord/dashboard/webapp/playwright.acceptance.config.ts +166 -0
  97. coord/dashboard/webapp/playwright.config.ts +93 -0
  98. coord/dashboard/webapp/postcss.config.js +6 -0
  99. coord/dashboard/webapp/public/icons/icon-192.png +0 -0
  100. coord/dashboard/webapp/public/icons/icon-512.png +0 -0
  101. coord/dashboard/webapp/public/icons/icon.svg +5 -0
  102. coord/dashboard/webapp/src/App.tsx +140 -0
  103. coord/dashboard/webapp/src/api/client.ts +199 -0
  104. coord/dashboard/webapp/src/api/generated.ts +176 -0
  105. coord/dashboard/webapp/src/components/ConnectionBadge.tsx +52 -0
  106. coord/dashboard/webapp/src/components/Detail.tsx +800 -0
  107. coord/dashboard/webapp/src/components/Gallery.tsx +341 -0
  108. coord/dashboard/webapp/src/components/Home.tsx +435 -0
  109. coord/dashboard/webapp/src/components/MobileKeyBar.tsx +280 -0
  110. coord/dashboard/webapp/src/components/PanelHeader.tsx +59 -0
  111. coord/dashboard/webapp/src/components/PipelineCard.tsx +168 -0
  112. coord/dashboard/webapp/src/components/SessionCard.tsx +99 -0
  113. coord/dashboard/webapp/src/components/SessionDetail.tsx +140 -0
  114. coord/dashboard/webapp/src/components/SessionsList.tsx +81 -0
  115. coord/dashboard/webapp/src/components/Terminal.tsx +376 -0
  116. coord/dashboard/webapp/src/components/__tests__/ConnectionBadge.test.tsx +81 -0
  117. coord/dashboard/webapp/src/components/__tests__/Detail.test.tsx +680 -0
  118. coord/dashboard/webapp/src/components/__tests__/Gallery.test.tsx +83 -0
  119. coord/dashboard/webapp/src/components/__tests__/Home.test.tsx +271 -0
  120. coord/dashboard/webapp/src/components/__tests__/MobileKeyBar.test.tsx +197 -0
  121. coord/dashboard/webapp/src/components/__tests__/PipelineCard.test.tsx +143 -0
  122. coord/dashboard/webapp/src/components/__tests__/SessionCard.test.tsx +106 -0
  123. coord/dashboard/webapp/src/components/__tests__/Terminal.test.tsx +504 -0
  124. coord/dashboard/webapp/src/components/ui/badge.tsx +41 -0
  125. coord/dashboard/webapp/src/components/ui/button.tsx +54 -0
  126. coord/dashboard/webapp/src/components/ui/card.tsx +55 -0
  127. coord/dashboard/webapp/src/components/ui/dialog.tsx +99 -0
  128. coord/dashboard/webapp/src/components/ui/dropdown-menu.tsx +189 -0
  129. coord/dashboard/webapp/src/components/ui/empty-state.tsx +35 -0
  130. coord/dashboard/webapp/src/components/ui/sheet.tsx +123 -0
  131. coord/dashboard/webapp/src/components/ui/skeleton.tsx +9 -0
  132. coord/dashboard/webapp/src/components/ui/tabs.tsx +55 -0
  133. coord/dashboard/webapp/src/components/ui/theme-provider.tsx +78 -0
  134. coord/dashboard/webapp/src/components/ui/theme-toggle.tsx +20 -0
  135. coord/dashboard/webapp/src/components/ui/toast.tsx +123 -0
  136. coord/dashboard/webapp/src/components/ui/toaster.tsx +30 -0
  137. coord/dashboard/webapp/src/components/ui/tooltip.tsx +26 -0
  138. coord/dashboard/webapp/src/components/ui/use-toast.ts +134 -0
  139. coord/dashboard/webapp/src/index.css +210 -0
  140. coord/dashboard/webapp/src/lib/pipeline.ts +29 -0
  141. coord/dashboard/webapp/src/lib/utils.ts +6 -0
  142. coord/dashboard/webapp/src/main.tsx +46 -0
  143. coord/dashboard/webapp/src/realtime/RealtimeProvider.tsx +112 -0
  144. coord/dashboard/webapp/src/realtime/__tests__/RealtimeProvider.test.tsx +189 -0
  145. coord/dashboard/webapp/src/realtime/__tests__/connection.test.ts +255 -0
  146. coord/dashboard/webapp/src/realtime/connection.ts +227 -0
  147. coord/dashboard/webapp/src/realtime/events.ts +100 -0
  148. coord/dashboard/webapp/src/routes/__tests__/paths.test.ts +92 -0
  149. coord/dashboard/webapp/src/routes/paths.ts +92 -0
  150. coord/dashboard/webapp/src/shell/ActivityRail.tsx +335 -0
  151. coord/dashboard/webapp/src/shell/AppShell.tsx +276 -0
  152. coord/dashboard/webapp/src/shell/ComingSoon.tsx +33 -0
  153. coord/dashboard/webapp/src/shell/EmptyDetail.tsx +26 -0
  154. coord/dashboard/webapp/src/shell/RouteNotFound.tsx +33 -0
  155. coord/dashboard/webapp/src/shell/ShellLayout.tsx +147 -0
  156. coord/dashboard/webapp/src/shell/StatusBar.tsx +46 -0
  157. coord/dashboard/webapp/src/shell/__tests__/ShellLayout.test.tsx +520 -0
  158. coord/dashboard/webapp/src/shell/__tests__/shellState.test.ts +95 -0
  159. coord/dashboard/webapp/src/shell/__tests__/stubViewport.ts +40 -0
  160. coord/dashboard/webapp/src/shell/breakpoints.ts +87 -0
  161. coord/dashboard/webapp/src/shell/railItems.ts +105 -0
  162. coord/dashboard/webapp/src/shell/shellState.ts +174 -0
  163. coord/dashboard/webapp/src/shell/useRegionFocus.ts +95 -0
  164. coord/dashboard/webapp/src/test-setup.ts +41 -0
  165. coord/dashboard/webapp/src/vite-env.d.ts +2 -0
  166. coord/dashboard/webapp/tailwind.config.js +140 -0
  167. coord/dashboard/webapp/tsconfig.json +25 -0
  168. coord/dashboard/webapp/tsconfig.node.json +11 -0
  169. coord/dashboard/webapp/vite.config.ts +71 -0
  170. coord/db.py +1076 -0
  171. coord/dead_end.py +332 -0
  172. coord/deploy/README.md +33 -0
  173. coord/deploy/coord-agent.service +89 -0
  174. coord/deploy/coord-db-backup.service +60 -0
  175. coord/deploy/coord-db-backup.sh +74 -0
  176. coord/deploy/coord-db-backup.timer +18 -0
  177. coord/deploy/coord-drive-queue.service +117 -0
  178. coord/deploy/coord-drive-queue.timer +39 -0
  179. coord/deploy/coord-notify.service +48 -0
  180. coord/deploy/coord-notify.timer +24 -0
  181. coord/deploy/coord-release-propagate.service +83 -0
  182. coord/deploy/coord-release-propagate.timer +38 -0
  183. coord/deploy/coord-release-window.service +119 -0
  184. coord/deploy/coord-release-window.timer +36 -0
  185. coord/deploy/coord-serve.service +82 -0
  186. coord/deploy/coord-web-dist-build.service +43 -0
  187. coord/deploy/coord-web-dist-build.timer +36 -0
  188. coord/deploy/coord-web.service +125 -0
  189. coord/deploy_manifest.py +80 -0
  190. coord/deploy_units.py +384 -0
  191. coord/deps.py +115 -0
  192. coord/diagnose.py +1623 -0
  193. coord/dispatch.py +1009 -0
  194. coord/dist_name.py +123 -0
  195. coord/drive.py +3101 -0
  196. coord/drive_queue.py +2298 -0
  197. coord/drive_state.py +870 -0
  198. coord/events.py +381 -0
  199. coord/failure_class.py +914 -0
  200. coord/filelock.py +168 -0
  201. coord/fleet_config_health.py +300 -0
  202. coord/freshness.py +206 -0
  203. coord/gate_a.py +469 -0
  204. coord/gate_b.py +411 -0
  205. coord/gate_snapshot.py +385 -0
  206. coord/gates.py +582 -0
  207. coord/github_ops.py +1954 -0
  208. coord/goal.py +125 -0
  209. coord/graph_health.py +348 -0
  210. coord/health/__init__.py +69 -0
  211. coord/health/aggregate.py +129 -0
  212. coord/health/checks/__init__.py +13 -0
  213. coord/health/checks/agent_install.py +280 -0
  214. coord/health/checks/cargo_targets.py +171 -0
  215. coord/health/checks/claude_binary.py +65 -0
  216. coord/health/checks/deploy_lane_facts.py +458 -0
  217. coord/health/checks/disk.py +99 -0
  218. coord/health/checks/fleet_board.py +89 -0
  219. coord/health/checks/fleet_deploy_lanes.py +469 -0
  220. coord/health/checks/fleet_phantom.py +69 -0
  221. coord/health/checks/fleet_unit_drift.py +151 -0
  222. coord/health/checks/graph.py +192 -0
  223. coord/health/checks/plan_usage.py +88 -0
  224. coord/health/checks/repo_state.py +161 -0
  225. coord/health/checks/spawned_coord.py +465 -0
  226. coord/health/checks/timer_active.py +254 -0
  227. coord/health/checks/toolchain.py +547 -0
  228. coord/health/checks/unit_drift.py +648 -0
  229. coord/health/checks/unit_enablement.py +171 -0
  230. coord/health/checks/worktrees.py +96 -0
  231. coord/health/cli.py +121 -0
  232. coord/health/context.py +106 -0
  233. coord/health/fleet_snapshot.py +477 -0
  234. coord/health/models.py +250 -0
  235. coord/health/pypi.py +231 -0
  236. coord/health/registry.py +240 -0
  237. coord/health/render.py +82 -0
  238. coord/health/units.py +60 -0
  239. coord/hooks.py +106 -0
  240. coord/housekeeping.py +204 -0
  241. coord/interactive.py +4286 -0
  242. coord/issue_store.py +1496 -0
  243. coord/liveness_auditor.py +293 -0
  244. coord/machine_pause.py +755 -0
  245. coord/merge_queue.py +4681 -0
  246. coord/milestone_chat.py +600 -0
  247. coord/milestone_dispatch.py +943 -0
  248. coord/milestone_gate.py +709 -0
  249. coord/milestone_order.py +840 -0
  250. coord/mock_author.py +334 -0
  251. coord/models.py +891 -0
  252. coord/network.py +269 -0
  253. coord/new_issue_chat.py +229 -0
  254. coord/notify.py +3226 -0
  255. coord/openapi.py +404 -0
  256. coord/overlap_fence.py +133 -0
  257. coord/parentage.py +200 -0
  258. coord/parentage_github.py +58 -0
  259. coord/pipeline.py +481 -0
  260. coord/plan_parser.py +266 -0
  261. coord/plans.py +543 -0
  262. coord/platform_paths.py +43 -0
  263. coord/pr_body_lint.py +67 -0
  264. coord/prereqs.py +533 -0
  265. coord/progress.py +425 -0
  266. coord/providers/__init__.py +683 -0
  267. coord/providers/base.py +218 -0
  268. coord/providers/claude.py +284 -0
  269. coord/providers/claude_pty.py +610 -0
  270. coord/providers/opencode.py +896 -0
  271. coord/reconcile.py +2233 -0
  272. coord/refine_chat.py +485 -0
  273. coord/release_cordon.py +525 -0
  274. coord/release_propagate.py +1176 -0
  275. coord/release_verify.py +777 -0
  276. coord/release_window.py +322 -0
  277. coord/reports.py +1643 -0
  278. coord/revalidate.py +1101 -0
  279. coord/review.py +3317 -0
  280. coord/scorecard.py +484 -0
  281. coord/serve_app.py +7192 -0
  282. coord/skills/update-issue/SKILL.md +93 -0
  283. coord/smoke.py +1030 -0
  284. coord/split_work.py +210 -0
  285. coord/stage_projection.py +650 -0
  286. coord/state.py +5720 -0
  287. coord/test_author.py +1064 -0
  288. coord/test_chat.py +352 -0
  289. coord/test_orchestrator.py +494 -0
  290. coord/test_report.py +178 -0
  291. coord/tui_release.py +271 -0
  292. coord/usage.py +753 -0
  293. coord/usage_limits.py +358 -0
  294. coord/usage_rollup.py +709 -0
  295. coord/worker_events.py +954 -0
@@ -0,0 +1,341 @@
1
+ /**
2
+ * Component gallery (#1546) — dev-only route (`/gallery`, guarded by
3
+ * `import.meta.env.DEV` in App.tsx) rendering every ui/* primitive. This is
4
+ * the fastest way for a human, or a Playwright acceptance slice, to see the
5
+ * whole design-token + primitive system at once instead of hunting through
6
+ * the app for one usage of each.
7
+ *
8
+ * Two proof mechanisms for "renders correctly in both themes":
9
+ * - The live `<ThemeToggle>` at the top drives the real `data-theme` on
10
+ * <html>, exactly like the shipped app. Flipping it re-themes *every*
11
+ * primitive on this page, including the ones below that portal to
12
+ * `document.body` (Dialog/Sheet/DropdownMenu/Toast) — portals only
13
+ * change where a node sits in the React tree, not the DOM, so they stay
14
+ * inside <html> and inherit its `data-theme` cascade regardless.
15
+ * - The "side by side" section at the bottom forces dark and light in two
16
+ * adjacent panes at once via a *non-portalled* subtree, for the
17
+ * non-overlay primitives (Button/Badge/Card/Skeleton/EmptyState) where a
18
+ * true simultaneous comparison is cheap. Overlay primitives aren't
19
+ * duplicated there — they'd portal out of the forced-theme pane and
20
+ * misleadingly render in whatever theme is live instead.
21
+ */
22
+ import { useState, type ReactNode } from 'react'
23
+ import { AlertTriangle, Inbox, MoreHorizontal, Play, Terminal as TerminalIcon } from 'lucide-react'
24
+ import { Button } from '@/components/ui/button'
25
+ import { Badge } from '@/components/ui/badge'
26
+ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
27
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
28
+ import {
29
+ Dialog,
30
+ DialogContent,
31
+ DialogDescription,
32
+ DialogFooter,
33
+ DialogHeader,
34
+ DialogTitle,
35
+ DialogTrigger,
36
+ } from '@/components/ui/dialog'
37
+ import {
38
+ DropdownMenu,
39
+ DropdownMenuContent,
40
+ DropdownMenuItem,
41
+ DropdownMenuLabel,
42
+ DropdownMenuSeparator,
43
+ DropdownMenuShortcut,
44
+ DropdownMenuTrigger,
45
+ } from '@/components/ui/dropdown-menu'
46
+ import {
47
+ Sheet,
48
+ SheetContent,
49
+ SheetDescription,
50
+ SheetHeader,
51
+ SheetTitle,
52
+ SheetTrigger,
53
+ } from '@/components/ui/sheet'
54
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
55
+ import { Skeleton } from '@/components/ui/skeleton'
56
+ import { EmptyState } from '@/components/ui/empty-state'
57
+ import { Toaster } from '@/components/ui/toaster'
58
+ import { toast } from '@/components/ui/use-toast'
59
+ import { ThemeProvider, useTheme } from '@/components/ui/theme-provider'
60
+ import { ThemeToggle } from '@/components/ui/theme-toggle'
61
+
62
+ function Section({ title, children }: { title: string; children: ReactNode }) {
63
+ return (
64
+ <section className="flex flex-col gap-3">
65
+ <h2 className="text-step-1 font-semibold tracking-tight">{title}</h2>
66
+ <div className="flex flex-wrap items-center gap-3">{children}</div>
67
+ </section>
68
+ )
69
+ }
70
+
71
+ function GalleryBody() {
72
+ const { theme } = useTheme()
73
+ const [tab, setTab] = useState('overview')
74
+
75
+ return (
76
+ <div className="mx-auto flex max-w-3xl flex-col gap-10 p-6 sm:p-10">
77
+ <header className="flex items-start justify-between gap-4 border-b border-border pb-6">
78
+ <div>
79
+ <h1 className="text-step-3 font-semibold tracking-tight">Component gallery</h1>
80
+ <p className="mt-1 text-sm text-muted-foreground">
81
+ coord web's design tokens + shadcn/ui primitive inventory (#1546). Dev-only —
82
+ route-guarded out of reach in production (see App.tsx).
83
+ </p>
84
+ </div>
85
+ <div className="flex items-center gap-2 text-sm text-muted-foreground">
86
+ <span className="mono">{theme}</span>
87
+ <ThemeToggle />
88
+ </div>
89
+ </header>
90
+
91
+ <Section title="Button">
92
+ <Button>Primary</Button>
93
+ <Button variant="outline">Outline</Button>
94
+ <Button variant="secondary">Secondary</Button>
95
+ <Button variant="ghost">Ghost</Button>
96
+ <Button variant="destructive">Destructive</Button>
97
+ <Button variant="link">Link</Button>
98
+ <Button size="sm">Small</Button>
99
+ <Button size="lg">Large</Button>
100
+ <Button size="icon" aria-label="Play">
101
+ <Play />
102
+ </Button>
103
+ <Button disabled>Disabled</Button>
104
+ </Section>
105
+
106
+ <Section title="Badge">
107
+ <Badge>Default</Badge>
108
+ <Badge variant="secondary">Secondary</Badge>
109
+ <Badge variant="outline">Outline</Badge>
110
+ <Badge variant="success">Passed</Badge>
111
+ <Badge variant="warning">3 findings</Badge>
112
+ <Badge variant="destructive">Failed</Badge>
113
+ </Section>
114
+
115
+ <Section title="Card">
116
+ <Card className="w-full max-w-sm">
117
+ <CardHeader>
118
+ <CardTitle>W1-1: design tokens</CardTitle>
119
+ <CardDescription>#1546 · claude-coordinator</CardDescription>
120
+ </CardHeader>
121
+ <CardContent className="text-sm text-muted-foreground">
122
+ Dark/light theme, component primitive baseline.
123
+ </CardContent>
124
+ <CardFooter className="gap-2">
125
+ <Badge variant="success">Test · passed</Badge>
126
+ <span className="mono ml-auto text-xs text-faint">18m</span>
127
+ </CardFooter>
128
+ </Card>
129
+ </Section>
130
+
131
+ <Section title="Tabs">
132
+ <Tabs value={tab} onValueChange={setTab} className="w-full">
133
+ <TabsList>
134
+ <TabsTrigger value="overview">Overview</TabsTrigger>
135
+ <TabsTrigger value="findings">
136
+ Findings <span className="ml-1 rounded-full bg-secondary px-1.5 text-faint">3</span>
137
+ </TabsTrigger>
138
+ <TabsTrigger value="log">Log</TabsTrigger>
139
+ </TabsList>
140
+ <TabsContent value="overview" className="text-sm text-muted-foreground">
141
+ Overview panel content.
142
+ </TabsContent>
143
+ <TabsContent value="findings" className="text-sm text-muted-foreground">
144
+ Findings panel content.
145
+ </TabsContent>
146
+ <TabsContent value="log" className="text-sm text-muted-foreground">
147
+ Log panel content.
148
+ </TabsContent>
149
+ </Tabs>
150
+ </Section>
151
+
152
+ <Section title="Dialog">
153
+ <Dialog>
154
+ <DialogTrigger asChild>
155
+ <Button variant="outline">Open dialog</Button>
156
+ </DialogTrigger>
157
+ <DialogContent>
158
+ <DialogHeader>
159
+ <DialogTitle>Drop to backlog?</DialogTitle>
160
+ <DialogDescription>
161
+ The session will stop and the branch stays as-is. You can resume from the
162
+ backlog later.
163
+ </DialogDescription>
164
+ </DialogHeader>
165
+ <DialogFooter>
166
+ <Button variant="outline">Cancel</Button>
167
+ <Button variant="destructive">Drop to backlog</Button>
168
+ </DialogFooter>
169
+ </DialogContent>
170
+ </Dialog>
171
+ </Section>
172
+
173
+ <Section title="Dropdown menu">
174
+ <DropdownMenu>
175
+ <DropdownMenuTrigger asChild>
176
+ <Button variant="outline" size="icon" aria-label="More actions">
177
+ <MoreHorizontal />
178
+ </Button>
179
+ </DropdownMenuTrigger>
180
+ <DropdownMenuContent align="end">
181
+ <DropdownMenuLabel>Start — interactive</DropdownMenuLabel>
182
+ <DropdownMenuItem>
183
+ <Play /> Work
184
+ <DropdownMenuShortcut>W</DropdownMenuShortcut>
185
+ </DropdownMenuItem>
186
+ <DropdownMenuItem>
187
+ <TerminalIcon /> Testing
188
+ <DropdownMenuShortcut>T</DropdownMenuShortcut>
189
+ </DropdownMenuItem>
190
+ <DropdownMenuSeparator />
191
+ <DropdownMenuItem variant="hot">
192
+ <AlertTriangle /> Address review findings
193
+ </DropdownMenuItem>
194
+ <DropdownMenuItem variant="danger">Stop session</DropdownMenuItem>
195
+ </DropdownMenuContent>
196
+ </DropdownMenu>
197
+ </Section>
198
+
199
+ <Section title="Sheet (mobile action sheet)">
200
+ <Sheet>
201
+ <SheetTrigger asChild>
202
+ <Button variant="outline">Open action sheet</Button>
203
+ </SheetTrigger>
204
+ <SheetContent side="bottom">
205
+ <SheetHeader>
206
+ <SheetTitle>#1289 · Tab-group focus ring</SheetTitle>
207
+ <SheetDescription>Choose an action</SheetDescription>
208
+ </SheetHeader>
209
+ <div className="flex flex-col gap-1 py-2">
210
+ <Button variant="ghost" className="justify-start">
211
+ Read diff
212
+ </Button>
213
+ <Button variant="ghost" className="justify-start text-attn">
214
+ Address findings
215
+ </Button>
216
+ </div>
217
+ </SheetContent>
218
+ </Sheet>
219
+ </Section>
220
+
221
+ <Section title="Tooltip">
222
+ <TooltipProvider>
223
+ <Tooltip>
224
+ <TooltipTrigger asChild>
225
+ <Button variant="outline" size="icon" aria-label="Help">
226
+ ?
227
+ </Button>
228
+ </TooltipTrigger>
229
+ <TooltipContent>Stage strip shows Work → Test → Review → Merge</TooltipContent>
230
+ </Tooltip>
231
+ </TooltipProvider>
232
+ </Section>
233
+
234
+ <Section title="Skeleton">
235
+ <div className="flex flex-col gap-2">
236
+ <Skeleton className="h-4 w-48" />
237
+ <Skeleton className="h-4 w-32" />
238
+ </div>
239
+ </Section>
240
+
241
+ <Section title="Empty state">
242
+ <Card className="w-full">
243
+ <EmptyState
244
+ icon={<Inbox />}
245
+ title="No issues match this filter"
246
+ description="Try a different repo or clear the search."
247
+ action={
248
+ <Button variant="outline" size="sm">
249
+ Clear filters
250
+ </Button>
251
+ }
252
+ />
253
+ </Card>
254
+ </Section>
255
+
256
+ <Section title="Toast">
257
+ <Button
258
+ variant="outline"
259
+ onClick={() =>
260
+ toast({ title: 'Drive started', description: 'dellserver · issue-1538' })
261
+ }
262
+ >
263
+ Default
264
+ </Button>
265
+ <Button
266
+ variant="outline"
267
+ onClick={() =>
268
+ toast({
269
+ variant: 'success',
270
+ title: 'Test passed',
271
+ description: '612 tests · 3m 18s',
272
+ })
273
+ }
274
+ >
275
+ Success
276
+ </Button>
277
+ <Button
278
+ variant="outline"
279
+ onClick={() =>
280
+ toast({
281
+ variant: 'destructive',
282
+ title: 'Merge blocked',
283
+ description: 'CI is red on develop',
284
+ })
285
+ }
286
+ >
287
+ Destructive
288
+ </Button>
289
+ <Toaster />
290
+ </Section>
291
+
292
+ <section className="flex flex-col gap-3 border-t border-border pt-8">
293
+ <h2 className="text-step-1 font-semibold tracking-tight">Side by side</h2>
294
+ <p className="text-sm text-muted-foreground">
295
+ Both themes at once, forced independent of the live toggle above (non-overlay
296
+ primitives only — see the file header comment for why).
297
+ </p>
298
+ <div className="grid gap-4 sm:grid-cols-2">
299
+ {(['dark', 'light'] as const).map(t => (
300
+ <div
301
+ key={t}
302
+ data-theme={t}
303
+ className="flex flex-col gap-4 rounded-lg border border-border bg-background p-5 text-foreground"
304
+ >
305
+ <span className="mono text-xs uppercase tracking-wide text-faint">{t}</span>
306
+ <div className="flex flex-wrap gap-2">
307
+ <Button size="sm">Primary</Button>
308
+ <Button size="sm" variant="outline">
309
+ Outline
310
+ </Button>
311
+ <Badge variant="success">Passed</Badge>
312
+ <Badge variant="warning">Findings</Badge>
313
+ <Badge variant="destructive">Failed</Badge>
314
+ </div>
315
+ <Card>
316
+ <CardHeader>
317
+ <CardTitle>#1538</CardTitle>
318
+ <CardDescription>coord web --fixture</CardDescription>
319
+ </CardHeader>
320
+ </Card>
321
+ </div>
322
+ ))}
323
+ </div>
324
+ </section>
325
+ </div>
326
+ )
327
+ }
328
+
329
+ /**
330
+ * Wrapped in its own ThemeProvider so the gallery is a self-contained route
331
+ * (works even if it's ever linked to directly) — App.tsx already wraps the
332
+ * whole app in one too, and nesting is harmless since both read/write the
333
+ * same `data-theme` attribute and localStorage key.
334
+ */
335
+ export default function Gallery() {
336
+ return (
337
+ <ThemeProvider>
338
+ <GalleryBody />
339
+ </ThemeProvider>
340
+ )
341
+ }