@burdenoff/microfe-vibecontrols 2026.526.6 → 2026.527.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 (45) hide show
  1. package/dist/components/agent-manager/detail/SessionConfigPanel.js +6 -6
  2. package/dist/components/ai/AIContextsTab.js +5 -5
  3. package/dist/components/ai/AITasksTab.js +7 -7
  4. package/dist/components/ai/AITasksTab.js.map +1 -1
  5. package/dist/components/ai/AITemplatesTab.js +5 -5
  6. package/dist/components/docs/DocsTabPanel.js +61 -61
  7. package/dist/components/docs/DocsTabPanel.js.map +1 -1
  8. package/dist/components/notes/NotesTabPanel.js +173 -173
  9. package/dist/components/notes/NotesTabPanel.js.map +1 -1
  10. package/dist/components/shared/PluginGate.js +4 -4
  11. package/dist/components/shared/index.js +2 -2
  12. package/dist/components/tunnels/TunnelCreateWizard.js +35 -35
  13. package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
  14. package/dist/hooks/usePluginAvailability.js +104 -104
  15. package/dist/hooks/usePluginAvailability.js.map +1 -1
  16. package/dist/pages/ActionsPage.js +202 -202
  17. package/dist/pages/ActionsPage.js.map +1 -1
  18. package/dist/pages/AgentDetailsPage.js +682 -682
  19. package/dist/pages/AgentDetailsPage.js.map +1 -1
  20. package/dist/pages/AgentsPage.js +228 -228
  21. package/dist/pages/AgentsPage.js.map +1 -1
  22. package/dist/pages/CatalogDetailPage.js +61 -61
  23. package/dist/pages/ComponentDetailPage.js +66 -66
  24. package/dist/pages/ComponentDetailPage.js.map +1 -1
  25. package/dist/pages/SessionDetailsPage.js +500 -446
  26. package/dist/pages/SessionDetailsPage.js.map +1 -1
  27. package/dist/pages/SessionsPage.js +425 -425
  28. package/dist/pages/SessionsPage.js.map +1 -1
  29. package/dist/pages/TargetsPage.js +221 -221
  30. package/dist/pages/TargetsPage.js.map +1 -1
  31. package/dist/pages/TemplateDetailPage.js +11 -11
  32. package/dist/pages/VibeDeckPage.js +344 -344
  33. package/dist/pages/VibeDeckPage.js.map +1 -1
  34. package/dist/pages/VibesPage.js +305 -305
  35. package/dist/pages/VibesPage.js.map +1 -1
  36. package/dist/pages/tunnels/TunnelsTab.js +90 -90
  37. package/dist/pages/tunnels/TunnelsTab.js.map +1 -1
  38. package/dist/pages/tunnels/tabs/TunnelSettingsTab.js +4 -4
  39. package/dist/providers/QuotaExhaustedProvider.js +51 -0
  40. package/dist/providers/QuotaExhaustedProvider.js.map +1 -0
  41. package/dist/providers/VibeControlsProvider.js +96 -76
  42. package/dist/providers/VibeControlsProvider.js.map +1 -1
  43. package/dist/utils/quotaUtils.js +80 -2
  44. package/dist/utils/quotaUtils.js.map +1 -1
  45. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import { useTr as e } from "../../../shared/hooks/useTr.js";
2
- import { LoadingState as t } from "../../shared/LoadingState.js";
3
- import { ErrorState as n } from "../../shared/ErrorState.js";
4
- import { ConfirmDialog as r } from "../../shared/ConfirmDialog.js";
2
+ import { ConfirmDialog as t } from "../../shared/ConfirmDialog.js";
3
+ import { LoadingState as n } from "../../shared/LoadingState.js";
4
+ import { ErrorState as r } from "../../shared/ErrorState.js";
5
5
  import "../../shared/index.js";
6
6
  import { fetchSessions as i, terminateSession as a, updateSessionConfig as o } from "../../../services/aiApi.js";
7
7
  import { useCallback as s, useEffect as c, useState as l } from "react";
@@ -99,8 +99,8 @@ function g({ sessionId: g, agent: _ }) {
99
99
  g,
100
100
  R
101
101
  ]);
102
- if (T) return /* @__PURE__ */ f(t, { message: "Loading config..." });
103
- if (k && !y) return /* @__PURE__ */ f(n, {
102
+ if (T) return /* @__PURE__ */ f(n, { message: "Loading config..." });
103
+ if (k && !y) return /* @__PURE__ */ f(r, {
104
104
  message: k,
105
105
  onRetry: R
106
106
  });
@@ -231,7 +231,7 @@ function g({ sessionId: g, agent: _ }) {
231
231
  })
232
232
  ]
233
233
  }),
