@apteva/apteva-darwin-arm64 0.4.41 → 0.4.51

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 (94) hide show
  1. package/apteva +0 -0
  2. package/dist/ActivityPage.9v5ha2p7.js +3 -0
  3. package/dist/{ActivityPage.7907h64p.js.map → ActivityPage.9v5ha2p7.js.map} +3 -3
  4. package/dist/ApiDocsPage.qsehxvkb.js +4 -0
  5. package/dist/ApiDocsPage.qsehxvkb.js.map +10 -0
  6. package/dist/App.168av39e.js +221 -0
  7. package/dist/{App.qcknavjz.js.map → App.168av39e.js.map} +15 -15
  8. package/dist/App.2j20h2gt.js +8 -0
  9. package/dist/App.2j20h2gt.js.map +12 -0
  10. package/dist/App.7gj4jht5.js +53 -0
  11. package/dist/{App.apjrmctz.js.map → App.7gj4jht5.js.map} +50 -52
  12. package/dist/App.aexwv4rk.js +4 -0
  13. package/dist/App.aexwv4rk.js.map +10 -0
  14. package/dist/App.anvw0hjc.js +61 -0
  15. package/dist/App.anvw0hjc.js.map +13 -0
  16. package/dist/App.cjcyr5aj.js +4 -0
  17. package/dist/App.cjcyr5aj.js.map +10 -0
  18. package/dist/App.dmvykj97.js +4 -0
  19. package/dist/App.dmvykj97.js.map +10 -0
  20. package/dist/App.e2kkda2a.js +4 -0
  21. package/dist/App.e2kkda2a.js.map +10 -0
  22. package/dist/App.j4ec9k18.js +13 -0
  23. package/dist/App.j4ec9k18.js.map +10 -0
  24. package/dist/{App.7fb3e7mp.js → App.jdkx6eqd.js} +1 -1
  25. package/dist/App.kz3qyyre.js +4 -0
  26. package/dist/{App.myxqcj9x.js.map → App.kz3qyyre.js.map} +3 -3
  27. package/dist/App.sd685nt9.js +4 -0
  28. package/dist/App.sd685nt9.js.map +10 -0
  29. package/dist/App.shfd8tp9.js +20 -0
  30. package/dist/{App.3qw8nben.js.map → App.shfd8tp9.js.map} +6 -4
  31. package/dist/App.wghtdzsk.js +1 -0
  32. package/dist/App.x6x8s16g.js +4 -0
  33. package/dist/App.x6x8s16g.js.map +14 -0
  34. package/dist/App.y2vn8m06.js +4 -0
  35. package/dist/App.y2vn8m06.js.map +10 -0
  36. package/dist/ConnectionsPage.1dyyfqbk.js +3 -0
  37. package/dist/McpPage.xvr8hk05.js +3 -0
  38. package/dist/SettingsPage.5jmnefwe.js +3 -0
  39. package/dist/SkillsPage.jw7carjq.js +3 -0
  40. package/dist/TasksPage.r8txe0e9.js +3 -0
  41. package/dist/TasksPage.r8txe0e9.js.map +9 -0
  42. package/dist/TelemetryPage.pcafk41x.js +3 -0
  43. package/dist/TelemetryPage.pcafk41x.js.map +9 -0
  44. package/dist/TestsPage.pkymr7yt.js +3 -0
  45. package/dist/ThreadsPage.49tgq4fq.js +3 -0
  46. package/dist/apteva-kit.css +1 -1
  47. package/dist/index.html +1 -1
  48. package/dist/styles.css +1 -1
  49. package/package.json +1 -1
  50. package/dist/ActivityPage.7907h64p.js +0 -3
  51. package/dist/ApiDocsPage.k3jjenpq.js +0 -4
  52. package/dist/ApiDocsPage.k3jjenpq.js.map +0 -10
  53. package/dist/App.01nq20st.js +0 -4
  54. package/dist/App.01nq20st.js.map +0 -10
  55. package/dist/App.1maqvamf.js +0 -4
  56. package/dist/App.1maqvamf.js.map +0 -14
  57. package/dist/App.2yjrh32f.js +0 -4
  58. package/dist/App.2yjrh32f.js.map +0 -10
  59. package/dist/App.3qw8nben.js +0 -20
  60. package/dist/App.7sy3wq8c.js +0 -4
  61. package/dist/App.7sy3wq8c.js.map +0 -10
  62. package/dist/App.apjrmctz.js +0 -57
  63. package/dist/App.av6t2yhe.js +0 -4
  64. package/dist/App.av6t2yhe.js.map +0 -10
  65. package/dist/App.jqj5a094.js +0 -46
  66. package/dist/App.jqj5a094.js.map +0 -13
  67. package/dist/App.mc7xf85h.js +0 -4
  68. package/dist/App.mc7xf85h.js.map +0 -10
  69. package/dist/App.myxqcj9x.js +0 -4
  70. package/dist/App.nm91r1mp.js +0 -13
  71. package/dist/App.nm91r1mp.js.map +0 -10
  72. package/dist/App.p02f4ret.js +0 -1
  73. package/dist/App.qcknavjz.js +0 -221
  74. package/dist/App.vc7vfhg4.js +0 -4
  75. package/dist/App.vc7vfhg4.js.map +0 -10
  76. package/dist/App.z4s9zkw5.js +0 -4
  77. package/dist/App.z4s9zkw5.js.map +0 -10
  78. package/dist/ConnectionsPage.z1pw5xe2.js +0 -3
  79. package/dist/McpPage.8vc97z0b.js +0 -3
  80. package/dist/SettingsPage.p61bz8kd.js +0 -3
  81. package/dist/SkillsPage.r9x43g3g.js +0 -3
  82. package/dist/TasksPage.1e0zkye4.js +0 -3
  83. package/dist/TasksPage.1e0zkye4.js.map +0 -9
  84. package/dist/TelemetryPage.p9vbe4gf.js +0 -3
  85. package/dist/TelemetryPage.p9vbe4gf.js.map +0 -9
  86. package/dist/TestsPage.d4xy504e.js +0 -3
  87. package/dist/ThreadsPage.m016am3x.js +0 -3
  88. /package/dist/{App.7fb3e7mp.js.map → App.jdkx6eqd.js.map} +0 -0
  89. /package/dist/{ConnectionsPage.z1pw5xe2.js.map → ConnectionsPage.1dyyfqbk.js.map} +0 -0
  90. /package/dist/{McpPage.8vc97z0b.js.map → McpPage.xvr8hk05.js.map} +0 -0
  91. /package/dist/{SettingsPage.p61bz8kd.js.map → SettingsPage.5jmnefwe.js.map} +0 -0
  92. /package/dist/{SkillsPage.r9x43g3g.js.map → SkillsPage.jw7carjq.js.map} +0 -0
  93. /package/dist/{TestsPage.d4xy504e.js.map → TestsPage.pkymr7yt.js.map} +0 -0
  94. /package/dist/{ThreadsPage.m016am3x.js.map → ThreadsPage.49tgq4fq.js.map} +0 -0
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/web/components/skills/SkillsPage.tsx"],
4
+ "sourcesContent": [
5
+ "import React, { useState, useEffect } from \"react\";\nimport { useAuth, useProjects } from \"../../context\";\nimport { useConfirm, useAlert } from \"../common/Modal\";\nimport { Select } from \"../common/Select\";\n\ninterface Skill {\n id: string;\n name: string;\n description: string;\n content: string;\n license: string | null;\n compatibility: string | null;\n metadata: Record<string, string>;\n allowed_tools: string[];\n source: \"local\" | \"skillsmp\" | \"github\" | \"import\";\n source_url: string | null;\n enabled: boolean;\n project_id: string | null; // null = global\n created_at: string;\n updated_at: string;\n}\n\ninterface MarketplaceSkill {\n id: string;\n name: string;\n description: string;\n content: string;\n author: string;\n version: string;\n license: string | null;\n compatibility: string | null;\n tags: string[];\n downloads: number;\n rating: number;\n repository: string | null;\n}\n\ninterface GitHubSkill {\n name: string;\n description: string;\n path: string;\n size: number;\n downloadUrl: string;\n}\n\nexport function SkillsPage() {\n const { authFetch } = useAuth();\n const { projects, currentProjectId } = useProjects();\n const [skills, setSkills] = useState<Skill[]>([]);\n const [loading, setLoading] = useState(true);\n const [activeTab, setActiveTab] = useState<\"installed\" | \"marketplace\" | \"github\">(\"installed\");\n const [showCreate, setShowCreate] = useState(false);\n const [showImport, setShowImport] = useState(false);\n const [selectedSkill, setSelectedSkill] = useState<Skill | null>(null);\n const { confirm, ConfirmDialog } = useConfirm();\n const { alert, AlertDialog } = useAlert();\n\n const hasProjects = projects.length > 0;\n\n // Marketplace state\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [marketplaceSkills, setMarketplaceSkills] = useState<MarketplaceSkill[]>([]);\n const [marketplaceLoading, setMarketplaceLoading] = useState(false);\n const [installing, setInstalling] = useState<string | null>(null);\n\n // GitHub state\n const [githubRepo, setGithubRepo] = useState(\"\");\n const [githubSkills, setGithubSkills] = useState<GitHubSkill[]>([]);\n const [githubLoading, setGithubLoading] = useState(false);\n const [githubError, setGithubError] = useState<string | null>(null);\n const [githubRepoInfo, setGithubRepoInfo] = useState<{ owner: string; repo: string; url: string } | null>(null);\n const [installingGithub, setInstallingGithub] = useState<string | null>(null);\n const [githubProjectId, setGithubProjectId] = useState<string | null>(\n currentProjectId && currentProjectId !== \"unassigned\" ? currentProjectId : null\n );\n\n // Filter skills based on global project selector\n // When a project is selected, show global + that project's skills\n const filteredSkills = skills.filter(skill => {\n if (!currentProjectId) return true; // \"All Projects\" - show everything\n if (currentProjectId === \"unassigned\") return skill.project_id === null; // Only global\n // Project selected: show global + project-specific\n return skill.project_id === null || skill.project_id === currentProjectId;\n });\n\n const fetchSkills = async () => {\n try {\n const res = await authFetch(\"/api/skills\");\n const data = await res.json();\n setSkills(data.skills || []);\n } catch (e) {\n console.error(\"Failed to fetch skills:\", e);\n }\n setLoading(false);\n };\n\n const searchMarketplace = async (query?: string) => {\n setMarketplaceLoading(true);\n try {\n const q = query !== undefined ? query : searchQuery;\n const endpoint = q\n ? `/api/skills/marketplace/search?q=${encodeURIComponent(q)}`\n : \"/api/skills/marketplace/featured\";\n const res = await authFetch(endpoint);\n const data = await res.json();\n setMarketplaceSkills(data.skills || []);\n } catch (e) {\n console.error(\"Failed to search marketplace:\", e);\n }\n setMarketplaceLoading(false);\n };\n\n useEffect(() => {\n fetchSkills();\n }, [authFetch]);\n\n useEffect(() => {\n if (activeTab === \"marketplace\" && marketplaceSkills.length === 0) {\n searchMarketplace(\"\");\n }\n }, [activeTab]);\n\n const toggleSkill = async (id: string) => {\n try {\n await authFetch(`/api/skills/${id}/toggle`, { method: \"POST\" });\n fetchSkills();\n } catch (e) {\n console.error(\"Failed to toggle skill:\", e);\n }\n };\n\n const deleteSkill = async (id: string) => {\n const confirmed = await confirm(\"Delete this skill?\", { confirmText: \"Delete\", title: \"Delete Skill\" });\n if (!confirmed) return;\n try {\n await authFetch(`/api/skills/${id}`, { method: \"DELETE\" });\n if (selectedSkill?.id === id) {\n setSelectedSkill(null);\n }\n fetchSkills();\n } catch (e) {\n console.error(\"Failed to delete skill:\", e);\n }\n };\n\n const installFromMarketplace = async (skill: MarketplaceSkill) => {\n setInstalling(skill.id);\n try {\n const res = await authFetch(`/api/skills/marketplace/${skill.id}/install`, { method: \"POST\" });\n const data = await res.json();\n if (res.ok) {\n await alert(`Installed \"${skill.name}\" successfully!`, { title: \"Skill Installed\" });\n fetchSkills();\n setActiveTab(\"installed\");\n } else {\n await alert(data.error || \"Failed to install skill\", { title: \"Installation Failed\" });\n }\n } catch (e) {\n console.error(\"Failed to install skill:\", e);\n await alert(\"Failed to install skill\", { title: \"Error\" });\n }\n setInstalling(null);\n };\n\n const isInstalled = (name: string) => skills.some((s) => s.name === name);\n\n // GitHub functions\n const browseGitHubRepo = async (repoInput?: string) => {\n const input = repoInput || githubRepo;\n if (!input.trim()) return;\n\n // Parse repo input: \"owner/repo\" or full URL\n let owner = \"\";\n let repo = \"\";\n\n if (input.includes(\"github.com\")) {\n const match = input.match(/github\\.com\\/([^/]+)\\/([^/]+)/);\n if (match) {\n owner = match[1];\n repo = match[2].replace(/\\.git$/, \"\");\n }\n } else if (input.includes(\"/\")) {\n const parts = input.split(\"/\");\n owner = parts[0];\n repo = parts[1];\n }\n\n if (!owner || !repo) {\n setGithubError(\"Invalid repo format. Use 'owner/repo' or GitHub URL\");\n return;\n }\n\n setGithubLoading(true);\n setGithubError(null);\n setGithubSkills([]);\n setGithubRepoInfo(null);\n\n try {\n const res = await authFetch(`/api/skills/github/${owner}/${repo}`);\n const data = await res.json();\n\n if (!res.ok) {\n setGithubError(data.error || \"Failed to fetch repository\");\n setGithubLoading(false);\n return;\n }\n\n setGithubSkills(data.skills || []);\n setGithubRepoInfo(data.repo || null);\n } catch (e) {\n setGithubError(\"Failed to fetch repository\");\n }\n setGithubLoading(false);\n };\n\n const installFromGitHub = async (skill: GitHubSkill) => {\n if (!githubRepoInfo) return;\n\n setInstallingGithub(skill.name);\n try {\n const res = await authFetch(\"/api/skills/github/install\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n owner: githubRepoInfo.owner,\n repo: githubRepoInfo.repo,\n skillName: skill.name,\n downloadUrl: skill.downloadUrl,\n projectId: githubProjectId,\n }),\n });\n\n const data = await res.json();\n if (res.ok) {\n await alert(`Installed \"${skill.name}\" successfully!`, { title: \"Skill Installed\" });\n fetchSkills();\n } else {\n await alert(data.error || \"Failed to install skill\", { title: \"Installation Failed\", variant: \"error\" });\n }\n } catch (e) {\n await alert(\"Failed to install skill\", { title: \"Error\", variant: \"error\" });\n }\n setInstallingGithub(null);\n };\n\n const installAllFromGitHub = async () => {\n if (!githubRepoInfo || githubSkills.length === 0) return;\n\n const uninstalled = githubSkills.filter(s => !isInstalled(s.name));\n if (uninstalled.length === 0) {\n await alert(\"All skills are already installed\", { title: \"Info\" });\n return;\n }\n\n const confirmed = await confirm(\n `Install ${uninstalled.length} skill(s) from ${githubRepoInfo.owner}/${githubRepoInfo.repo}?`,\n { confirmText: \"Install All\", title: \"Install Skills\" }\n );\n if (!confirmed) return;\n\n let installed = 0;\n for (const skill of uninstalled) {\n setInstallingGithub(skill.name);\n try {\n const res = await authFetch(\"/api/skills/github/install\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n owner: githubRepoInfo.owner,\n repo: githubRepoInfo.repo,\n skillName: skill.name,\n downloadUrl: skill.downloadUrl,\n projectId: githubProjectId,\n }),\n });\n if (res.ok) installed++;\n } catch (e) {\n // Continue with others\n }\n }\n setInstallingGithub(null);\n fetchSkills();\n await alert(`Installed ${installed} of ${uninstalled.length} skills`, { title: \"Installation Complete\" });\n };\n\n return (\n <>\n {ConfirmDialog}\n {AlertDialog}\n <div className=\"flex-1 overflow-auto p-6\">\n <div className=\"max-w-6xl\">\n {/* Header */}\n <div className=\"flex items-center justify-between mb-6\">\n <div>\n <h1 className=\"text-2xl font-semibold mb-1\">Skills</h1>\n <p className=\"text-[var(--color-text-muted)]\">\n Manage agent skills - instructions that teach agents how to perform tasks.\n </p>\n </div>\n {activeTab === \"installed\" && (\n <div className=\"flex gap-2\">\n <button\n onClick={() => setShowImport(true)}\n className=\"bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] text-white px-4 py-2 rounded font-medium transition border border-[var(--color-border-light)]\"\n >\n Import\n </button>\n <button\n onClick={() => setShowCreate(true)}\n className=\"bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-black px-4 py-2 rounded font-medium transition\"\n >\n + Create Skill\n </button>\n </div>\n )}\n </div>\n\n {/* Tabs */}\n <div className=\"flex gap-1 mb-6 bg-[var(--color-surface)] card p-1 w-fit\">\n <button\n onClick={() => setActiveTab(\"installed\")}\n className={`px-4 py-2 rounded text-sm font-medium transition ${\n activeTab === \"installed\"\n ? \"bg-[var(--color-surface-raised)] text-white\"\n : \"text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]\"\n }`}\n >\n Installed ({filteredSkills.length})\n </button>\n <button\n onClick={() => setActiveTab(\"github\")}\n className={`px-4 py-2 rounded text-sm font-medium transition ${\n activeTab === \"github\"\n ? \"bg-[var(--color-surface-raised)] text-white\"\n : \"text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]\"\n }`}\n >\n Browse GitHub\n </button>\n <button\n onClick={() => setActiveTab(\"marketplace\")}\n className={`px-4 py-2 rounded text-sm font-medium transition ${\n activeTab === \"marketplace\"\n ? \"bg-[var(--color-surface-raised)] text-white\"\n : \"text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]\"\n }`}\n >\n Marketplace\n </button>\n </div>\n\n {/* Installed Tab */}\n {activeTab === \"installed\" && (\n <>\n {loading ? (\n <div className=\"text-[var(--color-text-muted)]\">Loading skills...</div>\n ) : skills.length === 0 ? (\n <div className=\"text-center py-20 text-[var(--color-text-muted)]\">\n <p className=\"text-lg\">No skills installed</p>\n <p className=\"text-sm mt-1\">Create a skill or browse the marketplace</p>\n <button\n onClick={() => setActiveTab(\"marketplace\")}\n className=\"mt-4 bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-black px-4 py-2 rounded font-medium transition\"\n >\n Browse Marketplace\n </button>\n </div>\n ) : filteredSkills.length === 0 ? (\n <div className=\"bg-[var(--color-surface)] card p-6 text-center\">\n <p className=\"text-[var(--color-text-muted)]\">No skills match this filter.</p>\n </div>\n ) : (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {filteredSkills.map((skill) => {\n const project = hasProjects && skill.project_id\n ? projects.find(p => p.id === skill.project_id)\n : null;\n return (\n <SkillCard\n key={skill.id}\n skill={skill}\n project={project}\n onToggle={() => toggleSkill(skill.id)}\n onDelete={() => deleteSkill(skill.id)}\n onView={() => setSelectedSkill(skill)}\n />\n );\n })}\n </div>\n )}\n </>\n )}\n\n {/* GitHub Tab */}\n {activeTab === \"github\" && (\n <div className=\"space-y-6\">\n {/* Search */}\n <form\n onSubmit={(e) => {\n e.preventDefault();\n browseGitHubRepo();\n }}\n className=\"flex gap-2\"\n >\n <input\n type=\"text\"\n value={githubRepo}\n onChange={(e) => setGithubRepo(e.target.value)}\n placeholder=\"Enter GitHub repo (e.g., WordPress/agent-skills)\"\n className=\"flex-1 bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg px-4 py-3 focus:outline-none focus:border-[var(--color-accent)]\"\n />\n <button\n type=\"submit\"\n disabled={githubLoading}\n className=\"bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] disabled:opacity-50 text-black px-6 py-3 rounded-lg font-medium transition\"\n >\n {githubLoading ? \"...\" : \"Browse\"}\n </button>\n </form>\n\n {/* Project Scope Selector */}\n {hasProjects && githubSkills.length > 0 && (\n <div className=\"flex items-center gap-3 p-3 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded-lg\">\n <span className=\"text-sm text-[var(--color-text-muted)]\">Install to:</span>\n <Select\n value={githubProjectId || \"\"}\n onChange={(value) => setGithubProjectId(value || null)}\n options={[\n { value: \"\", label: \"Global (all projects)\" },\n ...projects.map(p => ({ value: p.id, label: p.name }))\n ]}\n placeholder=\"Select scope...\"\n />\n </div>\n )}\n\n {/* Error */}\n {githubError && (\n <div className=\"text-red-400 text-sm p-3 bg-red-500/10 border border-red-500/20 rounded-lg\">\n {githubError}\n </div>\n )}\n\n {/* Repo Info Header */}\n {githubRepoInfo && githubSkills.length > 0 && (\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <a\n href={githubRepoInfo.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-[var(--color-accent)] hover:underline font-medium\"\n >\n {githubRepoInfo.owner}/{githubRepoInfo.repo}\n </a>\n <span className=\"text-sm text-[var(--color-text-muted)]\">\n {githubSkills.length} skill{githubSkills.length !== 1 ? \"s\" : \"\"} found\n </span>\n </div>\n {githubSkills.some(s => !isInstalled(s.name)) && (\n <button\n onClick={installAllFromGitHub}\n disabled={!!installingGithub}\n className=\"text-sm bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-accent)] px-4 py-2 rounded transition disabled:opacity-50\"\n >\n Install All\n </button>\n )}\n </div>\n )}\n\n {/* Loading */}\n {githubLoading && (\n <div className=\"text-center py-8 text-[var(--color-text-muted)]\">\n Fetching skills from repository...\n </div>\n )}\n\n {/* Empty State */}\n {!githubLoading && !githubRepoInfo && !githubError && (\n <div className=\"bg-[var(--color-surface)] card p-8 text-center\">\n <div className=\"text-4xl mb-4\">📦</div>\n <h3 className=\"text-lg font-medium mb-2\">Browse Skills from GitHub</h3>\n <p className=\"text-[var(--color-text-muted)] mb-6 max-w-md mx-auto\">\n Enter a GitHub repository to browse and install skills. Skills are markdown files with instructions that teach agents how to perform specific tasks.\n </p>\n <div className=\"flex flex-wrap gap-2 justify-center\">\n {[\n { label: \"WordPress Skills\", repo: \"WordPress/agent-skills\" },\n ].map(({ label, repo }) => (\n <button\n key={repo}\n onClick={() => {\n setGithubRepo(repo);\n browseGitHubRepo(repo);\n }}\n className=\"text-sm bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-accent)] px-3 py-1.5 rounded transition\"\n >\n {label}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* No Skills Found */}\n {!githubLoading && githubRepoInfo && githubSkills.length === 0 && (\n <div className=\"text-center py-8 text-[var(--color-text-muted)]\">\n No skills found in this repository. Skills should be in subdirectories with a SKILL.md file.\n </div>\n )}\n\n {/* Skills Grid */}\n {githubSkills.length > 0 && (\n <div className=\"grid gap-4 md:grid-cols-2\">\n {githubSkills.map((skill) => {\n const installed = isInstalled(skill.name);\n const isInstalling = installingGithub === skill.name;\n\n return (\n <div\n key={skill.name}\n className={`bg-[var(--color-surface)] border rounded-lg p-4 transition ${\n installed ? \"border-green-500/30\" : \"border-[var(--color-border)] hover:border-[var(--color-border-light)]\"\n }`}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <h3 className=\"font-medium truncate\">{skill.name}</h3>\n {installed && (\n <span className=\"text-xs text-green-400\">✓ Installed</span>\n )}\n </div>\n <p className=\"text-sm text-[var(--color-text-muted)] mt-1 line-clamp-2\">\n {skill.description || \"No description\"}\n </p>\n <div className=\"flex items-center gap-2 mt-2 text-xs text-[var(--color-text-faint)]\">\n <span>{(skill.size / 1024).toFixed(1)}KB</span>\n <span className=\"px-1.5 py-0.5 rounded bg-blue-500/10 text-blue-400\">\n GitHub\n </span>\n </div>\n </div>\n <div className=\"flex-shrink-0\">\n {installed ? (\n <span className=\"text-xs text-[var(--color-text-faint)] px-3 py-1.5\">Added</span>\n ) : (\n <button\n onClick={() => installFromGitHub(skill)}\n disabled={isInstalling}\n className=\"text-sm bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-accent)] px-3 py-1.5 rounded transition disabled:opacity-50\"\n >\n {isInstalling ? \"Installing...\" : \"Install\"}\n </button>\n )}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {/* Info */}\n <div className=\"p-4 bg-[var(--color-surface)] card text-sm text-[var(--color-text-muted)]\">\n <p>\n Skills are sourced from GitHub repositories. Each skill should be in its own directory with a{\" \"}\n <code className=\"text-[var(--color-text-secondary)] bg-[var(--color-bg)] px-1 rounded\">SKILL.md</code> file containing instructions.\n </p>\n </div>\n </div>\n )}\n\n {/* Marketplace Tab */}\n {activeTab === \"marketplace\" && (\n <>\n {/* Search */}\n <div className=\"mb-6\">\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n onKeyDown={(e) => e.key === \"Enter\" && searchMarketplace()}\n placeholder=\"Search skills...\"\n className=\"flex-1 bg-[var(--color-surface)] border border-[var(--color-border)] rounded px-4 py-2 focus:outline-none focus:border-[var(--color-accent)]\"\n />\n <button\n onClick={() => searchMarketplace()}\n disabled={marketplaceLoading}\n className=\"bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] text-white px-4 py-2 rounded font-medium transition border border-[var(--color-border-light)]\"\n >\n {marketplaceLoading ? \"...\" : \"Search\"}\n </button>\n </div>\n </div>\n\n {marketplaceLoading ? (\n <div className=\"text-[var(--color-text-muted)]\">Loading...</div>\n ) : marketplaceSkills.length === 0 ? (\n <div className=\"text-center py-20 text-[var(--color-text-muted)]\">\n <p className=\"text-lg\">No skills found</p>\n <p className=\"text-sm mt-1\">Try a different search term</p>\n </div>\n ) : (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {marketplaceSkills.map((skill) => (\n <MarketplaceSkillCard\n key={skill.id}\n skill={skill}\n installed={isInstalled(skill.name)}\n installing={installing === skill.id}\n onInstall={() => installFromMarketplace(skill)}\n />\n ))}\n </div>\n )}\n </>\n )}\n </div>\n </div>\n\n {/* Create Modal */}\n {showCreate && (\n <CreateSkillModal\n authFetch={authFetch}\n onClose={() => setShowCreate(false)}\n onCreated={() => {\n setShowCreate(false);\n fetchSkills();\n }}\n projects={hasProjects ? projects : undefined}\n defaultProjectId={currentProjectId && currentProjectId !== \"unassigned\" ? currentProjectId : null}\n />\n )}\n\n {/* Import Modal */}\n {showImport && (\n <ImportSkillModal\n authFetch={authFetch}\n onClose={() => setShowImport(false)}\n onImported={() => {\n setShowImport(false);\n fetchSkills();\n }}\n />\n )}\n\n {/* View/Edit Modal */}\n {selectedSkill && (\n <ViewSkillModal\n skill={selectedSkill}\n authFetch={authFetch}\n onClose={() => setSelectedSkill(null)}\n onUpdated={() => {\n setSelectedSkill(null);\n fetchSkills();\n }}\n />\n )}\n </>\n );\n}\n\nfunction SkillCard({\n skill,\n project,\n onToggle,\n onDelete,\n onView,\n}: {\n skill: Skill;\n project?: { id: string; name: string; color: string } | null;\n onToggle: () => void;\n onDelete: () => void;\n onView: () => void;\n}) {\n const sourceLabel = {\n local: \"Local\",\n skillsmp: \"SkillsMP\",\n github: \"GitHub\",\n import: \"Imported\",\n }[skill.source];\n\n // Scope badge: Global or Project name\n const getScopeBadge = () => {\n if (project) {\n return (\n <span\n className=\"text-xs px-1.5 py-0.5 rounded\"\n style={{ backgroundColor: `${project.color}20`, color: project.color }}\n >\n {project.name}\n </span>\n );\n }\n if (skill.project_id === null) {\n return (\n <span className=\"text-xs text-[var(--color-text-muted)] bg-[var(--color-surface-raised)] px-1.5 py-0.5 rounded\">\n Global\n </span>\n );\n }\n return null;\n };\n\n return (\n <div\n className={`bg-[var(--color-surface)] rounded-lg p-5 border transition cursor-pointer ${\n skill.enabled ? \"border-[var(--color-border)]\" : \"border-[var(--color-border)] opacity-60\"\n } hover:border-[var(--color-border-light)]`}\n onClick={onView}\n >\n <div className=\"flex items-start justify-between mb-3\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <h3 className=\"font-semibold text-lg truncate\">{skill.name}</h3>\n {getScopeBadge()}\n </div>\n <p className=\"text-xs text-[var(--color-text-muted)] flex items-center gap-2 mt-0.5\">\n <span className={`px-1.5 py-0.5 rounded text-[10px] ${\n skill.source === \"skillsmp\" ? \"bg-purple-500/20 text-purple-400\" :\n skill.source === \"github\" ? \"bg-blue-500/20 text-blue-400\" :\n \"bg-[var(--color-surface-raised)] text-[var(--color-text-secondary)]\"\n }`}>\n {sourceLabel}\n </span>\n {skill.metadata?.version && <span>v{skill.metadata.version}</span>}\n </p>\n </div>\n <button\n onClick={(e) => {\n e.stopPropagation();\n onToggle();\n }}\n className={`w-10 h-5 rounded-full transition-colors relative ${\n skill.enabled ? \"bg-[var(--color-accent)]\" : \"bg-[var(--color-surface-raised)]\"\n }`}\n >\n <span\n className={`absolute top-0.5 w-4 h-4 rounded-full bg-white transition-transform ${\n skill.enabled ? \"left-5\" : \"left-0.5\"\n }`}\n />\n </button>\n </div>\n\n <p className=\"text-sm text-[var(--color-text-secondary)] line-clamp-2 mb-4\">{skill.description}</p>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"flex gap-1 flex-wrap\">\n {skill.allowed_tools.slice(0, 2).map((tool) => (\n <span key={tool} className=\"text-xs bg-[var(--color-surface-raised)] px-2 py-0.5 rounded text-[var(--color-text-muted)]\">\n {tool}\n </span>\n ))}\n {skill.allowed_tools.length > 2 && (\n <span className=\"text-xs text-[var(--color-text-muted)]\">+{skill.allowed_tools.length - 2}</span>\n )}\n </div>\n <button\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n className=\"text-red-400 hover:text-red-300 text-sm\"\n >\n Delete\n </button>\n </div>\n </div>\n );\n}\n\nfunction MarketplaceSkillCard({\n skill,\n installed,\n installing,\n onInstall,\n}: {\n skill: MarketplaceSkill;\n installed: boolean;\n installing: boolean;\n onInstall: () => void;\n}) {\n return (\n <div className=\"bg-[var(--color-surface)] rounded-lg p-5 border border-[var(--color-border)] hover:border-[var(--color-border-light)] transition\">\n <div className=\"flex items-start justify-between mb-3\">\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"font-semibold text-lg truncate\">{skill.name}</h3>\n <p className=\"text-xs text-[var(--color-text-muted)] mt-0.5\">\n by {skill.author} · v{skill.version}\n </p>\n </div>\n <div className=\"flex items-center gap-1 text-yellow-500 text-sm\">\n ★ {skill.rating.toFixed(1)}\n </div>\n </div>\n\n <p className=\"text-sm text-[var(--color-text-secondary)] line-clamp-2 mb-4\">{skill.description}</p>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"flex gap-1 flex-wrap\">\n {skill.tags.slice(0, 3).map((tag) => (\n <span key={tag} className=\"text-xs bg-[var(--color-surface-raised)] px-2 py-0.5 rounded text-[var(--color-text-muted)]\">\n {tag}\n </span>\n ))}\n </div>\n {installed ? (\n <span className=\"text-green-400 text-sm\">✓ Installed</span>\n ) : (\n <button\n onClick={onInstall}\n disabled={installing}\n className=\"bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] disabled:opacity-50 text-black px-3 py-1 rounded text-sm font-medium transition\"\n >\n {installing ? \"Installing...\" : \"Install\"}\n </button>\n )}\n </div>\n\n <div className=\"mt-3 text-xs text-[var(--color-text-faint)]\">\n {skill.downloads.toLocaleString()} downloads\n </div>\n </div>\n );\n}\n\nfunction CreateSkillModal({\n authFetch,\n onClose,\n onCreated,\n projects,\n defaultProjectId,\n}: {\n authFetch: (url: string, options?: RequestInit) => Promise<Response>;\n onClose: () => void;\n onCreated: () => void;\n projects?: Array<{ id: string; name: string; color: string }>;\n defaultProjectId?: string | null;\n}) {\n const [name, setName] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [content, setContent] = useState(\"\");\n const [projectId, setProjectId] = useState<string | null>(defaultProjectId || null);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const hasProjects = projects && projects.length > 0;\n\n const handleSave = async () => {\n if (!name || !description || !content) {\n setError(\"All fields are required\");\n return;\n }\n\n setSaving(true);\n setError(null);\n\n try {\n const body: Record<string, unknown> = {\n name,\n description,\n content, // Just the instructions, not wrapped in frontmatter\n source: \"local\",\n };\n\n // Add project_id if selected\n if (projectId) {\n body.project_id = projectId;\n }\n\n const res = await authFetch(\"/api/skills\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n const data = await res.json();\n if (!res.ok) {\n setError(data.error || \"Failed to create skill\");\n setSaving(false);\n return;\n }\n\n onCreated();\n } catch (e) {\n setError(\"Failed to create skill\");\n setSaving(false);\n }\n };\n\n return (\n <div className=\"fixed inset-0 bg-black/60 flex items-center justify-center z-50 p-4\" onClick={onClose}>\n <div\n className=\"bg-[var(--color-surface)] card w-full max-w-2xl max-h-[90vh] overflow-auto\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"p-6 border-b border-[var(--color-border)]\">\n <h2 className=\"text-xl font-semibold\">Create Skill</h2>\n </div>\n\n <div className=\"p-6 space-y-4\">\n {error && (\n <div className=\"bg-red-500/10 border border-red-500/30 rounded p-3 text-red-400 text-sm\">\n {error}\n </div>\n )}\n\n <div>\n <label className=\"block text-sm text-[var(--color-text-secondary)] mb-1\">Name</label>\n <input\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, \"-\"))}\n placeholder=\"my-skill-name\"\n className=\"w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 focus:outline-none focus:border-[var(--color-accent)]\"\n />\n <p className=\"text-xs text-[var(--color-text-faint)] mt-1\">Lowercase letters, numbers, and hyphens only</p>\n </div>\n\n <div>\n <label className=\"block text-sm text-[var(--color-text-secondary)] mb-1\">Description</label>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"What this skill does and when to use it...\"\n className=\"w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 focus:outline-none focus:border-[var(--color-accent)]\"\n />\n </div>\n\n {/* Project Scope - only show when projects exist */}\n {hasProjects && (\n <div>\n <label className=\"block text-sm text-[var(--color-text-secondary)] mb-1\">Scope</label>\n <Select\n value={projectId || \"\"}\n onChange={(value) => setProjectId(value || null)}\n options={[\n { value: \"\", label: \"Global (all projects)\" },\n ...projects!.map(p => ({ value: p.id, label: p.name }))\n ]}\n placeholder=\"Select scope...\"\n />\n <p className=\"text-xs text-[var(--color-text-faint)] mt-1\">\n Global skills are available to all agents. Project-scoped skills are only available to agents in that project.\n </p>\n </div>\n )}\n\n <div>\n <label className=\"block text-sm text-[var(--color-text-secondary)] mb-1\">Instructions (Markdown)</label>\n <textarea\n value={content}\n onChange={(e) => setContent(e.target.value)}\n placeholder=\"# Skill Instructions&#10;&#10;Write detailed instructions here...\"\n rows={12}\n className=\"w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 focus:outline-none focus:border-[var(--color-accent)] font-mono text-sm\"\n />\n </div>\n </div>\n\n <div className=\"p-6 border-t border-[var(--color-border)] flex justify-end gap-3\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-[var(--color-text-secondary)] hover:text-white transition\"\n >\n Cancel\n </button>\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] disabled:opacity-50 text-black px-4 py-2 rounded font-medium transition\"\n >\n {saving ? \"Creating...\" : \"Create Skill\"}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nfunction ImportSkillModal({\n authFetch,\n onClose,\n onImported,\n}: {\n authFetch: (url: string, options?: RequestInit) => Promise<Response>;\n onClose: () => void;\n onImported: () => void;\n}) {\n const [content, setContent] = useState(\"\");\n const [importing, setImporting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const handleImport = async () => {\n if (!content.trim()) {\n setError(\"Paste SKILL.md content\");\n return;\n }\n\n setImporting(true);\n setError(null);\n\n try {\n const res = await authFetch(\"/api/skills/import\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ content }),\n });\n\n const data = await res.json();\n if (!res.ok) {\n setError(data.error || \"Failed to import skill\");\n setImporting(false);\n return;\n }\n\n onImported();\n } catch (e) {\n setError(\"Failed to import skill\");\n setImporting(false);\n }\n };\n\n return (\n <div className=\"fixed inset-0 bg-black/60 flex items-center justify-center z-50 p-4\" onClick={onClose}>\n <div\n className=\"bg-[var(--color-surface)] card w-full max-w-2xl max-h-[90vh] overflow-auto\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"p-6 border-b border-[var(--color-border)]\">\n <h2 className=\"text-xl font-semibold\">Import Skill</h2>\n <p className=\"text-sm text-[var(--color-text-muted)] mt-1\">Paste the contents of a SKILL.md file</p>\n </div>\n\n <div className=\"p-6 space-y-4\">\n {error && (\n <div className=\"bg-red-500/10 border border-red-500/30 rounded p-3 text-red-400 text-sm\">\n {error}\n </div>\n )}\n\n <textarea\n value={content}\n onChange={(e) => setContent(e.target.value)}\n placeholder={`---\nname: skill-name\ndescription: What this skill does...\n---\n\n# Instructions\n\nYour skill instructions here...`}\n rows={16}\n className=\"w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 focus:outline-none focus:border-[var(--color-accent)] font-mono text-sm\"\n />\n </div>\n\n <div className=\"p-6 border-t border-[var(--color-border)] flex justify-end gap-3\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-[var(--color-text-secondary)] hover:text-white transition\"\n >\n Cancel\n </button>\n <button\n onClick={handleImport}\n disabled={importing}\n className=\"bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] disabled:opacity-50 text-black px-4 py-2 rounded font-medium transition\"\n >\n {importing ? \"Importing...\" : \"Import Skill\"}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nfunction ViewSkillModal({\n skill,\n authFetch,\n onClose,\n onUpdated,\n}: {\n skill: Skill;\n authFetch: (url: string, options?: RequestInit) => Promise<Response>;\n onClose: () => void;\n onUpdated: () => void;\n}) {\n const [editing, setEditing] = useState(false);\n const [content, setContent] = useState(skill.content);\n const [saving, setSaving] = useState(false);\n\n const handleSave = async () => {\n setSaving(true);\n try {\n await authFetch(`/api/skills/${skill.id}`, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ content }),\n });\n onUpdated();\n } catch (e) {\n console.error(\"Failed to save:\", e);\n }\n setSaving(false);\n };\n\n const handleExport = async () => {\n try {\n const res = await authFetch(`/api/skills/${skill.id}/export`);\n const text = await res.text();\n const blob = new Blob([text], { type: \"text/markdown\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `${skill.name}-SKILL.md`;\n a.click();\n URL.revokeObjectURL(url);\n } catch (e) {\n console.error(\"Failed to export:\", e);\n }\n };\n\n return (\n <div className=\"fixed inset-0 bg-black/60 flex items-center justify-center z-50 p-4\" onClick={onClose}>\n <div\n className=\"bg-[var(--color-surface)] card w-full max-w-3xl max-h-[90vh] overflow-auto\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"p-6 border-b border-[var(--color-border)] flex items-center justify-between\">\n <div>\n <h2 className=\"text-xl font-semibold\">{skill.name}</h2>\n <p className=\"text-sm text-[var(--color-text-muted)] mt-0.5\">{skill.description}</p>\n </div>\n <div className=\"flex gap-2\">\n <button\n onClick={handleExport}\n className=\"text-sm text-[var(--color-text-secondary)] hover:text-white transition px-3 py-1 rounded border border-[var(--color-border-light)]\"\n >\n Export\n </button>\n <button\n onClick={() => setEditing(!editing)}\n className=\"text-sm text-[var(--color-text-secondary)] hover:text-white transition px-3 py-1 rounded border border-[var(--color-border-light)]\"\n >\n {editing ? \"View\" : \"Edit\"}\n </button>\n </div>\n </div>\n\n <div className=\"p-6\">\n {editing ? (\n <textarea\n value={content}\n onChange={(e) => setContent(e.target.value)}\n rows={20}\n className=\"w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 focus:outline-none focus:border-[var(--color-accent)] font-mono text-sm\"\n />\n ) : (\n <pre className=\"bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded p-4 font-mono text-sm overflow-auto max-h-[60vh] whitespace-pre-wrap\">\n {skill.content}\n </pre>\n )}\n </div>\n\n <div className=\"p-6 border-t border-[var(--color-border)] flex justify-between\">\n <div className=\"text-xs text-[var(--color-text-faint)]\">\n {skill.source !== \"local\" && skill.source_url && (\n <a href={skill.source_url} target=\"_blank\" rel=\"noopener noreferrer\" className=\"text-[var(--color-accent)] hover:underline\">\n View source →\n </a>\n )}\n </div>\n <div className=\"flex gap-3\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-[var(--color-text-secondary)] hover:text-white transition\"\n >\n Close\n </button>\n {editing && (\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] disabled:opacity-50 text-black px-4 py-2 rounded font-medium transition\"\n >\n {saving ? \"Saving...\" : \"Save Changes\"}\n </button>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "F89C130753CEA5A864756E2164756E21",
9
+ "names": []
10
+ }
@@ -1,4 +1,4 @@
1
- import{X as n,aa as e}from"./App.3qw8nben.js";var o=n(e(),1);function t({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function i({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function a({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function s({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function c({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:[o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"},void 0,!1,void 0,this),o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function l({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function u({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function h({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:[o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"},void 0,!1,void 0,this),o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function d({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function k({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function p({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function v({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function L({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function M({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function m({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function g({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function f({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function w({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function I({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function C({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function W({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function P({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 4v16m8-8H4"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function B({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:[o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h5M20 20v-5h-5"},void 0,!1,void 0,this),o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M20.49 9A9 9 0 005.64 5.64L4 4m16 16l-1.64-1.64A9 9 0 013.51 15"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function N({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:[o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 8v4l3 3"},void 0,!1,void 0,this),o.jsxDEV("circle",{cx:"12",cy:"12",r:"9",strokeWidth:2},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function z({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:[o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"},void 0,!1,void 0,this),o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 14l2 2 4-4"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function H({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function A({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}
1
+ import{X as n,aa as e}from"./App.shfd8tp9.js";var o=n(e(),1);function t({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function i({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function a({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function s({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function c({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:[o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"},void 0,!1,void 0,this),o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function l({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function u({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function h({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:[o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"},void 0,!1,void 0,this),o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function d({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function k({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function p({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function v({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function L({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function M({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function m({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function g({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function f({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function w({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function I({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function C({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function W({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function P({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 4v16m8-8H4"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function B({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:[o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h5M20 20v-5h-5"},void 0,!1,void 0,this),o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M20.49 9A9 9 0 005.64 5.64L4 4m16 16l-1.64-1.64A9 9 0 013.51 15"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function N({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:[o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 8v4l3 3"},void 0,!1,void 0,this),o.jsxDEV("circle",{cx:"12",cy:"12",r:"9",strokeWidth:2},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function z({className:r="w-4 h-4"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:[o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"},void 0,!1,void 0,this),o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 14l2 2 4-4"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function H({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function A({className:r="w-5 h-5"}){return o.jsxDEV("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:o.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}
2
2
  export{t as k,i as l,a as m,s as n,c as o,l as p,u as q,h as r,d as s,k as t,p as u,v,L as w,M as x,m as y,g as z,f as A,w as B,I as C,C as D,W as E,P as F,B as G,N as H,z as I,H as J,A as K};
3
3
 
4
4
  //# debugId=AF49E0E4F6CBFBFF64756E2164756E21
@@ -0,0 +1,4 @@
1
+ import{$ as Rq,X as c,aa as Gq,ja as Jq}from"./App.shfd8tp9.js";var Q=c(Rq(),1);var q=c(Gq(),1);function C(H){return H.authSchemes.some((J)=>J.toUpperCase()==="API_KEY")}function Qq(H){return H.authSchemes.some((J)=>J.toUpperCase()==="OAUTH2")}function Lq(H){return C(H)&&Qq(H)}function wq({providerId:H="composio",projectId:J,onConnectionComplete:U,onBrowseTriggers:F,hideMcpConfig:y}){let{authFetch:Z}=Jq(),[A,I]=Q.useState([]),[k,P]=Q.useState([]),[S,h]=Q.useState(!0),[R,Wq]=Q.useState(""),[g,O]=Q.useState(null),[b,D]=Q.useState(null),[s,_]=Q.useState(null),[L,M]=Q.useState(null),[X,w]=Q.useState(null),[f,u]=Q.useState(""),[V,x]=Q.useState({}),[T,E]=Q.useState(null),[v,n]=Q.useState(""),[o,l]=Q.useState(!1),[t,j]=Q.useState(null),[r,i]=Q.useState(null),N=Q.useCallback(async()=>{h(!0),_(null);let z=J&&J!=="unassigned"?`?project_id=${J}`:"";try{let[G,W]=await Promise.all([Z(`/api/integrations/${H}/apps${z}`),Z(`/api/integrations/${H}/connected${z}`)]),Y=await G.json(),$=await W.json();I(Y.apps||[]),P($.accounts||[])}catch(G){console.error("Failed to fetch integrations:",G),_("Failed to load integrations")}h(!1)},[Z,H,J]);Q.useEffect(()=>{N()},[N]),Q.useEffect(()=>{if(new URLSearchParams(window.location.search).get("connected"))window.history.replaceState({},"",window.location.pathname),N(),U?.()},[N,U]),Q.useEffect(()=>{if(!b?.connectionId)return;let z=J&&J!=="unassigned"?`?project_id=${J}`:"",G=setInterval(async()=>{try{let Y=await(await Z(`/api/integrations/${H}/connection/${b.connectionId}${z}`)).json();if(Y.connection?.status==="active")D(null),O(null),N(),U?.();else if(Y.connection?.status==="failed")D(null),O(null),_(`Connection to ${b.appSlug} failed`)}catch(W){}},2000);return()=>clearInterval(G)},[b,Z,H,J,N,U]);let m=async(z,G,W,Y)=>{if(Lq(z)&&!G&&!Y&&!W){M({app:z});return}if(C(z)&&!G&&!Y&&!W){w({app:z}),u(""),x({});return}O(z.slug),_(null);try{let $={appSlug:z.slug};if(Y&&Object.keys(Y).length>0)$.credentials={authScheme:"API_KEY",fields:Y};else if(G)$.credentials={authScheme:"API_KEY",apiKey:G};let kq=J&&J!=="unassigned"?`?project_id=${J}`:"",qq=await Z(`/api/integrations/${H}/connect${kq}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify($)}),B=await qq.json();if(!qq.ok){_(B.error||"Failed to initiate connection"),O(null),w(null);return}if(B.status==="active"||!B.redirectUrl){O(null),w(null),N(),U?.();return}if(B.redirectUrl){D({appSlug:z.slug,connectionId:B.connectionId});let zq=window.open(B.redirectUrl,`connect-${z.slug}`,"width=600,height=700,left=200,top=100");if(!zq||zq.closed)window.location.href=B.redirectUrl}}catch($){_(`Failed to connect: ${$}`),O(null),w(null)}},Xq=(z)=>{if(z.preventDefault(),!X)return;if(X.app.credentialFields&&X.app.credentialFields.length>0){if(!X.app.credentialFields.filter(($)=>$.required!==!1).every(($)=>V[$.name]?.trim()))return;m(X.app,void 0,!1,V)}else{if(!f.trim())return;m(X.app,f.trim())}},Yq=async(z)=>{let G=J&&J!=="unassigned"?`?project_id=${J}`:"";try{let W=await Z(`/api/integrations/${H}/connection/${z.id}${G}`,{method:"DELETE"});if(W.ok)N();else{let Y=await W.json();_(Y.error||"Failed to disconnect")}}catch(W){_(`Failed to disconnect: ${W}`)}},Zq=(z)=>{E({app:z}),n(`${z.name} MCP`),j(null)},_q=async()=>{if(!T||!v.trim())return;l(!0),_(null);try{let z=J&&J!=="unassigned"?`?project_id=${J}`:"",G=await Z(`/api/integrations/${H}/configs${z}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:v.replace(/[^a-zA-Z0-9\s-]/g,"").substring(0,30),toolkitSlug:T.app.slug})}),W=await G.json();if(!G.ok){_(W.error||"Failed to create MCP config"),l(!1);return}let Y=!1;if(W.config?.id)try{Y=(await Z(`/api/integrations/${H}/configs/${W.config.id}/add${z}`,{method:"POST"})).ok}catch{}j(v),U?.()}catch(z){_(`Failed to create MCP config: ${z}`)}finally{l(!1)}},$q=(z)=>{i({message:`Disconnect ${z.appName}?`,onConfirm:()=>{Yq(z),i(null)}})},a=(z)=>{return k.some((G)=>G.status==="active"&&(G.appId===z.slug||z.providerSlug&&G.appId===z.providerSlug))},p=(z)=>{return k.find((G)=>G.appId===z.slug&&G.status==="active")||z.providerSlug&&k.find((G)=>G.appId===z.providerSlug&&G.status==="active")||k.find((G)=>G.appId===z.slug)||z.providerSlug&&k.find((G)=>G.appId===z.providerSlug)||void 0},e=A.filter((z)=>{if(!R)return!0;let G=R.toLowerCase();return z.name.toLowerCase().includes(G)||z.slug.toLowerCase().includes(G)||z.description?.toLowerCase().includes(G)||z.categories.some((W)=>W.toLowerCase().includes(G))}),d=e.filter((z)=>a(z)),K=e.filter((z)=>!a(z));if(S)return q.jsxDEV("div",{className:"text-center py-8 text-[var(--color-text-muted)]",children:"Loading apps..."},void 0,!1,void 0,this);return q.jsxDEV("div",{className:"space-y-6",children:[L&&q.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:q.jsxDEV("div",{className:"bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg p-6 w-full max-w-md mx-4",children:[q.jsxDEV("div",{className:"flex items-center gap-3 mb-4",children:[L.app.logo&&q.jsxDEV("img",{src:L.app.logo,alt:L.app.name,className:"w-10 h-10 object-contain"},void 0,!1,void 0,this),q.jsxDEV("div",{children:[q.jsxDEV("h3",{className:"font-medium",children:["Connect ",L.app.name]},void 0,!0,void 0,this),q.jsxDEV("p",{className:"text-xs text-[var(--color-text-muted)]",children:"Choose how to authenticate"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("div",{className:"space-y-3",children:[q.jsxDEV("button",{onClick:()=>{M(null),w({app:L.app}),u(""),x({})},className:"w-full text-left p-3 bg-[var(--color-bg)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-accent)] rounded-lg transition",children:[q.jsxDEV("div",{className:"font-medium text-sm",children:"API Key"},void 0,!1,void 0,this),q.jsxDEV("div",{className:"text-xs text-[var(--color-text-muted)] mt-0.5",children:["Enter your ",L.app.name," API key directly"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("button",{onClick:()=>{M(null),m(L.app,void 0,!0)},className:"w-full text-left p-3 bg-[var(--color-bg)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-accent)] rounded-lg transition",children:[q.jsxDEV("div",{className:"font-medium text-sm",children:"OAuth"},void 0,!1,void 0,this),q.jsxDEV("div",{className:"text-xs text-[var(--color-text-muted)] mt-0.5",children:["Sign in with your ",L.app.name," account"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("button",{onClick:()=>M(null),className:"w-full text-sm text-[var(--color-text-muted)] hover:text-white mt-4 py-2 transition",children:"Cancel"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X&&q.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:q.jsxDEV("div",{className:"bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg p-6 w-full max-w-md mx-4",children:[q.jsxDEV("div",{className:"flex items-center gap-3 mb-4",children:[X.app.logo&&q.jsxDEV("img",{src:X.app.logo,alt:X.app.name,className:"w-10 h-10 object-contain"},void 0,!1,void 0,this),q.jsxDEV("div",{children:[q.jsxDEV("h3",{className:"font-medium",children:["Connect ",X.app.name]},void 0,!0,void 0,this),q.jsxDEV("p",{className:"text-xs text-[var(--color-text-muted)]",children:X.app.credentialFields?.length?"Enter your credentials to connect":"Enter your API key to connect"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("form",{onSubmit:Xq,children:[X.app.credentialFields&&X.app.credentialFields.length>0?q.jsxDEV("div",{className:"space-y-3 mb-4",children:X.app.credentialFields.map((z,G)=>q.jsxDEV("div",{children:[q.jsxDEV("label",{className:"block text-xs text-[var(--color-text-secondary)] mb-1",children:[z.name.replace(/([A-Z])/g," $1").replace(/[-_]/g," ").replace(/\b\w/g,(W)=>W.toUpperCase()).trim(),z.required!==!1&&q.jsxDEV("span",{className:"text-red-400 ml-0.5",children:"*"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z.description&&q.jsxDEV("p",{className:"text-[10px] text-[var(--color-text-faint)] mb-1",children:z.description},void 0,!1,void 0,this),q.jsxDEV("input",{type:"password",value:V[z.name]||"",onChange:(W)=>x((Y)=>({...Y,[z.name]:W.target.value})),placeholder:`Enter ${z.name}...`,className:"w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded-lg px-4 py-2 focus:outline-none focus:border-[var(--color-accent)]",autoFocus:G===0},void 0,!1,void 0,this)]},z.name,!0,void 0,this))},void 0,!1,void 0,this):q.jsxDEV("input",{type:"password",value:f,onChange:(z)=>u(z.target.value),placeholder:"Enter API Key...",className:"w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded-lg px-4 py-2 mb-4 focus:outline-none focus:border-[var(--color-accent)]",autoFocus:!0},void 0,!1,void 0,this),q.jsxDEV("div",{className:"flex gap-2",children:[q.jsxDEV("button",{type:"button",onClick:()=>w(null),className:"flex-1 text-sm bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] px-4 py-2 rounded transition",children:"Cancel"},void 0,!1,void 0,this),q.jsxDEV("button",{type:"submit",disabled:g===X.app.slug||(X.app.credentialFields?.length?!X.app.credentialFields.filter((z)=>z.required!==!1).every((z)=>V[z.name]?.trim()):!f.trim()),className:"flex-1 text-sm bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-white px-4 py-2 rounded transition disabled:opacity-50",children:g===X.app.slug?"Connecting...":"Connect"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),T&&q.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:q.jsxDEV("div",{className:"bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg p-6 w-full max-w-md mx-4",children:t?q.jsxDEV(q.Fragment,{children:[q.jsxDEV("div",{className:"text-center mb-4",children:[q.jsxDEV("div",{className:"w-12 h-12 bg-green-500/20 rounded-full flex items-center justify-center mx-auto mb-3",children:q.jsxDEV("span",{className:"text-green-400 text-2xl",children:"✓"},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.jsxDEV("h3",{className:"font-medium text-lg",children:"MCP Config Created!"},void 0,!1,void 0,this),q.jsxDEV("p",{className:"text-sm text-[var(--color-text-secondary)] mt-2",children:['"',t,'" has been created and added to your servers.']},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("button",{onClick:()=>{E(null),j(null)},className:"w-full text-sm bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-white px-4 py-2 rounded transition",children:"Done"},void 0,!1,void 0,this)]},void 0,!0,void 0,this):q.jsxDEV(q.Fragment,{children:[q.jsxDEV("div",{className:"flex items-center gap-3 mb-4",children:[T.app.logo&&q.jsxDEV("img",{src:T.app.logo,alt:T.app.name,className:"w-10 h-10 object-contain"},void 0,!1,void 0,this),q.jsxDEV("div",{children:[q.jsxDEV("h3",{className:"font-medium",children:"Create MCP Config"},void 0,!1,void 0,this),q.jsxDEV("p",{className:"text-xs text-[var(--color-text-muted)]",children:["Create an MCP config for ",T.app.name]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("form",{onSubmit:(z)=>{z.preventDefault(),_q()},children:[q.jsxDEV("label",{className:"block text-xs text-[var(--color-text-secondary)] mb-1",children:"Config Name"},void 0,!1,void 0,this),q.jsxDEV("input",{type:"text",value:v,onChange:(z)=>n(z.target.value),placeholder:"Enter config name...",className:"w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded-lg px-4 py-2 mb-4 focus:outline-none focus:border-[var(--color-accent)]",autoFocus:!0,maxLength:30},void 0,!1,void 0,this),q.jsxDEV("div",{className:"flex gap-2",children:[q.jsxDEV("button",{type:"button",onClick:()=>E(null),className:"flex-1 text-sm bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] px-4 py-2 rounded transition",children:"Cancel"},void 0,!1,void 0,this),q.jsxDEV("button",{type:"submit",disabled:!v.trim()||o,className:"flex-1 text-sm bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-white px-4 py-2 rounded transition disabled:opacity-50",children:o?"Creating...":"Create Config"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),r&&q.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:q.jsxDEV("div",{className:"bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg p-6 w-full max-w-sm mx-4",children:[q.jsxDEV("p",{className:"text-center mb-4",children:r.message},void 0,!1,void 0,this),q.jsxDEV("div",{className:"flex gap-2",children:[q.jsxDEV("button",{onClick:()=>i(null),className:"flex-1 text-sm bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] px-4 py-2 rounded transition",children:"Cancel"},void 0,!1,void 0,this),q.jsxDEV("button",{onClick:r.onConfirm,className:"flex-1 text-sm bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded transition",children:"Confirm"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),s&&q.jsxDEV("div",{className:"text-red-400 text-sm p-3 bg-red-500/10 border border-red-500/20 rounded-lg flex items-center justify-between",children:[q.jsxDEV("span",{children:s},void 0,!1,void 0,this),q.jsxDEV("button",{onClick:()=>_(null),className:"text-red-400 hover:text-red-300",children:"×"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b&&q.jsxDEV("div",{className:"text-yellow-400 text-sm p-3 bg-yellow-500/10 border border-yellow-500/20 rounded-lg flex items-center gap-2",children:[q.jsxDEV("span",{className:"animate-spin",children:"⟳"},void 0,!1,void 0,this),q.jsxDEV("span",{children:["Waiting for ",b.appSlug," authorization..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("div",{children:q.jsxDEV("input",{type:"text",value:R,onChange:(z)=>Wq(z.target.value),placeholder:"Search apps...",className:"w-full bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg px-4 py-2 focus:outline-none focus:border-[var(--color-accent)]"},void 0,!1,void 0,this)},void 0,!1,void 0,this),d.length>0&&q.jsxDEV("div",{children:[q.jsxDEV("h3",{className:"text-sm font-medium text-[var(--color-text-secondary)] mb-3",children:["Connected (",d.length,")"]},void 0,!0,void 0,this),q.jsxDEV("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:d.map((z)=>q.jsxDEV(Hq,{app:z,connection:p(z),onConnect:()=>m(z),onDisconnect:()=>{let G=p(z);if(G)$q(G)},onCreateMcpConfig:y?void 0:()=>Zq(z),onBrowseTriggers:F?()=>F(z.slug):void 0,onUpdateKey:C(z)?()=>{w({app:z}),u(""),x({})}:void 0,connecting:g===z.slug},z.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("div",{children:[q.jsxDEV("h3",{className:"text-sm font-medium text-[var(--color-text-secondary)] mb-3",children:["Available Apps (",K.length,")"]},void 0,!0,void 0,this),K.length===0?q.jsxDEV("p",{className:"text-[var(--color-text-muted)] text-sm",children:R?"No apps match your search":"No apps available"},void 0,!1,void 0,this):q.jsxDEV("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:K.slice(0,50).map((z)=>q.jsxDEV(Hq,{app:z,onConnect:()=>m(z),connecting:g===z.slug},z.id,!1,void 0,this))},void 0,!1,void 0,this),K.length>50&&q.jsxDEV("p",{className:"text-xs text-[var(--color-text-faint)] mt-3 text-center",children:["Showing first 50 of ",K.length," apps. Use search to find more."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Hq({app:H,connection:J,onConnect:U,onDisconnect:F,onCreateMcpConfig:y,onBrowseTriggers:Z,onUpdateKey:A,connecting:I}){let k=J?.status==="active",P=C(H),S=Qq(H),h=P&&S;return q.jsxDEV("div",{className:`bg-[var(--color-surface)] border rounded-lg p-3 transition ${k?"border-green-500/30":"border-[var(--color-border)] hover:border-[var(--color-border-light)]"}`,children:[q.jsxDEV("div",{className:"flex items-start gap-3",children:[q.jsxDEV("div",{className:"w-10 h-10 rounded bg-[var(--color-surface-raised)] flex items-center justify-center flex-shrink-0 overflow-hidden",children:H.logo?q.jsxDEV("img",{src:H.logo,alt:H.name,className:"w-8 h-8 object-contain",onError:(R)=>{R.target.style.display="none"}},void 0,!1,void 0,this):q.jsxDEV("span",{className:"text-lg",children:H.name[0]?.toUpperCase()},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.jsxDEV("div",{className:"flex-1 min-w-0",children:[q.jsxDEV("div",{className:"flex items-center gap-2",children:[q.jsxDEV("h4",{className:"font-medium text-sm truncate",children:H.name},void 0,!1,void 0,this),k&&q.jsxDEV("span",{className:"text-xs text-green-400",children:"✓"},void 0,!1,void 0,this),!k&&P&&!S&&q.jsxDEV("span",{className:"text-[10px] bg-[var(--color-surface-raised)] text-[var(--color-text-secondary)] px-1.5 py-0.5 rounded",title:"Requires API Key",children:"API Key"},void 0,!1,void 0,this),!k&&h&&q.jsxDEV("span",{className:"text-[10px] bg-[#1a2a1a] text-[#6a6] px-1.5 py-0.5 rounded",title:"Supports API Key or OAuth",children:"API Key / OAuth"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H.description&&q.jsxDEV("p",{className:"text-xs text-[var(--color-text-muted)] line-clamp-2 mt-0.5",children:H.description},void 0,!1,void 0,this),H.categories.length>0&&q.jsxDEV("div",{className:"flex flex-wrap gap-1 mt-1",children:H.categories.slice(0,2).map((R)=>q.jsxDEV("span",{className:"text-[10px] bg-[var(--color-surface-raised)] text-[var(--color-text-faint)] px-1.5 py-0.5 rounded",children:R},R,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("div",{className:"mt-3 flex gap-2",children:k?q.jsxDEV(q.Fragment,{children:[y&&q.jsxDEV("button",{onClick:y,className:"flex-1 text-xs bg-[#1a2a1a] hover:bg-[#1a3a1a] border border-green-500/30 hover:border-green-500/50 text-green-400 px-3 py-1.5 rounded transition",children:"Create MCP Config"},void 0,!1,void 0,this),Z&&q.jsxDEV("button",{onClick:Z,className:"flex-1 text-xs bg-[#1a1a2a] hover:bg-[#1a1a3a] border border-blue-500/30 hover:border-blue-500/50 text-blue-400 px-3 py-1.5 rounded transition",children:"Browse Triggers"},void 0,!1,void 0,this),A&&q.jsxDEV("button",{onClick:A,className:"text-xs text-[var(--color-text-muted)] hover:text-[var(--color-accent)] transition px-2",title:"Update API Key",children:"Key"},void 0,!1,void 0,this),F&&q.jsxDEV("button",{onClick:F,className:"text-xs text-[var(--color-text-muted)] hover:text-red-400 transition px-2",title:"Disconnect",children:"×"},void 0,!1,void 0,this)]},void 0,!0,void 0,this):q.jsxDEV("button",{onClick:U,disabled:I,className:"w-full text-xs bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-accent)] px-3 py-1.5 rounded transition disabled:opacity-50",children:I?"Connecting...":P&&!S?"Enter API Key":"Connect"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}
2
+ export{wq as j};
3
+
4
+ //# debugId=5A2FB95F167B84D164756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/web/components/mcp/IntegrationsPanel.tsx"],
4
4
  "sourcesContent": [
5
- "import React, { useState, useEffect, useCallback } from \"react\";\nimport { useAuth } from \"../../context\";\n\n// Types\ninterface IntegrationApp {\n id: string;\n name: string;\n slug: string;\n description: string | null;\n logo: string | null;\n categories: string[];\n authSchemes: string[];\n providerSlug?: string;\n credentialFields?: {\n name: string;\n description?: string;\n required?: boolean;\n }[];\n}\n\ninterface ConnectedAccount {\n id: string;\n appId: string;\n appName: string;\n status: \"active\" | \"pending\" | \"failed\" | \"expired\";\n createdAt: string;\n}\n\ninterface IntegrationProvider {\n id: string;\n name: string;\n connected: boolean;\n}\n\n// Check if app supports API_KEY auth\nfunction supportsApiKey(app: IntegrationApp): boolean {\n return app.authSchemes.some(s => s.toUpperCase() === \"API_KEY\");\n}\n\n// Check if app supports OAuth\nfunction supportsOAuth(app: IntegrationApp): boolean {\n return app.authSchemes.some(s => s.toUpperCase() === \"OAUTH2\");\n}\n\n// Check if app supports multiple auth methods\nfunction hasMultipleAuthMethods(app: IntegrationApp): boolean {\n return supportsApiKey(app) && supportsOAuth(app);\n}\n\n// Main component\nexport function IntegrationsPanel({\n providerId = \"composio\",\n projectId,\n onConnectionComplete,\n onBrowseTriggers,\n hideMcpConfig,\n}: {\n providerId?: string;\n projectId?: string | null;\n onConnectionComplete?: () => void;\n onBrowseTriggers?: (toolkitSlug: string) => void;\n hideMcpConfig?: boolean;\n}) {\n const { authFetch } = useAuth();\n const [apps, setApps] = useState<IntegrationApp[]>([]);\n const [connectedAccounts, setConnectedAccounts] = useState<ConnectedAccount[]>([]);\n const [loading, setLoading] = useState(true);\n const [search, setSearch] = useState(\"\");\n const [connecting, setConnecting] = useState<string | null>(null);\n const [pendingConnection, setPendingConnection] = useState<{\n appSlug: string;\n connectionId?: string;\n } | null>(null);\n const [error, setError] = useState<string | null>(null);\n // For auth method selection (when app supports both OAuth and API Key)\n const [authMethodModal, setAuthMethodModal] = useState<{ app: IntegrationApp } | null>(null);\n // For API Key / credential modal\n const [apiKeyModal, setApiKeyModal] = useState<{ app: IntegrationApp } | null>(null);\n const [apiKeyInput, setApiKeyInput] = useState(\"\");\n const [credentialInputs, setCredentialInputs] = useState<Record<string, string>>({});\n // For MCP config creation modal\n const [mcpConfigModal, setMcpConfigModal] = useState<{ app: IntegrationApp } | null>(null);\n const [mcpConfigName, setMcpConfigName] = useState(\"\");\n const [mcpConfigCreating, setMcpConfigCreating] = useState(false);\n const [mcpConfigSuccess, setMcpConfigSuccess] = useState<string | null>(null);\n // For confirmation modal\n const [confirmModal, setConfirmModal] = useState<{\n message: string;\n onConfirm: () => void;\n } | null>(null);\n\n // Fetch apps and connected accounts\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n try {\n const [appsRes, connectedRes] = await Promise.all([\n authFetch(`/api/integrations/${providerId}/apps${projectParam}`),\n authFetch(`/api/integrations/${providerId}/connected${projectParam}`),\n ]);\n\n const appsData = await appsRes.json();\n const connectedData = await connectedRes.json();\n\n setApps(appsData.apps || []);\n setConnectedAccounts(connectedData.accounts || []);\n } catch (e) {\n console.error(\"Failed to fetch integrations:\", e);\n setError(\"Failed to load integrations\");\n }\n setLoading(false);\n }, [authFetch, providerId, projectId]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n // Check for connection completion from URL params\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const connectedApp = params.get(\"connected\");\n if (connectedApp) {\n // Remove the query param\n window.history.replaceState({}, \"\", window.location.pathname);\n // Refresh to show new connection\n fetchData();\n onConnectionComplete?.();\n }\n }, [fetchData, onConnectionComplete]);\n\n // Poll for pending connection status\n useEffect(() => {\n if (!pendingConnection?.connectionId) return;\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n\n const pollInterval = setInterval(async () => {\n try {\n const res = await authFetch(\n `/api/integrations/${providerId}/connection/${pendingConnection.connectionId}${projectParam}`\n );\n const data = await res.json();\n\n if (data.connection?.status === \"active\") {\n setPendingConnection(null);\n setConnecting(null);\n fetchData();\n onConnectionComplete?.();\n } else if (data.connection?.status === \"failed\") {\n setPendingConnection(null);\n setConnecting(null);\n setError(`Connection to ${pendingConnection.appSlug} failed`);\n }\n } catch (e) {\n // Keep polling\n }\n }, 2000);\n\n return () => clearInterval(pollInterval);\n }, [pendingConnection, authFetch, providerId, projectId, fetchData, onConnectionComplete]);\n\n // Initiate connection\n const connectApp = async (app: IntegrationApp, apiKey?: string, forceOAuth?: boolean, fields?: Record<string, string>) => {\n // If app supports multiple auth methods and user hasn't chosen, show choice\n if (hasMultipleAuthMethods(app) && !apiKey && !fields && !forceOAuth) {\n setAuthMethodModal({ app });\n return;\n }\n\n // If app supports API key (and user didn't choose OAuth), show credential modal\n if (supportsApiKey(app) && !apiKey && !fields && !forceOAuth) {\n setApiKeyModal({ app });\n setApiKeyInput(\"\");\n setCredentialInputs({});\n return;\n }\n\n setConnecting(app.slug);\n setError(null);\n\n try {\n // Build request body\n const body: any = { appSlug: app.slug };\n if (fields && Object.keys(fields).length > 0) {\n // Multi-field credentials\n body.credentials = {\n authScheme: \"API_KEY\",\n fields,\n };\n } else if (apiKey) {\n body.credentials = {\n authScheme: \"API_KEY\",\n apiKey,\n };\n }\n\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n const res = await authFetch(`/api/integrations/${providerId}/connect${projectParam}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n const data = await res.json();\n\n if (!res.ok) {\n setError(data.error || \"Failed to initiate connection\");\n setConnecting(null);\n setApiKeyModal(null);\n return;\n }\n\n // API_KEY connections are immediately active (no redirect)\n if (data.status === \"active\" || !data.redirectUrl) {\n setConnecting(null);\n setApiKeyModal(null);\n fetchData();\n onConnectionComplete?.();\n return;\n }\n\n if (data.redirectUrl) {\n // Store pending connection for polling\n setPendingConnection({\n appSlug: app.slug,\n connectionId: data.connectionId,\n });\n\n // Open OAuth in popup\n const popup = window.open(\n data.redirectUrl,\n `connect-${app.slug}`,\n \"width=600,height=700,left=200,top=100\"\n );\n\n // If popup blocked, redirect instead\n if (!popup || popup.closed) {\n window.location.href = data.redirectUrl;\n }\n }\n } catch (e) {\n setError(`Failed to connect: ${e}`);\n setConnecting(null);\n setApiKeyModal(null);\n }\n };\n\n // Handle API key / credential form submission\n const handleApiKeySubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (!apiKeyModal) return;\n const hasFields = apiKeyModal.app.credentialFields && apiKeyModal.app.credentialFields.length > 0;\n if (hasFields) {\n // Check required fields are filled\n const requiredFields = apiKeyModal.app.credentialFields!.filter(f => f.required !== false);\n const allFilled = requiredFields.every(f => credentialInputs[f.name]?.trim());\n if (!allFilled) return;\n connectApp(apiKeyModal.app, undefined, false, credentialInputs);\n } else {\n if (!apiKeyInput.trim()) return;\n connectApp(apiKeyModal.app, apiKeyInput.trim());\n }\n };\n\n // Disconnect (called after confirmation)\n const disconnectApp = async (account: ConnectedAccount) => {\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n try {\n const res = await authFetch(\n `/api/integrations/${providerId}/connection/${account.id}${projectParam}`,\n { method: \"DELETE\" }\n );\n\n if (res.ok) {\n fetchData();\n } else {\n const data = await res.json();\n setError(data.error || \"Failed to disconnect\");\n }\n } catch (e) {\n setError(`Failed to disconnect: ${e}`);\n }\n };\n\n // Open MCP config creation modal\n const openMcpConfigModal = (app: IntegrationApp) => {\n setMcpConfigModal({ app });\n setMcpConfigName(`${app.name} MCP`);\n setMcpConfigSuccess(null);\n };\n\n // Create MCP config from connected app\n const createMcpConfig = async () => {\n if (!mcpConfigModal || !mcpConfigName.trim()) return;\n\n setMcpConfigCreating(true);\n setError(null);\n\n try {\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n const res = await authFetch(`/api/integrations/${providerId}/configs${projectParam}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n name: mcpConfigName.replace(/[^a-zA-Z0-9\\s-]/g, \"\").substring(0, 30),\n toolkitSlug: mcpConfigModal.app.slug,\n }),\n });\n\n const data = await res.json();\n\n if (!res.ok) {\n setError(data.error || \"Failed to create MCP config\");\n setMcpConfigCreating(false);\n return;\n }\n\n // Auto-add the server locally\n let autoAdded = false;\n if (data.config?.id) {\n try {\n const addRes = await authFetch(\n `/api/integrations/${providerId}/configs/${data.config.id}/add${projectParam}`,\n { method: \"POST\" }\n );\n autoAdded = addRes.ok;\n } catch {\n // Non-fatal — server was still created on the provider\n }\n }\n\n setMcpConfigSuccess(mcpConfigName);\n onConnectionComplete?.();\n } catch (e) {\n setError(`Failed to create MCP config: ${e}`);\n } finally {\n setMcpConfigCreating(false);\n }\n };\n\n // Handle disconnect with confirmation modal\n const handleDisconnect = (account: ConnectedAccount) => {\n setConfirmModal({\n message: `Disconnect ${account.appName}?`,\n onConfirm: () => {\n disconnectApp(account);\n setConfirmModal(null);\n },\n });\n };\n\n // Check if app is connected (also matches via providerSlug for multi-toolkit providers)\n const isConnected = (app: IntegrationApp) => {\n return connectedAccounts.some(\n (a) => a.status === \"active\" && (\n a.appId === app.slug ||\n (app.providerSlug && a.appId === app.providerSlug)\n )\n );\n };\n\n // Get connection for app (prefer active account, also matches via providerSlug)\n const getConnection = (app: IntegrationApp) => {\n return connectedAccounts.find((a) => a.appId === app.slug && a.status === \"active\")\n || (app.providerSlug && connectedAccounts.find((a) => a.appId === app.providerSlug && a.status === \"active\"))\n || connectedAccounts.find((a) => a.appId === app.slug)\n || (app.providerSlug && connectedAccounts.find((a) => a.appId === app.providerSlug))\n || undefined;\n };\n\n // Filter apps\n const filteredApps = apps.filter((app) => {\n if (!search) return true;\n const s = search.toLowerCase();\n return (\n app.name.toLowerCase().includes(s) ||\n app.slug.toLowerCase().includes(s) ||\n app.description?.toLowerCase().includes(s) ||\n app.categories.some((c) => c.toLowerCase().includes(s))\n );\n });\n\n // Group by connected/not connected\n const connectedApps = filteredApps.filter((app) => isConnected(app));\n const availableApps = filteredApps.filter((app) => !isConnected(app));\n\n if (loading) {\n return <div className=\"text-center py-8 text-[#666]\">Loading apps...</div>;\n }\n\n return (\n <div className=\"space-y-6\">\n {/* Auth Method Choice Modal */}\n {authMethodModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4\">\n <div className=\"flex items-center gap-3 mb-4\">\n {authMethodModal.app.logo && (\n <img\n src={authMethodModal.app.logo}\n alt={authMethodModal.app.name}\n className=\"w-10 h-10 object-contain\"\n />\n )}\n <div>\n <h3 className=\"font-medium\">Connect {authMethodModal.app.name}</h3>\n <p className=\"text-xs text-[#666]\">Choose how to authenticate</p>\n </div>\n </div>\n <div className=\"space-y-3\">\n <button\n onClick={() => {\n setAuthMethodModal(null);\n setApiKeyModal({ app: authMethodModal.app });\n setApiKeyInput(\"\");\n setCredentialInputs({});\n }}\n className=\"w-full text-left p-3 bg-[#0a0a0a] hover:bg-[#1a1a1a] border border-[#333] hover:border-[#f97316] rounded-lg transition\"\n >\n <div className=\"font-medium text-sm\">API Key</div>\n <div className=\"text-xs text-[#666] mt-0.5\">\n Enter your {authMethodModal.app.name} API key directly\n </div>\n </button>\n <button\n onClick={() => {\n setAuthMethodModal(null);\n connectApp(authMethodModal.app, undefined, true);\n }}\n className=\"w-full text-left p-3 bg-[#0a0a0a] hover:bg-[#1a1a1a] border border-[#333] hover:border-[#f97316] rounded-lg transition\"\n >\n <div className=\"font-medium text-sm\">OAuth</div>\n <div className=\"text-xs text-[#666] mt-0.5\">\n Sign in with your {authMethodModal.app.name} account\n </div>\n </button>\n </div>\n <button\n onClick={() => setAuthMethodModal(null)}\n className=\"w-full text-sm text-[#666] hover:text-white mt-4 py-2 transition\"\n >\n Cancel\n </button>\n </div>\n </div>\n )}\n\n {/* API Key / Credentials Modal */}\n {apiKeyModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4\">\n <div className=\"flex items-center gap-3 mb-4\">\n {apiKeyModal.app.logo && (\n <img\n src={apiKeyModal.app.logo}\n alt={apiKeyModal.app.name}\n className=\"w-10 h-10 object-contain\"\n />\n )}\n <div>\n <h3 className=\"font-medium\">Connect {apiKeyModal.app.name}</h3>\n <p className=\"text-xs text-[#666]\">\n {apiKeyModal.app.credentialFields?.length\n ? \"Enter your credentials to connect\"\n : \"Enter your API key to connect\"}\n </p>\n </div>\n </div>\n <form onSubmit={handleApiKeySubmit}>\n {apiKeyModal.app.credentialFields && apiKeyModal.app.credentialFields.length > 0 ? (\n <div className=\"space-y-3 mb-4\">\n {apiKeyModal.app.credentialFields.map((field, idx) => (\n <div key={field.name}>\n <label className=\"block text-xs text-[#888] mb-1\">\n {field.name.replace(/([A-Z])/g, \" $1\").replace(/[-_]/g, \" \").replace(/\\b\\w/g, c => c.toUpperCase()).trim()}\n {field.required !== false && <span className=\"text-red-400 ml-0.5\">*</span>}\n </label>\n {field.description && (\n <p className=\"text-[10px] text-[#555] mb-1\">{field.description}</p>\n )}\n <input\n type=\"password\"\n value={credentialInputs[field.name] || \"\"}\n onChange={(e) => setCredentialInputs(prev => ({ ...prev, [field.name]: e.target.value }))}\n placeholder={`Enter ${field.name}...`}\n className=\"w-full bg-[#0a0a0a] border border-[#333] rounded-lg px-4 py-2 focus:outline-none focus:border-[#f97316]\"\n autoFocus={idx === 0}\n />\n </div>\n ))}\n </div>\n ) : (\n <input\n type=\"password\"\n value={apiKeyInput}\n onChange={(e) => setApiKeyInput(e.target.value)}\n placeholder=\"Enter API Key...\"\n className=\"w-full bg-[#0a0a0a] border border-[#333] rounded-lg px-4 py-2 mb-4 focus:outline-none focus:border-[#f97316]\"\n autoFocus\n />\n )}\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => setApiKeyModal(null)}\n className=\"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={\n connecting === apiKeyModal.app.slug ||\n (apiKeyModal.app.credentialFields?.length\n ? !apiKeyModal.app.credentialFields.filter(f => f.required !== false).every(f => credentialInputs[f.name]?.trim())\n : !apiKeyInput.trim())\n }\n className=\"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50\"\n >\n {connecting === apiKeyModal.app.slug ? \"Connecting...\" : \"Connect\"}\n </button>\n </div>\n </form>\n </div>\n </div>\n )}\n\n {/* MCP Config Creation Modal */}\n {mcpConfigModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4\">\n {mcpConfigSuccess ? (\n <>\n <div className=\"text-center mb-4\">\n <div className=\"w-12 h-12 bg-green-500/20 rounded-full flex items-center justify-center mx-auto mb-3\">\n <span className=\"text-green-400 text-2xl\">✓</span>\n </div>\n <h3 className=\"font-medium text-lg\">MCP Config Created!</h3>\n <p className=\"text-sm text-[#888] mt-2\">\n \"{mcpConfigSuccess}\" has been created and added to your servers.\n </p>\n </div>\n <button\n onClick={() => {\n setMcpConfigModal(null);\n setMcpConfigSuccess(null);\n }}\n className=\"w-full text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition\"\n >\n Done\n </button>\n </>\n ) : (\n <>\n <div className=\"flex items-center gap-3 mb-4\">\n {mcpConfigModal.app.logo && (\n <img\n src={mcpConfigModal.app.logo}\n alt={mcpConfigModal.app.name}\n className=\"w-10 h-10 object-contain\"\n />\n )}\n <div>\n <h3 className=\"font-medium\">Create MCP Config</h3>\n <p className=\"text-xs text-[#666]\">\n Create an MCP config for {mcpConfigModal.app.name}\n </p>\n </div>\n </div>\n <form onSubmit={(e) => { e.preventDefault(); createMcpConfig(); }}>\n <label className=\"block text-xs text-[#888] mb-1\">Config Name</label>\n <input\n type=\"text\"\n value={mcpConfigName}\n onChange={(e) => setMcpConfigName(e.target.value)}\n placeholder=\"Enter config name...\"\n className=\"w-full bg-[#0a0a0a] border border-[#333] rounded-lg px-4 py-2 mb-4 focus:outline-none focus:border-[#f97316]\"\n autoFocus\n maxLength={30}\n />\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => setMcpConfigModal(null)}\n className=\"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={!mcpConfigName.trim() || mcpConfigCreating}\n className=\"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50\"\n >\n {mcpConfigCreating ? \"Creating...\" : \"Create Config\"}\n </button>\n </div>\n </form>\n </>\n )}\n </div>\n </div>\n )}\n\n {/* Confirmation Modal */}\n {confirmModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-sm mx-4\">\n <p className=\"text-center mb-4\">{confirmModal.message}</p>\n <div className=\"flex gap-2\">\n <button\n onClick={() => setConfirmModal(null)}\n className=\"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n onClick={confirmModal.onConfirm}\n className=\"flex-1 text-sm bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded transition\"\n >\n Confirm\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Error */}\n {error && (\n <div className=\"text-red-400 text-sm p-3 bg-red-500/10 border border-red-500/20 rounded-lg flex items-center justify-between\">\n <span>{error}</span>\n <button onClick={() => setError(null)} className=\"text-red-400 hover:text-red-300\">\n ×\n </button>\n </div>\n )}\n\n {/* Pending connection notice */}\n {pendingConnection && (\n <div className=\"text-yellow-400 text-sm p-3 bg-yellow-500/10 border border-yellow-500/20 rounded-lg flex items-center gap-2\">\n <span className=\"animate-spin\">⟳</span>\n <span>Waiting for {pendingConnection.appSlug} authorization...</span>\n </div>\n )}\n\n {/* Search */}\n <div>\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search apps...\"\n className=\"w-full bg-[#111] border border-[#333] rounded-lg px-4 py-2 focus:outline-none focus:border-[#f97316]\"\n />\n </div>\n\n {/* Connected Apps */}\n {connectedApps.length > 0 && (\n <div>\n <h3 className=\"text-sm font-medium text-[#888] mb-3\">\n Connected ({connectedApps.length})\n </h3>\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {connectedApps.map((app) => (\n <AppCard\n key={app.id}\n app={app}\n connection={getConnection(app)}\n onConnect={() => connectApp(app)}\n onDisconnect={() => {\n const conn = getConnection(app);\n if (conn) handleDisconnect(conn);\n }}\n onCreateMcpConfig={hideMcpConfig ? undefined : () => openMcpConfigModal(app)}\n onBrowseTriggers={onBrowseTriggers ? () => onBrowseTriggers(app.slug) : undefined}\n onUpdateKey={supportsApiKey(app) ? () => {\n setApiKeyModal({ app });\n setApiKeyInput(\"\");\n setCredentialInputs({});\n } : undefined}\n connecting={connecting === app.slug}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Available Apps */}\n <div>\n <h3 className=\"text-sm font-medium text-[#888] mb-3\">\n Available Apps ({availableApps.length})\n </h3>\n {availableApps.length === 0 ? (\n <p className=\"text-[#666] text-sm\">\n {search ? \"No apps match your search\" : \"No apps available\"}\n </p>\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {availableApps.slice(0, 50).map((app) => (\n <AppCard\n key={app.id}\n app={app}\n onConnect={() => connectApp(app)}\n connecting={connecting === app.slug}\n />\n ))}\n </div>\n )}\n {availableApps.length > 50 && (\n <p className=\"text-xs text-[#555] mt-3 text-center\">\n Showing first 50 of {availableApps.length} apps. Use search to find more.\n </p>\n )}\n </div>\n </div>\n );\n}\n\n// App card component\nfunction AppCard({\n app,\n connection,\n onConnect,\n onDisconnect,\n onCreateMcpConfig,\n onBrowseTriggers,\n onUpdateKey,\n connecting,\n}: {\n app: IntegrationApp;\n connection?: ConnectedAccount;\n onConnect: () => void;\n onDisconnect?: () => void;\n onCreateMcpConfig?: () => void;\n onBrowseTriggers?: () => void;\n onUpdateKey?: () => void;\n connecting: boolean;\n}) {\n const isConnected = connection?.status === \"active\";\n const hasApiKey = supportsApiKey(app);\n const hasOAuth = supportsOAuth(app);\n const hasBothMethods = hasApiKey && hasOAuth;\n\n return (\n <div\n className={`bg-[#111] border rounded-lg p-3 transition ${\n isConnected ? \"border-green-500/30\" : \"border-[#1a1a1a] hover:border-[#333]\"\n }`}\n >\n <div className=\"flex items-start gap-3\">\n {/* Logo */}\n <div className=\"w-10 h-10 rounded bg-[#1a1a1a] flex items-center justify-center flex-shrink-0 overflow-hidden\">\n {app.logo ? (\n <img\n src={app.logo}\n alt={app.name}\n className=\"w-8 h-8 object-contain\"\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n ) : (\n <span className=\"text-lg\">{app.name[0]?.toUpperCase()}</span>\n )}\n </div>\n\n {/* Info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <h4 className=\"font-medium text-sm truncate\">{app.name}</h4>\n {isConnected && (\n <span className=\"text-xs text-green-400\">✓</span>\n )}\n {!isConnected && hasApiKey && !hasOAuth && (\n <span className=\"text-[10px] bg-[#222] text-[#888] px-1.5 py-0.5 rounded\" title=\"Requires API Key\">\n API Key\n </span>\n )}\n {!isConnected && hasBothMethods && (\n <span className=\"text-[10px] bg-[#1a2a1a] text-[#6a6] px-1.5 py-0.5 rounded\" title=\"Supports API Key or OAuth\">\n API Key / OAuth\n </span>\n )}\n </div>\n {app.description && (\n <p className=\"text-xs text-[#666] line-clamp-2 mt-0.5\">\n {app.description}\n </p>\n )}\n {app.categories.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mt-1\">\n {app.categories.slice(0, 2).map((cat) => (\n <span\n key={cat}\n className=\"text-[10px] bg-[#1a1a1a] text-[#555] px-1.5 py-0.5 rounded\"\n >\n {cat}\n </span>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"mt-3 flex gap-2\">\n {isConnected ? (\n <>\n {onCreateMcpConfig && (\n <button\n onClick={onCreateMcpConfig}\n className=\"flex-1 text-xs bg-[#1a2a1a] hover:bg-[#1a3a1a] border border-green-500/30 hover:border-green-500/50 text-green-400 px-3 py-1.5 rounded transition\"\n >\n Create MCP Config\n </button>\n )}\n {onBrowseTriggers && (\n <button\n onClick={onBrowseTriggers}\n className=\"flex-1 text-xs bg-[#1a1a2a] hover:bg-[#1a1a3a] border border-blue-500/30 hover:border-blue-500/50 text-blue-400 px-3 py-1.5 rounded transition\"\n >\n Browse Triggers\n </button>\n )}\n {onUpdateKey && (\n <button\n onClick={onUpdateKey}\n className=\"text-xs text-[#666] hover:text-[#f97316] transition px-2\"\n title=\"Update API Key\"\n >\n Key\n </button>\n )}\n {onDisconnect && (\n <button\n onClick={onDisconnect}\n className=\"text-xs text-[#666] hover:text-red-400 transition px-2\"\n title=\"Disconnect\"\n >\n ×\n </button>\n )}\n </>\n ) : (\n <button\n onClick={onConnect}\n disabled={connecting}\n className=\"w-full text-xs bg-[#1a1a1a] hover:bg-[#222] border border-[#333] hover:border-[#f97316] px-3 py-1.5 rounded transition disabled:opacity-50\"\n >\n {connecting ? \"Connecting...\" : (hasApiKey && !hasOAuth) ? \"Enter API Key\" : \"Connect\"}\n </button>\n )}\n </div>\n </div>\n );\n}\n\nexport default IntegrationsPanel;\n"
5
+ "import React, { useState, useEffect, useCallback } from \"react\";\nimport { useAuth } from \"../../context\";\n\n// Types\ninterface IntegrationApp {\n id: string;\n name: string;\n slug: string;\n description: string | null;\n logo: string | null;\n categories: string[];\n authSchemes: string[];\n providerSlug?: string;\n credentialFields?: {\n name: string;\n description?: string;\n required?: boolean;\n }[];\n}\n\ninterface ConnectedAccount {\n id: string;\n appId: string;\n appName: string;\n status: \"active\" | \"pending\" | \"failed\" | \"expired\";\n createdAt: string;\n}\n\ninterface IntegrationProvider {\n id: string;\n name: string;\n connected: boolean;\n}\n\n// Check if app supports API_KEY auth\nfunction supportsApiKey(app: IntegrationApp): boolean {\n return app.authSchemes.some(s => s.toUpperCase() === \"API_KEY\");\n}\n\n// Check if app supports OAuth\nfunction supportsOAuth(app: IntegrationApp): boolean {\n return app.authSchemes.some(s => s.toUpperCase() === \"OAUTH2\");\n}\n\n// Check if app supports multiple auth methods\nfunction hasMultipleAuthMethods(app: IntegrationApp): boolean {\n return supportsApiKey(app) && supportsOAuth(app);\n}\n\n// Main component\nexport function IntegrationsPanel({\n providerId = \"composio\",\n projectId,\n onConnectionComplete,\n onBrowseTriggers,\n hideMcpConfig,\n}: {\n providerId?: string;\n projectId?: string | null;\n onConnectionComplete?: () => void;\n onBrowseTriggers?: (toolkitSlug: string) => void;\n hideMcpConfig?: boolean;\n}) {\n const { authFetch } = useAuth();\n const [apps, setApps] = useState<IntegrationApp[]>([]);\n const [connectedAccounts, setConnectedAccounts] = useState<ConnectedAccount[]>([]);\n const [loading, setLoading] = useState(true);\n const [search, setSearch] = useState(\"\");\n const [connecting, setConnecting] = useState<string | null>(null);\n const [pendingConnection, setPendingConnection] = useState<{\n appSlug: string;\n connectionId?: string;\n } | null>(null);\n const [error, setError] = useState<string | null>(null);\n // For auth method selection (when app supports both OAuth and API Key)\n const [authMethodModal, setAuthMethodModal] = useState<{ app: IntegrationApp } | null>(null);\n // For API Key / credential modal\n const [apiKeyModal, setApiKeyModal] = useState<{ app: IntegrationApp } | null>(null);\n const [apiKeyInput, setApiKeyInput] = useState(\"\");\n const [credentialInputs, setCredentialInputs] = useState<Record<string, string>>({});\n // For MCP config creation modal\n const [mcpConfigModal, setMcpConfigModal] = useState<{ app: IntegrationApp } | null>(null);\n const [mcpConfigName, setMcpConfigName] = useState(\"\");\n const [mcpConfigCreating, setMcpConfigCreating] = useState(false);\n const [mcpConfigSuccess, setMcpConfigSuccess] = useState<string | null>(null);\n // For confirmation modal\n const [confirmModal, setConfirmModal] = useState<{\n message: string;\n onConfirm: () => void;\n } | null>(null);\n\n // Fetch apps and connected accounts\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n try {\n const [appsRes, connectedRes] = await Promise.all([\n authFetch(`/api/integrations/${providerId}/apps${projectParam}`),\n authFetch(`/api/integrations/${providerId}/connected${projectParam}`),\n ]);\n\n const appsData = await appsRes.json();\n const connectedData = await connectedRes.json();\n\n setApps(appsData.apps || []);\n setConnectedAccounts(connectedData.accounts || []);\n } catch (e) {\n console.error(\"Failed to fetch integrations:\", e);\n setError(\"Failed to load integrations\");\n }\n setLoading(false);\n }, [authFetch, providerId, projectId]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n // Check for connection completion from URL params\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const connectedApp = params.get(\"connected\");\n if (connectedApp) {\n // Remove the query param\n window.history.replaceState({}, \"\", window.location.pathname);\n // Refresh to show new connection\n fetchData();\n onConnectionComplete?.();\n }\n }, [fetchData, onConnectionComplete]);\n\n // Poll for pending connection status\n useEffect(() => {\n if (!pendingConnection?.connectionId) return;\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n\n const pollInterval = setInterval(async () => {\n try {\n const res = await authFetch(\n `/api/integrations/${providerId}/connection/${pendingConnection.connectionId}${projectParam}`\n );\n const data = await res.json();\n\n if (data.connection?.status === \"active\") {\n setPendingConnection(null);\n setConnecting(null);\n fetchData();\n onConnectionComplete?.();\n } else if (data.connection?.status === \"failed\") {\n setPendingConnection(null);\n setConnecting(null);\n setError(`Connection to ${pendingConnection.appSlug} failed`);\n }\n } catch (e) {\n // Keep polling\n }\n }, 2000);\n\n return () => clearInterval(pollInterval);\n }, [pendingConnection, authFetch, providerId, projectId, fetchData, onConnectionComplete]);\n\n // Initiate connection\n const connectApp = async (app: IntegrationApp, apiKey?: string, forceOAuth?: boolean, fields?: Record<string, string>) => {\n // If app supports multiple auth methods and user hasn't chosen, show choice\n if (hasMultipleAuthMethods(app) && !apiKey && !fields && !forceOAuth) {\n setAuthMethodModal({ app });\n return;\n }\n\n // If app supports API key (and user didn't choose OAuth), show credential modal\n if (supportsApiKey(app) && !apiKey && !fields && !forceOAuth) {\n setApiKeyModal({ app });\n setApiKeyInput(\"\");\n setCredentialInputs({});\n return;\n }\n\n setConnecting(app.slug);\n setError(null);\n\n try {\n // Build request body\n const body: any = { appSlug: app.slug };\n if (fields && Object.keys(fields).length > 0) {\n // Multi-field credentials\n body.credentials = {\n authScheme: \"API_KEY\",\n fields,\n };\n } else if (apiKey) {\n body.credentials = {\n authScheme: \"API_KEY\",\n apiKey,\n };\n }\n\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n const res = await authFetch(`/api/integrations/${providerId}/connect${projectParam}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n const data = await res.json();\n\n if (!res.ok) {\n setError(data.error || \"Failed to initiate connection\");\n setConnecting(null);\n setApiKeyModal(null);\n return;\n }\n\n // API_KEY connections are immediately active (no redirect)\n if (data.status === \"active\" || !data.redirectUrl) {\n setConnecting(null);\n setApiKeyModal(null);\n fetchData();\n onConnectionComplete?.();\n return;\n }\n\n if (data.redirectUrl) {\n // Store pending connection for polling\n setPendingConnection({\n appSlug: app.slug,\n connectionId: data.connectionId,\n });\n\n // Open OAuth in popup\n const popup = window.open(\n data.redirectUrl,\n `connect-${app.slug}`,\n \"width=600,height=700,left=200,top=100\"\n );\n\n // If popup blocked, redirect instead\n if (!popup || popup.closed) {\n window.location.href = data.redirectUrl;\n }\n }\n } catch (e) {\n setError(`Failed to connect: ${e}`);\n setConnecting(null);\n setApiKeyModal(null);\n }\n };\n\n // Handle API key / credential form submission\n const handleApiKeySubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (!apiKeyModal) return;\n const hasFields = apiKeyModal.app.credentialFields && apiKeyModal.app.credentialFields.length > 0;\n if (hasFields) {\n // Check required fields are filled\n const requiredFields = apiKeyModal.app.credentialFields!.filter(f => f.required !== false);\n const allFilled = requiredFields.every(f => credentialInputs[f.name]?.trim());\n if (!allFilled) return;\n connectApp(apiKeyModal.app, undefined, false, credentialInputs);\n } else {\n if (!apiKeyInput.trim()) return;\n connectApp(apiKeyModal.app, apiKeyInput.trim());\n }\n };\n\n // Disconnect (called after confirmation)\n const disconnectApp = async (account: ConnectedAccount) => {\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n try {\n const res = await authFetch(\n `/api/integrations/${providerId}/connection/${account.id}${projectParam}`,\n { method: \"DELETE\" }\n );\n\n if (res.ok) {\n fetchData();\n } else {\n const data = await res.json();\n setError(data.error || \"Failed to disconnect\");\n }\n } catch (e) {\n setError(`Failed to disconnect: ${e}`);\n }\n };\n\n // Open MCP config creation modal\n const openMcpConfigModal = (app: IntegrationApp) => {\n setMcpConfigModal({ app });\n setMcpConfigName(`${app.name} MCP`);\n setMcpConfigSuccess(null);\n };\n\n // Create MCP config from connected app\n const createMcpConfig = async () => {\n if (!mcpConfigModal || !mcpConfigName.trim()) return;\n\n setMcpConfigCreating(true);\n setError(null);\n\n try {\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n const res = await authFetch(`/api/integrations/${providerId}/configs${projectParam}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n name: mcpConfigName.replace(/[^a-zA-Z0-9\\s-]/g, \"\").substring(0, 30),\n toolkitSlug: mcpConfigModal.app.slug,\n }),\n });\n\n const data = await res.json();\n\n if (!res.ok) {\n setError(data.error || \"Failed to create MCP config\");\n setMcpConfigCreating(false);\n return;\n }\n\n // Auto-add the server locally\n let autoAdded = false;\n if (data.config?.id) {\n try {\n const addRes = await authFetch(\n `/api/integrations/${providerId}/configs/${data.config.id}/add${projectParam}`,\n { method: \"POST\" }\n );\n autoAdded = addRes.ok;\n } catch {\n // Non-fatal — server was still created on the provider\n }\n }\n\n setMcpConfigSuccess(mcpConfigName);\n onConnectionComplete?.();\n } catch (e) {\n setError(`Failed to create MCP config: ${e}`);\n } finally {\n setMcpConfigCreating(false);\n }\n };\n\n // Handle disconnect with confirmation modal\n const handleDisconnect = (account: ConnectedAccount) => {\n setConfirmModal({\n message: `Disconnect ${account.appName}?`,\n onConfirm: () => {\n disconnectApp(account);\n setConfirmModal(null);\n },\n });\n };\n\n // Check if app is connected (also matches via providerSlug for multi-toolkit providers)\n const isConnected = (app: IntegrationApp) => {\n return connectedAccounts.some(\n (a) => a.status === \"active\" && (\n a.appId === app.slug ||\n (app.providerSlug && a.appId === app.providerSlug)\n )\n );\n };\n\n // Get connection for app (prefer active account, also matches via providerSlug)\n const getConnection = (app: IntegrationApp) => {\n return connectedAccounts.find((a) => a.appId === app.slug && a.status === \"active\")\n || (app.providerSlug && connectedAccounts.find((a) => a.appId === app.providerSlug && a.status === \"active\"))\n || connectedAccounts.find((a) => a.appId === app.slug)\n || (app.providerSlug && connectedAccounts.find((a) => a.appId === app.providerSlug))\n || undefined;\n };\n\n // Filter apps\n const filteredApps = apps.filter((app) => {\n if (!search) return true;\n const s = search.toLowerCase();\n return (\n app.name.toLowerCase().includes(s) ||\n app.slug.toLowerCase().includes(s) ||\n app.description?.toLowerCase().includes(s) ||\n app.categories.some((c) => c.toLowerCase().includes(s))\n );\n });\n\n // Group by connected/not connected\n const connectedApps = filteredApps.filter((app) => isConnected(app));\n const availableApps = filteredApps.filter((app) => !isConnected(app));\n\n if (loading) {\n return <div className=\"text-center py-8 text-[var(--color-text-muted)]\">Loading apps...</div>;\n }\n\n return (\n <div className=\"space-y-6\">\n {/* Auth Method Choice Modal */}\n {authMethodModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg p-6 w-full max-w-md mx-4\">\n <div className=\"flex items-center gap-3 mb-4\">\n {authMethodModal.app.logo && (\n <img\n src={authMethodModal.app.logo}\n alt={authMethodModal.app.name}\n className=\"w-10 h-10 object-contain\"\n />\n )}\n <div>\n <h3 className=\"font-medium\">Connect {authMethodModal.app.name}</h3>\n <p className=\"text-xs text-[var(--color-text-muted)]\">Choose how to authenticate</p>\n </div>\n </div>\n <div className=\"space-y-3\">\n <button\n onClick={() => {\n setAuthMethodModal(null);\n setApiKeyModal({ app: authMethodModal.app });\n setApiKeyInput(\"\");\n setCredentialInputs({});\n }}\n className=\"w-full text-left p-3 bg-[var(--color-bg)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-accent)] rounded-lg transition\"\n >\n <div className=\"font-medium text-sm\">API Key</div>\n <div className=\"text-xs text-[var(--color-text-muted)] mt-0.5\">\n Enter your {authMethodModal.app.name} API key directly\n </div>\n </button>\n <button\n onClick={() => {\n setAuthMethodModal(null);\n connectApp(authMethodModal.app, undefined, true);\n }}\n className=\"w-full text-left p-3 bg-[var(--color-bg)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-accent)] rounded-lg transition\"\n >\n <div className=\"font-medium text-sm\">OAuth</div>\n <div className=\"text-xs text-[var(--color-text-muted)] mt-0.5\">\n Sign in with your {authMethodModal.app.name} account\n </div>\n </button>\n </div>\n <button\n onClick={() => setAuthMethodModal(null)}\n className=\"w-full text-sm text-[var(--color-text-muted)] hover:text-white mt-4 py-2 transition\"\n >\n Cancel\n </button>\n </div>\n </div>\n )}\n\n {/* API Key / Credentials Modal */}\n {apiKeyModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg p-6 w-full max-w-md mx-4\">\n <div className=\"flex items-center gap-3 mb-4\">\n {apiKeyModal.app.logo && (\n <img\n src={apiKeyModal.app.logo}\n alt={apiKeyModal.app.name}\n className=\"w-10 h-10 object-contain\"\n />\n )}\n <div>\n <h3 className=\"font-medium\">Connect {apiKeyModal.app.name}</h3>\n <p className=\"text-xs text-[var(--color-text-muted)]\">\n {apiKeyModal.app.credentialFields?.length\n ? \"Enter your credentials to connect\"\n : \"Enter your API key to connect\"}\n </p>\n </div>\n </div>\n <form onSubmit={handleApiKeySubmit}>\n {apiKeyModal.app.credentialFields && apiKeyModal.app.credentialFields.length > 0 ? (\n <div className=\"space-y-3 mb-4\">\n {apiKeyModal.app.credentialFields.map((field, idx) => (\n <div key={field.name}>\n <label className=\"block text-xs text-[var(--color-text-secondary)] mb-1\">\n {field.name.replace(/([A-Z])/g, \" $1\").replace(/[-_]/g, \" \").replace(/\\b\\w/g, c => c.toUpperCase()).trim()}\n {field.required !== false && <span className=\"text-red-400 ml-0.5\">*</span>}\n </label>\n {field.description && (\n <p className=\"text-[10px] text-[var(--color-text-faint)] mb-1\">{field.description}</p>\n )}\n <input\n type=\"password\"\n value={credentialInputs[field.name] || \"\"}\n onChange={(e) => setCredentialInputs(prev => ({ ...prev, [field.name]: e.target.value }))}\n placeholder={`Enter ${field.name}...`}\n className=\"w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded-lg px-4 py-2 focus:outline-none focus:border-[var(--color-accent)]\"\n autoFocus={idx === 0}\n />\n </div>\n ))}\n </div>\n ) : (\n <input\n type=\"password\"\n value={apiKeyInput}\n onChange={(e) => setApiKeyInput(e.target.value)}\n placeholder=\"Enter API Key...\"\n className=\"w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded-lg px-4 py-2 mb-4 focus:outline-none focus:border-[var(--color-accent)]\"\n autoFocus\n />\n )}\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => setApiKeyModal(null)}\n className=\"flex-1 text-sm bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={\n connecting === apiKeyModal.app.slug ||\n (apiKeyModal.app.credentialFields?.length\n ? !apiKeyModal.app.credentialFields.filter(f => f.required !== false).every(f => credentialInputs[f.name]?.trim())\n : !apiKeyInput.trim())\n }\n className=\"flex-1 text-sm bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-white px-4 py-2 rounded transition disabled:opacity-50\"\n >\n {connecting === apiKeyModal.app.slug ? \"Connecting...\" : \"Connect\"}\n </button>\n </div>\n </form>\n </div>\n </div>\n )}\n\n {/* MCP Config Creation Modal */}\n {mcpConfigModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg p-6 w-full max-w-md mx-4\">\n {mcpConfigSuccess ? (\n <>\n <div className=\"text-center mb-4\">\n <div className=\"w-12 h-12 bg-green-500/20 rounded-full flex items-center justify-center mx-auto mb-3\">\n <span className=\"text-green-400 text-2xl\">✓</span>\n </div>\n <h3 className=\"font-medium text-lg\">MCP Config Created!</h3>\n <p className=\"text-sm text-[var(--color-text-secondary)] mt-2\">\n \"{mcpConfigSuccess}\" has been created and added to your servers.\n </p>\n </div>\n <button\n onClick={() => {\n setMcpConfigModal(null);\n setMcpConfigSuccess(null);\n }}\n className=\"w-full text-sm bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-white px-4 py-2 rounded transition\"\n >\n Done\n </button>\n </>\n ) : (\n <>\n <div className=\"flex items-center gap-3 mb-4\">\n {mcpConfigModal.app.logo && (\n <img\n src={mcpConfigModal.app.logo}\n alt={mcpConfigModal.app.name}\n className=\"w-10 h-10 object-contain\"\n />\n )}\n <div>\n <h3 className=\"font-medium\">Create MCP Config</h3>\n <p className=\"text-xs text-[var(--color-text-muted)]\">\n Create an MCP config for {mcpConfigModal.app.name}\n </p>\n </div>\n </div>\n <form onSubmit={(e) => { e.preventDefault(); createMcpConfig(); }}>\n <label className=\"block text-xs text-[var(--color-text-secondary)] mb-1\">Config Name</label>\n <input\n type=\"text\"\n value={mcpConfigName}\n onChange={(e) => setMcpConfigName(e.target.value)}\n placeholder=\"Enter config name...\"\n className=\"w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded-lg px-4 py-2 mb-4 focus:outline-none focus:border-[var(--color-accent)]\"\n autoFocus\n maxLength={30}\n />\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => setMcpConfigModal(null)}\n className=\"flex-1 text-sm bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={!mcpConfigName.trim() || mcpConfigCreating}\n className=\"flex-1 text-sm bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-white px-4 py-2 rounded transition disabled:opacity-50\"\n >\n {mcpConfigCreating ? \"Creating...\" : \"Create Config\"}\n </button>\n </div>\n </form>\n </>\n )}\n </div>\n </div>\n )}\n\n {/* Confirmation Modal */}\n {confirmModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg p-6 w-full max-w-sm mx-4\">\n <p className=\"text-center mb-4\">{confirmModal.message}</p>\n <div className=\"flex gap-2\">\n <button\n onClick={() => setConfirmModal(null)}\n className=\"flex-1 text-sm bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n onClick={confirmModal.onConfirm}\n className=\"flex-1 text-sm bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded transition\"\n >\n Confirm\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Error */}\n {error && (\n <div className=\"text-red-400 text-sm p-3 bg-red-500/10 border border-red-500/20 rounded-lg flex items-center justify-between\">\n <span>{error}</span>\n <button onClick={() => setError(null)} className=\"text-red-400 hover:text-red-300\">\n ×\n </button>\n </div>\n )}\n\n {/* Pending connection notice */}\n {pendingConnection && (\n <div className=\"text-yellow-400 text-sm p-3 bg-yellow-500/10 border border-yellow-500/20 rounded-lg flex items-center gap-2\">\n <span className=\"animate-spin\">⟳</span>\n <span>Waiting for {pendingConnection.appSlug} authorization...</span>\n </div>\n )}\n\n {/* Search */}\n <div>\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search apps...\"\n className=\"w-full bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg px-4 py-2 focus:outline-none focus:border-[var(--color-accent)]\"\n />\n </div>\n\n {/* Connected Apps */}\n {connectedApps.length > 0 && (\n <div>\n <h3 className=\"text-sm font-medium text-[var(--color-text-secondary)] mb-3\">\n Connected ({connectedApps.length})\n </h3>\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {connectedApps.map((app) => (\n <AppCard\n key={app.id}\n app={app}\n connection={getConnection(app)}\n onConnect={() => connectApp(app)}\n onDisconnect={() => {\n const conn = getConnection(app);\n if (conn) handleDisconnect(conn);\n }}\n onCreateMcpConfig={hideMcpConfig ? undefined : () => openMcpConfigModal(app)}\n onBrowseTriggers={onBrowseTriggers ? () => onBrowseTriggers(app.slug) : undefined}\n onUpdateKey={supportsApiKey(app) ? () => {\n setApiKeyModal({ app });\n setApiKeyInput(\"\");\n setCredentialInputs({});\n } : undefined}\n connecting={connecting === app.slug}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Available Apps */}\n <div>\n <h3 className=\"text-sm font-medium text-[var(--color-text-secondary)] mb-3\">\n Available Apps ({availableApps.length})\n </h3>\n {availableApps.length === 0 ? (\n <p className=\"text-[var(--color-text-muted)] text-sm\">\n {search ? \"No apps match your search\" : \"No apps available\"}\n </p>\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {availableApps.slice(0, 50).map((app) => (\n <AppCard\n key={app.id}\n app={app}\n onConnect={() => connectApp(app)}\n connecting={connecting === app.slug}\n />\n ))}\n </div>\n )}\n {availableApps.length > 50 && (\n <p className=\"text-xs text-[var(--color-text-faint)] mt-3 text-center\">\n Showing first 50 of {availableApps.length} apps. Use search to find more.\n </p>\n )}\n </div>\n </div>\n );\n}\n\n// App card component\nfunction AppCard({\n app,\n connection,\n onConnect,\n onDisconnect,\n onCreateMcpConfig,\n onBrowseTriggers,\n onUpdateKey,\n connecting,\n}: {\n app: IntegrationApp;\n connection?: ConnectedAccount;\n onConnect: () => void;\n onDisconnect?: () => void;\n onCreateMcpConfig?: () => void;\n onBrowseTriggers?: () => void;\n onUpdateKey?: () => void;\n connecting: boolean;\n}) {\n const isConnected = connection?.status === \"active\";\n const hasApiKey = supportsApiKey(app);\n const hasOAuth = supportsOAuth(app);\n const hasBothMethods = hasApiKey && hasOAuth;\n\n return (\n <div\n className={`bg-[var(--color-surface)] border rounded-lg p-3 transition ${\n isConnected ? \"border-green-500/30\" : \"border-[var(--color-border)] hover:border-[var(--color-border-light)]\"\n }`}\n >\n <div className=\"flex items-start gap-3\">\n {/* Logo */}\n <div className=\"w-10 h-10 rounded bg-[var(--color-surface-raised)] flex items-center justify-center flex-shrink-0 overflow-hidden\">\n {app.logo ? (\n <img\n src={app.logo}\n alt={app.name}\n className=\"w-8 h-8 object-contain\"\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n ) : (\n <span className=\"text-lg\">{app.name[0]?.toUpperCase()}</span>\n )}\n </div>\n\n {/* Info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <h4 className=\"font-medium text-sm truncate\">{app.name}</h4>\n {isConnected && (\n <span className=\"text-xs text-green-400\">✓</span>\n )}\n {!isConnected && hasApiKey && !hasOAuth && (\n <span className=\"text-[10px] bg-[var(--color-surface-raised)] text-[var(--color-text-secondary)] px-1.5 py-0.5 rounded\" title=\"Requires API Key\">\n API Key\n </span>\n )}\n {!isConnected && hasBothMethods && (\n <span className=\"text-[10px] bg-[#1a2a1a] text-[#6a6] px-1.5 py-0.5 rounded\" title=\"Supports API Key or OAuth\">\n API Key / OAuth\n </span>\n )}\n </div>\n {app.description && (\n <p className=\"text-xs text-[var(--color-text-muted)] line-clamp-2 mt-0.5\">\n {app.description}\n </p>\n )}\n {app.categories.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mt-1\">\n {app.categories.slice(0, 2).map((cat) => (\n <span\n key={cat}\n className=\"text-[10px] bg-[var(--color-surface-raised)] text-[var(--color-text-faint)] px-1.5 py-0.5 rounded\"\n >\n {cat}\n </span>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"mt-3 flex gap-2\">\n {isConnected ? (\n <>\n {onCreateMcpConfig && (\n <button\n onClick={onCreateMcpConfig}\n className=\"flex-1 text-xs bg-[#1a2a1a] hover:bg-[#1a3a1a] border border-green-500/30 hover:border-green-500/50 text-green-400 px-3 py-1.5 rounded transition\"\n >\n Create MCP Config\n </button>\n )}\n {onBrowseTriggers && (\n <button\n onClick={onBrowseTriggers}\n className=\"flex-1 text-xs bg-[#1a1a2a] hover:bg-[#1a1a3a] border border-blue-500/30 hover:border-blue-500/50 text-blue-400 px-3 py-1.5 rounded transition\"\n >\n Browse Triggers\n </button>\n )}\n {onUpdateKey && (\n <button\n onClick={onUpdateKey}\n className=\"text-xs text-[var(--color-text-muted)] hover:text-[var(--color-accent)] transition px-2\"\n title=\"Update API Key\"\n >\n Key\n </button>\n )}\n {onDisconnect && (\n <button\n onClick={onDisconnect}\n className=\"text-xs text-[var(--color-text-muted)] hover:text-red-400 transition px-2\"\n title=\"Disconnect\"\n >\n ×\n </button>\n )}\n </>\n ) : (\n <button\n onClick={onConnect}\n disabled={connecting}\n className=\"w-full text-xs bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-accent)] px-3 py-1.5 rounded transition disabled:opacity-50\"\n >\n {connecting ? \"Connecting...\" : (hasApiKey && !hasOAuth) ? \"Enter API Key\" : \"Connect\"}\n </button>\n )}\n </div>\n </div>\n );\n}\n\nexport default IntegrationsPanel;\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "A61D71DAA9DF5C0964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "5A2FB95F167B84D164756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -0,0 +1,4 @@
1
+ import{$ as b,X as s,aa as d}from"./App.shfd8tp9.js";var r=s(b(),1),e=s(d(),1);function h({value:o,options:i,onChange:v,placeholder:m="Select...",compact:u}){let[a,l]=r.useState(!1),c=r.useRef(null),n=i.find((t)=>t.value===o);return r.useEffect(()=>{function t(f){if(c.current&&!c.current.contains(f.target))l(!1)}return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[]),e.jsxDEV("div",{ref:c,className:"relative",children:[e.jsxDEV("button",{type:"button",onClick:()=>l(!a),className:`w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] btn ${u?"px-2.5 py-1.5 text-sm":"px-3 py-2"} text-left flex items-center justify-between focus:outline-none focus:border-[var(--color-accent)] text-[var(--color-text)] hover:border-[var(--color-border-light)] transition`,children:[e.jsxDEV("span",{className:n?"text-[var(--color-text)]":"text-[var(--color-text-muted)]",children:n?e.jsxDEV(e.Fragment,{children:[n.label,n.recommended&&e.jsxDEV("span",{className:"text-[var(--color-accent)] text-xs ml-2",children:"(Recommended)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this):m},void 0,!1,void 0,this),e.jsxDEV(p,{isOpen:a},void 0,!1,void 0,this)]},void 0,!0,void 0,this),a&&e.jsxDEV("div",{className:"absolute z-50 w-full min-w-max mt-1 bg-[var(--color-surface)] border border-[var(--color-border-light)] shadow-lg max-h-60 overflow-y-auto scrollbar-hide",style:{borderRadius:"var(--radius-button)"},children:i.map((t)=>e.jsxDEV("button",{type:"button",onClick:()=>{v(t.value),l(!1)},className:`w-full ${u?"px-2.5 py-1.5 text-sm":"px-3 py-2"} text-left flex items-center justify-between hover:bg-[var(--color-surface-raised)] transition ${t.value===o?"bg-[var(--color-surface-raised)] text-[var(--color-accent)]":"text-[var(--color-text)]"}`,children:[e.jsxDEV("span",{children:[t.label,t.recommended&&e.jsxDEV("span",{className:"text-[var(--color-accent)] text-xs ml-2",children:"(Recommended)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),t.value===o&&e.jsxDEV("svg",{className:"w-4 h-4 text-[var(--color-accent)]",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},t.value,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function p({isOpen:o}){return e.jsxDEV("svg",{className:`w-4 h-4 text-[var(--color-text-muted)] transition-transform ${o?"rotate-180":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsxDEV("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"},void 0,!1,void 0,this)},void 0,!1,void 0,this)}
2
+ export{h as U};
3
+
4
+ //# debugId=A830E20FD61DEFBB64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/web/components/common/Select.tsx"],
4
+ "sourcesContent": [
5
+ "import React, { useState, useRef, useEffect } from \"react\";\n\ninterface SelectOption {\n value: string;\n label: string;\n recommended?: boolean;\n}\n\ninterface SelectProps {\n value: string;\n options: SelectOption[];\n onChange: (value: string) => void;\n placeholder?: string;\n compact?: boolean;\n}\n\nexport function Select({ value, options, onChange, placeholder = \"Select...\", compact }: SelectProps) {\n const [isOpen, setIsOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n const selectedOption = options.find(o => o.value === value);\n\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (ref.current && !ref.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n }\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, []);\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n className={`w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] btn ${compact ? \"px-2.5 py-1.5 text-sm\" : \"px-3 py-2\"} text-left flex items-center justify-between focus:outline-none focus:border-[var(--color-accent)] text-[var(--color-text)] hover:border-[var(--color-border-light)] transition`}\n >\n <span className={selectedOption ? \"text-[var(--color-text)]\" : \"text-[var(--color-text-muted)]\"}>\n {selectedOption ? (\n <>\n {selectedOption.label}\n {selectedOption.recommended && (\n <span className=\"text-[var(--color-accent)] text-xs ml-2\">(Recommended)</span>\n )}\n </>\n ) : placeholder}\n </span>\n <ChevronIcon isOpen={isOpen} />\n </button>\n\n {isOpen && (\n <div className=\"absolute z-50 w-full min-w-max mt-1 bg-[var(--color-surface)] border border-[var(--color-border-light)] shadow-lg max-h-60 overflow-y-auto scrollbar-hide\" style={{ borderRadius: \"var(--radius-button)\" }}>\n {options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => {\n onChange(option.value);\n setIsOpen(false);\n }}\n className={`w-full ${compact ? \"px-2.5 py-1.5 text-sm\" : \"px-3 py-2\"} text-left flex items-center justify-between hover:bg-[var(--color-surface-raised)] transition ${\n option.value === value ? \"bg-[var(--color-surface-raised)] text-[var(--color-accent)]\" : \"text-[var(--color-text)]\"\n }`}\n >\n <span>\n {option.label}\n {option.recommended && (\n <span className=\"text-[var(--color-accent)] text-xs ml-2\">(Recommended)</span>\n )}\n </span>\n {option.value === value && (\n <svg className=\"w-4 h-4 text-[var(--color-accent)]\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction ChevronIcon({ isOpen }: { isOpen: boolean }) {\n return (\n <svg\n className={`w-4 h-4 text-[var(--color-text-muted)] transition-transform ${isOpen ? \"rotate-180\" : \"\"}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n );\n}\n"
6
+ ],
7
+ "mappings": "qDAAA,0BAgBO,SAAS,CAAM,EAAG,QAAO,UAAS,WAAU,cAAc,YAAa,WAAwB,CACpG,IAAO,EAAQ,GAAa,WAAS,EAAK,EACpC,EAAM,SAAuB,IAAI,EAEjC,EAAiB,EAAQ,KAAK,KAAK,EAAE,QAAU,CAAK,EAY1D,OAVA,YAAU,IAAM,CACd,SAAS,CAAkB,CAAC,EAAmB,CAC7C,GAAI,EAAI,SAAW,CAAC,EAAI,QAAQ,SAAS,EAAM,MAAc,EAC3D,EAAU,EAAK,EAInB,OADA,SAAS,iBAAiB,YAAa,CAAkB,EAClD,IAAM,SAAS,oBAAoB,YAAa,CAAkB,GACxE,CAAC,CAAC,EAGH,SAgDE,MAhDF,CAAK,IAAK,EAAK,UAAU,WAAzB,SAgDE,CA/CA,SAgBE,SAhBF,CACE,KAAK,SACL,QAAS,IAAM,EAAU,CAAC,CAAM,EAChC,UAAW,6EAA6E,EAAU,wBAA0B,6LAH9H,SAgBE,CAXA,SASE,OATF,CAAM,UAAW,EAAiB,2BAA6B,iCAA/D,SACG,EACC,8BAKE,CAJC,EAAe,MACf,EAAe,aACd,SAAyE,OAAzE,CAAM,UAAU,0CAAhB,+CAAyE,IAH7E,qBAKE,EACA,GARN,qBASE,EACF,SAAC,EAAD,CAAa,OAAQ,GAArB,qBAA6B,IAf/B,qBAgBE,EAED,GACC,SA0BE,MA1BF,CAAK,UAAU,4JAA4J,MAAO,CAAE,aAAc,sBAAuB,EAAzN,SACG,EAAQ,IAAI,CAAC,IACZ,SAsBE,SAtBF,CAEE,KAAK,SACL,QAAS,IAAM,CACb,EAAS,EAAO,KAAK,EACrB,EAAU,EAAK,GAEjB,UAAW,UAAU,EAAU,wBAA0B,6GACvD,EAAO,QAAU,EAAQ,8DAAgE,6BAR7F,SAsBE,CAXA,SAKE,OALF,UAKE,CAJC,EAAO,MACP,EAAO,aACN,SAAyE,OAAzE,CAAM,UAAU,0CAAhB,+CAAyE,IAH7E,qBAKE,EACD,EAAO,QAAU,GAChB,SAEE,MAFF,CAAK,UAAU,qCAAqC,KAAK,OAAO,OAAO,eAAe,QAAQ,YAA9F,SACE,SAAC,OAAD,CAAM,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,kBAArE,qBAAsF,GADxF,qBAEE,IAnBC,EAAO,MADd,cAsBE,CACH,GAzBH,qBA0BE,IA9CN,qBAgDE,EAIN,SAAS,CAAW,EAAG,UAA+B,CACpD,OACE,SAOE,MAPF,CACE,UAAW,+DAA+D,EAAS,aAAe,KAClG,KAAK,OACL,OAAO,eACP,QAAQ,YAJV,SAME,SAAC,OAAD,CAAM,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,kBAArE,qBAAsF,GANxF,qBAOE",
8
+ "debugId": "A830E20FD61DEFBB64756E2164756E21",
9
+ "names": []
10
+ }