{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "deployment-pipeline",
  "title": "Deployment Pipeline",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/deployment-pipeline/DeploymentPipeline.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  Check,\n  CheckCircle2,\n  ChevronDown,\n  ChevronUp,\n  Clock,\n  Copy,\n  ExternalLink,\n  GitBranch,\n  GitCommit,\n  Layers,\n  Loader2,\n  MoreHorizontal,\n  Play,\n  RotateCcw,\n  RotateCw,\n  Terminal,\n  Undo2,\n  XCircle,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Avatar, AvatarFallback } from '@/components/ui/avatar'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu'\nimport { Separator } from '@/components/ui/separator'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'\n\nexport type DeploymentEnvironment = 'all' | 'production' | 'preview' | 'staging'\nexport type DeploymentStatus = 'ready' | 'building' | 'failed' | 'rolled-back'\nexport type DeploymentTrigger = 'push' | 'manual' | 'rollback'\n\nexport interface DeploymentRecord {\n  id: string\n  commitMessage: string\n  commitHash: string\n  branch: string\n  environment: 'production' | 'preview' | 'staging'\n  status: DeploymentStatus\n  duration: string\n  deployer: {\n    name: string\n    initials: string\n  }\n  trigger: DeploymentTrigger\n  deployedAt: string\n  url: string\n}\n\nexport interface PipelineStep {\n  id: string\n  name: string\n  duration: string\n  description: string\n  status: 'completed' | 'in-progress' | 'pending'\n}\n\nexport interface DeploymentPipelineProps {\n  initialEnv?: DeploymentEnvironment\n  initialLogsOpen?: boolean\n  className?: string\n}\n\nconst branches = ['main', 'staging', 'preview/safari-tabs', 'preview/e2e-tests']\n\nconst pipelineSteps: PipelineStep[] = [\n  { id: 'step-1', name: 'Queued', duration: '0.2s', description: 'Worker allocated', status: 'completed' },\n  { id: 'step-2', name: 'Build & Bundle', duration: '42s', description: 'Vite & TS compilation', status: 'completed' },\n  {\n    id: 'step-3',\n    name: 'Static Generation',\n    duration: '18s',\n    description: '42 SSG pages rendered',\n    status: 'completed',\n  },\n  { id: 'step-4', name: 'Edge Propagation', duration: '3s', description: 'Synced to 310 PoPs', status: 'completed' },\n  { id: 'step-5', name: 'Ready', duration: 'Instant', description: 'Verified & live', status: 'completed' },\n]\n\nconst terminalLogs = [\n  {\n    time: '00:00:00.120',\n    type: 'info',\n    prefix: '❯ [worker]',\n    text: 'Initializing deployment worker in region iad-1 (runner-edge-iad-4)...',\n  },\n  {\n    time: '00:00:00.340',\n    type: 'info',\n    prefix: '❯ [git]',\n    text: 'Cloning repository uipkge/core-registry at commit a3f89b1 (branch: main)...',\n  },\n  {\n    time: '00:00:01.050',\n    type: 'info',\n    prefix: '❯ [cache]',\n    text: 'Restoring pnpm store cache (v9.15.0)... (1,482 packages restored, 98.4% cache hit)',\n  },\n  { time: '00:00:02.410', type: 'cmd', prefix: '$', text: 'pnpm run build:registry && pnpm run build' },\n  { time: '00:00:04.180', type: 'stdout', prefix: '  [vite]', text: 'Transformed 482 modules in 312ms' },\n  {\n    time: '00:00:15.920',\n    type: 'stdout',\n    prefix: '  [astro]',\n    text: 'Building static entrypoints for production (Vue 3.5 + React 19 islands)...',\n  },\n  { time: '00:00:32.400', type: 'stdout', prefix: '  [astro]', text: '✓ 42 static pages rendered in 16.48s' },\n  {\n    time: '00:00:44.210',\n    type: 'stdout',\n    prefix: '  [registry]',\n    text: 'Generated 120 manifests into public/r/vue/*.json and public/r/react/*.json',\n  },\n  {\n    time: '00:00:58.800',\n    type: 'info',\n    prefix: '❯ [edge]',\n    text: 'Optimizing edge assets with Brotli compression (saved 4.8 MB)...',\n  },\n  {\n    time: '00:01:01.320',\n    type: 'info',\n    prefix: '❯ [edge]',\n    text: 'Propagating edge routes to Cloudflare global network across 310 PoPs...',\n  },\n  {\n    time: '00:01:03.200',\n    type: 'success',\n    prefix: '✓ [ready]',\n    text: 'Deployment successfully verified and healthy at https://uipkge.dev',\n  },\n  {\n    time: '00:01:03.210',\n    type: 'success',\n    prefix: '✓ [exit]',\n    text: 'Process completed with exit code 0 (success in 1m 03.2s)',\n  },\n]\n\nconst deployments: DeploymentRecord[] = [\n  {\n    id: 'd-1042',\n    commitMessage: 'feat(blocks): add ecommerce suite (#412)',\n    commitHash: 'a3f89b1',\n    branch: 'main',\n    environment: 'production',\n    status: 'ready',\n    duration: '1m 03s',\n    deployer: { name: 'Jordan Diaz', initials: 'JD' },\n    trigger: 'push',\n    deployedAt: '12m ago',\n    url: 'https://uipkge.dev',\n  },\n  {\n    id: 'd-1041',\n    commitMessage: 'fix(tabs): resolve indicator jitter in safari (#411)',\n    commitHash: 'f79b20e',\n    branch: 'preview/safari-tabs',\n    environment: 'preview',\n    status: 'ready',\n    duration: '48s',\n    deployer: { name: 'Amara Osei', initials: 'AO' },\n    trigger: 'push',\n    deployedAt: '2h ago',\n    url: 'https://uipkge-pr-411.uipkge.dev',\n  },\n  {\n    id: 'd-1040',\n    commitMessage: 'refactor(avatar): extract avatar-group primitive (#410)',\n    commitHash: '91bc8d3',\n    branch: 'staging',\n    environment: 'staging',\n    status: 'ready',\n    duration: '54s',\n    deployer: { name: 'Jonas Weber', initials: 'JW' },\n    trigger: 'manual',\n    deployedAt: '5h ago',\n    url: 'https://staging.uipkge.dev',\n  },\n  {\n    id: 'd-1039',\n    commitMessage: 'test(e2e): add playwright visual regression suite (#409)',\n    commitHash: '62e08a4',\n    branch: 'preview/e2e-tests',\n    environment: 'preview',\n    status: 'building',\n    duration: '1m 12s',\n    deployer: { name: 'Priya Nair', initials: 'PN' },\n    trigger: 'push',\n    deployedAt: 'Just now',\n    url: 'https://uipkge-pr-409.uipkge.dev',\n  },\n  {\n    id: 'd-1038',\n    commitMessage: 'perf(theme): eliminate css custom property recalculation (#408)',\n    commitHash: '3d12fa9',\n    branch: 'staging',\n    environment: 'staging',\n    status: 'failed',\n    duration: '24s',\n    deployer: { name: 'Marcus Lee', initials: 'ML' },\n    trigger: 'push',\n    deployedAt: 'Yesterday',\n    url: 'https://staging-failed.uipkge.dev',\n  },\n  {\n    id: 'd-1037',\n    commitMessage: 'chore(deps): update reka-ui to v1.1.0 (#407)',\n    commitHash: '180eac2',\n    branch: 'main',\n    environment: 'production',\n    status: 'rolled-back',\n    duration: '1m 20s',\n    deployer: { name: 'Jordan Diaz', initials: 'JD' },\n    trigger: 'rollback',\n    deployedAt: '2 days ago',\n    url: 'https://uipkge-v2-rollback.uipkge.dev',\n  },\n]\n\nexport function DeploymentPipeline({ initialEnv = 'all', initialLogsOpen = true, className }: DeploymentPipelineProps) {\n  const [selectedEnv, setSelectedEnv] = React.useState<DeploymentEnvironment>(initialEnv)\n  const [selectedBranch, setSelectedBranch] = React.useState<string>('main')\n  const [showLogs, setShowLogs] = React.useState<boolean>(initialLogsOpen)\n  const [copiedLogs, setCopiedLogs] = React.useState<boolean>(false)\n  const [copiedUrlId, setCopiedUrlId] = React.useState<string | null>(null)\n  const [isDeploying, setIsDeploying] = React.useState<boolean>(false)\n\n  const filteredDeployments =\n    selectedEnv === 'all' ? deployments : deployments.filter((d) => d.environment === selectedEnv)\n\n  function triggerDeployment() {\n    setIsDeploying(true)\n    setTimeout(() => {\n      setIsDeploying(false)\n    }, 1200)\n  }\n\n  function copyLogs() {\n    const text = terminalLogs.map((l) => `[${l.time}] ${l.prefix} ${l.text}`).join('\\n')\n    if (typeof navigator !== 'undefined' && navigator.clipboard) {\n      navigator.clipboard.writeText(text)\n      setCopiedLogs(true)\n      setTimeout(() => {\n        setCopiedLogs(false)\n      }, 2000)\n    }\n  }\n\n  function copyUrl(url: string, id: string) {\n    if (typeof navigator !== 'undefined' && navigator.clipboard) {\n      navigator.clipboard.writeText(url)\n      setCopiedUrlId(id)\n      setTimeout(() => {\n        setCopiedUrlId(null)\n      }, 2000)\n    }\n  }\n\n  return (\n    <div data-slot=\"deployment-pipeline\" className={cn('w-full space-y-6', className)}>\n      {/* Header Section */}\n      <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n        <div className=\"flex items-center gap-3\">\n          <div className=\"bg-card flex size-10 items-center justify-center rounded-lg border shadow-xs\">\n            <Layers className=\"text-primary size-5\" aria-hidden=\"true\" />\n          </div>\n          <div>\n            <h2 className=\"text-2xl font-bold tracking-tight\">Deployments</h2>\n            <div className=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n              <span className=\"text-foreground font-mono font-medium\">uipkge</span>\n              <span>/</span>\n              <span className=\"font-mono\">core-registry</span>\n            </div>\n          </div>\n        </div>\n\n        <div className=\"flex flex-wrap items-center gap-2\">\n          <DropdownMenu>\n            <DropdownMenuTrigger asChild>\n              <Button variant=\"outline\" size=\"sm\" className=\"font-mono text-xs\">\n                <GitBranch className=\"text-muted-foreground size-3.5\" aria-hidden=\"true\" />\n                <span>{selectedBranch}</span>\n                <ChevronDown className=\"text-muted-foreground size-3.5 opacity-60\" aria-hidden=\"true\" />\n              </Button>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\" className=\"w-48\">\n              <DropdownMenuLabel>Select branch</DropdownMenuLabel>\n              <DropdownMenuSeparator />\n              {branches.map((branch) => (\n                <DropdownMenuItem\n                  key={branch}\n                  className={selectedBranch === branch ? 'bg-accent font-semibold' : ''}\n                  onClick={() => setSelectedBranch(branch)}\n                >\n                  <GitBranch className=\"mr-2 size-3.5\" aria-hidden=\"true\" />\n                  <span className=\"font-mono text-xs\">{branch}</span>\n                </DropdownMenuItem>\n              ))}\n            </DropdownMenuContent>\n          </DropdownMenu>\n\n          <Button size=\"sm\" disabled={isDeploying} onClick={triggerDeployment}>\n            {isDeploying ? (\n              <Loader2 className=\"size-3.5 animate-spin\" aria-hidden=\"true\" />\n            ) : (\n              <Play className=\"size-3.5 fill-current\" aria-hidden=\"true\" />\n            )}\n            {isDeploying ? 'Triggering...' : 'Trigger Deployment'}\n          </Button>\n        </div>\n      </div>\n\n      {/* Environment Tabs Navigation */}\n      <Tabs\n        value={selectedEnv}\n        onValueChange={(val) => setSelectedEnv(val as DeploymentEnvironment)}\n        className=\"w-full\"\n      >\n        <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n          <TabsList variant=\"segmented\" className=\"w-full sm:w-auto\">\n            <TabsTrigger value=\"all\">All</TabsTrigger>\n            <TabsTrigger value=\"production\">Production</TabsTrigger>\n            <TabsTrigger value=\"preview\">Preview</TabsTrigger>\n            <TabsTrigger value=\"staging\">Staging</TabsTrigger>\n          </TabsList>\n          <span className=\"text-muted-foreground text-xs tabular-nums\">\n            Showing {filteredDeployments.length} of {deployments.length} deployments\n          </span>\n        </div>\n      </Tabs>\n\n      {/* Latest Deployment Hero Card */}\n      <Card className=\"border-border shadow-xs\">\n        <CardHeader className=\"space-y-4 pb-4\">\n          <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n            <div className=\"space-y-1.5\">\n              <div className=\"flex flex-wrap items-center gap-2\">\n                <CardTitle className=\"text-base font-semibold\">Latest Deployment</CardTitle>\n                <div className=\"border-success/30 bg-success/10 text-success inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium\">\n                  <span className=\"relative flex size-2 shrink-0\">\n                    <span className=\"bg-success absolute inline-flex h-full w-full rounded-full opacity-75\" />\n                    <span className=\"bg-success relative inline-flex size-2 rounded-full\" />\n                  </span>\n                  Live · Production\n                </div>\n              </div>\n              <CardDescription>\n                <a\n                  href=\"https://uipkge.dev\"\n                  target=\"_blank\"\n                  rel=\"noopener noreferrer\"\n                  className=\"text-foreground hover:text-primary inline-flex min-h-6 items-center gap-1 py-0.5 font-mono text-xs font-medium underline underline-offset-4 transition-colors\"\n                >\n                  https://uipkge.dev\n                  <ExternalLink className=\"text-muted-foreground size-3\" aria-hidden=\"true\" />\n                </a>\n              </CardDescription>\n            </div>\n\n            <div className=\"flex flex-wrap items-center gap-2\">\n              <Button variant=\"outline\" size=\"sm\" onClick={() => setShowLogs(!showLogs)}>\n                <Terminal className=\"size-3.5\" aria-hidden=\"true\" />\n                <span>{showLogs ? 'Hide Build Logs' : 'View Build Logs'}</span>\n                {showLogs ? (\n                  <ChevronUp className=\"text-muted-foreground size-3.5\" aria-hidden=\"true\" />\n                ) : (\n                  <ChevronDown className=\"text-muted-foreground size-3.5\" aria-hidden=\"true\" />\n                )}\n              </Button>\n              <Button variant=\"outline\" size=\"sm\">\n                <RotateCw className=\"size-3.5\" aria-hidden=\"true\" />\n                <span>Redeploy</span>\n              </Button>\n              <Button variant=\"outline\" size=\"sm\">\n                <Undo2 className=\"size-3.5\" aria-hidden=\"true\" />\n                <span>Instant Rollback</span>\n              </Button>\n            </div>\n          </div>\n\n          {/* Commit Details Bar */}\n          <div className=\"bg-muted/40 flex flex-wrap items-center gap-x-4 gap-y-2 rounded-lg border px-3.5 py-2.5 text-xs\">\n            <div className=\"flex items-center gap-2\">\n              <Avatar className=\"size-5\">\n                <AvatarFallback className=\"text-xs font-medium\">JD</AvatarFallback>\n              </Avatar>\n              <span className=\"text-foreground font-medium\">Jordan Diaz</span>\n            </div>\n            <Separator orientation=\"vertical\" className=\"hidden h-3.5 sm:block\" />\n            <span className=\"text-foreground font-medium\">feat(blocks): add ecommerce suite (#412)</span>\n            <Separator orientation=\"vertical\" className=\"hidden h-3.5 sm:block\" />\n            <div className=\"text-muted-foreground flex items-center gap-1 font-mono\">\n              <GitCommit className=\"size-3.5\" aria-hidden=\"true\" />\n              <span>a3f89b1</span>\n            </div>\n            <Separator orientation=\"vertical\" className=\"hidden h-3.5 sm:block\" />\n            <div className=\"text-muted-foreground flex items-center gap-1 font-mono\">\n              <GitBranch className=\"size-3.5\" aria-hidden=\"true\" />\n              <span>main</span>\n            </div>\n            <Separator orientation=\"vertical\" className=\"hidden h-3.5 sm:block\" />\n            <div className=\"text-muted-foreground flex items-center gap-1\">\n              <Clock className=\"size-3.5\" aria-hidden=\"true\" />\n              <span>Deployed 12m ago</span>\n            </div>\n          </div>\n        </CardHeader>\n\n        <CardContent className=\"space-y-4 pt-0\">\n          {/* Execution Stepper */}\n          <div className=\"space-y-2.5\">\n            <div className=\"flex items-center justify-between\">\n              <span className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                Pipeline Execution\n              </span>\n              <span className=\"text-muted-foreground font-mono text-xs\">5 of 5 steps completed · 1m 03s</span>\n            </div>\n\n            <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-5\">\n              {pipelineSteps.map((step, index) => (\n                <div\n                  key={step.id}\n                  className=\"bg-card/60 hover:bg-muted/40 flex flex-col justify-between rounded-lg border p-3 shadow-2xs transition-colors\"\n                >\n                  <div className=\"flex items-center justify-between\">\n                    <span className=\"bg-success/15 text-success flex size-5 items-center justify-center rounded-full\">\n                      <Check className=\"size-3 stroke-[3]\" aria-hidden=\"true\" />\n                    </span>\n                    <span className=\"text-muted-foreground font-mono text-xs\">{step.duration}</span>\n                  </div>\n                  <div className=\"mt-2\">\n                    <p className=\"text-foreground text-xs font-semibold\">\n                      {index + 1}. {step.name}\n                    </p>\n                    <p className=\"text-muted-foreground truncate text-xs\">{step.description}</p>\n                  </div>\n                </div>\n              ))}\n            </div>\n          </div>\n\n          {/* Collapsible Dark Terminal / Build Log Viewer */}\n          {showLogs && (\n            <div className=\"overflow-hidden rounded-lg border border-zinc-800 bg-zinc-950 font-mono text-xs shadow-inner\">\n              <div className=\"flex items-center justify-between border-b border-zinc-800 bg-zinc-900/90 px-3.5 py-2\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"flex items-center gap-1.5\">\n                    <span className=\"bg-destructive/80 size-2.5 rounded-full\" />\n                    <span className=\"bg-warning/80 size-2.5 rounded-full\" />\n                    <span className=\"bg-success/80 size-2.5 rounded-full\" />\n                  </div>\n                  <span className=\"text-muted-foreground text-xs\">\n                    build-stdout — node v22.12.0 — runner-edge-iad-4\n                  </span>\n                </div>\n                <div className=\"flex items-center gap-2\">\n                  <span className=\"text-muted-foreground text-muted-foreground hidden text-xs sm:inline\">\n                    Total: 1m 03.2s\n                  </span>\n                  <Button\n                    variant=\"ghost\"\n                    size=\"xs\"\n                    className=\"h-6 gap-1 px-2 text-zinc-300 hover:bg-zinc-800 hover:text-zinc-100\"\n                    onClick={copyLogs}\n                  >\n                    {copiedLogs ? (\n                      <Check className=\"text-success size-3\" aria-hidden=\"true\" />\n                    ) : (\n                      <Copy className=\"size-3\" aria-hidden=\"true\" />\n                    )}\n                    <span>{copiedLogs ? 'Copied' : 'Copy logs'}</span>\n                  </Button>\n                </div>\n              </div>\n\n              <div className=\"max-h-72 space-y-1 overflow-y-auto p-4 select-text\">\n                {terminalLogs.map((line, idx) => (\n                  <div key={idx} className=\"flex items-start gap-2 leading-relaxed\">\n                    <span className=\"text-muted-foreground select-none\">[{line.time}]</span>\n                    <span\n                      className={cn(\n                        'font-medium select-none',\n                        line.type === 'success' && 'text-success',\n                        line.type === 'info' && 'text-info',\n                        line.type === 'cmd' && 'text-warning',\n                        line.type === 'stdout' && 'text-muted-foreground',\n                      )}\n                    >\n                      {line.prefix}\n                    </span>\n                    <span\n                      className={cn(\n                        line.type === 'success' && 'text-success font-medium',\n                        line.type === 'cmd' && 'font-semibold text-zinc-100',\n                        line.type === 'info' && 'text-zinc-300',\n                        line.type === 'stdout' && 'text-zinc-300',\n                      )}\n                    >\n                      {line.text}\n                    </span>\n                  </div>\n                ))}\n              </div>\n\n              <div className=\"text-muted-foreground flex items-center justify-between border-t border-zinc-800 bg-zinc-900/60 px-3.5 py-1.5 text-xs\">\n                <div className=\"flex items-center gap-2\">\n                  <span className=\"bg-success/10 text-success inline-flex items-center gap-1 rounded px-1.5 py-0.5 font-medium\">\n                    <Check className=\"size-3\" aria-hidden=\"true\" /> Exit code: 0\n                  </span>\n                  <span>Clean build</span>\n                </div>\n                <span className=\"text-muted-foreground\">Memory: 412 MB / 2048 MB</span>\n              </div>\n            </div>\n          )}\n        </CardContent>\n      </Card>\n\n      {/* Deployment History Table */}\n      <Card className=\"border-border shadow-xs\">\n        <CardHeader className=\"pb-3\">\n          <CardTitle className=\"text-base font-semibold\">Deployment History</CardTitle>\n          <CardDescription className=\"text-xs\">\n            Past deployments across production, preview, and staging environments.\n          </CardDescription>\n        </CardHeader>\n        <CardContent className=\"p-0\">\n          <div className=\"overflow-x-auto\">\n            <Table>\n              <TableHeader>\n                <TableRow>\n                  <TableHead className=\"w-10\">\n                    <span className=\"sr-only\">Status</span>\n                  </TableHead>\n                  <TableHead>Commit & Message</TableHead>\n                  <TableHead>Environment</TableHead>\n                  <TableHead>Duration</TableHead>\n                  <TableHead>Deployer</TableHead>\n                  <TableHead>Trigger</TableHead>\n                  <TableHead className=\"text-right\">Deployed</TableHead>\n                  <TableHead className=\"w-10\">\n                    <span className=\"sr-only\">Actions</span>\n                  </TableHead>\n                </TableRow>\n              </TableHeader>\n              <TableBody>\n                {filteredDeployments.map((deployment) => (\n                  <TableRow key={deployment.id} className=\"hover:bg-muted/50\">\n                    <TableCell className=\"py-3\">\n                      {deployment.status === 'ready' && (\n                        <span title=\"Ready\">\n                          <CheckCircle2 className=\"text-success size-4\" aria-hidden=\"true\" />\n                        </span>\n                      )}\n                      {deployment.status === 'building' && (\n                        <span title=\"Building\">\n                          <Loader2 className=\"text-info size-4 animate-spin\" aria-hidden=\"true\" />\n                        </span>\n                      )}\n                      {deployment.status === 'failed' && (\n                        <span title=\"Failed\">\n                          <XCircle className=\"text-destructive size-4\" aria-hidden=\"true\" />\n                        </span>\n                      )}\n                      {deployment.status === 'rolled-back' && (\n                        <span title=\"Rolled back\">\n                          <Undo2 className=\"text-warning size-4\" aria-hidden=\"true\" />\n                        </span>\n                      )}\n                    </TableCell>\n                    <TableCell>\n                      <div className=\"min-w-[220px]\">\n                        <p className=\"text-foreground max-w-sm truncate text-sm font-medium\">\n                          {deployment.commitMessage}\n                        </p>\n                        <div className=\"text-muted-foreground mt-0.5 flex items-center gap-2 font-mono text-xs\">\n                          <span className=\"flex items-center gap-1\">\n                            <GitBranch className=\"size-3\" aria-hidden=\"true\" />\n                            {deployment.branch}\n                          </span>\n                          <span>·</span>\n                          <span className=\"flex items-center gap-1\">\n                            <GitCommit className=\"size-3\" aria-hidden=\"true\" />\n                            {deployment.commitHash}\n                          </span>\n                        </div>\n                      </div>\n                    </TableCell>\n                    <TableCell>\n                      <Badge\n                        variant={\n                          deployment.environment === 'production'\n                            ? 'default'\n                            : deployment.environment === 'preview'\n                              ? 'secondary'\n                              : 'outline'\n                        }\n                        className=\"text-xs capitalize\"\n                      >\n                        {deployment.environment}\n                      </Badge>\n                    </TableCell>\n                    <TableCell className=\"text-muted-foreground font-mono text-xs tabular-nums\">\n                      {deployment.duration}\n                    </TableCell>\n                    <TableCell>\n                      <div className=\"flex items-center gap-2\">\n                        <Avatar className=\"size-6\">\n                          <AvatarFallback className=\"text-xs font-medium\">\n                            {deployment.deployer.initials}\n                          </AvatarFallback>\n                        </Avatar>\n                        <span className=\"text-foreground text-xs\">{deployment.deployer.name}</span>\n                      </div>\n                    </TableCell>\n                    <TableCell>\n                      <div className=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n                        {deployment.trigger === 'push' && <GitCommit className=\"size-3.5\" aria-hidden=\"true\" />}\n                        {deployment.trigger === 'manual' && <Play className=\"size-3.5\" aria-hidden=\"true\" />}\n                        {deployment.trigger === 'rollback' && <RotateCcw className=\"size-3.5\" aria-hidden=\"true\" />}\n                        <span className=\"capitalize\">{deployment.trigger}</span>\n                      </div>\n                    </TableCell>\n                    <TableCell className=\"text-muted-foreground text-right text-xs whitespace-nowrap tabular-nums\">\n                      {deployment.deployedAt}\n                    </TableCell>\n                    <TableCell>\n                      <DropdownMenu>\n                        <DropdownMenuTrigger asChild>\n                          <Button variant=\"ghost\" size=\"icon-sm\" className=\"text-muted-foreground\">\n                            <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n                            <span className=\"sr-only\">Open actions for {deployment.id}</span>\n                          </Button>\n                        </DropdownMenuTrigger>\n                        <DropdownMenuContent align=\"end\">\n                          <DropdownMenuLabel>Actions</DropdownMenuLabel>\n                          <DropdownMenuSeparator />\n                          <DropdownMenuItem>\n                            <Undo2 className=\"mr-2 size-4\" aria-hidden=\"true\" />\n                            Rollback to this deploy\n                          </DropdownMenuItem>\n                          <DropdownMenuItem onClick={() => copyUrl(deployment.url, deployment.id)}>\n                            {copiedUrlId === deployment.id ? (\n                              <Check className=\"text-success mr-2 size-4\" aria-hidden=\"true\" />\n                            ) : (\n                              <Copy className=\"mr-2 size-4\" aria-hidden=\"true\" />\n                            )}\n                            {copiedUrlId === deployment.id ? 'Copied URL' : 'Copy deployment URL'}\n                          </DropdownMenuItem>\n                          <DropdownMenuItem onClick={() => setShowLogs(true)}>\n                            <Terminal className=\"mr-2 size-4\" aria-hidden=\"true\" />\n                            Inspect build logs\n                          </DropdownMenuItem>\n                          <DropdownMenuItem asChild>\n                            <a\n                              href={deployment.url}\n                              target=\"_blank\"\n                              rel=\"noopener noreferrer\"\n                              className=\"flex items-center\"\n                            >\n                              <ExternalLink className=\"mr-2 size-4\" aria-hidden=\"true\" />\n                              View live preview\n                            </a>\n                          </DropdownMenuItem>\n                        </DropdownMenuContent>\n                      </DropdownMenu>\n                    </TableCell>\n                  </TableRow>\n                ))}\n                {filteredDeployments.length === 0 && (\n                  <TableRow>\n                    <TableCell colSpan={8} className=\"text-muted-foreground h-24 text-center text-sm\">\n                      No deployments match the selected environment filter.\n                    </TableCell>\n                  </TableRow>\n                )}\n              </TableBody>\n            </Table>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/DeploymentPipeline.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/avatar.json",
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/dropdown-menu.json",
    "https://uipkge.dev/r/react/separator.json",
    "https://uipkge.dev/r/react/table.json",
    "https://uipkge.dev/r/react/tabs.json"
  ],
  "description": "CI/CD deployment history, active environment status, execution stepper, collapsible build log terminal with stdout timestamps, and filterable deployments table.",
  "categories": [
    "devops",
    "app"
  ]
}