@burdenoff/microfe-vibecontrols 2026.528.6 → 2026.528.8

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 (42) hide show
  1. package/dist/VibeControlsRoot.js +90 -81
  2. package/dist/VibeControlsRoot.js.map +1 -1
  3. package/dist/VibeControlsRoutes.js +144 -140
  4. package/dist/VibeControlsRoutes.js.map +1 -1
  5. package/dist/components/audit/AuditLogFilters.js +71 -47
  6. package/dist/components/audit/AuditLogFilters.js.map +1 -1
  7. package/dist/components/shared/AgentSetupBanner.js +50 -45
  8. package/dist/components/shared/AgentSetupBanner.js.map +1 -1
  9. package/dist/components/shared/LinkToVibePanel.js +97 -0
  10. package/dist/components/shared/LinkToVibePanel.js.map +1 -0
  11. package/dist/components/shared/index.js +1 -0
  12. package/dist/components/templates/TemplateWizard.js +2 -2
  13. package/dist/components/templates/TemplateWizard.js.map +1 -1
  14. package/dist/components/vibe/VibeLinkedEntitiesPanel.js +60 -0
  15. package/dist/components/vibe/VibeLinkedEntitiesPanel.js.map +1 -0
  16. package/dist/components/vibedeck/VibeDeckButtonTile.js +25 -23
  17. package/dist/components/vibedeck/VibeDeckButtonTile.js.map +1 -1
  18. package/dist/components/vibedeck/VibeDeckGrid.js +2 -2
  19. package/dist/components/vibedeck/VibeDeckGrid.js.map +1 -1
  20. package/dist/constants/pluginCatalog.js +1 -1
  21. package/dist/microfe-vibecontrols.css +1 -1
  22. package/dist/pages/AgentDetailsPage.js +2 -2
  23. package/dist/pages/AgentDetailsPage.js.map +1 -1
  24. package/dist/pages/AnalyticsPage.js +255 -204
  25. package/dist/pages/AnalyticsPage.js.map +1 -1
  26. package/dist/pages/OverviewPage.js +1 -11
  27. package/dist/pages/OverviewPage.js.map +1 -1
  28. package/dist/pages/PluginsCatalogPage.js +287 -0
  29. package/dist/pages/PluginsCatalogPage.js.map +1 -0
  30. package/dist/pages/SessionsPage.js +825 -629
  31. package/dist/pages/SessionsPage.js.map +1 -1
  32. package/dist/pages/VibeAuditPage.js +184 -153
  33. package/dist/pages/VibeAuditPage.js.map +1 -1
  34. package/dist/pages/VibeCalendarPage.js +132 -107
  35. package/dist/pages/VibeCalendarPage.js.map +1 -1
  36. package/dist/pages/VibeDeckPage.js +416 -379
  37. package/dist/pages/VibeDeckPage.js.map +1 -1
  38. package/dist/pages/VibeDetailsPage.js +621 -557
  39. package/dist/pages/VibeDetailsPage.js.map +1 -1
  40. package/dist/pages/tunnels/TunnelsTab.js +115 -90
  41. package/dist/pages/tunnels/TunnelsTab.js.map +1 -1
  42. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"VibeDeckButtonTile.js","names":[],"sources":["../../../src/components/vibedeck/VibeDeckButtonTile.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport {\n Play,\n Pencil,\n Trash2,\n Terminal,\n Globe,\n FileCode,\n AlertTriangle,\n Check,\n X,\n Loader2,\n} from 'lucide-react';\nimport { SelectionCheckbox } from '../shared/SelectionCheckbox';\n\ninterface ActionRef {\n id: string;\n name: string;\n displayName: string | null;\n actionType: string;\n command: string | null;\n script: string | null;\n webhookUrl: string | null;\n targetAgentId: string | null;\n}\n\ninterface ButtonData {\n id: string;\n label: string;\n icon: string | null;\n color: string | null;\n command: string | null;\n actionType: string;\n category: string | null;\n confirmationRequired: boolean;\n keyboardShortcut: string | null;\n targetAgentId: string | null;\n scriptInterpreter: string | null;\n webhookUrl: string | null;\n webhookMethod: string | null;\n actionId?: string | null;\n action?: ActionRef | null;\n}\n\ninterface VibeDeckButtonTileProps {\n button: ButtonData;\n onExecute: (id: string) => void;\n onEdit: (id: string) => void;\n onDelete: (id: string) => void;\n canUpdate: boolean;\n canDelete: boolean;\n canExecute: boolean;\n executing?: boolean;\n /** Visual feedback state after execution completes */\n executionStatus?: 'idle' | 'executing' | 'success' | 'error';\n isDragOver?: boolean;\n selected?: boolean;\n onToggleSelect?: (checked: boolean) => void;\n previewMode?: boolean;\n}\n\nexport const VibeDeckButtonTile: FC<VibeDeckButtonTileProps> = ({\n button,\n onExecute,\n onEdit,\n onDelete,\n canUpdate,\n canDelete,\n canExecute,\n executing = false,\n executionStatus = 'idle',\n isDragOver = false,\n selected = false,\n onToggleSelect,\n previewMode = false,\n}) => {\n const colorClasses: Record<string, string> = {\n red: 'border-status-error-border/30 bg-status-error-bg-subtle',\n green: 'border-status-success-border/30 bg-status-success-bg-subtle',\n blue: 'border-accent-blue/30 bg-accent-blue-subtle',\n yellow: 'border-status-warning-border/30 bg-status-warning-bg-subtle',\n purple: 'border-accent-purple/30 bg-accent-purple-subtle',\n orange: 'border-status-warning-border/30 bg-status-warning-bg-subtle',\n cyan: 'border-accent-teal/30 bg-accent-teal-subtle',\n pink: 'border-accent-purple/30 bg-accent-purple-subtle',\n };\n\n const previewColorClasses: Record<string, string> = {\n red: 'border-status-error-border/40 bg-gradient-to-br from-status-error-bg/15 to-status-error-bg/5 hover:shadow-status-error-bg/20',\n green:\n 'border-status-success-border/40 bg-gradient-to-br from-status-success-bg/15 to-status-success-bg/5 hover:shadow-status-success-bg/20',\n blue: 'border-accent-blue/40 bg-gradient-to-br from-accent-blue/15 to-accent-blue/5 hover:shadow-accent-blue/20',\n yellow:\n 'border-status-warning-border/40 bg-gradient-to-br from-status-warning-bg/15 to-status-warning-bg/5 hover:shadow-status-warning-bg/20',\n purple:\n 'border-accent-purple/40 bg-gradient-to-br from-accent-purple/15 to-accent-purple/5 hover:shadow-accent-purple/20',\n orange:\n 'border-status-warning-border/40 bg-gradient-to-br from-status-warning-bg/15 to-status-warning-bg/5 hover:shadow-status-warning-bg/20',\n cyan: 'border-accent-teal/40 bg-gradient-to-br from-accent-teal/15 to-accent-teal/5 hover:shadow-accent-teal/20',\n pink: 'border-accent-purple/40 bg-gradient-to-br from-accent-purple/15 to-accent-purple/5 hover:shadow-accent-purple/20',\n };\n\n const tileColor = previewMode\n ? button.color && previewColorClasses[button.color]\n ? previewColorClasses[button.color]\n : 'border-border-default bg-gradient-to-br from-bg-secondary to-bg-surface hover:shadow-action-primary-bg/10'\n : button.color && colorClasses[button.color]\n ? colorClasses[button.color]\n : 'border-border-default bg-bg-secondary';\n\n // Prefer action fields when linked, fall back to inline (deprecated) fields\n const effectiveActionType = button.action?.actionType || button.actionType;\n const effectiveCommand = button.action?.command ?? button.command;\n const effectiveScript = button.action?.script ?? null;\n const effectiveWebhookUrl = button.action?.webhookUrl ?? button.webhookUrl;\n const actionName = button.action?.displayName || button.action?.name || null;\n\n const isWebhook = effectiveActionType === 'WEBHOOK';\n const isScript = effectiveActionType === 'SCRIPT';\n const ActionIcon = isWebhook ? Globe : isScript ? FileCode : Terminal;\n const tooltip = isWebhook\n ? `${button.webhookMethod || 'POST'} ${effectiveWebhookUrl || ''}`\n : isScript\n ? `Script (${button.scriptInterpreter || 'bash'})${effectiveScript ? `: ${effectiveScript.slice(0, 60)}` : ''}`\n : `${effectiveCommand || ''}${button.keyboardShortcut ? ` (${button.keyboardShortcut})` : ''}`;\n\n // In preview mode, the entire tile is clickable to execute\n const handleTileClick = () => {\n if (previewMode && canExecute && !executing) {\n onExecute(button.id);\n }\n };\n\n // Status-dependent styles\n const statusRing =\n executionStatus === 'executing'\n ? 'ring-2 ring-action-primary-bg/60 ring-offset-1'\n : executionStatus === 'success'\n ? 'ring-2 ring-status-success-border/50 ring-offset-1'\n : executionStatus === 'error'\n ? 'ring-2 ring-status-error-border/50 ring-offset-1'\n : '';\n\n const statusBorderOverride =\n executionStatus === 'executing'\n ? 'border-action-primary-bg/60'\n : executionStatus === 'success'\n ? 'border-status-success-border/50'\n : executionStatus === 'error'\n ? 'border-status-error-border/50'\n : '';\n\n return (\n <motion.div\n className={`relative group h-full ${statusRing} ${isDragOver ? 'ring-2 ring-action-primary-bg ring-offset-1' : ''} ${selected ? 'ring-2 ring-action-primary-bg/40 ring-offset-1' : ''} ${previewMode && canExecute ? 'cursor-pointer' : ''} rounded-lg`}\n whileHover={{ scale: previewMode ? 1.04 : 1.02, transition: { duration: 0.15 } }}\n whileTap={previewMode ? { scale: 0.95, transition: { duration: 0.1 } } : { scale: 0.96 }}\n >\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (handleTileClick as (...a: unknown[]) => unknown)();\n }\n }}\n onClick={handleTileClick}\n className={`w-full h-full min-h-[80px] rounded-lg border-2 p-3 flex flex-col items-center justify-center gap-2 transition-all ${tileColor} ${statusBorderOverride} ${executionStatus === 'executing' ? 'animate-pulse' : ''} ${previewMode ? 'hover:shadow-lg transition-shadow duration-200' : ''}`}\n title={tooltip}\n >\n {/* Top-left: webhook method or script interpreter badge */}\n {isWebhook && button.webhookMethod && (\n <span\n className={`absolute left-1.5 text-[9px] font-bold text-text-tertiary bg-bg-tertiary/80 rounded px-1 py-0.5 uppercase ${!previewMode && onToggleSelect ? 'top-8' : 'top-1.5'}`}\n >\n {button.webhookMethod}\n </span>\n )}\n {isScript && button.scriptInterpreter && (\n <span\n className={`absolute left-1.5 text-[9px] font-bold text-text-tertiary bg-bg-tertiary/80 rounded px-1 py-0.5 ${!previewMode && onToggleSelect ? 'top-8' : 'top-1.5'}`}\n >\n {button.scriptInterpreter}\n </span>\n )}\n\n {!previewMode && onToggleSelect && (\n <div\n className=\"absolute top-1.5 left-1.5 z-10\"\n onClick={(event) => event.stopPropagation()}\n >\n <SelectionCheckbox\n checked={selected}\n onChange={onToggleSelect}\n ariaLabel={`Select vibe deck button ${button.label}`}\n />\n </div>\n )}\n\n {/* Bottom-left: confirmation required warning */}\n {button.confirmationRequired && (\n <AlertTriangle\n size={10}\n className=\"absolute bottom-1.5 left-1.5 text-status-warning-text\"\n />\n )}\n\n <ActionIcon\n size={previewMode ? 24 : 20}\n className={previewMode ? 'text-text-primary' : 'text-text-secondary'}\n />\n <span\n className={`font-medium text-text-primary text-center leading-tight line-clamp-2 ${previewMode ? 'text-base' : 'text-sm'}`}\n >\n {button.label}\n </span>\n {actionName && (\n <span className=\"text-[10px] text-action-primary-bg/70 font-medium truncate max-w-full px-1\">\n {actionName}\n </span>\n )}\n {button.category && (\n <span className=\"text-[10px] text-text-tertiary uppercase tracking-wider\">\n {button.category}\n </span>\n )}\n\n {/* Execution status indicator */}\n <AnimatePresence>\n {executionStatus === 'executing' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.8 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-action-primary-bg flex items-center justify-center shadow-sm\">\n <Loader2 size={11} className=\"text-text-inverse animate-spin\" />\n </div>\n </motion.div>\n )}\n {executionStatus === 'success' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.5 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.5 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-status-success-bg flex items-center justify-center shadow-sm\">\n <Check size={11} className=\"text-text-inverse\" strokeWidth={3} />\n </div>\n </motion.div>\n )}\n {executionStatus === 'error' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.5 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.5 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-status-error-bg flex items-center justify-center shadow-sm\">\n <X size={11} className=\"text-text-inverse\" strokeWidth={3} />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Preview mode: centered play overlay on hover */}\n {previewMode && canExecute && executionStatus !== 'executing' && (\n <div className=\"absolute inset-0 rounded-lg flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-bg-elevated/40 backdrop-blur-[1px]\">\n <div className=\"size-10 rounded-full bg-status-success-bg/90 flex items-center justify-center shadow-md\">\n <Play size={18} className=\"text-status-success-text ml-0.5\" />\n </div>\n </div>\n )}\n </div>\n\n {/* Top-right: Play button — visible in edit mode when user has execute permission */}\n {!previewMode && canExecute && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onExecute(button.id);\n }}\n disabled={executing}\n className=\"absolute top-0.5 right-0.5 p-1 rounded bg-bg-elevated/80 text-status-success-text/60 hover:text-status-success-text hover:bg-bg-elevated transition-colors shadow-sm\"\n title=\"Execute\"\n >\n <Play size={12} />\n </button>\n )}\n\n {/* Bottom-right: Edit / Delete — visible on hover in edit mode only */}\n {!previewMode && (canUpdate || canDelete) && (\n <div className=\"absolute bottom-0.5 right-0.5 flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity\">\n {canUpdate && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit(button.id);\n }}\n className=\"p-1 rounded bg-bg-elevated/80 hover:bg-bg-elevated text-text-tertiary hover:text-text-primary shadow-sm\"\n title=\"Edit\"\n >\n <Pencil size={12} />\n </button>\n )}\n {canDelete && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(button.id);\n }}\n className=\"p-1 rounded bg-bg-elevated/80 hover:bg-bg-elevated text-text-tertiary hover:text-status-error-text shadow-sm\"\n title=\"Delete\"\n >\n <Trash2 size={12} />\n </button>\n )}\n </div>\n )}\n </motion.div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"VibeDeckButtonTile.js","names":[],"sources":["../../../src/components/vibedeck/VibeDeckButtonTile.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport {\n Play,\n Pencil,\n Trash2,\n Terminal,\n Globe,\n FileCode,\n AlertTriangle,\n Check,\n X,\n Loader2,\n} from 'lucide-react';\nimport { SelectionCheckbox } from '../shared/SelectionCheckbox';\n\ninterface ActionRef {\n id: string;\n name: string;\n displayName: string | null;\n actionType: string;\n command: string | null;\n script: string | null;\n webhookUrl: string | null;\n targetAgentId: string | null;\n}\n\ninterface ButtonData {\n id: string;\n label: string;\n icon: string | null;\n color: string | null;\n command: string | null;\n actionType: string;\n category: string | null;\n confirmationRequired: boolean;\n keyboardShortcut: string | null;\n targetAgentId: string | null;\n scriptInterpreter: string | null;\n webhookUrl: string | null;\n webhookMethod: string | null;\n actionId?: string | null;\n action?: ActionRef | null;\n}\n\ninterface VibeDeckButtonTileProps {\n button: ButtonData;\n onExecute: (id: string) => void;\n onEdit: (id: string) => void;\n onDelete: (id: string) => void;\n canUpdate: boolean;\n canDelete: boolean;\n canExecute: boolean;\n executing?: boolean;\n /** Visual feedback state after execution completes */\n executionStatus?: 'idle' | 'executing' | 'success' | 'error';\n isDragOver?: boolean;\n selected?: boolean;\n onToggleSelect?: (checked: boolean) => void;\n previewMode?: boolean;\n}\n\nexport const VibeDeckButtonTile: FC<VibeDeckButtonTileProps> = ({\n button,\n onExecute,\n onEdit,\n onDelete,\n canUpdate,\n canDelete,\n canExecute,\n executing = false,\n executionStatus = 'idle',\n isDragOver = false,\n selected = false,\n onToggleSelect,\n previewMode = false,\n}) => {\n const colorClasses: Record<string, string> = {\n red: 'border-status-error-border/30 bg-status-error-bg-subtle',\n green: 'border-status-success-border/30 bg-status-success-bg-subtle',\n blue: 'border-accent-blue/30 bg-accent-blue-subtle',\n yellow: 'border-status-warning-border/30 bg-status-warning-bg-subtle',\n purple: 'border-accent-purple/30 bg-accent-purple-subtle',\n orange: 'border-status-warning-border/30 bg-status-warning-bg-subtle',\n cyan: 'border-accent-teal/30 bg-accent-teal-subtle',\n pink: 'border-accent-purple/30 bg-accent-purple-subtle',\n };\n\n const previewColorClasses: Record<string, string> = {\n red: 'border-status-error-border/40 bg-gradient-to-br from-status-error-bg/15 to-status-error-bg/5 hover:shadow-status-error-bg/20',\n green:\n 'border-status-success-border/40 bg-gradient-to-br from-status-success-bg/15 to-status-success-bg/5 hover:shadow-status-success-bg/20',\n blue: 'border-accent-blue/40 bg-gradient-to-br from-accent-blue/15 to-accent-blue/5 hover:shadow-accent-blue/20',\n yellow:\n 'border-status-warning-border/40 bg-gradient-to-br from-status-warning-bg/15 to-status-warning-bg/5 hover:shadow-status-warning-bg/20',\n purple:\n 'border-accent-purple/40 bg-gradient-to-br from-accent-purple/15 to-accent-purple/5 hover:shadow-accent-purple/20',\n orange:\n 'border-status-warning-border/40 bg-gradient-to-br from-status-warning-bg/15 to-status-warning-bg/5 hover:shadow-status-warning-bg/20',\n cyan: 'border-accent-teal/40 bg-gradient-to-br from-accent-teal/15 to-accent-teal/5 hover:shadow-accent-teal/20',\n pink: 'border-accent-purple/40 bg-gradient-to-br from-accent-purple/15 to-accent-purple/5 hover:shadow-accent-purple/20',\n };\n\n // Glass-button visual: frosted background + soft border + shadow that\n // intensifies on hover. Per the round-3 streamdeck redesign, both\n // preview and edit modes share the same base treatment so the deck\n // feels consistent — only the per-color tint differs.\n const glassBase =\n 'border-border-default bg-bg-elevated/80 backdrop-blur-md shadow-lg hover:border-border-focus hover:shadow-xl';\n const tileColor = previewMode\n ? button.color && previewColorClasses[button.color]\n ? `${previewColorClasses[button.color]} backdrop-blur-md shadow-lg hover:shadow-xl`\n : glassBase\n : button.color && colorClasses[button.color]\n ? `${colorClasses[button.color]} backdrop-blur-md shadow-md hover:shadow-lg`\n : glassBase;\n\n // Prefer action fields when linked, fall back to inline (deprecated) fields\n const effectiveActionType = button.action?.actionType || button.actionType;\n const effectiveCommand = button.action?.command ?? button.command;\n const effectiveScript = button.action?.script ?? null;\n const effectiveWebhookUrl = button.action?.webhookUrl ?? button.webhookUrl;\n const actionName = button.action?.displayName || button.action?.name || null;\n\n const isWebhook = effectiveActionType === 'WEBHOOK';\n const isScript = effectiveActionType === 'SCRIPT';\n const ActionIcon = isWebhook ? Globe : isScript ? FileCode : Terminal;\n const tooltip = isWebhook\n ? `${button.webhookMethod || 'POST'} ${effectiveWebhookUrl || ''}`\n : isScript\n ? `Script (${button.scriptInterpreter || 'bash'})${effectiveScript ? `: ${effectiveScript.slice(0, 60)}` : ''}`\n : `${effectiveCommand || ''}${button.keyboardShortcut ? ` (${button.keyboardShortcut})` : ''}`;\n\n // In preview mode, the entire tile is clickable to execute\n const handleTileClick = () => {\n if (previewMode && canExecute && !executing) {\n onExecute(button.id);\n }\n };\n\n // Status-dependent styles\n const statusRing =\n executionStatus === 'executing'\n ? 'ring-2 ring-action-primary-bg/60 ring-offset-1'\n : executionStatus === 'success'\n ? 'ring-2 ring-status-success-border/50 ring-offset-1'\n : executionStatus === 'error'\n ? 'ring-2 ring-status-error-border/50 ring-offset-1'\n : '';\n\n const statusBorderOverride =\n executionStatus === 'executing'\n ? 'border-action-primary-bg/60'\n : executionStatus === 'success'\n ? 'border-status-success-border/50'\n : executionStatus === 'error'\n ? 'border-status-error-border/50'\n : '';\n\n // Calm hover + tap motion — drops the previous jumpy executing\n // `animate={{scale}}` loop. Per round-3 UX, the whole tile is the click\n // target so we apply the press-down motion at the wrapper level.\n const tileClickable = previewMode ? canExecute && !executing : canUpdate;\n\n return (\n <motion.div\n className={`relative group h-full ${statusRing} ${isDragOver ? 'ring-2 ring-action-primary-bg ring-offset-1' : ''} ${selected ? 'ring-2 ring-action-primary-bg/40 ring-offset-1' : ''} ${tileClickable ? 'cursor-pointer' : ''} rounded-lg focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:outline-none`}\n whileHover={tileClickable ? { scale: 1.03 } : undefined}\n whileTap={tileClickable ? { scale: 0.97 } : undefined}\n transition={{ duration: 0.15 }}\n >\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (handleTileClick as (...a: unknown[]) => unknown)();\n }\n }}\n onClick={handleTileClick}\n className={`w-full h-full min-h-[80px] rounded-lg border-2 p-3 flex flex-col items-center justify-center gap-2 transition-all duration-200 ${tileColor} ${statusBorderOverride} ${executionStatus === 'executing' ? 'animate-pulse' : ''}`}\n title={tooltip}\n >\n {/* Top-left: webhook method or script interpreter badge */}\n {isWebhook && button.webhookMethod && (\n <span\n className={`absolute left-1.5 text-[9px] font-bold text-text-tertiary bg-bg-tertiary/80 rounded px-1 py-0.5 uppercase ${!previewMode && onToggleSelect ? 'top-8' : 'top-1.5'}`}\n >\n {button.webhookMethod}\n </span>\n )}\n {isScript && button.scriptInterpreter && (\n <span\n className={`absolute left-1.5 text-[9px] font-bold text-text-tertiary bg-bg-tertiary/80 rounded px-1 py-0.5 ${!previewMode && onToggleSelect ? 'top-8' : 'top-1.5'}`}\n >\n {button.scriptInterpreter}\n </span>\n )}\n\n {!previewMode && onToggleSelect && (\n <div\n className=\"absolute top-1.5 left-1.5 z-10\"\n onClick={(event) => event.stopPropagation()}\n >\n <SelectionCheckbox\n checked={selected}\n onChange={onToggleSelect}\n ariaLabel={`Select vibe deck button ${button.label}`}\n />\n </div>\n )}\n\n {/* Bottom-left: confirmation required warning */}\n {button.confirmationRequired && (\n <AlertTriangle\n size={10}\n className=\"absolute bottom-1.5 left-1.5 text-status-warning-text\"\n />\n )}\n\n <ActionIcon\n size={previewMode ? 24 : 20}\n className={previewMode ? 'text-text-primary' : 'text-text-secondary'}\n />\n <span\n className={`font-medium text-text-primary text-center leading-tight line-clamp-2 ${previewMode ? 'text-base' : 'text-sm'}`}\n >\n {button.label}\n </span>\n {actionName && (\n <span className=\"text-[10px] text-action-primary-bg/70 font-medium truncate max-w-full px-1\">\n {actionName}\n </span>\n )}\n {button.category && (\n <span className=\"text-[10px] text-text-tertiary uppercase tracking-wider\">\n {button.category}\n </span>\n )}\n\n {/* Execution status indicator */}\n <AnimatePresence>\n {executionStatus === 'executing' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.8 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-action-primary-bg flex items-center justify-center shadow-sm\">\n <Loader2 size={11} className=\"text-text-inverse animate-spin\" />\n </div>\n </motion.div>\n )}\n {executionStatus === 'success' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.5 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.5 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-status-success-bg flex items-center justify-center shadow-sm\">\n <Check size={11} className=\"text-text-inverse\" strokeWidth={3} />\n </div>\n </motion.div>\n )}\n {executionStatus === 'error' && (\n <motion.div\n initial={{ opacity: 0, scale: 0.5 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.5 }}\n className=\"absolute top-1.5 right-1.5 z-10\"\n >\n <div className=\"size-5 rounded-full bg-status-error-bg flex items-center justify-center shadow-sm\">\n <X size={11} className=\"text-text-inverse\" strokeWidth={3} />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Preview mode: centered play overlay on hover */}\n {previewMode && canExecute && executionStatus !== 'executing' && (\n <div className=\"absolute inset-0 rounded-lg flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-bg-elevated/40 backdrop-blur-[1px]\">\n <div className=\"size-10 rounded-full bg-status-success-bg/90 flex items-center justify-center shadow-md\">\n <Play size={18} className=\"text-status-success-text ml-0.5\" />\n </div>\n </div>\n )}\n </div>\n\n {/* Prominent Play button — calm, centred-top, glass-styled.\n Round-3 redesign drops the jumpy scale loop and bumps the size\n so the action is obvious in edit mode without competing with\n the tile's drag handle on hover. */}\n {!previewMode && canExecute && (\n <motion.button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onExecute(button.id);\n }}\n disabled={executing}\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n transition={{ duration: 0.15 }}\n className=\"absolute -top-3 left-1/2 -translate-x-1/2 size-14 rounded-full bg-action-primary-bg text-action-primary-text shadow-xl flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed opacity-0 group-hover:opacity-100 focus-visible:opacity-100 transition-opacity duration-200 z-20\"\n title=\"Execute\"\n aria-label=\"Execute button\"\n >\n <Play size={20} className=\"ml-0.5\" />\n </motion.button>\n )}\n\n {/* Bottom-right: Edit / Delete — visible on hover in edit mode only */}\n {!previewMode && (canUpdate || canDelete) && (\n <div className=\"absolute bottom-0.5 right-0.5 flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity\">\n {canUpdate && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit(button.id);\n }}\n className=\"p-1 rounded bg-bg-elevated/80 hover:bg-bg-elevated text-text-tertiary hover:text-text-primary shadow-sm\"\n title=\"Edit\"\n >\n <Pencil size={12} />\n </button>\n )}\n {canDelete && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(button.id);\n }}\n className=\"p-1 rounded bg-bg-elevated/80 hover:bg-bg-elevated text-text-tertiary hover:text-status-error-text shadow-sm\"\n title=\"Delete\"\n >\n <Trash2 size={12} />\n </button>\n )}\n </div>\n )}\n </motion.div>\n );\n};\n"],"mappings":"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"}
@@ -107,9 +107,9 @@ var s = ({ gridColumns: s, gridRows: c, buttons: l, onExecuteButton: u, onEditBu
107
107
  }) : g ? /* @__PURE__ */ o("button", {
108
108
  type: "button",
109
109
  onClick: () => m(t, n),
110
- className: "w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-default/50 hover:border-border-default flex items-center justify-center text-text-tertiary hover:text-text-secondary transition-all hover:bg-bg-secondary/50",
110
+ className: "w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-strong text-text-tertiary hover:border-border-focus hover:text-text-secondary flex items-center justify-center transition-all hover:bg-bg-secondary/50",
111
111
  children: /* @__PURE__ */ o(a, { size: 18 })
112
- }) : /* @__PURE__ */ o("div", { className: "w-full h-full min-h-[80px] rounded-lg border border-border-default/20" })
112
+ }) : /* @__PURE__ */ o("div", { className: "w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-default" })
113
113
  }, r));
