@runfusion/fusion 0.36.0 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/bin.js +1599 -174
  2. package/dist/client/.vite/manifest.json +66 -66
  3. package/dist/client/assets/AgentDetailView-CquLtIia.js +18 -0
  4. package/dist/client/assets/{AgentPermissionPolicyEditor-BoD6come.js → AgentPermissionPolicyEditor-Dk-oEs1X.js} +1 -1
  5. package/dist/client/assets/AgentsView-BZVOpQ05.js +29 -0
  6. package/dist/client/assets/ChatView-CErtz86Y.js +6 -0
  7. package/dist/client/assets/{DevServerView-Dd613aZ5.js → DevServerView-BRA00XoT.js} +1 -1
  8. package/dist/client/assets/{DirectoryPicker-H-fUl2dF.js → DirectoryPicker-D496NTjZ.js} +1 -1
  9. package/dist/client/assets/{DocumentsView-Dshc9e5K.js → DocumentsView-DIRlgdeB.js} +1 -1
  10. package/dist/client/assets/{EvalsView-50W0K5h7.js → EvalsView-By5mtr80.js} +1 -1
  11. package/dist/client/assets/{ExperimentalAgentOnboardingModal-BXBljPFj.js → ExperimentalAgentOnboardingModal-Br57oNdX.js} +1 -1
  12. package/dist/client/assets/GoalsView-B65urz9k.css +1 -0
  13. package/dist/client/assets/GoalsView-COI14CWJ.js +1 -0
  14. package/dist/client/assets/{InsightsView-sVbGRKTl.js → InsightsView-Hm7vX2lr.js} +2 -2
  15. package/dist/client/assets/{MemoryView-006a_sB0.js → MemoryView-BLozyYur.js} +1 -1
  16. package/dist/client/assets/{NodesView-CiRPqgVx.js → NodesView-bXC6WoE2.js} +1 -1
  17. package/dist/client/assets/{PiExtensionsManager-Y1ETuTxf.js → PiExtensionsManager-DEiqcMkx.js} +2 -2
  18. package/dist/client/assets/{PluginManager-Df_KHiXn.js → PluginManager-l4224zxk.js} +1 -1
  19. package/dist/client/assets/{ResearchView-DU_QuS_-.js → ResearchView-CpsR1Q56.js} +1 -1
  20. package/dist/client/assets/{SecretsView-D61Jvysn.js → SecretsView-Bwme1zZI.js} +1 -1
  21. package/dist/client/assets/{SettingsModal-BarzmqNb.js → SettingsModal-32vUNWRe.js} +1 -1
  22. package/dist/client/assets/SettingsModal-D_uIvf6n.css +1 -0
  23. package/dist/client/assets/SettingsModal-DdrXxMPW.js +31 -0
  24. package/dist/client/assets/{SetupWizardModal-BF3iRNq9.js → SetupWizardModal-BFD9E0H_.js} +1 -1
  25. package/dist/client/assets/{SkillsView-tCKOFw3j.js → SkillsView-CZMLY7F_.js} +1 -1
  26. package/dist/client/assets/{StashRecoveryView-nGtypd10.js → StashRecoveryView-jgZeWbZo.js} +1 -1
  27. package/dist/client/assets/{TodoView-IyGPV6AO.js → TodoView-DXdnOymj.js} +2 -2
  28. package/dist/client/assets/{dashboard-view-DiA5-hnb.js → dashboard-view-H8SnaCPP.js} +2 -2
  29. package/dist/client/assets/{folder-open-Byqfi_N-.js → folder-open-Dh5_gv6L.js} +1 -1
  30. package/dist/client/assets/index-B9hAW3eU.css +1 -0
  31. package/dist/client/assets/index-w1dPHtmq.js +742 -0
  32. package/dist/client/assets/{upload-D6_BjqVi.js → upload-ntU2YHPl.js} +1 -1
  33. package/dist/client/assets/{users-CERYgInO.js → users-BWK61s9U.js} +1 -1
  34. package/dist/client/index.html +40 -3
  35. package/dist/client/version.json +1 -1
  36. package/dist/droid-cli/package.json +1 -1
  37. package/dist/extension.js +1449 -125
  38. package/dist/pi-claude-cli/package.json +1 -1
  39. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  40. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  41. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  42. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  43. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  44. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  45. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  46. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  47. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  48. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  49. package/package.json +1 -1
  50. package/skill/fusion/SKILL.md +1 -1
  51. package/skill/fusion/references/extension-tools.md +16 -0
  52. package/skill/fusion/references/fusion-capabilities.md +1 -0
  53. package/dist/client/assets/AgentDetailView-CGycokdR.js +0 -18
  54. package/dist/client/assets/AgentsView-B_afRRfc.js +0 -29
  55. package/dist/client/assets/ChatView-IjNrSZSf.js +0 -6
  56. package/dist/client/assets/GoalsView-Cg136Jcn.css +0 -1
  57. package/dist/client/assets/GoalsView-Dh508Z2s.js +0 -1
  58. package/dist/client/assets/SettingsModal-0gevFhXV.css +0 -1
  59. package/dist/client/assets/SettingsModal-Cpur3WpT.js +0 -31
  60. package/dist/client/assets/index-B9Ro_NwC.js +0 -742
  61. package/dist/client/assets/index-DVFBXjGT.css +0 -1
