@runfusion/fusion 0.14.3 → 0.16.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 +4151 -2184
- package/dist/client/assets/AgentDetailView-BoEpPOjM.css +1 -0
- package/dist/client/assets/AgentDetailView-KQz9dg0n.js +18 -0
- package/dist/client/assets/AgentsView-8Xo-c04o.js +517 -0
- package/dist/client/assets/ChatView-CjgOh8x7.js +1 -0
- package/dist/client/assets/DevServerView-BOPrzi-j.js +1 -0
- package/dist/client/assets/{DirectoryPicker-BkAIXNrP.js → DirectoryPicker-CFj7FOgn.js} +1 -1
- package/dist/client/assets/DocumentsView-CcJNmH06.js +1 -0
- package/dist/client/assets/{InsightsView-Dz9Ivclw.js → InsightsView-B0DKRIYV.js} +1 -1
- package/dist/client/assets/MemoryView-DDbr1DaJ.js +2 -0
- package/dist/client/assets/NodesView-BprfihLf.css +1 -0
- package/dist/client/assets/NodesView-BqtHfXsl.js +14 -0
- package/dist/client/assets/{PiExtensionsManager-C_U2g7y3.js → PiExtensionsManager-QgzWFBAT.js} +3 -3
- package/dist/client/assets/{PluginManager-pIDsTk5v.js → PluginManager-KHiz9oLY.js} +1 -1
- package/dist/client/assets/ResearchView-CVxPC1vz.css +1 -0
- package/dist/client/assets/ResearchView-s3SrjNBm.js +1 -0
- package/dist/client/assets/RoadmapsView-BlbAZTdi.js +6 -0
- package/dist/client/assets/RoadmapsView-DdGlfuu-.css +1 -0
- package/dist/client/assets/SettingsModal-D0QA2W5K.css +1 -0
- package/dist/client/assets/{SettingsModal-BiZVi3cI.js → SettingsModal-D5EUFR2z.js} +1 -1
- package/dist/client/assets/SettingsModal-c9MG4sxl.js +31 -0
- package/dist/client/assets/{SetupWizardModal-BcIGBBpA.js → SetupWizardModal-tTXAm1Wb.js} +1 -1
- package/dist/client/assets/SkillsView-CS4ONN3D.js +1 -0
- package/dist/client/assets/{folder-open-CgjcFqww.js → folder-open-DObdkm5J.js} +1 -1
- package/dist/client/assets/index-BRaIPmpp.js +682 -0
- package/dist/client/assets/index-DeED_ky2.css +1 -0
- package/dist/client/assets/{star-4nUh67-U.js → star-BkGA2L-k.js} +1 -1
- package/dist/client/assets/{upload-CEt5-Bnq.js → upload-B0NF4J5P.js} +1 -1
- package/dist/client/assets/{users-4I0JDmgO.js → users-DgomiHTd.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/extension.js +4248 -3235
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/manifest.json +16 -0
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +32 -0
- package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraphView.css +101 -0
- package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraphView.tsx +320 -0
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/storage.test.ts +31 -0
- package/dist/plugins/fusion-plugin-dependency-graph/src/index.ts +25 -0
- package/dist/plugins/fusion-plugin-dependency-graph/src/storage.ts +23 -0
- package/package.json +8 -4
- package/skill/fusion/references/engine-tools.md +2 -2
- package/dist/client/assets/AgentDetailView-B5tq9ius.css +0 -1
- package/dist/client/assets/AgentDetailView-BBCnqhqI.js +0 -18
- package/dist/client/assets/AgentsView-BY-Yq-Te.js +0 -522
- package/dist/client/assets/ChatView-DkoJNxFW.js +0 -1
- package/dist/client/assets/DevServerView-qvs6pp6c.js +0 -1
- package/dist/client/assets/DocumentsView-BcaUGgaL.js +0 -1
- package/dist/client/assets/MemoryView-BsweARBT.js +0 -2
- package/dist/client/assets/NodesView-DCoS6iYh.css +0 -1
- package/dist/client/assets/NodesView-bAU-v4bJ.js +0 -14
- package/dist/client/assets/ResearchView-BzRdUzNq.css +0 -1
- package/dist/client/assets/ResearchView-D4Eib_uR.js +0 -1
- package/dist/client/assets/RoadmapsView-BOYnyMCh.css +0 -1
- package/dist/client/assets/RoadmapsView-BaGwsUGS.js +0 -6
- package/dist/client/assets/SettingsModal-CRyg643t.js +0 -31
- package/dist/client/assets/SettingsModal-DcGFm6NR.css +0 -1
- package/dist/client/assets/SkillMultiselect-DDHJnrkn.css +0 -1
- package/dist/client/assets/SkillMultiselect-DPARHJeQ.js +0 -1
- package/dist/client/assets/SkillsView-Da_d_HPu.js +0 -1
- package/dist/client/assets/TodoView-5rAeqYtV.js +0 -6
- package/dist/client/assets/TodoView-SeO9o7km.css +0 -1
- package/dist/client/assets/index-D1gTSlYB.css +0 -1
- package/dist/client/assets/index-DoQ5ALYY.js +0 -662
- package/dist/client/assets/list-checks-C9YWtF7h.js +0 -6
package/dist/client/assets/{PiExtensionsManager-C_U2g7y3.js → PiExtensionsManager-QgzWFBAT.js}
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{c as
|
|
1
|
+
import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{c as M,dW as Z,dX as H,dY as Q,R as $,dO as y,J as V,ae as T,O as ee,W as se,cl as L,F as _,dZ as ae,d_ as te,d$ as D,X as ie}from"./index-BRaIPmpp.js";import"./vendor-xterm-DzcZoU0P.js";/**
|
|
2
2
|
* @license lucide-react v1.7.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const ne=[["path",{d:"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z",key:"e79jfc"}],["circle",{cx:"13.5",cy:"6.5",r:".5",fill:"currentColor",key:"1okk4w"}],["circle",{cx:"17.5",cy:"10.5",r:".5",fill:"currentColor",key:"f64h9f"}],["circle",{cx:"6.5",cy:"12.5",r:".5",fill:"currentColor",key:"qy21gx"}],["circle",{cx:"8.5",cy:"7.5",r:".5",fill:"currentColor",key:"fotxhn"}]],M
|
|
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"}]],O=M("palette",ne);/**
|
|
7
7
|
* @license lucide-react v1.7.0 - ISC
|
|
8
8
|
*
|
|
9
9
|
* This source code is licensed under the ISC license.
|
|
10
10
|
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
-
*/const le=[["path",{d:"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z",key:"w46dr5"}]],W=
|
|
11
|
+
*/const le=[["path",{d:"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z",key:"w46dr5"}]],W=M("puzzle",le);function ce(t){return t.replace(/-/g,"-")}function re(t){return{"fusion-global":"Fusion Global","pi-global":"Pi Global","fusion-project":"Fusion Project","pi-project":"Pi Project",package:"Package"}[t]??t}function oe(t){return t.startsWith("npm:")?"npm":t.startsWith("git:")?"git":"local"}function de(t){return t.replace(/^(npm:|git:)/,"")}function he({addToast:t,projectId:x}){const[c,A]=l.useState(null),[f,P]=l.useState(!0),[N,S]=l.useState(!1),[E,w]=l.useState(!1),[h,F]=l.useState(""),[G,I]=l.useState(new Set),[p,X]=l.useState([]),[b,C]=l.useState(!0),[q,z]=l.useState(!1),r=l.useCallback(async()=>{try{P(!0);const s=await Z();A(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);X(s.extensions)}catch(s){t(`Failed to load extensions: ${s instanceof Error?s.message:String(s)}`,"error")}finally{C(!1)}},[t,x]),B=l.useCallback(async s=>{try{z(!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{z(!1)}},[p,x,m,t]);l.useEffect(()=>{r()},[r]),l.useEffect(()=>{m()},[m]);const J=s=>{I(i=>{const a=new Set(i);return a.has(s)?a.delete(s):a.add(s),a})},R=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)}},K=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)}},U=async s=>{if(!c)return;const i=c.packages.filter(a=>(typeof a=="string"?a:a.source)!==s);try{await D({packages:i}),t("Package removed","success"),await r()}catch(a){t(`Failed to remove package: ${a instanceof Error?a.message:String(a)}`,"error")}},Y=async(s,i)=>{if(!c)return;const a=c[s].filter(n=>n!==i);try{await D({[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:()=>Y(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(),R())},disabled:N}),e.jsxs("button",{className:"btn btn-primary",onClick:R,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:K,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=oe(a),g=de(a),j=typeof s=="object"&&s!==null,v=j&&(s.extensions?.length??0)>0||(s.skills?.length??0)>0||(s.prompts?.length??0)>0||(s.themes?.length??0)>0,k=G.has(i);return e.jsxs("div",{className:"pi-ext-package-card",children:[e.jsxs("div",{className:"pi-ext-package-header",children:[j&&v?e.jsx("button",{className:"pi-ext-expand-btn",onClick:()=>J(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:()=>U(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(W,{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(L,{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(O,{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",W,"extensions"),u("Skills",L,"skills"),u("Prompts",_,"prompts"),u("Themes",O,"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--${ce(s.source)}`,children:re(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 B(s),disabled:q,"aria-label":`Toggle ${s.name}`}),e.jsx("span",{className:"toggle-slider"})]})})]},s.id))})]})]})}export{he as PiExtensionsManager};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as o,j as s}from"./vendor-react-K0fH_qHe.js";import{w as T,dQ as ee,s as se,X as A,an as ne,J as O,dR as V,V as M,R as te,dS as ie,aF as ae,ch as le,dT as re,dU as ce,dV as de,dW as ue,dX as _,ce as oe}from"./index-DoQ5ALYY.js";import{D as me}from"./DirectoryPicker-BkAIXNrP.js";import"./vendor-xterm-DzcZoU0P.js";import"./folder-open-CgjcFqww.js";const ge=[{id:"fusion-plugin-agent-browser-runtime",name:"Agent Browser Runtime",path:"./plugins/fusion-plugin-agent-browser-runtime",experimental:!0},{id:"fusion-plugin-hermes-runtime",name:"Hermes Runtime",path:"./plugins/fusion-plugin-hermes-runtime",experimental:!0},{id:"fusion-plugin-paperclip-runtime",name:"Paperclip Runtime",path:"./plugins/fusion-plugin-paperclip-runtime"},{id:"fusion-plugin-openclaw-runtime",name:"OpenClaw Runtime",path:"./plugins/fusion-plugin-openclaw-runtime",experimental:!0}],N={started:"var(--color-success)",loaded:"var(--color-warning)",error:"var(--color-error)",stopped:"var(--color-muted)",installed:"var(--color-info)"};function fe({addToast:l,projectId:c}){const[x,b]=o.useState([]),[S,w]=o.useState(!0),[H,f]=o.useState(!1),[j,v]=o.useState(""),[C,P]=o.useState(!1),[h,R]=o.useState(null),[i,y]=o.useState(null),[a,p]=o.useState({}),[J,$]=o.useState(!1),[I,E]=o.useState(null),{confirm:X}=T(),m=o.useCallback(async()=>{try{w(!0);const e=await ee(c);b(e)}catch(e){l(`Failed to load plugins: ${e instanceof Error?e.message:String(e)}`,"error")}finally{w(!1)}},[c,l]);o.useEffect(()=>{m()},[m]);const G=o.useRef([]);G.current=x,o.useEffect(()=>{const e=c?`?projectId=${encodeURIComponent(c)}`:"",n=d=>{try{const t=JSON.parse(d.data);if(c&&t.projectId&&t.projectId!==c)return;switch(t.transition){case"installing":case"enabled":case"disabled":case"settings-updated":b(u=>{const g=u.findIndex(r=>r.id===t.pluginId);if(g>=0){const r=[...u];return r[g]={...r[g],enabled:t.enabled,state:t.state,settings:t.settings,error:t.error},r}else return m(),u});break;case"uninstalled":b(u=>u.filter(g=>g.id!==t.pluginId));break;case"error":b(u=>{const g=u.findIndex(r=>r.id===t.pluginId);if(g>=0){const r=[...u];return r[g]={...r[g],state:t.state,error:t.error},r}return u});break}}catch{}};return se(`/api/events${e}`,{events:{"plugin:lifecycle":n},onReconnect:()=>{m()}})},[c,m]);const z=async()=>{if(!j.trim()){l("Please enter a plugin path","error");return}try{P(!0),await _({path:j},c),l("Plugin installed successfully","success"),f(!1),v(""),await m()}catch(e){l(`Failed to install plugin: ${e instanceof Error?e.message:String(e)}`,"error")}finally{P(!1)}},K=async e=>{try{E(e.id),await _({path:e.path},c),l(`${e.name} installed successfully`,"success"),await m()}catch(n){l(`Failed to install ${e.name}: ${n instanceof Error?n.message:String(n)}`,"error")}finally{E(null)}},B=async e=>{try{await de(e.id,c),l(`${e.name} enabled`,"success"),await m()}catch(n){l(`Failed to enable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},F=async e=>{try{await ce(e.id,c),l(`${e.name} disabled`,"success"),await m()}catch(n){l(`Failed to disable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},U=async e=>{try{R(e.id),await re(e.id,c),l(`${e.name} reloaded`,"success"),await m()}catch(n){l(`Failed to reload plugin: ${n instanceof Error?n.message:String(n)}`,"error")}finally{R(null)}},L=async e=>{if(await X({title:"Uninstall Plugin",message:`Are you sure you want to uninstall "${e.name}"?`,danger:!0}))try{await ue(e.id,c),l(`${e.name} uninstalled`,"success"),await m(),y(null)}catch(d){l(`Failed to uninstall plugin: ${d instanceof Error?d.message:String(d)}`,"error")}},q=async e=>{y(e);try{$(!0);const n=await oe(e.id,c);p(n)}catch{p({})}finally{$(!1)}},Q=async()=>{if(i)try{await le(i.id,a,c),l("Settings saved","success")}catch(e){l(`Failed to save settings: ${e instanceof Error?e.message:String(e)}`,"error")}};if(i)return s.jsxs("div",{className:"plugin-manager-detail","data-testid":"plugin-manager-detail",children:[s.jsxs("div",{className:"plugin-manager-detail-header",children:[s.jsx("button",{className:"btn-icon",onClick:()=>y(null),"aria-label":"Back to plugin list",children:s.jsx(A,{size:16})}),s.jsxs("div",{className:"plugin-detail-title",children:[s.jsx("h4",{className:"plugin-detail-name",children:i.name}),s.jsx("span",{className:"plugin-state-badge",style:{color:N[i.state]||N.installed},children:i.state})]})]}),s.jsxs("div",{className:"plugin-detail-content",children:[s.jsxs("div",{className:"plugin-detail-card",children:[i.description&&s.jsx("p",{className:"plugin-description",children:i.description}),i.author&&s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Author:"}),i.author]}),i.homepage&&s.jsxs("p",{className:"plugin-detail-meta-row plugin-homepage",children:[s.jsx("span",{className:"text-muted",children:"Homepage:"}),s.jsxs("a",{href:i.homepage,target:"_blank",rel:"noopener noreferrer",children:[i.homepage,s.jsx(ne,{size:12})]})]}),s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Version:"}),i.version]})]}),s.jsxs("div",{className:"plugin-detail-card",children:[s.jsx("h5",{className:"plugin-detail-section-heading",children:"Settings"}),J?s.jsx("p",{className:"text-muted",children:"Loading..."}):i.settingsSchema&&Object.keys(i.settingsSchema).length>0?s.jsxs("div",{className:"plugin-settings-form",children:[Object.entries(i.settingsSchema).map(([e,n])=>{const d=`setting-${e}-help`;return s.jsxs("div",{className:"form-group",children:[s.jsxs("label",{htmlFor:`setting-${e}`,children:[n.label||e,n.required&&" *"]}),n.type==="string"&&!n.multiline&&s.jsx("input",{className:"input",type:"text",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="string"&&n.multiline&&s.jsx("textarea",{className:"input",id:`setting-${e}`,rows:4,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="password"&&s.jsx("input",{className:"input",type:"password",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="number"&&s.jsx("input",{className:"input",type:"number",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:Number(t.target.value)}),"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="boolean"&&s.jsxs("label",{className:"checkbox-label",children:[s.jsx("input",{type:"checkbox",checked:a[e]??!1,onChange:t=>p({...a,[e]:t.target.checked})}),n.description]}),n.type==="enum"&&s.jsxs("select",{className:"select",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),"aria-describedby":n.description&&!n.required?d:void 0,children:[s.jsx("option",{value:"",children:"Select..."}),n.enumValues?.map(t=>s.jsx("option",{value:t,children:t},t))]}),n.type==="array"&&s.jsxs("div",{className:"plugin-settings-array",children:[a[e]?.map((t,u)=>s.jsxs("div",{className:"plugin-settings-array-item",children:[s.jsx("input",{className:"input",type:n.itemType==="number"?"number":"text",value:t??"",onChange:g=>{const r=g.target.value,k=[...a[e]||[]];k[u]=n.itemType==="number"?Number(r):r,p({...a,[e]:k})}}),s.jsx("button",{className:"btn-icon",onClick:()=>{const r=[...a[e]||[]];r.splice(u,1),p({...a,[e]:r})},"aria-label":"Remove item",children:s.jsx(A,{size:14})})]},u)),s.jsxs("button",{className:"btn btn-secondary",onClick:()=>{const t=a[e]||[],u=n.itemType==="number"?0:"";p({...a,[e]:[...t,u]})},children:[s.jsx(O,{size:14})," Add Item"]})]}),n.description&&!n.required&&!n.multiline&&s.jsx("span",{id:d,className:"form-help",children:n.description})]},e)}),s.jsx("button",{className:"btn btn-primary",onClick:Q,children:"Save Settings"})]}):s.jsx("p",{className:"text-muted",children:"No configurable settings."})]}),s.jsxs("div",{className:"plugin-detail-actions",children:[i.state==="started"&&s.jsxs("button",{className:"btn btn-secondary",onClick:()=>U(i),disabled:h===i.id,children:[s.jsx(V,{size:14,className:h===i.id?"spin":""}),h===i.id?"Reloading...":"Reload"]}),i.enabled?s.jsx("button",{className:"btn btn-secondary",onClick:()=>F(i),children:"Disable"}):s.jsx("button",{className:"btn btn-primary",onClick:()=>B(i),children:"Enable"}),s.jsxs("button",{className:"btn btn-danger",onClick:()=>L(i),children:[s.jsx(M,{size:14})," Uninstall"]})]})]})]});const W=new Set(x.map(e=>e.id)),Y=new Map(x.map(e=>[e.id,e])),D=x,Z=()=>s.jsxs("section",{className:"plugin-bundled-runtime-section","aria-label":"Bundled Runtime Plugins",children:[s.jsxs("div",{className:"plugin-bundled-runtime-header",children:[s.jsx("h4",{className:"plugin-bundled-runtime-heading",children:"Bundled Runtime Plugins"}),s.jsx("p",{className:"plugin-bundled-runtime-description",children:"Install Fusion's bundled runtimes directly from this screen."})]}),s.jsx("div",{className:"plugin-bundled-runtime-list","aria-label":"Bundled runtime plugin recommendations",children:ge.map(e=>{const n=W.has(e.id);return s.jsxs("div",{className:"plugin-bundled-runtime-item",children:[s.jsxs("div",{className:"plugin-bundled-runtime-meta",children:[s.jsx("span",{className:"plugin-bundled-runtime-name",children:e.name}),e.experimental&&s.jsx("span",{className:"plugin-bundled-runtime-badge",children:"Experimental"}),s.jsx("span",{className:`plugin-bundled-runtime-status ${n?"plugin-bundled-runtime-status--installed":"plugin-bundled-runtime-status--available"}`,children:n?"Installed":"Not installed"})]}),s.jsx("button",{className:`btn ${n?"btn-secondary":"btn-primary"} btn-sm`,onClick:()=>{if(n){const d=Y.get(e.id);d&&q(d);return}K(e)},disabled:I===e.id,children:n?"Manage":I===e.id?"Installing...":`Install ${e.name}`})]},e.id)})})]});return s.jsxs("div",{className:"plugin-manager","data-testid":"plugin-manager",children:[s.jsxs("div",{className:"plugin-manager-header",children:[s.jsx("span",{className:"plugin-manager-header-title",children:"Installed Plugins"}),s.jsxs("div",{className:"plugin-manager-actions",children:[s.jsxs("button",{className:"btn btn-sm btn-ghost",onClick:m,title:"Refresh","aria-label":"Refresh plugin list",children:[s.jsx(te,{size:14,className:S?"spin":""}),"Refresh"]}),s.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>f(!0),children:[s.jsx(O,{size:14})," Install"]})]})]}),H&&s.jsxs("div",{className:"plugin-install-form",children:[s.jsxs("p",{className:"plugin-install-hint",children:["Browse to a plugin package root (contains ",s.jsx("code",{children:"manifest.json"}),") or a built ",s.jsx("code",{children:"dist"})," directory."]}),s.jsx(me,{value:j,onChange:v,placeholder:"Absolute path to plugin directory or dist folder",onInputKeyDown:e=>{e.key==="Enter"&&(e.preventDefault(),z())}}),s.jsxs("div",{className:"plugin-install-actions",children:[s.jsx("button",{className:"btn btn-primary",onClick:z,disabled:C||!j.trim(),children:C?"Installing...":"Install Plugin"}),s.jsx("button",{className:"btn btn-secondary",onClick:()=>{f(!1),v("")},children:"Cancel"})]})]}),S?s.jsx("div",{className:"settings-empty-state",children:"Loading plugins..."}):s.jsxs(s.Fragment,{children:[D.length===0?s.jsxs("div",{className:"settings-empty-state",children:[s.jsx(ie,{size:32,className:"text-muted"}),s.jsx("p",{children:"No plugins installed."}),s.jsx("p",{className:"text-muted",children:"Install a plugin to get started, or use a bundled runtime below."})]}):s.jsx("div",{className:"plugin-list",children:D.map(e=>s.jsxs("div",{className:"plugin-item",children:[s.jsxs("div",{className:"plugin-info",children:[s.jsx("span",{className:"plugin-name",children:e.name}),s.jsxs("span",{className:"plugin-version text-muted",children:["v",e.version]}),s.jsx("span",{className:"plugin-state-badge",style:{color:N[e.state]||N.installed},children:e.state})]}),s.jsxs("div",{className:"plugin-actions",children:[e.state==="started"&&s.jsx("button",{className:"btn-icon",onClick:()=>U(e),disabled:h===e.id,title:"Reload",children:s.jsx(V,{size:14,className:h===e.id?"spin":""})}),s.jsxs("label",{className:"toggle-switch",children:[s.jsx("input",{type:"checkbox",checked:e.enabled,onChange:()=>e.enabled?F(e):B(e)}),s.jsx("span",{className:"toggle-slider"})]}),s.jsx("button",{className:"btn-icon",onClick:()=>q(e),title:"Settings",children:s.jsx(ae,{size:14})}),s.jsx("button",{className:"btn-icon",onClick:()=>L(e),title:"Uninstall",children:s.jsx(M,{size:14})})]})]},e.id))}),Z()]})]})}export{fe as PluginManager,N as STATE_COLORS};
|
|
1
|
+
import{r as o,j as s}from"./vendor-react-K0fH_qHe.js";import{w as T,dM as ee,s as se,X as O,ap as ne,J as A,dN as M,W as _,R as te,dO as ie,aI as ae,cb as le,dP as re,dQ as ce,dR as de,dS as ue,dT as V,c8 as oe}from"./index-BRaIPmpp.js";import{D as me}from"./DirectoryPicker-CFj7FOgn.js";import"./vendor-xterm-DzcZoU0P.js";import"./folder-open-DObdkm5J.js";const ge=[{id:"fusion-plugin-agent-browser-runtime",name:"Agent Browser Runtime",path:"./plugins/fusion-plugin-agent-browser-runtime",experimental:!0},{id:"fusion-plugin-hermes-runtime",name:"Hermes Runtime",path:"./plugins/fusion-plugin-hermes-runtime",experimental:!0},{id:"fusion-plugin-paperclip-runtime",name:"Paperclip Runtime",path:"./plugins/fusion-plugin-paperclip-runtime"},{id:"fusion-plugin-openclaw-runtime",name:"OpenClaw Runtime",path:"./plugins/fusion-plugin-openclaw-runtime",experimental:!0}],N={started:"var(--color-success)",loaded:"var(--color-warning)",error:"var(--color-error)",stopped:"var(--color-muted)",installed:"var(--color-info)"};function fe({addToast:l,projectId:c}){const[x,b]=o.useState([]),[S,w]=o.useState(!0),[H,f]=o.useState(!1),[j,v]=o.useState(""),[C,P]=o.useState(!1),[h,R]=o.useState(null),[i,y]=o.useState(null),[a,p]=o.useState({}),[J,I]=o.useState(!1),[$,E]=o.useState(null),{confirm:G}=T(),m=o.useCallback(async()=>{try{w(!0);const e=await ee(c);b(e)}catch(e){l(`Failed to load plugins: ${e instanceof Error?e.message:String(e)}`,"error")}finally{w(!1)}},[c,l]);o.useEffect(()=>{m()},[m]);const K=o.useRef([]);K.current=x,o.useEffect(()=>{const e=c?`?projectId=${encodeURIComponent(c)}`:"",n=d=>{try{const t=JSON.parse(d.data);if(c&&t.projectId&&t.projectId!==c)return;switch(t.transition){case"installing":case"enabled":case"disabled":case"settings-updated":b(u=>{const g=u.findIndex(r=>r.id===t.pluginId);if(g>=0){const r=[...u];return r[g]={...r[g],enabled:t.enabled,state:t.state,settings:t.settings,error:t.error},r}else return m(),u});break;case"uninstalled":b(u=>u.filter(g=>g.id!==t.pluginId));break;case"error":b(u=>{const g=u.findIndex(r=>r.id===t.pluginId);if(g>=0){const r=[...u];return r[g]={...r[g],state:t.state,error:t.error},r}return u});break}}catch{}};return se(`/api/events${e}`,{events:{"plugin:lifecycle":n},onReconnect:()=>{m()}})},[c,m]);const z=async()=>{if(!j.trim()){l("Please enter a plugin path","error");return}try{P(!0),await V({path:j},c),l("Plugin installed successfully","success"),f(!1),v(""),await m()}catch(e){l(`Failed to install plugin: ${e instanceof Error?e.message:String(e)}`,"error")}finally{P(!1)}},Q=async e=>{try{E(e.id),await V({path:e.path},c),l(`${e.name} installed successfully`,"success"),await m()}catch(n){l(`Failed to install ${e.name}: ${n instanceof Error?n.message:String(n)}`,"error")}finally{E(null)}},B=async e=>{try{await de(e.id,c),l(`${e.name} enabled`,"success"),await m()}catch(n){l(`Failed to enable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},F=async e=>{try{await ce(e.id,c),l(`${e.name} disabled`,"success"),await m()}catch(n){l(`Failed to disable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},L=async e=>{try{R(e.id),await re(e.id,c),l(`${e.name} reloaded`,"success"),await m()}catch(n){l(`Failed to reload plugin: ${n instanceof Error?n.message:String(n)}`,"error")}finally{R(null)}},U=async e=>{if(await G({title:"Uninstall Plugin",message:`Are you sure you want to uninstall "${e.name}"?`,danger:!0}))try{await ue(e.id,c),l(`${e.name} uninstalled`,"success"),await m(),y(null)}catch(d){l(`Failed to uninstall plugin: ${d instanceof Error?d.message:String(d)}`,"error")}},q=async e=>{y(e);try{I(!0);const n=await oe(e.id,c);p(n)}catch{p({})}finally{I(!1)}},W=async()=>{if(i)try{await le(i.id,a,c),l("Settings saved","success")}catch(e){l(`Failed to save settings: ${e instanceof Error?e.message:String(e)}`,"error")}};if(i)return s.jsxs("div",{className:"plugin-manager-detail","data-testid":"plugin-manager-detail",children:[s.jsxs("div",{className:"plugin-manager-detail-header",children:[s.jsx("button",{className:"btn-icon",onClick:()=>y(null),"aria-label":"Back to plugin list",children:s.jsx(O,{size:16})}),s.jsxs("div",{className:"plugin-detail-title",children:[s.jsx("h4",{className:"plugin-detail-name",children:i.name}),s.jsx("span",{className:"plugin-state-badge",style:{color:N[i.state]||N.installed},children:i.state})]})]}),s.jsxs("div",{className:"plugin-detail-content",children:[s.jsxs("div",{className:"plugin-detail-card",children:[i.description&&s.jsx("p",{className:"plugin-description",children:i.description}),i.author&&s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Author:"}),i.author]}),i.homepage&&s.jsxs("p",{className:"plugin-detail-meta-row plugin-homepage",children:[s.jsx("span",{className:"text-muted",children:"Homepage:"}),s.jsxs("a",{href:i.homepage,target:"_blank",rel:"noopener noreferrer",children:[i.homepage,s.jsx(ne,{size:12})]})]}),s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Version:"}),i.version]})]}),s.jsxs("div",{className:"plugin-detail-card",children:[s.jsx("h5",{className:"plugin-detail-section-heading",children:"Settings"}),J?s.jsx("p",{className:"text-muted",children:"Loading..."}):i.settingsSchema&&Object.keys(i.settingsSchema).length>0?s.jsxs("div",{className:"plugin-settings-form",children:[Object.entries(i.settingsSchema).map(([e,n])=>{const d=`setting-${e}-help`;return s.jsxs("div",{className:"form-group",children:[s.jsxs("label",{htmlFor:`setting-${e}`,children:[n.label||e,n.required&&" *"]}),n.type==="string"&&!n.multiline&&s.jsx("input",{className:"input",type:"text",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="string"&&n.multiline&&s.jsx("textarea",{className:"input",id:`setting-${e}`,rows:4,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="password"&&s.jsx("input",{className:"input",type:"password",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="number"&&s.jsx("input",{className:"input",type:"number",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:Number(t.target.value)}),"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="boolean"&&s.jsxs("label",{className:"checkbox-label",children:[s.jsx("input",{type:"checkbox",checked:a[e]??!1,onChange:t=>p({...a,[e]:t.target.checked})}),n.description]}),n.type==="enum"&&s.jsxs("select",{className:"select",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),"aria-describedby":n.description&&!n.required?d:void 0,children:[s.jsx("option",{value:"",children:"Select..."}),n.enumValues?.map(t=>s.jsx("option",{value:t,children:t},t))]}),n.type==="array"&&s.jsxs("div",{className:"plugin-settings-array",children:[a[e]?.map((t,u)=>s.jsxs("div",{className:"plugin-settings-array-item",children:[s.jsx("input",{className:"input",type:n.itemType==="number"?"number":"text",value:t??"",onChange:g=>{const r=g.target.value,k=[...a[e]||[]];k[u]=n.itemType==="number"?Number(r):r,p({...a,[e]:k})}}),s.jsx("button",{className:"btn-icon",onClick:()=>{const r=[...a[e]||[]];r.splice(u,1),p({...a,[e]:r})},"aria-label":"Remove item",children:s.jsx(O,{size:14})})]},u)),s.jsxs("button",{className:"btn btn-secondary",onClick:()=>{const t=a[e]||[],u=n.itemType==="number"?0:"";p({...a,[e]:[...t,u]})},children:[s.jsx(A,{size:14})," Add Item"]})]}),n.description&&!n.required&&!n.multiline&&s.jsx("span",{id:d,className:"form-help",children:n.description})]},e)}),s.jsx("button",{className:"btn btn-primary",onClick:W,children:"Save Settings"})]}):s.jsx("p",{className:"text-muted",children:"No configurable settings."})]}),s.jsxs("div",{className:"plugin-detail-actions",children:[i.state==="started"&&s.jsxs("button",{className:"btn btn-secondary",onClick:()=>L(i),disabled:h===i.id,children:[s.jsx(M,{size:14,className:h===i.id?"spin":""}),h===i.id?"Reloading...":"Reload"]}),i.enabled?s.jsx("button",{className:"btn btn-secondary",onClick:()=>F(i),children:"Disable"}):s.jsx("button",{className:"btn btn-primary",onClick:()=>B(i),children:"Enable"}),s.jsxs("button",{className:"btn btn-danger",onClick:()=>U(i),children:[s.jsx(_,{size:14})," Uninstall"]})]})]})]});const X=new Set(x.map(e=>e.id)),Y=new Map(x.map(e=>[e.id,e])),D=x,Z=()=>s.jsxs("section",{className:"plugin-bundled-runtime-section","aria-label":"Bundled Runtime Plugins",children:[s.jsxs("div",{className:"plugin-bundled-runtime-header",children:[s.jsx("h4",{className:"plugin-bundled-runtime-heading",children:"Bundled Runtime Plugins"}),s.jsx("p",{className:"plugin-bundled-runtime-description",children:"Install Fusion's bundled runtimes directly from this screen."})]}),s.jsx("div",{className:"plugin-bundled-runtime-list","aria-label":"Bundled runtime plugin recommendations",children:ge.map(e=>{const n=X.has(e.id);return s.jsxs("div",{className:"plugin-bundled-runtime-item",children:[s.jsxs("div",{className:"plugin-bundled-runtime-meta",children:[s.jsx("span",{className:"plugin-bundled-runtime-name",children:e.name}),e.experimental&&s.jsx("span",{className:"plugin-bundled-runtime-badge",children:"Experimental"}),s.jsx("span",{className:`plugin-bundled-runtime-status ${n?"plugin-bundled-runtime-status--installed":"plugin-bundled-runtime-status--available"}`,children:n?"Installed":"Not installed"})]}),s.jsx("button",{className:`btn ${n?"btn-secondary":"btn-primary"} btn-sm`,onClick:()=>{if(n){const d=Y.get(e.id);d&&q(d);return}Q(e)},disabled:$===e.id,children:n?"Manage":$===e.id?"Installing...":`Install ${e.name}`})]},e.id)})})]});return s.jsxs("div",{className:"plugin-manager","data-testid":"plugin-manager",children:[s.jsxs("div",{className:"plugin-manager-header",children:[s.jsx("span",{className:"plugin-manager-header-title",children:"Installed Plugins"}),s.jsxs("div",{className:"plugin-manager-actions",children:[s.jsxs("button",{className:"btn btn-sm",onClick:m,title:"Refresh","aria-label":"Refresh plugin list",children:[s.jsx(te,{size:14,className:S?"spin":""}),"Refresh"]}),s.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>f(!0),children:[s.jsx(A,{size:14})," Install"]})]})]}),H&&s.jsxs("div",{className:"plugin-install-form",children:[s.jsxs("p",{className:"plugin-install-hint",children:["Browse to a plugin package root (contains ",s.jsx("code",{children:"manifest.json"}),") or a built ",s.jsx("code",{children:"dist"})," directory."]}),s.jsx(me,{value:j,onChange:v,placeholder:"Absolute path to plugin directory or dist folder",onInputKeyDown:e=>{e.key==="Enter"&&(e.preventDefault(),z())}}),s.jsxs("div",{className:"plugin-install-actions",children:[s.jsx("button",{className:"btn btn-primary",onClick:z,disabled:C||!j.trim(),children:C?"Installing...":"Install Plugin"}),s.jsx("button",{className:"btn btn-secondary",onClick:()=>{f(!1),v("")},children:"Cancel"})]})]}),S?s.jsx("div",{className:"settings-empty-state",children:"Loading plugins..."}):s.jsxs(s.Fragment,{children:[D.length===0?s.jsxs("div",{className:"settings-empty-state",children:[s.jsx(ie,{size:32,className:"text-muted"}),s.jsx("p",{children:"No plugins installed."}),s.jsx("p",{className:"text-muted",children:"Install a plugin to get started, or use a bundled runtime below."})]}):s.jsx("div",{className:"plugin-list",children:D.map(e=>s.jsxs("div",{className:"plugin-item",children:[s.jsxs("div",{className:"plugin-info",children:[s.jsx("span",{className:"plugin-name",children:e.name}),s.jsxs("span",{className:"plugin-version text-muted",children:["v",e.version]}),s.jsx("span",{className:"plugin-state-badge",style:{color:N[e.state]||N.installed},children:e.state})]}),s.jsxs("div",{className:"plugin-actions",children:[e.state==="started"&&s.jsx("button",{className:"btn-icon",onClick:()=>L(e),disabled:h===e.id,title:"Reload",children:s.jsx(M,{size:14,className:h===e.id?"spin":""})}),s.jsxs("label",{className:"toggle-switch",children:[s.jsx("input",{type:"checkbox",checked:e.enabled,onChange:()=>e.enabled?F(e):B(e)}),s.jsx("span",{className:"toggle-slider"})]}),s.jsx("button",{className:"btn-icon",onClick:()=>q(e),title:"Settings",children:s.jsx(ae,{size:14})}),s.jsx("button",{className:"btn-icon",onClick:()=>U(e),title:"Uninstall",children:s.jsx(_,{size:14})})]})]},e.id))}),Z()]})]})}export{fe as PluginManager,N as STATE_COLORS};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.research-task-action-modal__body{display:flex;flex-direction:column;gap:var(--space-md)}.research-task-action-modal__preview{display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-md)}.research-task-action-modal__preview p{margin:0}.research-task-action-modal__field{display:flex;flex-direction:column;gap:var(--space-xs);color:var(--text-muted);font-size:.75rem;letter-spacing:.03em;text-transform:uppercase}.research-task-action-modal__textarea{min-height:calc(var(--space-2xl) * 2);resize:vertical}@media(max-width:768px){.research-task-action-modal{width:min(100%,calc(100vw - (var(--space-md) * 2)))}}.research-view{display:flex;flex-direction:column;gap:var(--space-md);height:100%;min-height:0;padding:var(--space-lg);padding-bottom:var(--space-lg)}.research-view__header{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-md)}.research-view__title{margin:0}.research-view__subtitle{margin:var(--space-xs) 0 0;color:var(--text-muted)}.research-view__layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2fr);gap:var(--space-md);min-height:0;flex:1}.research-view__sidebar,.research-view__reader{padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-md);min-height:0}.research-view__form{display:flex;flex-direction:column;gap:var(--space-sm)}.research-view__form .form-group,.research-view__history-header.form-group,.research-view__actions .form-group{margin:0;padding:0}.research-view__textarea{min-height:calc(var(--space-2xl) * 3);resize:vertical}.research-view__providers{display:grid;gap:var(--space-xs)}.research-view__history-header{display:flex;flex-direction:column;align-items:stretch;gap:var(--space-xs)}.research-view__history-search-row{display:flex;align-items:center;gap:var(--space-xs)}.research-view__history-search-row .input{flex:1;min-width:0}.research-view__history{display:flex;flex-direction:column;gap:var(--space-xs);flex:1;min-height:0;overflow:auto}.research-view__history-item{border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-sm);background:var(--surface);color:var(--text);text-align:left;padding:var(--space-sm);min-height:calc(var(--space-lg) * 2 + var(--space-xs));display:flex;flex-direction:column;justify-content:center;gap:var(--space-xs);cursor:pointer;transition:border-color var(--transition-fast),box-shadow var(--transition-fast),background-color var(--transition-fast),transform var(--transition-fast)}.research-view__history-item:hover{background:var(--card-hover);border-color:var(--todo)}.research-view__history-item:focus-visible{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring-strong)}.research-view__history-item:active{transform:scale(.97)}.research-view__history-item--active{border-color:var(--todo);box-shadow:var(--focus-ring)}.research-view__status-row{display:flex;align-items:center;gap:var(--space-xs);text-transform:capitalize}.research-view__run-title,.research-view__run-query,.research-view__run-summary{margin:0}.research-view__run-query{color:var(--text-muted)}.research-view__actions{display:flex;flex-wrap:wrap;gap:var(--space-xs);margin-top:var(--space-sm)}.research-view__citations{margin:var(--space-sm) 0 0;padding-left:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-xs)}.research-view__citations a{color:var(--text)}.research-view__error{color:var(--color-error)}.research-view__findings{display:flex;flex-direction:column;gap:var(--space-sm)}.research-view__finding{padding:var(--space-sm)}.research-view__finding h4,.research-view__finding p{margin:0}.research-view__finding-actions{margin-top:var(--space-sm)}.research-view__events{margin:var(--space-sm) 0 0;padding-left:var(--space-lg)}.research-view__stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-sm)}.research-view__stat-card{border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-sm);padding:var(--space-sm);background:var(--surface)}.research-view__stat-label{color:var(--text-muted);text-transform:uppercase;font-size:.6875rem}.research-view__stat-value{font-family:var(--font-mono);font-size:.8125rem}.research-view__state--error{border-color:var(--color-error)}@media(max-width:768px){.research-view{padding:var(--space-md);padding-bottom:calc(var(--space-md) + var(--mobile-nav-height) + env(safe-area-inset-bottom,0px) + var(--standalone-bottom-gap))}.research-view__layout{grid-template-columns:minmax(0,1fr)}.research-view__header{flex-direction:column}.research-view__stats{grid-template-columns:minmax(0,1fr)}.research-view__history-item{min-height:calc(var(--space-lg) * 2 + var(--space-sm))}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{as as ie,at as ce,s as le,au as oe,av as de,aw as ue,ax as he,ay as me,az as ve,aA as be,y as fe,aB as xe,L as pe,S as je}from"./index-BRaIPmpp.js";import"./vendor-xterm-DzcZoU0P.js";const D={webSearch:!0,pageFetch:!0,github:!1,localDocs:!0,llmSynthesis:!0};function W(d){const t=d?.researchGlobalDefaults,u=d?.researchSettings;return{enabled:u?.enabled??d?.researchEnabled??d?.researchGlobalEnabled??!0,searchProvider:u?.searchProvider??t?.searchProvider,synthesisProvider:u?.synthesisProvider??t?.synthesisProvider,synthesisModelId:u?.synthesisModelId??t?.synthesisModelId,enabledSources:{webSearch:u?.enabledSources?.webSearch??t?.enabledSources?.webSearch??D.webSearch,pageFetch:u?.enabledSources?.pageFetch??t?.enabledSources?.pageFetch??D.pageFetch,github:u?.enabledSources?.github??t?.enabledSources?.github??D.github,localDocs:u?.enabledSources?.localDocs??t?.enabledSources?.localDocs??D.localDocs,llmSynthesis:u?.enabledSources?.llmSynthesis??t?.enabledSources?.llmSynthesis??D.llmSynthesis},limits:{maxConcurrentRuns:u?.limits?.maxConcurrentRuns??d?.researchMaxConcurrentRuns??d?.researchGlobalMaxConcurrentRuns??3,maxSourcesPerRun:u?.limits?.maxSourcesPerRun??t?.maxSourcesPerRun??d?.researchMaxSourcesPerRun??d?.researchGlobalMaxSourcesPerRun??20,maxDurationMs:u?.limits?.maxDurationMs??d?.researchDefaultTimeout??d?.researchGlobalDefaultTimeout??3e5,requestTimeoutMs:u?.limits?.requestTimeoutMs??d?.researchFetchTimeoutMs??3e4},defaultExportFormat:t?.defaultExportFormat??"markdown"}}const ge=300,ye=4e3;function Se(d){const t=d?.projectId,[u,f]=a.useState([]),[m,r]=a.useState(null),[I,g]=a.useState(null),[x,S]=a.useState({available:!0}),[R,N]=a.useState(!0),[T,k]=a.useState(null),[y,C]=a.useState(""),_=a.useRef(0),E=a.useRef(0),M=a.useRef(t);a.useEffect(()=>{M.current!==t&&(M.current=t,E.current++)},[t]);const p=a.useCallback(async(c=y)=>{const l=++_.current,i=t;k(null);try{const n=await ie({q:c||void 0,limit:100},i);if(l!==_.current||i!==t)return;f(n.runs),S(n.availability),m&&!n.runs.some(b=>b.id===m)&&(r(null),g(null))}catch(n){if(l!==_.current||i!==t)return;k(n instanceof Error?n.message:"Failed to load research runs")}finally{l===_.current&&N(!1)}},[t,y,m]),j=a.useCallback(async c=>{const l=await ce(c,t);return g(l.run),S(l.availability),l.run},[t]);return a.useEffect(()=>{N(!0);const c=window.setTimeout(()=>{p(y)},ge);return()=>window.clearTimeout(c)},[p,y]),a.useEffect(()=>{if(!m){g(null);return}j(m)},[j,m]),a.useEffect(()=>{const c=E.current,l=()=>E.current!==c,i=t?`?projectId=${encodeURIComponent(t)}`:"";let n=!0;const b=()=>{!n||l()||(p(),m&&j(m))},A=le(`/api/events${i}`,{events:{"research:run:created":b,"research:run:updated":b,"research:run:completed":b,"research:run:failed":b,"research:run:cancelled":b},onReconnect:b}),q=window.setInterval(b,ye);return()=>{n=!1,A(),window.clearInterval(q)}},[t,p,m,j]),{runs:u,selectedRun:I,selectedRunId:m,setSelectedRunId:r,availability:x,loading:R,error:T,searchQuery:y,setSearchQuery:C,refresh:p,createRun:c=>ve(c,t),cancelRun:async c=>{const l=await me(c,t);return m===c&&g(l.run),await p(),l},retryRun:async c=>{const l=await he(c,t);return m===c&&g(l.run),await p(),l},exportRun:(c,l)=>ue(c,l,t),createTaskFromRun:(c,l,i,n,b,A)=>de(c,{title:l,findingId:i,description:n,priority:b,attachExport:A},t),attachRunToTask:(c,l,i,n)=>oe(c,{taskId:l,findingId:i,attachExport:n},t),statusCounts:u.reduce((c,l)=>(c[l.status]+=1,c),{pending:0,running:0,completed:0,failed:0,cancelled:0})}}function _e({open:d,mode:t,run:u,finding:f,projectId:m,onClose:r,onConfirm:I}){const[g,x]=a.useState(!1),[S,R]=a.useState(""),[N,T]=a.useState(""),[k,y]=a.useState("normal"),[C,_]=a.useState(""),[E,M]=a.useState([]),[p,j]=a.useState(!1),[c,l]=a.useState(!1),i=a.useMemo(()=>{const n=(f.content??"").split(/(?<=[.!?])\s+/)[0]??"";return`${f.heading||"Research finding"} — ${n}`.trim()},[f.content,f.heading]);return a.useEffect(()=>{d&&(x(!1),R(`Research: ${f.heading||u.title}`),T(i),y("normal"),_(""),t==="enrich"&&(j(!0),be(50,0,m).then(n=>M(n.filter(b=>b.column!=="archived"))).finally(()=>j(!1))))},[d,t,m,f.heading,i,u.title]),d?e.jsx("div",{className:"modal-overlay open",role:"presentation",onClick:r,children:e.jsxs("div",{className:"modal modal-lg research-task-action-modal",role:"dialog","aria-modal":"true",onClick:n=>n.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:r,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:"})," ",u.id]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Finding:"})," ",f.id,f.heading?` — ${f.heading}`:""]}),e.jsx("p",{children:i||"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:S,onChange:n=>R(n.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Description",e.jsx("textarea",{className:"input research-task-action-modal__textarea",value:N,onChange:n=>T(n.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Priority",e.jsxs("select",{className:"select",value:k,onChange:n=>y(n.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:C,placeholder:p?"Loading tasks…":"Enter task ID",onChange:n=>_(n.target.value)}),e.jsx("datalist",{id:"research-task-action-task-list",children:E.map(n=>e.jsx("option",{value:n.id,children:n.title},n.id))})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:g,onChange:n=>x(n.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:r,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",type:"button",disabled:c||t==="enrich"&&!C,onClick:()=>{l(!0),I({taskId:t==="enrich"?C:void 0,title:t==="create"?S.trim():void 0,description:t==="create"?N.trim():void 0,priority:t==="create"?k:void 0,attachExport:g}).finally(()=>l(!1))},children:t==="create"?"Create Task":"Enrich Task"})]})]})}):null}const Re=["web-search","page-fetch","github","local-docs","llm-synthesis"],we={"web-search":"webSearch","page-fetch":"pageFetch",github:"github","local-docs":"localDocs","llm-synthesis":"llmSynthesis"},Ne={"web-search":"Web Search","page-fetch":"Page Fetch",github:"GitHub","local-docs":"Local Docs","llm-synthesis":"LLM Synthesis"};function Te({projectId:d,addToast:t,onOpenSettings:u,readinessVersion:f=0}){const{runs:m,selectedRun:r,selectedRunId:I,setSelectedRunId:g,availability:x,loading:S,error:R,searchQuery:N,setSearchQuery:T,createRun:k,cancelRun:y,retryRun:C,exportRun:_,createTaskFromRun:E,attachRunToTask:M,statusCounts:p,refresh:j}=Se({projectId:d}),[c,l]=a.useState(""),[i,n]=a.useState(()=>W(void 0)),[b,A]=a.useState([]),[q,Q]=a.useState(!1),[Y,X]=a.useState([]),[L,O]=a.useState(null),[P,$]=a.useState(null),B=x.supportedProviders??Re,U=s=>i.enabledSources[we[s]];a.useEffect(()=>{const s=B.filter(o=>U(o));X(o=>{const v=o.filter(h=>s.includes(h));return v.length>0?v:s})},[i.enabledSources,B]),a.useEffect(()=>{let s=!1;return Promise.all([fe(d),xe().catch(()=>({providers:[]}))]).then(([o,v])=>{s||(n(W(o)),A(v.providers.filter(h=>h.type==="api_key").map(h=>({id:h.id,authenticated:h.authenticated}))))}).catch(()=>{s||n(W(void 0))}),()=>{s=!0}},[d,f]);const re=a.useMemo(()=>r?r.status:"No run selected",[r]),ae=a.useMemo(()=>r?r.status==="pending"?"status-dot status-dot--pending":r.status==="running"?"status-dot status-dot--connecting":r.status==="completed"?"status-dot status-dot--online":r.status==="failed"||r.status==="cancelled"?"status-dot status-dot--error":"status-dot":"status-dot",[r]),H=x.supportedExportFormats??["markdown","json","html"],V=i.searchProvider,Z=i.enabledSources.webSearch&&!V,ee=i.enabledSources.llmSynthesis&&(!i.synthesisProvider||!i.synthesisModelId),z=a.useMemo(()=>new Map(b.map(s=>[s.id,s.authenticated])),[b]),K=a.useMemo(()=>{const s=new Set;return i.enabledSources.webSearch&&V&&s.add(V),i.enabledSources.llmSynthesis&&i.synthesisProvider&&s.add(i.synthesisProvider),[...s].filter(o=>z.has(o))},[i.enabledSources.llmSynthesis,i.enabledSources.webSearch,i.synthesisProvider,V,z]).find(s=>z.get(s)!==!0),F=a.useMemo(()=>x.available?i.enabled?Z||ee?{reason:"Research defaults are incomplete.",details:"Select the required provider/model defaults in Research settings.",settingsSection:"research-global"}:K?{reason:`Missing API key for ${K}.`,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:x.reason??"Research is unavailable for this project.",details:x.setupInstructions,settingsSection:"research-project"},[x.available,x.reason,x.setupInstructions,i.enabled,K,Z,ee]),G=async(s,o,v)=>{O(s);try{await o(),t?.(v,"success"),await j()}catch(h){t?.(h instanceof Error?h.message:"Action failed","error")}finally{O(null)}},J=async s=>{if(r){O(`export-${s}`);try{const o=await _(r.id,s),v=new Blob([o.content],{type:"text/plain;charset=utf-8"}),h=URL.createObjectURL(v),w=document.createElement("a");w.href=h,w.download=o.filename,document.body.appendChild(w),w.click(),w.remove(),URL.revokeObjectURL(h),t?.(`Exported ${o.filename}`,"success")}catch(o){t?.(o instanceof Error?o.message:"Export failed","error")}finally{O(null)}}},ne=async()=>{if(c.trim()){Q(!0);try{const s=Y.filter(v=>U(v));if(s.length===0){Q(!1),t?.("No enabled research sources are available for this project.","error");return}const o=await k({query:c.trim(),providers:s});g(o.run.id),l(""),t?.("Research run created","success"),await j()}catch(s){t?.(s instanceof Error?s.message:"Failed to create run","error")}finally{Q(!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:"Create and track research runs with cited findings."})]}),e.jsx("button",{className:"btn",type:"button",onClick:()=>void j(),children:"Refresh"})]}),F?e.jsxs("div",{className:"research-view__state research-view__state--error card","data-testid":"research-state-unavailable",children:[e.jsx("p",{children:F.reason}),F.details&&e.jsx("p",{children:F.details}),e.jsxs("p",{children:["Current defaults: provider ",i.searchProvider??"(not set)",", max sources ",i.limits.maxSourcesPerRun]}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:()=>void j(),children:"Refresh"}),e.jsx("button",{className:"btn btn-primary",type:"button",onClick:()=>u?.(F.settingsSection),children:"Open Settings"})]})]}):e.jsxs("div",{className:"research-view__layout",children:[e.jsxs("aside",{className:"research-view__sidebar card",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:c,onChange:s=>l(s.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Providers"}),e.jsx("div",{className:"research-view__providers",children:B.map(s=>e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:Y.includes(s),disabled:!U(s),onChange:()=>{U(s)&&X(o=>o.includes(s)?o.filter(v=>v!==s):[...o,s])}}),e.jsx("span",{children:Ne[s]??s})]},s))})]}),e.jsxs("button",{className:"btn btn-primary",type:"button",disabled:!c.trim()||q,onClick:()=>void ne(),children:[q?e.jsx(pe,{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(je,{size:14}),e.jsx("input",{id:"research-run-search",className:"input",placeholder:"Search runs",value:N,onChange:s=>T(s.target.value)})]})]}),e.jsx("div",{className:"research-view__history","data-testid":"research-state-running",children:m.map(s=>e.jsxs("button",{type:"button",className:`research-view__history-item${I===s.id?" research-view__history-item--active":""}`,onClick:()=>g(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:[S&&e.jsx("p",{"data-testid":"research-state-loading",children:"Loading research runs…"}),!S&&R&&e.jsx("p",{"data-testid":"research-state-error",children:R}),!S&&!R&&m.length===0&&e.jsx("p",{"data-testid":"research-state-empty",children:"No research runs yet"}),r&&e.jsxs("div",{children:[e.jsxs("div",{className:"research-view__status-row",children:[e.jsx("span",{className:ae}),e.jsx("strong",{children:re})]}),e.jsx("h3",{className:"research-view__run-title",children:r.title}),e.jsx("p",{className:"research-view__run-query",children:r.query}),e.jsx("p",{className:"research-view__run-summary","data-testid":"research-state-results",children:r.results?.summary??"No summary yet."}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",disabled:L==="cancel",onClick:()=>void G("cancel",()=>y(r.id),"Run cancelled"),children:"Cancel"}),e.jsx("button",{className:"btn",type:"button",disabled:L==="retry",onClick:()=>void G("retry",()=>C(r.id),"Run retried"),children:"Retry"}),H.includes("markdown")&&e.jsx("button",{className:"btn",type:"button",disabled:L==="export-markdown",onClick:()=>void J("markdown"),children:"Export MD"}),H.includes("json")&&e.jsx("button",{className:"btn",type:"button",disabled:L==="export-json",onClick:()=>void J("json"),children:"Export JSON"}),H.includes("html")&&e.jsx("button",{className:"btn",type:"button",disabled:L==="export-html",onClick:()=>void J("html"),children:"Export HTML"})]}),r.error&&e.jsx("p",{className:"research-view__error",children:r.error}),Array.isArray(r.results?.findings)&&r.results.findings.length>0&&e.jsx("div",{className:"research-view__findings",children:r.results.findings.map((s,o)=>{const h=s.id?.trim()||`finding-${o+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:()=>$({mode:"create",findingId:h}),children:"Create Task"}),e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>$({mode:"enrich",findingId:h}),children:"Enrich Task"})]})]},h)})}),Array.isArray(r.results?.citations)&&r.results.citations.length>0&&e.jsx("ul",{className:"research-view__citations",children:r.results.citations.map(s=>e.jsx("li",{children:e.jsx("a",{href:s,target:"_blank",rel:"noreferrer",children:s})},s))}),r.events.length>0&&e.jsxs("details",{children:[e.jsx("summary",{children:"Run history"}),e.jsx("ul",{className:"research-view__events",children:r.events.map(s=>e.jsx("li",{children:s.message},s.id))})]})]}),!r&&m.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:p.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:p.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:p.failed})]})]})]})]}),r&&P&&(()=>{const s=r.results?.findings?.findIndex((v,h)=>(v.id?.trim()||`finding-${h+1}`)===P.findingId)??-1,o=s>=0?r.results.findings[s]:null;return o?e.jsx(_e,{open:!0,mode:P.mode,run:r,finding:{id:P.findingId,heading:o.heading,content:o.content},projectId:d,onClose:()=>$(null),onConfirm:async({taskId:v,title:h,description:w,priority:se,attachExport:te})=>{P.mode==="create"?await G("create-task",()=>E(r.id,h,P.findingId,w,se,te),"Task created from research"):v&&await G("attach-task",()=>M(r.id,v,P.findingId,te),"Task enriched from research"),$(null)}}):null})()]})}export{Te as ResearchView};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{c as Dt,b8 as Mt,b9 as Rt,ba as It,bb as $t,bc as zt,bd as tt,be as At,bf as Ot,bg as at,bh as Ht,bi as Bt,bj as Gt,bk as Pt,bl as Tt,bm as Lt,bn as Vt,bo as Ut,w as Kt,q as Wt,J as ze,bp as me,X as re,aM as Fe,W as Pe,af as qt,al as ut,aL as st,ab as Jt,bq as qe,br as Yt}from"./index-BRaIPmpp.js";import"./vendor-xterm-DzcZoU0P.js";/**
|
|
2
|
+
* @license lucide-react v1.7.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const Xt=[["path",{d:"M12 2v4",key:"3427ic"}],["path",{d:"m16.2 7.8 2.9-2.9",key:"r700ao"}],["path",{d:"M18 12h4",key:"wj9ykh"}],["path",{d:"m16.2 16.2 2.9 2.9",key:"1bxg5t"}],["path",{d:"M12 18v4",key:"jadmvz"}],["path",{d:"m4.9 19.1 2.9-2.9",key:"bwix9q"}],["path",{d:"M2 12h4",key:"j09sii"}],["path",{d:"m4.9 4.9 2.9 2.9",key:"giyufr"}]],Qt=Dt("loader",Xt);function Zt(l){const n=l?.projectId,[v,f]=a.useState([]),[C,w]=a.useState(null),[y,g]=a.useState(null),[k,D]=a.useState([]),[j,S]=a.useState({}),[A,J]=a.useState(!1),[L,$]=a.useState(null),[ne,pe]=a.useState(null),[Te,ge]=a.useState(!1),[he,Z]=a.useState(null),[fe,B]=a.useState([]),[O,G]=a.useState(!1),[be,P]=a.useState({}),[ie,ee]=a.useState({}),Y=a.useRef(be),ve=a.useRef(ie),oe=a.useRef(fe);Y.current=be,ve.current=ie,oe.current=fe;const xe=a.useRef(n),M=a.useRef(0),le=a.useRef(0),_e=a.useRef(v),x=a.useRef(C),de=a.useRef(k),we=a.useRef(j),R=a.useRef(n),Ae=a.useRef(ne);_e.current=v,x.current=C,de.current=k,we.current=j,R.current=n,Ae.current=ne,a.useEffect(()=>{xe.current!==n&&(xe.current=n,M.current++,w(null),g(null),D([]),S({}),pe(null),Z(null),B([]),G(!1),P({}),ee({}))},[n]);const X=a.useCallback(async()=>{J(!0),$(null);try{const s=await Mt(n);f(s)}catch(s){$(s instanceof Error?s:new Error("Failed to fetch roadmaps"))}finally{J(!1)}},[n]),N=a.useCallback(async s=>{try{const d=await Rt(s,n);g(d),D(d.milestones||[]);const i={};for(const r of d.milestones||[])i[r.id]=r.features||[];S(i)}catch(d){$(d instanceof Error?d:new Error("Failed to fetch roadmap"))}},[n]);a.useEffect(()=>{X()},[X]),a.useEffect(()=>{C?N(C):(g(null),D([]),S({}))},[C,N]);const Oe=a.useCallback(async(s,d)=>{try{const i=await It(s,R.current);f(r=>[...r,i]),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to create roadmap");throw d?.onError?.(r),r}},[]),je=a.useCallback(async(s,d,i)=>{try{const r=await $t(s,d,R.current);f(c=>c.map(o=>o.id===s?r:o)),x.current===s&&g(c=>c?{...c,...r}:null),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to update roadmap");throw i?.onError?.(c),c}},[]),He=a.useCallback(async(s,d)=>{try{await zt(s,R.current),f(i=>i.filter(r=>r.id!==s)),x.current===s&&(w(null),g(null),D([]),S({})),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to delete roadmap");throw d?.onError?.(r),r}},[]),Le=a.useCallback(s=>{w(s)},[]),p=a.useCallback(async(s,d)=>{const i=x.current;if(!i){const r=new Error("No roadmap selected");throw d?.onError?.(r),r}try{const r=await tt(i,s,R.current);D(c=>[...c,r]),S(c=>({...c,[r.id]:[]})),x.current&&N(x.current),d?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to create milestone");throw d?.onError?.(c),c}},[N]),I=a.useCallback(async(s,d,i)=>{try{const r=await At(s,d,R.current);D(c=>c.map(o=>o.id===s?r:o)),x.current&&N(x.current),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to update milestone");throw i?.onError?.(c),c}},[N]),te=a.useCallback(async(s,d)=>{try{await Ot(s,R.current),D(i=>i.filter(r=>r.id!==s)),S(i=>{const r={...i};return delete r[s],r}),x.current&&N(x.current),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to delete milestone");throw d?.onError?.(r),r}},[N]),Ve=a.useCallback(async(s,d,i)=>{try{const r=await at(s,d,R.current);S(c=>({...c,[s]:[...c[s]||[],r]})),x.current&&N(x.current),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to create feature");throw i?.onError?.(c),c}},[N]),De=a.useCallback(async(s,d,i)=>{try{const r=await Ht(s,d,R.current);S(c=>{const o={};for(const[h,m]of Object.entries(c))o[h]=m.map(_=>_.id===s?r:_);return o}),x.current&&N(x.current),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to update feature");throw i?.onError?.(c),c}},[N]),Me=a.useCallback(async(s,d)=>{try{await Bt(s,R.current),S(i=>{const r={};for(const[c,o]of Object.entries(i))r[c]=o.filter(h=>h.id!==s);return r}),x.current&&N(x.current),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to delete feature");throw d?.onError?.(r),r}},[N]),E=a.useCallback(async(s,d,i)=>{const r=de.current,c=d.map(o=>r.find(h=>h.id===o)).filter(o=>o!==void 0).map((o,h)=>({...o,orderIndex:h}));D(c);try{await Gt(s,d,R.current),x.current&&N(x.current),i?.onSuccess?.()}catch(o){D(r);const h=o instanceof Error?o:new Error("Failed to reorder milestones");throw i?.onError?.(h),h}},[N]),ce=a.useCallback(async(s,d,i)=>{const r=we.current[s]||[],c=r.map(m=>m.id);if(JSON.stringify(c)===JSON.stringify(d)){i?.onSuccess?.();return}const o=we.current,h=d.map(m=>r.find(_=>_.id===m)).filter(m=>m!==void 0).map((m,_)=>({...m,orderIndex:_}));S(m=>({...m,[s]:h}));try{await Pt(s,d,R.current),x.current&&N(x.current),i?.onSuccess?.()}catch(m){S(o);const _=m instanceof Error?m:new Error("Failed to reorder features");throw i?.onError?.(_),_}},[N]),Q=a.useCallback(async(s,d,i,r)=>{const c=we.current;let o=null;for(const[F,W]of Object.entries(c))if(W.some(Ke=>Ke.id===s)){o=F;break}if(!o){const F=new Error("Feature not found");throw r?.onError?.(F),F}if(o===d){const F=c[o]||[],W=Math.max(0,Math.min(i,F.length-1));if(F.findIndex(We=>We.id===s)===W){r?.onSuccess?.();return}}const h=c[o]||[],m=c[d]||[],_=h.find(F=>F.id===s);if(!_){const F=new Error("Feature not found");throw r?.onError?.(F),F}const H=h.filter(F=>F.id!==s).map((F,W)=>({...F,orderIndex:W})),ye={..._,milestoneId:d,orderIndex:i},se=[...m];se.splice(i,0,ye);const Ue=se.map((F,W)=>({...F,orderIndex:W}));S(o===d?F=>({...F,[o]:Ue}):F=>({...F,[o]:H,[d]:Ue}));try{await Tt(s,d,i,n),x.current&&N(x.current),r?.onSuccess?.()}catch(F){S(c);const W=F instanceof Error?F:new Error("Failed to move feature");throw r?.onError?.(W),W}},[N,n]);function V(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`draft-${Date.now()}-${Math.random().toString(36).slice(2,11)}`}const ae=a.useCallback(async(s,d=5,i)=>{const r=x.current;if(!r){const h=new Error("No roadmap selected");throw i?.onError?.(h),h}const c=M.current,o=R.current;G(!0);try{const h=await Lt(r,s,d,o);if(M.current!==c)return;const m=h.suggestions.map(_=>({id:V(),title:_.title,description:_.description}));B(m),i?.onSuccess?.()}catch(h){if(M.current!==c)return;const m=h instanceof Error?h:new Error("Failed to generate suggestions");throw i?.onError?.(m),m}finally{M.current===c&&G(!1)}},[]),Re=a.useCallback((s,d)=>{const r=oe.current.map(c=>c.id===s?{...c,...d}:c);oe.current=r,B(c=>c.map(o=>o.id===s?{...o,...d}:o))},[]),U=a.useCallback(async(s,d)=>{const i=x.current;if(!i){const m=new Error("No roadmap selected");throw d?.onError?.(m),m}const r=M.current,c=oe.current,o=c.findIndex(m=>m.id===s);if(o===-1){const m=new Error("Suggestion draft not found");throw d?.onError?.(m),m}const h=c[o];if(!h.title.trim()){const m=new Error("Title cannot be empty");throw d?.onError?.(m),m}B(m=>m.filter(_=>_.id!==s));try{if(await tt(i,{title:h.title,description:h.description},R.current),M.current!==r){B(m=>{const _=[...m];return _.splice(o,0,h),_});return}x.current&&N(x.current),d?.onSuccess?.()}catch(m){B(H=>{const ye=[...H];return ye.splice(o,0,h),ye});const _=m instanceof Error?m:new Error("Failed to accept suggestion");throw d?.onError?.(_),_}},[N]),K=a.useCallback(async s=>{const d=x.current;if(!d){const o=new Error("No roadmap selected");throw s?.onError?.(o),o}const i=[...oe.current];if(i.length===0)return;const r=i.findIndex(o=>!o.title.trim());if(r!==-1){const o=new Error(`Title cannot be empty at position ${r+1}`);throw s?.onError?.(o),o}B([]);const c=M.current;for(let o=0;o<i.length&&M.current===c;o++){const h=i[o];try{await tt(d,{title:h.title,description:h.description},R.current)}catch(m){const _=m instanceof Error?m:new Error("Failed to accept all suggestions");throw s?.onError?.(_),_}}M.current===c&&(x.current&&N(x.current),s?.onSuccess?.())},[N]),Je=a.useCallback(s=>ve.current[s]??!1,[]),Be=a.useCallback(async(s,d,i)=>{const r=M.current,c=R.current;ee(o=>({...o,[s]:!0}));try{const o=await Vt(s,d,c);if(M.current!==r)return;const h=o.suggestions.map(m=>({id:V(),title:m.title,description:m.description}));P(m=>({...m,[s]:h})),i?.onSuccess?.()}catch(o){if(M.current!==r)return;const h=o instanceof Error?o:new Error("Failed to generate feature suggestions");throw i?.onError?.(h),h}finally{M.current===r&&ee(o=>({...o,[s]:!1}))}},[]),Ce=a.useCallback((s,d,i)=>{const c=(Y.current[s]||[]).map(o=>o.id===d?{...o,...i}:o);Y.current={...Y.current,[s]:c},P(o=>({...o,[s]:o[s]?.map(h=>h.id===d?{...h,...i}:h)||[]}))},[]),Ge=a.useCallback(async(s,d,i)=>{const r=M.current,c=Y.current[s]||[],o=c.findIndex(m=>m.id===d);if(o===-1){const m=new Error("Suggestion draft not found");throw i?.onError?.(m),m}const h=c[o];if(!h.title.trim()){const m=new Error("Title cannot be empty");throw i?.onError?.(m),m}P(m=>({...m,[s]:m[s]?.filter(_=>_.id!==d)||[]}));try{if(await at(s,{title:h.title,description:h.description},R.current),M.current!==r){P(m=>{const H=[...m[s]||[]];return H.splice(o,0,h),{...m,[s]:H}});return}x.current&&N(x.current),i?.onSuccess?.()}catch(m){P(H=>{const se=[...H[s]||[]];return se.splice(o,0,h),{...H,[s]:se}});const _=m instanceof Error?m:new Error("Failed to accept suggestion");throw i?.onError?.(_),_}},[N]),Ye=a.useCallback(async(s,d)=>{const i=[...Y.current[s]||[]];if(i.length===0)return;const r=i.findIndex(o=>!o.title.trim());if(r!==-1){const o=new Error(`Title cannot be empty at position ${r+1}`);throw d?.onError?.(o),o}P(o=>({...o,[s]:[]}));const c=M.current;for(let o=0;o<i.length&&M.current===c;o++){const h=i[o];try{await at(s,{title:h.title,description:h.description},R.current)}catch(m){const _=m instanceof Error?m:new Error("Failed to accept all suggestions");throw d?.onError?.(_),_}}M.current===c&&(x.current&&N(x.current),d?.onSuccess?.())},[N]),Ne=a.useCallback(()=>{B([]),G(!1)},[]),Xe=a.useCallback(s=>{P(d=>{const i={...d};return delete i[s],i}),ee(d=>{const i={...d};return delete i[s],i})},[]),ue=a.useCallback(async(s,d)=>{const i=++le.current,r=n;ge(!0),Z(null);try{const c=await Ut(s,r);if(le.current!==i||n!==r)return;pe(c),d?.onSuccess?.()}catch(c){if(le.current!==i||n!==r)return;const o=c instanceof Error?c:new Error(String(c));Z(o),pe(null),d?.onError?.(o)}finally{le.current===i&&ge(!1)}},[n]),Ie=a.useCallback(()=>{pe(null),Z(null),ge(!1)},[]),Qe=a.useCallback(async()=>{await X(),x.current&&await N(x.current)},[X,N]);return{roadmaps:v,selectedRoadmapId:C,selectedRoadmap:y,milestones:k,featuresByMilestoneId:j,loading:A,error:L,createRoadmap:Oe,updateRoadmap:je,deleteRoadmap:He,selectRoadmap:Le,createMilestone:p,updateMilestone:I,deleteMilestone:te,reorderMilestones:E,createFeature:Ve,updateFeature:De,deleteFeature:Me,reorderFeatures:ce,moveFeature:Q,milestoneSuggestions:fe,isGeneratingSuggestions:O,generateMilestoneSuggestions:ae,updateMilestoneSuggestionDraft:Re,acceptMilestoneSuggestion:U,acceptAllMilestoneSuggestions:K,clearMilestoneSuggestions:Ne,featureSuggestionsByMilestoneId:be,isGeneratingFeatureSuggestions:Je,generateFeatureSuggestions:Be,updateFeatureSuggestionDraft:Ce,acceptFeatureSuggestion:Ge,acceptAllFeatureSuggestions:Ye,clearFeatureSuggestions:Xe,handoffPayload:ne,isFetchingHandoff:Te,handoffError:he,fetchHandoff:ue,clearHandoff:Ie,refresh:Qe}}function ea({isOpen:l,onClose:n,roadmapTitle:v,handoffPayload:f,isLoading:C,error:w,onFetchHandoff:y,onCopyToClipboard:g}){return l?e.jsx("div",{className:"modal-overlay open",onClick:n,role:"presentation",children:e.jsxs("div",{className:"modal modal-lg",onClick:k=>k.stopPropagation(),role:"dialog","aria-modal":"true","aria-labelledby":"handoff-modal-title",children:[e.jsxs("div",{className:"modal-header",children:[e.jsxs("h2",{id:"handoff-modal-title",children:["Export Roadmap: ",v]}),e.jsx("button",{className:"modal-close",onClick:n,"aria-label":"Close modal",children:e.jsx(re,{size:18})})]}),e.jsxs("div",{className:"modal-body",children:[e.jsx("p",{className:"text-muted roadmaps-view__handoff-intro",children:"Export roadmap data for use in mission and task planning flows. This is a read-only export — no missions or tasks will be created."}),w&&e.jsxs("div",{className:"form-error roadmaps-view__handoff-error",children:["Error loading handoff data: ",w.message]}),!f&&!C&&e.jsx("div",{className:"roadmaps-view__handoff-empty-state",children:e.jsxs("button",{className:"btn btn-primary",onClick:y,children:[e.jsx(st,{size:16,className:"roadmaps-view__handoff-button-icon"}),"Load Handoff Data"]})}),C&&e.jsxs("div",{className:"roadmaps-view__handoff-loading-state",children:[e.jsx(Qt,{size:24,className:"spin"}),e.jsx("p",{className:"roadmaps-view__handoff-loading-text",children:"Loading handoff data..."})]}),f&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"roadmaps-view__handoff-section",children:[e.jsx("h3",{className:"roadmaps-view__handoff-section-title",children:"Mission Planning Handoff"}),e.jsx("div",{className:"card roadmaps-view__handoff-card",children:e.jsx("pre",{className:"roadmaps-view__handoff-pre roadmaps-view__handoff-pre--mission",children:JSON.stringify(f.mission,null,2)})})]}),e.jsxs("div",{className:"roadmaps-view__handoff-section",children:[e.jsxs("h3",{className:"roadmaps-view__handoff-section-title",children:["Feature Task Planning Handoffs (",f.features.length,")"]}),e.jsx("div",{className:"card roadmaps-view__handoff-card",children:e.jsx("pre",{className:"roadmaps-view__handoff-pre roadmaps-view__handoff-pre--features",children:JSON.stringify(f.features,null,2)})})]})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("div",{className:"modal-actions-left",children:f&&e.jsxs("button",{className:"btn btn-sm",onClick:g,children:[e.jsx(Yt,{size:14,className:"roadmaps-view__handoff-copy-icon"}),"Copy to Clipboard"]})}),e.jsx("div",{className:"modal-actions-right",children:e.jsx("button",{className:"btn",onClick:n,children:"Close"})})]})]})}):null}function ta({roadmap:l,isSelected:n,onSelect:v,onEdit:f,onDelete:C,onExport:w}){const y=j=>{j.key==="Enter"&&v()},g=j=>{j.stopPropagation(),f()},k=j=>{j.stopPropagation(),C()},D=j=>{j.stopPropagation(),w()};return e.jsxs("div",{className:`roadmaps-view__sidebar-item${n?" roadmaps-view__sidebar-item--active":""}`,onClick:v,onKeyDown:y,role:"button",tabIndex:0,"aria-selected":n,"data-testid":`roadmap-item-${l.id}`,children:[e.jsxs("div",{className:"roadmaps-view__sidebar-item-content",children:[e.jsx("div",{className:"roadmaps-view__sidebar-item-title",children:l.title}),l.description&&e.jsx("div",{className:"roadmaps-view__sidebar-item-desc",children:l.description})]}),e.jsxs("div",{className:"roadmaps-view__sidebar-item-actions",onClick:g,role:"presentation",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:D,title:"Export roadmap","aria-label":"Export roadmap","data-testid":`roadmap-export-${l.id}`,type:"button",children:e.jsx(st,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:g,title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":`roadmap-edit-${l.id}`,type:"button",children:e.jsx(Fe,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:k,title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":`roadmap-delete-${l.id}`,type:"button",children:e.jsx(Pe,{size:14})})]})]})}function aa({roadmaps:l,selectedRoadmapId:n,onSelect:v,onCreate:f,onEdit:C,onDelete:w,onExport:y,showCreateForm:g,onCancelCreate:k,onSaveCreate:D}){return e.jsxs("div",{className:"roadmaps-view__mobile-list","data-testid":"roadmaps-view__mobile-list",children:[e.jsxs("div",{className:"roadmaps-view__mobile-list-header",children:[e.jsx("h2",{className:"roadmaps-view__mobile-list-title",children:"Roadmaps"}),!g&&e.jsx("button",{className:"roadmaps-view__mobile-add-btn",onClick:f,title:"Create roadmap","aria-label":"Create roadmap","data-testid":"mobile-create-roadmap-btn",children:e.jsx(ze,{size:18})})]}),g&&e.jsx("div",{className:"roadmaps-view__mobile-create-form",children:e.jsx(mt,{onSave:D,onCancel:k})}),l.length===0&&!g?e.jsxs("div",{className:"roadmaps-view__mobile-empty",children:[e.jsx("p",{children:"No roadmaps yet."}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:f,children:[e.jsx(ze,{size:14}),e.jsx("span",{children:"Create Roadmap"})]})]}):e.jsx("div",{className:"roadmaps-view__mobile-list-items",children:l.map(j=>e.jsxs("div",{className:`roadmaps-view__mobile-item${j.id===n?" roadmaps-view__mobile-item--active":""}`,onClick:()=>v(j.id),role:"button",tabIndex:0,onKeyDown:S=>{S.key==="Enter"&&v(j.id)},"data-testid":`mobile-roadmap-item-${j.id}`,children:[e.jsxs("div",{className:"roadmaps-view__mobile-item-content",children:[e.jsx("span",{className:"roadmaps-view__mobile-item-title",children:j.title}),j.description&&e.jsx("span",{className:"roadmaps-view__mobile-item-desc",children:j.description})]}),e.jsxs("div",{className:"roadmaps-view__mobile-item-actions",children:[e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:S=>{S.stopPropagation(),y(j)},title:"Export roadmap","aria-label":"Export roadmap","data-testid":`mobile-roadmap-export-${j.id}`,children:e.jsx(st,{size:16})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:S=>{S.stopPropagation(),C(j)},title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":`mobile-roadmap-edit-${j.id}`,children:e.jsx(Fe,{size:16})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn roadmaps-view__mobile-action-btn--danger",onClick:S=>{S.stopPropagation(),w(j.id)},title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":`mobile-roadmap-delete-${j.id}`,children:e.jsx(Pe,{size:16})})]})]},j.id))})]})}function sa({roadmapTitle:l,onBack:n,onEdit:v,onDelete:f,onCreate:C}){return e.jsxs("div",{className:"roadmaps-view__mobile-header","data-testid":"roadmaps-view__mobile-header",children:[e.jsx("button",{className:"roadmaps-view__mobile-back-btn",onClick:n,title:"Back to roadmap list","aria-label":"Back to roadmap list","data-testid":"mobile-back-btn",children:e.jsx(Jt,{size:20})}),e.jsx("h2",{className:"roadmaps-view__mobile-header-title",children:l}),e.jsxs("div",{className:"roadmaps-view__mobile-header-actions",children:[e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:C,title:"Create roadmap","aria-label":"Create roadmap","data-testid":"mobile-header-create-btn",children:e.jsx(ze,{size:18})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:v,title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":"mobile-header-edit-btn",children:e.jsx(Fe,{size:18})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn roadmaps-view__mobile-action-btn--danger",onClick:f,title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":"mobile-header-delete-btn",children:e.jsx(Pe,{size:18})})]})]})}function ra({milestone:l,features:n,onEditMilestone:v,onDeleteMilestone:f,onAddFeature:C,onEditFeature:w,onDeleteFeature:y,milestoneEdit:g,onMilestoneEditChange:k,onMilestoneEditFieldChange:D,onCancelMilestoneEdit:j,onSaveMilestoneEdit:S,featureEdit:A,onFeatureEditChange:J,onStartFeatureEdit:L,onCancelFeatureEdit:$,onSaveFeatureEdit:ne,projectId:pe,addToast:Te,isMilestoneDragging:ge,isMilestoneDropTarget:he,milestoneDropPosition:Z,onMilestoneDragStart:fe,onMilestoneDragEnd:B,onMilestoneDragOver:O,onMilestoneDrop:G,onMilestoneDragLeave:be,isFeatureDragging:P,isFeatureDropTarget:ie,featureDropIndex:ee,onFeatureDragStart:Y,onFeatureDragEnd:ve,onFeatureDragOver:oe,onFeatureDrop:xe,onFeatureDragLeave:M,onFeatureDropOnMilestone:le,featureSuggestions:_e,isGeneratingFeatureSuggestions:x,onGenerateFeatureSuggestions:de,onAcceptFeatureSuggestion:we,onAcceptAllFeatureSuggestions:R,onUpdateFeatureSuggestionDraft:Ae,onClearFeatureSuggestions:X}){const N=g?.milestoneId===l.id,Oe=p=>{p.key==="Enter"?(p.preventDefault(),g&&S({title:g.value})):p.key==="Escape"&&j()},je=p=>{p.key==="Escape"&&j()},He=["roadmaps-view__milestone",ge?"roadmaps-view__milestone--dragging":"",he?"roadmaps-view__milestone--drop-target":"",he&&Z==="before"?"roadmaps-view__milestone--drop-before":"",he&&Z==="after"?"roadmaps-view__milestone--drop-after":""].filter(Boolean).join(" "),Le=["roadmaps-view__feature-list",ie?"roadmaps-view__feature-list--drop-target":""].filter(Boolean).join(" ");return e.jsxs("div",{className:He,draggable:!N,onDragStart:p=>{N||(fe(l.id),p.dataTransfer.setData("text/plain",`milestone:${l.id}`),p.dataTransfer.effectAllowed="move")},onDragEnd:B,onDragOver:p=>{p.dataTransfer.types.includes("text/plain")&&p.dataTransfer.types.includes("text/plain")&&(p.preventDefault(),p.dataTransfer.dropEffect="move",O(l.id))},onDrop:p=>{p.preventDefault(),p.dataTransfer.getData("text/plain")?.startsWith("feature:")||G(l.id)},onDragLeave:be,"data-testid":`milestone-card-${l.id}`,children:[e.jsx("div",{className:"roadmaps-view__milestone-header",children:N?e.jsxs("div",{className:"roadmaps-view__inline-edit",children:[e.jsxs("div",{className:"roadmaps-view__inline-edit-row",children:[e.jsx("span",{className:"roadmaps-view__drag-handle",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`milestone-drag-handle-${l.id}`,children:e.jsx(qe,{size:14})}),e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:g.value,onChange:p=>{D("title"),k(p.target.value)},onKeyDown:Oe,placeholder:"Milestone title",autoFocus:!0,"data-testid":`milestone-title-input-${l.id}`}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",onClick:()=>S({title:g.value}),"aria-label":"Save milestone title",title:"Save",children:e.jsx(me,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:j,"aria-label":"Cancel editing",title:"Cancel",children:e.jsx(re,{size:14})})]}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:g.field==="description"?g.value:l.description||"",onChange:p=>{D("description"),k(p.target.value)},onKeyDown:je,placeholder:"Milestone description (optional)",rows:2,"data-testid":`milestone-desc-input-${l.id}`})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"roadmaps-view__milestone-title-row",children:[e.jsx("span",{className:"roadmaps-view__drag-handle",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`milestone-drag-handle-${l.id}`,children:e.jsx(qe,{size:14})}),e.jsx("h3",{className:"roadmaps-view__milestone-title",children:l.title}),e.jsxs("div",{className:"roadmaps-view__milestone-actions",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:v,title:"Edit milestone","aria-label":"Edit milestone","data-testid":`milestone-edit-${l.id}`,children:e.jsx(Fe,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:f,title:"Delete milestone","aria-label":"Delete milestone","data-testid":`milestone-delete-${l.id}`,children:e.jsx(Pe,{size:14})})]})]}),l.description&&e.jsx("p",{className:"roadmaps-view__milestone-desc",children:l.description})]})}),e.jsxs("div",{className:"roadmaps-view__milestone-actions-bar",children:[e.jsxs("button",{className:"roadmaps-view__add-feature-btn",onClick:C,title:"Add feature","aria-label":"Add feature","data-testid":`add-feature-${l.id}`,children:[e.jsx(ze,{size:12}),e.jsx("span",{children:"Add Feature"})]}),e.jsxs("button",{className:"roadmaps-view__suggest-btn",onClick:()=>{de?.()},disabled:x??!1,title:"Generate feature suggestions with AI","aria-label":"Generate feature suggestions","data-testid":`generate-features-${l.id}`,children:[e.jsx(ut,{size:12}),e.jsx("span",{children:x?"Generating...":"AI Suggestions"})]})]}),e.jsxs("div",{className:Le,onDragOver:p=>{p.preventDefault(),p.dataTransfer.dropEffect="move",p.dataTransfer.getData("text/plain")?.startsWith("feature:")&&le()},onDrop:p=>{p.preventDefault();const I=p.dataTransfer.getData("text/plain");I?.startsWith("feature:")&&xe(I.split(":")[1],n.length)},onDragLeave:M,children:[n.length===0?e.jsx("p",{className:"roadmaps-view__empty-features",children:"No features yet."}):n.map((p,I)=>{const te=A?.featureId===p.id,Ve=P(p.id),De=E=>{E.key==="Enter"?(E.preventDefault(),A&&ne({title:A.value})):E.key==="Escape"&&$()},Me=["roadmaps-view__feature-item",Ve?"roadmaps-view__feature-item--dragging":"",ie&&ee===I?"roadmaps-view__feature-item--drop-before":"",ie&&ee===I+1?"roadmaps-view__feature-item--drop-after":""].filter(Boolean).join(" ");return e.jsx("div",{className:Me,draggable:!te,onDragStart:E=>{te||(Y(p.id,l.id),E.dataTransfer.setData("text/plain",`feature:${p.id}`),E.dataTransfer.effectAllowed="move")},onDragEnd:ve,onDragOver:E=>{if(E.preventDefault(),E.stopPropagation(),E.dataTransfer.dropEffect="move",E.dataTransfer.getData("text/plain")?.startsWith("feature:")){const Q=E.currentTarget.getBoundingClientRect(),V=Q.top+Q.height/2,ae=E.clientY<V?"before":"after";oe(p.id,ae)}},onDrop:E=>{E.preventDefault(),E.stopPropagation();const ce=E.dataTransfer.getData("text/plain");if(ce?.startsWith("feature:")){const Q=ce.split(":")[1],V=E.currentTarget.getBoundingClientRect(),ae=V.top+V.height/2,Re=E.clientY<ae?"before":"after";let U=I;Re==="after"&&(U=I+1),xe(Q,U)}},onDragLeave:M,"data-testid":`feature-item-${p.id}`,children:te?e.jsx("div",{className:"roadmaps-view__inline-edit roadmaps-view__inline-edit--compact",children:e.jsxs("div",{className:"roadmaps-view__inline-edit-row",children:[e.jsx("span",{className:"roadmaps-view__drag-handle roadmaps-view__drag-handle--feature",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`feature-drag-handle-${p.id}`,children:e.jsx(qe,{size:12})}),e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:A.value,onChange:E=>J(E.target.value),onKeyDown:De,placeholder:"Feature title",autoFocus:!0,"data-testid":`feature-title-input-${p.id}`}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",onClick:()=>ne({title:A.value}),"aria-label":"Save feature title",title:"Save",children:e.jsx(me,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:$,"aria-label":"Cancel editing",title:"Cancel",children:e.jsx(re,{size:14})})]})}):e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"roadmaps-view__drag-handle roadmaps-view__drag-handle--feature",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`feature-drag-handle-${p.id}`,children:e.jsx(qe,{size:12})}),e.jsxs("div",{className:"roadmaps-view__feature-content",children:[e.jsx("span",{className:"roadmaps-view__feature-title",children:p.title}),p.description&&e.jsx("p",{className:"roadmaps-view__feature-desc",children:p.description})]}),e.jsxs("div",{className:"roadmaps-view__feature-actions",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:()=>w(p.id),title:"Edit feature","aria-label":"Edit feature","data-testid":`feature-edit-${p.id}`,children:e.jsx(Fe,{size:12})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:()=>y(p.id),title:"Delete feature","aria-label":"Delete feature","data-testid":`feature-delete-${p.id}`,children:e.jsx(Pe,{size:12})})]})]})},p.id)}),_e&&_e.length>0&&e.jsxs("div",{className:"roadmap-suggestion-section",children:[e.jsxs("div",{className:"roadmap-suggestion-header",children:[e.jsx("h4",{className:"roadmap-suggestion-title",children:"AI Feature Suggestions"}),e.jsxs("div",{className:"roadmap-suggestion-actions",children:[e.jsx("button",{className:"roadmap-suggestion-accept-all-btn",onClick:()=>R?.(),title:"Accept all suggestions","aria-label":"Accept all","data-testid":`accept-all-features-${l.id}`,children:"Accept All"}),e.jsx("button",{className:"roadmap-suggestion-clear-btn",onClick:()=>X?.(),title:"Clear suggestions","aria-label":"Clear","data-testid":`clear-features-${l.id}`,children:"Clear"})]})]}),e.jsx("div",{className:"roadmap-suggestion-list",children:_e.map(p=>e.jsx(na,{suggestion:p,onUpdateDraft:I=>Ae?.(l.id,p.id,I),onAccept:()=>{we?.(l.id,p.id)},testIdPrefix:`feature-suggestion-${l.id}`},p.id))})]})]})]})}function na({suggestion:l,onUpdateDraft:n,onAccept:v,testIdPrefix:f}){const[C,w]=a.useState(!1),[y,g]=a.useState(l.title),[k,D]=a.useState(l.description||""),j=()=>{g(l.title),D(l.description||""),w(!0)},S=()=>{n({title:y.trim(),description:k.trim()||void 0}),w(!1)},A=()=>{g(l.title),D(l.description||""),w(!1)},J=()=>{l.title.trim()&&v()},L=l.title.trim().length>0;return C?e.jsx("div",{className:"roadmap-suggestion-card roadmap-suggestion-card--editing",children:e.jsxs("div",{className:"roadmap-suggestion-edit-form",children:[e.jsx("input",{type:"text",className:"roadmap-suggestion-input",value:y,onChange:$=>g($.target.value),placeholder:"Feature title",autoFocus:!0,"data-testid":`${f}-${l.id}-title-input`}),e.jsx("textarea",{className:"roadmap-suggestion-textarea",value:k,onChange:$=>D($.target.value),placeholder:"Description (optional)",rows:2,"data-testid":`${f}-${l.id}-desc-input`}),e.jsxs("div",{className:"roadmap-suggestion-edit-actions",children:[e.jsx("button",{className:"roadmap-suggestion-save-btn",onClick:S,disabled:!y.trim(),title:"Save","data-testid":`${f}-${l.id}-save`,children:e.jsx(me,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-cancel-btn",onClick:A,title:"Cancel","data-testid":`${f}-${l.id}-cancel`,children:e.jsx(re,{size:12})})]})]})}):e.jsxs("div",{className:"roadmap-suggestion-card","data-testid":`${f}-${l.id}`,children:[e.jsxs("div",{className:"roadmap-suggestion-content",children:[e.jsx("span",{className:"roadmap-suggestion-card-title",children:l.title}),l.description&&e.jsx("p",{className:"roadmap-suggestion-card-desc",children:l.description})]}),e.jsxs("div",{className:"roadmap-suggestion-card-actions",children:[e.jsx("button",{className:"roadmap-suggestion-edit-btn",onClick:j,title:"Edit suggestion","aria-label":"Edit","data-testid":`${f}-${l.id}-edit`,children:e.jsx(Fe,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-accept-btn",onClick:J,disabled:!L,title:"Accept this suggestion","aria-label":"Accept","data-testid":`${f}-${l.id}-accept`,children:e.jsx(me,{size:12})})]})]})}function ct({suggestion:l,onUpdateDraft:n,onAccept:v,testIdPrefix:f}){const[C,w]=a.useState(!1),[y,g]=a.useState(l.title),[k,D]=a.useState(l.description||""),j=()=>{g(l.title),D(l.description||""),w(!0)},S=()=>{n({title:y.trim(),description:k.trim()||void 0}),w(!1)},A=()=>{g(l.title),D(l.description||""),w(!1)},J=()=>{l.title.trim()&&v()},L=l.title.trim().length>0;return C?e.jsx("div",{className:"roadmap-suggestion-card roadmap-suggestion-card--editing",children:e.jsxs("div",{className:"roadmap-suggestion-edit-form",children:[e.jsx("input",{type:"text",className:"roadmap-suggestion-input",value:y,onChange:$=>g($.target.value),placeholder:"Milestone title",autoFocus:!0,"data-testid":`${f}-${l.id}-title-input`}),e.jsx("textarea",{className:"roadmap-suggestion-textarea",value:k,onChange:$=>D($.target.value),placeholder:"Description (optional)",rows:2,"data-testid":`${f}-${l.id}-desc-input`}),e.jsxs("div",{className:"roadmap-suggestion-edit-actions",children:[e.jsx("button",{className:"roadmap-suggestion-save-btn",onClick:S,disabled:!y.trim(),title:"Save","data-testid":`${f}-${l.id}-save`,children:e.jsx(me,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-cancel-btn",onClick:A,title:"Cancel","data-testid":`${f}-${l.id}-cancel`,children:e.jsx(re,{size:12})})]})]})}):e.jsxs("div",{className:"roadmap-suggestion-card","data-testid":`${f}-${l.id}`,children:[e.jsxs("div",{className:"roadmap-suggestion-content",children:[e.jsx("span",{className:"roadmap-suggestion-card-title",children:l.title}),l.description&&e.jsx("p",{className:"roadmap-suggestion-card-desc",children:l.description})]}),e.jsxs("div",{className:"roadmap-suggestion-card-actions",children:[e.jsx("button",{className:"roadmap-suggestion-edit-btn",onClick:j,title:"Edit suggestion","aria-label":"Edit","data-testid":`${f}-${l.id}-edit`,children:e.jsx(Fe,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-accept-btn",onClick:J,disabled:!L,title:"Accept this suggestion","aria-label":"Accept","data-testid":`${f}-${l.id}-accept`,children:e.jsx(me,{size:12})})]})]})}function mt({onSave:l,onCancel:n}){const[v,f]=a.useState(""),[C,w]=a.useState(""),y=g=>{g.preventDefault(),v.trim()&&l({title:v.trim(),description:C.trim()||void 0})};return e.jsx("div",{className:"roadmaps-view__create-form","data-testid":"create-roadmap-form",children:e.jsxs("form",{onSubmit:y,children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:v,onChange:g=>f(g.target.value),placeholder:"Roadmap title",autoFocus:!0,"data-testid":"create-roadmap-title"}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:C,onChange:g=>w(g.target.value),placeholder:"Roadmap description (optional)",rows:2,"data-testid":"create-roadmap-description"}),e.jsxs("div",{className:"roadmaps-view__create-form-actions",children:[e.jsx("button",{type:"submit",className:"roadmaps-view__btn roadmaps-view__btn--primary",disabled:!v.trim(),"data-testid":"create-roadmap-submit",children:"Create"}),e.jsx("button",{type:"button",className:"roadmaps-view__btn",onClick:n,"data-testid":"create-roadmap-cancel",children:"Cancel"})]})]})})}function ia({onSave:l,onCancel:n}){const[v,f]=a.useState(""),[C,w]=a.useState(""),y=g=>{g.preventDefault(),v.trim()&&l({title:v.trim(),description:C.trim()||void 0})};return e.jsx("div",{className:"roadmaps-view__create-form roadmaps-view__create-form--inline","data-testid":"create-milestone-form",children:e.jsxs("form",{onSubmit:y,className:"roadmaps-view__inline-form",children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:v,onChange:g=>f(g.target.value),placeholder:"Milestone title",autoFocus:!0,"data-testid":"create-milestone-title"}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:C,onChange:g=>w(g.target.value),placeholder:"Description (optional)",rows:1,"data-testid":"create-milestone-description"}),e.jsxs("div",{className:"roadmaps-view__inline-form-actions",children:[e.jsx("button",{type:"submit",className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",disabled:!v.trim(),"aria-label":"Save milestone",title:"Save","data-testid":"create-milestone-submit",children:e.jsx(me,{size:14})}),e.jsx("button",{type:"button",className:"roadmaps-view__icon-btn",onClick:n,"aria-label":"Cancel",title:"Cancel","data-testid":"create-milestone-cancel",children:e.jsx(re,{size:14})})]})]})})}function oa({onSave:l,onCancel:n}){const[v,f]=a.useState(""),[C,w]=a.useState(""),y=g=>{g.preventDefault(),v.trim()&&l({title:v.trim(),description:C.trim()||void 0})};return e.jsx("div",{className:"roadmaps-view__create-form roadmaps-view__create-form--inline","data-testid":"create-feature-form",children:e.jsxs("form",{onSubmit:y,className:"roadmaps-view__inline-form",children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:v,onChange:g=>f(g.target.value),placeholder:"Feature title",autoFocus:!0,"data-testid":"create-feature-title"}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:C,onChange:g=>w(g.target.value),placeholder:"Description (optional)",rows:1,"data-testid":"create-feature-description"}),e.jsxs("div",{className:"roadmaps-view__inline-form-actions",children:[e.jsx("button",{type:"submit",className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",disabled:!v.trim(),"aria-label":"Save feature",title:"Save","data-testid":"create-feature-submit",children:e.jsx(me,{size:14})}),e.jsx("button",{type:"button",className:"roadmaps-view__icon-btn",onClick:n,"aria-label":"Cancel",title:"Cancel","data-testid":"create-feature-cancel",children:e.jsx(re,{size:14})})]})]})})}function ma({projectId:l,addToast:n}){const{confirm:v}=Kt(),f=Wt()==="mobile",{roadmaps:C,selectedRoadmapId:w,selectedRoadmap:y,milestones:g,featuresByMilestoneId:k,loading:D,error:j,createRoadmap:S,updateRoadmap:A,deleteRoadmap:J,selectRoadmap:L,createMilestone:$,updateMilestone:ne,deleteMilestone:pe,createFeature:Te,updateFeature:ge,deleteFeature:he,reorderMilestones:Z,reorderFeatures:fe,moveFeature:B,milestoneSuggestions:O,isGeneratingSuggestions:G,generateMilestoneSuggestions:be,updateMilestoneSuggestionDraft:P,acceptMilestoneSuggestion:ie,acceptAllMilestoneSuggestions:ee,clearMilestoneSuggestions:Y,featureSuggestionsByMilestoneId:ve,isGeneratingFeatureSuggestions:oe,generateFeatureSuggestions:xe,updateFeatureSuggestionDraft:M,acceptFeatureSuggestion:le,acceptAllFeatureSuggestions:_e,clearFeatureSuggestions:x,handoffPayload:de,isFetchingHandoff:we,handoffError:R,fetchHandoff:Ae,clearHandoff:X}=Zt({projectId:l}),[N,Oe]=a.useState(!1),[je,He]=a.useState(null),[Le,p]=a.useState(""),[I,te]=a.useState(""),[Ve,De]=a.useState(!1),Me=a.useRef(null);a.useEffect(()=>{Me.current!==null&&Me.current!==w&&De(!1),Me.current=w},[w]);const[E,ce]=a.useState({roadmapId:null,field:null,value:""}),[Q,V]=a.useState({milestoneId:null,field:null,value:""}),[ae,Re]=a.useState({featureId:null,field:null,value:""}),[U,K]=a.useState({type:null,parentId:void 0,title:"",description:""}),[Je,Be]=a.useState(!1),[Ce,Ge]=a.useState({draggingId:null,dropTargetId:null,dropPosition:null}),Ye=a.useCallback(t=>{Ge(u=>({...u,draggingId:t}))},[]),Ne=a.useCallback(()=>{Ge({draggingId:null,dropTargetId:null,dropPosition:null})},[]),Xe=a.useCallback(t=>{Ge(u=>u.draggingId===t?u:{...u,dropTargetId:t,dropPosition:null})},[]),[ue,Ie]=a.useState({draggingId:null,draggingMilestoneId:null,dropTargetMilestoneId:null,dropTargetIndex:null,dropPosition:null}),Qe=a.useCallback((t,u)=>{Ie(b=>({...b,draggingId:t,draggingMilestoneId:u}))},[]),s=a.useCallback(()=>{Ie({draggingId:null,draggingMilestoneId:null,dropTargetMilestoneId:null,dropTargetIndex:null,dropPosition:null})},[]),d=a.useCallback((t,u)=>{Ie(b=>{if(b.draggingId===t)return b;const T=(k[b.draggingMilestoneId||""]||[]).findIndex(Ee=>Ee.id===t);let q;return u==="before"?q=T:q=T+1,{...b,dropTargetMilestoneId:b.draggingMilestoneId,dropTargetIndex:q,dropPosition:u}})},[k]),i=a.useCallback(()=>{Ie(t=>({...t,dropTargetMilestoneId:t.draggingMilestoneId,dropTargetIndex:(k[t.draggingMilestoneId||""]||[]).length}))},[k]),r=a.useCallback(async(t,u)=>{const{draggingMilestoneId:b,dropTargetMilestoneId:z}=ue;if(!b){s();return}const T=z||b,q=k[b]||[],Ee=q.find(ke=>ke.id===t);if(!Ee){s();return}if(b!==T){if(b===T){s();return}try{await B(t,T,u,{onError:ke=>{n(`Failed to move feature: ${ke.message}`,"error")}})}catch{}}else{const ke=[...q],kt=ke.findIndex($e=>$e.id===t);ke.splice(kt,1),ke.splice(u,0,Ee);const dt=ke.map($e=>$e.id),Ft=q.map($e=>$e.id);if(dt.join(",")===Ft.join(",")){s();return}try{await fe(b,dt,{onError:$e=>{n(`Failed to reorder features: ${$e.message}`,"error")}})}catch{}}s()},[ue,k,fe,B,n,s]),c=a.useCallback(t=>{const u=t.currentTarget.getBoundingClientRect(),b=t.clientX,z=t.clientY;(b<u.left||b>u.right||z<u.top||z>u.bottom)&&Ie(T=>({...T,dropTargetMilestoneId:null,dropTargetIndex:null,dropPosition:null}))},[]),o=a.useCallback(t=>ue.draggingId===t,[ue.draggingId]),h=a.useCallback(async t=>{const{draggingId:u}=Ce;if(!u||u===t){Ne();return}const b=g.map(Ee=>Ee.id),z=b.indexOf(u),T=b.indexOf(t);if(z===-1||T===-1){Ne();return}const q=[...b];if(q.splice(z,1),q.splice(T,0,u),q.join(",")===b.join(",")){Ne();return}try{await Z(w,q,{onError:Ee=>{n(`Failed to reorder milestones: ${Ee.message}`,"error")}})}catch{}Ne()},[Ce,g,w,Z,n,Ne]),m=a.useCallback(t=>{const u=t.currentTarget.getBoundingClientRect(),b=t.clientX,z=t.clientY;(b<u.left||b>u.right||z<u.top||z>u.bottom)&&Ge(T=>({...T,dropTargetId:null,dropPosition:null}))},[]),_=a.useCallback(t=>{L(t.id),ce({roadmapId:t.id,field:"title",value:t.title})},[L]),H=a.useCallback(()=>{ce({roadmapId:null,field:null,value:""})},[]),ye=a.useCallback(async t=>{if(E.roadmapId)try{await A(E.roadmapId,t,{onError:u=>n(u.message,"error")}),H()}catch{}},[E.roadmapId,A,H,n]),se=a.useCallback(async t=>{if(await v({title:"Delete Roadmap",message:"Delete this roadmap? This cannot be undone.",danger:!0}))try{await J(t,{onError:b=>n(b.message,"error")}),n("Roadmap deleted","success")}catch{}},[J,n,v]),Ue=a.useCallback((t,u)=>{He(t),p(u),Oe(!0),X()},[X]),F=a.useCallback(()=>{Oe(!1),He(null),p(""),X()},[X]),W=a.useCallback(()=>{je&&Ae(je,{onError:t=>n(`Failed to load handoff: ${t.message}`,"error")})},[je,Ae,n]),Ke=a.useCallback(()=>{if(de){const t=JSON.stringify(de,null,2);navigator.clipboard.writeText(t).then(()=>{n("Handoff data copied to clipboard","success")}).catch(()=>{n("Failed to copy to clipboard","error")})}},[de,n]),We=a.useCallback(async t=>{try{await S(t,{onError:u=>n(u.message,"error")}),K({type:null,parentId:void 0,title:"",description:""}),n("Roadmap created","success")}catch{}},[S,n]),pt=a.useCallback(t=>{V({milestoneId:t.id,field:"title",value:t.title})},[]),gt=a.useCallback(t=>{V(u=>({...u,value:t}))},[]),ht=a.useCallback(t=>{V(u=>({...u,field:t}))},[]),Ze=a.useCallback(()=>{V({milestoneId:null,field:null,value:""})},[]),ft=a.useCallback(async t=>{if(Q.milestoneId)try{await ne(Q.milestoneId,t,{onError:u=>n(u.message,"error")}),Ze()}catch{}},[Q.milestoneId,ne,Ze,n]),bt=a.useCallback(async t=>{if(await v({title:"Delete Milestone",message:"Delete this milestone and all its features?",danger:!0}))try{await pe(t,{onError:b=>n(b.message,"error")}),n("Milestone deleted","success")}catch{}},[pe,n,v]),vt=a.useCallback(async t=>{try{await $(t,{onError:u=>n(u.message,"error")}),K({type:null,parentId:void 0,title:"",description:""}),n("Milestone created","success")}catch{}},[$,n]),rt=a.useCallback((t,u,b)=>{Re({featureId:t,field:"title",value:u})},[]),xt=a.useCallback(t=>{Re(u=>({...u,value:t}))},[]),et=a.useCallback(()=>{Re({featureId:null,field:null,value:""})},[]),_t=a.useCallback(async t=>{if(ae.featureId)try{await ge(ae.featureId,t,{onError:u=>n(u.message,"error")}),et()}catch{}},[ae.featureId,ge,et,n]),wt=a.useCallback(async t=>{if(await v({title:"Delete Feature",message:"Delete this feature?",danger:!0}))try{await he(t,{onError:b=>n(b.message,"error")}),n("Feature deleted","success")}catch{}},[he,n,v]),nt=a.useCallback(async()=>{if(I.trim())try{await be(I,5,{onError:t=>n(t.message,"error")})}catch{}},[I,be,n]),it=a.useCallback(async t=>{try{await ie(t,{onError:u=>n(u.message,"error")}),n("Milestone added","success")}catch{}},[ie,n]),ot=a.useCallback(async()=>{try{await ee({onError:t=>n(t.message,"error")}),n(`${O.length} milestones added`,"success"),te("")}catch{}},[ee,O.length,n]),lt=a.useCallback(()=>{Y(),te("")},[Y]),jt=a.useCallback(async t=>{try{await xe(t,{count:5},{onError:u=>n(u.message,"error")})}catch{}},[xe,n]),Ct=a.useCallback(async(t,u)=>{try{await le(t,u,{onError:b=>n(b.message,"error")}),n("Feature added","success")}catch{}},[le,n]),Nt=a.useCallback((t,u,b)=>{M(t,u,b)},[M]),yt=a.useCallback(async t=>{const u=ve[t]||[];try{await _e(t,{onError:b=>n(b.message,"error")}),n(`${u.length} features added`,"success")}catch{}},[_e,ve,n]),St=a.useCallback(t=>{x(t)},[x]),Et=a.useCallback(async(t,u)=>{try{await Te(t,u,{onError:b=>n(b.message,"error")}),K({type:null,parentId:void 0,title:"",description:""}),n("Feature created","success")}catch{}},[Te,n]),Se=w;return D&&C.length===0?e.jsx("div",{className:"roadmaps-view roadmaps-view--loading",children:e.jsx("div",{className:"roadmaps-view__loading-state",children:"Loading roadmaps..."})}):j&&C.length===0?e.jsx("div",{className:"roadmaps-view roadmaps-view--error",children:e.jsxs("div",{className:"roadmaps-view__error-state",children:[e.jsx("p",{children:"Failed to load roadmaps"}),e.jsx("p",{className:"roadmaps-view__error-msg",children:j.message})]})}):e.jsxs("div",{className:"roadmaps-view",children:[f&&!Se&&e.jsx(aa,{roadmaps:C,selectedRoadmapId:Se,onSelect:t=>L(t),onCreate:()=>Be(!0),onEdit:_,onDelete:se,onExport:t=>Ue(t.id,t.title),showCreateForm:Je,onCancelCreate:()=>Be(!1),onSaveCreate:async t=>{await We(t),Be(!1)}}),!f&&e.jsxs("aside",{className:"roadmaps-view__sidebar","aria-label":"Roadmaps",children:[e.jsxs("div",{className:"roadmaps-view__sidebar-header",children:[e.jsx("h2",{className:"roadmaps-view__sidebar-title",children:"Roadmaps"}),e.jsx("button",{className:"roadmaps-view__add-btn",onClick:()=>K({type:"roadmap",title:"",description:""}),title:"Create roadmap","aria-label":"Create roadmap","data-testid":"create-roadmap-btn",children:e.jsx(ze,{size:16})})]}),U.type==="roadmap"&&e.jsx(mt,{onSave:We,onCancel:()=>K({type:null,parentId:void 0,title:"",description:""})}),e.jsx("div",{className:"roadmaps-view__sidebar-list",children:C.length===0?e.jsx("p",{className:"roadmaps-view__empty-sidebar",children:"No roadmaps yet. Click + to create one."}):C.map(t=>e.jsx(ta,{roadmap:t,isSelected:t.id===Se,onSelect:()=>L(t.id),onEdit:()=>_(t),onDelete:()=>se(t.id),onExport:()=>Ue(t.id,t.title)},t.id))})]}),e.jsxs("main",{className:"roadmaps-view__main","aria-label":"Roadmap content",children:[f&&Se&&e.jsx(sa,{roadmapTitle:y?.title||"Untitled Roadmap",onBack:()=>L(null),onEdit:()=>{y&&_(y)},onDelete:()=>se(Se),onCreate:()=>Be(!0)}),Se?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"roadmaps-view__roadmap-header",children:E.roadmapId===Se?e.jsx("div",{className:"roadmaps-view__inline-edit",children:e.jsxs("div",{className:"roadmaps-view__inline-edit-row",children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input roadmaps-view__inline-input--large",value:E.value,onChange:t=>ce(u=>({...u,value:t.target.value})),onKeyDown:t=>{t.key==="Enter"?ye({title:E.value}):t.key==="Escape"&&H()},placeholder:"Roadmap title",autoFocus:!0,"data-testid":"roadmap-title-input"}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",onClick:()=>ye({title:E.value}),"aria-label":"Save",title:"Save",children:e.jsx(me,{size:16})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:H,"aria-label":"Cancel",title:"Cancel",children:e.jsx(re,{size:16})})]})}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"roadmaps-view__roadmap-title-row",children:[e.jsx("h1",{className:"roadmaps-view__roadmap-title",children:y?.title||"Untitled Roadmap"}),e.jsxs("div",{className:"roadmaps-view__roadmap-actions",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:()=>{y&&_(y)},title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":"edit-roadmap-btn",children:e.jsx(Fe,{size:16})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:()=>se(Se),title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":"delete-roadmap-btn",children:e.jsx(Pe,{size:16})})]})]}),y?.description&&e.jsx("p",{className:"roadmaps-view__roadmap-desc",children:y.description})]})}),f?Ve?e.jsxs("div",{className:"roadmap-suggestion-section",children:[e.jsxs("div",{className:"roadmap-suggestion-header",children:[e.jsx("h3",{className:"roadmap-suggestion-title",children:"Generate Milestone Ideas"}),e.jsx("button",{className:"roadmap-suggestion-collapse-btn",onClick:()=>De(!1),"aria-label":"Collapse suggestion panel","data-testid":"collapse-suggestion-panel-btn",children:e.jsx(qt,{size:16})})]}),e.jsxs("div",{className:"roadmap-suggestion-form",children:[e.jsx("textarea",{className:"roadmap-suggestion-input",value:I,onChange:t=>te(t.target.value),placeholder:"Describe your roadmap goal (e.g., 'Build a user authentication system with OAuth, profiles, and admin dashboard')",rows:2,disabled:G||!w,"data-testid":"goal-prompt-input",autoFocus:!0}),e.jsxs("div",{className:"roadmap-suggestion-actions",children:[e.jsx("button",{className:"roadmap-suggestion-generate-btn",onClick:nt,disabled:!I.trim()||G||!w,"data-testid":"generate-suggestions-btn",children:G?"Generating...":"Generate Milestones"}),O.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"roadmap-suggestion-accept-all-btn",onClick:ot,"data-testid":"accept-all-suggestions-btn",children:["Accept All (",O.length,")"]}),e.jsx("button",{className:"roadmap-suggestion-clear-btn",onClick:lt,title:"Clear suggestions","aria-label":"Clear suggestions","data-testid":"clear-suggestions-btn",children:e.jsx(re,{size:14})})]})]})]}),O.length>0&&e.jsx("div",{className:"roadmap-suggestion-list",children:O.map(t=>e.jsx(ct,{suggestion:t,onUpdateDraft:u=>P(t.id,u),onAccept:()=>it(t.id),testIdPrefix:"suggestion"},t.id))})]}):e.jsx("div",{className:"roadmap-suggestion-section",children:e.jsxs("button",{className:"roadmap-suggestion-expand-btn",onClick:()=>De(!0),disabled:!w,"data-testid":"expand-suggestion-panel-btn",children:[e.jsx(ut,{size:16}),"Generate Milestone Ideas"]})}):e.jsxs("div",{className:"roadmap-suggestion-section",children:[e.jsx("div",{className:"roadmap-suggestion-header",children:e.jsx("h3",{className:"roadmap-suggestion-title",children:"Generate Milestone Ideas"})}),e.jsxs("div",{className:"roadmap-suggestion-form",children:[e.jsx("textarea",{className:"roadmap-suggestion-input",value:I,onChange:t=>te(t.target.value),placeholder:"Describe your roadmap goal (e.g., 'Build a user authentication system with OAuth, profiles, and admin dashboard')",rows:2,disabled:G||!w,"data-testid":"goal-prompt-input"}),e.jsxs("div",{className:"roadmap-suggestion-actions",children:[e.jsx("button",{className:"roadmap-suggestion-generate-btn",onClick:nt,disabled:!I.trim()||G||!w,"data-testid":"generate-suggestions-btn",children:G?"Generating...":"Generate Milestones"}),O.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"roadmap-suggestion-accept-all-btn",onClick:ot,"data-testid":"accept-all-suggestions-btn",children:["Accept All (",O.length,")"]}),e.jsx("button",{className:"roadmap-suggestion-clear-btn",onClick:lt,title:"Clear suggestions","aria-label":"Clear suggestions","data-testid":"clear-suggestions-btn",children:e.jsx(re,{size:14})})]})]})]}),O.length>0&&e.jsx("div",{className:"roadmap-suggestion-list",children:O.map(t=>e.jsx(ct,{suggestion:t,onUpdateDraft:u=>P(t.id,u),onAccept:()=>it(t.id),testIdPrefix:"suggestion"},t.id))})]}),e.jsxs("div",{className:"roadmaps-view__milestone-lanes",children:[U.type==="milestone"&&e.jsx(ia,{onSave:vt,onCancel:()=>K({type:null,parentId:void 0,title:"",description:""})}),g.length===0&&U.type!=="milestone"?e.jsxs("div",{className:"roadmaps-view__empty-milestones",children:[e.jsx("p",{children:"This roadmap has no milestones."}),e.jsxs("button",{className:"roadmaps-view__add-milestone-btn",onClick:()=>K({type:"milestone",title:"",description:""}),"data-testid":"add-milestone-btn-empty",children:[e.jsx(ze,{size:14}),e.jsx("span",{children:"Add Milestone"})]})]}):e.jsxs(e.Fragment,{children:[U.type!=="milestone"&&e.jsxs("button",{className:"roadmaps-view__add-milestone-fab",onClick:()=>K({type:"milestone",title:"",description:""}),"data-testid":"add-milestone-btn",children:[e.jsx(ze,{size:14}),e.jsx("span",{children:"Add Milestone"})]}),g.map(t=>e.jsx(ra,{milestone:t,features:k[t.id]||[],onEditMilestone:()=>pt(t),onDeleteMilestone:()=>bt(t.id),onAddFeature:()=>K({type:"feature",parentId:t.id,title:"",description:""}),onEditFeature:u=>{const b=k[t.id]?.find(z=>z.id===u);b&&rt(u,b.title,b.description)},onDeleteFeature:wt,milestoneEdit:Q,onMilestoneEditChange:gt,onMilestoneEditFieldChange:ht,onCancelMilestoneEdit:Ze,onSaveMilestoneEdit:ft,featureEdit:ae,onFeatureEditChange:xt,onStartFeatureEdit:rt,onCancelFeatureEdit:et,onSaveFeatureEdit:_t,projectId:l,addToast:n,isMilestoneDragging:Ce.draggingId===t.id,isMilestoneDropTarget:Ce.dropTargetId===t.id,milestoneDropPosition:Ce.dropTargetId===t.id?Ce.dropPosition:null,onMilestoneDragStart:Ye,onMilestoneDragEnd:Ne,onMilestoneDragOver:Xe,onMilestoneDrop:h,onMilestoneDragLeave:m,isFeatureDragging:o,isFeatureDropTarget:ue.dropTargetMilestoneId===t.id,featureDropIndex:ue.dropTargetMilestoneId===t.id?ue.dropTargetIndex:null,onFeatureDragStart:Qe,onFeatureDragEnd:s,onFeatureDragOver:d,onFeatureDrop:r,onFeatureDragLeave:c,onFeatureDropOnMilestone:i,featureSuggestions:ve[t.id],isGeneratingFeatureSuggestions:oe(t.id),onGenerateFeatureSuggestions:()=>jt(t.id),onAcceptFeatureSuggestion:u=>Ct(t.id,u),onAcceptAllFeatureSuggestions:()=>yt(t.id),onUpdateFeatureSuggestionDraft:(u,b,z)=>Nt(u,b,z),onClearFeatureSuggestions:()=>St(t.id)},t.id))]})]})]}):e.jsx("div",{className:"roadmaps-view__empty-main",children:e.jsx("p",{children:"Select a roadmap from the sidebar to view its milestones."})})]}),U.type==="feature"&&U.parentId&&e.jsx("div",{className:"roadmaps-view__feature-create-overlay",children:e.jsx(oa,{onSave:t=>Et(U.parentId,t),onCancel:()=>K({type:null,parentId:void 0,title:"",description:""})})}),e.jsx(ea,{isOpen:N,onClose:F,roadmapId:je||"",roadmapTitle:Le,handoffPayload:de,isLoading:we,error:R,onFetchHandoff:W,onCopyToClipboard:Ke})]})}export{ma as RoadmapsView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.roadmaps-view{display:flex;height:100%;overflow:hidden}.roadmaps-view--loading,.roadmaps-view--error{display:flex;align-items:center;justify-content:center}.roadmaps-view__loading-state,.roadmaps-view__error-state{text-align:center;color:var(--text-muted)}.roadmaps-view__error-msg{font-size:.85rem;margin-top:4px}.roadmaps-view__handoff-intro,.roadmaps-view__handoff-error,.roadmaps-view__handoff-section{margin-bottom:var(--space-lg)}.roadmaps-view__handoff-empty-state,.roadmaps-view__handoff-loading-state{text-align:center;padding:var(--space-xl)}.roadmaps-view__handoff-button-icon{margin-right:var(--space-sm)}.roadmaps-view__handoff-loading-text{margin-top:var(--space-md)}.roadmaps-view__handoff-section-title{margin-bottom:var(--space-sm)}.roadmaps-view__handoff-card{padding:var(--space-md)}.roadmaps-view__handoff-pre{white-space:pre-wrap;font-size:.75rem;overflow:auto}.roadmaps-view__handoff-pre--mission{max-height:200px}.roadmaps-view__handoff-pre--features{max-height:300px}.roadmaps-view__handoff-copy-icon{margin-right:var(--space-xs)}.roadmaps-view__sidebar{width:280px;flex-shrink:0;display:flex;flex-direction:column;border-right:1px solid var(--border);background:var(--surface-elevated)}.roadmaps-view__sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-md) var(--space-lg);border-bottom:1px solid var(--border)}.roadmaps-view__sidebar-title{font-size:1rem;font-weight:600;color:var(--text-primary)}.roadmaps-view__add-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;border-radius:var(--radius-sm);background:var(--accent);color:var(--cta-text);cursor:pointer;transition:opacity var(--transition-fast)}.roadmaps-view__add-btn:hover{opacity:.85}.roadmaps-view__sidebar-list{flex:1;overflow-y:auto;padding:var(--space-sm)}.roadmaps-view__empty-sidebar{padding:var(--space-lg);text-align:center;color:var(--text-muted);font-size:.9rem}.roadmaps-view__sidebar-item{display:flex;align-items:flex-start;justify-content:space-between;padding:var(--space-sm) var(--space-md);border-radius:var(--radius-sm);cursor:pointer;transition:background var(--transition-fast);gap:var(--space-sm)}.roadmaps-view__sidebar-item:hover{background:var(--surface-hover)}.roadmaps-view__sidebar-item--active{background:var(--card-hover)}.roadmaps-view__sidebar-item-content{flex:1;min-width:0}.roadmaps-view__sidebar-item-title{font-weight:500;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.roadmaps-view__sidebar-item-desc{font-size:.8rem;color:var(--text-muted);margin-top:2px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.roadmaps-view__sidebar-item-actions{display:flex;gap:2px;opacity:0;transition:opacity var(--transition-fast)}.roadmaps-view__sidebar-item:hover .roadmaps-view__sidebar-item-actions{opacity:1}.roadmaps-view__icon-btn{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--text-muted);cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast)}.roadmaps-view__icon-btn:hover{background:var(--surface-hover, color-mix(in srgb, var(--text) 6%, transparent));color:var(--text)}.roadmaps-view__icon-btn--danger:hover{background:color-mix(in srgb,var(--color-error) 10%,transparent);color:var(--color-error)}.roadmaps-view__icon-btn--success:hover{background:color-mix(in srgb,var(--color-success) 10%,transparent);color:var(--color-success)}.roadmaps-view__icon-btn:disabled{opacity:.4;cursor:not-allowed}.roadmaps-view__main{flex:1;display:flex;flex-direction:column;min-width:0;overflow:hidden}.roadmaps-view__empty-main{display:flex;align-items:center;justify-content:center;flex:1;color:var(--text-muted)}.roadmaps-view__roadmap-header{padding:var(--space-lg);border-bottom:1px solid var(--border)}.roadmaps-view__roadmap-title-row{display:flex;align-items:center;gap:var(--space-md)}.roadmaps-view__roadmap-title{font-size:1.5rem;font-weight:600;color:var(--text-primary);flex:1}.roadmaps-view__roadmap-actions{display:flex;gap:var(--space-xs)}.roadmaps-view__roadmap-desc{margin-top:var(--space-sm);color:var(--text-muted);font-size:.95rem}.roadmaps-view__milestone-lanes{flex:1;display:flex;flex-direction:row;gap:var(--space-md);padding:var(--space-md);overflow-x:auto;overflow-y:hidden}.roadmaps-view__milestone{min-width:300px;width:320px;flex-shrink:0;display:flex;flex-direction:column;background:var(--surface-elevated);border:1px solid var(--border);border-radius:var(--radius-md);box-shadow:var(--shadow-sm);transition:opacity var(--transition-fast),border-color var(--transition-fast),box-shadow var(--transition-fast);cursor:grab}.roadmaps-view__milestone:active{cursor:grabbing}.roadmaps-view__milestone--dragging{opacity:.5}.roadmaps-view__milestone--drop-target{border-color:var(--accent)}.roadmaps-view__milestone--drop-before{border-top:3px solid var(--accent)}.roadmaps-view__milestone--drop-after{border-bottom:3px solid var(--accent)}.roadmaps-view__drag-handle{display:flex;align-items:center;justify-content:center;color:var(--text-muted);cursor:grab;padding:2px;border-radius:var(--radius-sm);transition:color var(--transition-fast),background var(--transition-fast)}.roadmaps-view__drag-handle:hover{color:var(--text-primary);background:var(--surface-hover)}.roadmaps-view__milestone-header{padding:var(--space-md);border-bottom:1px solid var(--border)}.roadmaps-view__milestone-title-row{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-sm)}.roadmaps-view__milestone-title{font-size:1rem;font-weight:600;color:var(--text-primary);flex:1}.roadmaps-view__milestone-actions{display:flex;gap:2px}.roadmaps-view__milestone-desc{margin-top:var(--space-xs);font-size:.85rem;color:var(--text-muted)}.roadmaps-view__milestone-actions-bar{padding:var(--space-sm) var(--space-md);border-bottom:1px solid var(--border)}.roadmaps-view__add-feature-btn{display:inline-flex;align-items:center;gap:var(--space-xs);padding:var(--space-xs) var(--space-sm);border:1px dashed var(--border);border-radius:var(--radius-sm);background:transparent;color:var(--text-muted);font-size:.8rem;cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast)}.roadmaps-view__add-feature-btn:hover{background:var(--surface-hover);color:var(--text-primary);border-color:var(--text-muted)}.roadmaps-view__suggest-btn{display:flex;align-items:center;gap:var(--space-xs);padding:var(--space-xs) var(--space-sm);background:var(--accent);color:var(--cta-text);border:1px solid var(--accent);border-radius:var(--radius-md);font-size:.75rem;cursor:pointer;transition:background var(--transition-fast),transform var(--transition-fast)}.roadmaps-view__suggest-btn:hover{background:color-mix(in srgb,var(--accent) 88%,var(--bg) 12%);border-color:color-mix(in srgb,var(--accent) 88%,var(--bg) 12%)}.roadmaps-view__suggest-btn:active{transform:scale(.97)}.roadmaps-view__suggest-btn:disabled{opacity:.5;cursor:not-allowed}.roadmaps-view__feature-list{flex:1;overflow-y:auto;padding:var(--space-sm);transition:background var(--transition-fast)}.roadmaps-view__feature-list--drop-target{background:color-mix(in srgb,var(--color-info) 5%,transparent)}.roadmaps-view__empty-features{padding:var(--space-md);text-align:center;color:var(--text-muted);font-size:.85rem}.roadmaps-view__feature-item{display:flex;align-items:flex-start;justify-content:space-between;padding:var(--space-sm);border-bottom:1px solid var(--border);gap:var(--space-sm);transition:opacity var(--transition-fast),border-color var(--transition-fast);cursor:grab}.roadmaps-view__feature-item:active{cursor:grabbing}.roadmaps-view__feature-item:last-child{border-bottom:none}.roadmaps-view__feature-item--dragging{opacity:.5}.roadmaps-view__feature-item--drop-before{border-top:3px solid var(--accent)}.roadmaps-view__feature-item--drop-after{border-bottom:3px solid var(--accent)}.roadmaps-view__drag-handle--feature{flex-shrink:0}.roadmaps-view__feature-content{flex:1;min-width:0}.roadmaps-view__feature-title{font-weight:500;color:var(--text-primary);font-size:.9rem}.roadmaps-view__feature-desc{font-size:.8rem;color:var(--text-muted);margin-top:2px}.roadmaps-view__feature-actions{display:flex;gap:2px;opacity:0;transition:opacity var(--transition-fast)}.roadmaps-view__feature-item:hover .roadmaps-view__feature-actions{opacity:1}.roadmaps-view__inline-edit{display:flex;flex-direction:column;gap:var(--space-sm)}.roadmaps-view__inline-edit-row{display:flex;align-items:center;gap:var(--space-xs)}.roadmaps-view__inline-input{flex:1;padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface-input);color:var(--text-primary);font-size:.9rem;font-family:inherit}.roadmaps-view__inline-input:focus{outline:none;border-color:var(--accent)}.roadmaps-view__inline-input--large{font-size:1.1rem;font-weight:600;padding:var(--space-sm) var(--space-md)}.roadmaps-view__inline-textarea{width:100%;padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface-input);color:var(--text-primary);font-size:.85rem;font-family:inherit;resize:vertical}.roadmaps-view__inline-textarea:focus{outline:none;border-color:var(--accent)}.roadmaps-view__create-form{padding:var(--space-md);border-bottom:1px solid var(--border);background:var(--surface-elevated)}.roadmaps-view__create-form-actions{display:flex;gap:var(--space-sm);margin-top:var(--space-sm)}.roadmaps-view__btn{padding:var(--space-sm) var(--space-md);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface-input);color:var(--text-primary);font-size:.85rem;cursor:pointer;transition:background var(--transition-fast)}.roadmaps-view__btn:hover{background:var(--surface-hover)}.roadmaps-view__btn--primary{background:var(--accent);border-color:var(--accent);color:var(--cta-text)}.roadmaps-view__btn--primary:hover{opacity:.9}.roadmaps-view__btn:disabled{opacity:.5;cursor:not-allowed}.roadmaps-view__empty-milestones{display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1;gap:var(--space-md);color:var(--text-muted);padding:var(--space-xl)}.roadmaps-view__add-milestone-btn,.roadmaps-view__add-milestone-fab{display:inline-flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) var(--space-lg);border:1px dashed var(--border);border-radius:var(--radius-sm);background:transparent;color:var(--text-muted);font-size:.9rem;cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast)}.roadmaps-view__add-milestone-fab{align-self:flex-start;min-width:150px}.roadmaps-view__add-milestone-btn:hover,.roadmaps-view__add-milestone-fab:hover{background:var(--surface-hover);color:var(--text-primary);border-color:var(--text-muted)}.roadmaps-view__create-form--inline{border:1px dashed var(--border);border-radius:var(--radius-sm);margin:var(--space-sm);background:var(--surface-elevated)}.roadmaps-view__inline-form{display:flex;flex-direction:column;gap:var(--space-xs)}.roadmaps-view__inline-form-actions{display:flex;justify-content:flex-end;gap:var(--space-xs)}.roadmaps-view__feature-create-overlay{position:fixed;bottom:var(--space-lg);left:50%;transform:translate(-50%);z-index:100}.roadmaps-view__inline-edit--compact .roadmaps-view__inline-input{padding:var(--space-xs) var(--space-sm);font-size:.85rem}.roadmap-suggestion-section{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-lg);margin-bottom:var(--space-lg)}.roadmap-suggestion-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--space-md)}.roadmap-suggestion-title{font-size:1rem;font-weight:600;color:var(--text-primary);margin:0}.roadmap-suggestion-form{display:flex;flex-direction:column;gap:var(--space-sm)}.roadmap-suggestion-input{width:100%;padding:var(--space-sm) var(--space-md);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface-input);color:var(--text-primary);font-size:.9rem;font-family:inherit;resize:vertical;min-height:60px;transition:border-color var(--transition-fast)}.roadmap-suggestion-input:focus{outline:none;border-color:var(--accent);box-shadow:var(--focus-ring)}.roadmap-suggestion-input:disabled{opacity:.6;cursor:not-allowed}.roadmap-suggestion-input::placeholder{color:var(--text-muted)}.roadmap-suggestion-actions{display:flex;gap:var(--space-sm);align-items:center}.roadmap-suggestion-generate-btn{padding:var(--space-sm) var(--space-lg);background:var(--accent);color:var(--cta-text);border:none;border-radius:var(--radius-sm);font-size:.9rem;font-weight:500;cursor:pointer;transition:opacity var(--transition-fast),transform var(--transition-instant)}.roadmap-suggestion-generate-btn:hover:not(:disabled){opacity:.9}.roadmap-suggestion-generate-btn:active:not(:disabled){transform:scale(.98)}.roadmap-suggestion-generate-btn:disabled{opacity:.5;cursor:not-allowed}.roadmap-suggestion-accept-all-btn{padding:var(--space-sm) var(--space-md);background:var(--color-success);color:var(--cta-text);border:none;border-radius:var(--radius-sm);font-size:.85rem;font-weight:500;cursor:pointer;transition:opacity var(--transition-fast),transform var(--transition-instant)}.roadmap-suggestion-accept-all-btn:hover{opacity:.9}.roadmap-suggestion-accept-all-btn:active{transform:scale(.98)}.roadmap-suggestion-clear-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;color:var(--text-muted);border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;transition:color var(--transition-fast),border-color var(--transition-fast)}.roadmap-suggestion-clear-btn:hover{color:var(--color-error);border-color:var(--color-error)}.roadmap-suggestion-list{display:flex;flex-direction:column;gap:var(--space-sm);margin-top:var(--space-md)}.roadmap-suggestion-card{display:flex;align-items:flex-start;justify-content:space-between;padding:var(--space-md);background:var(--surface-elevated);border:1px solid var(--border);border-radius:var(--radius-sm);transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.roadmap-suggestion-card:hover{border-color:var(--accent);box-shadow:var(--shadow-sm)}.roadmap-suggestion-card-content{display:flex;flex-direction:column;gap:var(--space-xs);flex:1;min-width:0}.roadmap-suggestion-card-title{font-size:.9rem;font-weight:500;color:var(--text-primary)}.roadmap-suggestion-card-desc{font-size:.85rem;color:var(--text-muted);line-height:1.4}.roadmap-suggestion-card-actions{display:flex;gap:var(--space-xs);flex-shrink:0}.roadmap-suggestion-accept-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:var(--color-success);color:var(--cta-text);border:none;border-radius:var(--radius-sm);cursor:pointer;transition:opacity var(--transition-fast),transform var(--transition-instant)}.roadmap-suggestion-accept-btn:hover{opacity:.9}.roadmap-suggestion-accept-btn:active{transform:scale(.95)}.roadmap-suggestion-accept-btn:disabled{opacity:.5;cursor:not-allowed}.roadmap-suggestion-edit-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:var(--surface-elevated);color:var(--text-muted);border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;transition:background-color var(--transition-fast),color var(--transition-fast)}.roadmap-suggestion-edit-btn:hover{background:var(--surface-hover);color:var(--text-primary)}.roadmap-suggestion-card--editing{background:var(--surface-elevated);border-color:var(--accent)}.roadmap-suggestion-edit-form{display:flex;flex-direction:column;gap:var(--space-sm);flex:1;min-width:0}.roadmap-suggestion-textarea{width:100%;padding:var(--space-sm);background:var(--bg);color:var(--text-primary);border:1px solid var(--border);border-radius:var(--radius-sm);font-size:.9rem;font-family:inherit;resize:vertical;transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.roadmap-suggestion-textarea:focus{outline:none;border-color:var(--accent);box-shadow:var(--focus-ring)}.roadmap-suggestion-textarea::placeholder{color:var(--text-dim)}.roadmap-suggestion-edit-actions{display:flex;gap:var(--space-xs)}.roadmap-suggestion-save-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:var(--color-success);color:var(--cta-text);border:none;border-radius:var(--radius-sm);cursor:pointer;transition:opacity var(--transition-fast)}.roadmap-suggestion-save-btn:hover:not(:disabled){opacity:.9}.roadmap-suggestion-save-btn:disabled{opacity:.5;cursor:not-allowed}.roadmap-suggestion-cancel-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:var(--surface-elevated);color:var(--text-muted);border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;transition:background-color var(--transition-fast),color var(--transition-fast)}.roadmap-suggestion-cancel-btn:hover{background:var(--surface-hover);color:var(--text-primary)}.roadmap-suggestion-expand-btn{width:100%;display:flex;align-items:center;justify-content:center;gap:var(--space-sm);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-md) var(--space-lg);color:var(--text-primary);cursor:pointer;font-size:.9rem;font-weight:600;transition:background var(--transition-fast),color var(--transition-fast)}.roadmap-suggestion-expand-btn:hover:not(:disabled){background:var(--card-hover)}.roadmap-suggestion-expand-btn:active:not(:disabled){transform:scale(.98)}.roadmap-suggestion-expand-btn:disabled{opacity:.5;cursor:not-allowed}.roadmap-suggestion-collapse-btn{display:flex;align-items:center;justify-content:center;background:none;border:none;color:var(--text-muted);cursor:pointer;padding:var(--space-xs);border-radius:var(--radius-sm);transition:color var(--transition-fast)}.roadmap-suggestion-collapse-btn:hover{color:var(--text-primary)}@media(max-width:768px){.roadmaps-view{overflow-y:auto;-webkit-overflow-scrolling:touch}.roadmaps-view__sidebar{display:none}.roadmaps-view__main{overflow-y:auto;-webkit-overflow-scrolling:touch;flex:1;padding-bottom:calc(var(--mobile-nav-height) + env(safe-area-inset-bottom,0px))}.roadmaps-view__mobile-list{display:flex;flex-direction:column;width:100%;height:100%;background:var(--surface)}.roadmaps-view__mobile-list-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-md) var(--space-lg);border-bottom:1px solid var(--border);flex-shrink:0}.roadmaps-view__mobile-list-title{margin:0;font-size:1rem;font-weight:600;color:var(--text)}.roadmaps-view__mobile-add-btn{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;border-radius:var(--radius-md);background:var(--accent);color:var(--cta-text);cursor:pointer;transition:opacity var(--transition-fast)}.roadmaps-view__mobile-add-btn:hover{opacity:.85}.roadmaps-view__mobile-add-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.roadmaps-view__mobile-create-form{padding:var(--space-md);border-bottom:1px solid var(--border);background:var(--bg)}.roadmaps-view__mobile-list-items{flex:1;overflow-y:auto}.roadmaps-view__mobile-item{display:flex;align-items:center;justify-content:space-between;padding:var(--space-md) var(--space-lg);border-bottom:1px solid var(--border);min-height:44px;cursor:pointer;transition:background var(--transition-fast)}.roadmaps-view__mobile-item:hover{background:var(--surface-hover)}.roadmaps-view__mobile-item--active{background:color-mix(in srgb,var(--accent) 10%,transparent);border-left:3px solid var(--accent)}.roadmaps-view__mobile-item-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.roadmaps-view__mobile-item-title{font-weight:500;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.roadmaps-view__mobile-item-desc{font-size:.8rem;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.roadmaps-view__mobile-item-actions{display:flex;gap:var(--space-xs);flex-shrink:0}.roadmaps-view__mobile-action-btn{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;border-radius:var(--radius-md);background:transparent;color:var(--text-muted);cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast)}.roadmaps-view__mobile-action-btn:hover{background:var(--surface-hover);color:var(--text)}.roadmaps-view__mobile-action-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.roadmaps-view__mobile-action-btn--danger:hover{background:color-mix(in srgb,var(--color-error) 10%,transparent);color:var(--color-error)}.roadmaps-view__mobile-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-md);padding:var(--space-2xl);color:var(--text-muted);text-align:center}.roadmaps-view__mobile-header{display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) var(--space-md);border-bottom:1px solid var(--border);background:var(--surface);flex-shrink:0;position:sticky;top:0;z-index:10}.roadmaps-view__mobile-back-btn{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;border-radius:var(--radius-md);background:transparent;color:var(--text-muted);cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast);flex-shrink:0}.roadmaps-view__mobile-back-btn:hover{background:var(--surface-hover);color:var(--text)}.roadmaps-view__mobile-back-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.roadmaps-view__mobile-header-title{flex:1;margin:0;font-size:1rem;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.roadmaps-view__mobile-header-actions{display:flex;gap:var(--space-xs);flex-shrink:0}.roadmaps-view__milestone-lanes{flex-direction:column;overflow-x:hidden;overflow-y:auto;padding-bottom:calc(var(--mobile-nav-height) + env(safe-area-inset-bottom,0px))}.roadmaps-view__milestone{width:100%;min-width:unset}.roadmap-suggestion-section{padding:var(--space-md);margin:var(--space-md)}.roadmap-suggestion-actions{flex-wrap:wrap}.roadmap-suggestion-generate-btn,.roadmap-suggestion-accept-all-btn{flex:1}.roadmap-suggestion-card{padding:var(--space-sm)}.roadmaps-view__roadmap-header{padding:var(--space-md) var(--space-lg)}.roadmaps-view__create-form{margin:var(--space-sm)}.roadmaps-view__icon-btn{width:36px;height:36px}.roadmaps-view__feature-create-overlay{bottom:calc(var(--mobile-nav-height) + env(safe-area-inset-bottom,0px) + var(--space-md))}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.settings-header-actions{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>.btn{height:26px;box-sizing:border-box}@media(max-width:768px){.settings-header-actions>.btn-icon{min-height:26px;min-width:26px}}.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:5px;padding:4px 10px}.settings-github-star-btn__count{display:inline-flex;align-items:center;padding:4px 9px;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:has(.settings-modal){padding-top:0;align-items:stretch;justify-content:stretch}.modal.settings-modal{width:100vw;min-width:0;max-width:100vw;height:100dvh;min-height:0;max-height:100dvh;margin:0;border:none;border-radius:0;resize:none}}.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)}}.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:10px 8px;gap:2px;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-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}@media(max-width:768px){.settings-research-source-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) var(--radius) 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) 0 var(--space-md);margin:0;color:var(--text);border-bottom:1px solid var(--border);margin-bottom:var(--space-xs)}.settings-section-heading--spaced{margin-top:var(--space-xl)}.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);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)}.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 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-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}.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;gap:var(--space-sm);padding-top:var(--space-md);border-top:var(--btn-border-width) solid var(--border);margin-top:var(--space-md)}.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)}.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-direction:column}.auth-panel-body{padding-inline:var(--space-md)}.auth-section-hint{padding:12px 16px;margin-bottom:12px;background:var(--bg-tertiary);border-radius:var(--radius);font-size:13px;color:var(--text-muted);border-left:3px solid var(--text-muted)}.auth-provider-group{margin-bottom:10px}.auth-group-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--text-muted);margin-bottom:4px;padding:0 4px}.auth-provider-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);margin-bottom:4px;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;align-items:center;justify-content:space-between;padding:8px 12px;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:4px;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:inline-flex;align-items:center;gap:var(--space-sm)}.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(--color-accent) 20%,transparent);color:var(--color-accent)}.settings-lane-badge--inherited{background-color:color-mix(in srgb,var(--color-text-muted) 15%,transparent);color:var(--text-muted)}.settings-description{font-size:13px;color:var(--text-secondary);padding-inline:var(--space-xl);margin-block:0 var(--space-md);line-height:1.5}.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:4px;border-left:none;border-bottom:2px solid transparent;border-radius:var(--radius) var(--radius) 0 0;padding:6px 12px;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:break-all}.settings-content input,.settings-content select,.settings-content textarea{font-size:16px}.settings-section-heading{padding:var(--space-lg) 0 var(--space-md);margin:0}.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 14px}.settings-scope-banner{padding:var(--space-sm) var(--space-lg)}.memory-editor-frame{min-height:45vh}.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:12px 14px;gap:var(--space-sm)}.auth-section-hint{margin:0 14px 12px;padding:10px 14px}.auth-provider-group{margin-bottom:12px}.auth-group-label{padding:0 14px}.auth-provider-card{margin:0 14px 8px}.auth-provider-header{flex-wrap:wrap;padding:10px 14px;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-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:12px 14px 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)}@media(max-width:768px){.auth-custom-provider-item{flex-direction:column;align-items:flex-start}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./vendor-react-K0fH_qHe.js";import{
|
|
1
|
+
import{r as e}from"./vendor-react-K0fH_qHe.js";import{dd as C}from"./index-BRaIPmpp.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};
|