@runfusion/fusion 0.41.0 → 0.42.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 (83) hide show
  1. package/dist/bin.js +44240 -41922
  2. package/dist/client/.vite/manifest.json +72 -72
  3. package/dist/client/assets/AgentDetailView-C5Lb3fd3.js +18 -0
  4. package/dist/client/assets/AgentDetailView-DiWELtb1.css +1 -0
  5. package/dist/client/assets/{AgentPermissionPolicyEditor-VDXL4XQc.js → AgentPermissionPolicyEditor-DtRcvE6M.js} +2 -2
  6. package/dist/client/assets/{AgentsView-ChXccELt.js → AgentsView-BVW-NOYD.js} +3 -3
  7. package/dist/client/assets/ChatView-Dy-oIkrK.js +6 -0
  8. package/dist/client/assets/{DevServerView-DGOahw1o.js → DevServerView-DLsFSP4s.js} +1 -1
  9. package/dist/client/assets/{DirectoryPicker-DgqHlxyh.js → DirectoryPicker-_QawX-uL.js} +1 -1
  10. package/dist/client/assets/{DocumentsView-CbbZwzbH.js → DocumentsView-DierUJsj.js} +1 -1
  11. package/dist/client/assets/{EvalsView-BL_ue7fJ.js → EvalsView-B83lYKQl.js} +1 -1
  12. package/dist/client/assets/{ExperimentalAgentOnboardingModal-8H4XAu4O.js → ExperimentalAgentOnboardingModal-CTctYTPU.js} +1 -1
  13. package/dist/client/assets/{GoalsView-CO4FVL3E.js → GoalsView-CKn8i0i0.js} +1 -1
  14. package/dist/client/assets/{InsightsView-C5vLvWVE.js → InsightsView-EpRHCD8G.js} +1 -1
  15. package/dist/client/assets/{MemoryView-BL3W3yOv.js → MemoryView-Df_ocTc5.js} +2 -2
  16. package/dist/client/assets/NodesView-DF7xJ_3z.js +14 -0
  17. package/dist/client/assets/{PiExtensionsManager-HvSiVeDN.js → PiExtensionsManager-BOooOEDx.js} +2 -2
  18. package/dist/client/assets/{PluginManager-DIjrlhnU.js → PluginManager-CHrDAzK6.js} +1 -1
  19. package/dist/client/assets/{PullRequestView-C2jQX8xZ.js → PullRequestView-CJU21OZ6.js} +2 -2
  20. package/dist/client/assets/{ReliabilityView-DbqEwoRs.js → ReliabilityView-uHkW1Qeu.js} +1 -1
  21. package/dist/client/assets/{ResearchView-C1QghmLI.js → ResearchView-oZ2-vbjL.js} +1 -1
  22. package/dist/client/assets/{SecretsView-Y2MQ-9n5.js → SecretsView-BpkqSV_E.js} +1 -1
  23. package/dist/client/assets/SessionTerminal-D9IW4cDj.js +2 -0
  24. package/dist/client/assets/{SettingsModal-DabcZZ6S.js → SettingsModal-BmB5l2bA.js} +1 -1
  25. package/dist/client/assets/SettingsModal-C8gsAazm.js +31 -0
  26. package/dist/client/assets/{SetupWizardModal-Db-Rxinm.js → SetupWizardModal-BYLEU_7o.js} +1 -1
  27. package/dist/client/assets/{SkillsView-CIEY1-DE.js → SkillsView-8GgQ8Z_Z.js} +1 -1
  28. package/dist/client/assets/{StashRecoveryView-B6iDu5tI.js → StashRecoveryView-CT1t1Uf2.js} +1 -1
  29. package/dist/client/assets/{TodoView-B8IK_BPM.js → TodoView-BUj6ITAb.js} +2 -2
  30. package/dist/client/assets/WorkflowNodeEditor-CN7GPmvV.js +8 -0
  31. package/dist/client/assets/WorkflowNodeEditor-aPj8cv81.css +1 -0
  32. package/dist/client/assets/app-B2ZxMfJT.js +13 -0
  33. package/dist/client/assets/app-BffGU_HQ.js +13 -0
  34. package/dist/client/assets/app-C8AHhs5N.js +13 -0
  35. package/dist/client/assets/app-DCot4oXA.js +13 -0
  36. package/dist/client/assets/app-Ri9Te2Dv.js +13 -0
  37. package/dist/client/assets/app-sEkTyT-w.js +13 -0
  38. package/dist/client/assets/{dashboard-view-O5j3PSGY.js → dashboard-view-C3SsjXo1.js} +1621 -1621
  39. package/dist/client/assets/{dashboard-view-Dn4CztR6.js → dashboard-view-CrYwb0oQ.js} +1 -1
  40. package/dist/client/assets/dashboard-view-Du53JbmQ.css +1 -0
  41. package/dist/client/assets/{folder-open-C9XAaduE.js → folder-open-CREXTATY.js} +1 -1
  42. package/dist/client/assets/index-2kYpdJrx.js +793 -0
  43. package/dist/client/assets/index-CJUfvGdC.css +1 -0
  44. package/dist/client/assets/{upload-BRAEugYV.js → upload-BvLUlwaH.js} +1 -1
  45. package/dist/client/assets/{users-BlflbMZ3.js → users-CjhbU-sF.js} +1 -1
  46. package/dist/client/index.html +2 -2
  47. package/dist/client/version.json +1 -1
  48. package/dist/droid-cli/package.json +1 -1
  49. package/dist/extension.js +43622 -41519
  50. package/dist/pi-claude-cli/package.json +1 -1
  51. package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
  52. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  53. package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +59 -8
  54. package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
  55. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  56. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  57. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  58. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  59. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  60. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  61. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  62. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  63. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  64. package/package.json +2 -1
  65. package/skill/fusion/references/extension-tools.md +3 -3
  66. package/skill/fusion/references/fusion-capabilities.md +2 -2
  67. package/dist/client/assets/AgentDetailView-CY-O6VkV.css +0 -1
  68. package/dist/client/assets/AgentDetailView-krC0B2O0.js +0 -18
  69. package/dist/client/assets/ChatView-Dz_xBKit.js +0 -6
  70. package/dist/client/assets/NodesView-DfBNNm9c.js +0 -14
  71. package/dist/client/assets/SessionTerminal-DaTXNT3A.js +0 -2
  72. package/dist/client/assets/SettingsModal-BAzm2kYd.js +0 -31
  73. package/dist/client/assets/WorkflowNodeEditor-DaPyvD_R.js +0 -8
  74. package/dist/client/assets/WorkflowNodeEditor-Po5uv_dN.css +0 -1
  75. package/dist/client/assets/app-CTRT_hQh.js +0 -13
  76. package/dist/client/assets/app-CVg6W-HU.js +0 -13
  77. package/dist/client/assets/app-CY3pQXOr.js +0 -13
  78. package/dist/client/assets/app-DNh04p5I.js +0 -13
  79. package/dist/client/assets/app-DhHgtB9j.js +0 -13
  80. package/dist/client/assets/app-NL_hPGDS.js +0 -13
  81. package/dist/client/assets/dashboard-view-BgiLoG1G.css +0 -1
  82. package/dist/client/assets/index-BHGM5W8a.css +0 -1
  83. package/dist/client/assets/index-CgfrecpF.js +0 -793
