@xopcai/xopc 0.0.105 → 0.0.106

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 (100) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/adapters/gateway-setup.js +2 -2
  3. package/dist/extensions/feishu/src/adapters/gateway-setup.js.map +1 -1
  4. package/dist/extensions/feishu/src/directory/directory-adapter.js +1 -1
  5. package/dist/extensions/feishu/src/directory/directory-adapter.js.map +1 -1
  6. package/dist/extensions/feishu/src/outbound/outbound-adapter.js +4 -3
  7. package/dist/extensions/feishu/src/outbound/outbound-adapter.js.map +1 -1
  8. package/dist/extensions/feishu/src/plugin.d.ts +6 -3
  9. package/dist/extensions/feishu/src/plugin.js +59 -40
  10. package/dist/extensions/feishu/src/plugin.js.map +1 -1
  11. package/dist/extensions/feishu/src/streaming/streaming-adapter.js +20 -16
  12. package/dist/extensions/feishu/src/streaming/streaming-adapter.js.map +1 -1
  13. package/dist/extensions/feishu/src/transport/socket-mode/monitor.js +1 -1
  14. package/dist/extensions/feishu/src/transport/webhook/monitor.js +1 -1
  15. package/dist/extensions/feishu/src/workflow-progress.d.ts +1 -1
  16. package/dist/extensions/feishu/src/workflow-progress.js +2 -2
  17. package/dist/extensions/feishu/src/workflow-progress.js.map +1 -1
  18. package/dist/extensions/telegram/src/adapters/gateway-setup.js +8 -6
  19. package/dist/extensions/telegram/src/adapters/gateway-setup.js.map +1 -1
  20. package/dist/extensions/telegram/src/command-handler.d.ts +1 -1
  21. package/dist/extensions/telegram/src/command-handler.js +11 -9
  22. package/dist/extensions/telegram/src/command-handler.js.map +1 -1
  23. package/dist/extensions/telegram/src/inbound-processor.js +1 -2
  24. package/dist/extensions/telegram/src/inbound-processor.js.map +1 -1
  25. package/dist/extensions/telegram/src/plugin.d.ts +1 -0
  26. package/dist/extensions/telegram/src/plugin.js +6 -6
  27. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  28. package/dist/extensions/telegram/src/workflow-progress.d.ts +1 -1
  29. package/dist/extensions/telegram/src/workflow-progress.js.map +1 -1
  30. package/dist/extensions/telegram/xopc.extension.json +1 -1
  31. package/dist/extensions/weixin/src/cli/gateway-qr-login.d.ts +4 -0
  32. package/dist/extensions/weixin/src/cli/gateway-qr-login.js +34 -5
  33. package/dist/extensions/weixin/src/cli/gateway-qr-login.js.map +1 -1
  34. package/dist/extensions/weixin/src/cli/qr-login.js +4 -3
  35. package/dist/extensions/weixin/src/cli/qr-login.js.map +1 -1
  36. package/dist/extensions/weixin/src/plugin.d.ts +1 -0
  37. package/dist/extensions/weixin/src/plugin.js +7 -6
  38. package/dist/extensions/weixin/src/plugin.js.map +1 -1
  39. package/dist/extensions/weixin/src/workflow-progress.d.ts +1 -1
  40. package/dist/extensions/weixin/src/workflow-progress.js.map +1 -1
  41. package/dist/gateway/static/root/assets/{agents-XzgIVKcI.js → agents-3eP0vqFO.js} +1 -1
  42. package/dist/gateway/static/root/assets/{apps-page-B7Us3RMl.js → apps-page-CZ2ZKrko.js} +1 -1
  43. package/dist/gateway/static/root/assets/{channels-settings-BgeV6fzw.js → channels-settings-BbETa93K.js} +1 -1
  44. package/dist/gateway/static/root/assets/{cron-page-DKGHEeAU.js → cron-page-DCtUkHMu.js} +1 -1
  45. package/dist/gateway/static/root/assets/{dist-DJDkNhu5.js → dist-OM9qGfm5.js} +1 -1
  46. package/dist/gateway/static/root/assets/{extension-debug-page-DI1XJTJi.js → extension-debug-page-D-WHrr_w.js} +1 -1
  47. package/dist/gateway/static/root/assets/{extension-page-SuafGTT_.js → extension-page-CCgjSoKn.js} +1 -1
  48. package/dist/gateway/static/root/assets/{extension-settings-page-cKmGax9v.js → extension-settings-page-BJH5a-Gn.js} +1 -1
  49. package/dist/gateway/static/root/assets/{heartbeat-config-api-CRiDcxtt.js → heartbeat-config-api-CVyP6pFj.js} +1 -1
  50. package/dist/gateway/static/root/assets/{index-50FVtgXU.js → index-CEZxETzw.js} +177 -177
  51. package/dist/gateway/static/root/assets/{logs-page-DM8o5-Bm.js → logs-page-R6Vv_Ja6.js} +1 -1
  52. package/dist/gateway/static/root/assets/{note-detail-page-j53jtvq9.js → note-detail-page-BUDarLhh.js} +1 -1
  53. package/dist/gateway/static/root/assets/{note-time-Ck2H2Qpw.js → note-time-Cc2-T21g.js} +1 -1
  54. package/dist/gateway/static/root/assets/{notes-page-CsWIw35Q.js → notes-page-EAHl16bq.js} +1 -1
  55. package/dist/gateway/static/root/assets/{schema-form-BvmGNxiJ.js → schema-form-CrlOmEZt.js} +1 -1
  56. package/dist/gateway/static/root/assets/{sessions-page-CLPsbyOW.js → sessions-page-Ce_xuuSB.js} +1 -1
  57. package/dist/gateway/static/root/assets/{settings-advanced-gate-DRdayl8P.js → settings-advanced-gate-BBAQxxew.js} +1 -1
  58. package/dist/gateway/static/root/assets/{settings-form-section-BlIYg2gZ.js → settings-form-section-DjPD-ErC.js} +1 -1
  59. package/dist/gateway/static/root/assets/{settings-page-CRGHT_bm.js → settings-page-KhQ9QgH0.js} +1 -1
  60. package/dist/gateway/static/root/assets/{share-preview-page-BlT6Akvk.js → share-preview-page-BjvPht3V.js} +1 -1
  61. package/dist/gateway/static/root/assets/{skills-page-Ce-RIH2y.js → skills-page-C0laq7l1.js} +1 -1
  62. package/dist/gateway/static/root/assets/{voice-api-key-field-CJGTidqc.js → voice-api-key-field-DeGckWkl.js} +1 -1
  63. package/dist/gateway/static/root/assets/{workflow-page.utils-_sjXCMvi.js → workflow-page.utils-D4sqR0yX.js} +1 -1
  64. package/dist/gateway/static/root/assets/{workflows-page-o63aaARK.js → workflows-page-DFjM95g5.js} +1 -1
  65. package/dist/gateway/static/root/index.html +1 -1
  66. package/dist/package.js +1 -1
  67. package/dist/src/agent/mcp/bundle-mcp-config.js +16 -8
  68. package/dist/src/agent/mcp/bundle-mcp-config.js.map +1 -1
  69. package/dist/src/agent/mcp/bundle-mcp-policy.js +2 -2
  70. package/dist/src/agent/mcp/bundle-mcp-policy.js.map +1 -1
  71. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  72. package/dist/src/agent/mcp/mcp-http.js +1 -1
  73. package/dist/src/agent/mcp/mcp-http.js.map +1 -1
  74. package/dist/src/agent/mcp/mcp-transport-config.js +2 -6
  75. package/dist/src/agent/mcp/mcp-transport-config.js.map +1 -1
  76. package/dist/src/agent/workflow/index.js +2 -1
  77. package/dist/src/agent/workflow/runtime.d.ts +2 -2
  78. package/dist/src/agent/workflow/runtime.js +1 -14
  79. package/dist/src/agent/workflow/runtime.js.map +1 -1
  80. package/dist/src/agent/workflow/snapshot-empty.d.ts +2 -0
  81. package/dist/src/agent/workflow/snapshot-empty.js +19 -0
  82. package/dist/src/agent/workflow/snapshot-empty.js.map +1 -0
  83. package/dist/src/agent/workflow/snapshot.js +1 -1
  84. package/dist/src/agent/workflow/snapshot.js.map +1 -1
  85. package/dist/src/connectors/health.js +1 -1
  86. package/dist/src/connectors/install.js +1 -1
  87. package/dist/src/gateway/hono/routes/mcp.js +1 -1
  88. package/dist/src/tui/tui-startup-resources.js +1 -1
  89. package/dist/src/voice/stt/availability.d.ts +6 -0
  90. package/dist/src/voice/stt/availability.js +14 -6
  91. package/dist/src/voice/stt/availability.js.map +1 -1
  92. package/dist/src/voice/stt/index.js +2 -1
  93. package/dist/src/voice/stt/index.js.map +1 -1
  94. package/dist/src/voice/stt/mention.d.ts +2 -0
  95. package/dist/src/voice/stt/mention.js +20 -0
  96. package/dist/src/voice/stt/mention.js.map +1 -0
  97. package/dist/src/voice/stt/preflight.d.ts +1 -4
  98. package/dist/src/voice/stt/preflight.js +1 -18
  99. package/dist/src/voice/stt/preflight.js.map +1 -1
  100. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{a as t,n,t as r}from"./vendor-react-BOUWij0V.js";import{i,o as a}from"./url-DPEStU4M.js";import{i as o}from"./vendor-swr-BIWyz7Rc.js";import{t as s}from"./copy-Dv6d4Dvw.js";import{a as c}from"./fetch-CkvRO30i.js";import{Bi as l,C as u,Cr as d,D as f,Dr as p,E as m,Er as h,It as g,Lo as _,Mo as v,No as y,O as b,Oi as x,Or as S,Qo as C,Ri as w,Rr as T,S as E,Si as D,Sr as O,T as k,To as A,Tr as j,Ui as ee,Va as M,Yi as N,Zr as te,_ as ne,_i as P,a as F,b as re,ca as ie,d as ae,es as I,f as L,fi as R,fo as z,g as B,h as V,i as H,kt as U,li as W,m as oe,na as G,o as K,r as se,s as ce,ta as q,ti as le,to as J,u as ue,ua as de,ui as Y,uo as fe,v as pe,va as me,w as he,wa as ge,wr as _e,x as ve,y as ye}from"./index-50FVtgXU.js";import{a as be,c as xe,d as Se,f as Ce,i as we,l as Te,m as Ee,n as De,o as X,p as Oe,r as ke,s as Ae,t as je,u as Me}from"./workflow-page.utils-_sjXCMvi.js";var Z=e(t(),1),Q=n(),Ne=[`queued`,`running`,`succeeded`,`attention`],Pe=10080*60*1e3,Fe=new Set([`failed`,`timeout`,`cancelled`]);function Ie(e){return e.metadata?.sessionKey?.trim()||null}function Le(e,t){return e.length<=t?e:`${e.slice(0,t-1)}…`}function Re(e,t){if(!e||typeof e!=`object`)return null;let n=e;for(let e of t){let t=n[e];if(typeof t==`string`&&t.trim())return t.trim()}return null}function ze(e,t=90){let n=e.metadata?.input?.goal?.trim()||(typeof e.metadata?.input?.payload==`string`?e.metadata.input.payload.trim():null)||Re(e.metadata?.input?.payload,[`query`,`goal`,`prompt`,`input`,`message`])||Re(e.metadata?.input?.variables,[`query`,`goal`,`prompt`,`input`,`message`]);return n?Le(n,t):null}function Be(e,t=90){return ze(e,t)??Le(e.title?.trim()||e.definitionId,t)}function Ve(e,t=44){return Le(e.title?.trim()||e.definitionId,t)}function He(e,t){let n=t.trim().toLowerCase();return n?[ze(e,500),e.title,e.definitionId,e.id].filter(Boolean).join(` `).toLowerCase().includes(n):!0}function Ue(e,t){let n=t.workflowFilterId.trim();return e.filter(e=>n&&e.definitionId!==n||!Te(e,t.triggerFilter??`all`)?!1:He(e,t.searchQuery))}function We(e){return e.completedAtMs??e.createdAtMs}function Ge(e,t){return t-We(e)<=Pe}function Ke(e,t){return e.status===`queued`?`queued`:e.status===`running`?`running`:e.status===`succeeded`?Ge(e,t)?`succeeded`:null:Fe.has(e.status)?`attention`:null}function qe(e,t){let n=[...t];return e===`queued`?n.sort((e,t)=>e.createdAtMs-t.createdAtMs):e===`running`?n.sort((e,t)=>(t.startedAtMs??t.createdAtMs)-(e.startedAtMs??e.createdAtMs)):n.sort((e,t)=>We(t)-We(e))}function Je(e,t){let n={queued:[],running:[],succeeded:[],attention:[]};for(let r of e){let e=Ke(r,t);e&&n[e].push(r)}let r=qe(`succeeded`,n.succeeded),i=r.length,a=r.slice(0,20),o=Math.max(0,i-20);return Ne.map(e=>e===`succeeded`?{id:e,runs:a,totalInWindow:i,hiddenByCap:o}:{id:e,runs:qe(e,n[e])})}var Ye=new Map;function Xe(e){let t=Ye.get(e);return t||(t=new Intl.RelativeTimeFormat(e,{numeric:`auto`}),Ye.set(e,t)),t}function Ze(e,t,n){let r=Math.round((t-e)/1e3),i=Xe(n);if(r<60)return i.format(-r,`second`);let a=Math.round(r/60);if(a<60)return i.format(-a,`minute`);let o=Math.round(a/60);if(o<48)return i.format(-o,`hour`);let s=Math.round(o/24);return i.format(-s,`day`)}function Qe(e){return e.status===`queued`||e.status===`running`}function $e(e){return e.status===`failed`||e.status===`timeout`||e.status===`cancelled`}var $=r(),et=(0,Z.memo)(function(e){let t=(0,Q.c)(65),{run:n,language:r,localeTag:i,nowMs:o,selected:s,onOpen:c,onOpenChat:l,onCancel:u,onRetry:d}=e,f=a(r).workflows,[p,m]=(0,Z.useState)(!1),h;t[0]===n?h=t[1]:(h=Ie(n),t[0]=n,t[1]=h);let g=!h,_;t[2]===n?_=t[3]:(_=Qe(n),t[2]=n,t[3]=_);let v=_,y=n.status===`running`||n.status===`queued`,b;t[4]!==n.metrics.agentCount||t[5]!==n.metrics.doneAgentCount?(b=n.metrics.agentCount>0?Math.round(n.metrics.doneAgentCount/n.metrics.agentCount*100):0,t[4]=n.metrics.agentCount,t[5]=n.metrics.doneAgentCount,t[6]=b):b=t[6];let x=b,S=n.metrics.errorAgentCount>0,C=n.startedAtMs??n.createdAtMs,w=ke(v?o-C:n.metrics.durationMs),T=X(f.taskArtifacts,{count:n.metrics.artifactCount}),E;t[7]===n?E=t[8]:(E=Be(n),t[7]=n,t[8]=E);let O=E,k;t[9]===n?k=t[10]:(k=Ve(n),t[9]=n,t[10]=k);let A=k,j;t[11]!==c||t[12]!==n?(j=()=>{c(n)},t[11]=c,t[12]=n,t[13]=j):j=t[13];let ee=j,M;t[14]!==g||t[15]!==l||t[16]!==n?(M=()=>{g||l(n)},t[14]=g,t[15]=l,t[16]=n,t[17]=M):M=t[17];let N=M,te=s?`border-accent/70 ring-1 ring-accent/30`:`border-edge`,ne;t[18]===te?ne=t[19]:(ne=Y(`group relative overflow-hidden rounded-xl border bg-surface-panel p-3.5 transition-colors`,te,`hover:border-edge-strong hover:bg-surface-hover/50`),t[18]=te,t[19]=ne);let P;t[20]===Symbol.for(`react.memo_cache_sentinel`)?(P=Y(`w-full text-left`,le.focusRingPanel),t[20]=P):P=t[20];let F;t[21]===O?F=t[22]:(F=(0,$.jsx)(`div`,{className:`line-clamp-2 text-sm font-semibold leading-5 text-fg`,children:O}),t[21]=O,t[22]=F);let re;t[23]===A?re=t[24]:(re=(0,$.jsx)(`div`,{className:`mt-1 truncate text-[11px] font-medium text-fg-muted`,children:A}),t[23]=A,t[24]=re);let ie;t[25]!==F||t[26]!==re?(ie=(0,$.jsxs)(`div`,{className:`min-w-0`,children:[F,re]}),t[25]=F,t[26]=re,t[27]=ie):ie=t[27];let ae;t[28]===n.status?ae=t[29]:(ae=Y(`shrink-0 rounded-full px-2 py-0.5 text-[10px] font-semibold shadow-sm`,Me(n.status)),t[28]=n.status,t[29]=ae);let I;t[30]!==i||t[31]!==o||t[32]!==C?(I=Ze(C,o,i),t[30]=i,t[31]=o,t[32]=C,t[33]=I):I=t[33];let L;t[34]===I?L=t[35]:(L=(0,$.jsx)(`span`,{children:I}),t[34]=I,t[35]=L);let R=w===`—`?null:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`span`,{"aria-hidden":!0,children:`·`}),(0,$.jsx)(`span`,{children:X(f.taskElapsed,{duration:w})})]}),z;t[36]!==L||t[37]!==R?(z=(0,$.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-1.5 text-[11px] text-fg-subtle`,children:[L,R]}),t[36]=L,t[37]=R,t[38]=z):z=t[38];let B=n.metrics.artifactCount>0?(0,$.jsx)(`span`,{className:`rounded-full bg-surface-hover px-2 py-0.5 font-medium text-fg-muted`,children:T}):null,V=s?(0,$.jsx)(`span`,{className:`font-medium text-accent-fg`,children:f.taskOpenDetails}):null,H;t[39]!==B||t[40]!==V?(H=(0,$.jsxs)(`div`,{className:`mt-3 flex flex-wrap items-center gap-2 text-[11px] text-fg-subtle`,children:[B,V]}),t[39]=B,t[40]=V,t[41]=H):H=t[41];let U;t[42]===m?U=t[43]:(U=()=>m(nt),t[42]=m,t[43]=U);let oe;t[44]===Symbol.for(`react.memo_cache_sentinel`)?(oe=(0,$.jsx)(fe,{className:`size-4`,"aria-hidden":!0}),t[44]=oe):oe=t[44];let G;t[45]!==f.taskActionsAria||t[46]!==p||t[47]!==U?(G=(0,$.jsx)(W,{variant:`ghost`,className:`size-7 p-0 opacity-0 group-hover:opacity-100 group-focus-within:opacity-100`,"aria-label":f.taskActionsAria,"aria-expanded":p,onClick:U,children:oe}),t[45]=f.taskActionsAria,t[46]=p,t[47]=U,t[48]=G):G=t[48];let K;t[49]!==v||t[50]!==g||t[51]!==N||t[52]!==f.cancel||t[53]!==f.continueInChat||t[54]!==f.rerun||t[55]!==f.taskCloseMenu||t[56]!==p||t[57]!==u||t[58]!==d||t[59]!==n||t[60]!==m?(K=p?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`button`,{type:`button`,className:`fixed inset-0 z-10 cursor-default`,"aria-label":f.taskCloseMenu,onClick:()=>m(!1)}),(0,$.jsxs)(`div`,{className:`absolute right-0 z-20 mt-1 min-w-36 rounded-lg border border-edge bg-surface-panel py-1 shadow-surface`,children:[(0,$.jsx)(tt,{label:f.continueInChat,disabled:g,onClick:()=>{m(!1),N()}}),v?(0,$.jsx)(tt,{label:f.cancel,tone:`danger`,onClick:()=>{m(!1),u(n.id)}}):null,$e(n)?(0,$.jsx)(tt,{label:f.rerun,onClick:()=>{m(!1),d(n.id)}}):null]})]}):null,t[49]=v,t[50]=g,t[51]=N,t[52]=f.cancel,t[53]=f.continueInChat,t[54]=f.rerun,t[55]=f.taskCloseMenu,t[56]=p,t[57]=u,t[58]=d,t[59]=n,t[60]=m,t[61]=K):K=t[61];let se;return t[62]!==G||t[63]!==K?(se=(0,$.jsxs)(`div`,{className:`absolute right-2 top-2`,children:[G,K]}),t[62]=G,t[63]=K,t[64]=se):se=t[64],(0,$.jsxs)(`div`,{className:ne,children:[(0,$.jsxs)(`button`,{type:`button`,onClick:ee,"aria-label":`${f.taskOpenDetails}: ${O}`,"aria-current":s?`true`:void 0,className:P,children:[(0,$.jsxs)(`div`,{className:`pr-7`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-start justify-between gap-2`,children:[ie,(0,$.jsx)(`span`,{className:ae,children:f.status[n.status]??n.status})]}),z]}),y?(0,$.jsxs)(`div`,{className:`mt-2.5`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-2 text-[11px] text-fg-muted`,children:[(0,$.jsx)(`span`,{children:X(f.agentProgress,{done:n.metrics.doneAgentCount,total:n.metrics.agentCount})}),(0,$.jsxs)(`span`,{children:[x,`%`]})]}),(0,$.jsx)(`div`,{className:`mt-1.5 h-1.5 overflow-hidden rounded-full bg-surface-hover`,children:(0,$.jsx)(`div`,{className:`h-full rounded-full bg-accent transition-all`,style:{width:`${x}%`}})})]}):null,H,S?(0,$.jsxs)(`div`,{className:`mt-2 flex items-center gap-1 text-[11px] text-amber-700 dark:text-amber-300`,children:[(0,$.jsx)(D,{className:`size-3 shrink-0`,"aria-hidden":!0}),X(f.runRowErrorSummary,{count:n.metrics.errorAgentCount})]}):null]}),se]})});function tt(e){let t=(0,Q.c)(8),{label:n,disabled:r,tone:i,onClick:a}=e,o=r?`cursor-not-allowed text-fg-subtle`:`text-fg hover:bg-surface-hover`,s=i===`danger`&&!r&&`text-red-600 dark:text-red-300`,c;t[0]!==o||t[1]!==s?(c=Y(`block w-full px-3 py-1.5 text-left text-xs`,o,s),t[0]=o,t[1]=s,t[2]=c):c=t[2];let l;return t[3]!==r||t[4]!==n||t[5]!==a||t[6]!==c?(l=(0,$.jsx)(`button`,{type:`button`,disabled:r,onClick:a,className:c,children:n}),t[3]=r,t[4]=n,t[5]=a,t[6]=c,t[7]=l):l=t[7],l}function nt(e){return!e}function rt(e,t){return t.boardColumns[e]}var it=(0,Z.memo)(function(e){let t=(0,Q.c)(14),{column:n,language:r,localeTag:i,nowMs:o,selectedRunId:s,onOpenRun:c,onOpenRunChat:l,onCancelRun:u,onRetryRun:d}=e,f=a(r).workflows,[p,m]=(0,Z.useState)(!1),h=n.id===`succeeded`,g=h?5:n.runs.length,_;t[0]!==g||t[1]!==n.runs||t[2]!==p||t[3]!==h?(_=h&&!p?n.runs.slice(0,g):n.runs,t[0]=g,t[1]=n.runs,t[2]=p,t[3]=h,t[4]=_):_=t[4];let v=_,y=h&&n.runs.length>5&&!p,b=h&&p,x;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(x=Y(`flex min-h-112 w-73 shrink-0 snap-center flex-col rounded-2xl border border-edge bg-surface-panel/40`),t[5]=x):x=t[5];let S;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,$.jsx)(`span`,{className:`size-2 rounded-full bg-accent`,"aria-hidden":!0}),t[6]=S):S=t[6];let C;t[7]===n.runs.length?C=t[8]:(C=(0,$.jsx)(`span`,{className:`rounded-full bg-surface-hover px-2.5 py-1 text-xs font-semibold tabular-nums text-fg-muted`,children:n.runs.length}),t[7]=n.runs.length,t[8]=C);let w=v.length===0?(0,$.jsx)(`div`,{className:`flex min-h-32 items-center justify-center rounded-xl border border-dashed border-edge bg-surface-panel/40 px-4 py-6 text-center text-xs text-fg-subtle`,children:f.boardColumnEmpty}):v.map(e=>(0,$.jsx)(et,{run:e,language:r,localeTag:i,nowMs:o,selected:e.id===s,onOpen:c,onOpenChat:l,onCancel:u,onRetry:d},e.id)),T=y?(0,$.jsx)(W,{variant:`ghost`,className:`h-8 w-full text-xs`,onClick:()=>m(!0),children:X(f.boardExpandSucceeded,{count:Math.min(n.runs.length,n.totalInWindow??n.runs.length)})}):null,E=b?(0,$.jsx)(W,{variant:`ghost`,className:`h-8 w-full text-xs`,onClick:()=>m(!1),children:f.boardCollapseSucceeded}):null,D=h&&(n.hiddenByCap??0)>0?(0,$.jsx)(`p`,{className:`px-1 text-center text-[11px] text-fg-subtle`,children:X(f.boardSucceededCapHint,{count:n.hiddenByCap??0})}):null,O;return t[9]!==w||t[10]!==T||t[11]!==E||t[12]!==D?(O=(0,$.jsxs)(`div`,{className:`flex flex-1 flex-col gap-3 p-2.5`,children:[w,T,E,D]}),t[9]=w,t[10]=T,t[11]=E,t[12]=D,t[13]=O):O=t[13],(0,$.jsxs)(`section`,{className:x,"aria-label":rt(n.id,f),children:[(0,$.jsxs)(`header`,{className:`sticky top-0 z-10 flex items-center justify-between gap-2 rounded-t-2xl border-b border-edge-subtle bg-surface-panel/90 px-3.5 py-3 backdrop-blur`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[S,(0,$.jsx)(`h2`,{className:`truncate text-sm font-semibold text-fg`,children:rt(n.id,f)})]}),C]}),O]})}),at=(0,Z.memo)(function(e){let t=(0,Q.c)(45),{runs:n,language:r,localeTag:i,labels:a,searchQuery:o,workflowFilterId:s,triggerFilter:c,selectedRunId:l,loading:u,onOpenRun:d,onOpenRunChat:f,onCancelRun:p,onRetryRun:m,onStart:h}=e,g;t[0]===n?g=t[1]:(g=n.some(ot),t[0]=n,t[1]=g);let _=g,[v,y]=(0,Z.useState)(st),b,x;t[2]===_?(b=t[3],x=t[4]):(b=()=>{if(!_)return;let e=window.setInterval(()=>y(Date.now()),1e3);return()=>window.clearInterval(e)},x=[_],t[2]=_,t[3]=b,t[4]=x),(0,Z.useEffect)(b,x);let S;t[5]!==v||t[6]!==n||t[7]!==o||t[8]!==c||t[9]!==s?(S=Je(Ue(n,{searchQuery:o,workflowFilterId:s,triggerFilter:c}),v),t[5]=v,t[6]=n,t[7]=o,t[8]=c,t[9]=s,t[10]=S):S=t[10];let C=S,w=C.reduce(ct,0);if(u&&w===0){let e;return t[11]===a.loading?e=t[12]:(e=(0,$.jsx)(`p`,{className:`text-sm text-fg-muted`,children:a.loading}),t[11]=a.loading,t[12]=e),e}if(!u&&w===0){let e;t[13]===a.boardEmptyTitle?e=t[14]:(e=(0,$.jsx)(`p`,{className:`text-sm font-medium text-fg`,children:a.boardEmptyTitle}),t[13]=a.boardEmptyTitle,t[14]=e);let n;t[15]===a.boardEmptyHint?n=t[16]:(n=(0,$.jsx)(`p`,{className:`mx-auto mt-2 max-w-md text-sm leading-6 text-fg-muted`,children:a.boardEmptyHint}),t[15]=a.boardEmptyHint,t[16]=n);let r;t[17]!==a.boardStart||t[18]!==h?(r=(0,$.jsx)(`div`,{className:`mt-4 flex justify-center`,children:(0,$.jsx)(W,{variant:`primary`,onClick:h,children:a.boardStart})}),t[17]=a.boardStart,t[18]=h,t[19]=r):r=t[19];let i;return t[20]!==e||t[21]!==n||t[22]!==r?(i=(0,$.jsxs)(`div`,{className:`rounded-2xl border border-dashed border-edge bg-surface-panel/40 px-6 py-12 text-center`,children:[e,n,r]}),t[20]=e,t[21]=n,t[22]=r,t[23]=i):i=t[23],i}let T;if(t[24]!==C||t[25]!==r||t[26]!==i||t[27]!==v||t[28]!==p||t[29]!==d||t[30]!==f||t[31]!==m||t[32]!==l){let e;t[34]!==r||t[35]!==i||t[36]!==v||t[37]!==p||t[38]!==d||t[39]!==f||t[40]!==m||t[41]!==l?(e=e=>(0,$.jsx)(it,{column:e,language:r,localeTag:i,nowMs:v,selectedRunId:l,onOpenRun:d,onOpenRunChat:f,onCancelRun:p,onRetryRun:m},e.id),t[34]=r,t[35]=i,t[36]=v,t[37]=p,t[38]=d,t[39]=f,t[40]=m,t[41]=l,t[42]=e):e=t[42],T=C.map(e),t[24]=C,t[25]=r,t[26]=i,t[27]=v,t[28]=p,t[29]=d,t[30]=f,t[31]=m,t[32]=l,t[33]=T}else T=t[33];let E;return t[43]===T?E=t[44]:(E=(0,$.jsx)(`div`,{className:`-mx-1 flex min-w-0 snap-x snap-mandatory gap-3 overflow-x-auto px-1 pb-2`,children:T}),t[43]=T,t[44]=E),E});function ot(e){return e.status===`queued`||e.status===`running`}function st(){return Date.now()}function ct(e,t){return e+t.runs.length}function lt(e){let t=(0,Q.c)(57),{open:n,definition:r,language:i,onClose:o,onRun:s}=e,c;t[0]===i?c=t[1]:(c=a(i),t[0]=i,t[1]=c);let l=c.workflows;if(!r)return null;let u;t[2]!==r||t[3]!==i?(u=Ee(r,i),t[2]=r,t[3]=i,t[4]=u):u=t[4];let f=u,m=r.runtime?.source??``,g;t[5]===o?g=t[6]:(g=e=>!e&&o(),t[5]=o,t[6]=g);let _;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,$.jsx)(j,{className:`xopc-dialog-overlay fixed inset-0 z-65 bg-scrim backdrop-blur-[1px]`}),t[7]=_):_=t[7];let v;t[8]===r.title?v=t[9]:(v=(0,$.jsx)(S,{className:`text-base font-semibold text-fg`,children:r.title}),t[8]=r.title,t[9]=v);let y;t[10]===f.description?y=t[11]:(y=(0,$.jsx)(_e,{className:`mt-1 text-sm text-fg-muted`,children:f.description}),t[10]=f.description,t[11]=y);let b;t[12]!==v||t[13]!==y?(b=(0,$.jsxs)(`div`,{className:`border-b border-edge px-5 py-4`,children:[v,y]}),t[12]=v,t[13]=y,t[14]=b):b=t[14];let x;t[15]!==l.whenToUseHeading||t[16]!==f.whenToUse?(x=f.whenToUse?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.whenToUseHeading}),(0,$.jsx)(`p`,{className:`mt-2 text-sm leading-6 text-fg-muted`,children:f.whenToUse})]}):null,t[15]=l.whenToUseHeading,t[16]=f.whenToUse,t[17]=x):x=t[17];let C;t[18]!==r||t[19]!==l?(C=(0,$.jsx)(dt,{definition:r,labels:l}),t[18]=r,t[19]=l,t[20]=C):C=t[20];let w;t[21]!==r.inputSchema||t[22]!==l.inputsHeading?(w=r.inputSchema?(0,$.jsx)(pt,{title:l.inputsHeading,schema:r.inputSchema}):null,t[21]=r.inputSchema,t[22]=l.inputsHeading,t[23]=w):w=t[23];let T;t[24]!==r.outputSchema||t[25]!==l.outputsHeading?(T=r.outputSchema?(0,$.jsx)(pt,{title:l.outputsHeading,schema:r.outputSchema}):null,t[24]=r.outputSchema,t[25]=l.outputsHeading,t[26]=T):T=t[26];let E;t[27]!==r.phases||t[28]!==l.phasesHeading?(E=r.phases.length>0?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.phasesHeading}),(0,$.jsx)(`ol`,{className:`mt-2 space-y-2`,children:r.phases.map(ut)})]}):null,t[27]=r.phases,t[28]=l.phasesHeading,t[29]=E):E=t[29];let D;t[30]!==l.scriptHeading||t[31]!==m?(D=m?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.scriptHeading}),(0,$.jsx)(`pre`,{className:`mt-2 max-h-64 overflow-auto rounded-xl border border-edge bg-surface-base/50 p-3 font-mono text-xs leading-5 text-fg-muted`,children:m})]}):null,t[30]=l.scriptHeading,t[31]=m,t[32]=D):D=t[32];let O;t[33]!==w||t[34]!==T||t[35]!==E||t[36]!==D||t[37]!==x||t[38]!==C?(O=(0,$.jsxs)(`div`,{className:`min-h-0 flex-1 space-y-4 overflow-auto px-5 py-4`,children:[x,C,w,T,E,D]}),t[33]=w,t[34]=T,t[35]=E,t[36]=D,t[37]=x,t[38]=C,t[39]=O):O=t[39];let k;t[40]!==l.closeResult||t[41]!==o?(k=(0,$.jsx)(W,{variant:`secondary`,onClick:o,children:l.closeResult}),t[40]=l.closeResult,t[41]=o,t[42]=k):k=t[42];let A;t[43]!==l.runWorkflow||t[44]!==s?(A=(0,$.jsx)(W,{variant:`primary`,onClick:s,children:l.runWorkflow}),t[43]=l.runWorkflow,t[44]=s,t[45]=A):A=t[45];let ee;t[46]!==k||t[47]!==A?(ee=(0,$.jsxs)(`div`,{className:`flex justify-end gap-2 border-t border-edge px-5 py-4`,children:[k,A]}),t[46]=k,t[47]=A,t[48]=ee):ee=t[48];let M;t[49]!==O||t[50]!==ee||t[51]!==b?(M=(0,$.jsxs)(h,{children:[_,(0,$.jsxs)(d,{className:`fixed left-1/2 top-1/2 z-66 flex max-h-[min(85vh,44rem)] w-[min(100%-2rem,48rem)] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-2xl border border-edge bg-surface-panel shadow-popover outline-none`,children:[b,O,ee]})]}),t[49]=O,t[50]=ee,t[51]=b,t[52]=M):M=t[52];let N;return t[53]!==n||t[54]!==M||t[55]!==g?(N=(0,$.jsx)(p,{open:n,onOpenChange:g,children:M}),t[53]=n,t[54]=M,t[55]=g,t[56]=N):N=t[56],N}function ut(e,t){return(0,$.jsxs)(`li`,{className:`rounded-xl border border-edge bg-surface-base/40 px-3 py-2`,children:[(0,$.jsxs)(`div`,{className:`text-sm font-medium text-fg`,children:[t+1,`. `,e.title]}),e.description?(0,$.jsx)(`p`,{className:`mt-1 text-xs leading-5 text-fg-muted`,children:e.description}):null]},e.id)}function dt(e){let t=(0,Q.c)(39),{definition:n,labels:r}=e,i=n.permissions,a=n.resources,o;t[0]!==r.permissionsTools||t[1]!==i?(o=i?.tools?.length?[r.permissionsTools,i.tools.join(`, `)]:null,t[0]=r.permissionsTools,t[1]=i,t[2]=o):o=t[2];let s;t[3]!==r.networkDisabled||t[4]!==r.networkEnabled||t[5]!==r.permissionsNetwork||t[6]!==i?(s=i?.network==null?null:[r.permissionsNetwork,i.network?r.networkEnabled:r.networkDisabled],t[3]=r.networkDisabled,t[4]=r.networkEnabled,t[5]=r.permissionsNetwork,t[6]=i,t[7]=s):s=t[7];let c;t[8]!==r.permissionsFileSystem||t[9]!==i?(c=i?.fileSystem?[r.permissionsFileSystem,i.fileSystem]:null,t[8]=r.permissionsFileSystem,t[9]=i,t[10]=c):c=t[10];let l;t[11]!==r.permissionsApproval||t[12]!==i?.approvalRequired?(l=i?.approvalRequired?[r.permissionsApproval,r.permissionsApproval]:null,t[11]=r.permissionsApproval,t[12]=i?.approvalRequired,t[13]=l):l=t[13];let u;t[14]!==r.resourcesSkills||t[15]!==a?(u=a?.skills?.length?[r.resourcesSkills,a.skills.join(`, `)]:null,t[14]=r.resourcesSkills,t[15]=a,t[16]=u):u=t[16];let d;t[17]!==r.resourcesContextFiles||t[18]!==a?(d=a?.contextFiles?.length?[r.resourcesContextFiles,a.contextFiles.join(`, `)]:null,t[17]=r.resourcesContextFiles,t[18]=a,t[19]=d):d=t[19];let f;t[20]!==r.resourcesPromptTemplates||t[21]!==a?(f=a?.promptTemplates?.length?[r.resourcesPromptTemplates,a.promptTemplates.join(`, `)]:null,t[20]=r.resourcesPromptTemplates,t[21]=a,t[22]=f):f=t[22];let p;t[23]!==o||t[24]!==s||t[25]!==c||t[26]!==l||t[27]!==u||t[28]!==d||t[29]!==f?(p=[o,s,c,l,u,d,f].filter(Boolean),t[23]=o,t[24]=s,t[25]=c,t[26]=l,t[27]=u,t[28]=d,t[29]=f,t[30]=p):p=t[30];let m=p,h;t[31]===r.capabilitiesHeading?h=t[32]:(h=(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:r.capabilitiesHeading}),t[31]=r.capabilitiesHeading,t[32]=h);let g;t[33]!==r.capabilityNone||t[34]!==m?(g=m.length>0?(0,$.jsx)(`div`,{className:`mt-2 grid gap-2 sm:grid-cols-2`,children:m.map(ft)}):(0,$.jsx)(`p`,{className:`mt-2 text-sm text-fg-muted`,children:r.capabilityNone}),t[33]=r.capabilityNone,t[34]=m,t[35]=g):g=t[35];let _;return t[36]!==g||t[37]!==h?(_=(0,$.jsxs)(`section`,{children:[h,g]}),t[36]=g,t[37]=h,t[38]=_):_=t[38],_}function ft(e){let[t,n]=e;return(0,$.jsxs)(`div`,{className:`rounded-xl border border-edge bg-surface-base/40 px-3 py-2`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 text-xs font-medium text-fg-muted`,children:[(0,$.jsx)(ee,{className:`size-3.5 text-fg-subtle`,"aria-hidden":!0}),t]}),(0,$.jsx)(`div`,{className:`mt-1 break-words text-sm text-fg`,children:n})]},`${t}:${n}`)}function pt(e){let t=(0,Q.c)(16),{title:n,schema:r}=e,i;t[0]===r.properties?i=t[1]:(i=Object.keys(r.properties??{}),t[0]=r.properties,t[1]=i);let a=i,o;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(o=(0,$.jsx)(_,{className:`size-3.5`,"aria-hidden":!0}),t[2]=o):o=t[2];let s;t[3]===n?s=t[4]:(s=(0,$.jsxs)(`h3`,{className:`flex items-center gap-2 text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:[o,n]}),t[3]=n,t[4]=s);let c;t[5]===a?c=t[6]:(c=a.length>0?(0,$.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:a.map(mt)}):null,t[5]=a,t[6]=c);let l;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,$.jsx)(`summary`,{className:`cursor-pointer text-xs text-fg-subtle hover:text-fg-muted`,children:`JSON`}),t[7]=l):l=t[7];let u;t[8]===r?u=t[9]:(u=JSON.stringify(r,null,2),t[8]=r,t[9]=u);let d;t[10]===u?d=t[11]:(d=(0,$.jsxs)(`details`,{className:`mt-2`,children:[l,(0,$.jsx)(`pre`,{className:`mt-2 max-h-48 overflow-auto rounded-xl border border-edge bg-surface-base/50 p-3 font-mono text-xs leading-5 text-fg-muted`,children:u})]}),t[10]=u,t[11]=d);let f;return t[12]!==s||t[13]!==c||t[14]!==d?(f=(0,$.jsxs)(`section`,{children:[s,c,d]}),t[12]=s,t[13]=c,t[14]=d,t[15]=f):f=t[15],f}function mt(e){return(0,$.jsx)(`span`,{className:`rounded-lg border border-edge-subtle bg-surface-base px-2 py-1 text-xs text-fg-muted`,children:e},e)}function ht({open:e,language:t,saving:n,onClose:r,onSave:i}){let o=a(t).workflows,[s,c]=(0,Z.useState)(``),[l,u]=(0,Z.useState)(``),[f,m]=(0,Z.useState)(!1),[g,_]=(0,Z.useState)(!1),[v,y]=(0,Z.useState)(null),[x,C]=(0,Z.useState)(null);(0,Z.useEffect)(()=>{e&&(c(``),m(!1),_(!1),y(null),C(null),u(`export const meta = {
1
+ import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{a as t,n,t as r}from"./vendor-react-BOUWij0V.js";import{i,o as a}from"./url-DPEStU4M.js";import{i as o}from"./vendor-swr-BIWyz7Rc.js";import{t as s}from"./copy-Dv6d4Dvw.js";import{a as c}from"./fetch-CkvRO30i.js";import{Bi as l,C as u,Cr as d,D as f,Dr as p,E as m,Er as h,It as g,Lo as _,Mo as v,No as y,O as b,Oi as x,Or as S,Qo as C,Ri as w,Rr as T,S as E,Si as D,Sr as O,T as k,To as A,Tr as j,Ui as ee,Va as M,Yi as N,Zr as te,_ as ne,_i as P,a as F,b as re,ca as ie,d as ae,es as I,f as L,fi as R,fo as z,g as B,h as V,i as H,kt as U,li as W,m as oe,na as G,o as K,r as se,s as ce,ta as q,ti as le,to as J,u as ue,ua as de,ui as Y,uo as fe,v as pe,va as me,w as he,wa as ge,wr as _e,x as ve,y as ye}from"./index-CEZxETzw.js";import{a as be,c as xe,d as Se,f as Ce,i as we,l as Te,m as Ee,n as De,o as X,p as Oe,r as ke,s as Ae,t as je,u as Me}from"./workflow-page.utils-D4sqR0yX.js";var Z=e(t(),1),Q=n(),Ne=[`queued`,`running`,`succeeded`,`attention`],Pe=10080*60*1e3,Fe=new Set([`failed`,`timeout`,`cancelled`]);function Ie(e){return e.metadata?.sessionKey?.trim()||null}function Le(e,t){return e.length<=t?e:`${e.slice(0,t-1)}…`}function Re(e,t){if(!e||typeof e!=`object`)return null;let n=e;for(let e of t){let t=n[e];if(typeof t==`string`&&t.trim())return t.trim()}return null}function ze(e,t=90){let n=e.metadata?.input?.goal?.trim()||(typeof e.metadata?.input?.payload==`string`?e.metadata.input.payload.trim():null)||Re(e.metadata?.input?.payload,[`query`,`goal`,`prompt`,`input`,`message`])||Re(e.metadata?.input?.variables,[`query`,`goal`,`prompt`,`input`,`message`]);return n?Le(n,t):null}function Be(e,t=90){return ze(e,t)??Le(e.title?.trim()||e.definitionId,t)}function Ve(e,t=44){return Le(e.title?.trim()||e.definitionId,t)}function He(e,t){let n=t.trim().toLowerCase();return n?[ze(e,500),e.title,e.definitionId,e.id].filter(Boolean).join(` `).toLowerCase().includes(n):!0}function Ue(e,t){let n=t.workflowFilterId.trim();return e.filter(e=>n&&e.definitionId!==n||!Te(e,t.triggerFilter??`all`)?!1:He(e,t.searchQuery))}function We(e){return e.completedAtMs??e.createdAtMs}function Ge(e,t){return t-We(e)<=Pe}function Ke(e,t){return e.status===`queued`?`queued`:e.status===`running`?`running`:e.status===`succeeded`?Ge(e,t)?`succeeded`:null:Fe.has(e.status)?`attention`:null}function qe(e,t){let n=[...t];return e===`queued`?n.sort((e,t)=>e.createdAtMs-t.createdAtMs):e===`running`?n.sort((e,t)=>(t.startedAtMs??t.createdAtMs)-(e.startedAtMs??e.createdAtMs)):n.sort((e,t)=>We(t)-We(e))}function Je(e,t){let n={queued:[],running:[],succeeded:[],attention:[]};for(let r of e){let e=Ke(r,t);e&&n[e].push(r)}let r=qe(`succeeded`,n.succeeded),i=r.length,a=r.slice(0,20),o=Math.max(0,i-20);return Ne.map(e=>e===`succeeded`?{id:e,runs:a,totalInWindow:i,hiddenByCap:o}:{id:e,runs:qe(e,n[e])})}var Ye=new Map;function Xe(e){let t=Ye.get(e);return t||(t=new Intl.RelativeTimeFormat(e,{numeric:`auto`}),Ye.set(e,t)),t}function Ze(e,t,n){let r=Math.round((t-e)/1e3),i=Xe(n);if(r<60)return i.format(-r,`second`);let a=Math.round(r/60);if(a<60)return i.format(-a,`minute`);let o=Math.round(a/60);if(o<48)return i.format(-o,`hour`);let s=Math.round(o/24);return i.format(-s,`day`)}function Qe(e){return e.status===`queued`||e.status===`running`}function $e(e){return e.status===`failed`||e.status===`timeout`||e.status===`cancelled`}var $=r(),et=(0,Z.memo)(function(e){let t=(0,Q.c)(65),{run:n,language:r,localeTag:i,nowMs:o,selected:s,onOpen:c,onOpenChat:l,onCancel:u,onRetry:d}=e,f=a(r).workflows,[p,m]=(0,Z.useState)(!1),h;t[0]===n?h=t[1]:(h=Ie(n),t[0]=n,t[1]=h);let g=!h,_;t[2]===n?_=t[3]:(_=Qe(n),t[2]=n,t[3]=_);let v=_,y=n.status===`running`||n.status===`queued`,b;t[4]!==n.metrics.agentCount||t[5]!==n.metrics.doneAgentCount?(b=n.metrics.agentCount>0?Math.round(n.metrics.doneAgentCount/n.metrics.agentCount*100):0,t[4]=n.metrics.agentCount,t[5]=n.metrics.doneAgentCount,t[6]=b):b=t[6];let x=b,S=n.metrics.errorAgentCount>0,C=n.startedAtMs??n.createdAtMs,w=ke(v?o-C:n.metrics.durationMs),T=X(f.taskArtifacts,{count:n.metrics.artifactCount}),E;t[7]===n?E=t[8]:(E=Be(n),t[7]=n,t[8]=E);let O=E,k;t[9]===n?k=t[10]:(k=Ve(n),t[9]=n,t[10]=k);let A=k,j;t[11]!==c||t[12]!==n?(j=()=>{c(n)},t[11]=c,t[12]=n,t[13]=j):j=t[13];let ee=j,M;t[14]!==g||t[15]!==l||t[16]!==n?(M=()=>{g||l(n)},t[14]=g,t[15]=l,t[16]=n,t[17]=M):M=t[17];let N=M,te=s?`border-accent/70 ring-1 ring-accent/30`:`border-edge`,ne;t[18]===te?ne=t[19]:(ne=Y(`group relative overflow-hidden rounded-xl border bg-surface-panel p-3.5 transition-colors`,te,`hover:border-edge-strong hover:bg-surface-hover/50`),t[18]=te,t[19]=ne);let P;t[20]===Symbol.for(`react.memo_cache_sentinel`)?(P=Y(`w-full text-left`,le.focusRingPanel),t[20]=P):P=t[20];let F;t[21]===O?F=t[22]:(F=(0,$.jsx)(`div`,{className:`line-clamp-2 text-sm font-semibold leading-5 text-fg`,children:O}),t[21]=O,t[22]=F);let re;t[23]===A?re=t[24]:(re=(0,$.jsx)(`div`,{className:`mt-1 truncate text-[11px] font-medium text-fg-muted`,children:A}),t[23]=A,t[24]=re);let ie;t[25]!==F||t[26]!==re?(ie=(0,$.jsxs)(`div`,{className:`min-w-0`,children:[F,re]}),t[25]=F,t[26]=re,t[27]=ie):ie=t[27];let ae;t[28]===n.status?ae=t[29]:(ae=Y(`shrink-0 rounded-full px-2 py-0.5 text-[10px] font-semibold shadow-sm`,Me(n.status)),t[28]=n.status,t[29]=ae);let I;t[30]!==i||t[31]!==o||t[32]!==C?(I=Ze(C,o,i),t[30]=i,t[31]=o,t[32]=C,t[33]=I):I=t[33];let L;t[34]===I?L=t[35]:(L=(0,$.jsx)(`span`,{children:I}),t[34]=I,t[35]=L);let R=w===`—`?null:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`span`,{"aria-hidden":!0,children:`·`}),(0,$.jsx)(`span`,{children:X(f.taskElapsed,{duration:w})})]}),z;t[36]!==L||t[37]!==R?(z=(0,$.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-1.5 text-[11px] text-fg-subtle`,children:[L,R]}),t[36]=L,t[37]=R,t[38]=z):z=t[38];let B=n.metrics.artifactCount>0?(0,$.jsx)(`span`,{className:`rounded-full bg-surface-hover px-2 py-0.5 font-medium text-fg-muted`,children:T}):null,V=s?(0,$.jsx)(`span`,{className:`font-medium text-accent-fg`,children:f.taskOpenDetails}):null,H;t[39]!==B||t[40]!==V?(H=(0,$.jsxs)(`div`,{className:`mt-3 flex flex-wrap items-center gap-2 text-[11px] text-fg-subtle`,children:[B,V]}),t[39]=B,t[40]=V,t[41]=H):H=t[41];let U;t[42]===m?U=t[43]:(U=()=>m(nt),t[42]=m,t[43]=U);let oe;t[44]===Symbol.for(`react.memo_cache_sentinel`)?(oe=(0,$.jsx)(fe,{className:`size-4`,"aria-hidden":!0}),t[44]=oe):oe=t[44];let G;t[45]!==f.taskActionsAria||t[46]!==p||t[47]!==U?(G=(0,$.jsx)(W,{variant:`ghost`,className:`size-7 p-0 opacity-0 group-hover:opacity-100 group-focus-within:opacity-100`,"aria-label":f.taskActionsAria,"aria-expanded":p,onClick:U,children:oe}),t[45]=f.taskActionsAria,t[46]=p,t[47]=U,t[48]=G):G=t[48];let K;t[49]!==v||t[50]!==g||t[51]!==N||t[52]!==f.cancel||t[53]!==f.continueInChat||t[54]!==f.rerun||t[55]!==f.taskCloseMenu||t[56]!==p||t[57]!==u||t[58]!==d||t[59]!==n||t[60]!==m?(K=p?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`button`,{type:`button`,className:`fixed inset-0 z-10 cursor-default`,"aria-label":f.taskCloseMenu,onClick:()=>m(!1)}),(0,$.jsxs)(`div`,{className:`absolute right-0 z-20 mt-1 min-w-36 rounded-lg border border-edge bg-surface-panel py-1 shadow-surface`,children:[(0,$.jsx)(tt,{label:f.continueInChat,disabled:g,onClick:()=>{m(!1),N()}}),v?(0,$.jsx)(tt,{label:f.cancel,tone:`danger`,onClick:()=>{m(!1),u(n.id)}}):null,$e(n)?(0,$.jsx)(tt,{label:f.rerun,onClick:()=>{m(!1),d(n.id)}}):null]})]}):null,t[49]=v,t[50]=g,t[51]=N,t[52]=f.cancel,t[53]=f.continueInChat,t[54]=f.rerun,t[55]=f.taskCloseMenu,t[56]=p,t[57]=u,t[58]=d,t[59]=n,t[60]=m,t[61]=K):K=t[61];let se;return t[62]!==G||t[63]!==K?(se=(0,$.jsxs)(`div`,{className:`absolute right-2 top-2`,children:[G,K]}),t[62]=G,t[63]=K,t[64]=se):se=t[64],(0,$.jsxs)(`div`,{className:ne,children:[(0,$.jsxs)(`button`,{type:`button`,onClick:ee,"aria-label":`${f.taskOpenDetails}: ${O}`,"aria-current":s?`true`:void 0,className:P,children:[(0,$.jsxs)(`div`,{className:`pr-7`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-start justify-between gap-2`,children:[ie,(0,$.jsx)(`span`,{className:ae,children:f.status[n.status]??n.status})]}),z]}),y?(0,$.jsxs)(`div`,{className:`mt-2.5`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-2 text-[11px] text-fg-muted`,children:[(0,$.jsx)(`span`,{children:X(f.agentProgress,{done:n.metrics.doneAgentCount,total:n.metrics.agentCount})}),(0,$.jsxs)(`span`,{children:[x,`%`]})]}),(0,$.jsx)(`div`,{className:`mt-1.5 h-1.5 overflow-hidden rounded-full bg-surface-hover`,children:(0,$.jsx)(`div`,{className:`h-full rounded-full bg-accent transition-all`,style:{width:`${x}%`}})})]}):null,H,S?(0,$.jsxs)(`div`,{className:`mt-2 flex items-center gap-1 text-[11px] text-amber-700 dark:text-amber-300`,children:[(0,$.jsx)(D,{className:`size-3 shrink-0`,"aria-hidden":!0}),X(f.runRowErrorSummary,{count:n.metrics.errorAgentCount})]}):null]}),se]})});function tt(e){let t=(0,Q.c)(8),{label:n,disabled:r,tone:i,onClick:a}=e,o=r?`cursor-not-allowed text-fg-subtle`:`text-fg hover:bg-surface-hover`,s=i===`danger`&&!r&&`text-red-600 dark:text-red-300`,c;t[0]!==o||t[1]!==s?(c=Y(`block w-full px-3 py-1.5 text-left text-xs`,o,s),t[0]=o,t[1]=s,t[2]=c):c=t[2];let l;return t[3]!==r||t[4]!==n||t[5]!==a||t[6]!==c?(l=(0,$.jsx)(`button`,{type:`button`,disabled:r,onClick:a,className:c,children:n}),t[3]=r,t[4]=n,t[5]=a,t[6]=c,t[7]=l):l=t[7],l}function nt(e){return!e}function rt(e,t){return t.boardColumns[e]}var it=(0,Z.memo)(function(e){let t=(0,Q.c)(14),{column:n,language:r,localeTag:i,nowMs:o,selectedRunId:s,onOpenRun:c,onOpenRunChat:l,onCancelRun:u,onRetryRun:d}=e,f=a(r).workflows,[p,m]=(0,Z.useState)(!1),h=n.id===`succeeded`,g=h?5:n.runs.length,_;t[0]!==g||t[1]!==n.runs||t[2]!==p||t[3]!==h?(_=h&&!p?n.runs.slice(0,g):n.runs,t[0]=g,t[1]=n.runs,t[2]=p,t[3]=h,t[4]=_):_=t[4];let v=_,y=h&&n.runs.length>5&&!p,b=h&&p,x;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(x=Y(`flex min-h-112 w-73 shrink-0 snap-center flex-col rounded-2xl border border-edge bg-surface-panel/40`),t[5]=x):x=t[5];let S;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,$.jsx)(`span`,{className:`size-2 rounded-full bg-accent`,"aria-hidden":!0}),t[6]=S):S=t[6];let C;t[7]===n.runs.length?C=t[8]:(C=(0,$.jsx)(`span`,{className:`rounded-full bg-surface-hover px-2.5 py-1 text-xs font-semibold tabular-nums text-fg-muted`,children:n.runs.length}),t[7]=n.runs.length,t[8]=C);let w=v.length===0?(0,$.jsx)(`div`,{className:`flex min-h-32 items-center justify-center rounded-xl border border-dashed border-edge bg-surface-panel/40 px-4 py-6 text-center text-xs text-fg-subtle`,children:f.boardColumnEmpty}):v.map(e=>(0,$.jsx)(et,{run:e,language:r,localeTag:i,nowMs:o,selected:e.id===s,onOpen:c,onOpenChat:l,onCancel:u,onRetry:d},e.id)),T=y?(0,$.jsx)(W,{variant:`ghost`,className:`h-8 w-full text-xs`,onClick:()=>m(!0),children:X(f.boardExpandSucceeded,{count:Math.min(n.runs.length,n.totalInWindow??n.runs.length)})}):null,E=b?(0,$.jsx)(W,{variant:`ghost`,className:`h-8 w-full text-xs`,onClick:()=>m(!1),children:f.boardCollapseSucceeded}):null,D=h&&(n.hiddenByCap??0)>0?(0,$.jsx)(`p`,{className:`px-1 text-center text-[11px] text-fg-subtle`,children:X(f.boardSucceededCapHint,{count:n.hiddenByCap??0})}):null,O;return t[9]!==w||t[10]!==T||t[11]!==E||t[12]!==D?(O=(0,$.jsxs)(`div`,{className:`flex flex-1 flex-col gap-3 p-2.5`,children:[w,T,E,D]}),t[9]=w,t[10]=T,t[11]=E,t[12]=D,t[13]=O):O=t[13],(0,$.jsxs)(`section`,{className:x,"aria-label":rt(n.id,f),children:[(0,$.jsxs)(`header`,{className:`sticky top-0 z-10 flex items-center justify-between gap-2 rounded-t-2xl border-b border-edge-subtle bg-surface-panel/90 px-3.5 py-3 backdrop-blur`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[S,(0,$.jsx)(`h2`,{className:`truncate text-sm font-semibold text-fg`,children:rt(n.id,f)})]}),C]}),O]})}),at=(0,Z.memo)(function(e){let t=(0,Q.c)(45),{runs:n,language:r,localeTag:i,labels:a,searchQuery:o,workflowFilterId:s,triggerFilter:c,selectedRunId:l,loading:u,onOpenRun:d,onOpenRunChat:f,onCancelRun:p,onRetryRun:m,onStart:h}=e,g;t[0]===n?g=t[1]:(g=n.some(ot),t[0]=n,t[1]=g);let _=g,[v,y]=(0,Z.useState)(st),b,x;t[2]===_?(b=t[3],x=t[4]):(b=()=>{if(!_)return;let e=window.setInterval(()=>y(Date.now()),1e3);return()=>window.clearInterval(e)},x=[_],t[2]=_,t[3]=b,t[4]=x),(0,Z.useEffect)(b,x);let S;t[5]!==v||t[6]!==n||t[7]!==o||t[8]!==c||t[9]!==s?(S=Je(Ue(n,{searchQuery:o,workflowFilterId:s,triggerFilter:c}),v),t[5]=v,t[6]=n,t[7]=o,t[8]=c,t[9]=s,t[10]=S):S=t[10];let C=S,w=C.reduce(ct,0);if(u&&w===0){let e;return t[11]===a.loading?e=t[12]:(e=(0,$.jsx)(`p`,{className:`text-sm text-fg-muted`,children:a.loading}),t[11]=a.loading,t[12]=e),e}if(!u&&w===0){let e;t[13]===a.boardEmptyTitle?e=t[14]:(e=(0,$.jsx)(`p`,{className:`text-sm font-medium text-fg`,children:a.boardEmptyTitle}),t[13]=a.boardEmptyTitle,t[14]=e);let n;t[15]===a.boardEmptyHint?n=t[16]:(n=(0,$.jsx)(`p`,{className:`mx-auto mt-2 max-w-md text-sm leading-6 text-fg-muted`,children:a.boardEmptyHint}),t[15]=a.boardEmptyHint,t[16]=n);let r;t[17]!==a.boardStart||t[18]!==h?(r=(0,$.jsx)(`div`,{className:`mt-4 flex justify-center`,children:(0,$.jsx)(W,{variant:`primary`,onClick:h,children:a.boardStart})}),t[17]=a.boardStart,t[18]=h,t[19]=r):r=t[19];let i;return t[20]!==e||t[21]!==n||t[22]!==r?(i=(0,$.jsxs)(`div`,{className:`rounded-2xl border border-dashed border-edge bg-surface-panel/40 px-6 py-12 text-center`,children:[e,n,r]}),t[20]=e,t[21]=n,t[22]=r,t[23]=i):i=t[23],i}let T;if(t[24]!==C||t[25]!==r||t[26]!==i||t[27]!==v||t[28]!==p||t[29]!==d||t[30]!==f||t[31]!==m||t[32]!==l){let e;t[34]!==r||t[35]!==i||t[36]!==v||t[37]!==p||t[38]!==d||t[39]!==f||t[40]!==m||t[41]!==l?(e=e=>(0,$.jsx)(it,{column:e,language:r,localeTag:i,nowMs:v,selectedRunId:l,onOpenRun:d,onOpenRunChat:f,onCancelRun:p,onRetryRun:m},e.id),t[34]=r,t[35]=i,t[36]=v,t[37]=p,t[38]=d,t[39]=f,t[40]=m,t[41]=l,t[42]=e):e=t[42],T=C.map(e),t[24]=C,t[25]=r,t[26]=i,t[27]=v,t[28]=p,t[29]=d,t[30]=f,t[31]=m,t[32]=l,t[33]=T}else T=t[33];let E;return t[43]===T?E=t[44]:(E=(0,$.jsx)(`div`,{className:`-mx-1 flex min-w-0 snap-x snap-mandatory gap-3 overflow-x-auto px-1 pb-2`,children:T}),t[43]=T,t[44]=E),E});function ot(e){return e.status===`queued`||e.status===`running`}function st(){return Date.now()}function ct(e,t){return e+t.runs.length}function lt(e){let t=(0,Q.c)(57),{open:n,definition:r,language:i,onClose:o,onRun:s}=e,c;t[0]===i?c=t[1]:(c=a(i),t[0]=i,t[1]=c);let l=c.workflows;if(!r)return null;let u;t[2]!==r||t[3]!==i?(u=Ee(r,i),t[2]=r,t[3]=i,t[4]=u):u=t[4];let f=u,m=r.runtime?.source??``,g;t[5]===o?g=t[6]:(g=e=>!e&&o(),t[5]=o,t[6]=g);let _;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,$.jsx)(j,{className:`xopc-dialog-overlay fixed inset-0 z-65 bg-scrim backdrop-blur-[1px]`}),t[7]=_):_=t[7];let v;t[8]===r.title?v=t[9]:(v=(0,$.jsx)(S,{className:`text-base font-semibold text-fg`,children:r.title}),t[8]=r.title,t[9]=v);let y;t[10]===f.description?y=t[11]:(y=(0,$.jsx)(_e,{className:`mt-1 text-sm text-fg-muted`,children:f.description}),t[10]=f.description,t[11]=y);let b;t[12]!==v||t[13]!==y?(b=(0,$.jsxs)(`div`,{className:`border-b border-edge px-5 py-4`,children:[v,y]}),t[12]=v,t[13]=y,t[14]=b):b=t[14];let x;t[15]!==l.whenToUseHeading||t[16]!==f.whenToUse?(x=f.whenToUse?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.whenToUseHeading}),(0,$.jsx)(`p`,{className:`mt-2 text-sm leading-6 text-fg-muted`,children:f.whenToUse})]}):null,t[15]=l.whenToUseHeading,t[16]=f.whenToUse,t[17]=x):x=t[17];let C;t[18]!==r||t[19]!==l?(C=(0,$.jsx)(dt,{definition:r,labels:l}),t[18]=r,t[19]=l,t[20]=C):C=t[20];let w;t[21]!==r.inputSchema||t[22]!==l.inputsHeading?(w=r.inputSchema?(0,$.jsx)(pt,{title:l.inputsHeading,schema:r.inputSchema}):null,t[21]=r.inputSchema,t[22]=l.inputsHeading,t[23]=w):w=t[23];let T;t[24]!==r.outputSchema||t[25]!==l.outputsHeading?(T=r.outputSchema?(0,$.jsx)(pt,{title:l.outputsHeading,schema:r.outputSchema}):null,t[24]=r.outputSchema,t[25]=l.outputsHeading,t[26]=T):T=t[26];let E;t[27]!==r.phases||t[28]!==l.phasesHeading?(E=r.phases.length>0?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.phasesHeading}),(0,$.jsx)(`ol`,{className:`mt-2 space-y-2`,children:r.phases.map(ut)})]}):null,t[27]=r.phases,t[28]=l.phasesHeading,t[29]=E):E=t[29];let D;t[30]!==l.scriptHeading||t[31]!==m?(D=m?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.scriptHeading}),(0,$.jsx)(`pre`,{className:`mt-2 max-h-64 overflow-auto rounded-xl border border-edge bg-surface-base/50 p-3 font-mono text-xs leading-5 text-fg-muted`,children:m})]}):null,t[30]=l.scriptHeading,t[31]=m,t[32]=D):D=t[32];let O;t[33]!==w||t[34]!==T||t[35]!==E||t[36]!==D||t[37]!==x||t[38]!==C?(O=(0,$.jsxs)(`div`,{className:`min-h-0 flex-1 space-y-4 overflow-auto px-5 py-4`,children:[x,C,w,T,E,D]}),t[33]=w,t[34]=T,t[35]=E,t[36]=D,t[37]=x,t[38]=C,t[39]=O):O=t[39];let k;t[40]!==l.closeResult||t[41]!==o?(k=(0,$.jsx)(W,{variant:`secondary`,onClick:o,children:l.closeResult}),t[40]=l.closeResult,t[41]=o,t[42]=k):k=t[42];let A;t[43]!==l.runWorkflow||t[44]!==s?(A=(0,$.jsx)(W,{variant:`primary`,onClick:s,children:l.runWorkflow}),t[43]=l.runWorkflow,t[44]=s,t[45]=A):A=t[45];let ee;t[46]!==k||t[47]!==A?(ee=(0,$.jsxs)(`div`,{className:`flex justify-end gap-2 border-t border-edge px-5 py-4`,children:[k,A]}),t[46]=k,t[47]=A,t[48]=ee):ee=t[48];let M;t[49]!==O||t[50]!==ee||t[51]!==b?(M=(0,$.jsxs)(h,{children:[_,(0,$.jsxs)(d,{className:`fixed left-1/2 top-1/2 z-66 flex max-h-[min(85vh,44rem)] w-[min(100%-2rem,48rem)] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-2xl border border-edge bg-surface-panel shadow-popover outline-none`,children:[b,O,ee]})]}),t[49]=O,t[50]=ee,t[51]=b,t[52]=M):M=t[52];let N;return t[53]!==n||t[54]!==M||t[55]!==g?(N=(0,$.jsx)(p,{open:n,onOpenChange:g,children:M}),t[53]=n,t[54]=M,t[55]=g,t[56]=N):N=t[56],N}function ut(e,t){return(0,$.jsxs)(`li`,{className:`rounded-xl border border-edge bg-surface-base/40 px-3 py-2`,children:[(0,$.jsxs)(`div`,{className:`text-sm font-medium text-fg`,children:[t+1,`. `,e.title]}),e.description?(0,$.jsx)(`p`,{className:`mt-1 text-xs leading-5 text-fg-muted`,children:e.description}):null]},e.id)}function dt(e){let t=(0,Q.c)(39),{definition:n,labels:r}=e,i=n.permissions,a=n.resources,o;t[0]!==r.permissionsTools||t[1]!==i?(o=i?.tools?.length?[r.permissionsTools,i.tools.join(`, `)]:null,t[0]=r.permissionsTools,t[1]=i,t[2]=o):o=t[2];let s;t[3]!==r.networkDisabled||t[4]!==r.networkEnabled||t[5]!==r.permissionsNetwork||t[6]!==i?(s=i?.network==null?null:[r.permissionsNetwork,i.network?r.networkEnabled:r.networkDisabled],t[3]=r.networkDisabled,t[4]=r.networkEnabled,t[5]=r.permissionsNetwork,t[6]=i,t[7]=s):s=t[7];let c;t[8]!==r.permissionsFileSystem||t[9]!==i?(c=i?.fileSystem?[r.permissionsFileSystem,i.fileSystem]:null,t[8]=r.permissionsFileSystem,t[9]=i,t[10]=c):c=t[10];let l;t[11]!==r.permissionsApproval||t[12]!==i?.approvalRequired?(l=i?.approvalRequired?[r.permissionsApproval,r.permissionsApproval]:null,t[11]=r.permissionsApproval,t[12]=i?.approvalRequired,t[13]=l):l=t[13];let u;t[14]!==r.resourcesSkills||t[15]!==a?(u=a?.skills?.length?[r.resourcesSkills,a.skills.join(`, `)]:null,t[14]=r.resourcesSkills,t[15]=a,t[16]=u):u=t[16];let d;t[17]!==r.resourcesContextFiles||t[18]!==a?(d=a?.contextFiles?.length?[r.resourcesContextFiles,a.contextFiles.join(`, `)]:null,t[17]=r.resourcesContextFiles,t[18]=a,t[19]=d):d=t[19];let f;t[20]!==r.resourcesPromptTemplates||t[21]!==a?(f=a?.promptTemplates?.length?[r.resourcesPromptTemplates,a.promptTemplates.join(`, `)]:null,t[20]=r.resourcesPromptTemplates,t[21]=a,t[22]=f):f=t[22];let p;t[23]!==o||t[24]!==s||t[25]!==c||t[26]!==l||t[27]!==u||t[28]!==d||t[29]!==f?(p=[o,s,c,l,u,d,f].filter(Boolean),t[23]=o,t[24]=s,t[25]=c,t[26]=l,t[27]=u,t[28]=d,t[29]=f,t[30]=p):p=t[30];let m=p,h;t[31]===r.capabilitiesHeading?h=t[32]:(h=(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:r.capabilitiesHeading}),t[31]=r.capabilitiesHeading,t[32]=h);let g;t[33]!==r.capabilityNone||t[34]!==m?(g=m.length>0?(0,$.jsx)(`div`,{className:`mt-2 grid gap-2 sm:grid-cols-2`,children:m.map(ft)}):(0,$.jsx)(`p`,{className:`mt-2 text-sm text-fg-muted`,children:r.capabilityNone}),t[33]=r.capabilityNone,t[34]=m,t[35]=g):g=t[35];let _;return t[36]!==g||t[37]!==h?(_=(0,$.jsxs)(`section`,{children:[h,g]}),t[36]=g,t[37]=h,t[38]=_):_=t[38],_}function ft(e){let[t,n]=e;return(0,$.jsxs)(`div`,{className:`rounded-xl border border-edge bg-surface-base/40 px-3 py-2`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 text-xs font-medium text-fg-muted`,children:[(0,$.jsx)(ee,{className:`size-3.5 text-fg-subtle`,"aria-hidden":!0}),t]}),(0,$.jsx)(`div`,{className:`mt-1 break-words text-sm text-fg`,children:n})]},`${t}:${n}`)}function pt(e){let t=(0,Q.c)(16),{title:n,schema:r}=e,i;t[0]===r.properties?i=t[1]:(i=Object.keys(r.properties??{}),t[0]=r.properties,t[1]=i);let a=i,o;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(o=(0,$.jsx)(_,{className:`size-3.5`,"aria-hidden":!0}),t[2]=o):o=t[2];let s;t[3]===n?s=t[4]:(s=(0,$.jsxs)(`h3`,{className:`flex items-center gap-2 text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:[o,n]}),t[3]=n,t[4]=s);let c;t[5]===a?c=t[6]:(c=a.length>0?(0,$.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:a.map(mt)}):null,t[5]=a,t[6]=c);let l;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,$.jsx)(`summary`,{className:`cursor-pointer text-xs text-fg-subtle hover:text-fg-muted`,children:`JSON`}),t[7]=l):l=t[7];let u;t[8]===r?u=t[9]:(u=JSON.stringify(r,null,2),t[8]=r,t[9]=u);let d;t[10]===u?d=t[11]:(d=(0,$.jsxs)(`details`,{className:`mt-2`,children:[l,(0,$.jsx)(`pre`,{className:`mt-2 max-h-48 overflow-auto rounded-xl border border-edge bg-surface-base/50 p-3 font-mono text-xs leading-5 text-fg-muted`,children:u})]}),t[10]=u,t[11]=d);let f;return t[12]!==s||t[13]!==c||t[14]!==d?(f=(0,$.jsxs)(`section`,{children:[s,c,d]}),t[12]=s,t[13]=c,t[14]=d,t[15]=f):f=t[15],f}function mt(e){return(0,$.jsx)(`span`,{className:`rounded-lg border border-edge-subtle bg-surface-base px-2 py-1 text-xs text-fg-muted`,children:e},e)}function ht({open:e,language:t,saving:n,onClose:r,onSave:i}){let o=a(t).workflows,[s,c]=(0,Z.useState)(``),[l,u]=(0,Z.useState)(``),[f,m]=(0,Z.useState)(!1),[g,_]=(0,Z.useState)(!1),[v,y]=(0,Z.useState)(null),[x,C]=(0,Z.useState)(null);(0,Z.useEffect)(()=>{e&&(c(``),m(!1),_(!1),y(null),C(null),u(`export const meta = {
2
2
  name: 'my_workflow',
3
3
  description: 'Describe what this workflow does.',
4
4
  whenToUse: 'When the user asks for …',
@@ -9,7 +9,7 @@
9
9
  <link rel="icon" type="image/svg+xml" href="/logo.svg" />
10
10
  <link rel="apple-touch-icon" href="/logo.svg" />
11
11
  <title>xopc</title>
12
- <script type="module" crossorigin src="/assets/index-50FVtgXU.js"></script>
12
+ <script type="module" crossorigin src="/assets/index-CEZxETzw.js"></script>
13
13
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-aKtaBQYM.js">
14
14
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-zJ_50EbN.js">
15
15
  <link rel="modulepreload" crossorigin href="/assets/vendor-codemirror-DYoKfS8f.js">
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.0.105";
2
+ var version = "0.0.106";
3
3
  //#endregion
4
4
  export { version };
5
5
 
@@ -1,18 +1,26 @@
1
- import { isManagedConnectorServer } from "../../connectors/materialize.js";
2
1
  import { normalizeConfiguredMcpServers } from "../../config/mcp-config-normalize.js";
2
+ import { loadEnabledBundleMcpConfig } from "../../extensions/bundle-mcp.js";
3
3
  //#region src/agent/mcp/bundle-mcp-config.ts
4
- function listConnectorManagedMcpServers(params) {
4
+ function listConfiguredMcpServers(params) {
5
5
  const configuredMcp = normalizeConfiguredMcpServers(params.cfg?.mcp?.servers);
6
- return Object.fromEntries(Object.entries(configuredMcp).filter(([, server]) => isManagedConnectorServer(server)).map(([name, server]) => [name, params.mapConfiguredServer(server, name)]));
6
+ return Object.fromEntries(Object.entries(configuredMcp).map(([name, server]) => [name, params.mapConfiguredServer(server, name)]));
7
7
  }
8
8
  function loadMergedBundleMcpConfig(params) {
9
9
  const mapConfiguredServer = params.mapConfiguredServer ?? ((server) => server);
10
+ const bundled = loadEnabledBundleMcpConfig({
11
+ workspaceDir: params.workspaceDir,
12
+ cfg: params.cfg
13
+ });
14
+ const configured = listConfiguredMcpServers({
15
+ cfg: params.cfg,
16
+ mapConfiguredServer
17
+ });
10
18
  return {
11
- config: { mcpServers: listConnectorManagedMcpServers({
12
- cfg: params.cfg,
13
- mapConfiguredServer
14
- }) },
15
- diagnostics: []
19
+ config: { mcpServers: {
20
+ ...bundled.config.mcpServers,
21
+ ...configured
22
+ } },
23
+ diagnostics: bundled.diagnostics
16
24
  };
17
25
  }
18
26
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"bundle-mcp-config.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-config.ts"],"sourcesContent":["import { normalizeConfiguredMcpServers } from '../../config/mcp-config-normalize.js';\nimport { isManagedConnectorServer } from '../../connectors/materialize.js';\nimport type { Config } from '../../config/schema.js';\nimport {\n type BundleMcpConfig,\n type BundleMcpDiagnostic,\n type BundleMcpServerConfig,\n} from '../../extensions/bundle-mcp.js';\n\nexport type MergedBundleMcpConfig = {\n config: BundleMcpConfig;\n diagnostics: BundleMcpDiagnostic[];\n};\n\nexport type BundleMcpServerMapper = (\n server: BundleMcpServerConfig,\n name: string,\n) => BundleMcpServerConfig;\n\nfunction listConnectorManagedMcpServers(params: {\n cfg?: Config;\n mapConfiguredServer: BundleMcpServerMapper;\n}): BundleMcpConfig[\"mcpServers\"] {\n const configuredMcp = normalizeConfiguredMcpServers(params.cfg?.mcp?.servers);\n return Object.fromEntries(\n Object.entries(configuredMcp)\n .filter(([, server]) => isManagedConnectorServer(server))\n .map(([name, server]) => [\n name,\n params.mapConfiguredServer(server as BundleMcpServerConfig, name),\n ]),\n ) satisfies BundleMcpConfig[\"mcpServers\"];\n}\n\nexport function loadMergedBundleMcpConfig(params: {\n workspaceDir: string;\n cfg?: Config;\n mapConfiguredServer?: BundleMcpServerMapper;\n}): MergedBundleMcpConfig {\n const mapConfiguredServer = params.mapConfiguredServer ?? ((server) => server);\n\n return {\n config: {\n mcpServers: listConnectorManagedMcpServers({\n cfg: params.cfg,\n mapConfiguredServer,\n }),\n },\n diagnostics: [],\n };\n}\n"],"mappings":";;;AAmBA,SAAS,+BAA+B,QAGN;CAChC,MAAM,gBAAgB,8BAA8B,OAAO,KAAK,KAAK,QAAQ;AAC7E,QAAO,OAAO,YACZ,OAAO,QAAQ,cAAc,CAC1B,QAAQ,GAAG,YAAY,yBAAyB,OAAO,CAAC,CACxD,KAAK,CAAC,MAAM,YAAY,CACvB,MACA,OAAO,oBAAoB,QAAiC,KAAK,CAClE,CAAC,CACL;;AAGH,SAAgB,0BAA0B,QAIhB;CACxB,MAAM,sBAAsB,OAAO,yBAAyB,WAAW;AAEvE,QAAO;EACL,QAAQ,EACN,YAAY,+BAA+B;GACzC,KAAK,OAAO;GACZ;GACD,CAAC,EACH;EACD,aAAa,EAAE;EAChB"}
1
+ {"version":3,"file":"bundle-mcp-config.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-config.ts"],"sourcesContent":["import { normalizeConfiguredMcpServers } from '../../config/mcp-config-normalize.js';\nimport type { Config } from '../../config/schema.js';\nimport {\n loadEnabledBundleMcpConfig,\n type BundleMcpConfig,\n type BundleMcpDiagnostic,\n type BundleMcpServerConfig,\n} from '../../extensions/bundle-mcp.js';\n\nexport type MergedBundleMcpConfig = {\n config: BundleMcpConfig;\n diagnostics: BundleMcpDiagnostic[];\n};\n\nexport type BundleMcpServerMapper = (\n server: BundleMcpServerConfig,\n name: string,\n) => BundleMcpServerConfig;\n\nfunction listConfiguredMcpServers(params: {\n cfg?: Config;\n mapConfiguredServer: BundleMcpServerMapper;\n}): BundleMcpConfig[\"mcpServers\"] {\n const configuredMcp = normalizeConfiguredMcpServers(params.cfg?.mcp?.servers);\n return Object.fromEntries(\n Object.entries(configuredMcp)\n .map(([name, server]) => [\n name,\n params.mapConfiguredServer(server as BundleMcpServerConfig, name),\n ]),\n ) satisfies BundleMcpConfig[\"mcpServers\"];\n}\n\nexport function loadMergedBundleMcpConfig(params: {\n workspaceDir: string;\n cfg?: Config;\n mapConfiguredServer?: BundleMcpServerMapper;\n}): MergedBundleMcpConfig {\n const mapConfiguredServer = params.mapConfiguredServer ?? ((server) => server);\n const bundled = loadEnabledBundleMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n const configured = listConfiguredMcpServers({\n cfg: params.cfg,\n mapConfiguredServer,\n });\n\n return {\n config: {\n mcpServers: {\n ...bundled.config.mcpServers,\n ...configured,\n },\n },\n diagnostics: bundled.diagnostics,\n };\n}\n"],"mappings":";;;AAmBA,SAAS,yBAAyB,QAGA;CAChC,MAAM,gBAAgB,8BAA8B,OAAO,KAAK,KAAK,QAAQ;AAC7E,QAAO,OAAO,YACZ,OAAO,QAAQ,cAAc,CAC1B,KAAK,CAAC,MAAM,YAAY,CACvB,MACA,OAAO,oBAAoB,QAAiC,KAAK,CAClE,CAAC,CACL;;AAGH,SAAgB,0BAA0B,QAIhB;CACxB,MAAM,sBAAsB,OAAO,yBAAyB,WAAW;CACvE,MAAM,UAAU,2BAA2B;EACzC,cAAc,OAAO;EACrB,KAAK,OAAO;EACb,CAAC;CACF,MAAM,aAAa,yBAAyB;EAC1C,KAAK,OAAO;EACZ;EACD,CAAC;AAEF,QAAO;EACL,QAAQ,EACN,YAAY;GACV,GAAG,QAAQ,OAAO;GAClB,GAAG;GACJ,EACF;EACD,aAAa,QAAQ;EACtB"}
@@ -1,10 +1,10 @@
1
1
  import "./bundle-mcp-names.js";
2
- import { listConnectorInstances } from "../../connectors/instances.js";
2
+ import { hasAnyMcpServers } from "../../extensions/bundle-mcp.js";
3
3
  //#region src/agent/mcp/bundle-mcp-policy.ts
4
4
  function shouldCreateBundleMcpRuntimeForAttempt(params) {
5
5
  if (params.toolsEnabled === false) return false;
6
6
  if (params.disabledTools?.has("bundle-mcp")) return false;
7
- return listConnectorInstances(params.cfg ?? {}).length > 0;
7
+ return hasAnyMcpServers(params.cfg ?? {});
8
8
  }
9
9
  function isMcpToolName(toolName) {
10
10
  return toolName.includes("__");
@@ -1 +1 @@
1
- {"version":3,"file":"bundle-mcp-policy.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-policy.ts"],"sourcesContent":["import { TOOL_NAME_SEPARATOR } from './bundle-mcp-names.js';\nimport { listConnectorInstances } from '../../connectors/instances.js';\nimport type { Config } from '../../config/schema.js';\n\nexport function shouldCreateBundleMcpRuntimeForAttempt(params: {\n cfg?: Config;\n toolsEnabled?: boolean;\n disabledTools?: Set<string>;\n}): boolean {\n if (params.toolsEnabled === false) {\n return false;\n }\n if (params.disabledTools?.has('bundle-mcp')) {\n return false;\n }\n return listConnectorInstances(params.cfg ?? ({} as Config)).length > 0;\n}\n\nexport function isMcpToolName(toolName: string): boolean {\n return toolName.includes(TOOL_NAME_SEPARATOR);\n}\n\nexport function parseMcpToolName(toolName: string): { serverId: string; toolId: string } | null {\n const idx = toolName.indexOf(TOOL_NAME_SEPARATOR);\n if (idx <= 0) {\n return null;\n }\n return {\n serverId: toolName.slice(0, idx),\n toolId: toolName.slice(idx + TOOL_NAME_SEPARATOR.length),\n };\n}\n"],"mappings":";;;AAIA,SAAgB,uCAAuC,QAI3C;AACV,KAAI,OAAO,iBAAiB,MAC1B,QAAO;AAET,KAAI,OAAO,eAAe,IAAI,aAAa,CACzC,QAAO;AAET,QAAO,uBAAuB,OAAO,OAAQ,EAAE,CAAY,CAAC,SAAS;;AAGvE,SAAgB,cAAc,UAA2B;AACvD,QAAO,SAAS,SAAA,KAA6B;;AAG/C,SAAgB,iBAAiB,UAA+D;CAC9F,MAAM,MAAM,SAAS,QAAA,KAA4B;AACjD,KAAI,OAAO,EACT,QAAO;AAET,QAAO;EACL,UAAU,SAAS,MAAM,GAAG,IAAI;EAChC,QAAQ,SAAS,MAAM,MAAA,EAAiC;EACzD"}
1
+ {"version":3,"file":"bundle-mcp-policy.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-policy.ts"],"sourcesContent":["import { TOOL_NAME_SEPARATOR } from './bundle-mcp-names.js';\nimport { hasAnyMcpServers } from '../../extensions/bundle-mcp.js';\nimport type { Config } from '../../config/schema.js';\n\nexport function shouldCreateBundleMcpRuntimeForAttempt(params: {\n cfg?: Config;\n toolsEnabled?: boolean;\n disabledTools?: Set<string>;\n}): boolean {\n if (params.toolsEnabled === false) {\n return false;\n }\n if (params.disabledTools?.has('bundle-mcp')) {\n return false;\n }\n return hasAnyMcpServers(params.cfg ?? ({} as Config));\n}\n\nexport function isMcpToolName(toolName: string): boolean {\n return toolName.includes(TOOL_NAME_SEPARATOR);\n}\n\nexport function parseMcpToolName(toolName: string): { serverId: string; toolId: string } | null {\n const idx = toolName.indexOf(TOOL_NAME_SEPARATOR);\n if (idx <= 0) {\n return null;\n }\n return {\n serverId: toolName.slice(0, idx),\n toolId: toolName.slice(idx + TOOL_NAME_SEPARATOR.length),\n };\n}\n"],"mappings":";;;AAIA,SAAgB,uCAAuC,QAI3C;AACV,KAAI,OAAO,iBAAiB,MAC1B,QAAO;AAET,KAAI,OAAO,eAAe,IAAI,aAAa,CACzC,QAAO;AAET,QAAO,iBAAiB,OAAO,OAAQ,EAAE,CAAY;;AAGvD,SAAgB,cAAc,UAA2B;AACvD,QAAO,SAAS,SAAA,KAA6B;;AAG/C,SAAgB,iBAAiB,UAA+D;CAC9F,MAAM,MAAM,SAAS,QAAA,KAA4B;AACjD,KAAI,OAAO,EACT,QAAO;AAET,QAAO;EACL,UAAU,SAAS,MAAM,GAAG,IAAI;EAChC,QAAQ,SAAS,MAAM,MAAA,EAAiC;EACzD"}
@@ -3,9 +3,9 @@ import { init_logger } from "../../utils/logger.js";
3
3
  import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
4
4
  import { resolveGlobalSingleton } from "../../utils/global-singleton.js";
5
5
  import { sanitizeServerName } from "./bundle-mcp-names.js";
6
- import { resolveConnectorSecretReferences } from "../../connectors/secret-store.js";
7
6
  import { redactSensitiveUrlLikeString } from "../../utils/redact-sensitive-url.js";
8
7
  import { loadEmbeddedMcpConfig } from "./embedded-mcp.js";
8
+ import { resolveConnectorSecretReferences } from "../../connectors/secret-store.js";
9
9
  import { isMcpConfigRecord } from "./mcp-config-shared.js";
10
10
  import { resolveMcpTransport } from "./mcp-transport.js";
11
11
  import crypto from "node:crypto";
@@ -30,7 +30,7 @@ function resolveHttpMcpServerLaunchConfig(raw, options) {
30
30
  return {
31
31
  ok: true,
32
32
  config: {
33
- transportType: options?.transportType ?? "sse",
33
+ transportType: options?.transportType ?? "streamable-http",
34
34
  url,
35
35
  headers
36
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-http.js","names":[],"sources":["../../../../src/agent/mcp/mcp-http.ts"],"sourcesContent":["import {\n redactSensitiveUrl,\n redactSensitiveUrlLikeString,\n} from \"../../utils/redact-sensitive-url.js\";\nimport { isMcpConfigRecord, toMcpStringRecord } from \"./mcp-config-shared.js\";\n\nexport type HttpMcpTransportType = \"sse\" | \"streamable-http\";\n\nexport type HttpMcpServerLaunchConfig = {\n transportType: HttpMcpTransportType;\n url: string;\n headers?: Record<string, string>;\n};\n\nexport type HttpMcpServerLaunchResult =\n | { ok: true; config: HttpMcpServerLaunchConfig }\n | { ok: false; reason: string };\n\nexport function resolveHttpMcpServerLaunchConfig(\n raw: unknown,\n options?: {\n transportType?: HttpMcpTransportType;\n onDroppedHeader?: (key: string, value: unknown) => void;\n onMalformedHeaders?: (value: unknown) => void;\n },\n): HttpMcpServerLaunchResult {\n if (!isMcpConfigRecord(raw)) {\n return { ok: false, reason: \"server config must be an object\" };\n }\n if (typeof raw.url !== \"string\" || raw.url.trim().length === 0) {\n return { ok: false, reason: \"its url is missing\" };\n }\n const url = raw.url.trim();\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return {\n ok: false,\n reason: `its url is not a valid URL: ${redactSensitiveUrlLikeString(url)}`,\n };\n }\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n return {\n ok: false,\n reason: `only http and https URLs are supported, got ${parsed.protocol}`,\n };\n }\n\n let headers: Record<string, string> | undefined;\n if (raw.headers !== undefined && raw.headers !== null) {\n if (!isMcpConfigRecord(raw.headers)) {\n options?.onMalformedHeaders?.(raw.headers);\n } else {\n headers = toMcpStringRecord(raw.headers, {\n onDroppedEntry: options?.onDroppedHeader,\n });\n }\n }\n\n return {\n ok: true,\n config: {\n transportType: options?.transportType ?? \"sse\",\n url,\n headers,\n },\n };\n}\n\nexport function describeHttpMcpServerLaunchConfig(config: HttpMcpServerLaunchConfig): string {\n return redactSensitiveUrl(config.url);\n}\n"],"mappings":";;;AAkBA,SAAgB,iCACd,KACA,SAK2B;AAC3B,KAAI,CAAC,kBAAkB,IAAI,CACzB,QAAO;EAAE,IAAI;EAAO,QAAQ;EAAmC;AAEjE,KAAI,OAAO,IAAI,QAAQ,YAAY,IAAI,IAAI,MAAM,CAAC,WAAW,EAC3D,QAAO;EAAE,IAAI;EAAO,QAAQ;EAAsB;CAEpD,MAAM,MAAM,IAAI,IAAI,MAAM;CAC1B,IAAI;AACJ,KAAI;AACF,WAAS,IAAI,IAAI,IAAI;SACf;AACN,SAAO;GACL,IAAI;GACJ,QAAQ,+BAA+B,6BAA6B,IAAI;GACzE;;AAEH,KAAI,OAAO,aAAa,WAAW,OAAO,aAAa,SACrD,QAAO;EACL,IAAI;EACJ,QAAQ,+CAA+C,OAAO;EAC/D;CAGH,IAAI;AACJ,KAAI,IAAI,YAAY,KAAA,KAAa,IAAI,YAAY,KAC/C,KAAI,CAAC,kBAAkB,IAAI,QAAQ,CACjC,UAAS,qBAAqB,IAAI,QAAQ;KAE1C,WAAU,kBAAkB,IAAI,SAAS,EACvC,gBAAgB,SAAS,iBAC1B,CAAC;AAIN,QAAO;EACL,IAAI;EACJ,QAAQ;GACN,eAAe,SAAS,iBAAiB;GACzC;GACA;GACD;EACF;;AAGH,SAAgB,kCAAkC,QAA2C;AAC3F,QAAO,mBAAmB,OAAO,IAAI"}
1
+ {"version":3,"file":"mcp-http.js","names":[],"sources":["../../../../src/agent/mcp/mcp-http.ts"],"sourcesContent":["import {\n redactSensitiveUrl,\n redactSensitiveUrlLikeString,\n} from \"../../utils/redact-sensitive-url.js\";\nimport { isMcpConfigRecord, toMcpStringRecord } from \"./mcp-config-shared.js\";\n\nexport type HttpMcpTransportType = \"sse\" | \"streamable-http\";\n\nexport type HttpMcpServerLaunchConfig = {\n transportType: HttpMcpTransportType;\n url: string;\n headers?: Record<string, string>;\n};\n\nexport type HttpMcpServerLaunchResult =\n | { ok: true; config: HttpMcpServerLaunchConfig }\n | { ok: false; reason: string };\n\nexport function resolveHttpMcpServerLaunchConfig(\n raw: unknown,\n options?: {\n transportType?: HttpMcpTransportType;\n onDroppedHeader?: (key: string, value: unknown) => void;\n onMalformedHeaders?: (value: unknown) => void;\n },\n): HttpMcpServerLaunchResult {\n if (!isMcpConfigRecord(raw)) {\n return { ok: false, reason: \"server config must be an object\" };\n }\n if (typeof raw.url !== \"string\" || raw.url.trim().length === 0) {\n return { ok: false, reason: \"its url is missing\" };\n }\n const url = raw.url.trim();\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return {\n ok: false,\n reason: `its url is not a valid URL: ${redactSensitiveUrlLikeString(url)}`,\n };\n }\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n return {\n ok: false,\n reason: `only http and https URLs are supported, got ${parsed.protocol}`,\n };\n }\n\n let headers: Record<string, string> | undefined;\n if (raw.headers !== undefined && raw.headers !== null) {\n if (!isMcpConfigRecord(raw.headers)) {\n options?.onMalformedHeaders?.(raw.headers);\n } else {\n headers = toMcpStringRecord(raw.headers, {\n onDroppedEntry: options?.onDroppedHeader,\n });\n }\n }\n\n return {\n ok: true,\n config: {\n transportType: options?.transportType ?? \"streamable-http\",\n url,\n headers,\n },\n };\n}\n\nexport function describeHttpMcpServerLaunchConfig(config: HttpMcpServerLaunchConfig): string {\n return redactSensitiveUrl(config.url);\n}\n"],"mappings":";;;AAkBA,SAAgB,iCACd,KACA,SAK2B;AAC3B,KAAI,CAAC,kBAAkB,IAAI,CACzB,QAAO;EAAE,IAAI;EAAO,QAAQ;EAAmC;AAEjE,KAAI,OAAO,IAAI,QAAQ,YAAY,IAAI,IAAI,MAAM,CAAC,WAAW,EAC3D,QAAO;EAAE,IAAI;EAAO,QAAQ;EAAsB;CAEpD,MAAM,MAAM,IAAI,IAAI,MAAM;CAC1B,IAAI;AACJ,KAAI;AACF,WAAS,IAAI,IAAI,IAAI;SACf;AACN,SAAO;GACL,IAAI;GACJ,QAAQ,+BAA+B,6BAA6B,IAAI;GACzE;;AAEH,KAAI,OAAO,aAAa,WAAW,OAAO,aAAa,SACrD,QAAO;EACL,IAAI;EACJ,QAAQ,+CAA+C,OAAO;EAC/D;CAGH,IAAI;AACJ,KAAI,IAAI,YAAY,KAAA,KAAa,IAAI,YAAY,KAC/C,KAAI,CAAC,kBAAkB,IAAI,QAAQ,CACjC,UAAS,qBAAqB,IAAI,QAAQ;KAE1C,WAAU,kBAAkB,IAAI,SAAS,EACvC,gBAAgB,SAAS,iBAC1B,CAAC;AAIN,QAAO;EACL,IAAI;EACJ,QAAQ;GACN,eAAe,SAAS,iBAAiB;GACzC;GACA;GACD;EACF;;AAGH,SAAgB,kCAAkC,QAA2C;AAC3F,QAAO,mBAAmB,OAAO,IAAI"}
@@ -71,12 +71,8 @@ function resolveMcpTransportConfig(serverName, rawServer) {
71
71
  log.warn(`bundle-mcp: skipped server "${logServerName}" because transport "${sanitizeForLog(effectiveTransport)}" is not supported.`);
72
72
  return null;
73
73
  }
74
- if (effectiveTransport === "streamable-http") {
75
- const httpTransport = resolveHttpTransportConfig(serverName, rawServer, "streamable-http");
76
- if (httpTransport) return httpTransport;
77
- }
78
- const sseTransport = resolveHttpTransportConfig(serverName, rawServer, "sse");
79
- if (sseTransport) return sseTransport;
74
+ const httpTransport = resolveHttpTransportConfig(serverName, rawServer, effectiveTransport === "sse" ? "sse" : "streamable-http");
75
+ if (httpTransport) return httpTransport;
80
76
  const stdioReason = stdioLaunch.ok === false ? stdioLaunch.reason : "not a stdio server";
81
77
  const httpLaunch = resolveHttpMcpServerLaunchConfig(rawServer);
82
78
  const httpReason = httpLaunch.ok === false ? httpLaunch.reason : "not an HTTP MCP server";
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-transport-config.js","names":[],"sources":["../../../../src/agent/mcp/mcp-transport-config.ts"],"sourcesContent":["import { resolveXopcMcpTransportAlias } from \"../../config/mcp-config-normalize.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Bundle\");\nimport { normalizeLowercaseStringOrEmpty } from \"../../utils/string-coerce.js\";\nimport { sanitizeForLog } from \"../../utils/sanitize-log.js\";\nimport {\n describeHttpMcpServerLaunchConfig,\n resolveHttpMcpServerLaunchConfig,\n type HttpMcpTransportType,\n} from \"./mcp-http.js\";\nimport {\n describeStdioMcpServerLaunchConfig,\n resolveStdioMcpServerLaunchConfig,\n} from \"./mcp-stdio.js\";\n\ntype ResolvedBaseMcpTransportConfig = {\n description: string;\n connectionTimeoutMs: number;\n};\n\nexport type ResolvedStdioMcpTransportConfig = ResolvedBaseMcpTransportConfig & {\n kind: \"stdio\";\n transportType: \"stdio\";\n command: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n};\n\nexport type ResolvedHttpMcpTransportConfig = ResolvedBaseMcpTransportConfig & {\n kind: \"http\";\n transportType: HttpMcpTransportType;\n url: string;\n headers?: Record<string, string>;\n};\n\nexport type ResolvedMcpTransportConfig =\n | ResolvedStdioMcpTransportConfig\n | ResolvedHttpMcpTransportConfig;\n\nconst DEFAULT_CONNECTION_TIMEOUT_MS = 30_000;\n\nfunction getConnectionTimeoutMs(rawServer: unknown): number {\n if (\n rawServer &&\n typeof rawServer === \"object\" &&\n typeof (rawServer as { connectionTimeoutMs?: unknown }).connectionTimeoutMs === \"number\" &&\n (rawServer as { connectionTimeoutMs: number }).connectionTimeoutMs > 0\n ) {\n return (rawServer as { connectionTimeoutMs: number }).connectionTimeoutMs;\n }\n return DEFAULT_CONNECTION_TIMEOUT_MS;\n}\n\nfunction getRequestedTransport(rawServer: unknown): string {\n if (\n !rawServer ||\n typeof rawServer !== \"object\" ||\n typeof (rawServer as { transport?: unknown }).transport !== \"string\"\n ) {\n return \"\";\n }\n return normalizeLowercaseStringOrEmpty((rawServer as { transport?: string }).transport);\n}\n\nfunction getRequestedTransportAlias(rawServer: unknown): HttpMcpTransportType | \"\" {\n if (\n !rawServer ||\n typeof rawServer !== \"object\" ||\n typeof (rawServer as { type?: unknown }).type !== \"string\"\n ) {\n return \"\";\n }\n return resolveXopcMcpTransportAlias((rawServer as { type?: string }).type) ?? \"\";\n}\n\nfunction resolveHttpTransportConfig(\n serverName: string,\n rawServer: unknown,\n transportType: HttpMcpTransportType,\n): ResolvedHttpMcpTransportConfig | null {\n const launch = resolveHttpMcpServerLaunchConfig(rawServer, {\n transportType,\n onDroppedHeader: (key) => {\n log.warn(\n {\n phase: 'agent.mcp_connect',\n serverName,\n header: key,\n },\n `bundle-mcp: server \"${serverName}\": header \"${key}\" has an unsupported value type and was ignored`,\n );\n },\n onMalformedHeaders: () => {\n log.warn(\n { phase: 'agent.mcp_connect', serverName },\n `bundle-mcp: server \"${serverName}\": \"headers\" must be a JSON object; the value was ignored`,\n );\n },\n });\n if (!launch.ok) {\n return null;\n }\n return {\n kind: \"http\",\n transportType: launch.config.transportType,\n url: launch.config.url,\n headers: launch.config.headers,\n description: describeHttpMcpServerLaunchConfig(launch.config),\n connectionTimeoutMs: getConnectionTimeoutMs(rawServer),\n };\n}\n\nexport function resolveMcpTransportConfig(\n serverName: string,\n rawServer: unknown,\n): ResolvedMcpTransportConfig | null {\n const logServerName = sanitizeForLog(serverName);\n const requestedTransport = getRequestedTransport(rawServer);\n const requestedTransportAlias = requestedTransport ? \"\" : getRequestedTransportAlias(rawServer);\n const effectiveTransport = requestedTransport || requestedTransportAlias;\n const stdioLaunch = resolveStdioMcpServerLaunchConfig(rawServer, {\n onDroppedEnv: (key) => {\n log.warn(\n `bundle-mcp: server \"${logServerName}\": env \"${sanitizeForLog(key)}\" is blocked for stdio startup safety and was ignored.`,\n );\n },\n });\n if (stdioLaunch.ok) {\n return {\n kind: \"stdio\",\n transportType: \"stdio\",\n command: stdioLaunch.config.command,\n args: stdioLaunch.config.args,\n env: stdioLaunch.config.env,\n cwd: stdioLaunch.config.cwd,\n description: describeStdioMcpServerLaunchConfig(stdioLaunch.config),\n connectionTimeoutMs: getConnectionTimeoutMs(rawServer),\n };\n }\n\n if (\n effectiveTransport &&\n effectiveTransport !== \"sse\" &&\n effectiveTransport !== \"streamable-http\"\n ) {\n log.warn(\n `bundle-mcp: skipped server \"${logServerName}\" because transport \"${sanitizeForLog(effectiveTransport)}\" is not supported.`,\n );\n return null;\n }\n\n if (effectiveTransport === \"streamable-http\") {\n const httpTransport = resolveHttpTransportConfig(serverName, rawServer, \"streamable-http\");\n if (httpTransport) {\n return httpTransport;\n }\n }\n\n const sseTransport = resolveHttpTransportConfig(serverName, rawServer, \"sse\");\n if (sseTransport) {\n return sseTransport;\n }\n\n const stdioReason =\n stdioLaunch.ok === false ? stdioLaunch.reason : 'not a stdio server';\n const httpLaunch = resolveHttpMcpServerLaunchConfig(rawServer);\n const httpReason =\n httpLaunch.ok === false ? httpLaunch.reason : 'not an HTTP MCP server';\n log.warn(\n `bundle-mcp: skipped server \"${logServerName}\" because ${stdioReason} and ${httpReason}.`,\n );\n return null;\n}\n"],"mappings":";;;;;;;;aACqD;oBAE0B;AAD/E,MAAM,MAAM,aAAa,aAAa;AAsCtC,MAAM,gCAAgC;AAEtC,SAAS,uBAAuB,WAA4B;AAC1D,KACE,aACA,OAAO,cAAc,YACrB,OAAQ,UAAgD,wBAAwB,YAC/E,UAA8C,sBAAsB,EAErE,QAAQ,UAA8C;AAExD,QAAO;;AAGT,SAAS,sBAAsB,WAA4B;AACzD,KACE,CAAC,aACD,OAAO,cAAc,YACrB,OAAQ,UAAsC,cAAc,SAE5D,QAAO;AAET,QAAO,gCAAiC,UAAqC,UAAU;;AAGzF,SAAS,2BAA2B,WAA+C;AACjF,KACE,CAAC,aACD,OAAO,cAAc,YACrB,OAAQ,UAAiC,SAAS,SAElD,QAAO;AAET,QAAO,6BAA8B,UAAgC,KAAK,IAAI;;AAGhF,SAAS,2BACP,YACA,WACA,eACuC;CACvC,MAAM,SAAS,iCAAiC,WAAW;EACzD;EACA,kBAAkB,QAAQ;AACxB,OAAI,KACF;IACE,OAAO;IACP;IACA,QAAQ;IACT,EACD,uBAAuB,WAAW,aAAa,IAAI,iDACpD;;EAEH,0BAA0B;AACxB,OAAI,KACF;IAAE,OAAO;IAAqB;IAAY,EAC1C,uBAAuB,WAAW,2DACnC;;EAEJ,CAAC;AACF,KAAI,CAAC,OAAO,GACV,QAAO;AAET,QAAO;EACL,MAAM;EACN,eAAe,OAAO,OAAO;EAC7B,KAAK,OAAO,OAAO;EACnB,SAAS,OAAO,OAAO;EACvB,aAAa,kCAAkC,OAAO,OAAO;EAC7D,qBAAqB,uBAAuB,UAAU;EACvD;;AAGH,SAAgB,0BACd,YACA,WACmC;CACnC,MAAM,gBAAgB,eAAe,WAAW;CAChD,MAAM,qBAAqB,sBAAsB,UAAU;CAC3D,MAAM,0BAA0B,qBAAqB,KAAK,2BAA2B,UAAU;CAC/F,MAAM,qBAAqB,sBAAsB;CACjD,MAAM,cAAc,kCAAkC,WAAW,EAC/D,eAAe,QAAQ;AACrB,MAAI,KACF,uBAAuB,cAAc,UAAU,eAAe,IAAI,CAAC,wDACpE;IAEJ,CAAC;AACF,KAAI,YAAY,GACd,QAAO;EACL,MAAM;EACN,eAAe;EACf,SAAS,YAAY,OAAO;EAC5B,MAAM,YAAY,OAAO;EACzB,KAAK,YAAY,OAAO;EACxB,KAAK,YAAY,OAAO;EACxB,aAAa,mCAAmC,YAAY,OAAO;EACnE,qBAAqB,uBAAuB,UAAU;EACvD;AAGH,KACE,sBACA,uBAAuB,SACvB,uBAAuB,mBACvB;AACA,MAAI,KACF,+BAA+B,cAAc,uBAAuB,eAAe,mBAAmB,CAAC,qBACxG;AACD,SAAO;;AAGT,KAAI,uBAAuB,mBAAmB;EAC5C,MAAM,gBAAgB,2BAA2B,YAAY,WAAW,kBAAkB;AAC1F,MAAI,cACF,QAAO;;CAIX,MAAM,eAAe,2BAA2B,YAAY,WAAW,MAAM;AAC7E,KAAI,aACF,QAAO;CAGT,MAAM,cACJ,YAAY,OAAO,QAAQ,YAAY,SAAS;CAClD,MAAM,aAAa,iCAAiC,UAAU;CAC9D,MAAM,aACJ,WAAW,OAAO,QAAQ,WAAW,SAAS;AAChD,KAAI,KACF,+BAA+B,cAAc,YAAY,YAAY,OAAO,WAAW,GACxF;AACD,QAAO"}
1
+ {"version":3,"file":"mcp-transport-config.js","names":[],"sources":["../../../../src/agent/mcp/mcp-transport-config.ts"],"sourcesContent":["import { resolveXopcMcpTransportAlias } from \"../../config/mcp-config-normalize.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Bundle\");\nimport { normalizeLowercaseStringOrEmpty } from \"../../utils/string-coerce.js\";\nimport { sanitizeForLog } from \"../../utils/sanitize-log.js\";\nimport {\n describeHttpMcpServerLaunchConfig,\n resolveHttpMcpServerLaunchConfig,\n type HttpMcpTransportType,\n} from \"./mcp-http.js\";\nimport {\n describeStdioMcpServerLaunchConfig,\n resolveStdioMcpServerLaunchConfig,\n} from \"./mcp-stdio.js\";\n\ntype ResolvedBaseMcpTransportConfig = {\n description: string;\n connectionTimeoutMs: number;\n};\n\nexport type ResolvedStdioMcpTransportConfig = ResolvedBaseMcpTransportConfig & {\n kind: \"stdio\";\n transportType: \"stdio\";\n command: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n};\n\nexport type ResolvedHttpMcpTransportConfig = ResolvedBaseMcpTransportConfig & {\n kind: \"http\";\n transportType: HttpMcpTransportType;\n url: string;\n headers?: Record<string, string>;\n};\n\nexport type ResolvedMcpTransportConfig =\n | ResolvedStdioMcpTransportConfig\n | ResolvedHttpMcpTransportConfig;\n\nconst DEFAULT_CONNECTION_TIMEOUT_MS = 30_000;\n\nfunction getConnectionTimeoutMs(rawServer: unknown): number {\n if (\n rawServer &&\n typeof rawServer === \"object\" &&\n typeof (rawServer as { connectionTimeoutMs?: unknown }).connectionTimeoutMs === \"number\" &&\n (rawServer as { connectionTimeoutMs: number }).connectionTimeoutMs > 0\n ) {\n return (rawServer as { connectionTimeoutMs: number }).connectionTimeoutMs;\n }\n return DEFAULT_CONNECTION_TIMEOUT_MS;\n}\n\nfunction getRequestedTransport(rawServer: unknown): string {\n if (\n !rawServer ||\n typeof rawServer !== \"object\" ||\n typeof (rawServer as { transport?: unknown }).transport !== \"string\"\n ) {\n return \"\";\n }\n return normalizeLowercaseStringOrEmpty((rawServer as { transport?: string }).transport);\n}\n\nfunction getRequestedTransportAlias(rawServer: unknown): HttpMcpTransportType | \"\" {\n if (\n !rawServer ||\n typeof rawServer !== \"object\" ||\n typeof (rawServer as { type?: unknown }).type !== \"string\"\n ) {\n return \"\";\n }\n return resolveXopcMcpTransportAlias((rawServer as { type?: string }).type) ?? \"\";\n}\n\nfunction resolveHttpTransportConfig(\n serverName: string,\n rawServer: unknown,\n transportType: HttpMcpTransportType,\n): ResolvedHttpMcpTransportConfig | null {\n const launch = resolveHttpMcpServerLaunchConfig(rawServer, {\n transportType,\n onDroppedHeader: (key) => {\n log.warn(\n {\n phase: 'agent.mcp_connect',\n serverName,\n header: key,\n },\n `bundle-mcp: server \"${serverName}\": header \"${key}\" has an unsupported value type and was ignored`,\n );\n },\n onMalformedHeaders: () => {\n log.warn(\n { phase: 'agent.mcp_connect', serverName },\n `bundle-mcp: server \"${serverName}\": \"headers\" must be a JSON object; the value was ignored`,\n );\n },\n });\n if (!launch.ok) {\n return null;\n }\n return {\n kind: \"http\",\n transportType: launch.config.transportType,\n url: launch.config.url,\n headers: launch.config.headers,\n description: describeHttpMcpServerLaunchConfig(launch.config),\n connectionTimeoutMs: getConnectionTimeoutMs(rawServer),\n };\n}\n\nexport function resolveMcpTransportConfig(\n serverName: string,\n rawServer: unknown,\n): ResolvedMcpTransportConfig | null {\n const logServerName = sanitizeForLog(serverName);\n const requestedTransport = getRequestedTransport(rawServer);\n const requestedTransportAlias = requestedTransport ? \"\" : getRequestedTransportAlias(rawServer);\n const effectiveTransport = requestedTransport || requestedTransportAlias;\n const stdioLaunch = resolveStdioMcpServerLaunchConfig(rawServer, {\n onDroppedEnv: (key) => {\n log.warn(\n `bundle-mcp: server \"${logServerName}\": env \"${sanitizeForLog(key)}\" is blocked for stdio startup safety and was ignored.`,\n );\n },\n });\n if (stdioLaunch.ok) {\n return {\n kind: \"stdio\",\n transportType: \"stdio\",\n command: stdioLaunch.config.command,\n args: stdioLaunch.config.args,\n env: stdioLaunch.config.env,\n cwd: stdioLaunch.config.cwd,\n description: describeStdioMcpServerLaunchConfig(stdioLaunch.config),\n connectionTimeoutMs: getConnectionTimeoutMs(rawServer),\n };\n }\n\n if (\n effectiveTransport &&\n effectiveTransport !== \"sse\" &&\n effectiveTransport !== \"streamable-http\"\n ) {\n log.warn(\n `bundle-mcp: skipped server \"${logServerName}\" because transport \"${sanitizeForLog(effectiveTransport)}\" is not supported.`,\n );\n return null;\n }\n\n const httpTransport = resolveHttpTransportConfig(\n serverName,\n rawServer,\n effectiveTransport === \"sse\" ? \"sse\" : \"streamable-http\",\n );\n if (httpTransport) {\n return httpTransport;\n }\n\n const stdioReason =\n stdioLaunch.ok === false ? stdioLaunch.reason : 'not a stdio server';\n const httpLaunch = resolveHttpMcpServerLaunchConfig(rawServer);\n const httpReason =\n httpLaunch.ok === false ? httpLaunch.reason : 'not an HTTP MCP server';\n log.warn(\n `bundle-mcp: skipped server \"${logServerName}\" because ${stdioReason} and ${httpReason}.`,\n );\n return null;\n}\n"],"mappings":";;;;;;;;aACqD;oBAE0B;AAD/E,MAAM,MAAM,aAAa,aAAa;AAsCtC,MAAM,gCAAgC;AAEtC,SAAS,uBAAuB,WAA4B;AAC1D,KACE,aACA,OAAO,cAAc,YACrB,OAAQ,UAAgD,wBAAwB,YAC/E,UAA8C,sBAAsB,EAErE,QAAQ,UAA8C;AAExD,QAAO;;AAGT,SAAS,sBAAsB,WAA4B;AACzD,KACE,CAAC,aACD,OAAO,cAAc,YACrB,OAAQ,UAAsC,cAAc,SAE5D,QAAO;AAET,QAAO,gCAAiC,UAAqC,UAAU;;AAGzF,SAAS,2BAA2B,WAA+C;AACjF,KACE,CAAC,aACD,OAAO,cAAc,YACrB,OAAQ,UAAiC,SAAS,SAElD,QAAO;AAET,QAAO,6BAA8B,UAAgC,KAAK,IAAI;;AAGhF,SAAS,2BACP,YACA,WACA,eACuC;CACvC,MAAM,SAAS,iCAAiC,WAAW;EACzD;EACA,kBAAkB,QAAQ;AACxB,OAAI,KACF;IACE,OAAO;IACP;IACA,QAAQ;IACT,EACD,uBAAuB,WAAW,aAAa,IAAI,iDACpD;;EAEH,0BAA0B;AACxB,OAAI,KACF;IAAE,OAAO;IAAqB;IAAY,EAC1C,uBAAuB,WAAW,2DACnC;;EAEJ,CAAC;AACF,KAAI,CAAC,OAAO,GACV,QAAO;AAET,QAAO;EACL,MAAM;EACN,eAAe,OAAO,OAAO;EAC7B,KAAK,OAAO,OAAO;EACnB,SAAS,OAAO,OAAO;EACvB,aAAa,kCAAkC,OAAO,OAAO;EAC7D,qBAAqB,uBAAuB,UAAU;EACvD;;AAGH,SAAgB,0BACd,YACA,WACmC;CACnC,MAAM,gBAAgB,eAAe,WAAW;CAChD,MAAM,qBAAqB,sBAAsB,UAAU;CAC3D,MAAM,0BAA0B,qBAAqB,KAAK,2BAA2B,UAAU;CAC/F,MAAM,qBAAqB,sBAAsB;CACjD,MAAM,cAAc,kCAAkC,WAAW,EAC/D,eAAe,QAAQ;AACrB,MAAI,KACF,uBAAuB,cAAc,UAAU,eAAe,IAAI,CAAC,wDACpE;IAEJ,CAAC;AACF,KAAI,YAAY,GACd,QAAO;EACL,MAAM;EACN,eAAe;EACf,SAAS,YAAY,OAAO;EAC5B,MAAM,YAAY,OAAO;EACzB,KAAK,YAAY,OAAO;EACxB,KAAK,YAAY,OAAO;EACxB,aAAa,mCAAmC,YAAY,OAAO;EACnE,qBAAqB,uBAAuB,UAAU;EACvD;AAGH,KACE,sBACA,uBAAuB,SACvB,uBAAuB,mBACvB;AACA,MAAI,KACF,+BAA+B,cAAc,uBAAuB,eAAe,mBAAmB,CAAC,qBACxG;AACD,SAAO;;CAGT,MAAM,gBAAgB,2BACpB,YACA,WACA,uBAAuB,QAAQ,QAAQ,kBACxC;AACD,KAAI,cACF,QAAO;CAGT,MAAM,cACJ,YAAY,OAAO,QAAQ,YAAY,SAAS;CAClD,MAAM,aAAa,iCAAiC,UAAU;CAC9D,MAAM,aACJ,WAAW,OAAO,QAAQ,WAAW,SAAS;AAChD,KAAI,KACF,+BAA+B,cAAc,YAAY,YAAY,OAAO,WAAW,GACxF;AACD,QAAO"}
@@ -3,9 +3,10 @@ import { BUILTIN_WORKFLOWS } from "./builtins/index.js";
3
3
  import { parseWorkflowScript } from "./parser.js";
4
4
  import { createWorkflowCatalog, defaultUserDir } from "./catalog.js";
5
5
  import { _resetLastWorkflowMemoryForTests, getLastWorkflowMemory } from "./last-run-memory.js";
6
- import { emptySnapshotFor, runWorkflow } from "./runtime.js";
6
+ import { emptySnapshotFor } from "./snapshot-empty.js";
7
7
  import { createWorkflowSnapshot, previewValue, recomputeCounts, renderWorkflowText } from "./snapshot.js";
8
8
  import { WorkflowProgressBroker, _resetWorkflowProgressBrokerForTests, getWorkflowProgressBroker } from "./progress-broker.js";
9
+ import { runWorkflow } from "./runtime.js";
9
10
  import { STRUCTURED_OUTPUT_TOOL_NAME, createStructuredOutputTool } from "./structured-output-tool.js";
10
11
  import { DelegateSubagentRunner } from "./subagent-runner.js";
11
12
  export { BUILTIN_WORKFLOWS, DelegateSubagentRunner, STRUCTURED_OUTPUT_TOOL_NAME, WorkflowProgressBroker, _resetLastWorkflowMemoryForTests, _resetWorkflowProgressBrokerForTests, applySubagentProgress, createStructuredOutputTool, createWorkflowCatalog, createWorkflowSnapshot, defaultUserDir, emptySnapshotFor, getLastWorkflowMemory, getWorkflowProgressBroker, parseWorkflowScript, previewValue, recomputeCounts, renderWorkflowText, runWorkflow };
@@ -24,11 +24,11 @@
24
24
  * means the workflow tool, tests, and any future runner share one runtime.
25
25
  */
26
26
  import type { Api, Model } from '@earendil-works/pi-ai';
27
- import type { SubagentRunner, WorkflowRunOptions, WorkflowRunResult, WorkflowSnapshot } from './types.js';
27
+ import type { SubagentRunner, WorkflowRunOptions, WorkflowRunResult } from './types.js';
28
28
  export interface RunWorkflowDeps {
29
29
  runner: SubagentRunner;
30
30
  /** Resolve a model ref (`provider/model` or configured typed id) to a {@link Model}. Throws on unknown ref. */
31
31
  resolveModelId?: (modelId: string) => Model<Api>;
32
32
  }
33
33
  export declare function runWorkflow<T = unknown>(script: string, deps: RunWorkflowDeps, options: WorkflowRunOptions): Promise<WorkflowRunResult<T>>;
34
- export declare function emptySnapshotFor(name: string, description?: string, phaseTitles?: string[]): WorkflowSnapshot;
34
+ export { emptySnapshotFor } from './snapshot-empty.js';
@@ -1,4 +1,5 @@
1
1
  import { parseWorkflowScript } from "./parser.js";
2
+ import { emptySnapshotFor } from "./snapshot-empty.js";
2
3
  import { availableParallelism } from "node:os";
3
4
  import { Script, createContext } from "node:vm";
4
5
  //#region src/agent/workflow/runtime.ts
@@ -236,20 +237,6 @@ async function runWorkflow(script, deps, options) {
236
237
  durationMs: Date.now() - started
237
238
  };
238
239
  }