234
- /* @__PURE__ */ f(r, {
234
+ /* @__PURE__ */ f(t, {
235
235
  isOpen: N,
236
236
  onClose: () => P(!1),
237
237
  onConfirm: V,
@@ -1,7 +1,7 @@
1
1
  import { useTr as e } from "../../shared/hooks/useTr.js";
2
- import { LoadingState as t } from "../shared/LoadingState.js";
3
- import { ErrorState as n } from "../shared/ErrorState.js";
4
- import { ConfirmDialog as r } from "../shared/ConfirmDialog.js";
2
+ import { ConfirmDialog as t } from "../shared/ConfirmDialog.js";
3
+ import { LoadingState as n } from "../shared/LoadingState.js";
4
+ import { ErrorState as r } from "../shared/ErrorState.js";
5
5
  import { EmptyState as i } from "../shared/EmptyState.js";
6
6
  import { Card as a } from "../shared/Card.js";
7
7
  import { SelectionCheckbox as o } from "../shared/SelectionCheckbox.js";
@@ -106,7 +106,7 @@ function C({ agent: C }) {
106
106
  return t ? r.add(e) : r.delete(e), r;
107
107
  });
108
108
  };
109
- return te ? /* @__PURE__ */ y(t, { message: w("vibecontrols.ai.contexts.loading", "Loading contexts...") }) : O ? /* @__PURE__ */ y(n, {
109
+ return te ? /* @__PURE__ */ y(n, { message: w("vibecontrols.ai.contexts.loading", "Loading contexts...") }) : O ? /* @__PURE__ */ y(r, {
110
110
  title: w("vibecontrols.ai.contexts.loadFailed", "Failed to load contexts"),
111
111
  message: O,
112
112
  onRetry: J
@@ -360,7 +360,7 @@ function C({ agent: C }) {
360
360
  ]
361
361
  })
362
362
  }),
363
- /* @__PURE__ */ y(r, {
363
+ /* @__PURE__ */ y(t, {
364
364
  isOpen: H.length > 0,
365
365
  title: H.length > 1 ? "Delete Contexts" : "Delete Context",
366
366
  message: H.length > 1 ? `Are you sure you want to delete ${H.length} selected contexts? This action cannot be undone.` : "Are you sure you want to delete this context? This action cannot be undone.",
@@ -1,8 +1,8 @@
1
1
  import { useTr as e } from "../../shared/hooks/useTr.js";
2
- import { useVibeControls as t } from "../../providers/VibeControlsProvider.js";
3
- import { LoadingState as n } from "../shared/LoadingState.js";
4
- import { ErrorState as r } from "../shared/ErrorState.js";
5
- import { ConfirmDialog as ee } from "../shared/ConfirmDialog.js";
2
+ import { ConfirmDialog as t } from "../shared/ConfirmDialog.js";
3
+ import { useVibeControls as n } from "../../providers/VibeControlsProvider.js";
4
+ import { LoadingState as r } from "../shared/LoadingState.js";
5
+ import { ErrorState as ee } from "../shared/ErrorState.js";
6
6
  import { EmptyState as i } from "../shared/EmptyState.js";
7
7
  import { Card as te } from "../shared/Card.js";
8
8
  import { SelectionCheckbox as a } from "../shared/SelectionCheckbox.js";
@@ -59,7 +59,7 @@ var m = "ai-task", h = "AI", g = "vibecontrols:ai-project-id", _ = [
59
59
  }
60
60
  }, ce = "id key title description type status priority assigneeId storyPoints dueDate labels tags metadata createdBy createdAt updatedAt";
61
61
  function y() {
62
- let y = e(), b = se(), { workspaceId: le } = t(), x = le || new URLSearchParams(window.location.search).get("workspace") || "", [S, C] = c(() => {
62
+ let y = e(), b = se(), { workspaceId: le } = n(), x = le || new URLSearchParams(window.location.search).get("workspace") || "", [S, C] = c(() => {
63
63
  try {
64
64
  return localStorage.getItem(d(g));
65
65
  } catch {
@@ -250,7 +250,7 @@ function y() {
250
250
  }), n;
251
251
  });
252
252
  }, [w]);
253
- return x ? ue && w.length === 0 ? /* @__PURE__ */ f(n, { message: y("vibecontrols.ai.tasks.loading", "Loading AI tasks from PlanMagnet...") }) : D && w.length === 0 ? /* @__PURE__ */ f(r, {
253
+ return x ? ue && w.length === 0 ? /* @__PURE__ */ f(r, { message: y("vibecontrols.ai.tasks.loading", "Loading AI tasks from PlanMagnet...") }) : D && w.length === 0 ? /* @__PURE__ */ f(ee, {
254
254
  title: y("vibecontrols.ai.tasks.loadFailed", "Failed to load tasks"),
255
255
  message: D,
256
256
  action: /* @__PURE__ */ p("button", {
@@ -526,7 +526,7 @@ function y() {
526
526
  ]
527
527
  })
528
528
  }),
529
- /* @__PURE__ */ f(ee, {
529
+ /* @__PURE__ */ f(t, {
530
530
  isOpen: pe,
531
531
  onClose: () => F(!1),
532
532
  onConfirm: ye,
@@ -1 +1 @@
1
- {"version":3,"file":"AITasksTab.js","names":[],"sources":["../../../src/components/ai/AITasksTab.tsx"],"sourcesContent":["/**\n * AI Tasks Tab — Kanban board backed by PlanMagnet's WorkItem model\n */\n\nimport { useState, useCallback, useEffect, useMemo } from 'react';\nimport { gql } from '@apollo/client';\nimport { useApolloClient } from '@apollo/client/react';\nimport { Plus, X, GripVertical, RefreshCw, AlertCircle } from 'lucide-react';\nimport {\n Card,\n EmptyState,\n LoadingState,\n ErrorState,\n ConfirmDialog,\n SelectionCheckbox,\n} from '@/components/shared';\nimport { useVibeControls } from '@/providers/VibeControlsProvider';\nimport { getProfileScopedKey } from '@burdenoff/fe-libs/shared/utils';\nimport { useTr } from '../../shared/hooks/useTr';\n\nconst AI_TASK_LABEL = 'ai-task';\nconst AI_PROJECT_KEY = 'AI';\nconst AI_PROJECT_STORAGE_KEY = 'vibecontrols:ai-project-id';\n\ntype TaskStatus = 'BACKLOG' | 'TODO' | 'IN_PROGRESS' | 'IN_REVIEW' | 'DONE';\ntype TaskPriority = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';\n\ninterface WorkItem {\n id: string;\n key: string;\n title: string;\n description?: string | null;\n type: string;\n status: TaskStatus;\n priority: TaskPriority;\n assigneeId?: string | null;\n storyPoints?: number | null;\n dueDate?: string | null;\n labels: string[];\n tags: string[];\n metadata?: Record<string, unknown> | null;\n createdBy: string;\n createdAt: string;\n updatedAt: string;\n}\n\nconst columns: { id: TaskStatus; label: string; color: string }[] = [\n { id: 'BACKLOG', label: 'Backlog', color: 'border-t-text-secondary' },\n { id: 'TODO', label: 'To Do', color: 'border-t-action-primary-bg' },\n { id: 'IN_PROGRESS', label: 'In Progress', color: 'border-t-status-warning-text' },\n { id: 'IN_REVIEW', label: 'In Review', color: 'border-t-action-primary-bg' },\n { id: 'DONE', label: 'Done', color: 'border-t-status-success-text' },\n];\n\nconst priorityLabels: Record<string, { label: string; color: string }> = {\n CRITICAL: { label: 'Critical', color: 'text-status-error-text' },\n HIGH: { label: 'High', color: 'text-status-warning-text' },\n MEDIUM: { label: 'Medium', color: 'text-action-primary-bg' },\n LOW: { label: 'Low', color: 'text-text-secondary' },\n};\n\nconst WORKITEM_FIELDS = `id key title description type status priority assigneeId storyPoints dueDate labels tags metadata createdBy createdAt updatedAt`;\n\nexport function AITasksTab() {\n const tr = useTr();\n const apolloClient = useApolloClient();\n const { workspaceId: ctxWorkspaceId } = useVibeControls();\n // Fall back to URL param if context doesn't have workspaceId\n const workspaceId =\n ctxWorkspaceId || new URLSearchParams(window.location.search).get('workspace') || '';\n\n const [projectId, setProjectId] = useState<string | null>(() => {\n try {\n return localStorage.getItem(getProfileScopedKey(AI_PROJECT_STORAGE_KEY));\n } catch {\n return null;\n }\n });\n const [items, setItems] = useState<WorkItem[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [selectedTaskIds, setSelectedTaskIds] = useState<Set<string>>(new Set());\n const [bulkMoveStatus, setBulkMoveStatus] = useState<TaskStatus>('TODO');\n const [bulkDeleting, setBulkDeleting] = useState(false);\n const [bulkMoving, setBulkMoving] = useState(false);\n const [showBulkDeleteDialog, setShowBulkDeleteDialog] = useState(false);\n\n const gqlFetch = useCallback(\n async <T,>(query: string, variables?: Record<string, unknown>): Promise<T> => {\n const document = gql(query);\n const trimmed = query.trimStart();\n\n if (trimmed.startsWith('mutation')) {\n const result = await apolloClient.mutate<T>({ mutation: document, variables });\n if (result.error) throw new Error(result.error.message || 'Mutation failed');\n if (!result.data) throw new Error('Mutation returned no data');\n return result.data;\n }\n\n const result = await apolloClient.query<T>({\n query: document,\n variables,\n fetchPolicy: 'network-only',\n });\n if (result.error) throw new Error(result.error.message || 'Query failed');\n if (!result.data) throw new Error('Query returned no data');\n return result.data;\n },\n [apolloClient]\n );\n\n // ── Project auto-discovery ─────────────────────────────────────────\n useEffect(() => {\n if (projectId || !workspaceId) return;\n let cancelled = false;\n (async () => {\n try {\n const data = await gqlFetch<{\n planmagnetProjects: { items: { id: string; key: string }[] };\n }>(`query($wsId: ID!) { planmagnetProjects(workspaceId: $wsId) { items { id key } } }`, {\n wsId: workspaceId,\n });\n const existing = data.planmagnetProjects.items.find((p) => p.key === AI_PROJECT_KEY);\n if (existing && !cancelled) {\n setProjectId(existing.id);\n try {\n localStorage.setItem(getProfileScopedKey(AI_PROJECT_STORAGE_KEY), existing.id);\n } catch {\n // localStorage unavailable\n }\n return;\n }\n const createData = await gqlFetch<{ planmagnetCreateProject: { id: string } }>(\n `mutation($wsId: ID!, $input: PlanmagnetCreateProjectInput!) { planmagnetCreateProject(workspaceId: $wsId, input: $input) { id } }`,\n {\n wsId: workspaceId,\n input: {\n name: 'AI Tasks',\n key: AI_PROJECT_KEY,\n ownerId: 'system',\n methodology: 'KANBAN',\n tags: [AI_TASK_LABEL],\n },\n }\n );\n if (createData.planmagnetCreateProject.id && !cancelled) {\n setProjectId(createData.planmagnetCreateProject.id);\n try {\n localStorage.setItem(\n getProfileScopedKey(AI_PROJECT_STORAGE_KEY),\n createData.planmagnetCreateProject.id\n );\n } catch {\n // localStorage unavailable\n }\n }\n } catch (err) {\n console.error('Failed to find/create AI project:', err);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [workspaceId, projectId, apolloClient]);\n\n // ── Fetch tasks ────────────────────────────────────────────────────\n const fetchTasks = useCallback(async () => {\n if (!workspaceId) return;\n setLoading(true);\n setError(null);\n try {\n const data = await gqlFetch<{\n planmagnetWorkItems: { items: WorkItem[]; totalCount: number };\n }>(\n `query($wsId: ID!, $filter: PlanmagnetWorkItemFilter, $pagination: PlanmagnetPaginationInput) {\n planmagnetWorkItems(workspaceId: $wsId, filter: $filter, pagination: $pagination) {\n items { ${WORKITEM_FIELDS} }\n totalCount\n }\n }`,\n { wsId: workspaceId, filter: { type: 'TASK' }, pagination: { first: 200 } }\n );\n const all = data.planmagnetWorkItems.items ?? [];\n setItems(\n all.filter((i) => i.labels?.includes(AI_TASK_LABEL) || i.tags?.includes(AI_TASK_LABEL))\n );\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load tasks');\n } finally {\n setLoading(false);\n }\n }, [workspaceId, apolloClient]);\n\n useEffect(() => {\n fetchTasks();\n }, [fetchTasks]);\n\n const selectedTasks = useMemo(\n () => items.filter((item) => selectedTaskIds.has(item.id)),\n [items, selectedTaskIds]\n );\n const allVisibleSelected =\n items.length > 0 && items.every((item) => selectedTaskIds.has(item.id));\n const partiallySelected =\n items.some((item) => selectedTaskIds.has(item.id)) && !allVisibleSelected;\n\n // ── Create ─────────────────────────────────────────────────────────\n const [showCreate, setShowCreate] = useState(false);\n const [newTitle, setNewTitle] = useState('');\n const [newDescription, setNewDescription] = useState('');\n const [newStatus, setNewStatus] = useState<TaskStatus>('BACKLOG');\n const [newPriority, setNewPriority] = useState<TaskPriority>('MEDIUM');\n const [creating, setCreating] = useState(false);\n\n const handleCreate = async () => {\n if (!newTitle.trim() || !workspaceId || !projectId) return;\n setCreating(true);\n try {\n await gqlFetch(\n `mutation($wsId: ID!, $input: PlanmagnetCreateWorkItemInput!) { planmagnetCreateWorkItem(workspaceId: $wsId, input: $input) { id } }`,\n {\n wsId: workspaceId,\n input: {\n title: newTitle.trim(),\n description: newDescription.trim() || undefined,\n type: 'TASK',\n status: newStatus,\n priority: newPriority,\n labels: [AI_TASK_LABEL],\n projectId,\n },\n }\n );\n setNewTitle('');\n setNewDescription('');\n setNewStatus('BACKLOG');\n setNewPriority('MEDIUM');\n setShowCreate(false);\n fetchTasks();\n } catch (err) {\n console.error('Failed to create task:', err);\n } finally {\n setCreating(false);\n }\n };\n\n // ── Move (drag-drop status change) ─────────────────────────────────\n const [draggedId, setDraggedId] = useState<string | null>(null);\n\n const handleStatusChange = useCallback(\n async (taskId: string, targetStatus: TaskStatus) => {\n // Optimistic update\n setItems((prev) => prev.map((i) => (i.id === taskId ? { ...i, status: targetStatus } : i)));\n try {\n await gqlFetch(\n 'mutation($id: ID!, $input: PlanmagnetUpdateWorkItemInput!) { planmagnetUpdateWorkItem(id: $id, input: $input) { id } }',\n { id: taskId, input: { status: targetStatus } }\n );\n } catch (err) {\n console.error('Failed to move task:', err);\n fetchTasks(); // revert on failure\n }\n },\n [fetchTasks, gqlFetch]\n );\n\n const handleDrop = useCallback(\n (targetStatus: TaskStatus) => {\n if (!draggedId) return;\n const item = items.find((i) => i.id === draggedId);\n setDraggedId(null);\n if (!item || item.status === targetStatus) return;\n handleStatusChange(draggedId, targetStatus);\n },\n [draggedId, items, handleStatusChange]\n );\n\n // ── Delete ─────────────────────────────────────────────────────────\n const handleDelete = useCallback(\n async (id: string) => {\n setItems((prev) => prev.filter((i) => i.id !== id)); // optimistic\n try {\n await gqlFetch('mutation($id: ID!) { planmagnetDeleteWorkItem(id: $id) }', { id });\n } catch (err) {\n console.error('Failed to delete task:', err);\n fetchTasks(); // revert\n }\n },\n [fetchTasks, gqlFetch]\n );\n\n const handleBulkDelete = useCallback(async () => {\n if (selectedTasks.length === 0) return;\n setBulkDeleting(true);\n try {\n await Promise.allSettled(\n selectedTasks.map((task) =>\n gqlFetch('mutation($id: ID!) { planmagnetDeleteWorkItem(id: $id) }', { id: task.id })\n )\n );\n setSelectedTaskIds(new Set());\n setShowBulkDeleteDialog(false);\n await fetchTasks();\n } catch (err) {\n console.error('Failed to bulk delete tasks:', err);\n } finally {\n setBulkDeleting(false);\n }\n }, [fetchTasks, gqlFetch, selectedTasks]);\n\n const handleBulkMove = useCallback(async () => {\n if (selectedTasks.length === 0) return;\n setBulkMoving(true);\n try {\n setItems((prev) =>\n prev.map((item) =>\n selectedTaskIds.has(item.id) ? { ...item, status: bulkMoveStatus } : item\n )\n );\n await Promise.allSettled(\n selectedTasks.map((task) =>\n gqlFetch(\n 'mutation($id: ID!, $input: PlanmagnetUpdateWorkItemInput!) { planmagnetUpdateWorkItem(id: $id, input: $input) { id } }',\n { id: task.id, input: { status: bulkMoveStatus } }\n )\n )\n );\n setSelectedTaskIds(new Set());\n await fetchTasks();\n } catch (err) {\n console.error('Failed to bulk move tasks:', err);\n fetchTasks();\n } finally {\n setBulkMoving(false);\n }\n }, [bulkMoveStatus, fetchTasks, gqlFetch, selectedTaskIds, selectedTasks]);\n\n const toggleTaskSelection = useCallback((taskId: string, checked: boolean) => {\n setSelectedTaskIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(taskId);\n } else {\n next.delete(taskId);\n }\n return next;\n });\n }, []);\n\n const toggleAllVisibleTasks = useCallback(\n (checked: boolean) => {\n setSelectedTaskIds((prev) => {\n const next = new Set(prev);\n items.forEach((item) => {\n if (checked) {\n next.add(item.id);\n } else {\n next.delete(item.id);\n }\n });\n return next;\n });\n },\n [items]\n );\n\n const clearSelection = () => setSelectedTaskIds(new Set());\n\n // ── Render ─────────────────────────────────────────────────────────\n if (!workspaceId) {\n return (\n <EmptyState\n icon={<AlertCircle className=\"w-8 h-8 text-text-secondary\" />}\n title={tr('vibecontrols.ai.tasks.noWorkspace', 'No workspace selected')}\n description={tr(\n 'vibecontrols.ai.tasks.noWorkspaceDesc',\n 'Select a workspace to manage AI tasks'\n )}\n />\n );\n }\n\n if (loading && items.length === 0) {\n return (\n <LoadingState\n message={tr('vibecontrols.ai.tasks.loading', 'Loading AI tasks from PlanMagnet...')}\n />\n );\n }\n\n if (error && items.length === 0) {\n return (\n <ErrorState\n title={tr('vibecontrols.ai.tasks.loadFailed', 'Failed to load tasks')}\n message={error}\n action={\n <button\n onClick={fetchTasks}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors text-sm\"\n >\n <RefreshCw className=\"w-4 h-4\" />\n {tr('vibecontrols.ai.tasks.retry', 'Retry')}\n </button>\n }\n />\n );\n }\n\n return (\n <div className=\"space-y-4\">\n {/* Toolbar */}\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-2\">\n <p className=\"text-sm text-text-secondary\">\n {items.length} task{items.length !== 1 ? 's' : ''}\n </p>\n <button\n onClick={fetchTasks}\n className=\"p-1 hover:bg-bg-sunken rounded-md text-text-secondary hover:text-text-primary transition-colors\"\n title=\"Refresh\"\n >\n <RefreshCw className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n <button\n onClick={() => setShowCreate(true)}\n className=\"flex w-full items-center justify-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm text-action-primary-text transition-colors hover:bg-action-primary-bg-hover sm:w-auto\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('vibecontrols.ai.tasks.createTask', 'Create Task')}\n </button>\n </div>\n\n {items.length > 0 && (\n <div className=\"rounded-lg border border-border-default bg-bg-surface p-4\">\n <div className=\"flex flex-col gap-3 xl:flex-row xl:items-center xl:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleTasks}\n ariaLabel=\"Select all visible AI tasks\"\n />\n <span className=\"text-sm font-medium text-text-primary\">\n {tr('vibecontrols.ai.tasks.selectAllVisible', 'Select all visible')}\n </span>\n </div>\n {selectedTaskIds.size > 0 && (\n <button\n onClick={clearSelection}\n className=\"text-sm text-text-secondary hover:text-text-primary\"\n >\n {tr('vibecontrols.ai.tasks.clearSelection', 'Clear selection')}\n </button>\n )}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"rounded-full bg-bg-sunken px-3 py-1 text-sm font-medium text-text-secondary\">\n {selectedTaskIds.size} {tr('vibecontrols.ai.tasks.selected', 'selected')}\n </span>\n <select\n value={bulkMoveStatus}\n onChange={(event) => setBulkMoveStatus(event.target.value as TaskStatus)}\n className=\"rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n {columns.map((column) => (\n <option key={column.id} value={column.id}>\n Move to {column.label}\n </option>\n ))}\n </select>\n <button\n onClick={handleBulkMove}\n disabled={selectedTasks.length === 0 || bulkMoving}\n className=\"rounded-md border border-action-primary-bg/40 px-3 py-2 text-sm font-medium text-action-primary-bg hover:bg-action-primary-bg/10 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr('vibecontrols.ai.tasks.moveSelected', 'Move Selected')}\n {selectedTasks.length > 0 ? ` (${selectedTasks.length})` : ''}\n </button>\n <button\n onClick={() => setShowBulkDeleteDialog(true)}\n disabled={selectedTasks.length === 0 || bulkDeleting}\n className=\"rounded-md border border-status-error-border px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr('vibecontrols.ai.tasks.deleteSelected', 'Delete Selected')}\n {selectedTasks.length > 0 ? ` (${selectedTasks.length})` : ''}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Kanban Board */}\n {items.length === 0 ? (\n <EmptyState\n icon={<GripVertical className=\"w-8 h-8 text-text-secondary\" />}\n title={tr('vibecontrols.ai.tasks.emptyTitle', 'No AI tasks')}\n description={tr(\n 'vibecontrols.ai.tasks.emptyDescription',\n 'Create tasks to track and organize your AI vibecoding work. Tasks are stored in PlanMagnet.'\n )}\n action={\n <button\n onClick={() => setShowCreate(true)}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('vibecontrols.ai.tasks.createTask', 'Create Task')}\n </button>\n }\n />\n ) : (\n <div className=\"flex gap-3 overflow-x-auto pb-2\">\n {columns.map((col) => {\n const colItems = items.filter((i) => i.status === col.id);\n return (\n <div\n key={col.id}\n className={`flex-shrink-0 w-56 bg-bg-sunken rounded-lg border-t-2 ${col.color}`}\n onDragOver={(e) => e.preventDefault()}\n onDrop={(e) => {\n e.preventDefault();\n handleDrop(col.id);\n }}\n >\n <div className=\"px-3 py-2 flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-text-primary uppercase tracking-wide\">\n {col.label}\n </h4>\n <span className=\"text-xs text-text-secondary bg-bg-surface rounded-full px-1.5 py-0.5\">\n {colItems.length}\n </span>\n </div>\n <div className=\"px-2 pb-2 space-y-2 min-h-[100px]\">\n {colItems.map((item) => (\n <Card\n key={item.id}\n className=\"p-0 cursor-grab active:cursor-grabbing\"\n padding=\"none\"\n >\n <div draggable onDragStart={() => setDraggedId(item.id)} className=\"p-2\">\n <div className=\"flex items-start justify-between gap-1\">\n <div className=\"flex items-start gap-2 min-w-0 flex-1\">\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedTaskIds.has(item.id)}\n onChange={(checked) => toggleTaskSelection(item.id, checked)}\n ariaLabel={`Select task ${item.title}`}\n />\n </div>\n <div className=\"min-w-0 flex-1\">\n {item.key && (\n <span className=\"text-[10px] font-mono text-text-secondary\">\n {item.key}\n </span>\n )}\n <span className=\"block text-sm font-medium text-text-primary line-clamp-2\">\n {item.title}\n </span>\n </div>\n </div>\n <button\n onClick={(e) => {\n e.stopPropagation();\n handleDelete(item.id);\n }}\n className=\"p-0.5 hover:bg-status-error-bg rounded flex-shrink-0\"\n >\n <X className=\"w-3 h-3 text-text-secondary hover:text-status-error-text\" />\n </button>\n </div>\n <div className=\"flex items-center gap-1.5 mt-1.5\">\n {item.priority && priorityLabels[item.priority] && (\n <span\n className={`text-[10px] font-medium ${priorityLabels[item.priority].color}`}\n >\n {priorityLabels[item.priority].label}\n </span>\n )}\n {item.storyPoints != null && (\n <span className=\"text-[10px] text-text-secondary bg-bg-surface rounded px-1\">\n {item.storyPoints}pt\n </span>\n )}\n </div>\n </div>\n </Card>\n ))}\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {/* Create Task Dialog */}\n {showCreate && (\n <div\n className=\"fixed inset-0 bg-bg-overlay flex items-center justify-center z-50 p-4\"\n onClick={() => setShowCreate(false)}\n >\n <div\n className=\"bg-bg-surface border border-border-default rounded-lg shadow-xl w-full max-w-sm p-6\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"mb-4 flex items-start justify-between gap-3\">\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {tr('vibecontrols.ai.tasks.newAITask', 'New AI Task')}\n </h3>\n <button\n onClick={() => setShowCreate(false)}\n className=\"p-1 hover:bg-bg-sunken rounded-md\"\n >\n <X className=\"w-4 h-4 text-text-secondary\" />\n </button>\n </div>\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibecontrols.ai.tasks.title', 'Title')}\n </label>\n <input\n type=\"text\"\n value={newTitle}\n onChange={(e) => setNewTitle(e.target.value)}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary text-sm focus:outline-none focus:border-border-strong\"\n placeholder={tr('vibecontrols.ai.tasks.titlePlaceholder', 'Task title')}\n autoFocus\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) handleCreate();\n }}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibecontrols.ai.tasks.description', 'Description')}\n </label>\n <textarea\n value={newDescription}\n onChange={(e) => setNewDescription(e.target.value)}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary text-sm focus:outline-none focus:border-border-strong resize-none\"\n placeholder={tr(\n 'vibecontrols.ai.tasks.descriptionPlaceholder',\n 'Optional description'\n )}\n rows={3}\n />\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Status</label>\n <select\n value={newStatus}\n onChange={(e) => setNewStatus(e.target.value as TaskStatus)}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary text-sm\"\n >\n {columns.map((c) => (\n <option key={c.id} value={c.id}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Priority\n </label>\n <select\n value={newPriority}\n onChange={(e) => setNewPriority(e.target.value as TaskPriority)}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary text-sm\"\n >\n <option value=\"CRITICAL\">Critical</option>\n <option value=\"HIGH\">High</option>\n <option value=\"MEDIUM\">Medium</option>\n <option value=\"LOW\">Low</option>\n </select>\n </div>\n </div>\n </div>\n <div className=\"flex justify-end gap-2 mt-6\">\n <button\n onClick={() => setShowCreate(false)}\n className=\"px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken rounded-md transition-colors\"\n >\n Cancel\n </button>\n <button\n onClick={handleCreate}\n disabled={!newTitle.trim() || creating || !projectId}\n className=\"px-4 py-2 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50\"\n >\n {creating ? 'Creating...' : 'Create'}\n </button>\n </div>\n </div>\n </div>\n )}\n\n <ConfirmDialog\n isOpen={showBulkDeleteDialog}\n onClose={() => setShowBulkDeleteDialog(false)}\n onConfirm={handleBulkDelete}\n title=\"Delete AI Tasks\"\n message={`Delete ${selectedTasks.length} selected AI task${selectedTasks.length === 1 ? '' : 's'}? This cannot be undone.`}\n confirmLabel={bulkDeleting ? 'Deleting...' : 'Delete'}\n variant=\"danger\"\n isLoading={bulkDeleting}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAoBA,IAAM,IAAgB,WAChB,IAAiB,MACjB,IAAyB,8BAwBzB,IAA8D;CAClE;EAAE,IAAI;EAAW,OAAO;EAAW,OAAO;EAA2B;CACrE;EAAE,IAAI;EAAQ,OAAO;EAAS,OAAO;EAA8B;CACnE;EAAE,IAAI;EAAe,OAAO;EAAe,OAAO;EAAgC;CAClF;EAAE,IAAI;EAAa,OAAO;EAAa,OAAO;EAA8B;CAC5E;EAAE,IAAI;EAAQ,OAAO;EAAQ,OAAO;EAAgC;CACrE,EAEK,IAAmE;CACvE,UAAU;EAAE,OAAO;EAAY,OAAO;EAA0B;CAChE,MAAM;EAAE,OAAO;EAAQ,OAAO;EAA4B;CAC1D,QAAQ;EAAE,OAAO;EAAU,OAAO;EAA0B;CAC5D,KAAK;EAAE,OAAO;EAAO,OAAO;EAAuB;CACpD,EAEK,KAAkB;AAExB,SAAgB,IAAa;CAC3B,IAAM,IAAK,GAAO,EACZ,IAAe,IAAiB,EAChC,EAAE,aAAa,OAAmB,GAAiB,EAEnD,IACJ,MAAkB,IAAI,gBAAgB,OAAO,SAAS,OAAO,CAAC,IAAI,YAAY,IAAI,IAE9E,CAAC,GAAW,KAAgB,QAA8B;AAC9D,MAAI;AACF,UAAO,aAAa,QAAQ,EAAoB,EAAuB,CAAC;UAClE;AACN,UAAO;;GAET,EACI,CAAC,GAAO,KAAY,EAAqB,EAAE,CAAC,EAC5C,CAAC,IAAS,KAAc,EAAS,GAAK,EACtC,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAiB,KAAsB,kBAAsB,IAAI,KAAK,CAAC,EACxE,CAAC,GAAgB,MAAqB,EAAqB,OAAO,EAClE,CAAC,GAAc,KAAmB,EAAS,GAAM,EACjD,CAAC,IAAY,KAAiB,EAAS,GAAM,EAC7C,CAAC,IAAsB,KAA2B,EAAS,GAAM,EAEjE,IAAW,EACf,OAAW,GAAe,MAAoD;EAC5E,IAAM,IAAW,GAAI,EAAM;AAG3B,MAFgB,EAAM,WAAW,CAErB,WAAW,WAAW,EAAE;GAClC,IAAM,IAAS,MAAM,EAAa,OAAU;IAAE,UAAU;IAAU;IAAW,CAAC;AAC9E,OAAI,EAAO,MAAO,OAAU,MAAM,EAAO,MAAM,WAAW,kBAAkB;AAC5E,OAAI,CAAC,EAAO,KAAM,OAAU,MAAM,4BAA4B;AAC9D,UAAO,EAAO;;EAGhB,IAAM,IAAS,MAAM,EAAa,MAAS;GACzC,OAAO;GACP;GACA,aAAa;GACd,CAAC;AACF,MAAI,EAAO,MAAO,OAAU,MAAM,EAAO,MAAM,WAAW,eAAe;AACzE,MAAI,CAAC,EAAO,KAAM,OAAU,MAAM,yBAAyB;AAC3D,SAAO,EAAO;IAEhB,CAAC,EAAa,CACf;AAGD,SAAgB;AACd,MAAI,KAAa,CAAC,EAAa;EAC/B,IAAI,IAAY;AA8ChB,UA7CC,YAAY;AACX,OAAI;IAMF,IAAM,KALO,MAAM,EAEhB,qFAAqF,EACtF,MAAM,GACP,CAAC,EACoB,mBAAmB,MAAM,MAAM,MAAM,EAAE,QAAQ,EAAe;AACpF,QAAI,KAAY,CAAC,GAAW;AAC1B,OAAa,EAAS,GAAG;AACzB,SAAI;AACF,mBAAa,QAAQ,EAAoB,EAAuB,EAAE,EAAS,GAAG;aACxE;AAGR;;IAEF,IAAM,IAAa,MAAM,EACvB,qIACA;KACE,MAAM;KACN,OAAO;MACL,MAAM;MACN,KAAK;MACL,SAAS;MACT,aAAa;MACb,MAAM,CAAC,EAAc;MACtB;KACF,CACF;AACD,QAAI,EAAW,wBAAwB,MAAM,CAAC,GAAW;AACvD,OAAa,EAAW,wBAAwB,GAAG;AACnD,SAAI;AACF,mBAAa,QACX,EAAoB,EAAuB,EAC3C,EAAW,wBAAwB,GACpC;aACK;;YAIH,GAAK;AACZ,YAAQ,MAAM,qCAAqC,EAAI;;MAEvD,QACS;AACX,OAAY;;IAEb;EAAC;EAAa;EAAW;EAAa,CAAC;CAG1C,IAAM,IAAa,EAAY,YAAY;AACpC,SAEL;GADA,EAAW,GAAK,EAChB,EAAS,KAAK;AACd,OAAI;AAaF,QAZa,MAAM,EAGjB;;sBAEc,GAAgB;;;YAI9B;KAAE,MAAM;KAAa,QAAQ,EAAE,MAAM,QAAQ;KAAE,YAAY,EAAE,OAAO,KAAK;KAAE,CAC5E,EACgB,oBAAoB,SAAS,EAAE,EAE1C,QAAQ,MAAM,EAAE,QAAQ,SAAS,EAAc,IAAI,EAAE,MAAM,SAAS,EAAc,CAAC,CACxF;YACM,GAAK;AACZ,MAAS,aAAe,QAAQ,EAAI,UAAU,uBAAuB;aAC7D;AACR,MAAW,GAAM;;;IAElB,CAAC,GAAa,EAAa,CAAC;AAE/B,SAAgB;AACd,KAAY;IACX,CAAC,EAAW,CAAC;CAEhB,IAAM,IAAgB,SACd,EAAM,QAAQ,MAAS,EAAgB,IAAI,EAAK,GAAG,CAAC,EAC1D,CAAC,GAAO,EAAgB,CACzB,EACK,IACJ,EAAM,SAAS,KAAK,EAAM,OAAO,MAAS,EAAgB,IAAI,EAAK,GAAG,CAAC,EACnE,KACJ,EAAM,MAAM,MAAS,EAAgB,IAAI,EAAK,GAAG,CAAC,IAAI,CAAC,GAGnD,CAAC,IAAY,KAAiB,EAAS,GAAM,EAC7C,CAAC,GAAU,KAAe,EAAS,GAAG,EACtC,CAAC,GAAgB,KAAqB,EAAS,GAAG,EAClD,CAAC,GAAW,KAAgB,EAAqB,UAAU,EAC3D,CAAC,GAAa,KAAkB,EAAuB,SAAS,EAChE,CAAC,GAAU,KAAe,EAAS,GAAM,EAEzC,IAAe,YAAY;AAC3B,SAAC,EAAS,MAAM,IAAI,CAAC,KAAe,CAAC,IACzC;KAAY,GAAK;AACjB,OAAI;AAqBF,IApBA,MAAM,EACJ,uIACA;KACE,MAAM;KACN,OAAO;MACL,OAAO,EAAS,MAAM;MACtB,aAAa,EAAe,MAAM,IAAI,KAAA;MACtC,MAAM;MACN,QAAQ;MACR,UAAU;MACV,QAAQ,CAAC,EAAc;MACvB;MACD;KACF,CACF,EACD,EAAY,GAAG,EACf,EAAkB,GAAG,EACrB,EAAa,UAAU,EACvB,EAAe,SAAS,EACxB,EAAc,GAAM,EACpB,GAAY;YACL,GAAK;AACZ,YAAQ,MAAM,0BAA0B,EAAI;aACpC;AACR,MAAY,GAAM;;;IAKhB,CAAC,GAAW,MAAgB,EAAwB,KAAK,EAEzD,IAAqB,EACzB,OAAO,GAAgB,MAA6B;AAElD,KAAU,MAAS,EAAK,KAAK,MAAO,EAAE,OAAO,IAAS;GAAE,GAAG;GAAG,QAAQ;GAAc,GAAG,EAAG,CAAC;AAC3F,MAAI;AACF,SAAM,EACJ,0HACA;IAAE,IAAI;IAAQ,OAAO,EAAE,QAAQ,GAAc;IAAE,CAChD;WACM,GAAK;AAEZ,GADA,QAAQ,MAAM,wBAAwB,EAAI,EAC1C,GAAY;;IAGhB,CAAC,GAAY,EAAS,CACvB,EAEK,KAAa,GAChB,MAA6B;AAC5B,MAAI,CAAC,EAAW;EAChB,IAAM,IAAO,EAAM,MAAM,MAAM,EAAE,OAAO,EAAU;AAClD,KAAa,KAAK,EACd,GAAC,KAAQ,EAAK,WAAW,MAC7B,EAAmB,GAAW,EAAa;IAE7C;EAAC;EAAW;EAAO;EAAmB,CACvC,EAGK,KAAe,EACnB,OAAO,MAAe;AACpB,KAAU,MAAS,EAAK,QAAQ,MAAM,EAAE,OAAO,EAAG,CAAC;AACnD,MAAI;AACF,SAAM,EAAS,4DAA4D,EAAE,OAAI,CAAC;WAC3E,GAAK;AAEZ,GADA,QAAQ,MAAM,0BAA0B,EAAI,EAC5C,GAAY;;IAGhB,CAAC,GAAY,EAAS,CACvB,EAEK,KAAmB,EAAY,YAAY;AAC3C,QAAc,WAAW,GAC7B;KAAgB,GAAK;AACrB,OAAI;AAQF,IAPA,MAAM,QAAQ,WACZ,EAAc,KAAK,MACjB,EAAS,4DAA4D,EAAE,IAAI,EAAK,IAAI,CAAC,CACtF,CACF,EACD,kBAAmB,IAAI,KAAK,CAAC,EAC7B,EAAwB,GAAM,EAC9B,MAAM,GAAY;YACX,GAAK;AACZ,YAAQ,MAAM,gCAAgC,EAAI;aAC1C;AACR,MAAgB,GAAM;;;IAEvB;EAAC;EAAY;EAAU;EAAc,CAAC,EAEnC,KAAiB,EAAY,YAAY;AACzC,QAAc,WAAW,GAC7B;KAAc,GAAK;AACnB,OAAI;AAeF,IAdA,GAAU,MACR,EAAK,KAAK,MACR,EAAgB,IAAI,EAAK,GAAG,GAAG;KAAE,GAAG;KAAM,QAAQ;KAAgB,GAAG,EACtE,CACF,EACD,MAAM,QAAQ,WACZ,EAAc,KAAK,MACjB,EACE,0HACA;KAAE,IAAI,EAAK;KAAI,OAAO,EAAE,QAAQ,GAAgB;KAAE,CACnD,CACF,CACF,EACD,kBAAmB,IAAI,KAAK,CAAC,EAC7B,MAAM,GAAY;YACX,GAAK;AAEZ,IADA,QAAQ,MAAM,8BAA8B,EAAI,EAChD,GAAY;aACJ;AACR,MAAc,GAAM;;;IAErB;EAAC;EAAgB;EAAY;EAAU;EAAiB;EAAc,CAAC,EAEpE,KAAsB,GAAa,GAAgB,MAAqB;AAC5E,KAAoB,MAAS;GAC3B,IAAM,IAAO,IAAI,IAAI,EAAK;AAM1B,UALI,IACF,EAAK,IAAI,EAAO,GAEhB,EAAK,OAAO,EAAO,EAEd;IACP;IACD,EAAE,CAAC,EAEA,KAAwB,GAC3B,MAAqB;AACpB,KAAoB,MAAS;GAC3B,IAAM,IAAO,IAAI,IAAI,EAAK;AAQ1B,UAPA,EAAM,SAAS,MAAS;AACtB,IAAI,IACF,EAAK,IAAI,EAAK,GAAG,GAEjB,EAAK,OAAO,EAAK,GAAG;KAEtB,EACK;IACP;IAEJ,CAAC,EAAM,CACR;AA4CD,QAvCK,IAaD,MAAW,EAAM,WAAW,IAE5B,kBAAC,GAAD,EACE,SAAS,EAAG,iCAAiC,sCAAsC,EACnF,CAAA,GAIF,KAAS,EAAM,WAAW,IAE1B,kBAAC,GAAD;EACE,OAAO,EAAG,oCAAoC,uBAAuB;EACrE,SAAS;EACT,QACE,kBAAC,UAAD;GACE,SAAS;GACT,WAAU;aAFZ,CAIE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAChC,EAAG,+BAA+B,QAAQ,CACpC;;EAEX,CAAA,GAKJ,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAb;OACG,EAAM;OAAO;OAAM,EAAM,WAAW,IAAU,KAAN;OACvC;SACJ,kBAAC,UAAD;MACE,SAAS;MACT,WAAU;MACV,OAAM;gBAEN,kBAAC,GAAD,EAAW,WAAU,eAAgB,CAAA;MAC9B,CAAA,CACL;QACN,kBAAC,UAAD;KACE,eAAe,EAAc,GAAK;KAClC,WAAU;eAFZ,CAIE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC3B,EAAG,oCAAoC,cAAc,CAC/C;OACL;;GAEL,EAAM,SAAS,KACd,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QACE,SAAS;QACT,eAAe;QACf,UAAU;QACV,WAAU;QACV,CAAA,EACF,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAG,0CAA0C,qBAAqB;QAC9D,CAAA,CACH;UACL,EAAgB,OAAO,KACtB,kBAAC,UAAD;OACE,eApFa,kBAAmB,IAAI,KAAK,CAAC;OAqF1C,WAAU;iBAET,EAAG,wCAAwC,kBAAkB;OACvD,CAAA,CAEP;SAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,QAAD;QAAM,WAAU;kBAAhB;SACG,EAAgB;SAAK;SAAE,EAAG,kCAAkC,WAAW;SACnE;;OACP,kBAAC,UAAD;QACE,OAAO;QACP,WAAW,MAAU,GAAkB,EAAM,OAAO,MAAoB;QACxE,WAAU;kBAET,EAAQ,KAAK,MACZ,kBAAC,UAAD;SAAwB,OAAO,EAAO;mBAAtC,CAA0C,YAC/B,EAAO,MACT;WAFI,EAAO,GAEX,CACT;QACK,CAAA;OACT,kBAAC,UAAD;QACE,SAAS;QACT,UAAU,EAAc,WAAW,KAAK;QACxC,WAAU;kBAHZ,CAKG,EAAG,sCAAsC,gBAAgB,EACzD,EAAc,SAAS,IAAI,KAAK,EAAc,OAAO,KAAK,GACpD;;OACT,kBAAC,UAAD;QACE,eAAe,EAAwB,GAAK;QAC5C,UAAU,EAAc,WAAW,KAAK;QACxC,WAAU;kBAHZ,CAKG,EAAG,wCAAwC,kBAAkB,EAC7D,EAAc,SAAS,IAAI,KAAK,EAAc,OAAO,KAAK,GACpD;;OACL;QACF;;IACF,CAAA;GAIP,EAAM,WAAW,IAChB,kBAAC,GAAD;IACE,MAAM,kBAAC,IAAD,EAAc,WAAU,+BAAgC,CAAA;IAC9D,OAAO,EAAG,oCAAoC,cAAc;IAC5D,aAAa,EACX,0CACA,8FACD;IACD,QACE,kBAAC,UAAD;KACE,eAAe,EAAc,GAAK;KAClC,WAAU;eAFZ,CAIE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC3B,EAAG,oCAAoC,cAAc,CAC/C;;IAEX,CAAA,GAEF,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAQ,KAAK,MAAQ;KACpB,IAAM,IAAW,EAAM,QAAQ,MAAM,EAAE,WAAW,EAAI,GAAG;AACzD,YACE,kBAAC,OAAD;MAEE,WAAW,yDAAyD,EAAI;MACxE,aAAa,MAAM,EAAE,gBAAgB;MACrC,SAAS,MAAM;AAEb,OADA,EAAE,gBAAgB,EAClB,GAAW,EAAI,GAAG;;gBANtB,CASE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAI;QACF,CAAA,EACL,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAS;QACL,CAAA,CACH;UACN,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAS,KAAK,MACb,kBAAC,IAAD;QAEE,WAAU;QACV,SAAQ;kBAER,kBAAC,OAAD;SAAK,WAAA;SAAU,mBAAmB,GAAa,EAAK,GAAG;SAAE,WAAU;mBAAnE,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,OAAD;YAAK,UAAU,MAAU,EAAM,iBAAiB;sBAC9C,kBAAC,GAAD;aACE,SAAS,EAAgB,IAAI,EAAK,GAAG;aACrC,WAAW,MAAY,GAAoB,EAAK,IAAI,EAAQ;aAC5D,WAAW,eAAe,EAAK;aAC/B,CAAA;YACE,CAAA,EACN,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACG,EAAK,OACJ,kBAAC,QAAD;aAAM,WAAU;uBACb,EAAK;aACD,CAAA,EAET,kBAAC,QAAD;aAAM,WAAU;uBACb,EAAK;aACD,CAAA,CACH;cACF;cACN,kBAAC,UAAD;WACE,UAAU,MAAM;AAEd,YADA,EAAE,iBAAiB,EACnB,GAAa,EAAK,GAAG;;WAEvB,WAAU;qBAEV,kBAAC,IAAD,EAAG,WAAU,4DAA6D,CAAA;WACnE,CAAA,CACL;aACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACG,EAAK,YAAY,EAAe,EAAK,aACpC,kBAAC,QAAD;WACE,WAAW,2BAA2B,EAAe,EAAK,UAAU;qBAEnE,EAAe,EAAK,UAAU;WAC1B,CAAA,EAER,EAAK,eAAe,QACnB,kBAAC,QAAD;WAAM,WAAU;qBAAhB,CACG,EAAK,aAAY,KACb;aAEL;YACF;;QACD,EAlDA,EAAK,GAkDL,CACP;OACE,CAAA,CACF;QAxEC,EAAI,GAwEL;MAER;IACE,CAAA;GAIP,MACC,kBAAC,OAAD;IACE,WAAU;IACV,eAAe,EAAc,GAAM;cAEnC,kBAAC,OAAD;KACE,WAAU;KACV,UAAU,MAAM,EAAE,iBAAiB;eAFrC;MAIE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAG,mCAAmC,cAAc;QAClD,CAAA,EACL,kBAAC,UAAD;QACE,eAAe,EAAc,GAAM;QACnC,WAAU;kBAEV,kBAAC,IAAD,EAAG,WAAU,+BAAgC,CAAA;QACtC,CAAA,CACL;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;SAAO,WAAU;mBACd,EAAG,+BAA+B,QAAQ;SACrC,CAAA,EACR,kBAAC,SAAD;SACE,MAAK;SACL,OAAO;SACP,WAAW,MAAM,EAAY,EAAE,OAAO,MAAM;SAC5C,WAAU;SACV,aAAa,EAAG,0CAA0C,aAAa;SACvE,WAAA;SACA,YAAY,MAAM;AAChB,UAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,YAAU,GAAc;;SAEtD,CAAA,CACE,EAAA,CAAA;QACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;SAAO,WAAU;mBACd,EAAG,qCAAqC,cAAc;SACjD,CAAA,EACR,kBAAC,YAAD;SACE,OAAO;SACP,WAAW,MAAM,EAAkB,EAAE,OAAO,MAAM;SAClD,WAAU;SACV,aAAa,EACX,gDACA,uBACD;SACD,MAAM;SACN,CAAA,CACE,EAAA,CAAA;QACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;UAAO,WAAU;oBAAmD;UAAc,CAAA,EAClF,kBAAC,UAAD;UACE,OAAO;UACP,WAAW,MAAM,EAAa,EAAE,OAAO,MAAoB;UAC3D,WAAU;oBAET,EAAQ,KAAK,MACZ,kBAAC,UAAD;WAAmB,OAAO,EAAE;qBACzB,EAAE;WACI,EAFI,EAAE,GAEN,CACT;UACK,CAAA,CACL,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;UAAO,WAAU;oBAAmD;UAE5D,CAAA,EACR,kBAAC,UAAD;UACE,OAAO;UACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAsB;UAC/D,WAAU;oBAHZ;WAKE,kBAAC,UAAD;YAAQ,OAAM;sBAAW;YAAiB,CAAA;WAC1C,kBAAC,UAAD;YAAQ,OAAM;sBAAO;YAAa,CAAA;WAClC,kBAAC,UAAD;YAAQ,OAAM;sBAAS;YAAe,CAAA;WACtC,kBAAC,UAAD;YAAQ,OAAM;sBAAM;YAAY,CAAA;WACzB;YACL,EAAA,CAAA,CACF;;QACF;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,UAAD;QACE,eAAe,EAAc,GAAM;QACnC,WAAU;kBACX;QAEQ,CAAA,EACT,kBAAC,UAAD;QACE,SAAS;QACT,UAAU,CAAC,EAAS,MAAM,IAAI,KAAY,CAAC;QAC3C,WAAU;kBAET,IAAW,gBAAgB;QACrB,CAAA,CACL;;MACF;;IACF,CAAA;GAGR,kBAAC,IAAD;IACE,QAAQ;IACR,eAAe,EAAwB,GAAM;IAC7C,WAAW;IACX,OAAM;IACN,SAAS,UAAU,EAAc,OAAO,mBAAmB,EAAc,WAAW,IAAI,KAAK,IAAI;IACjG,cAAc,IAAe,gBAAgB;IAC7C,SAAQ;IACR,WAAW;IACX,CAAA;GACE;MApVJ,kBAAC,GAAD;EACE,MAAM,kBAAC,IAAD,EAAa,WAAU,+BAAgC,CAAA;EAC7D,OAAO,EAAG,qCAAqC,wBAAwB;EACvE,aAAa,EACX,yCACA,wCACD;EACD,CAAA"}
1
+ {"version":3,"file":"AITasksTab.js","names":[],"sources":["../../../src/components/ai/AITasksTab.tsx"],"sourcesContent":["/**\n * AI Tasks Tab — Kanban board backed by PlanMagnet's WorkItem model\n */\n\nimport { useState, useCallback, useEffect, useMemo } from 'react';\nimport { gql } from '@apollo/client';\nimport { useApolloClient } from '@apollo/client/react';\nimport { Plus, X, GripVertical, RefreshCw, AlertCircle } from 'lucide-react';\nimport {\n Card,\n EmptyState,\n LoadingState,\n ErrorState,\n ConfirmDialog,\n SelectionCheckbox,\n} from '@/components/shared';\nimport { useVibeControls } from '@/providers/VibeControlsProvider';\nimport { getProfileScopedKey } from '@burdenoff/fe-libs/shared/utils';\nimport { useTr } from '../../shared/hooks/useTr';\n\nconst AI_TASK_LABEL = 'ai-task';\nconst AI_PROJECT_KEY = 'AI';\nconst AI_PROJECT_STORAGE_KEY = 'vibecontrols:ai-project-id';\n\ntype TaskStatus = 'BACKLOG' | 'TODO' | 'IN_PROGRESS' | 'IN_REVIEW' | 'DONE';\ntype TaskPriority = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';\n\ninterface WorkItem {\n id: string;\n key: string;\n title: string;\n description?: string | null;\n type: string;\n status: TaskStatus;\n priority: TaskPriority;\n assigneeId?: string | null;\n storyPoints?: number | null;\n dueDate?: string | null;\n labels: string[];\n tags: string[];\n metadata?: Record<string, unknown> | null;\n createdBy: string;\n createdAt: string;\n updatedAt: string;\n}\n\nconst columns: { id: TaskStatus; label: string; color: string }[] = [\n { id: 'BACKLOG', label: 'Backlog', color: 'border-t-text-secondary' },\n { id: 'TODO', label: 'To Do', color: 'border-t-action-primary-bg' },\n { id: 'IN_PROGRESS', label: 'In Progress', color: 'border-t-status-warning-text' },\n { id: 'IN_REVIEW', label: 'In Review', color: 'border-t-action-primary-bg' },\n { id: 'DONE', label: 'Done', color: 'border-t-status-success-text' },\n];\n\nconst priorityLabels: Record<string, { label: string; color: string }> = {\n CRITICAL: { label: 'Critical', color: 'text-status-error-text' },\n HIGH: { label: 'High', color: 'text-status-warning-text' },\n MEDIUM: { label: 'Medium', color: 'text-action-primary-bg' },\n LOW: { label: 'Low', color: 'text-text-secondary' },\n};\n\nconst WORKITEM_FIELDS = `id key title description type status priority assigneeId storyPoints dueDate labels tags metadata createdBy createdAt updatedAt`;\n\nexport function AITasksTab() {\n const tr = useTr();\n const apolloClient = useApolloClient();\n const { workspaceId: ctxWorkspaceId } = useVibeControls();\n // Fall back to URL param if context doesn't have workspaceId\n const workspaceId =\n ctxWorkspaceId || new URLSearchParams(window.location.search).get('workspace') || '';\n\n const [projectId, setProjectId] = useState<string | null>(() => {\n try {\n return localStorage.getItem(getProfileScopedKey(AI_PROJECT_STORAGE_KEY));\n } catch {\n return null;\n }\n });\n const [items, setItems] = useState<WorkItem[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [selectedTaskIds, setSelectedTaskIds] = useState<Set<string>>(new Set());\n const [bulkMoveStatus, setBulkMoveStatus] = useState<TaskStatus>('TODO');\n const [bulkDeleting, setBulkDeleting] = useState(false);\n const [bulkMoving, setBulkMoving] = useState(false);\n const [showBulkDeleteDialog, setShowBulkDeleteDialog] = useState(false);\n\n const gqlFetch = useCallback(\n async <T,>(query: string, variables?: Record<string, unknown>): Promise<T> => {\n const document = gql(query);\n const trimmed = query.trimStart();\n\n if (trimmed.startsWith('mutation')) {\n const result = await apolloClient.mutate<T>({ mutation: document, variables });\n if (result.error) throw new Error(result.error.message || 'Mutation failed');\n if (!result.data) throw new Error('Mutation returned no data');\n return result.data;\n }\n\n const result = await apolloClient.query<T>({\n query: document,\n variables,\n fetchPolicy: 'network-only',\n });\n if (result.error) throw new Error(result.error.message || 'Query failed');\n if (!result.data) throw new Error('Query returned no data');\n return result.data;\n },\n [apolloClient]\n );\n\n // ── Project auto-discovery ─────────────────────────────────────────\n useEffect(() => {\n if (projectId || !workspaceId) return;\n let cancelled = false;\n (async () => {\n try {\n const data = await gqlFetch<{\n planmagnetProjects: { items: { id: string; key: string }[] };\n }>(`query($wsId: ID!) { planmagnetProjects(workspaceId: $wsId) { items { id key } } }`, {\n wsId: workspaceId,\n });\n const existing = data.planmagnetProjects.items.find((p) => p.key === AI_PROJECT_KEY);\n if (existing && !cancelled) {\n setProjectId(existing.id);\n try {\n localStorage.setItem(getProfileScopedKey(AI_PROJECT_STORAGE_KEY), existing.id);\n } catch {\n // localStorage unavailable\n }\n return;\n }\n const createData = await gqlFetch<{ planmagnetCreateProject: { id: string } }>(\n `mutation($wsId: ID!, $input: PlanmagnetCreateProjectInput!) { planmagnetCreateProject(workspaceId: $wsId, input: $input) { id } }`,\n {\n wsId: workspaceId,\n input: {\n name: 'AI Tasks',\n key: AI_PROJECT_KEY,\n ownerId: 'system',\n methodology: 'KANBAN',\n tags: [AI_TASK_LABEL],\n },\n }\n );\n if (createData.planmagnetCreateProject.id && !cancelled) {\n setProjectId(createData.planmagnetCreateProject.id);\n try {\n localStorage.setItem(\n getProfileScopedKey(AI_PROJECT_STORAGE_KEY),\n createData.planmagnetCreateProject.id\n );\n } catch {\n // localStorage unavailable\n }\n }\n } catch (err) {\n console.error('Failed to find/create AI project:', err);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [workspaceId, projectId, apolloClient]);\n\n // ── Fetch tasks ────────────────────────────────────────────────────\n const fetchTasks = useCallback(async () => {\n if (!workspaceId) return;\n setLoading(true);\n setError(null);\n try {\n const data = await gqlFetch<{\n planmagnetWorkItems: { items: WorkItem[]; totalCount: number };\n }>(\n `query($wsId: ID!, $filter: PlanmagnetWorkItemFilter, $pagination: PlanmagnetPaginationInput) {\n planmagnetWorkItems(workspaceId: $wsId, filter: $filter, pagination: $pagination) {\n items { ${WORKITEM_FIELDS} }\n totalCount\n }\n }`,\n { wsId: workspaceId, filter: { type: 'TASK' }, pagination: { first: 200 } }\n );\n const all = data.planmagnetWorkItems.items ?? [];\n setItems(\n all.filter((i) => i.labels?.includes(AI_TASK_LABEL) || i.tags?.includes(AI_TASK_LABEL))\n );\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load tasks');\n } finally {\n setLoading(false);\n }\n }, [workspaceId, apolloClient]);\n\n useEffect(() => {\n fetchTasks();\n }, [fetchTasks]);\n\n const selectedTasks = useMemo(\n () => items.filter((item) => selectedTaskIds.has(item.id)),\n [items, selectedTaskIds]\n );\n const allVisibleSelected =\n items.length > 0 && items.every((item) => selectedTaskIds.has(item.id));\n const partiallySelected =\n items.some((item) => selectedTaskIds.has(item.id)) && !allVisibleSelected;\n\n // ── Create ─────────────────────────────────────────────────────────\n const [showCreate, setShowCreate] = useState(false);\n const [newTitle, setNewTitle] = useState('');\n const [newDescription, setNewDescription] = useState('');\n const [newStatus, setNewStatus] = useState<TaskStatus>('BACKLOG');\n const [newPriority, setNewPriority] = useState<TaskPriority>('MEDIUM');\n const [creating, setCreating] = useState(false);\n\n const handleCreate = async () => {\n if (!newTitle.trim() || !workspaceId || !projectId) return;\n setCreating(true);\n try {\n await gqlFetch(\n `mutation($wsId: ID!, $input: PlanmagnetCreateWorkItemInput!) { planmagnetCreateWorkItem(workspaceId: $wsId, input: $input) { id } }`,\n {\n wsId: workspaceId,\n input: {\n title: newTitle.trim(),\n description: newDescription.trim() || undefined,\n type: 'TASK',\n status: newStatus,\n priority: newPriority,\n labels: [AI_TASK_LABEL],\n projectId,\n },\n }\n );\n setNewTitle('');\n setNewDescription('');\n setNewStatus('BACKLOG');\n setNewPriority('MEDIUM');\n setShowCreate(false);\n fetchTasks();\n } catch (err) {\n console.error('Failed to create task:', err);\n } finally {\n setCreating(false);\n }\n };\n\n // ── Move (drag-drop status change) ─────────────────────────────────\n const [draggedId, setDraggedId] = useState<string | null>(null);\n\n const handleStatusChange = useCallback(\n async (taskId: string, targetStatus: TaskStatus) => {\n // Optimistic update\n setItems((prev) => prev.map((i) => (i.id === taskId ? { ...i, status: targetStatus } : i)));\n try {\n await gqlFetch(\n 'mutation($id: ID!, $input: PlanmagnetUpdateWorkItemInput!) { planmagnetUpdateWorkItem(id: $id, input: $input) { id } }',\n { id: taskId, input: { status: targetStatus } }\n );\n } catch (err) {\n console.error('Failed to move task:', err);\n fetchTasks(); // revert on failure\n }\n },\n [fetchTasks, gqlFetch]\n );\n\n const handleDrop = useCallback(\n (targetStatus: TaskStatus) => {\n if (!draggedId) return;\n const item = items.find((i) => i.id === draggedId);\n setDraggedId(null);\n if (!item || item.status === targetStatus) return;\n handleStatusChange(draggedId, targetStatus);\n },\n [draggedId, items, handleStatusChange]\n );\n\n // ── Delete ─────────────────────────────────────────────────────────\n const handleDelete = useCallback(\n async (id: string) => {\n setItems((prev) => prev.filter((i) => i.id !== id)); // optimistic\n try {\n await gqlFetch('mutation($id: ID!) { planmagnetDeleteWorkItem(id: $id) }', { id });\n } catch (err) {\n console.error('Failed to delete task:', err);\n fetchTasks(); // revert\n }\n },\n [fetchTasks, gqlFetch]\n );\n\n const handleBulkDelete = useCallback(async () => {\n if (selectedTasks.length === 0) return;\n setBulkDeleting(true);\n try {\n await Promise.allSettled(\n selectedTasks.map((task) =>\n gqlFetch('mutation($id: ID!) { planmagnetDeleteWorkItem(id: $id) }', { id: task.id })\n )\n );\n setSelectedTaskIds(new Set());\n setShowBulkDeleteDialog(false);\n await fetchTasks();\n } catch (err) {\n console.error('Failed to bulk delete tasks:', err);\n } finally {\n setBulkDeleting(false);\n }\n }, [fetchTasks, gqlFetch, selectedTasks]);\n\n const handleBulkMove = useCallback(async () => {\n if (selectedTasks.length === 0) return;\n setBulkMoving(true);\n try {\n setItems((prev) =>\n prev.map((item) =>\n selectedTaskIds.has(item.id) ? { ...item, status: bulkMoveStatus } : item\n )\n );\n await Promise.allSettled(\n selectedTasks.map((task) =>\n gqlFetch(\n 'mutation($id: ID!, $input: PlanmagnetUpdateWorkItemInput!) { planmagnetUpdateWorkItem(id: $id, input: $input) { id } }',\n { id: task.id, input: { status: bulkMoveStatus } }\n )\n )\n );\n setSelectedTaskIds(new Set());\n await fetchTasks();\n } catch (err) {\n console.error('Failed to bulk move tasks:', err);\n fetchTasks();\n } finally {\n setBulkMoving(false);\n }\n }, [bulkMoveStatus, fetchTasks, gqlFetch, selectedTaskIds, selectedTasks]);\n\n const toggleTaskSelection = useCallback((taskId: string, checked: boolean) => {\n setSelectedTaskIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(taskId);\n } else {\n next.delete(taskId);\n }\n return next;\n });\n }, []);\n\n const toggleAllVisibleTasks = useCallback(\n (checked: boolean) => {\n setSelectedTaskIds((prev) => {\n const next = new Set(prev);\n items.forEach((item) => {\n if (checked) {\n next.add(item.id);\n } else {\n next.delete(item.id);\n }\n });\n return next;\n });\n },\n [items]\n );\n\n const clearSelection = () => setSelectedTaskIds(new Set());\n\n // ── Render ─────────────────────────────────────────────────────────\n if (!workspaceId) {\n return (\n <EmptyState\n icon={<AlertCircle className=\"w-8 h-8 text-text-secondary\" />}\n title={tr('vibecontrols.ai.tasks.noWorkspace', 'No workspace selected')}\n description={tr(\n 'vibecontrols.ai.tasks.noWorkspaceDesc',\n 'Select a workspace to manage AI tasks'\n )}\n />\n );\n }\n\n if (loading && items.length === 0) {\n return (\n <LoadingState\n message={tr('vibecontrols.ai.tasks.loading', 'Loading AI tasks from PlanMagnet...')}\n />\n );\n }\n\n if (error && items.length === 0) {\n return (\n <ErrorState\n title={tr('vibecontrols.ai.tasks.loadFailed', 'Failed to load tasks')}\n message={error}\n action={\n <button\n onClick={fetchTasks}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors text-sm\"\n >\n <RefreshCw className=\"w-4 h-4\" />\n {tr('vibecontrols.ai.tasks.retry', 'Retry')}\n </button>\n }\n />\n );\n }\n\n return (\n <div className=\"space-y-4\">\n {/* Toolbar */}\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-2\">\n <p className=\"text-sm text-text-secondary\">\n {items.length} task{items.length !== 1 ? 's' : ''}\n </p>\n <button\n onClick={fetchTasks}\n className=\"p-1 hover:bg-bg-sunken rounded-md text-text-secondary hover:text-text-primary transition-colors\"\n title=\"Refresh\"\n >\n <RefreshCw className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n <button\n onClick={() => setShowCreate(true)}\n className=\"flex w-full items-center justify-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm text-action-primary-text transition-colors hover:bg-action-primary-bg-hover sm:w-auto\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('vibecontrols.ai.tasks.createTask', 'Create Task')}\n </button>\n </div>\n\n {items.length > 0 && (\n <div className=\"rounded-lg border border-border-default bg-bg-surface p-4\">\n <div className=\"flex flex-col gap-3 xl:flex-row xl:items-center xl:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleTasks}\n ariaLabel=\"Select all visible AI tasks\"\n />\n <span className=\"text-sm font-medium text-text-primary\">\n {tr('vibecontrols.ai.tasks.selectAllVisible', 'Select all visible')}\n </span>\n </div>\n {selectedTaskIds.size > 0 && (\n <button\n onClick={clearSelection}\n className=\"text-sm text-text-secondary hover:text-text-primary\"\n >\n {tr('vibecontrols.ai.tasks.clearSelection', 'Clear selection')}\n </button>\n )}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"rounded-full bg-bg-sunken px-3 py-1 text-sm font-medium text-text-secondary\">\n {selectedTaskIds.size} {tr('vibecontrols.ai.tasks.selected', 'selected')}\n </span>\n <select\n value={bulkMoveStatus}\n onChange={(event) => setBulkMoveStatus(event.target.value as TaskStatus)}\n className=\"rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n {columns.map((column) => (\n <option key={column.id} value={column.id}>\n Move to {column.label}\n </option>\n ))}\n </select>\n <button\n onClick={handleBulkMove}\n disabled={selectedTasks.length === 0 || bulkMoving}\n className=\"rounded-md border border-action-primary-bg/40 px-3 py-2 text-sm font-medium text-action-primary-bg hover:bg-action-primary-bg/10 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr('vibecontrols.ai.tasks.moveSelected', 'Move Selected')}\n {selectedTasks.length > 0 ? ` (${selectedTasks.length})` : ''}\n </button>\n <button\n onClick={() => setShowBulkDeleteDialog(true)}\n disabled={selectedTasks.length === 0 || bulkDeleting}\n className=\"rounded-md border border-status-error-border px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr('vibecontrols.ai.tasks.deleteSelected', 'Delete Selected')}\n {selectedTasks.length > 0 ? ` (${selectedTasks.length})` : ''}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Kanban Board */}\n {items.length === 0 ? (\n <EmptyState\n icon={<GripVertical className=\"w-8 h-8 text-text-secondary\" />}\n title={tr('vibecontrols.ai.tasks.emptyTitle', 'No AI tasks')}\n description={tr(\n 'vibecontrols.ai.tasks.emptyDescription',\n 'Create tasks to track and organize your AI vibecoding work. Tasks are stored in PlanMagnet.'\n )}\n action={\n <button\n onClick={() => setShowCreate(true)}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('vibecontrols.ai.tasks.createTask', 'Create Task')}\n </button>\n }\n />\n ) : (\n <div className=\"flex gap-3 overflow-x-auto pb-2\">\n {columns.map((col) => {\n const colItems = items.filter((i) => i.status === col.id);\n return (\n <div\n key={col.id}\n className={`flex-shrink-0 w-56 bg-bg-sunken rounded-lg border-t-2 ${col.color}`}\n onDragOver={(e) => e.preventDefault()}\n onDrop={(e) => {\n e.preventDefault();\n handleDrop(col.id);\n }}\n >\n <div className=\"px-3 py-2 flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-text-primary uppercase tracking-wide\">\n {col.label}\n </h4>\n <span className=\"text-xs text-text-secondary bg-bg-surface rounded-full px-1.5 py-0.5\">\n {colItems.length}\n </span>\n </div>\n <div className=\"px-2 pb-2 space-y-2 min-h-[100px]\">\n {colItems.map((item) => (\n <Card\n key={item.id}\n className=\"p-0 cursor-grab active:cursor-grabbing\"\n padding=\"none\"\n >\n <div draggable onDragStart={() => setDraggedId(item.id)} className=\"p-2\">\n <div className=\"flex items-start justify-between gap-1\">\n <div className=\"flex items-start gap-2 min-w-0 flex-1\">\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedTaskIds.has(item.id)}\n onChange={(checked) => toggleTaskSelection(item.id, checked)}\n ariaLabel={`Select task ${item.title}`}\n />\n </div>\n <div className=\"min-w-0 flex-1\">\n {item.key && (\n <span className=\"text-[10px] font-mono text-text-secondary\">\n {item.key}\n </span>\n )}\n <span className=\"block text-sm font-medium text-text-primary line-clamp-2\">\n {item.title}\n </span>\n </div>\n </div>\n <button\n onClick={(e) => {\n e.stopPropagation();\n handleDelete(item.id);\n }}\n className=\"p-0.5 hover:bg-status-error-bg rounded flex-shrink-0\"\n >\n <X className=\"w-3 h-3 text-text-secondary hover:text-status-error-text\" />\n </button>\n </div>\n <div className=\"flex items-center gap-1.5 mt-1.5\">\n {item.priority && priorityLabels[item.priority] && (\n <span\n className={`text-[10px] font-medium ${priorityLabels[item.priority].color}`}\n >\n {priorityLabels[item.priority].label}\n </span>\n )}\n {item.storyPoints != null && (\n <span className=\"text-[10px] text-text-secondary bg-bg-surface rounded px-1\">\n {item.storyPoints}pt\n </span>\n )}\n </div>\n </div>\n </Card>\n ))}\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {/* Create Task Dialog */}\n {showCreate && (\n <div\n className=\"fixed inset-0 bg-bg-overlay flex items-center justify-center z-50 p-4\"\n onClick={() => setShowCreate(false)}\n >\n <div\n className=\"bg-bg-surface border border-border-default rounded-lg shadow-xl w-full max-w-sm p-6\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"mb-4 flex items-start justify-between gap-3\">\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {tr('vibecontrols.ai.tasks.newAITask', 'New AI Task')}\n </h3>\n <button\n onClick={() => setShowCreate(false)}\n className=\"p-1 hover:bg-bg-sunken rounded-md\"\n >\n <X className=\"w-4 h-4 text-text-secondary\" />\n </button>\n </div>\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibecontrols.ai.tasks.title', 'Title')}\n </label>\n <input\n type=\"text\"\n value={newTitle}\n onChange={(e) => setNewTitle(e.target.value)}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary text-sm focus:outline-none focus:border-border-strong\"\n placeholder={tr('vibecontrols.ai.tasks.titlePlaceholder', 'Task title')}\n autoFocus\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) handleCreate();\n }}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibecontrols.ai.tasks.description', 'Description')}\n </label>\n <textarea\n value={newDescription}\n onChange={(e) => setNewDescription(e.target.value)}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary text-sm focus:outline-none focus:border-border-strong resize-none\"\n placeholder={tr(\n 'vibecontrols.ai.tasks.descriptionPlaceholder',\n 'Optional description'\n )}\n rows={3}\n />\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Status</label>\n <select\n value={newStatus}\n onChange={(e) => setNewStatus(e.target.value as TaskStatus)}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary text-sm\"\n >\n {columns.map((c) => (\n <option key={c.id} value={c.id}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Priority\n </label>\n <select\n value={newPriority}\n onChange={(e) => setNewPriority(e.target.value as TaskPriority)}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary text-sm\"\n >\n <option value=\"CRITICAL\">Critical</option>\n <option value=\"HIGH\">High</option>\n <option value=\"MEDIUM\">Medium</option>\n <option value=\"LOW\">Low</option>\n </select>\n </div>\n </div>\n </div>\n <div className=\"flex justify-end gap-2 mt-6\">\n <button\n onClick={() => setShowCreate(false)}\n className=\"px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken rounded-md transition-colors\"\n >\n Cancel\n </button>\n <button\n onClick={handleCreate}\n disabled={!newTitle.trim() || creating || !projectId}\n className=\"px-4 py-2 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50\"\n >\n {creating ? 'Creating...' : 'Create'}\n </button>\n </div>\n </div>\n </div>\n )}\n\n <ConfirmDialog\n isOpen={showBulkDeleteDialog}\n onClose={() => setShowBulkDeleteDialog(false)}\n onConfirm={handleBulkDelete}\n title=\"Delete AI Tasks\"\n message={`Delete ${selectedTasks.length} selected AI task${selectedTasks.length === 1 ? '' : 's'}? This cannot be undone.`}\n confirmLabel={bulkDeleting ? 'Deleting...' : 'Delete'}\n variant=\"danger\"\n isLoading={bulkDeleting}\n />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { useTr as e } from "../../shared/hooks/useTr.js";
2
- import { LoadingState as t } from "../shared/LoadingState.js";
3
- import { ErrorState as n } from "../shared/ErrorState.js";
4
- import { ConfirmDialog as r } from "../shared/ConfirmDialog.js";
2
+ import { ConfirmDialog as t } from "../shared/ConfirmDialog.js";
3
+ import { LoadingState as n } from "../shared/LoadingState.js";
4
+ import { ErrorState as r } from "../shared/ErrorState.js";
5
5
  import { EmptyState as i } from "../shared/EmptyState.js";
6
6
  import { Card as a } from "../shared/Card.js";
7
7
  import { SelectionCheckbox as o } from "../shared/SelectionCheckbox.js";
@@ -124,7 +124,7 @@ function g({ agentId: g }) {
124
124
  return t ? r.add(e) : r.delete(e), r;
125
125
  });
126
126
  };
127
- return de ? /* @__PURE__ */ p(t, { message: _("vibecontrols.ai.templates.loading", "Loading templates...") }) : b ? /* @__PURE__ */ p(n, {
127
+ return de ? /* @__PURE__ */ p(n, { message: _("vibecontrols.ai.templates.loading", "Loading templates...") }) : b ? /* @__PURE__ */ p(r, {
128
128
  title: _("vibecontrols.ai.templates.loadFailed", "Failed to load templates"),
129
129
  message: b,
130
130
  onRetry: Y
@@ -454,7 +454,7 @@ function g({ agentId: g }) {
454
454
  ]
455
455
  })
456
456
  }),
457
- /* @__PURE__ */ p(r, {
457
+ /* @__PURE__ */ p(t, {
458
458
  isOpen: F.length > 0,
459
459
  title: F.length > 1 ? "Delete Templates" : "Delete Template",
460
460
  message: F.length > 1 ? `Are you sure you want to delete ${F.length} selected templates? This action cannot be undone.` : "Are you sure you want to delete this template? This action cannot be undone.",
@@ -1,46 +1,46 @@
1
1
  import { useTr as e } from "../../shared/hooks/useTr.js";
2
- import { useCompileDocsSiteMutation as t, useCreateDocsPageMutation as n, useCreateDocsSiteMutation as r, useDeleteDocsPageMutation as i, useDeleteDocsSiteMutation as a, useDocsContentQuery as ee, useGenerateDocsSignedUrlMutation as te, useGetDocsRevisionLazyQuery as ne, useGetDocsSiteQuery as re, useRollbackDocsRevisionMutation as ie, useUpdateDocsPageMutation as ae, useUpdateDocsSiteMutation as o, useUpdateDocsSiteVisibilityMutation as s } from "../../generated/wspace-operations.js";
3
- import { useVibeNavigate as c } from "../../providers/VibeControlsProvider.js";
4
- import { LoadingState as l } from "../shared/LoadingState.js";
5
- import { ErrorState as u } from "../shared/ErrorState.js";
6
- import { QuotaExhaustedDialog as d } from "../shared/QuotaExhaustedDialog.js";
7
- import { isQuotaExhaustedError as f } from "../../utils/quotaUtils.js";
2
+ import { QuotaExhaustedDialog as t } from "../shared/QuotaExhaustedDialog.js";
3
+ import { isQuotaExhaustedError as n, markQuotaHandledLocally as r } from "../../utils/quotaUtils.js";
4
+ import { useCompileDocsSiteMutation as ee, useCreateDocsPageMutation as te, useCreateDocsSiteMutation as ne, useDeleteDocsPageMutation as re, useDeleteDocsSiteMutation as ie, useDocsContentQuery as i, useGenerateDocsSignedUrlMutation as a, useGetDocsRevisionLazyQuery as o, useGetDocsSiteQuery as s, useRollbackDocsRevisionMutation as c, useUpdateDocsPageMutation as l, useUpdateDocsSiteMutation as u, useUpdateDocsSiteVisibilityMutation as d } from "../../generated/wspace-operations.js";
5
+ import { useVibeNavigate as f } from "../../providers/VibeControlsProvider.js";
6
+ import { LoadingState as p } from "../shared/LoadingState.js";
7
+ import { ErrorState as m } from "../shared/ErrorState.js";
8
8
  import "../shared/index.js";
9
- import { DocsEmptyState as p } from "./DocsEmptyState.js";
10
- import { DocsPreviewPanel as m } from "./DocsPreviewPanel.js";
11
- import { DocsEditPanel as h } from "./DocsEditPanel.js";
12
- import { useEffect as g, useRef as _, useState as v } from "react";
13
- import { AlertCircle as y, X as b } from "lucide-react";
9
+ import { DocsEmptyState as h } from "./DocsEmptyState.js";
10
+ import { DocsPreviewPanel as g } from "./DocsPreviewPanel.js";
11
+ import { DocsEditPanel as _ } from "./DocsEditPanel.js";
12
+ import { useEffect as v, useRef as y, useState as b } from "react";
13
+ import { AlertCircle as ae, X as oe } from "lucide-react";
14
14
  import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
15
- import { resolveGatewayUrls as oe } from "@burdenoff/fe-libs/shared/config";
15
+ import { resolveGatewayUrls as se } from "@burdenoff/fe-libs/shared/config";
16
16
  //#region src/components/docs/DocsTabPanel.tsx
17
- function w({ vibeId: w, ownerType: se, ownerId: ce }) {
18
- let T = e(), E = se || "VIBE", D = ce || w || "", [O, k] = v("preview"), [A, j] = v(null), [M, N] = v(!1), [P, F] = v(null), [I, L] = v(""), [R, z] = v(null), B = c(), [V, H] = v(!1), { data: U, loading: W, error: G, refetch: K } = re({
17
+ function w({ vibeId: w, ownerType: ce, ownerId: le }) {
18
+ let T = e(), E = ce || "VIBE", D = le || w || "", [O, k] = b("preview"), [A, j] = b(null), [M, N] = b(!1), [P, F] = b(null), [I, L] = b(""), [R, z] = b(null), B = f(), [V, H] = b(!1), { data: U, loading: W, error: G, refetch: K } = s({
19
19
  variables: {
20
20
  ownerType: E,
21
21
  ownerId: D
22
22
  },
23
23
  skip: !D,
24
24
  fetchPolicy: "cache-and-network"
25
- }), q = U?.vibecontrolsDocsSiteByOwner ?? null, J = q?.pages || [], { data: le, loading: ue, refetch: de } = ee({
25
+ }), q = U?.vibecontrolsDocsSiteByOwner ?? null, J = q?.pages || [], { data: ue, loading: de, refetch: fe } = i({
26
26
  variables: {
27
27
  siteId: q?.id || "",
28
28
  path: I
29
29
  },
30
30
  skip: !q?.id || !q.currentRevisionId,
31
31
  fetchPolicy: "network-only"
32
- }), fe = le?.docsContent?.html ?? null, Y = _(void 0);
33
- g(() => {
32
+ }), pe = ue?.docsContent?.html ?? null, Y = y(void 0);
33
+ v(() => {
34
34
  let e = q?.currentRevisionId ?? null;
35
35
  if (Y.current === void 0) {
36
36
  Y.current = e;
37
37
  return;
38
38
  }
39
- e && e !== Y.current && (Y.current = e, de());
39
+ e && e !== Y.current && (Y.current = e, fe());
40
40
  }, [q?.currentRevisionId]);
41
- let pe = oe(), me = q?.workspaceId ? `${pe.workspaceBaseUrl}/workspaces/static/${q.workspaceId}/docs/${D}/` : null, [he, { loading: ge }] = r(), [_e] = o(), [ve] = s(), [ye, { loading: be }] = n(), [xe] = ae(), [Se] = i(), [Ce] = t(), [we] = te(), [Te] = ie(), [Ee] = a(), [De] = ne({ fetchPolicy: "network-only" }), Oe = async (e = "DOCUSAURUS") => {
41
+ let me = se(), he = q?.workspaceId ? `${me.workspaceBaseUrl}/workspaces/static/${q.workspaceId}/docs/${D}/` : null, [ge, { loading: _e }] = ne(), [ve] = u(), [ye] = d(), [be, { loading: xe }] = te(), [Se] = l(), [Ce] = re(), [we] = ee(), [Te] = a(), [Ee] = c(), [De] = ie(), [Oe] = o({ fetchPolicy: "network-only" }), ke = async (e = "DOCUSAURUS") => {
42
42
  try {
43
- await he({
43
+ await ge({
44
44
  variables: { input: {
45
45
  ownerType: E,
46
46
  ownerId: D,
@@ -51,21 +51,21 @@ function w({ vibeId: w, ownerType: se, ownerId: ce }) {
51
51
  awaitRefetchQueries: !0
52
52
  }), k("edit");
53
53
  } catch (e) {
54
- if (f(e)) {
55
- H(!0);
54
+ if (n(e)) {
55
+ r(), H(!0);
56
56
  return;
57
57
  }
58
58
  throw e;
59
59
  }
60
- }, ke = async (e, t) => {
61
- await xe({ variables: {
60
+ }, Ae = async (e, t) => {
61
+ await Se({ variables: {
62
62
  id: e,
63
63
  input: t
64
64
  } });
65
- }, Ae = async (e, t) => {
65
+ }, X = async (e, t) => {
66
66
  if (!q) return;
67
67
  let n = J.length, r = `page-${n + 1}`;
68
- await ye({ variables: { input: {
68
+ await be({ variables: { input: {
69
69
  siteId: q.id,
70
70
  parentId: e || null,
71
71
  slug: r,
@@ -75,13 +75,13 @@ function w({ vibeId: w, ownerType: se, ownerId: ce }) {
75
75
  sidebarPosition: n,
76
76
  category: t || null
77
77
  } } }), await K();
78
- }, X = async (e) => {
79
- confirm("Delete this page?") && (await Se({ variables: { id: e } }), await K());
78
+ }, je = async (e) => {
79
+ confirm("Delete this page?") && (await Ce({ variables: { id: e } }), await K());
80
80
  }, Z = async () => {
81
81
  if (q) {
82
82
  N(!0), F(null);
83
83
  try {
84
- let { data: e } = await Ce({ variables: {
84
+ let { data: e } = await we({ variables: {
85
85
  siteId: q.id,
86
86
  publish: !0
87
87
  } });
@@ -91,15 +91,15 @@ function w({ vibeId: w, ownerType: se, ownerId: ce }) {
91
91
  }
92
92
  }
93
93
  }, Q = async (e) => {
94
- let { data: t } = await De({ variables: { id: e } }), n = t?.docsRevision;
94
+ let { data: t } = await Oe({ variables: { id: e } }), n = t?.docsRevision;
95
95
  return n && (j(n), [
96
96
  "SUCCEEDED",
97
97
  "PUBLISHED",
98
98
  "FAILED"
99
99
  ].includes(n.status) && (N(!1), (n.status === "PUBLISHED" || n.status === "SUCCEEDED") && (L(""), await K()))), n;
100
- }, je = async (e) => {
100
+ }, Me = async (e) => {
101
101
  if (!q) return;
102
- e.visibility && e.visibility !== q.visibility && await ve({ variables: {
102
+ e.visibility && e.visibility !== q.visibility && await ye({ variables: {
103
103
  id: q.id,
104
104
  visibility: e.visibility
105
105
  } });
@@ -108,23 +108,23 @@ function w({ vibeId: w, ownerType: se, ownerId: ce }) {
108
108
  provider: e.provider,
109
109
  providerConfig: e.providerConfig
110
110
  };
111
- Object.keys(t).length > 0 && await _e({ variables: {
111
+ Object.keys(t).length > 0 && await ve({ variables: {
112
112
  id: q.id,
113
113
  input: t
114
114
  } }), await K();
115
- }, Me = async () => {
115
+ }, Ne = async () => {
116
116
  if (!q?.currentRevisionId) return null;
117
117
  try {
118
- let { data: e } = await we({ variables: { siteId: q.id } });
118
+ let { data: e } = await Te({ variables: { siteId: q.id } });
119
119
  return e?.generateDocsSignedUrl?.url ?? null;
120
120
  } catch {
121
121
  return null;
122
122
  }
123
- }, Ne = async (e) => {
123
+ }, Pe = async (e) => {
124
124
  if (q && confirm("Roll back to this revision? The current published docs will be replaced.")) {
125
125
  z(e);
126
126
  try {
127
- await Te({ variables: {
127
+ await Ee({ variables: {
128
128
  siteId: q.id,
129
129
  revisionId: e
130
130
  } }), await K();
@@ -132,19 +132,19 @@ function w({ vibeId: w, ownerType: se, ownerId: ce }) {
132
132
  z(null);
133
133
  }
134
134
  }
135
- }, Pe = async () => {
136
- q && confirm("Delete this docs site and all its pages and revisions? This cannot be undone.") && (await Ee({ variables: { id: q.id } }), await K());
135
+ }, Fe = async () => {
136
+ q && confirm("Delete this docs site and all its pages and revisions? This cannot be undone.") && (await De({ variables: { id: q.id } }), await K());
137
137
  };
138
- if (W && !q) return /* @__PURE__ */ S(l, { message: T("vibecontrols.docs.tab.loading", "Loading documentation...") });
139
- if (G && !q) return /* @__PURE__ */ S(u, {
138
+ if (W && !q) return /* @__PURE__ */ S(p, { message: T("vibecontrols.docs.tab.loading", "Loading documentation...") });
139
+ if (G && !q) return /* @__PURE__ */ S(m, {
140
140
  title: T("vibecontrols.docs.tab.loadFailed", "Failed to load docs"),
141
141
  message: G.message,
142
142
  onRetry: () => K()
143
143
  });
144
- if (!q) return /* @__PURE__ */ C(x, { children: [/* @__PURE__ */ S(p, {
145
- onCreate: Oe,
146
- loading: ge
147
- }), /* @__PURE__ */ S(d, {
144
+ if (!q) return /* @__PURE__ */ C(x, { children: [/* @__PURE__ */ S(h, {
145
+ onCreate: ke,
146
+ loading: _e
147
+ }), /* @__PURE__ */ S(t, {
148
148
  isOpen: V,
149
149
  onClose: () => H(!1),
150
150
  onConfirm: () => {
@@ -156,7 +156,7 @@ function w({ vibeId: w, ownerType: se, ownerId: ce }) {
156
156
  let $ = P ? /* @__PURE__ */ C("div", {
157
157
  className: "flex items-center gap-2 px-4 py-2 mb-2 bg-status-danger-bg text-status-danger-text text-sm rounded-md",
158
158
  children: [
159
- /* @__PURE__ */ S(y, { className: "w-4 h-4 shrink-0" }),
159
+ /* @__PURE__ */ S(ae, { className: "w-4 h-4 shrink-0" }),
160
160
  /* @__PURE__ */ S("span", {
161
161
  className: "flex-1",
162
162
  children: P
@@ -164,40 +164,40 @@ function w({ vibeId: w, ownerType: se, ownerId: ce }) {
164
164
  /* @__PURE__ */ S("button", {
165
165
  onClick: () => F(null),
166
166
  className: "p-0.5 hover:opacity-70",
167
- children: /* @__PURE__ */ S(b, { className: "w-3.5 h-3.5" })
167
+ children: /* @__PURE__ */ S(oe, { className: "w-3.5 h-3.5" })
168
168
  })
169
169
  ]
170
170
  }) : null;
171
- return O === "edit" ? /* @__PURE__ */ C(x, { children: [$, /* @__PURE__ */ S(h, {
171
+ return O === "edit" ? /* @__PURE__ */ C(x, { children: [$, /* @__PURE__ */ S(_, {
172
172
  site: q,
173
173
  pages: J,
174
174
  onBack: () => k("preview"),
175
- onSavePage: ke,
176
- onAddPage: Ae,
177
- pageAdding: be,
178
- onDeletePage: X,
175
+ onSavePage: Ae,
176
+ onAddPage: X,
177
+ pageAdding: xe,
178
+ onDeletePage: je,
179
179
  onCompile: Z,
180
- onSaveSettings: je,
181
- onRollback: Ne,
182
- onDeleteSite: Pe,
180
+ onSaveSettings: Me,
181
+ onRollback: Pe,
182
+ onDeleteSite: Fe,
183
183
  rollingBack: R,
184
184
  compileRevision: A,
185
185
  onPollRevision: Q,
186
186
  compiling: M
187
187
  })] }) : /* @__PURE__ */ C(x, { children: [
188
188
  $,
189
- /* @__PURE__ */ S(m, {
189
+ /* @__PURE__ */ S(g, {
190
190
  site: q,
191
191
  pages: J,
192
192
  selectedPageSlug: I,
193
193
  onSelectPage: L,
194
- docsBaseUrl: q.currentRevisionId ? me ?? null : null,
195
- docsHtml: q.currentRevisionId ? fe : null,
196
- docsContentLoading: ue,
194
+ docsBaseUrl: q.currentRevisionId ? he ?? null : null,
195
+ docsHtml: q.currentRevisionId ? pe : null,
196
+ docsContentLoading: de,
197
197
  onEdit: () => k("edit"),
198
198
  onCompile: Z,
199
199
  onSettings: () => k("edit"),
200
- onGetShareUrl: Me,
200
+ onGetShareUrl: Ne,
201
201
  onOpenFullScreen: () => {
202
202
  B(`/${{
203
203
  VIBE: "vibes",
@@ -209,7 +209,7 @@ function w({ vibeId: w, ownerType: se, ownerId: ce }) {
209
209
  onPollRevision: Q,
210
210
  compiling: M
211
211
  }),
212
- /* @__PURE__ */ S(d, {
212
+ /* @__PURE__ */ S(t, {
213
213
  isOpen: V,
214
214
  onClose: () => H(!1),
215
215
  onConfirm: () => {