114
114
  }
115
115
  }
@@ -1 +1 @@
1
- {"version":3,"file":"VibeDeckGrid.js","names":[],"sources":["../../../src/components/vibedeck/VibeDeckGrid.tsx"],"sourcesContent":["import { type FC, type ReactElement, useState, useCallback, useMemo } from 'react';\nimport { Plus } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { VibeDeckButtonTile } from './VibeDeckButtonTile';\n\ninterface ActionRef {\n id: string;\n name: string;\n displayName: string | null;\n actionType: string;\n command: string | null;\n script: string | null;\n webhookUrl: string | null;\n targetAgentId: string | null;\n}\n\ninterface ButtonData {\n id: string;\n label: string;\n icon: string | null;\n color: string | null;\n command: string | null;\n actionType: string;\n category: string | null;\n confirmationRequired: boolean;\n keyboardShortcut: string | null;\n targetAgentId: string | null;\n scriptInterpreter: string | null;\n webhookUrl: string | null;\n webhookMethod: string | null;\n actionId?: string | null;\n action?: ActionRef | null;\n row: number;\n column: number;\n rowSpan: number;\n colSpan: number;\n}\n\ninterface VibeDeckGridProps {\n gridColumns: number;\n gridRows: number;\n buttons: ButtonData[];\n onExecuteButton: (id: string) => void;\n onEditButton: (id: string) => void;\n onDeleteButton: (id: string) => void;\n onDropButton: (buttonId: string, targetRow: number, targetColumn: number) => void;\n onAddButton: (row: number, column: number) => void;\n executingButtonId: string | null;\n canCreate: boolean;\n canUpdate: boolean;\n canDelete: boolean;\n canExecute: boolean;\n}\n\nexport const VibeDeckGrid: FC<VibeDeckGridProps> = ({\n gridColumns,\n gridRows,\n buttons,\n onExecuteButton,\n onEditButton,\n onDeleteButton,\n onDropButton,\n onAddButton,\n executingButtonId,\n canCreate,\n canUpdate,\n canDelete,\n canExecute,\n}) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string) => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n\n const [dragState, setDragState] = useState<{\n draggingId: string | null;\n targetKey: string | null;\n }>({ draggingId: null, targetKey: null });\n\n // Build a map of occupied cells (memoized to stabilize hook dependencies)\n const { occupiedCells, buttonAtCell } = useMemo(() => {\n const occupied = new Set<string>();\n const cellMap = new Map<string, ButtonData>();\n for (const btn of buttons) {\n for (let r = btn.row; r < btn.row + btn.rowSpan; r++) {\n for (let c = btn.column; c < btn.column + btn.colSpan; c++) {\n occupied.add(`${r},${c}`);\n }\n }\n cellMap.set(`${btn.row},${btn.column}`, btn);\n }\n return { occupiedCells: occupied, buttonAtCell: cellMap };\n }, [buttons]);\n\n const handleDragStart = useCallback((e: React.DragEvent, buttonId: string) => {\n e.dataTransfer.setData('text/plain', buttonId);\n e.dataTransfer.effectAllowed = 'move';\n setDragState({ draggingId: buttonId, targetKey: null });\n }, []);\n\n const isDropValid = useCallback(\n (targetRow: number, targetCol: number) => {\n if (!dragState.draggingId) return false;\n const btn = buttons.find((b) => b.id === dragState.draggingId);\n if (!btn) return false;\n // Check grid boundary\n if (targetRow + btn.rowSpan > gridRows || targetCol + btn.colSpan > gridColumns) return false;\n // Check collision with other buttons\n for (let r = targetRow; r < targetRow + btn.rowSpan; r++) {\n for (let c = targetCol; c < targetCol + btn.colSpan; c++) {\n if (occupiedCells.has(`${r},${c}`)) {\n // Allow overlap with the dragged button's own current footprint\n const isOwnCell =\n r >= btn.row &&\n r < btn.row + btn.rowSpan &&\n c >= btn.column &&\n c < btn.column + btn.colSpan;\n if (!isOwnCell) return false;\n }\n }\n }\n return true;\n },\n [dragState.draggingId, buttons, gridRows, gridColumns, occupiedCells]\n );\n\n const handleDragOver = useCallback(\n (e: React.DragEvent, key: string, row: number, col: number) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n if (isDropValid(row, col)) {\n setDragState((prev) => ({ ...prev, targetKey: key }));\n } else {\n setDragState((prev) => ({ ...prev, targetKey: null }));\n }\n },\n [isDropValid]\n );\n\n const handleDragLeave = useCallback(() => {\n setDragState((prev) => ({ ...prev, targetKey: null }));\n }, []);\n\n const handleDrop = useCallback(\n (e: React.DragEvent, row: number, col: number) => {\n e.preventDefault();\n const buttonId = e.dataTransfer.getData('text/plain');\n setDragState({ draggingId: null, targetKey: null });\n if (buttonId && isDropValid(row, col)) {\n onDropButton(buttonId, row, col);\n }\n },\n [onDropButton, isDropValid]\n );\n\n const handleDragEnd = useCallback(() => {\n setDragState({ draggingId: null, targetKey: null });\n }, []);\n\n // Build grid cells\n const cells: ReactElement[] = [];\n for (let row = 0; row < gridRows; row++) {\n for (let col = 0; col < gridColumns; col++) {\n const key = `${row},${col}`;\n const button = buttonAtCell.get(key);\n\n if (button) {\n const isDragging = dragState.draggingId === button.id;\n cells.push(\n <div\n key={key}\n style={{\n gridRow: `${row + 1} / span ${button.rowSpan}`,\n gridColumn: `${col + 1} / span ${button.colSpan}`,\n }}\n draggable={canUpdate}\n onDragStart={(e) => handleDragStart(e, button.id)}\n onDragEnd={handleDragEnd}\n className={`${isDragging ? 'opacity-40' : ''} ${canUpdate ? 'cursor-grab active:cursor-grabbing' : ''}`}\n >\n <VibeDeckButtonTile\n button={button}\n onExecute={onExecuteButton}\n onEdit={onEditButton}\n onDelete={onDeleteButton}\n canUpdate={canUpdate}\n canDelete={canDelete}\n canExecute={canExecute}\n executing={executingButtonId === button.id}\n />\n </div>\n );\n } else if (!occupiedCells.has(key)) {\n const isDropTarget = dragState.draggingId && dragState.targetKey === key;\n cells.push(\n <div\n key={key}\n style={{ gridRow: row + 1, gridColumn: col + 1 }}\n onDragOver={(e) => handleDragOver(e, key, row, col)}\n onDragLeave={handleDragLeave}\n onDrop={(e) => handleDrop(e, row, col)}\n >\n {dragState.draggingId ? (\n <div\n className={`w-full h-full min-h-[80px] rounded-lg border-2 border-dashed flex items-center justify-center transition-all ${\n isDropTarget\n ? 'border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg'\n : 'border-border-default/30 text-text-tertiary/30'\n }`}\n >\n {isDropTarget && (\n <span className=\"text-xs font-medium\">\n {tr('vibeDeck.dropHere', 'Drop here')}\n </span>\n )}\n </div>\n ) : canCreate ? (\n <button\n type=\"button\"\n onClick={() => onAddButton(row, col)}\n className=\"w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-default/50 hover:border-border-default flex items-center justify-center text-text-tertiary hover:text-text-secondary transition-all hover:bg-bg-secondary/50\"\n >\n <Plus size={18} />\n </button>\n ) : (\n <div className=\"w-full h-full min-h-[80px] rounded-lg border border-border-default/20\" />\n )}\n </div>\n );\n }\n }\n }\n\n return (\n <div\n className=\"grid gap-3\"\n style={{\n gridTemplateColumns: `repeat(${gridColumns}, 1fr)`,\n gridTemplateRows: `repeat(${gridRows}, auto)`,\n }}\n >\n {cells}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"VibeDeckGrid.js","names":[],"sources":["../../../src/components/vibedeck/VibeDeckGrid.tsx"],"sourcesContent":["import { type FC, type ReactElement, useState, useCallback, useMemo } from 'react';\nimport { Plus } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { VibeDeckButtonTile } from './VibeDeckButtonTile';\n\ninterface ActionRef {\n id: string;\n name: string;\n displayName: string | null;\n actionType: string;\n command: string | null;\n script: string | null;\n webhookUrl: string | null;\n targetAgentId: string | null;\n}\n\ninterface ButtonData {\n id: string;\n label: string;\n icon: string | null;\n color: string | null;\n command: string | null;\n actionType: string;\n category: string | null;\n confirmationRequired: boolean;\n keyboardShortcut: string | null;\n targetAgentId: string | null;\n scriptInterpreter: string | null;\n webhookUrl: string | null;\n webhookMethod: string | null;\n actionId?: string | null;\n action?: ActionRef | null;\n row: number;\n column: number;\n rowSpan: number;\n colSpan: number;\n}\n\ninterface VibeDeckGridProps {\n gridColumns: number;\n gridRows: number;\n buttons: ButtonData[];\n onExecuteButton: (id: string) => void;\n onEditButton: (id: string) => void;\n onDeleteButton: (id: string) => void;\n onDropButton: (buttonId: string, targetRow: number, targetColumn: number) => void;\n onAddButton: (row: number, column: number) => void;\n executingButtonId: string | null;\n canCreate: boolean;\n canUpdate: boolean;\n canDelete: boolean;\n canExecute: boolean;\n}\n\nexport const VibeDeckGrid: FC<VibeDeckGridProps> = ({\n gridColumns,\n gridRows,\n buttons,\n onExecuteButton,\n onEditButton,\n onDeleteButton,\n onDropButton,\n onAddButton,\n executingButtonId,\n canCreate,\n canUpdate,\n canDelete,\n canExecute,\n}) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string) => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n\n const [dragState, setDragState] = useState<{\n draggingId: string | null;\n targetKey: string | null;\n }>({ draggingId: null, targetKey: null });\n\n // Build a map of occupied cells (memoized to stabilize hook dependencies)\n const { occupiedCells, buttonAtCell } = useMemo(() => {\n const occupied = new Set<string>();\n const cellMap = new Map<string, ButtonData>();\n for (const btn of buttons) {\n for (let r = btn.row; r < btn.row + btn.rowSpan; r++) {\n for (let c = btn.column; c < btn.column + btn.colSpan; c++) {\n occupied.add(`${r},${c}`);\n }\n }\n cellMap.set(`${btn.row},${btn.column}`, btn);\n }\n return { occupiedCells: occupied, buttonAtCell: cellMap };\n }, [buttons]);\n\n const handleDragStart = useCallback((e: React.DragEvent, buttonId: string) => {\n e.dataTransfer.setData('text/plain', buttonId);\n e.dataTransfer.effectAllowed = 'move';\n setDragState({ draggingId: buttonId, targetKey: null });\n }, []);\n\n const isDropValid = useCallback(\n (targetRow: number, targetCol: number) => {\n if (!dragState.draggingId) return false;\n const btn = buttons.find((b) => b.id === dragState.draggingId);\n if (!btn) return false;\n // Check grid boundary\n if (targetRow + btn.rowSpan > gridRows || targetCol + btn.colSpan > gridColumns) return false;\n // Check collision with other buttons\n for (let r = targetRow; r < targetRow + btn.rowSpan; r++) {\n for (let c = targetCol; c < targetCol + btn.colSpan; c++) {\n if (occupiedCells.has(`${r},${c}`)) {\n // Allow overlap with the dragged button's own current footprint\n const isOwnCell =\n r >= btn.row &&\n r < btn.row + btn.rowSpan &&\n c >= btn.column &&\n c < btn.column + btn.colSpan;\n if (!isOwnCell) return false;\n }\n }\n }\n return true;\n },\n [dragState.draggingId, buttons, gridRows, gridColumns, occupiedCells]\n );\n\n const handleDragOver = useCallback(\n (e: React.DragEvent, key: string, row: number, col: number) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n if (isDropValid(row, col)) {\n setDragState((prev) => ({ ...prev, targetKey: key }));\n } else {\n setDragState((prev) => ({ ...prev, targetKey: null }));\n }\n },\n [isDropValid]\n );\n\n const handleDragLeave = useCallback(() => {\n setDragState((prev) => ({ ...prev, targetKey: null }));\n }, []);\n\n const handleDrop = useCallback(\n (e: React.DragEvent, row: number, col: number) => {\n e.preventDefault();\n const buttonId = e.dataTransfer.getData('text/plain');\n setDragState({ draggingId: null, targetKey: null });\n if (buttonId && isDropValid(row, col)) {\n onDropButton(buttonId, row, col);\n }\n },\n [onDropButton, isDropValid]\n );\n\n const handleDragEnd = useCallback(() => {\n setDragState({ draggingId: null, targetKey: null });\n }, []);\n\n // Build grid cells\n const cells: ReactElement[] = [];\n for (let row = 0; row < gridRows; row++) {\n for (let col = 0; col < gridColumns; col++) {\n const key = `${row},${col}`;\n const button = buttonAtCell.get(key);\n\n if (button) {\n const isDragging = dragState.draggingId === button.id;\n cells.push(\n <div\n key={key}\n style={{\n gridRow: `${row + 1} / span ${button.rowSpan}`,\n gridColumn: `${col + 1} / span ${button.colSpan}`,\n }}\n draggable={canUpdate}\n onDragStart={(e) => handleDragStart(e, button.id)}\n onDragEnd={handleDragEnd}\n className={`${isDragging ? 'opacity-40' : ''} ${canUpdate ? 'cursor-grab active:cursor-grabbing' : ''}`}\n >\n <VibeDeckButtonTile\n button={button}\n onExecute={onExecuteButton}\n onEdit={onEditButton}\n onDelete={onDeleteButton}\n canUpdate={canUpdate}\n canDelete={canDelete}\n canExecute={canExecute}\n executing={executingButtonId === button.id}\n />\n </div>\n );\n } else if (!occupiedCells.has(key)) {\n const isDropTarget = dragState.draggingId && dragState.targetKey === key;\n cells.push(\n <div\n key={key}\n style={{ gridRow: row + 1, gridColumn: col + 1 }}\n onDragOver={(e) => handleDragOver(e, key, row, col)}\n onDragLeave={handleDragLeave}\n onDrop={(e) => handleDrop(e, row, col)}\n >\n {dragState.draggingId ? (\n <div\n className={`w-full h-full min-h-[80px] rounded-lg border-2 border-dashed flex items-center justify-center transition-all ${\n isDropTarget\n ? 'border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg'\n : 'border-border-default/30 text-text-tertiary/30'\n }`}\n >\n {isDropTarget && (\n <span className=\"text-xs font-medium\">\n {tr('vibeDeck.dropHere', 'Drop here')}\n </span>\n )}\n </div>\n ) : canCreate ? (\n <button\n type=\"button\"\n onClick={() => onAddButton(row, col)}\n className=\"w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-strong text-text-tertiary hover:border-border-focus hover:text-text-secondary flex items-center justify-center transition-all hover:bg-bg-secondary/50\"\n >\n <Plus size={18} />\n </button>\n ) : (\n <div className=\"w-full h-full min-h-[80px] rounded-lg border-2 border-dashed border-border-default\" />\n )}\n </div>\n );\n }\n }\n }\n\n return (\n <div\n className=\"grid gap-3\"\n style={{\n gridTemplateColumns: `repeat(${gridColumns}, 1fr)`,\n gridTemplateRows: `repeat(${gridRows}, auto)`,\n }}\n >\n {cells}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -310,6 +310,6 @@ function f(e) {
310
310
  };