239
- function emptySnapshotFor(name, description, phaseTitles) {
240
- return {
241
- name,
242
- description,
243
- phases: phaseTitles ? [...phaseTitles] : [],
244
- logs: [],
245
- agents: [],
246
- agentCount: 0,
247
- runningCount: 0,
248
- doneCount: 0,
249
- errorCount: 0,
250
- skippedCount: 0
251
- };
252
- }
253
240
  function clampConcurrency(requested) {
254
241
  if (typeof requested === "number" && Number.isFinite(requested) && requested >= 1) return Math.min(Math.floor(requested), DEFAULT_CONCURRENCY_CEILING);
255
242
  let cpu = DEFAULT_CONCURRENCY_CEILING;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","names":[],"sources":["../../../../src/agent/workflow/runtime.ts"],"sourcesContent":["/**\n * Sandboxed workflow runtime.\n *\n * Parses the script via {@link parseWorkflowScript} (which strips the `meta`\n * export), wraps the remaining body in an async IIFE, and runs it inside a\n * Node `vm` context with a curated set of globals:\n *\n * - `agent(prompt, opts)` — spawns a subagent through the injected\n * {@link SubagentRunner} and returns its result (string, or schema-validated\n * object). Failures resolve to `null`.\n * - `parallel(thunks)` — concurrent fan-out; thunks (not promises!) so the\n * limiter sees each agent() call.\n * - `pipeline(items, ...stages)` — per-item sequential stages, items run\n * concurrently (no stage barrier). Each stage receives\n * `(prevResult, originalItem, index)`. A stage that throws drops that item\n * to `null` and skips remaining stages.\n * - `phase(title)` — marks the current phase; surfaces through `onPhase`.\n * - `log(message)` — appends to the workflow log.\n * - `budget` — `{ total, spent(), remaining() }` for self-pacing scripts.\n * - `args`, `cwd`, `process.cwd()`.\n *\n * The runtime is the only code that touches `vm`. It exposes no IO surface,\n * carries no LLM dependency, and is fully driven by injected callbacks — that\n * means the workflow tool, tests, and any future runner share one runtime.\n */\n\nimport { availableParallelism } from 'node:os';\nimport { createContext, Script } from 'node:vm';\n\nimport type { Api, Model } from '@earendil-works/pi-ai';\n\nimport { parseWorkflowScript } from './parser.js';\nimport type {\n AgentScriptOptions,\n SubagentRunner,\n WorkflowMetaPhase,\n WorkflowRunOptions,\n WorkflowRunResult,\n WorkflowSnapshot,\n WorkflowAgentStatus,\n} from './types.js';\n\nconst DEFAULT_CONCURRENCY_FLOOR = 1;\nconst DEFAULT_CONCURRENCY_CEILING = 16;\nconst DEFAULT_MAX_SUBAGENTS = 1000;\n\ninterface RuntimeState {\n currentPhase?: string;\n logs: string[];\n phases: string[];\n agentCount: number;\n spent: number;\n}\n\nexport interface RunWorkflowDeps {\n runner: SubagentRunner;\n /** Resolve a model ref (`provider/model` or configured typed id) to a {@link Model}. Throws on unknown ref. */\n resolveModelId?: (modelId: string) => Model<Api>;\n}\n\nexport async function runWorkflow<T = unknown>(\n script: string,\n deps: RunWorkflowDeps,\n options: WorkflowRunOptions,\n): Promise<WorkflowRunResult<T>> {\n const started = Date.now();\n const { meta, body } = parseWorkflowScript(script);\n\n const state: RuntimeState = { logs: [], phases: [], agentCount: 0, spent: 0 };\n const concurrency = clampConcurrency(options.concurrency);\n const maxSubagents = Math.max(1, options.maxSubagents ?? DEFAULT_MAX_SUBAGENTS);\n const limiter = createLimiter(concurrency);\n const pendingAgentRuns = new Set<Promise<unknown>>();\n const phaseDefaultModels = buildPhaseModelMap(meta.phases);\n\n const log = (message: unknown) => {\n const text = String(message);\n state.logs.push(text);\n options.onLog?.(text);\n };\n\n const phase = (title: unknown) => {\n const text = requireString(title, 'phase title');\n state.currentPhase = text;\n if (!state.phases.includes(text)) state.phases.push(text);\n options.onPhase?.(text);\n };\n\n const budget = Object.freeze({\n total: options.tokenBudget ?? null,\n spent: () => state.spent,\n remaining: () =>\n options.tokenBudget == null\n ? Number.POSITIVE_INFINITY\n : Math.max(0, options.tokenBudget - state.spent),\n });\n\n const throwIfAborted = () => {\n if (options.signal?.aborted) throw new Error('workflow aborted');\n };\n\n const resolveAgentModel = (\n normalized: AgentScriptOptions,\n assignedPhase: string | undefined,\n ): Model<Api> | undefined => {\n const realId = normalized.model?.trim();\n if (realId) {\n if (!deps.resolveModelId) {\n throw new Error('workflow runtime missing resolveModelId; cannot resolve real model id');\n }\n return deps.resolveModelId(realId);\n }\n if (assignedPhase) {\n const phaseRef = phaseDefaultModels.get(assignedPhase);\n if (phaseRef) {\n if (!deps.resolveModelId) return undefined;\n return deps.resolveModelId(phaseRef);\n }\n }\n return undefined;\n };\n\n const agent = async (prompt: unknown, agentOptions: unknown = {}) => {\n throwIfAborted();\n if (budget.total !== null && budget.remaining() <= 0) {\n throw new Error('workflow token budget exhausted');\n }\n if (state.agentCount >= maxSubagents) {\n throw new Error(`workflow agent quota exhausted (max ${maxSubagents})`);\n }\n\n const taskPrompt = requireString(prompt, 'agent prompt');\n const normalized = normalizeAgentOptions(agentOptions);\n const assignedPhase = normalized.phase ?? state.currentPhase;\n const requestedLabel = normalized.label?.trim();\n\n state.agentCount += 1;\n const id = state.agentCount;\n const label = requestedLabel || defaultAgentLabel(assignedPhase, id);\n options.onAgentQueued?.({ id, label, phase: assignedPhase, prompt: taskPrompt });\n\n const runPromise = limiter(async () => {\n options.onAgentStart?.({ id, label, phase: assignedPhase, prompt: taskPrompt });\n\n try {\n throwIfAborted();\n const resolvedModel = resolveAgentModel(normalized, assignedPhase);\n const enhanced = options.enhanceSubagentRun?.({\n id,\n label,\n phase: assignedPhase,\n prompt: taskPrompt,\n });\n const result = await deps.runner.run<unknown>(taskPrompt, {\n label,\n schema: normalized.schema,\n allowedToolNames: normalized.toolset,\n maxIterations: normalized.maxIterations,\n phase: assignedPhase,\n signal: options.signal,\n model: resolvedModel,\n ...enhanced,\n });\n throwIfAborted();\n\n const status: WorkflowAgentStatus = result === null ? 'error' : 'done';\n state.spent += estimateTokens(result);\n options.onAgentEnd?.({ id, label, phase: assignedPhase, result, status });\n return result;\n } catch (e) {\n if (options.signal?.aborted) {\n options.onAgentEnd?.({ id, label, phase: assignedPhase, result: null, status: 'skipped' });\n throw e;\n }\n const message = e instanceof Error ? e.message : String(e);\n log(`agent ${label} failed: ${message}`);\n options.onAgentEnd?.({ id, label, phase: assignedPhase, result: null, status: 'error' });\n return null;\n }\n });\n\n pendingAgentRuns.add(runPromise);\n // `then` (not `finally`) keeps the bookkeeping promise from re-throwing into\n // the unhandled-rejection channel when `runPromise` rejects on abort.\n runPromise.then(\n () => pendingAgentRuns.delete(runPromise),\n () => pendingAgentRuns.delete(runPromise),\n );\n return runPromise;\n };\n\n const parallel = async (thunks: unknown) => {\n throwIfAborted();\n if (!Array.isArray(thunks)) throw new TypeError('parallel() expects an array of functions');\n for (const t of thunks) {\n if (typeof t !== 'function') {\n throw new TypeError(\n 'parallel() expects an array of functions, not promises. Wrap each call: () => agent(...)',\n );\n }\n }\n return Promise.all(\n thunks.map(async (thunk, index) => {\n try {\n return await (thunk as () => unknown)();\n } catch (e) {\n if (options.signal?.aborted) throw e;\n const message = e instanceof Error ? e.message : String(e);\n log(`parallel[${index}] failed: ${message}`);\n return null;\n }\n }),\n );\n };\n\n const pipeline = async (items: unknown, ...stages: Array<unknown>) => {\n throwIfAborted();\n if (!Array.isArray(items)) {\n throw new TypeError('pipeline() expects an array as the first argument');\n }\n for (const stage of stages) {\n if (typeof stage !== 'function') {\n throw new TypeError(\n 'pipeline() stages must be functions: pipeline(items, item => ..., result => ...)',\n );\n }\n }\n const typedStages = stages as Array<\n (prev: unknown, original: unknown, index: number) => unknown\n >;\n return Promise.all(\n items.map(async (item, index) => {\n let value: unknown = item;\n for (const stage of typedStages) {\n try {\n throwIfAborted();\n value = await stage(value, item, index);\n throwIfAborted();\n } catch (e) {\n if (options.signal?.aborted) throw e;\n const message = e instanceof Error ? e.message : String(e);\n log(`pipeline[${index}] failed: ${message}`);\n return null;\n }\n }\n return value;\n }),\n );\n };\n\n const context = createContext({\n agent,\n parallel,\n pipeline,\n log,\n phase,\n args: options.args,\n cwd: options.cwd,\n process: Object.freeze({ cwd: () => options.cwd }),\n budget,\n console: {\n log,\n info: log,\n warn: (m: unknown) => log(`[warn] ${String(m)}`),\n error: (m: unknown) => log(`[error] ${String(m)}`),\n },\n JSON,\n Math,\n Array,\n Object,\n String,\n Number,\n Boolean,\n Set,\n Map,\n Promise,\n });\n\n const wrapped = `(async () => {\\n${body}\\n})()`;\n const script$ = new Script(wrapped, { filename: `${meta.name}.workflow.js` });\n\n let result: unknown;\n try {\n result = await script$.runInContext(context);\n // Wait for any agent() runs the script forgot to await before declaring success.\n await Promise.allSettled([...pendingAgentRuns]);\n } catch (e) {\n // Drain pending agent calls before propagating, so the snapshot reflects final state.\n await Promise.allSettled([...pendingAgentRuns]);\n throw rewriteScriptError(e);\n }\n\n assertStructuredCloneable(result, 'workflow result');\n\n return {\n meta,\n result: result as T,\n logs: state.logs,\n phases: state.phases,\n agentCount: state.agentCount,\n durationMs: Date.now() - started,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Initial snapshot helper — kept here so the runtime is the single source of\n// truth for \"what a fresh snapshot looks like for this workflow\".\n// ---------------------------------------------------------------------------\n\nexport function emptySnapshotFor(\n name: string,\n description?: string,\n phaseTitles?: string[],\n): WorkflowSnapshot {\n return {\n name,\n description,\n phases: phaseTitles ? [...phaseTitles] : [],\n logs: [],\n agents: [],\n agentCount: 0,\n runningCount: 0,\n doneCount: 0,\n errorCount: 0,\n skippedCount: 0,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internals\n// ---------------------------------------------------------------------------\n\nfunction clampConcurrency(requested?: number): number {\n if (typeof requested === 'number' && Number.isFinite(requested) && requested >= 1) {\n return Math.min(Math.floor(requested), DEFAULT_CONCURRENCY_CEILING);\n }\n let cpu = DEFAULT_CONCURRENCY_CEILING;\n try {\n cpu = availableParallelism();\n } catch {\n // Some sandboxes throw; fall back to the ceiling.\n }\n return Math.max(DEFAULT_CONCURRENCY_FLOOR, Math.min(DEFAULT_CONCURRENCY_CEILING, cpu - 2));\n}\n\nfunction createLimiter(limit: number) {\n let active = 0;\n const queue: Array<() => void> = [];\n const next = () => {\n active -= 1;\n const resume = queue.shift();\n if (resume) resume();\n };\n return async <T>(fn: () => Promise<T>): Promise<T> => {\n if (active >= limit) {\n await new Promise<void>((resolve) => queue.push(resolve));\n }\n active += 1;\n try {\n return await fn();\n } finally {\n next();\n }\n };\n}\n\nfunction buildPhaseModelMap(phases: WorkflowMetaPhase[] | undefined): Map<string, string> {\n const out = new Map<string, string>();\n if (!phases) return out;\n for (const p of phases) {\n if (p && typeof p.title === 'string' && typeof p.model === 'string' && p.model.trim()) {\n out.set(p.title, p.model.trim());\n }\n }\n return out;\n}\n\nfunction requireString(value: unknown, name: string): string {\n if (typeof value !== 'string') throw new TypeError(`${name} must be a string`);\n return value;\n}\n\nfunction optionalString(value: unknown, name: string): string | undefined {\n if (value === undefined) return undefined;\n return requireString(value, name);\n}\n\nfunction normalizeAgentOptions(value: unknown): AgentScriptOptions {\n if (value === undefined || value === null) return {};\n if (typeof value !== 'object') throw new TypeError('agent options must be an object');\n const options = value as AgentScriptOptions;\n const toolset = options.toolset;\n if (toolset !== undefined) {\n if (!Array.isArray(toolset) || toolset.some((t) => typeof t !== 'string')) {\n throw new TypeError('agent toolset must be an array of strings');\n }\n }\n const maxIterations = options.maxIterations;\n if (maxIterations !== undefined) {\n if (typeof maxIterations !== 'number' || !Number.isFinite(maxIterations) || maxIterations < 1) {\n throw new TypeError('agent maxIterations must be a positive number');\n }\n }\n const modelStr = optionalString(options.model, 'agent model');\n return {\n label: optionalString(options.label, 'agent label'),\n phase: optionalString(options.phase, 'agent phase'),\n schema: options.schema,\n model: modelStr,\n toolset,\n maxIterations,\n };\n}\n\nfunction assertStructuredCloneable(value: unknown, name: string): void {\n try {\n structuredClone(value);\n } catch (e) {\n const promisePath = findPromisePath(value, '');\n if (promisePath !== null) {\n throw new Error(\n `${name} contains a Promise at \\`${promisePath || '<root>'}\\` — missing 'await' before parallel()/pipeline()/agent(). ` +\n `Async return auto-unwraps a bare Promise, but a Promise nested in an object/array is returned as-is.`,\n );\n }\n const detail = e instanceof Error ? ` ${e.message}` : '';\n throw new Error(\n `${name} must be structured-cloneable; did you forget to await agent(), parallel(), or pipeline()?${detail}`,\n );\n }\n}\n\n/**\n * Find the first Promise lurking in `value`, returning a JS-path like\n * \"results[0].pending\". Returns null when no Promise is found. Bounded\n * depth/breadth so it never explodes on weird user shapes.\n */\nfunction findPromisePath(value: unknown, path: string, depth = 0): string | null {\n if (depth > 4) return null;\n if (isThenable(value)) return path;\n if (Array.isArray(value)) {\n for (let i = 0; i < Math.min(value.length, 32); i++) {\n const inner = findPromisePath(value[i], `${path}[${i}]`, depth + 1);\n if (inner !== null) return inner;\n }\n return null;\n }\n if (value !== null && typeof value === 'object') {\n let count = 0;\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n if (count++ > 32) break;\n const inner = findPromisePath(child, path ? `${path}.${key}` : key, depth + 1);\n if (inner !== null) return inner;\n }\n }\n return null;\n}\n\nfunction isThenable(value: unknown): boolean {\n return (\n value !== null &&\n typeof value === 'object' &&\n typeof (value as { then?: unknown }).then === 'function'\n );\n}\n\n/**\n * Rewrite TypeErrors that look like \"called .map on a Promise\" with an\n * await-shaped hint. Static lint catches the obvious form at parse time;\n * this is the safety net for cases lint can't see (dynamic indirection,\n * values stashed in helper closures).\n */\nconst PROMISE_METHOD_ERROR =\n /\\.(map|filter|forEach|flat|flatMap|find|some|every|reduce|join|length|then)\\b is not a function/;\n\nfunction rewriteScriptError(error: unknown): Error {\n // VM-context errors aren't `instanceof` host classes (the vm has its own\n // global constructors), so check by name + duck-typing message.\n const asError = error as { name?: string; message?: string } | null | undefined;\n const isTypeError = asError?.name === 'TypeError' && typeof asError.message === 'string';\n if (!isTypeError) {\n return error instanceof Error ? error : new Error(String(error));\n }\n const message = (asError as { message: string }).message;\n if (!PROMISE_METHOD_ERROR.test(message)) {\n return error instanceof Error ? error : new Error(message);\n }\n return new Error(\n `${message}\\n\\nHint: parallel()/pipeline()/agent() return a Promise — 'await' the call before using its result.\\n` +\n ` ❌ const r = parallel(...); r.map(...)\\n` +\n ` ✅ const r = await parallel(...); r.map(...)`,\n );\n}\n\nfunction defaultAgentLabel(phase: string | undefined, index: number): string {\n return phase ? `${phase} agent ${index}` : `agent ${index}`;\n}\n\nfunction estimateTokens(value: unknown): number {\n if (value === null || value === undefined) return 0;\n try {\n return Math.ceil(JSON.stringify(value).length / 4);\n } catch {\n return Math.ceil(String(value).length / 4);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"runtime.js","names":[],"sources":["../../../../src/agent/workflow/runtime.ts"],"sourcesContent":["/**\n * Sandboxed workflow runtime.\n *\n * Parses the script via {@link parseWorkflowScript} (which strips the `meta`\n * export), wraps the remaining body in an async IIFE, and runs it inside a\n * Node `vm` context with a curated set of globals:\n *\n * - `agent(prompt, opts)` — spawns a subagent through the injected\n * {@link SubagentRunner} and returns its result (string, or schema-validated\n * object). Failures resolve to `null`.\n * - `parallel(thunks)` — concurrent fan-out; thunks (not promises!) so the\n * limiter sees each agent() call.\n * - `pipeline(items, ...stages)` — per-item sequential stages, items run\n * concurrently (no stage barrier). Each stage receives\n * `(prevResult, originalItem, index)`. A stage that throws drops that item\n * to `null` and skips remaining stages.\n * - `phase(title)` — marks the current phase; surfaces through `onPhase`.\n * - `log(message)` — appends to the workflow log.\n * - `budget` — `{ total, spent(), remaining() }` for self-pacing scripts.\n * - `args`, `cwd`, `process.cwd()`.\n *\n * The runtime is the only code that touches `vm`. It exposes no IO surface,\n * carries no LLM dependency, and is fully driven by injected callbacks — that\n * means the workflow tool, tests, and any future runner share one runtime.\n */\n\nimport { availableParallelism } from 'node:os';\nimport { createContext, Script } from 'node:vm';\n\nimport type { Api, Model } from '@earendil-works/pi-ai';\n\nimport { parseWorkflowScript } from './parser.js';\nimport type {\n AgentScriptOptions,\n SubagentRunner,\n WorkflowMetaPhase,\n WorkflowRunOptions,\n WorkflowRunResult,\n WorkflowAgentStatus,\n} from './types.js';\n\nconst DEFAULT_CONCURRENCY_FLOOR = 1;\nconst DEFAULT_CONCURRENCY_CEILING = 16;\nconst DEFAULT_MAX_SUBAGENTS = 1000;\n\ninterface RuntimeState {\n currentPhase?: string;\n logs: string[];\n phases: string[];\n agentCount: number;\n spent: number;\n}\n\nexport interface RunWorkflowDeps {\n runner: SubagentRunner;\n /** Resolve a model ref (`provider/model` or configured typed id) to a {@link Model}. Throws on unknown ref. */\n resolveModelId?: (modelId: string) => Model<Api>;\n}\n\nexport async function runWorkflow<T = unknown>(\n script: string,\n deps: RunWorkflowDeps,\n options: WorkflowRunOptions,\n): Promise<WorkflowRunResult<T>> {\n const started = Date.now();\n const { meta, body } = parseWorkflowScript(script);\n\n const state: RuntimeState = { logs: [], phases: [], agentCount: 0, spent: 0 };\n const concurrency = clampConcurrency(options.concurrency);\n const maxSubagents = Math.max(1, options.maxSubagents ?? DEFAULT_MAX_SUBAGENTS);\n const limiter = createLimiter(concurrency);\n const pendingAgentRuns = new Set<Promise<unknown>>();\n const phaseDefaultModels = buildPhaseModelMap(meta.phases);\n\n const log = (message: unknown) => {\n const text = String(message);\n state.logs.push(text);\n options.onLog?.(text);\n };\n\n const phase = (title: unknown) => {\n const text = requireString(title, 'phase title');\n state.currentPhase = text;\n if (!state.phases.includes(text)) state.phases.push(text);\n options.onPhase?.(text);\n };\n\n const budget = Object.freeze({\n total: options.tokenBudget ?? null,\n spent: () => state.spent,\n remaining: () =>\n options.tokenBudget == null\n ? Number.POSITIVE_INFINITY\n : Math.max(0, options.tokenBudget - state.spent),\n });\n\n const throwIfAborted = () => {\n if (options.signal?.aborted) throw new Error('workflow aborted');\n };\n\n const resolveAgentModel = (\n normalized: AgentScriptOptions,\n assignedPhase: string | undefined,\n ): Model<Api> | undefined => {\n const realId = normalized.model?.trim();\n if (realId) {\n if (!deps.resolveModelId) {\n throw new Error('workflow runtime missing resolveModelId; cannot resolve real model id');\n }\n return deps.resolveModelId(realId);\n }\n if (assignedPhase) {\n const phaseRef = phaseDefaultModels.get(assignedPhase);\n if (phaseRef) {\n if (!deps.resolveModelId) return undefined;\n return deps.resolveModelId(phaseRef);\n }\n }\n return undefined;\n };\n\n const agent = async (prompt: unknown, agentOptions: unknown = {}) => {\n throwIfAborted();\n if (budget.total !== null && budget.remaining() <= 0) {\n throw new Error('workflow token budget exhausted');\n }\n if (state.agentCount >= maxSubagents) {\n throw new Error(`workflow agent quota exhausted (max ${maxSubagents})`);\n }\n\n const taskPrompt = requireString(prompt, 'agent prompt');\n const normalized = normalizeAgentOptions(agentOptions);\n const assignedPhase = normalized.phase ?? state.currentPhase;\n const requestedLabel = normalized.label?.trim();\n\n state.agentCount += 1;\n const id = state.agentCount;\n const label = requestedLabel || defaultAgentLabel(assignedPhase, id);\n options.onAgentQueued?.({ id, label, phase: assignedPhase, prompt: taskPrompt });\n\n const runPromise = limiter(async () => {\n options.onAgentStart?.({ id, label, phase: assignedPhase, prompt: taskPrompt });\n\n try {\n throwIfAborted();\n const resolvedModel = resolveAgentModel(normalized, assignedPhase);\n const enhanced = options.enhanceSubagentRun?.({\n id,\n label,\n phase: assignedPhase,\n prompt: taskPrompt,\n });\n const result = await deps.runner.run<unknown>(taskPrompt, {\n label,\n schema: normalized.schema,\n allowedToolNames: normalized.toolset,\n maxIterations: normalized.maxIterations,\n phase: assignedPhase,\n signal: options.signal,\n model: resolvedModel,\n ...enhanced,\n });\n throwIfAborted();\n\n const status: WorkflowAgentStatus = result === null ? 'error' : 'done';\n state.spent += estimateTokens(result);\n options.onAgentEnd?.({ id, label, phase: assignedPhase, result, status });\n return result;\n } catch (e) {\n if (options.signal?.aborted) {\n options.onAgentEnd?.({ id, label, phase: assignedPhase, result: null, status: 'skipped' });\n throw e;\n }\n const message = e instanceof Error ? e.message : String(e);\n log(`agent ${label} failed: ${message}`);\n options.onAgentEnd?.({ id, label, phase: assignedPhase, result: null, status: 'error' });\n return null;\n }\n });\n\n pendingAgentRuns.add(runPromise);\n // `then` (not `finally`) keeps the bookkeeping promise from re-throwing into\n // the unhandled-rejection channel when `runPromise` rejects on abort.\n runPromise.then(\n () => pendingAgentRuns.delete(runPromise),\n () => pendingAgentRuns.delete(runPromise),\n );\n return runPromise;\n };\n\n const parallel = async (thunks: unknown) => {\n throwIfAborted();\n if (!Array.isArray(thunks)) throw new TypeError('parallel() expects an array of functions');\n for (const t of thunks) {\n if (typeof t !== 'function') {\n throw new TypeError(\n 'parallel() expects an array of functions, not promises. Wrap each call: () => agent(...)',\n );\n }\n }\n return Promise.all(\n thunks.map(async (thunk, index) => {\n try {\n return await (thunk as () => unknown)();\n } catch (e) {\n if (options.signal?.aborted) throw e;\n const message = e instanceof Error ? e.message : String(e);\n log(`parallel[${index}] failed: ${message}`);\n return null;\n }\n }),\n );\n };\n\n const pipeline = async (items: unknown, ...stages: Array<unknown>) => {\n throwIfAborted();\n if (!Array.isArray(items)) {\n throw new TypeError('pipeline() expects an array as the first argument');\n }\n for (const stage of stages) {\n if (typeof stage !== 'function') {\n throw new TypeError(\n 'pipeline() stages must be functions: pipeline(items, item => ..., result => ...)',\n );\n }\n }\n const typedStages = stages as Array<\n (prev: unknown, original: unknown, index: number) => unknown\n >;\n return Promise.all(\n items.map(async (item, index) => {\n let value: unknown = item;\n for (const stage of typedStages) {\n try {\n throwIfAborted();\n value = await stage(value, item, index);\n throwIfAborted();\n } catch (e) {\n if (options.signal?.aborted) throw e;\n const message = e instanceof Error ? e.message : String(e);\n log(`pipeline[${index}] failed: ${message}`);\n return null;\n }\n }\n return value;\n }),\n );\n };\n\n const context = createContext({\n agent,\n parallel,\n pipeline,\n log,\n phase,\n args: options.args,\n cwd: options.cwd,\n process: Object.freeze({ cwd: () => options.cwd }),\n budget,\n console: {\n log,\n info: log,\n warn: (m: unknown) => log(`[warn] ${String(m)}`),\n error: (m: unknown) => log(`[error] ${String(m)}`),\n },\n JSON,\n Math,\n Array,\n Object,\n String,\n Number,\n Boolean,\n Set,\n Map,\n Promise,\n });\n\n const wrapped = `(async () => {\\n${body}\\n})()`;\n const script$ = new Script(wrapped, { filename: `${meta.name}.workflow.js` });\n\n let result: unknown;\n try {\n result = await script$.runInContext(context);\n // Wait for any agent() runs the script forgot to await before declaring success.\n await Promise.allSettled([...pendingAgentRuns]);\n } catch (e) {\n // Drain pending agent calls before propagating, so the snapshot reflects final state.\n await Promise.allSettled([...pendingAgentRuns]);\n throw rewriteScriptError(e);\n }\n\n assertStructuredCloneable(result, 'workflow result');\n\n return {\n meta,\n result: result as T,\n logs: state.logs,\n phases: state.phases,\n agentCount: state.agentCount,\n durationMs: Date.now() - started,\n };\n}\n\nexport { emptySnapshotFor } from './snapshot-empty.js';\n\n// ---------------------------------------------------------------------------\n// Internals\n// ---------------------------------------------------------------------------\n\nfunction clampConcurrency(requested?: number): number {\n if (typeof requested === 'number' && Number.isFinite(requested) && requested >= 1) {\n return Math.min(Math.floor(requested), DEFAULT_CONCURRENCY_CEILING);\n }\n let cpu = DEFAULT_CONCURRENCY_CEILING;\n try {\n cpu = availableParallelism();\n } catch {\n // Some sandboxes throw; fall back to the ceiling.\n }\n return Math.max(DEFAULT_CONCURRENCY_FLOOR, Math.min(DEFAULT_CONCURRENCY_CEILING, cpu - 2));\n}\n\nfunction createLimiter(limit: number) {\n let active = 0;\n const queue: Array<() => void> = [];\n const next = () => {\n active -= 1;\n const resume = queue.shift();\n if (resume) resume();\n };\n return async <T>(fn: () => Promise<T>): Promise<T> => {\n if (active >= limit) {\n await new Promise<void>((resolve) => queue.push(resolve));\n }\n active += 1;\n try {\n return await fn();\n } finally {\n next();\n }\n };\n}\n\nfunction buildPhaseModelMap(phases: WorkflowMetaPhase[] | undefined): Map<string, string> {\n const out = new Map<string, string>();\n if (!phases) return out;\n for (const p of phases) {\n if (p && typeof p.title === 'string' && typeof p.model === 'string' && p.model.trim()) {\n out.set(p.title, p.model.trim());\n }\n }\n return out;\n}\n\nfunction requireString(value: unknown, name: string): string {\n if (typeof value !== 'string') throw new TypeError(`${name} must be a string`);\n return value;\n}\n\nfunction optionalString(value: unknown, name: string): string | undefined {\n if (value === undefined) return undefined;\n return requireString(value, name);\n}\n\nfunction normalizeAgentOptions(value: unknown): AgentScriptOptions {\n if (value === undefined || value === null) return {};\n if (typeof value !== 'object') throw new TypeError('agent options must be an object');\n const options = value as AgentScriptOptions;\n const toolset = options.toolset;\n if (toolset !== undefined) {\n if (!Array.isArray(toolset) || toolset.some((t) => typeof t !== 'string')) {\n throw new TypeError('agent toolset must be an array of strings');\n }\n }\n const maxIterations = options.maxIterations;\n if (maxIterations !== undefined) {\n if (typeof maxIterations !== 'number' || !Number.isFinite(maxIterations) || maxIterations < 1) {\n throw new TypeError('agent maxIterations must be a positive number');\n }\n }\n const modelStr = optionalString(options.model, 'agent model');\n return {\n label: optionalString(options.label, 'agent label'),\n phase: optionalString(options.phase, 'agent phase'),\n schema: options.schema,\n model: modelStr,\n toolset,\n maxIterations,\n };\n}\n\nfunction assertStructuredCloneable(value: unknown, name: string): void {\n try {\n structuredClone(value);\n } catch (e) {\n const promisePath = findPromisePath(value, '');\n if (promisePath !== null) {\n throw new Error(\n `${name} contains a Promise at \\`${promisePath || '<root>'}\\` — missing 'await' before parallel()/pipeline()/agent(). ` +\n `Async return auto-unwraps a bare Promise, but a Promise nested in an object/array is returned as-is.`,\n );\n }\n const detail = e instanceof Error ? ` ${e.message}` : '';\n throw new Error(\n `${name} must be structured-cloneable; did you forget to await agent(), parallel(), or pipeline()?${detail}`,\n );\n }\n}\n\n/**\n * Find the first Promise lurking in `value`, returning a JS-path like\n * \"results[0].pending\". Returns null when no Promise is found. Bounded\n * depth/breadth so it never explodes on weird user shapes.\n */\nfunction findPromisePath(value: unknown, path: string, depth = 0): string | null {\n if (depth > 4) return null;\n if (isThenable(value)) return path;\n if (Array.isArray(value)) {\n for (let i = 0; i < Math.min(value.length, 32); i++) {\n const inner = findPromisePath(value[i], `${path}[${i}]`, depth + 1);\n if (inner !== null) return inner;\n }\n return null;\n }\n if (value !== null && typeof value === 'object') {\n let count = 0;\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n if (count++ > 32) break;\n const inner = findPromisePath(child, path ? `${path}.${key}` : key, depth + 1);\n if (inner !== null) return inner;\n }\n }\n return null;\n}\n\nfunction isThenable(value: unknown): boolean {\n return (\n value !== null &&\n typeof value === 'object' &&\n typeof (value as { then?: unknown }).then === 'function'\n );\n}\n\n/**\n * Rewrite TypeErrors that look like \"called .map on a Promise\" with an\n * await-shaped hint. Static lint catches the obvious form at parse time;\n * this is the safety net for cases lint can't see (dynamic indirection,\n * values stashed in helper closures).\n */\nconst PROMISE_METHOD_ERROR =\n /\\.(map|filter|forEach|flat|flatMap|find|some|every|reduce|join|length|then)\\b is not a function/;\n\nfunction rewriteScriptError(error: unknown): Error {\n // VM-context errors aren't `instanceof` host classes (the vm has its own\n // global constructors), so check by name + duck-typing message.\n const asError = error as { name?: string; message?: string } | null | undefined;\n const isTypeError = asError?.name === 'TypeError' && typeof asError.message === 'string';\n if (!isTypeError) {\n return error instanceof Error ? error : new Error(String(error));\n }\n const message = (asError as { message: string }).message;\n if (!PROMISE_METHOD_ERROR.test(message)) {\n return error instanceof Error ? error : new Error(message);\n }\n return new Error(\n `${message}\\n\\nHint: parallel()/pipeline()/agent() return a Promise — 'await' the call before using its result.\\n` +\n ` ❌ const r = parallel(...); r.map(...)\\n` +\n ` ✅ const r = await parallel(...); r.map(...)`,\n );\n}\n\nfunction defaultAgentLabel(phase: string | undefined, index: number): string {\n return phase ? `${phase} agent ${index}` : `agent ${index}`;\n}\n\nfunction estimateTokens(value: unknown): number {\n if (value === null || value === undefined) return 0;\n try {\n return Math.ceil(JSON.stringify(value).length / 4);\n } catch {\n return Math.ceil(String(value).length / 4);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { WorkflowSnapshot } from './types.js';
2
+ export declare function emptySnapshotFor(name: string, description?: string, phaseTitles?: string[]): WorkflowSnapshot;
@@ -0,0 +1,19 @@
1
+ //#region src/agent/workflow/snapshot-empty.ts
2
+ function emptySnapshotFor(name, description, phaseTitles) {
3
+ return {
4
+ name,
5
+ description,
6
+ phases: phaseTitles ? [...phaseTitles] : [],
7
+ logs: [],
8
+ agents: [],
9
+ agentCount: 0,
10
+ runningCount: 0,
11
+ doneCount: 0,
12
+ errorCount: 0,
13
+ skippedCount: 0
14
+ };
15
+ }
16
+ //#endregion
17
+ export { emptySnapshotFor };
18
+
19
+ //# sourceMappingURL=snapshot-empty.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-empty.js","names":[],"sources":["../../../../src/agent/workflow/snapshot-empty.ts"],"sourcesContent":["import type { WorkflowSnapshot } from './types.js';\n\nexport function emptySnapshotFor(\n name: string,\n description?: string,\n phaseTitles?: string[],\n): WorkflowSnapshot {\n return {\n name,\n description,\n phases: phaseTitles ? [...phaseTitles] : [],\n logs: [],\n agents: [],\n agentCount: 0,\n runningCount: 0,\n doneCount: 0,\n errorCount: 0,\n skippedCount: 0,\n };\n}\n"],"mappings":";AAEA,SAAgB,iBACd,MACA,aACA,aACkB;AAClB,QAAO;EACL;EACA;EACA,QAAQ,cAAc,CAAC,GAAG,YAAY,GAAG,EAAE;EAC3C,MAAM,EAAE;EACR,QAAQ,EAAE;EACV,YAAY;EACZ,cAAc;EACd,WAAW;EACX,YAAY;EACZ,cAAc;EACf"}
@@ -1,4 +1,4 @@
1
- import { emptySnapshotFor } from "./runtime.js";
1
+ import { emptySnapshotFor } from "./snapshot-empty.js";
2
2
  //#region src/agent/workflow/snapshot.ts
3
3
  function createWorkflowSnapshot(meta) {
4
4
  return emptySnapshotFor(meta.name, meta.description, meta.phases?.map((p) => p.title));
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.js","names":[],"sources":["../../../../src/agent/workflow/snapshot.ts"],"sourcesContent":["/**\n * Workflow progress snapshot model + text renderers.\n *\n * The runtime emits per-event callbacks (`onPhase`, `onAgentStart`, `onAgentEnd`,\n * `onLog`). The workflow tool wraps those callbacks to mutate a snapshot and push\n * a text rendering through `onUpdate` — keeping TUI / Gateway / IM consumers in\n * lock-step from a single source of truth.\n */\n\nimport type {\n WorkflowAgentSnapshot,\n WorkflowAgentStatus,\n WorkflowMeta,\n WorkflowSnapshot,\n} from './types.js';\nimport { emptySnapshotFor } from './runtime.js';\n\nexport function createWorkflowSnapshot(meta: WorkflowMeta): WorkflowSnapshot {\n return emptySnapshotFor(\n meta.name,\n meta.description,\n meta.phases?.map((p) => p.title),\n );\n}\n\nexport function recomputeCounts(snapshot: WorkflowSnapshot): void {\n let running = 0;\n let done = 0;\n let error = 0;\n let skipped = 0;\n for (const agent of snapshot.agents) {\n switch (agent.status) {\n case 'running':\n running++;\n break;\n case 'done':\n done++;\n break;\n case 'error':\n error++;\n break;\n case 'skipped':\n skipped++;\n break;\n }\n }\n snapshot.agentCount = snapshot.agents.length;\n snapshot.runningCount = running;\n snapshot.doneCount = done;\n snapshot.errorCount = error;\n snapshot.skippedCount = skipped;\n}\n\nexport interface RenderOptions {\n maxAgentsPerPhase?: number;\n maxLogs?: number;\n showResultPreviews?: boolean;\n}\n\nexport function renderWorkflowText(\n snapshot: WorkflowSnapshot,\n completed = false,\n options: RenderOptions = {},\n): string {\n const maxAgentsPerPhase = options.maxAgentsPerPhase ?? 6;\n const maxLogs = options.maxLogs ?? 2;\n const showPreviews = options.showResultPreviews ?? false;\n\n const state = stateSuffix(snapshot);\n const header = completed\n ? `◆ workflow ✓ ${snapshot.name} (${snapshot.doneCount}/${snapshot.agentCount} done${state})`\n : `◆ workflow: ${snapshot.name} (${snapshot.doneCount}/${snapshot.agentCount} done${state})`;\n const lines = [header];\n\n const phaseNames = uniqueOrdered([\n ...snapshot.phases,\n ...(snapshot.currentPhase ? [snapshot.currentPhase] : []),\n ...snapshot.agents.map((a) => a.phase).filter((p): p is string => Boolean(p)),\n ]);\n const rendered = new Set<WorkflowAgentSnapshot>();\n\n for (const phase of phaseNames) {\n const agents = snapshot.agents.filter((a) => a.phase === phase);\n if (agents.length === 0 && snapshot.currentPhase !== phase) continue;\n for (const a of agents) rendered.add(a);\n\n const counts = countAgents(agents);\n const completeHere = agents.length > 0 && counts.done + counts.error + counts.skipped === agents.length;\n const marker =\n counts.running > 0 || (!completeHere && snapshot.currentPhase === phase)\n ? '▶'\n : completeHere\n ? '✓'\n : ' ';\n\n const tail =\n (counts.running ? ` · ${counts.running} running` : '') +\n (counts.error ? ` · ${counts.error} errors` : '') +\n (counts.skipped ? ` · ${counts.skipped} skipped` : '');\n lines.push(` ${marker} ${phase} ${counts.done}/${agents.length}${tail}`);\n\n const visible = agents.slice(-maxAgentsPerPhase);\n for (const agent of visible) {\n const previewText = showPreviews && agent.resultPreview ? ` — ${agent.resultPreview}` : '';\n lines.push(\n ` #${agent.id} ${statusIcon(agent.status)} ${shorten(agent.label, 56)}${previewText}`,\n );\n }\n if (agents.length > visible.length) {\n lines.push(` … ${agents.length - visible.length} earlier agents`);\n }\n }\n\n const unphased = snapshot.agents.filter((a) => !rendered.has(a));\n if (unphased.length > 0) {\n lines.push(' unphased');\n for (const agent of unphased.slice(-maxAgentsPerPhase)) {\n const previewText = showPreviews && agent.resultPreview ? ` — ${agent.resultPreview}` : '';\n lines.push(\n ` #${agent.id} ${statusIcon(agent.status)} ${shorten(agent.label, 56)}${previewText}`,\n );\n }\n }\n\n const visibleLogs = snapshot.logs.slice(-maxLogs);\n if (visibleLogs.length > 0) {\n lines.push('');\n for (const log of visibleLogs) {\n lines.push(` log: ${shorten(log, 80)}`);\n }\n }\n return lines.join('\\n');\n}\n\nexport function previewValue(value: unknown, max = 80): string {\n if (value === null || value === undefined) return '';\n const text = typeof value === 'string' ? value : safeStringify(value);\n if (!text) return '';\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\n// ---------------------------------------------------------------------------\n\nfunction countAgents(agents: WorkflowAgentSnapshot[]) {\n let done = 0;\n let running = 0;\n let error = 0;\n let skipped = 0;\n for (const a of agents) {\n if (a.status === 'done') done++;\n else if (a.status === 'running') running++;\n else if (a.status === 'error') error++;\n else if (a.status === 'skipped') skipped++;\n }\n return { done, running, error, skipped };\n}\n\nfunction statusIcon(status: WorkflowAgentStatus): string {\n switch (status) {\n case 'queued':\n return '○';\n case 'running':\n return '●';\n case 'done':\n return '✓';\n case 'error':\n return '✗';\n case 'skipped':\n return '-';\n }\n}\n\nfunction stateSuffix(snapshot: WorkflowSnapshot): string {\n if (snapshot.errorCount > 0) return `, ${snapshot.errorCount} errors`;\n if (snapshot.skippedCount > 0) return `, ${snapshot.skippedCount} skipped`;\n if (snapshot.runningCount > 0) return `, ${snapshot.runningCount} running`;\n return '';\n}\n\nfunction uniqueOrdered(values: string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const v of values) {\n if (!seen.has(v)) {\n seen.add(v);\n out.push(v);\n }\n }\n return out;\n}\n\nfunction shorten(value: string, max: number): string {\n const text = value.replace(/\\s+/g, ' ').trim();\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"snapshot.js","names":[],"sources":["../../../../src/agent/workflow/snapshot.ts"],"sourcesContent":["/**\n * Workflow progress snapshot model + text renderers.\n *\n * The runtime emits per-event callbacks (`onPhase`, `onAgentStart`, `onAgentEnd`,\n * `onLog`). The workflow tool wraps those callbacks to mutate a snapshot and push\n * a text rendering through `onUpdate` — keeping TUI / Gateway / IM consumers in\n * lock-step from a single source of truth.\n */\n\nimport type {\n WorkflowAgentSnapshot,\n WorkflowAgentStatus,\n WorkflowMeta,\n WorkflowSnapshot,\n} from './types.js';\nimport { emptySnapshotFor } from './snapshot-empty.js';\n\nexport function createWorkflowSnapshot(meta: WorkflowMeta): WorkflowSnapshot {\n return emptySnapshotFor(\n meta.name,\n meta.description,\n meta.phases?.map((p) => p.title),\n );\n}\n\nexport function recomputeCounts(snapshot: WorkflowSnapshot): void {\n let running = 0;\n let done = 0;\n let error = 0;\n let skipped = 0;\n for (const agent of snapshot.agents) {\n switch (agent.status) {\n case 'running':\n running++;\n break;\n case 'done':\n done++;\n break;\n case 'error':\n error++;\n break;\n case 'skipped':\n skipped++;\n break;\n }\n }\n snapshot.agentCount = snapshot.agents.length;\n snapshot.runningCount = running;\n snapshot.doneCount = done;\n snapshot.errorCount = error;\n snapshot.skippedCount = skipped;\n}\n\nexport interface RenderOptions {\n maxAgentsPerPhase?: number;\n maxLogs?: number;\n showResultPreviews?: boolean;\n}\n\nexport function renderWorkflowText(\n snapshot: WorkflowSnapshot,\n completed = false,\n options: RenderOptions = {},\n): string {\n const maxAgentsPerPhase = options.maxAgentsPerPhase ?? 6;\n const maxLogs = options.maxLogs ?? 2;\n const showPreviews = options.showResultPreviews ?? false;\n\n const state = stateSuffix(snapshot);\n const header = completed\n ? `◆ workflow ✓ ${snapshot.name} (${snapshot.doneCount}/${snapshot.agentCount} done${state})`\n : `◆ workflow: ${snapshot.name} (${snapshot.doneCount}/${snapshot.agentCount} done${state})`;\n const lines = [header];\n\n const phaseNames = uniqueOrdered([\n ...snapshot.phases,\n ...(snapshot.currentPhase ? [snapshot.currentPhase] : []),\n ...snapshot.agents.map((a) => a.phase).filter((p): p is string => Boolean(p)),\n ]);\n const rendered = new Set<WorkflowAgentSnapshot>();\n\n for (const phase of phaseNames) {\n const agents = snapshot.agents.filter((a) => a.phase === phase);\n if (agents.length === 0 && snapshot.currentPhase !== phase) continue;\n for (const a of agents) rendered.add(a);\n\n const counts = countAgents(agents);\n const completeHere = agents.length > 0 && counts.done + counts.error + counts.skipped === agents.length;\n const marker =\n counts.running > 0 || (!completeHere && snapshot.currentPhase === phase)\n ? '▶'\n : completeHere\n ? '✓'\n : ' ';\n\n const tail =\n (counts.running ? ` · ${counts.running} running` : '') +\n (counts.error ? ` · ${counts.error} errors` : '') +\n (counts.skipped ? ` · ${counts.skipped} skipped` : '');\n lines.push(` ${marker} ${phase} ${counts.done}/${agents.length}${tail}`);\n\n const visible = agents.slice(-maxAgentsPerPhase);\n for (const agent of visible) {\n const previewText = showPreviews && agent.resultPreview ? ` — ${agent.resultPreview}` : '';\n lines.push(\n ` #${agent.id} ${statusIcon(agent.status)} ${shorten(agent.label, 56)}${previewText}`,\n );\n }\n if (agents.length > visible.length) {\n lines.push(` … ${agents.length - visible.length} earlier agents`);\n }\n }\n\n const unphased = snapshot.agents.filter((a) => !rendered.has(a));\n if (unphased.length > 0) {\n lines.push(' unphased');\n for (const agent of unphased.slice(-maxAgentsPerPhase)) {\n const previewText = showPreviews && agent.resultPreview ? ` — ${agent.resultPreview}` : '';\n lines.push(\n ` #${agent.id} ${statusIcon(agent.status)} ${shorten(agent.label, 56)}${previewText}`,\n );\n }\n }\n\n const visibleLogs = snapshot.logs.slice(-maxLogs);\n if (visibleLogs.length > 0) {\n lines.push('');\n for (const log of visibleLogs) {\n lines.push(` log: ${shorten(log, 80)}`);\n }\n }\n return lines.join('\\n');\n}\n\nexport function previewValue(value: unknown, max = 80): string {\n if (value === null || value === undefined) return '';\n const text = typeof value === 'string' ? value : safeStringify(value);\n if (!text) return '';\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\n// ---------------------------------------------------------------------------\n\nfunction countAgents(agents: WorkflowAgentSnapshot[]) {\n let done = 0;\n let running = 0;\n let error = 0;\n let skipped = 0;\n for (const a of agents) {\n if (a.status === 'done') done++;\n else if (a.status === 'running') running++;\n else if (a.status === 'error') error++;\n else if (a.status === 'skipped') skipped++;\n }\n return { done, running, error, skipped };\n}\n\nfunction statusIcon(status: WorkflowAgentStatus): string {\n switch (status) {\n case 'queued':\n return '○';\n case 'running':\n return '●';\n case 'done':\n return '✓';\n case 'error':\n return '✗';\n case 'skipped':\n return '-';\n }\n}\n\nfunction stateSuffix(snapshot: WorkflowSnapshot): string {\n if (snapshot.errorCount > 0) return `, ${snapshot.errorCount} errors`;\n if (snapshot.skippedCount > 0) return `, ${snapshot.skippedCount} skipped`;\n if (snapshot.runningCount > 0) return `, ${snapshot.runningCount} running`;\n return '';\n}\n\nfunction uniqueOrdered(values: string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const v of values) {\n if (!seen.has(v)) {\n seen.add(v);\n out.push(v);\n }\n }\n return out;\n}\n\nfunction shorten(value: string, max: number): string {\n const text = value.replace(/\\s+/g, ' ').trim();\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { getConnectorInstance } from "./instances.js";
2
1
  import { createBundleMcpToolRuntime, mapBundleMcpToolsForGateway } from "../agent/mcp/bundle-mcp-materialize.js";
3
2
  import { getWorkspacePath } from "../config/workspace-path-helpers.js";
3
+ import { getConnectorInstance } from "./instances.js";
4
4
  //#region src/connectors/health.ts
5
5
  function classifyConnectorHealthError(error) {
6
6
  const message = error instanceof Error ? error.message : String(error);
@@ -1,6 +1,6 @@
1
1
  import { CredentialResolver, init_credentials } from "../auth/credentials.js";
2
- import { getConnectorDefinition } from "./catalog.js";
3
2
  import { saveConnectorSecrets } from "./secret-store.js";
3
+ import { getConnectorDefinition } from "./catalog.js";
4
4
  import { isManagedConnectorServer, materializeConnectorMcpServer } from "./materialize.js";
5
5
  import { appendConnectorAuditRecord } from "./usage.js";
6
6
  import { listConnectorInstances } from "./instances.js";