@runfusion/fusion 0.25.0 → 0.27.0
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.
- package/README.md +6 -0
- package/dist/bin.js +28004 -16888
- package/dist/client/assets/AgentDetailView-B7QRcHJH.css +1 -0
- package/dist/client/assets/AgentDetailView-DwLmRXTY.js +18 -0
- package/dist/client/assets/{AgentsView-B3jYk8Kt.js → AgentsView-D-N6aA0P.js} +12 -7
- package/dist/client/assets/ChatView-DnCdKu8Z.js +1 -0
- package/dist/client/assets/{DevServerView-DyGDEiBP.js → DevServerView-BiA1nYtt.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-D5UIeIl6.js → DirectoryPicker-DvBviDG6.js} +1 -1
- package/dist/client/assets/{DocumentsView-DNHu1T8K.js → DocumentsView-BWXOxpuq.js} +1 -1
- package/dist/client/assets/{EvalsView-CpRobtDi.js → EvalsView-CJFbtL7i.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-DOY_oZi7.js → ExperimentalAgentOnboardingModal-DuGIPd0B.js} +1 -1
- package/dist/client/assets/InsightsView-BBpRiolN.js +11 -0
- package/dist/client/assets/{MemoryView-PSc5lGJt.js → MemoryView-48LuNkKk.js} +2 -2
- package/dist/client/assets/NodesView-CGQWSNZM.js +14 -0
- package/dist/client/assets/{PiExtensionsManager-DL_QcN56.js → PiExtensionsManager-i-7UL2oh.js} +2 -2
- package/dist/client/assets/PluginManager-DoSAykD6.js +1 -0
- package/dist/client/assets/{ResearchView-BzCcDAS4.css → ResearchView-BEI4ZSGs.css} +1 -1
- package/dist/client/assets/ResearchView-XZuRtOxE.js +1 -0
- package/dist/client/assets/SettingsModal-Ci0_sqbU.css +1 -0
- package/dist/client/assets/{SettingsModal-CUCyaAyE.js → SettingsModal-CmeF8CN4.js} +1 -1
- package/dist/client/assets/SettingsModal-DBcjf9Bu.js +31 -0
- package/dist/client/assets/SettingsModal-DWKgRxBA.css +1 -0
- package/dist/client/assets/{SetupWizardModal-BKscasuh.js → SetupWizardModal-CgtvpMX9.js} +1 -1
- package/dist/client/assets/{SkillsView-BdELqTy7.js → SkillsView-DErYRumF.js} +1 -1
- package/dist/client/assets/StashRecoveryView-B_8WIQEo.css +1 -0
- package/dist/client/assets/StashRecoveryView-QJrNS4Vg.js +1 -0
- package/dist/client/assets/{TodoView-DFNGBDNV.js → TodoView-BD9NRwq0.js} +2 -2
- package/dist/client/assets/createLucideIcon-BazL2hk5.js +21 -0
- package/dist/client/assets/dashboard-view-BWGH_fAq.js +63 -0
- package/dist/client/assets/dashboard-view-BoTzlP8b.css +1 -0
- package/dist/client/assets/dashboard-view-DdGlfuu-.css +1 -0
- package/dist/client/assets/dashboard-view-Ws9_ZnKu.js +21 -0
- package/dist/client/assets/{folder-open-k1xmUMyr.js → folder-open-CHSlllzf.js} +1 -1
- package/dist/client/assets/index-DCovGm5b.css +1 -0
- package/dist/client/assets/index-bEwSVl7B.js +692 -0
- package/dist/client/assets/{star-ne32r3Y4.js → star-BgVwWAPz.js} +1 -1
- package/dist/client/assets/{upload-MS-2Gx53.js → upload-CAzycxr9.js} +1 -1
- package/dist/client/assets/{users-C519GSjH.js → users-CZnxCCCJ.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/droid-cli/src/__tests__/index.test.ts +228 -0
- package/dist/extension.js +15810 -10205
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/pi-claude-cli/src/__tests__/provider.test.ts +36 -22
- package/dist/pi-claude-cli/src/provider.ts +7 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/manifest.json +24 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +44 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/TestRunnerPanel.test.tsx +99 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/config-flow.test.ts +91 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/dashboard-view.test.tsx +40 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/dashboard-views.test.ts +46 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/draft-store.test.ts +50 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/fixtures/exec-mock.ts +80 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/fixtures/fixtures.test.ts +40 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/fixtures/registry.ts +82 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/generator.test.ts +54 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/manage-view.test.tsx +98 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/manifest.test.ts +36 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/registration.test.ts +29 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/run-routes.test.ts +98 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/runner.test.ts +55 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/runtime-availability.test.ts +61 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/validation.test.ts +30 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/wizard-routes.test.ts +61 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/workflow-integration.test.ts +19 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/dashboard-view.css +43 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/dashboard-view.tsx +49 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/generation/generator.ts +95 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/generation/redact.ts +9 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/generation/runner.ts +79 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/generation/types.ts +31 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/index.ts +58 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/manage/EditDraftModal.tsx +75 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/manage/useDrafts.ts +73 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/manage-view.css +79 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/manage-view.tsx +122 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/routes/wizard-routes.ts +272 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/run/TestRunnerPanel.css +70 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/run/TestRunnerPanel.tsx +98 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/run/useRunGeneratedCli.ts +37 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/runtime/__tests__/executor-runtime-env.test.ts +191 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/runtime/executor-runtime-env.ts +75 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/storage/draft-store.ts +85 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/store/__tests__/cli-press-store.test.ts +128 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/store/__tests__/credentials.test.ts +62 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/store/cli-press-store.ts +427 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/store/cli-press-types.ts +110 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/store/credentials.ts +95 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/wizard/steps.tsx +55 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/wizard/types.ts +33 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/wizard/validation.ts +63 -0
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/manifest.json +10 -0
- package/dist/plugins/fusion-plugin-reports/package.json +18 -2
- package/dist/plugins/fusion-plugin-reports/src/__tests__/approval.test.ts +164 -0
- package/dist/plugins/fusion-plugin-reports/src/__tests__/manifest.test.ts +14 -0
- package/dist/plugins/fusion-plugin-reports/src/__tests__/routes-approval.test.ts +109 -0
- package/dist/plugins/fusion-plugin-reports/src/__tests__/scaffold.test.ts +60 -0
- package/dist/plugins/fusion-plugin-reports/src/__tests__/share-blocks.test.ts +83 -0
- package/dist/plugins/fusion-plugin-reports/src/aggregation.ts +23 -0
- package/dist/plugins/fusion-plugin-reports/src/approval.ts +97 -0
- package/dist/plugins/fusion-plugin-reports/src/cadence.ts +23 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/ReportsView.css +82 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/ReportsView.tsx +24 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/__tests__/ReportComparisonDrawer.test.tsx +12 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/__tests__/ReportDetailPanel.test.tsx +12 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/__tests__/ReportFiltersBar.test.tsx +14 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/__tests__/ReportsView.test.tsx +27 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/__tests__/api.test.ts +19 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/__tests__/useReportSectionDiff.test.ts +11 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/__tests__/useReports.test.ts +13 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/api.ts +85 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/components/ReportApprovalPanel.css +59 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/components/ReportApprovalPanel.tsx +58 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/components/ReportComparisonDrawer.tsx +21 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/components/ReportDetailPanel.tsx +29 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/components/ReportEmptyState.tsx +3 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/components/ReportFiltersBar.tsx +19 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/components/ReportListItem.tsx +8 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/components/ShareBlocksPanel.css +29 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/components/ShareBlocksPanel.tsx +43 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/components/__tests__/ReportApprovalPanel.test.tsx +38 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/components/__tests__/ShareBlocksPanel.test.tsx +24 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/test-setup.ts +18 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/types.ts +22 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/useReportPreview.ts +44 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/useReportSectionDiff.ts +59 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/useReports.ts +71 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/useViewportMode.ts +13 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard-view.tsx +6 -0
- package/dist/plugins/fusion-plugin-reports/src/index.ts +48 -2
- package/dist/plugins/fusion-plugin-reports/src/pipeline.ts +58 -0
- package/dist/plugins/fusion-plugin-reports/src/render/__tests__/escape.test.ts +20 -0
- package/dist/plugins/fusion-plugin-reports/src/render/__tests__/html-template.test.ts +110 -0
- package/dist/plugins/fusion-plugin-reports/src/render/__tests__/standalone-html.test.ts +66 -0
- package/dist/plugins/fusion-plugin-reports/src/render/escape.ts +12 -0
- package/dist/plugins/fusion-plugin-reports/src/render/html-styles.ts +40 -0
- package/dist/plugins/fusion-plugin-reports/src/render/html-template.ts +137 -0
- package/dist/plugins/fusion-plugin-reports/src/render/index.ts +4 -0
- package/dist/plugins/fusion-plugin-reports/src/render/standalone-html.ts +75 -0
- package/dist/plugins/fusion-plugin-reports/src/report-schema.ts +31 -0
- package/dist/plugins/fusion-plugin-reports/src/routes/__tests__/report-export-routes.test.ts +104 -0
- package/dist/plugins/fusion-plugin-reports/src/routes/report-approval-routes.ts +98 -0
- package/dist/plugins/fusion-plugin-reports/src/routes/report-export-routes.ts +77 -0
- package/dist/plugins/fusion-plugin-reports/src/routes/report-list-routes.ts +72 -0
- package/dist/plugins/fusion-plugin-reports/src/runs-store.ts +69 -0
- package/dist/plugins/fusion-plugin-reports/src/share-blocks.ts +82 -0
- package/dist/plugins/fusion-plugin-reports/src/store/report-store.ts +51 -2
- package/dist/plugins/fusion-plugin-reports/src/store/report-types.ts +6 -1
- package/dist/plugins/fusion-plugin-roadmap/bundled.js +1672 -0
- package/dist/plugins/fusion-plugin-roadmap/manifest.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/package.json +4 -41
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +2 -3
- package/skill/fusion/references/engine-tools.md +1 -1
- package/skill/fusion/references/extension-tools.md +3 -3
- package/skill/fusion/references/fusion-capabilities.md +1 -1
- package/dist/client/assets/AgentDetailView-BwJaLqZh.css +0 -1
- package/dist/client/assets/AgentDetailView-ZbHEbYRT.js +0 -18
- package/dist/client/assets/ChatView-DhPkiEGs.js +0 -1
- package/dist/client/assets/InsightsView-vp0RE8Mg.js +0 -11
- package/dist/client/assets/NodesView-DMj6HGeC.js +0 -14
- package/dist/client/assets/PluginManager-BtYKm8IT.js +0 -1
- package/dist/client/assets/ResearchView-BhWqfdV0.js +0 -1
- package/dist/client/assets/SettingsModal-BAgB4_AR.js +0 -31
- package/dist/client/assets/SettingsModal-BNSrO1M9.css +0 -1
- package/dist/client/assets/SettingsModal-DzsLquBu.css +0 -1
- package/dist/client/assets/index-Qq2JOOWx.css +0 -1
- package/dist/client/assets/index-TFYXEVpn.js +0 -692
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/api-client.test.ts +0 -101
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/index.test.ts +0 -92
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/roadmap-routes.test.ts +0 -48
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/roadmap-suggestions.test.ts +0 -31
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/RoadmapsView.css +0 -1299
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/RoadmapsView.tsx +0 -2559
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/__tests__/RoadmapsView.test.tsx +0 -1144
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/__tests__/useRoadmaps.test.ts +0 -1756
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/api.ts +0 -70
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/test-setup.ts +0 -7
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/types.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useConfirm.ts +0 -8
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useRoadmaps.ts +0 -1188
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useViewportMode.ts +0 -20
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard-view.tsx +0 -6
- package/dist/plugins/fusion-plugin-roadmap/src/index.ts +0 -74
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-routes.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-schema.ts +0 -41
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-suggestions.d.ts +0 -15
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-suggestions.ts +0 -15
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.d.ts +0 -283
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.js +0 -21
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.ts +0 -310
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.d.ts +0 -5
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.js +0 -361
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.ts +0 -408
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.d.ts +0 -68
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.js +0 -300
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.ts +0 -381
- package/dist/plugins/fusion-plugin-roadmap/src/server/index.d.ts +0 -3
- package/dist/plugins/fusion-plugin-roadmap/src/server/index.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-handoff.test.ts +0 -445
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-ordering.test.ts +0 -334
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-store.test.ts +0 -1318
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-handoff.ts +0 -163
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.d.ts +0 -37
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.js +0 -188
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.ts +0 -311
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.d.ts +0 -299
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.js +0 -765
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.ts +0 -1001
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{u as Le}from"./SettingsModal-
|
|
2
|
-
`).map(r=>r.replace(/^-\s+/,"").trim()).filter(r=>r.length>0&&(r.startsWith("- ")||r.startsWith("* ")));(x.length>0||b.length>0)&&t.push({name:E,key:M,items:x.length>0?x:b.length>0?[b]:[],expanded:!0})}}return t}function ts(i){if(!i)return null;const t=i.match(/##\s+Last\s+Updated:\s*(\d{4}-\d{2}-\d{2})/i);return t?t[1]:null}function as(i){return i.reduce((t,m)=>t+m.items.length,0)}function ns(i){switch(i){case"file":return"File (.fusion/memory/, agent/<agent-name>/memory/)";case"readonly":return"Read-Only";case"qmd":return"QMD (Quantized Memory Distillation)";default:return i}}function rs(i){switch(i){case"healthy":return"Healthy";case"warning":return"Warning";case"issues":return"Issues Found"}}function os({projectId:i,addToast:t}){const[m,u]=a.useState("working"),[C,A]=a.useState(new Set),[E,M]=a.useState(!1),[b,x]=a.useState(null),[r,p]=a.useState({memoryEnabled:!0,memoryAutoSummarizeEnabled:!1,memoryAutoSummarizeThresholdChars:5e4,memoryAutoSummarizeSchedule:"0 3 * * *",memoryDreamsEnabled:!1,memoryDreamsSchedule:"0 4 * * *"}),[T,J]=a.useState(""),[X,L]=a.useState(!1),[S,P]=a.useState(null),{insightsContent:F,insightsLoading:ee,insightsExists:ue,saveInsights:$,memorySettings:o,settingsLoading:v,saveMemorySettings:se,savingMemorySettings:I,backendStatus:c,backendLoading:k,extractInsights:W,extracting:y,auditReport:d,auditLoading:te,refreshAudit:U,compactMemory:f,compacting:ae,installQmdAction:H,installingQmd:ne,testRetrieval:Q,memoryFiles:Y,memoryFilesLoading:re,selectedFilePath:D,selectedFileContent:z,selectedFileLoading:ye,selectedFileDirty:R,setSelectedFileContent:ge,selectFile:B,saveSelectedFile:ie,savingSelectedFile:G,reloadMemoryFiles:le,triggerDreamNow:V,dreamRunning:me}=Ge({projectId:i});a.useEffect(()=>{p(o)},[o]);const K=a.useMemo(()=>r.memoryEnabled!==o.memoryEnabled||r.memoryAutoSummarizeEnabled!==o.memoryAutoSummarizeEnabled||r.memoryAutoSummarizeThresholdChars!==o.memoryAutoSummarizeThresholdChars||r.memoryAutoSummarizeSchedule!==o.memoryAutoSummarizeSchedule||r.memoryDreamsEnabled!==o.memoryDreamsEnabled||r.memoryDreamsSchedule!==o.memoryDreamsSchedule,[r,o]),j=a.useMemo(()=>Y.find(s=>s.path===D),[Y,D]),be=j?Ze[j.layer]:"Edits the selected memory file.",N=a.useMemo(()=>ss(F),[F]),q=a.useMemo(()=>as(N),[N]),ce=a.useMemo(()=>ts(F),[F]),oe=a.useCallback(s=>{A(h=>{const g=new Set(h);return g.has(s)?g.delete(s):g.add(s),g})},[]),xe=a.useCallback(async s=>{try{await B(s)}catch{t("Failed to load memory file","error")}},[B,t]),pe=a.useCallback(async()=>{try{await ie(),t("Memory saved","success")}catch{t("Failed to save memory","error")}},[ie,t]),fe=a.useCallback(async()=>{if(!K)return;const s={};r.memoryEnabled!==o.memoryEnabled&&(s.memoryEnabled=r.memoryEnabled),r.memoryAutoSummarizeEnabled!==o.memoryAutoSummarizeEnabled&&(s.memoryAutoSummarizeEnabled=r.memoryAutoSummarizeEnabled),r.memoryAutoSummarizeThresholdChars!==o.memoryAutoSummarizeThresholdChars&&(s.memoryAutoSummarizeThresholdChars=r.memoryAutoSummarizeThresholdChars),r.memoryAutoSummarizeSchedule!==o.memoryAutoSummarizeSchedule&&(s.memoryAutoSummarizeSchedule=r.memoryAutoSummarizeSchedule),r.memoryDreamsEnabled!==o.memoryDreamsEnabled&&(s.memoryDreamsEnabled=r.memoryDreamsEnabled),r.memoryDreamsSchedule!==o.memoryDreamsSchedule&&(s.memoryDreamsSchedule=r.memoryDreamsSchedule);try{await se(s),t("Memory settings saved","success")}catch{t("Failed to save memory settings","error")}},[K,r,o,se,t]),je=a.useCallback(async()=>{try{const s=await H();t(s.qmdAvailable?"qmd installed successfully":"qmd install finished, but qmd is still unavailable",s.qmdAvailable?"success":"info")}catch{t("Failed to install qmd","error")}},[H,t]),Se=a.useCallback(async()=>{L(!0),P(null);try{const s=await Q(T);P(s),t(s.qmdAvailable?"Memory retrieval test complete":"qmd is not installed; local fallback was used",s.qmdAvailable?"success":"info")}catch{t("Failed to test memory retrieval","error")}finally{L(!1)}},[T,Q,t]),Z=a.useCallback(async()=>{try{await V(),t("Dream processing completed","success"),await le()}catch(s){t(s instanceof Error?s.message:"Failed to run dream processing","error")}},[V,le,t]),_=a.useCallback(async()=>{try{await f(D),t("Memory file compacted","success")}catch{t("Failed to compact memory","error")}},[f,D,t]),de=a.useCallback(async()=>{try{const s=await W();t(s.summary,"success")}catch(s){t(s instanceof Error?s.message:"Failed to extract insights","error")}},[W,t]),ve=a.useCallback(async()=>{if(b!==null)try{await $(b),M(!1),x(null),t("Insights saved","success")}catch{t("Failed to save insights","error")}},[b,$,t]),Ne=a.useCallback(()=>{x(F??""),M(!0)},[F]),Ce=a.useCallback(()=>{M(!1),x(null)},[]),n=!k&&c!==null,l=c?.capabilities?.writable??!1;return e.jsxs("div",{className:"memory-view",children:[e.jsx("div",{className:"memory-view-header",children:e.jsxs("div",{children:[e.jsx("h2",{children:"Memory"}),e.jsx("p",{className:"memory-view-description",children:"Working memory, long-term insights, and engine status"})]})}),e.jsxs("div",{className:"memory-view-tabs",role:"tablist",children:[e.jsx("button",{type:"button",role:"tab","aria-selected":m==="working",className:`memory-view-tab${m==="working"?" memory-view-tab--active":""}`,onClick:()=>u("working"),"data-testid":"memory-tab-working",children:"Working Memory"}),e.jsx("button",{type:"button",role:"tab","aria-selected":m==="insights",className:`memory-view-tab${m==="insights"?" memory-view-tab--active":""}`,onClick:()=>u("insights"),"data-testid":"memory-tab-insights",children:"Insights"}),e.jsx("button",{type:"button",role:"tab","aria-selected":m==="engines",className:`memory-view-tab${m==="engines"?" memory-view-tab--active":""}`,onClick:()=>u("engines"),"data-testid":"memory-tab-engines",children:"Engines"})]}),e.jsxs("div",{className:"memory-view-content",children:[m==="working"&&e.jsxs("div",{className:"memory-working-tab",children:[n&&!l&&e.jsx("div",{className:"memory-readonly-banner",children:"This memory backend is read-only. Changes cannot be saved."}),re||ye?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading memory file…"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-editor-section",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryViewFilePath",children:"Memory File"}),e.jsx("select",{id:"memoryViewFilePath",className:"select",value:D,onChange:s=>{xe(s.target.value)},disabled:R,children:Y.map(s=>e.jsx("option",{value:s.path,title:`${s.label} — ${s.path}`,children:es(s)},s.path))}),e.jsx("small",{children:R?"Save or discard the current edits before switching files.":"Choose any project memory file to view or edit."})]}),j&&e.jsxs("div",{className:"memory-file-summary",children:[e.jsx("span",{children:Ke[j.layer]}),e.jsx("strong",{children:j.path}),e.jsxs("small",{children:[j.size.toLocaleString()," bytes · updated ",new Date(j.updatedAt).toLocaleString()]})]}),e.jsxs("div",{className:"form-group memory-editor-form-group",children:[e.jsx("label",{children:j?.label||"Memory Editor"}),e.jsx("small",{children:be}),e.jsx("div",{className:"memory-editor-container",children:e.jsx(Fe,{content:z,onChange:ge,readOnly:!l,filePath:D})})]})]}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsxs("span",{className:"memory-char-count",children:[z.length," characters"]}),e.jsx("div",{className:"memory-flex-spacer"}),l&&z.length>0&&e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:_,disabled:ae||R,children:ae?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Compacting…"]}):"Compact Selected File"}),R&&l&&e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:pe,disabled:G,children:G?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Saving…"]}):"Save"})]}),e.jsxs("div",{className:"memory-config-section",children:[e.jsxs("div",{className:"memory-settings-group",children:[e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryDreamsEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryDreamsEnabled",type:"checkbox",checked:r.memoryDreamsEnabled,onChange:s=>{p(h=>({...h,memoryDreamsEnabled:s.target.checked}))},disabled:!r.memoryEnabled||v}),"Process dreams from daily memory"]}),e.jsx("small",{children:"Turns daily notes into DREAMS.md and promotes reusable lessons into MEMORY.md."})]}),r.memoryEnabled&&r.memoryDreamsEnabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryDreamsSchedule",children:"Dream Schedule"}),e.jsx("input",{id:"memoryDreamsSchedule",type:"text",className:"input",value:r.memoryDreamsSchedule,onChange:s=>{p(h=>({...h,memoryDreamsSchedule:s.target.value}))},placeholder:"0 4 * * *",disabled:v}),e.jsx("small",{children:"Cron expression for dream processing."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:Z,disabled:me||!r.memoryDreamsEnabled,children:me?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Dreaming…"]}):"Dream Now"}),e.jsx("small",{children:"Manually trigger dream processing now."})]})]})]}),e.jsxs("div",{className:"memory-settings-group",children:[e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryAutoSummarizeEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryAutoSummarizeEnabled",type:"checkbox",checked:r.memoryAutoSummarizeEnabled,onChange:s=>{p(h=>({...h,memoryAutoSummarizeEnabled:s.target.checked}))},disabled:!r.memoryEnabled||v}),"Auto-Summarize Memory"]}),e.jsx("small",{children:"Automatically compact memory when it exceeds the threshold on a schedule"})]}),r.memoryEnabled&&r.memoryAutoSummarizeEnabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeThresholdChars",children:"Compaction Threshold (chars)"}),e.jsx("input",{id:"memoryAutoSummarizeThresholdChars",type:"number",className:"input",value:r.memoryAutoSummarizeThresholdChars,onChange:s=>{p(h=>({...h,memoryAutoSummarizeThresholdChars:parseInt(s.target.value,10)||5e4}))},min:1e3,disabled:v}),e.jsx("small",{children:"Memory will be compacted when it exceeds this character count"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeSchedule",children:"Schedule (cron)"}),e.jsx("input",{id:"memoryAutoSummarizeSchedule",type:"text",className:"input",value:r.memoryAutoSummarizeSchedule,onChange:s=>{p(h=>({...h,memoryAutoSummarizeSchedule:s.target.value}))},placeholder:"0 3 * * *",disabled:v}),e.jsx("small",{children:"Cron expression for auto-summarize schedule (default: daily at 3 AM)"})]})]})]}),!r.memoryEnabled&&e.jsx("div",{className:"settings-empty-state memory-status-message",children:"Memory is currently disabled. Enable memory tools in Settings to edit these automations."}),K&&e.jsx("div",{className:"memory-action-bar",children:e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:fe,disabled:I||v,children:I?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Saving…"]}):"Save Settings"})})]})]})]}),m==="insights"&&e.jsx("div",{className:"memory-insights-tab",children:ee?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading insights…"})]}):E?e.jsxs("div",{className:"memory-insights-editor-layout",children:[e.jsx("div",{className:"memory-editor-container",children:e.jsx(Fe,{content:b??"",onChange:x,readOnly:!1,filePath:".fusion/memory/INSIGHTS.md"})}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Ce,children:"Cancel"}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:ve,children:"Save Insights"})]})]}):!ue||N.length===0?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx("p",{children:"No insights extracted yet."}),e.jsx("p",{children:'Insights are automatically extracted from working memory. Click "Extract Now" to trigger extraction manually.'}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm memory-empty-extract-button",onClick:de,disabled:y,children:y?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Extracting…"]}):"Extract Now"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-stats-row",children:[e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value",children:q}),e.jsx("div",{className:"memory-stat-label",children:"Total Insights"})]}),e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value",children:N.length}),e.jsx("div",{className:"memory-stat-label",children:"Categories"})]}),ce&&e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value memory-stat-value--updated",children:ce}),e.jsx("div",{className:"memory-stat-label",children:"Last Updated"})]})]}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:de,disabled:y,children:y?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Extracting…"]}):"Extract Now"}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Ne,children:"Edit Raw"})]}),e.jsx("div",{className:"memory-categories-list",children:N.map(s=>{const h=!C.has(s.key);return e.jsxs("div",{className:"memory-category-section",children:[e.jsxs("div",{className:"memory-category-header",onClick:()=>oe(s.key),role:"button",tabIndex:0,onKeyDown:g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),oe(s.key))},children:[e.jsx("h4",{children:s.name}),e.jsx("span",{className:"memory-category-count",children:s.items.length})]}),h&&e.jsx("div",{className:"memory-category-items",children:s.items.map((g,ze)=>e.jsx("div",{className:"memory-insight-item",children:g.replace(/^-\s+/,"").replace(/^\*\s+/,"")},ze))})]},s.key)})})]})}),m==="engines"&&e.jsx("div",{className:"memory-engines-tab",children:k||te?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading engine status…"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-engine-card memory-qmd-card",children:[e.jsx("h3",{children:"QMD Integration"}),c?.qmdAvailable===!0?e.jsxs("div",{className:"memory-engine-status",children:[e.jsx("span",{className:"memory-health-badge memory-health-badge--healthy",children:"Installed"}),e.jsx("span",{className:"memory-char-count",children:"qmd is available on PATH."})]}):c?.qmdAvailable===!1?e.jsxs("div",{className:"settings-empty-state memory-status-message",children:[e.jsxs("span",{children:["qmd is not installed. Search will use local files. Install indexed retrieval: ",e.jsx("code",{children:c.qmdInstallCommand||"bun install -g @tobilu/qmd"})]}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:je,disabled:ne,children:ne?"Installing…":"Install qmd"})]}):e.jsxs("div",{className:"memory-engine-status",children:[e.jsx("span",{className:"memory-health-badge",children:"Checking"}),e.jsx("span",{className:"memory-char-count",children:"Checking qmd availability…"})]}),e.jsxs("div",{className:"memory-capability-row",children:[c?.capabilities?.readable&&e.jsx("span",{className:"memory-capability-badge",children:"Readable"}),c?.capabilities?.writable&&e.jsx("span",{className:"memory-capability-badge",children:"Writable"}),c?.capabilities?.supportsAtomicWrite&&e.jsx("span",{className:"memory-capability-badge",children:"Atomic Writes"}),c?.capabilities?.persistent&&e.jsx("span",{className:"memory-capability-badge",children:"Persistent"})]})]}),e.jsxs("div",{className:"memory-engine-card memory-retrieval-card",children:[e.jsx("h3",{children:"Test Memory Search"}),e.jsxs("div",{className:"memory-retrieval-input-row",children:[e.jsx("input",{type:"text",className:"input",value:T,onChange:s=>J(s.target.value),placeholder:"Search memory with qmd"}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Se,disabled:X,children:X?"Testing…":"Test Retrieval"})]}),e.jsx("small",{className:"settings-muted",children:"Runs the same qmd-backed memory_search path agents use."}),S&&e.jsxs("div",{className:"memory-test-result",children:[e.jsxs("strong",{children:[S.results.length," result",S.results.length===1?"":"s"," ",'for "',S.query,'"']}),e.jsxs("small",{children:["qmd ",S.qmdAvailable?"available":"missing"," · ",S.usedFallback?"local fallback used":"qmd path used"]}),S.results.length>0?e.jsx("ul",{children:S.results.map((s,h)=>e.jsxs("li",{children:[e.jsxs("span",{children:[s.path,":",s.lineStart]}),e.jsx("p",{children:s.snippet})]},`${s.path}-${s.lineStart}-${h}`))}):e.jsx("small",{children:"No matching memory found."})]})]}),e.jsxs("div",{className:"memory-engine-card",children:[e.jsx("h3",{children:"Current Backend"}),e.jsx("div",{className:"memory-engine-status",children:e.jsx("span",{className:"memory-emphasis-text",children:ns(c?.currentBackend??"unknown")})}),e.jsxs("div",{className:"memory-capability-row",children:[c?.capabilities?.readable&&e.jsx("span",{className:"memory-capability-badge",children:"Readable"}),c?.capabilities?.writable&&e.jsx("span",{className:"memory-capability-badge",children:"Writable"}),c?.capabilities?.supportsAtomicWrite&&e.jsx("span",{className:"memory-capability-badge",children:"Atomic Writes"}),c?.capabilities?.persistent&&e.jsx("span",{className:"memory-capability-badge",children:"Persistent"})]})]}),d&&e.jsxs("div",{className:"memory-engine-card",children:[e.jsxs("div",{className:"memory-health-header",children:[e.jsx("h3",{children:"Health Status"}),e.jsx("span",{className:`memory-health-badge memory-health-badge--${d.health}`,children:rs(d.health)})]}),e.jsxs("div",{className:"memory-health-grid",children:[e.jsxs("div",{children:[e.jsx("div",{className:"memory-health-label",children:"Working Memory"}),e.jsxs("div",{className:"memory-emphasis-text",children:[d.workingMemory.size," chars"]}),e.jsxs("div",{className:"memory-health-detail",children:[d.workingMemory.sectionCount," sections"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"memory-health-label",children:"Insights Memory"}),e.jsxs("div",{className:"memory-emphasis-text",children:[d.insightsMemory.size," chars"]}),e.jsxs("div",{className:"memory-health-detail",children:[d.insightsMemory.insightCount," insights"]})]})]}),e.jsxs("div",{className:"memory-health-section",children:[e.jsx("div",{className:"memory-health-label",children:"Last Extraction"}),e.jsx("div",{className:"memory-emphasis-text",children:d.extraction.success?e.jsx("span",{className:"memory-status-text memory-status-text--success",children:"Success"}):e.jsx("span",{className:"memory-status-text memory-status-text--error",children:"Failed"})}),e.jsx("div",{className:"memory-health-detail",children:d.extraction.summary||`${d.extraction.insightCount} insights extracted`})]}),e.jsxs("div",{className:"memory-health-section",children:[e.jsx("div",{className:"memory-health-label",children:"Pruning"}),e.jsx("div",{className:"memory-emphasis-text",children:d.pruning.applied?e.jsx("span",{className:"memory-status-text memory-status-text--warning",children:"Applied"}):e.jsx("span",{className:"memory-status-text memory-status-text--muted",children:"Not needed"})}),d.pruning.applied&&e.jsx("div",{className:"memory-health-detail",children:d.pruning.reason})]})]}),d&&d.checks.length>0&&e.jsxs("div",{className:"memory-engine-card",children:[e.jsx("h3",{children:"Audit Checks"}),e.jsx("div",{children:d.checks.map(s=>e.jsxs("div",{className:"memory-audit-check",children:[e.jsx("span",{className:s.passed?"memory-audit-check-passed":"memory-audit-check-failed",children:s.passed?"✓":"✗"}),e.jsxs("div",{className:"memory-audit-check-content",children:[e.jsx("div",{className:"memory-emphasis-text",children:s.name}),e.jsx("div",{className:"memory-health-detail",children:s.details})]})]},s.id))})]}),e.jsx("div",{className:"memory-action-bar",children:e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:()=>U(),children:"Run Audit"})}),e.jsxs("div",{className:"memory-settings-note",children:[e.jsx("span",{children:"Note: Change backend type in"}),e.jsx("button",{type:"button",className:"memory-settings-note-button",onClick:()=>{t("Open Settings → Memory to change backend type","info")},children:"Settings → Memory"})]})]})})]})]})}export{os as MemoryView};
|
|
1
|
+
import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{u as Le}from"./SettingsModal-CmeF8CN4.js";import{bC as Ee,bD as Me,bE as Ie,y as Re,bF as qe,bG as Pe,bH as _e,bI as ke,bJ as we,bK as We,bL as Oe,bM as Te,bN as Ae,bO as $e,x as Ue,bP as He,L as w,bQ as Fe}from"./index-bEwSVl7B.js";import"./vendor-xterm-DzcZoU0P.js";const O=".fusion/memory/MEMORY.md",Qe=5e4,Ye="0 3 * * *",Be="0 4 * * *";function he(i){return{memoryEnabled:i.memoryEnabled!==!1,memoryAutoSummarizeEnabled:i.memoryAutoSummarizeEnabled??!1,memoryAutoSummarizeThresholdChars:i.memoryAutoSummarizeThresholdChars??Qe,memoryAutoSummarizeSchedule:i.memoryAutoSummarizeSchedule??Ye,memoryDreamsEnabled:i.memoryDreamsEnabled??!1,memoryDreamsSchedule:i.memoryDreamsSchedule??Be}}function De(i,t){return i.some(m=>m.path===t)?t:i.find(m=>m.path===O)?.path??i[0]?.path??O}function Ge(i={}){const{projectId:t}=i,[m,u]=a.useState(""),[C,A]=a.useState(!0),[E,M]=a.useState(!1),[b,x]=a.useState(!1),[r,p]=a.useState(null),[T,J]=a.useState(!0),[X,L]=a.useState(!1),[S,_]=a.useState(()=>he({})),[F,ee]=a.useState(!0),[ue,$]=a.useState(!1),[o,v]=a.useState([]),[se,I]=a.useState(!0),[c,k]=a.useState(O),[W,y]=a.useState(""),[d,te]=a.useState(!1),[U,f]=a.useState(!1),[ae,H]=a.useState(!1),[ne,Q]=a.useState(!1),[Y,re]=a.useState(!1),[D,z]=a.useState(null),[ye,R]=a.useState(!0),[ge,B]=a.useState(!1),[ie,G]=a.useState(!1),[le,V]=a.useState(null),{status:me,loading:K,refresh:j}=Le({projectId:t}),be=a.useCallback(n=>{y(n),f(!0)},[]),N=a.useCallback(async n=>{te(!0);try{const{content:l}=await Ee(n,t);k(n),y(l),f(!1)}finally{te(!1)}},[t]),q=a.useCallback(async()=>{I(!0);try{const{files:n}=await Me(t);if(v(n),n.length===0){k(O),y(""),f(!1);return}const l=De(n,c);l!==c&&await N(l)}finally{I(!1)}},[t,c,N]);a.useEffect(()=>{let n=!1;async function l(){try{const s=await $e(t);n||(u(s.content),A(!1))}catch{n||(u(""),A(!1))}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){try{const s=await we(t);n||(p(s.content),L(s.exists),J(!1))}catch{n||(p(null),L(!1),J(!1))}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){ee(!0);try{const s=await Ue(t);n||_(he(s))}catch{n||_(he({}))}finally{n||ee(!1)}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){I(!0);try{const{files:s}=await Me(t);if(n)return;if(v(s),s.length===0){k(O),y(""),f(!1);return}const h=De(s,c),{content:g}=await Ee(h,t);if(n)return;k(h),y(g),f(!1)}catch{n||(v([]),k(O),y(""),f(!1))}finally{n||I(!1)}}return l(),()=>{n=!0}},[t,c]),a.useEffect(()=>{let n=!1;async function l(){try{const s=await ke(t);n||(z(s),R(!1))}catch{n||(z(null),R(!1))}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){try{const s=await He(t);n||V(s)}catch{n||V(null)}}return l(),()=>{n=!0}},[t]);const ce=a.useCallback(n=>{u(n),M(!0)},[]),oe=a.useCallback(async()=>{if(E){x(!0);try{await Ie(m,t),M(!1)}finally{x(!1)}}},[m,E,t]),xe=a.useCallback(async n=>{$(!0);try{const l=await Re(n,t);_(he(l))}finally{$(!1)}},[t]),pe=a.useCallback(async n=>{await N(n)},[N]),fe=a.useCallback(async()=>{if(U){H(!0);try{await qe(c,W,t),f(!1),await q()}finally{H(!1)}}},[W,U,c,t,q]),je=a.useCallback(async()=>{G(!0);try{const n=await Pe(t);return await j(),n}finally{G(!1)}},[t,j]),Se=a.useCallback(async n=>_e(n,t),[t]),Z=a.useCallback(async()=>{try{const n=await ke(t);z(n)}catch{z(null)}},[t]),P=a.useCallback(async()=>{try{const n=await we(t);p(n.content),L(n.exists)}catch{p(null),L(!1)}},[t]),de=a.useCallback(async n=>{await We(n,t),await P()},[t,P]),ve=a.useCallback(async()=>{Q(!0);try{const n=await Oe(t);return await Promise.all([P(),Z()]),{success:n.success,summary:n.summary}}finally{Q(!1)}},[t,P,Z]),Ne=a.useCallback(async()=>{re(!0);try{return await Te(t)}finally{re(!1)}},[t]),Ce=a.useCallback(async n=>{B(!0);try{const l=n?await Ae(n,t):await Ae(t);if(n){const s=l.path??n;k(s),y(l.content),f(!1),await q();return}u(l.content),M(!0)}finally{B(!1)}},[t,q]);return{workingMemory:m,workingMemoryLoading:C,workingMemoryDirty:E,setWorkingMemory:ce,saveWorkingMemory:oe,savingWorkingMemory:b,insightsContent:r,insightsLoading:T,insightsExists:X,refreshInsights:P,saveInsights:de,memorySettings:S,settingsLoading:F,savingMemorySettings:ue,saveMemorySettings:xe,memoryFiles:o,memoryFilesLoading:se,selectedFilePath:c,selectedFileContent:W,selectedFileLoading:d,selectedFileDirty:U,setSelectedFileContent:be,selectFile:pe,saveSelectedFile:fe,savingSelectedFile:ae,reloadMemoryFiles:q,backendStatus:me,backendLoading:K,extractInsights:ve,extracting:ne,triggerDreamNow:Ne,dreamRunning:Y,auditReport:D,auditLoading:ye,refreshAudit:Z,compactMemory:Ce,compacting:ge,installQmdAction:je,installingQmd:ie,testRetrieval:Se,stats:le}}const Ve={Patterns:"pattern",Principles:"principle",Conventions:"convention",Pitfalls:"pitfall",Context:"context"},Ke={"long-term":"Long-term",daily:"Daily",dreams:"Dreams"},Ze={"long-term":"Curated durable decisions, conventions, constraints, and pitfalls promoted from dreams.",daily:"Raw daily observations, open loops, and running context for dream processing.",dreams:"Synthesized patterns and open loops promoted from daily memory."},Je=72;function Xe(i,t){if(i.length<=t)return i;const m=Math.max(1,t-1),u=Math.ceil(m/2),C=Math.floor(m/2);return`${i.slice(0,u)}…${i.slice(i.length-C)}`}function es(i){const t=`${i.label} — ${i.path}`;return Xe(t,Je)}function ss(i){if(!i)return[];const t=[],m=i.split(/(?=^## )/m);for(const u of m){const C=u.trim();if(!C)continue;const A=C.match(/^##\s+(.+?)(\n|$)/);if(A){const E=A[1].trim(),M=Ve[E]??E.toLowerCase(),b=C.slice(A[0].length).trim(),x=b.split(`
|
|
2
|
+
`).map(r=>r.replace(/^-\s+/,"").trim()).filter(r=>r.length>0&&(r.startsWith("- ")||r.startsWith("* ")));(x.length>0||b.length>0)&&t.push({name:E,key:M,items:x.length>0?x:b.length>0?[b]:[],expanded:!0})}}return t}function ts(i){if(!i)return null;const t=i.match(/##\s+Last\s+Updated:\s*(\d{4}-\d{2}-\d{2})/i);return t?t[1]:null}function as(i){return i.reduce((t,m)=>t+m.items.length,0)}function ns(i){switch(i){case"file":return"File (.fusion/memory/, agent/<agent-name>/memory/)";case"readonly":return"Read-Only";case"qmd":return"QMD (Quantized Memory Distillation)";default:return i}}function rs(i){switch(i){case"healthy":return"Healthy";case"warning":return"Warning";case"issues":return"Issues Found"}}function os({projectId:i,addToast:t}){const[m,u]=a.useState("working"),[C,A]=a.useState(new Set),[E,M]=a.useState(!1),[b,x]=a.useState(null),[r,p]=a.useState({memoryEnabled:!0,memoryAutoSummarizeEnabled:!1,memoryAutoSummarizeThresholdChars:5e4,memoryAutoSummarizeSchedule:"0 3 * * *",memoryDreamsEnabled:!1,memoryDreamsSchedule:"0 4 * * *"}),[T,J]=a.useState(""),[X,L]=a.useState(!1),[S,_]=a.useState(null),{insightsContent:F,insightsLoading:ee,insightsExists:ue,saveInsights:$,memorySettings:o,settingsLoading:v,saveMemorySettings:se,savingMemorySettings:I,backendStatus:c,backendLoading:k,extractInsights:W,extracting:y,auditReport:d,auditLoading:te,refreshAudit:U,compactMemory:f,compacting:ae,installQmdAction:H,installingQmd:ne,testRetrieval:Q,memoryFiles:Y,memoryFilesLoading:re,selectedFilePath:D,selectedFileContent:z,selectedFileLoading:ye,selectedFileDirty:R,setSelectedFileContent:ge,selectFile:B,saveSelectedFile:ie,savingSelectedFile:G,reloadMemoryFiles:le,triggerDreamNow:V,dreamRunning:me}=Ge({projectId:i});a.useEffect(()=>{p(o)},[o]);const K=a.useMemo(()=>r.memoryEnabled!==o.memoryEnabled||r.memoryAutoSummarizeEnabled!==o.memoryAutoSummarizeEnabled||r.memoryAutoSummarizeThresholdChars!==o.memoryAutoSummarizeThresholdChars||r.memoryAutoSummarizeSchedule!==o.memoryAutoSummarizeSchedule||r.memoryDreamsEnabled!==o.memoryDreamsEnabled||r.memoryDreamsSchedule!==o.memoryDreamsSchedule,[r,o]),j=a.useMemo(()=>Y.find(s=>s.path===D),[Y,D]),be=j?Ze[j.layer]:"Edits the selected memory file.",N=a.useMemo(()=>ss(F),[F]),q=a.useMemo(()=>as(N),[N]),ce=a.useMemo(()=>ts(F),[F]),oe=a.useCallback(s=>{A(h=>{const g=new Set(h);return g.has(s)?g.delete(s):g.add(s),g})},[]),xe=a.useCallback(async s=>{try{await B(s)}catch{t("Failed to load memory file","error")}},[B,t]),pe=a.useCallback(async()=>{try{await ie(),t("Memory saved","success")}catch{t("Failed to save memory","error")}},[ie,t]),fe=a.useCallback(async()=>{if(!K)return;const s={};r.memoryEnabled!==o.memoryEnabled&&(s.memoryEnabled=r.memoryEnabled),r.memoryAutoSummarizeEnabled!==o.memoryAutoSummarizeEnabled&&(s.memoryAutoSummarizeEnabled=r.memoryAutoSummarizeEnabled),r.memoryAutoSummarizeThresholdChars!==o.memoryAutoSummarizeThresholdChars&&(s.memoryAutoSummarizeThresholdChars=r.memoryAutoSummarizeThresholdChars),r.memoryAutoSummarizeSchedule!==o.memoryAutoSummarizeSchedule&&(s.memoryAutoSummarizeSchedule=r.memoryAutoSummarizeSchedule),r.memoryDreamsEnabled!==o.memoryDreamsEnabled&&(s.memoryDreamsEnabled=r.memoryDreamsEnabled),r.memoryDreamsSchedule!==o.memoryDreamsSchedule&&(s.memoryDreamsSchedule=r.memoryDreamsSchedule);try{await se(s),t("Memory settings saved","success")}catch{t("Failed to save memory settings","error")}},[K,r,o,se,t]),je=a.useCallback(async()=>{try{const s=await H();t(s.qmdAvailable?"qmd installed successfully":"qmd install finished, but qmd is still unavailable",s.qmdAvailable?"success":"info")}catch{t("Failed to install qmd","error")}},[H,t]),Se=a.useCallback(async()=>{L(!0),_(null);try{const s=await Q(T);_(s),t(s.qmdAvailable?"Memory retrieval test complete":"qmd is not installed; local fallback was used",s.qmdAvailable?"success":"info")}catch{t("Failed to test memory retrieval","error")}finally{L(!1)}},[T,Q,t]),Z=a.useCallback(async()=>{try{await V(),t("Dream processing completed","success"),await le()}catch(s){t(s instanceof Error?s.message:"Failed to run dream processing","error")}},[V,le,t]),P=a.useCallback(async()=>{try{await f(D),t("Memory file compacted","success")}catch{t("Failed to compact memory","error")}},[f,D,t]),de=a.useCallback(async()=>{try{const s=await W();t(s.summary,"success")}catch(s){t(s instanceof Error?s.message:"Failed to extract insights","error")}},[W,t]),ve=a.useCallback(async()=>{if(b!==null)try{await $(b),M(!1),x(null),t("Insights saved","success")}catch{t("Failed to save insights","error")}},[b,$,t]),Ne=a.useCallback(()=>{x(F??""),M(!0)},[F]),Ce=a.useCallback(()=>{M(!1),x(null)},[]),n=!k&&c!==null,l=c?.capabilities?.writable??!1;return e.jsxs("div",{className:"memory-view",children:[e.jsx("div",{className:"memory-view-header",children:e.jsxs("div",{children:[e.jsx("h2",{children:"Memory"}),e.jsx("p",{className:"memory-view-description",children:"Working memory, long-term insights, and engine status"})]})}),e.jsxs("div",{className:"memory-view-tabs",role:"tablist",children:[e.jsx("button",{type:"button",role:"tab","aria-selected":m==="working",className:`memory-view-tab${m==="working"?" memory-view-tab--active":""}`,onClick:()=>u("working"),"data-testid":"memory-tab-working",children:"Working Memory"}),e.jsx("button",{type:"button",role:"tab","aria-selected":m==="insights",className:`memory-view-tab${m==="insights"?" memory-view-tab--active":""}`,onClick:()=>u("insights"),"data-testid":"memory-tab-insights",children:"Insights"}),e.jsx("button",{type:"button",role:"tab","aria-selected":m==="engines",className:`memory-view-tab${m==="engines"?" memory-view-tab--active":""}`,onClick:()=>u("engines"),"data-testid":"memory-tab-engines",children:"Engines"})]}),e.jsxs("div",{className:"memory-view-content",children:[m==="working"&&e.jsxs("div",{className:"memory-working-tab",children:[n&&!l&&e.jsx("div",{className:"memory-readonly-banner",children:"This memory backend is read-only. Changes cannot be saved."}),re||ye?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading memory file…"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-editor-section",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryViewFilePath",children:"Memory File"}),e.jsx("select",{id:"memoryViewFilePath",className:"select",value:D,onChange:s=>{xe(s.target.value)},disabled:R,children:Y.map(s=>e.jsx("option",{value:s.path,title:`${s.label} — ${s.path}`,children:es(s)},s.path))}),e.jsx("small",{children:R?"Save or discard the current edits before switching files.":"Choose any project memory file to view or edit."})]}),j&&e.jsxs("div",{className:"memory-file-summary",children:[e.jsx("span",{children:Ke[j.layer]}),e.jsx("strong",{children:j.path}),e.jsxs("small",{children:[j.size.toLocaleString()," bytes · updated ",new Date(j.updatedAt).toLocaleString()]})]}),e.jsxs("div",{className:"form-group memory-editor-form-group",children:[e.jsx("label",{children:j?.label||"Memory Editor"}),e.jsx("small",{children:be}),e.jsx("div",{className:"memory-editor-container",children:e.jsx(Fe,{content:z,onChange:ge,readOnly:!l,filePath:D})})]})]}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsxs("span",{className:"memory-char-count",children:[z.length," characters"]}),e.jsx("div",{className:"memory-flex-spacer"}),l&&z.length>0&&e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:P,disabled:ae||R,children:ae?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Compacting…"]}):"Compact Selected File"}),R&&l&&e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:pe,disabled:G,children:G?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Saving…"]}):"Save"})]}),e.jsxs("div",{className:"memory-config-section",children:[e.jsxs("div",{className:"memory-settings-group",children:[e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryDreamsEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryDreamsEnabled",type:"checkbox",checked:r.memoryDreamsEnabled,onChange:s=>{p(h=>({...h,memoryDreamsEnabled:s.target.checked}))},disabled:!r.memoryEnabled||v}),"Process dreams from daily memory"]}),e.jsx("small",{children:"Turns daily notes into DREAMS.md and promotes reusable lessons into MEMORY.md."})]}),r.memoryEnabled&&r.memoryDreamsEnabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryDreamsSchedule",children:"Dream Schedule"}),e.jsx("input",{id:"memoryDreamsSchedule",type:"text",className:"input",value:r.memoryDreamsSchedule,onChange:s=>{p(h=>({...h,memoryDreamsSchedule:s.target.value}))},placeholder:"0 4 * * *",disabled:v}),e.jsx("small",{children:"Cron expression for dream processing."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:Z,disabled:me||!r.memoryDreamsEnabled,children:me?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Dreaming…"]}):"Dream Now"}),e.jsx("small",{children:"Manually trigger dream processing now."})]})]})]}),e.jsxs("div",{className:"memory-settings-group",children:[e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryAutoSummarizeEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryAutoSummarizeEnabled",type:"checkbox",checked:r.memoryAutoSummarizeEnabled,onChange:s=>{p(h=>({...h,memoryAutoSummarizeEnabled:s.target.checked}))},disabled:!r.memoryEnabled||v}),"Auto-Summarize Memory"]}),e.jsx("small",{children:"Automatically compact memory when it exceeds the threshold on a schedule"})]}),r.memoryEnabled&&r.memoryAutoSummarizeEnabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeThresholdChars",children:"Compaction Threshold (chars)"}),e.jsx("input",{id:"memoryAutoSummarizeThresholdChars",type:"number",className:"input",value:r.memoryAutoSummarizeThresholdChars,onChange:s=>{p(h=>({...h,memoryAutoSummarizeThresholdChars:parseInt(s.target.value,10)||5e4}))},min:1e3,disabled:v}),e.jsx("small",{children:"Memory will be compacted when it exceeds this character count"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeSchedule",children:"Schedule (cron)"}),e.jsx("input",{id:"memoryAutoSummarizeSchedule",type:"text",className:"input",value:r.memoryAutoSummarizeSchedule,onChange:s=>{p(h=>({...h,memoryAutoSummarizeSchedule:s.target.value}))},placeholder:"0 3 * * *",disabled:v}),e.jsx("small",{children:"Cron expression for auto-summarize schedule (default: daily at 3 AM)"})]})]})]}),!r.memoryEnabled&&e.jsx("div",{className:"settings-empty-state memory-status-message",children:"Memory is currently disabled. Enable memory tools in Settings to edit these automations."}),K&&e.jsx("div",{className:"memory-action-bar",children:e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:fe,disabled:I||v,children:I?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Saving…"]}):"Save Settings"})})]})]})]}),m==="insights"&&e.jsx("div",{className:"memory-insights-tab",children:ee?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading insights…"})]}):E?e.jsxs("div",{className:"memory-insights-editor-layout",children:[e.jsx("div",{className:"memory-editor-container",children:e.jsx(Fe,{content:b??"",onChange:x,readOnly:!1,filePath:".fusion/memory/INSIGHTS.md"})}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Ce,children:"Cancel"}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:ve,children:"Save Insights"})]})]}):!ue||N.length===0?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx("p",{children:"No insights extracted yet."}),e.jsx("p",{children:'Insights are automatically extracted from working memory. Click "Extract Now" to trigger extraction manually.'}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm memory-empty-extract-button",onClick:de,disabled:y,children:y?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Extracting…"]}):"Extract Now"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-stats-row",children:[e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value",children:q}),e.jsx("div",{className:"memory-stat-label",children:"Total Insights"})]}),e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value",children:N.length}),e.jsx("div",{className:"memory-stat-label",children:"Categories"})]}),ce&&e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value memory-stat-value--updated",children:ce}),e.jsx("div",{className:"memory-stat-label",children:"Last Updated"})]})]}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:de,disabled:y,children:y?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Extracting…"]}):"Extract Now"}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Ne,children:"Edit Raw"})]}),e.jsx("div",{className:"memory-categories-list",children:N.map(s=>{const h=!C.has(s.key);return e.jsxs("div",{className:"memory-category-section",children:[e.jsxs("div",{className:"memory-category-header",onClick:()=>oe(s.key),role:"button",tabIndex:0,onKeyDown:g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),oe(s.key))},children:[e.jsx("h4",{children:s.name}),e.jsx("span",{className:"memory-category-count",children:s.items.length})]}),h&&e.jsx("div",{className:"memory-category-items",children:s.items.map((g,ze)=>e.jsx("div",{className:"memory-insight-item",children:g.replace(/^-\s+/,"").replace(/^\*\s+/,"")},ze))})]},s.key)})})]})}),m==="engines"&&e.jsx("div",{className:"memory-engines-tab",children:k||te?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading engine status…"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-engine-card memory-qmd-card",children:[e.jsx("h3",{children:"QMD Integration"}),c?.qmdAvailable===!0?e.jsxs("div",{className:"memory-engine-status",children:[e.jsx("span",{className:"memory-health-badge memory-health-badge--healthy",children:"Installed"}),e.jsx("span",{className:"memory-char-count",children:"qmd is available on PATH."})]}):c?.qmdAvailable===!1?e.jsxs("div",{className:"settings-empty-state memory-status-message",children:[e.jsxs("span",{children:["qmd is not installed. Search will use local files. Install indexed retrieval: ",e.jsx("code",{children:c.qmdInstallCommand||"bun install -g @tobilu/qmd"})]}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:je,disabled:ne,children:ne?"Installing…":"Install qmd"})]}):e.jsxs("div",{className:"memory-engine-status",children:[e.jsx("span",{className:"memory-health-badge",children:"Checking"}),e.jsx("span",{className:"memory-char-count",children:"Checking qmd availability…"})]}),e.jsxs("div",{className:"memory-capability-row",children:[c?.capabilities?.readable&&e.jsx("span",{className:"memory-capability-badge",children:"Readable"}),c?.capabilities?.writable&&e.jsx("span",{className:"memory-capability-badge",children:"Writable"}),c?.capabilities?.supportsAtomicWrite&&e.jsx("span",{className:"memory-capability-badge",children:"Atomic Writes"}),c?.capabilities?.persistent&&e.jsx("span",{className:"memory-capability-badge",children:"Persistent"})]})]}),e.jsxs("div",{className:"memory-engine-card memory-retrieval-card",children:[e.jsx("h3",{children:"Test Memory Search"}),e.jsxs("div",{className:"memory-retrieval-input-row",children:[e.jsx("input",{type:"text",className:"input",value:T,onChange:s=>J(s.target.value),placeholder:"Search memory with qmd"}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Se,disabled:X,children:X?"Testing…":"Test Retrieval"})]}),e.jsx("small",{className:"settings-muted",children:"Runs the same qmd-backed memory_search path agents use."}),S&&e.jsxs("div",{className:"memory-test-result",children:[e.jsxs("strong",{children:[S.results.length," result",S.results.length===1?"":"s"," ",'for "',S.query,'"']}),e.jsxs("small",{children:["qmd ",S.qmdAvailable?"available":"missing"," · ",S.usedFallback?"local fallback used":"qmd path used"]}),S.results.length>0?e.jsx("ul",{children:S.results.map((s,h)=>e.jsxs("li",{children:[e.jsxs("span",{children:[s.path,":",s.lineStart]}),e.jsx("p",{children:s.snippet})]},`${s.path}-${s.lineStart}-${h}`))}):e.jsx("small",{children:"No matching memory found."})]})]}),e.jsxs("div",{className:"memory-engine-card",children:[e.jsx("h3",{children:"Current Backend"}),e.jsx("div",{className:"memory-engine-status",children:e.jsx("span",{className:"memory-emphasis-text",children:ns(c?.currentBackend??"unknown")})}),e.jsxs("div",{className:"memory-capability-row",children:[c?.capabilities?.readable&&e.jsx("span",{className:"memory-capability-badge",children:"Readable"}),c?.capabilities?.writable&&e.jsx("span",{className:"memory-capability-badge",children:"Writable"}),c?.capabilities?.supportsAtomicWrite&&e.jsx("span",{className:"memory-capability-badge",children:"Atomic Writes"}),c?.capabilities?.persistent&&e.jsx("span",{className:"memory-capability-badge",children:"Persistent"})]})]}),d&&e.jsxs("div",{className:"memory-engine-card",children:[e.jsxs("div",{className:"memory-health-header",children:[e.jsx("h3",{children:"Health Status"}),e.jsx("span",{className:`memory-health-badge memory-health-badge--${d.health}`,children:rs(d.health)})]}),e.jsxs("div",{className:"memory-health-grid",children:[e.jsxs("div",{children:[e.jsx("div",{className:"memory-health-label",children:"Working Memory"}),e.jsxs("div",{className:"memory-emphasis-text",children:[d.workingMemory.size," chars"]}),e.jsxs("div",{className:"memory-health-detail",children:[d.workingMemory.sectionCount," sections"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"memory-health-label",children:"Insights Memory"}),e.jsxs("div",{className:"memory-emphasis-text",children:[d.insightsMemory.size," chars"]}),e.jsxs("div",{className:"memory-health-detail",children:[d.insightsMemory.insightCount," insights"]})]})]}),e.jsxs("div",{className:"memory-health-section",children:[e.jsx("div",{className:"memory-health-label",children:"Last Extraction"}),e.jsx("div",{className:"memory-emphasis-text",children:d.extraction.success?e.jsx("span",{className:"memory-status-text memory-status-text--success",children:"Success"}):e.jsx("span",{className:"memory-status-text memory-status-text--error",children:"Failed"})}),e.jsx("div",{className:"memory-health-detail",children:d.extraction.summary||`${d.extraction.insightCount} insights extracted`})]}),e.jsxs("div",{className:"memory-health-section",children:[e.jsx("div",{className:"memory-health-label",children:"Pruning"}),e.jsx("div",{className:"memory-emphasis-text",children:d.pruning.applied?e.jsx("span",{className:"memory-status-text memory-status-text--warning",children:"Applied"}):e.jsx("span",{className:"memory-status-text memory-status-text--muted",children:"Not needed"})}),d.pruning.applied&&e.jsx("div",{className:"memory-health-detail",children:d.pruning.reason})]})]}),d&&d.checks.length>0&&e.jsxs("div",{className:"memory-engine-card",children:[e.jsx("h3",{children:"Audit Checks"}),e.jsx("div",{children:d.checks.map(s=>e.jsxs("div",{className:"memory-audit-check",children:[e.jsx("span",{className:s.passed?"memory-audit-check-passed":"memory-audit-check-failed",children:s.passed?"✓":"✗"}),e.jsxs("div",{className:"memory-audit-check-content",children:[e.jsx("div",{className:"memory-emphasis-text",children:s.name}),e.jsx("div",{className:"memory-health-detail",children:s.details})]})]},s.id))})]}),e.jsx("div",{className:"memory-action-bar",children:e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:()=>U(),children:"Run Audit"})}),e.jsxs("div",{className:"memory-settings-note",children:[e.jsx("span",{children:"Note: Change backend type in"}),e.jsx("button",{type:"button",className:"memory-settings-note-button",onClick:()=>{t("Open Settings → Memory to change backend type","info")},children:"Settings → Memory"})]})]})})]})]})}export{os as MemoryView};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{c as ze,aJ as ls,aK as os,aL as cs,aM as is,aN as Le,aO as be,aP as Ve,aQ as ye,aR as Oe,A as Fe,ap as ds,U as Ke,aS as Ue,aT as us,W as _e,u as ms,R as Ne,a as we,I as he,aU as Te,aV as hs,aW as fs,aX as $e,X as me,a8 as gs,a9 as xs,aY as De,F as ps,aZ as Ie,a_ as js,a$ as vs,b0 as bs,b1 as ys,b2 as _s,G as Ns}from"./index-bEwSVl7B.js";import{v as ks}from"./projectDetection-G3XuxD2X.js";import{U as Be}from"./upload-CAzycxr9.js";import"./vendor-xterm-DzcZoU0P.js";/**
|
|
2
|
+
* @license lucide-react v1.7.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const Cs=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}],["path",{d:"M5 12.859a10 10 0 0 1 5.17-2.69",key:"1dl1wf"}],["path",{d:"M19 12.859a10 10 0 0 0-2.007-1.523",key:"4k23kn"}],["path",{d:"M2 8.82a15 15 0 0 1 4.177-2.643",key:"1grhjp"}],["path",{d:"M22 8.82a15 15 0 0 0-11.288-3.764",key:"z3jwby"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],Ss=ze("wifi-off",Cs);/**
|
|
7
|
+
* @license lucide-react v1.7.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const ws=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]],Ms=ze("wifi",ws);function pe(t){const{lastSyncAt:r,remoteReachable:a,diff:i}=t,u=i.global.length+i.project.length;return r===null?{syncState:"never-synced",lastSyncAt:r,diffCount:0}:a?u>0?{syncState:"diff",lastSyncAt:r,diffCount:u}:{syncState:"synced",lastSyncAt:r,diffCount:0}:{syncState:"error",lastSyncAt:r,diffCount:u}}function ke(t){if(t===null)return"Never synced";const r=new Date(t);if(Number.isNaN(r.getTime()))return"Never synced";const i=Date.now()-r.getTime(),u=Math.floor(i/1e3),m=Math.floor(u/60),o=Math.floor(m/60),j=Math.floor(o/24);return m<1?"Synced just now":m<60?`Synced ${m}m ago`:o<24?`Synced ${o}h ago`:`Synced ${j}d ago`}function Ps(t){switch(t){case"synced":return"var(--color-success)";case"pending":return"var(--color-warning)";case"diff":return"var(--color-warning)";case"error":return"var(--color-error)";case"never-synced":return"var(--text-muted)"}}const Es=3e4;function Rs(){const[t,r]=s.useState({}),[a,i]=s.useState(!1),[u,m]=s.useState({}),[o,j]=s.useState(null),g=s.useRef(new Set),c=s.useRef(!1),N=s.useRef(null),w=s.useRef(null),v=s.useCallback(async(p,x)=>{try{const S=await ls(p);r(Z=>({...Z,[p]:S})),j(null)}catch(S){console.error(`Failed to fetch sync status for node ${p}:`,S),j(S instanceof Error?S.message:"Failed to fetch sync status")}},[]),d=s.useCallback(async()=>{const p=Array.from(g.current);if(p.length===0)return;N.current&&N.current.abort(),N.current=new AbortController;const x=!c.current;x&&i(!0),j(null);try{const S=await Promise.allSettled(p.map(H=>v(H,x)));c.current=!0,S.filter(H=>H.status==="rejected").length>0&&j("Some sync status requests failed")}catch(S){if(S instanceof Error&&S.name==="AbortError")return;j(S instanceof Error?S.message:"Failed to fetch sync status"),c.current=!0}finally{i(!1)}},[v]),M=s.useCallback(()=>{w.current&&clearInterval(w.current),w.current=setInterval(()=>{d()},Es)},[d]),_=s.useCallback(()=>{w.current&&(clearInterval(w.current),w.current=null)},[]);s.useEffect(()=>(d(),M(),()=>{_(),N.current&&N.current.abort()}),[d,M,_]);const l=s.useCallback(p=>{g.current.has(p)||(g.current.add(p),v(p,!c.current))},[v]),b=s.useCallback(p=>{g.current.delete(p),r(x=>{const S={...x};return delete S[p],S}),g.current.size===0&&_()},[_]),C=s.useCallback(async p=>{m(x=>({...x,[p]:!0})),j(null);try{const x=await os(p);return v(p,!1),!x.success&&x.error&&j(x.error),x}catch(x){const S=x instanceof Error?x.message:"Push settings failed";throw j(S),x}finally{m(x=>{const S={...x};return delete S[p],S})}},[v]),k=s.useCallback(async p=>{m(x=>({...x,[p]:!0})),j(null);try{const x=await cs(p);return v(p,!1),!x.success&&x.error&&j(x.error),x}catch(x){const S=x instanceof Error?x.message:"Pull settings failed";throw j(S),x}finally{m(x=>{const S={...x};return delete S[p],S})}},[v]),$=s.useCallback(async p=>{m(x=>({...x,[p]:!0})),j(null);try{return await is(p)}catch(x){const S=x instanceof Error?x.message:"Auth sync failed";throw j(S),x}finally{m(x=>{const S={...x};return delete S[p],S})}},[]),V=s.useCallback(p=>t[p]?.authMatch,[t]),A=s.useCallback(p=>t[p]?.authDiff,[t]);return{syncStatusMap:t,loading:a,actionLoading:u,error:o,refresh:d,trackNode:l,untrackNode:b,pushSettings:C,pullSettings:k,syncAuth:$,getAuthSyncState:V,getAuthProviders:A}}const As=1e4,Ls=1e3;function $s(){const[t,r]=s.useState([]),[a,i]=s.useState(!0),[u,m]=s.useState(null),o=s.useRef(null),j=s.useRef(0),g=s.useCallback(async()=>{try{m(null);const c=await Le();r(c.nodes)}catch(c){m(c instanceof Error?c.message:"Failed to fetch mesh state")}},[]);return s.useEffect(()=>{let c=!1;async function N(){i(!0);try{const v=await Le();c||(r(v.nodes),m(null))}catch(v){c||m(v instanceof Error?v.message:"Failed to fetch mesh state")}finally{c||i(!1)}}N();const w=()=>{if(document.visibilityState!=="visible")return;const v=Date.now();v-j.current<Ls||(j.current=v,g())};return document.addEventListener("visibilitychange",w),()=>{c=!0,document.removeEventListener("visibilitychange",w)}},[g]),s.useEffect(()=>{if(!a)return o.current=setInterval(()=>{g()},As),()=>{o.current&&(clearInterval(o.current),o.current=null)}},[a,g]),{meshState:t,loading:a,error:u,refresh:g}}const de={online:{label:"Online",color:"var(--color-success)",className:"node-card__status--online"},offline:{label:"Offline",color:"var(--color-error)",className:"node-card__status--offline"},connecting:{label:"Connecting",color:"var(--color-warning)",className:"node-card__status--connecting"},error:{label:"Error",color:"var(--color-error)",className:"node-card__status--error"},creating:{label:"Creating",color:"var(--color-warning)",className:"node-card__status--creating"},recreating:{label:"Recreating",color:"var(--color-warning)",className:"node-card__status--recreating"},deleting:{label:"Deleting",color:"var(--color-error)",className:"node-card__status--deleting"},running:{label:"Running",color:"var(--color-success)",className:"node-card__status--online"},stopped:{label:"Stopped",color:"var(--color-error)",className:"node-card__status--offline"},exited:{label:"Exited",color:"var(--color-error)",className:"node-card__status--offline"}},Ds={match:"var(--color-success)",differs:"var(--color-warning)","not-synced":"var(--text-muted)"};function Is(t,r){if(t==="match")return"Auth credentials match";if(t==="not-synced")return"Auth not synced";if(r&&Object.keys(r).length>0){const a=Object.entries(r).filter(([,i])=>i==="differs").map(([i])=>i);if(a.length>0)return`Auth credentials differ: ${a.join(", ")}`}return"Auth credentials differ"}function zs(t,r=42){return t.length<=r?t:`${t.slice(0,r-3)}...`}function Vs(t,r){const a=t.node,i=r.node;if(a.id!==i.id||a.name!==i.name||a.type!==i.type||a.url!==i.url||a.status!==i.status||a.maxConcurrent!==i.maxConcurrent||a.updatedAt!==i.updatedAt||t.isLoading!==r.isLoading)return!1;const u=t.managedDockerNode,m=r.managedDockerNode;if(!!u!=!!m||u&&m&&(u.id!==m.id||u.status!==m.status||u.imageTag!==m.imageTag||u.updatedAt!==m.updatedAt))return!1;const o=t.syncStatus,j=r.syncStatus;if(!(!o&&!j)){if(!o||!j)return!1;if(o.syncState!==j.syncState||o.lastSyncAt!==j.lastSyncAt||o.diffCount!==j.diffCount)return!1}if(t.authSyncState!==r.authSyncState)return!1;const g=t.authSyncProviders,c=r.authSyncProviders;if(g!==c){if(!g||!c)return!1;{const v=Object.keys(g),d=Object.keys(c);if(v.length!==d.length||v.some(M=>g[M]!==c[M]))return!1}}const N=be(t.projects,a),w=be(r.projects,i);return N===w}function Os({node:t,projects:r,onHealthCheck:a,onEdit:i,onRemove:u,isLoading:m=!1,syncStatus:o,authSyncState:j,authSyncProviders:g,managedDockerNode:c}){const[N,w]=s.useState(!1),v=de[t.status]??de.offline,d=c?de[c.status]??de.error:null,M=c?.hostConfig.type==="remote"?`Remote: ${c.hostConfig.host??"unknown"}`:"Local Docker",_=s.useMemo(()=>be(r,t),[r,t]),l=s.useCallback(()=>{i(t)},[i,t]),b=s.useCallback(V=>{V.stopPropagation(),a(t.id)},[a,t.id]),C=s.useCallback(V=>{V.stopPropagation(),i(t)},[i,t]),k=s.useCallback(V=>{if(V.stopPropagation(),!N){w(!0);return}u(t.id),w(!1)},[N,u,t.id]),$=s.useCallback(V=>{(V.key==="Enter"||V.key===" ")&&(V.preventDefault(),i(t))},[i,t]);return e.jsxs("article",{className:`node-card ${m?"node-card--loading":""}`,"data-node-id":t.id,role:"button",tabIndex:0,onClick:l,onKeyDown:$,children:[e.jsx("header",{className:"node-card__header",children:e.jsxs("div",{className:"node-card__title-wrap",children:[e.jsx("div",{className:"node-card__icon",children:e.jsx(Ve,{size:18})}),e.jsxs("div",{children:[e.jsx("h3",{className:"node-card__name",title:t.name,children:t.name}),e.jsxs("div",{className:"node-card__meta-row",children:[e.jsx("span",{className:"node-card__type-badge",children:t.type==="local"?"Local":"Remote"}),c&&e.jsxs("span",{className:"node-card__docker-badge",title:"Managed Docker node",children:[e.jsx(ye,{size:12,"aria-hidden":!0}),"Docker"]}),e.jsxs("span",{className:`node-card__status ${v.className}`,style:{color:v.color},"data-status":t.status,children:[e.jsx("span",{className:"node-card__status-indicator",style:{backgroundColor:v.color},"aria-hidden":!0}),v.label]}),c&&d&&e.jsxs("span",{className:`node-card__status ${d.className}`,style:{color:d.color},"data-status":c.status,children:[e.jsx("span",{className:"node-card__status-indicator",style:{backgroundColor:d.color},"aria-hidden":!0}),d.label]}),t.type==="remote"&&j&&e.jsx("span",{className:`node-card__auth-indicator node-card__auth-indicator--${j}`,title:Is(j,g),"aria-label":`Auth sync: ${j==="match"?"credentials match":j==="differs"?"credentials differ":"not synced"}`,style:{color:Ds[j]},children:e.jsx(Oe,{size:14})})]})]})]})}),e.jsxs("div",{className:"node-card__body",children:[t.type==="remote"&&t.url&&e.jsx("div",{className:"node-card__url",title:t.url,children:zs(t.url)}),c&&e.jsxs("div",{className:"node-card__docker-meta",children:[e.jsxs("span",{title:`${c.imageName}:${c.imageTag}`,children:[c.imageName,":",c.imageTag]}),e.jsx("span",{title:M,children:M})]}),e.jsxs("div",{className:"node-card__metrics",children:[e.jsxs("div",{className:"node-card__metric",children:[e.jsx("span",{className:"node-card__metric-label",children:"Projects"}),e.jsx("span",{className:"node-card__metric-value",children:_})]}),e.jsxs("div",{className:"node-card__metric",children:[e.jsx("span",{className:"node-card__metric-label",children:"Concurrency"}),e.jsx("span",{className:"node-card__metric-value",children:t.maxConcurrent})]})]}),t.type==="remote"&&o&&e.jsxs("div",{className:"node-card__sync","data-sync-state":o.syncState,"data-testid":"node-card-sync",children:[e.jsx("span",{className:"node-card__sync-dot",style:{backgroundColor:Ps(o.syncState)},"aria-hidden":!0}),e.jsx("span",{className:"node-card__sync-time",children:ke(o.lastSyncAt)})]})]}),e.jsxs("footer",{className:"node-card__actions",children:[e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:b,disabled:m,"aria-label":"Run node health check",title:"Health Check",children:[e.jsx(Fe,{size:14}),e.jsx("span",{children:"Health"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:C,disabled:m,"aria-label":"Edit node",title:"Edit",children:[e.jsx(ds,{size:14}),e.jsx("span",{children:"Edit"})]}),c&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",disabled:!0,"aria-label":"Start node container",title:"Available after FN-3113",children:[e.jsx(Ke,{size:14}),e.jsx("span",{children:"Start"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",disabled:!0,"aria-label":"Stop node container",title:"Available after FN-3113",children:[e.jsx(Ue,{size:14}),e.jsx("span",{children:"Stop"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",disabled:!0,"aria-label":"Restart node container",title:"Available after FN-3113",children:[e.jsx(us,{size:14}),e.jsx("span",{children:"Restart"})]})]}),e.jsxs("button",{className:`btn btn-sm node-card__action node-card__action--remove ${N?"btn-danger is-armed":""}`,type:"button",onClick:k,disabled:m,"aria-label":N?"Confirm remove node":"Remove node",title:N?"Confirm remove":"Remove",children:[e.jsx(_e,{size:14}),e.jsx("span",{children:N?"Confirm":"Remove"})]})]})]})}const Fs=s.memo(Os,Vs),ce={online:"var(--success, var(--color-success))",offline:"var(--text-dim)",connecting:"var(--color-warning)",error:"var(--color-error)"},ue=28,Ks=12,Us=300,Ts=120;function Bs({nodes:t,className:r}){const a=s.useMemo(()=>t.find(c=>c.nodeType==="local")??t[0],[t]),i=s.useMemo(()=>t.filter(c=>c.nodeId!==a?.nodeId),[t,a?.nodeId]),u=s.useMemo(()=>Us+Math.max(0,i.length-4)*20,[i.length]),m=u/2,o=u/2,j=s.useMemo(()=>{const c=new Map;if(a&&c.set(a.nodeId,{x:m,y:o,node:a}),i.length>0){const N=Math.min(Ts,u/2-ue-10),w=2*Math.PI/i.length,v=-Math.PI/2;i.forEach((d,M)=>{const _=v+M*w;c.set(d.nodeId,{node:d,x:m+N*Math.cos(_),y:o+N*Math.sin(_)})})}return c},[m,o,a,i,u]),g=s.useMemo(()=>{const c=new Set,N=[];for(const w of t){const v=j.get(w.nodeId);if(v)for(const d of w.knownPeers){const M=j.get(d.peerNodeId);if(!M)continue;const _=[w.nodeId,d.peerNodeId].sort().join("::");c.has(_)||(c.add(_),N.push({key:_,from:v,to:M}))}}return N},[j,t]);return t.length===0?e.jsx("div",{className:`mesh-topology mesh-topology--empty ${r??""}`,children:e.jsx("div",{className:"mesh-topology__empty-state",children:e.jsx("p",{children:"No nodes to display"})})}):e.jsxs("div",{className:`mesh-topology ${r??""}`,children:[e.jsxs("svg",{className:"mesh-topology__svg",viewBox:`0 0 ${u} ${u}`,preserveAspectRatio:"xMidYMid meet","aria-label":"Node mesh topology visualization",children:[g.map(c=>e.jsx("line",{className:"mesh-topology__link mesh-topology__peer-line",x1:c.from.x,y1:c.from.y,x2:c.to.x,y2:c.to.y},c.key)),Array.from(j.values()).map(({node:c,x:N,y:w})=>e.jsxs("g",{className:"mesh-topology__node",transform:`translate(${N}, ${w})`,children:[e.jsx("circle",{className:"mesh-topology__node-circle",r:ue,fill:ce[c.status],"aria-label":`${c.nodeName} (${c.status})`}),e.jsx("text",{className:"mesh-topology__node-label",y:ue+Ks,textAnchor:"middle",children:c.nodeName.length>12?`${c.nodeName.slice(0,10)}…`:c.nodeName}),e.jsxs("g",{className:"mesh-topology__node-type",transform:`translate(0 ${-ue-10})`,children:[e.jsx("circle",{className:"mesh-topology__node-type-badge",r:"8"}),e.jsx("text",{className:"mesh-topology__node-type-text",textAnchor:"middle",dominantBaseline:"middle",children:c.nodeType==="local"?"L":"R"})]})]},c.nodeId))]}),e.jsxs("div",{className:"mesh-topology__legend",children:[e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:ce.online}}),e.jsx("span",{children:"Online"})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:ce.offline}}),e.jsx("span",{children:"Offline"})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:ce.connecting}}),e.jsx("span",{children:"Connecting"})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:ce.error}}),e.jsx("span",{children:"Error"})]})]}),g.length===0&&e.jsx("p",{className:"mesh-topology__notice",children:"Peer-to-peer discovery data unavailable."})]})}const Hs=s.memo(Bs),Ce=1,Se=10;function qs(t){const r={projectMappings:{}};t.name.trim()||(r.name="Name is required"),t.type==="remote"&&!t.url?.trim()&&(r.url="URL is required for remote nodes"),(!Number.isFinite(t.maxConcurrent)||t.maxConcurrent<Ce||t.maxConcurrent>Se)&&(r.maxConcurrent=`Concurrency must be between ${Ce} and ${Se}`);for(const a of t.projectMappings){const i=ks(a.path);i.valid||(r.projectMappings[a.projectId]=i.error??"Path is invalid")}return r}function Ys({isOpen:t,onClose:r,onSubmit:a,onDiscoverRemoteProjects:i,addToast:u,projects:m}){ms(t);const[o,j]=s.useState(""),[g,c]=s.useState("local"),[N,w]=s.useState(""),[v,d]=s.useState(""),[M,_]=s.useState(2),[l,b]=s.useState("auto-generate"),[C,k]=s.useState({}),[$,V]=s.useState({projectMappings:{}}),[A,p]=s.useState(!1),[x,S]=s.useState("idle"),[Z,H]=s.useState(null),[Y,ee]=s.useState([]),U=s.useCallback(()=>{j(""),c("local"),w(""),d(""),_(2),b("auto-generate"),k({}),V({projectMappings:{}}),p(!1),S("idle"),H(null),ee([])},[]),X=s.useCallback(()=>{A||(U(),r())},[A,r,U]);s.useEffect(()=>{if(!t){U();return}const y=L=>{L.key==="Escape"&&(L.preventDefault(),X())};return document.addEventListener("keydown",y),()=>{document.removeEventListener("keydown",y)}},[X,t,U]);const G=s.useMemo(()=>({name:o.trim(),type:g,url:g==="remote"&&N.trim()||void 0,apiKey:g==="remote"&&l==="provide"&&v||void 0,maxConcurrent:M,apiKeyMode:l,projectMappings:Object.entries(C).map(([y,L])=>({projectId:y,path:L.trim()}))}),[v,l,M,o,C,g,N]),te=s.useCallback(async()=>{if(A||x==="loading")return;const y=N.trim();if(!y){V(L=>({...L,url:"URL is required for remote nodes"}));return}S("loading"),H(null);try{const L=await i({url:y,apiKey:l==="provide"&&v.trim().length>0?v:void 0});ee(L.projects),S("success"),k(D=>{if(Object.keys(D).length===0)return D;const K={...D};for(const ae of m){if(!(ae.id in K))continue;const ne=L.projects.filter(se=>se.name===ae.name);ne.length===1&&(K[ae.id]=ne[0].path)}return K})}catch(L){S("error"),ee([]),H(L instanceof Error?L.message:"Failed to discover remote projects")}},[v,l,x,A,i,m,N]);s.useEffect(()=>{if(g!=="remote"){S("idle"),H(null),ee([]);return}S("idle"),H(null),ee([])},[v,l,g,N]);const J=s.useCallback(async()=>{if(A)return;const y=qs(G);if(V(y),!(y.name||y.url||y.maxConcurrent||Object.keys(y.projectMappings).length>0)){if(G.type==="remote"&&x!=="success"){H("Discover remote projects before adding this node.");return}p(!0);try{await a(G),u(`Node "${G.name}" registered`,"success"),X()}catch(L){const D=L instanceof Error?L.message:"Failed to register node";u(D,"error")}finally{p(!1)}}},[u,X,x,G,A,a]),T=y=>{k(L=>{if(y.id in L){const{[y.id]:D,...K}=L;return K}if(g==="remote"&&x==="success"){const D=Y.filter(K=>K.name===y.name);return D.length===1?{...L,[y.id]:D[0].path}:{...L,[y.id]:""}}return{...L,[y.id]:y.path}})},E=(y,L)=>{k(D=>({...D,[y]:L}))};return t?e.jsx("div",{className:"modal-overlay open",onClick:X,children:e.jsxs("div",{className:"modal modal-md add-node-modal",onClick:y=>y.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":"Add Node",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Add Node"}),e.jsx("button",{className:"modal-close",onClick:X,disabled:A,"aria-label":"Close add node modal",children:"×"})]}),e.jsxs("div",{className:"modal-body add-node-modal__body",children:[e.jsx("p",{className:"add-node-modal__description",children:"Register an existing Fusion node by providing its connection details and concurrency settings."}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Name"}),e.jsx("input",{className:"input",type:"text",value:o,onChange:y=>j(y.target.value),placeholder:"Build Machine",disabled:A,"aria-invalid":!!$.name,autoFocus:!0}),$.name&&e.jsx("span",{className:"form-error add-node-modal__error",children:$.name})]}),e.jsxs("div",{className:"add-node-modal__type-toggle",children:[e.jsx("button",{type:"button",className:`add-node-modal__type-btn ${g==="local"?"active":""}`,"data-type":"local",onClick:()=>c("local"),disabled:A,"aria-pressed":g==="local",children:"Local"}),e.jsx("button",{type:"button",className:`add-node-modal__type-btn ${g==="remote"?"active":""}`,"data-type":"remote",onClick:()=>c("remote"),disabled:A,"aria-pressed":g==="remote",children:"Remote"})]}),g==="remote"&&e.jsxs("div",{className:"add-node-modal__remote-fields","data-testid":"remote-fields-container","data-visible":!0,children:[e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Reachable URL / Hostname"}),e.jsx("input",{className:"input",type:"text",value:N,onChange:y=>w(y.target.value),placeholder:"https://node.example.com",disabled:A,"aria-invalid":!!$.url}),$.url&&e.jsx("span",{className:"form-error add-node-modal__error",children:$.url})]}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"API Key Mode"}),e.jsxs("select",{className:"select",value:l,onChange:y=>b(y.target.value),disabled:A,children:[e.jsx("option",{value:"auto-generate",children:"Auto-generate"}),e.jsx("option",{value:"provide",children:"Provide key manually"})]})]}),l==="provide"&&e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"API Key"}),e.jsx("input",{className:"input",type:"password",value:v,onChange:y=>d(y.target.value),placeholder:"Enter node API key",disabled:A})]}),e.jsxs("div",{className:"add-node-modal__discovery-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>void te(),disabled:A||x==="loading",children:x==="loading"?"Discovering...":"Discover Remote Projects"}),x==="success"&&e.jsx("span",{className:"add-node-modal__discovery-state","data-state":"success",children:Y.length>0?`Discovered ${Y.length} remote project${Y.length===1?"":"s"}.`:"No projects discovered on remote node."}),x==="error"&&Z&&e.jsx("span",{className:"form-error add-node-modal__error",children:Z}),x==="idle"&&e.jsx("span",{className:"add-node-modal__hint",children:"Discover remote projects before adding this node."})]}),x==="success"&&Y.length>0&&e.jsx("div",{className:"add-node-modal__discovered-list","aria-label":"Discovered remote projects",children:Y.map(y=>e.jsxs("div",{className:"card add-node-modal__discovered-card",children:[e.jsxs("div",{className:"add-node-modal__discovered-row",children:[e.jsx("strong",{children:y.name}),e.jsx("span",{className:"card-status-badge card-status-badge--in-review",children:y.status})]}),e.jsx("div",{className:"add-node-modal__hint",children:y.path})]},`${y.id}-${y.path}`))})]}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Max Concurrent"}),e.jsx("input",{className:"input",type:"number",min:Ce,max:Se,value:M,onChange:y=>_(Number(y.target.value)),disabled:A,"aria-invalid":!!$.maxConcurrent}),e.jsx("span",{className:"add-node-modal__hint",children:"Max simultaneous task agents (1–10)"}),$.maxConcurrent&&e.jsx("span",{className:"form-error add-node-modal__error",children:$.maxConcurrent})]}),e.jsxs("section",{className:"add-node-modal__projects","aria-label":"Project path mappings",children:[e.jsx("h4",{className:"add-node-modal__projects-title",children:"Attach Existing Projects"}),e.jsx("p",{className:"add-node-modal__hint",children:"Select existing projects to run on this node and provide the node-specific absolute path for each one."}),m.length===0?e.jsx("p",{className:"add-node-modal__hint",children:"No projects are currently registered."}):e.jsx("div",{className:"add-node-modal__project-list",children:m.map(y=>{const L=y.id in C,D=$.projectMappings[y.id];return e.jsxs("div",{className:"card add-node-modal__project-card",children:[e.jsxs("label",{className:"checkbox-label add-node-modal__project-toggle",children:[e.jsx("input",{type:"checkbox",checked:L,onChange:()=>T(y),disabled:A}),e.jsx("span",{children:y.name})]}),L&&e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Path on this node"}),g==="remote"&&x==="success"&&e.jsx("span",{className:"add-node-modal__hint",children:(()=>{const K=Y.filter(ae=>ae.name===y.name);return K.length===1?`Remote-authoritative path discovered: ${K[0].path}`:K.length>1?"Multiple remote projects matched this name. Enter the correct path manually.":"No exact remote name match. Enter this path manually."})()}),e.jsx("input",{className:"input",type:"text",value:C[y.id]??"",onChange:K=>E(y.id,K.target.value),disabled:A,placeholder:"/absolute/path/to/project","aria-invalid":!!D}),D&&e.jsx("span",{className:"form-error add-node-modal__error",children:D})]})]},y.id)})})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:X,disabled:A,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary btn-sm","data-testid":"add-node-submit",onClick:J,disabled:A,children:A?"Adding...":"Add Node"})]})]})}):null}function Xs(){const[t,r]=s.useState([]),[a,i]=s.useState(!1),[u,m]=s.useState(null),[o,j]=s.useState(!1),[g,c]=s.useState(null),[N,w]=s.useState(!1),v=s.useCallback(async()=>{i(!0),m(null);try{const _=await fetch("/api/docker/contexts");if(!_.ok)throw new Error(`Failed to load Docker contexts (${_.status})`);const l=await _.json();return r(l),l}catch(_){const l=_ instanceof Error?_.message:String(_);throw m(l),_}finally{i(!1)}},[]),d=s.useCallback(async _=>{j(!0);try{const l=await fetch("/api/docker/test-connection",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hostConfig:_})});if(!l.ok)throw new Error(`Failed to test Docker connection (${l.status})`);const b=await l.json();return c(b),b}finally{j(!1)}},[]),M=s.useCallback(async()=>{w(!0);try{const _=await fetch("/api/docker/local-available");if(!_.ok)throw new Error(`Failed to check local Docker availability (${_.status})`);return await _.json()}finally{w(!1)}},[]);return{contexts:t,isLoadingContexts:a,contextsError:u,loadContexts:v,isTestingConnection:o,lastTestResult:g,testConnection:d,isCheckingLocal:N,checkLocalDocker:M}}function Js({value:t,onChange:r}){const[a,i]=s.useState(!!(t?.tlsCaPath||t?.tlsCertPath||t?.tlsKeyPath||t?.tlsVerify));s.useEffect(()=>{a||r({tlsVerify:void 0,tlsCaPath:void 0,tlsCertPath:void 0,tlsKeyPath:void 0})},[a,r]);const u=s.useMemo(()=>({tlsVerify:t?.tlsVerify??!0,tlsCaPath:t?.tlsCaPath??"",tlsCertPath:t?.tlsCertPath??"",tlsKeyPath:t?.tlsKeyPath??""}),[t]);return e.jsxs("div",{className:"docker-tls-config",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:a,onChange:m=>i(m.target.checked)}),"Use TLS"]}),a&&e.jsxs("div",{className:"docker-tls-config__fields",children:[e.jsxs("div",{className:"docker-tls-config__field",children:[e.jsx("label",{htmlFor:"docker-tls-ca-path",children:"CA Certificate Path"}),e.jsx("input",{id:"docker-tls-ca-path",className:"input",value:u.tlsCaPath,onChange:m=>r({...u,tlsCaPath:m.target.value}),placeholder:"/etc/docker/ca.pem"})]}),e.jsxs("div",{className:"docker-tls-config__field",children:[e.jsx("label",{htmlFor:"docker-tls-cert-path",children:"Client Certificate Path"}),e.jsx("input",{id:"docker-tls-cert-path",className:"input",value:u.tlsCertPath,onChange:m=>r({...u,tlsCertPath:m.target.value}),placeholder:"/etc/docker/cert.pem"})]}),e.jsxs("div",{className:"docker-tls-config__field",children:[e.jsx("label",{htmlFor:"docker-tls-key-path",children:"Client Key Path"}),e.jsx("input",{id:"docker-tls-key-path",className:"input",value:u.tlsKeyPath,onChange:m=>r({...u,tlsKeyPath:m.target.value}),placeholder:"/etc/docker/key.pem"})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:u.tlsVerify,onChange:m=>r({...u,tlsVerify:m.target.checked})}),"Verify TLS Certificate"]})]})]})}function Ws({value:t,onChange:r,onError:a}){const i=t?.context?"context":t?.host?"host":"local",[u,m]=s.useState(i),[o,j]=s.useState(t?.context??""),[g,c]=s.useState(t?.host??""),[N,w]=s.useState(null),{contexts:v,isLoadingContexts:d,contextsError:M,loadContexts:_,testConnection:l,isTestingConnection:b,lastTestResult:C,checkLocalDocker:k,isCheckingLocal:$}=Xs(),V=s.useMemo(()=>({tlsVerify:t?.tlsVerify,tlsCaPath:t?.tlsCaPath,tlsCertPath:t?.tlsCertPath,tlsKeyPath:t?.tlsKeyPath}),[t]);s.useEffect(()=>{if(u==="local"){r({});return}if(u==="context"){_().catch(p=>a?.(p instanceof Error?p.message:String(p))),r(o?{context:o}:{});return}r({host:g,...V})},[u]);const A=s.useCallback(p=>{u==="host"&&r({host:g,...p})},[g,u,r]);return e.jsxs("div",{className:"docker-target-selector",children:[e.jsxs("div",{className:"docker-target-selector__modes",role:"group","aria-label":"Docker target mode",children:[e.jsx("button",{type:"button",className:`btn btn-sm ${u==="local"?"docker-target-selector__mode-active":""}`,onClick:()=>{m("local"),k().then(p=>w(p.available?`Docker is available${p.version?` (${p.version})`:""}`:`Docker not found${p.error?`: ${p.error}`:""}`)).catch(p=>{const x=p instanceof Error?p.message:String(p);w(`Docker not found: ${x}`),a?.(x)})},children:"Local Docker"}),e.jsx("button",{type:"button",className:`btn btn-sm ${u==="context"?"docker-target-selector__mode-active":""}`,onClick:()=>m("context"),children:"Docker Context"}),e.jsx("button",{type:"button",className:`btn btn-sm ${u==="host"?"docker-target-selector__mode-active":""}`,onClick:()=>m("host"),children:"Remote Host"})]}),u==="local"&&N&&e.jsx("div",{className:"docker-target-selector__status",children:N}),u==="context"&&e.jsxs("div",{className:"docker-target-selector__panel",children:[e.jsxs("div",{className:"docker-target-selector__context-row",children:[e.jsxs("select",{className:"select",value:o,onChange:p=>{const x=p.target.value;j(x),r(x?{context:x}:{})},children:[e.jsx("option",{value:"",children:"Select context"}),v.map(p=>e.jsxs("option",{value:p.name,children:[p.name,p.isCurrentContext?" (current)":"",p.dockerHost?` — ${p.dockerHost}`:""]},p.name))]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon",onClick:()=>void _(),disabled:d,"aria-label":"Refresh contexts",children:e.jsx(Ne,{size:14})})]}),M&&e.jsx("div",{className:"docker-target-selector__error",children:M})]}),u==="host"&&e.jsxs("div",{className:"docker-target-selector__panel",children:[e.jsxs("div",{className:"docker-target-selector__field",children:[e.jsx("label",{htmlFor:"docker-target-selector-host",children:"Docker Host"}),e.jsx("input",{id:"docker-target-selector-host",className:"input",placeholder:"tcp://host:2376",value:g,onChange:p=>{const x=p.target.value;c(x),r({host:x,...V})}})]}),e.jsx(Js,{value:V,onChange:A})]}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>void l(u==="local"?void 0:u==="context"?{context:o}:{host:g,...V}),disabled:b||$,children:b?"Testing...":"Test Connection"}),C&&e.jsx("div",{className:C.success?"docker-target-selector__success":"docker-target-selector__error",children:C.success?`Connected${C.dockerVersion?` (Docker ${C.dockerVersion})`:""}`:C.error??"Connection failed"})]})}const je="http://localhost:4040";function Gs({isOpen:t,onClose:r,onSubmit:a,addToast:i}){const[u,m]=s.useState(""),[o,j]=s.useState({}),[g,c]=s.useState(je),[N,w]=s.useState("auto"),[v,d]=s.useState(""),[M,_]=s.useState(!1),[l,b]=s.useState(!1),[C,k]=s.useState(!0),[$,V]=s.useState(4096),[A,p]=s.useState(2),[x,S]=s.useState(!1),[Z,H]=s.useState("runfusion/fusion"),[Y,ee]=s.useState("latest"),[U,X]=s.useState([]),[G,te]=s.useState([]),[J,T]=s.useState({}),[E,y]=s.useState(!1),L=s.useCallback(()=>{m(""),j({}),c(je),w("auto"),d(""),_(!1),b(!1),k(!0),V(4096),p(2),S(!1),H("runfusion/fusion"),ee("latest"),X([]),te([]),T({}),y(!1)},[]),D=s.useCallback(()=>{E||(L(),r())},[r,L,E]);s.useEffect(()=>{if(!t){L();return}const h=F=>{F.key==="Escape"&&(F.preventDefault(),D())};return document.addEventListener("keydown",h),()=>document.removeEventListener("keydown",h)},[D,t,L]);const K=s.useMemo(()=>({nodeId:null,name:u.trim(),imageName:Z.trim()||"runfusion/fusion",imageTag:Y.trim()||"latest",hostConfig:{context:o.context?.trim()||void 0,host:o.host?.trim()||void 0,tlsVerify:o.tlsVerify,tlsCaPath:o.tlsCaPath?.trim()||void 0,tlsCertPath:o.tlsCertPath?.trim()||void 0,tlsKeyPath:o.tlsKeyPath?.trim()||void 0},envVars:Object.fromEntries(U.map(h=>[h.key.trim(),h.value]).filter(([h])=>!!h)),volumeMounts:G.map(h=>({hostPath:h.hostPath.trim(),containerPath:h.containerPath.trim(),mode:h.mode})).filter(h=>h.hostPath&&h.containerPath),resourceSizing:{memoryMB:$,cpus:A},extraClis:[M?"claude-cli":null,l?"droid-cli":null].filter(Boolean),persistentStorage:C,reachableUrl:g.trim()||null,apiKey:N==="manual"&&v.trim()||null}),[v,N,A,o,U,Z,Y,M,l,$,G,u,C,g]),ae=s.useCallback(()=>{X(h=>[...h,{key:"",value:""}])},[]),ne=s.useCallback((h,F)=>{X(B=>B.map((q,oe)=>oe===h?F:q))},[]),se=s.useCallback(h=>{X(F=>F.filter((B,q)=>q!==h))},[]),le=s.useCallback(()=>{te(h=>[...h,{hostPath:"",containerPath:"",mode:"rw"}])},[]),R=s.useCallback((h,F)=>{te(B=>B.map((q,oe)=>oe===h?F:q))},[]),I=s.useCallback(h=>{te(F=>F.filter((B,q)=>q!==h))},[]),W=s.useCallback(async()=>{if(E)return;const h={};if((!K.name||K.name.length>64)&&(h.name="Name is required and must be 64 characters or fewer"),K.reachableUrl||(h.reachableUrl="URL is required"),$<512&&(h.memoryMB="Memory must be at least 512 MB"),A<.5&&(h.cpus="CPUs must be at least 0.5"),T(h),!(Object.keys(h).length>0)){y(!0);try{await a(K),D()}catch{}finally{y(!1)}}},[D,A,K,$,a,E]);return t?e.jsx("div",{className:"modal-overlay open",onClick:D,children:e.jsxs("div",{className:"modal docker-onboarding",role:"dialog","aria-modal":"true","aria-label":"Docker node onboarding",onClick:h=>h.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Provision Docker Node"}),e.jsx("button",{className:"modal-close",onClick:D,disabled:E,"aria-label":"Close onboarding modal",children:"×"})]}),e.jsxs("div",{className:"modal-body docker-onboarding__body",children:[e.jsxs("section",{className:"docker-onboarding__section",children:[e.jsx("h4",{className:"docker-onboarding__section-title",children:"Required Settings"}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Node Name"}),e.jsx("input",{className:"input",value:u,onChange:h=>m(h.target.value),disabled:E,placeholder:"my-docker-node",autoFocus:!0})]}),J.name&&e.jsx("div",{className:"form-error",children:J.name}),e.jsx(Ws,{value:o,onChange:j}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Reachable URL"}),e.jsx("input",{className:"input",value:g,onChange:h=>c(h.target.value),disabled:E,placeholder:je})]}),J.reachableUrl&&e.jsx("div",{className:"form-error",children:J.reachableUrl}),e.jsxs("div",{className:"docker-onboarding__radio-group",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"radio",checked:N==="auto",onChange:()=>w("auto"),disabled:E}),"Auto-generate"]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"radio",checked:N==="manual",onChange:()=>w("manual"),disabled:E}),"Provide manually"]})]}),N==="manual"&&e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"API Key"}),e.jsx("input",{className:"input",type:"password",value:v,onChange:h=>d(h.target.value),disabled:E,placeholder:"Enter API key"})]}),e.jsxs("div",{className:"docker-onboarding__checkbox-group",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:M,onChange:h=>_(h.target.checked),disabled:E}),"Claude CLI"]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:l,onChange:h=>b(h.target.checked),disabled:E}),"Droid CLI"]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:C,onChange:h=>k(h.target.checked),disabled:E}),"Keep data across container recreations"]})]}),e.jsxs("div",{className:"docker-onboarding__inline-fields",children:[e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Memory (MB)"}),e.jsx("input",{className:"input",type:"number",min:512,value:$,onChange:h=>V(Number(h.target.value)),disabled:E})]}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"CPUs"}),e.jsx("input",{className:"input",type:"number",min:.5,step:.5,value:A,onChange:h=>p(Number(h.target.value)),disabled:E})]})]}),J.memoryMB&&e.jsx("div",{className:"form-error",children:J.memoryMB}),J.cpus&&e.jsx("div",{className:"form-error",children:J.cpus})]}),e.jsxs("section",{className:"docker-onboarding__section",children:[e.jsxs("button",{type:"button",className:`docker-onboarding__advanced-toggle ${x?"is-expanded":""}`,onClick:()=>S(h=>!h),disabled:E,children:[e.jsx("span",{children:"Advanced"}),e.jsx(we,{})]}),e.jsx("div",{className:`docker-onboarding__advanced-content ${x?"is-expanded":""}`,children:e.jsxs("div",{children:[e.jsxs("div",{className:"docker-onboarding__inline-fields",children:[e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Image"}),e.jsx("input",{className:"input",value:Z,onChange:h=>H(h.target.value),disabled:E,placeholder:"runfusion/fusion"})]}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Tag"}),e.jsx("input",{className:"input",value:Y,onChange:h=>ee(h.target.value),disabled:E,placeholder:"latest"})]})]}),e.jsxs("div",{className:"docker-onboarding__kv-list",children:[e.jsx("h5",{children:"Environment Variables"}),U.map((h,F)=>e.jsxs("div",{className:"docker-onboarding__kv-row docker-onboarding__kv-row--env",children:[e.jsx("input",{className:"input",placeholder:"KEY",value:h.key,disabled:E,onChange:B=>ne(F,{key:B.target.value,value:h.value})}),e.jsx("input",{className:"input",placeholder:"Value",value:h.value,disabled:E,onChange:B=>ne(F,{key:h.key,value:B.target.value})}),e.jsx("button",{type:"button",className:"btn btn-icon","aria-label":"Remove environment variable",onClick:()=>se(F),disabled:E,children:e.jsx(_e,{size:14})})]},`env-${F}`)),e.jsxs("button",{type:"button",className:"btn btn-sm docker-onboarding__kv-add",onClick:ae,disabled:E,children:[e.jsx(he,{size:14}),"Add variable"]})]}),e.jsxs("div",{className:"docker-onboarding__kv-list",children:[e.jsx("h5",{children:"Volume Mounts"}),G.map((h,F)=>e.jsxs("div",{className:"docker-onboarding__kv-row docker-onboarding__kv-row--mount",children:[e.jsx("input",{className:"input",placeholder:"Host path",value:h.hostPath,disabled:E,onChange:B=>R(F,{hostPath:B.target.value,containerPath:h.containerPath,mode:h.mode})}),e.jsx("input",{className:"input",placeholder:"Container path",value:h.containerPath,disabled:E,onChange:B=>R(F,{hostPath:h.hostPath,containerPath:B.target.value,mode:h.mode})}),e.jsxs("select",{className:"select",value:h.mode,disabled:E,onChange:B=>R(F,{hostPath:h.hostPath,containerPath:h.containerPath,mode:B.target.value==="ro"?"ro":"rw"}),children:[e.jsx("option",{value:"rw",children:"rw"}),e.jsx("option",{value:"ro",children:"ro"})]}),e.jsx("button",{type:"button",className:"btn btn-icon","aria-label":"Remove volume mount",onClick:()=>I(F),disabled:E,children:e.jsx(_e,{size:14})})]},`mount-${F}`)),e.jsxs("button",{type:"button",className:"btn btn-sm docker-onboarding__kv-add",onClick:le,disabled:E,children:[e.jsx(he,{size:14}),"Add mount"]})]})]})})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn",onClick:D,disabled:E,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void W(),disabled:E,children:E?"Creating...":"Create Docker Node"})]})]})}):null}function Zs({nodeId:t,entries:r,loading:a=!1,singleNode:i=!1}){const[u,m]=s.useState(!1),[o,j]=s.useState("all"),[g,c]=s.useState("all"),N=s.useCallback(()=>{m(l=>!l)},[]),w=s.useMemo(()=>{const l=new Set;for(const b of r)l.add(b.nodeName);return Array.from(l).sort()},[r]),v=s.useMemo(()=>{let l=[...r];return o!=="all"&&(l=l.filter(b=>b.direction===o)),!i&&g!=="all"&&(l=l.filter(b=>b.nodeName===g)),l.sort((b,C)=>{const k=new Date(b.timestamp).getTime();return new Date(C.timestamp).getTime()-k}),l},[r,o,g,i]),d=s.useCallback(l=>new Date(l).toLocaleString(),[]),M=s.useCallback(l=>{switch(l){case"success":return"settings-sync-log__badge--success";case"conflict":return"settings-sync-log__badge--conflict";case"error":return"settings-sync-log__badge--error";default:return""}},[]),_=s.useCallback(l=>{switch(l){case"success":return"Success";case"conflict":return"Conflict";case"error":return"Error";default:return l}},[]);return e.jsxs("div",{className:"settings-sync-log",children:[e.jsxs("button",{className:"settings-sync-log__header",type:"button",onClick:N,"aria-expanded":u,"data-testid":"settings-sync-log-header",children:[e.jsx(we,{size:16,className:`settings-sync-log__chevron ${u?"settings-sync-log__chevron--expanded":""}`}),e.jsxs("span",{children:[r.length," ",r.length===1?"entry":"entries"]})]}),u&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"settings-sync-log__filters",children:[e.jsxs("label",{children:["Direction:",e.jsxs("select",{value:o,onChange:l=>j(l.target.value),children:[e.jsx("option",{value:"all",children:"All"}),e.jsx("option",{value:"push",children:"Push"}),e.jsx("option",{value:"pull",children:"Pull"})]})]}),!i&&e.jsxs("label",{children:["Node:",e.jsxs("select",{value:g,onChange:l=>c(l.target.value),children:[e.jsx("option",{value:"all",children:"All Nodes"}),w.map(l=>e.jsx("option",{value:l,children:l},l))]})]})]}),a&&r.length===0?e.jsx("div",{className:"settings-sync-log__empty",children:"Loading..."}):v.length===0?e.jsx("div",{className:"settings-sync-log__empty",children:"No sync history available"}):e.jsx("div",{className:"settings-sync-log__list",children:v.map(l=>e.jsxs("div",{className:"settings-sync-log__entry",children:[e.jsx("span",{className:"settings-sync-log__entry-timestamp",children:d(l.timestamp)}),e.jsx("span",{className:"settings-sync-log__entry-direction",children:l.direction==="push"?e.jsx(Be,{size:14,"data-testid":"upload-icon"}):e.jsx(Te,{size:14,"data-testid":"download-icon"})}),e.jsx("span",{className:`settings-sync-log__entry-result ${M(l.result)}`,children:_(l.result)}),!i&&e.jsx("span",{className:"settings-sync-log__entry-node",children:l.nodeName}),l.details&&e.jsx("span",{className:"settings-sync-log__entry-details",title:l.details,children:l.details})]},l.id))})]})]})}function Qs(t,r){const a=typeof t=="string"?t:JSON.stringify(t,null,2),i=typeof r=="string"?r:JSON.stringify(r,null,2);if(a===i)return a;const u=a.split(`
|
|
12
|
+
`),m=i.split(`
|
|
13
|
+
`),o=[],j=Math.max(u.length,m.length);for(let g=0;g<j;g++){const c=u[g],N=m[g];c!==void 0&&c!==N&&o.push(`- ${c}`),N!==void 0&&N!==c&&o.push(`+ ${N}`),c!==void 0&&c===N&&o.push(` ${c}`)}return o.join(`
|
|
14
|
+
`)}function et({isOpen:t,onClose:r,onResolve:a,conflicts:i,localNodeName:u,remoteNodeName:m,addToast:o}){const[j,g]=s.useState({}),[c,N]=s.useState(!1);s.useEffect(()=>{const l={};for(const b of i)j[b.key]||(l[b.key]={resolution:"local"});Object.keys(l).length>0&&g(b=>({...b,...l}))},[i,j]),s.useEffect(()=>{if(!t)return;const l=b=>{b.key==="Escape"&&(b.preventDefault(),r())};return document.addEventListener("keydown",l),()=>document.removeEventListener("keydown",l)},[t,r]);const w=s.useCallback((l,b)=>{g(C=>{const k=C[l]??{};return b==="manual"?{...C,[l]:{resolution:"manual",manualValue:k.manualValue??JSON.stringify(i.find($=>$.key===l)?.localValue??null,null,2)}}:{...C,[l]:{resolution:b}}})},[i]),v=s.useCallback((l,b)=>{g(C=>({...C,[l]:{...C[l],resolution:"manual",manualValue:b}}))},[]),d=s.useCallback(l=>{const b={};for(const C of i)b[C.key]={resolution:l};g(b)},[i]),M=s.useCallback(async()=>{N(!0);try{const l=i.map(b=>{const C=j[b.key]??{resolution:"local"};let k;switch(C.resolution){case"remote":k=b.remoteValue;break;case"manual":try{k=JSON.parse(C.manualValue??"null")}catch{k=C.manualValue??null}break;case"local":default:k=b.localValue;break}return{key:b.key,value:k}});await a(l),o("Settings conflicts resolved successfully","success"),r()}catch(l){const b=l instanceof Error?l.message:"Failed to resolve conflicts";o(b,"error")}finally{N(!1)}},[o,i,r,a,j]),_=s.useMemo(()=>{const l={};for(const b of i)l[b.key]=Qs(b.localValue,b.remoteValue);return l},[i]);return!t||i.length===0?null:e.jsx("div",{className:"modal-overlay open",onClick:r,children:e.jsxs("div",{className:"modal modal-lg settings-sync-conflict-modal",onClick:l=>l.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":"Resolve Settings Conflicts",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Resolve Settings Conflicts"}),e.jsx("button",{className:"modal-close",onClick:r,"aria-label":"Close conflict modal",children:"×"})]}),e.jsxs("div",{className:"modal-body",children:[e.jsx("div",{className:"settings-sync-conflict-modal__conflict-list",children:i.map(l=>{const b=j[l.key]??{resolution:"local"},C=_[l.key];return e.jsxs("div",{className:"settings-sync-conflict-modal__conflict-item",children:[e.jsx("div",{className:"settings-sync-conflict-modal__key",children:l.key}),e.jsxs("div",{className:"settings-sync-conflict-modal__diff-panel",children:[e.jsxs("div",{className:"settings-sync-conflict-modal__diff-side",children:[e.jsx("div",{className:"settings-sync-conflict-modal__diff-label",children:u}),e.jsx("div",{className:"settings-sync-conflict-modal__diff-content",children:e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap"},children:C})})]}),e.jsxs("div",{className:"settings-sync-conflict-modal__diff-side",children:[e.jsx("div",{className:"settings-sync-conflict-modal__diff-label",children:m}),e.jsx("div",{className:"settings-sync-conflict-modal__diff-content",children:e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap"},children:C})})]})]}),e.jsxs("div",{className:"settings-sync-conflict-modal__resolution",children:[e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${l.key}`,checked:b.resolution==="local",onChange:()=>w(l.key,"local")}),"Keep Local"]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${l.key}`,checked:b.resolution==="remote",onChange:()=>w(l.key,"remote")}),"Keep Remote"]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${l.key}`,checked:b.resolution==="manual",onChange:()=>w(l.key,"manual")}),"Merge Manually"]})]}),b.resolution==="manual"&&e.jsx("textarea",{className:"settings-sync-conflict-modal__manual-input",value:b.manualValue??"",onChange:k=>v(l.key,k.target.value),placeholder:"Enter JSON value..."})]},l.key)})}),e.jsxs("div",{className:"settings-sync-conflict-modal__bulk-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>d("local"),type:"button",children:"Resolve All: Keep Local"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>d("remote"),type:"button",children:"Resolve All: Keep Remote"})]})]}),e.jsxs("div",{className:"modal-actions settings-sync-conflict-modal__footer",children:[e.jsx("button",{className:"btn btn-sm",onClick:r,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:M,disabled:c,children:c?"Resolving...":"Confirm"})]})]})})}const He=/(KEY|TOKEN|SECRET|PASSWORD)/i;function ve(t){if(!t)return"—";const r=new Date(t);return Number.isNaN(r.getTime())?"—":r.toLocaleString()}function st(t){if(!t)return"—";const r=new Date(t),a=Date.now();if(Number.isNaN(r.getTime())||r.getTime()>a)return"—";const i=Math.floor((a-r.getTime())/1e3);if(i<60)return`${i}s`;const u=Math.floor(i/60);if(u<60)return`${u}m`;const m=Math.floor(u/60);return m<24?`${m}h ${u%60}m`:`${Math.floor(m/24)}d ${m%24}h`}function tt(t){switch(t){case"synced":return"node-detail-modal__sync-dot--synced";case"diff":return"node-detail-modal__sync-dot--diff";case"error":return"node-detail-modal__sync-dot--error";case"pending":return"node-detail-modal__sync-dot--pending";case"never-synced":default:return"node-detail-modal__sync-dot--never"}}function at(t){return t==="running"?"success":t==="creating"||t==="recreating"||t==="restarting"?"warning":"error"}function nt(t){return t?`${t.charAt(0).toUpperCase()}${t.slice(1)}`:"Unknown"}function rt(t){if(!t)return"—";try{const r=new URL(t);return r.port?r.port:r.protocol==="https:"?"443":r.protocol==="http:"?"80":"—"}catch{return"—"}}function lt(t,r){return He.test(t)?"••••••••":r}function ot({isOpen:t,onClose:r,node:a,projects:i,onUpdate:u,onHealthCheck:m,addToast:o,syncStatus:j,onPushSettings:g,onPullSettings:c,onSyncAuth:N,syncHistory:w=[],onResolveConflicts:v,managedDockerNode:d,containerStatus:M,onFetchContainerStatus:_,onFetchLogs:l,onUpdateDockerConfig:b,onFetchDockerConfigDiff:C}){const k=s.useRef(!0),[$,V]=s.useState(!1),[A,p]=s.useState(""),[x,S]=s.useState(""),[Z,H]=s.useState(""),[Y,ee]=s.useState(2),[U,X]=s.useState(!1),[G,te]=s.useState(!1),[J,T]=s.useState(!1),[E,y]=s.useState(!1),[L,D]=s.useState(null),[K,ae]=s.useState(!1),[ne]=s.useState([]),[se,le]=s.useState(M),[R,I]=s.useState(!1),[W,h]=s.useState(!1),[F,B]=s.useState(""),[q,oe]=s.useState(!1),[fe,Me]=s.useState(!1),[f,O]=s.useState(a?.dockerConfig??null),[Pe,Ee]=s.useState({}),[ie,Re]=s.useState(!1),[qe,Ae]=s.useState(!1);s.useEffect(()=>(k.current=!0,()=>{k.current=!1}),[]),s.useEffect(()=>{le(M)},[M]),s.useEffect(()=>{if(!a||!t){V(!1),h(!1),B("");return}p(a.name),S(a.url??""),H(a.apiKey??""),ee(a.maxConcurrent),V(!1),O(a.dockerConfig??null),Me(!1),Ee({})},[t,a]),s.useEffect(()=>{if(!t)return;const n=P=>{P.key==="Escape"&&(P.preventDefault(),r())};return document.addEventListener("keydown",n),()=>document.removeEventListener("keydown",n)},[t,r]);const ge=s.useMemo(()=>a?hs(i,a):[],[a,i]),Ye=s.useMemo(()=>d?d.hostConfig.type==="remote"?d.hostConfig.host??"—":"Local Docker":"—",[d]),Xe=s.useMemo(()=>!d?.resourceSizing?.cpuLimit&&!d?.resourceSizing?.memoryLimit?"Default":`${d.resourceSizing?.cpuLimit??"Default CPU"} / ${d.resourceSizing?.memoryLimit??"Default memory"}`,[d]),Je=s.useCallback(async()=>{if(a)try{if(await m(a.id),!k.current)return;o(`Health check completed for ${a.name}`,"success")}catch(n){if(!k.current)return;const P=n instanceof Error?n.message:"Health check failed";o(P,"error")}},[o,a,m]),We=s.useCallback(async()=>{if(!(!a||!g)){D(null),te(!0);try{if(await g(a.id),!k.current)return;o("Settings pushed successfully","success")}catch(n){if(!k.current)return;const P=n instanceof Error?n.message:"Push settings failed";D(P),o(P,"error")}finally{k.current&&te(!1)}}},[o,a,g]),Ge=s.useCallback(async()=>{if(!(!a||!c)){D(null),T(!0);try{if(await c(a.id),!k.current)return;o("Settings pulled successfully","success")}catch(n){if(!k.current)return;const P=n instanceof Error?n.message:"Pull settings failed";D(P),o(P,"error")}finally{k.current&&T(!1)}}},[o,a,c]),Ze=s.useCallback(async()=>{if(!(!a||!N)){D(null),y(!0);try{if(await N(a.id),!k.current)return;o("Auth credentials synced successfully","success")}catch(n){if(!k.current)return;const P=n instanceof Error?n.message:"Auth sync failed";D(P),o(P,"error")}finally{k.current&&y(!1)}}},[o,a,N]),Qe=s.useCallback(()=>{D(null)},[]),es=s.useCallback(async()=>{if(!(!d||!_)){I(!0);try{const n=await _(d.id);if(!k.current)return;le(n)}catch(n){const P=n instanceof Error?n.message:"Failed to fetch container status";o(P,"error")}finally{k.current&&I(!1)}}},[o,d,_]),ss=s.useCallback(async()=>{if(!(!d||!l)){h(!0),oe(!0);try{const n=await l(d.id);if(!k.current)return;B(n)}catch(n){if(!k.current)return;B("");const P=n instanceof Error?n.message:"Failed to fetch container logs";o(P,"error")}finally{k.current&&oe(!1)}}},[o,d,l]),ts=s.useCallback(async()=>{if(!a||U)return;const n=A.trim();if(!n){o("Name is required","error");return}if(a.type==="remote"&&!x.trim()){o("URL is required for remote nodes","error");return}if(!Number.isFinite(Y)||Y<1){o("Concurrency must be at least 1","error");return}X(!0);try{await u(a.id,{name:n,url:a.type==="remote"&&x.trim()||void 0,apiKey:a.type==="remote"&&Z||void 0,maxConcurrent:Y}),o(`Updated ${n}`,"success"),V(!1)}catch(P){const Q=P instanceof Error?P.message:"Failed to update node";o(Q,"error")}finally{X(!1)}},[o,Z,U,Y,A,a,u,x]);s.useEffect(()=>{!a?.dockerConfig||!C||!t||C(a.id).then(n=>{k.current&&Ae(n.needsRecreate)}).catch(()=>{k.current&&Ae(!1)})},[t,a,C]);const as=s.useCallback(async()=>{if(!(!a||!f||!b||ie)){Re(!0);try{const n=await b(a.id,{image:f.image,volumeMounts:f.volumeMounts,environment:f.environment,resources:f.resources,host:f.host,extraClis:f.extraClis,persistence:f.persistence,containerName:f.containerName});if(!k.current)return;O(n),o("Docker config saved","success")}catch(n){if(!k.current)return;const P=n instanceof Error?n.message:"Failed to save Docker config";o(P,"error")}finally{k.current&&Re(!1)}}},[o,f,ie,a,b]),ns=s.useCallback(()=>{a&&(p(a.name),S(a.url??""),H(a.apiKey??""),ee(a.maxConcurrent),V(!1))},[a]);if(!t||!a)return null;const re=se?.status??d?.status,rs=at(re);return e.jsxs("div",{className:"modal-overlay open",onClick:r,children:[e.jsxs("div",{className:"modal modal-lg node-detail-modal",onClick:n=>n.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":`Node details for ${a.name}`,children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Node Details"}),e.jsx("button",{className:"modal-close",onClick:r,"aria-label":"Close node detail modal",children:"×"})]}),e.jsxs("div",{className:"modal-body node-detail-modal__body",children:[e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsxs("div",{className:"node-detail-modal__section-header",children:[e.jsx("h4",{children:"Overview"}),!$&&e.jsxs("button",{className:"btn btn-sm",onClick:()=>V(!0),children:[e.jsx(fs,{size:14}),"Edit"]})]}),e.jsxs("div",{className:"node-detail-modal__grid",children:[e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Name"}),$?e.jsx("input",{className:"input",value:A,onChange:n=>p(n.target.value),disabled:U}):e.jsx("strong",{children:a.name})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Type"}),e.jsx("strong",{children:a.type==="local"?"Local":"Remote"})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Status"}),e.jsx("strong",{children:a.status})]}),e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Max Concurrent"}),$?e.jsx("input",{className:"input",type:"number",min:1,max:10,value:Y,onChange:n=>ee(Number(n.target.value)),disabled:U}):e.jsx("strong",{children:a.maxConcurrent})]}),a.type==="remote"&&e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"node-detail-modal__field node-detail-modal__field--full",children:[e.jsx("span",{children:"URL"}),$?e.jsx("input",{className:"input",value:x,onChange:n=>S(n.target.value),disabled:U}):e.jsx("strong",{children:a.url??"—"})]}),e.jsxs("label",{className:"node-detail-modal__field node-detail-modal__field--full",children:[e.jsx("span",{children:"API Key"}),$?e.jsx("input",{className:"input",type:"password",value:Z,onChange:n=>H(n.target.value),placeholder:"Leave blank to keep unchanged",disabled:U}):e.jsx("strong",{children:a.apiKey?"••••••••":"Not configured"})]})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Created"}),e.jsx("strong",{children:ve(a.createdAt)})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Updated"}),e.jsx("strong",{children:ve(a.updatedAt)})]})]}),$&&e.jsxs("div",{className:"node-detail-modal__edit-actions",children:[e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:ts,disabled:U,children:[e.jsx($e,{size:14}),U?"Saving...":"Save"]}),e.jsxs("button",{className:"btn btn-sm",onClick:ns,disabled:U,children:[e.jsx(me,{size:14}),"Cancel"]})]})]}),e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsxs("h4",{children:[a.type==="local"?"Projects":"Assigned Projects"," (",ge.length,")"]}),ge.length===0?e.jsx("p",{className:"node-detail-modal__empty",children:a.type==="local"?"No projects are running on this node.":"No projects are assigned to this node."}):e.jsx("ul",{className:"node-detail-modal__project-list",children:ge.map(n=>e.jsxs("li",{className:"node-detail-modal__project-item",children:[e.jsx("span",{children:n.name}),e.jsx("code",{children:n.id})]},n.id))})]}),e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Health"}),e.jsxs("div",{className:"node-detail-modal__health-row",children:[e.jsxs("span",{children:["Status: ",e.jsx("strong",{children:a.status})]}),e.jsxs("span",{children:["Last check: ",e.jsx("strong",{children:ve(a.updatedAt)})]})]})]}),f&&e.jsxs("section",{className:"node-detail-modal__section node-detail-modal__docker-config",children:[e.jsxs("button",{className:"btn btn-sm node-detail-modal__docker-toggle",onClick:()=>Me(n=>!n),"aria-expanded":fe,children:[e.jsx(we,{size:14,className:fe?"node-detail-modal__docker-toggle-icon--expanded":""}),"Docker Configuration"]}),fe&&e.jsxs("div",{className:"node-detail-modal__docker-config-content",children:[e.jsx("div",{className:"node-detail-modal__grid",children:e.jsxs("label",{className:"node-detail-modal__field node-detail-modal__field--full",children:[e.jsx("span",{children:"Image"}),e.jsx("input",{className:"input",value:f.image,onChange:n=>O({...f,image:n.target.value})})]})}),e.jsxs("details",{children:[e.jsx("summary",{children:"Volume Mounts"}),e.jsxs("div",{className:"node-detail-modal__docker-list",children:[f.volumeMounts.map((n,P)=>e.jsxs("div",{className:"node-detail-modal__docker-row",children:[e.jsx("input",{className:"input",value:n.hostPath,placeholder:"Host path",onChange:Q=>{const z=[...f.volumeMounts];z[P]={...z[P],hostPath:Q.target.value},O({...f,volumeMounts:z})}}),e.jsx("input",{className:"input",value:n.containerPath,placeholder:"Container path",onChange:Q=>{const z=[...f.volumeMounts];z[P]={...z[P],containerPath:Q.target.value},O({...f,volumeMounts:z})}}),e.jsxs("select",{className:"input",value:n.mode??"rw",onChange:Q=>{const z=[...f.volumeMounts];z[P]={...z[P],mode:Q.target.value},O({...f,volumeMounts:z})},children:[e.jsx("option",{value:"rw",children:"rw"}),e.jsx("option",{value:"ro",children:"ro"})]}),e.jsxs("select",{className:"input",value:n.type??"volume",onChange:Q=>{const z=[...f.volumeMounts];z[P]={...z[P],type:Q.target.value},O({...f,volumeMounts:z})},children:[e.jsx("option",{value:"volume",children:"volume"}),e.jsx("option",{value:"bind",children:"bind"})]}),e.jsx("button",{className:"btn btn-sm",onClick:()=>O({...f,volumeMounts:f.volumeMounts.filter((Q,z)=>z!==P)}),children:"Remove"})]},`${n.hostPath}-${n.containerPath}-${P}`)),e.jsx("button",{className:"btn btn-sm",onClick:()=>O({...f,volumeMounts:[...f.volumeMounts,{hostPath:"",containerPath:"",mode:"rw",type:"volume"}]}),children:"Add Mount"})]})]}),e.jsxs("details",{children:[e.jsx("summary",{children:"Environment Variables"}),e.jsxs("div",{className:"node-detail-modal__docker-list",children:[Object.entries(f.environment).map(([n,P])=>{const Q=He.test(n)&&!Pe[n];return e.jsxs("div",{className:"node-detail-modal__docker-row",children:[e.jsx("input",{className:"input",value:n,onChange:z=>{const xe={...f.environment};delete xe[n],xe[z.target.value]=P,O({...f,environment:xe})}}),e.jsx("input",{className:"input",value:Q?"***":String(P),onChange:z=>O({...f,environment:{...f.environment,[n]:z.target.value}})}),e.jsx("button",{className:"btn btn-sm",onClick:()=>Ee(z=>({...z,[n]:!z[n]})),children:Pe[n]?e.jsx(gs,{size:14}):e.jsx(xs,{size:14})}),e.jsx("button",{className:"btn btn-sm",onClick:()=>{const z={...f.environment};delete z[n],O({...f,environment:z})},children:"Remove"})]},n)}),e.jsx("button",{className:"btn btn-sm",onClick:()=>{const n=`NEW_VAR_${Object.keys(f.environment).length+1}`;O({...f,environment:{...f.environment,[n]:""}})},children:"Add Variable"})]})]}),e.jsxs("details",{children:[e.jsx("summary",{children:"Resources"}),e.jsxs("div",{className:"node-detail-modal__docker-stack",children:[e.jsx("input",{className:"input",type:"number",placeholder:"Memory bytes (2 GB = 2147483648)",value:f.resources?.memoryBytes??"",onChange:n=>O({...f,resources:{...f.resources,memoryBytes:n.target.value?Number(n.target.value):void 0}})}),e.jsx("input",{className:"input",type:"number",placeholder:"CPU count",value:f.resources?.cpuCount??"",onChange:n=>O({...f,resources:{...f.resources,cpuCount:n.target.value?Number(n.target.value):void 0}})}),e.jsx("input",{className:"input",type:"number",placeholder:"PIDs limit",value:f.resources?.pidsLimit??"",onChange:n=>O({...f,resources:{...f.resources,pidsLimit:n.target.value?Number(n.target.value):void 0}})})]})]}),e.jsxs("details",{children:[e.jsx("summary",{children:"Host Config"}),e.jsxs("div",{className:"node-detail-modal__docker-stack",children:[e.jsx("input",{className:"input",placeholder:"Context name",value:f.host?.contextName??"",onChange:n=>O({...f,host:{...f.host,contextName:n.target.value}})}),e.jsx("input",{className:"input",placeholder:"Docker host URL",value:f.host?.dockerHost??"",onChange:n=>O({...f,host:{...f.host,dockerHost:n.target.value}})}),e.jsx("input",{className:"input",placeholder:"TLS CA cert path",value:f.host?.tlsCaCert??"",onChange:n=>O({...f,host:{...f.host,tlsCaCert:n.target.value}})}),e.jsx("input",{className:"input",placeholder:"TLS cert path",value:f.host?.tlsCert??"",onChange:n=>O({...f,host:{...f.host,tlsCert:n.target.value}})}),e.jsx("input",{className:"input",placeholder:"TLS key path",value:f.host?.tlsKey??"",onChange:n=>O({...f,host:{...f.host,tlsKey:n.target.value}})}),e.jsxs("label",{className:"node-detail-modal__checkbox",children:[e.jsx("input",{type:"checkbox",checked:f.host?.tlsVerify??!0,onChange:n=>O({...f,host:{...f.host,tlsVerify:n.target.checked}})}),"TLS verify"]})]})]}),e.jsxs("details",{children:[e.jsx("summary",{children:"Extra CLIs"}),e.jsxs("div",{className:"node-detail-modal__docker-list",children:[(f.extraClis??[]).map((n,P)=>e.jsxs("div",{className:"node-detail-modal__docker-row",children:[e.jsx("input",{className:"input",value:n,onChange:Q=>{const z=[...f.extraClis??[]];z[P]=Q.target.value,O({...f,extraClis:z})}}),e.jsx("button",{className:"btn btn-sm",onClick:()=>O({...f,extraClis:(f.extraClis??[]).filter((Q,z)=>z!==P)}),children:"Remove"})]},`${n}-${P}`)),e.jsx("button",{className:"btn btn-sm",onClick:()=>O({...f,extraClis:[...f.extraClis??[],""]}),children:"Add CLI"})]})]}),e.jsxs("details",{children:[e.jsx("summary",{children:"Persistence"}),e.jsxs("div",{className:"node-detail-modal__docker-stack",children:[e.jsx("input",{className:"input",placeholder:"Volume name",value:f.persistence?.volumeName??"",onChange:n=>O({...f,persistence:{...f.persistence,volumeName:n.target.value}})}),e.jsxs("label",{className:"node-detail-modal__checkbox",children:[e.jsx("input",{type:"checkbox",checked:f.persistence?.retainOnDelete??!1,onChange:n=>O({...f,persistence:{...f.persistence,retainOnDelete:n.target.checked}})}),"Retain on delete"]})]})]}),e.jsxs("div",{className:"node-detail-modal__docker-meta",children:[e.jsxs("span",{children:["Config v",f.configVersion," • Updated ",ke(f.lastUpdated??a.updatedAt)]}),qe&&e.jsx("span",{className:"node-detail-modal__docker-recreate",children:"Needs Recreate"})]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>void as(),disabled:ie,children:[e.jsx($e,{size:14}),ie?"Saving...":"Save Docker Config"]})]})]}),d&&e.jsxs("section",{className:"node-detail-modal__section docker-management",children:[e.jsx("h4",{children:"Docker Management"}),e.jsxs("div",{className:"docker-management__status-card",children:[e.jsxs("div",{className:"docker-management__status-row",children:[e.jsx("span",{className:`docker-management__status-dot docker-management__status-dot--${rs}`,"aria-hidden":!0}),e.jsx("strong",{children:nt(re)}),(re==="creating"||re==="recreating"||re==="restarting")&&e.jsx(De,{size:14,className:"spin","aria-hidden":!0})]}),e.jsxs("div",{className:"docker-management__status-meta",children:[re==="running"&&e.jsxs("span",{children:["Uptime: ",st(se?.startedAt)]}),re!=="running"&&se?.exitCode!==void 0&&e.jsxs("span",{children:["Exit code: ",se.exitCode]}),(se?.error||d.errorMessage)&&e.jsx("span",{children:se?.error??d.errorMessage})]}),e.jsx("button",{className:"btn btn-sm",onClick:()=>void es(),disabled:!_||R,children:R?"Refreshing...":"Refresh Status"})]}),e.jsxs("div",{className:"node-detail-modal__grid docker-management__info-grid",children:[e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Image"}),e.jsx("strong",{children:e.jsxs("code",{children:[d.imageName,":",d.imageTag]})})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Container ID"}),e.jsx("strong",{children:e.jsx("code",{children:d.containerId?d.containerId.slice(0,12):"—"})})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Host"}),e.jsx("strong",{children:Ye})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Persistent Storage"}),e.jsx("strong",{children:d.persistentStorage?"Yes":"No"})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Port"}),e.jsx("strong",{children:rt(d.reachableUrl)})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Resource Sizing"}),e.jsx("strong",{children:Xe})]})]}),e.jsxs("div",{className:"docker-management__actions",children:[e.jsxs("button",{className:"btn btn-sm",disabled:!0,title:"Available after FN-3113",children:[e.jsx(Ke,{size:14}),"Start"]}),e.jsxs("button",{className:"btn btn-sm",disabled:!0,title:"Available after FN-3113",children:[e.jsx(Ue,{size:14}),"Stop"]}),e.jsxs("button",{className:"btn btn-sm",disabled:!0,title:"Available after FN-3113",children:[e.jsx(De,{size:14}),"Restart"]}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>void ss(),disabled:!l,children:[e.jsx(ps,{size:14}),"View Logs"]})]}),W&&e.jsxs("div",{className:"docker-management__log-viewer",children:[e.jsxs("div",{className:"docker-management__log-viewer-header",children:[e.jsx("strong",{children:"Container Logs"}),e.jsx("button",{className:"btn-icon",onClick:()=>h(!1),"aria-label":"Close logs",children:e.jsx(me,{size:14})})]}),q?e.jsx("p",{children:"Fetching logs..."}):e.jsx("pre",{children:F.trim()||"No logs available"})]}),e.jsxs("details",{children:[e.jsx("summary",{children:"Environment Variables"}),e.jsx("dl",{className:"docker-management__env-list",children:Object.entries(d.envVars).map(([n,P])=>e.jsxs("div",{children:[e.jsx("dt",{children:n}),e.jsx("dd",{children:lt(n,P)})]},n))})]}),e.jsxs("details",{children:[e.jsx("summary",{children:"Volume Mounts"}),e.jsx("ul",{className:"docker-management__mounts-list",children:d.volumeMounts.map(n=>e.jsxs("li",{children:[e.jsxs("span",{children:[n.hostPath," → ",n.containerPath]}),n.readOnly&&e.jsx("span",{className:"node-card__type-badge",children:"Read-only"})]},`${n.hostPath}:${n.containerPath}`))})]})]}),a.type==="remote"&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Settings Sync"}),j&&e.jsxs("div",{className:"node-detail-modal__sync-status",children:[e.jsx("span",{className:`node-detail-modal__sync-dot ${tt(j.syncState)}`,"aria-hidden":!0}),e.jsxs("span",{children:["Last sync: ",e.jsx("strong",{children:j.lastSyncAt?ke(j.lastSyncAt):"Never synced"})]}),j.diffCount>0&&e.jsxs("span",{className:"node-detail-modal__sync-diff",children:["Differences: ",e.jsx("strong",{children:j.diffCount})]})]}),e.jsxs("div",{className:"node-detail-modal__sync-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:We,disabled:G||!g,children:[e.jsx(Be,{size:14}),G?"Pushing...":"Push Settings"]}),e.jsxs("button",{className:"btn btn-sm",onClick:Ge,disabled:J||!c,children:[e.jsx(Te,{size:14}),J?"Pulling...":"Pull Settings"]}),e.jsxs("button",{className:"btn btn-sm",onClick:Ze,disabled:E||!N,children:[e.jsx(Oe,{size:14}),E?"Syncing...":"Sync Auth"]})]}),L&&e.jsxs("div",{className:"node-detail-modal__sync-error",children:[e.jsx("span",{children:L}),e.jsx("button",{className:"node-detail-modal__sync-error-dismiss",onClick:Qe,"aria-label":"Dismiss error",children:e.jsx(me,{size:14})})]})]}),a.type==="remote"&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Sync History"}),e.jsx(Zs,{nodeId:a.id,entries:w,singleNode:!0})]})]}),e.jsxs("div",{className:"modal-actions node-detail-modal__actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:Je,children:[e.jsx(Fe,{size:14}),"Health Check"]}),e.jsx("button",{className:"btn btn-sm",onClick:r,children:"Close"})]})]}),a.type==="remote"&&e.jsx(et,{isOpen:K,onClose:()=>ae(!1),onResolve:v??(async()=>{}),conflicts:ne,localNodeName:"Local",remoteNodeName:a.name,addToast:o})]})}const ct=15e3,it=1e3;function dt(){const[t,r]=s.useState([]),[a,i]=s.useState(!0),[u,m]=s.useState(null),o=s.useRef(null),j=s.useRef(0),g=s.useCallback(async()=>{try{m(null);const v=await Ie();r(v)}catch(v){m(v instanceof Error?v.message:"Failed to fetch managed Docker nodes")}},[]);s.useEffect(()=>{let v=!1;async function d(){i(!0);try{const _=await Ie();v||(r(_),m(null))}catch(_){v||m(_ instanceof Error?_.message:"Failed to fetch managed Docker nodes")}finally{v||i(!1)}}d();const M=()=>{if(document.visibilityState!=="visible")return;const _=Date.now();_-j.current<it||(j.current=_,g())};return document.addEventListener("visibilitychange",M),()=>{v=!0,document.removeEventListener("visibilitychange",M)}},[g]),s.useEffect(()=>{if(!a)return o.current=setInterval(()=>{g()},ct),()=>{o.current&&(clearInterval(o.current),o.current=null)}},[a,g]);const c=s.useCallback(async v=>js(v),[]),N=s.useCallback(async(v,d)=>(await vs(v,d)).logs,[]),w=s.useCallback(async v=>{const d=await bs(v),M={...d,nodeId:d.nodeId??void 0,containerId:d.containerId??void 0,status:d.status,hostConfig:{type:d.hostConfig.host||d.hostConfig.context?"remote":"local",host:d.hostConfig.host,context:d.hostConfig.context},reachableUrl:d.reachableUrl??void 0,volumeMounts:d.volumeMounts.map(_=>({hostPath:_.hostPath,containerPath:_.containerPath,readOnly:_.mode==="ro"?!0:void 0})),persistentStorage:d.persistentStorage,resourceSizing:{cpuLimit:d.resourceSizing.cpus!==void 0?String(d.resourceSizing.cpus):void 0,memoryLimit:d.resourceSizing.memoryMB!==void 0?`${d.resourceSizing.memoryMB}MB`:void 0},errorMessage:d.errorMessage??void 0};return r(_=>[..._,M]),M},[]);return{dockerNodes:t,loading:a,error:u,refresh:g,getContainerStatus:c,getLogs:N,create:w}}function xt({addToast:t,onClose:r}){const{nodes:a,loading:i,error:u,refresh:m,register:o,update:j,unregister:g,healthCheck:c,patchDockerConfig:N,fetchDockerDiff:w,discoverRemoteProjects:v}=ys(),{projects:d,refresh:M}=_s(),{meshState:_,loading:l,error:b}=$s(),{syncStatusMap:C,pushSettings:k,pullSettings:$,syncAuth:V,trackNode:A,getAuthSyncState:p,getAuthProviders:x}=Rs(),{dockerNodes:S,loading:Z,refresh:H,getContainerStatus:Y,getLogs:ee,create:U}=dt(),[X,G]=s.useState(!1),[te,J]=s.useState(!1),[T,E]=s.useState(null);s.useEffect(()=>{const R=a.filter(I=>I.type==="remote");for(const I of R)A(I.id)},[a,A]),s.useEffect(()=>{if(!T)return;const R=a.find(I=>I.id===T.id)??null;E(R)},[a,T]);const y=s.useMemo(()=>{const R=a.length,I=a.filter(q=>q.status==="online").length,W=a.filter(q=>q.status==="offline"||q.status==="error").length,h=a.filter(q=>q.type==="remote").length,F=a.filter(q=>q.type==="remote"&&C[q.id]&&pe(C[q.id]).syncState==="synced").length,B=S.length;return{total:R,online:I,offline:W,remote:h,synced:F,docker:B}},[S.length,a,C]),L=s.useCallback(async R=>{await o(R),await M()},[M,o]),D=s.useCallback(async R=>{try{await U(R),t(`Docker node "${R.name}" created`,"success"),J(!1)}catch(I){const W=I instanceof Error?I.message:"Failed to create Docker node";throw t(W,"error"),I}},[t,U]),K=s.useMemo(()=>{const R=new Map;for(const I of S)I.nodeId&&R.set(I.nodeId,I);return R},[S]),ae=s.useCallback(async()=>{try{await Promise.all([m(),H()])}catch{t("Failed to refresh nodes","error")}},[t,m,H]),ne=s.useCallback(async R=>{try{await c(R),t("Node health check complete","success")}catch(I){const W=I instanceof Error?I.message:"Health check failed";t(W,"error")}},[t,c]),se=s.useCallback(async R=>{try{await g(R),t("Node removed","success"),T?.id===R&&E(null)}catch(I){const W=I instanceof Error?I.message:"Failed to remove node";t(W,"error")}},[t,T?.id,g]),le=s.useCallback(async(R,I)=>{await j(R,I)},[j]);return e.jsxs("div",{className:"nodes-view","data-testid":"nodes-view",children:[e.jsxs("div",{className:"nodes-view-header",children:[e.jsxs("div",{className:"nodes-view-title",children:[e.jsxs("h2",{children:[e.jsx(Ve,{size:20}),"Nodes"]}),e.jsxs("span",{className:"nodes-view-count",children:[a.length," registered"]})]}),e.jsxs("div",{className:"nodes-view-actions",children:[e.jsx("button",{className:"btn-icon nodes-view-close",onClick:r,"aria-label":"Close nodes view",children:e.jsx(me,{size:16})}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>void ae(),disabled:i||Z,children:[e.jsx(Ne,{size:14,className:i?"spin":""}),"Refresh"]}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>G(!0),children:[e.jsx(he,{size:14}),"Add Node"]}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>J(!0),title:"Add a managed Docker node",children:[e.jsx(ye,{size:14}),"Add Docker Node"]})]})]}),e.jsxs("div",{className:"nodes-view-stats",children:[e.jsxs("div",{className:"nodes-view-stat","data-testid":"nodes-stat-total",children:[e.jsx("span",{children:"Total"}),e.jsx("strong",{children:y.total})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--online","data-testid":"nodes-stat-online",children:[e.jsxs("span",{children:[e.jsx(Ms,{size:14})," Online"]}),e.jsx("strong",{children:y.online})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--offline","data-testid":"nodes-stat-offline",children:[e.jsxs("span",{children:[e.jsx(Ss,{size:14})," Offline"]}),e.jsx("strong",{children:y.offline})]}),e.jsxs("div",{className:"nodes-view-stat","data-testid":"nodes-stat-remote",children:[e.jsxs("span",{children:[e.jsx(Ns,{size:14})," Remote"]}),e.jsx("strong",{children:y.remote})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--synced","data-testid":"nodes-stat-synced",children:[e.jsxs("span",{children:[e.jsx(Ne,{size:14})," Synced"]}),e.jsx("strong",{children:y.synced})]}),e.jsxs("div",{className:"nodes-view-stat","data-testid":"nodes-stat-docker",children:[e.jsxs("span",{children:[e.jsx(ye,{size:14})," Docker"]}),e.jsx("strong",{children:y.docker})]})]}),(u||b)&&e.jsx("div",{className:"nodes-view-error",children:u??b}),!l&&_.length>0&&e.jsxs("section",{className:"nodes-view-topology","aria-label":"Mesh Topology",children:[e.jsx("h3",{className:"nodes-view-section-title",children:"Mesh Topology"}),e.jsx(Hs,{nodes:_})]}),i?e.jsx("div",{className:"nodes-view-grid",children:Array.from({length:4}).map((R,I)=>e.jsx("div",{className:"node-card node-card--loading","aria-hidden":!0},I))}):a.length===0?e.jsxs("div",{className:"nodes-view-empty",children:[e.jsx("p",{children:"No nodes are registered yet."}),e.jsxs("button",{className:"btn btn-primary",onClick:()=>G(!0),children:[e.jsx(he,{size:14}),"Add First Node"]})]}):e.jsx("div",{className:"nodes-view-grid",children:a.map(R=>{const I=R.type==="remote"&&C[R.id]?pe(C[R.id]):void 0;return e.jsx(Fs,{node:R,projects:d,onHealthCheck:W=>{ne(W)},onEdit:W=>E(W),onRemove:W=>{se(W)},isLoading:i,syncStatus:I,authSyncState:R.type==="remote"?p(R.id):void 0,authSyncProviders:R.type==="remote"?x(R.id):void 0,managedDockerNode:K.get(R.id)},R.id)})}),e.jsx(Ys,{isOpen:X,onClose:()=>G(!1),onSubmit:L,onDiscoverRemoteProjects:v,addToast:t,projects:d}),e.jsx(Gs,{isOpen:te,onClose:()=>J(!1),onSubmit:D,addToast:t}),e.jsx(ot,{isOpen:T!==null,onClose:()=>E(null),node:T,projects:d,onUpdate:le,onHealthCheck:ne,addToast:t,syncStatus:T?.type==="remote"&&T&&C[T.id]?pe(C[T.id]):void 0,onPushSettings:k,onPullSettings:$,onSyncAuth:V,managedDockerNode:T?K.get(T.id):void 0,onFetchContainerStatus:Y,onFetchLogs:ee,onUpdateDockerConfig:N,onFetchDockerConfigDiff:w})]})}export{xt as NodesView};
|
package/dist/client/assets/{PiExtensionsManager-DL_QcN56.js → PiExtensionsManager-i-7UL2oh.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{c as J,
|
|
1
|
+
import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{c as J,ev as Q,ew as V,ex as Y,R as $,ek as y,I as Z,a as T,b as ee,W as se,ey as L,cE as D,F as A,ez as ae,eA as te,eB as I,X as ie}from"./index-bEwSVl7B.js";import"./vendor-xterm-DzcZoU0P.js";/**
|
|
2
2
|
* @license lucide-react v1.7.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const ne=[["path",{d:"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z",key:"e79jfc"}],["circle",{cx:"13.5",cy:"6.5",r:".5",fill:"currentColor",key:"1okk4w"}],["circle",{cx:"17.5",cy:"10.5",r:".5",fill:"currentColor",key:"f64h9f"}],["circle",{cx:"6.5",cy:"12.5",r:".5",fill:"currentColor",key:"qy21gx"}],["circle",{cx:"8.5",cy:"7.5",r:".5",fill:"currentColor",key:"fotxhn"}]],
|
|
6
|
+
*/const ne=[["path",{d:"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z",key:"e79jfc"}],["circle",{cx:"13.5",cy:"6.5",r:".5",fill:"currentColor",key:"1okk4w"}],["circle",{cx:"17.5",cy:"10.5",r:".5",fill:"currentColor",key:"f64h9f"}],["circle",{cx:"6.5",cy:"12.5",r:".5",fill:"currentColor",key:"qy21gx"}],["circle",{cx:"8.5",cy:"7.5",r:".5",fill:"currentColor",key:"fotxhn"}]],W=J("palette",ne);function le(t){return t.replace(/-/g,"-")}function ce(t){return{"fusion-global":"Fusion Global","pi-global":"Pi Global","fusion-project":"Fusion Project","pi-project":"Pi Project",package:"Package"}[t]??t}function re(t){return t.startsWith("npm:")?"npm":t.startsWith("git:")?"git":"local"}function oe(t){return t.replace(/^(npm:|git:)/,"")}function pe({addToast:t,projectId:x}){const[c,B]=l.useState(null),[f,P]=l.useState(!0),[N,E]=l.useState(!1),[S,w]=l.useState(!1),[h,F]=l.useState(""),[G,M]=l.useState(new Set),[p,O]=l.useState([]),[b,C]=l.useState(!0),[_,R]=l.useState(!1),r=l.useCallback(async()=>{try{P(!0);const s=await Q();B(s)}catch(s){t(`Failed to load Pi settings: ${s instanceof Error?s.message:String(s)}`,"error")}finally{P(!1)}},[t]),m=l.useCallback(async()=>{try{C(!0);const s=await V(x);O(s.extensions)}catch(s){t(`Failed to load extensions: ${s instanceof Error?s.message:String(s)}`,"error")}finally{C(!1)}},[t,x]),q=l.useCallback(async s=>{try{R(!0);const i=s.enabled?[...p.filter(a=>a.enabled&&a.id!==s.id).map(a=>a.id),s.id]:p.filter(a=>a.enabled&&a.id!==s.id).map(a=>a.id);await Y(i,x),await m(),t(s.enabled?"Extension disabled":"Extension enabled","success")}catch(i){t(`Failed to update extension: ${i instanceof Error?i.message:String(i)}`,"error")}finally{R(!1)}},[p,x,m,t]);l.useEffect(()=>{r()},[r]),l.useEffect(()=>{m()},[m]);const K=s=>{M(i=>{const a=new Set(i);return a.has(s)?a.delete(s):a.add(s),a})},z=async()=>{if(!h.trim()){t("Please enter a package source","error");return}try{E(!0),await ae(h.trim()),t("Package installed successfully","success"),F(""),await r()}catch(s){t(`Failed to install package: ${s instanceof Error?s.message:String(s)}`,"error")}finally{E(!1)}},U=async()=>{try{w(!0),await te(x),await Promise.all([r(),m()]),t("Fusion skill reinstalled successfully","success")}catch(s){t(`Failed to reinstall Fusion skill: ${s instanceof Error?s.message:String(s)}`,"error")}finally{w(!1)}},X=async s=>{if(!c)return;const i=c.packages.filter(a=>(typeof a=="string"?a:a.source)!==s);try{await I({packages:i}),t("Package removed","success"),await r()}catch(a){t(`Failed to remove package: ${a instanceof Error?a.message:String(a)}`,"error")}},H=async(s,i)=>{if(!c)return;const a=c[s].filter(n=>n!==i);try{await I({[s]:a}),t(`${s.slice(0,-1)} removed`,"success"),await r()}catch(n){t(`Failed to update settings: ${n instanceof Error?n.message:String(n)}`,"error")}},u=(s,i,a)=>!c||c[a].length===0?null:e.jsxs("div",{className:"pi-ext-section",children:[e.jsxs("div",{className:"pi-ext-section-header",children:[e.jsx(i,{size:14}),e.jsx("span",{children:s}),e.jsx("span",{className:"pi-ext-count",children:c[a].length})]}),e.jsx("div",{className:"pi-ext-resource-list",children:c[a].map((n,g)=>e.jsxs("span",{className:"pi-ext-resource-tag",children:[e.jsx("span",{className:"pi-ext-resource-path",children:n}),e.jsx("button",{className:"btn-icon touch-target pi-ext-resource-remove",onClick:()=>H(a,n),title:`Remove ${n}`,"aria-label":`Remove ${n}`,children:e.jsx(ie,{})})]},g))})]});return e.jsxs("div",{className:"pi-ext-manager",children:[e.jsxs("div",{className:"pi-ext-manager-header",children:[e.jsx("h4",{className:"pi-ext-manager-title",children:"Pi Extensions"}),e.jsx("div",{className:"pi-ext-manager-actions",children:e.jsx("button",{className:"btn-icon",onClick:r,title:"Refresh",disabled:f,children:e.jsx($,{size:16,className:f?"spin":""})})})]}),f?e.jsx("div",{className:"loading-state",children:"Loading Pi settings…"}):c?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"pi-ext-add-form",children:[e.jsxs("div",{className:"pi-ext-add-form-row",children:[e.jsx("input",{type:"text",className:"input",placeholder:"npm:pi-extension-name or git:https://github.com/...",value:h,onChange:s=>F(s.target.value),onKeyDown:s=>{s.key==="Enter"&&(s.preventDefault(),z())},disabled:N}),e.jsxs("button",{className:"btn btn-primary",onClick:z,disabled:N||!h.trim(),children:[e.jsx(Z,{size:14}),N?"Installing…":"Add"]})]}),e.jsx("div",{className:"pi-ext-add-form-row",children:e.jsx("button",{className:"btn",onClick:U,disabled:S,children:S?"Reinstalling Fusion…":"Reinstall Fusion skill"})})]}),c.packages.length>0?e.jsx("div",{className:"pi-ext-package-list",children:c.packages.map((s,i)=>{const a=typeof s=="string"?s:s.source,n=re(a),g=oe(a),j=typeof s=="object"&&s!==null,v=j&&(s.extensions?.length??0)>0||(s.skills?.length??0)>0||(s.prompts?.length??0)>0||(s.themes?.length??0)>0,k=G.has(i);return e.jsxs("div",{className:"pi-ext-package-card",children:[e.jsxs("div",{className:"pi-ext-package-header",children:[j&&v?e.jsx("button",{className:"pi-ext-expand-btn",onClick:()=>K(i),"aria-expanded":k,children:k?e.jsx(T,{size:14}):e.jsx(ee,{size:14})}):e.jsx("span",{className:"pi-ext-expand-placeholder"}),e.jsx("span",{className:`pi-ext-source-badge pi-ext-source-badge--${n}`,children:n}),e.jsx("span",{className:"pi-ext-package-source",children:g}),e.jsxs("div",{className:"pi-ext-package-actions",children:[j&&v&&e.jsxs("span",{className:"pi-ext-filter-hint",children:[s.extensions?.length??0," ext,"," ",s.skills?.length??0," skill,"," ",s.prompts?.length??0," prompt,"," ",s.themes?.length??0," theme"]}),e.jsx("button",{className:"btn-icon touch-target pi-ext-remove-btn",onClick:()=>X(a),title:"Remove package","aria-label":`Remove package ${g}`,children:e.jsx(se,{size:14})})]})]}),j&&v&&k&&e.jsxs("div",{className:"pi-ext-filter-list",children:[s.extensions?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(L,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Extensions:"}),s.extensions.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.skills?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(D,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Skills:"}),s.skills.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.prompts?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(A,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Prompts:"}),s.prompts.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.themes?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(W,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Themes:"}),s.themes.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null]})]},i)})}):e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"No packages configured."}),e.jsx("p",{className:"text-muted",children:"Add a package source above to get started."})]}),e.jsxs("div",{className:"pi-ext-top-level",children:[u("Extensions",L,"extensions"),u("Skills",D,"skills"),u("Prompts",A,"prompts"),u("Themes",W,"themes")]})]}):e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"Failed to load Pi settings."})]}),e.jsxs("div",{className:"pi-ext-discovered-section",children:[e.jsxs("div",{className:"pi-ext-discovered-header",children:[e.jsx("h4",{children:"Discovered Extensions"}),e.jsx("button",{className:"btn-icon",onClick:m,disabled:b,title:"Refresh extensions",children:e.jsx($,{className:b?"spin":""})})]}),e.jsx("p",{className:"pi-ext-description",children:"Installed extensions resolved from packages and configured paths."}),b?e.jsx("div",{className:"loading-state",children:"Loading extensions…"}):p.length===0?e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"No extensions discovered."})]}):e.jsx("div",{className:"pi-ext-list",children:p.map(s=>e.jsxs("div",{className:"pi-ext-item",children:[e.jsxs("div",{className:"pi-ext-item-content",children:[e.jsxs("div",{className:"pi-ext-info",children:[e.jsx("span",{className:"pi-ext-name",children:s.name}),e.jsx("span",{className:`pi-ext-source-badge pi-ext-source-badge--${le(s.source)}`,children:ce(s.source)})]}),e.jsx("span",{className:"pi-ext-path",children:s.path})]}),e.jsx("div",{className:"pi-ext-actions",children:e.jsxs("label",{className:"toggle-switch",children:[e.jsx("input",{type:"checkbox",checked:s.enabled,onChange:()=>void q(s),disabled:_,"aria-label":`Toggle ${s.name}`}),e.jsx("span",{className:"toggle-slider"})]})})]},s.id))})]})]})}export{pe as PiExtensionsManager};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as g,j as e}from"./vendor-react-K0fH_qHe.js";import{v as fe,ei as ye,ej as Y,s as je,X as Z,at as Ne,aR as Se,I as T,aY as ee,W as se,R as ve,ek as we,ap as Ce,el as Ie,em as $e,cu as Pe,en as Re,eo as ke,ep as Ee,eq as Be,er as te,cr as Le,es as Ae}from"./index-bEwSVl7B.js";import{D as Fe}from"./DirectoryPicker-DvBviDG6.js";import"./vendor-xterm-DzcZoU0P.js";import"./folder-open-CHSlllzf.js";const ie="fusion-plugin-agent-browser",ne={enabled:{type:"boolean",label:"Enable Agent Browser",group:"General"},installChannel:{type:"enum",label:"Install Channel",enumValues:["stable","beta","nightly"],defaultValue:"stable",group:"General"},commandTimeoutMs:{type:"number",label:"Command Timeout (ms)",defaultValue:12e4,group:"General"},headlessMode:{type:"boolean",label:"Headless Mode",defaultValue:!0,group:"Browser"},allowedDomains:{type:"array",label:"Allowed Domains",itemType:"string",group:"Browser"},promptExecutorSystem:{type:"string",label:"Executor System Prompt",multiline:!0,group:"Prompt Contributions"},promptExecutorTask:{type:"string",label:"Executor Task Prompt",multiline:!0,group:"Prompt Contributions"},promptTriage:{type:"string",label:"Triage Prompt",multiline:!0,group:"Prompt Contributions"},promptReviewer:{type:"string",label:"Reviewer Prompt",multiline:!0,group:"Prompt Contributions"},promptHeartbeat:{type:"string",label:"Heartbeat Prompt",multiline:!0,group:"Prompt Contributions"},skillExposure:{type:"enum",label:"Skill Exposure",enumValues:["none","selected","all"],defaultValue:"selected",group:"Skills"}},ae=[{id:"fusion-plugin-hermes-runtime",name:"Hermes Runtime",description:"Runtime provider for Hermes CLI-backed execution.",category:"runtime",path:"./plugins/fusion-plugin-hermes-runtime",experimental:!0},{id:"fusion-plugin-paperclip-runtime",name:"Paperclip Runtime",description:"Runtime provider for Paperclip agent connections.",category:"runtime",path:"./plugins/fusion-plugin-paperclip-runtime"},{id:"fusion-plugin-openclaw-runtime",name:"OpenClaw Runtime",description:"Runtime provider for OpenClaw execution.",category:"runtime",path:"./plugins/fusion-plugin-openclaw-runtime",experimental:!0},{id:"fusion-plugin-droid-runtime",name:"Droid Runtime",description:"Runtime provider for Droid CLI execution.",category:"runtime",path:"./plugins/fusion-plugin-droid-runtime",experimental:!0},{id:"fusion-plugin-dependency-graph",name:"Dependency Graph",description:"Dashboard plugin for task dependency graph visualization.",category:"integration",path:"./plugins/fusion-plugin-dependency-graph"},{id:"fusion-plugin-reports",name:"Reports",description:"View report history, compare runs side-by-side, and export standalone HTML summaries.",category:"integration",path:"./plugins/fusion-plugin-reports"},{id:"fusion-plugin-whatsapp-chat",name:"WhatsApp Chat",description:"Pairs to WhatsApp Web (multi-device) with QR or pairing code, then bridges direct chats to a Fusion agent.",category:"integration",path:"./plugins/fusion-plugin-whatsapp-chat"},{id:"fusion-plugin-cli-printing-press",name:"CLI Printing Press",description:"Guided wizard for drafting external service CLI definitions.",category:"integration",path:"./plugins/fusion-plugin-cli-printing-press"},{id:ie,name:"Agent Browser",description:"Built-in integration metadata. Package install support lands in FN-3101.",category:"integration",hasSetup:!0}],I={started:"var(--color-success)",loaded:"var(--color-warning)",error:"var(--color-error)",stopped:"var(--color-muted)",installed:"var(--color-info)"};function De(r){const o=r.settingsSchema,h=o&&Object.keys(o).length>0;return r.id!==ie?h?o:void 0:h?{...ne,...o}:ne}function ze(r){const o=new Map,h=[];for(const[x,f]of Object.entries(r))if(f.group){const N=o.get(f.group)??[];N.push([x,f]),o.set(f.group,N)}else h.push([x,f]);return{grouped:o,ungrouped:h}}function _e({addToast:r,projectId:o}){const[h,x]=g.useState([]),[f,N]=g.useState(!0),[le,$]=g.useState(!1),[w,P]=g.useState(""),[B,L]=g.useState(!1),[A,F]=g.useState(!1),[S,D]=g.useState(null),[l,R]=g.useState(null),[p,b]=g.useState({}),[re,z]=g.useState(!1),[O,G]=g.useState(null),[ce,k]=g.useState({}),[oe,U]=g.useState(null),[C,q]=g.useState(null),{confirm:ue}=fe(),m=g.useCallback(async()=>{try{N(!0);const s=await ye(o);x(s)}catch(s){r(`Failed to load plugins: ${s instanceof Error?s.message:String(s)}`,"error")}finally{N(!1)}},[o,r]);g.useEffect(()=>{m()},[m]),g.useEffect(()=>{const s=ae.filter(c=>c.hasSetup&&h.some(i=>i.id===c.id));if(s.length===0)return;let n=!1;return Promise.all(s.map(async c=>{try{const i=await Y(c.id,o);if(n)return;k(u=>({...u,[c.id]:i}))}catch{if(n)return;k(i=>({...i,[c.id]:{hasSetup:!0,setupCheckDeferred:!0,deferredReason:"plugin-not-started",pluginState:"installed"}}))}})),()=>{n=!0}},[h,o]);const de=g.useRef([]);de.current=h,g.useEffect(()=>{const s=o?`?projectId=${encodeURIComponent(o)}`:"",n=c=>{try{const i=JSON.parse(c.data);if(i.scope==="project"&&(i.projectId??o)!==o)return;switch(i.transition){case"installing":case"enabled":case"disabled":case"settings-updated":x(u=>{const a=u.findIndex(t=>t.id===i.pluginId);if(a>=0){const t=[...u];return t[a]={...t[a],enabled:i.enabled,state:i.state,settings:i.settings,error:i.error},t}else return m(),u});break;case"state-changed":x(u=>{const a=u.findIndex(t=>t.id===i.pluginId);if(a>=0){const t=[...u];return t[a]={...t[a],state:i.state,error:i.error},t}return u});break;case"uninstalled":x(u=>u.filter(a=>a.id!==i.pluginId));break;case"error":x(u=>{const a=u.findIndex(t=>t.id===i.pluginId);if(a>=0){const t=[...u];return t[a]={...t[a],state:i.state,error:i.error},t}return u});break}}catch{}};return je(`/api/events${s}`,{events:{"plugin:lifecycle":n},onReconnect:()=>{m()}})},[o,m]);const M=async()=>{if(!w.trim()){r("Please enter a plugin path","error");return}try{L(!0),await te({path:w,...A?{aiScanOnLoad:!0}:{}},o),r("Plugin installed globally","success"),$(!1),P(""),F(!1),await m()}catch(s){r(`Failed to install plugin: ${s instanceof Error?s.message:String(s)}`,"error")}finally{L(!1)}},pe=async s=>{if(!s.path){r(`${s.name} is built in and does not have an installable package yet`,"warning");return}try{G(s.id),await te({path:s.path},o),r(`${s.name} installed globally`,"success"),await m()}catch(n){r(`Failed to install ${s.name}: ${n instanceof Error?n.message:String(n)}`,"error")}finally{G(null)}},V=async s=>{try{q(s.id);const n=await Ae(s.id,o);if(!n.success){r(`Failed to install ${s.name} setup: ${n.error??"unknown error"}`,"error");return}r(`${s.name} setup installed`,"success"),U(s.id);const c=await Y(s.id,o);k(i=>({...i,[s.id]:c}))}catch(n){r(`Failed to install ${s.name} setup: ${n instanceof Error?n.message:String(n)}`,"error")}finally{q(null),U(null)}},_=async s=>{try{const n=await Ee(s.id,o);if(n.state==="error"){r(`Failed to enable ${s.name}: ${n.error??"Unknown error"}`,"error"),await m();return}r(`${s.name} enabled for this project`,"success"),await m()}catch(n){r(`Failed to enable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},H=async s=>{try{await ke(s.id,o),r(`${s.name} disabled for this project`,"success"),await m()}catch(n){r(`Failed to disable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},W=async s=>{try{D(s.id),await Re(s.id,o),r(`${s.name} reloaded`,"success"),await m()}catch(n){r(`Failed to reload plugin: ${n instanceof Error?n.message:String(n)}`,"error")}finally{D(null)}},J=async s=>{if(await ue({title:"Uninstall Plugin Globally",message:`Are you sure you want to uninstall "${s.name}" globally (all projects)?`,danger:!0}))try{await Be(s.id,o),r(`${s.name} uninstalled globally`,"success"),await m(),R(null)}catch(c){r(`Failed to uninstall plugin: ${c instanceof Error?c.message:String(c)}`,"error")}},ge=async(s,n)=>{try{await Ie(s.id,{aiScanOnLoad:n},o),r(`AI scan on load ${n?"enabled":"disabled"}`,"success"),await m()}catch(c){r(`Failed to update plugin: ${c instanceof Error?c.message:String(c)}`,"error")}},me=async s=>{try{await $e(s.id,o),r(`${s.name} rescanned`,"success"),await m()}catch(n){r(`Failed to rescan plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},E=async s=>{R(s);try{z(!0);const n=await Le(s.id,o);b(n)}catch{b({})}finally{z(!1)}},he=async()=>{if(l)try{await Pe(l.id,p,o),r("Settings saved","success")}catch(s){r(`Failed to save settings: ${s instanceof Error?s.message:String(s)}`,"error")}};if(l)return e.jsxs("div",{className:"plugin-manager-detail","data-testid":"plugin-manager-detail",children:[e.jsxs("div",{className:"plugin-manager-detail-header",children:[e.jsx("button",{className:"btn-icon",onClick:()=>R(null),"aria-label":"Back to plugin list",children:e.jsx(Z,{size:16})}),e.jsxs("div",{className:"plugin-detail-title",children:[e.jsx("h4",{className:"plugin-detail-name",children:l.name}),e.jsx("span",{className:"plugin-state-badge",style:{color:I[l.state]||I.installed},children:l.state})]})]}),e.jsxs("div",{className:"plugin-detail-content",children:[e.jsxs("div",{className:"plugin-detail-card",children:[l.description&&e.jsx("p",{className:"plugin-description",children:l.description}),l.author&&e.jsxs("p",{className:"plugin-detail-meta-row",children:[e.jsx("span",{className:"text-muted",children:"Author:"}),l.author]}),l.homepage&&e.jsxs("p",{className:"plugin-detail-meta-row plugin-homepage",children:[e.jsx("span",{className:"text-muted",children:"Homepage:"}),e.jsxs("a",{href:l.homepage,target:"_blank",rel:"noopener noreferrer",children:[l.homepage,e.jsx(Ne,{size:12})]})]}),e.jsxs("p",{className:"plugin-detail-meta-row",children:[e.jsx("span",{className:"text-muted",children:"Version:"}),l.version]})]}),e.jsxs("div",{className:"plugin-detail-card",children:[e.jsx("h5",{className:"plugin-detail-section-heading",children:"Security Scan"}),e.jsxs("div",{className:"plugin-security-row",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:!!l.aiScanOnLoad,onChange:s=>void ge(l,s.target.checked)}),"Enable AI scan before load/reload"]}),e.jsxs("button",{className:"btn btn-secondary btn-sm",onClick:()=>void me(l),children:[e.jsx(Se,{size:14})," Rescan and Reload"]})]}),e.jsx("p",{className:"text-muted",children:"Turning this on only updates configuration. Use Rescan and Reload to run it now."}),l.lastSecurityScan?e.jsxs("div",{className:"plugin-security-results",children:[e.jsxs("div",{className:"plugin-security-header",children:[e.jsx("span",{className:`plugin-state-badge plugin-security-badge plugin-security-badge--${l.lastSecurityScan.verdict}`,children:l.lastSecurityScan.verdict}),e.jsx("span",{className:"text-muted",children:l.lastSecurityScan.scannedAt})]}),e.jsx("p",{className:"plugin-security-summary",children:l.lastSecurityScan.summary}),e.jsxs("details",{children:[e.jsxs("summary",{children:["Findings (",l.lastSecurityScan.findings.length,")"]}),e.jsx("ul",{className:"plugin-security-findings",children:l.lastSecurityScan.findings.map((s,n)=>e.jsxs("li",{children:[e.jsx("strong",{children:s.severity})," ",s.category," — ",s.file,": ",s.reason]},`${s.file}-${n}`))})]})]}):e.jsx("p",{className:"text-muted",children:"No security scan has been run yet."})]}),e.jsxs("div",{className:"plugin-detail-card",children:[e.jsx("h5",{className:"plugin-detail-section-heading",children:"Settings"}),re?e.jsx("p",{className:"text-muted",children:"Loading..."}):(()=>{const s=De(l);return s&&Object.keys(s).length>0?e.jsxs("div",{className:"plugin-settings-form",children:[(()=>{const{grouped:n,ungrouped:c}=ze(s),i=[];c.length>0&&i.push({title:null,entries:c});for(const[u,a]of n.entries())i.push({title:u,entries:a});return i.map(u=>e.jsxs("div",{className:u.title?"plugin-settings-group":void 0,children:[u.title&&e.jsx("h6",{className:"plugin-settings-group-heading",children:u.title}),u.entries.map(([a,t])=>{const y=`setting-${a}-help`;return e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:`setting-${a}`,children:[t.label||a,t.required&&" *"]}),t.type==="string"&&!t.multiline&&e.jsx("input",{className:"input",type:"text",id:`setting-${a}`,value:p[a]??"",onChange:d=>b({...p,[a]:d.target.value}),placeholder:t.description,"aria-describedby":t.description&&!t.required?y:void 0}),t.type==="string"&&t.multiline&&e.jsx("textarea",{className:"input",id:`setting-${a}`,rows:4,value:p[a]??"",onChange:d=>b({...p,[a]:d.target.value}),placeholder:t.description,"aria-describedby":t.description&&!t.required?y:void 0}),t.type==="password"&&e.jsx("input",{className:"input",type:"password",id:`setting-${a}`,value:p[a]??"",onChange:d=>b({...p,[a]:d.target.value}),placeholder:t.description,"aria-describedby":t.description&&!t.required?y:void 0}),t.type==="number"&&e.jsx("input",{className:"input",type:"number",id:`setting-${a}`,value:p[a]??"",onChange:d=>b({...p,[a]:Number(d.target.value)}),"aria-describedby":t.description&&!t.required?y:void 0}),t.type==="boolean"&&e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:p[a]??!1,onChange:d=>b({...p,[a]:d.target.checked})}),t.description]}),t.type==="enum"&&e.jsxs("select",{className:"select",id:`setting-${a}`,value:p[a]??"",onChange:d=>b({...p,[a]:d.target.value}),"aria-describedby":t.description&&!t.required?y:void 0,children:[e.jsx("option",{value:"",children:"Select..."}),t.enumValues?.map(d=>e.jsx("option",{value:d,children:d},d))]}),t.type==="array"&&e.jsxs("div",{className:"plugin-settings-array",children:[p[a]?.map((d,j)=>e.jsxs("div",{className:"plugin-settings-array-item",children:[e.jsx("input",{className:"input",type:t.itemType==="number"?"number":"text",value:d??"",onChange:Q=>{const v=Q.target.value,X=[...p[a]||[]];X[j]=t.itemType==="number"?Number(v):v,b({...p,[a]:X})}}),e.jsx("button",{className:"btn-icon",onClick:()=>{const v=[...p[a]||[]];v.splice(j,1),b({...p,[a]:v})},"aria-label":"Remove item",children:e.jsx(Z,{size:14})})]},j)),e.jsxs("button",{className:"btn btn-secondary",onClick:()=>{const d=p[a]||[],j=t.itemType==="number"?0:"";b({...p,[a]:[...d,j]})},children:[e.jsx(T,{size:14})," Add Item"]})]}),t.description&&!t.required&&!t.multiline&&e.jsx("span",{id:y,className:"form-help",children:t.description})]},a)})]},u.title??"ungrouped"))})(),e.jsx("button",{className:"btn btn-primary",onClick:he,children:"Save Settings"})]}):e.jsx("p",{className:"text-muted",children:"No configurable settings."})})()]}),e.jsxs("div",{className:"plugin-detail-actions",children:[l.state==="started"&&e.jsxs("button",{className:"btn btn-secondary",onClick:()=>W(l),disabled:S===l.id,children:[e.jsx(ee,{size:14,className:S===l.id?"spin":""}),S===l.id?"Reloading...":"Reload"]}),l.enabled?e.jsx("button",{className:"btn btn-secondary",onClick:()=>H(l),children:"Disable in Project"}):e.jsx("button",{className:"btn btn-primary",onClick:()=>_(l),children:"Enable in Project"}),e.jsxs("button",{className:"btn btn-danger",onClick:()=>J(l),children:[e.jsx(se,{size:14})," Uninstall Globally"]})]})]})]});const be=new Map(h.map(s=>[s.id,s])),K=h,xe=()=>e.jsxs("section",{className:"plugin-builtins-section","aria-label":"Built-in Plugins",children:[e.jsxs("div",{className:"plugin-builtins-header",children:[e.jsx("h4",{className:"plugin-builtins-heading",children:"Built-in Plugins"}),e.jsx("p",{className:"plugin-builtins-description",children:"Built-in plugin catalog for runtimes and integrations."})]}),e.jsx("div",{className:"plugin-builtins-list","aria-label":"Built-in plugin recommendations",children:ae.map(s=>{const n=be.get(s.id),c=!!n,i=ce[s.id],u=!!(i&&"setupCheckDeferred"in i&&i.setupCheckDeferred),a=i&&"status"in i?i.status:void 0,t=c&&s.hasSetup&&i?.hasSetup&&!u&&n?.state==="started"&&(a==="not-installed"||a==="error"),y=c&&i?.hasSetup&&a==="installed",d=oe===s.id,j=!s.path;return e.jsxs("div",{className:"plugin-builtins-item",children:[e.jsxs("div",{className:"plugin-builtins-meta",children:[e.jsx("span",{className:"plugin-builtins-name",children:s.name}),s.experimental&&e.jsx("span",{className:"plugin-builtins-runtime-badge",children:"Experimental"}),e.jsx("span",{className:"plugin-builtins-runtime-badge",children:s.category}),e.jsx("span",{className:`plugin-builtins-status ${c?"plugin-builtins-status--installed":"plugin-builtins-status--available"}`,children:c?"Installed":j?"Built in":"Not installed"}),t&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--warning",children:"Setup required"}),y&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--ready",children:"Setup ready"}),d&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--pending",children:"Checking setup..."}),u&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--deferred",children:"Start plugin to check setup"}),e.jsx("span",{className:"plugin-builtins-description-text",children:s.description})]}),j?c&&t?e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>void V(s),disabled:C===s.id||d,children:C===s.id?"Setting up...":"Install Setup"}):c&&n?e.jsx("button",{className:"btn btn-secondary btn-sm",onClick:()=>void E(n),children:"Manage"}):e.jsx("span",{className:"plugin-builtins-metadata-only",children:"Built-in metadata only"}):e.jsx("button",{className:`btn ${c&&!t?"btn-secondary":"btn-primary"} btn-sm`,onClick:()=>{if(!c){pe(s);return}if(t){V(s);return}n&&E(n)},disabled:O===s.id||C===s.id||d,children:c?t?C===s.id?"Setting up...":"Install Setup":"Manage":O===s.id?"Installing...":`Install ${s.name}`})]},s.id)})})]});return e.jsxs("div",{className:"plugin-manager","data-testid":"plugin-manager",children:[e.jsxs("div",{className:"plugin-manager-header",children:[e.jsx("span",{className:"plugin-manager-header-title",children:"Installed Plugins"}),e.jsxs("div",{className:"plugin-manager-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:m,title:"Refresh","aria-label":"Refresh plugin list",children:[e.jsx(ve,{size:14,className:f?"spin":""}),"Refresh"]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>$(!0),children:[e.jsx(T,{size:14})," Install"]})]})]}),le&&e.jsxs("div",{className:"plugin-install-form",children:[e.jsxs("p",{className:"plugin-install-hint",children:["Browse to a plugin package root (contains ",e.jsx("code",{children:"manifest.json"}),") or a built ",e.jsx("code",{children:"dist"})," directory."]}),e.jsx(Fe,{value:w,onChange:P,placeholder:"Absolute path to plugin directory or dist folder",onInputKeyDown:s=>{s.key==="Enter"&&(s.preventDefault(),M())}}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:A,onChange:s=>F(s.target.checked)}),"Enable AI security scan on load"]}),e.jsxs("div",{className:"plugin-install-actions",children:[e.jsx("button",{className:"btn btn-primary",onClick:M,disabled:B||!w.trim(),children:B?"Installing...":"Install Plugin Globally"}),e.jsx("button",{className:"btn btn-secondary",onClick:()=>{$(!1),P("")},children:"Cancel"})]})]}),f?e.jsx("div",{className:"settings-empty-state",children:"Loading plugins..."}):e.jsxs(e.Fragment,{children:[K.length===0?e.jsxs("div",{className:"settings-empty-state",children:[e.jsx(we,{size:32,className:"text-muted"}),e.jsx("p",{children:"No plugins installed."}),e.jsx("p",{className:"text-muted",children:"Install a plugin to get started, or use the built-in catalog below."})]}):e.jsx("div",{className:"plugin-list",children:K.map(s=>e.jsxs("div",{className:"plugin-item",children:[e.jsxs("div",{className:"plugin-info",children:[e.jsx("span",{className:"plugin-name",children:s.name}),e.jsxs("span",{className:"plugin-version text-muted",children:["v",s.version]}),e.jsx("span",{className:"plugin-state-badge",style:{color:I[s.state]||I.installed},children:s.state})]}),e.jsxs("div",{className:"plugin-actions",children:[s.state==="started"&&e.jsx("button",{className:"btn-icon",onClick:()=>W(s),disabled:S===s.id,title:"Reload",children:e.jsx(ee,{size:14,className:S===s.id?"spin":""})}),e.jsxs("label",{className:"toggle-switch",children:[e.jsx("input",{type:"checkbox",checked:s.enabled,onChange:()=>s.enabled?H(s):_(s),"aria-label":`${s.enabled?"Disable":"Enable"} ${s.name}`}),e.jsx("span",{className:"toggle-slider"})]}),e.jsx("button",{className:"btn-icon",onClick:()=>E(s),title:"Settings",children:e.jsx(Ce,{size:14})}),e.jsx("button",{className:"btn-icon",onClick:()=>J(s),title:"Uninstall globally",children:e.jsx(se,{size:14})})]})]},s.id))}),xe()]})]})}export{ne as AGENT_BROWSER_SETTINGS_SCHEMA,ie as BUILTIN_AGENT_BROWSER_PLUGIN_ID,_e as PluginManager,I as STATE_COLORS};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.research-task-action-modal__body{display:flex;flex-direction:column;gap:var(--space-md)}.research-task-action-modal__preview{display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-md)}.research-task-action-modal__preview p{margin:0}.research-task-action-modal__field{display:flex;flex-direction:column;gap:var(--space-xs);color:var(--text-muted);text-transform:uppercase}.research-task-action-modal__textarea{min-height:calc(var(--space-2xl) * 2);resize:vertical}@media(max-width:768px){.research-task-action-modal{width:min(100%,calc(100vw - (var(--space-md) * 2)))}.research-task-action-modal__body{gap:var(--space-lg)}.research-task-action-modal__preview{padding:var(--space-lg)}.research-task-action-modal .modal-actions{flex-direction:column;align-items:stretch;gap:var(--space-sm)}.research-task-action-modal .modal-actions .btn{min-height:calc(var(--space-lg) * 2 + var(--space-xs))}}.research-view{display:flex;flex-direction:column;gap:var(--space-md);height:100%;min-height:0;padding:var(--space-lg);padding-bottom:var(--space-lg)}.research-view__header{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-md)}.research-view__title{margin:0}.research-view__subtitle{margin:var(--space-xs) 0 0;color:var(--text-muted)}.research-view__layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2fr);gap:var(--space-md);min-height:0;flex:1}.research-view__sidebar,.research-view__reader{padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-md);min-height:0}.research-view__form{display:flex;flex-direction:column;gap:var(--space-sm)}.research-view__form .form-group,.research-view__history-header.form-group,.research-view__actions .form-group{margin:0;padding:0}.research-view__textarea{min-height:calc(var(--space-2xl) * 3);resize:vertical}.research-view__providers{display:grid;gap:var(--space-xs)}.research-view__history-header{display:flex;flex-direction:column;align-items:stretch;gap:var(--space-xs)}.research-view__history-search-row{display:flex;align-items:center;gap:var(--space-xs)}.research-view__history-search-row .input{flex:1;min-width:0}.research-view__history{display:flex;flex-direction:column;gap:var(--space-xs);flex:1;min-height:0;overflow:auto}.research-view__history-item{text-align:left;padding:var(--space-sm);min-height:calc(var(--space-lg) * 2 + var(--space-xs));display:flex;flex-direction:column;justify-content:center;gap:var(--space-xs);cursor:pointer}.research-view__history-item--active{border-color:var(--todo);box-shadow:var(--focus-ring)}.research-view__status-row{display:flex;align-items:center;gap:var(--space-xs);text-transform:capitalize}.research-view__run-title,.research-view__run-query,.research-view__run-summary{margin:0}.research-view__run-query{color:var(--text-muted)}.research-view__actions{display:flex;flex-wrap:wrap;gap:var(--space-xs);margin-top:var(--space-sm)}.research-view__citations{margin:var(--space-sm) 0 0;padding-left:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-xs)}.research-view__citations a{color:var(--text)}.research-view__error{color:var(--color-error)}.research-view__findings{display:flex;flex-direction:column;gap:var(--space-sm)}.research-view__finding{padding:var(--space-sm)}.research-view__finding h4,.research-view__finding p{margin:0}.research-view__finding-actions{margin-top:var(--space-sm)}.research-view__events{margin:var(--space-sm) 0 0;padding-left:var(--space-lg)}.research-view__stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-sm)}.research-view__stat-card{border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-sm);padding:var(--space-sm);background:var(--surface)}.research-view__stat-label{color:var(--text-muted);text-transform:uppercase}.research-view__stat-value{font-family:var(--font-mono)}.research-view__state--error{border-color:var(--color-error)}@media(max-width:768px){.research-view{padding:var(--space-md);padding-bottom:calc(var(--space-md) + var(--mobile-nav-height) + env(safe-area-inset-bottom,0px) + var(--standalone-bottom-gap))}.research-view__layout{grid-template-columns:minmax(0,1fr)}.research-view__header{flex-direction:column}.research-view__stats{grid-template-columns:minmax(0,1fr)}.research-view__history-item{min-height:calc(var(--space-lg) * 2 + var(--space-sm))}}
|
|
1
|
+
.research-task-action-modal__body{display:flex;flex-direction:column;gap:var(--space-md)}.research-task-action-modal__preview{display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-md)}.research-task-action-modal__preview p{margin:0}.research-task-action-modal__field{display:flex;flex-direction:column;gap:var(--space-xs);color:var(--text-muted);text-transform:uppercase}.research-task-action-modal__textarea{min-height:calc(var(--space-2xl) * 2);resize:vertical}@media(max-width:768px){.research-task-action-modal{width:min(100%,calc(100vw - (var(--space-md) * 2)))}.research-task-action-modal__body{gap:var(--space-lg)}.research-task-action-modal__preview{padding:var(--space-lg)}.research-task-action-modal .modal-actions{flex-direction:column;align-items:stretch;gap:var(--space-sm)}.research-task-action-modal .modal-actions .btn{min-height:calc(var(--space-lg) * 2 + var(--space-xs))}}.research-view{display:flex;flex-direction:column;gap:var(--space-md);height:100%;min-height:0;padding:var(--space-lg);padding-bottom:var(--space-lg)}.research-view__header{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-md)}.research-view__title{margin:0}.research-view__subtitle{margin:var(--space-xs) 0 0;color:var(--text-muted)}.research-view__layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2fr);gap:var(--space-md);min-height:0;flex:1}.research-view__sidebar,.research-view__reader{padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-md);min-height:0}.research-view__form{display:flex;flex-direction:column;gap:var(--space-sm)}.research-view__form .form-group,.research-view__history-header.form-group,.research-view__actions .form-group{margin:0;padding:0}.research-view__textarea{min-height:calc(var(--space-2xl) * 3);resize:vertical}.research-view__providers{display:grid;gap:var(--space-xs)}.research-view__history-header{display:flex;flex-direction:column;align-items:stretch;gap:var(--space-xs)}.research-view__history-search-row{display:flex;align-items:center;gap:var(--space-xs)}.research-view__history-search-row .input{flex:1;min-width:0}.research-view__history{display:flex;flex-direction:column;gap:var(--space-xs);flex:1;min-height:0;overflow:auto}.research-view__history-item{text-align:left;padding:var(--space-sm);min-height:calc(var(--space-lg) * 2 + var(--space-xs));display:flex;flex-direction:column;justify-content:center;gap:var(--space-xs);cursor:pointer}.research-view__history-item--active{border-color:var(--todo);box-shadow:var(--focus-ring)}.research-view__status-row{display:flex;align-items:center;gap:var(--space-xs);text-transform:capitalize}.research-view__run-title,.research-view__run-query,.research-view__run-summary{margin:0}.research-view__run-query{color:var(--text-muted)}.research-view__actions{display:flex;flex-wrap:wrap;gap:var(--space-xs);margin-top:var(--space-sm)}.research-view__citations{margin:var(--space-sm) 0 0;padding-left:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-xs)}.research-view__citations a{color:var(--text)}.research-view__error{color:var(--color-error)}.research-view__findings{display:flex;flex-direction:column;gap:var(--space-sm)}.research-view__finding{padding:var(--space-sm)}.research-view__finding h4,.research-view__finding p{margin:0}.research-view__finding-actions{margin-top:var(--space-sm)}.research-view__events{margin:var(--space-sm) 0 0;padding-left:var(--space-lg)}.research-view__stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-sm)}.research-view__stat-card{border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-sm);padding:var(--space-sm);background:var(--surface)}.research-view__stat-label{color:var(--text-muted);text-transform:uppercase}.research-view__stat-value{font-family:var(--font-mono)}.research-view__state--error{border-color:var(--color-error)}@media(max-width:768px){.research-view{overflow-y:auto;-webkit-overflow-scrolling:touch;padding:var(--space-md);padding-bottom:calc(var(--space-md) + var(--mobile-nav-height) + env(safe-area-inset-bottom,0px) + var(--standalone-bottom-gap))}.research-view__layout{display:flex;flex-direction:column;grid-template-columns:minmax(0,1fr);flex:initial}.research-view__history{flex:initial;min-height:initial;overflow:visible}.research-view__header{flex-direction:column}.research-view__stats{grid-template-columns:minmax(0,1fr)}.research-view__history-item{min-height:calc(var(--space-lg) * 2 + var(--space-sm))}}
|