@@ -0,0 +1,8 @@
1
+ import{r as o,j as e,b as Ga}from"./vendor-react-D37HfzIf.js";import{R as Ha,u as Ua,a as Ka,b as Ya,i as Ja,B as Xa,C as Qa,M as Za}from"./vendor-reactflow-CRZcPCXF.js";import{c as eo,ev as Vt,ew as _e,ex as la,ey as to,ez as so,eA as ao,eB as ia,z as ae,j as ut,J as Ne,T as Re,B as oo,aj as no,a as je,U as ke,b8 as ra,dP as lo,i as ft,dQ as Fs,ao as da,b7 as qt,b as Pe,m as Gt,b6 as io,eC as ro,eD as co,eE as uo,eF as fo,dV as mo,p as po,cS as Is,v as wo,eG as ho,eH as go,eI as xo,eJ as bo,eK as ko,eL as vo,dN as jo,eM as No,eN as yo,eO as Co,eP as Ms,eQ as As,eR as Ps,eS as So,eT as Eo,eU as Fo,eV as Io,eW as Mo,eX as Ao,eY as Po,eZ as Ro,e_ as Do,e$ as zo,f0 as Rs,f1 as To,f2 as Ds,f3 as zs,f4 as Lo,f5 as Lt,f6 as Oo,f7 as ca,f8 as $o,f9 as Ts,fa as Wo,bU as Ls,el as ua,M as _o,X as Ht,L as Fe,bL as Bo,fb as Ot,cE as fa,bx as Vo,ep as qo,by as Go,b0 as Ho,cI as Uo,fc as Ko,fd as Yo,fe as Jo,ff as Os,fg as Xo,fh as Qo,fi as Zo,b3 as ct,av as $e,fj as en,fk as tn,fl as sn,fm as an,cs as on,fn as nn,fo as ln}from"./index-2kYpdJrx.js";import{u as ve}from"./vendor-i18n-CV0mwX_-.js";import{U as rn}from"./upload-BvLUlwaH.js";import"./vendor-xterm-tcedd2Jt.js";import"./vendor-codemirror-jBKmHyH0.js";/**
2
+ * @license lucide-react v1.7.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const dn=[["path",{d:"m16 6 4 14",key:"ji33uf"}],["path",{d:"M12 6v14",key:"1n7gus"}],["path",{d:"M8 8v12",key:"1gg7y9"}],["path",{d:"M4 4v16",key:"6qkkli"}]],cn=eo("library",dn),un=80,fn=24,$s=16,Ws=to+un,mn=0,pn=0,$t=la+fn;function wn(a){return!(_e(a.id)||a.parentId)}function hn(a,d){const i=new Set(a),g=new Map,l=new Map;for(const N of a)l.set(N,0);for(const N of d)N.data?.kind!=="rework"&&(!i.has(N.source)||!i.has(N.target)||N.source!==N.target&&((g.get(N.source)??g.set(N.source,[]).get(N.source)).push(N.target),l.set(N.target,(l.get(N.target)??0)+1)));const w=a.filter(N=>N==="start"),D=w.length?w:a.filter(N=>(l.get(N)??0)===0),u=new Map,R=a.length+1,M=[];for(const N of D)u.set(N,0),M.push(N);let C=a.length*a.length+a.length+1;for(;M.length&&C-- >0;){const N=M.shift(),p=u.get(N)??0;for(const c of g.get(N)??[]){const j=p+1,h=u.get(c);(h===void 0||j>h)&&j<=R&&(u.set(c,j),M.push(c))}}let z=0;for(const N of u.values())N>z&&(z=N);const x=u.size?z+1:0;for(const N of a)u.has(N)||u.set(N,x);return u}function _s(a,d,i){const g=a.filter(wn),l=g.map(C=>C.id),w=hn(l,d),D=new Map(g.map(C=>[C.id,C])),u=new Map,R=new Map;for(const C of l){const z=w.get(C)??0;(R.get(z)??R.set(z,[]).get(z)).push(C)}const M=i.length>0;for(const[C,z]of R){const x=[...z].sort((c,j)=>{const h=D.get(c),T=D.get(j);return h.position.y!==T.position.y?h.position.y-T.position.y:c<j?-1:c>j?1:0}),N=mn+C*Ws;if(!M){x.forEach((c,j)=>{u.set(c,{x:N,y:pn+j*$t})});continue}const p=new Map;for(const c of x){const j=D.get(c),h=j.data.column??(Vt(j.position.y,i)?Vt(j.position.y,i):void 0);if(!h){u.set(c,{x:N,y:j.position.y});continue}const T=i.findIndex(v=>v.id===h),k=T>=0?T:0,P=so(k),U=P+$s,ee=P+ao-la-$s,B=Math.max(1,Math.floor((ee-U)/$t)+1),K=p.get(h??`__idx${k}`)??0,de=K%B,_=Math.floor(K/B),Y=U+de*$t,ce=N+_*(Ws/2);u.set(c,{x:ce,y:Y}),p.set(h??`__idx${k}`,K+1)}}return u}function Bs(a,d){return a.map(i=>{const g=d.get(i.id);return g?{...i,position:g}:i})}let Vs=0;function gn(){return Vs+=1,`col-${Date.now().toString(36)}-${Vs}`}function qs({columns:a,onChange:d,violations:i,readOnly:g,projectId:l,addToast:w,columnAgentsEnabled:D}){const{t:u}=ve("app"),[R,M]=o.useState([]),[C,z]=o.useState([]),[x,N]=o.useState(!0),[p,c]=o.useState(null);o.useEffect(()=>{let v=!1;return ia(l).then(S=>{v||M(S)}).catch(S=>{v||w(ae(S)||u("workflowColumns.traitsLoadFailed","Failed to load traits"),"error")}),()=>{v=!0}},[l,w,u]),o.useEffect(()=>{let v=!1;return N(!0),c(null),Promise.resolve(ut(void 0,l)).then(S=>{v||(z(S??[]),N(!1))}).catch(S=>{if(v)return;const $=ae(S)||u("workflowColumns.agentsLoadFailed","Failed to load agents");c($),N(!1),w($,"error")}),()=>{v=!0}},[l,w,u]);const j=o.useMemo(()=>C.map(v=>v.id).join(","),[C]),h=o.useMemo(()=>{const v=new Map;for(const S of C)v.set(S.id,S);return v},[j]),T=o.useCallback((v,S)=>{d(a.map($=>{if($.id!==v)return $;if(!S){const{agent:W,...ne}=$;return ne}return{...$,agent:S}}))},[a,d]),k=o.useCallback((v,S)=>{if(!S){T(v,void 0);return}const $=a.find(W=>W.id===v)?.agent;T(v,{agentId:S,mode:$?.mode??"defer"})},[a,T]),P=o.useCallback((v,S)=>{const $=a.find(W=>W.id===v)?.agent;$&&T(v,{...$,mode:S})},[a,T]),U=g||!D||x||!!p,ee=i.filter(v=>v.columnId===null),B=o.useCallback(v=>i.filter(S=>S.columnId===v),[i]),K=o.useCallback(()=>{const v=gn();d([...a,{id:v,name:u("workflowColumns.newColumnName","New column"),traits:[]}])},[a,d,u]),de=o.useCallback((v,S)=>{d(a.map($=>$.id===v?{...$,name:S}:$))},[a,d]),_=o.useCallback(v=>{d(a.filter(S=>S.id!==v))},[a,d]),Y=o.useCallback((v,S)=>{const $=v+S;if($<0||$>=a.length)return;const W=[...a];[W[v],W[$]]=[W[$],W[v]],d(W)},[a,d]),ce=o.useCallback((v,S)=>{d(a.map($=>{if($.id!==v)return $;const W=$.traits.some(ne=>ne.trait===S);return{...$,traits:W?$.traits.filter(ne=>ne.trait!==S):[...$.traits,{trait:S}]}}))},[a,d]);return e.jsxs("aside",{className:"wf-column-panel","data-testid":"wf-column-panel",children:[e.jsxs("header",{className:"wf-column-panel-header",children:[e.jsx("h3",{children:u("workflowColumns.title","Columns")}),e.jsxs("button",{className:"wf-column-add",onClick:K,disabled:g,title:g?u("workflowColumns.readOnlyHint","Built-in workflows are read-only — duplicate to edit"):void 0,children:[e.jsx(Ne,{size:13})," ",u("workflowColumns.add","Add column")]})]}),ee.length>0&&e.jsx("div",{className:"wf-column-panel-errors",role:"alert",children:ee.map((v,S)=>e.jsxs("p",{className:"wf-column-violation",children:[e.jsx(Re,{size:12,"aria-hidden":!0})," ",v.message]},`${v.code}-${S}`))}),a.length===0?e.jsx("p",{className:"wf-column-panel-empty",children:u("workflowColumns.empty","No columns yet. Add a column to place nodes into board lanes.")}):e.jsx("ul",{className:"wf-column-list",children:a.map((v,S)=>{const $=B(v.id),W=v.agent?.agentId,ne=W?h.get(W):void 0,re=!!W&&!x&&!p&&!ne,le=ne?.name??(re?u("workflowColumns.agentNotFound","Agent not found — {{id}}",{id:W??""}):W);return e.jsxs("li",{className:`wf-column-item${$.length?" wf-column-item--error":""}`,"data-testid":`wf-column-${v.id}`,"data-column-error":$.length?"true":void 0,children:[e.jsxs("div",{className:"wf-column-item-head",children:[e.jsx("input",{className:"wf-column-name","aria-label":u("workflowColumns.nameLabel","Column name"),value:v.name,disabled:g,onChange:Q=>de(v.id,Q.target.value)}),W&&e.jsxs("span",{className:`wf-column-agent-badge${re?" wf-column-agent-badge--stale":""}`,"data-testid":`wf-column-agent-badge-${v.id}`,title:v.agent?.mode==="override"?u("workflowColumns.agentBadgeOverride","Column agent (override)"):u("workflowColumns.agentBadgeDefer","Column agent (defer)"),children:[e.jsx(oo,{size:11,"aria-hidden":!0})," ",le]}),e.jsxs("div",{className:"wf-column-item-actions",children:[e.jsx("button",{className:"wf-column-move","aria-label":u("workflowColumns.moveUp","Move column up"),disabled:g||S===0,onClick:()=>Y(S,-1),children:e.jsx(no,{size:13})}),e.jsx("button",{className:"wf-column-move","aria-label":u("workflowColumns.moveDown","Move column down"),disabled:g||S===a.length-1,onClick:()=>Y(S,1),children:e.jsx(je,{size:13})}),e.jsx("button",{className:"wf-column-remove","aria-label":u("workflowColumns.remove","Remove column"),disabled:g,onClick:()=>_(v.id),children:e.jsx(ke,{size:13})})]})]}),$.map((Q,se)=>e.jsxs("p",{className:"wf-column-violation",role:"alert",children:[e.jsx(Re,{size:12,"aria-hidden":!0})," ",Q.message]},`${Q.code}-${se}`)),e.jsxs("div",{className:"wf-column-traits",children:[e.jsx("span",{className:"wf-column-traits-label",children:u("workflowColumns.traits","Traits")}),e.jsx("div",{className:"wf-column-trait-options",children:R.map(Q=>{const se=v.traits.some(E=>E.trait===Q.id);return e.jsxs("label",{className:"wf-column-trait",title:Q.description,children:[e.jsx("input",{type:"checkbox",checked:se,disabled:g,onChange:()=>ce(v.id,Q.id)}),e.jsx("span",{children:Q.name})]},Q.id)})})]}),e.jsxs("div",{className:"wf-column-agent",children:[e.jsx("span",{className:"wf-column-agent-label",children:u("workflowColumns.agent","Column agent")}),e.jsxs("select",{className:"wf-column-agent-select","data-testid":`wf-column-agent-select-${v.id}`,"aria-label":u("workflowColumns.agentLabel","Column agent"),value:W??"",disabled:U,title:D?g?u("workflowColumns.readOnlyHint","Built-in workflows are read-only — duplicate to edit"):void 0:u("workflowColumns.agentFlagHint","Enable both experimentalFeatures.workflowColumns and experimentalFeatures.workflowGraphExecutor to staff columns with agents"),onChange:Q=>k(v.id,Q.target.value),children:[e.jsx("option",{value:"",children:u("workflowColumns.agentNone","(none)")}),re&&W&&e.jsx("option",{value:W,children:u("workflowColumns.agentNotFound","Agent not found — {{id}}",{id:W})}),C.map(Q=>e.jsx("option",{value:Q.id,children:Q.name},Q.id))]}),p&&e.jsxs("p",{className:"wf-column-agent-error",role:"alert",children:[e.jsx(Re,{size:12,"aria-hidden":!0})," ",p]}),re&&e.jsxs("p",{className:"wf-column-agent-stale",role:"alert","data-testid":`wf-column-agent-stale-${v.id}`,children:[e.jsx(Re,{size:12,"aria-hidden":!0})," ",u("workflowColumns.agentNotFound","Agent not found — {{id}}",{id:W??""})]}),W&&e.jsxs("div",{className:"wf-column-agent-mode",role:"radiogroup","aria-label":u("workflowColumns.agentMode","Agent mode"),children:[e.jsxs("label",{className:"wf-column-agent-mode-option",children:[e.jsx("input",{type:"radio",name:`wf-column-agent-mode-${v.id}`,checked:(v.agent?.mode??"defer")==="defer",disabled:U,onChange:()=>P(v.id,"defer")}),e.jsx("span",{title:u("workflowColumns.agentModeDeferHint","Column agent applies only when the work carries no agent/model settings of its own"),children:u("workflowColumns.agentModeDefer","Defer")})]}),e.jsxs("label",{className:"wf-column-agent-mode-option",children:[e.jsx("input",{type:"radio",name:`wf-column-agent-mode-${v.id}`,checked:v.agent?.mode==="override",disabled:U,onChange:()=>P(v.id,"override")}),e.jsx("span",{title:u("workflowColumns.agentModeOverrideHint","Column agent supersedes node- and task-level agent/model settings"),children:u("workflowColumns.agentModeOverride","Override")})]})]})]})]},v.id)})})]})}const xn=["string","text","number","boolean","enum","multi-enum","date","url"],Gs={string:["input"],text:["textarea","input"],number:["input"],boolean:["toggle"],enum:["select","radio","chips"],"multi-enum":["chips"],date:["input"],url:["input"]},bn=["#4f7cff","#22c55e","#f59e0b","#ef4444","#a855f7","#06b6d4","#ec4899","#64748b"];function mt(a){return a==="enum"||a==="multi-enum"}function kn(a){return a.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}let Hs=0;function vn(){return Hs+=1,`field-${Date.now().toString(36)}-${Hs}`}function jn({field:a}){const d=o.useMemo(()=>{if(mt(a.type)){const g=a.options?.[0];return g?a.type==="multi-enum"?{node:e.jsx("span",{className:"card-field-badge card-field-badge--multi",title:a.name,children:(a.options??[]).slice(0,2).map(l=>e.jsx("span",{className:"card-field-badge-token",style:l.color?{backgroundColor:l.color,borderColor:l.color,color:"#fff"}:void 0,children:l.label},l.value))})}:{node:e.jsx("span",{className:"card-field-badge card-field-badge--enum",title:`${a.name}: ${g.label}`,style:g.color?{backgroundColor:g.color,borderColor:g.color,color:"#fff"}:void 0,children:g.label})}:null}if(a.type==="boolean")return{node:e.jsx("span",{className:"card-field-badge card-field-badge--boolean",title:a.name,children:a.name})};const i=a.type==="number"?"42":a.type==="date"?"2026-06-04":a.type==="url"?"example.com":a.name;return{node:e.jsx("span",{className:"card-field-badge",title:a.name,children:i})}},[a]);return d?e.jsx("div",{className:"wf-field-preview","data-testid":`wf-field-preview-${a.id}`,children:e.jsx("div",{className:"card-field-badges",children:d.node})}):null}function Us({fields:a,onChange:d,readOnly:i,addToast:g}){const{t:l}=ve("app"),[w,D]=o.useState(null),u=o.useCallback((c,j)=>{d(a.map(h=>h.id===c?{...h,...j}:h))},[a,d]),R=o.useCallback(()=>{const c=vn();d([...a,{id:c,name:l("workflowFields.newFieldName","New field"),type:"string"}])},[a,d,l]),M=o.useCallback(c=>{d(a.filter(j=>j.id!==c))},[a,d]),C=o.useCallback((c,j)=>{const h=kn(j);if(h){if(h!==c&&a.some(T=>T.id===h)){g(l("workflowFields.duplicateId","A field with that id already exists"),"error");return}u(c,{id:h})}},[a,u,g,l]),z=o.useCallback((c,j)=>{const h=a.find(k=>k.id===c);if(!h)return;const T={type:j};mt(j)?(!h.options||h.options.length===0)&&(T.options=[{value:"option-1",label:l("workflowFields.newOptionLabel","Option 1")}]):T.options=void 0,h.render?.widget&&!Gs[j].includes(h.render.widget)&&(T.render={...h.render,widget:void 0}),T.default=void 0,u(c,T)},[a,u,l]),x=o.useCallback((c,j)=>u(c,{options:j}),[u]),N=o.useCallback((c,j)=>{const h=!j||j.placement===void 0&&j.widget===void 0&&!j.badge;u(c,{render:h?void 0:j})},[u]),p=c=>{const j=k=>u(c.id,{default:k});if(c.type==="boolean")return e.jsxs("label",{className:"wf-field--checkbox",children:[e.jsx("input",{type:"checkbox",checked:c.default===!0,disabled:i,onChange:k=>j(k.target.checked)}),e.jsx("span",{children:l("workflowFields.defaultTrue","Default on")})]});if(mt(c.type)){const k=c.type==="multi-enum"?Array.isArray(c.default)?c.default[0]??"":"":typeof c.default=="string"?c.default:"";return e.jsxs("select",{"aria-label":l("workflowFields.defaultLabel","Default value"),value:k,disabled:i,onChange:P=>{const U=P.target.value;if(U==="")return j(void 0);j(c.type==="multi-enum"?[U]:U)},children:[e.jsx("option",{value:"",children:l("workflowFields.noDefault","— none —")}),(c.options??[]).map(P=>e.jsx("option",{value:P.value,children:P.label},P.value))]})}const h=c.type==="number"?"number":c.type==="date"?"date":c.type==="url"?"url":"text",T=c.type==="number"?typeof c.default=="number"?String(c.default):"":typeof c.default=="string"?c.default:"";return e.jsx("input",{type:h,"aria-label":l("workflowFields.defaultLabel","Default value"),defaultValue:T,disabled:i,onBlur:k=>{const P=k.target.value;if(P==="")return j(void 0);j(c.type==="number"?Number(P):P)}})};return e.jsxs("aside",{className:"wf-fields-panel","data-testid":"wf-fields-panel",children:[e.jsxs("header",{className:"wf-fields-panel-header",children:[e.jsx("h3",{children:l("workflowFields.title","Fields")}),e.jsxs("button",{className:"wf-fields-add",onClick:R,disabled:i,title:i?l("workflowFields.readOnlyHint","Built-in workflows are read-only — duplicate to edit"):void 0,children:[e.jsx(Ne,{size:13})," ",l("workflowFields.add","Add field")]})]}),a.length===0?e.jsx("p",{className:"wf-fields-panel-empty",children:l("workflowFields.empty","No custom fields yet. Add a field to extend the task form and cards.")}):e.jsx("ul",{className:"wf-fields-list",children:a.map(c=>{const j=Gs[c.type],h=c.render?.placement??"detail",T=w===c.id;return e.jsxs("li",{className:"wf-field-item","data-testid":`wf-field-${c.id}`,children:[e.jsxs("div",{className:"wf-field-item-head",children:[e.jsx("input",{className:"wf-field-name","aria-label":l("workflowFields.nameLabel","Field name"),value:c.name,disabled:i,onChange:k=>u(c.id,{name:k.target.value})}),e.jsx("button",{className:"wf-field-remove","aria-label":l("workflowFields.remove","Remove field"),disabled:i,onClick:()=>M(c.id),children:e.jsx(ke,{size:13})})]}),e.jsx("div",{className:"wf-field-id-row",children:T?e.jsxs(e.Fragment,{children:[e.jsx("input",{className:"wf-field-id","aria-label":l("workflowFields.idLabel","Field id"),defaultValue:c.id,disabled:i,onBlur:k=>{C(c.id,k.target.value),D(null)}}),e.jsxs("p",{className:"wf-field-id-warn",role:"note",children:[e.jsx(Re,{size:11,"aria-hidden":!0})," ",l("workflowFields.idWarn","Changing the id discards values stored under the old id (remove + add).")]})]}):e.jsxs(e.Fragment,{children:[e.jsx("code",{className:"wf-field-id-static",children:c.id}),e.jsx("button",{className:"wf-field-id-edit",disabled:i,onClick:()=>D(c.id),children:l("workflowFields.editId","Edit id")})]})}),e.jsxs("div",{className:"wf-field-row",children:[e.jsxs("label",{className:"wf-field-sub",children:[e.jsx("span",{children:l("workflowFields.typeLabel","Type")}),e.jsx("select",{value:c.type,disabled:i,onChange:k=>z(c.id,k.target.value),children:xn.map(k=>e.jsx("option",{value:k,children:k},k))})]}),e.jsxs("label",{className:"wf-field--checkbox wf-field-required",children:[e.jsx("input",{type:"checkbox",checked:c.required===!0,disabled:i,onChange:k=>u(c.id,{required:k.target.checked||void 0})}),e.jsx("span",{children:l("workflowFields.required","Required")})]})]}),e.jsxs("label",{className:"wf-field-sub",children:[e.jsx("span",{children:l("workflowFields.default","Default")}),p(c)]}),mt(c.type)&&e.jsxs("div",{className:"wf-field-options","data-testid":`wf-field-options-${c.id}`,children:[e.jsx("span",{className:"wf-field-options-label",children:l("workflowFields.options","Options")}),(c.options??[]).map((k,P)=>e.jsxs("div",{className:"wf-field-option-row",children:[e.jsx("input",{className:"wf-field-option-value","aria-label":l("workflowFields.optionValue","Option value"),value:k.value,disabled:i,onChange:U=>{const ee=[...c.options??[]];ee[P]={...k,value:U.target.value},x(c.id,ee)}}),e.jsx("input",{className:"wf-field-option-label","aria-label":l("workflowFields.optionLabel","Option label"),value:k.label,disabled:i,onChange:U=>{const ee=[...c.options??[]];ee[P]={...k,label:U.target.value},x(c.id,ee)}}),e.jsx("div",{className:"wf-field-option-colors",role:"group","aria-label":l("workflowFields.optionColor","Option color"),children:bn.map(U=>e.jsx("button",{type:"button",className:`wf-field-color-swatch${k.color===U?" is-active":""}`,style:{backgroundColor:U},"aria-label":U,"aria-pressed":k.color===U,disabled:i,onClick:()=>{const ee=[...c.options??[]];ee[P]={...k,color:k.color===U?void 0:U},x(c.id,ee)}},U))}),e.jsx("button",{className:"wf-field-option-remove","aria-label":l("workflowFields.removeOption","Remove option"),disabled:i,onClick:()=>x(c.id,(c.options??[]).filter((U,ee)=>ee!==P)),children:e.jsx(ke,{size:12})})]},P)),e.jsxs("button",{className:"wf-field-option-add",disabled:i,onClick:()=>{const k=(c.options??[]).length+1;x(c.id,[...c.options??[],{value:`option-${k}`,label:l("workflowFields.optionN","Option {{n}}",{n:k})}])},children:[e.jsx(Ne,{size:12})," ",l("workflowFields.addOption","Add option")]})]}),e.jsxs("div",{className:"wf-field-render",children:[e.jsxs("label",{className:"wf-field-sub",children:[e.jsx("span",{children:l("workflowFields.placement","Placement")}),e.jsxs("select",{value:h,disabled:i,onChange:k=>N(c.id,{...c.render,placement:k.target.value}),children:[e.jsx("option",{value:"detail",children:l("workflowFields.placementDetail","Detail (inline)")}),e.jsx("option",{value:"detail-section",children:l("workflowFields.placementSection","Detail section")}),e.jsx("option",{value:"card",children:l("workflowFields.placementCard","Card badge")})]})]}),e.jsxs("label",{className:"wf-field-sub",children:[e.jsx("span",{children:l("workflowFields.widget","Widget")}),e.jsxs("select",{value:c.render?.widget??"",disabled:i,onChange:k=>N(c.id,{...c.render,widget:k.target.value||void 0}),children:[e.jsx("option",{value:"",children:l("workflowFields.widgetDefault","Default")}),j.map(k=>e.jsx("option",{value:k,children:k},k))]})]}),e.jsxs("label",{className:"wf-field--checkbox",children:[e.jsx("input",{type:"checkbox",checked:c.render?.badge===!0,disabled:i,onChange:k=>N(c.id,{...c.render,badge:k.target.checked||void 0})}),e.jsx("span",{children:l("workflowFields.badge","Render as badge")})]})]}),h==="card"&&e.jsx(jn,{field:c})]},c.id)})})]})}const Nn={planningProvider:{group:"models",label:"Plan/Triage provider",description:"Provider used when planning or triaging tasks."},planningModelId:{group:"models",label:"Plan/Triage model",description:"Model used when planning or triaging tasks."},planningFallbackProvider:{group:"models",label:"Plan/Triage fallback provider"},planningFallbackModelId:{group:"models",label:"Plan/Triage fallback model"},executionProvider:{group:"models",label:"Executor provider",description:"Provider used by task implementation agents."},executionModelId:{group:"models",label:"Executor model",description:"Model used by task implementation agents."},validatorProvider:{group:"models",label:"Reviewer provider",description:"Provider used by review and validation agents."},validatorModelId:{group:"models",label:"Reviewer model",description:"Model used by review and validation agents."},validatorFallbackProvider:{group:"models",label:"Reviewer fallback provider"},validatorFallbackModelId:{group:"models",label:"Reviewer fallback model"},titleSummarizerProvider:{group:"models",label:"Title summarizer provider"},titleSummarizerModelId:{group:"models",label:"Title summarizer model"},requirePrApproval:{group:"review",label:"Require PR approval"},requirePlanApproval:{group:"review",label:"Require plan approval"},reviewHandoffPolicy:{group:"review",label:"Review handoff policy"},maxReviewerContextRetries:{group:"review",label:"Reviewer context retries"},maxReviewerFallbackRetries:{group:"review",label:"Reviewer fallback retries"},reflectionEnabled:{group:"review",label:"Reflection enabled"},workflowStepTimeoutMs:{group:"steps",label:"Step timeout"},workflowStepScopeEnforcement:{group:"steps",label:"Step scope enforcement"},planOnlyScopeLeakEnforcement:{group:"steps",label:"Plan-only scope leak enforcement"},workflowRevisionForkOnScopeMismatch:{group:"steps",label:"Fork revision on scope mismatch"},strictScopeEnforcement:{group:"steps",label:"Strict scope enforcement"},runStepsInNewSessions:{group:"steps",label:"Run steps in new sessions"},maxParallelSteps:{group:"steps",label:"Max parallel steps"},buildRetryCount:{group:"steps",label:"Build retry count"},verificationFixRetries:{group:"steps",label:"Verification fix retries"},maxPostReviewFixes:{group:"steps",label:"Post-review fix passes"}},yn=["models","review","steps","advanced"],Cn={models:"Models",review:"Review & Approval",steps:"Step Execution",advanced:"Advanced"};function ma(a){return Nn[a.id]??{group:"advanced",label:a.name,description:a.description}}function Sn(a){const d=new Map;for(const i of a){const g=ma(i).group,l=d.get(g)??[];l.push(i),d.set(g,l)}return yn.map(i=>({group:i,settings:d.get(i)??[]})).filter(i=>i.settings.length>0)}function Be({htmlFor:a,label:d,help:i,error:g,scope:l,disabled:w,clearable:D,onClear:u,children:R}){const{t:M}=ve("app");return e.jsxs("div",{className:`settings-field-row${w?" is-disabled":""}`,children:[e.jsxs("div",{className:"settings-field-row-head",children:[e.jsx("label",{className:"settings-field-row-label",htmlFor:a,children:d}),l&&e.jsx("span",{className:`settings-field-row-scope settings-field-row-scope--${l}`,"data-testid":"settings-field-row-scope",children:l})]}),e.jsxs("div",{className:"settings-field-row-control",children:[R,D&&e.jsx("button",{type:"button",className:"settings-field-row-clear","aria-label":M("settings.clearToDefault","Reset to default"),title:M("settings.clearToDefault","Reset to default"),disabled:w,onClick:u,children:e.jsx(ra,{size:13,"aria-hidden":!0})})]}),i&&e.jsx("p",{className:"settings-field-row-help",children:i}),g&&e.jsx("p",{className:"settings-field-row-error",role:"alert",children:g})]})}function En({descriptor:a,value:d,onChange:i,error:g,clearable:l}){const{key:w,label:D,help:u,scope:R,disabled:M}=a;return e.jsx(Be,{htmlFor:w,label:D,help:u,error:g,scope:R,disabled:M,clearable:l,onClear:()=>i(null),children:e.jsx("label",{className:"settings-toggle",children:e.jsx("input",{id:w,type:"checkbox",checked:d===!0,disabled:M,onChange:C=>i(C.target.checked)})})})}function Fn({descriptor:a,value:d,onChange:i,error:g,clearable:l}){const{key:w,label:D,help:u,scope:R,disabled:M,min:C,max:z,step:x,placeholder:N}=a;return e.jsx(Be,{htmlFor:w,label:D,help:u,error:g,scope:R,disabled:M,clearable:l,onClear:()=>i(null),children:e.jsx("input",{id:w,className:"settings-number",type:"number",value:d??"",min:C,max:z,step:x,placeholder:N,disabled:M,onChange:p=>{const c=p.target.value;if(c==="")return i(null);const j=Number(c);Number.isNaN(j)||i(j)}})})}function Ks({descriptor:a,value:d,onChange:i,error:g,clearable:l}){const{key:w,label:D,help:u,scope:R,disabled:M,options:C}=a;return e.jsx(Be,{htmlFor:w,label:D,help:u,error:g,scope:R,disabled:M,clearable:l,onClear:()=>i(null),children:e.jsx("select",{id:w,className:"settings-select",value:d??"",disabled:M,onChange:z=>i(z.target.value),children:C.map(z=>e.jsx("option",{value:z.value,children:z.label},z.value))})})}function In({descriptor:a,value:d,onChange:i,error:g,clearable:l}){const{key:w,label:D,help:u,scope:R,disabled:M,placeholder:C}=a;return e.jsx(Be,{htmlFor:w,label:D,help:u,error:g,scope:R,disabled:M,clearable:l,onClear:()=>i(null),children:e.jsx("input",{id:w,className:"settings-text",type:"text",value:d??"",placeholder:C,disabled:M,onChange:z=>i(z.target.value)})})}function Mn({descriptor:a,value:d,onChange:i,error:g,clearable:l}){const{key:w,label:D,help:u,scope:R,disabled:M,placeholder:C}=a;return e.jsx(Be,{htmlFor:w,label:D,help:u,error:g,scope:R,disabled:M,clearable:l,onClear:()=>i(null),children:e.jsx("textarea",{id:w,className:"settings-textarea",value:d??"",placeholder:C,disabled:M,rows:3,onChange:z=>i(z.target.value)})})}const An=["string","text","number","boolean","enum","multi-enum"],Ys={string:["input"],text:["textarea","input"],number:["input"],boolean:["toggle"],enum:["select","radio","chips"],"multi-enum":["chips"]},Pn=["#4f7cff","#22c55e","#f59e0b","#ef4444","#a855f7","#06b6d4","#ec4899","#64748b"];function Wt(a){return a==="enum"||a==="multi-enum"}function Rn(a){return a.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}let Js=0;function Dn(){return Js+=1,`setting-${Date.now().toString(36)}-${Js}`}function zn({settings:a,onChange:d,readOnly:i,addToast:g}){const{t:l}=ve("app"),[w,D]=o.useState(null),u=o.useCallback((p,c)=>{d(a.map(j=>j.id===p?{...j,...c}:j))},[a,d]),R=o.useCallback(()=>{d([...a,{id:Dn(),name:l("workflowSettings.newSettingName","New setting"),type:"string"}])},[a,d,l]),M=o.useCallback(p=>d(a.filter(c=>c.id!==p)),[a,d]),C=o.useCallback((p,c)=>{const j=Rn(c);if(j){if(j!==p&&a.some(h=>h.id===j)){g(l("workflowSettings.duplicateId","A setting with that id already exists"),"error");return}u(p,{id:j})}},[a,u,g,l]),z=o.useCallback((p,c)=>{const j=a.find(T=>T.id===p);if(!j)return;const h={type:c};Wt(c)?(!j.options||j.options.length===0)&&(h.options=[{value:"option-1",label:l("workflowSettings.newOptionLabel","Option 1")}]):h.options=void 0,j.render?.widget&&!Ys[c].includes(j.render.widget)&&(h.render=void 0),h.default=void 0,u(p,h)},[a,u,l]),x=o.useCallback((p,c)=>u(p,{options:c}),[u]),N=p=>{const c=T=>u(p.id,{default:T});if(p.type==="boolean")return e.jsxs("label",{className:"wf-setting--checkbox",children:[e.jsx("input",{type:"checkbox",checked:p.default===!0,disabled:i,onChange:T=>c(T.target.checked)}),e.jsx("span",{children:l("workflowSettings.defaultTrue","Default on")})]});if(Wt(p.type)){const T=p.type==="multi-enum"?Array.isArray(p.default)?p.default[0]??"":"":typeof p.default=="string"?p.default:"";return e.jsxs("select",{"aria-label":l("workflowSettings.defaultLabel","Default value"),value:T,disabled:i,onChange:k=>{const P=k.target.value;if(P==="")return c(void 0);c(p.type==="multi-enum"?[P]:P)},children:[e.jsx("option",{value:"",children:l("workflowSettings.noDefault","— none —")}),(p.options??[]).map(k=>e.jsx("option",{value:k.value,children:k.label},k.value))]})}const j=p.type==="number"?"number":"text",h=p.type==="number"?typeof p.default=="number"?String(p.default):"":typeof p.default=="string"?p.default:"";return e.jsx("input",{type:j,"aria-label":l("workflowSettings.defaultLabel","Default value"),defaultValue:h,disabled:i,onBlur:T=>{const k=T.target.value;if(k==="")return c(void 0);c(p.type==="number"?Number(k):k)}})};return e.jsxs("div",{className:"wf-settings-tabpanel","data-testid":"wf-settings-definitions",children:[e.jsx("div",{className:"wf-settings-tabpanel-head",children:e.jsxs("button",{className:"wf-settings-add",onClick:R,disabled:i,title:i?l("workflowSettings.readOnlyHint","Built-in workflows are read-only — duplicate to edit"):void 0,children:[e.jsx(Ne,{size:13})," ",l("workflowSettings.add","Add setting")]})}),i&&e.jsx("p",{className:"wf-settings-note wf-settings-note--info",role:"note",children:l("workflowSettings.builtinDefinitionsReadOnly","Built-in workflow — declarations are read-only. Values are editable below.")}),a.length===0?e.jsx("p",{className:"wf-settings-empty",children:l("workflowSettings.empty","No settings declared yet. Add a setting to expose a typed, per-project knob.")}):e.jsx("ul",{className:"wf-settings-list",children:a.map(p=>{const c=Ys[p.type],j=w===p.id;return e.jsxs("li",{className:"wf-setting-item","data-testid":`wf-setting-${p.id}`,children:[e.jsxs("div",{className:"wf-setting-item-head",children:[e.jsx("input",{className:"wf-setting-name","aria-label":l("workflowSettings.nameLabel","Setting name"),value:p.name,disabled:i,onChange:h=>u(p.id,{name:h.target.value})}),e.jsx("button",{className:"wf-setting-remove","aria-label":l("workflowSettings.remove","Remove setting"),disabled:i,onClick:()=>M(p.id),children:e.jsx(ke,{size:13})})]}),e.jsx("div",{className:"wf-setting-id-row",children:j?e.jsxs(e.Fragment,{children:[e.jsx("input",{className:"wf-setting-id","aria-label":l("workflowSettings.idLabel","Setting id"),defaultValue:p.id,disabled:i,onBlur:h=>{C(p.id,h.target.value),D(null)}}),e.jsxs("p",{className:"wf-setting-id-warn",role:"note",children:[e.jsx(Re,{size:11,"aria-hidden":!0})," ",l("workflowSettings.idWarn","Changing the id discards values stored under the old id (remove + add).")]})]}):e.jsxs(e.Fragment,{children:[e.jsx("code",{className:"wf-setting-id-static",children:p.id}),e.jsx("button",{className:"wf-setting-id-edit",disabled:i,onClick:()=>D(p.id),children:l("workflowSettings.editId","Edit id")})]})}),e.jsxs("div",{className:"wf-setting-row",children:[e.jsxs("label",{className:"wf-setting-sub",children:[e.jsx("span",{children:l("workflowSettings.typeLabel","Type")}),e.jsx("select",{value:p.type,disabled:i,onChange:h=>z(p.id,h.target.value),children:An.map(h=>e.jsx("option",{value:h,children:h},h))})]}),e.jsxs("label",{className:"wf-setting-sub",children:[e.jsx("span",{children:l("workflowSettings.widget","Widget")}),e.jsxs("select",{value:p.render?.widget??"",disabled:i,onChange:h=>u(p.id,{render:h.target.value?{widget:h.target.value}:void 0}),children:[e.jsx("option",{value:"",children:l("workflowSettings.widgetDefault","Default")}),c.map(h=>e.jsx("option",{value:h,children:h},h))]})]})]}),e.jsxs("label",{className:"wf-setting-sub",children:[e.jsx("span",{children:l("workflowSettings.default","Default")}),N(p)]}),e.jsxs("label",{className:"wf-setting-sub",children:[e.jsx("span",{children:l("workflowSettings.description","Description")}),e.jsx("input",{"aria-label":l("workflowSettings.descriptionLabel","Setting description"),value:p.description??"",disabled:i,onChange:h=>u(p.id,{description:h.target.value||void 0})})]}),Wt(p.type)&&e.jsxs("div",{className:"wf-setting-options","data-testid":`wf-setting-options-${p.id}`,children:[e.jsx("span",{className:"wf-setting-options-label",children:l("workflowSettings.options","Options")}),(p.options??[]).map((h,T)=>e.jsxs("div",{className:"wf-setting-option-row",children:[e.jsx("input",{className:"wf-setting-option-value","aria-label":l("workflowSettings.optionValue","Option value"),value:h.value,disabled:i,onChange:k=>{const P=[...p.options??[]];P[T]={...h,value:k.target.value},x(p.id,P)}}),e.jsx("input",{className:"wf-setting-option-label","aria-label":l("workflowSettings.optionLabel","Option label"),value:h.label,disabled:i,onChange:k=>{const P=[...p.options??[]];P[T]={...h,label:k.target.value},x(p.id,P)}}),e.jsx("div",{className:"wf-setting-option-colors",role:"group","aria-label":l("workflowSettings.optionColor","Option color"),children:Pn.map(k=>e.jsx("button",{type:"button",className:`wf-setting-color-swatch${h.color===k?" is-active":""}`,style:{backgroundColor:k},"aria-label":k,"aria-pressed":h.color===k,disabled:i,onClick:()=>{const P=[...p.options??[]];P[T]={...h,color:h.color===k?void 0:k},x(p.id,P)}},k))}),e.jsx("button",{className:"wf-setting-option-remove","aria-label":l("workflowSettings.removeOption","Remove option"),disabled:i,onClick:()=>x(p.id,(p.options??[]).filter((k,P)=>P!==T)),children:e.jsx(ke,{size:12})})]},T)),e.jsxs("button",{className:"wf-setting-option-add",disabled:i,onClick:()=>{const h=(p.options??[]).length+1;x(p.id,[...p.options??[],{value:`option-${h}`,label:l("workflowSettings.optionN","Option {{n}}",{n:h})}])},children:[e.jsx(Ne,{size:12})," ",l("workflowSettings.addOption","Add option")]})]})]},p.id)})})]})}function Tn(a){if(typeof a=="string")return a;try{return JSON.stringify(a)}catch{return String(a)}}const Ln=[{id:"planning",providerId:"planningProvider",modelId:"planningModelId",label:"Plan/Triage Model",help:"Provider and model used when planning or triaging tasks. Leave unset to inherit from the default lane."},{id:"execution",providerId:"executionProvider",modelId:"executionModelId",label:"Executor Model",help:"Provider and model used by task implementation agents. Leave unset to inherit from the default lane."},{id:"validator",providerId:"validatorProvider",modelId:"validatorModelId",label:"Reviewer Model",help:"Provider and model used by review and validation agents. Leave unset to inherit from the default lane."},{id:"planning-fallback",providerId:"planningFallbackProvider",modelId:"planningFallbackModelId",label:"Planning Fallback Model",help:"Fallback provider and model used when the primary Plan/Triage model cannot be used."},{id:"validator-fallback",providerId:"validatorFallbackProvider",modelId:"validatorFallbackModelId",label:"Reviewer Fallback Model",help:"Fallback provider and model used when the primary Reviewer model cannot be used."},{id:"title-summarizer",providerId:"titleSummarizerProvider",modelId:"titleSummarizerModelId",label:"Title Summarizer Model",help:"Provider and model used for title summarization when this workflow declares the lane."},{id:"title-summarizer-fallback",providerId:"titleSummarizerFallbackProvider",modelId:"titleSummarizerFallbackModelId",label:"Title Summarizer Fallback Model",help:"Fallback provider and model used for title summarization when this workflow declares the lane."}];function On(a){if(!a)return null;const d=a.indexOf("/");return d<=0||d===a.length-1?null:{provider:a.slice(0,d),modelId:a.slice(d+1)}}function $n({workflowId:a,settings:d,boundProjectId:i,currentProjectId:g,addToast:l}){const{t:w}=ve("app"),[D,u]=o.useState(null),[R,M]=o.useState(!1),[C,z]=o.useState({}),[x,N]=o.useState({}),[p,c]=o.useState(!1),[j,h]=o.useState(!1),[T,k]=o.useState([]),[P,U]=o.useState(!1),[ee,B]=o.useState([]),[K,de]=o.useState([]),_=o.useRef(0),Y=o.useRef(0),ce=o.useMemo(()=>new Map(d.map(f=>[f.id,f])),[d]),v=o.useMemo(()=>Ln.filter(f=>{const A=ce.get(f.providerId),V=ce.get(f.modelId);return A?.type==="string"&&V?.type==="string"}),[ce]),S=o.useMemo(()=>new Set(v.flatMap(f=>[f.providerId,f.modelId])),[v]),$=i!==void 0&&g!==void 0&&g!==i,W=o.useCallback(async()=>{if(i===void 0)return;const f=++_.current;M(!0);try{const A=await lo(a,i);_.current===f&&(u(A),z({}),N({}))}catch{_.current===f&&l(w("workflowSettings.loadFailed","Failed to load setting values"),"error")}finally{_.current===f&&M(!1)}},[a,i,l,w]);if(o.useEffect(()=>{W()},[W]),o.useEffect(()=>{if(i===void 0||v.length===0){k([]),B([]),de([]),U(!1);return}const f=++Y.current;U(!0),ft().then(A=>{Y.current===f&&(k(A.models??[]),B(A.favoriteProviders??[]),de(A.favoriteModels??[]))}).catch(()=>{Y.current===f&&(k([]),B([]),de([]),l(w("workflowSettings.modelsLoadFailed","Failed to load available models"),"error"))}).finally(()=>{Y.current===f&&U(!1)})},[i,v.length,l,w]),i===void 0)return e.jsx("div",{className:"wf-settings-tabpanel","data-testid":"wf-settings-values",children:e.jsx("p",{className:"wf-settings-note wf-settings-note--info",role:"note",children:w("workflowSettings.requiresProject","Open a project to view and edit per-project setting values.")})});const ne=f=>{if(Object.prototype.hasOwnProperty.call(C,f.id)){const A=C[f.id];return A===null?f.default:A}return D?.effective?.[f.id]??f.default},re=f=>Object.prototype.hasOwnProperty.call(C,f.id)?C[f.id]!==null:D?Object.prototype.hasOwnProperty.call(D.stored,f.id):!1,le=(f,A)=>{z(V=>({...V,[f]:A})),N(V=>{if(!V[f])return V;const Z={...V};return delete Z[f],Z})},Q=f=>le(f,null),se=(f,A)=>{const V=On(A);z(Z=>({...Z,[f.providerId]:V?.provider??null,[f.modelId]:V?.modelId??null})),N(Z=>{if(!Z[f.providerId]&&!Z[f.modelId])return Z;const ie={...Z};return delete ie[f.providerId],delete ie[f.modelId],ie})},E=Object.keys(C).length>0,H=o.useCallback(async()=>{if(!E)return;const f=new Set(Object.keys(C));c(!0);try{const A=await Fs(a,C,i);u(A),z(V=>{const Z={...V};for(const ie of f)delete Z[ie];return Z}),N({}),l(w("workflowSettings.valuesSaved","Setting values saved"),"success")}catch(A){if(A instanceof da&&A.status===400&&A.details){const V=A.details.rejections??[];if(V.length>0){const Z={};for(const ie of V)Z[ie.settingId]=ie;N(Z),l(w("workflowSettings.valuesRejected","Some values were rejected — see the highlighted fields"),"error");return}}l(w("workflowSettings.saveFailed","Failed to save setting values"),"error")}finally{c(!1)}},[E,a,C,i,l,w]),s=f=>{const A=ce.get(f);return A?ne(A):void 0},ue=f=>{const A=ce.get(f);return A?re(A):!1},ye=f=>{const A=s(f.providerId),V=s(f.modelId),Z=typeof A=="string"&&typeof V=="string"?`${A}/${V}`:"",ie=x[f.providerId]?.message??x[f.modelId]?.message,J=ue(f.providerId)||ue(f.modelId),he=P||T.length===0,X=!P&&T.length===0?` ${w("workflowSettings.noModelsAvailable","No models are available. Configure authentication before selecting a workflow model.")}`:"";return e.jsxs("div",{className:"wf-settings-value-item","data-testid":`wf-settings-value-${f.id}`,children:[e.jsx(Be,{htmlFor:`wf-model-lane-${f.id}`,label:f.label,help:`${f.help}${X}`,error:ie,scope:"project",disabled:P,clearable:J,onClear:()=>se(f,""),children:e.jsx(Gt,{id:`wf-model-lane-${f.id}`,label:f.label,models:T,value:Z,onChange:fe=>se(f,fe),placeholder:w("workflowSettings.selectModel","Select a model…"),defaultOptionLabel:w("workflowSettings.useInheritedModel","Use inherited/default model"),disabled:he,favoriteProviders:ee,favoriteModels:K})}),J&&e.jsx("span",{className:"wf-settings-customized","data-testid":`wf-settings-customized-${f.id}`,children:w("workflowSettings.customized","Customized")})]},f.id)},oe=f=>{const A=ne(f),V=x[f.id]?.message,Z=re(f),ie=ma(f),J={key:f.id,label:ie.label,help:ie.description??f.description,scope:"project"},he=Z;switch(f.type){case"boolean":return e.jsx(En,{descriptor:J,value:A===!0,error:V,clearable:he,onChange:X=>X===null?Q(f.id):le(f.id,X)});case"number":return e.jsx(Fn,{descriptor:J,value:typeof A=="number"?A:null,error:V,clearable:he,onChange:X=>X===null?Q(f.id):le(f.id,X)});case"enum":return e.jsx(Ks,{descriptor:{...J,options:(f.options??[]).map(X=>({value:X.value,label:X.label}))},value:typeof A=="string"?A:null,error:V,clearable:he,onChange:X=>X===null?Q(f.id):le(f.id,X)});case"multi-enum":{const X=Array.isArray(A)?A[0]??null:null;return e.jsx(Ks,{descriptor:{...J,options:(f.options??[]).map(fe=>({value:fe.value,label:fe.label}))},value:X,error:V,clearable:he,onChange:fe=>fe===null?Q(f.id):le(f.id,[fe])})}case"text":return e.jsx(Mn,{descriptor:J,value:typeof A=="string"?A:null,error:V,clearable:he,onChange:X=>X===null||X===""?Q(f.id):le(f.id,X)});case"string":default:return e.jsx(In,{descriptor:J,value:typeof A=="string"?A:null,error:V,clearable:he,onChange:X=>X===null||X===""?Q(f.id):le(f.id,X)})}},De=D?.orphaned??[],Xe=o.useCallback(async f=>{try{const A=await Fs(a,{[f]:null},i);u(A),l(w("workflowSettings.orphanDeleted","Orphaned value removed"),"success")}catch{l(w("workflowSettings.saveFailed","Failed to save setting values"),"error")}},[a,i,l,w]);return e.jsxs("div",{className:"wf-settings-tabpanel","data-testid":"wf-settings-values",children:[$&&e.jsxs("p",{className:"wf-settings-note wf-settings-note--warn",role:"note","data-testid":"wf-settings-stale-notice",children:[e.jsx(Re,{size:12,"aria-hidden":!0})," ",w("workflowSettings.staleContext","Values shown are for project {{project}} — reopen the editor to edit values for the current project.",{project:i})]}),e.jsx("div",{className:"wf-settings-values-head",children:e.jsxs("button",{className:"wf-settings-save-values",onClick:H,disabled:!E||p||$,"data-testid":"wf-settings-save-values",children:[e.jsx(qt,{size:13})," ",w("workflowSettings.saveValues","Save values")]})}),d.length===0?e.jsx("p",{className:"wf-settings-empty",children:R?w("workflowSettings.loading","Loading…"):w("workflowSettings.noDeclarations","This workflow declares no settings, so there are no values to edit.")}):e.jsx("div",{className:"wf-settings-values-list",children:Sn(d).map(({group:f,settings:A})=>{const V=new Set(A.map(J=>J.id)),Z=f==="models"?v.filter(J=>V.has(J.providerId)&&V.has(J.modelId)):[],ie=A.filter(J=>!S.has(J.id));return e.jsxs("section",{className:"wf-settings-value-group","data-testid":`wf-settings-group-${f}`,children:[e.jsx("h4",{className:"wf-settings-value-group-title",children:w(`workflowSettings.group.${f}`,Cn[f])}),Z.map(J=>ye(J)),ie.map(J=>e.jsxs("div",{className:"wf-settings-value-item","data-testid":`wf-settings-value-${J.id}`,children:[oe(J),re(J)&&e.jsx("span",{className:"wf-settings-customized","data-testid":`wf-settings-customized-${J.id}`,children:w("workflowSettings.customized","Customized")})]},J.id))]},f)})}),De.length>0&&e.jsxs("div",{className:"wf-settings-orphaned","data-testid":"wf-settings-orphaned",children:[e.jsxs("button",{className:"wf-settings-orphaned-toggle",onClick:()=>h(f=>!f),"aria-expanded":j,children:[j?e.jsx(je,{size:13}):e.jsx(Pe,{size:13})," ",w("workflowSettings.orphanedTitle","Orphaned values ({{count}})",{count:De.length})]}),j&&e.jsxs("div",{className:"wf-settings-orphaned-body",children:[e.jsx("p",{className:"wf-settings-note wf-settings-note--muted",role:"note",children:w("workflowSettings.orphanedNote","These stored values no longer match a current declaration (the setting was retyped or removed). They are ignored by the engine; delete them to clean up.")}),e.jsx("ul",{className:"wf-settings-orphaned-list",children:De.map(f=>e.jsxs("li",{className:"wf-settings-orphaned-row","data-testid":`wf-settings-orphan-${f.id}`,children:[e.jsx("code",{className:"wf-settings-orphan-id",children:f.id}),e.jsx("span",{className:"wf-settings-orphan-value",children:Tn(f.value)}),e.jsx("button",{className:"wf-settings-orphan-delete","aria-label":w("workflowSettings.deleteOrphan","Delete orphaned value"),disabled:$||p,onClick:()=>Xe(f.id),children:e.jsx(ke,{size:12})})]},f.id))})]})]}),d.length>0&&e.jsxs("p",{className:"wf-settings-reset-hint",role:"note",children:[e.jsx(ra,{size:11,"aria-hidden":!0})," ",w("workflowSettings.clearHint","Use the reset control on a row to clear a value back to its declaration default.")]})]})}function Xs({workflowId:a,settings:d,onChange:i,readOnly:g,projectId:l,addToast:w,initialTab:D}){const{t:u}=ve("app"),[R,M]=o.useState(()=>D??(d.length>0?"values":"definitions")),C=o.useRef({workflowId:a,projectId:l});C.current.workflowId!==a&&(C.current={workflowId:a,projectId:l});const z=C.current.projectId;return e.jsxs("aside",{className:"wf-settings-panel","data-testid":"wf-settings-panel",children:[e.jsx("header",{className:"wf-settings-panel-header",children:e.jsx("h3",{children:u("workflowSettings.title","Settings")})}),e.jsxs("div",{className:"wf-settings-tabs",role:"tablist",children:[e.jsx("button",{role:"tab","aria-selected":R==="definitions",className:`wf-settings-tab${R==="definitions"?" is-active":""}`,onClick:()=>M("definitions"),"data-testid":"wf-settings-tab-definitions",children:u("workflowSettings.definitionsTab","Definitions")}),e.jsx("button",{role:"tab","aria-selected":R==="values",className:`wf-settings-tab${R==="values"?" is-active":""}`,onClick:()=>M("values"),"data-testid":"wf-settings-tab-values",children:u("workflowSettings.valuesTab","Values")})]}),R==="definitions"?e.jsx(zn,{settings:d,onChange:i,readOnly:g,addToast:w}):e.jsx($n,{workflowId:a,settings:d,boundProjectId:z,currentProjectId:l,addToast:w},a)]})}function pa({row:a,depth:d,selectedNodeId:i,selectedEdgeId:g,onSelectNode:l,onSelectEdge:w}){const{t:D}=ve("app"),u=a.children.length>0,[R,M]=o.useState(d===0),C=i===a.id;return e.jsxs("div",{className:"mobile-wf-node-group",children:[e.jsxs("div",{className:`mobile-wf-node-row${C?" mobile-wf-node-row--selected":""}`,style:{"--mobile-wf-depth":String(d)},"data-testid":`mobile-wf-node-${a.id}`,children:[e.jsxs("button",{type:"button",className:"mobile-wf-node-main",onClick:()=>l(a.id),"aria-current":C?"true":void 0,children:[e.jsx("span",{className:"mobile-wf-node-kind",children:a.kind}),e.jsxs("span",{className:"mobile-wf-node-text",children:[e.jsx("span",{className:"mobile-wf-node-title",children:a.label}),a.summary?e.jsx("span",{className:"mobile-wf-node-summary",children:a.summary}):null]}),a.editable?e.jsx(io,{size:14,"aria-hidden":!0}):null]}),u?e.jsx("button",{type:"button",className:"mobile-wf-node-expand","aria-expanded":R,"aria-label":R?D("common.collapse","Collapse"):D("common.expand","Expand"),onClick:()=>M(z=>!z),children:R?e.jsx(je,{size:16}):e.jsx(Pe,{size:16})}):null]}),(a.columnName||a.outgoing.length>0)&&e.jsxs("div",{className:"mobile-wf-node-meta",style:{"--mobile-wf-depth":String(d)},children:[a.columnName?e.jsx("span",{className:"mobile-wf-column-chip",children:a.columnName}):null,a.outgoing.map(z=>e.jsxs("button",{type:"button",className:`mobile-wf-edge-chip${g===z.id?" mobile-wf-edge-chip--selected":""}`,"data-testid":`mobile-wf-edge-${z.id}`,onClick:()=>w(z.id),children:[e.jsx(ro,{size:12,"aria-hidden":!0}),e.jsx("span",{children:z.label}),e.jsx("span",{className:"mobile-wf-edge-target",children:z.targetLabel})]},z.id))]}),u&&R?e.jsx("div",{className:"mobile-wf-node-children",children:a.children.map(z=>e.jsx(pa,{row:z,depth:d+1,selectedNodeId:i,selectedEdgeId:g,onSelectNode:l,onSelectEdge:w},z.id))}):null]})}function Wn({rows:a,selectedNodeId:d,selectedEdgeId:i,onSelectNode:g,onSelectEdge:l}){const{t:w}=ve("app");return a.length===0?e.jsx("div",{className:"mobile-wf-graph-empty","data-testid":"mobile-wf-graph-empty",children:w("workflowNodes.mobileGraphEmpty","No graph nodes yet.")}):e.jsx("div",{className:"mobile-wf-graph","data-testid":"mobile-wf-graph",children:a.map(D=>e.jsx(pa,{row:D,depth:0,selectedNodeId:d,selectedEdgeId:i,onSelectNode:g,onSelectEdge:l},D.id))})}function _n(a){return typeof a.label=="string"&&a.label.trim()?a.label:String(a.data?.condition??"success")}function Qs(a){return a.data.label||a.id}function Zs(a,d){const i=Math.round(a.position.y),g=Math.round(d.position.y);return i!==g?i-g:Math.round(a.position.x)-Math.round(d.position.x)}function Bn(a,d){const i=new Map(a.map(g=>[g.id,g.name||g.id]));for(const g of d){if(!_e(g.id))continue;const l=co(g.id);i.has(l)||i.set(l,g.data.label||l)}return i}function Vn(a,d,i=[],g={},l){const w=Bn(i,a),D=new Map(a.map(x=>[x.id,x])),u=new Map,R=new Map;for(const x of a){if(!x.parentId)continue;const N=u.get(x.parentId)??[];N.push(x),u.set(x.parentId,N)}for(const x of u.values())x.sort(Zs);for(const x of d){const N=R.get(x.source)??[];N.push(x),R.set(x.source,N)}const M=x=>{const N=D.get(x.target);return{id:x.id,source:x.source,target:x.target,targetLabel:N?Qs(N):x.target,label:_n(x),kind:typeof x.data?.kind=="string"?x.data.kind:void 0}},C=x=>{const N=(u.get(x.id)??[]).map(C),p=x.data.column;return{id:x.id,label:Qs(x),kind:x.data.kind,summary:fo(x.data,g,l),columnName:p?w.get(p)??p:void 0,editable:x.data.kind!=="start"&&x.data.kind!=="end"&&!_e(x.id),parentId:x.parentId,templateLocalId:x.parentId?uo(x.parentId,x.id):void 0,outgoing:(R.get(x.id)??[]).map(M),children:N}};return a.filter(x=>!x.parentId&&!_e(x.id)).sort(Zs).map(C)}function qn(a){switch(typeof a?.seam=="string"?a.seam:""){case"planning":return"Generate the task plan and write the planning artifact that downstream workflow nodes consume.";case"execute":return"Run Fusion's standard implementation prompt for this task, generated from the task spec, current project context, workflow fields, and available tools.";case"step-execute":return"Run Fusion's step implementation prompt for the active planned step in the task worktree.";case"review":return"Run Fusion's review boundary for completed implementation work and route the task based on the review result.";case"merge":return"Run Fusion's merge boundary: verify merge readiness, apply the configured merge strategy, and update the final task state.";default:return""}}const Gn=[{id:"claude-code",name:"Claude Code",tier:"native"},{id:"codex",name:"Codex",tier:"hybrid"},{id:"droid",name:"Droid",tier:"hybrid"},{id:"pi",name:"Pi",tier:"hybrid"},{id:"generic",name:"Generic CLI",tier:"generic"}],We=a=>a.startsWith("builtin:");function ea(a,d){return a&&d?`${a}/${d}`:""}function ta(a){if(!a)return{provider:"",modelId:""};const d=a.indexOf("/");return d===-1?{provider:"",modelId:""}:{provider:a.slice(0,d),modelId:a.slice(d+1)}}function _t(a,d,i,g,l,w,D){const{ir:u,layout:R}=ca(a,i,g,l.length?l:void 0,w.length?w:void 0,D.length?D:void 0);return JSON.stringify({name:a,description:d,ir:u,layout:R})}let sa=0;function aa(){return sa+=1,`n-${Date.now().toString(36)}-${sa}`}const Hn=["step-headings","json-steps"],Un=["approve","revise","rethink","unavailable"],oa=["in-review","merged","failed","awaiting-approval","task-created","workflow-notify"],Bt="__custom",na=[{kind:"prompt",label:"Prompt",icon:Vo},{kind:"prompt",label:"User input",icon:qo,presetConfig:{awaitInput:!0}},{kind:"script",label:"Script",icon:Go},{kind:"gate",label:"Gate",icon:Ho},{kind:"merge",label:"Merge boundary",icon:Uo},{kind:"hold",label:"Hold",icon:Ko,presetConfig:{release:"manual"}},{kind:"split",label:"Split",icon:Yo},{kind:"join",label:"Join",icon:Jo,presetConfig:{mode:"all",onBranchFailure:"collect"}},{kind:"foreach",label:"For-each step",icon:Os,presetConfig:{source:"task-steps"}},{kind:"loop",label:"Loop",icon:Os,presetConfig:{maxIterations:3,exitWhen:{type:"output-contains",value:"DONE"}}},{kind:"step-review",label:"Step review",icon:Xo,presetConfig:{type:"code"}},{kind:"parse-steps",label:"Parse steps",icon:fa,presetConfig:{artifact:"PROMPT.md",parser:"step-headings"}},{kind:"code",label:"Code",icon:Qo,presetConfig:{source:""}},{kind:"notify",label:"Notify",icon:Zo,presetConfig:{event:"in-review",title:"{{taskTitle}}",message:""}}];function Kn(a){const d={name:a.name,gateMode:a.gateMode??"advisory"};return a.description&&(d.description=a.description),a.mode==="script"?(a.scriptName&&(d.scriptName=a.scriptName),{kind:"script",label:a.name,config:d}):(d.prompt=a.prompt??"",d.toolMode=a.toolMode==="coding"?"coding":"readonly",a.modelProvider&&a.modelId&&(d.modelProvider=a.modelProvider,d.modelId=a.modelId),{kind:"prompt",label:a.name,config:d})}const Yn=new Set(["prompt","script","gate","code","hold","split","join","foreach","loop","step-review","parse-steps","notify","merge"]);function Jn({workflows:a,onCreate:d,onDesign:i,onClose:g}){const{t:l}=ve("app"),[w,D]=o.useState(""),[u,R]=o.useState(""),[M,C]=o.useState(null),[z,x]=o.useState(!1),[N,p]=o.useState(!1),[c,j]=o.useState(""),[h,T]=o.useState(!1),[k,P]=o.useState(null),U=o.useRef(null),[ee,B]=o.useState(!1),K=o.useRef(null),de=o.useRef([]),_=o.useMemo(()=>{const E={id:null,name:l("workflows.templateBlank","Blank"),description:l("workflows.templateBlankDescription","Start from an empty start → end graph."),nodeCount:0,builtin:!1},H=a.filter(oe=>oe.kind!=="fragment"),s=oe=>({id:oe.id,name:oe.name,description:oe.description??"",nodeCount:oe.ir.nodes.length,source:oe,builtin:We(oe.id)}),ue=H.filter(oe=>We(oe.id)).map(s),ye=H.filter(oe=>!We(oe.id)).map(s);return[E,...ue,...ye]},[a,l]),[Y,ce]=o.useState(0),v=_[Y]??_[0];o.useEffect(()=>{K.current?.focus()},[]);const S=o.useCallback(E=>{const H=_[E];H&&(ce(E),ee||(H.id===null?(D(""),R("")):(D(l("workflows.templateCopyName","{{name}} copy",{name:H.name})),R(H.description))),M&&C(null))},[_,ee,M,l]),$=o.useCallback(E=>{if(E.key==="ArrowDown"||E.key==="ArrowRight"){E.preventDefault();const H=Math.min(Y+1,_.length-1);S(H),de.current[H]?.focus()}else if(E.key==="ArrowUp"||E.key==="ArrowLeft"){E.preventDefault();const H=Math.max(Y-1,0);S(H),de.current[H]?.focus()}else(E.key==="Enter"||E.key===" ")&&(E.preventDefault(),S(Y),K.current?.focus())},[Y,_.length,S]),W=ua(g),ne=o.useCallback(async E=>{E.preventDefault();const H=w.trim();if(!H){C(l("workflows.createNameRequired","Enter a workflow name"));return}x(!0),C(null);try{await d(H,u.trim(),v)}catch(s){C(ae(s)||l("workflows.createFailed","Failed to create workflow")),x(!1)}},[w,u,v,d,l]),re=o.useCallback(async()=>{const E=c.trim();if(!E){P(l("workflows.aiPromptRequired","Describe the workflow you want"));return}const H=new AbortController;U.current=H,T(!0),P(null);try{await i(E,w.trim(),H.signal)}catch(s){if(H.signal.aborted)return;P(ae(s)||l("workflows.aiFailed","Failed to design workflow"))}finally{U.current===H&&(U.current=null),T(!1)}},[c,w,i,l]),le=o.useCallback(()=>{U.current?.abort(),T(!1)},[]),Q=_.findIndex(E=>E.id!==null&&E.builtin),se=_.findIndex(E=>E.id!==null&&!E.builtin);return e.jsx("div",{className:"modal-overlay open wf-create-overlay",...W,children:e.jsxs("div",{className:"modal wf-create-modal","data-testid":"wf-create-dialog",role:"dialog","aria-modal":"true","aria-label":l("workflows.createTitle","New workflow"),onClick:E=>E.stopPropagation(),onKeyDown:E=>{E.key==="Escape"&&(E.stopPropagation(),g())},children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:l("workflows.createTitle","New workflow")}),e.jsx("button",{type:"button",className:"modal-close",onClick:g,"aria-label":l("actions.close","Close"),children:e.jsx(Ht,{size:16})})]}),e.jsxs("form",{onSubmit:ne,children:[e.jsxs("div",{className:"modal-body",children:[e.jsxs("div",{className:"wf-ai-create","aria-busy":h,"data-testid":"wf-ai-create",children:[e.jsxs("button",{type:"button",className:"wf-ai-toggle","data-testid":"wf-ai-toggle","aria-expanded":N,onClick:()=>{p(E=>!E),P(null)},children:[e.jsx($e,{size:13})," ",l("workflows.aiToggle","Describe it instead")]}),N&&e.jsxs("div",{className:"wf-ai-create-body",children:[e.jsx("textarea",{className:"wf-ai-prompt","data-testid":"wf-ai-prompt",rows:3,value:c,disabled:h,placeholder:l("workflows.aiPromptPlaceholder","e.g. Run lint and tests before merge, then post a changelog comment after merge"),onChange:E=>{j(E.target.value),k&&P(null)}}),k&&e.jsx("p",{className:"wf-create-error",role:"alert","data-testid":"wf-ai-error",children:k}),e.jsxs("div",{className:"wf-ai-actions",children:[e.jsxs("button",{type:"button",className:"btn btn-primary wf-ai-submit","data-testid":"wf-ai-submit",disabled:h,onClick:()=>void re(),children:[h?e.jsx(Fe,{size:13,className:"wf-spin"}):e.jsx($e,{size:13})," ",l("workflows.aiSubmit","Design with AI")]}),h&&e.jsx("button",{type:"button",className:"btn wf-ai-cancel","data-testid":"wf-ai-cancel",onClick:le,children:l("common.cancel","Cancel")})]})]})]}),e.jsxs("div",{className:"wf-field",children:[e.jsx("span",{id:"wf-template-label",children:l("workflows.templatePickerLabel","Start from")}),e.jsx("div",{className:"wf-template-list",role:"radiogroup","aria-labelledby":"wf-template-label","data-testid":"wf-template-list",children:_.map((E,H)=>{const s=H===Y,ue=E.id??"blank";return e.jsxs("div",{children:[H===Q&&Q>=0&&e.jsx("p",{className:"wf-template-section",children:l("workflows.templateSectionBuiltin","Built-in workflows")}),H===se&&se>=0&&e.jsx("p",{className:"wf-template-section",children:l("workflows.templateSectionYours","Your workflows")}),e.jsxs("div",{ref:ye=>{de.current[H]=ye},role:"radio","aria-checked":s,tabIndex:s?0:-1,className:`wf-template-option${s?" selected":""}`,"data-testid":E.id===null?"wf-template-option-blank":`wf-template-option-${E.id}`,onClick:()=>{S(H),de.current[H]?.focus()},onKeyDown:$,children:[e.jsx("span",{className:"wf-template-option-name",children:E.name}),E.description&&e.jsx("span",{className:"wf-template-option-desc",children:E.description}),E.id!==null&&e.jsx("span",{className:"wf-template-option-count",children:l("workflows.templateNodeCount","{{count}} nodes",{count:E.nodeCount})})]})]},ue)})})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:l("workflows.createName","Name")}),e.jsx("input",{ref:K,"data-testid":"wf-create-name",value:w,onChange:E=>{D(E.target.value),B(!0),M&&C(null)}})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:l("workflows.createDescription","Description (optional)")}),e.jsx("textarea",{rows:2,"data-testid":"wf-create-description",value:u,onChange:E=>R(E.target.value)})]}),M&&e.jsx("p",{className:"wf-create-error",role:"alert","data-testid":"wf-create-error",children:M})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{type:"button",className:"btn",onClick:g,children:l("common.cancel","Cancel")}),e.jsxs("button",{type:"submit",className:"btn btn-primary","data-testid":"wf-create-submit",disabled:z,children:[z?e.jsx(Fe,{size:13,className:"wf-spin"}):null," ",l("workflows.createSubmit","Create")]})]})]})]})})}function Xn({onClose:a,addToast:d,projectId:i,initialPanel:g,initialAction:l,initialWorkflowId:w,modalRef:D}){const[u,R]=o.useState([]),[M,C]=o.useState(null),x=po()==="mobile",[N,p]=o.useState(()=>Is()),[c,j]=o.useState(!1),[h,T]=o.useState(!1),[k,P]=o.useState(null),[U,ee]=o.useState(!1),[B,K,de]=Ua([]),[_,Y,ce]=Ka([]),[v,S]=o.useState(null),[$,W]=o.useState(null),[ne,re]=o.useState(!1),[le,Q]=o.useState(!1),[se,E]=o.useState(()=>g==="settings"?"settings":"graph"),H=x||le,{t:s}=ve("app"),{confirm:ue}=wo(),[ye,oe]=o.useState(l==="create"),De=o.useRef(null),Xe=o.useRef(null),[f,A]=o.useState(""),[V,Z]=o.useState(""),[ie,J]=o.useState(!1),[he,X]=o.useState(!1),fe=o.useRef(null),[te,Ve]=o.useState([]),[Ce,qe]=o.useState([]),[Se,Qe]=o.useState([]),pt=o.useRef(null),[Ut,wa]=o.useState([]),[ha,ga]=o.useState([...Hn]),[wt,xa]=o.useState([]),[ht,ba]=o.useState([]),Kt="fusion:wf-templates-collapsed",[ze,ka]=o.useState(()=>{try{const t=localStorage.getItem(Kt);return t!=null?t==="1":Is()}catch{return!1}}),[Ze,Yt]=o.useState(""),[et,Jt]=o.useState(null),Xt="fusion:wf-sidebar-columns-collapsed",Qt="fusion:wf-sidebar-fields-collapsed",Zt="fusion:wf-sidebar-settings-collapsed",[Ge,va]=o.useState(()=>{try{return localStorage.getItem(Xt)==="1"}catch{return!1}}),[He,ja]=o.useState(()=>{try{return localStorage.getItem(Qt)==="1"}catch{return!1}}),[Ue,Na]=o.useState(()=>{try{return localStorage.getItem(Zt)==="1"}catch{return!1}});o.useEffect(()=>{try{localStorage.setItem(Xt,Ge?"1":"0")}catch{}},[Ge]),o.useEffect(()=>{try{localStorage.setItem(Qt,He?"1":"0")}catch{}},[He]),o.useEffect(()=>{try{localStorage.setItem(Zt,Ue?"1":"0")}catch{}},[Ue]);const{setViewport:es}=Ya(),gt=o.useRef(null),tt=o.useMemo(()=>`fusion:wf-migration-notice-dismissed${i?`:${i}`:""}`,[i]),[ya,ts]=o.useState(!1),[ss,xt]=o.useState(null),[as,os]=o.useState([]),[ns,ls]=o.useState(!1),st=o.useRef(null),[bt,kt]=o.useState(!1),[at,vt]=o.useState(""),[ge,jt]=o.useState(!1),[Te,Le]=o.useState(null),ot=o.useRef(null),Nt=o.useRef(!1),F=o.useMemo(()=>u.find(t=>t.id===M),[u,M]),q=!!F&&We(F.id),is=o.useRef(M);is.current=M;const Ca=o.useMemo(()=>!F||q?!1:!B.some(t=>Yn.has(t.data.kind)),[F,q,B]),{experimentalFeatures:rs}=ho(i),ds=rs?.workflowColumns===!0&&rs?.workflowGraphExecutor===!0;o.useEffect(()=>{let t=!1;return ia(i).then(n=>{t||wa(n)}).catch(()=>{}),()=>{t=!0}},[i]),o.useEffect(()=>{let t=!1;return go(i).then(n=>{!t&&n.length>0&&ga(n)}).catch(()=>{}),()=>{t=!0}},[i]),o.useEffect(()=>{let t=!1;return xo().then(n=>{t||xa(n.templates??[])}).catch(()=>{}),bo().then(n=>{t||ba(n.templates??[])}).catch(()=>{}),()=>{t=!0}},[]),o.useEffect(()=>{try{localStorage.setItem(Kt,ze?"1":"0")}catch{}},[ze]),o.useEffect(()=>{v&&re(!1)},[v]),o.useEffect(()=>{g==="settings"&&E("settings")},[g]);const yt=o.useMemo(()=>u.filter(t=>t.kind==="fragment"),[u]),me=o.useMemo(()=>{const t=Ze.trim().toLowerCase(),n=I=>!t||I.toLowerCase().includes(t),r=(I,G)=>I.name.localeCompare(G.name),b=[...yt].sort(r).filter(I=>n(I.name)),y=[...wt].sort(r).filter(I=>n(I.name)),O=[...ht].sort((I,G)=>I.template.name.localeCompare(G.template.name)).filter(I=>n(I.template.name));return{fragmentEntries:b,stepEntries:y,pluginEntries:O}},[yt,wt,ht,Ze]),Ct=yt.length+wt.length+ht.length,cs=Ct>0,St=o.useMemo(()=>te.length?ko(te,Ut):[],[te,Ut]),Ie=o.useMemo(()=>vo(B,te),[B,te]),us=St.filter(t=>t.severity==="error").length,Ke=o.useMemo(()=>q||!F||fe.current===null?!1:_t(f,V,B,_,te,Ce,Se)!==fe.current,[q,F,f,V,B,_,te,Ce,Se]),Oe=o.useCallback(async()=>{j(!0);try{const t=await jo(i);R(t),C(n=>n&&t.some(r=>r.id===n)?n:l!=="create"&&w&&t.some(r=>r.id===w)?w:x?null:t[0]?.id??null)}catch(t){d(ae(t)||"Failed to load workflows","error")}finally{j(!1)}},[i,d,x,l,w]);o.useEffect(()=>{Oe()},[Oe]),o.useEffect(()=>{!w||!x||!N||M===w&&Xe.current!==w&&(Xe.current=w,p(!1))},[M,w,x,N]);const fs=o.useRef(!1);o.useEffect(()=>{if(fs.current)return;fs.current=!0;let t=!1;return(async()=>{try{const n=await No(i);if(t)return;if(n.migrated>0){if(await Oe(),t)return;let r=!1;try{r=localStorage.getItem(tt)==="1"}catch{}r||ts(!0)}}catch{}})(),()=>{t=!0}},[i,Oe,tt]);const Sa=o.useCallback(()=>{ts(!1);try{localStorage.setItem(tt,"1")}catch{}},[tt]),nt=o.useCallback(async()=>{if(F)try{await yo(F.id,i)}catch(t){d(ae(t)||s("workflows.exportFailed","Failed to export workflow"),"error")}},[F,i,d,s]),Ea=o.useCallback(async t=>{const n=t.target.files?.[0];if(st.current&&(st.current.value=""),!!n){xt(null),os([]),ls(!0);try{const r=await n.text();let b;try{b=JSON.parse(r)}catch{xt(s("workflows.importInvalidJson","That file isn't valid JSON."));return}const y=await Co(b,i);await Oe(),C(y.workflow.id),p(!1),d(s("workflows.imported",'Imported workflow "{{name}}"',{name:y.workflow.name}),"success"),y.strippedApprovalFlags&&d(s("workflows.importStripped","Auto-approval flags were removed from imported nodes"),"warning"),y.warnings.length>0&&os(y.warnings)}catch(r){r instanceof da&&r.status>=400&&r.status<500?xt(ae(r)||s("workflows.importFailed","Import failed")):d(ae(r)||s("workflows.importFailed","Import failed"),"error")}finally{ls(!1)}}},[i,Oe,d,s]);o.useEffect(()=>{if(!F){K([]),Y([]),Ve([]),qe([]),Qe([]),A(""),Z(""),fe.current=null;return}const t=Ms(F),n=As(F),r=Ps(F),b=So(F),y=_s(t.nodes,t.edges,n),O=Bs(t.nodes,y);K(O),Y(t.edges),Ve(n),qe(r),Qe(b),A(F.name),Z(F.description??""),J(!1),X(!1),fe.current=_t(F.name,F.description??"",O,t.edges,n,r,b),S(null),W(null),P(null),es({x:0,y:0,zoom:1},{duration:0}),Nt.current?(Nt.current=!1,ee(!0)):ee(!1)},[F,K,Y,es]);const Et=o.useRef(!1);o.useEffect(()=>{if(g!=="settings"||Et.current||!F)return;const t=pt.current;t&&(Et.current=!0,t.scrollIntoView({behavior:"smooth",inline:"end",block:"nearest"}))},[g,F]),o.useEffect(()=>()=>{Et.current=!1},[g]);const[Ft,ms]=o.useState(null);o.useEffect(()=>{K(t=>{const n=t.filter(r=>!_e(r.id)&&r.type!=="group");return[...Eo(te),...n]})},[te,K]);const Fa=o.useCallback(t=>{const n=Fo(t,_,B);if("error"in n){n.error==="cycle"&&d(s("workflowNodes.cycleBlocked","That connection would create a cycle — only rework edges inside a for-each template may loop back"),"warning");return}Y(r=>[...r,n.edge])},[_,B,Y,d,s]),Ia=o.useCallback((t,n)=>{if(_e(n.id)||te.length===0)return;const r=Vt(n.position.y,te);r&&K(b=>b.map(y=>y.id===n.id?{...y,data:{...y.data,column:r}}:y))},[te,K]),lt=o.useCallback((t,n,r)=>{const b=aa(),y=n??(t==="merge"?"Merge boundary":t.charAt(0).toUpperCase()+t.slice(1)),O=t==="gate"?{gateMode:"gate"}:{},I=r?{...O,...r}:O;if(t==="foreach"||t==="loop"){const G=Io(b,aa()),we=t==="foreach"?s("workflowNodes.stepExecuteLabel","Step execute"):s("workflowNodes.loopStepLabel","Loop step"),Ee=t==="foreach"?{seam:"step-execute"}:{prompt:""};K(Tt=>[...Tt,{id:b,type:t,position:{x:200+Tt.length*40,y:240+Tt.length%3*70},data:{kind:t,label:y,config:I,templateEmpty:!1},style:{width:Ao,height:Mo},deletable:!0},{id:G,type:"prompt",position:{x:Ro,y:Po},parentId:b,extent:"parent",data:{kind:"prompt",label:we,config:Ee},deletable:!0}]),S(b);return}K(G=>[...G,{id:b,type:t,position:{x:200+G.length*40,y:240+G.length%3*70},data:{kind:t,label:y,config:I},deletable:!0}]),S(b)},[K,s]),it=o.useCallback(t=>{if(q)return;const{kind:n,label:r,config:b}=Kn(t);lt(n,r,b)},[q,lt]),ps=o.useCallback(t=>{if(q)return!1;const n=Do(t.ir,B);if(n.length>0)return Jt(n.join(", ")),!1;Jt(null);const r=zo(B,_,t.ir,{x:240,y:200+B.length%4*40},t.layout);return K(r.nodes),Y(r.edges),S(r.insertedNodeIds[0]??null),!0},[q,B,_,K,Y]),ws=o.useCallback(()=>{K(t=>Bs(t,_s(t,_,te)))},[K,_,te]),hs=o.useCallback(async()=>{if(!F||q)return;const t=at.trim();if(!t){Le(s("workflows.aiPromptRequired","Describe the workflow you want"));return}const n=new AbortController;ot.current=n;const r=F;jt(!0),Le(null);try{const b=await Rs({prompt:t,workflowId:r.id},i,n.signal);if(is.current!==r.id){d(s("workflows.aiStaleDiscarded","Discarded AI design — you switched workflows"),"warning");return}if(!await ue({title:s("workflows.aiReplaceTitle","Replace graph?"),message:s("workflows.aiReplaceConfirm","Replace the current graph with the AI design? Unsaved changes will be lost."),confirmLabel:s("workflows.aiReplaceConfirmLabel","Replace"),danger:!0}))return;const O=Ms({...r,ir:b.ir,layout:b.layout});K(O.nodes),Y(O.edges),Ve(As({...r,ir:b.ir})),qe(Ps({...r,ir:b.ir})),S(null),W(null),P(null),ee(b.interpreterOnly),b.strippedApprovalFlags&&d(s("workflows.importStripped","Auto-approval flags were removed from imported nodes"),"warning"),kt(!1),vt("")}catch(b){if(n.signal.aborted)return;Le(ae(b)||s("workflows.aiFailed","Failed to design workflow"))}finally{ot.current===n&&(ot.current=null),jt(!1)}},[F,q,at,i,ue,s,K,Y,d]),gs=o.useCallback(()=>{ot.current?.abort(),jt(!1)},[]),L=o.useCallback(t=>{v&&K(n=>n.map(r=>r.id===v?{...r,data:{...r.data,..."config"in t?{config:typeof t.config=="function"?t.config(r.data.config??{}):{...r.data.config??{},...t.config}}:t}}:r))},[v,K]),It=o.useCallback(t=>{$&&Y(n=>n.map(r=>{if(r.id!==$)return r;const b=t.condition??r.data?.condition??"success",y=t.rework??r.data?.kind==="rework";return{...r,label:y?`${Ds(b)} (rework)`:Ds(b),data:{...r.data??{},condition:b,kind:y?"rework":void 0},type:y?"step":void 0,animated:y,className:To(b,y)}}))},[$,Y]),xs=o.useCallback(t=>{const n=new Set(t);let r=null;K(b=>(r=zs(b,_,n),r.nodes)),r&&Y(r.edges),v!==null&&n.has(v)&&S(null),$!==null&&n.has($)&&W(null)},[_,K,Y,v,$]),Ma=o.useCallback(async({nodes:t,edges:n})=>{if(q)return!1;const r=new Set([...t.map(I=>I.id),...n.map(I=>I.id)]),b=zs(B,_,r),y=new Set(B.map(I=>I.id));for(const I of b.nodes)y.delete(I.id);const O=new Set(_.map(I=>I.id));for(const I of b.edges)O.delete(I.id);return y.size===0&&O.size===0?!1:{nodes:B.filter(I=>y.has(I.id)),edges:_.filter(I=>O.has(I.id))}},[q,B,_]),Aa=o.useCallback(()=>{S(null),gt.current?.focus()},[]),Pa=o.useCallback(()=>{W(null),gt.current?.focus()},[]),Ye=o.useCallback(()=>{oe(!1),De.current?.focus()},[]),Ra=o.useCallback(async(t,n,r)=>{const b=r.source!==void 0?Lo(r.source.ir,r.source.layout):{ir:ln(t),layout:nn()},y=await Lt({name:t,description:n||void 0,kind:"workflow",ir:b.ir,layout:b.layout},i);R(O=>[...O,y]),C(y.id),p(!1),d(s("workflows.created",'Created workflow "{{name}}"',{name:y.name}),"success"),Ye()},[i,d,s,Ye]),Da=o.useCallback(async(t,n,r)=>{const b=await Rs({prompt:t},i,r),y=`AI: ${t.slice(0,30)}`,I=await Lt({name:n||y,kind:"workflow",ir:b.ir,layout:b.layout},i);Nt.current=b.interpreterOnly,R(G=>[...G,I]),C(I.id),p(!1),d(s("workflows.created",'Created workflow "{{name}}"',{name:I.name}),"success"),b.strippedApprovalFlags&&d(s("workflows.importStripped","Auto-approval flags were removed from imported nodes"),"warning"),Ye()},[i,d,s,Ye]),bs=o.useCallback(async()=>{if(!(!F||We(F.id)||!await ue({title:s("workflows.deleteTitle","Delete workflow?"),message:s("workflows.deleteMessage",'Delete workflow "{{name}}"? This cannot be undone.',{name:F.name}),confirmLabel:s("common.delete","Delete"),danger:!0})))try{await Oo(F.id,i),R(n=>n.filter(r=>r.id!==F.id)),C(null),x&&p(!0),d(s("workflows.deleted","Workflow deleted"),"success")}catch(n){d(ae(n)||s("workflows.deleteFailed","Failed to delete workflow"),"error")}},[F,i,d,ue,s,x]),ks=o.useCallback(async()=>{if(F)try{const t=await Lt({name:`${F.name} (copy)`,description:F.description,ir:F.ir,layout:F.layout},i);R(n=>[...n,t]),C(t.id),p(!1),d(`Duplicated to "${t.name}" — editable`,"success")}catch(t){d(ae(t)||"Failed to duplicate workflow","error")}},[F,i,d]),vs=o.useCallback(async()=>{if(F&&!We(F.id)){if(Ie.length>0){const t=s("workflowColumns.unplacedCount","{{count}} nodes not placed in a column",{count:Ie.length});P(t),d(t,"error");return}if(us>0){const t=s("workflowColumns.compositionBlocked","Resolve trait conflicts on highlighted columns before saving");P(t),d(t,"error");return}T(!0),P(null),ee(!1),ms(null);try{const t=f.trim()||F.name,{ir:n,layout:r}=ca(t,B,_,te.length?te:void 0,Ce.length?Ce:void 0,Se.length?Se:void 0),b=t!==F.name,y=V!==(F.description??""),O=async G=>{R(we=>we.map(Ee=>Ee.id===G.id?G:Ee)),fe.current=_t(G.name,G.description??"",B,_,te,Ce,Se),A(G.name),Z(G.description??"");try{await $o(G.id,i),d(s("workflows.saved","Workflow saved"),"success")}catch(we){const Ee=ae(we)||"";Ee.includes("require the workflow interpreter (deferred)")?ee(!0):P(Ee||s("workflows.savedNotCompilable","Workflow saved but cannot be compiled"))}},I={ir:n,layout:r,...b?{name:t}:{},...y?{description:V}:{}};try{await O(await Ts(F.id,I,i))}catch(G){if(!(G?.details?.policyEscalation===!0))throw G;if(!window.confirm(`${ae(G)}
7
+
8
+ ${s("workflowColumns.confirmPolicyEscalation","Bind it anyway? The column agent will run with broader permissions than this project's default.")}`)){d(s("workflowColumns.escalationDeclined","Save cancelled — column agent binding not confirmed"),"error");return}await O(await Ts(F.id,{...I,confirmPolicyEscalation:!0},i))}}catch(t){const n=ae(t)||s("workflows.saveFailed","Failed to save workflow"),r=/node '([^']+)'/.exec(n);r&&B.some(b=>b.id===r[1])&&ms({nodeId:r[1],message:n}),P(n),d(n,"error")}finally{T(!1)}}},[F,f,V,B,_,te,Ce,Se,Ie,us,i,d,s]),Mt=o.useMemo(()=>{const t=new Set(Ie),n=new Map;for(const r of B)r.parentId&&n.set(r.parentId,(n.get(r.parentId)??0)+1);return B.map(r=>{let b;t.has(r.id)&&(b=s("workflowColumns.nodeUnplaced","Not placed in a column")),Ft?.nodeId===r.id&&(b=Ft.message);const y=r.data.kind==="foreach"||r.data.kind==="loop",O=r.data.kind==="loop"?s("workflowNodes.loopEmptyHint","Drag loop steps here"):s("workflowNodes.foreachEmptyHint","Drag a step-execute node here"),I=y?(n.get(r.id)??0)===0:void 0;return b===r.data.errorBadge&&(!y||I===r.data.templateEmpty&&r.data.emptyHint===O)?r:{...r,data:{...r.data,errorBadge:b,...y?{templateEmpty:I,emptyHint:O}:{}}}})},[B,Ie,Ft,s]),m=B.find(t=>t.id===v)??null,js=m!==null&&m.data.kind!=="start"&&m.data.kind!=="end",xe=_.find(t=>t.id===$)??null,za=x&&js&&!ne,Ta=x&&xe!==null,[At,Ns]=o.useState(!1),ys=o.useCallback(()=>{Ns(t=>!t)},[]),La=o.useCallback(t=>{!At||t.key!=="Escape"||(t.preventDefault(),t.stopPropagation(),Ns(!1))},[At]),Cs=m&&(m.data.kind==="prompt"||m.data.kind==="gate")?String(m.data.config?.prompt??(q?qn(m.data.config):"")):"",Ss=o.useMemo(()=>{if(!xe)return"readonly";const t=B.find(n=>n.id===xe.source);return Wo(t?.data.kind)},[xe,B]),Pt=o.useMemo(()=>{const t=F?.ir;return t&&t.version==="v2"&&Array.isArray(t.artifacts)?t.artifacts.map(n=>n.key):[]},[F]),[Me,Rt]=o.useState([]),[be,rt]=o.useState([]);o.useEffect(()=>{rt([])},[i]);const[Je,Es]=o.useState([]),[Oa,$a]=o.useState(Gn);o.useEffect(()=>{let t=!1;return Promise.resolve(ft()).then(n=>{!t&&n?.models&&Rt(n.models)}).catch(()=>{}),Promise.resolve(ut()).then(n=>{!t&&Array.isArray(n)&&rt(n)}).catch(()=>{}),Promise.resolve(Ls(i)).then(n=>{!t&&Array.isArray(n)&&Es(n)}).catch(()=>{}),()=>{t=!0}},[i]);const Dt=o.useMemo(()=>({models:Me.map(t=>({provider:t.provider,id:t.id,name:t.name})),agents:be.map(t=>({id:t.id,name:t.name})),skills:Je.map(t=>({id:t.id,name:t.name}))}),[Me,be,Je]),Wa=o.useMemo(()=>Vn(Mt,_,te,Dt,s),[Mt,_,te,Dt,s]),pe=m?.data.config?.executor??"model",Ae=o.useMemo(()=>{const t=m?.data.column??(m?.parentId?B.find(r=>r.id===m.parentId)?.data.column:void 0);if(!t)return;const n=te.find(r=>r.id===t);if(!(!n?.agent||n.agent.mode!=="override"))return n.agent},[m?.data.column,m?.parentId,B,te]),_a=o.useMemo(()=>Ae?be.find(t=>t.id===Ae.agentId):void 0,[Ae,be]);o.useEffect(()=>{if(pe!=="cli-agent")return;let t=!1;return fetch("/api/cli-agents").then(n=>n.ok?n.json():null).then(n=>{t||!n?.adapters||$a(n.adapters)}).catch(()=>{}),()=>{t=!0}},[pe]),o.useEffect(()=>{if(m?.data.kind==="step-review"&&Me.length===0){ft().then(t=>Rt(t.models)).catch(t=>{d(ae(t)||"Failed to load models","error")});return}!m||m.data.kind!=="prompt"&&m.data.kind!=="gate"||(pe==="model"&&Me.length===0?ft().then(t=>Rt(t.models)).catch(t=>{d(ae(t)||"Failed to load models","error")}):pe==="agent"&&be.length===0?ut(void 0,i).then(rt).catch(t=>{d(ae(t)||"Failed to load agents","error")}):pe==="skill"&&Je.length===0&&Ls(i).then(Es).catch(t=>{d(ae(t)||"Failed to load skills","error")}))},[pe,m?.id,m?.data.kind,i,d,Me.length,be.length,Je.length]);const dt=o.useCallback(t=>{if(!Ke){t();return}ue({title:s("workflows.discardTitle","Discard unsaved changes?"),message:s("workflows.discardMessage","You have unsaved changes to this workflow. Discard them?"),confirmLabel:s("workflows.discardConfirm","Discard"),danger:!0}).then(n=>{n&&t()})},[Ke,ue,s]),zt=o.useCallback(()=>{dt(a)},[dt,a]),Ba=o.useCallback(t=>{if(t===M){p(!1);return}dt(()=>{C(t),p(!1)})},[dt,M]);o.useEffect(()=>{if(!Ae||be.length>0)return;let t=!1;return Promise.resolve(ut(void 0,i)).then(n=>{t||rt(n??[])}).catch(n=>{t||d(ae(n)||"Failed to load agents","error")}),()=>{t=!0}},[Ae,be.length,i,d]);const Va=ua(zt),qa=At&&(m?.data.kind==="prompt"||m?.data.kind==="gate")?Ga.createPortal(e.jsxs("div",{className:"wf-prompt-editor wf-prompt-editor--fullscreen",onKeyDown:La,children:[e.jsxs("div",{className:"wf-prompt-fullscreen-header",children:[e.jsx("span",{children:s("workflowEditor.editingPrompt","Editing Prompt")}),e.jsx("button",{type:"button",className:"btn btn-sm wf-prompt-expand-btn",onClick:ys,"aria-label":s("workflowEditor.collapsePrompt","Collapse prompt editor"),title:s("workflowEditor.collapsePrompt","Collapse prompt editor"),children:e.jsx(_o,{size:14})})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"Prompt"}),e.jsx("textarea",{rows:void 0,value:Cs,readOnly:q,onChange:t=>L({config:{prompt:t.target.value}}),autoFocus:!0})]})]}),document.body):null;return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"modal-overlay open wf-editor-overlay",...Va,children:e.jsxs("div",{className:"modal wf-editor-modal",ref:D,onClick:t=>t.stopPropagation(),onKeyDown:t=>{if(t.key!=="Escape"||ye)return;const r=t.target.tagName;r==="INPUT"||r==="TEXTAREA"||r==="SELECT"||(t.stopPropagation(),zt())},children:[e.jsxs("header",{className:"wf-editor-header",children:[e.jsx("h2",{children:"Workflows"}),e.jsx("button",{className:"wf-editor-close",onClick:zt,"aria-label":"Close workflow editor",children:e.jsx(Ht,{size:18})})]}),ya?e.jsxs("div",{className:"wf-migration-notice",role:"status","data-testid":"wf-migration-notice",children:[e.jsx("span",{className:"wf-migration-notice-text",children:s("workflows.migrationNotice",'Your legacy workflow steps were converted — find them as templates in the palette and as the "Migrated steps" workflow.')}),e.jsx("button",{type:"button",className:"wf-migration-notice-dismiss","data-testid":"wf-migration-notice-dismiss",onClick:Sa,"aria-label":s("common.dismiss","Dismiss"),children:e.jsx(Ht,{size:14})})]}):null,e.jsxs("div",{className:`wf-editor-body${N?" wf-editor-body--list-stage":" wf-editor-body--editor-stage"}${H?" wf-editor-body--simple-layout":""}${za?" wf-editor-body--mobile-node-detail":""}${Ta?" wf-editor-body--mobile-edge-detail":""}`,children:[e.jsxs("aside",{className:"wf-editor-sidebar",children:[e.jsxs("button",{className:"wf-editor-new",ref:De,"data-testid":"wf-new-workflow",onClick:()=>oe(!0),children:[e.jsx(Ne,{size:14})," ",s("workflows.newWorkflow","New workflow")]}),e.jsxs("button",{type:"button",className:"wf-editor-import","data-testid":"wf-import",disabled:ns,onClick:()=>st.current?.click(),title:s("workflows.importTooltip","Import a workflow from a JSON file"),children:[ns?e.jsx(Fe,{size:14,className:"wf-spin"}):e.jsx(rn,{size:14})," ",s("workflows.import","Import")]}),e.jsx("input",{ref:st,type:"file",accept:".json",className:"wf-editor-import-input","data-testid":"wf-import-input",style:{display:"none"},onChange:Ea}),ss&&e.jsx("div",{className:"wf-editor-import-error",role:"alert","data-testid":"wf-import-error",children:ss}),as.length>0&&e.jsx("div",{className:"wf-editor-import-warnings","data-testid":"wf-import-warnings",children:as.map((t,n)=>e.jsx("p",{className:"wf-editor-import-warning",children:t},n))}),x&&u.length>0&&!F?e.jsx("div",{className:"wf-editor-select-note","data-testid":"wf-mobile-select-note",children:s("workflows.mobileSelectNote","Select a workflow to edit.")}):null,c?e.jsxs("div",{className:"wf-editor-empty",children:[e.jsx(Fe,{size:16,className:"wf-spin"})," Loading…"]}):u.length===0?e.jsx("div",{className:"wf-editor-empty",children:"No workflows yet."}):e.jsx("ul",{className:"wf-editor-list",children:u.map(t=>e.jsx("li",{children:e.jsx("button",{className:`wf-editor-list-item${t.id===M?" active":""}`,onClick:()=>Ba(t.id),children:t.name})},t.id))}),F&&!H&&e.jsxs("div",{className:"wf-sidebar-panels",children:[e.jsxs("section",{className:"wf-sidebar-section","data-testid":"wf-sidebar-columns-section",children:[e.jsxs("button",{type:"button",className:"wf-sidebar-section-toggle","aria-expanded":!Ge,"data-testid":"wf-sidebar-columns-toggle",onClick:()=>va(t=>!t),children:[Ge?e.jsx(Pe,{size:13}):e.jsx(je,{size:13}),e.jsx("span",{children:s("workflowColumns.title","Columns")})]}),!Ge&&e.jsx(qs,{columns:te,onChange:Ve,violations:St,readOnly:q,projectId:i,addToast:d,columnAgentsEnabled:ds})]}),e.jsxs("section",{className:"wf-sidebar-section","data-testid":"wf-sidebar-fields-section",children:[e.jsxs("button",{type:"button",className:"wf-sidebar-section-toggle","aria-expanded":!He,"data-testid":"wf-sidebar-fields-toggle",onClick:()=>ja(t=>!t),children:[He?e.jsx(Pe,{size:13}):e.jsx(je,{size:13}),e.jsx("span",{children:s("workflowFields.title","Fields")})]}),!He&&e.jsx(Us,{fields:Ce,onChange:qe,readOnly:q,addToast:d})]}),e.jsxs("section",{className:"wf-sidebar-section","data-testid":"wf-sidebar-settings-section",children:[e.jsxs("button",{type:"button",className:"wf-sidebar-section-toggle","aria-expanded":!Ue,"data-testid":"wf-sidebar-settings-toggle",onClick:()=>Na(t=>!t),children:[Ue?e.jsx(Pe,{size:13}):e.jsx(je,{size:13}),e.jsx("span",{children:s("workflowSettings.title","Settings")})]}),!Ue&&e.jsx("div",{ref:pt,className:"wf-settings-panel-wrap",children:e.jsx(Xs,{workflowId:F.id,settings:Se,onChange:Qe,readOnly:q,projectId:i,addToast:d,initialTab:"values"})})]})]})]}),e.jsxs("section",{className:"wf-editor-canvas-wrap",children:[e.jsxs("button",{type:"button",className:"wf-editor-mobile-back",onClick:()=>p(!0),"aria-label":s("workflows.backToWorkflowList","Back to workflows"),children:[e.jsx(Bo,{size:16}),e.jsx("span",{children:s("common.back","Back")})]}),F?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"wf-name-strip",children:[q?e.jsx("span",{className:"wf-workflow-name wf-workflow-name--readonly","data-testid":"wf-workflow-name",children:F.name}):ie?e.jsx("input",{className:"wf-workflow-name-input","data-testid":"wf-workflow-name-input",autoFocus:!0,value:f,"aria-label":s("workflows.nameLabel","Workflow name"),onChange:t=>A(t.target.value),onKeyDown:t=>{t.key==="Enter"?(t.preventDefault(),f.trim()||A(F.name),J(!1)):t.key==="Escape"&&(t.preventDefault(),A(F.name),J(!1))},onBlur:()=>{f.trim()||A(F.name),J(!1)}}):e.jsx("button",{type:"button",className:"wf-workflow-name","data-testid":"wf-workflow-name",onClick:()=>J(!0),title:s("workflows.clickToRename","Click to rename"),children:f||F.name}),q?F.description?e.jsx("span",{className:"wf-workflow-description wf-workflow-description--readonly","data-testid":"wf-workflow-description",children:F.description}):null:he?e.jsx("input",{className:"wf-workflow-description-input","data-testid":"wf-workflow-description-input",autoFocus:!0,value:V,"aria-label":s("workflows.descriptionLabel","Workflow description"),placeholder:s("workflows.descriptionPlaceholder","Add a description"),onChange:t=>Z(t.target.value),onKeyDown:t=>{t.key==="Enter"?(t.preventDefault(),X(!1)):t.key==="Escape"&&(t.preventDefault(),Z(F.description??""),X(!1))},onBlur:()=>X(!1)}):e.jsx("button",{type:"button",className:"wf-workflow-description","data-testid":"wf-workflow-description",onClick:()=>X(!0),title:s("workflows.clickToEditDescription","Click to edit description"),children:V||s("workflows.descriptionPlaceholder","Add a description")}),!x&&e.jsxs("button",{type:"button",className:"wf-layout-toggle","data-testid":"wf-layout-toggle","aria-pressed":le,onClick:()=>Q(t=>!t),children:[le?e.jsx(Ot,{size:14}):e.jsx(fa,{size:14}),e.jsx("span",{children:le?s("workflows.showCanvasEditor","Show canvas editor"):s("workflows.showSimpleEditor","Show simple editor")})]})]}),H&&e.jsxs("div",{className:"wf-mobile-shell","data-testid":"wf-mobile-shell",children:[e.jsx("nav",{className:"wf-mobile-tabs","aria-label":s("workflows.mobileEditorNav","Workflow editor sections"),children:[["graph",s("workflowNodes.mobileGraph","Graph")],["add",s("workflowNodes.mobileAdd","Add")],["settings",s("workflowSettings.title","Settings")],["fields",s("workflowFields.title","Fields")],["columns",s("workflowColumns.title","Columns")],["actions",s("workflowNodes.mobileActions","Actions")]].map(([t,n])=>e.jsx("button",{type:"button",className:`wf-mobile-tab${se===t?" wf-mobile-tab--active":""}`,"aria-current":se===t?"page":void 0,"data-testid":`wf-mobile-tab-${t}`,onClick:()=>E(t),children:n},t))}),e.jsxs("div",{className:"wf-mobile-panel","data-testid":`wf-mobile-panel-${se}`,children:[se==="graph"&&e.jsx(Wn,{rows:Wa,selectedNodeId:v,selectedEdgeId:$,onSelectNode:t=>{S(t),W(null),re(!1)},onSelectEdge:t=>{W(t),S(null)}}),se==="add"&&e.jsx("div",{className:"wf-mobile-add",children:q?e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:s("workflows.readOnlyBuiltin","Read-only built-in workflow")}):e.jsxs(e.Fragment,{children:[e.jsxs("section",{className:"wf-mobile-add-section",children:[e.jsx("h3",{children:s("workflowNodes.mobileNodeKinds","Node types")}),e.jsx("div",{className:"wf-mobile-add-grid",children:na.map(({kind:t,label:n,icon:r,presetConfig:b})=>e.jsxs("button",{type:"button",className:"wf-mobile-add-option","data-testid":`wf-mobile-add-${t}-${n.toLowerCase().replace(/[^a-z0-9]+/g,"-")}`,onClick:()=>{lt(t,n,b),E("graph")},children:[e.jsx(r,{size:16,"aria-hidden":!0}),e.jsx("span",{children:n})]},n))})]}),cs&&e.jsxs("section",{className:"wf-mobile-add-section",children:[e.jsx("h3",{children:s("workflowNodes.templatesSection","Templates")}),Ct>8&&e.jsx("input",{type:"text",className:"wf-templates-filter wf-mobile-template-filter","data-testid":"wf-mobile-template-filter",value:Ze,onChange:t=>Yt(t.target.value),placeholder:s("workflowNodes.templateFilterPlaceholder","Filter templates"),"aria-label":s("workflowNodes.templateFilterLabel","Filter templates")}),et&&e.jsx("div",{className:"wf-templates-conflict",role:"alert","data-testid":"wf-mobile-tpl-conflict",children:s("workflowNodes.templateSeamConflict",`This fragment duplicates the "{{seam}}" seam already on the canvas, so it can't be inserted.`,{seam:et})}),me.fragmentEntries.length>0&&e.jsxs("div",{className:"wf-mobile-template-group",children:[e.jsx("h4",{children:s("workflowNodes.templatesFragments","Fragments")}),me.fragmentEntries.map(t=>e.jsx("button",{type:"button",className:"wf-mobile-template-option","data-testid":`wf-mobile-tpl-fragment-${t.id}`,onClick:()=>{ps(t)&&E("graph")},children:t.name},t.id))]}),me.stepEntries.length>0&&e.jsxs("div",{className:"wf-mobile-template-group",children:[e.jsx("h4",{children:s("workflowNodes.templatesBuiltinSteps","Built-in steps")}),me.stepEntries.map(t=>e.jsx("button",{type:"button",className:"wf-mobile-template-option","data-testid":`wf-mobile-tpl-step-${t.id}`,onClick:()=>{it(t),E("graph")},children:t.name},t.id))]}),me.pluginEntries.length>0&&e.jsxs("div",{className:"wf-mobile-template-group",children:[e.jsx("h4",{children:s("workflowNodes.templatesPluginSteps","Plugin steps")}),me.pluginEntries.map(({pluginId:t,template:n})=>e.jsxs("button",{type:"button",className:"wf-mobile-template-option","data-testid":`wf-mobile-tpl-plugin-${n.id}`,onClick:()=>{it(n),E("graph")},children:[e.jsx("span",{children:n.name}),e.jsx("span",{className:"wf-templates-badge",children:t})]},`${t}:${n.id}`))]})]})]})}),se==="settings"&&F&&e.jsx("div",{ref:pt,className:"wf-mobile-destination",children:e.jsx(Xs,{workflowId:F.id,settings:Se,onChange:Qe,readOnly:q,projectId:i,addToast:d,initialTab:"values"})}),se==="fields"&&e.jsx("div",{className:"wf-mobile-destination",children:e.jsx(Us,{fields:Ce,onChange:qe,readOnly:q,addToast:d})}),se==="columns"&&e.jsx("div",{className:"wf-mobile-destination",children:e.jsx(qs,{columns:te,onChange:Ve,violations:St,readOnly:q,projectId:i,addToast:d,columnAgentsEnabled:ds})}),se==="actions"&&e.jsx("div",{className:"wf-mobile-actions",children:q?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:s("workflows.readOnlyBuiltin","Read-only built-in workflow")}),e.jsxs("button",{className:"wf-editor-action","data-testid":"wf-mobile-export",onClick:nt,children:[e.jsx(ct,{size:15})," ",s("workflows.export","Export")]}),e.jsxs("button",{className:"wf-editor-save wf-editor-duplicate-primary","data-testid":"wf-mobile-duplicate",onClick:ks,children:[e.jsx(Ne,{size:15})," ",s("workflows.duplicateToCustomize","Duplicate to customize")]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"wf-editor-save","data-testid":"wf-mobile-save",onClick:vs,disabled:h,children:[h?e.jsx(Fe,{size:15,className:"wf-spin"}):e.jsx(qt,{size:15}),s("common.save","Save")]}),e.jsxs("button",{className:"wf-editor-action","data-testid":"wf-mobile-ai-edit",onClick:()=>kt(t=>!t),children:[e.jsx($e,{size:15})," ",s("workflows.aiEdit","Design with AI")]}),bt&&e.jsxs("div",{className:"wf-ai-panel wf-mobile-ai-panel","data-testid":"wf-mobile-ai-panel",role:"dialog","aria-busy":ge,children:[e.jsx("textarea",{className:"wf-ai-prompt","data-testid":"wf-mobile-ai-edit-prompt",rows:4,value:at,disabled:ge,placeholder:s("workflows.aiPromptPlaceholder","e.g. Run lint and tests before merge, then post a changelog comment after merge"),onChange:t=>{vt(t.target.value),Te&&Le(null)}}),Te&&e.jsx("p",{className:"wf-create-error",role:"alert","data-testid":"wf-mobile-ai-edit-error",children:Te}),e.jsxs("div",{className:"wf-ai-actions",children:[e.jsxs("button",{type:"button",className:"btn btn-primary wf-ai-submit","data-testid":"wf-mobile-ai-edit-submit",disabled:ge,onClick:()=>void hs(),children:[ge?e.jsx(Fe,{size:13,className:"wf-spin"}):e.jsx($e,{size:13}),s("workflows.aiSubmit","Design with AI")]}),ge&&e.jsx("button",{type:"button",className:"btn wf-ai-cancel",onClick:gs,children:s("common.cancel","Cancel")})]})]}),e.jsxs("button",{className:"wf-editor-action","data-testid":"wf-mobile-auto-layout",onClick:ws,children:[e.jsx(Ot,{size:15})," ",s("workflowNodes.autoLayout","Auto-layout")]}),e.jsxs("button",{className:"wf-editor-action","data-testid":"wf-mobile-export",onClick:nt,disabled:Ke,children:[e.jsx(ct,{size:15})," ",s("workflows.export","Export")]}),e.jsxs("button",{className:"wf-editor-delete","data-testid":"wf-mobile-delete",onClick:bs,children:[e.jsx(ke,{size:15})," ",s("common.delete","Delete")]})]})})]})]}),q?e.jsxs("div",{className:"wf-editor-readonly-banner",role:"status","data-testid":"wf-readonly-banner",children:[e.jsx("span",{className:"wf-editor-readonly-note",children:s("workflows.readOnlyBuiltin","Read-only built-in workflow")}),e.jsxs("button",{className:"wf-editor-action","data-testid":"wf-export",onClick:nt,title:s("workflows.exportTooltip","Download as JSON — contains your full prompt and command text"),children:[e.jsx(ct,{size:13})," ",s("workflows.export","Export")]}),e.jsxs("button",{className:"wf-editor-save wf-editor-duplicate-primary",onClick:ks,children:[e.jsx(Ne,{size:13})," ",s("workflows.duplicateToCustomize","Duplicate to customize")]})]}):e.jsxs("div",{className:"wf-editor-toolbar",children:[e.jsx("div",{className:"wf-editor-palette",children:na.map(({kind:t,label:n,icon:r,presetConfig:b})=>e.jsxs("button",{className:"wf-palette-btn",onClick:()=>lt(t,n,b),children:[e.jsx(r,{size:13})," ",n]},n))}),e.jsxs("div",{className:"wf-editor-actions",children:[e.jsxs("div",{className:"wf-ai-edit-wrap",children:[e.jsxs("button",{className:"wf-editor-action","data-testid":"wf-ai-edit","aria-expanded":bt,onClick:()=>{kt(t=>!t),Le(null)},children:[e.jsx($e,{size:13})," ",s("workflows.aiEdit","Design with AI")]}),bt&&e.jsxs("div",{className:"wf-ai-panel","data-testid":"wf-ai-panel",role:"dialog","aria-busy":ge,"aria-label":s("workflows.aiEdit","Design with AI"),children:[e.jsx("textarea",{className:"wf-ai-prompt","data-testid":"wf-ai-edit-prompt",rows:3,value:at,disabled:ge,placeholder:s("workflows.aiPromptPlaceholder","e.g. Run lint and tests before merge, then post a changelog comment after merge"),onChange:t=>{vt(t.target.value),Te&&Le(null)}}),Te&&e.jsx("p",{className:"wf-create-error",role:"alert","data-testid":"wf-ai-edit-error",children:Te}),e.jsxs("div",{className:"wf-ai-actions",children:[e.jsxs("button",{type:"button",className:"btn btn-primary wf-ai-submit","data-testid":"wf-ai-edit-submit",disabled:ge,onClick:()=>void hs(),children:[ge?e.jsx(Fe,{size:13,className:"wf-spin"}):e.jsx($e,{size:13})," ",s("workflows.aiSubmit","Design with AI")]}),ge&&e.jsx("button",{type:"button",className:"btn wf-ai-cancel","data-testid":"wf-ai-edit-cancel",onClick:gs,children:s("common.cancel","Cancel")})]})]})]}),e.jsxs("button",{className:"wf-editor-action",onClick:ws,"data-testid":"wf-auto-layout",children:[e.jsx(Ot,{size:13})," ",s("workflowNodes.autoLayout","Auto-layout")]}),e.jsxs("button",{className:"wf-editor-action","data-testid":"wf-export",onClick:nt,disabled:Ke,title:Ke?s("workflows.exportDirtyTooltip","Save before exporting"):s("workflows.exportTooltip","Download as JSON — contains your full prompt and command text"),children:[e.jsx(ct,{size:13})," ",s("workflows.export","Export")]}),e.jsxs("button",{className:"wf-editor-delete",onClick:bs,children:[e.jsx(ke,{size:13})," ",s("common.delete","Delete")]}),e.jsxs("button",{className:"wf-editor-save",onClick:vs,disabled:h,children:[h?e.jsx(Fe,{size:13,className:"wf-spin"}):e.jsx(qt,{size:13})," ",s("common.save","Save")]})]})]}),cs&&e.jsxs("section",{className:"wf-templates","data-testid":"wf-palette-templates","aria-label":s("workflowNodes.templatesSection","Templates"),children:[e.jsxs("div",{className:"wf-templates-header",children:[e.jsxs("button",{type:"button",className:"wf-templates-toggle","aria-expanded":!ze,"data-testid":"wf-templates-toggle",onClick:()=>ka(t=>!t),children:[ze?e.jsx(Pe,{size:13}):e.jsx(je,{size:13}),e.jsx(cn,{size:13})," ",s("workflowNodes.templatesSection","Templates")]}),!ze&&Ct>8&&e.jsx("input",{type:"text",className:"wf-templates-filter","data-testid":"wf-template-filter",value:Ze,onChange:t=>Yt(t.target.value),placeholder:s("workflowNodes.templateFilterPlaceholder","Filter templates"),"aria-label":s("workflowNodes.templateFilterLabel","Filter templates")})]}),!ze&&e.jsxs("div",{className:"wf-templates-body",children:[et&&e.jsx("div",{className:"wf-templates-conflict",role:"alert","data-testid":"wf-tpl-conflict",children:s("workflowNodes.templateSeamConflict",`This fragment duplicates the "{{seam}}" seam already on the canvas, so it can't be inserted.`,{seam:et})}),me.fragmentEntries.length>0&&e.jsxs("div",{className:"wf-templates-group",children:[e.jsx("h4",{className:"wf-templates-group-title",children:s("workflowNodes.templatesFragments","Fragments")}),e.jsx("div",{className:"wf-templates-entries",children:me.fragmentEntries.map(t=>e.jsx("button",{type:"button",className:"wf-templates-entry","data-testid":`wf-tpl-fragment-${t.id}`,disabled:q,"aria-label":s("workflowNodes.insertTemplate","Insert template {{name}}",{name:t.name}),onClick:()=>ps(t),children:t.name},t.id))})]}),me.stepEntries.length>0&&e.jsxs("div",{className:"wf-templates-group",children:[e.jsx("h4",{className:"wf-templates-group-title",children:s("workflowNodes.templatesBuiltinSteps","Built-in steps")}),e.jsx("div",{className:"wf-templates-entries",children:me.stepEntries.map(t=>e.jsx("button",{type:"button",className:"wf-templates-entry","data-testid":`wf-tpl-step-${t.id}`,disabled:q,"aria-label":s("workflowNodes.insertTemplate","Insert template {{name}}",{name:t.name}),onClick:()=>it(t),children:t.name},t.id))})]}),me.pluginEntries.length>0&&e.jsxs("div",{className:"wf-templates-group",children:[e.jsx("h4",{className:"wf-templates-group-title",children:s("workflowNodes.templatesPluginSteps","Plugin steps")}),e.jsx("div",{className:"wf-templates-entries",children:me.pluginEntries.map(({pluginId:t,template:n})=>e.jsxs("button",{type:"button",className:"wf-templates-entry","data-testid":`wf-tpl-plugin-${n.id}`,disabled:q,"aria-label":s("workflowNodes.insertTemplate","Insert template {{name}}",{name:n.name}),onClick:()=>it(n),children:[n.name,e.jsx("span",{className:"wf-templates-badge",children:t})]},`${t}:${n.id}`))})]})]})]}),k&&e.jsx("div",{className:"wf-editor-banner",role:"alert",children:k}),U&&e.jsx("div",{className:"wf-editor-banner wf-editor-banner--info",role:"status","data-testid":"wf-interpreter-only-banner",children:s("workflowNodes.interpreterOnly","This workflow branches, so it runs on the graph interpreter — it can't compile to the linear step engine, but it will still run.")}),Ie.length>0&&e.jsx("div",{className:"wf-editor-banner wf-editor-banner--warn",role:"alert","data-testid":"wf-unplaced-summary",children:s("workflowColumns.unplacedCount","{{count}} nodes not placed in a column",{count:Ie.length})}),e.jsxs("div",{className:"wf-editor-canvas",ref:gt,tabIndex:-1,children:[x&&ne&&m&&m.data.kind!=="start"&&m.data.kind!=="end"&&e.jsxs("button",{type:"button",className:"wf-inspector-toggle wf-inspector-toggle--collapsed","data-testid":"wf-inspector-toggle","aria-expanded":"false",onClick:()=>re(!1),children:[e.jsx(Pe,{size:13}),e.jsx("span",{children:s("workflowNodes.showInspector","Show node details")})]}),Ca&&e.jsx("div",{className:"wf-trivial-hint",role:"status","data-testid":"wf-trivial-hint",children:s("workflowNodes.trivialGraphHint","This workflow only runs start → end. Add steps from the palette above to build it out.")}),e.jsx(en.Provider,{value:Dt,children:e.jsxs(Ja,{nodes:Mt,edges:_,nodeTypes:sn,onNodesChange:de,onEdgesChange:ce,onConnect:Fa,onNodeDragStop:Ia,deleteKeyCode:q?null:["Backspace","Delete"],onBeforeDelete:Ma,onNodesDelete:Aa,onEdgesDelete:Pa,onNodeClick:(t,n)=>{S(n.id),W(null),re(!1)},onEdgeClick:(t,n)=>{W(n.id),S(null)},onPaneClick:()=>{S(null),W(null)},defaultEdgeOptions:{interactionWidth:tn},defaultViewport:{x:0,y:0,zoom:1},children:[e.jsx(Xa,{}),e.jsx(Qa,{}),e.jsx(Za,{pannable:!0,zoomable:!0})]})})]})]}):e.jsxs("div",{className:"wf-editor-empty wf-editor-canvas-empty wf-editor-onboard",children:[e.jsx(an,{className:"wf-editor-onboard-icon",size:40,"aria-hidden":!0}),e.jsx("h3",{className:"wf-editor-onboard-title",children:s("workflows.emptyTitle","No workflow selected")}),e.jsx("p",{className:"wf-editor-onboard-text",children:s("workflows.emptyDescription","Workflows orchestrate the steps and gates that run around task execution. Create one to start arranging that flow.")}),e.jsxs("button",{className:"wf-editor-save wf-editor-onboard-cta","data-testid":"wf-empty-create",onClick:()=>oe(!0),children:[e.jsx(Ne,{size:14})," ",s("workflows.newWorkflow","New workflow")]})]})]}),js&&!(x&&ne)&&!(le&&!x)&&e.jsxs("aside",{className:"wf-editor-inspector","data-testid":"wf-node-inspector",children:[e.jsxs("div",{className:"wf-inspector-heading",children:[e.jsx("h3",{children:"Node"}),x&&e.jsxs("button",{type:"button",className:"wf-inspector-toggle wf-inspector-toggle--expanded","data-testid":"wf-inspector-toggle","aria-expanded":"true",onClick:()=>{H?S(null):re(!0)},children:[e.jsx(je,{size:13}),e.jsx("span",{children:s("workflowNodes.collapseInspector","Collapse")})]})]}),q&&e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:"Read-only built-in — duplicate the workflow to edit nodes."}),e.jsx("fieldset",{className:"wf-inspector-fields",disabled:q,children:e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"Name"}),e.jsx("input",{value:m.data.label,onChange:t=>L({label:t.target.value})})]})}),m.data.kind==="prompt"||m.data.kind==="gate"?e.jsxs("div",{className:"wf-prompt-editor",children:[e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"Prompt"}),e.jsx("textarea",{rows:5,value:Cs,readOnly:q,onChange:t=>L({config:{prompt:t.target.value}})})]}),e.jsx("button",{type:"button",className:"btn btn-sm wf-prompt-expand-btn wf-prompt-expand-btn--inline",onClick:ys,"aria-label":s("workflowEditor.expandPrompt","Expand prompt editor"),title:s("workflowEditor.expandPrompt","Expand prompt editor"),children:e.jsx(on,{size:14})})]}):null,e.jsxs("fieldset",{className:"wf-inspector-fields",disabled:q,children:[m.data.kind==="prompt"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"Executor"}),e.jsxs("select",{value:pe,onChange:t=>L({config:{executor:t.target.value}}),children:[e.jsx("option",{value:"model",children:"Model"}),e.jsx("option",{value:"agent",children:"Agent"}),e.jsx("option",{value:"skill",children:"Skill"}),e.jsx("option",{value:"cli",children:"CLI / script"}),e.jsx("option",{value:"cli-agent",children:s("workflowEditor.cliAgent.executorOption")})]})]}),Ae&&e.jsx("p",{className:"wf-inspector-note wf-inspector-note--warn","data-testid":"wf-node-overridden-by-column-agent",children:s("workflowColumns.overriddenByColumnAgent","Overridden by column agent {{name}} — this node's executor settings are superseded.",{name:_a?.name??s("workflowColumns.agentNotFound","Agent not found — {{id}}",{id:Ae.agentId})})}),pe==="model"&&e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"Model"}),e.jsx(Gt,{label:"Model",models:Me,value:ea(String(m.data.config?.modelProvider??""),String(m.data.config?.modelId??"")),onChange:t=>{const{provider:n,modelId:r}=ta(t);L({config:{modelProvider:n||void 0,modelId:r||void 0}})}})]}),pe==="agent"&&(()=>{const t=String(m.data.config?.agentId??""),n=t!==""&&!be.some(r=>r.id===t);return e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"Agent"}),e.jsxs("select",{value:t,onChange:r=>L({config:{agentId:r.target.value||void 0}}),children:[e.jsx("option",{value:"",children:"— select agent —"}),n&&e.jsx("option",{value:t,children:s("workflowColumns.agentNotFound","Agent not found — {{id}}",{id:t})}),be.map(r=>e.jsx("option",{value:r.id,children:r.name},r.id))]}),n&&e.jsx("p",{className:"wf-inspector-note wf-inspector-note--warn","data-testid":"wf-node-agent-stale",children:s("workflowColumns.agentNotFound","Agent not found — {{id}}",{id:t})})]})})(),pe==="skill"&&e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"Skill"}),e.jsxs("select",{value:String(m.data.config?.skillName??""),onChange:t=>L({config:{skillName:t.target.value||void 0}}),children:[e.jsx("option",{value:"",children:"— select skill —"}),Je.map(t=>e.jsx("option",{value:t.name,children:t.name},t.id))]})]}),pe==="cli"&&e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"CLI mode"}),e.jsxs("select",{value:String(m.data.config?.cliMode??"command"),onChange:t=>L({config:{cliMode:t.target.value}}),children:[e.jsx("option",{value:"command",children:"Command"}),e.jsx("option",{value:"script",children:"Named script"})]})]}),(m.data.config?.cliMode??"command")==="command"?e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"Command"}),e.jsx("textarea",{rows:3,placeholder:"npm test -- --runInBand",value:String(m.data.config?.cliCommand??""),onChange:t=>L({config:{cliCommand:t.target.value}})}),e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:"Runs an arbitrary command in the task worktree. The first time this exact command runs, the task pauses for your approval. The node prompt is passed via FUSION_NODE_PROMPT."}),e.jsxs("label",{className:"wf-field wf-field--checkbox",children:[e.jsx("input",{type:"checkbox",checked:m.data.config?.cliSkipApproval===!0,onChange:t=>L({config:{cliSkipApproval:t.target.checked}})}),e.jsx("span",{children:"Skip first-run approval (runs without pausing)"})]})]}):e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"Script name"}),e.jsx("input",{value:String(m.data.config?.scriptName??""),onChange:t=>L({config:{scriptName:t.target.value}})}),e.jsx("span",{className:"wf-inspector-note",children:"Named script from project settings. The node prompt is passed via FUSION_NODE_PROMPT."})]})]}),pe==="cli-agent"&&e.jsxs("div",{"data-testid":"cli-agent-config",children:[e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowEditor.cliAgent.adapterLabel")}),e.jsxs("select",{"data-testid":"cli-agent-adapter",value:String(m.data.config?.cliAdapterId??""),onChange:t=>L({config:{cliAdapterId:t.target.value||void 0}}),children:[e.jsx("option",{value:"",children:s("workflowEditor.cliAgent.adapterPlaceholder")}),Oa.map(t=>e.jsxs("option",{value:t.id,children:[t.name," (",s(`workflowEditor.cliAgent.tier.${t.tier}`),")"]},t.id))]}),e.jsx("span",{className:"wf-inspector-note",children:s("workflowEditor.cliAgent.adapterNote")})]}),e.jsxs("label",{className:"wf-field wf-field--checkbox",children:[e.jsx("input",{type:"checkbox","data-testid":"cli-agent-autonomy",checked:!!m.data.config?.cliAutonomy?.autoApprove,onChange:t=>L({config:{cliAutonomy:{...m.data.config?.cliAutonomy??{},autoApprove:t.target.checked}}})}),e.jsx("span",{children:s("workflowEditor.cliAgent.autonomyLabel")})]}),!!m.data.config?.cliAutonomy?.autoApprove&&e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:s("workflowEditor.cliAgent.autonomyNote")}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowEditor.cliAgent.notifyLabel")}),e.jsxs("select",{"data-testid":"cli-agent-notify",value:String(m.data.config?.cliNotify?.mode??"banner"),onChange:t=>L({config:{cliNotify:{mode:t.target.value}}}),children:[e.jsx("option",{value:"banner",children:s("workflowEditor.cliAgent.notify.banner")}),e.jsx("option",{value:"banner+notify",children:s("workflowEditor.cliAgent.notify.bannerNotify")})]}),e.jsx("span",{className:"wf-inspector-note",children:s("workflowEditor.cliAgent.notifyNote")})]})]}),e.jsxs("label",{className:"wf-field wf-field--checkbox",children:[e.jsx("input",{type:"checkbox",checked:!!m.data.config?.autoApprove,onChange:t=>L({config:{autoApprove:t.target.checked}})}),e.jsx("span",{children:"Auto-approve requests"})]}),!!m.data.config?.autoApprove&&e.jsx("p",{className:"wf-inspector-note",children:"Runs without pausing for approval — e.g. a CLI command executes on its first run without waiting for your sign-off."}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"Max retries"}),e.jsx("input",{type:"number",min:1,max:10,placeholder:"default",value:m.data.config?.maxRetries!=null?String(m.data.config.maxRetries):"",onChange:t=>{const n=t.target.value.trim();if(n==="")L({config:r=>{const b={...r};return delete b.maxRetries,b}});else{const r=parseInt(n,10);isNaN(r)||L({config:{maxRetries:r}})}}})]}),e.jsxs("label",{className:"wf-field wf-field--checkbox",children:[e.jsx("input",{type:"checkbox",checked:!!m.data.config?.awaitInput,onChange:t=>L({config:{awaitInput:t.target.checked}})}),e.jsx("span",{children:"Wait for user input"})]}),!!m.data.config?.awaitInput&&e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:"This node pauses the task until you reply in the task's comments and unpause. The Prompt field above is shown to the user as the question."})]}):null,m.data.kind==="script"?e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:"Script name"}),e.jsx("input",{value:String(m.data.config?.scriptName??""),onChange:t=>L({config:{scriptName:t.target.value}})})]}):null,m.data.kind==="hold"?e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.releaseCondition","Release condition")}),e.jsxs("select",{value:String(m.data.config?.release??"manual"),onChange:t=>L({config:{release:t.target.value}}),children:[e.jsx("option",{value:"manual",children:s("workflowNodes.releaseManual","Manual promote")}),e.jsx("option",{value:"timer",children:s("workflowNodes.releaseTimer","Timer")}),e.jsx("option",{value:"capacity",children:s("workflowNodes.releaseCapacity","Downstream capacity")}),e.jsx("option",{value:"dependency",children:s("workflowNodes.releaseDependency","Dependency complete")}),e.jsx("option",{value:"external-event",children:s("workflowNodes.releaseExternal","External event")})]})]}):null,m.data.kind==="join"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.joinMode","Join mode")}),e.jsxs("select",{value:(()=>{const t=m.data.config?.mode;return t&&typeof t=="object"&&"quorum"in t?"quorum":typeof t=="string"?t:"all"})(),onChange:t=>{const n=t.target.value;L(n==="quorum"?{config:{mode:{quorum:2}}}:{config:{mode:n}})},children:[e.jsx("option",{value:"all",children:s("workflowNodes.joinAll","All branches")}),e.jsx("option",{value:"any",children:s("workflowNodes.joinAny","Any branch")}),e.jsx("option",{value:"quorum",children:s("workflowNodes.joinQuorum","Quorum (n)")})]})]}),(()=>{const t=m.data.config?.mode;return t&&typeof t=="object"&&"quorum"in t})()&&e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.quorumN","Quorum count (n)")}),e.jsx("input",{type:"number",min:1,value:String(m.data.config?.mode?.quorum??2),onChange:t=>{const n=parseInt(t.target.value,10);isNaN(n)||L({config:{mode:{quorum:n}}})}})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.failurePolicy","On branch failure")}),e.jsxs("select",{value:String(m.data.config?.onBranchFailure??"collect"),onChange:t=>L({config:{onBranchFailure:t.target.value}}),children:[e.jsx("option",{value:"collect",children:s("workflowNodes.failureCollect","Collect (wait for all)")}),e.jsx("option",{value:"fail-fast",children:s("workflowNodes.failureFailFast","Fail-fast (cancel siblings)")})]})]})]}):null,m.data.kind==="split"?e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:s("workflowNodes.splitNote","Branches run concurrently from this node. Execute and merge seams are not allowed inside a branch.")}):null,m.data.kind==="foreach"?(()=>{const t=String(m.data.config?.mode??"sequential"),n=t==="parallel";return e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.foreachMode","Mode")}),e.jsxs("select",{value:t,onChange:r=>{const b=r.target.value;L({config:y=>({...y,mode:b,...b==="parallel"&&y.isolation==="shared"?{isolation:"worktree"}:{}})})},children:[e.jsx("option",{value:"sequential",children:s("workflowNodes.foreachSequential","Sequential")}),e.jsx("option",{value:"parallel",children:s("workflowNodes.foreachParallel","Parallel")})]})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.foreachIsolation","Isolation")}),e.jsxs("select",{value:String(m.data.config?.isolation??(n?"worktree":"shared")),onChange:r=>L({config:{isolation:r.target.value}}),children:[e.jsx("option",{value:"shared",disabled:n,children:s("workflowNodes.foreachShared","Shared worktree")}),e.jsx("option",{value:"worktree",children:s("workflowNodes.foreachWorktree","Per-step worktree")})]})]}),n&&e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.foreachConcurrency","Concurrency")}),e.jsx("input",{type:"number",min:1,max:8,placeholder:"2",value:m.data.config?.concurrency!=null?String(m.data.config.concurrency):"",onChange:r=>{const b=r.target.value.trim();if(b==="")L({config:y=>{const O={...y};return delete O.concurrency,O}});else{const y=parseInt(b,10);isNaN(y)||L({config:{concurrency:y}})}}})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.foreachMaxRework","Max rework cycles")}),e.jsx("input",{type:"number",min:1,max:10,placeholder:"3",value:m.data.config?.maxReworkCycles!=null?String(m.data.config.maxReworkCycles):"",onChange:r=>{const b=r.target.value.trim();if(b==="")L({config:y=>{const O={...y};return delete O.maxReworkCycles,O}});else{const y=parseInt(b,10);isNaN(y)||L({config:{maxReworkCycles:y}})}}})]}),e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:s("workflowNodes.foreachNote","Expands once per planned step. Drop a step-execute node (and optional step-review) into the region.")})]})})():null,m.data.kind==="loop"?(()=>{const t=m.data.config?.exitWhen&&typeof m.data.config.exitWhen=="object"?m.data.config.exitWhen:{type:"output-contains",value:"DONE"},n=String(t.type??"output-contains"),r=String(n==="output-matches"?t.pattern??"":t.value??"");return e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.loopExitType","Exit condition")}),e.jsxs("select",{value:n,onChange:b=>{const y=b.target.value;L({config:O=>{const I=O.exitWhen&&typeof O.exitWhen=="object"?O.exitWhen:{},G=String(y==="output-matches"?I.pattern??I.value??"":I.value??I.pattern??""),we={...I,type:y};return delete we.pattern,delete we.value,{...O,exitWhen:y==="output-matches"?{...we,pattern:G}:{...we,value:G}}}})},children:[e.jsx("option",{value:"output-contains",children:s("workflowNodes.loopOutputContains","Output contains")}),e.jsx("option",{value:"output-matches",children:s("workflowNodes.loopOutputMatches","Output matches regex")})]})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:n==="output-matches"?s("workflowNodes.loopPattern","Pattern"):s("workflowNodes.loopValue","Value")}),e.jsx("input",{value:r,placeholder:n==="output-matches"?"DONE|COMPLETE":"DONE",onChange:b=>{const y=b.target.value;L({config:O=>{const I=O.exitWhen&&typeof O.exitWhen=="object"?O.exitWhen:{};return{...O,exitWhen:n==="output-matches"?{...I,type:n,pattern:y}:{...I,type:n,value:y}}}})}})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.loopNodeId","Watch node id (optional)")}),e.jsx("input",{value:String(t.nodeId??""),placeholder:s("workflowNodes.loopNodeIdPlaceholder","Template exit node"),onChange:b=>{const y=b.target.value.trim();L({config:O=>{const G={...O.exitWhen&&typeof O.exitWhen=="object"?O.exitWhen:{type:"output-contains",value:"DONE"}};return y?G.nodeId=y:delete G.nodeId,{...O,exitWhen:G}}})}})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.loopMaxIterations","Max iterations")}),e.jsx("input",{type:"number",min:1,max:50,placeholder:"3",value:m.data.config?.maxIterations!=null?String(m.data.config.maxIterations):"",onChange:b=>{const y=b.target.value.trim();L({config:O=>{const I={...O};if(y==="")delete I.maxIterations;else{const G=parseInt(y,10);isNaN(G)||(I.maxIterations=G)}return I}})}})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.loopTimeoutMs","Timeout (ms)")}),e.jsx("input",{type:"number",min:1,max:36e5,placeholder:"300000",value:m.data.config?.timeoutMs!=null?String(m.data.config.timeoutMs):"",onChange:b=>{const y=b.target.value.trim();L({config:O=>{const I={...O};if(y==="")delete I.timeoutMs;else{const G=parseInt(y,10);isNaN(G)||(I.timeoutMs=G)}return I}})}})]}),e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:s("workflowNodes.loopNote","Repeats the template until the selected output matches, an iteration limit is reached, or the timeout expires.")})]})})():null,m.data.kind==="step-review"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.reviewType","Review type")}),e.jsxs("select",{value:String(m.data.config?.type??"code"),onChange:t=>L({config:{type:t.target.value}}),children:[e.jsx("option",{value:"plan",children:s("workflowNodes.reviewPlan","Plan review")}),e.jsx("option",{value:"code",children:s("workflowNodes.reviewCode","Code review")})]})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.reviewModel","Review model (optional)")}),e.jsx(Gt,{label:s("workflowNodes.reviewModel","Review model (optional)"),models:Me,value:ea(String(m.data.config?.modelProvider??""),String(m.data.config?.modelId??"")),onChange:t=>{const{provider:n,modelId:r}=ta(t);L({config:{modelProvider:n||void 0,modelId:r||void 0,model:t||void 0}})}})]}),e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:s("workflowNodes.reviewNote","Verdicts route as outcome edges. Click an outgoing edge to set its verdict and rework behavior.")})]}):null,m.data.kind==="parse-steps"?e.jsxs(e.Fragment,{children:[Pt.length>0?e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.parseArtifact","Artifact")}),e.jsx("select",{value:String(m.data.config?.artifact??Pt[0]),onChange:t=>L({config:{artifact:t.target.value}}),children:Pt.map(t=>e.jsx("option",{value:t,children:t},t))})]}):e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.parseArtifact","Artifact")}),e.jsx("input",{placeholder:"PROMPT.md",value:String(m.data.config?.artifact??"PROMPT.md"),onChange:t=>L({config:{artifact:t.target.value}})})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.parseParser","Parser")}),e.jsx("select",{value:String(m.data.config?.parser??"step-headings"),onChange:t=>L({config:{parser:t.target.value}}),children:Array.from(new Set([String(m.data.config?.parser??"step-headings"),...ha])).map(t=>e.jsx("option",{value:t,children:t},t))})]})]}):null,m.data.kind==="code"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.codeSource","Source (TypeScript)")}),e.jsx("textarea",{className:"wf-code-source",rows:8,spellCheck:!1,placeholder:'export default async (ctx) => ({ outcome: "success" });',value:String(m.data.config?.source??""),onChange:t=>L({config:{source:t.target.value}})})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.codeTimeout","Timeout (ms)")}),e.jsx("input",{type:"number",min:1,placeholder:"30000",value:m.data.config?.timeoutMs!=null?String(m.data.config.timeoutMs):"",onChange:t=>{const n=t.target.value.trim();if(n==="")L({config:r=>{const b={...r};return delete b.timeoutMs,b}});else{const r=parseInt(n,10);isNaN(r)||L({config:{timeoutMs:r}})}}})]}),e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:s("workflowNodes.codeNote","Runs sandboxed TypeScript. Syntax is validated at save.")})]}):null,m.data.kind==="notify"?(()=>{const t=String(m.data.config?.event??"workflow-notify"),n=!oa.includes(t);return e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.notifyEvent","Event type")}),e.jsxs("select",{value:n?Bt:t,onChange:r=>{const b=r.target.value;L({config:{event:b===Bt?"custom-event":b}})},children:[oa.map(r=>e.jsx("option",{value:r,children:r},r)),e.jsx("option",{value:Bt,children:s("workflowNodes.notifyCustom","Custom")})]})]}),n?e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.notifyCustomEvent","Custom event")}),e.jsx("input",{value:t,placeholder:"custom-event",onChange:r=>L({config:{event:r.target.value}})})]}):null,e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.notifyTitle","Title (optional)")}),e.jsx("input",{value:String(m.data.config?.title??"{{taskTitle}}"),placeholder:"{{taskTitle}}",onChange:r=>L({config:{title:r.target.value}})})]}),e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.notifyMessage","Message (optional)")}),e.jsx("textarea",{rows:4,value:String(m.data.config?.message??""),placeholder:"Task {{taskId}} reached {{workflowName}}",onChange:r=>L({config:{message:r.target.value}})})]}),e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:s("workflowNodes.notifyNote","Templates may use {{taskTitle}}, {{taskId}}, {{workflowName}}, and {{context:key}}.")})]})})():null,m.data.kind==="prompt"||m.data.kind==="gate"||m.data.kind==="script"?e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.gateMode","Gate mode")}),e.jsxs("select",{value:String(m.data.config?.gateMode??(m.data.kind==="prompt"?"advisory":"gate")),onChange:t=>L({config:{gateMode:t.target.value}}),children:[e.jsx("option",{value:"advisory",children:s("workflowNodes.advisory","Advisory")}),e.jsx("option",{value:"gate",children:s("workflowNodes.gateBlocks","Gate (blocks)")})]})]}):m.data.kind==="merge"?e.jsx("p",{className:"wf-inspector-note",children:s("workflowNodes.mergeBoundaryNote","Steps before this marker run pre-merge; steps after run post-merge.")}):null]}),!q&&e.jsxs("button",{type:"button",className:"wf-editor-delete wf-inspector-delete","data-testid":"wf-delete-node",onClick:()=>{xs([m.id]),S(null)},children:[e.jsx(ke,{size:13})," ",s("workflowNodes.deleteNode","Delete node")]})]}),xe&&e.jsxs("aside",{className:"wf-editor-inspector","data-testid":"wf-edge-inspector",children:[e.jsxs("div",{className:"wf-inspector-heading",children:[e.jsx("h3",{children:s("workflowNodes.edgeInspector","Edge")}),x&&e.jsxs("button",{type:"button",className:"wf-inspector-toggle wf-inspector-toggle--expanded","data-testid":"wf-edge-inspector-close","aria-expanded":"true",onClick:()=>W(null),children:[e.jsx(je,{size:13}),e.jsx("span",{children:s("workflowNodes.collapseInspector","Collapse")})]})]}),e.jsx("fieldset",{className:"wf-inspector-fields",disabled:q,children:Ss==="verdicts"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.edgeVerdict","Review verdict")}),e.jsxs("select",{"data-testid":"wf-edge-verdict",value:(()=>{const t=String(xe.data?.condition??"success");return t.startsWith("outcome:")?t.slice(8):""})(),onChange:t=>{const n=t.target.value;It({condition:n?`outcome:${n}`:"success"})},children:[e.jsx("option",{value:"",children:s("workflowNodes.edgeNoVerdict","— success (no verdict) —")}),Un.map(t=>e.jsx("option",{value:t,children:t},t))]})]}),e.jsxs("label",{className:"wf-field wf-field--checkbox",children:[e.jsx("input",{type:"checkbox","data-testid":"wf-edge-rework",checked:xe.data?.kind==="rework",onChange:t=>It({rework:t.target.checked})}),e.jsx("span",{children:s("workflowNodes.edgeRework","Rework edge (loop back, bounded)")})]}),e.jsx("p",{className:"wf-inspector-note wf-inspector-note--info",children:s("workflowNodes.edgeReworkNote","Rework edges are the only legal cycles — they loop back within the for-each step instance, bounded by Max rework cycles.")})]}):Ss==="conditions"?e.jsxs("label",{className:"wf-field",children:[e.jsx("span",{children:s("workflowNodes.edgeCondition","Condition")}),e.jsxs("select",{"data-testid":"wf-edge-condition",value:String(xe.data?.condition??"success"),onChange:t=>It({condition:t.target.value}),children:[e.jsx("option",{value:"success",children:"success"}),e.jsx("option",{value:"failure",children:"failure"})]})]}):e.jsx("p",{className:"wf-inspector-note",children:s("workflowNodes.edgeConditionLabel","Condition: {{condition}}",{condition:String(xe.data?.condition??"success")})})}),!q&&e.jsxs("button",{type:"button",className:"wf-editor-delete wf-inspector-delete","data-testid":"wf-delete-edge",onClick:()=>{xs([xe.id]),W(null)},children:[e.jsx(ke,{size:13})," ",s("workflowNodes.deleteEdge","Delete edge")]})]})]}),ye&&e.jsx(Jn,{workflows:u,onCreate:Ra,onDesign:Da,onClose:Ye})]})}),qa]})}function nl({isOpen:a,onClose:d,addToast:i,projectId:g,initialPanel:l,initialAction:w,initialWorkflowId:D}){const u=o.useRef(null);return mo(u,a,"fusion:workflow-node-editor-size"),a?e.jsx(Ha,{children:e.jsx(Xn,{onClose:d,addToast:i,projectId:g,initialPanel:l,initialAction:w,initialWorkflowId:D,modalRef:u})}):null}export{nl as WorkflowNodeEditor};
@@ -0,0 +1 @@
1
+ .wf-editor-modal{--wf-editor-touch-target: calc(var(--space-xl) + var(--space-lg) + var(--space-xs));display:flex;flex-direction:column;width:min(1200px,95vw);height:min(820px,92vh);min-width:640px;min-height:480px;resize:both;overflow:hidden;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-md)}.wf-create-modal{--wf-editor-touch-target: calc(var(--space-xl) + var(--space-lg) + var(--space-xs))}.wf-editor-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-md);border-bottom:1px solid var(--border)}.wf-editor-header h2{margin:0;font-size:1rem;color:var(--text)}.wf-editor-close{display:inline-flex;align-items:center;background:transparent;border:none;color:var(--text-muted);cursor:pointer}.wf-migration-notice{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm);padding:var(--space-sm) var(--space-md);background:var(--accent-subtle, color-mix(in srgb, #3b82f6 12%, transparent));border-bottom:1px solid var(--border);color:var(--text);font-size:.85rem}.wf-migration-notice-text{flex:1}.wf-migration-notice-dismiss{display:inline-flex;align-items:center;background:transparent;border:none;color:var(--text-muted);cursor:pointer;flex-shrink:0}.wf-migration-notice-dismiss:hover,.wf-editor-close:hover{color:var(--text)}.wf-editor-body{display:flex;flex:1;min-width:0;min-height:0}.wf-editor-sidebar{display:flex;flex-direction:column;gap:var(--space-xs);width:300px;min-width:0;padding:var(--space-sm);border-right:1px solid var(--border);overflow-x:hidden;overflow-y:auto}.wf-sidebar-panels{display:flex;flex-direction:column;gap:var(--space-xs);min-width:0;margin-top:var(--space-sm);padding-top:var(--space-sm);border-top:1px solid var(--border)}.wf-sidebar-section{display:flex;flex-direction:column;gap:var(--space-xs);min-width:0}.wf-sidebar-section-toggle{display:flex;align-items:center;gap:var(--space-xs);width:100%;min-width:0;padding:var(--space-xs) var(--space-sm);background:transparent;border:none;border-radius:var(--radius-sm);color:var(--text);font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;cursor:pointer}.wf-sidebar-section-toggle:hover{background:var(--bg-secondary)}.wf-sidebar-section .wf-column-panel,.wf-sidebar-section .wf-fields-panel{width:auto;min-width:0;padding:0 var(--space-xs) var(--space-xs);border-left:none;overflow-y:visible}.wf-sidebar-section .wf-column-panel-header h3,.wf-sidebar-section .wf-fields-panel-header h3{display:none}.wf-sidebar-section .wf-column-panel-header,.wf-sidebar-section .wf-fields-panel-header{justify-content:flex-end}.wf-editor-new{display:inline-flex;align-items:center;gap:var(--space-xs);padding:var(--space-xs) var(--space-sm);background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);cursor:pointer}.wf-editor-new:hover{background:var(--bg-tertiary)}.wf-editor-import{display:inline-flex;align-items:center;gap:var(--space-xs);padding:var(--space-xs) var(--space-sm);background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);cursor:pointer}.wf-editor-import:hover{background:var(--bg-tertiary)}.wf-editor-import:disabled{opacity:.6;cursor:default}.wf-editor-import-error{padding:var(--space-xs) var(--space-sm);background:color-mix(in srgb,var(--ws-error) 8%,var(--bg-secondary));border:1px solid var(--ws-error);border-radius:var(--radius-sm);color:var(--ws-error);font-size:.8rem}.wf-editor-import-warnings{padding:var(--space-xs) var(--space-sm);background:color-mix(in srgb,var(--ws-warning) 8%,var(--bg-secondary));border:1px solid var(--ws-warning);border-radius:var(--radius-sm);color:var(--ws-warning);font-size:.8rem}.wf-editor-import-warning{margin:0}.wf-editor-import-warning+.wf-editor-import-warning{margin-top:var(--space-xs)}.wf-editor-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px;min-width:0}.wf-editor-list li{min-width:0}.wf-editor-list-item{width:100%;min-width:0;overflow:hidden;text-align:left;text-overflow:ellipsis;white-space:nowrap;padding:var(--space-xs) var(--space-sm);background:transparent;border:1px solid transparent;border-radius:var(--radius-sm);color:var(--text);cursor:pointer}.wf-editor-list-item:hover{background:var(--bg-secondary)}.wf-editor-list-item.active{background:var(--bg-tertiary);border-color:var(--border)}.wf-editor-empty{display:flex;align-items:center;gap:var(--space-xs);padding:var(--space-md);color:var(--text-muted);font-size:.85rem}.wf-editor-select-note{padding:var(--space-sm) var(--space-md);background:color-mix(in srgb,var(--ws-info) 8%,var(--bg-secondary));border:1px solid var(--ws-info);border-radius:var(--radius-sm);color:var(--text);font-size:.85rem}.wf-editor-canvas-wrap{display:flex;flex-direction:column;flex:1;min-width:0}.wf-editor-mobile-back{display:none}.wf-editor-canvas-empty{flex:1;justify-content:center}.wf-editor-onboard{flex-direction:column;text-align:center;gap:var(--space-sm);padding:var(--space-lg)}.wf-editor-onboard-icon{color:var(--text-muted)}.wf-editor-onboard-title{margin:0;font-size:1rem;color:var(--text)}.wf-editor-onboard-text{margin:0;max-width:36ch;color:var(--text-muted)}.wf-editor-onboard-cta{margin-top:var(--space-xs)}.wf-trivial-hint{position:absolute;top:var(--space-sm);left:50%;transform:translate(-50%);z-index:5;pointer-events:none;max-width:min(90%,42ch);padding:var(--space-xs) var(--space-sm);background:color-mix(in srgb,var(--ws-info) 8%,var(--bg-secondary));border:1px solid var(--ws-info);border-radius:var(--radius-sm);color:var(--ws-info);font-size:.8rem;text-align:center}.wf-editor-toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm);padding:var(--space-sm);border-bottom:1px solid var(--border);flex-wrap:wrap}.wf-editor-palette{display:flex;gap:var(--space-xs);flex-wrap:wrap;min-width:0}.wf-palette-btn,.wf-editor-action,.wf-editor-delete,.wf-editor-save{display:inline-flex;align-items:center;gap:var(--space-xs);min-width:0;padding:var(--space-xs) var(--space-sm);background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);cursor:pointer;overflow-wrap:anywhere;transition:background var(--transition-fast)}.wf-palette-btn:hover,.wf-editor-action:hover,.wf-editor-delete:hover{background:var(--bg-tertiary)}.wf-editor-action:disabled{opacity:.6;cursor:default}.wf-editor-actions{display:flex;align-items:center;gap:var(--space-xs)}.wf-editor-readonly-note{font-size:.75rem;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:.04em}.wf-templates{display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-sm);border-bottom:1px solid var(--border)}.wf-templates-header{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm)}.wf-templates-toggle{display:inline-flex;align-items:center;gap:var(--space-xs);padding:var(--space-xs) var(--space-sm);background:transparent;border:none;border-radius:var(--radius-sm);color:var(--text);font-weight:600;cursor:pointer}.wf-templates-toggle:hover{background:var(--bg-tertiary)}.wf-templates-filter{flex:0 1 220px;padding:var(--space-xs) var(--space-sm);background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);font-size:.8rem}.wf-templates-body{display:flex;flex-direction:column;gap:var(--space-sm)}.wf-templates-conflict{padding:var(--space-xs) var(--space-sm);background:color-mix(in srgb,var(--ws-error) 8%,var(--bg-secondary));border:1px solid var(--ws-error);border-radius:var(--radius-sm);color:var(--ws-error);font-size:.8rem}.wf-templates-group{display:flex;flex-direction:column;gap:var(--space-xs)}.wf-templates-group-title{margin:0;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-tertiary)}.wf-templates-entries{display:flex;flex-wrap:wrap;gap:var(--space-xs)}.wf-templates-entry{display:inline-flex;align-items:center;gap:var(--space-xs);padding:var(--space-xs) var(--space-sm);background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);font-size:.8rem;cursor:pointer;transition:background var(--transition-fast)}.wf-templates-entry:hover{background:var(--bg-tertiary)}.wf-templates-entry:disabled{opacity:.6;cursor:default}.wf-templates-badge{padding:0 var(--space-xs);background:var(--accent-subtle, color-mix(in srgb, #3b82f6 12%, transparent));border-radius:var(--radius-sm);color:var(--text-muted);font-size:.7rem}.wf-inspector-fields{display:contents;border:none;margin:0;padding:0;min-inline-size:0}.wf-editor-save{background:var(--todo);border-color:var(--todo);color:var(--bg)}.wf-editor-save:disabled{opacity:.6;cursor:default}.wf-editor-delete{color:var(--ws-error)}.wf-inspector-delete{margin-top:var(--space-sm);justify-content:center}.wf-editor-banner{padding:var(--space-sm) var(--space-md);background:var(--bg-secondary);border-bottom:1px solid var(--ws-warning);color:var(--ws-warning);font-size:.85rem}.wf-editor-banner--info{border-bottom-color:var(--ws-info);color:var(--ws-info);background:color-mix(in srgb,var(--ws-info) 6%,var(--bg-secondary))}.wf-editor-canvas{flex:1;width:100%;min-width:0;min-height:0;overflow:hidden;position:relative}.wf-mobile-shell{display:none}.wf-layout-toggle{display:inline-flex;align-items:center;gap:var(--space-xs);width:fit-content;min-height:30px;padding:var(--space-xs) var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg-secondary);color:var(--text-muted);font:inherit;font-size:.8rem;cursor:pointer}.wf-layout-toggle:hover{background:var(--bg-tertiary);color:var(--text)}.wf-layout-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.wf-editor-body--simple-layout :where(.wf-editor-readonly-banner),.wf-editor-body--simple-layout :where(.wf-editor-toolbar),.wf-editor-body--simple-layout :where(.wf-templates),.wf-editor-body--simple-layout :where(.wf-editor-canvas){display:none}.wf-editor-body--simple-layout .wf-mobile-shell{display:flex;flex:1 1 auto;min-height:0;flex-direction:column;border-top:1px solid var(--border);overflow:hidden}.wf-mobile-tabs{display:flex;flex:0 0 auto;gap:var(--space-xs);padding:var(--space-sm);overflow-x:auto;overflow-y:visible;border-bottom:1px solid var(--border)}.wf-mobile-tab{flex:0 0 auto;min-height:var(--wf-editor-touch-target);padding:var(--space-sm) var(--space-md);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg-secondary);color:var(--text);cursor:pointer;transition:background var(--transition-fast),transform var(--transition-fast),box-shadow var(--transition-fast)}.wf-mobile-tab--active{border-color:var(--accent, var(--ws-info));background:var(--bg-tertiary)}.wf-mobile-tab:hover{background:var(--bg-tertiary)}.wf-mobile-tab:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.wf-mobile-tab:active{transform:scale(.97)}.wf-mobile-panel{flex:1 1 auto;min-height:0;overflow-y:auto}.wf-mobile-add,.wf-mobile-actions,.wf-mobile-destination{display:flex;flex-direction:column;gap:var(--space-sm);padding:var(--space-sm)}.wf-mobile-add-section{display:flex;flex-direction:column;gap:var(--space-sm)}.wf-mobile-add-section h3,.wf-mobile-template-group h4{margin:0;color:var(--text);font-size:.85rem}.wf-mobile-add-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-xs)}.wf-mobile-add-option,.wf-mobile-template-option{display:inline-flex;align-items:center;justify-content:flex-start;gap:var(--space-xs);min-width:0;min-height:var(--wf-editor-touch-target);padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg-secondary);color:var(--text);cursor:pointer;text-align:left;overflow-wrap:anywhere;transition:background var(--transition-fast),transform var(--transition-fast),box-shadow var(--transition-fast)}.wf-mobile-add-option:hover,.wf-mobile-template-option:hover{background:var(--bg-tertiary)}.wf-mobile-add-option:focus-visible,.wf-mobile-template-option:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.wf-mobile-add-option:active,.wf-mobile-template-option:active{transform:scale(.97)}.wf-mobile-template-filter{width:100%}.wf-mobile-template-group{display:flex;flex-direction:column;gap:var(--space-xs)}.wf-mobile-actions .wf-editor-action,.wf-mobile-actions .wf-editor-delete,.wf-mobile-actions .wf-editor-save{justify-content:center;min-height:var(--wf-editor-touch-target)}.wf-mobile-ai-panel{position:static;inset:auto;width:100%;box-shadow:none}.wf-editor-inspector{display:flex;flex-direction:column;gap:var(--space-sm);width:280px;padding:var(--space-md);border-left:1px solid var(--border);overflow-y:auto}.wf-editor-inspector h3{margin:0;font-size:.9rem;color:var(--text)}.wf-inspector-heading{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm)}.wf-inspector-toggle{display:inline-flex;align-items:center;gap:var(--space-xs);padding:var(--space-xs) var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg-secondary);color:var(--text);font:inherit;cursor:pointer}.wf-inspector-toggle:hover{background:var(--bg-tertiary)}.wf-inspector-toggle--collapsed{position:absolute;right:var(--space-sm);bottom:var(--space-sm);z-index:5;box-shadow:var(--shadow-sm)}.wf-field{display:flex;flex-direction:column;gap:var(--space-xs);font-size:.8rem;color:var(--text-muted)}.wf-field input,.wf-field textarea,.wf-field select{padding:var(--space-xs) var(--space-sm);background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);font:inherit}.wf-field input:focus,.wf-field textarea:focus,.wf-field select:focus{outline:none;box-shadow:var(--focus-ring)}.wf-prompt-editor{position:relative}.wf-prompt-editor--fullscreen{position:fixed;inset:0;z-index:10000;background:var(--surface);padding:max(var(--space-lg),env(safe-area-inset-top,0)) max(var(--space-lg),env(safe-area-inset-right,0)) max(var(--space-lg),env(safe-area-inset-bottom,0)) max(var(--space-lg),env(safe-area-inset-left,0));display:flex;flex-direction:column}.wf-prompt-editor--fullscreen .wf-field{flex:1;display:flex;flex-direction:column}.wf-prompt-editor--fullscreen textarea{flex:1;min-height:unset;resize:none;border-radius:var(--radius-md);font-size:.9375rem;line-height:1.6}.wf-prompt-fullscreen-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--space-md);font-size:.8125rem;font-weight:600;color:var(--text-muted)}.wf-prompt-expand-btn{display:inline-flex;align-items:center;gap:var(--space-xs)}.wf-prompt-expand-btn--inline{position:absolute;top:calc(var(--space-xs) + 1.2em + var(--space-xs));right:var(--space-xs);z-index:2;color:var(--text-muted);background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);padding:calc(var(--space-xs) / 2) var(--space-xs)}.wf-prompt-expand-btn--inline:hover{background:var(--bg-tertiary);color:var(--text)}.wf-prompt-editor:not(.wf-prompt-editor--fullscreen) textarea{padding-right:calc(var(--space-xl) + var(--space-md))}.wf-inspector-note{margin:0;font-size:.78rem;color:var(--text-tertiary)}.wf-inspector-note--info{color:var(--ws-warning)}.wf-field--checkbox{flex-direction:row;align-items:center;gap:var(--space-sm);cursor:pointer}.wf-field--checkbox input[type=checkbox]{width:auto;padding:0;margin:0;background:none;border:none;accent-color:var(--todo);cursor:pointer}.wf-node{display:flex;flex-direction:column;gap:2px;box-sizing:border-box;width:200px;max-width:240px;padding:var(--space-xs) var(--space-sm);background:var(--bg-secondary);border:1px solid var(--border);border-left:3px solid var(--border);border-radius:var(--radius-sm);color:var(--text);font-size:.8rem}.wf-node-header{display:flex;align-items:center;gap:var(--space-xs);min-width:0}.wf-node-summary{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.68rem;color:var(--text-muted)}.wf-node-start{border-left-color:var(--ws-success)}.wf-node-end{border-left-color:var(--text-muted)}.wf-node-prompt{border-left-color:var(--accent, var(--todo));background:color-mix(in srgb,var(--accent, var(--todo)) 5%,var(--bg-secondary))}.wf-node-script{border-left-color:var(--text-muted);font-family:var(--font-mono, monospace)}.wf-node-gate{border-left-color:var(--ws-warning);background:color-mix(in srgb,var(--ws-warning) 6%,var(--bg-secondary))}.wf-node-hold{border-left-color:var(--ws-warning)}.wf-node-split,.wf-node-join{border-left-color:var(--accent, var(--ws-info))}.wf-node-merge{border-left-color:var(--ws-info);border-style:dashed}.wf-node-step-execute{border-left-color:var(--accent, var(--ws-info));background:color-mix(in srgb,var(--accent, var(--ws-info)) 5%,var(--bg-secondary))}.wf-node-step-review{border-left-color:var(--ws-info);background:color-mix(in srgb,var(--ws-info) 6%,var(--bg-secondary))}.wf-node-parse-steps{border-left-color:var(--ws-info)}.wf-node-code{border-left-color:var(--text-muted);font-family:var(--font-mono, monospace)}.wf-foreach-group{width:100%;height:100%;box-sizing:border-box;border:1px dashed var(--accent, var(--ws-info));border-radius:var(--radius-md);background:color-mix(in srgb,var(--accent, var(--ws-info)) 6%,transparent);padding:var(--space-xs)}.wf-foreach-group.wf-node--error{border-color:var(--ws-error)}.wf-foreach-header{display:inline-flex;align-items:center;gap:var(--space-xs);font-size:.8rem;color:var(--text)}.wf-foreach-empty{margin-top:var(--space-sm);padding:var(--space-sm);border:1px dashed var(--border);border-radius:var(--radius-sm);font-size:.7rem;color:var(--text-muted);text-align:center}.wf-edge-rework .react-flow__edge-path{stroke:var(--accent, var(--ws-info));stroke-dasharray:5 4;stroke-width:2}.react-flow__edge.wf-edge-failure .react-flow__edge-path{stroke:var(--ws-error);stroke-dasharray:2 4;stroke-width:2}.wf-code-source{font-family:var(--font-mono, monospace);font-size:.72rem;white-space:pre;overflow-x:auto}.wf-editor-sidebar .wf-code-source{overflow-x:hidden;overflow-wrap:anywhere;white-space:pre-wrap}.wf-node-icon{display:inline-flex;flex-shrink:0;color:var(--text-muted)}.wf-node-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wf-node-badge{flex-shrink:0;font-size:.65rem;text-transform:uppercase;padding:1px var(--space-xs);border-radius:var(--radius-sm);background:var(--ws-warning);color:var(--bg)}.wf-spin{animation:wf-spin 1s linear infinite}@keyframes wf-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.wf-column-band{border:1px dashed var(--border);background:color-mix(in srgb,var(--bg-secondary) 65%,transparent);border-radius:var(--radius-md);pointer-events:none}.wf-node--error{border-color:var(--ws-error);border-left-color:var(--ws-error)}.wf-node-error-badge{display:inline-flex;align-items:center;gap:var(--space-xs);flex-shrink:0;font-size:.65rem;padding:1px var(--space-xs);border-radius:var(--radius-sm);background:var(--ws-error);color:var(--bg)}.wf-editor-readonly-banner{display:flex;align-items:center;justify-content:space-between;gap:var(--space-md);padding:var(--space-sm) var(--space-md);background:var(--bg-tertiary);border-bottom:1px solid var(--border)}.wf-editor-duplicate-primary{font-weight:600}.wf-editor-banner--warn{background:var(--ws-warning);color:var(--bg)}.wf-name-strip{display:flex;align-items:baseline;gap:var(--space-sm);padding:var(--space-xs) var(--space-sm);border-bottom:1px solid var(--border);flex-wrap:wrap}.wf-workflow-name,.wf-workflow-name--readonly{font-size:.95rem;font-weight:600;color:var(--text);background:none;border:1px solid transparent;border-radius:var(--radius-sm);padding:2px var(--space-xs);cursor:pointer;text-align:left}.wf-workflow-name:hover{background:var(--bg-tertiary)}.wf-workflow-name--readonly{cursor:default}.wf-workflow-name-input{font-size:.95rem;font-weight:600;color:var(--text);background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);padding:2px var(--space-xs)}.wf-workflow-description,.wf-workflow-description--readonly{font-size:.78rem;color:var(--text-tertiary);background:none;border:1px solid transparent;border-radius:var(--radius-sm);padding:2px var(--space-xs);cursor:pointer;text-align:left}.wf-workflow-description:hover{background:var(--bg-tertiary)}.wf-workflow-description--readonly{cursor:default}.wf-workflow-description-input{font-size:.78rem;color:var(--text);background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);padding:2px var(--space-xs);min-width:220px}.wf-template-list{display:flex;flex-direction:column;gap:var(--space-xs);max-height:220px;overflow-y:auto;padding:var(--space-xs);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg-secondary)}.wf-template-section{margin:var(--space-xs) 0 var(--space-xs);font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-tertiary)}.wf-template-option{display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-xs) var(--space-sm);border:1px solid transparent;border-radius:var(--radius-sm);cursor:pointer;color:var(--text)}.wf-template-option:hover{background:var(--bg-hover)}.wf-template-option.selected{border-color:var(--accent);background:var(--bg-active)}.wf-template-option:focus-visible{outline:none;box-shadow:var(--focus-ring)}.wf-template-option-name{font-size:.85rem;font-weight:600}.wf-template-option-desc{font-size:.78rem;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wf-template-option-count{font-size:.72rem;color:var(--text-tertiary)}.wf-create-error{margin:var(--space-xs) 0 0;font-size:.8rem;color:var(--ws-error)}.wf-column-panel{display:flex;flex-direction:column;gap:var(--space-sm);width:280px;min-width:260px;padding:var(--space-md);border-left:1px solid var(--border);overflow-y:auto}.wf-column-panel-header{display:flex;align-items:center;justify-content:space-between}.wf-column-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-sm)}.wf-column-item{border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-xs)}.wf-column-item--error{border-color:var(--ws-error)}.wf-column-item-head{display:flex;align-items:center;gap:var(--space-xs)}.wf-column-name{flex:1;min-width:0}.wf-column-item-actions{display:flex;gap:2px}.wf-column-violation{display:flex;align-items:center;gap:var(--space-xs);font-size:.7rem;color:var(--ws-error);margin:0}.wf-column-trait-options{display:flex;flex-wrap:wrap;gap:var(--space-xs)}.wf-column-trait{display:inline-flex;align-items:center;gap:2px;font-size:.7rem;color:var(--text-muted)}.wf-column-traits-label{font-size:.65rem;text-transform:uppercase;color:var(--text-tertiary)}.wf-ai-create{display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg-secondary)}.wf-ai-toggle{display:inline-flex;align-items:center;gap:var(--space-xs);align-self:flex-start;padding:var(--space-xs) var(--space-xs);background:transparent;border:none;border-radius:var(--radius-sm);color:var(--accent);font-size:.82rem;font-weight:600;cursor:pointer}.wf-ai-toggle:hover{background:var(--bg-hover)}.wf-ai-create-body{display:flex;flex-direction:column;gap:var(--space-xs)}.wf-ai-prompt{width:100%;resize:vertical;padding:var(--space-xs) var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg);color:var(--text);font-size:.85rem}.wf-ai-prompt:focus-visible{outline:none;box-shadow:var(--focus-ring)}.wf-ai-actions{display:flex;gap:var(--space-xs)}.wf-ai-edit-wrap{position:relative}.wf-ai-panel{position:absolute;top:calc(100% + var(--space-xs));right:0;z-index:20;width:320px;display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg);box-shadow:var(--shadow-md)}@media(max-width:768px){.wf-prompt-editor--fullscreen{padding:var(--space-sm)}.modal-overlay:has(.wf-editor-modal),.modal-overlay:has(.wf-create-modal){padding-top:0;align-items:stretch;justify-content:stretch}.wf-editor-modal,.wf-create-modal{width:100vw;min-width:0;max-width:100vw;height:100vh;height:100dvh;min-height:0;max-height:100dvh;margin:0;border:none;border-radius:0;resize:none;flex:1 1 auto}.wf-editor-header,.wf-migration-notice,.wf-editor-readonly-banner{flex-wrap:wrap}.wf-migration-notice,.wf-editor-readonly-banner{gap:var(--space-sm)}.wf-editor-body{flex-direction:column;width:100%;min-width:0;overflow-x:hidden}.wf-editor-body--list-stage .wf-editor-sidebar{display:flex;width:100%;min-width:0;flex:1 1 auto;max-height:none;border-right:none;border-bottom:none;overflow-x:hidden;overflow-y:auto}.wf-editor-body--list-stage .wf-editor-canvas-wrap,.wf-editor-body--list-stage .wf-editor-inspector,.wf-editor-body--editor-stage .wf-editor-sidebar{display:none}.wf-editor-body--editor-stage .wf-editor-canvas-wrap{display:flex;flex:0 1 auto;width:100%;min-width:0;min-height:0;overflow:hidden}.wf-editor-body--editor-stage .wf-editor-canvas{flex:1 1 auto;min-height:0}.wf-editor-body--editor-stage .wf-editor-inspector{width:100%;min-width:0;max-height:none;flex:1 1 auto;min-height:0;border-left:none;border-top:1px solid var(--border);overflow-y:auto}.wf-editor-mobile-back{display:inline-flex;align-items:center;align-self:flex-start;gap:var(--space-xs);min-height:var(--wf-editor-touch-target);margin:var(--space-sm) var(--space-sm) 0;padding:var(--space-sm) var(--space-md);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);color:var(--text);font-size:.8rem;cursor:pointer}.wf-editor-sidebar .wf-column-panel{width:100%;min-width:0;border-left:none;border-top:1px solid var(--border)}.wf-editor-body .wf-settings-panel{width:100%;min-width:0;max-height:50vh;border-left:none;border-top:1px solid var(--border);overflow-y:auto}.wf-editor-canvas-wrap{flex:1 1 auto;width:100%;min-width:0;min-height:0}.wf-editor-canvas{width:100%;min-width:0;max-width:100%;overflow:hidden}.wf-editor-body--editor-stage :where(.wf-editor-readonly-banner),.wf-editor-body--editor-stage :where(.wf-editor-toolbar),.wf-editor-body--editor-stage :where(.wf-templates),.wf-editor-body--editor-stage :where(.wf-editor-canvas){display:none}.wf-mobile-shell{display:flex;flex:1 1 auto;min-height:0;flex-direction:column;border-top:1px solid var(--border);overflow:hidden}.wf-editor-canvas .react-flow,.wf-editor-canvas .react-flow__renderer,.wf-editor-canvas .react-flow__pane,.wf-editor-canvas .react-flow__viewport{width:100%;min-width:0;max-width:100%;height:100%}.wf-editor-list-item,.wf-editor-new,.wf-editor-import,.wf-sidebar-section-toggle,.wf-palette-btn,.wf-editor-action,.wf-editor-delete,.wf-editor-save,.wf-templates-toggle,.wf-templates-entry,.wf-template-option,.wf-ai-toggle,.wf-workflow-name,.wf-workflow-name-input,.wf-column-panel button,.wf-fields-panel button,.wf-settings-panel button{min-height:var(--wf-editor-touch-target)}.wf-editor-list-item,.wf-editor-new,.wf-editor-import,.wf-palette-btn,.wf-editor-action,.wf-editor-delete,.wf-editor-save,.wf-templates-toggle,.wf-templates-entry,.wf-ai-toggle{padding:var(--space-sm) var(--space-md)}.wf-field input,.wf-field textarea,.wf-field select,.wf-templates-filter,.wf-ai-prompt{min-height:var(--wf-editor-touch-target);padding:var(--space-sm) var(--space-md)}.wf-template-list{max-height:40vh}.wf-editor-toolbar{flex-wrap:nowrap;overflow-x:auto}.wf-editor-palette,.wf-editor-actions{flex:0 0 auto;flex-wrap:nowrap}.wf-templates{flex:0 0 auto}.wf-templates-header{flex-wrap:nowrap}.wf-templates-toggle{flex:0 0 auto}.wf-inspector-toggle{min-height:var(--wf-editor-touch-target);padding:var(--space-sm) var(--space-md)}.wf-ai-panel{position:fixed;inset:var(--space-sm);top:auto;right:auto;z-index:30;width:auto}.wf-editor-inspector{width:100%;max-height:40vh;border-left:none;border-top:1px solid var(--border);overflow-y:auto}.wf-editor-body--mobile-node-detail .wf-editor-canvas-wrap{display:none;min-height:0}.wf-editor-body--mobile-node-detail .wf-editor-inspector{display:flex;flex:1 1 auto;width:100%;min-width:0;min-height:0;max-height:none;border-left:none;border-top:none;overflow-y:auto}.wf-editor-body--mobile-edge-detail .wf-editor-canvas-wrap{display:none;min-height:0}.wf-editor-body--mobile-edge-detail .wf-editor-inspector{display:flex;flex:1 1 auto;width:100%;min-width:0;min-height:0;max-height:none;border-left:none;border-top:none;overflow-y:auto}}.wf-fields-panel{display:flex;flex-direction:column;gap:var(--space-sm);width:300px;min-width:280px;padding:var(--space-md);border-left:1px solid var(--border);overflow-y:auto}.wf-fields-panel-header{display:flex;align-items:center;justify-content:space-between}.wf-fields-add{display:inline-flex;align-items:center;gap:4px}.wf-fields-panel-empty{font-size:.75rem;color:var(--text-muted);margin:0}.wf-fields-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-sm)}.wf-field-item{border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-xs)}.wf-field-item-head{display:flex;align-items:center;gap:var(--space-xs)}.wf-field-name{flex:1;min-width:0}.wf-field-id-row{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-xs)}.wf-field-id-static{font-family:var(--font-mono, monospace);font-size:.7rem;color:var(--text-tertiary);background:var(--surface-2, color-mix(in srgb, #ffffff 4%, transparent));padding:1px 6px;border-radius:var(--radius-sm)}.wf-field-id-edit{font-size:.65rem;background:none;border:none;color:var(--accent, #4f7cff);cursor:pointer;padding:0}.wf-field-id-warn{display:flex;align-items:center;gap:4px;width:100%;margin:0;font-size:.65rem;color:var(--ws-warning, #f59e0b)}.wf-field-row{display:flex;align-items:flex-end;gap:var(--space-sm)}.wf-field-sub{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0;font-size:.7rem;color:var(--text-muted)}.wf-field-sub>span{font-size:.65rem;text-transform:uppercase;color:var(--text-tertiary)}.wf-field--checkbox{display:inline-flex;align-items:center;gap:4px;font-size:.7rem;color:var(--text-muted)}.wf-field-required{flex:0 0 auto;white-space:nowrap}.wf-field-options{display:flex;flex-direction:column;gap:var(--space-xs);padding-top:var(--space-xs);border-top:1px dashed var(--border)}.wf-field-options-label{font-size:.65rem;text-transform:uppercase;color:var(--text-tertiary)}.wf-field-option-row{display:flex;align-items:center;gap:4px}.wf-field-option-value,.wf-field-option-label{flex:1;min-width:0}.wf-field-option-colors{display:inline-flex;gap:2px}.wf-field-color-swatch{width:14px;height:14px;border-radius:50%;border:1px solid var(--border);padding:0;cursor:pointer}.wf-field-color-swatch.is-active{outline:2px solid var(--text-primary, #fff);outline-offset:1px}.wf-field-option-add{display:inline-flex;align-items:center;gap:4px;align-self:flex-start;font-size:.7rem}.wf-field-render{display:flex;flex-direction:column;gap:var(--space-xs);padding-top:var(--space-xs);border-top:1px dashed var(--border)}.wf-field-preview{padding-top:var(--space-xs)}@media(max-width:768px){.wf-fields-panel{width:100%;min-width:0;padding:var(--space-sm);border-left:none;border-top:1px solid var(--border)}.wf-field-row,.wf-field-option-row{flex-wrap:wrap}}.settings-field-row{display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-sm) 0}.settings-field-row.is-disabled{opacity:.6}.settings-field-row-head{display:flex;align-items:center;gap:var(--space-xs);flex-wrap:wrap}.settings-field-row-label{font-size:.8rem;font-weight:500;color:var(--text)}.settings-field-row-scope{font-size:.6rem;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);background:var(--surface-muted, color-mix(in srgb, #ffffff 4%, transparent));border:1px solid var(--border);border-radius:var(--radius-sm);padding:1px 6px}.settings-field-row-scope--global{color:var(--accent, #7c5cbf);border-color:var(--accent, #7c5cbf)}.settings-field-row-control{display:flex;align-items:center;gap:var(--space-xs)}.settings-field-row-control>input:not([type=checkbox]),.settings-field-row-control>select,.settings-field-row-control>textarea{flex:1;min-width:0}.settings-field-row-clear{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;background:none;border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text-muted);cursor:pointer;padding:2px;transition:color var(--duration-fast) ease,border-color var(--duration-fast) ease}.settings-field-row-clear:hover:not(:disabled){color:var(--text);border-color:var(--text-muted)}.settings-field-row-clear:disabled{cursor:default;opacity:.5}.settings-field-row-help{margin:0;font-size:.7rem;color:var(--text-muted)}.settings-field-row-error{margin:0;font-size:.7rem;color:var(--color-error, #f85149)}.settings-toggle{display:inline-flex;align-items:center}.settings-toggle>input[type=checkbox]{cursor:pointer}.settings-toggle>input[type=checkbox]:disabled{cursor:default}.settings-number,.settings-select,.settings-text{width:100%}.settings-textarea{width:100%;resize:vertical;font-family:inherit}.settings-section{display:flex;flex-direction:column;gap:var(--space-sm);padding:var(--space-md) 0;border-bottom:1px solid var(--border)}.settings-section:last-child{border-bottom:none}.settings-section-head{display:flex;flex-direction:column;gap:var(--space-xs)}.settings-section-title{margin:0;font-size:.9rem;font-weight:600;color:var(--text)}.settings-section-desc{margin:0;font-size:.75rem;color:var(--text-muted)}.settings-section-body{display:flex;flex-direction:column;gap:var(--space-xs)}.wf-settings-panel-wrap{display:flex;min-height:0}.wf-settings-panel{display:flex;flex-direction:column;gap:var(--space-sm);width:320px;min-width:300px;padding:var(--space-md);border-left:1px solid var(--border);overflow-y:auto;color:var(--text)}.wf-settings-panel-header{display:flex;align-items:center;justify-content:space-between}.wf-settings-tabs{display:flex;gap:2px;border-bottom:1px solid var(--border)}.wf-settings-tab{flex:1;padding:6px 8px;font-size:.72rem;background:none;border:none;border-bottom:2px solid transparent;color:var(--text-muted);cursor:pointer;transition:color var(--duration-fast) ease,border-color var(--duration-fast) ease}.wf-settings-tab.is-active{color:var(--text);border-bottom-color:var(--accent, #4f7cff)}.wf-settings-tabpanel{display:flex;flex-direction:column;gap:var(--space-sm)}.wf-settings-tabpanel-head{display:flex;align-items:center;justify-content:flex-end}.wf-settings-add,.wf-settings-save-values,.wf-settings-option-add{display:inline-flex;align-items:center;gap:4px}.wf-settings-empty{font-size:.75rem;color:var(--text-muted);margin:0}.wf-settings-note{display:flex;align-items:center;gap:4px;margin:0;font-size:.7rem}.wf-settings-note--info,.wf-settings-note--muted{color:var(--text-muted)}.wf-settings-note--warn{color:var(--ws-warning, #f59e0b)}.wf-settings-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-sm)}.wf-setting-item{border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-xs)}.wf-setting-item-head{display:flex;align-items:center;gap:var(--space-xs)}.wf-setting-name{flex:1;min-width:0}.wf-setting-id-row{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-xs)}.wf-setting-id-static{font-family:var(--font-mono, monospace);font-size:.7rem;color:var(--text-muted);background:var(--surface-2, color-mix(in srgb, #ffffff 4%, transparent));padding:1px 6px;border-radius:var(--radius-sm)}.wf-setting-id-edit{font-size:.65rem;background:none;border:none;color:var(--accent, #4f7cff);cursor:pointer;padding:0}.wf-setting-id-warn{display:flex;align-items:center;gap:4px;width:100%;margin:0;font-size:.65rem;color:var(--ws-warning, #f59e0b)}.wf-setting-row{display:flex;align-items:flex-end;gap:var(--space-sm)}.wf-setting-sub{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0;font-size:.7rem;color:var(--text-muted)}.wf-setting-sub>span{font-size:.65rem;text-transform:uppercase;color:var(--text-muted)}.wf-setting--checkbox{display:inline-flex;align-items:center;gap:4px;font-size:.7rem;color:var(--text-muted)}.wf-setting-options{display:flex;flex-direction:column;gap:var(--space-xs);padding-top:var(--space-xs);border-top:1px dashed var(--border)}.wf-setting-options-label{font-size:.65rem;text-transform:uppercase;color:var(--text-muted)}.wf-setting-option-row{display:flex;align-items:center;gap:4px}.wf-setting-option-value,.wf-setting-option-label{flex:1;min-width:0}.wf-setting-option-colors{display:inline-flex;gap:2px}.wf-setting-color-swatch{width:14px;height:14px;border-radius:50%;border:1px solid var(--border);padding:0;cursor:pointer}.wf-setting-color-swatch.is-active{outline:2px solid var(--text);outline-offset:1px}.wf-settings-values-head{display:flex;align-items:center;justify-content:flex-end}.wf-settings-values-list{display:flex;flex-direction:column;gap:var(--space-md)}.wf-settings-value-group{display:flex;flex-direction:column;gap:var(--space-xs)}.wf-settings-value-group-title{margin:0;font-size:.72rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:0}.wf-settings-value-item{position:relative;display:flex;flex-direction:column;gap:2px}.wf-settings-customized{align-self:flex-start;font-size:.6rem;text-transform:uppercase;letter-spacing:.04em;color:var(--accent, #4f7cff)}.wf-settings-reset-hint{display:flex;align-items:center;gap:4px;margin:0;font-size:.65rem;color:var(--text-muted)}.wf-settings-orphaned{border-top:1px dashed var(--border);padding-top:var(--space-xs)}.wf-settings-orphaned-toggle{display:inline-flex;align-items:center;gap:4px;background:none;border:none;color:var(--text-muted);font-size:.72rem;cursor:pointer;padding:0}.wf-settings-orphaned-body{display:flex;flex-direction:column;gap:var(--space-xs);padding-top:var(--space-xs)}.wf-settings-orphaned-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}.wf-settings-orphaned-row{display:flex;align-items:center;gap:var(--space-xs)}.wf-settings-orphan-id{font-family:var(--font-mono, monospace);font-size:.7rem;color:var(--text-muted)}.wf-settings-orphan-value{flex:1;min-width:0;font-size:.7rem;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wf-settings-orphan-delete{background:none;border:none;color:var(--text-muted);cursor:pointer;padding:0}@media(max-width:768px){.wf-settings-panel-wrap{flex-direction:column}.wf-settings-panel{width:100%;min-width:0;padding:var(--space-sm);border-left:none;border-top:1px solid var(--border)}.wf-setting-row,.wf-setting-option-row,.wf-settings-orphaned-row{flex-wrap:wrap}}.mobile-wf-graph{display:flex;flex-direction:column;gap:var(--space-sm);padding:var(--space-sm);overflow-y:auto}.mobile-wf-node-group{display:flex;flex-direction:column;gap:var(--space-xs)}.mobile-wf-node-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--space-xs);padding-left:calc(var(--mobile-wf-depth, 0) * var(--space-md))}.mobile-wf-node-main{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:var(--space-sm);min-width:0;min-height:var(--wf-editor-touch-target, 44px);padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg-secondary);color:var(--text);text-align:left;cursor:pointer;transition:background var(--transition-fast),transform var(--transition-fast),box-shadow var(--transition-fast)}.mobile-wf-node-main:hover{background:var(--bg-tertiary)}.mobile-wf-node-main:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.mobile-wf-node-main:active{transform:scale(.97)}.mobile-wf-node-row--selected .mobile-wf-node-main{border-color:var(--accent, var(--ws-info));box-shadow:var(--focus-ring)}.mobile-wf-node-kind{min-width:4.5rem;max-width:6rem;padding:calc(var(--space-xs) / 2) var(--space-xs);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text-muted);font-size:.7rem;text-align:center;overflow-wrap:anywhere}.mobile-wf-node-text{display:flex;flex-direction:column;min-width:0;gap:calc(var(--space-xs) / 2)}.mobile-wf-node-title,.mobile-wf-node-summary,.mobile-wf-edge-target{min-width:0;overflow-wrap:anywhere}.mobile-wf-node-title{color:var(--text);font-size:.9rem;font-weight:600}.mobile-wf-node-summary{color:var(--text-muted);font-size:.78rem}.mobile-wf-node-expand{display:inline-flex;align-items:center;justify-content:center;width:var(--wf-editor-touch-target, 44px);min-height:var(--wf-editor-touch-target, 44px);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg-secondary);color:var(--text);cursor:pointer;transition:background var(--transition-fast),transform var(--transition-fast),box-shadow var(--transition-fast)}.mobile-wf-node-expand:hover{background:var(--bg-tertiary)}.mobile-wf-node-expand:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.mobile-wf-node-expand:active{transform:scale(.97)}.mobile-wf-node-meta{display:flex;flex-wrap:wrap;gap:var(--space-xs);padding-left:calc((var(--mobile-wf-depth, 0) * var(--space-md)) + var(--space-xs))}.mobile-wf-column-chip,.mobile-wf-edge-chip{display:inline-flex;align-items:center;gap:var(--space-xs);min-height:34px;max-width:100%;padding:var(--space-xs) var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg);color:var(--text-muted);font-size:.75rem}.mobile-wf-edge-chip{color:var(--text);cursor:pointer;transition:background var(--transition-fast),transform var(--transition-fast),box-shadow var(--transition-fast)}.mobile-wf-edge-chip:hover{background:var(--bg-secondary)}.mobile-wf-edge-chip:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.mobile-wf-edge-chip:active{transform:scale(.97)}.mobile-wf-edge-chip--selected{border-color:var(--accent, var(--ws-info))}.mobile-wf-edge-target{color:var(--text-muted)}.mobile-wf-node-children{display:flex;flex-direction:column;gap:var(--space-sm)}.mobile-wf-graph-empty{padding:var(--space-lg);color:var(--text-muted);text-align:center}