@burdenoff/microfe-botmanor 2026.821.1 → 2026.925.1

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 (65) hide show
  1. package/dist/botlit/BotlitRoutes.js.map +1 -1
  2. package/dist/botlit/BotmanorRoot.js.map +1 -1
  3. package/dist/botlit/BotmanorRootInner.js +4 -4
  4. package/dist/botlit/BotmanorRootInner.js.map +1 -1
  5. package/dist/botlit/components/ErrorState.js +33 -29
  6. package/dist/botlit/components/ErrorState.js.map +1 -1
  7. package/dist/botlit/components/RouteLoader.js +52 -48
  8. package/dist/botlit/components/RouteLoader.js.map +1 -1
  9. package/dist/botlit/components/VersionHistoryPanel.js +74 -77
  10. package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
  11. package/dist/botlit/components/WorkspaceRequired.js +31 -30
  12. package/dist/botlit/components/WorkspaceRequired.js.map +1 -1
  13. package/dist/botlit/hooks/internal/workspaceGateway.js.map +1 -1
  14. package/dist/botlit/hooks/useConversations.js.map +1 -1
  15. package/dist/botlit/hooks/useLLMProviders.js.map +1 -1
  16. package/dist/botlit/pages/A2AAgentDetailPage.js +1 -1
  17. package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
  18. package/dist/botlit/pages/A2ARegistryPage.js +116 -124
  19. package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
  20. package/dist/botlit/pages/AgentDetailPage.js +169 -172
  21. package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
  22. package/dist/botlit/pages/AgentsListPage.js +96 -90
  23. package/dist/botlit/pages/AgentsListPage.js.map +1 -1
  24. package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
  25. package/dist/botlit/pages/BotDetailPage.js +228 -231
  26. package/dist/botlit/pages/BotDetailPage.js.map +1 -1
  27. package/dist/botlit/pages/BotWorkflowTab.js +84 -87
  28. package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
  29. package/dist/botlit/pages/BotsListPage.js +144 -147
  30. package/dist/botlit/pages/BotsListPage.js.map +1 -1
  31. package/dist/botlit/pages/BucketsPage.js +3 -3
  32. package/dist/botlit/pages/BucketsPage.js.map +1 -1
  33. package/dist/botlit/pages/ChannelDetailPage.js +1 -1
  34. package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
  35. package/dist/botlit/pages/ChannelsPage.js +156 -149
  36. package/dist/botlit/pages/ChannelsPage.js.map +1 -1
  37. package/dist/botlit/pages/ChatPage.js +126 -129
  38. package/dist/botlit/pages/ChatPage.js.map +1 -1
  39. package/dist/botlit/pages/DashboardPage.js +111 -114
  40. package/dist/botlit/pages/DashboardPage.js.map +1 -1
  41. package/dist/botlit/pages/ExecutionsPage.js +163 -159
  42. package/dist/botlit/pages/ExecutionsPage.js.map +1 -1
  43. package/dist/botlit/pages/InstalledPackagesPage.js +3 -3
  44. package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
  45. package/dist/botlit/pages/KnowledgeBasesPage.js +84 -78
  46. package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
  47. package/dist/botlit/pages/MCPServersPage.js +159 -154
  48. package/dist/botlit/pages/MCPServersPage.js.map +1 -1
  49. package/dist/botlit/pages/PoliciesPage.js +119 -114
  50. package/dist/botlit/pages/PoliciesPage.js.map +1 -1
  51. package/dist/botlit/pages/RetrievalProfilesPage.js +102 -109
  52. package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
  53. package/dist/botlit/pages/SettingsPage.js +144 -159
  54. package/dist/botlit/pages/SettingsPage.js.map +1 -1
  55. package/dist/botlit/pages/SkillsPage.js +122 -105
  56. package/dist/botlit/pages/SkillsPage.js.map +1 -1
  57. package/dist/botlit/pages/StorePage.js +176 -175
  58. package/dist/botlit/pages/StorePage.js.map +1 -1
  59. package/dist/botlit/providers/BotlitProvider.js.map +1 -1
  60. package/dist/botlit/store/botlitStore.js +1 -1
  61. package/dist/botlit/store/botlitStore.js.map +1 -1
  62. package/dist/botlit/utils/navigation.js.map +1 -1
  63. package/dist/shared/hooks/useTr.js +14 -0
  64. package/dist/shared/hooks/useTr.js.map +1 -0
  65. package/package.json +33 -9