311
311
  }
312
312
  //#endregion
313
- export { e as AI_CORE_PACKAGE, t as AI_PROVIDER_PACKAGES, o as GIT_PACKAGE, s as GRAPHQL_PLAYGROUND_PACKAGE, i as PLAN_META_PACKAGE, a as PLAN_PLANNOTATOR_PACKAGE, l as SECURITY_META_PACKAGE, u as SECURITY_PROVIDER_PACKAGES, n as SESSION_MANAGER_PACKAGE, r as SESSION_PROVIDER_PACKAGES, f as getPluginMeta };
313
+ export { e as AI_CORE_PACKAGE, t as AI_PROVIDER_PACKAGES, o as GIT_PACKAGE, s as GRAPHQL_PLAYGROUND_PACKAGE, i as PLAN_META_PACKAGE, a as PLAN_PLANNOTATOR_PACKAGE, d as PLUGIN_CATALOG, l as SECURITY_META_PACKAGE, u as SECURITY_PROVIDER_PACKAGES, n as SESSION_MANAGER_PACKAGE, r as SESSION_PROVIDER_PACKAGES, f as getPluginMeta };
314
314
 
315
315
  //# sourceMappingURL=pluginCatalog.js.map
@@ -1,2 +1,2 @@
1
- @keyframes fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes slide-in-right{0%{opacity:0;transform:translate(8px)}to{opacity:1;transform:translate(0)}}@keyframes pulse-subtle{0%,to{opacity:1}50%{opacity:.7}}@keyframes shrink-width{0%{width:100%}to{width:0%}}.animate-fade-in{animation:fade-in var(--motion-duration-fast,.15s) ease-out forwards}.animate-slide-in-right{animation:slide-in-right var(--motion-duration-fast,.15s) ease-out forwards}.animate-pulse-subtle{animation:2s ease-in-out infinite pulse-subtle}.animate-shrink-width{animation:linear forwards shrink-width}.react-flow__pane{touch-action:none!important}.react-flow__edge{cursor:pointer}.react-flow__edge .react-flow__edge-path{transition:stroke-width .16s,filter .16s}.react-flow__edge:hover .react-flow__edge-path{stroke-width:3px}.react-flow__edge.selected .react-flow__edge-path{stroke-width:3px;filter:drop-shadow(0 0 2px var(--color-action-primary-bg))}
1
+ @media print{[data-app-shell-sidenav],[data-app-shell-header],nav[aria-label=Primary],.vc-print-hide{display:none!important}body{color:#000!important;background:#fff!important}.vc-printable{background:0 0!important;width:100%!important;max-width:none!important;margin:0!important;padding:0!important}.vc-printable .recharts-wrapper,.vc-printable .recharts-surface{width:100%!important;max-width:100%!important}table{page-break-inside:auto}tr{page-break-inside:avoid;page-break-after:auto}}@keyframes fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes slide-in-right{0%{opacity:0;transform:translate(8px)}to{opacity:1;transform:translate(0)}}@keyframes pulse-subtle{0%,to{opacity:1}50%{opacity:.7}}@keyframes shrink-width{0%{width:100%}to{width:0%}}.animate-fade-in{animation:fade-in var(--motion-duration-fast,.15s) ease-out forwards}.animate-slide-in-right{animation:slide-in-right var(--motion-duration-fast,.15s) ease-out forwards}.animate-pulse-subtle{animation:2s ease-in-out infinite pulse-subtle}.animate-shrink-width{animation:linear forwards shrink-width}.react-flow__pane{touch-action:none!important}.react-flow__edge{cursor:pointer}.react-flow__edge .react-flow__edge-path{transition:stroke-width .16s,filter .16s}.react-flow__edge:hover .react-flow__edge-path{stroke-width:3px}.react-flow__edge.selected .react-flow__edge-path{stroke-width:3px;filter:drop-shadow(0 0 2px var(--color-action-primary-bg))}
2
2
  /*$vite$:1*/
@@ -1363,7 +1363,7 @@ function bt() {
1363
1363
  return /* @__PURE__ */ C("button", {
1364
1364
  type: "button",
1365
1365
  onClick: () => kn(e.id),
1366
- className: `flex shrink-0 items-center gap-1.5 px-3 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${t ? "border-action-primary-bg text-action-primary-text" : "border-transparent text-text-secondary hover:text-text-primary hover:border-border-default"}`,
1366
+ className: `flex shrink-0 items-center gap-1.5 px-3 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${t ? "border-action-primary-bg text-action-primary-bg" : "border-transparent text-text-secondary hover:text-text-primary hover:border-border-default"}`,
1367
1367
  children: [
1368
1368
  /* @__PURE__ */ S(n, { className: "size-3.5" }),
1369
1369
  e.label,
@@ -1487,7 +1487,7 @@ function bt() {
1487
1487
  type: "button",
1488
1488
  onClick: () => Hn(e.packageName),
1489
1489
  disabled: xn === e.packageName,
1490
- className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs text-status-error-text bg-status-error-bg rounded-md hover:bg-status-error-bg/80 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
1490
+ className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-status-error-text bg-status-error-bg/15 border border-status-error-border/40 rounded-md hover:bg-status-error-bg/25 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
1491
1491
  children: [xn === e.packageName ? /* @__PURE__ */ S(_, { className: "size-3 animate-spin" }) : /* @__PURE__ */ S(lt, { className: "size-3" }), "Remove"]
1492
1492
  })]
1493
1493
  })]