@@ -1 +1 @@
1
- import{r as o,j as e}from"./vendor-react-K0fH_qHe.js";import{cA as w,ba as L,cB as O,cC as _,cD as $,X as W,b as Y,C as k,L as G}from"./index-B9Ro_NwC.js";import{D as q}from"./DirectoryPicker-H-fUl2dF.js";import{s as C}from"./projectDetection-G3XuxD2X.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";import"./folder-open-Byqfi_N-.js";function ee({onProjectRegistered:m,onClose:p}){const f="https://github.com/runfusion/fusion/discussions",[z,y]=o.useState(!0),[s,n]=o.useState(()=>({step:w()?"manual":"auth",manualMode:"existing",manualPath:"",manualCloneUrl:"",manualName:"",manualIsolationMode:"in-process",manualNodeId:"",isRegistering:!1,error:null})),[j,M]=o.useState(!1),[i,c]=o.useState(""),[u,x]=o.useState(()=>w()),{nodes:g,loading:I}=L(),S=g.find(a=>a.type==="local")?.id,N=o.useCallback(()=>{y(!1),p?.()},[p]),P=o.useCallback(a=>{n(t=>{const d={manualPath:a};return a&&(!t.manualName||t.manualName===C(t.manualPath))&&(d.manualName=C(a)),{...t,...d}})},[]),A=o.useCallback(async()=>{const a=s.manualPath.trim(),t=s.manualName.trim(),d=s.manualCloneUrl.trim();if(!(!a||!t)&&!(s.manualMode==="clone"&&!d)){n(r=>({...r,isRegistering:!0,error:null}));try{const r={name:t,path:a,isolationMode:s.manualIsolationMode,nodeId:s.manualNodeId||void 0,cloneUrl:s.manualMode==="clone"?d:void 0},h=await O(r);m(h),n(B=>({...B,step:"complete",isRegistering:!1}))}catch(r){n(h=>({...h,isRegistering:!1,error:r instanceof Error?r.message:"Failed to register project"}))}}},[s.manualPath,s.manualName,s.manualCloneUrl,s.manualMode,s.manualIsolationMode,s.manualNodeId,m]),b=o.useCallback(()=>{const a=i.trim();a&&(_(a),x(a),c(""),n(t=>t.step==="auth"?{...t,step:"manual"}:t))},[i]),R=o.useCallback(()=>{$(),x(void 0),c("")},[]),F=o.useCallback(()=>{n(a=>({...a,step:"manual"}))},[]);if(!z)return null;const v=s.manualMode==="existing",l=s.manualMode==="clone",T=s.manualPath.trim().length>0,U=s.manualName.trim().length>0,D=s.manualCloneUrl.trim().length>0,E=s.isRegistering||!T||!U||l&&!D;return e.jsx("div",{className:"modal-overlay open setup-wizard-overlay",role:"dialog","aria-modal":"true","aria-labelledby":"wizard-title",children:e.jsxs("div",{className:"modal setup-wizard-modal",children:[e.jsxs("div",{className:"setup-wizard-header",children:[e.jsxs("div",{className:"setup-wizard-heading",children:[e.jsxs("div",{className:"setup-wizard-brand","aria-label":"Fusion",children:[e.jsxs("svg",{className:"setup-wizard-brand-logo",width:28,height:28,viewBox:"0 0 128 128",fill:"none","aria-label":"Fusion logo",role:"img",children:[e.jsx("circle",{cx:"64",cy:"64",r:"52",stroke:"currentColor",strokeWidth:"8"}),e.jsx("path",{d:"M26 101C44 82 62 64 82 45C90 37 98 30 104 24C96 35 89 47 81 60C70 79 57 95 43 108C38 112 32 108 26 101Z",fill:"currentColor"})]}),e.jsx("span",{className:"setup-wizard-brand-name",children:"Fusion"})]}),e.jsxs("h2",{id:"wizard-title",className:"setup-wizard-title",children:[s.step==="auth"&&"Set Auth Token",s.step==="manual"&&"Welcome to Fusion",s.step==="complete"&&"Setup Complete!"]})]}),s.step!=="complete"&&e.jsx("button",{className:"modal-close",onClick:N,"aria-label":"Close wizard",children:e.jsx(W,{size:20})})]}),e.jsxs("div",{className:"setup-wizard-content",children:[s.step==="auth"&&e.jsxs("div",{className:"setup-wizard-auth-step",children:[e.jsx("p",{className:"setup-wizard-auth-step-description",children:"This dashboard requires an auth token to communicate with the Fusion daemon. Paste the token below to continue."}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"setup-auth-token",children:"Auth Token"}),e.jsx("input",{id:"setup-auth-token",type:"password",value:i,onChange:a=>c(a.target.value),placeholder:"Paste the daemon auth token",autoComplete:"off",spellCheck:!1,autoFocus:!0}),e.jsxs("p",{className:"form-hint",children:["The token was set via the ",e.jsx("code",{children:"FUSION_DAEMON_TOKEN"})," environment variable when starting the dashboard."]})]}),s.error&&e.jsx("div",{className:"wizard-error",role:"alert",children:s.error})]}),s.step==="manual"&&e.jsxs("div",{className:"setup-wizard-manual",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-name",children:"Project Name"}),e.jsx("input",{id:"project-name",type:"text",value:s.manualName,onChange:a=>n(t=>({...t,manualName:a.target.value})),placeholder:"my-project"}),e.jsx("p",{className:"form-hint",children:l?"By default this follows the destination folder name unless you edit it.":"By default this follows the selected directory name unless you edit it."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-path",children:l?"Destination Directory":"Project Directory"}),e.jsx(q,{value:s.manualPath,onChange:P,nodeId:s.manualNodeId||void 0,localNodeId:S,placeholder:l?"/path/for/new-clone":"/path/to/your/project"}),e.jsx("p",{className:"form-hint",children:l?"Select or type an absolute destination path. Fusion will clone into this directory.":"Select or type the absolute path to your project"})]}),e.jsxs("div",{className:"setup-wizard-advanced",children:[e.jsxs("button",{type:"button",className:"setup-wizard-advanced-toggle","aria-expanded":j,onClick:()=>M(a=>!a),children:[e.jsx(Y,{size:16,className:"setup-wizard-advanced-chevron"}),e.jsx("span",{children:"Advanced settings"})]}),j&&e.jsxs("div",{className:"setup-wizard-advanced-panel",children:[e.jsxs("fieldset",{className:"setup-wizard-mode-switch","aria-label":"Project setup mode",children:[e.jsx("legend",{children:"Setup Mode"}),e.jsxs("label",{className:`setup-wizard-mode-option${v?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"setup-mode",value:"existing",checked:v,onChange:()=>n(a=>({...a,manualMode:"existing",error:null}))}),e.jsx("span",{children:"Use Existing Directory"})]}),e.jsxs("label",{className:`setup-wizard-mode-option${l?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"setup-mode",value:"clone",checked:l,onChange:()=>n(a=>({...a,manualMode:"clone",error:null}))}),e.jsx("span",{children:"Clone Git Repository"})]})]}),l&&e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-clone-url",children:"Repository URL"}),e.jsx("input",{id:"project-clone-url",type:"text",value:s.manualCloneUrl,onChange:a=>n(t=>({...t,manualCloneUrl:a.target.value})),placeholder:"https://github.com/owner/repo.git"}),e.jsx("p",{className:"form-hint",children:"Fusion will run git clone into the destination directory, then register that cloned folder."})]}),e.jsx("div",{className:"form-group",children:e.jsxs("div",{className:"project-node-selector",children:[e.jsx("span",{className:"project-node-selector__label",children:"Runtime Node"}),e.jsxs("select",{value:s.manualNodeId,onChange:a=>n(t=>({...t,manualNodeId:a.target.value})),disabled:I||s.isRegistering,children:[e.jsx("option",{value:"",children:"Local node"}),g.map(a=>e.jsxs("option",{value:a.id,children:[a.name," (",a.type,")"]},a.id))]})]})}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Isolation Mode"}),e.jsxs("div",{className:"setup-wizard-isolation-options",children:[e.jsxs("label",{className:`setup-wizard-isolation-option${s.manualIsolationMode==="in-process"?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"isolation-mode",value:"in-process",checked:s.manualIsolationMode==="in-process",onChange:()=>n(a=>({...a,manualIsolationMode:"in-process"}))}),e.jsxs("div",{className:"setup-wizard-isolation-option-content",children:[e.jsx("strong",{children:"In-Process"}),e.jsx("span",{children:"Lower overhead, shared memory. Best for most projects."}),e.jsx("span",{className:"wizard-option-recommended",children:"Recommended"})]})]}),e.jsxs("label",{className:`setup-wizard-isolation-option${s.manualIsolationMode==="child-process"?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"isolation-mode",value:"child-process",checked:s.manualIsolationMode==="child-process",onChange:()=>n(a=>({...a,manualIsolationMode:"child-process"}))}),e.jsxs("div",{className:"setup-wizard-isolation-option-content",children:[e.jsx("strong",{children:"Child-Process"}),e.jsx("span",{children:"Isolated execution with crash containment."})]})]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"advanced-auth-token",children:"Browser Auth Token"}),e.jsxs("div",{className:"setup-wizard-auth-token",children:[e.jsx("input",{id:"advanced-auth-token",type:"password",value:i,onChange:a=>c(a.target.value),placeholder:u?"Enter a new token to replace the stored one":"Paste the auth token for this browser",autoComplete:"off",spellCheck:!1}),e.jsxs("div",{className:"setup-wizard-auth-token-actions",children:[e.jsx("button",{type:"button",className:"btn",onClick:b,disabled:i.trim().length===0,children:u?"Update token":"Set token"}),u&&e.jsx("button",{type:"button",className:"btn",onClick:R,children:"Reset token"})]})]}),e.jsx("p",{className:"form-hint",children:u?"A token is already stored in this browser. You can update or reset it below.":"No token is stored. Use the auth prompt at the top of the wizard, or set one here."})]})]})]}),s.error&&e.jsx("div",{className:"wizard-error",role:"alert",children:s.error})]}),s.step==="complete"&&e.jsxs("div",{className:"setup-wizard-complete",children:[e.jsxs("div",{className:"setup-wizard-success-streak","aria-hidden":"true",children:[e.jsx("div",{className:"setup-wizard-success-streak-core"}),e.jsx("div",{className:"setup-wizard-success-streak-glow"})]}),e.jsx(k,{size:64,className:"success-icon"}),e.jsx("h3",{children:"All Set!"}),e.jsx("p",{children:"Your project has been registered successfully."}),e.jsx("p",{children:"You can add more projects anytime from the project overview."})]})]}),e.jsxs("div",{className:"setup-wizard-footer",children:[e.jsx("a",{className:"btn setup-wizard-help-link",href:f,target:"_blank",rel:"noreferrer",children:"Need help?"}),s.step==="auth"&&e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"btn",onClick:F,children:"Skip"}),e.jsx("button",{className:"btn btn-primary",onClick:b,disabled:i.trim().length===0,children:e.jsx("span",{children:"Set Token & Continue"})})]}),s.step==="manual"&&e.jsx("button",{className:"btn btn-primary",onClick:A,disabled:E,children:s.isRegistering?e.jsxs(e.Fragment,{children:[e.jsx(G,{size:16,className:"animate-spin"}),e.jsx("span",{children:"Registering..."})]}):e.jsx("span",{children:"Register Project"})}),s.step==="complete"&&e.jsxs("button",{className:"btn btn-primary",onClick:N,children:[e.jsx(k,{size:16}),e.jsx("span",{children:"Get Started"})]})]})]})})}export{ee as SetupWizardModal};
1
+ import{r as o,j as e}from"./vendor-react-K0fH_qHe.js";import{cB as w,bb as L,cC as O,cD as _,cE as $,X as W,b as Y,C as k,L as G}from"./index-w1dPHtmq.js";import{D as q}from"./DirectoryPicker-D496NTjZ.js";import{s as C}from"./projectDetection-G3XuxD2X.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";import"./folder-open-Dh5_gv6L.js";function ee({onProjectRegistered:m,onClose:p}){const f="https://github.com/runfusion/fusion/discussions",[z,y]=o.useState(!0),[s,n]=o.useState(()=>({step:w()?"manual":"auth",manualMode:"existing",manualPath:"",manualCloneUrl:"",manualName:"",manualIsolationMode:"in-process",manualNodeId:"",isRegistering:!1,error:null})),[j,M]=o.useState(!1),[i,c]=o.useState(""),[u,x]=o.useState(()=>w()),{nodes:g,loading:I}=L(),S=g.find(a=>a.type==="local")?.id,N=o.useCallback(()=>{y(!1),p?.()},[p]),P=o.useCallback(a=>{n(t=>{const d={manualPath:a};return a&&(!t.manualName||t.manualName===C(t.manualPath))&&(d.manualName=C(a)),{...t,...d}})},[]),R=o.useCallback(async()=>{const a=s.manualPath.trim(),t=s.manualName.trim(),d=s.manualCloneUrl.trim();if(!(!a||!t)&&!(s.manualMode==="clone"&&!d)){n(r=>({...r,isRegistering:!0,error:null}));try{const r={name:t,path:a,isolationMode:s.manualIsolationMode,nodeId:s.manualNodeId||void 0,cloneUrl:s.manualMode==="clone"?d:void 0},h=await O(r);m(h),n(B=>({...B,step:"complete",isRegistering:!1}))}catch(r){n(h=>({...h,isRegistering:!1,error:r instanceof Error?r.message:"Failed to register project"}))}}},[s.manualPath,s.manualName,s.manualCloneUrl,s.manualMode,s.manualIsolationMode,s.manualNodeId,m]),b=o.useCallback(()=>{const a=i.trim();a&&(_(a),x(a),c(""),n(t=>t.step==="auth"?{...t,step:"manual"}:t))},[i]),A=o.useCallback(()=>{$(),x(void 0),c("")},[]),F=o.useCallback(()=>{n(a=>({...a,step:"manual"}))},[]);if(!z)return null;const v=s.manualMode==="existing",l=s.manualMode==="clone",T=s.manualPath.trim().length>0,U=s.manualName.trim().length>0,D=s.manualCloneUrl.trim().length>0,E=s.isRegistering||!T||!U||l&&!D;return e.jsx("div",{className:"modal-overlay open setup-wizard-overlay",role:"dialog","aria-modal":"true","aria-labelledby":"wizard-title",children:e.jsxs("div",{className:"modal setup-wizard-modal",children:[e.jsxs("div",{className:"setup-wizard-header",children:[e.jsxs("div",{className:"setup-wizard-heading",children:[e.jsxs("div",{className:"setup-wizard-brand","aria-label":"Fusion",children:[e.jsxs("svg",{className:"setup-wizard-brand-logo",width:28,height:28,viewBox:"0 0 128 128",fill:"none","aria-label":"Fusion logo",role:"img",children:[e.jsx("circle",{cx:"64",cy:"64",r:"52",stroke:"currentColor",strokeWidth:"8"}),e.jsx("path",{d:"M26 101C44 82 62 64 82 45C90 37 98 30 104 24C96 35 89 47 81 60C70 79 57 95 43 108C38 112 32 108 26 101Z",fill:"currentColor"})]}),e.jsx("span",{className:"setup-wizard-brand-name",children:"Fusion"})]}),e.jsxs("h2",{id:"wizard-title",className:"setup-wizard-title",children:[s.step==="auth"&&"Set Auth Token",s.step==="manual"&&"Welcome to Fusion",s.step==="complete"&&"Setup Complete!"]})]}),s.step!=="complete"&&e.jsx("button",{className:"modal-close",onClick:N,"aria-label":"Close wizard",children:e.jsx(W,{size:20})})]}),e.jsxs("div",{className:"setup-wizard-content",children:[s.step==="auth"&&e.jsxs("div",{className:"setup-wizard-auth-step",children:[e.jsx("p",{className:"setup-wizard-auth-step-description",children:"This dashboard requires an auth token to communicate with the Fusion daemon. Paste the token below to continue."}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"setup-auth-token",children:"Auth Token"}),e.jsx("input",{id:"setup-auth-token",type:"password",value:i,onChange:a=>c(a.target.value),placeholder:"Paste the daemon auth token",autoComplete:"off",spellCheck:!1,autoFocus:!0}),e.jsxs("p",{className:"form-hint",children:["The token was set via the ",e.jsx("code",{children:"FUSION_DAEMON_TOKEN"})," environment variable when starting the dashboard."]})]}),s.error&&e.jsx("div",{className:"wizard-error",role:"alert",children:s.error})]}),s.step==="manual"&&e.jsxs("div",{className:"setup-wizard-manual",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-name",children:"Project Name"}),e.jsx("input",{id:"project-name",type:"text",value:s.manualName,onChange:a=>n(t=>({...t,manualName:a.target.value})),placeholder:"my-project"}),e.jsx("p",{className:"form-hint",children:l?"By default this follows the destination folder name unless you edit it.":"By default this follows the selected directory name unless you edit it."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-path",children:l?"Destination Directory":"Project Directory"}),e.jsx(q,{value:s.manualPath,onChange:P,nodeId:s.manualNodeId||void 0,localNodeId:S,placeholder:l?"/path/for/new-clone":"/path/to/your/project"}),e.jsx("p",{className:"form-hint",children:l?"Select or type an absolute destination path. Fusion will clone into this directory.":"Select or type the absolute path to your project"})]}),e.jsxs("div",{className:"setup-wizard-advanced",children:[e.jsxs("button",{type:"button",className:"setup-wizard-advanced-toggle","aria-expanded":j,onClick:()=>M(a=>!a),children:[e.jsx(Y,{size:16,className:"setup-wizard-advanced-chevron"}),e.jsx("span",{children:"Advanced settings"})]}),j&&e.jsxs("div",{className:"setup-wizard-advanced-panel",children:[e.jsxs("fieldset",{className:"setup-wizard-mode-switch","aria-label":"Project setup mode",children:[e.jsx("legend",{children:"Setup Mode"}),e.jsxs("label",{className:`setup-wizard-mode-option${v?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"setup-mode",value:"existing",checked:v,onChange:()=>n(a=>({...a,manualMode:"existing",error:null}))}),e.jsx("span",{children:"Use Existing Directory"})]}),e.jsxs("label",{className:`setup-wizard-mode-option${l?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"setup-mode",value:"clone",checked:l,onChange:()=>n(a=>({...a,manualMode:"clone",error:null}))}),e.jsx("span",{children:"Clone Git Repository"})]})]}),l&&e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-clone-url",children:"Repository URL"}),e.jsx("input",{id:"project-clone-url",type:"text",value:s.manualCloneUrl,onChange:a=>n(t=>({...t,manualCloneUrl:a.target.value})),placeholder:"https://github.com/owner/repo.git"}),e.jsx("p",{className:"form-hint",children:"Fusion will run git clone into the destination directory, then register that cloned folder."})]}),e.jsx("div",{className:"form-group",children:e.jsxs("div",{className:"project-node-selector",children:[e.jsx("span",{className:"project-node-selector__label",children:"Runtime Node"}),e.jsxs("select",{value:s.manualNodeId,onChange:a=>n(t=>({...t,manualNodeId:a.target.value})),disabled:I||s.isRegistering,children:[e.jsx("option",{value:"",children:"Local node"}),g.map(a=>e.jsxs("option",{value:a.id,children:[a.name," (",a.type,")"]},a.id))]})]})}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Isolation Mode"}),e.jsxs("div",{className:"setup-wizard-isolation-options",children:[e.jsxs("label",{className:`setup-wizard-isolation-option${s.manualIsolationMode==="in-process"?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"isolation-mode",value:"in-process",checked:s.manualIsolationMode==="in-process",onChange:()=>n(a=>({...a,manualIsolationMode:"in-process"}))}),e.jsxs("div",{className:"setup-wizard-isolation-option-content",children:[e.jsx("strong",{children:"In-Process"}),e.jsx("span",{children:"Lower overhead, shared memory. Best for most projects."}),e.jsx("span",{className:"wizard-option-recommended",children:"Recommended"})]})]}),e.jsxs("label",{className:`setup-wizard-isolation-option${s.manualIsolationMode==="child-process"?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"isolation-mode",value:"child-process",checked:s.manualIsolationMode==="child-process",onChange:()=>n(a=>({...a,manualIsolationMode:"child-process"}))}),e.jsxs("div",{className:"setup-wizard-isolation-option-content",children:[e.jsx("strong",{children:"Child-Process"}),e.jsx("span",{children:"Isolated execution with crash containment."})]})]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"advanced-auth-token",children:"Browser Auth Token"}),e.jsxs("div",{className:"setup-wizard-auth-token",children:[e.jsx("input",{id:"advanced-auth-token",type:"password",value:i,onChange:a=>c(a.target.value),placeholder:u?"Enter a new token to replace the stored one":"Paste the auth token for this browser",autoComplete:"off",spellCheck:!1}),e.jsxs("div",{className:"setup-wizard-auth-token-actions",children:[e.jsx("button",{type:"button",className:"btn",onClick:b,disabled:i.trim().length===0,children:u?"Update token":"Set token"}),u&&e.jsx("button",{type:"button",className:"btn",onClick:A,children:"Reset token"})]})]}),e.jsx("p",{className:"form-hint",children:u?"A token is already stored in this browser. You can update or reset it below.":"No token is stored. Use the auth prompt at the top of the wizard, or set one here."})]})]})]}),s.error&&e.jsx("div",{className:"wizard-error",role:"alert",children:s.error})]}),s.step==="complete"&&e.jsxs("div",{className:"setup-wizard-complete",children:[e.jsxs("div",{className:"setup-wizard-success-streak","aria-hidden":"true",children:[e.jsx("div",{className:"setup-wizard-success-streak-core"}),e.jsx("div",{className:"setup-wizard-success-streak-glow"})]}),e.jsx(k,{size:64,className:"success-icon"}),e.jsx("h3",{children:"All Set!"}),e.jsx("p",{children:"Your project has been registered successfully."}),e.jsx("p",{children:"You can add more projects anytime from the project overview."})]})]}),e.jsxs("div",{className:"setup-wizard-footer",children:[e.jsx("a",{className:"btn setup-wizard-help-link",href:f,target:"_blank",rel:"noreferrer",children:"Need help?"}),s.step==="auth"&&e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"btn",onClick:F,children:"Skip"}),e.jsx("button",{className:"btn btn-primary",onClick:b,disabled:i.trim().length===0,children:e.jsx("span",{children:"Set Token & Continue"})})]}),s.step==="manual"&&e.jsx("button",{className:"btn btn-primary",onClick:R,disabled:E,children:s.isRegistering?e.jsxs(e.Fragment,{children:[e.jsx(G,{size:16,className:"animate-spin"}),e.jsx("span",{children:"Registering..."})]}):e.jsx("span",{children:"Register Project"})}),s.step==="complete"&&e.jsxs("button",{className:"btn btn-primary",onClick:N,children:[e.jsx(k,{size:16}),e.jsx("span",{children:"Get Started"})]})]})]})})}export{ee as SetupWizardModal};
@@ -1 +1 @@
1
- import{r as i,j as e}from"./vendor-react-K0fH_qHe.js";import{bN as X,bO as _,bP as q,bQ as B,bL as G,X as P,R as H,a as J,b as Y,L as Z,ax as I}from"./index-B9Ro_NwC.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";function ae({projectId:c,addToast:o,onClose:Q}){const[d,v]=i.useState([]),[f,y]=i.useState(!0),[A,E]=i.useState(!1),[L,p]=i.useState(null),[D,K]=i.useState([]),[m,V]=i.useState(""),[h,g]=i.useState(null),[k,x]=i.useState(null),[W,R]=i.useState(!1),[z,b]=i.useState(null),r=i.useRef(null),[N,M]=i.useState(""),F=m.trim()?d.filter(s=>s.name.toLowerCase().includes(m.toLowerCase())||s.relativePath.toLowerCase().includes(m.toLowerCase())):d,C=i.useCallback(async()=>{y(!0);try{const s=await X(c);v(s)}catch(s){const a=s instanceof Error?s.message:"Failed to load discovered skills";o(a,"error")}finally{y(!1)}},[c,o]),u=i.useCallback(async s=>{const a=l=>{if(!l||typeof l!="object")return!1;const t=l;if(typeof t.status=="number"&&t.status>=500)return!0;if(t.details&&typeof t.details=="object"){const w=t.details;if(typeof w.code=="string"&&w.code.startsWith("upstream_"))return!0}const n=l;return typeof n.error=="string"&&typeof n.code=="string"};E(!0),p(null);try{const l=await _(s,20,c);K(l.entries)}catch(l){if(a(l))p("Catalog is temporarily unavailable. Please try again later.");else{const t=l instanceof Error?l.message:"Failed to load catalog";p(t)}}finally{E(!1)}},[c]);i.useEffect(()=>{C(),u("")},[C,u]);const O=i.useCallback(s=>{V(s),r.current&&clearTimeout(r.current),r.current=setTimeout(()=>{M(s),r.current=null},300)},[]);i.useEffect(()=>()=>{r.current&&(clearTimeout(r.current),r.current=null)},[]),i.useEffect(()=>{u(N)},[N,u]);const T=i.useCallback(async(s,a)=>{const l=!a;v(t=>t.map(n=>n.id===s?{...n,toggling:!0}:n));try{await q(s,l,c),v(t=>t.map(n=>n.id===s?{...n,enabled:l,toggling:!1}:n)),o(`Skill ${l?"enabled":"disabled"}`,"success")}catch(t){v(w=>w.map(S=>S.id===s?{...S,toggling:!1}:S));const n=t instanceof Error?t.message:"Failed to toggle skill";o(`Failed to toggle skill: ${n}`,"error")}},[c,o]),j=i.useCallback(async s=>{R(!0),b(null),x(null);try{const a=await B(s,c);x(a)}catch(a){const l=a instanceof Error?a.message:"Failed to load skill content";b(l)}finally{R(!1)}},[c]),$=i.useCallback((s,a)=>{if(!(a&&a.target.closest(".skills-view-item-toggle"))){if(h===s){g(null),x(null),b(null);return}g(s),j(s)}},[h,j]),U=i.useCallback(s=>{h!==s&&g(s),j(s)},[j,h]);return e.jsxs("div",{className:"skills-view","data-testid":"skills-view",children:[e.jsxs("div",{className:"skills-view-header",children:[e.jsxs("div",{className:"skills-view-title",children:[e.jsxs("h2",{children:[e.jsx(G,{size:20}),"Skills"]}),e.jsxs("span",{className:"skills-view-count","aria-label":`${d.length} discovered skills`,children:[d.length," discovered"]})]}),e.jsxs("div",{className:"skills-view-actions",children:[e.jsx("button",{className:"btn-icon skills-view-close touch-target",onClick:Q,"aria-label":"Close skills view",children:e.jsx(P,{size:16})}),e.jsxs("button",{className:"btn btn-sm touch-target",onClick:()=>void C(),disabled:f,children:[e.jsx(H,{size:14,className:f?"spin":""}),"Refresh"]})]})]}),e.jsxs("div",{className:"skills-view-content",children:[e.jsx("div",{className:"skills-view-search",children:e.jsx("input",{type:"text",className:"form-input",placeholder:"Search skills...",value:m,onChange:s=>O(s.target.value),"aria-label":"Search skills"})}),e.jsxs("section",{className:"skills-view-section","aria-labelledby":"discovered-skills-title",children:[e.jsx("h3",{id:"discovered-skills-title",className:"skills-view-section-title",children:"Discovered Skills"}),f?e.jsxs("div",{className:"skills-view-loading",children:[e.jsx("span",{className:"spinner"}),"Loading discovered skills..."]}):d.length===0?e.jsx("div",{className:"skills-view-empty",children:e.jsx("p",{children:"No skills discovered in this project."})}):F.length===0?e.jsx("div",{className:"skills-view-empty",children:e.jsx("p",{children:"No discovered skills match your search."})}):e.jsx("div",{className:"skills-view-list",children:F.map(s=>{const a=h===s.id;return e.jsxs("div",{children:[e.jsxs("div",{className:`skills-view-item${a?" skills-view-item--selected":""}`,onClick:l=>$(s.id,l),role:"button",tabIndex:0,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),$(s.id))},"aria-expanded":a,"aria-label":`View details for ${s.name}`,children:[e.jsxs("div",{className:"skills-view-item-info",children:[e.jsxs("span",{className:"skills-view-item-name",children:[a?e.jsx(J,{size:14}):e.jsx(Y,{size:14}),s.name]}),e.jsx("span",{className:"skills-view-item-path",children:s.relativePath}),e.jsx("span",{className:"skills-view-item-source",children:s.metadata.source})]}),e.jsxs("label",{className:"skills-view-item-toggle",onClick:l=>l.stopPropagation(),children:[e.jsx("input",{type:"checkbox",checked:s.enabled,disabled:s.toggling,onChange:()=>void T(s.id,s.enabled),"aria-label":`${s.enabled?"Disable":"Enable"} ${s.name}`}),e.jsx("span",{className:"skills-view-toggle-slider"})]})]}),a&&e.jsxs("div",{className:"skills-view-detail","data-testid":"skill-detail",children:[e.jsxs("div",{className:"skills-view-detail-header",children:[e.jsx("span",{className:"skills-view-detail-title",children:s.name}),e.jsxs("button",{className:"btn btn-sm skills-view-detail-close",onClick:()=>{g(null),x(null),b(null)},"aria-label":"Close skill detail",children:[e.jsx(P,{size:14}),"Close"]})]}),W?e.jsxs("div",{className:"skills-view-detail-loading",children:[e.jsx(Z,{size:16,className:"spin"}),"Loading skill content..."]}):z?e.jsxs("div",{className:"skills-view-detail-error",children:[e.jsx(I,{size:14}),e.jsx("span",{children:z}),e.jsx("button",{className:"btn btn-sm",onClick:()=>U(s.id),children:"Retry"})]}):k?e.jsxs(e.Fragment,{children:[e.jsx("pre",{className:"skills-view-detail-content",children:k.skillMd||"(No SKILL.md found)"}),k.files.length>0&&e.jsxs("div",{className:"skills-view-detail-files",children:[e.jsx("span",{className:"skills-view-detail-files-label",children:"Files:"}),k.files.map(l=>e.jsxs("span",{className:"badge badge--sm",children:[l.name,l.type==="directory"&&"/"]},l.relativePath))]})]}):null]})]},s.id)})})]}),e.jsxs("section",{className:"skills-view-section","aria-labelledby":"catalog-title",children:[e.jsx("h3",{id:"catalog-title",className:"skills-view-section-title",children:"Skills Catalog"}),L?e.jsxs("div",{className:"skills-view-error",children:[e.jsx("p",{children:L}),e.jsx("button",{className:"btn btn-sm",onClick:()=>void u(N),children:"Try Again"})]}):A?e.jsxs("div",{className:"skills-view-loading",children:[e.jsx("span",{className:"spinner"}),"Loading catalog..."]}):D.length===0?e.jsx("div",{className:"skills-view-empty",children:m?e.jsx("p",{children:"No skills match your search."}):e.jsx("p",{children:"No skills available in the catalog."})}):e.jsx("div",{className:"skills-view-grid",children:D.map(s=>e.jsxs("div",{className:"skills-view-card",children:[e.jsx("h4",{className:"skills-view-card-title",children:s.name}),s.description&&e.jsx("p",{className:"skills-view-card-description",children:s.description}),s.tags&&s.tags.length>0&&e.jsx("div",{className:"skills-view-card-tags",children:s.tags.map(a=>e.jsx("span",{className:"badge badge--sm",children:a},a))}),s.installs!==void 0&&e.jsxs("span",{className:"skills-view-card-installs",children:[s.installs.toLocaleString()," installs"]})]},s.id))})]})]})]})}export{ae as SkillsView};
1
+ import{r as i,j as e}from"./vendor-react-K0fH_qHe.js";import{bO as X,bP as _,bQ as q,bR as B,bM as G,X as P,R as H,a as J,b as Y,L as Z,ay as I}from"./index-w1dPHtmq.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";function ae({projectId:c,addToast:o,onClose:Q}){const[d,v]=i.useState([]),[f,y]=i.useState(!0),[A,E]=i.useState(!1),[L,p]=i.useState(null),[D,K]=i.useState([]),[m,M]=i.useState(""),[h,g]=i.useState(null),[k,x]=i.useState(null),[V,R]=i.useState(!1),[z,b]=i.useState(null),r=i.useRef(null),[N,W]=i.useState(""),F=m.trim()?d.filter(s=>s.name.toLowerCase().includes(m.toLowerCase())||s.relativePath.toLowerCase().includes(m.toLowerCase())):d,C=i.useCallback(async()=>{y(!0);try{const s=await X(c);v(s)}catch(s){const a=s instanceof Error?s.message:"Failed to load discovered skills";o(a,"error")}finally{y(!1)}},[c,o]),u=i.useCallback(async s=>{const a=l=>{if(!l||typeof l!="object")return!1;const t=l;if(typeof t.status=="number"&&t.status>=500)return!0;if(t.details&&typeof t.details=="object"){const w=t.details;if(typeof w.code=="string"&&w.code.startsWith("upstream_"))return!0}const n=l;return typeof n.error=="string"&&typeof n.code=="string"};E(!0),p(null);try{const l=await _(s,20,c);K(l.entries)}catch(l){if(a(l))p("Catalog is temporarily unavailable. Please try again later.");else{const t=l instanceof Error?l.message:"Failed to load catalog";p(t)}}finally{E(!1)}},[c]);i.useEffect(()=>{C(),u("")},[C,u]);const O=i.useCallback(s=>{M(s),r.current&&clearTimeout(r.current),r.current=setTimeout(()=>{W(s),r.current=null},300)},[]);i.useEffect(()=>()=>{r.current&&(clearTimeout(r.current),r.current=null)},[]),i.useEffect(()=>{u(N)},[N,u]);const T=i.useCallback(async(s,a)=>{const l=!a;v(t=>t.map(n=>n.id===s?{...n,toggling:!0}:n));try{await q(s,l,c),v(t=>t.map(n=>n.id===s?{...n,enabled:l,toggling:!1}:n)),o(`Skill ${l?"enabled":"disabled"}`,"success")}catch(t){v(w=>w.map(S=>S.id===s?{...S,toggling:!1}:S));const n=t instanceof Error?t.message:"Failed to toggle skill";o(`Failed to toggle skill: ${n}`,"error")}},[c,o]),j=i.useCallback(async s=>{R(!0),b(null),x(null);try{const a=await B(s,c);x(a)}catch(a){const l=a instanceof Error?a.message:"Failed to load skill content";b(l)}finally{R(!1)}},[c]),$=i.useCallback((s,a)=>{if(!(a&&a.target.closest(".skills-view-item-toggle"))){if(h===s){g(null),x(null),b(null);return}g(s),j(s)}},[h,j]),U=i.useCallback(s=>{h!==s&&g(s),j(s)},[j,h]);return e.jsxs("div",{className:"skills-view","data-testid":"skills-view",children:[e.jsxs("div",{className:"skills-view-header",children:[e.jsxs("div",{className:"skills-view-title",children:[e.jsxs("h2",{children:[e.jsx(G,{size:20}),"Skills"]}),e.jsxs("span",{className:"skills-view-count","aria-label":`${d.length} discovered skills`,children:[d.length," discovered"]})]}),e.jsxs("div",{className:"skills-view-actions",children:[e.jsx("button",{className:"btn-icon skills-view-close touch-target",onClick:Q,"aria-label":"Close skills view",children:e.jsx(P,{size:16})}),e.jsxs("button",{className:"btn btn-sm touch-target",onClick:()=>void C(),disabled:f,children:[e.jsx(H,{size:14,className:f?"spin":""}),"Refresh"]})]})]}),e.jsxs("div",{className:"skills-view-content",children:[e.jsx("div",{className:"skills-view-search",children:e.jsx("input",{type:"text",className:"form-input",placeholder:"Search skills...",value:m,onChange:s=>O(s.target.value),"aria-label":"Search skills"})}),e.jsxs("section",{className:"skills-view-section","aria-labelledby":"discovered-skills-title",children:[e.jsx("h3",{id:"discovered-skills-title",className:"skills-view-section-title",children:"Discovered Skills"}),f?e.jsxs("div",{className:"skills-view-loading",children:[e.jsx("span",{className:"spinner"}),"Loading discovered skills..."]}):d.length===0?e.jsx("div",{className:"skills-view-empty",children:e.jsx("p",{children:"No skills discovered in this project."})}):F.length===0?e.jsx("div",{className:"skills-view-empty",children:e.jsx("p",{children:"No discovered skills match your search."})}):e.jsx("div",{className:"skills-view-list",children:F.map(s=>{const a=h===s.id;return e.jsxs("div",{children:[e.jsxs("div",{className:`skills-view-item${a?" skills-view-item--selected":""}`,onClick:l=>$(s.id,l),role:"button",tabIndex:0,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),$(s.id))},"aria-expanded":a,"aria-label":`View details for ${s.name}`,children:[e.jsxs("div",{className:"skills-view-item-info",children:[e.jsxs("span",{className:"skills-view-item-name",children:[a?e.jsx(J,{size:14}):e.jsx(Y,{size:14}),s.name]}),e.jsx("span",{className:"skills-view-item-path",children:s.relativePath}),e.jsx("span",{className:"skills-view-item-source",children:s.metadata.source})]}),e.jsxs("label",{className:"skills-view-item-toggle",onClick:l=>l.stopPropagation(),children:[e.jsx("input",{type:"checkbox",checked:s.enabled,disabled:s.toggling,onChange:()=>void T(s.id,s.enabled),"aria-label":`${s.enabled?"Disable":"Enable"} ${s.name}`}),e.jsx("span",{className:"skills-view-toggle-slider"})]})]}),a&&e.jsxs("div",{className:"skills-view-detail","data-testid":"skill-detail",children:[e.jsxs("div",{className:"skills-view-detail-header",children:[e.jsx("span",{className:"skills-view-detail-title",children:s.name}),e.jsxs("button",{className:"btn btn-sm skills-view-detail-close",onClick:()=>{g(null),x(null),b(null)},"aria-label":"Close skill detail",children:[e.jsx(P,{size:14}),"Close"]})]}),V?e.jsxs("div",{className:"skills-view-detail-loading",children:[e.jsx(Z,{size:16,className:"spin"}),"Loading skill content..."]}):z?e.jsxs("div",{className:"skills-view-detail-error",children:[e.jsx(I,{size:14}),e.jsx("span",{children:z}),e.jsx("button",{className:"btn btn-sm",onClick:()=>U(s.id),children:"Retry"})]}):k?e.jsxs(e.Fragment,{children:[e.jsx("pre",{className:"skills-view-detail-content",children:k.skillMd||"(No SKILL.md found)"}),k.files.length>0&&e.jsxs("div",{className:"skills-view-detail-files",children:[e.jsx("span",{className:"skills-view-detail-files-label",children:"Files:"}),k.files.map(l=>e.jsxs("span",{className:"badge badge--sm",children:[l.name,l.type==="directory"&&"/"]},l.relativePath))]})]}):null]})]},s.id)})})]}),e.jsxs("section",{className:"skills-view-section","aria-labelledby":"catalog-title",children:[e.jsx("h3",{id:"catalog-title",className:"skills-view-section-title",children:"Skills Catalog"}),L?e.jsxs("div",{className:"skills-view-error",children:[e.jsx("p",{children:L}),e.jsx("button",{className:"btn btn-sm",onClick:()=>void u(N),children:"Try Again"})]}):A?e.jsxs("div",{className:"skills-view-loading",children:[e.jsx("span",{className:"spinner"}),"Loading catalog..."]}):D.length===0?e.jsx("div",{className:"skills-view-empty",children:m?e.jsx("p",{children:"No skills match your search."}):e.jsx("p",{children:"No skills available in the catalog."})}):e.jsx("div",{className:"skills-view-grid",children:D.map(s=>e.jsxs("div",{className:"skills-view-card",children:[e.jsx("h4",{className:"skills-view-card-title",children:s.name}),s.description&&e.jsx("p",{className:"skills-view-card-description",children:s.description}),s.tags&&s.tags.length>0&&e.jsx("div",{className:"skills-view-card-tags",children:s.tags.map(a=>e.jsx("span",{className:"badge badge--sm",children:a},a))}),s.installs!==void 0&&e.jsxs("span",{className:"skills-view-card-installs",children:[s.installs.toLocaleString()," installs"]})]},s.id))})]})]})]})}export{ae as SkillsView};
@@ -1 +1 @@
1
- import{r as t,j as s}from"./vendor-react-K0fH_qHe.js";import{v as y,cx as i}from"./index-B9Ro_NwC.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";function S(){const{confirm:h}=y(),[c,u]=t.useState([]),[d,f]=t.useState(null),[p,x]=t.useState({}),[n,l]=t.useState(null),o=t.useCallback(async()=>{try{f(null);const a=await i("/stash-recovery/orphans");u(a.records??[])}catch(a){f(a instanceof Error?a.message:"Failed to load orphans")}},[]);t.useEffect(()=>{o()},[o]);const j=t.useMemo(()=>{const a=new Map;for(const e of c){const r=e.sourceTaskId??"Unknown source",m=a.get(r)??[];m.push(e),a.set(r,m)}return Array.from(a.entries())},[c]),v=t.useCallback(async a=>{const e=await i(`/stash-recovery/orphans/${a}/apply`,{method:"POST"});x(r=>({...r,[a]:e.ok?"Applied":e.stderr??e.reason??"Apply failed"}))},[]),b=t.useCallback(async a=>{await h({title:"Drop orphaned stash?",message:"This removes the stash entry permanently.",confirmLabel:"Drop",danger:!0})&&(await i(`/stash-recovery/orphans/${a}/drop`,{method:"POST",body:JSON.stringify({confirm:!0})}),await o())},[h,o]),N=t.useCallback(async a=>{l({sha:a,diff:"",truncated:!1,loading:!0,error:null});try{const e=await i(`/stash-recovery/orphans/${a}/diff`);l({sha:a,diff:e.diff??"",truncated:!!e.truncated,loading:!1,error:null})}catch(e){l({sha:a,diff:"",truncated:!1,loading:!1,error:e instanceof Error?e.message:"Failed to load diff"})}},[]);return c.length===0&&!d?s.jsxs("div",{className:"card stash-recovery-view",children:[s.jsx("p",{children:"No orphaned merger autostashes found."}),s.jsx("button",{className:"btn btn-sm",onClick:()=>void o(),children:"Refresh"})]}):s.jsxs("div",{className:"card stash-recovery-view",children:[s.jsxs("div",{className:"stash-recovery-header",children:[s.jsx("h2",{children:"Stash Recovery"}),s.jsxs("span",{children:[c.length," orphans"]}),s.jsx("button",{className:"btn btn-sm",onClick:()=>void o(),children:"Refresh"})]}),d&&s.jsx("div",{className:"form-error",children:d}),j.map(([a,e])=>s.jsxs("section",{children:[s.jsx("h3",{children:a}),e.map(r=>s.jsxs("div",{className:"stash-row",children:[s.jsxs("div",{className:"stash-field",children:[s.jsx("span",{className:"stash-field-label",children:"SHA"}),s.jsx("span",{children:r.sha.slice(0,7)})]}),s.jsxs("div",{className:"stash-field",children:[s.jsx("span",{className:"stash-field-label",children:"Classification"}),s.jsx("span",{children:r.classification})]}),s.jsxs("div",{className:"stash-field",children:[s.jsx("span",{className:"stash-field-label",children:"Changed paths"}),s.jsxs("span",{children:[r.changedPaths.length," files"]})]}),s.jsxs("div",{className:"stash-row-actions",children:[s.jsx("button",{className:"btn btn-sm stash-action-btn",onClick:()=>void N(r.sha),children:"Inspect diff"}),s.jsx("button",{className:"btn btn-sm stash-action-btn",onClick:()=>void v(r.sha),children:"Apply"})]}),s.jsx("div",{className:"stash-row-actions-danger",children:s.jsx("button",{className:"btn btn-sm btn-danger stash-action-btn",onClick:()=>void b(r.sha),children:"Drop"})}),p[r.sha]&&s.jsx("div",{className:"stash-status",children:p[r.sha]})]},r.sha))]},a)),n&&s.jsx("div",{className:"modal-overlay open",onClick:()=>l(null),children:s.jsxs("div",{className:"modal stash-recovery-diff-modal",role:"dialog","aria-modal":"true","aria-label":`Diff for ${n.sha}`,onClick:a=>a.stopPropagation(),children:[s.jsxs("div",{className:"modal-header",children:[s.jsxs("h3",{children:["Diff for ",n.sha.slice(0,7)]}),s.jsx("button",{className:"modal-close",onClick:()=>l(null),"aria-label":"Close diff dialog",children:"×"})]}),n.loading&&s.jsx("p",{children:"Loading diff…"}),n.error&&s.jsx("div",{className:"form-error",children:n.error}),!n.loading&&!n.error&&s.jsxs(s.Fragment,{children:[s.jsx("pre",{className:"stash-recovery-diff-pre",children:n.diff||"No diff output available."}),n.truncated&&s.jsx("p",{className:"stash-status",children:"Diff output truncated."})]}),s.jsx("div",{className:"modal-actions",children:s.jsx("button",{className:"btn",onClick:()=>l(null),children:"Close"})})]})})]})}export{S as StashRecoveryView};
1
+ import{r as t,j as s}from"./vendor-react-K0fH_qHe.js";import{v as N,cy as i}from"./index-w1dPHtmq.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";function S(){const{confirm:h}=N(),[c,u]=t.useState([]),[d,f]=t.useState(null),[p,x]=t.useState({}),[n,l]=t.useState(null),o=t.useCallback(async()=>{try{f(null);const a=await i("/stash-recovery/orphans");u(a.records??[])}catch(a){f(a instanceof Error?a.message:"Failed to load orphans")}},[]);t.useEffect(()=>{o()},[o]);const j=t.useMemo(()=>{const a=new Map;for(const e of c){const r=e.sourceTaskId??"Unknown source",m=a.get(r)??[];m.push(e),a.set(r,m)}return Array.from(a.entries())},[c]),v=t.useCallback(async a=>{const e=await i(`/stash-recovery/orphans/${a}/apply`,{method:"POST"});x(r=>({...r,[a]:e.ok?"Applied":e.stderr??e.reason??"Apply failed"}))},[]),b=t.useCallback(async a=>{await h({title:"Drop orphaned stash?",message:"This removes the stash entry permanently.",confirmLabel:"Drop",danger:!0})&&(await i(`/stash-recovery/orphans/${a}/drop`,{method:"POST",body:JSON.stringify({confirm:!0})}),await o())},[h,o]),y=t.useCallback(async a=>{l({sha:a,diff:"",truncated:!1,loading:!0,error:null});try{const e=await i(`/stash-recovery/orphans/${a}/diff`);l({sha:a,diff:e.diff??"",truncated:!!e.truncated,loading:!1,error:null})}catch(e){l({sha:a,diff:"",truncated:!1,loading:!1,error:e instanceof Error?e.message:"Failed to load diff"})}},[]);return c.length===0&&!d?s.jsxs("div",{className:"card stash-recovery-view",children:[s.jsx("p",{children:"No orphaned merger autostashes found."}),s.jsx("button",{className:"btn btn-sm",onClick:()=>void o(),children:"Refresh"})]}):s.jsxs("div",{className:"card stash-recovery-view",children:[s.jsxs("div",{className:"stash-recovery-header",children:[s.jsx("h2",{children:"Stash Recovery"}),s.jsxs("span",{children:[c.length," orphans"]}),s.jsx("button",{className:"btn btn-sm",onClick:()=>void o(),children:"Refresh"})]}),d&&s.jsx("div",{className:"form-error",children:d}),j.map(([a,e])=>s.jsxs("section",{children:[s.jsx("h3",{children:a}),e.map(r=>s.jsxs("div",{className:"stash-row",children:[s.jsxs("div",{className:"stash-field",children:[s.jsx("span",{className:"stash-field-label",children:"SHA"}),s.jsx("span",{children:r.sha.slice(0,7)})]}),s.jsxs("div",{className:"stash-field",children:[s.jsx("span",{className:"stash-field-label",children:"Classification"}),s.jsx("span",{children:r.classification})]}),s.jsxs("div",{className:"stash-field",children:[s.jsx("span",{className:"stash-field-label",children:"Changed paths"}),s.jsxs("span",{children:[r.changedPaths.length," files"]})]}),s.jsxs("div",{className:"stash-row-actions",children:[s.jsx("button",{className:"btn btn-sm stash-action-btn",onClick:()=>void y(r.sha),children:"Inspect diff"}),s.jsx("button",{className:"btn btn-sm stash-action-btn",onClick:()=>void v(r.sha),children:"Apply"})]}),s.jsx("div",{className:"stash-row-actions-danger",children:s.jsx("button",{className:"btn btn-sm btn-danger stash-action-btn",onClick:()=>void b(r.sha),children:"Drop"})}),p[r.sha]&&s.jsx("div",{className:"stash-status",children:p[r.sha]})]},r.sha))]},a)),n&&s.jsx("div",{className:"modal-overlay open",onClick:()=>l(null),children:s.jsxs("div",{className:"modal stash-recovery-diff-modal",role:"dialog","aria-modal":"true","aria-label":`Diff for ${n.sha}`,onClick:a=>a.stopPropagation(),children:[s.jsxs("div",{className:"modal-header",children:[s.jsxs("h3",{children:["Diff for ",n.sha.slice(0,7)]}),s.jsx("button",{className:"modal-close",onClick:()=>l(null),"aria-label":"Close diff dialog",children:"×"})]}),n.loading&&s.jsx("p",{children:"Loading diff…"}),n.error&&s.jsx("div",{className:"form-error",children:n.error}),!n.loading&&!n.error&&s.jsxs(s.Fragment,{children:[s.jsx("pre",{className:"stash-recovery-diff-pre",children:n.diff||"No diff output available."}),n.truncated&&s.jsx("p",{className:"stash-status",children:"Diff output truncated."})]}),s.jsx("div",{className:"modal-actions",children:s.jsx("button",{className:"btn",onClick:()=>l(null),children:"Close"})})]})})]})}export{S as StashRecoveryView};
@@ -1,6 +1,6 @@
1
- import{r,j as e}from"./vendor-react-K0fH_qHe.js";import{c as At,a7 as ut,a9 as St,cn as $t,co as Et,cp as Dt,cq as Ft,cr as Tt,cs as Mt,ct as _t,a8 as mt,cu as Ot,ac as Rt,v as Pt,i as Kt,z as V,cv as bt,L as Ut,J as Bt,bB as Y,X as Q,cw as pt,b3 as ht,_ as ft,aj as Xt,a as zt,az as Wt,B as xt}from"./index-B9Ro_NwC.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";/**
1
+ import{r,j as e}from"./vendor-react-K0fH_qHe.js";import{c as At,a7 as ut,a8 as mt,a9 as St,co as $t,cp as Et,cq as Dt,cr as Ft,cs as Tt,ct as Mt,cu as _t,cv as Ot,ac as Rt,v as Pt,j as Kt,z as V,cw as bt,L as Ut,J as Bt,bC as Y,X as Q,cx as pt,b4 as ht,_ as ft,aj as Xt,a as Wt,aA as qt,B as xt}from"./index-w1dPHtmq.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";/**
2
2
  * @license lucide-react v1.7.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
- */const qt=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M8 12h8",key:"1wcyev"}],["path",{d:"M12 8v8",key:"napkw2"}]],Gt=At("circle-plus",qt);function Ht(I){const{items:c,...f}=I;return f}function gt(I){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?`${I}-${crypto.randomUUID()}`:`${I}-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function Jt(I={}){const{projectId:c,addToast:f}=I,A=`${St.TODO_LISTS_PREFIX}${c??"global"}`,[N,j]=r.useState(()=>{const n=ut(A,{maxAgeMs:mt});return Array.isArray(n)?n:[]}),[L,k]=r.useState([]),[B,w]=r.useState(()=>N.length===0),[W,v]=r.useState(null),[E,D]=r.useState(null),[y,h]=r.useState([]),C=r.useRef(E);C.current=E,r.useEffect(()=>{let n=!1;const o=ut(A,{maxAgeMs:mt}),b=Array.isArray(o)&&o.length>0;b?(j(o),w(!1)):(j([]),w(!0));async function l(){b||w(!0),v(null);try{const d=await Ot(c);if(n)return;h(d);const s=d.map(Ht);j(s),Rt(A,s,{maxBytes:5e5});const i=C.current&&d.some(a=>a.id===C.current)?C.current:d[0]?.id??null;D(i),k(i?d.find(a=>a.id===i)?.items??[]:[])}catch(d){if(n)return;h([]),j([]),k([]),D(null),v(d instanceof Error?d.message:"Failed to load todo lists")}finally{n||w(!1)}}return l(),()=>{n=!0}},[A,c]),r.useEffect(()=>{if(!E){k([]);return}const n=y.find(o=>o.id===E);k(n?.items??[])},[y,E]);const q=r.useCallback(async n=>{const o=N,b=y,l=new Date().toISOString(),d={id:gt("temp-list"),projectId:c??"",title:n,createdAt:l,updatedAt:l};v(null),j(s=>[...s,d]),h(s=>[...s,{...d,items:[]}]);try{const s=await $t(n,c);j(i=>i.map(a=>a.id===d.id?s:a)),h(i=>i.map(a=>a.id===d.id?{...s,items:[]}:a)),C.current||D(s.id)}catch(s){j(o),h(b),v(s instanceof Error?s.message:"Failed to create list"),f?.("Failed to create todo list","error")}},[f,y,N,c]),G=r.useCallback(async(n,o)=>{const b=N,l=y;v(null),j(d=>d.map(s=>s.id===n?{...s,title:o}:s)),h(d=>d.map(s=>s.id===n?{...s,title:o}:s));try{const d=await Et(n,o,c);j(s=>s.map(i=>i.id===n?d:i)),h(s=>s.map(i=>i.id===n?{...d,items:i.items}:i))}catch(d){j(b),h(l),v(d instanceof Error?d.message:"Failed to rename list"),f?.("Failed to rename todo list","error")}},[f,y,N,c]),_=r.useCallback(async n=>{const o=N,b=y,l=C.current,d=l===n?N.find(s=>s.id!==n)?.id??null:l;v(null),j(s=>s.filter(i=>i.id!==n)),h(s=>s.filter(i=>i.id!==n)),l===n&&D(d);try{await Dt(n,c)}catch(s){j(o),h(b),D(l),v(s instanceof Error?s.message:"Failed to delete list"),f?.("Failed to delete todo list","error")}},[f,y,N,c]),S=r.useCallback(async n=>{const o=C.current;if(!o)return;const b=L,l=y,d=new Date().toISOString(),s=L.reduce((a,u)=>Math.max(a,u.sortOrder),-1),i={id:gt("temp-item"),listId:o,text:n,completed:!1,completedAt:null,createdAt:d,updatedAt:d,sortOrder:s+1};v(null),k(a=>[...a,i]),h(a=>a.map(u=>u.id===o?{...u,items:[...u.items,i]}:u));try{const a=await Ft(o,n,c);k(u=>u.map(x=>x.id===i.id?a:x)),h(u=>u.map(x=>x.id===o?{...x,items:x.items.map(T=>T.id===i.id?a:T)}:x))}catch(a){k(b),h(l),v(a instanceof Error?a.message:"Failed to create item"),f?.("Failed to create todo item","error")}},[f,L,y,c]),M=r.useCallback(async(n,o)=>{const b=L.find(a=>a.id===n);if(!b)return;const l=L,d=y,s=o.completed??b.completed,i={...b,...o,completed:s,completedAt:s?b.completedAt??new Date().toISOString():null,updatedAt:new Date().toISOString()};v(null),k(a=>a.map(u=>u.id===n?i:u)),h(a=>a.map(u=>u.id===i.listId?{...u,items:u.items.map(x=>x.id===n?i:x)}:u));try{const a=await Tt(n,o,c);k(u=>u.map(x=>x.id===n?a:x)),h(u=>u.map(x=>x.id===a.listId?{...x,items:x.items.map(T=>T.id===n?a:T)}:x))}catch(a){k(l),h(d),v(a instanceof Error?a.message:"Failed to update item"),f?.("Failed to update todo item","error")}},[f,L,y,c]),$=r.useCallback(async n=>{const o=L.find(b=>b.id===n);o&&await M(n,{completed:!o.completed})},[L,M]),O=r.useCallback(async n=>{const o=L,b=y;v(null),k(l=>l.filter(d=>d.id!==n)),h(l=>l.map(d=>({...d,items:d.items.filter(s=>s.id!==n)})));try{await Mt(n,c)}catch(l){k(o),h(b),v(l instanceof Error?l.message:"Failed to delete item"),f?.("Failed to delete todo item","error")}},[f,L,y,c]),F=r.useCallback(async n=>{const o=C.current;if(!o)return;const b=L,l=y,d=new Map(L.map(i=>[i.id,i])),s=n.map((i,a)=>{const u=d.get(i);return u?{...u,sortOrder:a}:null}).filter(i=>i!==null);v(null),k(s),h(i=>i.map(a=>a.id===o?{...a,items:s}:a));try{await _t(o,n,c)}catch(i){k(b),h(l),v(i instanceof Error?i.message:"Failed to reorder items"),f?.("Failed to reorder todo items","error")}},[f,L,y,c]);return{lists:N,items:L,loading:B,error:W,selectedListId:E,setSelectedListId:D,createList:q,renameList:G,deleteList:_,createItem:S,updateItem:M,toggleItem:$,deleteItem:O,reorderItems:F}}function Vt(I){return[...I].sort((c,f)=>c.sortOrder-f.sortOrder)}function ee({projectId:I,addToast:c,onPlanningMode:f,onTaskCreated:A,mobileKeyboardActive:N=!1}){const{lists:j,items:L,loading:k,error:B,selectedListId:w,setSelectedListId:W,createList:v,renameList:E,deleteList:D,createItem:y,updateItem:h,toggleItem:C,deleteItem:q,reorderItems:G}=Jt({projectId:I,addToast:(t,p)=>{if(p==="success"||p==="error"||p==="info"||p===void 0){c(t,p);return}c(t,"info")}}),[_,S]=r.useState(null),[M,$]=r.useState(""),[O,F]=r.useState(null),[n,o]=r.useState(""),[b,l]=r.useState(""),[d,s]=r.useState(!1),[i,a]=r.useState(""),[u,x]=r.useState([]),[T,Z]=r.useState(!1),[H,R]=r.useState(!1),[tt,P]=r.useState(null),J=r.useRef(null),{confirm:vt}=Pt(),et=r.useMemo(()=>j.find(t=>t.id===w)??null,[j,w]),X=r.useMemo(()=>Vt(L.filter(t=>t.listId===w)),[L,w]);function st(){S(null),$(""),l(""),s(!1)}function z(){F(null),o(""),a("")}function yt(t){st(),z(),W(t)}const jt=r.useCallback(async()=>{Z(!0);try{const t=await Kt(void 0,I);x(t),R(!0)}catch(t){c(`Failed to load agents: ${V(t)}`,"error"),R(!1),P(null)}finally{Z(!1)}},[I,c]);r.useEffect(()=>{S(null),$(""),l(""),s(!1),F(null),o(""),a(""),R(!1),P(null)},[w]),r.useEffect(()=>{if(!H)return;const t=p=>{J.current&&!J.current.contains(p.target)&&(R(!1),P(null))};return document.addEventListener("mousedown",t),()=>{document.removeEventListener("mousedown",t)}},[H]);function Lt(t){z(),S(t.id),$(t.title),s(!1)}async function nt(){if(!_)return;const t=M.trim();if(!t){S(null),$("");return}await E(_,t),S(null),$("")}function at(){S(null),$("")}function it(t){st(),F(t.id),o(t.text)}async function ot(){if(!O)return;const t=n.trim();if(!t){F(null),o("");return}await h(O,{text:t}),F(null),o("")}function dt(){F(null),o("")}async function rt(){const t=b.trim();t&&(await v(t),l(""),s(!1))}async function ct(){if(!w)return;const t=i.trim();t&&(await y(t),a(""))}async function It(t){await vt({title:"Delete List",message:"Delete this list and all its items?",danger:!0})&&await D(t)}async function kt(t){await q(t)}async function lt(t,p){const g=X.map(U=>U.id),m=g.findIndex(U=>U===t);if(m<0)return;const K=p==="up"?m-1:m+1;K<0||K>=g.length||([g[m],g[K]]=[g[K],g[m]],await G(g))}const wt=r.useCallback(async t=>{try{const p={description:t.text,column:"triage",source:{sourceType:"dashboard_ui"}},g=await bt(p,I);A?.(g),c(`Created ${g.id} from todo`,"success")}catch(p){c(`Failed to create task: ${V(p)}`,"error")}},[I,c,A]),Nt=r.useCallback(async(t,p)=>{try{const g={description:t.text,column:"triage",assignedAgentId:p,source:{sourceType:"dashboard_ui"}},m=await bt(g,I);A?.(m);const U=u.find(Ct=>Ct.id===p)?.name??p;c(`Created ${m.id} and assigned to ${U}`,"success"),R(!1),P(null)}catch(g){c(`Failed to create and assign task: ${V(g)}`,"error")}},[I,c,u,A]);return k?e.jsx("div",{className:"todo-view",children:e.jsxs("div",{className:"todo-loading",children:[e.jsx(Ut,{className:"todo-loading-icon","aria-hidden":"true"}),e.jsx("p",{children:"Loading todos..."})]})}):e.jsx("div",{className:`todo-view${N?" todo-view--mobile-keyboard-active":""}`,"data-testid":"todo-view-root",children:e.jsxs("div",{className:"todo-view-layout",children:[e.jsxs("aside",{className:"todo-view-sidebar","aria-label":"Todo lists sidebar",children:[e.jsxs("div",{className:"todo-sidebar-header",children:[e.jsx("h3",{className:"todo-sidebar-title",children:"Lists"}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-add-list-btn",onClick:()=>{z(),s(!0),S(null)},"aria-label":"Add list","data-testid":"add-list-button",children:e.jsx(Bt,{})})]}),d&&e.jsxs("div",{className:"todo-list-item",children:[e.jsx("input",{className:"input todo-inline-edit-input",placeholder:"New list title",value:b,onChange:t=>l(t.target.value),onKeyDown:t=>{t.key==="Enter"&&rt(),t.key==="Escape"&&(l(""),s(!1))},autoFocus:!0,"data-testid":"new-list-input"}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{rt()},"aria-label":"Save list",children:e.jsx(Y,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{l(""),s(!1)},"aria-label":"Cancel list",children:e.jsx(Q,{})})]}),j.length===0&&!d?e.jsxs("div",{className:"todo-empty-state",children:[e.jsx(pt,{"aria-hidden":"true"}),e.jsx("p",{children:"No todo lists yet. Create one to get started."}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>{z(),s(!0)},children:"Create List"})]}):e.jsx("div",{className:"todo-list-items",role:"list","aria-label":"Todo lists",children:j.map(t=>{const p=t.id===w,g=t.id===_;return e.jsx("div",{className:`todo-list-item${p?" todo-list-item--active":""}`,role:"listitem",children:g?e.jsxs(e.Fragment,{children:[e.jsx("input",{className:"input todo-inline-edit-input",value:M,onChange:m=>$(m.target.value),onKeyDown:m=>{m.key==="Enter"&&nt(),m.key==="Escape"&&at()},autoFocus:!0,"data-testid":`rename-list-input-${t.id}`}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{nt()},"aria-label":"Save list rename",children:e.jsx(Y,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:at,"aria-label":"Cancel list rename",children:e.jsx(Q,{})})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"todo-list-select-btn",onClick:()=>yt(t.id),"aria-label":`Select list ${t.title}`,"aria-current":p?"true":void 0,"data-testid":`todo-list-${t.id}`,children:e.jsx("span",{className:"todo-list-item-name",children:t.title})}),e.jsxs("div",{className:"todo-list-item-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{Lt(t)},"aria-label":`Rename ${t.title}`,"data-testid":`rename-list-button-${t.id}`,children:e.jsx(ht,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon btn-danger todo-icon-btn",onClick:()=>{It(t.id)},"aria-label":`Delete ${t.title}`,"data-testid":`delete-list-button-${t.id}`,children:e.jsx(ft,{})})]})]})},t.id)})})]}),e.jsxs("section",{className:"todo-view-main","aria-label":"Todo items",children:[B&&e.jsxs("div",{className:"todo-error-banner",role:"alert",children:[e.jsx("span",{className:"todo-error-message",children:B}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>window.location.reload(),children:"Retry"})]}),et?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"todo-items-header",children:e.jsx("h3",{children:et.title})}),e.jsxs("div",{className:"todo-add-item-row",children:[e.jsx("input",{className:"input",placeholder:"Add a todo item",value:i,onChange:t=>a(t.target.value),onKeyDown:t=>{t.key==="Enter"&&ct(),t.key==="Escape"&&a("")},"data-testid":"new-item-input"}),e.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>{ct()},children:"Add"})]}),X.length===0?e.jsx("div",{className:"todo-empty-state",children:e.jsx("p",{children:"No items in this list. Add one above."})}):e.jsx("div",{className:"todo-items-list",children:X.map((t,p)=>{const g=t.id===O;return e.jsxs("div",{className:"todo-item","data-testid":`todo-item-${t.id}`,children:[e.jsxs("div",{className:"todo-item-main-row",children:[e.jsx("input",{type:"checkbox",checked:t.completed,onChange:()=>{C(t.id)},className:"todo-item-checkbox","aria-label":`Toggle ${t.text}`,"data-testid":`toggle-item-${t.id}`}),g?e.jsx("input",{className:"input todo-inline-edit-input",value:n,onChange:m=>o(m.target.value),onKeyDown:m=>{m.key==="Enter"&&ot(),m.key==="Escape"&&dt()},autoFocus:!0,"data-testid":`edit-item-input-${t.id}`}):e.jsx("button",{type:"button",className:`todo-item-text${t.completed?" todo-item-text--completed":""}`,onClick:()=>it(t),children:t.text})]}),e.jsx("div",{className:"todo-item-actions","data-testid":`todo-item-actions-${t.id}`,children:g?e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{ot()},"aria-label":"Save item edit",children:e.jsx(Y,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:dt,"aria-label":"Cancel item edit",children:e.jsx(Q,{})})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"todo-item-reorder-btns",children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-item-reorder-btn",onClick:()=>{lt(t.id,"up")},disabled:p===0,"aria-label":`Move ${t.text} up`,"data-testid":`move-up-${t.id}`,children:e.jsx(Xt,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-item-reorder-btn",onClick:()=>{lt(t.id,"down")},disabled:p===X.length-1,"aria-label":`Move ${t.text} down`,"data-testid":`move-down-${t.id}`,children:e.jsx(zt,{})})]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{f?.(t.text)},"aria-label":`Start planning from ${t.text}`,"data-testid":`planning-from-${t.id}`,children:e.jsx(Wt,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{wt(t)},"aria-label":`Create task from ${t.text}`,"data-testid":`create-task-from-${t.id}`,children:e.jsx(Gt,{})}),e.jsxs("div",{className:"todo-agent-picker-trigger",ref:tt===t.id?J:void 0,children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{P(t.id),jt()},"aria-label":`Assign ${t.text} to agent`,"data-testid":`assign-agent-for-${t.id}`,children:e.jsx(xt,{})}),H&&tt===t.id&&e.jsx("div",{className:"todo-agent-picker-dropdown",onMouseDown:m=>{m.preventDefault()},children:T?e.jsx("div",{className:"todo-agent-picker-loading",children:"Loading agents..."}):u.length>0?u.map(m=>e.jsxs("button",{type:"button",className:"todo-agent-picker-item",onClick:()=>{Nt(t,m.id)},children:[e.jsx(xt,{}),e.jsx("span",{children:m.name}),e.jsx("span",{className:"todo-agent-picker-role",children:m.role})]},m.id)):e.jsx("div",{className:"todo-agent-picker-empty",children:"No agents available"})})]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>it(t),"aria-label":`Edit ${t.text}`,"data-testid":`edit-item-${t.id}`,children:e.jsx(ht,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon btn-danger todo-icon-btn",onClick:()=>{kt(t.id)},"aria-label":`Delete ${t.text}`,"data-testid":`delete-item-${t.id}`,children:e.jsx(ft,{})})]})})]},t.id)})})]}):e.jsxs("div",{className:"todo-empty-state",children:[e.jsx(pt,{"aria-hidden":"true"}),e.jsx("p",{children:"Select a list from the sidebar"})]})]})]})})}export{ee as TodoView};
6
+ */const zt=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M8 12h8",key:"1wcyev"}],["path",{d:"M12 8v8",key:"napkw2"}]],Gt=At("circle-plus",zt);function Ht(I){const{items:c,...f}=I;return f}function gt(I){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?`${I}-${crypto.randomUUID()}`:`${I}-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function Jt(I={}){const{projectId:c,addToast:f}=I,A=`${St.TODO_LISTS_PREFIX}${c??"global"}`,[N,j]=r.useState(()=>{const n=ut(A,{maxAgeMs:mt});return Array.isArray(n)?n:[]}),[L,k]=r.useState([]),[B,w]=r.useState(()=>N.length===0),[q,v]=r.useState(null),[E,D]=r.useState(null),[y,h]=r.useState([]),C=r.useRef(E);C.current=E,r.useEffect(()=>{let n=!1;const o=ut(A,{maxAgeMs:mt}),b=Array.isArray(o)&&o.length>0;b?(j(o),w(!1)):(j([]),w(!0));async function l(){b||w(!0),v(null);try{const d=await Ot(c);if(n)return;h(d);const s=d.map(Ht);j(s),Rt(A,s,{maxBytes:5e5});const i=C.current&&d.some(a=>a.id===C.current)?C.current:d[0]?.id??null;D(i),k(i?d.find(a=>a.id===i)?.items??[]:[])}catch(d){if(n)return;h([]),j([]),k([]),D(null),v(d instanceof Error?d.message:"Failed to load todo lists")}finally{n||w(!1)}}return l(),()=>{n=!0}},[A,c]),r.useEffect(()=>{if(!E){k([]);return}const n=y.find(o=>o.id===E);k(n?.items??[])},[y,E]);const z=r.useCallback(async n=>{const o=N,b=y,l=new Date().toISOString(),d={id:gt("temp-list"),projectId:c??"",title:n,createdAt:l,updatedAt:l};v(null),j(s=>[...s,d]),h(s=>[...s,{...d,items:[]}]);try{const s=await $t(n,c);j(i=>i.map(a=>a.id===d.id?s:a)),h(i=>i.map(a=>a.id===d.id?{...s,items:[]}:a)),C.current||D(s.id)}catch(s){j(o),h(b),v(s instanceof Error?s.message:"Failed to create list"),f?.("Failed to create todo list","error")}},[f,y,N,c]),G=r.useCallback(async(n,o)=>{const b=N,l=y;v(null),j(d=>d.map(s=>s.id===n?{...s,title:o}:s)),h(d=>d.map(s=>s.id===n?{...s,title:o}:s));try{const d=await Et(n,o,c);j(s=>s.map(i=>i.id===n?d:i)),h(s=>s.map(i=>i.id===n?{...d,items:i.items}:i))}catch(d){j(b),h(l),v(d instanceof Error?d.message:"Failed to rename list"),f?.("Failed to rename todo list","error")}},[f,y,N,c]),_=r.useCallback(async n=>{const o=N,b=y,l=C.current,d=l===n?N.find(s=>s.id!==n)?.id??null:l;v(null),j(s=>s.filter(i=>i.id!==n)),h(s=>s.filter(i=>i.id!==n)),l===n&&D(d);try{await Dt(n,c)}catch(s){j(o),h(b),D(l),v(s instanceof Error?s.message:"Failed to delete list"),f?.("Failed to delete todo list","error")}},[f,y,N,c]),S=r.useCallback(async n=>{const o=C.current;if(!o)return;const b=L,l=y,d=new Date().toISOString(),s=L.reduce((a,u)=>Math.max(a,u.sortOrder),-1),i={id:gt("temp-item"),listId:o,text:n,completed:!1,completedAt:null,createdAt:d,updatedAt:d,sortOrder:s+1};v(null),k(a=>[...a,i]),h(a=>a.map(u=>u.id===o?{...u,items:[...u.items,i]}:u));try{const a=await Ft(o,n,c);k(u=>u.map(x=>x.id===i.id?a:x)),h(u=>u.map(x=>x.id===o?{...x,items:x.items.map(T=>T.id===i.id?a:T)}:x))}catch(a){k(b),h(l),v(a instanceof Error?a.message:"Failed to create item"),f?.("Failed to create todo item","error")}},[f,L,y,c]),M=r.useCallback(async(n,o)=>{const b=L.find(a=>a.id===n);if(!b)return;const l=L,d=y,s=o.completed??b.completed,i={...b,...o,completed:s,completedAt:s?b.completedAt??new Date().toISOString():null,updatedAt:new Date().toISOString()};v(null),k(a=>a.map(u=>u.id===n?i:u)),h(a=>a.map(u=>u.id===i.listId?{...u,items:u.items.map(x=>x.id===n?i:x)}:u));try{const a=await Tt(n,o,c);k(u=>u.map(x=>x.id===n?a:x)),h(u=>u.map(x=>x.id===a.listId?{...x,items:x.items.map(T=>T.id===n?a:T)}:x))}catch(a){k(l),h(d),v(a instanceof Error?a.message:"Failed to update item"),f?.("Failed to update todo item","error")}},[f,L,y,c]),$=r.useCallback(async n=>{const o=L.find(b=>b.id===n);o&&await M(n,{completed:!o.completed})},[L,M]),O=r.useCallback(async n=>{const o=L,b=y;v(null),k(l=>l.filter(d=>d.id!==n)),h(l=>l.map(d=>({...d,items:d.items.filter(s=>s.id!==n)})));try{await Mt(n,c)}catch(l){k(o),h(b),v(l instanceof Error?l.message:"Failed to delete item"),f?.("Failed to delete todo item","error")}},[f,L,y,c]),F=r.useCallback(async n=>{const o=C.current;if(!o)return;const b=L,l=y,d=new Map(L.map(i=>[i.id,i])),s=n.map((i,a)=>{const u=d.get(i);return u?{...u,sortOrder:a}:null}).filter(i=>i!==null);v(null),k(s),h(i=>i.map(a=>a.id===o?{...a,items:s}:a));try{await _t(o,n,c)}catch(i){k(b),h(l),v(i instanceof Error?i.message:"Failed to reorder items"),f?.("Failed to reorder todo items","error")}},[f,L,y,c]);return{lists:N,items:L,loading:B,error:q,selectedListId:E,setSelectedListId:D,createList:z,renameList:G,deleteList:_,createItem:S,updateItem:M,toggleItem:$,deleteItem:O,reorderItems:F}}function Vt(I){return[...I].sort((c,f)=>c.sortOrder-f.sortOrder)}function ee({projectId:I,addToast:c,onPlanningMode:f,onTaskCreated:A,mobileKeyboardActive:N=!1}){const{lists:j,items:L,loading:k,error:B,selectedListId:w,setSelectedListId:q,createList:v,renameList:E,deleteList:D,createItem:y,updateItem:h,toggleItem:C,deleteItem:z,reorderItems:G}=Jt({projectId:I,addToast:(t,p)=>{if(p==="success"||p==="error"||p==="info"||p===void 0){c(t,p);return}c(t,"info")}}),[_,S]=r.useState(null),[M,$]=r.useState(""),[O,F]=r.useState(null),[n,o]=r.useState(""),[b,l]=r.useState(""),[d,s]=r.useState(!1),[i,a]=r.useState(""),[u,x]=r.useState([]),[T,Z]=r.useState(!1),[H,R]=r.useState(!1),[tt,P]=r.useState(null),J=r.useRef(null),{confirm:vt}=Pt(),et=r.useMemo(()=>j.find(t=>t.id===w)??null,[j,w]),X=r.useMemo(()=>Vt(L.filter(t=>t.listId===w)),[L,w]);function st(){S(null),$(""),l(""),s(!1)}function W(){F(null),o(""),a("")}function yt(t){st(),W(),q(t)}const jt=r.useCallback(async()=>{Z(!0);try{const t=await Kt(void 0,I);x(t),R(!0)}catch(t){c(`Failed to load agents: ${V(t)}`,"error"),R(!1),P(null)}finally{Z(!1)}},[I,c]);r.useEffect(()=>{S(null),$(""),l(""),s(!1),F(null),o(""),a(""),R(!1),P(null)},[w]),r.useEffect(()=>{if(!H)return;const t=p=>{J.current&&!J.current.contains(p.target)&&(R(!1),P(null))};return document.addEventListener("mousedown",t),()=>{document.removeEventListener("mousedown",t)}},[H]);function Lt(t){W(),S(t.id),$(t.title),s(!1)}async function nt(){if(!_)return;const t=M.trim();if(!t){S(null),$("");return}await E(_,t),S(null),$("")}function at(){S(null),$("")}function it(t){st(),F(t.id),o(t.text)}async function ot(){if(!O)return;const t=n.trim();if(!t){F(null),o("");return}await h(O,{text:t}),F(null),o("")}function dt(){F(null),o("")}async function rt(){const t=b.trim();t&&(await v(t),l(""),s(!1))}async function ct(){if(!w)return;const t=i.trim();t&&(await y(t),a(""))}async function It(t){await vt({title:"Delete List",message:"Delete this list and all its items?",danger:!0})&&await D(t)}async function kt(t){await z(t)}async function lt(t,p){const g=X.map(U=>U.id),m=g.findIndex(U=>U===t);if(m<0)return;const K=p==="up"?m-1:m+1;K<0||K>=g.length||([g[m],g[K]]=[g[K],g[m]],await G(g))}const wt=r.useCallback(async t=>{try{const p={description:t.text,column:"triage",source:{sourceType:"dashboard_ui"}},g=await bt(p,I);A?.(g),c(`Created ${g.id} from todo`,"success")}catch(p){c(`Failed to create task: ${V(p)}`,"error")}},[I,c,A]),Nt=r.useCallback(async(t,p)=>{try{const g={description:t.text,column:"triage",assignedAgentId:p,source:{sourceType:"dashboard_ui"}},m=await bt(g,I);A?.(m);const U=u.find(Ct=>Ct.id===p)?.name??p;c(`Created ${m.id} and assigned to ${U}`,"success"),R(!1),P(null)}catch(g){c(`Failed to create and assign task: ${V(g)}`,"error")}},[I,c,u,A]);return k?e.jsx("div",{className:"todo-view",children:e.jsxs("div",{className:"todo-loading",children:[e.jsx(Ut,{className:"todo-loading-icon","aria-hidden":"true"}),e.jsx("p",{children:"Loading todos..."})]})}):e.jsx("div",{className:`todo-view${N?" todo-view--mobile-keyboard-active":""}`,"data-testid":"todo-view-root",children:e.jsxs("div",{className:"todo-view-layout",children:[e.jsxs("aside",{className:"todo-view-sidebar","aria-label":"Todo lists sidebar",children:[e.jsxs("div",{className:"todo-sidebar-header",children:[e.jsx("h3",{className:"todo-sidebar-title",children:"Lists"}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-add-list-btn",onClick:()=>{W(),s(!0),S(null)},"aria-label":"Add list","data-testid":"add-list-button",children:e.jsx(Bt,{})})]}),d&&e.jsxs("div",{className:"todo-list-item",children:[e.jsx("input",{className:"input todo-inline-edit-input",placeholder:"New list title",value:b,onChange:t=>l(t.target.value),onKeyDown:t=>{t.key==="Enter"&&rt(),t.key==="Escape"&&(l(""),s(!1))},autoFocus:!0,"data-testid":"new-list-input"}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{rt()},"aria-label":"Save list",children:e.jsx(Y,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{l(""),s(!1)},"aria-label":"Cancel list",children:e.jsx(Q,{})})]}),j.length===0&&!d?e.jsxs("div",{className:"todo-empty-state",children:[e.jsx(pt,{"aria-hidden":"true"}),e.jsx("p",{children:"No todo lists yet. Create one to get started."}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>{W(),s(!0)},children:"Create List"})]}):e.jsx("div",{className:"todo-list-items",role:"list","aria-label":"Todo lists",children:j.map(t=>{const p=t.id===w,g=t.id===_;return e.jsx("div",{className:`todo-list-item${p?" todo-list-item--active":""}`,role:"listitem",children:g?e.jsxs(e.Fragment,{children:[e.jsx("input",{className:"input todo-inline-edit-input",value:M,onChange:m=>$(m.target.value),onKeyDown:m=>{m.key==="Enter"&&nt(),m.key==="Escape"&&at()},autoFocus:!0,"data-testid":`rename-list-input-${t.id}`}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{nt()},"aria-label":"Save list rename",children:e.jsx(Y,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:at,"aria-label":"Cancel list rename",children:e.jsx(Q,{})})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"todo-list-select-btn",onClick:()=>yt(t.id),"aria-label":`Select list ${t.title}`,"aria-current":p?"true":void 0,"data-testid":`todo-list-${t.id}`,children:e.jsx("span",{className:"todo-list-item-name",children:t.title})}),e.jsxs("div",{className:"todo-list-item-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{Lt(t)},"aria-label":`Rename ${t.title}`,"data-testid":`rename-list-button-${t.id}`,children:e.jsx(ht,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon btn-danger todo-icon-btn",onClick:()=>{It(t.id)},"aria-label":`Delete ${t.title}`,"data-testid":`delete-list-button-${t.id}`,children:e.jsx(ft,{})})]})]})},t.id)})})]}),e.jsxs("section",{className:"todo-view-main","aria-label":"Todo items",children:[B&&e.jsxs("div",{className:"todo-error-banner",role:"alert",children:[e.jsx("span",{className:"todo-error-message",children:B}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>window.location.reload(),children:"Retry"})]}),et?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"todo-items-header",children:e.jsx("h3",{children:et.title})}),e.jsxs("div",{className:"todo-add-item-row",children:[e.jsx("input",{className:"input",placeholder:"Add a todo item",value:i,onChange:t=>a(t.target.value),onKeyDown:t=>{t.key==="Enter"&&ct(),t.key==="Escape"&&a("")},"data-testid":"new-item-input"}),e.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>{ct()},children:"Add"})]}),X.length===0?e.jsx("div",{className:"todo-empty-state",children:e.jsx("p",{children:"No items in this list. Add one above."})}):e.jsx("div",{className:"todo-items-list",children:X.map((t,p)=>{const g=t.id===O;return e.jsxs("div",{className:"todo-item","data-testid":`todo-item-${t.id}`,children:[e.jsxs("div",{className:"todo-item-main-row",children:[e.jsx("input",{type:"checkbox",checked:t.completed,onChange:()=>{C(t.id)},className:"todo-item-checkbox","aria-label":`Toggle ${t.text}`,"data-testid":`toggle-item-${t.id}`}),g?e.jsx("input",{className:"input todo-inline-edit-input",value:n,onChange:m=>o(m.target.value),onKeyDown:m=>{m.key==="Enter"&&ot(),m.key==="Escape"&&dt()},autoFocus:!0,"data-testid":`edit-item-input-${t.id}`}):e.jsx("button",{type:"button",className:`todo-item-text${t.completed?" todo-item-text--completed":""}`,onClick:()=>it(t),children:t.text})]}),e.jsx("div",{className:"todo-item-actions","data-testid":`todo-item-actions-${t.id}`,children:g?e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{ot()},"aria-label":"Save item edit",children:e.jsx(Y,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:dt,"aria-label":"Cancel item edit",children:e.jsx(Q,{})})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"todo-item-reorder-btns",children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-item-reorder-btn",onClick:()=>{lt(t.id,"up")},disabled:p===0,"aria-label":`Move ${t.text} up`,"data-testid":`move-up-${t.id}`,children:e.jsx(Xt,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-item-reorder-btn",onClick:()=>{lt(t.id,"down")},disabled:p===X.length-1,"aria-label":`Move ${t.text} down`,"data-testid":`move-down-${t.id}`,children:e.jsx(Wt,{})})]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{f?.(t.text)},"aria-label":`Start planning from ${t.text}`,"data-testid":`planning-from-${t.id}`,children:e.jsx(qt,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{wt(t)},"aria-label":`Create task from ${t.text}`,"data-testid":`create-task-from-${t.id}`,children:e.jsx(Gt,{})}),e.jsxs("div",{className:"todo-agent-picker-trigger",ref:tt===t.id?J:void 0,children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{P(t.id),jt()},"aria-label":`Assign ${t.text} to agent`,"data-testid":`assign-agent-for-${t.id}`,children:e.jsx(xt,{})}),H&&tt===t.id&&e.jsx("div",{className:"todo-agent-picker-dropdown",onMouseDown:m=>{m.preventDefault()},children:T?e.jsx("div",{className:"todo-agent-picker-loading",children:"Loading agents..."}):u.length>0?u.map(m=>e.jsxs("button",{type:"button",className:"todo-agent-picker-item",onClick:()=>{Nt(t,m.id)},children:[e.jsx(xt,{}),e.jsx("span",{children:m.name}),e.jsx("span",{className:"todo-agent-picker-role",children:m.role})]},m.id)):e.jsx("div",{className:"todo-agent-picker-empty",children:"No agents available"})})]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>it(t),"aria-label":`Edit ${t.text}`,"data-testid":`edit-item-${t.id}`,children:e.jsx(ht,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon btn-danger todo-icon-btn",onClick:()=>{kt(t.id)},"aria-label":`Delete ${t.text}`,"data-testid":`delete-item-${t.id}`,children:e.jsx(ft,{})})]})})]},t.id)})})]}):e.jsxs("div",{className:"todo-empty-state",children:[e.jsx(pt,{"aria-hidden":"true"}),e.jsx("p",{children:"Select a list from the sidebar"})]})]})]})})}export{ee as TodoView};
@@ -1,4 +1,4 @@
1
- import{r as t,j as R}from"./vendor-react-K0fH_qHe.js";import{cy as Ee,cz as ve,t as Ye,w as je,bk as Xe}from"./index-B9Ro_NwC.js";import{c as pe}from"./createLucideIcon-BazL2hk5.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const xe=4,ke=300,Ae=24;function $e({taskId:o,position:s,scale:r,canDrag:a,onPositionChange:f,onDragStateChange:c,onDragEnd:m,onDoubleTap:M}){const[C,I]=t.useState(!1),w=t.useRef(null),T=t.useRef(s),_=t.useRef(!1),n=t.useRef(null),h=t.useRef(!1);T.current=s,h.current=C;const l=t.useCallback(()=>{n.current=null},[]),b=t.useCallback(u=>{w.current=null,I(!1),h.current=!1,u&&(c?.(!1),m?.(),_.current=!0,l())},[m,c,l]),z=t.useCallback(u=>{if(!u.isPrimary)return;if(u.defaultPrevented){l();return}const P=Date.now();n.current&&P-n.current.timeStamp>ke&&l(),a&&u.stopPropagation();const D=u.currentTarget;a&&typeof D.setPointerCapture=="function"&&D.setPointerCapture(u.pointerId),w.current={pointerId:u.pointerId,pointerType:u.pointerType,startPointer:{x:u.clientX,y:u.clientY},startPosition:T.current,defaultPrevented:u.defaultPrevented,movedBeyondThreshold:!1}},[a,l]),v=t.useCallback(u=>{const P=w.current;if(!P||P.pointerId!==u.pointerId)return;a&&u.stopPropagation();const D=u.clientX-P.startPointer.x,Y=u.clientY-P.startPointer.y,ee=Math.hypot(D,Y);if(ee>=xe&&(P.movedBeyondThreshold=!0),!a){P.movedBeyondThreshold&&l();return}if(!h.current&&ee>=xe&&(I(!0),h.current=!0,c?.(!0),l()),ee<xe)return;const W=r>0?r:1;f(o,{x:P.startPosition.x+D/W,y:P.startPosition.y+Y/W})},[a,c,f,l,r,o]),L=t.useCallback((u,P)=>{if(!M||P.defaultPrevented||P.movedBeyondThreshold)return Date.now()-(n.current?.timeStamp??0)>ke&&l(),!1;if(P.pointerType==="mouse")return l(),!1;const D={timeStamp:Date.now(),point:{x:P.startPointer.x,y:P.startPointer.y}},Y=n.current;return!Y||D.timeStamp-Y.timeStamp>ke||Math.hypot(D.point.x-Y.point.x,D.point.y-Y.point.y)>Ae?(n.current=D,!1):(_.current=!0,l(),M(),!0)},[M,l]),$=t.useCallback(u=>{const P=w.current;if(!P||P.pointerId!==u.pointerId)return;a&&u.stopPropagation(),a&&typeof u.currentTarget.hasPointerCapture=="function"&&u.currentTarget.hasPointerCapture(u.pointerId)&&typeof u.currentTarget.releasePointerCapture=="function"&&u.currentTarget.releasePointerCapture(u.pointerId);const D=h.current;!D&&L(u,P)&&u.preventDefault(),b(D)},[a,b,L]),G=t.useCallback(u=>{const P=w.current;!P||P.pointerId!==u.pointerId||(a&&u.stopPropagation(),a&&typeof u.currentTarget.hasPointerCapture=="function"&&u.currentTarget.hasPointerCapture(u.pointerId)&&typeof u.currentTarget.releasePointerCapture=="function"&&u.currentTarget.releasePointerCapture(u.pointerId),l(),b(h.current))},[a,b,l]),A=t.useCallback(u=>{_.current&&(_.current=!1,u.preventDefault(),u.stopPropagation())},[]);return t.useMemo(()=>({isDragging:C,onPointerDown:z,onPointerMove:v,onPointerUp:$,onPointerCancel:G,onClickCapture:A}),[C,A,G,z,v,$])}const Ge=new Set(["planning","researching","executing","finalizing","merging","merging-fix"]);function Le(o){return o?o.charAt(0).toUpperCase()+o.slice(1):"Executing"}function We({style:o,position:s,scale:r,isSelected:a=!1,isHighlighted:f=!1,isDimmed:c=!1,onMouseEnter:m,onMouseLeave:M,onClick:C,onNodePositionChange:I,onNodeDragStateChange:w,onNodeDragEnd:T,..._}){const{task:n,globalPaused:h,taskStuckTimeoutMs:l,lastFetchTimeMs:b,onOpenDetail:z}=_,v=n.status==="failed",L=n.paused===!0,$=Ee(n,l,b),G=n.column==="triage"&&n.status==="awaiting-approval",A=!h&&!v&&!L&&!$&&!G&&(n.column==="in-progress"||Ge.has(n.status)),u=typeof n.currentStep=="number"&&n.currentStep>=0&&Array.isArray(n.steps)&&n.currentStep<n.steps.length,P=n.column==="in-review",D=$e({taskId:n.id,position:s,scale:r,canDrag:a,onPositionChange:I,onDragStateChange:w,onDragEnd:T,onDoubleTap:()=>z(n)});return R.jsxs("div",{className:`graph-task-node${a?" graph-node--draggable graph-task-node--selected":""}${D.isDragging?" graph-node--dragging":""}${f?" graph-task-node--highlighted graph-node--highlighted":""}${c?" graph-task-node--dimmed graph-node--dimmed":""}${A?" graph-task-node--active":""}${P?" graph-task-node--in-review":""}`,style:o,draggable:!1,"data-testid":`graph-task-node-${n.id}`,"data-current-step":A&&u?String(n.currentStep):void 0,onMouseEnter:m,onMouseLeave:M,onClick:C,onDoubleClick:Y=>{Y.defaultPrevented||z(n)},onClickCapture:D.onClickCapture,onPointerDown:D.onPointerDown,onPointerMove:D.onPointerMove,onPointerUp:D.onPointerUp,onPointerCancel:D.onPointerCancel,children:[A?R.jsx("div",{className:"graph-task-active-indicator",children:R.jsx("span",{className:"graph-task-active-indicator-text",children:Le(n.status)})}):null,R.jsx(ve,{..._,onOpenDetail:()=>{},disableDrag:!0})]})}/**
1
+ import{r as t,j as R}from"./vendor-react-K0fH_qHe.js";import{cz as Ee,cA as ve,t as Ye,w as je,bl as Ae}from"./index-w1dPHtmq.js";import{c as pe}from"./createLucideIcon-BazL2hk5.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const xe=4,ke=300,Xe=24;function $e({taskId:o,position:s,scale:r,canDrag:a,onPositionChange:f,onDragStateChange:c,onDragEnd:m,onDoubleTap:M}){const[C,I]=t.useState(!1),w=t.useRef(null),T=t.useRef(s),_=t.useRef(!1),n=t.useRef(null),h=t.useRef(!1);T.current=s,h.current=C;const l=t.useCallback(()=>{n.current=null},[]),b=t.useCallback(u=>{w.current=null,I(!1),h.current=!1,u&&(c?.(!1),m?.(),_.current=!0,l())},[m,c,l]),z=t.useCallback(u=>{if(!u.isPrimary)return;if(u.defaultPrevented){l();return}const P=Date.now();n.current&&P-n.current.timeStamp>ke&&l(),a&&u.stopPropagation();const D=u.currentTarget;a&&typeof D.setPointerCapture=="function"&&D.setPointerCapture(u.pointerId),w.current={pointerId:u.pointerId,pointerType:u.pointerType,startPointer:{x:u.clientX,y:u.clientY},startPosition:T.current,defaultPrevented:u.defaultPrevented,movedBeyondThreshold:!1}},[a,l]),v=t.useCallback(u=>{const P=w.current;if(!P||P.pointerId!==u.pointerId)return;a&&u.stopPropagation();const D=u.clientX-P.startPointer.x,Y=u.clientY-P.startPointer.y,ee=Math.hypot(D,Y);if(ee>=xe&&(P.movedBeyondThreshold=!0),!a){P.movedBeyondThreshold&&l();return}if(!h.current&&ee>=xe&&(I(!0),h.current=!0,c?.(!0),l()),ee<xe)return;const W=r>0?r:1;f(o,{x:P.startPosition.x+D/W,y:P.startPosition.y+Y/W})},[a,c,f,l,r,o]),L=t.useCallback((u,P)=>{if(!M||P.defaultPrevented||P.movedBeyondThreshold)return Date.now()-(n.current?.timeStamp??0)>ke&&l(),!1;if(P.pointerType==="mouse")return l(),!1;const D={timeStamp:Date.now(),point:{x:P.startPointer.x,y:P.startPointer.y}},Y=n.current;return!Y||D.timeStamp-Y.timeStamp>ke||Math.hypot(D.point.x-Y.point.x,D.point.y-Y.point.y)>Xe?(n.current=D,!1):(_.current=!0,l(),M(),!0)},[M,l]),$=t.useCallback(u=>{const P=w.current;if(!P||P.pointerId!==u.pointerId)return;a&&u.stopPropagation(),a&&typeof u.currentTarget.hasPointerCapture=="function"&&u.currentTarget.hasPointerCapture(u.pointerId)&&typeof u.currentTarget.releasePointerCapture=="function"&&u.currentTarget.releasePointerCapture(u.pointerId);const D=h.current;!D&&L(u,P)&&u.preventDefault(),b(D)},[a,b,L]),G=t.useCallback(u=>{const P=w.current;!P||P.pointerId!==u.pointerId||(a&&u.stopPropagation(),a&&typeof u.currentTarget.hasPointerCapture=="function"&&u.currentTarget.hasPointerCapture(u.pointerId)&&typeof u.currentTarget.releasePointerCapture=="function"&&u.currentTarget.releasePointerCapture(u.pointerId),l(),b(h.current))},[a,b,l]),X=t.useCallback(u=>{_.current&&(_.current=!1,u.preventDefault(),u.stopPropagation())},[]);return t.useMemo(()=>({isDragging:C,onPointerDown:z,onPointerMove:v,onPointerUp:$,onPointerCancel:G,onClickCapture:X}),[C,X,G,z,v,$])}const Ge=new Set(["planning","researching","executing","finalizing","merging","merging-fix"]);function Le(o){return o?o.charAt(0).toUpperCase()+o.slice(1):"Executing"}function We({style:o,position:s,scale:r,isSelected:a=!1,isHighlighted:f=!1,isDimmed:c=!1,onMouseEnter:m,onMouseLeave:M,onClick:C,onNodePositionChange:I,onNodeDragStateChange:w,onNodeDragEnd:T,..._}){const{task:n,globalPaused:h,taskStuckTimeoutMs:l,lastFetchTimeMs:b,onOpenDetail:z}=_,v=n.status==="failed",L=n.paused===!0,$=Ee(n,l,b),G=n.column==="triage"&&n.status==="awaiting-approval",X=!h&&!v&&!L&&!$&&!G&&(n.column==="in-progress"||Ge.has(n.status)),u=typeof n.currentStep=="number"&&n.currentStep>=0&&Array.isArray(n.steps)&&n.currentStep<n.steps.length,P=n.column==="in-review",D=$e({taskId:n.id,position:s,scale:r,canDrag:a,onPositionChange:I,onDragStateChange:w,onDragEnd:T,onDoubleTap:()=>z(n)});return R.jsxs("div",{className:`graph-task-node${a?" graph-node--draggable graph-task-node--selected":""}${D.isDragging?" graph-node--dragging":""}${f?" graph-task-node--highlighted graph-node--highlighted":""}${c?" graph-task-node--dimmed graph-node--dimmed":""}${X?" graph-task-node--active":""}${P?" graph-task-node--in-review":""}`,style:o,draggable:!1,"data-testid":`graph-task-node-${n.id}`,"data-current-step":X&&u?String(n.currentStep):void 0,onMouseEnter:m,onMouseLeave:M,onClick:C,onDoubleClick:Y=>{Y.defaultPrevented||z(n)},onClickCapture:D.onClickCapture,onPointerDown:D.onPointerDown,onPointerMove:D.onPointerMove,onPointerUp:D.onPointerUp,onPointerCancel:D.onPointerCancel,children:[X?R.jsx("div",{className:"graph-task-active-indicator",children:R.jsx("span",{className:"graph-task-active-indicator-text",children:Le(n.status)})}):null,R.jsx(ve,{..._,onOpenDetail:()=>{},disableDrag:!0})]})}/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -18,4 +18,4 @@ import{r as t,j as R}from"./vendor-react-K0fH_qHe.js";import{cy as Ee,cz as ve,t
18
18
  *
19
19
  * This source code is licensed under the ISC license.
20
20
  * See the LICENSE file in the root directory of this source tree.
21
- */const qe=[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65",key:"13gj7c"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11",key:"durymu"}]],Je=pe("zoom-out",qe);function Qe({zoom:o,onZoomIn:s,onZoomOut:r,onFitToGraph:a,onResetView:f}){return R.jsxs("div",{className:"graph-toolbar","data-testid":"graph-toolbar",children:[R.jsx("button",{className:"btn btn-icon",title:"Zoom in (Ctrl+=)","aria-label":"Zoom in",onClick:s,children:R.jsx(Ke,{size:16})}),R.jsx("button",{className:"btn btn-icon",title:"Zoom out (Ctrl+-)","aria-label":"Zoom out",onClick:r,children:R.jsx(Je,{size:16})}),R.jsxs("div",{className:"graph-toolbar__zoom-label","aria-live":"polite",children:[Math.round(o*100),"%"]}),R.jsx("button",{className:"btn btn-icon",title:"Fit to graph (Ctrl+Shift+F)","aria-label":"Fit to graph",onClick:a,children:R.jsx(Fe,{size:16})}),R.jsx("button",{className:"btn btn-icon",title:"Reset view (Ctrl+0)","aria-label":"Reset view",onClick:f,children:R.jsx(Ze,{size:16})})]})}const et=280,tt=100;function nt({edges:o,positions:s,nodeWidth:r=et,nodeHeight:a=tt,nodeHeights:f,highlightedEdgeIds:c}){const m=!!(c&&c.size>0);return R.jsxs("svg",{className:"dependency-graph-edges","aria-hidden":"true",children:[R.jsx("defs",{children:R.jsx("marker",{id:"dependency-graph-arrowhead",markerWidth:"10",markerHeight:"7",refX:"10",refY:"3.5",orient:"auto",markerUnits:"strokeWidth",children:R.jsx("path",{d:"M 0 0 L 10 3.5 L 0 7 z",fill:"var(--border)"})})}),o.map(M=>{const C=s.get(M.source),I=s.get(M.target);if(!C||!I)return null;const w=`${M.source}->${M.target}`,T=m&&(c?.has(w)??!1),_=C.x+r/2,n=C.y+(f?.get(M.source)??a),h=I.x+r/2,l=I.y,b=n+(l-n)/2;return R.jsx("path",{"data-testid":"dependency-edge","data-edge-id":w,className:`dependency-graph-edge${T?" graph-edge--highlighted":""}${m&&!T?" graph-edge--dimmed":""}`,d:`M ${_} ${n} C ${_} ${b}, ${h} ${b}, ${h} ${l}`,fill:"none",stroke:T?"var(--todo)":"var(--border)",strokeWidth:T?"var(--space-xs)":"var(--btn-border-width)",opacity:m&&!T?.15:1,markerEnd:"url(#dependency-graph-arrowhead)",style:{transition:"opacity var(--transition-fast), stroke var(--transition-fast), stroke-width var(--transition-fast)"}},w)})]})}const ot=new Set(["triage","todo","in-progress","in-review"]);function rt(o){return o.filter(s=>ot.has(s.column))}const st={nodeWidth:280,nodeHeight:100,horizontalGap:40,verticalGap:80,orientation:"vertical"};function we(o,s){const r={...st,...s},a=o.nodes.map(n=>n.task.id);if(a.length===0)return new Map;const f=new Map,c=new Map;for(const n of a)c.set(n,0),f.set(n,[]);for(const n of o.edges)!c.has(n.source)||!c.has(n.target)||(f.get(n.target)?.push(n.source),c.set(n.source,(c.get(n.source)??0)+1));const m=a.filter(n=>(c.get(n)??0)===0),M=[];for(;m.length>0;){const n=m.shift();M.push(n);for(const h of f.get(n)??[]){const l=(c.get(h)??0)-1;c.set(h,l),l===0&&m.push(h)}}for(const n of a)M.includes(n)||M.push(n);const C=new Map;for(const n of M){const h=o.edges.filter(b=>b.source===n).map(b=>b.target);let l=0;for(const b of h)l=Math.max(l,(C.get(b)??0)+1);C.set(n,l)}const I=new Map;for(const n of a){const h=C.get(n)??0,l=I.get(h)??[];l.push(n),I.set(h,l)}const w=new Map,T=Array.from(I.keys()).sort((n,h)=>n-h),_=new Map;if(r.orientation==="vertical"){let n=0;for(const h of T){_.set(h,n);const l=I.get(h)??[],b=Math.max(r.nodeHeight,...l.map(z=>r.measuredHeights?.get(z)??r.nodeHeight));n+=b+r.verticalGap}}for(const n of T){const h=I.get(n)??[];if(h.sort(),r.orientation==="horizontal"){const L=-(h.reduce((A,u)=>A+(r.measuredHeights?.get(u)??r.nodeHeight),0)+Math.max(0,h.length-1)*r.verticalGap)/2,$=n*(r.nodeWidth+r.horizontalGap);let G=L;for(const A of h)w.set(A,{x:$,y:G}),G+=(r.measuredHeights?.get(A)??r.nodeHeight)+r.verticalGap;continue}const z=-(h.length*r.nodeWidth+Math.max(0,h.length-1)*r.horizontalGap)/2;h.forEach((v,L)=>{const $=z+L*(r.nodeWidth+r.horizontalGap),G=_.get(n)??n*(r.nodeHeight+r.verticalGap);w.set(v,{x:$,y:G})})}return w}function it(o){return t.useMemo(()=>{const s=o.map(f=>({task:f})),r=new Set(o.map(f=>f.id)),a=o.flatMap(f=>(f.dependencies??[]).filter(c=>r.has(c)).map(c=>({source:f.id,target:c})));return{nodes:s,edges:a}},[o])}const ce=.1,ue=3,Te=40,at=200;function J(o,s,r){return Math.min(r,Math.max(s,o))}function ct(o){if(!(o instanceof HTMLElement))return!1;const s=o.tagName.toLowerCase();return o.isContentEditable||s==="input"||s==="textarea"||s==="select"}function ut(){const[o,s]=t.useState({x:0,y:0}),[r,a]=t.useState(1),[f,c]=t.useState(!1),m=t.useRef(o),M=t.useRef(r),C=t.useRef(null),I=t.useRef(null),w=t.useRef(new Map),T=t.useRef(null),_=t.useRef({minX:0,minY:0,maxX:0,maxY:0});t.useEffect(()=>{m.current=o},[o]),t.useEffect(()=>{M.current=r},[r]),t.useEffect(()=>()=>{C.current!==null&&window.clearTimeout(C.current)},[]);const n=t.useMemo(()=>`translate(${o.x}px, ${o.y}px) scale(${r})`,[o.x,o.y,r]),h=t.useMemo(()=>Math.round(r*100),[r]),l=t.useCallback(i=>{if(!i){C.current!==null&&(window.clearTimeout(C.current),C.current=null),c(!1);return}c(!0),C.current!==null&&window.clearTimeout(C.current),C.current=window.setTimeout(()=>{c(!1),C.current=null},at)},[]),b=t.useCallback((i,d,g,S=M.current)=>{const x=_.current;if(x.maxX<=x.minX||x.maxY<=x.minY)return{x:J(i.x,-d,d),y:J(i.y,-g,g)};const U=d-x.maxX*S,O=-x.minX*S,j=g-x.maxY*S,B=-x.minY*S,Z=U>O?(U+O)/2:J(i.x,U,O),K=j>B?(j+B)/2:J(i.y,j,B);return{x:Z,y:K}},[]),z=t.useCallback((i,d,g,S)=>{const x=M.current,U=m.current,O=J(i,ce,ue),j=O/x,B=b({x:d.x-(d.x-U.x)*j,y:d.y-(d.y-U.y)*j},g,S,O);a(O),s(B)},[b]),v=t.useCallback((i,d,g,S)=>{l(!1);const x=S??{x:d/2,y:g/2};z(M.current*i,x,d,g)},[l,z]),L=t.useCallback((i,d)=>{if(i&&d){v(1.2,i,d);return}a(g=>J(g+.1,ce,ue))},[v]),$=t.useCallback((i,d)=>{if(i&&d){v(1/1.2,i,d);return}a(g=>J(g-.1,ce,ue))},[v]),G=t.useCallback(()=>{l(!0),s({x:0,y:0}),a(1)},[l]),A=t.useCallback((i,d,g,S)=>{if(l(!0),i.size===0){s({x:0,y:0}),a(1);return}const x=S?.nodeWidth??280,U=S?.nodeHeight??100,O=Array.from(i.entries()),j=Math.min(...O.map(([,q])=>q.x)),B=Math.min(...O.map(([,q])=>q.y)),Z=Math.max(...O.map(([,q])=>q.x+x)),K=Math.max(...O.map(([q,me])=>me.y+(S?.measuredHeights?.get(q)??U))),te=Math.max(1,Z-j),X=Math.max(1,K-B),re=Math.max(1,d-Te*2),se=Math.max(1,g-Te*2),ne=J(Math.min(re/te,se/X),ce,ue),he=(d-te*ne)/2-j*ne,de=(g-X*ne)/2-B*ne;a(ne),s(b({x:he,y:de},d,g,ne))},[b,l]),u=t.useCallback((i,d)=>{if(w.current.set(i,d),w.current.size===2){const[g,S]=Array.from(w.current.values());T.current={distance:Math.hypot(g.x-S.x,g.y-S.y),zoom:M.current,pan:m.current,midpoint:{x:(g.x+S.x)/2,y:(g.y+S.y)/2}},I.current=null;return}I.current={start:d,panStart:m.current}},[]),P=t.useCallback((i,d,g,S)=>{if(w.current.has(i)&&w.current.set(i,d),w.current.size===2&&T.current){l(!1);const[O,j]=Array.from(w.current.values()),Z=Math.hypot(O.x-j.x,O.y-j.y)/Math.max(1,T.current.distance),K={x:(O.x+j.x)/2,y:(O.y+j.y)/2},te=J(T.current.zoom*Z,ce,ue),X=te/T.current.zoom,re=b({x:K.x-(T.current.midpoint.x-T.current.pan.x)*X,y:K.y-(T.current.midpoint.y-T.current.pan.y)*X},g,S);a(te),s(re);return}const x=I.current;if(!x)return;l(!1);const U={x:x.panStart.x+(d.x-x.start.x),y:x.panStart.y+(d.y-x.start.y)};s(b(U,g,S))},[b,l]),D=t.useCallback(i=>{if(w.current.delete(i),w.current.size<2&&(T.current=null),w.current.size===1){const[d]=Array.from(w.current.values());I.current={start:d,panStart:m.current};return}w.current.size===0&&(I.current=null)},[]),Y=t.useCallback((i,d,g,S)=>{l(!1);const x={x:m.current.x-i,y:m.current.y-d};s(b(x,g,S))},[b,l]),ee=t.useCallback((i,d,g,S)=>{const x=i<0?1.1:.9;l(!1),z(M.current*x,d,g,S)},[l,z]),W=t.useCallback(i=>{_.current=i},[]),le=t.useCallback((i,d,g,S,x)=>{if(ct(i.target))return;const U=i.metaKey||i.ctrlKey;if(i.key==="Escape"){i.preventDefault(),G();return}if(U){if(i.key==="="||i.key==="+"){i.preventDefault(),v(1.2,d,g);return}if(i.key==="-"){i.preventDefault(),v(1/1.2,d,g);return}if(i.key==="0"){i.preventDefault(),G();return}(i.key==="f"||i.key==="F")&&i.shiftKey&&(i.preventDefault(),A(S,d,g,x))}},[A,G,v]);return{pan:o,zoom:r,zoomPercent:h,transform:n,transitioning:f,zoomIn:L,zoomOut:$,resetView:G,fitToGraph:A,setAnimate:l,onPointerDown:u,onPointerMove:P,onPointerUp:D,onWheelPan:Y,onWheelZoom:ee,handleKeyDown:le,setGraphBounds:W}}function lt(o){const{upstreamMap:s,downstreamMap:r}=t.useMemo(()=>{const f=new Map,c=new Map;for(const m of o)f.set(m.id,new Set(m.dependencies??[])),c.has(m.id)||c.set(m.id,new Set);for(const m of o)for(const M of m.dependencies??[])c.has(M)||c.set(M,new Set),c.get(M)?.add(m.id);return{upstreamMap:f,downstreamMap:c}},[o]);return{getChain:t.useCallback(f=>{if(!s.has(f)&&!r.has(f))return new Set;const c=new Set([f]),m=(M,C)=>{const I=[M],w=new Set([M]);for(;I.length>0;){const T=I.shift();if(!T)continue;const _=C.get(T);if(_)for(const n of _)w.has(n)||(w.add(n),c.add(n),I.push(n))}};return m(f,s),m(f,r),c},[r,s])}}const Me="fusion-plugin-dependency-graph:positions";function fe(o){if(!o||typeof o!="object")return!1;const s=o;return typeof s.x=="number"&&Number.isFinite(s.x)&&typeof s.y=="number"&&Number.isFinite(s.y)}function dt(o){const s=Ye(Me,o);if(!s)return{};try{const r=JSON.parse(s);if(!r||typeof r!="object")return{};const a={};for(const[f,c]of Object.entries(r))fe(c)&&(a[f]=c);return a}catch{return{}}}function ft(o,s,r){const a={};for(const[f,c]of Object.entries(o))s.has(f)&&fe(c)&&(a[f]=c);je(Me,JSON.stringify(a),r)}function pt(o){Xe(Me,o)}function ht(o,s,r){const a={};for(const[f,c]of Object.entries(o))r.has(f)&&fe(c)&&(a[f]=c);for(const[f,c]of Object.entries(s))r.has(f)&&fe(c)&&(a[f]=c);return a}function mt(o,s){const r={};for(const[a,f]of Object.entries(o))s.has(a)&&(r[a]=f);return r}function gt({projectId:o,visibleTaskIds:s}){const[r,a]=t.useState(null);t.useEffect(()=>{a(dt(o))},[o]);const f=t.useCallback(m=>{ft(m,s,o),a(mt(m,s))},[o,s]),c=t.useCallback(()=>{pt(o),a(null)},[o]);return{savedPositions:r,persistPositions:f,clearSavedPositions:c}}const ae=280,Q=100,yt=768,Ce=4;function xt({tasks:o,projectId:s,onOpenTaskDetail:r,onOpenDetail:a,addToast:f,globalPaused:c,onUpdateTask:m,onArchiveTask:M,onUnarchiveTask:C,onDeleteTask:I,onRetryTask:w,onOpenDetailWithTab:T,taskStuckTimeoutMs:_,onOpenMission:n,onMoveTask:h,lastFetchTimeMs:l,workflowStepNameLookup:b}){const z=t.useRef(null),v=t.useRef(!1),L=t.useRef(null),$=t.useRef(!1),G=t.useRef(new Map),[A,u]=t.useState(null),[P,D]=t.useState(null),[Y,ee]=t.useState({width:0,height:0}),[W,le]=t.useState(new Map),i=t.useMemo(()=>rt(o),[o]),d=it(i),{getChain:g}=lt(i),S=A??P,x=t.useMemo(()=>S?g(S):new Set,[S,g]),U=t.useMemo(()=>{const e=Y.width||(typeof window<"u"?window.innerWidth:0);return(Y.height||(typeof window<"u"?window.innerHeight:0))>e||e<yt?"horizontal":"vertical"},[Y.height,Y.width]),O=t.useMemo(()=>({nodeWidth:ae,nodeHeight:Q,horizontalGap:40,verticalGap:80,orientation:U,measuredHeights:W}),[W,U]),j=t.useMemo(()=>we(d,O),[d,O]),B=t.useMemo(()=>new Set(i.map(e=>e.id)),[i]),{savedPositions:Z,persistPositions:K,clearSavedPositions:te}=gt({projectId:s,visibleTaskIds:B}),[X,re]=t.useState(j),[se,ne]=t.useState(!1);t.useEffect(()=>{const e={};for(const[y,H]of j.entries())e[y]=H;const p=Z?ht(e,Z,B):e;re(new Map(Object.entries(p)))},[j,Z,B]),t.useEffect(()=>{const e=z.current;if(!e)return;const p=(H,E)=>{ee(k=>k.width===H&&k.height===E?k:{width:H,height:E})};if(typeof ResizeObserver>"u"){p(e.clientWidth||(typeof window<"u"?window.innerWidth:0),e.clientHeight||(typeof window<"u"?window.innerHeight:0));return}p(e.clientWidth,e.clientHeight);const y=new ResizeObserver(H=>{const E=H[0];E&&p(E.contentRect.width,E.contentRect.height)});return y.observe(e),()=>y.disconnect()},[]),t.useEffect(()=>{const e=z.current;if(!e)return;const p=new Set(d.nodes.map(k=>k.task.id)),y=new Map;for(const k of p){const N=e.querySelector(`[data-testid="graph-task-node-${k}"]`);N&&y.set(k,N)}G.current=y,le(k=>{let N=!1;const F=new Map;for(const[oe,ie]of k.entries()){if(!p.has(oe)){N=!0;continue}F.set(oe,ie)}return N?F:k});const H=(k,N)=>{le(F=>{const oe=F.get(k);if(oe!==void 0&&Math.abs(oe-N)<1)return F;const ie=new Map(F);return ie.set(k,N),ie})};for(const[k,N]of y.entries())H(k,N.offsetHeight||Q);if(typeof ResizeObserver>"u")return;const E=new ResizeObserver(k=>{for(const N of k){const F=N.target,oe=Array.from(y.entries()).find(([,ie])=>ie===F)?.[0];oe&&H(oe,F.offsetHeight||Q)}});for(const k of y.values())E.observe(k);return()=>E.disconnect()},[d.nodes,X,Y.height,Y.width]);const{transform:he,zoom:de,transitioning:q,zoomIn:me,zoomOut:De,resetView:Re,fitToGraph:ge,onPointerDown:Ie,onPointerMove:ze,onPointerUp:be,onWheelPan:He,onWheelZoom:Ne,handleKeyDown:Oe,setGraphBounds:Pe}=ut();t.useEffect(()=>{if(v.current||i.length===0)return;if(!!(Z&&Object.keys(Z).length>0)){v.current=!0;return}const p=z.current;p&&(ge(X,p.clientWidth,p.clientHeight,{nodeWidth:ae,nodeHeight:Q,measuredHeights:W}),v.current=!0)},[i.length,ge,W,X,Z]);const V=t.useMemo(()=>{const e=Array.from(X.values());if(e.length===0)return{minX:0,minY:0,maxX:0,maxY:0,width:0,height:0};const p=Math.min(...e.map(k=>k.x)),y=Math.min(...e.map(k=>k.y)),H=Math.max(...e.map(k=>k.x+ae)),E=Math.max(...Array.from(X.entries()).map(([k,N])=>N.y+(W.get(k)??Q)));return{minX:p,minY:y,maxX:H,maxY:E,width:Math.max(0,H-p),height:Math.max(0,E-y)}},[W,X]),ye=t.useMemo(()=>{if(X.size===0)return X;const e=new Map;for(const[p,y]of X.entries())e.set(p,{x:y.x-V.minX,y:y.y-V.minY});return e},[V.minX,V.minY,X]);t.useEffect(()=>{Pe({minX:0,minY:0,maxX:V.width,maxY:V.height})},[V.height,V.width,Pe]);const Se=t.useCallback(()=>{te();const e=we(d,O);re(e)},[te,d,O]),_e=t.useCallback(()=>{const e={};for(const[p,y]of X.entries())e[p]=y;K(e)},[K,X]);return R.jsxs("section",{className:"dependency-graph","data-testid":"dependency-graph",children:[R.jsx("div",{ref:z,className:"dependency-graph__viewport",onPointerDown:e=>{se||(L.current={x:e.clientX,y:e.clientY},$.current=!1,Ie(e.pointerId,{x:e.clientX,y:e.clientY}))},onPointerMove:e=>{if(se)return;const p=z.current;if(!p)return;const y=L.current;if(y){const H=Math.abs(e.clientX-y.x),E=Math.abs(e.clientY-y.y);(H>Ce||E>Ce)&&($.current=!0)}ze(e.pointerId,{x:e.clientX,y:e.clientY},p.clientWidth,p.clientHeight)},onPointerUp:e=>{se||be(e.pointerId),L.current=null},onPointerCancel:e=>{se||be(e.pointerId),L.current=null,$.current=!1},onWheel:e=>{e.preventDefault();const p=z.current;if(p){if(e.ctrlKey||e.metaKey){const y=p.getBoundingClientRect();Ne(e.deltaY,{x:e.clientX-y.left,y:e.clientY-y.top},p.clientWidth,p.clientHeight);return}He(e.deltaX,e.deltaY,p.clientWidth,p.clientHeight)}},onKeyDown:e=>{const p=z.current;p&&Oe(e,p.clientWidth,p.clientHeight,ye,{nodeWidth:ae,nodeHeight:Q,measuredHeights:W})},tabIndex:0,onClick:()=>{$.current||se||D(null)},children:i.length===0?R.jsx("div",{className:"dependency-graph__empty",children:"No active tasks to display in graph view."}):R.jsxs("div",{className:`graph-canvas-transform${q?" graph-canvas-transform--animate":""}`,style:{transform:he,width:`${V.width}px`,height:`${V.height}px`},children:[R.jsx(nt,{edges:d.edges,positions:ye,nodeWidth:ae,nodeHeight:Q,nodeHeights:W,highlightedEdgeIds:x.size>0?new Set(d.edges.filter(e=>x.has(e.source)&&x.has(e.target)).map(e=>`${e.source}->${e.target}`)):void 0}),R.jsx("div",{className:"dependency-graph__nodes-layer",children:d.nodes.map(e=>{const p=ye.get(e.task.id);return p?R.jsx(We,{task:e.task,projectId:s,isSelected:P===e.task.id,style:{minHeight:`${Q}px`,left:`${p.x}px`,top:`${p.y}px`},position:p,scale:de,onNodePositionChange:(y,H)=>{re(E=>{const k={x:H.x+V.minX,y:H.y+V.minY},N=E.get(y);if(N&&N.x===k.x&&N.y===k.y)return E;const F=new Map(E);return F.set(y,k),F})},onNodeDragStateChange:ne,onNodeDragEnd:_e,isHighlighted:x.size>0&&x.has(e.task.id),isDimmed:x.size>0&&!x.has(e.task.id),onOpenDetail:a??(y=>r?.(y.id)),addToast:f??(()=>{}),globalPaused:c,onUpdateTask:m,onArchiveTask:M,onUnarchiveTask:C,onDeleteTask:I,onRetryTask:w,onOpenDetailWithTab:T,taskStuckTimeoutMs:_,onOpenMission:n,onMoveTask:h,lastFetchTimeMs:l,workflowStepNameLookup:b,onMouseEnter:()=>u(e.task.id),onMouseLeave:()=>u(null),onClick:y=>{y.stopPropagation(),$.current=!1,D(H=>H===e.task.id?null:e.task.id)}},e.task.id):null})})]})}),R.jsx(Qe,{zoom:de,onZoomIn:()=>{const e=z.current;e&&me(e.clientWidth,e.clientHeight)},onZoomOut:()=>{const e=z.current;e&&De(e.clientWidth,e.clientHeight)},onFitToGraph:()=>{Se();const e=z.current;if(!e)return;const p=we(d,O),y=new Map,H=Array.from(p.values()),E=H.length>0?Math.min(...H.map(N=>N.x)):0,k=H.length>0?Math.min(...H.map(N=>N.y)):0;for(const[N,F]of p.entries())y.set(N,{x:F.x-E,y:F.y-k});ge(y,e.clientWidth,e.clientHeight,{nodeWidth:ae,nodeHeight:Q,measuredHeights:W})},onResetView:()=>{Se(),Re()}})]})}function kt(o){return new Map((o??[]).map(s=>[s.id,s.name]))}function Tt({context:o}){return t.createElement(xt,{tasks:o?.tasks??[],projectId:o?.projectId,workflowStepNameLookup:kt(o?.workflowSteps),onOpenDetail:o?.openTaskDetail})}export{xt as DependencyGraph,Tt as DependencyGraphDashboardView,Tt as default};
21
+ */const qe=[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65",key:"13gj7c"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11",key:"durymu"}]],Je=pe("zoom-out",qe);function Qe({zoom:o,onZoomIn:s,onZoomOut:r,onFitToGraph:a,onResetView:f}){return R.jsxs("div",{className:"graph-toolbar","data-testid":"graph-toolbar",children:[R.jsx("button",{className:"btn btn-icon",title:"Zoom in (Ctrl+=)","aria-label":"Zoom in",onClick:s,children:R.jsx(Ke,{size:16})}),R.jsx("button",{className:"btn btn-icon",title:"Zoom out (Ctrl+-)","aria-label":"Zoom out",onClick:r,children:R.jsx(Je,{size:16})}),R.jsxs("div",{className:"graph-toolbar__zoom-label","aria-live":"polite",children:[Math.round(o*100),"%"]}),R.jsx("button",{className:"btn btn-icon",title:"Fit to graph (Ctrl+Shift+F)","aria-label":"Fit to graph",onClick:a,children:R.jsx(Fe,{size:16})}),R.jsx("button",{className:"btn btn-icon",title:"Reset view (Ctrl+0)","aria-label":"Reset view",onClick:f,children:R.jsx(Ze,{size:16})})]})}const et=280,tt=100;function nt({edges:o,positions:s,nodeWidth:r=et,nodeHeight:a=tt,nodeHeights:f,highlightedEdgeIds:c}){const m=!!(c&&c.size>0);return R.jsxs("svg",{className:"dependency-graph-edges","aria-hidden":"true",children:[R.jsx("defs",{children:R.jsx("marker",{id:"dependency-graph-arrowhead",markerWidth:"10",markerHeight:"7",refX:"10",refY:"3.5",orient:"auto",markerUnits:"strokeWidth",children:R.jsx("path",{d:"M 0 0 L 10 3.5 L 0 7 z",fill:"var(--border)"})})}),o.map(M=>{const C=s.get(M.source),I=s.get(M.target);if(!C||!I)return null;const w=`${M.source}->${M.target}`,T=m&&(c?.has(w)??!1),_=C.x+r/2,n=C.y+(f?.get(M.source)??a),h=I.x+r/2,l=I.y,b=n+(l-n)/2;return R.jsx("path",{"data-testid":"dependency-edge","data-edge-id":w,className:`dependency-graph-edge${T?" graph-edge--highlighted":""}${m&&!T?" graph-edge--dimmed":""}`,d:`M ${_} ${n} C ${_} ${b}, ${h} ${b}, ${h} ${l}`,fill:"none",stroke:T?"var(--todo)":"var(--border)",strokeWidth:T?"var(--space-xs)":"var(--btn-border-width)",opacity:m&&!T?.15:1,markerEnd:"url(#dependency-graph-arrowhead)",style:{transition:"opacity var(--transition-fast), stroke var(--transition-fast), stroke-width var(--transition-fast)"}},w)})]})}const ot=new Set(["triage","todo","in-progress","in-review"]);function rt(o){return o.filter(s=>ot.has(s.column))}const st={nodeWidth:280,nodeHeight:100,horizontalGap:40,verticalGap:80,orientation:"vertical"};function we(o,s){const r={...st,...s},a=o.nodes.map(n=>n.task.id);if(a.length===0)return new Map;const f=new Map,c=new Map;for(const n of a)c.set(n,0),f.set(n,[]);for(const n of o.edges)!c.has(n.source)||!c.has(n.target)||(f.get(n.target)?.push(n.source),c.set(n.source,(c.get(n.source)??0)+1));const m=a.filter(n=>(c.get(n)??0)===0),M=[];for(;m.length>0;){const n=m.shift();M.push(n);for(const h of f.get(n)??[]){const l=(c.get(h)??0)-1;c.set(h,l),l===0&&m.push(h)}}for(const n of a)M.includes(n)||M.push(n);const C=new Map;for(const n of M){const h=o.edges.filter(b=>b.source===n).map(b=>b.target);let l=0;for(const b of h)l=Math.max(l,(C.get(b)??0)+1);C.set(n,l)}const I=new Map;for(const n of a){const h=C.get(n)??0,l=I.get(h)??[];l.push(n),I.set(h,l)}const w=new Map,T=Array.from(I.keys()).sort((n,h)=>n-h),_=new Map;if(r.orientation==="vertical"){let n=0;for(const h of T){_.set(h,n);const l=I.get(h)??[],b=Math.max(r.nodeHeight,...l.map(z=>r.measuredHeights?.get(z)??r.nodeHeight));n+=b+r.verticalGap}}for(const n of T){const h=I.get(n)??[];if(h.sort(),r.orientation==="horizontal"){const L=-(h.reduce((X,u)=>X+(r.measuredHeights?.get(u)??r.nodeHeight),0)+Math.max(0,h.length-1)*r.verticalGap)/2,$=n*(r.nodeWidth+r.horizontalGap);let G=L;for(const X of h)w.set(X,{x:$,y:G}),G+=(r.measuredHeights?.get(X)??r.nodeHeight)+r.verticalGap;continue}const z=-(h.length*r.nodeWidth+Math.max(0,h.length-1)*r.horizontalGap)/2;h.forEach((v,L)=>{const $=z+L*(r.nodeWidth+r.horizontalGap),G=_.get(n)??n*(r.nodeHeight+r.verticalGap);w.set(v,{x:$,y:G})})}return w}function it(o){return t.useMemo(()=>{const s=o.map(f=>({task:f})),r=new Set(o.map(f=>f.id)),a=o.flatMap(f=>(f.dependencies??[]).filter(c=>r.has(c)).map(c=>({source:f.id,target:c})));return{nodes:s,edges:a}},[o])}const ce=.1,ue=3,Te=40,at=200;function J(o,s,r){return Math.min(r,Math.max(s,o))}function ct(o){if(!(o instanceof HTMLElement))return!1;const s=o.tagName.toLowerCase();return o.isContentEditable||s==="input"||s==="textarea"||s==="select"}function ut(){const[o,s]=t.useState({x:0,y:0}),[r,a]=t.useState(1),[f,c]=t.useState(!1),m=t.useRef(o),M=t.useRef(r),C=t.useRef(null),I=t.useRef(null),w=t.useRef(new Map),T=t.useRef(null),_=t.useRef({minX:0,minY:0,maxX:0,maxY:0});t.useEffect(()=>{m.current=o},[o]),t.useEffect(()=>{M.current=r},[r]),t.useEffect(()=>()=>{C.current!==null&&window.clearTimeout(C.current)},[]);const n=t.useMemo(()=>`translate(${o.x}px, ${o.y}px) scale(${r})`,[o.x,o.y,r]),h=t.useMemo(()=>Math.round(r*100),[r]),l=t.useCallback(i=>{if(!i){C.current!==null&&(window.clearTimeout(C.current),C.current=null),c(!1);return}c(!0),C.current!==null&&window.clearTimeout(C.current),C.current=window.setTimeout(()=>{c(!1),C.current=null},at)},[]),b=t.useCallback((i,d,g,S=M.current)=>{const x=_.current;if(x.maxX<=x.minX||x.maxY<=x.minY)return{x:J(i.x,-d,d),y:J(i.y,-g,g)};const U=d-x.maxX*S,O=-x.minX*S,j=g-x.maxY*S,B=-x.minY*S,Z=U>O?(U+O)/2:J(i.x,U,O),K=j>B?(j+B)/2:J(i.y,j,B);return{x:Z,y:K}},[]),z=t.useCallback((i,d,g,S)=>{const x=M.current,U=m.current,O=J(i,ce,ue),j=O/x,B=b({x:d.x-(d.x-U.x)*j,y:d.y-(d.y-U.y)*j},g,S,O);a(O),s(B)},[b]),v=t.useCallback((i,d,g,S)=>{l(!1);const x=S??{x:d/2,y:g/2};z(M.current*i,x,d,g)},[l,z]),L=t.useCallback((i,d)=>{if(i&&d){v(1.2,i,d);return}a(g=>J(g+.1,ce,ue))},[v]),$=t.useCallback((i,d)=>{if(i&&d){v(1/1.2,i,d);return}a(g=>J(g-.1,ce,ue))},[v]),G=t.useCallback(()=>{l(!0),s({x:0,y:0}),a(1)},[l]),X=t.useCallback((i,d,g,S)=>{if(l(!0),i.size===0){s({x:0,y:0}),a(1);return}const x=S?.nodeWidth??280,U=S?.nodeHeight??100,O=Array.from(i.entries()),j=Math.min(...O.map(([,q])=>q.x)),B=Math.min(...O.map(([,q])=>q.y)),Z=Math.max(...O.map(([,q])=>q.x+x)),K=Math.max(...O.map(([q,me])=>me.y+(S?.measuredHeights?.get(q)??U))),te=Math.max(1,Z-j),A=Math.max(1,K-B),re=Math.max(1,d-Te*2),se=Math.max(1,g-Te*2),ne=J(Math.min(re/te,se/A),ce,ue),he=(d-te*ne)/2-j*ne,de=(g-A*ne)/2-B*ne;a(ne),s(b({x:he,y:de},d,g,ne))},[b,l]),u=t.useCallback((i,d)=>{if(w.current.set(i,d),w.current.size===2){const[g,S]=Array.from(w.current.values());T.current={distance:Math.hypot(g.x-S.x,g.y-S.y),zoom:M.current,pan:m.current,midpoint:{x:(g.x+S.x)/2,y:(g.y+S.y)/2}},I.current=null;return}I.current={start:d,panStart:m.current}},[]),P=t.useCallback((i,d,g,S)=>{if(w.current.has(i)&&w.current.set(i,d),w.current.size===2&&T.current){l(!1);const[O,j]=Array.from(w.current.values()),Z=Math.hypot(O.x-j.x,O.y-j.y)/Math.max(1,T.current.distance),K={x:(O.x+j.x)/2,y:(O.y+j.y)/2},te=J(T.current.zoom*Z,ce,ue),A=te/T.current.zoom,re=b({x:K.x-(T.current.midpoint.x-T.current.pan.x)*A,y:K.y-(T.current.midpoint.y-T.current.pan.y)*A},g,S);a(te),s(re);return}const x=I.current;if(!x)return;l(!1);const U={x:x.panStart.x+(d.x-x.start.x),y:x.panStart.y+(d.y-x.start.y)};s(b(U,g,S))},[b,l]),D=t.useCallback(i=>{if(w.current.delete(i),w.current.size<2&&(T.current=null),w.current.size===1){const[d]=Array.from(w.current.values());I.current={start:d,panStart:m.current};return}w.current.size===0&&(I.current=null)},[]),Y=t.useCallback((i,d,g,S)=>{l(!1);const x={x:m.current.x-i,y:m.current.y-d};s(b(x,g,S))},[b,l]),ee=t.useCallback((i,d,g,S)=>{const x=i<0?1.1:.9;l(!1),z(M.current*x,d,g,S)},[l,z]),W=t.useCallback(i=>{_.current=i},[]),le=t.useCallback((i,d,g,S,x)=>{if(ct(i.target))return;const U=i.metaKey||i.ctrlKey;if(i.key==="Escape"){i.preventDefault(),G();return}if(U){if(i.key==="="||i.key==="+"){i.preventDefault(),v(1.2,d,g);return}if(i.key==="-"){i.preventDefault(),v(1/1.2,d,g);return}if(i.key==="0"){i.preventDefault(),G();return}(i.key==="f"||i.key==="F")&&i.shiftKey&&(i.preventDefault(),X(S,d,g,x))}},[X,G,v]);return{pan:o,zoom:r,zoomPercent:h,transform:n,transitioning:f,zoomIn:L,zoomOut:$,resetView:G,fitToGraph:X,setAnimate:l,onPointerDown:u,onPointerMove:P,onPointerUp:D,onWheelPan:Y,onWheelZoom:ee,handleKeyDown:le,setGraphBounds:W}}function lt(o){const{upstreamMap:s,downstreamMap:r}=t.useMemo(()=>{const f=new Map,c=new Map;for(const m of o)f.set(m.id,new Set(m.dependencies??[])),c.has(m.id)||c.set(m.id,new Set);for(const m of o)for(const M of m.dependencies??[])c.has(M)||c.set(M,new Set),c.get(M)?.add(m.id);return{upstreamMap:f,downstreamMap:c}},[o]);return{getChain:t.useCallback(f=>{if(!s.has(f)&&!r.has(f))return new Set;const c=new Set([f]),m=(M,C)=>{const I=[M],w=new Set([M]);for(;I.length>0;){const T=I.shift();if(!T)continue;const _=C.get(T);if(_)for(const n of _)w.has(n)||(w.add(n),c.add(n),I.push(n))}};return m(f,s),m(f,r),c},[r,s])}}const Me="fusion-plugin-dependency-graph:positions";function fe(o){if(!o||typeof o!="object")return!1;const s=o;return typeof s.x=="number"&&Number.isFinite(s.x)&&typeof s.y=="number"&&Number.isFinite(s.y)}function dt(o){const s=Ye(Me,o);if(!s)return{};try{const r=JSON.parse(s);if(!r||typeof r!="object")return{};const a={};for(const[f,c]of Object.entries(r))fe(c)&&(a[f]=c);return a}catch{return{}}}function ft(o,s,r){const a={};for(const[f,c]of Object.entries(o))s.has(f)&&fe(c)&&(a[f]=c);je(Me,JSON.stringify(a),r)}function pt(o){Ae(Me,o)}function ht(o,s,r){const a={};for(const[f,c]of Object.entries(o))r.has(f)&&fe(c)&&(a[f]=c);for(const[f,c]of Object.entries(s))r.has(f)&&fe(c)&&(a[f]=c);return a}function mt(o,s){const r={};for(const[a,f]of Object.entries(o))s.has(a)&&(r[a]=f);return r}function gt({projectId:o,visibleTaskIds:s}){const[r,a]=t.useState(null);t.useEffect(()=>{a(dt(o))},[o]);const f=t.useCallback(m=>{ft(m,s,o),a(mt(m,s))},[o,s]),c=t.useCallback(()=>{pt(o),a(null)},[o]);return{savedPositions:r,persistPositions:f,clearSavedPositions:c}}const ae=280,Q=100,yt=768,Ce=4;function xt({tasks:o,projectId:s,onOpenTaskDetail:r,onOpenDetail:a,addToast:f,globalPaused:c,onUpdateTask:m,onArchiveTask:M,onUnarchiveTask:C,onDeleteTask:I,onRetryTask:w,onOpenDetailWithTab:T,taskStuckTimeoutMs:_,onOpenMission:n,onMoveTask:h,lastFetchTimeMs:l,workflowStepNameLookup:b}){const z=t.useRef(null),v=t.useRef(!1),L=t.useRef(null),$=t.useRef(!1),G=t.useRef(new Map),[X,u]=t.useState(null),[P,D]=t.useState(null),[Y,ee]=t.useState({width:0,height:0}),[W,le]=t.useState(new Map),i=t.useMemo(()=>rt(o),[o]),d=it(i),{getChain:g}=lt(i),S=X??P,x=t.useMemo(()=>S?g(S):new Set,[S,g]),U=t.useMemo(()=>{const e=Y.width||(typeof window<"u"?window.innerWidth:0);return(Y.height||(typeof window<"u"?window.innerHeight:0))>e||e<yt?"horizontal":"vertical"},[Y.height,Y.width]),O=t.useMemo(()=>({nodeWidth:ae,nodeHeight:Q,horizontalGap:40,verticalGap:80,orientation:U,measuredHeights:W}),[W,U]),j=t.useMemo(()=>we(d,O),[d,O]),B=t.useMemo(()=>new Set(i.map(e=>e.id)),[i]),{savedPositions:Z,persistPositions:K,clearSavedPositions:te}=gt({projectId:s,visibleTaskIds:B}),[A,re]=t.useState(j),[se,ne]=t.useState(!1);t.useEffect(()=>{const e={};for(const[y,H]of j.entries())e[y]=H;const p=Z?ht(e,Z,B):e;re(new Map(Object.entries(p)))},[j,Z,B]),t.useEffect(()=>{const e=z.current;if(!e)return;const p=(H,E)=>{ee(k=>k.width===H&&k.height===E?k:{width:H,height:E})};if(typeof ResizeObserver>"u"){p(e.clientWidth||(typeof window<"u"?window.innerWidth:0),e.clientHeight||(typeof window<"u"?window.innerHeight:0));return}p(e.clientWidth,e.clientHeight);const y=new ResizeObserver(H=>{const E=H[0];E&&p(E.contentRect.width,E.contentRect.height)});return y.observe(e),()=>y.disconnect()},[]),t.useEffect(()=>{const e=z.current;if(!e)return;const p=new Set(d.nodes.map(k=>k.task.id)),y=new Map;for(const k of p){const N=e.querySelector(`[data-testid="graph-task-node-${k}"]`);N&&y.set(k,N)}G.current=y,le(k=>{let N=!1;const F=new Map;for(const[oe,ie]of k.entries()){if(!p.has(oe)){N=!0;continue}F.set(oe,ie)}return N?F:k});const H=(k,N)=>{le(F=>{const oe=F.get(k);if(oe!==void 0&&Math.abs(oe-N)<1)return F;const ie=new Map(F);return ie.set(k,N),ie})};for(const[k,N]of y.entries())H(k,N.offsetHeight||Q);if(typeof ResizeObserver>"u")return;const E=new ResizeObserver(k=>{for(const N of k){const F=N.target,oe=Array.from(y.entries()).find(([,ie])=>ie===F)?.[0];oe&&H(oe,F.offsetHeight||Q)}});for(const k of y.values())E.observe(k);return()=>E.disconnect()},[d.nodes,A,Y.height,Y.width]);const{transform:he,zoom:de,transitioning:q,zoomIn:me,zoomOut:De,resetView:Re,fitToGraph:ge,onPointerDown:Ie,onPointerMove:ze,onPointerUp:be,onWheelPan:He,onWheelZoom:Ne,handleKeyDown:Oe,setGraphBounds:Pe}=ut();t.useEffect(()=>{if(v.current||i.length===0)return;if(!!(Z&&Object.keys(Z).length>0)){v.current=!0;return}const p=z.current;p&&(ge(A,p.clientWidth,p.clientHeight,{nodeWidth:ae,nodeHeight:Q,measuredHeights:W}),v.current=!0)},[i.length,ge,W,A,Z]);const V=t.useMemo(()=>{const e=Array.from(A.values());if(e.length===0)return{minX:0,minY:0,maxX:0,maxY:0,width:0,height:0};const p=Math.min(...e.map(k=>k.x)),y=Math.min(...e.map(k=>k.y)),H=Math.max(...e.map(k=>k.x+ae)),E=Math.max(...Array.from(A.entries()).map(([k,N])=>N.y+(W.get(k)??Q)));return{minX:p,minY:y,maxX:H,maxY:E,width:Math.max(0,H-p),height:Math.max(0,E-y)}},[W,A]),ye=t.useMemo(()=>{if(A.size===0)return A;const e=new Map;for(const[p,y]of A.entries())e.set(p,{x:y.x-V.minX,y:y.y-V.minY});return e},[V.minX,V.minY,A]);t.useEffect(()=>{Pe({minX:0,minY:0,maxX:V.width,maxY:V.height})},[V.height,V.width,Pe]);const Se=t.useCallback(()=>{te();const e=we(d,O);re(e)},[te,d,O]),_e=t.useCallback(()=>{const e={};for(const[p,y]of A.entries())e[p]=y;K(e)},[K,A]);return R.jsxs("section",{className:"dependency-graph","data-testid":"dependency-graph",children:[R.jsx("div",{ref:z,className:"dependency-graph__viewport",onPointerDown:e=>{se||(L.current={x:e.clientX,y:e.clientY},$.current=!1,Ie(e.pointerId,{x:e.clientX,y:e.clientY}))},onPointerMove:e=>{if(se)return;const p=z.current;if(!p)return;const y=L.current;if(y){const H=Math.abs(e.clientX-y.x),E=Math.abs(e.clientY-y.y);(H>Ce||E>Ce)&&($.current=!0)}ze(e.pointerId,{x:e.clientX,y:e.clientY},p.clientWidth,p.clientHeight)},onPointerUp:e=>{se||be(e.pointerId),L.current=null},onPointerCancel:e=>{se||be(e.pointerId),L.current=null,$.current=!1},onWheel:e=>{e.preventDefault();const p=z.current;if(p){if(e.ctrlKey||e.metaKey){const y=p.getBoundingClientRect();Ne(e.deltaY,{x:e.clientX-y.left,y:e.clientY-y.top},p.clientWidth,p.clientHeight);return}He(e.deltaX,e.deltaY,p.clientWidth,p.clientHeight)}},onKeyDown:e=>{const p=z.current;p&&Oe(e,p.clientWidth,p.clientHeight,ye,{nodeWidth:ae,nodeHeight:Q,measuredHeights:W})},tabIndex:0,onClick:()=>{$.current||se||D(null)},children:i.length===0?R.jsx("div",{className:"dependency-graph__empty",children:"No active tasks to display in graph view."}):R.jsxs("div",{className:`graph-canvas-transform${q?" graph-canvas-transform--animate":""}`,style:{transform:he,width:`${V.width}px`,height:`${V.height}px`},children:[R.jsx(nt,{edges:d.edges,positions:ye,nodeWidth:ae,nodeHeight:Q,nodeHeights:W,highlightedEdgeIds:x.size>0?new Set(d.edges.filter(e=>x.has(e.source)&&x.has(e.target)).map(e=>`${e.source}->${e.target}`)):void 0}),R.jsx("div",{className:"dependency-graph__nodes-layer",children:d.nodes.map(e=>{const p=ye.get(e.task.id);return p?R.jsx(We,{task:e.task,projectId:s,isSelected:P===e.task.id,style:{minHeight:`${Q}px`,left:`${p.x}px`,top:`${p.y}px`},position:p,scale:de,onNodePositionChange:(y,H)=>{re(E=>{const k={x:H.x+V.minX,y:H.y+V.minY},N=E.get(y);if(N&&N.x===k.x&&N.y===k.y)return E;const F=new Map(E);return F.set(y,k),F})},onNodeDragStateChange:ne,onNodeDragEnd:_e,isHighlighted:x.size>0&&x.has(e.task.id),isDimmed:x.size>0&&!x.has(e.task.id),onOpenDetail:a??(y=>r?.(y.id)),addToast:f??(()=>{}),globalPaused:c,onUpdateTask:m,onArchiveTask:M,onUnarchiveTask:C,onDeleteTask:I,onRetryTask:w,onOpenDetailWithTab:T,taskStuckTimeoutMs:_,onOpenMission:n,onMoveTask:h,lastFetchTimeMs:l,workflowStepNameLookup:b,onMouseEnter:()=>u(e.task.id),onMouseLeave:()=>u(null),onClick:y=>{y.stopPropagation(),$.current=!1,D(H=>H===e.task.id?null:e.task.id)}},e.task.id):null})})]})}),R.jsx(Qe,{zoom:de,onZoomIn:()=>{const e=z.current;e&&me(e.clientWidth,e.clientHeight)},onZoomOut:()=>{const e=z.current;e&&De(e.clientWidth,e.clientHeight)},onFitToGraph:()=>{Se();const e=z.current;if(!e)return;const p=we(d,O),y=new Map,H=Array.from(p.values()),E=H.length>0?Math.min(...H.map(N=>N.x)):0,k=H.length>0?Math.min(...H.map(N=>N.y)):0;for(const[N,F]of p.entries())y.set(N,{x:F.x-E,y:F.y-k});ge(y,e.clientWidth,e.clientHeight,{nodeWidth:ae,nodeHeight:Q,measuredHeights:W})},onResetView:()=>{Se(),Re()}})]})}function kt(o){return new Map((o??[]).map(s=>[s.id,s.name]))}function Tt({context:o}){return t.createElement(xt,{tasks:o?.tasks??[],projectId:o?.projectId,workflowStepNameLookup:kt(o?.workflowSteps),onOpenDetail:o?.openTaskDetail})}export{xt as DependencyGraph,Tt as DependencyGraphDashboardView,Tt as default};
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-B9Ro_NwC.js";/**
1
+ import{c as a}from"./index-w1dPHtmq.js";/**
2
2
  * @license lucide-react v1.7.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.