@@ -1 +1 @@
1
- {"version":3,"file":"BotWorkflowTab.js","names":[],"sources":["../../../src/botlit/pages/BotWorkflowTab.tsx"],"sourcesContent":["/**\n * BotWorkflowTab\n * @module botlit/pages\n *\n * Shown inside BotDetailPage → \"Workflow\" tab.\n *\n * A bot's behaviour is designed as a FluidGrids workflow. `BotApp.workflowId`\n * holds the binding (validated server-side by `assertWorkflowBindingsResolvable`\n * on wspace-botlit-svc), and the FluidGrids builder is already mounted INSIDE\n * Botlit at `workflows/workflow/:id/:version` — so this tab never leaves the\n * product.\n *\n * Flow:\n * 1. Bound → resolve the definition by id (`useWorkflowDefinition`), show\n * name / key / version / status, \"Open in builder\", \"Unbind\".\n * A binding that no longer resolves falls back to the raw id so\n * the user can still clear it.\n * 2. Not bound → zero state whose primary action creates a seeded workflow\n * definition, binds it via `updateBotApp(workflowId)` and drops\n * the user straight into the embedded builder.\n *\n * IMPORTANT — seed graph shape. `BotlitFluidGridsBridge.extractTriggerNodeIds`\n * reads nodes from `definitionJson.data.nodes` (NOT the top level) and treats a\n * node as a trigger when its `type` is `trigger`/`trigger:*`/`*_trigger`, OR its\n * `kind[]` / `data.nodeData.kind[]` contains `trigger`. The seed below uses the\n * workflow service's own BUILTIN manual trigger (`internal:api`, \"Trigger\n * Manually\") — the node the executor resolves as the entry point — and carries\n * `kind: ['trigger', ...]` in both places, so a freshly designed bot is\n * immediately runnable instead of failing with `WORKFLOW_NO_TRIGGER_NODE`.\n */\n\nimport type { FC } from 'react';\nimport { useCallback, useState } from 'react';\nimport { ExternalLink, Sparkles, Unlink, Workflow } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useCreateWorkflow, useWorkflowDefinition } from '@burdenoff/fluidgrids-fe-sdk';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { useUpdateBot } from '../hooks/useBots';\nimport { useBotlit } from '../providers/BotlitProvider';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Seed graph\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** First version minted for a bot's workflow — matches the builder's own default. */\nconst INITIAL_VERSION = 'v1';\n\n/**\n * BUILTIN \"Trigger Manually\" node (`MANUAL_TRIGGER_MANIFEST` in\n * wspace-workflow-svc). The executor resolves this type as a workflow's entry\n * node, and the builder renders it from the seeded node registry.\n */\nconst MANUAL_TRIGGER_NODE_TYPE = 'internal:api';\nconst MANUAL_TRIGGER_NODE_VERSION = '1.0.0';\nconst MANUAL_TRIGGER_OPERATION = 'onManualTrigger';\nconst MANUAL_TRIGGER_NAME = 'Trigger Manually';\nconst MANUAL_TRIGGER_DESCRIPTION =\n \"Runs the flow when you click 'Test workflow', or when this bot is invoked.\";\n\n/** `kind[]` the Botlit bridge scans for when classifying a node as a trigger. */\nconst MANUAL_TRIGGER_KIND = ['trigger', 'manual', 'entry'];\n\n/** Node shape written into `definitionJson.data.nodes`. */\ntype SeedNode = {\n id: string;\n type: string;\n position: { x: number; y: number };\n /** Top-level kind — the bridge's second trigger-detection path. */\n kind: string[];\n data: {\n operation_name: string;\n operation_type: string;\n version: string;\n nodeData: {\n nodeType: string;\n name: string;\n description: string;\n version: string;\n /** The bridge's third trigger-detection path. */\n kind: string[];\n operations: { name: string; type: string; role: string; description: string }[];\n };\n args: {\n context: { node: { id: string; type: string; kind: string[] } };\n state: Record<string, never>;\n credentials: never[];\n };\n };\n};\n\n/**\n * `definitionJson` document. Mirrors what the builder itself persists\n * (`useSaveWorkflow`) so the graph round-trips through the builder unchanged.\n */\ntype SeedDefinition = {\n key: string;\n name: string;\n description: string;\n workflow_type: string;\n data: {\n id: string;\n workflowKey: string;\n version: string;\n name: string;\n nodes: SeedNode[];\n edges: never[];\n sidebar: { active: string; panels: { nodeProperties: { selectedNode: null } } };\n stickyNotes: never[];\n };\n meta: { creator: string; version: string };\n tags: string[];\n};\n\n/**\n * Generate an opaque id. `crypto.randomUUID` is unavailable on insecure origins\n * and in some test environments, so fall back to a time+random token rather than\n * throwing mid-create.\n */\nfunction generateId(): string {\n const webCrypto = globalThis.crypto as Crypto | undefined;\n if (webCrypto && typeof webCrypto.randomUUID === 'function') {\n return webCrypto.randomUUID();\n }\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Build the starter graph: one manual trigger, nothing else. */\nfunction buildSeedDefinition(workflowKey: string, name: string): SeedDefinition {\n const triggerNode: SeedNode = {\n id: generateId(),\n type: MANUAL_TRIGGER_NODE_TYPE,\n position: { x: 160, y: 160 },\n kind: MANUAL_TRIGGER_KIND,\n data: {\n operation_name: MANUAL_TRIGGER_OPERATION,\n operation_type: 'trigger',\n version: MANUAL_TRIGGER_NODE_VERSION,\n nodeData: {\n nodeType: MANUAL_TRIGGER_NODE_TYPE,\n name: MANUAL_TRIGGER_NAME,\n description: MANUAL_TRIGGER_DESCRIPTION,\n version: MANUAL_TRIGGER_NODE_VERSION,\n kind: MANUAL_TRIGGER_KIND,\n operations: [\n {\n name: MANUAL_TRIGGER_OPERATION,\n type: 'trigger',\n role: 'trigger',\n description: MANUAL_TRIGGER_DESCRIPTION,\n },\n ],\n },\n args: {\n context: {\n node: {\n id: MANUAL_TRIGGER_NODE_TYPE,\n type: MANUAL_TRIGGER_NODE_TYPE,\n kind: MANUAL_TRIGGER_KIND,\n },\n },\n state: {},\n credentials: [],\n },\n },\n };\n\n return {\n key: workflowKey,\n name,\n description: name,\n workflow_type: 'query-conditional',\n data: {\n id: workflowKey,\n workflowKey,\n version: INITIAL_VERSION,\n name,\n nodes: [triggerNode],\n edges: [],\n sidebar: { active: 'store-browse', panels: { nodeProperties: { selectedNode: null } } },\n stickyNotes: [],\n },\n meta: { creator: 'botlit_bot_design', version: INITIAL_VERSION },\n tags: [],\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Component\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface BotWorkflowTabProps {\n botId: string;\n botName: string;\n /** `BotApp.workflowId` — the bound workflow definition id, if any. */\n workflowId: string | null | undefined;\n /** Refetch the bot so the tab reflects the new binding. */\n onWorkflowChanged: () => Promise<void> | void;\n}\n\nexport const BotWorkflowTab: FC<BotWorkflowTabProps> = ({\n botId,\n botName,\n workflowId,\n onWorkflowChanged,\n}) => {\n const { t: translate } = useI18n();\n // Stable identity: the create/unbind callbacks below close over `t`, so a new\n // function every render would invalidate them (and their consumers) each time.\n const t = useCallback(\n (key: string, fallback: string) => {\n const value = translate(key);\n return value === key ? fallback : value;\n },\n [translate]\n );\n const { navigateTo } = useBotlit();\n const { createWorkflow } = useCreateWorkflow();\n const [updateBot] = useUpdateBot();\n const [busy, setBusy] = useState(false);\n\n // Resolve by id — `BotApp.workflowId` stores the definition's opaque id, not\n // its workflowKey (which is what the builder route takes). The hook refetches\n // on its own when the bound id changes, so binding/unbinding only has to\n // refresh the bot.\n const { workflow, loading: workflowLoading } = useWorkflowDefinition(\n undefined,\n workflowId ?? undefined\n );\n\n const openBuilder = useCallback(\n (workflowKey: string, version: string) => {\n navigateTo(`workflows/workflow/${workflowKey}/${version || INITIAL_VERSION}`);\n },\n [navigateTo]\n );\n\n const handleDesign = useCallback(async () => {\n setBusy(true);\n try {\n const workflowKey = generateId();\n const name = `${botName} workflow`;\n const created = await createWorkflow({\n workflowKey,\n version: INITIAL_VERSION,\n name,\n description: t(\n 'botlit.botDetail.workflow.createdDescription',\n 'Behaviour designed for this Botlit bot.'\n ),\n definitionJson: buildSeedDefinition(workflowKey, name),\n });\n\n if (!created) {\n throw new Error(\n t('botlit.botDetail.workflow.createError', 'Failed to create the workflow')\n );\n }\n\n await updateBot({ botId, input: { workflowId: created.id } });\n await onWorkflowChanged();\n toast.success(\n t('botlit.botDetail.workflow.createSuccess', 'Workflow created and bound to this bot')\n );\n openBuilder(created.workflowKey, created.version);\n } catch (err: unknown) {\n const message =\n err instanceof Error\n ? err.message\n : t('botlit.botDetail.workflow.createError', 'Failed to create the workflow');\n toast.error(message);\n } finally {\n setBusy(false);\n }\n }, [botId, botName, createWorkflow, onWorkflowChanged, openBuilder, t, updateBot]);\n\n const handleUnbind = useCallback(async () => {\n if (\n !confirm(\n t(\n 'botlit.botDetail.workflow.unbindConfirm',\n 'Unbind this workflow from the bot? The workflow itself is not deleted.'\n )\n )\n ) {\n return;\n }\n setBusy(true);\n try {\n await updateBot({ botId, input: { workflowId: null } });\n await onWorkflowChanged();\n toast.success(t('botlit.botDetail.workflow.unbindSuccess', 'Workflow unbound'));\n } catch (err: unknown) {\n const message =\n err instanceof Error\n ? err.message\n : t('botlit.botDetail.workflow.unbindError', 'Failed to unbind the workflow');\n toast.error(message);\n } finally {\n setBusy(false);\n }\n }, [botId, onWorkflowChanged, t, updateBot]);\n\n // ── Not bound ─────────────────────────────────────────────────────────────\n if (!workflowId) {\n return (\n <Card>\n <CardContent className=\"pt-6\">\n <EmptyState\n illustration=\"empty-generic\"\n title={t('botlit.botDetail.workflow.empty.title', 'Design this bot as a workflow')}\n description={t(\n 'botlit.botDetail.workflow.empty.description',\n \"A bot's behaviour is designed as a FluidGrids workflow — the visual canvas where you wire triggers, agents, tools and conditions together. Start one and we will create it, bind it to this bot and open the builder for you.\"\n )}\n action={\n <Button\n leftIcon={<Sparkles size={16} />}\n isLoading={busy}\n disabled={busy}\n onClick={() => void handleDesign()}\n >\n {t('botlit.botDetail.workflow.empty.action', 'Design in workflow builder')}\n </Button>\n }\n />\n </CardContent>\n </Card>\n );\n }\n\n // ── Bound ─────────────────────────────────────────────────────────────────\n return (\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Workflow size={18} />\n {t('botlit.botDetail.workflow.bound.title', 'Bound workflow')}\n </CardTitle>\n <CardDescription>\n {t(\n 'botlit.botDetail.workflow.bound.description',\n 'This workflow defines what the bot does when it is invoked.'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n {workflowLoading ? (\n <div className=\"h-24 rounded-lg bg-bg-sunken motion-safe:animate-vc-shimmer\" />\n ) : workflow ? (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.botDetail.workflow.fields.name', 'Name')}\n </p>\n <p className=\"font-medium text-text-primary\">{workflow.name}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.botDetail.workflow.fields.key', 'Key')}\n </p>\n <p className=\"mt-1 break-all font-mono text-sm text-text-primary\">\n {workflow.workflowKey}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.botDetail.workflow.fields.version', 'Version')}\n </p>\n <Badge variant=\"outline\" className=\"mt-1\">\n {workflow.version}\n </Badge>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.botDetail.workflow.fields.status', 'Status')}\n </p>\n <div className=\"mt-1\">\n <StatusBadge status={workflow.status} />\n </div>\n </div>\n </div>\n ) : (\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.botDetail.workflow.fields.workflowId', 'Workflow ID')}\n </p>\n <p className=\"mt-1 break-all font-mono text-sm text-text-primary\">{workflowId}</p>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {t(\n 'botlit.botDetail.workflow.unresolved',\n 'This workflow could not be loaded — it may have been deleted. Unbind it and design a new one.'\n )}\n </p>\n </div>\n )}\n\n <div className=\"flex flex-wrap gap-2\">\n {workflow && (\n <Button\n leftIcon={<ExternalLink size={16} />}\n disabled={busy}\n onClick={() => openBuilder(workflow.workflowKey, workflow.version)}\n >\n {t('botlit.botDetail.workflow.actions.openBuilder', 'Open in builder')}\n </Button>\n )}\n <Button\n variant=\"outline\"\n leftIcon={<Unlink size={16} />}\n isLoading={busy}\n disabled={busy}\n onClick={() => void handleUnbind()}\n >\n {t('botlit.botDetail.workflow.actions.unbind', 'Unbind')}\n </Button>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"BotWorkflowTab.js","names":[],"sources":["../../../src/botlit/pages/BotWorkflowTab.tsx"],"sourcesContent":["/**\n * BotWorkflowTab\n * @module botlit/pages\n *\n * Shown inside BotDetailPage → \"Workflow\" tab.\n *\n * A bot's behaviour is designed as a FluidGrids workflow. `BotApp.workflowId`\n * holds the binding (validated server-side by `assertWorkflowBindingsResolvable`\n * on wspace-botlit-svc), and the FluidGrids builder is already mounted INSIDE\n * BotManor at `workflows/workflow/:id/:version` — so this tab never leaves the\n * product.\n *\n * Flow:\n * 1. Bound → resolve the definition by id (`useWorkflowDefinition`), show\n * name / key / version / status, \"Open in builder\", \"Unbind\".\n * A binding that no longer resolves falls back to the raw id so\n * the user can still clear it.\n * 2. Not bound → zero state whose primary action creates a seeded workflow\n * definition, binds it via `updateBotApp(workflowId)` and drops\n * the user straight into the embedded builder.\n *\n * IMPORTANT — seed graph shape. `BotlitFluidGridsBridge.extractTriggerNodeIds`\n * reads nodes from `definitionJson.data.nodes` (NOT the top level) and treats a\n * node as a trigger when its `type` is `trigger`/`trigger:*`/`*_trigger`, OR its\n * `kind[]` / `data.nodeData.kind[]` contains `trigger`. The seed below uses the\n * workflow service's own BUILTIN manual trigger (`internal:api`, \"Trigger\n * Manually\") — the node the executor resolves as the entry point — and carries\n * `kind: ['trigger', ...]` in both places, so a freshly designed bot is\n * immediately runnable instead of failing with `WORKFLOW_NO_TRIGGER_NODE`.\n */\n\nimport type { FC } from 'react';\nimport { useCallback, useState } from 'react';\nimport { ExternalLink, Sparkles, Unlink, Workflow } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { useCreateWorkflow, useWorkflowDefinition } from '@burdenoff/fluidgrids-fe-sdk';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { useUpdateBot } from '../hooks/useBots';\nimport { useBotlit } from '../providers/BotlitProvider';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Seed graph\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** First version minted for a bot's workflow — matches the builder's own default. */\nconst INITIAL_VERSION = 'v1';\n\n/**\n * BUILTIN \"Trigger Manually\" node (`MANUAL_TRIGGER_MANIFEST` in\n * wspace-workflow-svc). The executor resolves this type as a workflow's entry\n * node, and the builder renders it from the seeded node registry.\n */\nconst MANUAL_TRIGGER_NODE_TYPE = 'internal:api';\nconst MANUAL_TRIGGER_NODE_VERSION = '1.0.0';\nconst MANUAL_TRIGGER_OPERATION = 'onManualTrigger';\nconst MANUAL_TRIGGER_NAME = 'Trigger Manually';\nconst MANUAL_TRIGGER_DESCRIPTION =\n \"Runs the flow when you click 'Test workflow', or when this bot is invoked.\";\n\n/** `kind[]` the BotManor bridge scans for when classifying a node as a trigger. */\nconst MANUAL_TRIGGER_KIND = ['trigger', 'manual', 'entry'];\n\n/** Node shape written into `definitionJson.data.nodes`. */\ntype SeedNode = {\n id: string;\n type: string;\n position: { x: number; y: number };\n /** Top-level kind — the bridge's second trigger-detection path. */\n kind: string[];\n data: {\n operation_name: string;\n operation_type: string;\n version: string;\n nodeData: {\n nodeType: string;\n name: string;\n description: string;\n version: string;\n /** The bridge's third trigger-detection path. */\n kind: string[];\n operations: { name: string; type: string; role: string; description: string }[];\n };\n args: {\n context: { node: { id: string; type: string; kind: string[] } };\n state: Record<string, never>;\n credentials: never[];\n };\n };\n};\n\n/**\n * `definitionJson` document. Mirrors what the builder itself persists\n * (`useSaveWorkflow`) so the graph round-trips through the builder unchanged.\n */\ntype SeedDefinition = {\n key: string;\n name: string;\n description: string;\n workflow_type: string;\n data: {\n id: string;\n workflowKey: string;\n version: string;\n name: string;\n nodes: SeedNode[];\n edges: never[];\n sidebar: { active: string; panels: { nodeProperties: { selectedNode: null } } };\n stickyNotes: never[];\n };\n meta: { creator: string; version: string };\n tags: string[];\n};\n\n/**\n * Generate an opaque id. `crypto.randomUUID` is unavailable on insecure origins\n * and in some test environments, so fall back to a time+random token rather than\n * throwing mid-create.\n */\nfunction generateId(): string {\n const webCrypto = globalThis.crypto as Crypto | undefined;\n if (webCrypto && typeof webCrypto.randomUUID === 'function') {\n return webCrypto.randomUUID();\n }\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Build the starter graph: one manual trigger, nothing else. */\nfunction buildSeedDefinition(workflowKey: string, name: string): SeedDefinition {\n const triggerNode: SeedNode = {\n id: generateId(),\n type: MANUAL_TRIGGER_NODE_TYPE,\n position: { x: 160, y: 160 },\n kind: MANUAL_TRIGGER_KIND,\n data: {\n operation_name: MANUAL_TRIGGER_OPERATION,\n operation_type: 'trigger',\n version: MANUAL_TRIGGER_NODE_VERSION,\n nodeData: {\n nodeType: MANUAL_TRIGGER_NODE_TYPE,\n name: MANUAL_TRIGGER_NAME,\n description: MANUAL_TRIGGER_DESCRIPTION,\n version: MANUAL_TRIGGER_NODE_VERSION,\n kind: MANUAL_TRIGGER_KIND,\n operations: [\n {\n name: MANUAL_TRIGGER_OPERATION,\n type: 'trigger',\n role: 'trigger',\n description: MANUAL_TRIGGER_DESCRIPTION,\n },\n ],\n },\n args: {\n context: {\n node: {\n id: MANUAL_TRIGGER_NODE_TYPE,\n type: MANUAL_TRIGGER_NODE_TYPE,\n kind: MANUAL_TRIGGER_KIND,\n },\n },\n state: {},\n credentials: [],\n },\n },\n };\n\n return {\n key: workflowKey,\n name,\n description: name,\n workflow_type: 'query-conditional',\n data: {\n id: workflowKey,\n workflowKey,\n version: INITIAL_VERSION,\n name,\n nodes: [triggerNode],\n edges: [],\n sidebar: { active: 'store-browse', panels: { nodeProperties: { selectedNode: null } } },\n stickyNotes: [],\n },\n meta: { creator: 'botlit_bot_design', version: INITIAL_VERSION },\n tags: [],\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Component\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface BotWorkflowTabProps {\n botId: string;\n botName: string;\n /** `BotApp.workflowId` — the bound workflow definition id, if any. */\n workflowId: string | null | undefined;\n /** Refetch the bot so the tab reflects the new binding. */\n onWorkflowChanged: () => Promise<void> | void;\n}\n\nexport const BotWorkflowTab: FC<BotWorkflowTabProps> = ({\n botId,\n botName,\n workflowId,\n onWorkflowChanged,\n}) => {\n const t = useTr();\n const { navigateTo } = useBotlit();\n const { createWorkflow } = useCreateWorkflow();\n const [updateBot] = useUpdateBot();\n const [busy, setBusy] = useState(false);\n\n // Resolve by id — `BotApp.workflowId` stores the definition's opaque id, not\n // its workflowKey (which is what the builder route takes). The hook refetches\n // on its own when the bound id changes, so binding/unbinding only has to\n // refresh the bot.\n const { workflow, loading: workflowLoading } = useWorkflowDefinition(\n undefined,\n workflowId ?? undefined\n );\n\n const openBuilder = useCallback(\n (workflowKey: string, version: string) => {\n navigateTo(`workflows/workflow/${workflowKey}/${version || INITIAL_VERSION}`);\n },\n [navigateTo]\n );\n\n const handleDesign = useCallback(async () => {\n setBusy(true);\n try {\n const workflowKey = generateId();\n const name = `${botName} workflow`;\n const created = await createWorkflow({\n workflowKey,\n version: INITIAL_VERSION,\n name,\n description: t(\n 'botlit.botDetail.workflow.createdDescription',\n 'Behaviour designed for this BotManor bot.'\n ),\n definitionJson: buildSeedDefinition(workflowKey, name),\n });\n\n if (!created) {\n throw new Error(\n t('botlit.botDetail.workflow.createError', 'Failed to create the workflow')\n );\n }\n\n await updateBot({ botId, input: { workflowId: created.id } });\n await onWorkflowChanged();\n toast.success(\n t('botlit.botDetail.workflow.createSuccess', 'Workflow created and bound to this bot')\n );\n openBuilder(created.workflowKey, created.version);\n } catch (err: unknown) {\n const message =\n err instanceof Error\n ? err.message\n : t('botlit.botDetail.workflow.createError', 'Failed to create the workflow');\n toast.error(message);\n } finally {\n setBusy(false);\n }\n }, [botId, botName, createWorkflow, onWorkflowChanged, openBuilder, t, updateBot]);\n\n const handleUnbind = useCallback(async () => {\n if (\n !confirm(\n t(\n 'botlit.botDetail.workflow.unbindConfirm',\n 'Unbind this workflow from the bot? The workflow itself is not deleted.'\n )\n )\n ) {\n return;\n }\n setBusy(true);\n try {\n await updateBot({ botId, input: { workflowId: null } });\n await onWorkflowChanged();\n toast.success(t('botlit.botDetail.workflow.unbindSuccess', 'Workflow unbound'));\n } catch (err: unknown) {\n const message =\n err instanceof Error\n ? err.message\n : t('botlit.botDetail.workflow.unbindError', 'Failed to unbind the workflow');\n toast.error(message);\n } finally {\n setBusy(false);\n }\n }, [botId, onWorkflowChanged, t, updateBot]);\n\n // ── Not bound ─────────────────────────────────────────────────────────────\n if (!workflowId) {\n return (\n <Card>\n <CardContent className=\"pt-6\">\n <EmptyState\n illustration=\"empty-generic\"\n title={t('botlit.botDetail.workflow.empty.title', 'Design this bot as a workflow')}\n description={t(\n 'botlit.botDetail.workflow.empty.description',\n \"A bot's behaviour is designed as a FluidGrids workflow — the visual canvas where you wire triggers, agents, tools and conditions together. Start one and we will create it, bind it to this bot and open the builder for you.\"\n )}\n action={\n <Button\n leftIcon={<Sparkles size={16} />}\n isLoading={busy}\n disabled={busy}\n onClick={() => void handleDesign()}\n >\n {t('botlit.botDetail.workflow.empty.action', 'Design in workflow builder')}\n </Button>\n }\n />\n </CardContent>\n </Card>\n );\n }\n\n // ── Bound ─────────────────────────────────────────────────────────────────\n return (\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Workflow size={18} />\n {t('botlit.botDetail.workflow.bound.title', 'Bound workflow')}\n </CardTitle>\n <CardDescription>\n {t(\n 'botlit.botDetail.workflow.bound.description',\n 'This workflow defines what the bot does when it is invoked.'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n {workflowLoading ? (\n <div className=\"h-24 rounded-lg bg-bg-sunken motion-safe:animate-vc-shimmer\" />\n ) : workflow ? (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.botDetail.workflow.fields.name', 'Name')}\n </p>\n <p className=\"font-medium text-text-primary\">{workflow.name}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.botDetail.workflow.fields.key', 'Key')}\n </p>\n <p className=\"mt-1 break-all font-mono text-sm text-text-primary\">\n {workflow.workflowKey}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.botDetail.workflow.fields.version', 'Version')}\n </p>\n <Badge variant=\"outline\" className=\"mt-1\">\n {workflow.version}\n </Badge>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.botDetail.workflow.fields.status', 'Status')}\n </p>\n <div className=\"mt-1\">\n <StatusBadge status={workflow.status} />\n </div>\n </div>\n </div>\n ) : (\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.botDetail.workflow.fields.workflowId', 'Workflow ID')}\n </p>\n <p className=\"mt-1 break-all font-mono text-sm text-text-primary\">{workflowId}</p>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {t(\n 'botlit.botDetail.workflow.unresolved',\n 'This workflow could not be loaded — it may have been deleted. Unbind it and design a new one.'\n )}\n </p>\n </div>\n )}\n\n <div className=\"flex flex-wrap gap-2\">\n {workflow && (\n <Button\n leftIcon={<ExternalLink size={16} />}\n disabled={busy}\n onClick={() => openBuilder(workflow.workflowKey, workflow.version)}\n >\n {t('botlit.botDetail.workflow.actions.openBuilder', 'Open in builder')}\n </Button>\n )}\n <Button\n variant=\"outline\"\n leftIcon={<Unlink size={16} />}\n isLoading={busy}\n disabled={busy}\n onClick={() => void handleUnbind()}\n >\n {t('botlit.botDetail.workflow.actions.unbind', 'Unbind')}\n </Button>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1,134 +1,131 @@
1
- import { useBotlit as e } from "../providers/BotlitProvider.js";
2
- import { useBotlitStore as t } from "../store/botlitStore.js";
3
- import { useBots as n, useDeleteBot as r } from "../hooks/useBots.js";
4
- import { cn as i } from "../utils/cn.js";
5
- import { formatNumber as a, formatRelativeTime as o } from "../utils/formatters.js";
6
- import { PageLayout as s } from "../components/PageLayout.js";
7
- import { Card as c, CardContent as l } from "../components/Card.js";
8
- import { Button as u } from "../components/Button.js";
9
- import { StatusBadge as d } from "../components/Badge.js";
10
- import { isNative as f, nativeConfirm as p, nativeImpact as m, nativeNotify as h } from "../../utils/nativeBridge.js";
11
- import { EmptyState as g } from "../components/EmptyState.js";
12
- import { Input as _ } from "../components/Input.js";
13
- import { useState as v } from "react";
14
- import { GlassCard as y, PagePurpose as b } from "@burdenoff/fe-libs/ui";
15
- import { jsx as x, jsxs as S } from "react/jsx-runtime";
16
- import { Link as C } from "react-router";
17
- import { Bot as w, Edit as T, Grid3X3 as E, List as D, MoreVertical as O, Plus as k, Search as A, Trash2 as j, Workflow as M } from "lucide-react";
18
- import { useI18n as N } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
1
+ import { useTr as e } from "../../shared/hooks/useTr.js";
2
+ import { useBotlit as t } from "../providers/BotlitProvider.js";
3
+ import { useBotlitStore as n } from "../store/botlitStore.js";
4
+ import { useBots as r, useDeleteBot as i } from "../hooks/useBots.js";
5
+ import { cn as a } from "../utils/cn.js";
6
+ import { formatNumber as o, formatRelativeTime as s } from "../utils/formatters.js";
7
+ import { PageLayout as c } from "../components/PageLayout.js";
8
+ import { Card as l, CardContent as u } from "../components/Card.js";
9
+ import { Button as d } from "../components/Button.js";
10
+ import { StatusBadge as f } from "../components/Badge.js";
11
+ import { isNative as p, nativeConfirm as m, nativeImpact as h, nativeNotify as g } from "../../utils/nativeBridge.js";
12
+ import { EmptyState as _ } from "../components/EmptyState.js";
13
+ import { Input as v } from "../components/Input.js";
14
+ import { useState as y } from "react";
15
+ import { GlassCard as b, PagePurpose as x } from "@burdenoff/fe-libs/ui";
16
+ import { jsx as S, jsxs as C } from "react/jsx-runtime";
17
+ import { Link as w } from "react-router";
18
+ import { Bot as T, Edit as E, Grid3X3 as D, List as O, MoreVertical as k, Plus as A, Search as j, Trash2 as M, Workflow as N } from "lucide-react";
19
19
  import { toast as P } from "sonner";
20
20
  //#region src/botlit/pages/BotsListPage.tsx
21
21
  var F = () => {
22
- let { t: F } = N(), I = (e, t) => {
23
- let n = F(e);
24
- return n === e ? t : n;
25
- }, { navigateTo: L, getPath: R } = e(), { data: z, loading: B } = n(), [V] = r(), { viewMode: H, setViewMode: U, botFilter: W, updateBotFilter: G } = t(), [K, q] = v(null), J = (e) => {
26
- G({ search: e.target.value });
27
- }, Y = async (e) => {
28
- let t = `${I("botlit.botsList.delete.confirmPrefix", "Are you sure you want to delete")} "${e.name}"?`, n = await p({
22
+ let F = e(), { navigateTo: I, getPath: L } = t(), { data: R, loading: z } = r(), [B] = i(), { viewMode: V, setViewMode: H, botFilter: U, updateBotFilter: W } = n(), [G, K] = y(null), q = (e) => {
23
+ W({ search: e.target.value });
24
+ }, J = async (e) => {
25
+ let t = `${F("botlit.botsList.delete.confirmPrefix", "Are you sure you want to delete")} "${e.name}"?`, n = await m({
29
26
  title: "Delete bot?",
30
27
  message: t,
31
28
  okButtonTitle: "Delete",
32
29
  cancelButtonTitle: "Cancel"
33
30
  });
34
31
  if (n === null ? confirm(t) : n) {
35
- m("medium");
32
+ h("medium");
36
33
  try {
37
- await V(e.id), P.success(`${I("botlit.botsList.delete.successPrefix", "Bot")} "${e.name}" ${I("botlit.botsList.delete.successSuffix", "deleted successfully")}`), f() && h("success");
34
+ await B(e.id), P.success(`${F("botlit.botsList.delete.successPrefix", "Bot")} "${e.name}" ${F("botlit.botsList.delete.successSuffix", "deleted successfully")}`), p() && g("success");
38
35
  } catch (e) {
39
- let t = e instanceof Error ? e.message : I("botlit.botsList.delete.error", "Failed to delete bot");
40
- P.error(t), f() && h("error");
36
+ let t = e instanceof Error ? e.message : F("botlit.botsList.delete.error", "Failed to delete bot");
37
+ P.error(t), p() && g("error");
41
38
  }
42
39
  }
43
- q(null);
44
- }, X = z?.filter((e) => {
45
- if (W.search) {
46
- let t = W.search.toLowerCase();
40
+ K(null);
41
+ }, Y = R?.filter((e) => {
42
+ if (U.search) {
43
+ let t = U.search.toLowerCase();
47
44
  return e.name.toLowerCase().includes(t) || (e.description?.toLowerCase().includes(t) ?? !1);
48
45
  }
49
46
  return !0;
50
47
  });
51
- return /* @__PURE__ */ x(s, {
52
- title: I("botlit.botsList.title", "Bots"),
53
- description: I("botlit.botsList.description", "Manage your AI-powered bots"),
54
- actions: /* @__PURE__ */ x(u, {
55
- leftIcon: /* @__PURE__ */ x(k, { size: 16 }),
56
- onClick: () => L("bots/new"),
57
- children: I("botlit.botsList.actions.createBot", "Create Bot")
48
+ return /* @__PURE__ */ S(c, {
49
+ title: F("botlit.botsList.title", "Bots"),
50
+ description: F("botlit.botsList.description", "Manage your AI-powered bots"),
51
+ actions: /* @__PURE__ */ S(d, {
52
+ leftIcon: /* @__PURE__ */ S(A, { size: 16 }),
53
+ onClick: () => I("bots/new"),
54
+ children: F("botlit.botsList.actions.createBot", "Create Bot")
58
55
  }),
59
- children: /* @__PURE__ */ S("div", {
56
+ children: /* @__PURE__ */ C("div", {
60
57
  className: "space-y-6",
61
58
  children: [
62
- /* @__PURE__ */ x(b, {
63
- icon: /* @__PURE__ */ x(w, { size: 18 }),
64
- children: I("botlit.botsList.purpose", "A bot is the deployable, user-facing surface for your AI — it wraps one or more agents and exposes them to people through chat, channels (Slack, web widget, WhatsApp) and APIs. Create a bot here when you are ready to put an agent in front of real users, then connect channels and watch its executions.")
59
+ /* @__PURE__ */ S(x, {
60
+ icon: /* @__PURE__ */ S(T, { size: 18 }),
61
+ children: F("botlit.botsList.purpose", "A bot is the deployable, user-facing surface for your AI — it wraps one or more agents and exposes them to people through chat, channels (Slack, web widget, WhatsApp) and APIs. Create a bot here when you are ready to put an agent in front of real users, then connect channels and watch its executions.")
65
62
  }),
66
- z && z.length > 0 ? /* @__PURE__ */ S("div", {
63
+ R && R.length > 0 ? /* @__PURE__ */ C("div", {
67
64
  className: "grid grid-cols-2 gap-4 sm:grid-cols-3",
68
65
  children: [
69
- /* @__PURE__ */ S(y, {
66
+ /* @__PURE__ */ C(b, {
70
67
  treatment: "glass",
71
68
  glow: !0,
72
69
  className: "p-4",
73
- children: [/* @__PURE__ */ x("p", {
70
+ children: [/* @__PURE__ */ S("p", {
74
71
  className: "text-sm text-text-secondary",
75
- children: I("botlit.botsList.summary.total", "Total bots")
76
- }), /* @__PURE__ */ x("p", {
72
+ children: F("botlit.botsList.summary.total", "Total bots")
73
+ }), /* @__PURE__ */ S("p", {
77
74
  className: "mt-1 text-2xl font-semibold tabular-nums text-text-primary",
78
- children: z.length
75
+ children: R.length
79
76
  })]
80
77
  }),
81
- /* @__PURE__ */ S(y, {
78
+ /* @__PURE__ */ C(b, {
82
79
  treatment: "metric",
83
80
  className: "p-4",
84
- children: [/* @__PURE__ */ x("p", {
81
+ children: [/* @__PURE__ */ S("p", {
85
82
  className: "text-sm text-text-secondary",
86
- children: I("botlit.botsList.summary.active", "Active")
87
- }), /* @__PURE__ */ x("p", {
83
+ children: F("botlit.botsList.summary.active", "Active")
84
+ }), /* @__PURE__ */ S("p", {
88
85
  className: "mt-1 text-2xl font-semibold tabular-nums text-text-primary",
89
- children: z.filter((e) => e.status === "ACTIVE").length
86
+ children: R.filter((e) => e.status === "ACTIVE").length
90
87
  })]
91
88
  }),
92
- /* @__PURE__ */ S(y, {
89
+ /* @__PURE__ */ C(b, {
93
90
  treatment: "metric",
94
91
  className: "col-span-2 p-4 sm:col-span-1",
95
- children: [/* @__PURE__ */ x("p", {
92
+ children: [/* @__PURE__ */ S("p", {
96
93
  className: "text-sm text-text-secondary",
97
- children: I("botlit.botsList.summary.executions", "Total executions")
98
- }), /* @__PURE__ */ x("p", {
94
+ children: F("botlit.botsList.summary.executions", "Total executions")
95
+ }), /* @__PURE__ */ S("p", {
99
96
  className: "mt-1 text-2xl font-semibold tabular-nums text-text-primary",
100
- children: a(z.reduce((e, t) => e + (t.executionCount ?? 0), 0))
97
+ children: o(R.reduce((e, t) => e + (t.executionCount ?? 0), 0))
101
98
  })]
102
99
  })
103
100
  ]
104
101
  }) : null,
105
- /* @__PURE__ */ S("div", {
102
+ /* @__PURE__ */ C("div", {
106
103
  className: "flex items-center justify-between gap-4",
107
- children: [/* @__PURE__ */ S("div", {
104
+ children: [/* @__PURE__ */ C("div", {
108
105
  className: "relative flex-1 max-w-md",
109
- children: [/* @__PURE__ */ x(A, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ x(_, {
110
- placeholder: I("botlit.botsList.searchPlaceholder", "Search bots..."),
111
- value: W.search || "",
112
- onChange: J,
106
+ children: [/* @__PURE__ */ S(j, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ S(v, {
107
+ placeholder: F("botlit.botsList.searchPlaceholder", "Search bots..."),
108
+ value: U.search || "",
109
+ onChange: q,
113
110
  className: "pl-9"
114
111
  })]
115
- }), /* @__PURE__ */ S("div", {
112
+ }), /* @__PURE__ */ C("div", {
116
113
  className: "flex items-center gap-2",
117
- children: [/* @__PURE__ */ x(u, {
118
- variant: H === "grid" ? "secondary" : "ghost",
114
+ children: [/* @__PURE__ */ S(d, {
115
+ variant: V === "grid" ? "secondary" : "ghost",
119
116
  size: "icon",
120
- onClick: () => U("grid"),
121
- children: /* @__PURE__ */ x(E, { size: 18 })
122
- }), /* @__PURE__ */ x(u, {
123
- variant: H === "list" ? "secondary" : "ghost",
117
+ onClick: () => H("grid"),
118
+ children: /* @__PURE__ */ S(D, { size: 18 })
119
+ }), /* @__PURE__ */ S(d, {
120
+ variant: V === "list" ? "secondary" : "ghost",
124
121
  size: "icon",
125
- onClick: () => U("list"),
126
- children: /* @__PURE__ */ x(D, { size: 18 })
122
+ onClick: () => H("list"),
123
+ children: /* @__PURE__ */ S(O, { size: 18 })
127
124
  })]
128
125
  })]
129
126
  }),
130
- B ? /* @__PURE__ */ x("div", {
131
- className: i("gap-4", H === "grid" ? "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3" : "flex flex-col"),
127
+ z ? /* @__PURE__ */ S("div", {
128
+ className: a("gap-4", V === "grid" ? "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3" : "flex flex-col"),
132
129
  children: [
133
130
  1,
134
131
  2,
@@ -136,156 +133,156 @@ var F = () => {
136
133
  4,
137
134
  5,
138
135
  6
139
- ].map((e) => /* @__PURE__ */ x("div", { className: "h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg" }, e))
140
- }) : X && X.length > 0 ? H === "grid" ? /* @__PURE__ */ x("div", {
136
+ ].map((e) => /* @__PURE__ */ S("div", { className: "h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg" }, e))
137
+ }) : Y && Y.length > 0 ? V === "grid" ? /* @__PURE__ */ S("div", {
141
138
  className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
142
- children: X.map((e) => /* @__PURE__ */ x(c, {
139
+ children: Y.map((e) => /* @__PURE__ */ S(l, {
143
140
  className: "group hover:shadow-md transition-shadow cursor-pointer relative",
144
- onClick: () => L(`bots/${e.id}`),
145
- children: /* @__PURE__ */ S(l, {
141
+ onClick: () => I(`bots/${e.id}`),
142
+ children: /* @__PURE__ */ C(u, {
146
143
  className: "pt-6",
147
144
  children: [
148
- /* @__PURE__ */ S("div", {
145
+ /* @__PURE__ */ C("div", {
149
146
  className: "flex items-start justify-between",
150
- children: [/* @__PURE__ */ S("div", {
147
+ children: [/* @__PURE__ */ C("div", {
151
148
  className: "flex items-center gap-3",
152
- children: [/* @__PURE__ */ x("span", {
149
+ children: [/* @__PURE__ */ S("span", {
153
150
  className: "text-4xl",
154
151
  children: e.icon || "🤖"
155
- }), /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("h3", {
152
+ }), /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("h3", {
156
153
  className: "font-semibold text-text-primary",
157
154
  children: e.name
158
- }), /* @__PURE__ */ x(d, { status: e.status })] })]
159
- }), /* @__PURE__ */ S("div", {
155
+ }), /* @__PURE__ */ S(f, { status: e.status })] })]
156
+ }), /* @__PURE__ */ C("div", {
160
157
  className: "relative",
161
- children: [/* @__PURE__ */ x(u, {
158
+ children: [/* @__PURE__ */ S(d, {
162
159
  variant: "ghost",
163
160
  size: "icon",
164
161
  className: "opacity-0 group-hover:opacity-100 transition-opacity",
165
162
  onClick: (t) => {
166
- t.stopPropagation(), q(K === e.id ? null : e.id);
163
+ t.stopPropagation(), K(G === e.id ? null : e.id);
167
164
  },
168
- children: /* @__PURE__ */ x(O, { size: 16 })
169
- }), K === e.id && /* @__PURE__ */ S("div", {
165
+ children: /* @__PURE__ */ S(k, { size: 16 })
166
+ }), G === e.id && /* @__PURE__ */ C("div", {
170
167
  className: "absolute right-0 top-full mt-1 w-48 bg-popover border border-border-subtle rounded-md shadow-lg z-10",
171
168
  children: [
172
- /* @__PURE__ */ S("button", {
169
+ /* @__PURE__ */ C("button", {
173
170
  className: "w-full px-4 py-2 text-left text-sm hover:bg-accent flex items-center gap-2",
174
171
  onClick: (t) => {
175
- t.stopPropagation(), L(`bots/${e.id}/edit`), q(null);
172
+ t.stopPropagation(), I(`bots/${e.id}/edit`), K(null);
176
173
  },
177
- children: [/* @__PURE__ */ x(T, { size: 16 }), I("botlit.botsList.menu.editBot", "Edit Bot")]
174
+ children: [/* @__PURE__ */ S(E, { size: 16 }), F("botlit.botsList.menu.editBot", "Edit Bot")]
178
175
  }),
179
- /* @__PURE__ */ S("button", {
176
+ /* @__PURE__ */ C("button", {
180
177
  className: "w-full px-4 py-2 text-left text-sm hover:bg-accent flex items-center gap-2",
181
178
  onClick: (t) => {
182
- t.stopPropagation(), L(`bots/${e.id}?tab=workflow`), q(null);
179
+ t.stopPropagation(), I(`bots/${e.id}?tab=workflow`), K(null);
183
180
  },
184
- children: [/* @__PURE__ */ x(M, { size: 16 }), I("botlit.botsList.menu.design", "Design workflow")]
181
+ children: [/* @__PURE__ */ S(N, { size: 16 }), F("botlit.botsList.menu.design", "Design workflow")]
185
182
  }),
186
- /* @__PURE__ */ S("button", {
183
+ /* @__PURE__ */ C("button", {
187
184
  className: "w-full px-4 py-2 text-left text-sm hover:bg-accent flex items-center gap-2",
188
185
  onClick: (t) => {
189
- t.stopPropagation(), L(`bots/${e.id}/agents`), q(null);
186
+ t.stopPropagation(), I(`bots/${e.id}/agents`), K(null);
190
187
  },
191
- children: [/* @__PURE__ */ x(w, { size: 16 }), I("botlit.botsList.menu.viewAgents", "View Agents")]
188
+ children: [/* @__PURE__ */ S(T, { size: 16 }), F("botlit.botsList.menu.viewAgents", "View Agents")]
192
189
  }),
193
- /* @__PURE__ */ S("button", {
190
+ /* @__PURE__ */ C("button", {
194
191
  className: "w-full px-4 py-2 text-left text-sm hover:bg-accent text-status-error-text flex items-center gap-2",
195
192
  onClick: (t) => {
196
- t.stopPropagation(), Y(e);
193
+ t.stopPropagation(), J(e);
197
194
  },
198
- children: [/* @__PURE__ */ x(j, { size: 16 }), I("botlit.common.delete", "Delete")]
195
+ children: [/* @__PURE__ */ S(M, { size: 16 }), F("botlit.common.delete", "Delete")]
199
196
  })
200
197
  ]
201
198
  })]
202
199
  })]
203
200
  }),
204
- /* @__PURE__ */ x("p", {
201
+ /* @__PURE__ */ S("p", {
205
202
  className: "mt-3 text-sm text-text-secondary line-clamp-2",
206
203
  children: e.description
207
204
  }),
208
- /* @__PURE__ */ x("div", {
205
+ /* @__PURE__ */ S("div", {
209
206
  className: "mt-4 flex items-center gap-4 text-xs text-text-secondary",
210
- children: /* @__PURE__ */ S("span", {
207
+ children: /* @__PURE__ */ C("span", {
211
208
  className: "flex items-center gap-1",
212
209
  children: [
213
- /* @__PURE__ */ x(w, { size: 14 }),
210
+ /* @__PURE__ */ S(T, { size: 14 }),
214
211
  e.executionCount || 0,
215
212
  " ",
216
- I("botlit.common.executions", "executions")
213
+ F("botlit.common.executions", "executions")
217
214
  ]
218
215
  })
219
216
  }),
220
- /* @__PURE__ */ S("div", {
217
+ /* @__PURE__ */ C("div", {
221
218
  className: "mt-3 pt-3 border-t border-border-subtle flex items-center justify-between gap-2",
222
- children: [/* @__PURE__ */ S("span", {
219
+ children: [/* @__PURE__ */ C("span", {
223
220
  className: "text-xs text-text-secondary",
224
221
  children: [
225
- I("botlit.botsList.createdLabel", "Created"),
222
+ F("botlit.botsList.createdLabel", "Created"),
226
223
  " ",
227
- o(e.createdAt)
224
+ s(e.createdAt)
228
225
  ]
229
- }), /* @__PURE__ */ x(u, {
226
+ }), /* @__PURE__ */ S(d, {
230
227
  variant: "ghost",
231
228
  size: "sm",
232
- leftIcon: /* @__PURE__ */ x(M, { size: 14 }),
229
+ leftIcon: /* @__PURE__ */ S(N, { size: 14 }),
233
230
  onClick: (t) => {
234
- t.stopPropagation(), L(`bots/${e.id}?tab=workflow`);
231
+ t.stopPropagation(), I(`bots/${e.id}?tab=workflow`);
235
232
  },
236
- children: I("botlit.botsList.actions.design", "Design")
233
+ children: F("botlit.botsList.actions.design", "Design")
237
234
  })]
238
235
  })
239
236
  ]
240
237
  })
241
238
  }, e.id))
242
- }) : /* @__PURE__ */ x("div", {
239
+ }) : /* @__PURE__ */ S("div", {
243
240
  className: "space-y-2",
244
- children: X.map((e) => /* @__PURE__ */ x(c, {
241
+ children: Y.map((e) => /* @__PURE__ */ S(l, {
245
242
  className: "hover:shadow-md transition-shadow cursor-pointer",
246
- onClick: () => L(`bots/${e.id}`),
247
- children: /* @__PURE__ */ x(l, {
243
+ onClick: () => I(`bots/${e.id}`),
244
+ children: /* @__PURE__ */ S(u, {
248
245
  className: "py-4",
249
- children: /* @__PURE__ */ S("div", {
246
+ children: /* @__PURE__ */ C("div", {
250
247
  className: "flex items-center justify-between",
251
- children: [/* @__PURE__ */ S("div", {
248
+ children: [/* @__PURE__ */ C("div", {
252
249
  className: "flex items-center gap-4",
253
- children: [/* @__PURE__ */ x("span", {
250
+ children: [/* @__PURE__ */ S("span", {
254
251
  className: "text-3xl",
255
252
  children: e.icon || "🤖"
256
- }), /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ S("div", {
253
+ }), /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ C("div", {
257
254
  className: "flex items-center gap-2",
258
- children: [/* @__PURE__ */ x("h3", {
255
+ children: [/* @__PURE__ */ S("h3", {
259
256
  className: "font-semibold text-text-primary",
260
257
  children: e.name
261
- }), /* @__PURE__ */ x(d, { status: e.status })]
262
- }), /* @__PURE__ */ x("p", {
258
+ }), /* @__PURE__ */ S(f, { status: e.status })]
259
+ }), /* @__PURE__ */ S("p", {
263
260
  className: "text-sm text-text-secondary line-clamp-1",
264
261
  children: e.description
265
262
  })] })]
266
- }), /* @__PURE__ */ S("div", {
263
+ }), /* @__PURE__ */ C("div", {
267
264
  className: "flex items-center gap-6 text-sm text-text-secondary",
268
265
  children: [
269
- /* @__PURE__ */ S("span", { children: [
270
- a(e.executionCount),
266
+ /* @__PURE__ */ C("span", { children: [
267
+ o(e.executionCount),
271
268
  " ",
272
- I("botlit.common.executions", "executions")
269
+ F("botlit.common.executions", "executions")
273
270
  ] }),
274
- /* @__PURE__ */ x(u, {
271
+ /* @__PURE__ */ S(d, {
275
272
  variant: "ghost",
276
273
  size: "sm",
277
- leftIcon: /* @__PURE__ */ x(M, { size: 14 }),
274
+ leftIcon: /* @__PURE__ */ S(N, { size: 14 }),
278
275
  onClick: (t) => {
279
- t.stopPropagation(), L(`bots/${e.id}?tab=workflow`);
276
+ t.stopPropagation(), I(`bots/${e.id}?tab=workflow`);
280
277
  },
281
- children: I("botlit.botsList.actions.design", "Design")
278
+ children: F("botlit.botsList.actions.design", "Design")
282
279
  }),
283
- /* @__PURE__ */ x(u, {
280
+ /* @__PURE__ */ S(d, {
284
281
  variant: "ghost",
285
282
  size: "sm",
286
- children: /* @__PURE__ */ x(C, {
287
- to: R(`bots/${e.id}`),
288
- children: I("botlit.common.view", "View")
283
+ children: /* @__PURE__ */ S(w, {
284
+ to: L(`bots/${e.id}`),
285
+ children: F("botlit.common.view", "View")
289
286
  })
290
287
  })
291
288
  ]
@@ -293,14 +290,14 @@ var F = () => {
293
290
  })
294
291
  })
295
292
  }, e.id))
296
- }) : /* @__PURE__ */ x(g, {
293
+ }) : /* @__PURE__ */ S(_, {
297
294
  illustration: "empty-agents",
298
- title: I("botlit.botsList.empty.title", "No bots yet"),
299
- description: I("botlit.botsList.empty.description", "Create your first AI-powered bot to get started with building agents and automations."),
300
- action: /* @__PURE__ */ x(u, {
301
- leftIcon: /* @__PURE__ */ x(k, { size: 16 }),
302
- onClick: () => L("bots/new"),
303
- children: I("botlit.botsList.actions.createBot", "Create Bot")
295
+ title: F("botlit.botsList.empty.title", "No bots yet"),
296
+ description: F("botlit.botsList.empty.description", "Create your first AI-powered bot to get started with building agents and automations."),
297
+ action: /* @__PURE__ */ S(d, {
298
+ leftIcon: /* @__PURE__ */ S(A, { size: 16 }),
299
+ onClick: () => I("bots/new"),
300
+ children: F("botlit.botsList.actions.createBot", "Create Bot")
304
301
  })
305
302
  })
306
303
  ]