@runfusion/fusion 0.36.0 → 0.38.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.
Files changed (61) hide show
  1. package/dist/bin.js +1599 -174
  2. package/dist/client/.vite/manifest.json +66 -66
  3. package/dist/client/assets/AgentDetailView-CquLtIia.js +18 -0
  4. package/dist/client/assets/{AgentPermissionPolicyEditor-BoD6come.js → AgentPermissionPolicyEditor-Dk-oEs1X.js} +1 -1
  5. package/dist/client/assets/AgentsView-BZVOpQ05.js +29 -0
  6. package/dist/client/assets/ChatView-CErtz86Y.js +6 -0
  7. package/dist/client/assets/{DevServerView-Dd613aZ5.js → DevServerView-BRA00XoT.js} +1 -1
  8. package/dist/client/assets/{DirectoryPicker-H-fUl2dF.js → DirectoryPicker-D496NTjZ.js} +1 -1
  9. package/dist/client/assets/{DocumentsView-Dshc9e5K.js → DocumentsView-DIRlgdeB.js} +1 -1
  10. package/dist/client/assets/{EvalsView-50W0K5h7.js → EvalsView-By5mtr80.js} +1 -1
  11. package/dist/client/assets/{ExperimentalAgentOnboardingModal-BXBljPFj.js → ExperimentalAgentOnboardingModal-Br57oNdX.js} +1 -1
  12. package/dist/client/assets/GoalsView-B65urz9k.css +1 -0
  13. package/dist/client/assets/GoalsView-COI14CWJ.js +1 -0
  14. package/dist/client/assets/{InsightsView-sVbGRKTl.js → InsightsView-Hm7vX2lr.js} +2 -2
  15. package/dist/client/assets/{MemoryView-006a_sB0.js → MemoryView-BLozyYur.js} +1 -1
  16. package/dist/client/assets/{NodesView-CiRPqgVx.js → NodesView-bXC6WoE2.js} +1 -1
  17. package/dist/client/assets/{PiExtensionsManager-Y1ETuTxf.js → PiExtensionsManager-DEiqcMkx.js} +2 -2
  18. package/dist/client/assets/{PluginManager-Df_KHiXn.js → PluginManager-l4224zxk.js} +1 -1
  19. package/dist/client/assets/{ResearchView-DU_QuS_-.js → ResearchView-CpsR1Q56.js} +1 -1
  20. package/dist/client/assets/{SecretsView-D61Jvysn.js → SecretsView-Bwme1zZI.js} +1 -1
  21. package/dist/client/assets/{SettingsModal-BarzmqNb.js → SettingsModal-32vUNWRe.js} +1 -1
  22. package/dist/client/assets/SettingsModal-D_uIvf6n.css +1 -0
  23. package/dist/client/assets/SettingsModal-DdrXxMPW.js +31 -0
  24. package/dist/client/assets/{SetupWizardModal-BF3iRNq9.js → SetupWizardModal-BFD9E0H_.js} +1 -1
  25. package/dist/client/assets/{SkillsView-tCKOFw3j.js → SkillsView-CZMLY7F_.js} +1 -1
  26. package/dist/client/assets/{StashRecoveryView-nGtypd10.js → StashRecoveryView-jgZeWbZo.js} +1 -1
  27. package/dist/client/assets/{TodoView-IyGPV6AO.js → TodoView-DXdnOymj.js} +2 -2
  28. package/dist/client/assets/{dashboard-view-DiA5-hnb.js → dashboard-view-H8SnaCPP.js} +2 -2
  29. package/dist/client/assets/{folder-open-Byqfi_N-.js → folder-open-Dh5_gv6L.js} +1 -1
  30. package/dist/client/assets/index-B9hAW3eU.css +1 -0
  31. package/dist/client/assets/index-w1dPHtmq.js +742 -0
  32. package/dist/client/assets/{upload-D6_BjqVi.js → upload-ntU2YHPl.js} +1 -1
  33. package/dist/client/assets/{users-CERYgInO.js → users-BWK61s9U.js} +1 -1
  34. package/dist/client/index.html +40 -3
  35. package/dist/client/version.json +1 -1
  36. package/dist/droid-cli/package.json +1 -1
  37. package/dist/extension.js +1449 -125
  38. package/dist/pi-claude-cli/package.json +1 -1
  39. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  40. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  41. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  42. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  43. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  44. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  45. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  46. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  47. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  48. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  49. package/package.json +1 -1
  50. package/skill/fusion/SKILL.md +1 -1
  51. package/skill/fusion/references/extension-tools.md +16 -0
  52. package/skill/fusion/references/fusion-capabilities.md +1 -0
  53. package/dist/client/assets/AgentDetailView-CGycokdR.js +0 -18
  54. package/dist/client/assets/AgentsView-B_afRRfc.js +0 -29
  55. package/dist/client/assets/ChatView-IjNrSZSf.js +0 -6
  56. package/dist/client/assets/GoalsView-Cg136Jcn.css +0 -1
  57. package/dist/client/assets/GoalsView-Dh508Z2s.js +0 -1
  58. package/dist/client/assets/SettingsModal-0gevFhXV.css +0 -1
  59. package/dist/client/assets/SettingsModal-Cpur3WpT.js +0 -31
  60. package/dist/client/assets/index-B9Ro_NwC.js +0 -742
  61. package/dist/client/assets/index-DVFBXjGT.css +0 -1
