@cosmicstack/mercury-agent 1.1.6 → 1.1.9

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 (147) hide show
  1. package/README.md +39 -1
  2. package/dist/index.js +14347 -5964
  3. package/dist/index.js.map +1 -1
  4. package/dist/web/static/vendor/geist/Geist-Italic[wght].woff2 +0 -0
  5. package/dist/web/static/vendor/geist/Geist-Variable.woff2 +0 -0
  6. package/dist/web/static/vendor/geist/GeistMono-Italic[wght].woff2 +0 -0
  7. package/dist/web/static/vendor/geist/GeistMono-Variable.woff2 +0 -0
  8. package/dist/web/static/vendor/graphology.min.js +2 -0
  9. package/dist/web/static/vendor/icons.svg +108 -0
  10. package/dist/web/static/vendor/sql-wasm.wasm +0 -0
  11. package/dist/web/ui/assets/Chat-DCFkzIwn.js +28 -0
  12. package/dist/web/ui/assets/Chat-DCFkzIwn.js.map +1 -0
  13. package/dist/web/ui/assets/Dashboard-B81ollv8.js +2 -0
  14. package/dist/web/ui/assets/Dashboard-B81ollv8.js.map +1 -0
  15. package/dist/web/ui/assets/Goals-D0cR8yIP.js +12 -0
  16. package/dist/web/ui/assets/Goals-D0cR8yIP.js.map +1 -0
  17. package/dist/web/ui/assets/Graph-C3eHp3_J.js +7 -0
  18. package/dist/web/ui/assets/Graph-C3eHp3_J.js.map +1 -0
  19. package/dist/web/ui/assets/Kanban-DrkTRyni.js +45 -0
  20. package/dist/web/ui/assets/Kanban-DrkTRyni.js.map +1 -0
  21. package/dist/web/ui/assets/Login-GRQ-LjgN.js +2 -0
  22. package/dist/web/ui/assets/Login-GRQ-LjgN.js.map +1 -0
  23. package/dist/web/ui/assets/MarkdownRenderer-Dvh1jwyj.js +22 -0
  24. package/dist/web/ui/assets/MarkdownRenderer-Dvh1jwyj.js.map +1 -0
  25. package/dist/web/ui/assets/Memory-dAZsKmWz.js +12 -0
  26. package/dist/web/ui/assets/Memory-dAZsKmWz.js.map +1 -0
  27. package/dist/web/ui/assets/Permissions-DCiyUUfI.js +17 -0
  28. package/dist/web/ui/assets/Permissions-DCiyUUfI.js.map +1 -0
  29. package/dist/web/ui/assets/PersonDetail-iZgApJog.js +2 -0
  30. package/dist/web/ui/assets/PersonDetail-iZgApJog.js.map +1 -0
  31. package/dist/web/ui/assets/Persons-Bs_HhYjC.js +2 -0
  32. package/dist/web/ui/assets/Persons-Bs_HhYjC.js.map +1 -0
  33. package/dist/web/ui/assets/Providers-CL6wMWni.js +7 -0
  34. package/dist/web/ui/assets/Providers-CL6wMWni.js.map +1 -0
  35. package/dist/web/ui/assets/Schedules-BQwE1hP5.js +17 -0
  36. package/dist/web/ui/assets/Schedules-BQwE1hP5.js.map +1 -0
  37. package/dist/web/ui/assets/Settings-26SF-okR.js +12 -0
  38. package/dist/web/ui/assets/Settings-26SF-okR.js.map +1 -0
  39. package/dist/web/ui/assets/Skills-DANyYK_d.js +7 -0
  40. package/dist/web/ui/assets/Skills-DANyYK_d.js.map +1 -0
  41. package/dist/web/ui/assets/Tasks-DbwRozzx.js +7 -0
  42. package/dist/web/ui/assets/Tasks-DbwRozzx.js.map +1 -0
  43. package/dist/web/ui/assets/Usage-i_q6Ri4s.js +12 -0
  44. package/dist/web/ui/assets/Usage-i_q6Ri4s.js.map +1 -0
  45. package/dist/web/ui/assets/Workspace-ZR5syf-9.js +52 -0
  46. package/dist/web/ui/assets/Workspace-ZR5syf-9.js.map +1 -0
  47. package/dist/web/ui/assets/activity-CIP1IzSg.js +7 -0
  48. package/dist/web/ui/assets/activity-CIP1IzSg.js.map +1 -0
  49. package/dist/web/ui/assets/alert-dialog-CW-j2nG4.js +7 -0
  50. package/dist/web/ui/assets/alert-dialog-CW-j2nG4.js.map +1 -0
  51. package/dist/web/ui/assets/arrow-left-D2YO-iMS.js +7 -0
  52. package/dist/web/ui/assets/arrow-left-D2YO-iMS.js.map +1 -0
  53. package/dist/web/ui/assets/avatar-BLsf3GhK.js +7 -0
  54. package/dist/web/ui/assets/avatar-BLsf3GhK.js.map +1 -0
  55. package/dist/web/ui/assets/badge-DfDJNUtd.js +2 -0
  56. package/dist/web/ui/assets/badge-DfDJNUtd.js.map +1 -0
  57. package/dist/web/ui/assets/button-TaFPR-zy.js +2 -0
  58. package/dist/web/ui/assets/button-TaFPR-zy.js.map +1 -0
  59. package/dist/web/ui/assets/card-DAYo4Zl5.js +2 -0
  60. package/dist/web/ui/assets/card-DAYo4Zl5.js.map +1 -0
  61. package/dist/web/ui/assets/chevron-down-CQi0yuay.js +12 -0
  62. package/dist/web/ui/assets/chevron-down-CQi0yuay.js.map +1 -0
  63. package/dist/web/ui/assets/circle-check-DweDcOkA.js +7 -0
  64. package/dist/web/ui/assets/circle-check-DweDcOkA.js.map +1 -0
  65. package/dist/web/ui/assets/circle-x-BmL20etA.js +7 -0
  66. package/dist/web/ui/assets/circle-x-BmL20etA.js.map +1 -0
  67. package/dist/web/ui/assets/collapsible-BU_K9n8f.js +2 -0
  68. package/dist/web/ui/assets/collapsible-BU_K9n8f.js.map +1 -0
  69. package/dist/web/ui/assets/dialog-DovgkMhT.js +2 -0
  70. package/dist/web/ui/assets/dialog-DovgkMhT.js.map +1 -0
  71. package/dist/web/ui/assets/download-_QBatDio.js +7 -0
  72. package/dist/web/ui/assets/download-_QBatDio.js.map +1 -0
  73. package/dist/web/ui/assets/eye-Wpgtfmgw.js +7 -0
  74. package/dist/web/ui/assets/eye-Wpgtfmgw.js.map +1 -0
  75. package/dist/web/ui/assets/file-text-2EGFNyc1.js +7 -0
  76. package/dist/web/ui/assets/file-text-2EGFNyc1.js.map +1 -0
  77. package/dist/web/ui/assets/folder-open-C-OiZn9P.js +7 -0
  78. package/dist/web/ui/assets/folder-open-C-OiZn9P.js.map +1 -0
  79. package/dist/web/ui/assets/git-branch-BT9gCKgG.js +7 -0
  80. package/dist/web/ui/assets/git-branch-BT9gCKgG.js.map +1 -0
  81. package/dist/web/ui/assets/index-BhxU0YlT.js +163 -0
  82. package/dist/web/ui/assets/index-BhxU0YlT.js.map +1 -0
  83. package/dist/web/ui/assets/index-CUT6Fr2C.js +2 -0
  84. package/dist/web/ui/assets/index-CUT6Fr2C.js.map +1 -0
  85. package/dist/web/ui/assets/index-DOw1nKre.css +1 -0
  86. package/dist/web/ui/assets/input-L1uz5xAQ.js +2 -0
  87. package/dist/web/ui/assets/input-L1uz5xAQ.js.map +1 -0
  88. package/dist/web/ui/assets/loader-circle-BTFgt3hG.js +7 -0
  89. package/dist/web/ui/assets/loader-circle-BTFgt3hG.js.map +1 -0
  90. package/dist/web/ui/assets/pencil-uxK07iYy.js +7 -0
  91. package/dist/web/ui/assets/pencil-uxK07iYy.js.map +1 -0
  92. package/dist/web/ui/assets/plus-DcWFYr4m.js +7 -0
  93. package/dist/web/ui/assets/plus-DcWFYr4m.js.map +1 -0
  94. package/dist/web/ui/assets/power-DVIqVIMj.js +12 -0
  95. package/dist/web/ui/assets/power-DVIqVIMj.js.map +1 -0
  96. package/dist/web/ui/assets/progress-DMwOdxli.js +2 -0
  97. package/dist/web/ui/assets/progress-DMwOdxli.js.map +1 -0
  98. package/dist/web/ui/assets/search-D1OOxb1X.js +7 -0
  99. package/dist/web/ui/assets/search-D1OOxb1X.js.map +1 -0
  100. package/dist/web/ui/assets/select-Dnx_bUgy.js +2 -0
  101. package/dist/web/ui/assets/select-Dnx_bUgy.js.map +1 -0
  102. package/dist/web/ui/assets/send-D4uxqmyH.js +7 -0
  103. package/dist/web/ui/assets/send-D4uxqmyH.js.map +1 -0
  104. package/dist/web/ui/assets/sparkles-DLSJA4xU.js +7 -0
  105. package/dist/web/ui/assets/sparkles-DLSJA4xU.js.map +1 -0
  106. package/dist/web/ui/assets/switch-CvDDbCUA.js +2 -0
  107. package/dist/web/ui/assets/switch-CvDDbCUA.js.map +1 -0
  108. package/dist/web/ui/assets/terminal-DI3J3W_z.js +7 -0
  109. package/dist/web/ui/assets/terminal-DI3J3W_z.js.map +1 -0
  110. package/dist/web/ui/assets/textarea-CXLsr8tf.js +2 -0
  111. package/dist/web/ui/assets/textarea-CXLsr8tf.js.map +1 -0
  112. package/dist/web/ui/assets/vendor-dnd-DRBSMxXo.js +6 -0
  113. package/dist/web/ui/assets/vendor-dnd-DRBSMxXo.js.map +1 -0
  114. package/dist/web/ui/assets/vendor-markdown-DwTbvico.js +30 -0
  115. package/dist/web/ui/assets/vendor-markdown-DwTbvico.js.map +1 -0
  116. package/dist/web/ui/assets/vendor-motion-Dwx3-JO5.js +18 -0
  117. package/dist/web/ui/assets/vendor-motion-Dwx3-JO5.js.map +1 -0
  118. package/dist/web/ui/assets/vendor-radix-3UdfCgs_.js +65 -0
  119. package/dist/web/ui/assets/vendor-radix-3UdfCgs_.js.map +1 -0
  120. package/dist/web/ui/assets/vendor-react-C7pctHW3.js +44 -0
  121. package/dist/web/ui/assets/vendor-react-C7pctHW3.js.map +1 -0
  122. package/dist/web/ui/assets/vendor-syntax-xZUI6Op9.js +17 -0
  123. package/dist/web/ui/assets/vendor-syntax-xZUI6Op9.js.map +1 -0
  124. package/dist/web/ui/assets/zap-C-0oH5gt.js +7 -0
  125. package/dist/web/ui/assets/zap-C-0oH5gt.js.map +1 -0
  126. package/dist/web/ui/favicon.svg +10 -0
  127. package/dist/web/ui/icons/icon-192.svg +10 -0
  128. package/dist/web/ui/icons/icon-512-maskable.svg +10 -0
  129. package/dist/web/ui/icons/icon-512.svg +10 -0
  130. package/dist/web/ui/index.html +24 -0
  131. package/dist/web/ui/logo-dark.png +0 -0
  132. package/dist/web/ui/logo-full-dark.png +0 -0
  133. package/dist/web/ui/logo-full-light.png +0 -0
  134. package/dist/web/ui/logo-light.png +0 -0
  135. package/dist/web/ui/manifest.webmanifest +1 -0
  136. package/dist/web/ui/registerSW.js +1 -0
  137. package/dist/web/ui/sw.js +11 -0
  138. package/dist/web/ui/sw.js.map +1 -0
  139. package/dist/web/ui/workbox-0bb07689.js +3 -0
  140. package/dist/web/ui/workbox-0bb07689.js.map +1 -0
  141. package/package.json +11 -6
  142. package/src/web/static/vendor/geist/Geist-Italic[wght].woff2 +0 -0
  143. package/src/web/static/vendor/geist/Geist-Variable.woff2 +0 -0
  144. package/src/web/static/vendor/geist/GeistMono-Italic[wght].woff2 +0 -0
  145. package/src/web/static/vendor/geist/GeistMono-Variable.woff2 +0 -0
  146. package/src/web/static/vendor/graphology.min.js +2 -0
  147. package/src/web/static/vendor/icons.svg +108 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Chat-DCFkzIwn.js","sources":["../../node_modules/lucide-react/dist/esm/icons/file.js","../../node_modules/lucide-react/dist/esm/icons/panel-left-close.js","../../node_modules/lucide-react/dist/esm/icons/panel-left-open.js","../../node_modules/lucide-react/dist/esm/icons/wrench.js","../../src/components/chat/ThreadList.tsx","../../src/components/chat/WorkspacePanel.tsx","../../src/components/ui/popover.tsx","../../src/components/chat/ModelSwitcher.tsx","../../src/components/chat/CodeModeToggle.tsx","../../src/components/chat/ToolCallCard.tsx","../../src/components/chat/MessageBubble.tsx","../../src/components/chat/StreamingMessage.tsx","../../src/pages/Chat.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }]\n];\nconst File = createLucideIcon(\"file\", __iconNode);\n\nexport { __iconNode, File as default };\n//# sourceMappingURL=file.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"m16 15-3-3 3-3\", key: \"14y99z\" }]\n];\nconst PanelLeftClose = createLucideIcon(\"panel-left-close\", __iconNode);\n\nexport { __iconNode, PanelLeftClose as default };\n//# sourceMappingURL=panel-left-close.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"m14 9 3 3-3 3\", key: \"8010ee\" }]\n];\nconst PanelLeftOpen = createLucideIcon(\"panel-left-open\", __iconNode);\n\nexport { __iconNode, PanelLeftOpen as default };\n//# sourceMappingURL=panel-left-open.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\",\n key: \"cbrjhi\"\n }\n ]\n];\nconst Wrench = createLucideIcon(\"wrench\", __iconNode);\n\nexport { __iconNode, Wrench as default };\n//# sourceMappingURL=wrench.js.map\n","import { useState } from \"react\";\nimport { Plus, Trash2, Download, MessageSquare } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"@/components/ui/alert-dialog\";\nimport type { ChatThread } from \"@/lib/api\";\n\ninterface ThreadListProps {\n threads: ChatThread[];\n activeThreadId: string | null;\n onSelect: (id: string) => void;\n onDelete: (id: string) => void;\n onNew: () => void;\n onExport: (id: string) => void;\n}\n\nexport function ThreadList({\n threads,\n activeThreadId,\n onSelect,\n onDelete,\n onNew,\n onExport,\n}: ThreadListProps) {\n const [deleteTarget, setDeleteTarget] = useState<string | null>(null);\n\n function formatDate(iso: string): string {\n const d = new Date(iso);\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) {\n return d.toLocaleTimeString(undefined, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n }\n if (diffDays === 1) return \"Yesterday\";\n if (diffDays < 7) return `${diffDays} days ago`;\n return d.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n });\n }\n\n return (\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold text-foreground\">Conversations</h2>\n <Button size=\"sm\" onClick={onNew} className=\"h-7 gap-1 px-2 text-xs\">\n <Plus className=\"h-3.5 w-3.5\" />\n New Chat\n </Button>\n </div>\n\n {/* Thread list */}\n <ScrollArea className=\"flex-1\">\n {threads.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center gap-2 px-4 py-12 text-center\">\n <MessageSquare className=\"h-8 w-8 text-muted-foreground/40\" />\n <p className=\"text-sm text-muted-foreground\">\n No conversations yet\n </p>\n </div>\n ) : (\n <div className=\"p-2\">\n {threads.map((thread) => {\n const isActive = thread.id === activeThreadId;\n return (\n <ThreadItem\n key={thread.id}\n thread={thread}\n isActive={isActive}\n formatDate={formatDate}\n onSelect={() => onSelect(thread.id)}\n onDelete={() => setDeleteTarget(thread.id)}\n onExport={() => onExport(thread.id)}\n />\n );\n })}\n </div>\n )}\n </ScrollArea>\n\n {/* Delete confirmation */}\n <AlertDialog\n open={deleteTarget !== null}\n onOpenChange={(open) => {\n if (!open) setDeleteTarget(null);\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete conversation?</AlertDialogTitle>\n <AlertDialogDescription>\n This will permanently remove this conversation and all its\n messages. This action cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n onClick={() => {\n if (deleteTarget) {\n onDelete(deleteTarget);\n setDeleteTarget(null);\n }\n }}\n >\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n\nfunction ThreadItem({\n thread,\n isActive,\n formatDate,\n onSelect,\n onDelete,\n onExport,\n}: {\n thread: ChatThread;\n isActive: boolean;\n formatDate: (iso: string) => string;\n onSelect: () => void;\n onDelete: () => void;\n onExport: () => void;\n}) {\n return (\n <div\n onClick={onSelect}\n className={cn(\n \"group flex w-full cursor-pointer items-center rounded-lg pl-2 pr-1 py-2 text-left transition-all duration-150\",\n isActive\n ? \"border-l-2 border-l-primary bg-primary/10 text-foreground\"\n : \"border-l-2 border-l-transparent hover:bg-muted/60 text-foreground/80\"\n )}\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-medium leading-snug text-left\">\n {thread.title || \"New conversation\"}\n </div>\n <div className=\"text-xs text-muted-foreground text-left\">\n {formatDate(thread.createdAt)}\n </div>\n </div>\n\n {/* Delete button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n className={cn(\n \"shrink-0 rounded-md p-1 text-red-500 hover:bg-red-500/10 hover:text-red-600 transition-opacity\",\n isActive ? \"opacity-100\" : \"opacity-0 group-hover:opacity-100\"\n )}\n title=\"Delete\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n );\n}\n","import { useState, useCallback } from \"react\";\nimport {\n X,\n Folder,\n File,\n ChevronRight,\n ArrowUp,\n Loader2,\n} from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport api from \"@/lib/api\";\nimport type { WorkspaceTree, WorkspaceFile } from \"@/lib/api\";\nimport { Prism as SyntaxHighlighter } from \"react-syntax-highlighter\";\nimport { oneDark } from \"react-syntax-highlighter/dist/esm/styles/prism\";\n\ninterface WorkspacePanelProps {\n open: boolean;\n onClose: () => void;\n}\n\nconst EXT_LANG_MAP: Record<string, string> = {\n ts: \"typescript\",\n tsx: \"tsx\",\n js: \"javascript\",\n jsx: \"jsx\",\n py: \"python\",\n go: \"go\",\n rs: \"rust\",\n json: \"json\",\n yaml: \"yaml\",\n yml: \"yaml\",\n md: \"markdown\",\n css: \"css\",\n html: \"html\",\n sh: \"bash\",\n bash: \"bash\",\n sql: \"sql\",\n toml: \"toml\",\n xml: \"xml\",\n dockerfile: \"docker\",\n};\n\nfunction getLanguage(ext: string): string {\n return EXT_LANG_MAP[ext.toLowerCase().replace(/^\\./, \"\")] || \"text\";\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport function WorkspacePanel({ open, onClose }: WorkspacePanelProps) {\n const [tree, setTree] = useState<WorkspaceTree | null>(null);\n const [file, setFile] = useState<WorkspaceFile | null>(null);\n const [loading, setLoading] = useState(false);\n const [fileLoading, setFileLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const loadTree = useCallback(async (path?: string) => {\n setLoading(true);\n setError(null);\n setFile(null);\n try {\n const data = await api.workspace.tree(path);\n setTree(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load workspace\");\n } finally {\n setLoading(false);\n }\n }, []);\n\n const loadFile = useCallback(async (path: string) => {\n setFileLoading(true);\n try {\n const data = await api.workspace.file(path);\n setFile(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load file\");\n } finally {\n setFileLoading(false);\n }\n }, []);\n\n // Load tree on first open\n const [initialized, setInitialized] = useState(false);\n if (open && !initialized) {\n setInitialized(true);\n loadTree();\n }\n if (!open && initialized) {\n setInitialized(false);\n }\n\n if (!open) return null;\n\n // Build breadcrumb segments\n const breadcrumbs: { label: string; path: string }[] = [];\n if (tree) {\n const relative = tree.currentPath.replace(tree.root, \"\").replace(/^\\//, \"\");\n if (relative) {\n const parts = relative.split(\"/\");\n let accumulated = \"\";\n for (const part of parts) {\n accumulated = accumulated ? `${accumulated}/${part}` : part;\n breadcrumbs.push({ label: part, path: accumulated });\n }\n }\n }\n\n function navigateUp() {\n if (!tree) return;\n const rel = tree.currentPath.replace(tree.root, \"\").replace(/^\\//, \"\");\n const parts = rel.split(\"/\").filter(Boolean);\n if (parts.length <= 1) {\n loadTree();\n } else {\n parts.pop();\n loadTree(parts.join(\"/\"));\n }\n }\n\n return (\n <div className=\"flex h-full w-full flex-col border-l border-border bg-background\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border px-4 py-3\">\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"text-sm font-semibold text-foreground\">Workspace</h2>\n {tree && (\n <p className=\"truncate text-xs text-muted-foreground\">\n {tree.root}\n </p>\n )}\n </div>\n <Button variant=\"ghost\" size=\"icon\" onClick={onClose} className=\"h-7 w-7 shrink-0\">\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n\n {/* Breadcrumbs */}\n {tree && breadcrumbs.length > 0 && (\n <div className=\"flex items-center gap-1 border-b border-border px-4 py-2 text-xs\">\n <button\n onClick={() => loadTree()}\n className=\"text-primary hover:underline\"\n >\n root\n </button>\n {breadcrumbs.map((bc) => (\n <span key={bc.path} className=\"flex items-center gap-1\">\n <ChevronRight className=\"h-3 w-3 text-muted-foreground\" />\n <button\n onClick={() => loadTree(bc.path)}\n className=\"text-primary hover:underline\"\n >\n {bc.label}\n </button>\n </span>\n ))}\n </div>\n )}\n\n <ScrollArea className=\"flex-1\">\n {loading ? (\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-5 w-5 animate-spin text-primary\" />\n </div>\n ) : error ? (\n <div className=\"px-4 py-8 text-center text-sm text-destructive\">\n {error}\n </div>\n ) : (\n <div className=\"flex flex-col\">\n {/* File tree */}\n {tree && (\n <div className=\"border-b border-border\">\n {/* Up button */}\n {breadcrumbs.length > 0 && (\n <button\n onClick={navigateUp}\n className=\"flex w-full items-center gap-2 px-4 py-2 text-sm text-muted-foreground hover:bg-muted/50 transition-colors\"\n >\n <ArrowUp className=\"h-4 w-4\" />\n <span>..</span>\n </button>\n )}\n\n {tree.items.map((item) => (\n <button\n key={item.name}\n onClick={() => {\n if (item.type === \"directory\") {\n const rel = tree.currentPath\n .replace(tree.root, \"\")\n .replace(/^\\//, \"\");\n const newPath = rel\n ? `${rel}/${item.name}`\n : item.name;\n loadTree(newPath);\n } else {\n const rel = tree.currentPath\n .replace(tree.root, \"\")\n .replace(/^\\//, \"\");\n const filePath = rel\n ? `${rel}/${item.name}`\n : item.name;\n loadFile(filePath);\n }\n }}\n className={cn(\n \"flex w-full items-center gap-2 px-4 py-2 text-sm transition-colors hover:bg-muted/50\",\n item.type === \"directory\"\n ? \"text-foreground\"\n : \"text-foreground/80\"\n )}\n >\n {item.type === \"directory\" ? (\n <Folder className=\"h-4 w-4 shrink-0 text-primary/70\" />\n ) : (\n <File className=\"h-4 w-4 shrink-0 text-muted-foreground\" />\n )}\n <span className=\"truncate\">{item.name}</span>\n {item.size !== undefined && item.type === \"file\" && (\n <span className=\"ml-auto shrink-0 text-xs text-muted-foreground\">\n {formatSize(item.size)}\n </span>\n )}\n </button>\n ))}\n\n {tree.items.length === 0 && (\n <p className=\"px-4 py-6 text-center text-sm text-muted-foreground\">\n Empty directory\n </p>\n )}\n </div>\n )}\n\n {/* File preview */}\n {fileLoading && (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"h-5 w-5 animate-spin text-primary\" />\n </div>\n )}\n\n {file && !fileLoading && (\n <div className=\"flex flex-col\">\n <div className=\"flex items-center justify-between border-b border-border px-4 py-2\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-foreground\">\n {file.name}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {formatSize(file.size)}\n {file.truncated && \" (truncated)\"}\n </p>\n </div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setFile(null)}\n className=\"h-6 text-xs\"\n >\n Close\n </Button>\n </div>\n <div className=\"overflow-auto text-xs\">\n <SyntaxHighlighter\n language={getLanguage(file.ext)}\n style={oneDark}\n customStyle={{\n margin: 0,\n borderRadius: 0,\n fontSize: \"0.75rem\",\n lineHeight: \"1.5\",\n }}\n showLineNumbers\n wrapLongLines\n >\n {file.content}\n </SyntaxHighlighter>\n </div>\n </div>\n )}\n </div>\n )}\n </ScrollArea>\n </div>\n );\n}\n","import * as React from \"react\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { cn } from \"@/lib/utils\";\n\nconst Popover = PopoverPrimitive.Root;\nconst PopoverTrigger = PopoverPrimitive.Trigger;\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\nconst PopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };\n","import { useState, useCallback } from \"react\";\nimport { ChevronDown, Loader2, Check } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { Badge } from \"@/components/ui/badge\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport api from \"@/lib/api\";\nimport type { ModelsResponse } from \"@/lib/api\";\nimport { useChatStore } from \"@/stores/chat\";\n\ninterface ModelSwitcherProps {\n currentProvider: string;\n currentModel: string;\n}\n\nexport function ModelSwitcher({\n currentProvider,\n currentModel,\n}: ModelSwitcherProps) {\n const [open, setOpen] = useState(false);\n const [models, setModels] = useState<ModelsResponse | null>(null);\n const [loading, setLoading] = useState(false);\n const [switching, setSwitching] = useState<string | null>(null);\n\n const setProvider = useChatStore((s) => s.setProvider);\n const setModel = useChatStore((s) => s.setModel);\n\n const loadModels = useCallback(async () => {\n if (models) return;\n setLoading(true);\n try {\n const data = await api.chat.models.list();\n setModels(data);\n } catch {\n // silently fail\n } finally {\n setLoading(false);\n }\n }, [models]);\n\n async function handleSwitch(providerName: string) {\n setSwitching(providerName);\n try {\n await api.chat.models.switch(providerName);\n // Refresh model list to get new current\n const data = await api.chat.models.list();\n setModels(data);\n\n // Find the provider to get the model name\n const p = data.providers.find((pr) => pr.name === providerName);\n if (p) {\n setProvider(p.name);\n setModel(p.model);\n }\n setOpen(false);\n } catch {\n // silently fail\n } finally {\n setSwitching(null);\n }\n }\n\n const displayName =\n currentModel.length > 24\n ? currentModel.slice(0, 22) + \"...\"\n : currentModel || currentProvider || \"Model\";\n\n return (\n <Popover\n open={open}\n onOpenChange={(o) => {\n setOpen(o);\n if (o) loadModels();\n }}\n >\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 gap-1 px-2 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n <span className=\"max-w-[140px] truncate\">{displayName}</span>\n <ChevronDown className=\"h-3 w-3\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-72 p-2\">\n <p className=\"px-2 pb-2 text-xs font-semibold text-muted-foreground uppercase tracking-wider\">\n Providers\n </p>\n\n {loading ? (\n <div className=\"flex items-center justify-center py-4\">\n <Loader2 className=\"h-4 w-4 animate-spin text-primary\" />\n </div>\n ) : models ? (\n <div className=\"flex flex-col gap-0.5\">\n {models.providers.map((p) => {\n const isActive = p.name === currentProvider;\n const isSwitching = switching === p.name;\n return (\n <button\n key={p.name}\n disabled={!p.available || isSwitching}\n onClick={() => {\n if (!isActive && p.available) handleSwitch(p.name);\n }}\n className={cn(\n \"flex items-center gap-2 rounded-md px-2 py-2 text-left text-sm transition-colors\",\n p.available\n ? \"hover:bg-muted/60\"\n : \"cursor-not-allowed opacity-40\",\n isActive && \"bg-primary/10\"\n )}\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"font-medium text-foreground\">\n {p.name}\n </span>\n {isActive && (\n <Check className=\"h-3.5 w-3.5 text-primary\" />\n )}\n </div>\n <p className=\"truncate text-xs text-muted-foreground\">\n {p.model}\n </p>\n </div>\n {isSwitching ? (\n <Loader2 className=\"h-3.5 w-3.5 shrink-0 animate-spin text-primary\" />\n ) : (\n <Badge\n variant={p.available ? \"success\" : \"secondary\"}\n className=\"shrink-0 text-[10px] px-1.5 py-0\"\n >\n {p.available ? \"Ready\" : \"Unavailable\"}\n </Badge>\n )}\n </button>\n );\n })}\n </div>\n ) : (\n <p className=\"px-2 py-4 text-center text-sm text-muted-foreground\">\n No providers found\n </p>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport api from \"@/lib/api\";\nimport type { CodeStatus } from \"@/lib/api\";\n\ntype CodeState = \"off\" | \"plan\" | \"execute\";\n\nconst STATES: { value: CodeState; label: string }[] = [\n { value: \"off\", label: \"Off\" },\n { value: \"plan\", label: \"Plan\" },\n { value: \"execute\", label: \"Exec\" },\n];\n\nexport function CodeModeToggle() {\n const [status, setStatus] = useState<CodeStatus | null>(null);\n const [switching, setSwitching] = useState(false);\n\n const loadStatus = useCallback(async () => {\n try {\n const data = await api.code.status();\n setStatus(data);\n } catch {\n // not available\n }\n }, []);\n\n useEffect(() => {\n loadStatus();\n }, [loadStatus]);\n\n async function handleSet(state: CodeState) {\n if (!status || switching || state === status.state) return;\n setSwitching(true);\n try {\n const result = await api.code.set(state);\n setStatus((prev) =>\n prev\n ? {\n ...prev,\n state: result.state as CodeState,\n active: result.active,\n }\n : prev\n );\n } catch {\n // silently fail\n } finally {\n setSwitching(false);\n }\n }\n\n if (!status?.available) return null;\n\n return (\n <div className=\"flex items-center rounded-lg border border-border bg-muted/40 p-0.5\">\n {STATES.map((s) => {\n const isActive = status.state === s.value;\n return (\n <button\n key={s.value}\n disabled={switching}\n onClick={() => handleSet(s.value)}\n className={cn(\n \"rounded-md px-2.5 py-1 text-xs font-medium transition-all duration-150\",\n isActive\n ? s.value === \"plan\"\n ? \"bg-amber-500/15 text-amber-600 dark:text-amber-400 shadow-sm\"\n : s.value === \"execute\"\n ? \"bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 shadow-sm\"\n : \"bg-background text-muted-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\"\n )}\n >\n {s.label}\n </button>\n );\n })}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Wrench, Loader2, CheckCircle2, XCircle, ChevronRight } from \"lucide-react\";\nimport {\n Collapsible,\n CollapsibleTrigger,\n CollapsibleContent,\n} from \"@/components/ui/collapsible\";\nimport { cn } from \"@/lib/utils\";\n\ninterface ToolCallCardProps {\n tool: string;\n status: \"running\" | \"done\" | \"error\";\n result?: string;\n}\n\nconst statusConfig = {\n running: {\n icon: Loader2,\n label: \"Running...\",\n color: \"text-mercury-500\",\n border: \"border-l-mercury-500\",\n iconClass: \"animate-spin\",\n },\n done: {\n icon: CheckCircle2,\n label: \"Complete\",\n color: \"text-emerald-500\",\n border: \"border-l-emerald-500\",\n iconClass: \"\",\n },\n error: {\n icon: XCircle,\n label: \"Failed\",\n color: \"text-red-500\",\n border: \"border-l-red-500\",\n iconClass: \"\",\n },\n} as const;\n\nexport function ToolCallCard({ tool, status, result }: ToolCallCardProps) {\n const [open, setOpen] = useState(false);\n const config = statusConfig[status];\n const StatusIcon = config.icon;\n\n return (\n <Collapsible open={open} onOpenChange={setOpen}>\n <div\n className={cn(\n \"my-1.5 overflow-hidden rounded-md border border-border/60 border-l-2 bg-muted/30\",\n config.border\n )}\n >\n <CollapsibleTrigger className=\"flex w-full items-center gap-2 px-3 py-2 text-xs transition-colors hover:bg-muted/50\">\n <ChevronRight\n className={cn(\n \"h-3 w-3 text-muted-foreground transition-transform\",\n open && \"rotate-90\"\n )}\n />\n <Wrench className=\"h-3 w-3 text-muted-foreground\" />\n <span className=\"font-medium\">{tool}</span>\n <div className=\"ml-auto flex items-center gap-1.5\">\n <StatusIcon\n className={cn(\"h-3.5 w-3.5\", config.color, config.iconClass)}\n />\n <span className={cn(\"text-[0.6875rem]\", config.color)}>\n {config.label}\n </span>\n </div>\n </CollapsibleTrigger>\n\n <CollapsibleContent>\n {result && (\n <div className=\"max-h-40 overflow-auto border-t border-border/40 bg-background/50 px-3 py-2\">\n <pre className=\"whitespace-pre-wrap font-mono text-[0.75rem] leading-relaxed text-muted-foreground\">\n {result}\n </pre>\n </div>\n )}\n </CollapsibleContent>\n </div>\n </Collapsible>\n );\n}\n","import { useState, useCallback } from \"react\";\nimport { motion } from \"framer-motion\";\nimport { Copy, Check } from \"lucide-react\";\nimport type { ChatMessage } from \"@/lib/api\";\nimport { cn, formatDate } from \"@/lib/utils\";\nimport { useThemeStore } from \"@/stores/theme\";\nimport { MarkdownRenderer } from \"./MarkdownRenderer\";\nimport { ToolCallCard } from \"./ToolCallCard\";\n\ninterface MessageBubbleProps {\n message: ChatMessage;\n isLast?: boolean;\n}\n\nexport function MessageBubble({ message, isLast }: MessageBubbleProps) {\n const [copied, setCopied] = useState(false);\n const isUser = message.role === \"user\";\n const resolved = useThemeStore((s) => s.resolved);\n\n const handleCopy = useCallback(() => {\n navigator.clipboard.writeText(message.content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }, [message.content]);\n\n return (\n <motion.div\n initial={{ opacity: 0, y: 6 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.25, ease: \"easeOut\" }}\n className={cn(\n \"group flex gap-3\",\n isUser ? \"flex-row-reverse\" : \"flex-row\"\n )}\n >\n {/* Avatar */}\n <div\n className={cn(\n \"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full text-xs font-semibold\",\n isUser\n ? \"bg-primary text-primary-foreground\"\n : \"bg-card\"\n )}\n >\n {isUser ? (\n \"U\"\n ) : (\n <img\n src={resolved === \"dark\" ? \"/logo-dark.png\" : \"/logo-light.png\"}\n alt=\"Mercury\"\n className=\"h-full w-full object-contain\"\n />\n )}\n </div>\n\n {/* Content column */}\n <div\n className={cn(\n \"relative max-w-[80%] space-y-1\",\n isUser ? \"items-end\" : \"items-start\"\n )}\n >\n {/* Tool steps */}\n {message.steps?.map((step, i) => (\n <ToolCallCard\n key={`${message.id}-step-${i}`}\n tool={step.tool}\n status={step.status}\n result={step.result}\n />\n ))}\n\n {/* Bubble */}\n <div\n className={cn(\n \"relative rounded-2xl px-4 py-2.5\",\n isUser\n ? \"rounded-br-sm bg-mercury-500 text-white\"\n : \"rounded-bl-sm border border-border/60 bg-card text-card-foreground\"\n )}\n >\n {isUser ? (\n <p className=\"whitespace-pre-wrap text-sm leading-relaxed\">\n {message.content}\n </p>\n ) : (\n <MarkdownRenderer content={message.content} />\n )}\n\n {/* Hover actions */}\n <div\n className={cn(\n \"absolute -top-3 flex items-center gap-1 rounded-md border border-border bg-popover px-1 py-0.5 opacity-0 shadow-sm transition-opacity group-hover:opacity-100\",\n isUser ? \"right-0\" : \"left-0\"\n )}\n >\n <button\n onClick={handleCopy}\n className=\"rounded p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n {copied ? (\n <Check className=\"h-3 w-3 text-emerald-500\" />\n ) : (\n <Copy className=\"h-3 w-3\" />\n )}\n </button>\n </div>\n </div>\n\n {/* Timestamp */}\n <p\n className={cn(\n \"px-1 text-[0.6875rem] text-muted-foreground\",\n isUser ? \"text-right\" : \"text-left\"\n )}\n >\n {formatDate(message.timestamp)}\n </p>\n </div>\n </motion.div>\n );\n}\n","import { MarkdownRenderer } from \"./MarkdownRenderer\";\nimport { ToolCallCard } from \"./ToolCallCard\";\nimport { useThemeStore } from \"@/stores/theme\";\n\ninterface StreamingMessageProps {\n text: string;\n steps?: { tool: string; status: string }[];\n}\n\nexport function StreamingMessage({ text, steps }: StreamingMessageProps) {\n const isThinking = !text;\n const resolved = useThemeStore((s) => s.resolved);\n\n return (\n <div className=\"flex gap-3\">\n {/* Avatar */}\n <div className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full bg-card\">\n <img\n src={resolved === \"dark\" ? \"/logo-dark.png\" : \"/logo-light.png\"}\n alt=\"Mercury\"\n className=\"h-full w-full object-contain\"\n />\n </div>\n\n {/* Content */}\n <div className=\"max-w-[80%] space-y-1\">\n {/* Tool steps */}\n {steps?.map((step, i) => (\n <ToolCallCard\n key={`stream-step-${i}`}\n tool={step.tool}\n status={step.status as \"running\" | \"done\" | \"error\"}\n />\n ))}\n\n {/* Bubble */}\n <div className=\"rounded-2xl rounded-bl-sm border border-border/60 bg-card px-4 py-2.5 text-card-foreground\">\n {isThinking ? (\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground\">\n <span>Thinking</span>\n <span className=\"inline-flex w-5\">\n <span className=\"animate-pulse\">...</span>\n </span>\n </div>\n ) : (\n <div className=\"inline\">\n <MarkdownRenderer content={text} />\n <span className=\"ml-0.5 inline-block h-4 w-[3px] translate-y-[2px] rounded-sm bg-mercury-500 animate-cursor-blink\" />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useEffect, useRef, useCallback } from \"react\";\nimport { useParams, useNavigate } from \"react-router-dom\";\nimport {\n PanelLeftClose,\n PanelLeftOpen,\n FolderOpen,\n Settings,\n ArrowDown,\n Send,\n Loader2,\n MessageSquare,\n Check,\n X,\n Zap,\n} from \"lucide-react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport { Progress } from \"@/components/ui/progress\";\nimport { useChatStore } from \"@/stores/chat\";\nimport { useSSE } from \"@/hooks/useSSE\";\nimport api from \"@/lib/api\";\nimport type { ChatMessage, ChatThread } from \"@/lib/api\";\n\nimport { ThreadList } from \"@/components/chat/ThreadList\";\nimport { WorkspacePanel } from \"@/components/chat/WorkspacePanel\";\nimport { ModelSwitcher } from \"@/components/chat/ModelSwitcher\";\nimport { CodeModeToggle } from \"@/components/chat/CodeModeToggle\";\nimport { MessageBubble as MessageBubbleComponent } from \"@/components/chat/MessageBubble\";\nimport { StreamingMessage } from \"@/components/chat/StreamingMessage\";\n\n// ─── Hooks ───────────────────────────────────────────────────\n\nfunction useThreads() {\n const setThreads = useChatStore((s) => s.setThreads);\n const threads = useChatStore((s) => s.threads);\n const threadVersion = useChatStore((s) => s.threadVersion);\n const [loading, setLoading] = useState(true);\n\n const load = useCallback(async () => {\n try {\n const data = await api.chat.threads.list();\n setThreads(data.threads);\n } catch {\n // ignore\n } finally {\n setLoading(false);\n }\n }, [setThreads]);\n\n useEffect(() => {\n load();\n }, [load, threadVersion]);\n\n return { threads, loading, reload: load };\n}\n\nfunction useAutoScroll(deps: unknown[]) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [atBottom, setAtBottom] = useState(true);\n const userScrolledUp = useRef(false);\n\n const scrollToBottom = useCallback(() => {\n const el = containerRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n userScrolledUp.current = false;\n setAtBottom(true);\n }\n }, []);\n\n useEffect(() => {\n if (!userScrolledUp.current) {\n scrollToBottom();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n const handleScroll = useCallback(() => {\n const el = containerRef.current;\n if (!el) return;\n const threshold = 80;\n const isAtBottom =\n el.scrollHeight - el.scrollTop - el.clientHeight < threshold;\n setAtBottom(isAtBottom);\n if (!isAtBottom) {\n userScrolledUp.current = true;\n } else {\n userScrolledUp.current = false;\n }\n }, []);\n\n return { containerRef, atBottom, scrollToBottom, handleScroll };\n}\n\n// ─── Sub-components ──────────────────────────────────────────\n\nfunction WaitingIndicator() {\n return (\n <div className=\"flex w-full justify-start\">\n <div className=\"flex items-center gap-2 rounded-2xl bg-muted px-4 py-3 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin text-primary\" />\n Thinking...\n </div>\n </div>\n );\n}\n\nfunction PermissionPrompt({\n data,\n}: {\n data: { id: string; tool?: string; description?: string };\n}) {\n const [resolving, setResolving] = useState(false);\n\n async function handle(action: string) {\n setResolving(true);\n try {\n await api.chat.permission(data.id, action);\n } catch {\n // ignore\n } finally {\n setResolving(false);\n }\n }\n\n return (\n <div className=\"flex w-full justify-start\">\n <div className=\"max-w-[85%] rounded-2xl border border-amber-500/30 bg-amber-500/5 px-4 py-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium text-amber-600 dark:text-amber-400\">\n <Zap className=\"h-4 w-4\" />\n Permission Required\n </div>\n {data.tool && (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n Tool: <span className=\"font-medium text-foreground\">{data.tool}</span>\n </p>\n )}\n {data.description && (\n <p className=\"mt-1 text-sm text-foreground\">{data.description}</p>\n )}\n <div className=\"mt-3 flex items-center gap-2\">\n <Button\n size=\"sm\"\n className=\"h-7 gap-1 text-xs\"\n disabled={resolving}\n onClick={() => handle(\"allow\")}\n >\n {resolving ? (\n <Loader2 className=\"h-3 w-3 animate-spin\" />\n ) : (\n <Check className=\"h-3 w-3\" />\n )}\n Allow\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-7 gap-1 text-xs\"\n disabled={resolving}\n onClick={() => handle(\"deny\")}\n >\n <X className=\"h-3 w-3\" />\n Deny\n </Button>\n </div>\n </div>\n </div>\n );\n}\n\n// ─── Slash Commands ──────────────────────────────────────────\n\ninterface SlashCommand {\n command: string;\n description: string;\n category: string;\n}\n\nconst SLASH_COMMANDS: SlashCommand[] = [\n { command: \"/help\", description: \"Show all available commands\", category: \"General\" },\n { command: \"/progress\", description: \"Show current task progress\", category: \"General\" },\n { command: \"/halt\", description: \"Stop all sub-agents\", category: \"General\" },\n { command: \"/stop\", description: \"Stop all agents and clear tasks\", category: \"General\" },\n { command: \"/agents\", description: \"List active sub-agents and status\", category: \"Agents\" },\n { command: \"/agents kill\", description: \"Kill a specific sub-agent\", category: \"Agents\" },\n { command: \"/bg\", description: \"Run a shell command in background\", category: \"Background\" },\n { command: \"/bg:\", description: \"Delegate an LLM task to background\", category: \"Background\" },\n { command: \"/bg list\", description: \"Show all background tasks\", category: \"Background\" },\n { command: \"/bg current\", description: \"Move active task to background\", category: \"Background\" },\n { command: \"/bg stop\", description: \"Stop a background task\", category: \"Background\" },\n { command: \"/bg killall\", description: \"Stop all background tasks\", category: \"Background\" },\n { command: \"/bg clear\", description: \"Prune completed background tasks\", category: \"Background\" },\n { command: \"/models\", description: \"List available models\", category: \"Models\" },\n { command: \"/models use\", description: \"Switch to a different model\", category: \"Models\" },\n { command: \"/code\", description: \"Toggle programming mode\", category: \"Code\" },\n { command: \"/code plan\", description: \"Set plan-only mode\", category: \"Code\" },\n { command: \"/code execute\", description: \"Set execute mode\", category: \"Code\" },\n { command: \"/code off\", description: \"Disable programming mode\", category: \"Code\" },\n { command: \"/spotify\", description: \"Spotify status and controls\", category: \"Spotify\" },\n { command: \"/spotify play\", description: \"Play or search for music\", category: \"Spotify\" },\n { command: \"/spotify pause\", description: \"Pause playback\", category: \"Spotify\" },\n { command: \"/spotify next\", description: \"Skip to next track\", category: \"Spotify\" },\n { command: \"/spotify prev\", description: \"Previous track\", category: \"Spotify\" },\n { command: \"/spotify queue\", description: \"Show play queue\", category: \"Spotify\" },\n { command: \"/budget\", description: \"Show token budget status\", category: \"Budget\" },\n { command: \"/budget override\", description: \"Override budget for next request\", category: \"Budget\" },\n { command: \"/budget reset\", description: \"Reset daily usage counter\", category: \"Budget\" },\n { command: \"/budget set\", description: \"Set new daily budget limit\", category: \"Budget\" },\n { command: \"/memory\", description: \"Manage second-brain memory\", category: \"Memory\" },\n { command: \"/permissions\", description: \"Toggle permission mode\", category: \"General\" },\n { command: \"/ws\", description: \"Workspace file operations\", category: \"Workspace\" },\n { command: \"/exit\", description: \"Shutdown Mercury\", category: \"General\" },\n];\n\nfunction SlashCommandMenu({\n filter,\n selectedIndex,\n onSelect,\n}: {\n filter: string;\n selectedIndex: number;\n onSelect: (cmd: string) => void;\n}) {\n const filtered = SLASH_COMMANDS.filter((c) =>\n c.command.startsWith(filter.toLowerCase())\n );\n\n if (filtered.length === 0) return null;\n\n return (\n <motion.div\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 8 }}\n transition={{ duration: 0.15 }}\n className=\"absolute bottom-full left-0 right-0 mb-2 max-h-64 overflow-y-auto rounded-xl border border-border bg-popover shadow-xl\"\n >\n <div className=\"p-1\">\n {filtered.map((cmd, i) => (\n <button\n key={cmd.command}\n onMouseDown={(e) => {\n e.preventDefault();\n onSelect(cmd.command);\n }}\n className={cn(\n \"flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors\",\n i === selectedIndex\n ? \"bg-primary/10 text-primary\"\n : \"text-foreground hover:bg-muted\"\n )}\n >\n <span className=\"font-mono font-medium text-xs shrink-0\">\n {cmd.command}\n </span>\n <span className=\"text-muted-foreground text-xs truncate\">\n {cmd.description}\n </span>\n <span className=\"ml-auto text-[10px] text-muted-foreground/60 shrink-0\">\n {cmd.category}\n </span>\n </button>\n ))}\n </div>\n </motion.div>\n );\n}\n\nfunction ChatInput({\n onSend,\n disabled,\n}: {\n onSend: (text: string) => void;\n disabled: boolean;\n}) {\n const [text, setText] = useState(\"\");\n const [showSlash, setShowSlash] = useState(false);\n const [slashIndex, setSlashIndex] = useState(0);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n // Compute filtered commands for index bounds\n const slashFilter = showSlash ? text.split(\"\\n\")[0] : \"\";\n const filteredCommands = SLASH_COMMANDS.filter((c) =>\n c.command.startsWith(slashFilter.toLowerCase())\n );\n\n function handleSubmit() {\n const trimmed = text.trim();\n if (!trimmed || disabled) return;\n setShowSlash(false);\n onSend(trimmed);\n setText(\"\");\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n }\n }\n\n function selectSlashCommand(cmd: string) {\n // If the command typically takes arguments, add a trailing space\n const needsArg = [\"/bg\", \"/bg:\", \"/bg stop\", \"/models use\", \"/agents kill\", \"/spotify play\", \"/budget set\"].includes(cmd);\n setText(needsArg ? cmd + \" \" : cmd);\n setShowSlash(false);\n setSlashIndex(0);\n textareaRef.current?.focus();\n }\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (showSlash && filteredCommands.length > 0) {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setSlashIndex((prev) => Math.min(prev + 1, filteredCommands.length - 1));\n return;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setSlashIndex((prev) => Math.max(prev - 1, 0));\n return;\n }\n if (e.key === \"Tab\" || (e.key === \"Enter\" && !e.shiftKey)) {\n e.preventDefault();\n selectSlashCommand(filteredCommands[slashIndex].command);\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n setShowSlash(false);\n return;\n }\n }\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n }\n\n function handleChange(value: string) {\n setText(value);\n\n // Show slash menu when text starts with / and is a single line of just the command\n const firstLine = value.split(\"\\n\")[0];\n if (firstLine.startsWith(\"/\") && !firstLine.includes(\" \")) {\n setShowSlash(true);\n setSlashIndex(0);\n } else if (firstLine.startsWith(\"/\") && firstLine.split(\" \").length <= 2) {\n // Allow filtering for two-word commands like \"/bg list\"\n setShowSlash(true);\n setSlashIndex(0);\n } else {\n setShowSlash(false);\n }\n }\n\n function handleInput() {\n const el = textareaRef.current;\n if (el) {\n el.style.height = \"auto\";\n el.style.height = Math.min(el.scrollHeight, 200) + \"px\";\n }\n }\n\n return (\n <div className=\"border-t border-border bg-background/80 backdrop-blur-xl px-4 py-3\">\n <div className=\"mx-auto flex max-w-3xl items-end gap-2\">\n <div className=\"relative flex-1\">\n <AnimatePresence>\n {showSlash && filteredCommands.length > 0 && (\n <SlashCommandMenu\n filter={slashFilter}\n selectedIndex={slashIndex}\n onSelect={selectSlashCommand}\n />\n )}\n </AnimatePresence>\n <textarea\n ref={textareaRef}\n value={text}\n onChange={(e) => {\n handleChange(e.target.value);\n handleInput();\n }}\n onKeyDown={handleKeyDown}\n onBlur={() => {\n // Delay to allow click on menu item\n setTimeout(() => setShowSlash(false), 200);\n }}\n placeholder=\"Send a message... (type / for commands)\"\n rows={1}\n className={cn(\n \"w-full resize-none rounded-xl border border-border bg-muted/40 px-4 py-3 pr-12 text-sm text-foreground placeholder:text-muted-foreground\",\n \"focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary/40\",\n \"transition-all duration-150\"\n )}\n style={{ maxHeight: 200 }}\n />\n </div>\n <Button\n size=\"icon\"\n disabled={disabled || !text.trim()}\n onClick={handleSubmit}\n className=\"h-10 w-10 shrink-0 rounded-xl\"\n >\n <Send className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n\n// ─── Main Page ───────────────────────────────────────────────\n\nexport function ChatPage() {\n const { threadId: urlThreadId } = useParams<{ threadId?: string }>();\n const navigate = useNavigate();\n const { connected } = useSSE();\n const { threads, loading: threadsLoading, reload: reloadThreads } = useThreads();\n\n // Store state\n const messages = useChatStore((s) => s.messages);\n const streamingText = useChatStore((s) => s.streamingText);\n const isStreaming = useChatStore((s) => s.isStreaming);\n const waiting = useChatStore((s) => s.waiting);\n const activeThreadId = useChatStore((s) => s.activeThreadId);\n const provider = useChatStore((s) => s.provider);\n const model = useChatStore((s) => s.model);\n const totalSteps = useChatStore((s) => s.totalSteps);\n const completedSteps = useChatStore((s) => s.completedSteps);\n const currentStepTool = useChatStore((s) => s.currentStepTool);\n const setActiveThread = useChatStore((s) => s.setActiveThread);\n const addMessage = useChatStore((s) => s.addMessage);\n const clearMessages = useChatStore((s) => s.clearMessages);\n const setWaiting = useChatStore((s) => s.setWaiting);\n const clearStreaming = useChatStore((s) => s.clearStreaming);\n const resetSteps = useChatStore((s) => s.resetSteps);\n const bumpThreadVersion = useChatStore((s) => s.bumpThreadVersion);\n\n // Sync URL param → active thread\n useEffect(() => {\n if (urlThreadId && urlThreadId !== activeThreadId) {\n setActiveThread(urlThreadId);\n }\n }, [urlThreadId]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Panel state\n const [sidebarOpen, setSidebarOpen] = useState(true);\n const [workspaceOpen, setWorkspaceOpen] = useState(false);\n\n // Auto-scroll\n const { containerRef, atBottom, scrollToBottom, handleScroll } =\n useAutoScroll([messages, streamingText, waiting]);\n\n // Load thread messages when switching\n useEffect(() => {\n if (!activeThreadId) {\n clearMessages();\n return;\n }\n (async () => {\n try {\n const thread = await api.chat.threads.get(activeThreadId);\n clearMessages();\n if (thread.messages && thread.messages.length > 0) {\n thread.messages.forEach((m) => addMessage(m));\n }\n } catch {\n // Thread doesn't exist yet (new thread) — just clear\n clearMessages();\n }\n })();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeThreadId]);\n\n async function handleSend(content: string) {\n // Ensure we have a thread ID — create one if needed\n let threadId = activeThreadId;\n if (!threadId) {\n threadId = `web:${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n setActiveThread(threadId);\n }\n\n // Optimistic user message\n addMessage({\n id: crypto.randomUUID(),\n role: \"user\",\n content,\n timestamp: new Date().toISOString(),\n });\n\n // Immediately show waiting state\n setWaiting(true);\n\n // Persist user message to backend thread\n api.chat.threads.addMessage(threadId, \"user\", content)\n .then(() => bumpThreadVersion())\n .catch(() => {});\n\n try {\n await api.chat.send(content, threadId);\n // Reload threads in background to pick up new thread\n reloadThreads();\n } catch {\n setWaiting(false);\n clearStreaming();\n resetSteps();\n addMessage({\n id: crypto.randomUUID(),\n role: \"system\",\n content: \"Failed to send message. Please try again.\",\n timestamp: new Date().toISOString(),\n });\n }\n }\n\n async function handleDeleteThread(id: string) {\n try {\n await api.chat.threads.delete(id);\n if (activeThreadId === id) {\n setActiveThread(null);\n clearMessages();\n }\n reloadThreads();\n } catch {\n // ignore\n }\n }\n\n function handleNewThread() {\n const newId = `web:${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n setActiveThread(newId);\n clearMessages();\n reloadThreads();\n navigate(`/chat/${newId}`);\n }\n\n function handleSelectThread(id: string) {\n setActiveThread(id);\n navigate(`/chat/${id}`);\n }\n\n function handleExportThread(id: string) {\n const thread = threads.find((t) => t.id === id);\n if (!thread) return;\n const content = thread.messages\n .map((m) => `[${m.role}] ${m.content}`)\n .join(\"\\n\\n---\\n\\n\");\n const blob = new Blob([content], { type: \"text/plain\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `${thread.title || \"conversation\"}-${id.slice(0, 8)}.txt`;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n const isBusy = isStreaming || waiting;\n const hasSteps = totalSteps > 0;\n const stepProgress =\n totalSteps > 0 ? (completedSteps / totalSteps) * 100 : 0;\n\n return (\n <div className=\"flex h-full w-full overflow-hidden\">\n {/* ── Thread Sidebar (desktop) ── */}\n <div\n className={cn(\n \"hidden h-full shrink-0 border-r border-border bg-background transition-[width] duration-200 ease-in-out md:block overflow-hidden\",\n sidebarOpen ? \"w-[240px]\" : \"w-0 border-r-0\"\n )}\n >\n <div className=\"h-full w-[240px]\">\n <ThreadList\n threads={threads}\n activeThreadId={activeThreadId}\n onSelect={handleSelectThread}\n onDelete={handleDeleteThread}\n onNew={handleNewThread}\n onExport={handleExportThread}\n />\n </div>\n </div>\n\n {/* ── Mobile sidebar overlay ── */}\n <AnimatePresence>\n {sidebarOpen && (\n <>\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"fixed inset-0 z-40 bg-black/50 backdrop-blur-sm md:hidden\"\n onClick={() => setSidebarOpen(false)}\n />\n <motion.div\n initial={{ x: -260 }}\n animate={{ x: 0 }}\n exit={{ x: -260 }}\n transition={{ duration: 0.2, ease: \"easeInOut\" }}\n className=\"fixed inset-y-0 left-0 z-50 w-[260px] bg-background shadow-xl md:hidden\"\n >\n <ThreadList\n threads={threads}\n activeThreadId={activeThreadId}\n onSelect={(id) => {\n handleSelectThread(id);\n setSidebarOpen(false);\n }}\n onDelete={handleDeleteThread}\n onNew={() => {\n handleNewThread();\n setSidebarOpen(false);\n }}\n onExport={handleExportThread}\n />\n </motion.div>\n </>\n )}\n </AnimatePresence>\n\n {/* ── Main Chat Area ── */}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {/* Header */}\n <header className=\"flex h-12 items-center gap-2 border-b border-border bg-background/80 backdrop-blur-xl px-3\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setSidebarOpen(!sidebarOpen)}\n >\n {sidebarOpen ? (\n <PanelLeftClose className=\"h-4 w-4\" />\n ) : (\n <PanelLeftOpen className=\"h-4 w-4\" />\n )}\n </Button>\n\n {/* Logo */}\n <span className=\"hidden text-sm font-bold mercury-gradient-text sm:inline\">\n Mercury\n </span>\n\n <div className=\"mx-1 h-4 w-px bg-border\" />\n\n <ModelSwitcher currentProvider={provider} currentModel={model} />\n\n <div className=\"flex-1\" />\n\n <CodeModeToggle />\n\n {/* Connection indicator */}\n <div\n className={cn(\n \"h-2 w-2 rounded-full\",\n connected ? \"bg-emerald-500\" : \"bg-destructive\"\n )}\n title={connected ? \"Connected\" : \"Disconnected\"}\n />\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setWorkspaceOpen(!workspaceOpen)}\n >\n <FolderOpen className=\"h-4 w-4\" />\n </Button>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 hidden md:inline-flex\"\n onClick={() => (window.location.href = \"/settings\")}\n >\n <Settings className=\"h-4 w-4\" />\n </Button>\n </header>\n\n {/* Messages */}\n <div className=\"relative flex-1 min-h-0\">\n <div\n ref={containerRef}\n onScroll={handleScroll}\n className=\"h-full overflow-y-auto\"\n >\n <div className=\"mx-auto max-w-3xl space-y-4 px-4 py-6\">\n {threadsLoading && messages.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-24\">\n <Loader2 className=\"h-6 w-6 animate-spin text-primary\" />\n </div>\n ) : messages.length === 0 && !isStreaming && !waiting ? (\n <div className=\"flex flex-col items-center justify-center gap-3 py-24 text-center\">\n <div className=\"rounded-2xl bg-primary/10 p-4\">\n <MessageSquare className=\"h-8 w-8 text-primary\" />\n </div>\n <h3 className=\"text-lg font-semibold text-foreground\">\n Start a conversation\n </h3>\n <p className=\"max-w-sm text-sm text-muted-foreground\">\n Send a message to begin. Mercury is ready to assist you.\n </p>\n </div>\n ) : (\n <>\n {messages.map((msg) => {\n // Permission prompt detection for system messages\n if (msg.role === \"system\") {\n try {\n const parsed = JSON.parse(msg.content);\n if (parsed.id && (parsed.tool || parsed.description)) {\n return <PermissionPrompt key={msg.id} data={parsed} />;\n }\n } catch {\n // not a permission prompt, render as regular message\n }\n }\n return <MessageBubbleComponent key={msg.id} message={msg} />;\n })}\n {isStreaming && streamingText && (\n <StreamingMessage text={streamingText} />\n )}\n {waiting && !isStreaming && <WaitingIndicator />}\n </>\n )}\n </div>\n </div>\n\n {/* Scroll-to-bottom */}\n <AnimatePresence>\n {!atBottom && (\n <motion.div\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 10 }}\n className=\"absolute bottom-4 right-4\"\n >\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"h-9 w-9 rounded-full shadow-lg border-border bg-background/90 backdrop-blur-sm\"\n onClick={scrollToBottom}\n >\n <ArrowDown className=\"h-4 w-4\" />\n </Button>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n\n {/* Step progress */}\n {hasSteps && (\n <div className=\"px-4 py-1.5\">\n <div className=\"mx-auto max-w-3xl\">\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground mb-1\">\n <Loader2 className=\"h-3 w-3 animate-spin text-primary\" />\n <span>\n Step {completedSteps} of {totalSteps}\n {currentStepTool && (\n <span className=\"ml-1 text-foreground font-medium\">\n — {currentStepTool}\n </span>\n )}\n </span>\n </div>\n <Progress value={stepProgress} className=\"h-1\" />\n </div>\n </div>\n )}\n\n {/* Chat input */}\n <ChatInput onSend={handleSend} disabled={isBusy} />\n </div>\n\n {/* ── Workspace Panel ── */}\n <AnimatePresence mode=\"wait\">\n {workspaceOpen && (\n <motion.div\n initial={{ width: 0, opacity: 0 }}\n animate={{ width: 320, opacity: 1 }}\n exit={{ width: 0, opacity: 0 }}\n transition={{ duration: 0.2, ease: \"easeInOut\" }}\n className=\"hidden h-full shrink-0 overflow-hidden md:block\"\n >\n <div className=\"h-full w-[320px]\">\n <WorkspacePanel\n open={workspaceOpen}\n onClose={() => setWorkspaceOpen(false)}\n />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n"],"names":["__iconNode","File","createLucideIcon","PanelLeftClose","PanelLeftOpen","Wrench","ThreadList","threads","activeThreadId","onSelect","onDelete","onNew","onExport","deleteTarget","setDeleteTarget","useState","formatDate","iso","d","diffMs","diffDays","jsxs","jsx","Button","Plus","ScrollArea","MessageSquare","thread","isActive","ThreadItem","AlertDialog","open","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","cn","e","Trash2","EXT_LANG_MAP","getLanguage","ext","formatSize","bytes","WorkspacePanel","onClose","tree","setTree","file","setFile","loading","setLoading","fileLoading","setFileLoading","error","setError","loadTree","useCallback","path","data","api","err","loadFile","initialized","setInitialized","breadcrumbs","relative","parts","accumulated","part","navigateUp","X","bc","ChevronRight","Loader2","ArrowUp","item","rel","newPath","filePath","Folder","SyntaxHighlighter","oneDark","Popover","PopoverPrimitive.Root","PopoverTrigger","PopoverPrimitive.Trigger","PopoverContent","React.forwardRef","className","align","sideOffset","props","ref","PopoverPrimitive.Portal","PopoverPrimitive.Content","ModelSwitcher","currentProvider","currentModel","setOpen","models","setModels","switching","setSwitching","setProvider","useChatStore","s","setModel","loadModels","handleSwitch","providerName","p","pr","displayName","o","ChevronDown","isSwitching","Check","Badge","STATES","CodeModeToggle","status","setStatus","loadStatus","useEffect","handleSet","state","result","prev","statusConfig","CheckCircle2","XCircle","ToolCallCard","tool","config","StatusIcon","Collapsible","CollapsibleTrigger","CollapsibleContent","MessageBubble","message","isLast","copied","setCopied","isUser","resolved","useThemeStore","handleCopy","motion","_a","step","i","MarkdownRenderer","Copy","StreamingMessage","text","steps","isThinking","useThreads","setThreads","threadVersion","load","useAutoScroll","deps","containerRef","useRef","atBottom","setAtBottom","userScrolledUp","scrollToBottom","el","handleScroll","isAtBottom","WaitingIndicator","PermissionPrompt","resolving","setResolving","handle","action","Zap","SLASH_COMMANDS","SlashCommandMenu","filter","selectedIndex","filtered","c","cmd","ChatInput","onSend","disabled","setText","showSlash","setShowSlash","slashIndex","setSlashIndex","textareaRef","slashFilter","filteredCommands","handleSubmit","trimmed","selectSlashCommand","needsArg","handleKeyDown","handleChange","value","firstLine","handleInput","AnimatePresence","Send","ChatPage","urlThreadId","useParams","navigate","useNavigate","connected","useSSE","threadsLoading","reloadThreads","messages","streamingText","isStreaming","waiting","provider","model","totalSteps","completedSteps","currentStepTool","setActiveThread","addMessage","clearMessages","setWaiting","clearStreaming","resetSteps","bumpThreadVersion","sidebarOpen","setSidebarOpen","workspaceOpen","setWorkspaceOpen","m","handleSend","content","threadId","handleDeleteThread","id","handleNewThread","newId","handleSelectThread","handleExportThread","t","blob","url","a","isBusy","hasSteps","stepProgress","Fragment","FolderOpen","Settings","msg","parsed","MessageBubbleComponent","ArrowDown","Progress"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
@@ -0,0 +1,2 @@
1
+ import{j as e,m as c}from"./vendor-motion-Dwx3-JO5.js";import{r as x}from"./vendor-react-C7pctHW3.js";import{C as u,a as p,b as j,c as f}from"./card-DAYo4Zl5.js";import{P as w}from"./progress-DMwOdxli.js";import{B as h}from"./badge-DfDJNUtd.js";import{a as k,c as N,C as B,f as P,b,B as y,d as S}from"./index-BhxU0YlT.js";import{Z as T}from"./zap-C-0oH5gt.js";import{A as E}from"./activity-CIP1IzSg.js";import{C as U}from"./circle-check-DweDcOkA.js";import{C as A}from"./circle-x-BmL20etA.js";import"./vendor-radix-3UdfCgs_.js";import"./index-CUT6Fr2C.js";import"./vendor-syntax-xZUI6Op9.js";const g={hidden:{opacity:0,y:12},visible:s=>({opacity:1,y:0,transition:{delay:s*.07,duration:.35,ease:"easeOut"}})};function i({className:s}){return e.jsx("div",{className:N("animate-pulse rounded-lg bg-muted",s)})}function n({icon:s,label:d,children:r,index:m,glow:o}){return e.jsx(c.div,{custom:m,variants:g,initial:"hidden",animate:"visible",children:e.jsxs(u,{className:N(o&&"mercury-glow-sm"),children:[e.jsxs(p,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(j,{className:"text-sm font-medium text-muted-foreground",children:d}),e.jsx(s,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsx(f,{children:r})]})})}function I(){const[s,d]=x.useState(null),[r,m]=x.useState("");if(x.useEffect(()=>{k.status.get().then(d).catch(a=>m(a.message))},[]),r)return e.jsx("div",{className:"flex h-full items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-destructive",children:r})});if(!s)return e.jsxs("div",{className:"space-y-6 p-6 lg:p-8",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(i,{className:"h-8 w-40"}),e.jsx(i,{className:"h-4 w-56"})]}),e.jsx("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:Array.from({length:4}).map((a,t)=>e.jsx(i,{className:"h-[120px]"},t))}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(i,{className:"h-[200px]"}),e.jsx(i,{className:"h-[200px]"})]})]});const o=s.tokens.dailyBudget?Math.min(Math.round(s.tokens.dailyUsed/s.tokens.dailyBudget*100),100):0,l=Object.entries(s.providers),C=l.filter(([,a])=>a.enabled).length,v=Object.entries(s.memory.byType);return e.jsxs("div",{className:"space-y-6 p-6 lg:p-8",children:[e.jsxs(c.div,{initial:{opacity:0,y:-8},animate:{opacity:1,y:0},transition:{duration:.3},children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Status"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Agent is"," ",e.jsx("span",{className:N("font-medium",s.running?"text-emerald-500":"text-muted-foreground"),children:s.state})]})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(n,{icon:B,label:"Uptime",index:0,glow:!0,children:e.jsx("p",{className:"text-2xl font-bold tabular-nums",children:P(s.uptime)})}),e.jsxs(n,{icon:T,label:"Tokens Used",index:1,children:[e.jsxs("p",{className:"text-2xl font-bold tabular-nums",children:[b(s.tokens.dailyUsed),e.jsxs("span",{className:"ml-1 text-sm font-normal text-muted-foreground",children:["/ ",b(s.tokens.dailyBudget)]})]}),e.jsx(w,{value:o,className:"mt-3"})]}),e.jsx(n,{icon:y,label:"Total Memories",index:2,children:e.jsx("p",{className:"text-2xl font-bold tabular-nums",children:s.memory.total.toLocaleString()})}),e.jsx(n,{icon:S,label:"Active Providers",index:3,children:e.jsxs("p",{className:"text-2xl font-bold tabular-nums",children:[C,e.jsxs("span",{className:"ml-1 text-sm font-normal text-muted-foreground",children:["/ ",l.length]})]})})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(c.div,{custom:4,variants:g,initial:"hidden",animate:"visible",children:e.jsxs(u,{children:[e.jsx(p,{children:e.jsxs(j,{className:"flex items-center gap-2 text-base",children:[e.jsx(y,{className:"h-4 w-4"}),"Memory by Type"]})}),e.jsx(f,{children:v.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No memories stored yet."}):e.jsx("div",{className:"flex flex-col gap-3",children:v.map(([a,t])=>e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(h,{variant:"secondary",className:"capitalize",children:a}),e.jsx("span",{className:"text-sm font-medium tabular-nums",children:t.toLocaleString()})]},a))})})]})}),e.jsx(c.div,{custom:5,variants:g,initial:"hidden",animate:"visible",children:e.jsxs(u,{children:[e.jsx(p,{children:e.jsxs(j,{className:"flex items-center gap-2 text-base",children:[e.jsx(E,{className:"h-4 w-4"}),"Providers"]})}),e.jsx(f,{children:l.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No providers configured."}):e.jsx("div",{className:"flex flex-col gap-3",children:l.map(([a,t])=>e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-sm font-medium",children:a}),t.enabled?e.jsxs(h,{variant:"success",className:"gap-1",children:[e.jsx(U,{className:"h-3 w-3"}),"Enabled"]}):e.jsxs(h,{variant:"outline",className:"gap-1 text-muted-foreground",children:[e.jsx(A,{className:"h-3 w-3"}),"Disabled"]})]},a))})})]})})]})]})}export{I as DashboardPage};
2
+ //# sourceMappingURL=Dashboard-B81ollv8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dashboard-B81ollv8.js","sources":["../../src/pages/Dashboard.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { motion } from \"framer-motion\";\nimport {\n Activity,\n Zap,\n Brain,\n Cpu,\n Clock,\n CheckCircle2,\n XCircle,\n} from \"lucide-react\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Progress } from \"@/components/ui/progress\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { cn } from \"@/lib/utils\";\nimport { formatUptime, formatTokens } from \"@/lib/utils\";\nimport api, { type AgentStatus } from \"@/lib/api\";\n\nconst fadeUp = {\n hidden: { opacity: 0, y: 12 },\n visible: (i: number) => ({\n opacity: 1,\n y: 0,\n transition: { delay: i * 0.07, duration: 0.35, ease: \"easeOut\" as const },\n }),\n};\n\nfunction Skeleton({ className }: { className?: string }) {\n return (\n <div\n className={cn(\n \"animate-pulse rounded-lg bg-muted\",\n className\n )}\n />\n );\n}\n\nfunction StatCard({\n icon: Icon,\n label,\n children,\n index,\n glow,\n}: {\n icon: React.ElementType;\n label: string;\n children: React.ReactNode;\n index: number;\n glow?: boolean;\n}) {\n return (\n <motion.div\n custom={index}\n variants={fadeUp}\n initial=\"hidden\"\n animate=\"visible\"\n >\n <Card className={cn(glow && \"mercury-glow-sm\")}>\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"text-sm font-medium text-muted-foreground\">\n {label}\n </CardTitle>\n <Icon className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>{children}</CardContent>\n </Card>\n </motion.div>\n );\n}\n\nexport function DashboardPage() {\n const [data, setData] = useState<AgentStatus | null>(null);\n const [error, setError] = useState(\"\");\n\n useEffect(() => {\n api.status\n .get()\n .then(setData)\n .catch((err: Error) => setError(err.message));\n }, []);\n\n if (error) {\n return (\n <div className=\"flex h-full items-center justify-center p-8\">\n <p className=\"text-sm text-destructive\">{error}</p>\n </div>\n );\n }\n\n if (!data) {\n return (\n <div className=\"space-y-6 p-6 lg:p-8\">\n <div className=\"space-y-1\">\n <Skeleton className=\"h-8 w-40\" />\n <Skeleton className=\"h-4 w-56\" />\n </div>\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Skeleton key={i} className=\"h-[120px]\" />\n ))}\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Skeleton className=\"h-[200px]\" />\n <Skeleton className=\"h-[200px]\" />\n </div>\n </div>\n );\n }\n\n const tokenPct = data.tokens.dailyBudget\n ? Math.min(\n Math.round((data.tokens.dailyUsed / data.tokens.dailyBudget) * 100),\n 100\n )\n : 0;\n\n const providerEntries = Object.entries(data.providers);\n const activeProviders = providerEntries.filter(([, v]) => v.enabled).length;\n const memoryTypes = Object.entries(data.memory.byType);\n\n return (\n <div className=\"space-y-6 p-6 lg:p-8\">\n {/* Header */}\n <motion.div\n initial={{ opacity: 0, y: -8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3 }}\n >\n <h1 className=\"text-2xl font-bold tracking-tight\">Status</h1>\n <p className=\"text-sm text-muted-foreground\">\n Agent is{\" \"}\n <span\n className={cn(\n \"font-medium\",\n data.running ? \"text-emerald-500\" : \"text-muted-foreground\"\n )}\n >\n {data.state}\n </span>\n </p>\n </motion.div>\n\n {/* Hero Stats */}\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard icon={Clock} label=\"Uptime\" index={0} glow>\n <p className=\"text-2xl font-bold tabular-nums\">\n {formatUptime(data.uptime)}\n </p>\n </StatCard>\n\n <StatCard icon={Zap} label=\"Tokens Used\" index={1}>\n <p className=\"text-2xl font-bold tabular-nums\">\n {formatTokens(data.tokens.dailyUsed)}\n <span className=\"ml-1 text-sm font-normal text-muted-foreground\">\n / {formatTokens(data.tokens.dailyBudget)}\n </span>\n </p>\n <Progress value={tokenPct} className=\"mt-3\" />\n </StatCard>\n\n <StatCard icon={Brain} label=\"Total Memories\" index={2}>\n <p className=\"text-2xl font-bold tabular-nums\">\n {data.memory.total.toLocaleString()}\n </p>\n </StatCard>\n\n <StatCard icon={Cpu} label=\"Active Providers\" index={3}>\n <p className=\"text-2xl font-bold tabular-nums\">\n {activeProviders}\n <span className=\"ml-1 text-sm font-normal text-muted-foreground\">\n / {providerEntries.length}\n </span>\n </p>\n </StatCard>\n </div>\n\n {/* Detail Cards */}\n <div className=\"grid gap-4 md:grid-cols-2\">\n {/* Memory by Type */}\n <motion.div\n custom={4}\n variants={fadeUp}\n initial=\"hidden\"\n animate=\"visible\"\n >\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Brain className=\"h-4 w-4\" />\n Memory by Type\n </CardTitle>\n </CardHeader>\n <CardContent>\n {memoryTypes.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n No memories stored yet.\n </p>\n ) : (\n <div className=\"flex flex-col gap-3\">\n {memoryTypes.map(([type, count]) => (\n <div\n key={type}\n className=\"flex items-center justify-between\"\n >\n <Badge variant=\"secondary\" className=\"capitalize\">\n {type}\n </Badge>\n <span className=\"text-sm font-medium tabular-nums\">\n {count.toLocaleString()}\n </span>\n </div>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n </motion.div>\n\n {/* Provider Status */}\n <motion.div\n custom={5}\n variants={fadeUp}\n initial=\"hidden\"\n animate=\"visible\"\n >\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Activity className=\"h-4 w-4\" />\n Providers\n </CardTitle>\n </CardHeader>\n <CardContent>\n {providerEntries.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n No providers configured.\n </p>\n ) : (\n <div className=\"flex flex-col gap-3\">\n {providerEntries.map(([name, info]) => (\n <div\n key={name}\n className=\"flex items-center justify-between\"\n >\n <span className=\"text-sm font-medium\">{name}</span>\n {info.enabled ? (\n <Badge variant=\"success\" className=\"gap-1\">\n <CheckCircle2 className=\"h-3 w-3\" />\n Enabled\n </Badge>\n ) : (\n <Badge variant=\"outline\" className=\"gap-1 text-muted-foreground\">\n <XCircle className=\"h-3 w-3\" />\n Disabled\n </Badge>\n )}\n </div>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n </motion.div>\n </div>\n </div>\n );\n}\n"],"names":["fadeUp","i","Skeleton","className","jsx","cn","StatCard","Icon","label","children","index","glow","motion","Card","jsxs","CardHeader","CardTitle","CardContent","DashboardPage","data","setData","useState","error","setError","useEffect","api","err","_","tokenPct","providerEntries","activeProviders","v","memoryTypes","Clock","Zap","formatTokens","Progress","Brain","Cpu","type","count","Badge","Activity","name","info","CheckCircle2","XCircle"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import{j as e,m as y,A as B}from"./vendor-motion-Dwx3-JO5.js";import{r}from"./vendor-react-C7pctHW3.js";import{C as k,c as A}from"./card-DAYo4Zl5.js";import{B as b}from"./button-TaFPR-zy.js";import{I as R}from"./input-L1uz5xAQ.js";import{B as ae}from"./badge-DfDJNUtd.js";import{T as re}from"./textarea-CXLsr8tf.js";import{J as oe,K as H,M as O,N as _}from"./vendor-radix-3UdfCgs_.js";import{e as K,c as p,a as j,T as S,h as ie}from"./index-BhxU0YlT.js";import{D as le,a as ne,b as ce,c as de,d as me,e as xe}from"./dialog-DovgkMhT.js";import{A as ue,h as ge,T as he,a as pe,b as fe,c as je,d as ye,e as be,f as ve,g as Ne}from"./alert-dialog-CW-j2nG4.js";import{P as q}from"./plus-DcWFYr4m.js";import{C as $}from"./circle-x-BmL20etA.js";import{L as we}from"./loader-circle-BTFgt3hG.js";import{C as Ce}from"./circle-check-DweDcOkA.js";import"./index-CUT6Fr2C.js";import"./vendor-syntax-xZUI6Op9.js";/**
2
+ * @license lucide-react v0.511.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const De=[["path",{d:"M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z",key:"1fr9dc"}],["path",{d:"M8 10v4",key:"tgpxqk"}],["path",{d:"M12 10v2",key:"hh53o1"}],["path",{d:"M16 10v6",key:"1d6xys"}]],V=K("folder-kanban",De);/**
7
+ * @license lucide-react v0.511.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */const ke=[["path",{d:"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z",key:"m3kijz"}],["path",{d:"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z",key:"1fmvmk"}],["path",{d:"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0",key:"1f8sc4"}],["path",{d:"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5",key:"qeys4"}]],Ae=K("rocket",ke),Se=oe,W=r.forwardRef(({className:s,...a},o)=>e.jsx(H,{ref:o,className:p("inline-flex h-9 items-center justify-center gap-1 border-b border-border bg-transparent p-0 text-muted-foreground",s),...a}));W.displayName=H.displayName;const L=r.forwardRef(({className:s,...a},o)=>e.jsx(O,{ref:o,className:p("inline-flex items-center justify-center whitespace-nowrap px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:text-foreground data-[state=active]:shadow-none",s),...a}));L.displayName=O.displayName;const M=r.forwardRef(({className:s,...a},o)=>e.jsx(_,{ref:o,className:p("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",s),...a}));M.displayName=_.displayName;const Te={hidden:{opacity:0,y:12},visible:s=>({opacity:1,y:0,transition:{delay:s*.05,duration:.3,ease:"easeOut"}}),exit:{opacity:0,y:-8,transition:{duration:.2}}},Pe={visible:{transition:{staggerChildren:.05}}};function Ge({toasts:s}){return e.jsx("div",{className:"fixed bottom-6 right-6 z-50 flex flex-col gap-2",children:e.jsx(B,{children:s.map(a=>e.jsxs(y.div,{initial:{opacity:0,x:40},animate:{opacity:1,x:0},exit:{opacity:0,x:40},className:p("flex items-center gap-2 rounded-lg border px-4 py-3 text-sm shadow-lg backdrop-blur-sm",a.type==="success"?"border-emerald-500/30 bg-emerald-500/10 text-emerald-400":"border-destructive/30 bg-destructive/10 text-destructive"),children:[a.type==="success"?e.jsx(Ce,{className:"h-4 w-4"}):e.jsx($,{className:"h-4 w-4"}),a.message]},a.id))})})}function D({className:s}){return e.jsx("div",{className:p("animate-pulse rounded-lg bg-muted",s)})}function Ee(){return e.jsx(k,{children:e.jsxs(A,{className:"p-5 space-y-3",children:[e.jsx(D,{className:"h-5 w-3/4"}),e.jsx(D,{className:"h-3 w-full"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(D,{className:"h-3 w-16"}),e.jsx(D,{className:"h-3 w-20"})]})]})})}function Le({importance:s}){const a=s>=8?"Critical":s>=6?"High":s>=4?"Medium":"Low",o=s>=8?"text-red-400 bg-red-500/15":s>=6?"text-amber-400 bg-amber-500/15":s>=4?"text-[#00d4ff] bg-[#00d4ff]/15":"text-muted-foreground bg-muted";return e.jsx("span",{className:p("inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium",o),children:a})}function Me({item:s,onDelete:a,index:o,kind:i}){return e.jsx(y.div,{custom:o,variants:Te,initial:"hidden",animate:"visible",exit:"exit",layout:!0,children:e.jsx(k,{className:"group transition-colors hover:border-[#00d4ff]/20",children:e.jsx(A,{className:"p-5",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex-1 min-w-0 space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[i==="goal"?e.jsx(S,{className:"h-4 w-4 text-amber-400 shrink-0"}):e.jsx(V,{className:"h-4 w-4 text-cyan-400 shrink-0"}),e.jsx("h3",{className:"text-sm font-semibold text-foreground leading-tight",children:s.summary})]}),s.detail&&e.jsx("p",{className:"text-sm text-muted-foreground leading-relaxed line-clamp-3",children:s.detail}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 pt-0.5",children:[s.importance!=null&&e.jsx(Le,{importance:s.importance}),e.jsx("span",{className:"text-xs text-muted-foreground/50",children:ie(s.createdAt)})]})]}),e.jsxs(ue,{children:[e.jsx(ge,{asChild:!0,children:e.jsx(b,{size:"sm",variant:"ghost",className:"opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-destructive shrink-0",children:e.jsx(he,{className:"h-3.5 w-3.5"})})}),e.jsxs(pe,{children:[e.jsxs(fe,{children:[e.jsxs(je,{children:["Delete ",i==="goal"?"Goal":"Project"]}),e.jsxs(ye,{children:["Are you sure you want to delete this"," ",i==="goal"?"goal":"project","? This action cannot be undone."]})]}),e.jsxs(be,{children:[e.jsx(ve,{children:"Cancel"}),e.jsx(Ne,{onClick:()=>a(s.id),className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"Delete"})]})]})]})]})})})})}function Ie({open:s,onOpenChange:a,onSubmit:o,submitting:i,kind:c}){const[d,u]=r.useState(""),[m,x]=r.useState(""),[f,v]=r.useState("5"),N=l=>{l.preventDefault(),d.trim()&&o({type:c,summary:d.trim(),detail:m.trim()||void 0,importance:parseInt(f)})},T=()=>{u(""),x(""),v("5")};return e.jsx(le,{open:s,onOpenChange:l=>{l||T(),a(l)},children:e.jsxs(ne,{className:"sm:max-w-md",children:[e.jsxs(ce,{children:[e.jsxs(de,{children:["Add ",c==="goal"?"Goal":"Project"]}),e.jsxs(me,{children:["Create a new ",c==="goal"?"goal":"project"," in the Second Brain."]})]}),e.jsxs("form",{onSubmit:N,className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("label",{className:"text-sm font-medium text-foreground",children:["Summary ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(R,{placeholder:c==="goal"?"What do you want to achieve?":"What are you working on?",value:d,onChange:l=>u(l.target.value),required:!0})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:"Detail"}),e.jsx(re,{placeholder:"Additional context...",value:m,onChange:l=>x(l.target.value),rows:3})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:"Importance (1–10)"}),e.jsx(R,{type:"number",min:"1",max:"10",step:"1",value:f,onChange:l=>v(l.target.value)})]}),e.jsx(xe,{children:e.jsx(b,{type:"submit",disabled:i||!d.trim(),children:i?e.jsxs(e.Fragment,{children:[e.jsx(we,{className:"h-4 w-4 animate-spin"}),"Saving..."]}):`Add ${c==="goal"?"Goal":"Project"}`})})]})]})})}function z({items:s,loading:a,error:o,kind:i,onDelete:c,onRetry:d,onAdd:u}){return o?e.jsx(k,{className:"border-destructive/30",children:e.jsxs(A,{className:"flex items-center gap-3 p-4 text-sm text-destructive",children:[e.jsx($,{className:"h-4 w-4 shrink-0"}),o,e.jsx(b,{size:"sm",variant:"outline",className:"ml-auto",onClick:d,children:"Retry"})]})}):a?e.jsx("div",{className:"space-y-3",children:Array.from({length:3}).map((m,x)=>e.jsx(Ee,{},x))}):s.length===0?e.jsx(k,{children:e.jsxs(A,{className:"flex flex-col items-center justify-center py-16 text-center",children:[e.jsx("div",{className:"flex h-14 w-14 items-center justify-center rounded-full bg-muted mb-4",children:i==="goal"?e.jsx(S,{className:"h-7 w-7 text-muted-foreground"}):e.jsx(Ae,{className:"h-7 w-7 text-muted-foreground"})}),e.jsxs("h3",{className:"text-base font-medium text-foreground mb-1",children:["No ",i==="goal"?"goals":"projects"," yet"]}),e.jsx("p",{className:"text-sm text-muted-foreground max-w-sm",children:i==="goal"?"Add goals to help Mercury understand what you're working towards.":"Track active projects so Mercury can provide better context."}),e.jsxs(b,{className:"mt-4",onClick:u,children:[e.jsx(q,{className:"h-4 w-4"}),"Add ",i==="goal"?"Goal":"Project"]})]})}):e.jsx(y.div,{className:"space-y-3",variants:Pe,initial:"hidden",animate:"visible",children:e.jsx(B,{mode:"popLayout",children:s.map((m,x)=>e.jsx(Me,{item:m,onDelete:c,index:x,kind:i},m.id))})})}function Ye(){const[s,a]=r.useState([]),[o,i]=r.useState([]),[c,d]=r.useState(!0),[u,m]=r.useState(!0),[x,f]=r.useState(null),[v,N]=r.useState(null),[T,l]=r.useState(!1),[J,U]=r.useState("goal"),[X,I]=r.useState(!1),[P,Z]=r.useState("goals"),[Q,F]=r.useState([]),g=r.useCallback((t,n)=>{const h=Date.now();F(E=>[...E,{id:h,type:t,message:n}]),setTimeout(()=>{F(E=>E.filter(te=>te.id!==h))},3500)},[]),w=r.useCallback(async()=>{try{d(!0),f(null);const t=await j.brain.memory.list({type:"goal"});a(t.memories)}catch(t){f(t instanceof Error?t.message:"Failed to load goals")}finally{d(!1)}},[]),C=r.useCallback(async()=>{try{m(!0),N(null);const t=await j.brain.memory.list({type:"project"});i(t.memories)}catch(t){N(t instanceof Error?t.message:"Failed to load projects")}finally{m(!1)}},[]);r.useEffect(()=>{w(),C()},[w,C]);const G=t=>{U(t),l(!0)},Y=async t=>{I(!0);try{await j.brain.memory.create(t),g("success",`${t.type==="goal"?"Goal":"Project"} created`),l(!1),t.type==="goal"?w():C()}catch(n){g("error",n instanceof Error?n.message:"Failed to create")}finally{I(!1)}},ee=async t=>{try{await j.brain.memory.delete(t),a(n=>n.filter(h=>h.id!==t)),g("success","Goal deleted")}catch(n){g("error",n instanceof Error?n.message:"Failed to delete")}},se=async t=>{try{await j.brain.memory.delete(t),i(n=>n.filter(h=>h.id!==t)),g("success","Project deleted")}catch(n){g("error",n instanceof Error?n.message:"Failed to delete")}};return e.jsxs("div",{className:"space-y-6 p-6",children:[e.jsxs(y.div,{initial:{opacity:0,y:-8},animate:{opacity:1,y:0},transition:{duration:.3},className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex h-10 w-10 items-center justify-center rounded-lg bg-[#00d4ff]/10",children:e.jsx(S,{className:"h-5 w-5 text-[#00d4ff]"})}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("h1",{className:"text-2xl font-semibold text-foreground",children:"Goals & Projects"}),e.jsx(ae,{variant:"secondary",className:"tabular-nums",children:s.length+o.length})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Track objectives and active initiatives"})]})]}),e.jsxs(b,{onClick:()=>G(P==="goals"?"goal":"project"),children:[e.jsx(q,{className:"h-4 w-4"}),"Add ",P==="goals"?"Goal":"Project"]})]}),e.jsx(y.div,{initial:{opacity:0,y:8},animate:{opacity:1,y:0},transition:{delay:.1,duration:.3},children:e.jsxs(Se,{value:P,onValueChange:Z,className:"space-y-4",children:[e.jsxs(W,{className:"w-full sm:w-auto",children:[e.jsxs(L,{value:"goals",className:"gap-1.5",children:[e.jsx(S,{className:"h-3.5 w-3.5"}),"Goals",!c&&e.jsxs("span",{className:"ml-1 text-xs text-muted-foreground/60 tabular-nums",children:["(",s.length,")"]})]}),e.jsxs(L,{value:"projects",className:"gap-1.5",children:[e.jsx(V,{className:"h-3.5 w-3.5"}),"Projects",!u&&e.jsxs("span",{className:"ml-1 text-xs text-muted-foreground/60 tabular-nums",children:["(",o.length,")"]})]})]}),e.jsx(M,{value:"goals",children:e.jsx(z,{items:s,loading:c,error:x,kind:"goal",onDelete:ee,onRetry:w,onAdd:()=>G("goal")})}),e.jsx(M,{value:"projects",children:e.jsx(z,{items:o,loading:u,error:v,kind:"project",onDelete:se,onRetry:C,onAdd:()=>G("project")})})]})}),e.jsx(Ie,{open:T,onOpenChange:l,onSubmit:Y,submitting:X,kind:J}),e.jsx(Ge,{toasts:Q})]})}export{Ye as GoalsPage};
12
+ //# sourceMappingURL=Goals-D0cR8yIP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Goals-D0cR8yIP.js","sources":["../../node_modules/lucide-react/dist/esm/icons/folder-kanban.js","../../node_modules/lucide-react/dist/esm/icons/rocket.js","../../src/components/ui/tabs.tsx","../../src/pages/brain/Goals.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z\",\n key: \"1fr9dc\"\n }\n ],\n [\"path\", { d: \"M8 10v4\", key: \"tgpxqk\" }],\n [\"path\", { d: \"M12 10v2\", key: \"hh53o1\" }],\n [\"path\", { d: \"M16 10v6\", key: \"1d6xys\" }]\n];\nconst FolderKanban = createLucideIcon(\"folder-kanban\", __iconNode);\n\nexport { __iconNode, FolderKanban as default };\n//# sourceMappingURL=folder-kanban.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z\",\n key: \"m3kijz\"\n }\n ],\n [\n \"path\",\n {\n d: \"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z\",\n key: \"1fmvmk\"\n }\n ],\n [\"path\", { d: \"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0\", key: \"1f8sc4\" }],\n [\"path\", { d: \"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5\", key: \"qeys4\" }]\n];\nconst Rocket = createLucideIcon(\"rocket\", __iconNode);\n\nexport { __iconNode, Rocket as default };\n//# sourceMappingURL=rocket.js.map\n","import * as React from \"react\";\nimport * as TabsPrimitive from \"@radix-ui/react-tabs\";\nimport { cn } from \"@/lib/utils\";\n\nconst Tabs = TabsPrimitive.Root;\n\nconst TabsList = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.List>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.List\n ref={ref}\n className={cn(\n \"inline-flex h-9 items-center justify-center gap-1 border-b border-border bg-transparent p-0 text-muted-foreground\",\n className\n )}\n {...props}\n />\n));\nTabsList.displayName = TabsPrimitive.List.displayName;\n\nconst TabsTrigger = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Trigger\n ref={ref}\n className={cn(\n \"inline-flex items-center justify-center whitespace-nowrap px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:text-foreground data-[state=active]:shadow-none\",\n className\n )}\n {...props}\n />\n));\nTabsTrigger.displayName = TabsPrimitive.Trigger.displayName;\n\nconst TabsContent = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Content\n ref={ref}\n className={cn(\n \"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n className\n )}\n {...props}\n />\n));\nTabsContent.displayName = TabsPrimitive.Content.displayName;\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent };\n","import { useEffect, useState, useCallback } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport {\n Target,\n FolderKanban,\n Plus,\n Trash2,\n Loader2,\n CheckCircle2,\n XCircle,\n Rocket,\n} from \"lucide-react\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"@/components/ui/tabs\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n DialogDescription,\n} from \"@/components/ui/dialog\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\";\nimport { cn, formatDate } from \"@/lib/utils\";\nimport api, { type Memory, type MemoryCreate } from \"@/lib/api\";\n\n/* ── Animations ─────────────────────────────────────────────── */\n\nconst fadeUp = {\n hidden: { opacity: 0, y: 12 },\n visible: (i: number) => ({\n opacity: 1,\n y: 0,\n transition: { delay: i * 0.05, duration: 0.3, ease: \"easeOut\" as const },\n }),\n exit: { opacity: 0, y: -8, transition: { duration: 0.2 } },\n};\n\nconst stagger = {\n visible: { transition: { staggerChildren: 0.05 } },\n};\n\n/* ── Toast ──────────────────────────────────────────────────── */\n\ninterface Toast {\n id: number;\n type: \"success\" | \"error\";\n message: string;\n}\n\nfunction ToastBar({ toasts }: { toasts: Toast[] }) {\n return (\n <div className=\"fixed bottom-6 right-6 z-50 flex flex-col gap-2\">\n <AnimatePresence>\n {toasts.map((t) => (\n <motion.div\n key={t.id}\n initial={{ opacity: 0, x: 40 }}\n animate={{ opacity: 1, x: 0 }}\n exit={{ opacity: 0, x: 40 }}\n className={cn(\n \"flex items-center gap-2 rounded-lg border px-4 py-3 text-sm shadow-lg backdrop-blur-sm\",\n t.type === \"success\"\n ? \"border-emerald-500/30 bg-emerald-500/10 text-emerald-400\"\n : \"border-destructive/30 bg-destructive/10 text-destructive\"\n )}\n >\n {t.type === \"success\" ? (\n <CheckCircle2 className=\"h-4 w-4\" />\n ) : (\n <XCircle className=\"h-4 w-4\" />\n )}\n {t.message}\n </motion.div>\n ))}\n </AnimatePresence>\n </div>\n );\n}\n\n/* ── Skeleton ───────────────────────────────────────────────── */\n\nfunction Skeleton({ className }: { className?: string }) {\n return (\n <div className={cn(\"animate-pulse rounded-lg bg-muted\", className)} />\n );\n}\n\nfunction ItemCardSkeleton() {\n return (\n <Card>\n <CardContent className=\"p-5 space-y-3\">\n <Skeleton className=\"h-5 w-3/4\" />\n <Skeleton className=\"h-3 w-full\" />\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"h-3 w-16\" />\n <Skeleton className=\"h-3 w-20\" />\n </div>\n </CardContent>\n </Card>\n );\n}\n\n/* ── Priority Indicator ─────────────────────────────────────── */\n\nfunction PriorityIndicator({ importance }: { importance: number }) {\n const label =\n importance >= 8\n ? \"Critical\"\n : importance >= 6\n ? \"High\"\n : importance >= 4\n ? \"Medium\"\n : \"Low\";\n const color =\n importance >= 8\n ? \"text-red-400 bg-red-500/15\"\n : importance >= 6\n ? \"text-amber-400 bg-amber-500/15\"\n : importance >= 4\n ? \"text-[#00d4ff] bg-[#00d4ff]/15\"\n : \"text-muted-foreground bg-muted\";\n\n return (\n <span\n className={cn(\n \"inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium\",\n color\n )}\n >\n {label}\n </span>\n );\n}\n\n/* ── Item Card ──────────────────────────────────────────────── */\n\nfunction ItemCard({\n item,\n onDelete,\n index,\n kind,\n}: {\n item: Memory;\n onDelete: (id: string) => void;\n index: number;\n kind: \"goal\" | \"project\";\n}) {\n return (\n <motion.div\n custom={index}\n variants={fadeUp}\n initial=\"hidden\"\n animate=\"visible\"\n exit=\"exit\"\n layout\n >\n <Card className=\"group transition-colors hover:border-[#00d4ff]/20\">\n <CardContent className=\"p-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex-1 min-w-0 space-y-2\">\n {/* Title row */}\n <div className=\"flex items-center gap-2.5\">\n {kind === \"goal\" ? (\n <Target className=\"h-4 w-4 text-amber-400 shrink-0\" />\n ) : (\n <FolderKanban className=\"h-4 w-4 text-cyan-400 shrink-0\" />\n )}\n <h3 className=\"text-sm font-semibold text-foreground leading-tight\">\n {item.summary}\n </h3>\n </div>\n\n {/* Detail */}\n {item.detail && (\n <p className=\"text-sm text-muted-foreground leading-relaxed line-clamp-3\">\n {item.detail}\n </p>\n )}\n\n {/* Meta */}\n <div className=\"flex flex-wrap items-center gap-3 pt-0.5\">\n {item.importance != null && (\n <PriorityIndicator importance={item.importance} />\n )}\n <span className=\"text-xs text-muted-foreground/50\">\n {formatDate(item.createdAt)}\n </span>\n </div>\n </div>\n\n {/* Delete */}\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-destructive shrink-0\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n Delete {kind === \"goal\" ? \"Goal\" : \"Project\"}\n </AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to delete this{\" \"}\n {kind === \"goal\" ? \"goal\" : \"project\"}? This action cannot\n be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => onDelete(item.id)}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n </CardContent>\n </Card>\n </motion.div>\n );\n}\n\n/* ── Add Dialog ─────────────────────────────────────────────── */\n\nfunction AddItemDialog({\n open,\n onOpenChange,\n onSubmit,\n submitting,\n kind,\n}: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSubmit: (data: MemoryCreate) => void;\n submitting: boolean;\n kind: \"goal\" | \"project\";\n}) {\n const [summary, setSummary] = useState(\"\");\n const [detail, setDetail] = useState(\"\");\n const [importance, setImportance] = useState(\"5\");\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (!summary.trim()) return;\n onSubmit({\n type: kind,\n summary: summary.trim(),\n detail: detail.trim() || undefined,\n importance: parseInt(importance),\n });\n };\n\n const reset = () => {\n setSummary(\"\");\n setDetail(\"\");\n setImportance(\"5\");\n };\n\n return (\n <Dialog\n open={open}\n onOpenChange={(v) => {\n if (!v) reset();\n onOpenChange(v);\n }}\n >\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>\n Add {kind === \"goal\" ? \"Goal\" : \"Project\"}\n </DialogTitle>\n <DialogDescription>\n Create a new {kind === \"goal\" ? \"goal\" : \"project\"} in the Second\n Brain.\n </DialogDescription>\n </DialogHeader>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n Summary <span className=\"text-destructive\">*</span>\n </label>\n <Input\n placeholder={\n kind === \"goal\"\n ? \"What do you want to achieve?\"\n : \"What are you working on?\"\n }\n value={summary}\n onChange={(e) => setSummary(e.target.value)}\n required\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n Detail\n </label>\n <Textarea\n placeholder=\"Additional context...\"\n value={detail}\n onChange={(e) => setDetail(e.target.value)}\n rows={3}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n Importance (1–10)\n </label>\n <Input\n type=\"number\"\n min=\"1\"\n max=\"10\"\n step=\"1\"\n value={importance}\n onChange={(e) => setImportance(e.target.value)}\n />\n </div>\n\n <DialogFooter>\n <Button type=\"submit\" disabled={submitting || !summary.trim()}>\n {submitting ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Saving...\n </>\n ) : (\n `Add ${kind === \"goal\" ? \"Goal\" : \"Project\"}`\n )}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\n/* ── Tab Content ────────────────────────────────────────────── */\n\nfunction TabSection({\n items,\n loading,\n error,\n kind,\n onDelete,\n onRetry,\n onAdd,\n}: {\n items: Memory[];\n loading: boolean;\n error: string | null;\n kind: \"goal\" | \"project\";\n onDelete: (id: string) => void;\n onRetry: () => void;\n onAdd: () => void;\n}) {\n if (error) {\n return (\n <Card className=\"border-destructive/30\">\n <CardContent className=\"flex items-center gap-3 p-4 text-sm text-destructive\">\n <XCircle className=\"h-4 w-4 shrink-0\" />\n {error}\n <Button size=\"sm\" variant=\"outline\" className=\"ml-auto\" onClick={onRetry}>\n Retry\n </Button>\n </CardContent>\n </Card>\n );\n }\n\n if (loading) {\n return (\n <div className=\"space-y-3\">\n {Array.from({ length: 3 }).map((_, i) => (\n <ItemCardSkeleton key={i} />\n ))}\n </div>\n );\n }\n\n if (items.length === 0) {\n return (\n <Card>\n <CardContent className=\"flex flex-col items-center justify-center py-16 text-center\">\n <div className=\"flex h-14 w-14 items-center justify-center rounded-full bg-muted mb-4\">\n {kind === \"goal\" ? (\n <Target className=\"h-7 w-7 text-muted-foreground\" />\n ) : (\n <Rocket className=\"h-7 w-7 text-muted-foreground\" />\n )}\n </div>\n <h3 className=\"text-base font-medium text-foreground mb-1\">\n No {kind === \"goal\" ? \"goals\" : \"projects\"} yet\n </h3>\n <p className=\"text-sm text-muted-foreground max-w-sm\">\n {kind === \"goal\"\n ? \"Add goals to help Mercury understand what you're working towards.\"\n : \"Track active projects so Mercury can provide better context.\"}\n </p>\n <Button className=\"mt-4\" onClick={onAdd}>\n <Plus className=\"h-4 w-4\" />\n Add {kind === \"goal\" ? \"Goal\" : \"Project\"}\n </Button>\n </CardContent>\n </Card>\n );\n }\n\n return (\n <motion.div\n className=\"space-y-3\"\n variants={stagger}\n initial=\"hidden\"\n animate=\"visible\"\n >\n <AnimatePresence mode=\"popLayout\">\n {items.map((item, i) => (\n <ItemCard\n key={item.id}\n item={item}\n onDelete={onDelete}\n index={i}\n kind={kind}\n />\n ))}\n </AnimatePresence>\n </motion.div>\n );\n}\n\n/* ── Main Page ──────────────────────────────────────────────── */\n\nexport function GoalsPage() {\n const [goals, setGoals] = useState<Memory[]>([]);\n const [projects, setProjects] = useState<Memory[]>([]);\n const [goalsLoading, setGoalsLoading] = useState(true);\n const [projectsLoading, setProjectsLoading] = useState(true);\n const [goalsError, setGoalsError] = useState<string | null>(null);\n const [projectsError, setProjectsError] = useState<string | null>(null);\n const [dialogOpen, setDialogOpen] = useState(false);\n const [dialogKind, setDialogKind] = useState<\"goal\" | \"project\">(\"goal\");\n const [submitting, setSubmitting] = useState(false);\n const [activeTab, setActiveTab] = useState(\"goals\");\n const [toasts, setToasts] = useState<Toast[]>([]);\n\n const toast = useCallback((type: \"success\" | \"error\", message: string) => {\n const id = Date.now();\n setToasts((prev) => [...prev, { id, type, message }]);\n setTimeout(() => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, 3500);\n }, []);\n\n const fetchGoals = useCallback(async () => {\n try {\n setGoalsLoading(true);\n setGoalsError(null);\n const res = await api.brain.memory.list({ type: \"goal\" });\n setGoals(res.memories);\n } catch (err: unknown) {\n setGoalsError(\n err instanceof Error ? err.message : \"Failed to load goals\"\n );\n } finally {\n setGoalsLoading(false);\n }\n }, []);\n\n const fetchProjects = useCallback(async () => {\n try {\n setProjectsLoading(true);\n setProjectsError(null);\n const res = await api.brain.memory.list({ type: \"project\" });\n setProjects(res.memories);\n } catch (err: unknown) {\n setProjectsError(\n err instanceof Error ? err.message : \"Failed to load projects\"\n );\n } finally {\n setProjectsLoading(false);\n }\n }, []);\n\n useEffect(() => {\n fetchGoals();\n fetchProjects();\n }, [fetchGoals, fetchProjects]);\n\n const openDialog = (kind: \"goal\" | \"project\") => {\n setDialogKind(kind);\n setDialogOpen(true);\n };\n\n const handleCreate = async (data: MemoryCreate) => {\n setSubmitting(true);\n try {\n await api.brain.memory.create(data);\n toast(\"success\", `${data.type === \"goal\" ? \"Goal\" : \"Project\"} created`);\n setDialogOpen(false);\n if (data.type === \"goal\") fetchGoals();\n else fetchProjects();\n } catch (err: unknown) {\n toast(\"error\", err instanceof Error ? err.message : \"Failed to create\");\n } finally {\n setSubmitting(false);\n }\n };\n\n const handleDeleteGoal = async (id: string) => {\n try {\n await api.brain.memory.delete(id);\n setGoals((prev) => prev.filter((g) => g.id !== id));\n toast(\"success\", \"Goal deleted\");\n } catch (err: unknown) {\n toast(\"error\", err instanceof Error ? err.message : \"Failed to delete\");\n }\n };\n\n const handleDeleteProject = async (id: string) => {\n try {\n await api.brain.memory.delete(id);\n setProjects((prev) => prev.filter((p) => p.id !== id));\n toast(\"success\", \"Project deleted\");\n } catch (err: unknown) {\n toast(\"error\", err instanceof Error ? err.message : \"Failed to delete\");\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <motion.div\n initial={{ opacity: 0, y: -8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3 }}\n className=\"flex items-start justify-between gap-4\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-[#00d4ff]/10\">\n <Target className=\"h-5 w-5 text-[#00d4ff]\" />\n </div>\n <div>\n <div className=\"flex items-center gap-2.5\">\n <h1 className=\"text-2xl font-semibold text-foreground\">\n Goals &amp; Projects\n </h1>\n <Badge variant=\"secondary\" className=\"tabular-nums\">\n {goals.length + projects.length}\n </Badge>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n Track objectives and active initiatives\n </p>\n </div>\n </div>\n <Button\n onClick={() =>\n openDialog(activeTab === \"goals\" ? \"goal\" : \"project\")\n }\n >\n <Plus className=\"h-4 w-4\" />\n Add {activeTab === \"goals\" ? \"Goal\" : \"Project\"}\n </Button>\n </motion.div>\n\n {/* Tabs */}\n <motion.div\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: 0.1, duration: 0.3 }}\n >\n <Tabs\n value={activeTab}\n onValueChange={setActiveTab}\n className=\"space-y-4\"\n >\n <TabsList className=\"w-full sm:w-auto\">\n <TabsTrigger value=\"goals\" className=\"gap-1.5\">\n <Target className=\"h-3.5 w-3.5\" />\n Goals\n {!goalsLoading && (\n <span className=\"ml-1 text-xs text-muted-foreground/60 tabular-nums\">\n ({goals.length})\n </span>\n )}\n </TabsTrigger>\n <TabsTrigger value=\"projects\" className=\"gap-1.5\">\n <FolderKanban className=\"h-3.5 w-3.5\" />\n Projects\n {!projectsLoading && (\n <span className=\"ml-1 text-xs text-muted-foreground/60 tabular-nums\">\n ({projects.length})\n </span>\n )}\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"goals\">\n <TabSection\n items={goals}\n loading={goalsLoading}\n error={goalsError}\n kind=\"goal\"\n onDelete={handleDeleteGoal}\n onRetry={fetchGoals}\n onAdd={() => openDialog(\"goal\")}\n />\n </TabsContent>\n\n <TabsContent value=\"projects\">\n <TabSection\n items={projects}\n loading={projectsLoading}\n error={projectsError}\n kind=\"project\"\n onDelete={handleDeleteProject}\n onRetry={fetchProjects}\n onAdd={() => openDialog(\"project\")}\n />\n </TabsContent>\n </Tabs>\n </motion.div>\n\n {/* Add dialog */}\n <AddItemDialog\n open={dialogOpen}\n onOpenChange={setDialogOpen}\n onSubmit={handleCreate}\n submitting={submitting}\n kind={dialogKind}\n />\n\n <ToastBar toasts={toasts} />\n </div>\n );\n}\n"],"names":["__iconNode","FolderKanban","createLucideIcon","Rocket","Tabs","TabsPrimitive.Root","TabsList","React.forwardRef","className","props","ref","jsx","TabsPrimitive.List","cn","TabsTrigger","TabsPrimitive.Trigger","TabsContent","TabsPrimitive.Content","fadeUp","i","stagger","ToastBar","toasts","AnimatePresence","t","jsxs","motion","CheckCircle2","XCircle","Skeleton","ItemCardSkeleton","Card","CardContent","PriorityIndicator","importance","label","color","ItemCard","item","onDelete","index","kind","Target","formatDate","AlertDialog","AlertDialogTrigger","Button","Trash2","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","AddItemDialog","open","onOpenChange","onSubmit","submitting","summary","setSummary","useState","detail","setDetail","setImportance","handleSubmit","e","reset","Dialog","v","DialogContent","DialogHeader","DialogTitle","DialogDescription","Input","Textarea","DialogFooter","Fragment","Loader2","TabSection","items","loading","error","onRetry","onAdd","_","Plus","GoalsPage","goals","setGoals","projects","setProjects","goalsLoading","setGoalsLoading","projectsLoading","setProjectsLoading","goalsError","setGoalsError","projectsError","setProjectsError","dialogOpen","setDialogOpen","dialogKind","setDialogKind","setSubmitting","activeTab","setActiveTab","setToasts","toast","useCallback","type","message","id","prev","fetchGoals","res","api","err","fetchProjects","useEffect","openDialog","handleCreate","data","handleDeleteGoal","g","handleDeleteProject","p","Badge"],"mappings":"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","x_google_ignoreList":[0,1]}
@@ -0,0 +1,7 @@
1
+ import{j as s}from"./vendor-motion-Dwx3-JO5.js";import{r as d}from"./vendor-react-C7pctHW3.js";import{e as Se,a as pe}from"./index-BhxU0YlT.js";import{D as Ce,a as Ee,b as ze,c as De}from"./dialog-DovgkMhT.js";import{L as me}from"./loader-circle-BTFgt3hG.js";import{S as Fe}from"./search-D1OOxb1X.js";import"./vendor-syntax-xZUI6Op9.js";import"./vendor-radix-3UdfCgs_.js";/**
2
+ * @license lucide-react v0.511.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const Le=[["rect",{x:"16",y:"16",width:"6",height:"6",rx:"1",key:"4q2zg0"}],["rect",{x:"2",y:"16",width:"6",height:"6",rx:"1",key:"8cvhb9"}],["rect",{x:"9",y:"2",width:"6",height:"6",rx:"1",key:"1egb70"}],["path",{d:"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3",key:"1jsf9p"}],["path",{d:"M12 12V8",key:"2874zd"}]],ge=Se("network",Le),he={fact:"#3b82f6",preference:"#a78bfa",experience:"#22c55e",goal:"#f59e0b",project:"#00d4ff",person:"#ec4899",skill:"#6366f1",belief:"#f97316",observation:"#14b8a6",default:"#6b7280"};function Q(p){return he[p]||he.default}function Re(){return document.documentElement.classList.contains("dark")||document.documentElement.getAttribute("data-theme")!=="light"}function Qe(){const p=d.useRef(null),S=d.useRef(null),[b,u]=d.useState(!0),[F,q]=d.useState([]),[$,B]=d.useState([]),[R,O]=d.useState(""),[v,H]=d.useState(null),[be,J]=d.useState(!1),[G,ve]=d.useState(null),[ye,ee]=d.useState(null),[Ne,te]=d.useState(!1),[je,se]=d.useState(null),m=d.useRef({nodes:[],edges:[],positions:new Map,anchors:new Map,velocities:new Map,pan:{x:0,y:0},zoom:1,dragging:!1,dragNode:null,hoveredNode:null,selectedNode:null,lastMouse:{x:0,y:0},pressNode:null,pressX:0,pressY:0,pressT:0,moved:!1,searchQuery:"",animFrame:0,dpr:1});d.useEffect(()=>{m.current.searchQuery=R},[R]);const K=d.useCallback((e,o)=>{let t=0;for(const n of o)(n.source===e||n.target===e)&&t++;return t},[]),ne=d.useCallback((e,o,t)=>{const n=m.current,a=o/2,c=t/2;n.positions.clear(),n.anchors.clear(),n.velocities.clear(),e.forEach((l,r)=>{const i=r/e.length*Math.PI*2,D=150+Math.random()*100,C=a+D*Math.cos(i),N=c+D*Math.sin(i);n.positions.set(l.id,{x:C,y:N}),n.anchors.set(l.id,{x:C,y:N}),n.velocities.set(l.id,{seed:Math.random(),freq:9e-5+Math.random()*7e-5,amp:.25+Math.random()*.25})})},[]),oe=d.useCallback((e,o,t,n)=>{const a=m.current,c=80;for(let l=0;l<c;l++){const r=t*n,i=Math.sqrt(r/Math.max(1,e.length)),D=i*i,C=.01,N=new Map;e.forEach(x=>N.set(x.id,{fx:0,fy:0}));for(let x=0;x<e.length;x++)for(let f=x+1;f<e.length;f++){const h=a.positions.get(e[x].id),L=a.positions.get(e[f].id);if(!h||!L)continue;const z=h.x-L.x,j=h.y-L.y,E=Math.max(Math.sqrt(z*z+j*j),1),P=D/(E*E),W=z/E*P,T=j/E*P;N.get(e[x].id).fx+=W,N.get(e[x].id).fy+=T,N.get(e[f].id).fx-=W,N.get(e[f].id).fy-=T}o.forEach(x=>{const f=a.positions.get(x.source),h=a.positions.get(x.target);if(!f||!h)return;const L=h.x-f.x,z=h.y-f.y,j=N.get(x.source),E=N.get(x.target);j&&(j.fx+=L*C,j.fy+=z*C),E&&(E.fx-=L*C,E.fy-=z*C)});const g=t/2,y=n/2,k=.001;e.forEach(x=>{const f=a.positions.get(x.id),h=N.get(x.id);!f||!h||(h.fx+=(g-f.x)*k,h.fy+=(y-f.y)*k)});const M=.1;e.forEach(x=>{const f=N.get(x.id),h=a.positions.get(x.id);!f||!h||(h.x+=f.fx*M,h.y+=f.fy*M)})}e.forEach(l=>{const r=a.positions.get(l.id),i=a.anchors.get(l.id);r&&i&&(i.x=r.x,i.y=r.y)})},[]),Y=d.useCallback(()=>{const e=p.current,o=S.current;if(!e||!o)return;const t=window.devicePixelRatio||1;m.current.dpr=t;const n=o.clientWidth,a=o.clientHeight;e.width=n*t,e.height=a*t,e.style.width=`${n}px`,e.style.height=`${a}px`},[]),X=d.useCallback((e,o)=>{const t=m.current,n=t.dpr;return{x:(e*n-t.pan.x)/t.zoom,y:(o*n-t.pan.y)/t.zoom}},[]),I=d.useCallback((e,o)=>{const t=m.current;for(let n=t.nodes.length-1;n>=0;n--){const a=t.nodes[n],c=t.positions.get(a.id);if(!c)continue;const l=(a.size||8)*1.5,r=e-c.x,i=o-c.y;if(r*r+i*i<l*l)return a}return null},[]),ae=d.useCallback(e=>{const o=p.current;if(!o)return;const t=o.getContext("2d");if(!t)return;const n=m.current,a=n.dpr,c=o.width,l=o.height,r=Re();t.clearRect(0,0,c,l),t.fillStyle=r?"#0a0e14":"#ffffff",t.fillRect(0,0,c,l),t.save(),t.translate(n.pan.x,n.pan.y),t.scale(n.zoom,n.zoom);const i=n.hoveredNode||n.selectedNode,D=new Set,C=new Set;i&&(n.edges.forEach((g,y)=>{g.source===i.id&&(D.add(g.target),C.add(y)),g.target===i.id&&(D.add(g.source),C.add(y))}),D.add(i.id)),n.edges.forEach((g,y)=>{const k=n.positions.get(g.source),M=n.positions.get(g.target);if(!k||!M)return;if(C.has(y))t.strokeStyle=r?"rgba(0,212,255,0.7)":"rgba(0,136,170,0.6)",t.lineWidth=2*a/n.zoom;else if(i)t.strokeStyle=r?"rgba(0,212,255,0.06)":"rgba(0,136,170,0.05)",t.lineWidth=.6*a/n.zoom;else{const f=(Math.sin(e*22e-5+y*1.3)+1)*.5,h=(r?.16:.13)+f*.06;t.strokeStyle=r?`rgba(0,212,255,${h.toFixed(3)})`:`rgba(0,136,170,${h.toFixed(3)})`,t.lineWidth=(.7+f*.3)*a/n.zoom}t.beginPath(),t.moveTo(k.x,k.y),t.lineTo(M.x,M.y),t.stroke()});const N=n.searchQuery.toLowerCase();n.nodes.forEach(g=>{var E,P,W;const y=n.positions.get(g.id);if(!y)return;const k=((E=n.hoveredNode)==null?void 0:E.id)===g.id,M=((P=n.selectedNode)==null?void 0:P.id)===g.id,x=D.has(g.id),f=n.velocities.get(g.id),h=1+Math.sin(e*35e-5+((f==null?void 0:f.seed)??0)*11.7)*.01,z=(g.size||8)*a*(k||M?1.4:h);let j=1;if(N?j=(g.fullLabel||g.label).toLowerCase().includes(N)?1:.12:i&&(j=k||M||x?1:.18),t.globalAlpha=j,(k||M)&&(t.beginPath(),t.arc(y.x,y.y,z+5*a/n.zoom,0,Math.PI*2),t.fillStyle=r?"rgba(0,212,255,0.14)":"rgba(0,136,170,0.12)",t.fill()),t.beginPath(),t.arc(y.x,y.y,z,0,Math.PI*2),t.fillStyle=Q(g.type),t.fill(),k||M?(t.strokeStyle=r?"#f0f0f0":"#1a1a1a",t.lineWidth=2*a/n.zoom,t.stroke()):x&&i&&(t.strokeStyle=r?"rgba(0,212,255,0.65)":"rgba(0,136,170,0.55)",t.lineWidth=1.8*a/n.zoom,t.stroke()),k||M){const T=Math.max(10*a,11*a/n.zoom);t.font=`${T}px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,t.textAlign="center",t.textBaseline="top";const ie=g.label,de=t.measureText(ie),ue=6*a,fe=3*a,we=y.x-de.width/2-ue,xe=y.y+z+4*a,ke=de.width+ue*2,Me=T+fe*2;t.fillStyle=r?"rgba(10,14,20,0.92)":"rgba(255,255,255,0.95)",t.beginPath(),(W=t.roundRect)==null||W.call(t,we,xe,ke,Me,4*a),t.fill(),t.fillStyle=r?`rgba(240,240,240,${j})`:`rgba(20,20,20,${j})`,t.fillText(ie,y.x,xe+fe)}t.globalAlpha=1}),t.restore()},[]),re=d.useCallback(e=>{const o=m.current;o.nodes.forEach(t=>{var l;if(((l=o.dragNode)==null?void 0:l.id)===t.id)return;const n=o.positions.get(t.id),a=o.anchors.get(t.id),c=o.velocities.get(t.id);!n||!a||!c||(n.x=a.x+Math.sin(e*c.freq+c.seed*11.1)*c.amp,n.y=a.y+Math.cos(e*c.freq*.87+c.seed*17.3)*c.amp)})},[]),ce=d.useCallback(async e=>{ve(e),ee(null),se(null),J(!0),te(!0),m.current.selectedNode=e;try{const o=await pe.brain.memory.get(e.id);ee(o)}catch(o){se(o instanceof Error?o.message:"Failed to load details")}finally{te(!1)}},[]),U=d.useCallback(e=>{const o=p.current;if(!o)return;const t=o.getBoundingClientRect(),n=e.clientX-t.left,a=e.clientY-t.top,c=X(n,a),l=I(c.x,c.y),r=m.current;r.pressNode=l,r.pressX=e.clientX,r.pressY=e.clientY,r.pressT=performance.now(),r.moved=!1,l?r.dragNode=l:r.dragging=!0,r.lastMouse={x:e.clientX,y:e.clientY}},[X,I]),_=d.useCallback(e=>{const o=p.current;if(!o)return;const t=o.getBoundingClientRect(),n=e.clientX-t.left,a=e.clientY-t.top,c=m.current;if(c.pressT&&!c.moved){const l=e.clientX-c.pressX,r=e.clientY-c.pressY;l*l+r*r>16&&(c.moved=!0)}if(c.dragNode){const l=X(n,a),r=c.positions.get(c.dragNode.id),i=c.anchors.get(c.dragNode.id);r&&(r.x=l.x,r.y=l.y),i&&(i.x=l.x,i.y=l.y)}else if(c.dragging){const l=c.dpr;c.pan.x+=(e.clientX-c.lastMouse.x)*l,c.pan.y+=(e.clientY-c.lastMouse.y)*l}else{const l=X(n,a),r=I(l.x,l.y);r!==c.hoveredNode?(c.hoveredNode=r,H(r?{x:e.clientX-t.left+14,y:e.clientY-t.top+14,node:r,connections:K(r.id,c.edges)}:null)):r&&v&&H(i=>i?{...i,x:e.clientX-t.left+14,y:e.clientY-t.top+14}:null)}c.lastMouse={x:e.clientX,y:e.clientY}},[X,I,K,v]),A=d.useCallback(()=>{const e=m.current,o=!e.moved&&e.pressNode!==null&&performance.now()-e.pressT<500,t=e.pressNode;e.dragNode=null,e.dragging=!1,e.pressNode=null,e.pressT=0,e.moved=!1,o&&t&&ce(t)},[ce]),V=d.useCallback(e=>{e.preventDefault();const o=m.current,t=e.deltaY>0?.92:1.08,n=Math.min(3,Math.max(.3,o.zoom*t)),a=n/o.zoom,c=p.current;if(!c)return;const l=c.getBoundingClientRect(),r=(e.clientX-l.left)*o.dpr,i=(e.clientY-l.top)*o.dpr;o.pan.x=r-(r-o.pan.x)*a,o.pan.y=i-(i-o.pan.y)*a,o.zoom=n},[]);d.useEffect(()=>{let e=!1;async function o(){u(!0);try{const t=await pe.brain.graph();if(e)return;const n=t.nodes||[],a=t.edges||[];q(n),B(a);const c=m.current;c.nodes=n,c.edges=a,Y();const l=p.current,r=l?l.width:800,i=l?l.height:600;ne(n,r,i),oe(n,a,r,i)}catch(t){console.error("Failed to load graph data:",t)}e||u(!1)}return o(),()=>{e=!0}},[ne,oe,Y]),d.useEffect(()=>{const e=p.current;if(!e||b)return;Y();let o=!0;const t=a=>{o&&(re(a),ae(a),m.current.animFrame=requestAnimationFrame(t))};m.current.animFrame=requestAnimationFrame(t),e.addEventListener("mousedown",U),e.addEventListener("mousemove",_),e.addEventListener("mouseup",A),e.addEventListener("mouseleave",A),e.addEventListener("wheel",V,{passive:!1});const n=()=>{Y()};return window.addEventListener("resize",n),()=>{o=!1,cancelAnimationFrame(m.current.animFrame),e.removeEventListener("mousedown",U),e.removeEventListener("mousemove",_),e.removeEventListener("mouseup",A),e.removeEventListener("mouseleave",A),e.removeEventListener("wheel",V),window.removeEventListener("resize",n)}},[b,Y,re,ae,U,_,A,V]);const le=F.length?[...new Set(F.map(e=>e.type))].sort():[];return s.jsxs("div",{className:"flex h-full flex-col",children:[s.jsx("div",{className:"flex items-center justify-between border-b border-border/50 bg-background/80 px-6 py-4 backdrop-blur-sm",children:s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx("div",{className:"flex h-9 w-9 items-center justify-center rounded-lg bg-[#00d4ff]/10",children:s.jsx(ge,{className:"h-5 w-5 text-[#00d4ff]"})}),s.jsxs("div",{children:[s.jsx("h1",{className:"text-xl font-semibold tracking-tight text-foreground",children:"Knowledge Graph"}),s.jsx("p",{className:"text-xs text-muted-foreground",children:"Visualize connections in Mercury's memory"})]})]})}),s.jsxs("div",{ref:S,className:"relative flex-1",style:{minHeight:500},children:[b&&s.jsx("div",{className:"absolute inset-0 z-20 flex items-center justify-center bg-background/60 backdrop-blur-sm",children:s.jsxs("div",{className:"flex flex-col items-center gap-3",children:[s.jsx(me,{className:"h-8 w-8 animate-spin text-[#00d4ff]"}),s.jsx("span",{className:"text-sm text-muted-foreground",children:"Loading knowledge graph..."})]})}),!b&&F.length===0&&s.jsx("div",{className:"absolute inset-0 z-20 flex items-center justify-center",children:s.jsxs("div",{className:"flex flex-col items-center gap-3 text-center",children:[s.jsx(ge,{className:"h-12 w-12 text-muted-foreground/40"}),s.jsx("p",{className:"text-sm text-muted-foreground",children:"No knowledge graph data available yet"})]})}),s.jsx("canvas",{ref:p,className:`absolute inset-0 h-full w-full ${v?"cursor-pointer":"cursor-grab"}`}),s.jsx("div",{className:"absolute right-4 top-4 z-10",children:s.jsxs("div",{className:"flex items-center gap-2 rounded-lg border border-border/60 bg-background/90 px-3 py-1.5 shadow-lg backdrop-blur-sm",children:[s.jsx(Fe,{className:"h-4 w-4 text-muted-foreground"}),s.jsx("input",{type:"text",placeholder:"Search nodes...",value:R,onChange:e=>O(e.target.value),className:"w-48 border-none bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground/60"})]})}),le.length>0&&s.jsxs("div",{className:"absolute bottom-4 left-4 z-10 rounded-lg border border-border/60 bg-background/90 px-3 py-2.5 shadow-lg backdrop-blur-sm",children:[s.jsx("p",{className:"mb-1.5 text-[10px] font-medium uppercase tracking-wider text-muted-foreground",children:"Node Types"}),s.jsx("div",{className:"flex flex-col gap-1",children:le.map(e=>s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("span",{className:"inline-block h-2.5 w-2.5 rounded-full",style:{backgroundColor:Q(e)}}),s.jsx("span",{className:"text-[11px] capitalize text-foreground/80",children:e})]},e))})]}),v&&s.jsxs("div",{className:"pointer-events-none absolute z-30 rounded-lg border border-border/60 bg-popover/95 px-3 py-2 shadow-xl backdrop-blur-sm",style:{left:v.x,top:v.y,maxWidth:320,transform:S.current&&v.x+340>S.current.clientWidth?"translateX(calc(-100% - 28px))":void 0},children:[s.jsx("p",{className:"break-words text-sm font-medium leading-snug text-foreground",children:v.node.fullLabel||v.node.label}),s.jsxs("div",{className:"mt-1 flex items-center gap-2",children:[s.jsx("span",{className:"inline-block h-2 w-2 rounded-full",style:{backgroundColor:Q(v.node.type)}}),s.jsx("span",{className:"text-xs capitalize text-muted-foreground",children:v.node.type}),s.jsx("span",{className:"text-xs text-muted-foreground/60",children:"·"}),s.jsxs("span",{className:"text-xs text-muted-foreground",children:[v.connections," connection",v.connections!==1?"s":""]})]}),s.jsx("p",{className:"mt-1.5 text-[10px] uppercase tracking-wider text-muted-foreground/70",children:"Click for details"})]})]}),s.jsx(Te,{open:be,onOpenChange:e=>{J(e),e||(m.current.selectedNode=null)},node:G,memory:ye,loading:Ne,error:je,connections:G?K(G.id,$):0})]})}function Z(p){if(!p)return"—";const S=typeof p=="number"?new Date(p):new Date(p);return Number.isNaN(S.getTime())?String(p):S.toLocaleString()}function Te({open:p,onOpenChange:S,node:b,memory:u,loading:F,error:q,connections:$}){if(!b)return null;const B=Q(b.type),R=b.fullLabel||b.label,O=(u==null?void 0:u.summary)||R,v=u==null?void 0:u.detail;return s.jsx(Ce,{open:p,onOpenChange:S,children:s.jsxs(Ee,{className:"max-w-2xl",children:[s.jsxs(ze,{children:[s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("span",{className:"inline-block h-3 w-3 rounded-full",style:{backgroundColor:B}}),s.jsx("span",{className:"text-xs font-medium uppercase tracking-wider text-muted-foreground",children:b.type})]}),s.jsx(De,{className:"mt-1 break-words text-lg leading-snug",children:O})]}),F&&s.jsxs("div",{className:"flex items-center gap-2 py-4 text-sm text-muted-foreground",children:[s.jsx(me,{className:"h-4 w-4 animate-spin"}),"Loading details…"]}),!F&&u&&s.jsxs("div",{className:"space-y-4",children:[v&&s.jsxs("div",{children:[s.jsx("p",{className:"mb-1 text-[10px] font-medium uppercase tracking-wider text-muted-foreground",children:"Detail"}),s.jsx("p",{className:"whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground/90",children:v})]}),s.jsxs("div",{className:"grid grid-cols-2 gap-3 text-xs sm:grid-cols-3",children:[u.scope&&s.jsx(w,{label:"Scope",value:u.scope}),typeof u.importance=="number"&&s.jsx(w,{label:"Importance",value:u.importance.toFixed(2)}),typeof u.confidence=="number"&&s.jsx(w,{label:"Confidence",value:u.confidence.toFixed(2)}),typeof u.evidenceCount=="number"&&s.jsx(w,{label:"Evidence",value:String(u.evidenceCount)}),s.jsx(w,{label:"Connections",value:String($)}),u.evidenceKind&&s.jsx(w,{label:"Source",value:u.evidenceKind}),s.jsx(w,{label:"Created",value:Z(u.createdAt)}),u.updatedAt&&s.jsx(w,{label:"Updated",value:Z(u.updatedAt)}),u.lastSeenAt&&s.jsx(w,{label:"Last seen",value:Z(u.lastSeenAt)})]}),s.jsx("div",{className:"border-t border-border/40 pt-2",children:s.jsx("p",{className:"font-mono text-[10px] text-muted-foreground/70",children:u.id})})]}),!F&&!u&&s.jsxs("div",{className:"space-y-3",children:[s.jsx("p",{className:"whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground/90",children:R}),s.jsxs("div",{className:"grid grid-cols-2 gap-3 text-xs",children:[s.jsx(w,{label:"Type",value:b.type}),s.jsx(w,{label:"Connections",value:String($)}),typeof b.importance=="number"&&s.jsx(w,{label:"Importance",value:b.importance.toFixed(2)}),typeof b.confidence=="number"&&s.jsx(w,{label:"Confidence",value:b.confidence.toFixed(2)})]}),q&&s.jsxs("p",{className:"text-xs text-muted-foreground/70",children:["Could not load full record: ",q]}),s.jsx("p",{className:"font-mono text-[10px] text-muted-foreground/70",children:b.id})]})]})})}function w({label:p,value:S}){return s.jsxs("div",{children:[s.jsx("p",{className:"text-[10px] font-medium uppercase tracking-wider text-muted-foreground",children:p}),s.jsx("p",{className:"mt-0.5 break-words text-foreground/90",children:S})]})}export{Qe as GraphPage};
7
+ //# sourceMappingURL=Graph-C3eHp3_J.js.map