@runfusion/fusion 0.30.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +72183 -52586
- package/dist/client/.vite/manifest.json +549 -0
- package/dist/client/assets/{AgentDetailView-Cu4TgvBn.js → AgentDetailView-CnFf_eBZ.js} +3 -3
- package/dist/client/assets/AgentPermissionPolicyEditor-CGxjOr6G.css +1 -0
- package/dist/client/assets/AgentPermissionPolicyEditor-Cmkt9Z01.js +6 -0
- package/dist/client/assets/{AgentsView-CIH4Acck.js → AgentsView-LkVv9hph.js} +3 -3
- package/dist/client/assets/ChatView-DYjECCRG.js +1 -0
- package/dist/client/assets/{DevServerView-Bd8JZ-3C.js → DevServerView-D7legPr1.js} +1 -1
- package/dist/client/assets/{DevServerView-DlZpuAnj.css → DevServerView-VTQY28P7.css} +1 -1
- package/dist/client/assets/{DirectoryPicker-BOGqZNiq.js → DirectoryPicker-DctpCNrd.js} +1 -1
- package/dist/client/assets/DocumentsView-DORp5JjC.js +1 -0
- package/dist/client/assets/EvalsView-CYVJ1pbc.js +1 -0
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-BM7EnSvJ.js → ExperimentalAgentOnboardingModal-BULVNAiq.js} +1 -1
- package/dist/client/assets/GoalsView-Cg136Jcn.css +1 -0
- package/dist/client/assets/GoalsView-bmpZKOI_.js +1 -0
- package/dist/client/assets/{InsightsView-B0J4mhzV.css → InsightsView-C9-mqVvf.css} +1 -1
- package/dist/client/assets/InsightsView-mmtem0RU.js +11 -0
- package/dist/client/assets/{MemoryView-CE1D9euM.js → MemoryView-HVpO1fCH.js} +2 -2
- package/dist/client/assets/{NodesView-Zxusnhxu.js → NodesView-CM0eoCP8.js} +3 -3
- package/dist/client/assets/{PiExtensionsManager-BlMmxtLZ.js → PiExtensionsManager-Cyfas2VT.js} +2 -2
- package/dist/client/assets/{PluginManager-D4eZ0zA4.js → PluginManager-C7QDE3Lk.js} +1 -1
- package/dist/client/assets/ReliabilityView-C1C1j1SD.js +1 -0
- package/dist/client/assets/ReliabilityView-D9AsVv5l.css +1 -0
- package/dist/client/assets/ResearchView-Bn2WxwnQ.js +1 -0
- package/dist/client/assets/SecretsView-BFhVwJu6.css +1 -0
- package/dist/client/assets/SecretsView-DgrrgzFc.js +1 -0
- package/dist/client/assets/SettingsModal-BCZrCLl3.js +31 -0
- package/dist/client/assets/{SettingsModal-sp7SNwS9.css → SettingsModal-BZBV2kLr.css} +1 -1
- package/dist/client/assets/{SettingsModal-BAx4gt2A.css → SettingsModal-DZrJ5PFH.css} +1 -1
- package/dist/client/assets/{SettingsModal-DRnZ6eBW.js → SettingsModal-YCJM5is3.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-BmmRM3g-.js → SetupWizardModal-BT-mj3VD.js} +1 -1
- package/dist/client/assets/{SkillsView-DWVtT2-8.js → SkillsView-Db7dYpqd.js} +1 -1
- package/dist/client/assets/{StashRecoveryView-CKkaWzzc.js → StashRecoveryView-CSYYcWux.js} +1 -1
- package/dist/client/assets/TodoView-zqCqfy26.js +6 -0
- package/dist/client/assets/dashboard-view-PpcsMDvN.js +21 -0
- package/dist/client/assets/{folder-open-BTN2_Wuv.js → folder-open-mxsFQlAX.js} +1 -1
- package/dist/client/assets/index-Ba-F8c1g.js +732 -0
- package/dist/client/assets/index-D4HhaIOp.css +1 -0
- package/dist/client/assets/{upload-euJEs_N2.js → upload-j7JjaJzG.js} +1 -1
- package/dist/client/assets/{users-B7miEHCZ.js → users-DZ_0WcB6.js} +1 -1
- package/dist/client/index.html +15 -27
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +52863 -36171
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +1 -1
- package/skill/fusion/SKILL.md +2 -2
- package/skill/fusion/references/cli-commands.md +1 -1
- package/skill/fusion/references/engine-tools.md +1 -0
- package/skill/fusion/references/extension-tools.md +23 -2
- package/skill/fusion/references/fusion-capabilities.md +4 -2
- package/skill/fusion/workflows/task-management.md +1 -1
- package/dist/client/assets/AgentPermissionPolicyEditor-Ceg2Dszn.js +0 -6
- package/dist/client/assets/AgentPermissionPolicyEditor-CthjqUL_.css +0 -1
- package/dist/client/assets/ChatView-DqJoFquZ.js +0 -1
- package/dist/client/assets/DocumentsView-B-ELcw4o.js +0 -1
- package/dist/client/assets/EvalsView-Ccl9QBYN.js +0 -1
- package/dist/client/assets/InsightsView-DLF49bzu.js +0 -11
- package/dist/client/assets/ReliabilityView-KmH60I_5.js +0 -1
- package/dist/client/assets/ReliabilityView-rxA_HgEG.css +0 -1
- package/dist/client/assets/ResearchView-C14Zh7c9.js +0 -1
- package/dist/client/assets/SettingsModal-c1QwWno0.js +0 -31
- package/dist/client/assets/TodoView-hbD0NOCY.js +0 -6
- package/dist/client/assets/dashboard-view-VNPB3ca0.js +0 -21
- package/dist/client/assets/index-CZFBq256.css +0 -1
- package/dist/client/assets/index-DzSLVOnp.js +0 -695
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as g,j as e}from"./vendor-react-K0fH_qHe.js";import{v as ye,er as je,es as Y,s as Ne,X as Z,au as Se,aS as ve,J as T,a_ as ee,Y as se,R as we,et as Ce,aq as Ie,eu as $e,ev as Pe,cz as Re,ew as Ee,ex as ke,ey as Be,ez as Ae,eA as te,cw as Le,eB as Fe}from"./index-DzSLVOnp.js";import{D as De}from"./DirectoryPicker-BOGqZNiq.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";import"./folder-open-BTN2_Wuv.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 ze(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 Oe(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,$]=g.useState(!1),[w,P]=g.useState(""),[B,A]=g.useState(!1),[L,F]=g.useState(!1),[S,D]=g.useState(null),[r,R]=g.useState(null),[p,b]=g.useState({}),[ce,z]=g.useState(!1),[O,G]=g.useState(null),[oe,E]=g.useState({}),[ue,U]=g.useState(null),[C,q]=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 _=async()=>{if(!w.trim()){i("Please enter a plugin path","error");return}try{A(!0),await te({path:w,...L?{aiScanOnLoad:!0}:{}},c),i("Plugin installed globally","success"),$(!1),P(""),F(!1),await m()}catch(s){i(`Failed to install plugin: ${s instanceof Error?s.message:String(s)}`,"error")}finally{A(!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)}},M=async s=>{try{q(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 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{q(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 Ae(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 $e(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 Pe(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{z(!0);const n=await Le(s.id,c);b(n)}catch{b({})}finally{z(!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=ze(r);return s&&Object.keys(s).length>0?e.jsxs("div",{className:"plugin-settings-form",children:[(()=>{const{grouped:n,ungrouped:o}=Oe(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:()=>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 M(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){M(s);return}n&&k(n)},disabled:O===s.id||C===s.id||d,children:o?t?C===s.id?"Setting up...":"Install Setup":"Manage":O===s.id?"Installing...":`Install ${s.name}`})]},s.id)})})]});return e.jsxs("div",{className:"plugin-manager","data-testid":"plugin-manager",children:[e.jsxs("div",{className:"plugin-manager-header",children:[e.jsx("span",{className:"plugin-manager-header-title",children:"Installed Plugins"}),e.jsxs("div",{className:"plugin-manager-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:m,title:"Refresh","aria-label":"Refresh plugin list",children:[e.jsx(we,{size:14,className:f?"spin":""}),"Refresh"]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>$(!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:P,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:L,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:()=>{$(!1),P("")},children:"Cancel"})]})]}),f?e.jsx("div",{className:"settings-empty-state",children:"Loading plugins..."}):e.jsxs(e.Fragment,{children:[K.length===0?e.jsxs("div",{className:"settings-empty-state",children:[e.jsx(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,eA as je,eB as Y,s as Ne,X as Z,az as Se,aX as ve,J as T,b3 as ee,Y as se,R as we,eC as Ce,av as Ie,eD as $e,eE as Pe,cC as Re,eF as Ee,eG as ke,eH as Be,eI as Ae,eJ as te,cz as Le,eK as Fe}from"./index-Ba-F8c1g.js";import{D as De}from"./DirectoryPicker-DctpCNrd.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";import"./folder-open-mxsFQlAX.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 ze(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 Oe(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,$]=g.useState(!1),[w,P]=g.useState(""),[B,A]=g.useState(!1),[L,F]=g.useState(!1),[S,D]=g.useState(null),[r,R]=g.useState(null),[p,b]=g.useState({}),[ce,z]=g.useState(!1),[O,G]=g.useState(null),[oe,E]=g.useState({}),[ue,U]=g.useState(null),[C,q]=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{A(!0),await te({path:w,...L?{aiScanOnLoad:!0}:{}},c),i("Plugin installed globally","success"),$(!1),P(""),F(!1),await m()}catch(s){i(`Failed to install plugin: ${s instanceof Error?s.message:String(s)}`,"error")}finally{A(!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)}},V=async s=>{try{q(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 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{q(null),U(null)}},_=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 Ae(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 $e(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 Pe(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{z(!0);const n=await Le(s.id,c);b(n)}catch{b({})}finally{z(!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=ze(r);return s&&Object.keys(s).length>0?e.jsxs("div",{className:"plugin-settings-form",children:[(()=>{const{grouped:n,ungrouped:o}=Oe(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:X=>{const v=X.target.value,Q=[...p[a]||[]];Q[j]=t.itemType==="number"?Number(v):v,b({...p,[a]:Q})}}),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:()=>_(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:O===s.id||C===s.id||d,children:o?t?C===s.id?"Setting up...":"Install Setup":"Manage":O===s.id?"Installing...":`Install ${s.name}`})]},s.id)})})]});return e.jsxs("div",{className:"plugin-manager","data-testid":"plugin-manager",children:[e.jsxs("div",{className:"plugin-manager-header",children:[e.jsx("span",{className:"plugin-manager-header-title",children:"Installed Plugins"}),e.jsxs("div",{className:"plugin-manager-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:m,title:"Refresh","aria-label":"Refresh plugin list",children:[e.jsx(we,{size:14,className:f?"spin":""}),"Refresh"]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>$(!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:P,placeholder:"Absolute path to plugin directory or dist folder",onInputKeyDown:s=>{s.key==="Enter"&&(s.preventDefault(),M())}}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:L,onChange:s=>F(s.target.checked)}),"Enable AI security scan on load"]}),e.jsxs("div",{className:"plugin-install-actions",children:[e.jsx("button",{className:"btn btn-primary",onClick:M,disabled:B||!w.trim(),children:B?"Installing...":"Install Plugin Globally"}),e.jsx("button",{className:"btn btn-secondary",onClick:()=>{$(!1),P("")},children:"Cancel"})]})]}),f?e.jsx("div",{className:"settings-empty-state",children:"Loading plugins..."}):e.jsxs(e.Fragment,{children:[K.length===0?e.jsxs("div",{className:"settings-empty-state",children:[e.jsx(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):_(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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as i,j as e}from"./vendor-react-K0fH_qHe.js";function j(s){return`${(s*100).toFixed(1)}%`}function y(s){return s===null?"—":`${(s/6e4).toFixed(1)}m`}function c(s){if(!s)return"—";const d=new Date(s);return Number.isNaN(d.getTime())?s:d.toLocaleString()}function R(){const[s,d]=i.useState(null),[o,b]=i.useState(!1),[v,h]=i.useState(!1),[m,u]=i.useState(null),n=i.useCallback(async()=>{const t=await fetch("/api/health/reliability");if(!t.ok)throw new Error(`Failed to load reliability metrics (${t.status})`);const a=await t.json();d(a)},[]),p=i.useCallback(async()=>{u(null);const t=await fetch("/api/health/reliability/reset",{method:"POST"});if(!t.ok)throw new Error(`Failed to reset reliability metrics (${t.status})`);await n(),h(!1)},[n]);i.useEffect(()=>{n();const t=setInterval(()=>{n()},6e4);return()=>clearInterval(t)},[n]);const r=s?.headline.inReviewFailureRate7d,l=i.useMemo(()=>r==null?null:Math.max(0,Math.min(1,1-r)),[r]),w=i.useMemo(()=>l===null?"var(--text-muted)":l>=.95?"var(--color-success)":l>=.9?"var(--color-warning)":"var(--color-error)",[l]),f=i.useMemo(()=>(s?.perDay??[]).reduce((t,a)=>t+a.tasksEnteredInReview,0),[s?.perDay]),N=i.useMemo(()=>(s?.perDay??[]).reduce((t,a)=>t+a.tasksBouncedToInProgress,0),[s?.perDay]),g=i.useMemo(()=>s?.perDay?o?s.perDay:s.perDay.filter(t=>t.hasSamples!==!1):[],[s?.perDay,o]),x=i.useMemo(()=>Object.values(s?.mergeAttempts.histogram??{}).reduce((t,a)=>t+a,0),[s?.mergeAttempts.histogram]),D=s?c(s.resetAt??new Date(Date.parse(s.generatedAt)-s.windowDays*864e5).toISOString()):"—";return e.jsxs("section",{className:"reliability-view",children:[e.jsxs("div",{className:"card reliability-card reliability-headline-card",children:[e.jsxs("div",{className:"reliability-section-header",children:[e.jsx("h2",{children:"Reliability"}),e.jsx("button",{className:"btn btn-danger btn-sm",onClick:()=>h(!0),children:"Reset stats"})]}),e.jsx("div",{className:"reliability-headline",style:{color:w},children:r==null?`Insufficient data — ${s?.headline.reason??"unknown"}`:j(l??0)}),l!==null?e.jsx("div",{className:"reliability-muted",children:"In-review success rate (last 7d)"}):null,s?.resetAt?e.jsx("div",{className:"reliability-muted",children:`Counting since ${c(s.resetAt)}`}):null,e.jsxs("details",{className:"reliability-details",children:[e.jsx("summary",{children:"Details"}),e.jsxs("div",{className:"reliability-details-content",children:[e.jsx("div",{children:`${N} bounced / ${f} entered (last ${s?.windowDays??7}d)`}),r!=null?e.jsx("div",{children:`Failure rate: ${j(r)}`}):null,e.jsx("div",{children:`Window: ${D} → ${c(s?.generatedAt)}`}),s?.resetAt?e.jsx("div",{children:`Reset baseline: ${c(s.resetAt)}`}):null,s?.headline.reason?e.jsx("div",{children:`Reason: ${s.headline.reason}`}):null]})]})]}),e.jsxs("div",{className:"reliability-grid",children:[e.jsxs("div",{className:"card reliability-card",children:[e.jsxs("div",{className:"reliability-section-header",children:[e.jsx("h3",{children:"In-review flow"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>b(t=>!t),children:o?"Hide empty days":"Show empty days"})]}),e.jsxs("table",{className:"reliability-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Date"}),e.jsx("th",{children:"Entered"}),e.jsx("th",{children:"Bounced"})]})}),e.jsx("tbody",{children:g.map(t=>e.jsxs("tr",{children:[e.jsx("td",{children:t.date}),e.jsx("td",{children:t.tasksEnteredInReview}),e.jsx("td",{children:t.tasksBouncedToInProgress})]},t.date))})]})]}),e.jsxs("div",{className:"card reliability-card",children:[e.jsx("h3",{children:"Duration"}),e.jsxs("div",{className:"reliability-stat-row",children:[e.jsx("span",{children:"P50"}),e.jsx("strong",{children:y(s?.duration.p50Ms??null)})]}),e.jsxs("div",{className:"reliability-stat-row",children:[e.jsx("span",{children:"P95"}),e.jsx("strong",{children:y(s?.duration.p95Ms??null)})]}),e.jsxs("div",{className:"reliability-muted",children:["Samples: ",s?.duration.sampleCount??0]}),e.jsxs("details",{className:"reliability-details",children:[e.jsx("summary",{children:"More stats"}),e.jsxs("div",{className:"reliability-details-content",children:[e.jsx("div",{children:`P50 raw: ${s?.duration.p50Ms??"—"} ms`}),e.jsx("div",{children:`P95 raw: ${s?.duration.p95Ms??"—"} ms`}),e.jsx("div",{children:`Sample count: ${s?.duration.sampleCount??0}`}),s?.duration.reason?e.jsx("div",{children:`Reason: ${s.duration.reason}`}):null]})]})]}),e.jsxs("div",{className:"card reliability-card",children:[e.jsx("h3",{children:"Merge attempts"}),e.jsxs("div",{className:"reliability-stat-row",children:[e.jsx("span",{children:"Mean"}),e.jsx("strong",{children:s?.mergeAttempts.mean?.toFixed(2)??"—"})]}),e.jsxs("div",{className:"reliability-stat-row",children:[e.jsx("span",{children:"Max"}),e.jsx("strong",{children:s?.mergeAttempts.max??"—"})]}),e.jsx("ul",{className:"reliability-histogram",children:Object.entries(s?.mergeAttempts.histogram??{}).map(([t,a])=>e.jsxs("li",{children:[e.jsx("span",{children:t}),e.jsx("div",{className:"reliability-histogram-bar-wrap",children:e.jsx("div",{className:"reliability-histogram-bar",style:{width:`${Math.min(a*20,100)}%`}})}),e.jsx("strong",{children:a})]},t))}),e.jsxs("details",{className:"reliability-details",children:[e.jsx("summary",{children:"More stats"}),e.jsxs("div",{className:"reliability-details-content",children:[e.jsx("div",{children:`Tasks counted: ${x}`}),e.jsx("div",{children:`Histogram total: ${x}`}),s?.mergeAttempts.reason?e.jsx("div",{children:`Reason: ${s.mergeAttempts.reason}`}):null]})]})]})]}),v?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-labelledby":"reliability-reset-title",children:[e.jsx("div",{className:"modal-header",children:e.jsx("h2",{id:"reliability-reset-title",children:"Reset reliability stats?"})}),e.jsx("p",{children:"This sets a new baseline for reliability statistics. Historical events older than the reset time are excluded from counts but are not deleted."}),m?e.jsx("div",{className:"form-error",children:m}):null,e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn",onClick:()=>h(!1),children:"Cancel"}),e.jsx("button",{className:"btn btn-danger",onClick:()=>{p().catch(t=>{u(t instanceof Error?t.message:"Failed to reset reliability stats")})},children:"Confirm reset"})]})]})}):null]})}export{R as ReliabilityView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.reliability-view{display:flex;flex-direction:column;gap:var(--space-lg);height:100%;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}.reliability-card{padding:var(--space-lg);border:var(--border-width-thin, .0625rem) solid var(--border);border-radius:var(--radius-md);background:var(--card)}.reliability-headline-card{display:flex;flex-direction:column;gap:var(--space-sm)}.reliability-headline{font-size:var(--font-size-2xl, 1.75rem);font-weight:700}.reliability-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-lg)}.reliability-section-header{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm)}.reliability-table{width:100%;border-collapse:collapse;margin-top:var(--space-sm)}.reliability-table th,.reliability-table td{text-align:left;padding:var(--space-xs) var(--space-sm);border-bottom:var(--border-width-thin, .0625rem) solid var(--border)}.reliability-stat-row{display:flex;justify-content:space-between;align-items:center;padding:var(--space-xs) 0}.reliability-muted{color:var(--text-muted)}.reliability-details{margin-top:var(--space-sm)}.reliability-details summary{color:var(--text-muted);cursor:pointer}.reliability-details-content{margin-top:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-xs);color:var(--text-muted)}.reliability-histogram{list-style:none;margin:var(--space-sm) 0 0;padding:0;display:flex;flex-direction:column;gap:var(--space-sm)}.reliability-histogram li{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,6fr) minmax(0,1fr);align-items:center;gap:var(--space-sm)}.reliability-histogram-bar-wrap{width:100%;border-radius:var(--radius-pill);background:color-mix(in srgb,var(--color-info) 15%,transparent);overflow:hidden}.reliability-histogram-bar{height:var(--space-md);background:var(--color-info)}@media(max-width:768px){.reliability-view{padding-bottom:calc(var(--space-lg) + var(--mobile-nav-height) + env(safe-area-inset-bottom,0px) + var(--standalone-bottom-gap))}.reliability-grid{grid-template-columns:minmax(0,1fr)}.reliability-section-header{flex-direction:column;align-items:flex-start}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as n,j as e}from"./vendor-react-K0fH_qHe.js";import{a6 as K,a7 as ce,a8 as ie,aj as le,aC as he,ab as se,aD as me,s as be,aE as fe,aF as xe,aG as ve,aH as pe,aI as ye,aJ as Re,an as _e,u as ge,aK as je,x as Se,aL as we,L as Ne,S as ke}from"./index-Ba-F8c1g.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const Ee="builtin",z={pageFetch:!0,github:!1,localDocs:!0,llmSynthesis:!0};function te(r){const t=r?.researchGlobalDefaults,i=r?.researchSettings;return{enabled:i?.enabled??r?.researchEnabled??r?.researchGlobalEnabled??!0,searchProvider:i?.searchProvider??t?.searchProvider??r?.researchGlobalWebSearchProvider??Ee,synthesisProvider:i?.synthesisProvider??t?.synthesisProvider,synthesisModelId:i?.synthesisModelId??t?.synthesisModelId,enabledSources:{webSearch:!0,pageFetch:i?.enabledSources?.pageFetch??t?.enabledSources?.pageFetch??z.pageFetch,github:i?.enabledSources?.github??t?.enabledSources?.github??z.github,localDocs:i?.enabledSources?.localDocs??t?.enabledSources?.localDocs??z.localDocs,llmSynthesis:i?.enabledSources?.llmSynthesis??t?.enabledSources?.llmSynthesis??z.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 Ce=300,Ae=4e3,Te=["queued","running","cancelling","retry_waiting"];function ae(r,t){if(r instanceof _e){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 Ie(r){if(!r)return{cancelable:!1,retryable:!1,isTransitioning:!1,blockingReason:"No run selected"};const t=Te.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 g;return!i&&t?g="Run is already transitioning":!i&&r.status==="completed"?g="Completed runs cannot be cancelled":!i&&r.status==="cancelled"?g="Run is already cancelled":!i&&r.status==="retry_exhausted"?g="Retry attempts exhausted":!i&&r.status==="failed"?g="Failed runs cannot be cancelled":!i&&r.status==="timed_out"&&(g="Timed out runs cannot be cancelled"),!a&&y&&f===!1&&(g=r.lifecycle?.errorCode==="RETRY_EXHAUSTED"?"Retry attempts exhausted":"Run is not retryable"),{cancelable:i,retryable:a,isTransitioning:t,blockingReason:g}}function Pe(r){const t=r?.projectId,i=t??"",f=`${ie.RESEARCH_RUNS_PREFIX}${i}`,y=`${ie.RESEARCH_SELECTED_ID_PREFIX}${i}`,a=K(f,{maxAgeMs:ce}),g=K(y,{maxAgeMs:le}),N=n.useRef(Array.isArray(a)&&a.length>0),[j,A]=n.useState(()=>Array.isArray(a)?a:[]),[v,I]=n.useState(g??null),[F,S]=n.useState(null),[D,P]=n.useState({available:!0}),[q,L]=n.useState(!(Array.isArray(a)&&a.length>0)),[H,M]=n.useState(null),[T,_]=n.useState(null),[R,k]=n.useState(""),o=n.useRef(0),x=n.useRef(0),$=n.useRef(t);n.useEffect(()=>{$.current!==t&&($.current=t,x.current++);const c=K(f,{maxAgeMs:ce}),l=K(y,{maxAgeMs:le}),h=Array.isArray(c)&&c.length>0;A(Array.isArray(c)?c:[]),I(l??null),S(null),L(!h),N.current=h},[t,f,y]);const E=n.useCallback(async(c=R)=>{const l=++o.current,h=t;N.current||L(!0),M(null),_(null);try{const m=await he({q:c||void 0,limit:100},h);if(l!==o.current||h!==t)return;A(m.runs),se(f,m.runs,{maxBytes:5e5}),N.current=!0,P(m.availability),v&&!m.runs.some(p=>p.id===v)&&(I(null),se(y,null,{maxBytes:5e5}),S(null))}catch(m){if(l!==o.current||h!==t)return;const p=ae(m,"Failed to load research runs");M(p.message),_(p)}finally{l===o.current&&L(!1)}},[t,f,R,y,v]),O=n.useCallback(async c=>{const l=await me(c,t);return S(l.run),P(l.availability),l.run},[t]);n.useEffect(()=>{N.current||L(!0);const c=window.setTimeout(()=>{E(R)},Ce);return()=>window.clearTimeout(c)},[E,R]),n.useEffect(()=>{if(!v){S(null);return}O(v)},[O,v]),n.useEffect(()=>{const c=x.current,l=()=>x.current!==c,h=t?`?projectId=${encodeURIComponent(t)}`:"";let m=!0;const p=()=>{!m||l()||(E(),v&&O(v))},w=be(`/api/events${h}`,{events:{"research:run:created":p,"research:run:updated":p,"research:run:completed":p,"research:run:failed":p,"research:run:cancelled":p},onReconnect:p}),U=window.setInterval(p,Ae);return()=>{m=!1,w(),window.clearInterval(U)}},[t,E,v,O]);const V=n.useCallback(c=>{I(c),se(y,c,{maxBytes:5e5})},[y]);return{runs:j,selectedRun:F,selectedRunId:v,setSelectedRunId:V,availability:D,loading:q,error:H,searchQuery:R,setSearchQuery:k,refresh:E,createRun:c=>Re(c,t),cancelRun:async c=>{try{_(null);const l=await ye(c,t);return v===c&&S(l.run),await E(),l}catch(l){const h=ae(l,"Failed to cancel run");throw _(h),h}},retryRun:async c=>{try{_(null);const l=await pe(c,t);return v===c&&S(l.run),await E(),l}catch(l){const h=ae(l,"Failed to retry run");throw _(h),h}},exportRun:(c,l)=>ve(c,l,t),createTaskFromRun:(c,l,h,m,p,w)=>xe(c,{title:l,findingId:h,description:m,priority:p,attachExport:w},t),attachRunToTask:(c,l,h,m)=>fe(c,{taskId:l,findingId:h,attachExport:m},t),uiError:T,runActionState:Ie(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 Le({open:r,mode:t,run:i,finding:f,projectId:y,onClose:a,onConfirm:g}){ge(r);const[N,j]=n.useState(!1),[A,v]=n.useState(""),[I,F]=n.useState(""),[S,D]=n.useState("normal"),[P,q]=n.useState(""),[L,H]=n.useState([]),[M,T]=n.useState(!1),[_,R]=n.useState(!1),k=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),v(`Research: ${f.heading||i.title}`),F(k),D("normal"),q(""),t==="enrich"&&(T(!0),je(50,0,y).then(o=>H(o.filter(x=>x.column!=="archived"))).finally(()=>T(!1))))},[r,t,y,f.heading,k,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:k||"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=>v(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:I,onChange:o=>F(o.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Priority",e.jsxs("select",{className:"select",value:S,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:P,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:_||t==="enrich"&&!P,onClick:()=>{R(!0),g({taskId:t==="enrich"?P:void 0,title:t==="create"?A.trim():void 0,description:t==="create"?I.trim():void 0,priority:t==="create"?S:void 0,attachExport:N}).finally(()=>R(!1))},children:t==="create"?"Create Task":"Enrich Task"})]})]})}):null}const Me=["web-search","page-fetch","github","local-docs","llm-synthesis"],Fe={"web-search":"webSearch","page-fetch":"pageFetch",github:"github","local-docs":"localDocs","llm-synthesis":"llmSynthesis"},De={"web-search":"Web Search","page-fetch":"Page Fetch",github:"GitHub","local-docs":"Local Docs","llm-synthesis":"LLM Synthesis"};function Ge({projectId:r,addToast:t,onOpenSettings:i,readinessVersion:f=0}){const{runs:y,selectedRun:a,selectedRunId:g,setSelectedRunId:N,availability:j,loading:A,error:v,searchQuery:I,setSearchQuery:F,createRun:S,cancelRun:D,retryRun:P,exportRun:q,createTaskFromRun:L,attachRunToTask:H,statusCounts:M,refresh:T,uiError:_,runActionState:R}=Pe({projectId:r}),[k,o]=n.useState(""),[x,$]=n.useState(()=>te(void 0)),[E,O]=n.useState([]),[V,c]=n.useState(!1),[l,h]=n.useState([]),[m,p]=n.useState(null),[w,U]=n.useState(null),Q=j.supportedProviders??Me,W=x.searchProvider,X=s=>s==="web-search"?!0:x.enabledSources[Fe[s]];n.useEffect(()=>{const s=Q.filter(d=>X(d));h(d=>{const b=d.filter(u=>s.includes(u));return b.length>0?b:s})},[x.enabledSources,Q]),n.useEffect(()=>{let s=!1;return Promise.all([Se(r),we().catch(()=>({providers:[]}))]).then(([d,b])=>{s||($(te(d)),O(b.providers.filter(u=>u.type==="api_key").map(u=>({id:u.id,authenticated:u.authenticated}))))}).catch(()=>{s||$(te(void 0))}),()=>{s=!0}},[r,f]);const oe=n.useMemo(()=>a?a.status:"No run selected",[a]),de=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]),Y=j.supportedExportFormats??["markdown","json","html"],J=n.useMemo(()=>new Map(E.map(s=>[s.id,s.authenticated])),[E]),Z=n.useMemo(()=>{const s=new Set;return x.enabledSources.webSearch&&W&&s.add(W),x.enabledSources.llmSynthesis&&x.synthesisProvider&&s.add(x.synthesisProvider),[...s].filter(d=>J.has(d))},[x.enabledSources.llmSynthesis,x.enabledSources.webSearch,x.synthesisProvider,W,J]).find(s=>J.get(s)!==!0),G=n.useMemo(()=>j.available?x.enabled?Z?{reason:`Missing API key for ${Z}.`,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,x.enabled,Z]),B=async(s,d,b)=>{p(s);try{await d(),t?.(b,"success"),await T()}catch(u){t?.(u instanceof Error?u.message:"Action failed","error")}finally{p(null)}},ee=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)}}},ue=async()=>{if(k.trim()){c(!0);try{const s=l.filter(b=>X(b));if(s.length===0){c(!1),t?.("No enabled research sources are available for this project.","error");return}const d=await S({query:k.trim(),providers:s});N(d.run.id),o(""),t?.("Research run created","success"),await T()}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 T(),children:"Refresh"})})]}),G?e.jsxs("div",{className:"research-view__state research-view__state--error card","data-testid":"research-state-unavailable",children:[e.jsx("p",{children:G.reason}),G.details&&e.jsx("p",{children:G.details}),e.jsxs("p",{children:["Current defaults: provider ",x.searchProvider??"(not set)",", max sources ",x.limits.maxSourcesPerRun]}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:()=>void T(),children:"Refresh"}),e.jsx("button",{className:"btn btn-primary",type:"button",onClick:()=>i?.(G.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:k,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:Q.map(s=>{const d=X(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:[De[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:!k.trim()||V,onClick:()=>void ue(),children:[V?e.jsx(Ne,{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(ke,{size:14}),e.jsx("input",{id:"research-run-search",className:"input",placeholder:"Search runs",value:I,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${g===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&&v&&e.jsx("p",{"data-testid":"research-state-error",children:v}),!A&&!v&&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:de}),e.jsx("strong",{children:oe})]}),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:R.cancelable?void 0:R.blockingReason,disabled:m==="cancel"||m==="retry"||!R.cancelable,onClick:()=>void B("cancel",()=>D(a.id),"Run cancelled"),children:"Cancel"}),e.jsx("button",{className:"btn",type:"button",title:R.retryable?void 0:R.blockingReason,disabled:m==="cancel"||m==="retry"||!R.retryable,onClick:()=>void B("retry",()=>P(a.id),"Run retried"),children:"Retry"}),Y.includes("markdown")&&e.jsx("button",{className:"btn",type:"button",disabled:m==="export-markdown",onClick:()=>void ee("markdown"),children:"Export MD"}),Y.includes("json")&&e.jsx("button",{className:"btn",type:"button",disabled:m==="export-json",onClick:()=>void ee("json"),children:"Export JSON"}),Y.includes("html")&&e.jsx("button",{className:"btn",type:"button",disabled:m==="export-html",onClick:()=>void ee("html"),children:"Export HTML"})]}),a.error&&e.jsx("p",{className:"research-view__error",children:a.error}),_&&e.jsxs("div",{className:"form-error",role:"alert",children:[e.jsx("p",{children:_.message}),_.setupHint&&e.jsx("p",{children:_.setupHint}),_.code==="MISSING_CREDENTIALS"&&e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>i?.("authentication"),children:"Open Authentication Settings"}),_.code==="FEATURE_DISABLED"&&e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>i?.("research-project"),children:"Open Research Settings"})]}),R.blockingReason&&e.jsx("p",{className:"research-view__run-query",children:R.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&&w&&(()=>{const s=a.results?.findings?.findIndex((b,u)=>(b.id?.trim()||`finding-${u+1}`)===w.findingId)??-1,d=s>=0?a.results.findings[s]:null;return d?e.jsx(Le,{open:!0,mode:w.mode,run:a,finding:{id:w.findingId,heading:d.heading,content:d.content},projectId:r,onClose:()=>U(null),onConfirm:async({taskId:b,title:u,description:C,priority:re,attachExport:ne})=>{w.mode==="create"?await B("create-task",()=>L(a.id,u,w.findingId,C,re,ne),"Task created from research"):b&&await B("attach-task",()=>H(a.id,b,w.findingId,ne),"Task enriched from research"),U(null)}}):null})()]})}export{Ge as ResearchView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.secrets-view{display:flex;flex-direction:column;gap:var(--space-lg);padding-block:var(--space-md);padding-inline:var(--space-xl)}.secrets-header{display:flex;align-items:center;justify-content:space-between;gap:var(--space-md)}.secrets-header h2{margin:0}.secrets-header-actions{display:flex;gap:var(--space-sm)}.secrets-loading,.secrets-empty{color:var(--text-muted);display:flex;align-items:center;gap:var(--space-sm);padding-block:var(--space-sm)}.secrets-sync-card{display:flex;flex-direction:column;gap:var(--space-md)}.secrets-sync-header{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:var(--space-md)}.secrets-sync-status{display:inline-flex;align-items:center;gap:var(--space-xs);margin:0;color:var(--text-muted)}.secrets-sync-copy{margin:0;max-width:60ch;color:var(--text-muted);line-height:1.5}.secrets-sync-actions{display:flex;gap:var(--space-sm)}.secrets-list{display:flex;flex-direction:column;gap:var(--space-md)}.secrets-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--space-md);align-items:start}.secrets-row-main{display:flex;flex-direction:column;gap:var(--space-sm)}.secrets-row-key{font-family:var(--font-mono);font-size:1em;overflow-wrap:anywhere}.secrets-row-meta{display:flex;flex-wrap:wrap;gap:var(--space-sm);row-gap:var(--space-xs)}.secrets-chip{border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-pill);padding:var(--space-xs) var(--space-sm);color:var(--text-muted)}.secrets-revealed{margin:0;max-width:100%;overflow-x:auto;white-space:pre-wrap;word-break:break-all;font-family:var(--font-mono);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-sm);padding:var(--space-sm);background:var(--surface)}.secrets-row-side{display:flex;flex-direction:column;gap:var(--space-sm);align-items:flex-end}.secrets-row-read{color:var(--text-muted);font-size:.95em;font-weight:400}.secrets-row-actions,.secrets-confirm,.secrets-value-row,.secrets-radio-row{display:flex;gap:var(--space-sm);align-items:center}.secrets-radio-row{flex-wrap:wrap;row-gap:var(--space-xs)}.secrets-modal-body{display:flex;flex-direction:column;gap:var(--space-md);padding:0 var(--space-xl) var(--space-lg)}.secrets-modal-body .form-group{margin:0;padding:0}.secrets-value-row .input{flex:1}@media(max-width:768px){.secrets-view{padding-inline:var(--space-md);padding-bottom:calc(var(--space-md) + var(--mobile-nav-height) + env(safe-area-inset-bottom,0px) + var(--standalone-bottom-gap, 0px))}.secrets-header,.secrets-row,.secrets-sync-header{grid-template-columns:minmax(0,1fr);display:flex;flex-direction:column;align-items:stretch;gap:var(--space-sm)}.secrets-sync-header{flex-wrap:wrap}.secrets-sync-copy{max-width:none}.secrets-sync-actions{flex-direction:column}.secrets-row-key{font-size:.95em}.secrets-row-side{width:100%;align-items:flex-start;gap:var(--space-sm)}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{R as B,J as ce,ad as I,ae as J,bw as oe,bx as ie,b1 as de,Y as pe}from"./index-Ba-F8c1g.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const he="__sync_passphrase__",E={key:"",value:"",description:"",scope:"project",accessPolicy:"prompt",envExportable:!1,envExportKey:""},ve=({addToast:c})=>{const[w,Y]=l.useState([]),[k,P]=l.useState(!0),[R,z]=l.useState(null),[K,x]=l.useState(null),[o,M]=l.useState(null),[q,h]=l.useState(!1),[H,j]=l.useState(null),[n,r]=l.useState(E),[T,b]=l.useState(!1),[_,f]=l.useState({}),[G,$]=l.useState(null),[i,U]=l.useState(!1),[Q,A]=l.useState(!1),[y,O]=l.useState(""),[N,D]=l.useState(""),[W,V]=l.useState(!1),g=l.useRef(new Map),S=l.useRef(new Map),t=l.useCallback(async(s,a)=>{const d=await fetch(s,{...a,headers:{"Content-Type":"application/json",...a?.headers??{}}});if(!d.ok){const p=await d.json().catch(()=>({error:"Request failed"}));throw new Error(String(p?.error??"Request failed"))}if(d.status!==204)return d.json()},[]),u=l.useCallback(async()=>{P(!0),z(null);try{const s=await t("/api/secrets");Y(s.secrets)}catch(s){z(s instanceof Error?s.message:String(s))}finally{P(!1)}},[t]),v=l.useCallback(async()=>{try{const s=await t("/api/secrets/sync-passphrase");U(!!s.configured)}catch(s){c?.(`Failed to load sync passphrase status: ${s instanceof Error?s.message:String(s)}`,"error")}},[c,t]);l.useEffect(()=>(u(),v(),()=>{g.current.forEach(s=>clearTimeout(s)),S.current.forEach(s=>clearTimeout(s))}),[u,v]);const C=()=>{A(!1),O(""),D("")},X=async s=>{await t("/api/secrets/sync-passphrase",{method:"PUT",body:JSON.stringify({passphrase:s})})},Z=async()=>{V(!0);try{await X(y),c?.(i?"Sync passphrase rotated":"Sync passphrase set","success"),C(),await v()}catch(s){c?.(`Failed to save sync passphrase: ${s instanceof Error?s.message:String(s)}`,"error")}finally{V(!1)}},ee=async()=>{if(window.confirm("Clear the cross-node sync passphrase? Existing sync pairs will stop working until you set a new passphrase."))try{await t("/api/secrets/sync-passphrase",{method:"DELETE"}),c?.("Sync passphrase cleared","success"),await v()}catch(a){c?.(`Failed to clear sync passphrase: ${a instanceof Error?a.message:String(a)}`,"error")}},se=()=>{M(null),r(E),h(!0),b(!1),x(null)},ae=s=>{M(s),r({key:s.key,value:"",description:s.description??"",scope:s.scope,accessPolicy:s.accessPolicy,envExportable:s.envExportable,envExportKey:s.envExportKey??""}),h(!0),b(!1),x(null)},ne=async()=>{x(null);try{if(o){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 t(`/api/secrets/${o.scope}/${o.id}`,{method:"PATCH",body:JSON.stringify(s)})}else await t("/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),r(E),await u()}catch(s){x(s instanceof Error?s.message:String(s))}},le=async s=>{const a=await t(`/api/secrets/${s.scope}/${s.id}/reveal`,{method:"POST"});f(m=>({...m,[s.id]:a.value})),c?.("Revealed","success");const d=setTimeout(()=>{f(m=>({...m,[s.id]:null}))},3e4),p=g.current.get(s.id);p&&clearTimeout(p),g.current.set(s.id,d)},re=async s=>{const a=_[s.id];if(!a)return;await navigator.clipboard.writeText(a),$(s.id),c?.("Copied","success");const d=setTimeout(()=>{$(null),f(m=>({...m,[s.id]:null}))},1500),p=S.current.get(s.id);p&&clearTimeout(p),S.current.set(s.id,d)},te=async s=>{await t(`/api/secrets/${s.scope}/${s.id}`,{method:"DELETE"}),j(null),await u()},F=l.useMemo(()=>[...w].filter(s=>!(s.scope==="global"&&s.key===he)).sort((s,a)=>s.key.localeCompare(a.key)),[w]),L=y.length>0&&y===N;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 u(),children:[e.jsx(B,{size:14})," Refresh"]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:se,children:[e.jsx(ce,{size:14})," 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 ${i?"status-dot--online":"status-dot--pending"}`,"aria-hidden":"true"})," ",i?"Configured":"Not configured"]})]}),e.jsxs("div",{className:"secrets-sync-actions",children:[e.jsx("button",{className:"btn",onClick:()=>A(!0),children:i?"Rotate":"Set passphrase"}),i?e.jsx("button",{className:"btn btn-danger",onClick:()=>void ee(),children:"Clear"}):null]})]}),e.jsxs("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. "," ",e.jsx("a",{href:"/docs/secrets.md#cross-node-sync",target:"_blank",rel:"noreferrer",children:"Learn more"})]})]}),R?e.jsx("div",{className:"form-error",children:R}):null,k?e.jsxs("div",{className:"secrets-loading",children:[e.jsx(B,{size:14,className:"spin"})," Loading…"]}):null,!k&&F.length===0?e.jsx("div",{className:"secrets-empty",children:"No secrets found."}):null,e.jsx("div",{className:"secrets-list",children:F.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",{className:"btn btn-icon",onClick:()=>void le(s),"aria-label":"Reveal",children:a?e.jsx(I,{size:14}):e.jsx(J,{size:14})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>void re(s),"aria-label":"Copy",disabled:!a,children:G===s.id?e.jsx(oe,{size:14}):e.jsx(ie,{size:14})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>ae(s),"aria-label":"Edit",children:e.jsx(de,{size:14})}),e.jsx("button",{className:"btn btn-icon btn-danger",onClick:()=>j(s.id),"aria-label":"Delete",children:e.jsx(pe,{size:14})})]}),H===s.id?e.jsxs("div",{className:"secrets-confirm",children:[e.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void te(s),children:"Confirm"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>j(null),children:"Cancel"})]}):null]})]},s.id)})}),Q?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":i?"Rotate sync passphrase":"Set sync passphrase",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:i?"Rotate sync passphrase":"Set sync passphrase"}),e.jsx("button",{className:"modal-close",onClick:C,"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:y,onChange:s=>O(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:N,onChange:s=>D(s.target.value)})]}),!L&&N.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:C,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void Z(),disabled:!L||W,children:i?"Rotate":"Set passphrase"})]})})]})}):null,q?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":o?"Edit secret":"Add secret",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:o?"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=>r(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:T?"text":"password",autoComplete:"off",spellCheck:!1,value:n.value,onChange:s=>r(a=>({...a,value:s.target.value}))}),e.jsx("button",{className:"btn btn-icon",onClick:()=>b(s=>!s),children:T?e.jsx(I,{size:14}):e.jsx(J,{size:14})})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Description"}),e.jsx("textarea",{className:"input",value:n.description,onChange:s=>r(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:()=>r(s=>({...s,scope:"project"})),disabled:!!o})," Project"]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",checked:n.scope==="global",onChange:()=>r(s=>({...s,scope:"global"})),disabled:!!o})," Global"]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Access policy"}),e.jsxs("select",{className:"select",value:n.accessPolicy,onChange:s=>r(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=>r(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=>r(a=>({...a,envExportKey:s.target.value}))})]}):null,K?e.jsx("div",{className:"form-error",children:K}):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 ne(),children:o?"Save":"Create"})]})})]})}):null]})};export{ve as SecretsView};
|