@@ -1,2 +1,2 @@
1
- import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{u as Le}from"./SettingsModal-BarzmqNb.js";import{bR as Ee,bS as ke,bT as Ie,y as Re,bU as qe,bV as _e,bW as Pe,bX as Me,bY as we,bZ as We,b_ as Te,b$ as Oe,c0 as Ae,c1 as $e,x as Ue,c2 as He,L as w,c3 as Fe}from"./index-B9Ro_NwC.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const T=".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===T)?.path??i[0]?.path??T}function Ve(i={}){const{projectId:t}=i,[m,u]=a.useState(""),[C,A]=a.useState(!0),[E,k]=a.useState(!1),[b,x]=a.useState(!1),[r,p]=a.useState(null),[O,K]=a.useState(!0),[J,L]=a.useState(!1),[S,P]=a.useState(()=>he({})),[F,ee]=a.useState(!0),[ue,$]=a.useState(!1),[o,v]=a.useState([]),[se,I]=a.useState(!0),[c,M]=a.useState(T),[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,V]=a.useState(!1),[le,G]=a.useState(null),{status:me,loading:Z,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);M(n),y(l),f(!1)}finally{te(!1)}},[t]),q=a.useCallback(async()=>{I(!0);try{const{files:n}=await ke(t);if(v(n),n.length===0){M(T),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),K(!1))}catch{n||(p(null),L(!1),K(!1))}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){ee(!0);try{const s=await Ue(t);n||P(he(s))}catch{n||P(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 ke(t);if(n)return;if(v(s),s.length===0){M(T),y(""),f(!1);return}const h=De(s,c),{content:g}=await Ee(h,t);if(n)return;M(h),y(g),f(!1)}catch{n||(v([]),M(T),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 Me(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||G(s)}catch{n||G(null)}}return l(),()=>{n=!0}},[t]);const ce=a.useCallback(n=>{u(n),k(!0)},[]),oe=a.useCallback(async()=>{if(E){x(!0);try{await Ie(m,t),k(!1)}finally{x(!1)}}},[m,E,t]),xe=a.useCallback(async n=>{$(!0);try{const l=await Re(n,t);P(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()=>{V(!0);try{const n=await _e(t);return await j(),n}finally{V(!1)}},[t,j]),Se=a.useCallback(async n=>Pe(n,t),[t]),X=a.useCallback(async()=>{try{const n=await Me(t);z(n)}catch{z(null)}},[t]),_=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 _()},[t,_]),ve=a.useCallback(async()=>{Q(!0);try{const n=await Te(t);return await Promise.all([_(),X()]),{success:n.success,summary:n.summary}}finally{Q(!1)}},[t,_,X]),Ne=a.useCallback(async()=>{re(!0);try{return await Oe(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;M(s),y(l.content),f(!1),await q();return}u(l.content),k(!0)}finally{B(!1)}},[t,q]);return{workingMemory:m,workingMemoryLoading:C,workingMemoryDirty:E,setWorkingMemory:ce,saveWorkingMemory:oe,savingWorkingMemory:b,insightsContent:r,insightsLoading:O,insightsExists:J,refreshInsights:_,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:Z,extractInsights:ve,extracting:ne,triggerDreamNow:Ne,dreamRunning:Y,auditReport:D,auditLoading:ye,refreshAudit:X,compactMemory:Ce,compacting:ge,installQmdAction:je,installingQmd:ie,testRetrieval:Se,stats:le}}const Ge={Patterns:"pattern",Principles:"principle",Conventions:"convention",Pitfalls:"pitfall",Context:"context"},Ze={"long-term":"Long-term",daily:"Daily",dreams:"Dreams"},Xe={"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."},Ke=72;function Je(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 Je(t,Ke)}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(),k=Ge[E]??E.toLowerCase(),b=C.slice(A[0].length).trim(),x=b.split(`
1
+ import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{u as Le}from"./SettingsModal-32vUNWRe.js";import{bS as Ee,bT as ke,bU as Ie,y as Re,bV as qe,bW as _e,bX as Pe,bY as Me,bZ as we,b_ as We,b$ as Te,c0 as Oe,c1 as Ae,c2 as $e,x as Ue,c3 as He,L as w,c4 as Fe}from"./index-w1dPHtmq.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const T=".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===T)?.path??i[0]?.path??T}function Ve(i={}){const{projectId:t}=i,[m,u]=a.useState(""),[C,A]=a.useState(!0),[E,k]=a.useState(!1),[b,x]=a.useState(!1),[r,p]=a.useState(null),[O,K]=a.useState(!0),[J,L]=a.useState(!1),[S,P]=a.useState(()=>he({})),[F,ee]=a.useState(!0),[ue,$]=a.useState(!1),[o,v]=a.useState([]),[se,I]=a.useState(!0),[c,M]=a.useState(T),[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,V]=a.useState(!1),[le,G]=a.useState(null),{status:me,loading:Z,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);M(n),y(l),f(!1)}finally{te(!1)}},[t]),q=a.useCallback(async()=>{I(!0);try{const{files:n}=await ke(t);if(v(n),n.length===0){M(T),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),K(!1))}catch{n||(p(null),L(!1),K(!1))}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){ee(!0);try{const s=await Ue(t);n||P(he(s))}catch{n||P(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 ke(t);if(n)return;if(v(s),s.length===0){M(T),y(""),f(!1);return}const h=De(s,c),{content:g}=await Ee(h,t);if(n)return;M(h),y(g),f(!1)}catch{n||(v([]),M(T),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 Me(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||G(s)}catch{n||G(null)}}return l(),()=>{n=!0}},[t]);const ce=a.useCallback(n=>{u(n),k(!0)},[]),oe=a.useCallback(async()=>{if(E){x(!0);try{await Ie(m,t),k(!1)}finally{x(!1)}}},[m,E,t]),xe=a.useCallback(async n=>{$(!0);try{const l=await Re(n,t);P(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()=>{V(!0);try{const n=await _e(t);return await j(),n}finally{V(!1)}},[t,j]),Se=a.useCallback(async n=>Pe(n,t),[t]),X=a.useCallback(async()=>{try{const n=await Me(t);z(n)}catch{z(null)}},[t]),_=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 _()},[t,_]),ve=a.useCallback(async()=>{Q(!0);try{const n=await Te(t);return await Promise.all([_(),X()]),{success:n.success,summary:n.summary}}finally{Q(!1)}},[t,_,X]),Ne=a.useCallback(async()=>{re(!0);try{return await Oe(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;M(s),y(l.content),f(!1),await q();return}u(l.content),k(!0)}finally{B(!1)}},[t,q]);return{workingMemory:m,workingMemoryLoading:C,workingMemoryDirty:E,setWorkingMemory:ce,saveWorkingMemory:oe,savingWorkingMemory:b,insightsContent:r,insightsLoading:O,insightsExists:J,refreshInsights:_,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:Z,extractInsights:ve,extracting:ne,triggerDreamNow:Ne,dreamRunning:Y,auditReport:D,auditLoading:ye,refreshAudit:X,compactMemory:Ce,compacting:ge,installQmdAction:je,installingQmd:ie,testRetrieval:Se,stats:le}}const Ge={Patterns:"pattern",Principles:"principle",Conventions:"convention",Pitfalls:"pitfall",Context:"context"},Ze={"long-term":"Long-term",daily:"Daily",dreams:"Dreams"},Xe={"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."},Ke=72;function Je(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 Je(t,Ke)}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(),k=Ge[E]??E.toLowerCase(),b=C.slice(A[0].length).trim(),x=b.split(`
2
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:k,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 ds({projectId:i,addToast:t}){const[m,u]=a.useState("working"),[C,A]=a.useState(new Set),[E,k]=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 * * *"}),[O,K]=a.useState(""),[J,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:M,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:V,reloadMemoryFiles:le,triggerDreamNow:G,dreamRunning:me}=Ve({projectId:i});a.useEffect(()=>{p(o)},[o]);const Z=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?Xe[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(!Z)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")}},[Z,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(O);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)}},[O,Q,t]),X=a.useCallback(async()=>{try{await G(),t("Dream processing completed","success"),await le()}catch(s){t(s instanceof Error?s.message:"Failed to run dream processing","error")}},[G,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),k(!1),x(null),t("Insights saved","success")}catch{t("Failed to save insights","error")}},[b,$,t]),Ne=a.useCallback(()=>{x(F??""),k(!0)},[F]),Ce=a.useCallback(()=>{k(!1),x(null)},[]),n=!M&&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:Ze[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:V,children:V?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:X,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."}),Z&&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:M||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:O,onChange:s=>K(s.target.value),placeholder:"Search memory with qmd"}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Se,disabled:J,children:J?"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{ds as MemoryView};
@@ -1,4 +1,4 @@
1
- import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{c as Ve,aR as os,aS as cs,aT as is,aU as ds,aV as De,aF as he,aW as ye,aX as Fe,aY as _e,aZ as Oe,A as Ke,aw as us,Q as Ue,a_ as Te,a$ as ms,_ as Ne,u as hs,R as ke,a as Me,J as fe,b0 as Be,b1 as fs,b2 as gs,b3 as ps,b4 as $e,X as me,ae as xs,af as js,b5 as Ie,F as bs,b6 as ze,b7 as vs,b8 as ys,b9 as _s,ba as Ns,bb as ks,G as Cs}from"./index-B9Ro_NwC.js";import{v as Ss}from"./projectDetection-G3XuxD2X.js";import{U as He}from"./upload-D6_BjqVi.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";/**
1
+ import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{c as Ve,aS as os,aT as cs,aU as is,aV as ds,aW as De,aG as he,aX as ye,aY as Fe,aZ as _e,a_ as Oe,A as Ke,ax as us,Q as Ue,a$ as Te,b0 as ms,_ as Ne,u as hs,R as ke,a as Me,J as fe,b1 as Be,b2 as fs,b3 as gs,b4 as ps,b5 as $e,X as me,ae as xs,af as js,b6 as Ie,F as bs,b7 as ze,b8 as vs,b9 as ys,ba as _s,bb as Ns,bc as ks,G as Cs}from"./index-w1dPHtmq.js";import{v as Ss}from"./projectDetection-G3XuxD2X.js";import{U as He}from"./upload-ntU2YHPl.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";/**
2
2
  * @license lucide-react v1.7.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,6 +1,6 @@
1
- import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{c as Y,eX as Z,eY as H,eZ as Q,R as $,eM as y,J as V,a as T,b as ee,_ as se,e_ as L,cT as D,F as _,e$ as ae,f0 as te,f1 as M,X as ie}from"./index-B9Ro_NwC.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";/**
1
+ import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{c as Z,eZ as H,e_ as Q,e$ as V,R as $,eO as y,J as Y,a as T,b as ee,_ as se,f0 as L,cU as D,F as _,f1 as ae,f2 as te,f3 as O,X as ie}from"./index-w1dPHtmq.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.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"}]],A=Y("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 he({addToast:t,projectId:x}){const[c,G]=l.useState(null),[f,P]=l.useState(!0),[N,S]=l.useState(!1),[E,w]=l.useState(!1),[h,F]=l.useState(""),[I,O]=l.useState(new Set),[p,W]=l.useState([]),[b,C]=l.useState(!0),[X,R]=l.useState(!1),r=l.useCallback(async()=>{try{P(!0);const s=await Z();G(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 H(x);W(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 Q(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 B=s=>{O(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{S(!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{S(!1)}},J=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)}},K=async s=>{if(!c)return;const i=c.packages.filter(a=>(typeof a=="string"?a:a.source)!==s);try{await M({packages:i}),t("Package removed","success"),await r()}catch(a){t(`Failed to remove package: ${a instanceof Error?a.message:String(a)}`,"error")}},U=async(s,i)=>{if(!c)return;const a=c[s].filter(n=>n!==i);try{await M({[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:()=>U(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(V,{size:14}),N?"Installing…":"Add"]})]}),e.jsx("div",{className:"pi-ext-add-form-row",children:e.jsx("button",{className:"btn",onClick:J,disabled:E,children:E?"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=I.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:()=>B(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:()=>K(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(_,{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(A,{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",_,"prompts"),u("Themes",A,"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:X,"aria-label":`Toggle ${s.name}`}),e.jsx("span",{className:"toggle-slider"})]})})]},s.id))})]})]})}export{he as PiExtensionsManager};
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"}]],A=Z("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 he({addToast:t,projectId:x}){const[c,G]=l.useState(null),[j,P]=l.useState(!0),[N,S]=l.useState(!1),[E,w]=l.useState(!1),[h,F]=l.useState(""),[I,M]=l.useState(new Set),[p,U]=l.useState([]),[b,C]=l.useState(!0),[W,R]=l.useState(!1),r=l.useCallback(async()=>{try{P(!0);const s=await H();G(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 Q(x);U(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 V(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 B=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{S(!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{S(!1)}},J=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)}},K=async s=>{if(!c)return;const i=c.packages.filter(a=>(typeof a=="string"?a:a.source)!==s);try{await O({packages:i}),t("Package removed","success"),await r()}catch(a){t(`Failed to remove package: ${a instanceof Error?a.message:String(a)}`,"error")}},X=async(s,i)=>{if(!c)return;const a=c[s].filter(n=>n!==i);try{await O({[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:()=>X(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:j,children:e.jsx($,{size:16,className:j?"spin":""})})})]}),j?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(Y,{size:14}),N?"Installing…":"Add"]})]}),e.jsx("div",{className:"pi-ext-add-form-row",children:e.jsx("button",{className:"btn",onClick:J,disabled:E,children:E?"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),f=typeof s=="object"&&s!==null,v=f&&(s.extensions?.length??0)>0||(s.skills?.length??0)>0||(s.prompts?.length??0)>0||(s.themes?.length??0)>0,k=I.has(i);return e.jsxs("div",{className:"pi-ext-package-card",children:[e.jsxs("div",{className:"pi-ext-package-header",children:[f&&v?e.jsx("button",{className:"pi-ext-expand-btn",onClick:()=>B(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:[f&&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:()=>K(a),title:"Remove package","aria-label":`Remove package ${g}`,children:e.jsx(se,{size:14})})]})]}),f&&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(_,{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(A,{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",_,"prompts"),u("Themes",A,"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:W,"aria-label":`Toggle ${s.name}`}),e.jsx("span",{className:"toggle-slider"})]})})]},s.id))})]})]})}export{he as PiExtensionsManager};
@@ -1 +1 @@
1
- import{r as g,j as e}from"./vendor-react-K0fH_qHe.js";import{v as ye,eK as je,eL as Z,s as Ne,X as Y,aA as Se,aZ as ve,J as T,b5 as ee,_ as se,R as we,eM as Ce,aw as Ie,eN as Pe,eO as $e,cJ as Re,eP as Ee,eQ as ke,eR as Be,eS as Le,eT as te,cG as Ae,eU as Fe}from"./index-B9Ro_NwC.js";import{D as De}from"./DirectoryPicker-H-fUl2dF.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";import"./folder-open-Byqfi_N-.js";const le="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:le,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 Oe(i){const c=i.settingsSchema,h=c&&Object.keys(c).length>0;return i.id!==le?h?c:void 0:h?{...ne,...c}:ne}function ze(i){const c=new Map,h=[];for(const[x,f]of Object.entries(i))if(f.group){const N=c.get(f.group)??[];N.push([x,f]),c.set(f.group,N)}else h.push([x,f]);return{grouped:c,ungrouped:h}}function ie(i,c="plugin-error-text"){return i.state!=="error"||!i.error?null:e.jsx("p",{className:c,title:i.error,children:i.error})}function We({addToast:i,projectId:c}){const[h,x]=g.useState([]),[f,N]=g.useState(!0),[re,P]=g.useState(!1),[w,$]=g.useState(""),[B,L]=g.useState(!1),[A,F]=g.useState(!1),[S,D]=g.useState(null),[r,R]=g.useState(null),[p,b]=g.useState({}),[ce,O]=g.useState(!1),[z,G]=g.useState(null),[oe,E]=g.useState({}),[ue,U]=g.useState(null),[C,M]=g.useState(null),{confirm:de}=ye(),m=g.useCallback(async()=>{try{N(!0);const s=await je(c);x(s)}catch(s){i(`Failed to load plugins: ${s instanceof Error?s.message:String(s)}`,"error")}finally{N(!1)}},[c,i]);g.useEffect(()=>{m()},[m]),g.useEffect(()=>{const s=ae.filter(o=>o.hasSetup&&h.some(l=>l.id===o.id));if(s.length===0)return;let n=!1;return Promise.all(s.map(async o=>{try{const l=await Z(o.id,c);if(n)return;E(u=>({...u,[o.id]:l}))}catch{if(n)return;E(l=>({...l,[o.id]:{hasSetup:!0,setupCheckDeferred:!0,deferredReason:"plugin-not-started",pluginState:"installed"}}))}})),()=>{n=!0}},[h,c]);const pe=g.useRef([]);pe.current=h,g.useEffect(()=>{const s=c?`?projectId=${encodeURIComponent(c)}`:"",n=o=>{try{const l=JSON.parse(o.data);if(l.scope==="project"&&(l.projectId??c)!==c)return;switch(l.transition){case"installing":case"enabled":case"disabled":case"settings-updated":x(u=>{const a=u.findIndex(t=>t.id===l.pluginId);if(a>=0){const t=[...u];return t[a]={...t[a],enabled:l.enabled,state:l.state,settings:l.settings,error:l.error},t}else return m(),u});break;case"state-changed":x(u=>{const a=u.findIndex(t=>t.id===l.pluginId);if(a>=0){const t=[...u];return t[a]={...t[a],state:l.state,error:l.error},t}return u});break;case"uninstalled":x(u=>u.filter(a=>a.id!==l.pluginId));break;case"error":x(u=>{const a=u.findIndex(t=>t.id===l.pluginId);if(a>=0){const t=[...u];return t[a]={...t[a],state:l.state,error:l.error},t}return u});break}}catch{}};return Ne(`/api/events${s}`,{events:{"plugin:lifecycle":n},onReconnect:()=>{m()}})},[c,m]);const _=async()=>{if(!w.trim()){i("Please enter a plugin path","error");return}try{L(!0),await te({path:w,...A?{aiScanOnLoad:!0}:{}},c),i("Plugin installed globally","success"),P(!1),$(""),F(!1),await m()}catch(s){i(`Failed to install plugin: ${s instanceof Error?s.message:String(s)}`,"error")}finally{L(!1)}},ge=async s=>{if(!s.path){i(`${s.name} is built in and does not have an installable package yet`,"warning");return}try{G(s.id),await te({path:s.path},c),i(`${s.name} installed globally`,"success"),await m()}catch(n){i(`Failed to install ${s.name}: ${n instanceof Error?n.message:String(n)}`,"error")}finally{G(null)}},q=async s=>{try{M(s.id);const n=await Fe(s.id,c);if(!n.success){i(`Failed to install ${s.name} setup: ${n.error??"unknown error"}`,"error");return}i(`${s.name} setup installed`,"success"),U(s.id);const o=await Z(s.id,c);E(l=>({...l,[s.id]:o}))}catch(n){i(`Failed to install ${s.name} setup: ${n instanceof Error?n.message:String(n)}`,"error")}finally{M(null),U(null)}},V=async s=>{try{const n=await Be(s.id,c);if(n.state==="error"){i(`Failed to enable ${s.name}: ${n.error??"Unknown error"}`,"error"),await m();return}i(`${s.name} enabled for this project`,"success"),await m()}catch(n){i(`Failed to enable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},H=async s=>{try{await ke(s.id,c),i(`${s.name} disabled for this project`,"success"),await m()}catch(n){i(`Failed to disable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},W=async s=>{try{D(s.id),await Ee(s.id,c),i(`${s.name} reloaded`,"success"),await m()}catch(n){i(`Failed to reload plugin: ${n instanceof Error?n.message:String(n)}`,"error")}finally{D(null)}},J=async s=>{if(await de({title:"Uninstall Plugin Globally",message:`Are you sure you want to uninstall "${s.name}" globally (all projects)?`,danger:!0}))try{await Le(s.id,c),i(`${s.name} uninstalled globally`,"success"),await m(),R(null)}catch(o){i(`Failed to uninstall plugin: ${o instanceof Error?o.message:String(o)}`,"error")}},me=async(s,n)=>{try{await Pe(s.id,{aiScanOnLoad:n},c),i(`AI scan on load ${n?"enabled":"disabled"}`,"success"),await m()}catch(o){i(`Failed to update plugin: ${o instanceof Error?o.message:String(o)}`,"error")}},he=async s=>{try{await $e(s.id,c),i(`${s.name} rescanned`,"success"),await m()}catch(n){i(`Failed to rescan plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},k=async s=>{R(s);try{O(!0);const n=await Ae(s.id,c);b(n)}catch{b({})}finally{O(!1)}},be=async()=>{if(r)try{await Re(r.id,p,c),i("Settings saved","success")}catch(s){i(`Failed to save settings: ${s instanceof Error?s.message:String(s)}`,"error")}};if(r)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(Y,{size:16})}),e.jsxs("div",{className:"plugin-detail-title",children:[e.jsxs("div",{className:"plugin-detail-title-copy",children:[e.jsx("h4",{className:"plugin-detail-name",children:r.name}),ie(r,"plugin-error-text plugin-error-text--detail")]}),e.jsx("span",{className:"plugin-state-badge",style:{color:I[r.state]||I.installed},children:r.state})]})]}),e.jsxs("div",{className:"plugin-detail-content",children:[e.jsxs("div",{className:"plugin-detail-card",children:[r.description&&e.jsx("p",{className:"plugin-description",children:r.description}),r.author&&e.jsxs("p",{className:"plugin-detail-meta-row",children:[e.jsx("span",{className:"text-muted",children:"Author:"}),r.author]}),r.homepage&&e.jsxs("p",{className:"plugin-detail-meta-row plugin-homepage",children:[e.jsx("span",{className:"text-muted",children:"Homepage:"}),e.jsxs("a",{href:r.homepage,target:"_blank",rel:"noopener noreferrer",children:[r.homepage,e.jsx(Se,{size:12})]})]}),e.jsxs("p",{className:"plugin-detail-meta-row",children:[e.jsx("span",{className:"text-muted",children:"Version:"}),r.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:!!r.aiScanOnLoad,onChange:s=>void me(r,s.target.checked)}),"Enable AI scan before load/reload"]}),e.jsxs("button",{className:"btn btn-secondary btn-sm",onClick:()=>void he(r),children:[e.jsx(ve,{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."}),r.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--${r.lastSecurityScan.verdict}`,children:r.lastSecurityScan.verdict}),e.jsx("span",{className:"text-muted",children:r.lastSecurityScan.scannedAt})]}),e.jsx("p",{className:"plugin-security-summary",children:r.lastSecurityScan.summary}),e.jsxs("details",{children:[e.jsxs("summary",{children:["Findings (",r.lastSecurityScan.findings.length,")"]}),e.jsx("ul",{className:"plugin-security-findings",children:r.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"}),ce?e.jsx("p",{className:"text-muted",children:"Loading..."}):(()=>{const s=Oe(r);return s&&Object.keys(s).length>0?e.jsxs("div",{className:"plugin-settings-form",children:[(()=>{const{grouped:n,ungrouped:o}=ze(s),l=[];o.length>0&&l.push({title:null,entries:o});for(const[u,a]of n.entries())l.push({title:u,entries:a});return l.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(Y,{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:be,children:"Save Settings"})]}):e.jsx("p",{className:"text-muted",children:"No configurable settings."})})()]}),e.jsxs("div",{className:"plugin-detail-actions",children:[r.state==="started"&&e.jsxs("button",{className:"btn btn-secondary",onClick:()=>W(r),disabled:S===r.id,children:[e.jsx(ee,{size:14,className:S===r.id?"spin":""}),S===r.id?"Reloading...":"Reload"]}),r.enabled?e.jsx("button",{className:"btn btn-secondary",onClick:()=>H(r),children:"Disable in Project"}):e.jsx("button",{className:"btn btn-primary",onClick:()=>V(r),children:"Enable in Project"}),e.jsxs("button",{className:"btn btn-danger",onClick:()=>J(r),children:[e.jsx(se,{size:14})," Uninstall Globally"]})]})]})]});const xe=new Map(h.map(s=>[s.id,s])),K=h,fe=()=>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=xe.get(s.id),o=!!n,l=oe[s.id],u=!!(l&&"setupCheckDeferred"in l&&l.setupCheckDeferred),a=l&&"status"in l?l.status:void 0,t=o&&s.hasSetup&&l?.hasSetup&&!u&&n?.state==="started"&&(a==="not-installed"||a==="error"),y=o&&l?.hasSetup&&a==="installed",d=ue===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 ${o?"plugin-builtins-status--installed":"plugin-builtins-status--available"}`,children:o?"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?o&&t?e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>void q(s),disabled:C===s.id||d,children:C===s.id?"Setting up...":"Install Setup"}):o&&n?e.jsx("button",{className:"btn btn-secondary btn-sm",onClick:()=>void k(n),children:"Manage"}):e.jsx("span",{className:"plugin-builtins-metadata-only",children:"Built-in metadata only"}):e.jsx("button",{className:`btn ${o&&!t?"btn-secondary":"btn-primary"} btn-sm`,onClick:()=>{if(!o){ge(s);return}if(t){q(s);return}n&&k(n)},disabled:z===s.id||C===s.id||d,children:o?t?C===s.id?"Setting up...":"Install Setup":"Manage":z===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(we,{size:14,className:f?"spin":""}),"Refresh"]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>P(!0),children:[e.jsx(T,{size:14})," Install"]})]})]}),re&&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(De,{value:w,onChange:$,placeholder:"Absolute path to plugin directory or dist folder",onInputKeyDown:s=>{s.key==="Enter"&&(s.preventDefault(),_())}}),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:_,disabled:B||!w.trim(),children:B?"Installing...":"Install Plugin Globally"}),e.jsx("button",{className:"btn btn-secondary",onClick:()=>{P(!1),$("")},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(Ce,{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.jsx("div",{className:"plugin-info",children:e.jsxs("div",{className:"plugin-copy",children:[e.jsxs("div",{className:"plugin-copy-header",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})]}),ie(s)]})}),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):V(s),"aria-label":`${s.enabled?"Disable":"Enable"} ${s.name}`}),e.jsx("span",{className:"toggle-slider"})]}),e.jsx("button",{className:"btn-icon",onClick:()=>k(s),title:"Settings",children:e.jsx(Ie,{size:14})}),e.jsx("button",{className:"btn-icon",onClick:()=>J(s),title:"Uninstall globally",children:e.jsx(se,{size:14})})]})]},s.id))}),fe()]})]})}export{ne as AGENT_BROWSER_SETTINGS_SCHEMA,le as BUILTIN_AGENT_BROWSER_PLUGIN_ID,We as PluginManager,I as STATE_COLORS};
1
+ import{r as g,j as e}from"./vendor-react-K0fH_qHe.js";import{v as ye,eM as je,eN as Y,s as Ne,X as Z,aB as Se,a_ as ve,J as T,b6 as ee,_ as se,R as we,eO as Ce,ax as Ie,eP as Pe,eQ as $e,cK as Re,eR as Ee,eS as ke,eT as Be,eU as Le,eV as te,cH as Ae,eW as Fe}from"./index-w1dPHtmq.js";import{D as De}from"./DirectoryPicker-D496NTjZ.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";import"./folder-open-Dh5_gv6L.js";const le="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:le,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 Oe(i){const c=i.settingsSchema,h=c&&Object.keys(c).length>0;return i.id!==le?h?c:void 0:h?{...ne,...c}:ne}function ze(i){const c=new Map,h=[];for(const[x,f]of Object.entries(i))if(f.group){const N=c.get(f.group)??[];N.push([x,f]),c.set(f.group,N)}else h.push([x,f]);return{grouped:c,ungrouped:h}}function ie(i,c="plugin-error-text"){return i.state!=="error"||!i.error?null:e.jsx("p",{className:c,title:i.error,children:i.error})}function We({addToast:i,projectId:c}){const[h,x]=g.useState([]),[f,N]=g.useState(!0),[re,P]=g.useState(!1),[w,$]=g.useState(""),[B,L]=g.useState(!1),[A,F]=g.useState(!1),[S,D]=g.useState(null),[r,R]=g.useState(null),[p,b]=g.useState({}),[ce,O]=g.useState(!1),[z,U]=g.useState(null),[oe,E]=g.useState({}),[ue,G]=g.useState(null),[C,_]=g.useState(null),{confirm:de}=ye(),m=g.useCallback(async()=>{try{N(!0);const s=await je(c);x(s)}catch(s){i(`Failed to load plugins: ${s instanceof Error?s.message:String(s)}`,"error")}finally{N(!1)}},[c,i]);g.useEffect(()=>{m()},[m]),g.useEffect(()=>{const s=ae.filter(o=>o.hasSetup&&h.some(l=>l.id===o.id));if(s.length===0)return;let n=!1;return Promise.all(s.map(async o=>{try{const l=await Y(o.id,c);if(n)return;E(u=>({...u,[o.id]:l}))}catch{if(n)return;E(l=>({...l,[o.id]:{hasSetup:!0,setupCheckDeferred:!0,deferredReason:"plugin-not-started",pluginState:"installed"}}))}})),()=>{n=!0}},[h,c]);const pe=g.useRef([]);pe.current=h,g.useEffect(()=>{const s=c?`?projectId=${encodeURIComponent(c)}`:"",n=o=>{try{const l=JSON.parse(o.data);if(l.scope==="project"&&(l.projectId??c)!==c)return;switch(l.transition){case"installing":case"enabled":case"disabled":case"settings-updated":x(u=>{const a=u.findIndex(t=>t.id===l.pluginId);if(a>=0){const t=[...u];return t[a]={...t[a],enabled:l.enabled,state:l.state,settings:l.settings,error:l.error},t}else return m(),u});break;case"state-changed":x(u=>{const a=u.findIndex(t=>t.id===l.pluginId);if(a>=0){const t=[...u];return t[a]={...t[a],state:l.state,error:l.error},t}return u});break;case"uninstalled":x(u=>u.filter(a=>a.id!==l.pluginId));break;case"error":x(u=>{const a=u.findIndex(t=>t.id===l.pluginId);if(a>=0){const t=[...u];return t[a]={...t[a],state:l.state,error:l.error},t}return u});break}}catch{}};return Ne(`/api/events${s}`,{events:{"plugin:lifecycle":n},onReconnect:()=>{m()}})},[c,m]);const M=async()=>{if(!w.trim()){i("Please enter a plugin path","error");return}try{L(!0),await te({path:w,...A?{aiScanOnLoad:!0}:{}},c),i("Plugin installed globally","success"),P(!1),$(""),F(!1),await m()}catch(s){i(`Failed to install plugin: ${s instanceof Error?s.message:String(s)}`,"error")}finally{L(!1)}},ge=async s=>{if(!s.path){i(`${s.name} is built in and does not have an installable package yet`,"warning");return}try{U(s.id),await te({path:s.path},c),i(`${s.name} installed globally`,"success"),await m()}catch(n){i(`Failed to install ${s.name}: ${n instanceof Error?n.message:String(n)}`,"error")}finally{U(null)}},V=async s=>{try{_(s.id);const n=await Fe(s.id,c);if(!n.success){i(`Failed to install ${s.name} setup: ${n.error??"unknown error"}`,"error");return}i(`${s.name} setup installed`,"success"),G(s.id);const o=await Y(s.id,c);E(l=>({...l,[s.id]:o}))}catch(n){i(`Failed to install ${s.name} setup: ${n instanceof Error?n.message:String(n)}`,"error")}finally{_(null),G(null)}},q=async s=>{try{const n=await Be(s.id,c);if(n.state==="error"){i(`Failed to enable ${s.name}: ${n.error??"Unknown error"}`,"error"),await m();return}i(`${s.name} enabled for this project`,"success"),await m()}catch(n){i(`Failed to enable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},H=async s=>{try{await ke(s.id,c),i(`${s.name} disabled for this project`,"success"),await m()}catch(n){i(`Failed to disable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},W=async s=>{try{D(s.id),await Ee(s.id,c),i(`${s.name} reloaded`,"success"),await m()}catch(n){i(`Failed to reload plugin: ${n instanceof Error?n.message:String(n)}`,"error")}finally{D(null)}},J=async s=>{if(await de({title:"Uninstall Plugin Globally",message:`Are you sure you want to uninstall "${s.name}" globally (all projects)?`,danger:!0}))try{await Le(s.id,c),i(`${s.name} uninstalled globally`,"success"),await m(),R(null)}catch(o){i(`Failed to uninstall plugin: ${o instanceof Error?o.message:String(o)}`,"error")}},me=async(s,n)=>{try{await Pe(s.id,{aiScanOnLoad:n},c),i(`AI scan on load ${n?"enabled":"disabled"}`,"success"),await m()}catch(o){i(`Failed to update plugin: ${o instanceof Error?o.message:String(o)}`,"error")}},he=async s=>{try{await $e(s.id,c),i(`${s.name} rescanned`,"success"),await m()}catch(n){i(`Failed to rescan plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},k=async s=>{R(s);try{O(!0);const n=await Ae(s.id,c);b(n)}catch{b({})}finally{O(!1)}},be=async()=>{if(r)try{await Re(r.id,p,c),i("Settings saved","success")}catch(s){i(`Failed to save settings: ${s instanceof Error?s.message:String(s)}`,"error")}};if(r)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.jsxs("div",{className:"plugin-detail-title-copy",children:[e.jsx("h4",{className:"plugin-detail-name",children:r.name}),ie(r,"plugin-error-text plugin-error-text--detail")]}),e.jsx("span",{className:"plugin-state-badge",style:{color:I[r.state]||I.installed},children:r.state})]})]}),e.jsxs("div",{className:"plugin-detail-content",children:[e.jsxs("div",{className:"plugin-detail-card",children:[r.description&&e.jsx("p",{className:"plugin-description",children:r.description}),r.author&&e.jsxs("p",{className:"plugin-detail-meta-row",children:[e.jsx("span",{className:"text-muted",children:"Author:"}),r.author]}),r.homepage&&e.jsxs("p",{className:"plugin-detail-meta-row plugin-homepage",children:[e.jsx("span",{className:"text-muted",children:"Homepage:"}),e.jsxs("a",{href:r.homepage,target:"_blank",rel:"noopener noreferrer",children:[r.homepage,e.jsx(Se,{size:12})]})]}),e.jsxs("p",{className:"plugin-detail-meta-row",children:[e.jsx("span",{className:"text-muted",children:"Version:"}),r.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:!!r.aiScanOnLoad,onChange:s=>void me(r,s.target.checked)}),"Enable AI scan before load/reload"]}),e.jsxs("button",{className:"btn btn-secondary btn-sm",onClick:()=>void he(r),children:[e.jsx(ve,{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."}),r.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--${r.lastSecurityScan.verdict}`,children:r.lastSecurityScan.verdict}),e.jsx("span",{className:"text-muted",children:r.lastSecurityScan.scannedAt})]}),e.jsx("p",{className:"plugin-security-summary",children:r.lastSecurityScan.summary}),e.jsxs("details",{children:[e.jsxs("summary",{children:["Findings (",r.lastSecurityScan.findings.length,")"]}),e.jsx("ul",{className:"plugin-security-findings",children:r.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"}),ce?e.jsx("p",{className:"text-muted",children:"Loading..."}):(()=>{const s=Oe(r);return s&&Object.keys(s).length>0?e.jsxs("div",{className:"plugin-settings-form",children:[(()=>{const{grouped:n,ungrouped:o}=ze(s),l=[];o.length>0&&l.push({title:null,entries:o});for(const[u,a]of n.entries())l.push({title:u,entries:a});return l.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:be,children:"Save Settings"})]}):e.jsx("p",{className:"text-muted",children:"No configurable settings."})})()]}),e.jsxs("div",{className:"plugin-detail-actions",children:[r.state==="started"&&e.jsxs("button",{className:"btn btn-secondary",onClick:()=>W(r),disabled:S===r.id,children:[e.jsx(ee,{size:14,className:S===r.id?"spin":""}),S===r.id?"Reloading...":"Reload"]}),r.enabled?e.jsx("button",{className:"btn btn-secondary",onClick:()=>H(r),children:"Disable in Project"}):e.jsx("button",{className:"btn btn-primary",onClick:()=>q(r),children:"Enable in Project"}),e.jsxs("button",{className:"btn btn-danger",onClick:()=>J(r),children:[e.jsx(se,{size:14})," Uninstall Globally"]})]})]})]});const xe=new Map(h.map(s=>[s.id,s])),K=h,fe=()=>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=xe.get(s.id),o=!!n,l=oe[s.id],u=!!(l&&"setupCheckDeferred"in l&&l.setupCheckDeferred),a=l&&"status"in l?l.status:void 0,t=o&&s.hasSetup&&l?.hasSetup&&!u&&n?.state==="started"&&(a==="not-installed"||a==="error"),y=o&&l?.hasSetup&&a==="installed",d=ue===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 ${o?"plugin-builtins-status--installed":"plugin-builtins-status--available"}`,children:o?"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?o&&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"}):o&&n?e.jsx("button",{className:"btn btn-secondary btn-sm",onClick:()=>void k(n),children:"Manage"}):e.jsx("span",{className:"plugin-builtins-metadata-only",children:"Built-in metadata only"}):e.jsx("button",{className:`btn ${o&&!t?"btn-secondary":"btn-primary"} btn-sm`,onClick:()=>{if(!o){ge(s);return}if(t){V(s);return}n&&k(n)},disabled:z===s.id||C===s.id||d,children:o?t?C===s.id?"Setting up...":"Install Setup":"Manage":z===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(we,{size:14,className:f?"spin":""}),"Refresh"]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>P(!0),children:[e.jsx(T,{size:14})," Install"]})]})]}),re&&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(De,{value:w,onChange:$,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:()=>{P(!1),$("")},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(Ce,{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.jsx("div",{className:"plugin-info",children:e.jsxs("div",{className:"plugin-copy",children:[e.jsxs("div",{className:"plugin-copy-header",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})]}),ie(s)]})}),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):q(s),"aria-label":`${s.enabled?"Disable":"Enable"} ${s.name}`}),e.jsx("span",{className:"toggle-slider"})]}),e.jsx("button",{className:"btn-icon",onClick:()=>k(s),title:"Settings",children:e.jsx(Ie,{size:14})}),e.jsx("button",{className:"btn-icon",onClick:()=>J(s),title:"Uninstall globally",children:e.jsx(se,{size:14})})]})]},s.id))}),fe()]})]})}export{ne as AGENT_BROWSER_SETTINGS_SCHEMA,le as BUILTIN_AGENT_BROWSER_PLUGIN_ID,We as PluginManager,I as STATE_COLORS};
@@ -1 +1 @@
1
- import{r as n,j as e}from"./vendor-react-K0fH_qHe.js";import{a7 as z,a8 as le,a9 as oe,ak as de,aD as be,ac as te,aE as fe,s as ve,aF as W,aG as xe,aH as pe,aI as ye,aJ as ge,aK as Re,aL as _e,ao as je,u as Se,aM as we,x as Ne,aN as Ee,L as ke,S as Ce}from"./index-B9Ro_NwC.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const Ae="builtin",Q={pageFetch:!0,github:!1,localDocs:!0,llmSynthesis:!0};function ae(r){const t=r?.researchGlobalDefaults,i=r?.researchSettings;return{enabled:i?.enabled??r?.researchEnabled??r?.researchGlobalEnabled??!0,searchProvider:i?.searchProvider??t?.searchProvider??r?.researchGlobalWebSearchProvider??Ae,synthesisProvider:i?.synthesisProvider??t?.synthesisProvider,synthesisModelId:i?.synthesisModelId??t?.synthesisModelId,enabledSources:{webSearch:!0,pageFetch:i?.enabledSources?.pageFetch??t?.enabledSources?.pageFetch??Q.pageFetch,github:i?.enabledSources?.github??t?.enabledSources?.github??Q.github,localDocs:i?.enabledSources?.localDocs??t?.enabledSources?.localDocs??Q.localDocs,llmSynthesis:i?.enabledSources?.llmSynthesis??t?.enabledSources?.llmSynthesis??Q.llmSynthesis},limits:{maxConcurrentRuns:i?.limits?.maxConcurrentRuns??r?.researchMaxConcurrentRuns??r?.researchGlobalMaxConcurrentRuns??3,maxSourcesPerRun:i?.limits?.maxSourcesPerRun??t?.maxSourcesPerRun??r?.researchMaxSourcesPerRun??r?.researchGlobalMaxSourcesPerRun??20,maxDurationMs:i?.limits?.maxDurationMs??r?.researchDefaultTimeout??r?.researchGlobalDefaultTimeout??3e5,requestTimeoutMs:i?.limits?.requestTimeoutMs??r?.researchGlobalFetchTimeoutMs??3e4},defaultExportFormat:t?.defaultExportFormat??"markdown"}}const Pe=300,Te=4e3,Ie=["queued","running","cancelling","retry_waiting"];function re(r,t){if(r instanceof je){const i=r;return{message:r.message,status:r.status,code:i.researchCode??"INTERNAL_ERROR",setupHint:i.setupHint,retryable:i.retryable}}return r instanceof Error?{message:r.message,code:"INTERNAL_ERROR"}:{message:t,code:"INTERNAL_ERROR"}}function Le(r){if(!r)return{cancelable:!1,retryable:!1,isTransitioning:!1,blockingReason:"No run selected"};const t=Ie.includes(r.status),i=r.status==="queued"||r.status==="running",f=r.lifecycle?.retryable,y=r.status==="failed"||r.status==="timed_out",a=!!(y&&f);let _;return!i&&t?_="Run is already transitioning":!i&&r.status==="completed"?_="Completed runs cannot be cancelled":!i&&r.status==="cancelled"?_="Run is already cancelled":!i&&r.status==="retry_exhausted"?_="Retry attempts exhausted":!i&&r.status==="failed"?_="Failed runs cannot be cancelled":!i&&r.status==="timed_out"&&(_="Timed out runs cannot be cancelled"),!a&&y&&f===!1&&(_=r.lifecycle?.errorCode==="RETRY_EXHAUSTED"?"Retry attempts exhausted":"Run is not retryable"),{cancelable:i,retryable:a,isTransitioning:t,blockingReason:_}}function Me(r){const t=r?.projectId,i=t??"",f=`${oe.RESEARCH_RUNS_PREFIX}${i}`,y=`${oe.RESEARCH_SELECTED_ID_PREFIX}${i}`,a=z(f,{maxAgeMs:le}),_=z(y,{maxAgeMs:de}),N=n.useRef(Array.isArray(a)&&a.length>0),[j,A]=n.useState(()=>Array.isArray(a)?a:[]),[x,T]=n.useState(_??null),[F,w]=n.useState(null),[D,I]=n.useState({available:!0}),[q,L]=n.useState(!(Array.isArray(a)&&a.length>0)),[H,M]=n.useState(null),[P,R]=n.useState(null),[g,E]=n.useState(""),o=n.useRef(0),v=n.useRef(0),$=n.useRef(t);n.useEffect(()=>{$.current!==t&&($.current=t,v.current++);const c=z(f,{maxAgeMs:le}),l=z(y,{maxAgeMs:de}),h=Array.isArray(c)&&c.length>0;A(Array.isArray(c)?c:[]),T(l??null),w(null),L(!h),N.current=h},[t,f,y]);const k=n.useCallback(async(c=g)=>{const l=++o.current,h=t;N.current||L(!0),M(null),R(null);try{const m=await be({q:c||void 0,limit:100},h);if(l!==o.current||h!==t)return;A(m.runs),te(f,m.runs,{maxBytes:5e5}),N.current=!0,I(m.availability),x&&!m.runs.some(p=>p.id===x)&&(T(null),te(y,null,{maxBytes:5e5}),w(null))}catch(m){if(l!==o.current||h!==t)return;const p=re(m,"Failed to load research runs");M(p.message),R(p)}finally{l===o.current&&L(!1)}},[t,f,g,y,x]),O=n.useCallback(async c=>{const l=await fe(c,t);return w(l.run),I(l.availability),l.run},[t]);n.useEffect(()=>{N.current||L(!0);const c=window.setTimeout(()=>{k(g)},Pe);return()=>window.clearTimeout(c)},[k,g]),n.useEffect(()=>{if(!x){w(null);return}O(x)},[O,x]),n.useEffect(()=>{const c=v.current,l=()=>v.current!==c,h=t?`?projectId=${encodeURIComponent(t)}`:"";let m=!0;const p=()=>{!m||l()||(k(),x&&O(x))},S=`/api/events${h}`,U=ve(S,{events:{"research:run:created":p,"research:run:updated":p,"research:run:completed":p,"research:run:failed":p,"research:run:cancelled":p},onReconnect:()=>{W({view:"useResearch",trigger:"sse-reconnect",projectId:t,replayAttempted:!1,sseChannel:S}),p()}});W({view:"useResearch",trigger:"sse-open",projectId:t,replayAttempted:!1,sseChannel:S});const G=window.setInterval(p,Te);return()=>{m=!1,U(),window.clearInterval(G)}},[t,k,x,O]);const B=n.useCallback(c=>{T(c),te(y,c,{maxBytes:5e5})},[y]);return{runs:j,selectedRun:F,selectedRunId:x,setSelectedRunId:B,availability:D,loading:q,error:H,searchQuery:g,setSearchQuery:E,refresh:k,createRun:c=>_e(c,t),cancelRun:async c=>{try{R(null);const l=await Re(c,t);return x===c&&w(l.run),await k(),l}catch(l){const h=re(l,"Failed to cancel run");throw R(h),h}},retryRun:async c=>{try{R(null);const l=await ge(c,t);return x===c&&w(l.run),await k(),l}catch(l){const h=re(l,"Failed to retry run");throw R(h),h}},exportRun:(c,l)=>ye(c,l,t),createTaskFromRun:(c,l,h,m,p,S)=>pe(c,{title:l,findingId:h,description:m,priority:p,attachExport:S},t),attachRunToTask:(c,l,h,m)=>xe(c,{taskId:l,findingId:h,attachExport:m},t),uiError:P,runActionState:Le(F),statusCounts:j.reduce((c,l)=>(c[l.status]+=1,c),{queued:0,running:0,cancelling:0,retry_waiting:0,completed:0,failed:0,cancelled:0,timed_out:0,retry_exhausted:0})}}function Fe({open:r,mode:t,run:i,finding:f,projectId:y,onClose:a,onConfirm:_}){Se(r);const[N,j]=n.useState(!1),[A,x]=n.useState(""),[T,F]=n.useState(""),[w,D]=n.useState("normal"),[I,q]=n.useState(""),[L,H]=n.useState([]),[M,P]=n.useState(!1),[R,g]=n.useState(!1),E=n.useMemo(()=>{const o=(f.content??"").split(/(?<=[.!?])\s+/)[0]??"";return`${f.heading||"Research finding"} — ${o}`.trim()},[f.content,f.heading]);return n.useEffect(()=>{r&&(j(!1),x(`Research: ${f.heading||i.title}`),F(E),D("normal"),q(""),t==="enrich"&&(P(!0),we(50,0,y).then(o=>H(o.filter(v=>v.column!=="archived"))).finally(()=>P(!1))))},[r,t,y,f.heading,E,i.title]),r?e.jsx("div",{className:"modal-overlay open",role:"presentation",onClick:a,children:e.jsxs("div",{className:"modal modal-lg research-task-action-modal",role:"dialog","aria-modal":"true",onClick:o=>o.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:t==="create"?"Create task from finding":"Enrich existing task"}),e.jsx("button",{className:"modal-close",type:"button","aria-label":"Close",onClick:a,children:"×"})]}),e.jsxs("div",{className:"research-task-action-modal__body",children:[e.jsxs("div",{className:"card research-task-action-modal__preview",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Run:"})," ",i.id]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Finding:"})," ",f.id,f.heading?` — ${f.heading}`:""]}),e.jsx("p",{children:E||"No preview available."})]}),t==="create"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"research-task-action-modal__field",children:["Title",e.jsx("input",{className:"input",value:A,onChange:o=>x(o.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Description",e.jsx("textarea",{className:"input research-task-action-modal__textarea",value:T,onChange:o=>F(o.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Priority",e.jsxs("select",{className:"select",value:w,onChange:o=>D(o.target.value),children:[e.jsx("option",{value:"low",children:"Low"}),e.jsx("option",{value:"normal",children:"Normal"}),e.jsx("option",{value:"high",children:"High"}),e.jsx("option",{value:"urgent",children:"Urgent"})]})]})]}):e.jsxs("label",{className:"research-task-action-modal__field",children:["Target task",e.jsx("input",{className:"input",list:"research-task-action-task-list",value:I,placeholder:M?"Loading tasks…":"Enter task ID",onChange:o=>q(o.target.value)}),e.jsx("datalist",{id:"research-task-action-task-list",children:L.map(o=>e.jsx("option",{value:o.id,children:o.title},o.id))})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:N,onChange:o=>j(o.target.checked)}),e.jsx("span",{children:"Attach markdown export artifact"})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:a,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",type:"button",disabled:R||t==="enrich"&&!I,onClick:()=>{g(!0),_({taskId:t==="enrich"?I:void 0,title:t==="create"?A.trim():void 0,description:t==="create"?T.trim():void 0,priority:t==="create"?w:void 0,attachExport:N}).finally(()=>g(!1))},children:t==="create"?"Create Task":"Enrich Task"})]})]})}):null}const De=["web-search","page-fetch","github","local-docs","llm-synthesis"],qe={"web-search":"webSearch","page-fetch":"pageFetch",github:"github","local-docs":"localDocs","llm-synthesis":"llmSynthesis"},Oe={"web-search":"Web Search","page-fetch":"Page Fetch",github:"GitHub","local-docs":"Local Docs","llm-synthesis":"LLM Synthesis"};let ne=!1;function Be({projectId:r,addToast:t,onOpenSettings:i,readinessVersion:f=0}){n.useEffect(()=>(W({view:"ResearchView",trigger:ne?"route-active":"remount",projectId:r,replayAttempted:!1}),ne=!1,()=>{ne=!0,W({view:"ResearchView",trigger:"route-inactive",projectId:r,replayAttempted:!1})}),[r]);const{runs:y,selectedRun:a,selectedRunId:_,setSelectedRunId:N,availability:j,loading:A,error:x,searchQuery:T,setSearchQuery:F,createRun:w,cancelRun:D,retryRun:I,exportRun:q,createTaskFromRun:L,attachRunToTask:H,statusCounts:M,refresh:P,uiError:R,runActionState:g}=Me({projectId:r}),[E,o]=n.useState(""),[v,$]=n.useState(()=>ae(void 0)),[k,O]=n.useState([]),[B,c]=n.useState(!1),[l,h]=n.useState([]),[m,p]=n.useState(null),[S,U]=n.useState(null),G=j.supportedProviders??De,X=v.searchProvider,Y=s=>s==="web-search"?!0:v.enabledSources[qe[s]];n.useEffect(()=>{const s=G.filter(d=>Y(d));h(d=>{const b=d.filter(u=>s.includes(u));return b.length>0?b:s})},[v.enabledSources,G]),n.useEffect(()=>{let s=!1;return Promise.all([Ne(r),Ee().catch(()=>({providers:[]}))]).then(([d,b])=>{s||($(ae(d)),O(b.providers.filter(u=>u.type==="api_key").map(u=>({id:u.id,authenticated:u.authenticated}))))}).catch(()=>{s||$(ae(void 0))}),()=>{s=!0}},[r,f]);const ue=n.useMemo(()=>a?a.status:"No run selected",[a]),he=n.useMemo(()=>a?a.status==="queued"||a.status==="retry_waiting"?"status-dot status-dot--pending":a.status==="running"?"status-dot status-dot--connecting":a.status==="completed"?"status-dot status-dot--online":a.status==="failed"||a.status==="cancelled"?"status-dot status-dot--error":"status-dot":"status-dot",[a]),J=j.supportedExportFormats??["markdown","json","html"],Z=n.useMemo(()=>new Map(k.map(s=>[s.id,s.authenticated])),[k]),ee=n.useMemo(()=>{const s=new Set;return v.enabledSources.webSearch&&X&&s.add(X),v.enabledSources.llmSynthesis&&v.synthesisProvider&&s.add(v.synthesisProvider),[...s].filter(d=>Z.has(d))},[v.enabledSources.llmSynthesis,v.enabledSources.webSearch,v.synthesisProvider,X,Z]).find(s=>Z.get(s)!==!0),V=n.useMemo(()=>j.available?v.enabled?ee?{reason:`Missing API key for ${ee}.`,details:"Add provider credentials in Authentication settings.",settingsSection:"authentication"}:null:{reason:"Research is disabled for this project.",details:"Enable project research settings to create runs.",settingsSection:"research-project"}:{reason:j.reason??"Research is unavailable for this project.",details:j.setupInstructions,settingsSection:"research-project"},[j.available,j.reason,j.setupInstructions,v.enabled,ee]),K=async(s,d,b)=>{p(s);try{await d(),t?.(b,"success"),await P()}catch(u){t?.(u instanceof Error?u.message:"Action failed","error")}finally{p(null)}},se=async s=>{if(a){p(`export-${s}`);try{const d=await q(a.id,s),b=new Blob([d.content],{type:"text/plain;charset=utf-8"}),u=URL.createObjectURL(b),C=document.createElement("a");C.href=u,C.download=d.filename,document.body.appendChild(C),C.click(),C.remove(),URL.revokeObjectURL(u),t?.(`Exported ${d.filename}`,"success")}catch(d){t?.(d instanceof Error?d.message:"Export failed","error")}finally{p(null)}}},me=async()=>{if(E.trim()){c(!0);try{const s=l.filter(b=>Y(b));if(s.length===0){c(!1),t?.("No enabled research sources are available for this project.","error");return}const d=await w({query:E.trim(),providers:s});N(d.run.id),o(""),t?.("Research run created","success"),await P()}catch(s){t?.(s instanceof Error?s.message:"Failed to create run","error")}finally{c(!1)}}};return e.jsxs("section",{className:"research-view","aria-label":"Research view",children:[e.jsxs("header",{className:"research-view__header",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"research-view__title",children:"Research"}),e.jsx("p",{className:"research-view__subtitle",children:"Cited search and synthesis runs: gather sources, fetch content, and synthesize findings."})]}),e.jsx("div",{className:"research-view__header-actions",children:e.jsx("button",{className:"btn",type:"button",onClick:()=>void P(),children:"Refresh"})})]}),V?e.jsxs("div",{className:"research-view__state research-view__state--error card","data-testid":"research-state-unavailable",children:[e.jsx("p",{children:V.reason}),V.details&&e.jsx("p",{children:V.details}),e.jsxs("p",{children:["Current defaults: provider ",v.searchProvider??"(not set)",", max sources ",v.limits.maxSourcesPerRun]}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:()=>void P(),children:"Refresh"}),e.jsx("button",{className:"btn btn-primary",type:"button",onClick:()=>i?.(V.settingsSection),children:"Open Settings"})]})]}):e.jsx(e.Fragment,{children:e.jsxs("div",{className:"research-view__layout",children:[e.jsx("aside",{className:"research-view__sidebar card",children:e.jsxs("div",{className:"research-view__sidebar-content",children:[e.jsxs("div",{className:"research-view__form",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-query",children:"Query"}),e.jsx("textarea",{id:"research-query",className:"input research-view__textarea",value:E,onChange:s=>o(s.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Providers"}),e.jsx("div",{className:"research-view__providers",children:G.map(s=>{const d=Y(s),b=s==="web-search";return e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:b||l.includes(s),disabled:b||!d,onChange:()=>{b||!d||h(u=>u.includes(s)?u.filter(C=>C!==s):[...u,s])}}),e.jsxs("span",{children:[Oe[s]??s,b?e.jsx("span",{className:"research-view__provider-lock",children:"Always on"}):null]})]},s)})})]}),e.jsxs("button",{className:"btn btn-primary",type:"button",disabled:!E.trim()||B,onClick:()=>void me(),children:[B?e.jsx(ke,{className:"animate-spin",size:14}):null,"Create Run"]})]}),e.jsxs("div",{className:"research-view__history-header form-group",children:[e.jsx("label",{htmlFor:"research-run-search",children:"Search"}),e.jsxs("div",{className:"research-view__history-search-row",children:[e.jsx(Ce,{size:14}),e.jsx("input",{id:"research-run-search",className:"input",placeholder:"Search runs",value:T,onChange:s=>F(s.target.value)})]})]}),e.jsx("div",{className:"research-view__history","data-testid":"research-state-running",children:y.map(s=>e.jsxs("button",{type:"button",className:`research-view__history-item card${_===s.id?" research-view__history-item--active":""}`,onClick:()=>N(s.id),children:[e.jsx("span",{className:"card-id",children:s.id}),e.jsx("span",{children:s.title})]},s.id))})]})}),e.jsxs("div",{className:"research-view__reader card",children:[A&&e.jsx("p",{"data-testid":"research-state-loading",children:"Loading research runs…"}),!A&&x&&e.jsx("p",{"data-testid":"research-state-error",children:x}),!A&&!x&&y.length===0&&e.jsx("p",{"data-testid":"research-state-empty",children:"No research runs yet"}),e.jsxs("div",{className:"research-view__reader-content",children:[a&&e.jsxs("div",{className:"research-view__run-detail",children:[e.jsxs("div",{className:"research-view__status-row",children:[e.jsx("span",{className:he}),e.jsx("strong",{children:ue})]}),e.jsx("h3",{className:"research-view__run-title",children:a.title}),e.jsx("p",{className:"research-view__run-query",children:a.query}),e.jsx("p",{className:"research-view__run-summary","data-testid":"research-state-results",children:a.results?.summary??"No summary yet."}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",title:g.cancelable?void 0:g.blockingReason,disabled:m==="cancel"||m==="retry"||!g.cancelable,onClick:()=>void K("cancel",()=>D(a.id),"Run cancelled"),children:"Cancel"}),e.jsx("button",{className:"btn",type:"button",title:g.retryable?void 0:g.blockingReason,disabled:m==="cancel"||m==="retry"||!g.retryable,onClick:()=>void K("retry",()=>I(a.id),"Run retried"),children:"Retry"}),J.includes("markdown")&&e.jsx("button",{className:"btn",type:"button",disabled:m==="export-markdown",onClick:()=>void se("markdown"),children:"Export MD"}),J.includes("json")&&e.jsx("button",{className:"btn",type:"button",disabled:m==="export-json",onClick:()=>void se("json"),children:"Export JSON"}),J.includes("html")&&e.jsx("button",{className:"btn",type:"button",disabled:m==="export-html",onClick:()=>void se("html"),children:"Export HTML"})]}),a.error&&e.jsx("p",{className:"research-view__error",children:a.error}),R&&e.jsxs("div",{className:"form-error",role:"alert",children:[e.jsx("p",{children:R.message}),R.setupHint&&e.jsx("p",{children:R.setupHint}),R.code==="MISSING_CREDENTIALS"&&e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>i?.("authentication"),children:"Open Authentication Settings"}),R.code==="FEATURE_DISABLED"&&e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>i?.("research-project"),children:"Open Research Settings"})]}),g.blockingReason&&e.jsx("p",{className:"research-view__run-query",children:g.blockingReason}),Array.isArray(a.results?.findings)&&a.results.findings.length>0&&e.jsx("div",{className:"research-view__findings",children:a.results.findings.map((s,d)=>{const u=s.id?.trim()||`finding-${d+1}`;return e.jsxs("article",{className:"research-view__finding card",children:[e.jsx("h4",{children:s.heading}),e.jsx("p",{children:s.content}),e.jsxs("div",{className:"research-view__actions research-view__finding-actions",children:[e.jsx("button",{className:"btn btn-primary btn-sm",type:"button",onClick:()=>U({mode:"create",findingId:u}),children:"Create Task"}),e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>U({mode:"enrich",findingId:u}),children:"Enrich Task"})]})]},u)})}),Array.isArray(a.results?.citations)&&a.results.citations.length>0&&e.jsx("ul",{className:"research-view__citations",children:a.results.citations.map(s=>e.jsx("li",{children:e.jsx("a",{href:s,target:"_blank",rel:"noreferrer",children:s})},s))}),a.events.length>0&&e.jsxs("details",{children:[e.jsx("summary",{children:"Run history"}),e.jsx("ul",{className:"research-view__events",children:a.events.map(s=>e.jsx("li",{children:s.message},s.id))})]})]}),!a&&y.length>0&&e.jsx("p",{children:"Select a run to view details."}),e.jsxs("div",{className:"research-view__stats",children:[e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Running"}),e.jsx("div",{className:"research-view__stat-value",children:M.running})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Completed"}),e.jsx("div",{className:"research-view__stat-value",children:M.completed})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Failed"}),e.jsx("div",{className:"research-view__stat-value",children:M.failed})]})]})]})]})]})}),a&&S&&(()=>{const s=a.results?.findings?.findIndex((b,u)=>(b.id?.trim()||`finding-${u+1}`)===S.findingId)??-1,d=s>=0?a.results.findings[s]:null;return d?e.jsx(Fe,{open:!0,mode:S.mode,run:a,finding:{id:S.findingId,heading:d.heading,content:d.content},projectId:r,onClose:()=>U(null),onConfirm:async({taskId:b,title:u,description:C,priority:ce,attachExport:ie})=>{S.mode==="create"?await K("create-task",()=>L(a.id,u,S.findingId,C,ce,ie),"Task created from research"):b&&await K("attach-task",()=>H(a.id,b,S.findingId,ie),"Task enriched from research"),U(null)}}):null})()]})}export{Be as ResearchView};
1
+ import{r as n,j as e}from"./vendor-react-K0fH_qHe.js";import{a7 as z,a8 as le,a9 as oe,ak as de,aE as be,ac as te,aF as fe,s as ve,aG as W,aH as xe,aI as pe,aJ as ye,aK as ge,aL as Re,aM as _e,ao as je,u as Se,aN as we,x as Ne,aO as Ee,L as ke,S as Ce}from"./index-w1dPHtmq.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const Ae="builtin",Q={pageFetch:!0,github:!1,localDocs:!0,llmSynthesis:!0};function ae(r){const t=r?.researchGlobalDefaults,i=r?.researchSettings;return{enabled:i?.enabled??r?.researchEnabled??r?.researchGlobalEnabled??!0,searchProvider:i?.searchProvider??t?.searchProvider??r?.researchGlobalWebSearchProvider??Ae,synthesisProvider:i?.synthesisProvider??t?.synthesisProvider,synthesisModelId:i?.synthesisModelId??t?.synthesisModelId,enabledSources:{webSearch:!0,pageFetch:i?.enabledSources?.pageFetch??t?.enabledSources?.pageFetch??Q.pageFetch,github:i?.enabledSources?.github??t?.enabledSources?.github??Q.github,localDocs:i?.enabledSources?.localDocs??t?.enabledSources?.localDocs??Q.localDocs,llmSynthesis:i?.enabledSources?.llmSynthesis??t?.enabledSources?.llmSynthesis??Q.llmSynthesis},limits:{maxConcurrentRuns:i?.limits?.maxConcurrentRuns??r?.researchMaxConcurrentRuns??r?.researchGlobalMaxConcurrentRuns??3,maxSourcesPerRun:i?.limits?.maxSourcesPerRun??t?.maxSourcesPerRun??r?.researchMaxSourcesPerRun??r?.researchGlobalMaxSourcesPerRun??20,maxDurationMs:i?.limits?.maxDurationMs??r?.researchDefaultTimeout??r?.researchGlobalDefaultTimeout??3e5,requestTimeoutMs:i?.limits?.requestTimeoutMs??r?.researchGlobalFetchTimeoutMs??3e4},defaultExportFormat:t?.defaultExportFormat??"markdown"}}const Pe=300,Te=4e3,Ie=["queued","running","cancelling","retry_waiting"];function re(r,t){if(r instanceof je){const i=r;return{message:r.message,status:r.status,code:i.researchCode??"INTERNAL_ERROR",setupHint:i.setupHint,retryable:i.retryable}}return r instanceof Error?{message:r.message,code:"INTERNAL_ERROR"}:{message:t,code:"INTERNAL_ERROR"}}function Le(r){if(!r)return{cancelable:!1,retryable:!1,isTransitioning:!1,blockingReason:"No run selected"};const t=Ie.includes(r.status),i=r.status==="queued"||r.status==="running",f=r.lifecycle?.retryable,y=r.status==="failed"||r.status==="timed_out",a=!!(y&&f);let _;return!i&&t?_="Run is already transitioning":!i&&r.status==="completed"?_="Completed runs cannot be cancelled":!i&&r.status==="cancelled"?_="Run is already cancelled":!i&&r.status==="retry_exhausted"?_="Retry attempts exhausted":!i&&r.status==="failed"?_="Failed runs cannot be cancelled":!i&&r.status==="timed_out"&&(_="Timed out runs cannot be cancelled"),!a&&y&&f===!1&&(_=r.lifecycle?.errorCode==="RETRY_EXHAUSTED"?"Retry attempts exhausted":"Run is not retryable"),{cancelable:i,retryable:a,isTransitioning:t,blockingReason:_}}function Me(r){const t=r?.projectId,i=t??"",f=`${oe.RESEARCH_RUNS_PREFIX}${i}`,y=`${oe.RESEARCH_SELECTED_ID_PREFIX}${i}`,a=z(f,{maxAgeMs:le}),_=z(y,{maxAgeMs:de}),N=n.useRef(Array.isArray(a)&&a.length>0),[j,A]=n.useState(()=>Array.isArray(a)?a:[]),[x,T]=n.useState(_??null),[F,w]=n.useState(null),[D,I]=n.useState({available:!0}),[q,L]=n.useState(!(Array.isArray(a)&&a.length>0)),[H,M]=n.useState(null),[P,R]=n.useState(null),[g,E]=n.useState(""),o=n.useRef(0),v=n.useRef(0),$=n.useRef(t);n.useEffect(()=>{$.current!==t&&($.current=t,v.current++);const c=z(f,{maxAgeMs:le}),l=z(y,{maxAgeMs:de}),h=Array.isArray(c)&&c.length>0;A(Array.isArray(c)?c:[]),T(l??null),w(null),L(!h),N.current=h},[t,f,y]);const k=n.useCallback(async(c=g)=>{const l=++o.current,h=t;N.current||L(!0),M(null),R(null);try{const m=await be({q:c||void 0,limit:100},h);if(l!==o.current||h!==t)return;A(m.runs),te(f,m.runs,{maxBytes:5e5}),N.current=!0,I(m.availability),x&&!m.runs.some(p=>p.id===x)&&(T(null),te(y,null,{maxBytes:5e5}),w(null))}catch(m){if(l!==o.current||h!==t)return;const p=re(m,"Failed to load research runs");M(p.message),R(p)}finally{l===o.current&&L(!1)}},[t,f,g,y,x]),O=n.useCallback(async c=>{const l=await fe(c,t);return w(l.run),I(l.availability),l.run},[t]);n.useEffect(()=>{N.current||L(!0);const c=window.setTimeout(()=>{k(g)},Pe);return()=>window.clearTimeout(c)},[k,g]),n.useEffect(()=>{if(!x){w(null);return}O(x)},[O,x]),n.useEffect(()=>{const c=v.current,l=()=>v.current!==c,h=t?`?projectId=${encodeURIComponent(t)}`:"";let m=!0;const p=()=>{!m||l()||(k(),x&&O(x))},S=`/api/events${h}`,U=ve(S,{events:{"research:run:created":p,"research:run:updated":p,"research:run:completed":p,"research:run:failed":p,"research:run:cancelled":p},onReconnect:()=>{W({view:"useResearch",trigger:"sse-reconnect",projectId:t,replayAttempted:!1,sseChannel:S}),p()}});W({view:"useResearch",trigger:"sse-open",projectId:t,replayAttempted:!1,sseChannel:S});const G=window.setInterval(p,Te);return()=>{m=!1,U(),window.clearInterval(G)}},[t,k,x,O]);const B=n.useCallback(c=>{T(c),te(y,c,{maxBytes:5e5})},[y]);return{runs:j,selectedRun:F,selectedRunId:x,setSelectedRunId:B,availability:D,loading:q,error:H,searchQuery:g,setSearchQuery:E,refresh:k,createRun:c=>_e(c,t),cancelRun:async c=>{try{R(null);const l=await Re(c,t);return x===c&&w(l.run),await k(),l}catch(l){const h=re(l,"Failed to cancel run");throw R(h),h}},retryRun:async c=>{try{R(null);const l=await ge(c,t);return x===c&&w(l.run),await k(),l}catch(l){const h=re(l,"Failed to retry run");throw R(h),h}},exportRun:(c,l)=>ye(c,l,t),createTaskFromRun:(c,l,h,m,p,S)=>pe(c,{title:l,findingId:h,description:m,priority:p,attachExport:S},t),attachRunToTask:(c,l,h,m)=>xe(c,{taskId:l,findingId:h,attachExport:m},t),uiError:P,runActionState:Le(F),statusCounts:j.reduce((c,l)=>(c[l.status]+=1,c),{queued:0,running:0,cancelling:0,retry_waiting:0,completed:0,failed:0,cancelled:0,timed_out:0,retry_exhausted:0})}}function Fe({open:r,mode:t,run:i,finding:f,projectId:y,onClose:a,onConfirm:_}){Se(r);const[N,j]=n.useState(!1),[A,x]=n.useState(""),[T,F]=n.useState(""),[w,D]=n.useState("normal"),[I,q]=n.useState(""),[L,H]=n.useState([]),[M,P]=n.useState(!1),[R,g]=n.useState(!1),E=n.useMemo(()=>{const o=(f.content??"").split(/(?<=[.!?])\s+/)[0]??"";return`${f.heading||"Research finding"} — ${o}`.trim()},[f.content,f.heading]);return n.useEffect(()=>{r&&(j(!1),x(`Research: ${f.heading||i.title}`),F(E),D("normal"),q(""),t==="enrich"&&(P(!0),we(50,0,y).then(o=>H(o.filter(v=>v.column!=="archived"))).finally(()=>P(!1))))},[r,t,y,f.heading,E,i.title]),r?e.jsx("div",{className:"modal-overlay open",role:"presentation",onClick:a,children:e.jsxs("div",{className:"modal modal-lg research-task-action-modal",role:"dialog","aria-modal":"true",onClick:o=>o.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:t==="create"?"Create task from finding":"Enrich existing task"}),e.jsx("button",{className:"modal-close",type:"button","aria-label":"Close",onClick:a,children:"×"})]}),e.jsxs("div",{className:"research-task-action-modal__body",children:[e.jsxs("div",{className:"card research-task-action-modal__preview",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Run:"})," ",i.id]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Finding:"})," ",f.id,f.heading?` — ${f.heading}`:""]}),e.jsx("p",{children:E||"No preview available."})]}),t==="create"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"research-task-action-modal__field",children:["Title",e.jsx("input",{className:"input",value:A,onChange:o=>x(o.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Description",e.jsx("textarea",{className:"input research-task-action-modal__textarea",value:T,onChange:o=>F(o.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Priority",e.jsxs("select",{className:"select",value:w,onChange:o=>D(o.target.value),children:[e.jsx("option",{value:"low",children:"Low"}),e.jsx("option",{value:"normal",children:"Normal"}),e.jsx("option",{value:"high",children:"High"}),e.jsx("option",{value:"urgent",children:"Urgent"})]})]})]}):e.jsxs("label",{className:"research-task-action-modal__field",children:["Target task",e.jsx("input",{className:"input",list:"research-task-action-task-list",value:I,placeholder:M?"Loading tasks…":"Enter task ID",onChange:o=>q(o.target.value)}),e.jsx("datalist",{id:"research-task-action-task-list",children:L.map(o=>e.jsx("option",{value:o.id,children:o.title},o.id))})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:N,onChange:o=>j(o.target.checked)}),e.jsx("span",{children:"Attach markdown export artifact"})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:a,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",type:"button",disabled:R||t==="enrich"&&!I,onClick:()=>{g(!0),_({taskId:t==="enrich"?I:void 0,title:t==="create"?A.trim():void 0,description:t==="create"?T.trim():void 0,priority:t==="create"?w:void 0,attachExport:N}).finally(()=>g(!1))},children:t==="create"?"Create Task":"Enrich Task"})]})]})}):null}const De=["web-search","page-fetch","github","local-docs","llm-synthesis"],qe={"web-search":"webSearch","page-fetch":"pageFetch",github:"github","local-docs":"localDocs","llm-synthesis":"llmSynthesis"},Oe={"web-search":"Web Search","page-fetch":"Page Fetch",github:"GitHub","local-docs":"Local Docs","llm-synthesis":"LLM Synthesis"};let ne=!1;function Be({projectId:r,addToast:t,onOpenSettings:i,readinessVersion:f=0}){n.useEffect(()=>(W({view:"ResearchView",trigger:ne?"route-active":"remount",projectId:r,replayAttempted:!1}),ne=!1,()=>{ne=!0,W({view:"ResearchView",trigger:"route-inactive",projectId:r,replayAttempted:!1})}),[r]);const{runs:y,selectedRun:a,selectedRunId:_,setSelectedRunId:N,availability:j,loading:A,error:x,searchQuery:T,setSearchQuery:F,createRun:w,cancelRun:D,retryRun:I,exportRun:q,createTaskFromRun:L,attachRunToTask:H,statusCounts:M,refresh:P,uiError:R,runActionState:g}=Me({projectId:r}),[E,o]=n.useState(""),[v,$]=n.useState(()=>ae(void 0)),[k,O]=n.useState([]),[B,c]=n.useState(!1),[l,h]=n.useState([]),[m,p]=n.useState(null),[S,U]=n.useState(null),G=j.supportedProviders??De,X=v.searchProvider,Y=s=>s==="web-search"?!0:v.enabledSources[qe[s]];n.useEffect(()=>{const s=G.filter(d=>Y(d));h(d=>{const b=d.filter(u=>s.includes(u));return b.length>0?b:s})},[v.enabledSources,G]),n.useEffect(()=>{let s=!1;return Promise.all([Ne(r),Ee().catch(()=>({providers:[]}))]).then(([d,b])=>{s||($(ae(d)),O(b.providers.filter(u=>u.type==="api_key").map(u=>({id:u.id,authenticated:u.authenticated}))))}).catch(()=>{s||$(ae(void 0))}),()=>{s=!0}},[r,f]);const ue=n.useMemo(()=>a?a.status:"No run selected",[a]),he=n.useMemo(()=>a?a.status==="queued"||a.status==="retry_waiting"?"status-dot status-dot--pending":a.status==="running"?"status-dot status-dot--connecting":a.status==="completed"?"status-dot status-dot--online":a.status==="failed"||a.status==="cancelled"?"status-dot status-dot--error":"status-dot":"status-dot",[a]),J=j.supportedExportFormats??["markdown","json","html"],Z=n.useMemo(()=>new Map(k.map(s=>[s.id,s.authenticated])),[k]),ee=n.useMemo(()=>{const s=new Set;return v.enabledSources.webSearch&&X&&s.add(X),v.enabledSources.llmSynthesis&&v.synthesisProvider&&s.add(v.synthesisProvider),[...s].filter(d=>Z.has(d))},[v.enabledSources.llmSynthesis,v.enabledSources.webSearch,v.synthesisProvider,X,Z]).find(s=>Z.get(s)!==!0),V=n.useMemo(()=>j.available?v.enabled?ee?{reason:`Missing API key for ${ee}.`,details:"Add provider credentials in Authentication settings.",settingsSection:"authentication"}:null:{reason:"Research is disabled for this project.",details:"Enable project research settings to create runs.",settingsSection:"research-project"}:{reason:j.reason??"Research is unavailable for this project.",details:j.setupInstructions,settingsSection:"research-project"},[j.available,j.reason,j.setupInstructions,v.enabled,ee]),K=async(s,d,b)=>{p(s);try{await d(),t?.(b,"success"),await P()}catch(u){t?.(u instanceof Error?u.message:"Action failed","error")}finally{p(null)}},se=async s=>{if(a){p(`export-${s}`);try{const d=await q(a.id,s),b=new Blob([d.content],{type:"text/plain;charset=utf-8"}),u=URL.createObjectURL(b),C=document.createElement("a");C.href=u,C.download=d.filename,document.body.appendChild(C),C.click(),C.remove(),URL.revokeObjectURL(u),t?.(`Exported ${d.filename}`,"success")}catch(d){t?.(d instanceof Error?d.message:"Export failed","error")}finally{p(null)}}},me=async()=>{if(E.trim()){c(!0);try{const s=l.filter(b=>Y(b));if(s.length===0){c(!1),t?.("No enabled research sources are available for this project.","error");return}const d=await w({query:E.trim(),providers:s});N(d.run.id),o(""),t?.("Research run created","success"),await P()}catch(s){t?.(s instanceof Error?s.message:"Failed to create run","error")}finally{c(!1)}}};return e.jsxs("section",{className:"research-view","aria-label":"Research view",children:[e.jsxs("header",{className:"research-view__header",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"research-view__title",children:"Research"}),e.jsx("p",{className:"research-view__subtitle",children:"Cited search and synthesis runs: gather sources, fetch content, and synthesize findings."})]}),e.jsx("div",{className:"research-view__header-actions",children:e.jsx("button",{className:"btn",type:"button",onClick:()=>void P(),children:"Refresh"})})]}),V?e.jsxs("div",{className:"research-view__state research-view__state--error card","data-testid":"research-state-unavailable",children:[e.jsx("p",{children:V.reason}),V.details&&e.jsx("p",{children:V.details}),e.jsxs("p",{children:["Current defaults: provider ",v.searchProvider??"(not set)",", max sources ",v.limits.maxSourcesPerRun]}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:()=>void P(),children:"Refresh"}),e.jsx("button",{className:"btn btn-primary",type:"button",onClick:()=>i?.(V.settingsSection),children:"Open Settings"})]})]}):e.jsx(e.Fragment,{children:e.jsxs("div",{className:"research-view__layout",children:[e.jsx("aside",{className:"research-view__sidebar card",children:e.jsxs("div",{className:"research-view__sidebar-content",children:[e.jsxs("div",{className:"research-view__form",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-query",children:"Query"}),e.jsx("textarea",{id:"research-query",className:"input research-view__textarea",value:E,onChange:s=>o(s.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Providers"}),e.jsx("div",{className:"research-view__providers",children:G.map(s=>{const d=Y(s),b=s==="web-search";return e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:b||l.includes(s),disabled:b||!d,onChange:()=>{b||!d||h(u=>u.includes(s)?u.filter(C=>C!==s):[...u,s])}}),e.jsxs("span",{children:[Oe[s]??s,b?e.jsx("span",{className:"research-view__provider-lock",children:"Always on"}):null]})]},s)})})]}),e.jsxs("button",{className:"btn btn-primary",type:"button",disabled:!E.trim()||B,onClick:()=>void me(),children:[B?e.jsx(ke,{className:"animate-spin",size:14}):null,"Create Run"]})]}),e.jsxs("div",{className:"research-view__history-header form-group",children:[e.jsx("label",{htmlFor:"research-run-search",children:"Search"}),e.jsxs("div",{className:"research-view__history-search-row",children:[e.jsx(Ce,{size:14}),e.jsx("input",{id:"research-run-search",className:"input",placeholder:"Search runs",value:T,onChange:s=>F(s.target.value)})]})]}),e.jsx("div",{className:"research-view__history","data-testid":"research-state-running",children:y.map(s=>e.jsxs("button",{type:"button",className:`research-view__history-item card${_===s.id?" research-view__history-item--active":""}`,onClick:()=>N(s.id),children:[e.jsx("span",{className:"card-id",children:s.id}),e.jsx("span",{children:s.title})]},s.id))})]})}),e.jsxs("div",{className:"research-view__reader card",children:[A&&e.jsx("p",{"data-testid":"research-state-loading",children:"Loading research runs…"}),!A&&x&&e.jsx("p",{"data-testid":"research-state-error",children:x}),!A&&!x&&y.length===0&&e.jsx("p",{"data-testid":"research-state-empty",children:"No research runs yet"}),e.jsxs("div",{className:"research-view__reader-content",children:[a&&e.jsxs("div",{className:"research-view__run-detail",children:[e.jsxs("div",{className:"research-view__status-row",children:[e.jsx("span",{className:he}),e.jsx("strong",{children:ue})]}),e.jsx("h3",{className:"research-view__run-title",children:a.title}),e.jsx("p",{className:"research-view__run-query",children:a.query}),e.jsx("p",{className:"research-view__run-summary","data-testid":"research-state-results",children:a.results?.summary??"No summary yet."}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",title:g.cancelable?void 0:g.blockingReason,disabled:m==="cancel"||m==="retry"||!g.cancelable,onClick:()=>void K("cancel",()=>D(a.id),"Run cancelled"),children:"Cancel"}),e.jsx("button",{className:"btn",type:"button",title:g.retryable?void 0:g.blockingReason,disabled:m==="cancel"||m==="retry"||!g.retryable,onClick:()=>void K("retry",()=>I(a.id),"Run retried"),children:"Retry"}),J.includes("markdown")&&e.jsx("button",{className:"btn",type:"button",disabled:m==="export-markdown",onClick:()=>void se("markdown"),children:"Export MD"}),J.includes("json")&&e.jsx("button",{className:"btn",type:"button",disabled:m==="export-json",onClick:()=>void se("json"),children:"Export JSON"}),J.includes("html")&&e.jsx("button",{className:"btn",type:"button",disabled:m==="export-html",onClick:()=>void se("html"),children:"Export HTML"})]}),a.error&&e.jsx("p",{className:"research-view__error",children:a.error}),R&&e.jsxs("div",{className:"form-error",role:"alert",children:[e.jsx("p",{children:R.message}),R.setupHint&&e.jsx("p",{children:R.setupHint}),R.code==="MISSING_CREDENTIALS"&&e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>i?.("authentication"),children:"Open Authentication Settings"}),R.code==="FEATURE_DISABLED"&&e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>i?.("research-project"),children:"Open Research Settings"})]}),g.blockingReason&&e.jsx("p",{className:"research-view__run-query",children:g.blockingReason}),Array.isArray(a.results?.findings)&&a.results.findings.length>0&&e.jsx("div",{className:"research-view__findings",children:a.results.findings.map((s,d)=>{const u=s.id?.trim()||`finding-${d+1}`;return e.jsxs("article",{className:"research-view__finding card",children:[e.jsx("h4",{children:s.heading}),e.jsx("p",{children:s.content}),e.jsxs("div",{className:"research-view__actions research-view__finding-actions",children:[e.jsx("button",{className:"btn btn-primary btn-sm",type:"button",onClick:()=>U({mode:"create",findingId:u}),children:"Create Task"}),e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>U({mode:"enrich",findingId:u}),children:"Enrich Task"})]})]},u)})}),Array.isArray(a.results?.citations)&&a.results.citations.length>0&&e.jsx("ul",{className:"research-view__citations",children:a.results.citations.map(s=>e.jsx("li",{children:e.jsx("a",{href:s,target:"_blank",rel:"noreferrer",children:s})},s))}),a.events.length>0&&e.jsxs("details",{children:[e.jsx("summary",{children:"Run history"}),e.jsx("ul",{className:"research-view__events",children:a.events.map(s=>e.jsx("li",{children:s.message},s.id))})]})]}),!a&&y.length>0&&e.jsx("p",{children:"Select a run to view details."}),e.jsxs("div",{className:"research-view__stats",children:[e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Running"}),e.jsx("div",{className:"research-view__stat-value",children:M.running})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Completed"}),e.jsx("div",{className:"research-view__stat-value",children:M.completed})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Failed"}),e.jsx("div",{className:"research-view__stat-value",children:M.failed})]})]})]})]})]})}),a&&S&&(()=>{const s=a.results?.findings?.findIndex((b,u)=>(b.id?.trim()||`finding-${u+1}`)===S.findingId)??-1,d=s>=0?a.results.findings[s]:null;return d?e.jsx(Fe,{open:!0,mode:S.mode,run:a,finding:{id:S.findingId,heading:d.heading,content:d.content},projectId:r,onClose:()=>U(null),onConfirm:async({taskId:b,title:u,description:C,priority:ce,attachExport:ie})=>{S.mode==="create"?await K("create-task",()=>L(a.id,u,S.findingId,C,ce,ie),"Task created from research"):b&&await K("attach-task",()=>H(a.id,b,S.findingId,ie),"Task enriched from research"),U(null)}}):null})()]})}export{Be as ResearchView};
@@ -1 +1 @@
1
- import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{R as L,J as oe,ae as J,af as q,bB as ie,bC as de,b3 as pe,_ as ue}from"./index-B9Ro_NwC.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const he="__sync_passphrase__",k={key:"",value:"",description:"",scope:"project",accessPolicy:"prompt",envExportable:!1,envExportKey:""},c={className:"secrets-action-icon","aria-hidden":!0,style:{width:"1em",height:"1em"}},me={...c,className:"secrets-action-icon spin"},be=({addToast:o})=>{const[P,Y]=l.useState([]),[R,K]=l.useState(!0),[M,T]=l.useState(null),[_,y]=l.useState(null),[i,A]=l.useState(null),[G,h]=l.useState(!1),[U,b]=l.useState(null),[n,t]=l.useState(k),[N,f]=l.useState(!1),[$,g]=l.useState({}),[z,O]=l.useState(null),[d,Q]=l.useState(!1),[W,D]=l.useState(!1),[v,V]=l.useState(""),[S,F]=l.useState(""),[X,I]=l.useState(!1),C=l.useRef(new Map),E=l.useRef(new Map),r=l.useCallback(async(s,a)=>{const p=await fetch(s,{...a,headers:{"Content-Type":"application/json",...a?.headers??{}}});if(!p.ok){const u=await p.json().catch(()=>({error:"Request failed"}));throw new Error(String(u?.error??"Request failed"))}if(p.status!==204)return p.json()},[]),m=l.useCallback(async()=>{K(!0),T(null);try{const s=await r("/api/secrets");Y(s.secrets)}catch(s){T(s instanceof Error?s.message:String(s))}finally{K(!1)}},[r]),j=l.useCallback(async()=>{try{const s=await r("/api/secrets/sync-passphrase");Q(!!s.configured)}catch(s){o?.(`Failed to load sync passphrase status: ${s instanceof Error?s.message:String(s)}`,"error")}},[o,r]);l.useEffect(()=>(m(),j(),()=>{C.current.forEach(s=>clearTimeout(s)),E.current.forEach(s=>clearTimeout(s))}),[m,j]);const w=()=>{D(!1),V(""),F("")},Z=async s=>{await r("/api/secrets/sync-passphrase",{method:"PUT",body:JSON.stringify({passphrase:s})})},ee=async()=>{I(!0);try{await Z(v),o?.(d?"Sync passphrase rotated":"Sync passphrase set","success"),w(),await j()}catch(s){o?.(`Failed to save sync passphrase: ${s instanceof Error?s.message:String(s)}`,"error")}finally{I(!1)}},se=async()=>{if(window.confirm("Clear the cross-node sync passphrase? Existing sync pairs will stop working until you set a new passphrase."))try{await r("/api/secrets/sync-passphrase",{method:"DELETE"}),o?.("Sync passphrase cleared","success"),await j()}catch(a){o?.(`Failed to clear sync passphrase: ${a instanceof Error?a.message:String(a)}`,"error")}},ae=()=>{A(null),t(k),h(!0),f(!1),y(null)},ne=s=>{A(s),t({key:s.key,value:"",description:s.description??"",scope:s.scope,accessPolicy:s.accessPolicy,envExportable:s.envExportable,envExportKey:s.envExportKey??""}),h(!0),f(!1),y(null)},le=async()=>{y(null);try{if(i){const s={key:n.key,description:n.description||null,accessPolicy:n.accessPolicy,envExportable:n.envExportable,envExportKey:n.envExportable&&n.envExportKey||null};n.value&&(s.value=n.value),await r(`/api/secrets/${i.scope}/${i.id}`,{method:"PATCH",body:JSON.stringify(s)})}else await r("/api/secrets",{method:"POST",body:JSON.stringify({scope:n.scope,key:n.key,value:n.value,description:n.description||null,accessPolicy:n.accessPolicy,envExportable:n.envExportable,envExportKey:n.envExportable&&n.envExportKey||null})});h(!1),t(k),await m()}catch(s){y(s instanceof Error?s.message:String(s))}},te=async s=>{const a=await r(`/api/secrets/${s.scope}/${s.id}/reveal`,{method:"POST"});g(x=>({...x,[s.id]:a.value})),o?.("Revealed","success");const p=setTimeout(()=>{g(x=>({...x,[s.id]:null}))},3e4),u=C.current.get(s.id);u&&clearTimeout(u),C.current.set(s.id,p)},ce=async s=>{const a=$[s.id];if(!a)return;await navigator.clipboard.writeText(a),O(s.id),o?.("Copied","success");const p=setTimeout(()=>{O(null),g(x=>({...x,[s.id]:null}))},1500),u=E.current.get(s.id);u&&clearTimeout(u),E.current.set(s.id,p)},re=async s=>{await r(`/api/secrets/${s.scope}/${s.id}`,{method:"DELETE"}),b(null),await m()},B=l.useMemo(()=>[...P].filter(s=>!(s.scope==="global"&&s.key===he)).sort((s,a)=>s.key.localeCompare(a.key)),[P]),H=v.length>0&&v===S;return e.jsxs("section",{className:"secrets-view",children:[e.jsxs("div",{className:"secrets-header",children:[e.jsx("h2",{children:"Secrets"}),e.jsxs("div",{className:"secrets-header-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:()=>void m(),children:[e.jsx(L,{...c})," Refresh"]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:ae,children:[e.jsx(oe,{...c})," Add Secret"]})]})]}),e.jsxs("article",{className:"card secrets-sync-card",children:[e.jsxs("div",{className:"secrets-sync-header",children:[e.jsxs("div",{children:[e.jsx("h3",{children:"Cross-Node Sync Passphrase"}),e.jsxs("p",{className:"secrets-sync-status",children:[e.jsx("span",{className:`status-dot ${d?"status-dot--online":"status-dot--pending"}`,"aria-hidden":"true"})," ",d?"Configured":"Not configured"]})]}),e.jsxs("div",{className:"secrets-sync-actions",children:[e.jsx("button",{className:"btn",onClick:()=>D(!0),children:d?"Rotate":"Set passphrase"}),d?e.jsx("button",{className:"btn btn-danger",onClick:()=>void se(),children:"Clear"}):null]})]}),e.jsx("p",{className:"secrets-sync-copy",children:"Shared passphrase used to wrap cross-node secret bundles. Both nodes in a sync pair must share the same value. Stored locally only; never transmitted."})]}),M?e.jsx("div",{className:"form-error",children:M}):null,R?e.jsxs("div",{className:"secrets-loading",children:[e.jsx(L,{...me})," Loading…"]}):null,!R&&B.length===0?e.jsx("div",{className:"secrets-empty",children:"No secrets found."}):null,e.jsx("div",{className:"secrets-list",children:B.map(s=>{const a=$[s.id];return e.jsxs("article",{className:"card secrets-row",children:[e.jsxs("div",{className:"secrets-row-main",children:[e.jsx("div",{className:"secrets-row-key",children:s.key}),e.jsxs("div",{className:"secrets-row-meta",children:[e.jsx("span",{className:"secrets-chip",children:s.scope}),e.jsx("span",{className:"secrets-chip",children:s.accessPolicy}),s.envExportable?e.jsx("span",{className:"secrets-chip",children:"env_exportable"}):null]}),a?e.jsx("pre",{className:"secrets-revealed",children:a}):null]}),e.jsxs("div",{className:"secrets-row-side",children:[e.jsx("span",{className:"secrets-row-read",children:s.lastReadAt?new Date(s.lastReadAt).toLocaleString():"Never read"}),e.jsxs("div",{className:"secrets-row-actions",children:[e.jsx("button",{type:"button",className:"btn btn-icon secrets-visibility-toggle",onClick:()=>void te(s),"aria-label":a?"Hide":"Reveal",children:a?e.jsx(J,{...c}):e.jsx(q,{...c})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>void ce(s),"aria-label":"Copy",disabled:!a,children:z===s.id?e.jsx(ie,{...c}):e.jsx(de,{...c})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>ne(s),"aria-label":"Edit",children:e.jsx(pe,{...c})}),e.jsx("button",{className:"btn btn-icon btn-danger",onClick:()=>b(s.id),"aria-label":"Delete",children:e.jsx(ue,{...c})})]}),U===s.id?e.jsxs("div",{className:"secrets-confirm",children:[e.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void re(s),children:"Confirm"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>b(null),children:"Cancel"})]}):null]})]},s.id)})}),W?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":d?"Rotate sync passphrase":"Set sync passphrase",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:d?"Rotate sync passphrase":"Set sync passphrase"}),e.jsx("button",{className:"modal-close",onClick:w,"aria-label":"Close",children:"×"})]}),e.jsxs("div",{className:"secrets-modal-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Passphrase"}),e.jsx("input",{"aria-label":"Passphrase",className:"input",type:"password",autoComplete:"new-password",value:v,onChange:s=>V(s.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Confirm passphrase"}),e.jsx("input",{"aria-label":"Confirm passphrase",className:"input",type:"password",autoComplete:"new-password",value:S,onChange:s=>F(s.target.value)})]}),!H&&S.length>0?e.jsx("div",{className:"form-error",children:"Passphrases must match."}):null]}),e.jsx("div",{className:"modal-actions",children:e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn",onClick:w,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void ee(),disabled:!H||X,children:d?"Rotate":"Set passphrase"})]})})]})}):null,G?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":i?"Edit secret":"Add secret",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:i?"Edit secret":"Add secret"}),e.jsx("button",{className:"modal-close",onClick:()=>h(!1),"aria-label":"Close",children:"×"})]}),e.jsxs("div",{className:"secrets-modal-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Key"}),e.jsx("input",{className:"input",value:n.key,onChange:s=>t(a=>({...a,key:s.target.value}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Value"}),e.jsxs("div",{className:"secrets-value-row",children:[e.jsx("input",{className:"input",type:N?"text":"password",autoComplete:"off",spellCheck:!1,value:n.value,onChange:s=>t(a=>({...a,value:s.target.value}))}),e.jsx("button",{type:"button",className:"btn btn-icon secrets-visibility-toggle",onClick:()=>f(s=>!s),"aria-label":N?"Hide value":"Show value",children:N?e.jsx(J,{...c}):e.jsx(q,{...c})})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Description"}),e.jsx("textarea",{className:"input",value:n.description,onChange:s=>t(a=>({...a,description:s.target.value}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Scope"}),e.jsxs("div",{className:"secrets-radio-row",children:[e.jsxs("label",{children:[e.jsx("input",{type:"radio",checked:n.scope==="project",onChange:()=>t(s=>({...s,scope:"project"})),disabled:!!i})," Project"]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",checked:n.scope==="global",onChange:()=>t(s=>({...s,scope:"global"})),disabled:!!i})," Global"]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Access policy"}),e.jsxs("select",{className:"select",value:n.accessPolicy,onChange:s=>t(a=>({...a,accessPolicy:s.target.value})),children:[e.jsx("option",{value:"auto",children:"auto"}),e.jsx("option",{value:"prompt",children:"prompt"}),e.jsx("option",{value:"deny",children:"deny"})]})]}),e.jsx("div",{className:"form-group",children:e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:n.envExportable,onChange:s=>t(a=>({...a,envExportable:s.target.checked}))})," Export to env"]})}),n.envExportable?e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Env key"}),e.jsx("input",{className:"input",value:n.envExportKey,onChange:s=>t(a=>({...a,envExportKey:s.target.value}))})]}):null,_?e.jsx("div",{className:"form-error",children:_}):null]}),e.jsx("div",{className:"modal-actions",children:e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn",onClick:()=>h(!1),children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void le(),children:i?"Save":"Create"})]})})]})}):null]})};export{be as SecretsView};
1
+ import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{R as B,J as oe,ae as J,af as q,bC as ie,bD as de,b4 as pe,_ as ue}from"./index-w1dPHtmq.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const he="__sync_passphrase__",k={key:"",value:"",description:"",scope:"project",accessPolicy:"prompt",envExportable:!1,envExportKey:""},c={className:"secrets-action-icon","aria-hidden":!0,style:{width:"1em",height:"1em"}},me={...c,className:"secrets-action-icon spin"},be=({addToast:o})=>{const[P,Y]=l.useState([]),[R,K]=l.useState(!0),[M,T]=l.useState(null),[_,y]=l.useState(null),[i,A]=l.useState(null),[G,h]=l.useState(!1),[U,b]=l.useState(null),[n,t]=l.useState(k),[N,f]=l.useState(!1),[$,g]=l.useState({}),[z,D]=l.useState(null),[d,Q]=l.useState(!1),[W,O]=l.useState(!1),[v,V]=l.useState(""),[S,F]=l.useState(""),[X,I]=l.useState(!1),C=l.useRef(new Map),E=l.useRef(new Map),r=l.useCallback(async(s,a)=>{const p=await fetch(s,{...a,headers:{"Content-Type":"application/json",...a?.headers??{}}});if(!p.ok){const u=await p.json().catch(()=>({error:"Request failed"}));throw new Error(String(u?.error??"Request failed"))}if(p.status!==204)return p.json()},[]),m=l.useCallback(async()=>{K(!0),T(null);try{const s=await r("/api/secrets");Y(s.secrets)}catch(s){T(s instanceof Error?s.message:String(s))}finally{K(!1)}},[r]),j=l.useCallback(async()=>{try{const s=await r("/api/secrets/sync-passphrase");Q(!!s.configured)}catch(s){o?.(`Failed to load sync passphrase status: ${s instanceof Error?s.message:String(s)}`,"error")}},[o,r]);l.useEffect(()=>(m(),j(),()=>{C.current.forEach(s=>clearTimeout(s)),E.current.forEach(s=>clearTimeout(s))}),[m,j]);const w=()=>{O(!1),V(""),F("")},Z=async s=>{await r("/api/secrets/sync-passphrase",{method:"PUT",body:JSON.stringify({passphrase:s})})},ee=async()=>{I(!0);try{await Z(v),o?.(d?"Sync passphrase rotated":"Sync passphrase set","success"),w(),await j()}catch(s){o?.(`Failed to save sync passphrase: ${s instanceof Error?s.message:String(s)}`,"error")}finally{I(!1)}},se=async()=>{if(window.confirm("Clear the cross-node sync passphrase? Existing sync pairs will stop working until you set a new passphrase."))try{await r("/api/secrets/sync-passphrase",{method:"DELETE"}),o?.("Sync passphrase cleared","success"),await j()}catch(a){o?.(`Failed to clear sync passphrase: ${a instanceof Error?a.message:String(a)}`,"error")}},ae=()=>{A(null),t(k),h(!0),f(!1),y(null)},ne=s=>{A(s),t({key:s.key,value:"",description:s.description??"",scope:s.scope,accessPolicy:s.accessPolicy,envExportable:s.envExportable,envExportKey:s.envExportKey??""}),h(!0),f(!1),y(null)},le=async()=>{y(null);try{if(i){const s={key:n.key,description:n.description||null,accessPolicy:n.accessPolicy,envExportable:n.envExportable,envExportKey:n.envExportable&&n.envExportKey||null};n.value&&(s.value=n.value),await r(`/api/secrets/${i.scope}/${i.id}`,{method:"PATCH",body:JSON.stringify(s)})}else await r("/api/secrets",{method:"POST",body:JSON.stringify({scope:n.scope,key:n.key,value:n.value,description:n.description||null,accessPolicy:n.accessPolicy,envExportable:n.envExportable,envExportKey:n.envExportable&&n.envExportKey||null})});h(!1),t(k),await m()}catch(s){y(s instanceof Error?s.message:String(s))}},te=async s=>{const a=await r(`/api/secrets/${s.scope}/${s.id}/reveal`,{method:"POST"});g(x=>({...x,[s.id]:a.value})),o?.("Revealed","success");const p=setTimeout(()=>{g(x=>({...x,[s.id]:null}))},3e4),u=C.current.get(s.id);u&&clearTimeout(u),C.current.set(s.id,p)},ce=async s=>{const a=$[s.id];if(!a)return;await navigator.clipboard.writeText(a),D(s.id),o?.("Copied","success");const p=setTimeout(()=>{D(null),g(x=>({...x,[s.id]:null}))},1500),u=E.current.get(s.id);u&&clearTimeout(u),E.current.set(s.id,p)},re=async s=>{await r(`/api/secrets/${s.scope}/${s.id}`,{method:"DELETE"}),b(null),await m()},H=l.useMemo(()=>[...P].filter(s=>!(s.scope==="global"&&s.key===he)).sort((s,a)=>s.key.localeCompare(a.key)),[P]),L=v.length>0&&v===S;return e.jsxs("section",{className:"secrets-view",children:[e.jsxs("div",{className:"secrets-header",children:[e.jsx("h2",{children:"Secrets"}),e.jsxs("div",{className:"secrets-header-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:()=>void m(),children:[e.jsx(B,{...c})," Refresh"]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:ae,children:[e.jsx(oe,{...c})," Add Secret"]})]})]}),e.jsxs("article",{className:"card secrets-sync-card",children:[e.jsxs("div",{className:"secrets-sync-header",children:[e.jsxs("div",{children:[e.jsx("h3",{children:"Cross-Node Sync Passphrase"}),e.jsxs("p",{className:"secrets-sync-status",children:[e.jsx("span",{className:`status-dot ${d?"status-dot--online":"status-dot--pending"}`,"aria-hidden":"true"})," ",d?"Configured":"Not configured"]})]}),e.jsxs("div",{className:"secrets-sync-actions",children:[e.jsx("button",{className:"btn",onClick:()=>O(!0),children:d?"Rotate":"Set passphrase"}),d?e.jsx("button",{className:"btn btn-danger",onClick:()=>void se(),children:"Clear"}):null]})]}),e.jsx("p",{className:"secrets-sync-copy",children:"Shared passphrase used to wrap cross-node secret bundles. Both nodes in a sync pair must share the same value. Stored locally only; never transmitted."})]}),M?e.jsx("div",{className:"form-error",children:M}):null,R?e.jsxs("div",{className:"secrets-loading",children:[e.jsx(B,{...me})," Loading…"]}):null,!R&&H.length===0?e.jsx("div",{className:"secrets-empty",children:"No secrets found."}):null,e.jsx("div",{className:"secrets-list",children:H.map(s=>{const a=$[s.id];return e.jsxs("article",{className:"card secrets-row",children:[e.jsxs("div",{className:"secrets-row-main",children:[e.jsx("div",{className:"secrets-row-key",children:s.key}),e.jsxs("div",{className:"secrets-row-meta",children:[e.jsx("span",{className:"secrets-chip",children:s.scope}),e.jsx("span",{className:"secrets-chip",children:s.accessPolicy}),s.envExportable?e.jsx("span",{className:"secrets-chip",children:"env_exportable"}):null]}),a?e.jsx("pre",{className:"secrets-revealed",children:a}):null]}),e.jsxs("div",{className:"secrets-row-side",children:[e.jsx("span",{className:"secrets-row-read",children:s.lastReadAt?new Date(s.lastReadAt).toLocaleString():"Never read"}),e.jsxs("div",{className:"secrets-row-actions",children:[e.jsx("button",{type:"button",className:"btn btn-icon secrets-visibility-toggle",onClick:()=>void te(s),"aria-label":a?"Hide":"Reveal",children:a?e.jsx(J,{...c}):e.jsx(q,{...c})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>void ce(s),"aria-label":"Copy",disabled:!a,children:z===s.id?e.jsx(ie,{...c}):e.jsx(de,{...c})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>ne(s),"aria-label":"Edit",children:e.jsx(pe,{...c})}),e.jsx("button",{className:"btn btn-icon btn-danger",onClick:()=>b(s.id),"aria-label":"Delete",children:e.jsx(ue,{...c})})]}),U===s.id?e.jsxs("div",{className:"secrets-confirm",children:[e.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void re(s),children:"Confirm"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>b(null),children:"Cancel"})]}):null]})]},s.id)})}),W?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":d?"Rotate sync passphrase":"Set sync passphrase",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:d?"Rotate sync passphrase":"Set sync passphrase"}),e.jsx("button",{className:"modal-close",onClick:w,"aria-label":"Close",children:"×"})]}),e.jsxs("div",{className:"secrets-modal-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Passphrase"}),e.jsx("input",{"aria-label":"Passphrase",className:"input",type:"password",autoComplete:"new-password",value:v,onChange:s=>V(s.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Confirm passphrase"}),e.jsx("input",{"aria-label":"Confirm passphrase",className:"input",type:"password",autoComplete:"new-password",value:S,onChange:s=>F(s.target.value)})]}),!L&&S.length>0?e.jsx("div",{className:"form-error",children:"Passphrases must match."}):null]}),e.jsx("div",{className:"modal-actions",children:e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn",onClick:w,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void ee(),disabled:!L||X,children:d?"Rotate":"Set passphrase"})]})})]})}):null,G?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":i?"Edit secret":"Add secret",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:i?"Edit secret":"Add secret"}),e.jsx("button",{className:"modal-close",onClick:()=>h(!1),"aria-label":"Close",children:"×"})]}),e.jsxs("div",{className:"secrets-modal-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Key"}),e.jsx("input",{className:"input",value:n.key,onChange:s=>t(a=>({...a,key:s.target.value}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Value"}),e.jsxs("div",{className:"secrets-value-row",children:[e.jsx("input",{className:"input",type:N?"text":"password",autoComplete:"off",spellCheck:!1,value:n.value,onChange:s=>t(a=>({...a,value:s.target.value}))}),e.jsx("button",{type:"button",className:"btn btn-icon secrets-visibility-toggle",onClick:()=>f(s=>!s),"aria-label":N?"Hide value":"Show value",children:N?e.jsx(J,{...c}):e.jsx(q,{...c})})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Description"}),e.jsx("textarea",{className:"input",value:n.description,onChange:s=>t(a=>({...a,description:s.target.value}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Scope"}),e.jsxs("div",{className:"secrets-radio-row",children:[e.jsxs("label",{children:[e.jsx("input",{type:"radio",checked:n.scope==="project",onChange:()=>t(s=>({...s,scope:"project"})),disabled:!!i})," Project"]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",checked:n.scope==="global",onChange:()=>t(s=>({...s,scope:"global"})),disabled:!!i})," Global"]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Access policy"}),e.jsxs("select",{className:"select",value:n.accessPolicy,onChange:s=>t(a=>({...a,accessPolicy:s.target.value})),children:[e.jsx("option",{value:"auto",children:"auto"}),e.jsx("option",{value:"prompt",children:"prompt"}),e.jsx("option",{value:"deny",children:"deny"})]})]}),e.jsx("div",{className:"form-group",children:e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:n.envExportable,onChange:s=>t(a=>({...a,envExportable:s.target.checked}))})," Export to env"]})}),n.envExportable?e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Env key"}),e.jsx("input",{className:"input",value:n.envExportKey,onChange:s=>t(a=>({...a,envExportKey:s.target.value}))})]}):null,_?e.jsx("div",{className:"form-error",children:_}):null]}),e.jsx("div",{className:"modal-actions",children:e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn",onClick:()=>h(!1),children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void le(),children:i?"Save":"Create"})]})})]})}):null]})};export{be as SecretsView};
@@ -1 +1 @@
1
- import{r as e}from"./vendor-react-K0fH_qHe.js";import{dZ as C}from"./index-B9Ro_NwC.js";function L(k={}){const{projectId:d,pollInterval:b=6e4,autoRefresh:p=!1,enabled:t=!0}=k,[S,o]=e.useState(null),[m,l]=e.useState(t),[E,c]=e.useState(null),[R,v]=e.useState(null),r=e.useRef(null),n=e.useRef(null),a=e.useRef(!0),s=e.useCallback(async()=>{if(!t){l(!1),c(null),o(null);return}r.current&&r.current.abort(),r.current=new AbortController,l(!0),c(null),o(null);try{const u=await C(d);if(!a.current)return;o(u),c(null),v(new Date),l(!1)}catch(u){if(u instanceof Error&&u.name==="AbortError"||!a.current)return;const A=u instanceof Error?u.message:"Failed to fetch memory backend status";c(A),l(!1)}},[t,d]);e.useEffect(()=>(a.current=!0,t?(s(),()=>{a.current=!1}):(r.current&&r.current.abort(),o(null),c(null),l(!1),()=>{a.current=!1})),[t,s]),e.useEffect(()=>{if(!(!t||!p))return n.current=setInterval(()=>{s()},b),()=>{n.current&&(clearInterval(n.current),n.current=null)}},[t,p,b,s]),e.useEffect(()=>()=>{a.current=!1,r.current&&r.current.abort(),n.current&&(clearInterval(n.current),n.current=null)},[]);const h=e.useCallback(()=>s(),[s]),f=m?null:S,B=f?.currentBackend??null,i=f?.capabilities??null,y=f?.availableBackends??[],I=i?.readable??!1,g=i?.writable??!1,w=i?.supportsAtomicWrite??!1;return{status:f,currentBackend:B,capabilities:i,availableBackends:y,isReadable:I,isWritable:g,supportsAtomicWrite:w,loading:m,error:E,lastUpdated:R,refresh:h}}export{L as u};
1
+ import{r as e}from"./vendor-react-K0fH_qHe.js";import{d$ as C}from"./index-w1dPHtmq.js";function L(k={}){const{projectId:d,pollInterval:b=6e4,autoRefresh:p=!1,enabled:t=!0}=k,[S,o]=e.useState(null),[m,l]=e.useState(t),[E,c]=e.useState(null),[R,v]=e.useState(null),r=e.useRef(null),n=e.useRef(null),a=e.useRef(!0),s=e.useCallback(async()=>{if(!t){l(!1),c(null),o(null);return}r.current&&r.current.abort(),r.current=new AbortController,l(!0),c(null),o(null);try{const u=await C(d);if(!a.current)return;o(u),c(null),v(new Date),l(!1)}catch(u){if(u instanceof Error&&u.name==="AbortError"||!a.current)return;const A=u instanceof Error?u.message:"Failed to fetch memory backend status";c(A),l(!1)}},[t,d]);e.useEffect(()=>(a.current=!0,t?(s(),()=>{a.current=!1}):(r.current&&r.current.abort(),o(null),c(null),l(!1),()=>{a.current=!1})),[t,s]),e.useEffect(()=>{if(!(!t||!p))return n.current=setInterval(()=>{s()},b),()=>{n.current&&(clearInterval(n.current),n.current=null)}},[t,p,b,s]),e.useEffect(()=>()=>{a.current=!1,r.current&&r.current.abort(),n.current&&(clearInterval(n.current),n.current=null)},[]);const h=e.useCallback(()=>s(),[s]),f=m?null:S,B=f?.currentBackend??null,i=f?.capabilities??null,y=f?.availableBackends??[],I=i?.readable??!1,g=i?.writable??!1,w=i?.supportsAtomicWrite??!1;return{status:f,currentBackend:B,capabilities:i,availableBackends:y,isReadable:I,isWritable:g,supportsAtomicWrite:w,loading:m,error:E,lastUpdated:R,refresh:h}}export{L as u};
@@ -0,0 +1 @@
1
+ .settings-header-actions{--settings-header-action-height: calc(var(--space-md) * 2 + var(--space-xs) / 2);display:flex;align-items:stretch;gap:var(--space-xs);margin-left:auto;margin-right:var(--space-sm)}.settings-header-actions>.settings-github-star-btn,.settings-header-actions>.settings-header-help-btn{height:var(--settings-header-action-height);box-sizing:border-box}.settings-header-help-btn{display:inline-flex;align-items:center}@media(max-width:768px){.settings-modal .modal-header{flex-wrap:nowrap;align-items:center;column-gap:var(--space-sm)}.settings-modal-heading{flex:1 1 0;min-width:0}.settings-update-check{flex-wrap:wrap;row-gap:var(--space-xs)}.settings-header-actions{margin-left:auto;margin-right:var(--space-sm)}}.settings-github-star-btn{display:inline-flex;align-items:stretch;border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-pill);background:var(--card);color:var(--text);font-size:12px;font-weight:500;text-decoration:none;overflow:hidden;transition:border-color var(--transition-fast),background var(--transition-fast)}.settings-github-star-btn:hover{border-color:var(--text-muted);background:var(--card-hover)}.settings-github-star-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);border-color:var(--todo)}.settings-github-star-btn__action{display:inline-flex;align-items:center;gap:var(--space-xs);padding:var(--space-xs) calc(var(--space-sm) + var(--space-xs) / 2)}.settings-github-star-btn__count{display:inline-flex;align-items:center;padding:var(--space-xs) calc(var(--space-sm) + var(--space-xs) / 4);border-left:var(--btn-border-width) solid var(--border);background:color-mix(in srgb,var(--surface) 60%,var(--card));color:var(--text-muted);font-variant-numeric:tabular-nums}.settings-modal{width:min(95vw,1100px);max-width:95vw;min-width:520px;height:80vh;min-height:480px;max-height:calc(100dvh - var(--overlay-padding-top, 10vh) - 16px);overflow:hidden;resize:both}@media(max-width:768px){.modal-overlay.settings-modal-overlay,.modal-overlay:has(.settings-modal){padding:0;inset:0;align-items:stretch;justify-content:stretch}.modal.settings-modal{width:100vw;min-width:0;max-width:100vw;height:100dvh;min-height:100dvh;max-height:100dvh;margin:0;border:none;border-radius:0;resize:none;flex:1 1 auto}.modal.settings-modal[style*=--keyboard-overlap]{height:var(--vv-height, 100dvh);min-height:var(--vv-height, 100dvh);max-height:var(--vv-height, 100dvh);transform:translateY(var(--vv-offset-top, 0px));will-change:transform}}.settings-modal-heading{display:flex;flex-direction:column;gap:var(--space-xs)}.settings-modal-heading h3{margin:0}.settings-modal-version{margin:0;font-size:.85rem;color:var(--text-muted);font-weight:500}.settings-update-check{display:flex;align-items:center;gap:var(--space-sm)}.settings-version-check-btn{--settings-inline-touch-target: calc(var(--space-lg) + var(--space-lg) + var(--space-xs));display:inline-flex;align-items:center;gap:var(--space-xs);margin:0;min-height:var(--settings-inline-touch-target);padding:var(--space-xs) var(--space-sm);border:none;background:transparent;color:var(--text-muted);cursor:pointer;transition:opacity var(--transition-fast),box-shadow var(--transition-fast)}.settings-version-check-btn:hover:not(:disabled){opacity:.85}.settings-version-check-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);border-radius:var(--radius-sm)}.settings-version-check-btn:disabled{cursor:default;opacity:.7}.settings-version-check-btn svg{color:var(--text-muted)}.settings-version-check-btn svg.spinning{animation:settings-update-spin 1s linear infinite}.settings-update-result{font-size:.85rem;font-weight:500}.settings-update-result--up-to-date{color:var(--color-success)}.settings-update-result--available{color:var(--color-info)}.settings-update-result--error{color:var(--text-muted)}.settings-update-result-link{color:var(--color-info);text-decoration:underline;transition:color var(--transition-fast),box-shadow var(--transition-fast)}.settings-update-result-link:hover{color:color-mix(in srgb,var(--color-info) 80%,var(--text))}.settings-update-result-link:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);border-radius:var(--radius-sm)}@keyframes settings-update-spin{to{transform:rotate(360deg)}}.backup-stats{display:flex;align-items:center;gap:var(--space-lg);padding:var(--space-sm) var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:color-mix(in srgb,var(--surface) 85%,transparent)}.backup-stat{display:flex;flex:1 1 0;flex-direction:column;align-items:center;gap:var(--space-xs);min-width:0}.backup-stat-value{color:var(--text);font-size:1rem;font-weight:600;font-variant-numeric:tabular-nums}.backup-stat-label{color:var(--text-muted);font-size:.75rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.backup-list{margin-top:var(--space-sm)}.backup-list summary{padding:var(--space-sm) 0;color:var(--text-muted);cursor:pointer;transition:color var(--transition-fast)}.backup-list summary:hover{color:var(--text)}.backup-list summary:focus-visible{outline:none;border-radius:var(--radius-sm);box-shadow:var(--focus-ring-strong)}.backup-list ul{display:flex;flex-direction:column;gap:var(--space-xs);margin:0;margin-top:var(--space-sm);padding:0;list-style:none}.backup-list li{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm);padding:var(--space-sm) 0;border-top:var(--btn-border-width) solid color-mix(in srgb,var(--border) 80%,transparent)}.backup-list li code{min-width:0;color:var(--text);font-family:var(--font-mono);font-size:.75rem;white-space:nowrap;overflow-x:auto}.backup-size{color:var(--text-muted);font-family:var(--font-mono);font-size:.75rem;text-align:right;white-space:nowrap}@media(max-width:768px){.backup-stats{flex-direction:column;align-items:stretch;gap:var(--space-sm)}.backup-stat{align-items:flex-start}.backup-list ul{max-height:calc(var(--space-xl) * 9 + var(--space-md));overflow-y:auto;-webkit-overflow-scrolling:touch}.backup-list li code{white-space:normal;overflow-wrap:anywhere;word-break:normal}}.settings-layout{display:flex;flex:1;flex-direction:row;min-height:0;overflow:hidden}.settings-mobile-section-picker{display:none}.settings-sidebar{width:170px;min-width:170px;border-right:1px solid var(--border);display:flex;flex-direction:column;overflow-y:auto;padding:var(--space-sm) var(--space-sm);gap:calc(var(--space-xs) / 2);background:color-mix(in srgb,var(--text) 10%,transparent);scrollbar-color:var(--border) transparent;scrollbar-width:thin}.settings-sidebar::-webkit-scrollbar{width:6px}.settings-sidebar::-webkit-scrollbar-track{background:transparent}.settings-sidebar::-webkit-scrollbar-thumb{background:var(--border);border-radius:var(--radius-sm)}.settings-sidebar::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}.settings-research-source-locked{cursor:default;color:var(--text-muted)!important}.settings-research-source-locked input[type=checkbox]{cursor:not-allowed}.settings-research-source-grid,.settings-research-limits-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.settings-research-limit-field{display:flex;flex-direction:column;gap:var(--space-xs)}.settings-research-limits-error{grid-column:1 / -1}@media(max-width:768px){.settings-research-source-grid,.settings-research-limits-grid{grid-template-columns:1fr}}.settings-nav-item{display:block;width:100%;padding:var(--space-sm) var(--space-md);font-size:13px;font-weight:500;color:var(--text-muted);background:none;border:none;border-left:3px solid transparent;border-radius:0 var(--radius-md) var(--radius-md) 0;cursor:pointer;text-align:left;transition:background var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast)}.settings-nav-item:hover{background:var(--bg);color:var(--text);border-left-color:var(--border)}.settings-nav-item:focus-visible{box-shadow:var(--focus-ring-strong);outline:none}.settings-nav-item.active{background:var(--bg);color:var(--todo);font-weight:600;border-left-color:var(--todo)}.settings-group-header{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted);padding:var(--space-md) var(--space-md) var(--space-xs);margin-top:var(--space-sm);user-select:none}.settings-group-header:first-child{margin-top:0}.settings-content{flex:1;overflow-x:hidden;overflow-y:auto;padding:4px 0 12px;scrollbar-color:var(--border) transparent;scrollbar-width:thin}.settings-content::-webkit-scrollbar{width:6px}.settings-content::-webkit-scrollbar-track{background:transparent}.settings-content::-webkit-scrollbar-thumb{background:var(--border);border-radius:var(--radius-sm)}.settings-content::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}.settings-content>*{animation:settingsFadeIn var(--transition-normal)}@keyframes settingsFadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.settings-section-heading{font-size:14px;font-weight:600;padding:var(--space-lg) var(--space-xl) var(--space-md);margin:0 0 var(--space-md);color:var(--text);border-bottom:1px solid var(--border)}.settings-content>.settings-section-heading:first-child,.settings-modal-section>.settings-section-heading:first-child{padding-top:var(--space-md)}.settings-section-heading--spaced{margin-top:var(--space-lg)}.settings-section-description{margin:0;padding:0 var(--space-xl);margin-bottom:var(--space-sm);color:var(--text-muted);font-size:13px;line-height:1.5}.settings-plugins-subsection-toggle{display:inline-flex;gap:var(--space-xs);padding:0 var(--space-xl);margin:var(--space-md) 0}.settings-plugins-subsection-btn{display:inline-flex;align-items:center;justify-content:center;border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-pill);background:var(--surface);color:var(--text-muted);font-size:.85rem;font-weight:600;padding:var(--space-xs) var(--space-md);cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast),box-shadow var(--transition-fast)}.settings-plugins-subsection-btn:hover{background:var(--surface-hover, color-mix(in srgb, var(--text) 6%, transparent));color:var(--text)}.settings-plugins-subsection-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.settings-plugins-subsection-btn.active{background:color-mix(in srgb,var(--todo) 14%,transparent);border-color:color-mix(in srgb,var(--todo) 45%,var(--border));color:var(--todo)}.settings-plugins-subsection-panel{padding-bottom:var(--space-md)}.settings-scope-icon{margin-right:6px;display:inline-flex;vertical-align:middle;color:var(--text-muted)}.settings-scope-banner{display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) var(--space-xl);margin:0 var(--space-xl) var(--space-xs);font-size:12px;border-radius:var(--radius-md);color:var(--text-muted)}.settings-scope-global{background:color-mix(in srgb,var(--color-info) 8%,transparent);border-left:3px solid color-mix(in srgb,var(--color-info) 40%,transparent)}.settings-scope-project{background:color-mix(in srgb,var(--color-success) 8%,transparent);border-left:3px solid color-mix(in srgb,var(--color-success) 40%,transparent)}.settings-scope-mixed{background:color-mix(in srgb,var(--triage) 8%,transparent);border-left:3px solid color-mix(in srgb,var(--triage) 40%,transparent)}.settings-note{display:block;padding:0 var(--space-xl);margin-top:var(--space-xs);font-size:12px;color:var(--text-muted)}.form-inline-group{display:flex;align-items:center;gap:var(--space-sm)}.form-inline-group .input{flex:1;min-width:0}.btn-link{background:none;border:none;padding:0;font-size:12px;color:var(--accent, #4a90e2);cursor:pointer;text-decoration:underline;white-space:nowrap}.btn-link:hover{text-decoration:none}.settings-overlap-ignore-group code{font-family:var(--font-mono);font-size:.9em}.settings-button-row{display:flex;flex-wrap:wrap;gap:var(--space-sm);margin-top:var(--space-sm)}.settings-raw-output{margin:var(--space-sm) 0 0;padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);color:var(--text-muted);max-height:calc(var(--space-2xl) * 7);overflow:auto;font-family:var(--font-mono);font-size:calc(var(--space-sm) + var(--space-xs))}.settings-url-output{display:block;margin-top:var(--space-xs);padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);color:var(--text-muted);font-family:var(--font-mono);font-size:calc(var(--space-sm) + var(--space-xs));overflow-wrap:anywhere;word-break:break-word;overflow-x:auto;max-width:100%}.settings-qr-preview{margin-top:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-sm)}.settings-qr-preview-label{margin:0;font-size:calc(var(--space-sm) + var(--space-xs));color:var(--text-muted)}.settings-qr-preview-image-wrap{width:fit-content;max-width:100%;padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--card)}.settings-qr-preview-image{display:block;width:min(calc(var(--space-2xl) * 6),100%);height:auto;aspect-ratio:1 / 1}.remote-provider-selector{display:flex;gap:var(--space-xs);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);padding:var(--space-xs);background:var(--surface)}.remote-provider-option{position:relative;flex:1;cursor:pointer}.remote-provider-option input{position:absolute;opacity:0;width:0;height:0}.remote-provider-option span{display:block;padding:var(--space-sm) var(--space-md);text-align:center;border-radius:var(--radius-sm);border:var(--btn-border-width) solid transparent;color:var(--text-muted);transition:background var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast)}.remote-provider-option-content{display:inline-flex;align-items:center;gap:var(--space-xs)}.remote-provider-option input:checked+span{background:var(--card);color:var(--text);border-color:var(--border)}.remote-provider-option input:focus-visible+span{box-shadow:var(--focus-ring-strong)}.remote-status-bar{--status-color: var(--text-muted);display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) var(--space-md);border-radius:var(--radius-md);margin:0 var(--space-xl) var(--space-md);background:color-mix(in srgb,var(--status-color) 10%,transparent)}.remote-status-bar--running{--status-color: var(--color-success)}.remote-status-bar--starting{--status-color: var(--color-warning)}.remote-status-bar--error{--status-color: var(--color-error)}.remote-status-bar--stopped{--status-color: var(--text-muted)}.remote-share-block{display:flex;flex-direction:column;gap:var(--space-sm);margin:0 var(--space-xl) var(--space-md);padding:var(--space-sm) var(--space-md);border:1px solid var(--border);border-radius:var(--radius-md);background:color-mix(in srgb,var(--text-muted) 5%,transparent)}.remote-share-row{display:flex;flex-direction:column;gap:var(--space-xs)}.remote-share-row .settings-qr-preview-image{margin-top:var(--space-xs)}.remote-status-dot{width:var(--space-sm);height:var(--space-sm);border-radius:50%;display:inline-block;flex-shrink:0}.remote-status-dot--running{background:var(--color-success)}.remote-status-dot--starting{background:var(--color-warning)}.remote-status-dot--error{background:var(--color-error)}.remote-status-dot--stopped{background:var(--text-muted)}.remote-status-url{margin-left:auto;font-family:var(--font-mono);overflow-wrap:anywhere;word-break:break-word;user-select:all}.remote-provider-settings{display:flex;flex-direction:column;gap:var(--space-sm)}.remote-cli-detection{display:flex;align-items:flex-start;gap:var(--space-sm);margin:0 var(--space-xl) var(--space-md);padding:var(--space-sm) var(--space-md);border-radius:var(--radius-sm)}.remote-cli-detection--available{background:color-mix(in srgb,var(--color-success) 10%,transparent);color:var(--color-success)}.remote-cli-detection--missing{background:color-mix(in srgb,var(--color-warning) 10%,transparent);color:var(--color-warning)}.remote-cli-detection-content{display:flex;flex-direction:column;gap:var(--space-xs);color:var(--text)}.remote-cli-detection .btn{align-self:flex-start}.remote-cli-install-error{color:var(--color-error)}.remote-cli-manual{color:var(--text-dim)}.remote-external-tunnel-panel{display:flex;flex-direction:column;gap:var(--space-sm);margin:0 var(--space-xl) var(--space-md);padding:var(--space-sm) var(--space-md);border:1px solid var(--border);border-radius:var(--radius-md);background:color-mix(in srgb,var(--color-info) 10%,transparent)}.remote-external-tunnel-header{display:flex;align-items:center;gap:var(--space-sm);color:var(--color-info)}.remote-external-tunnel-qr{display:flex;flex-direction:column;gap:var(--space-xs)}.remote-external-tunnel-actions{display:flex;flex-direction:column;gap:var(--space-sm)}.remote-advanced-details{margin:var(--space-lg) var(--space-xl) 0;border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);padding:var(--space-md);background:var(--surface)}.remote-advanced-details>summary{cursor:pointer;color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs));list-style:none}.remote-advanced-details>summary::-webkit-details-marker{display:none}.remote-advanced-details>summary:before{content:"▸";margin-right:var(--space-xs)}.remote-advanced-details[open]>summary:before{content:"▾"}.settings-option-details{margin-top:var(--space-xs)}.settings-research-provider-group{display:flex;flex-direction:column;gap:var(--space-sm)}.settings-research-provider-advanced-details{margin-left:var(--space-md)}.settings-research-empty-state{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-sm)}@media(max-width:768px){.settings-research-provider-advanced-details{margin-left:0}}.settings-option-details>summary{cursor:pointer;color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs));list-style:none}.settings-option-details>summary::-webkit-details-marker{display:none}.settings-option-details>summary:before{content:"▸";margin-right:var(--space-xs)}.settings-option-details[open]>summary:before{content:"▾"}.remote-cf-advanced-details{margin-top:var(--space-xs)}.remote-cf-advanced-details>summary{cursor:pointer;color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs));list-style:none}.remote-cf-advanced-details>summary::-webkit-details-marker{display:none}.remote-cf-advanced-details>summary:before{content:"▸";margin-right:var(--space-xs)}.remote-cf-advanced-details[open]>summary:before{content:"▾"}.remote-cf-advanced-fields{display:flex;flex-direction:column;gap:var(--space-sm);margin-top:var(--space-sm)}.remote-tunnel-actions{margin-top:var(--space-md)}.remote-tunnel-actions .btn{width:100%}.settings-overlap-ignore-list{display:flex;flex-direction:column;gap:var(--space-sm);margin:var(--space-sm) 0}.settings-overlap-ignore-row,.settings-overlap-ignore-path-controls{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--space-sm);align-items:center}.settings-overlap-path-picker-modal{max-width:min(960px,calc(100vw - var(--space-2xl)))}.settings-overlap-path-picker-body{display:flex;flex-direction:column;gap:var(--space-sm);max-height:min(70vh,720px)}.settings-overlap-path-picker-note{margin:0;font-size:12px;color:var(--text-muted)}.settings-section-divider{border-top:1px solid var(--border);margin:var(--space-lg) var(--space-xl)}@media(max-width:768px){.settings-note{padding:0 var(--space-lg)}.settings-overlap-ignore-row,.settings-overlap-ignore-path-controls{grid-template-columns:minmax(0,1fr)}.settings-overlap-ignore-row>.btn{justify-self:start}.settings-overlap-path-picker-modal{max-width:calc(100vw - var(--space-md))}.remote-provider-selector{flex-direction:column}.remote-status-bar{flex-wrap:wrap;margin:0 var(--space-lg) var(--space-md)}.remote-share-block{margin:0 var(--space-lg) var(--space-md)}.remote-status-url{width:100%;margin-left:0;font-size:.8em}.remote-provider-option,.remote-tunnel-actions .btn{min-height:36px}.remote-cli-detection,.remote-external-tunnel-panel{margin:0 var(--space-lg) var(--space-md)}}.ntfy-advanced-disclosure{margin-top:var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:var(--surface)}.ntfy-advanced-disclosure>summary{cursor:pointer;list-style:none;padding:var(--space-sm) var(--space-md);font-size:12px;font-weight:600;color:var(--text)}.ntfy-advanced-disclosure>summary::-webkit-details-marker{display:none}.ntfy-advanced-content{padding:0 var(--space-md) var(--space-md);display:flex;flex-direction:column;gap:var(--space-sm)}.settings-inline-link{color:var(--todo);text-decoration:none;transition:text-decoration var(--transition-fast)}.settings-inline-link:hover{text-decoration:underline}.settings-inline-link:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);border-radius:var(--radius-sm)}.notification-provider-card{border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-lg);background:var(--surface);margin:0 var(--space-xl) var(--space-lg);overflow:hidden}.notification-provider-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-md) var(--space-lg);border-bottom:var(--btn-border-width) solid var(--border)}.notification-provider-body{padding:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-lg)}.notification-provider-actions{display:flex;flex-wrap:wrap;gap:var(--space-sm);padding-top:var(--space-md);border-top:var(--btn-border-width) solid var(--border);margin-top:var(--space-md)}.notification-test-feedback{display:flex;flex-direction:column;gap:var(--space-xs);margin-top:var(--space-sm)}.notification-test-feedback-item{border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-sm);padding:var(--space-xs) var(--space-sm)}.notification-test-feedback-item--success{border-color:color-mix(in srgb,var(--color-success) 45%,var(--border));background:color-mix(in srgb,var(--color-success) 8%,transparent);color:var(--color-success)}.notification-test-feedback-item--error{border-color:color-mix(in srgb,var(--color-error) 45%,var(--border));background:color-mix(in srgb,var(--color-error) 8%,transparent);color:var(--color-error)}@media(max-width:768px){.notification-provider-actions{flex-direction:column}.notification-provider-actions .btn{width:100%}}.memory-status-message{display:flex;gap:var(--space-md);align-items:center;justify-content:space-between;margin-bottom:var(--space-md)}.memory-status-message span{min-width:0}.memory-retrieval-test{margin-top:var(--space-lg)}.memory-test-result{margin:0 var(--space-xl) var(--space-lg);padding:var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:var(--card)}.memory-test-result strong,.memory-test-result span{color:var(--text);font-size:12px}.memory-test-result small{display:block;margin-top:var(--space-xs);color:var(--text-muted);font-size:12px}.memory-test-result ul{margin:var(--space-md) 0 0;padding:0;list-style:none}.memory-test-result li{padding-top:var(--space-sm);border-top:var(--btn-border-width) solid var(--border)}.memory-test-result li+li{margin-top:var(--space-sm)}.memory-test-result p{margin:var(--space-xs) 0 0;color:var(--text-muted);font-size:12px;line-height:1.5;overflow-wrap:anywhere}.memory-editor-section{margin-top:var(--space-lg);display:flex;flex:1 1 auto;flex-direction:column;min-height:0}.memory-editor-form-group{display:flex;flex:1 1 auto;flex-direction:column;min-height:0}.memory-file-summary{display:grid;grid-template-columns:auto minmax(0,1fr);gap:var(--space-xs) var(--space-md);align-items:center;margin:0 var(--space-xl) var(--space-md);padding:var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:var(--card)}.memory-file-summary span{display:inline-flex;align-items:center;justify-content:center;padding:var(--space-xs) var(--space-sm);border-radius:var(--radius-pill);color:var(--color-info);background:color-mix(in srgb,var(--color-info) 12%,transparent);font-size:11px;font-weight:600}.memory-file-summary strong{min-width:0;overflow-wrap:anywhere;color:var(--text);font-family:var(--font-mono);font-size:12px}.memory-file-summary small{grid-column:2;color:var(--text-muted);font-size:12px}.memory-editor-frame{min-height:50vh;border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);overflow:hidden;display:flex;flex:1 1 auto;flex-direction:column;min-width:0}.auth-panel-body{padding-inline:var(--space-md)}.auth-section-hint{padding:var(--space-md) var(--space-lg);margin-bottom:var(--space-md);background:var(--bg-tertiary);border-radius:var(--radius-md);font-size:13px;color:var(--text-muted);border-left:3px solid var(--text-muted)}.auth-provider-group{margin-bottom:calc(var(--space-sm) + var(--space-xs) / 2)}.auth-group-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--text-muted);margin-bottom:var(--space-xs);padding:0 4px}.auth-provider-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);margin-bottom:var(--space-xs);overflow:hidden;transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.auth-provider-card:hover{border-color:var(--text-dim)}.auth-provider-card--authenticated{border-color:color-mix(in srgb,var(--color-success) 40%,var(--border));background:color-mix(in srgb,var(--color-success) 5%,var(--surface))}.auth-provider-card--authenticated:hover{border-color:color-mix(in srgb,var(--color-success) 60%,var(--border))}.auth-provider-header{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--space-sm) var(--space-md);gap:12px}.auth-provider-info{display:flex;align-items:center;gap:10px;flex-wrap:wrap;flex:1;min-width:0}.auth-provider-info strong{font-weight:500;color:var(--text)}.auth-provider-icon-slot{display:inline-flex;align-items:center;justify-content:center;inline-size:calc(var(--space-md) + var(--space-xs) * 2);block-size:calc(var(--space-md) + var(--space-xs) * 2);flex-shrink:0}.auth-provider-icon-slot .provider-icon{display:inline-flex}.auth-hint{display:block;padding:12px 4px 0;font-size:12px;color:var(--text-muted);border-top:1px solid var(--border);margin-top:8px}.auth-apikey-section{display:flex;flex-direction:column;gap:var(--space-xs);align-items:flex-end;flex-shrink:0}.auth-apikey-input-row{display:flex;gap:6px;align-items:center}.auth-apikey-input{background:var(--bg-input);border:1px solid var(--border);border-radius:6px;color:var(--text);padding:6px 10px;font-size:13px;width:180px;font-family:monospace}.auth-apikey-input:focus{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring)}.auth-apikey-input:disabled{opacity:.6}.auth-apikey-progress{font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted);padding-right:4px}.auth-apikey-error{font-size:11px;color:var(--color-error);padding-right:4px}.auth-provider-actions-row{display:flex;width:100%;align-items:center;gap:var(--space-sm)}.auth-device-code-panel{width:100%;margin-top:var(--space-sm);padding:var(--space-sm);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:color-mix(in srgb,var(--surface) 85%,transparent);display:flex;flex-direction:column;gap:var(--space-sm)}.auth-device-code-pill{font-family:var(--font-mono);font-size:calc(var(--space-md) + var(--space-xs) * .5);letter-spacing:var(--space-xs);padding:var(--space-sm) var(--space-md);border-radius:var(--radius-pill);border:var(--btn-border-width) solid var(--border);background:var(--card);color:var(--text);display:flex;align-self:stretch}.auth-key-hint{font-family:var(--font-mono);font-size:12px;color:var(--text-muted);display:inline-block;margin-top:var(--space-xs);user-select:none}.settings-lane-badge{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:11px;font-weight:500;white-space:nowrap}.settings-lane-badge--override{background-color:color-mix(in srgb,var(--todo) 20%,transparent);color:var(--todo)}.settings-lane-badge--inherited{background-color:color-mix(in srgb,var(--text-muted) 15%,transparent);color:var(--text-muted)}.settings-description{font-size:13px;color:var(--text-dim);padding-inline:var(--space-xl);margin-block:0 var(--space-md);line-height:1.5}.settings-token-cap-row{display:flex;align-items:center;gap:var(--space-sm)}.settings-model-lane-label-row{display:flex;align-items:center;gap:var(--space-sm);margin-bottom:var(--space-xs)}.settings-model-lane-control-row{display:flex;align-items:center;gap:var(--space-sm)}.settings-model-lane-control-main{flex:1}.settings-summarization-actions{justify-content:flex-start}.settings-model-presets{display:flex;flex-direction:column;gap:var(--space-md)}.settings-preset-list{display:flex;flex-direction:column;gap:var(--space-sm)}.settings-preset-item{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-md);padding:var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:var(--card)}.settings-preset-item-meta{display:flex;flex-direction:column;gap:var(--space-xs);min-width:0}.settings-preset-item-meta strong{color:var(--text);overflow-wrap:anywhere}.settings-preset-summary{font-size:12px;overflow-wrap:anywhere}.settings-preset-item-actions{display:flex;gap:var(--space-xs);flex-wrap:wrap;justify-content:flex-end}.settings-preset-actions{display:flex;justify-content:flex-start}.settings-preset-editor{display:flex;flex-direction:column;gap:var(--space-md);padding:var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:color-mix(in srgb,var(--surface) 85%,var(--card))}.settings-preset-editor-fields{display:flex;flex-direction:column;gap:var(--space-sm)}.settings-preset-editor .form-group{padding:0}.settings-preset-editor-actions{justify-content:flex-start;margin-top:0;padding:0}.settings-preset-auto-select{margin-top:var(--space-sm)}.settings-preset-size-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-sm)}.settings-preset-size-row{padding:0}@media(max-width:768px){.settings-layout{flex-direction:column;min-height:0}.settings-mobile-section-picker{display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-md) var(--space-lg);border-bottom:var(--btn-border-width) solid var(--border);background:var(--surface)}.settings-mobile-section-picker label{color:var(--text-muted);font-weight:600;text-transform:uppercase}.settings-mobile-section-picker select{width:100%}.settings-mobile-section-picker select:focus-visible{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring-strong)}.settings-sidebar{display:none}.settings-nav-item{display:flex;align-items:center;justify-content:center;gap:var(--space-xs);border-left:none;border-bottom:2px solid transparent;border-radius:var(--radius-md) var(--radius-md) 0 0;padding:calc(var(--space-xs) + var(--space-xs) / 2) var(--space-md);white-space:nowrap}.settings-nav-item:hover{border-left-color:transparent;border-bottom-color:var(--border)}.settings-nav-item.active{border-left-color:transparent;border-bottom-color:var(--todo)}.settings-group-header{display:none}.notification-provider-card{margin:0 var(--space-lg) var(--space-md)}.notification-provider-header{padding:var(--space-sm) var(--space-md)}.notification-provider-body{padding:var(--space-md)}.settings-scope-icon{margin-right:0}.settings-content{flex:1;min-height:0;overflow-x:hidden;overflow-y:auto}.settings-content .form-group small{overflow-wrap:break-word;word-break:normal}.settings-content input,.settings-content select,.settings-content textarea{font-size:16px}.settings-section-heading{padding:var(--space-lg) var(--space-lg) var(--space-md);margin:0 0 var(--space-md)}.settings-plugins-subsection-toggle{display:flex;width:100%;padding:0 var(--space-lg)}.settings-plugins-subsection-btn{flex:1;min-height:36px}.settings-plugins-subsection-panel{padding-left:var(--space-lg);padding-right:var(--space-lg)}.form-group{padding:0 calc(var(--space-md) + var(--space-xs) / 2)}.settings-scope-banner{padding:var(--space-sm) var(--space-lg)}.memory-editor-frame{min-height:65vh}.memory-file-summary{grid-template-columns:1fr;margin:0 var(--space-lg) var(--space-md)}.memory-status-message{align-items:stretch;flex-direction:column}.memory-file-summary span{justify-content:flex-start}.memory-file-summary small{grid-column:auto}.settings-description{padding:0 var(--space-lg)}.settings-content .btn,.settings-preset-item-actions .btn{min-height:36px}.auth-provider-row{flex-wrap:wrap;padding:var(--space-md) calc(var(--space-md) + var(--space-xs) / 2);gap:var(--space-sm)}.auth-section-hint{margin:0 calc(var(--space-md) + var(--space-xs) / 2) var(--space-md);padding:calc(var(--space-sm) + var(--space-xs) / 2) calc(var(--space-md) + var(--space-xs) / 2)}.auth-provider-group{margin-bottom:var(--space-md)}.auth-group-label{padding:0 calc(var(--space-md) + var(--space-xs) / 2)}.auth-provider-card{margin:0 calc(var(--space-md) + var(--space-xs) / 2) var(--space-sm)}.auth-provider-header{flex-wrap:wrap;padding:calc(var(--space-sm) + var(--space-xs) / 2) calc(var(--space-md) + var(--space-xs) / 2);gap:10px}.auth-provider-header>div:not(.auth-provider-info):not(.auth-apikey-section){margin-left:auto}.auth-provider-actions-row{width:100%;justify-content:flex-end}.auth-device-code-panel{width:100%}.auth-device-code-pill{max-width:100%;overflow-wrap:anywhere}.auth-provider-info{width:100%;flex-basis:100%}.auth-apikey-section{width:100%;flex-basis:100%;align-items:flex-end}.auth-apikey-input-row{width:100%;flex-wrap:wrap;justify-content:flex-end}.auth-apikey-input{flex:1;min-width:120px;width:auto}.auth-apikey-input-row .btn{flex-shrink:0;margin-left:auto}.auth-hint{padding:var(--space-md) calc(var(--space-md) + var(--space-xs) / 2) 0}.settings-model-presets{gap:var(--space-sm)}.settings-preset-item{flex-direction:column;align-items:stretch;padding:var(--space-sm) var(--space-md)}.settings-preset-item-actions{justify-content:flex-start}.settings-preset-editor{padding:var(--space-sm) var(--space-md)}.settings-preset-editor-actions{flex-wrap:wrap}.settings-preset-size-grid{grid-template-columns:1fr;gap:var(--space-xs)}.settings-node-routing-note{padding:var(--space-sm) var(--space-md);font-size:12px}}.settings-node-routing-note{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-md) var(--space-lg);margin-top:var(--space-sm);color:var(--text-muted);font-size:13px;line-height:1.5}.settings-node-status{display:inline-flex;align-items:center;gap:var(--space-xs);margin-top:var(--space-sm);font-size:12px;color:var(--text-muted)}.auth-advanced-disclosure{margin-top:var(--space-md);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface)}.auth-advanced-disclosure>summary{cursor:pointer;padding:var(--space-sm) var(--space-md)}.auth-advanced-content{display:flex;flex-direction:column;gap:var(--space-sm);padding:0 var(--space-md) var(--space-md)}.auth-custom-provider-item{display:flex;justify-content:space-between;align-items:center;gap:var(--space-sm)}.auth-custom-provider-actions{display:flex;gap:var(--space-sm)}.settings-warning-banner{margin-top:var(--space-sm);padding:var(--space-sm) var(--space-md);border:1px solid var(--color-warning);border-radius:var(--radius-md);background:color-mix(in srgb,var(--color-warning) 12%,transparent);color:var(--text);font-size:var(--font-sm, .875rem);line-height:1.4}.settings-warning-banner strong{color:var(--color-warning);margin-right:var(--space-xs)}@media(max-width:768px){.auth-custom-provider-item{flex-direction:column;align-items:flex-start}.settings-warning-banner{padding:var(--space-sm)}}