specrails-desktop 2.60.0 → 2.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/client/dist/assets/{ActivityFeedPage-3J7fR8yB.js → ActivityFeedPage-Wi5XNgoG.js} +1 -1
  2. package/client/dist/assets/{AgentBrowserCapture-D4a3wYM1.js → AgentBrowserCapture-CkNWDZT3.js} +1 -1
  3. package/client/dist/assets/{AgentModeAnalyticsPane-Dps30tk9.js → AgentModeAnalyticsPane-CXz2j-Bt.js} +2 -2
  4. package/client/dist/assets/{AgentModeCodePane-CvLimey8.js → AgentModeCodePane-DnsBPtpS.js} +2 -2
  5. package/client/dist/assets/{AgentModeJobsPane-25tQlLpF.js → AgentModeJobsPane-U1J6PaBo.js} +1 -1
  6. package/client/dist/assets/{AgentsPage-CUDp_sfw.js → AgentsPage-CXrqu5vo.js} +1 -1
  7. package/client/dist/assets/{AnalyticsPage-DXWMGn8b.js → AnalyticsPage-Cvtt-LOO.js} +1 -1
  8. package/client/dist/assets/{CodePage-D981zRHy.js → CodePage-D35o-MFO.js} +1 -1
  9. package/client/dist/assets/{DesktopAnalyticsPage-BkFBq0E6.js → DesktopAnalyticsPage-CsDFy5rp.js} +1 -1
  10. package/client/dist/assets/{DocsDialog-BL7uSbIJ.js → DocsDialog-CSlMPemn.js} +1 -1
  11. package/client/dist/assets/{DocsPage-CsDLbmZX.js → DocsPage-BKlYAvWq.js} +1 -1
  12. package/client/dist/assets/{ExportDropdown-B4Olg1Fk.js → ExportDropdown-CweP_1GP.js} +1 -1
  13. package/client/dist/assets/InteractiveJobComposer-CFKvbQeJ.js +19 -0
  14. package/client/dist/assets/{JobDetailModal-DS_Owxs6.js → JobDetailModal-DYyGq1Vp.js} +1 -1
  15. package/client/dist/assets/{JobDetailPage-1TUQ9vlE.js → JobDetailPage-C6gpdYvj.js} +1 -1
  16. package/client/dist/assets/{JobsPage-BSrl8P7u.js → JobsPage-CgS0pnKd.js} +1 -1
  17. package/client/dist/assets/LoopBuilderPage-jUp20DSZ.js +1 -0
  18. package/client/dist/assets/{LoopPreviewModal-CH1r-KhU.js → LoopPreviewModal-DkLRfsYX.js} +1 -1
  19. package/client/dist/assets/{LoopWindowSurface-CiZdI6aw.js → LoopWindowSurface-CuACkXFV.js} +1 -1
  20. package/client/dist/assets/{LoopsPage-BwFujdGi.js → LoopsPage-ClSrWzDd.js} +1 -1
  21. package/client/dist/assets/{MinimizedChatsContext-BD2bsRBe.js → MinimizedChatsContext-CroAs6Kh.js} +1 -1
  22. package/client/dist/assets/{PluginsPage-B8f49Mvn.js → PluginsPage-nCKQOwRL.js} +1 -1
  23. package/client/dist/assets/{ProjectSettingsDialog-D7q-O6h3.js → ProjectSettingsDialog-BVDYwllU.js} +1 -1
  24. package/client/dist/assets/{RepositoryDeliveries-NNorcGzT.js → RepositoryDeliveries-DJCm1pZr.js} +1 -1
  25. package/client/dist/assets/{RepositoryScopeSelector-D-jb4bI_.js → RepositoryScopeSelector-CeCr6Jz-.js} +1 -1
  26. package/client/dist/assets/{ReviewPacketPage-DpZSzF-Q.js → ReviewPacketPage-kTErrEjx.js} +1 -1
  27. package/client/dist/assets/{TemplatePreviewModal-5CZdAZ0G.js → TemplatePreviewModal-B8yd1AGU.js} +1 -1
  28. package/client/dist/assets/{TicketDetailModalContext-BHmtj1As.js → TicketDetailModalContext-YBJX3RmP.js} +1 -1
  29. package/client/dist/assets/{Trans-wmTUDVyC.js → Trans-D5eOjfvG.js} +1 -1
  30. package/client/dist/assets/agentRuntime-B-myNBUP.js +1 -0
  31. package/client/dist/assets/agentRuntime-Bjt7Ij6_.js +1 -0
  32. package/client/dist/assets/agentRuntime-C_yLPKDy.js +1 -0
  33. package/client/dist/assets/agentRuntime-D2kYQqNO.js +1 -0
  34. package/client/dist/assets/agentRuntime-DvhEe1um.js +1 -0
  35. package/client/dist/assets/agentRuntime-DxC6-9rN.js +1 -0
  36. package/client/dist/assets/agentRuntime-TKQyg137.js +1 -0
  37. package/client/dist/assets/agentRuntime-WSv8G0pW.js +1 -0
  38. package/client/dist/assets/{formatDistanceToNow-Dax4zqPF.js → formatDistanceToNow-DZ3VWsHq.js} +1 -1
  39. package/client/dist/assets/{getTimezoneOffsetInMilliseconds-dpIo42JZ.js → getTimezoneOffsetInMilliseconds-9JiGlFrx.js} +1 -1
  40. package/client/dist/assets/{index-g8S62tpS.js → index-lTGJJTuk.js} +8 -8
  41. package/client/dist/assets/{jira-api-CLrIvXFm.js → jira-api-Bp0zXwjg.js} +1 -1
  42. package/client/dist/assets/{loops-Cm55CXJ4.js → loops-B2PhQLKR.js} +1 -1
  43. package/client/dist/assets/{loops-3IutojWt.js → loops-BqbF46st.js} +1 -1
  44. package/client/dist/assets/{loops-BAosWtXE.js → loops-CINnHbfI.js} +1 -1
  45. package/client/dist/assets/{loops-kIJJkaxf.js → loops-D-3XhH04.js} +1 -1
  46. package/client/dist/assets/{loops-DHQtnfze.js → loops-DKkEEjZ_.js} +1 -1
  47. package/client/dist/assets/{loops-D7tL_Saw.js → loops-DzWR5-v6.js} +1 -1
  48. package/client/dist/assets/{loops--KWr0X-w.js → loops-WyWDkhok.js} +1 -1
  49. package/client/dist/assets/{loops-BISDssL5.js → loops-scD5fIBf.js} +1 -1
  50. package/client/dist/assets/{narration-DvLQBW9U.js → narration-BEKMVxGm.js} +1 -1
  51. package/client/dist/assets/{narration-CHI06czm.js → narration-CjLwGKap.js} +1 -1
  52. package/client/dist/assets/{narration-DjKB3pQZ.js → narration-DANWuGsW.js} +1 -1
  53. package/client/dist/assets/{narration-eSx3gR0W.js → narration-DGeEDWiT.js} +1 -1
  54. package/client/dist/assets/{narration-DtCYvRLM.js → narration-DJgpGwIP.js} +1 -1
  55. package/client/dist/assets/{narration-n3hOA7LY.js → narration-DbHnz0qV.js} +1 -1
  56. package/client/dist/assets/{narration-thJOeT2-.js → narration-bZSsTZG8.js} +1 -1
  57. package/client/dist/assets/{narration--hUhjM5v.js → narration-i6aKJKEc.js} +1 -1
  58. package/client/dist/assets/{project-repositories-BkyT8AjU.js → project-repositories-CadLZOnr.js} +1 -1
  59. package/client/dist/assets/{spending-Oov7p52A.js → spending-DQDNtM8q.js} +1 -1
  60. package/client/dist/assets/{useDesktop-DpiS8Uov.js → useDesktop-DKNbOF0u.js} +1 -1
  61. package/client/dist/assets/{useRuntimeRuns-DBm1mul0.js → useRuntimeRuns-D3YMw9qx.js} +1 -1
  62. package/client/dist/assets/{useSharedWebSocket-BZxKaVNT.js → useSharedWebSocket-DaWuiO0S.js} +2 -2
  63. package/client/dist/index.html +17 -17
  64. package/docs/internals/configuration.md +2 -0
  65. package/docs/internals/core-runtime-updates.md +3 -3
  66. package/docs/internals/programmatic-agent-runtime.md +2 -0
  67. package/package.json +1 -1
  68. package/server/dist/modules/agent-runtime/runtime/agent-runtime-bridge.js +12 -0
  69. package/server/dist/modules/agent-runtime/runtime/agent-runtime-effective-config.js +2 -0
  70. package/server/dist/modules/agent-runtime/runtime/agent-runtime-settings-router.js +6 -2
  71. package/server/dist/modules/agent-runtime/runtime/agent-runtime-settings.js +18 -6
  72. package/server/dist/modules/loops/runtime/loop-core-factory.js +2 -2
  73. package/server/dist/modules/loops/runtime/loop-definition.js +1 -0
  74. package/server/dist/modules/loops/runtime/loop-factory.js +1 -1
  75. package/server/dist/modules/loops/runtime/loop-graph.js +8 -1
  76. package/server/dist/modules/loops/runtime/loop-implement-recipe.js +28 -9
  77. package/server/dist/modules/loops/runtime/loop-templates.js +3 -3
  78. package/server/dist/schemas/agent-runtime.schema.json +9 -7
  79. package/client/dist/assets/InteractiveJobComposer-Z6fl4791.js +0 -19
  80. package/client/dist/assets/LoopBuilderPage-Dh5uk2Qy.js +0 -1
  81. package/client/dist/assets/agentRuntime-7Ydcvr6P.js +0 -1
  82. package/client/dist/assets/agentRuntime-BHVw9orA.js +0 -1
  83. package/client/dist/assets/agentRuntime-DCPDaQcV.js +0 -1
  84. package/client/dist/assets/agentRuntime-DKTw4Ajg.js +0 -1
  85. package/client/dist/assets/agentRuntime-DVhij_i_.js +0 -1
  86. package/client/dist/assets/agentRuntime-Doss-T8o.js +0 -1
  87. package/client/dist/assets/agentRuntime-eZSMUlkM.js +0 -1
  88. package/client/dist/assets/agentRuntime-qSSU7fQk.js +0 -1
@@ -1,19 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{h as r,l as i,r as a}from"./useSharedWebSocket-BZxKaVNT.js";import{n as o,t as s}from"./createLucideIcon-Bjbbp_KS.js";import{a as c,r as l,s as u}from"./useDesktop-DpiS8Uov.js";import{$ as d,Q as f,V as p,tt as m}from"./TicketDetailModalContext-BHmtj1As.js";import{n as h}from"./provider-capabilities-lePfeT_Y.js";import{n as g}from"./save-OsUqVn99.js";import{l as _}from"./MinimizedChatsContext-BD2bsRBe.js";import{n as v}from"./file-text-BcLCfcWZ.js";import{t as y}from"./circle-x-CMYsN4ZH.js";import{t as b}from"./git-branch-BRM0F5GN.js";import{t as x}from"./loader-circle-DcygOQpC.js";import{n as S,t as C}from"./square-Ci-PFcFe.js";import{t as w}from"./rotate-ccw-Wh4id13q.js";import{t as T}from"./search-Cq_gE3Ik.js";import{t as E}from"./triangle-alert-H9T4jAmh.js";import{t as D}from"./x-CBMI9ejn.js";import{L as O,l as k,n as A,r as j,t as M,u as N}from"./dialog-CMgps2MY.js";import{t as P}from"./utils-BC4DHlz2.js";import{n as F,t as I}from"./lib-CGdyxIWg.js";import{t as L}from"./button-D1xExSTF.js";import{n as R}from"./project-repositories-BkyT8AjU.js";import{t as ee}from"./useRuntimeRuns-DBm1mul0.js";import{$ as z,At as te,C as ne,Ct as re,E as ie,Gt as B,Ht as V,K as H,Mt as ae,St as U,T as oe,U as se,Y as W,Yt as ce,b as le,et as ue,gt as de,k as fe,kt as pe,q as me,st as he,tn as ge,tt as _e,w as ve,x as ye,y as be,zt as xe}from"./index-g8S62tpS.js";import{l as Se,n as Ce,p as we,r as Te,t as Ee}from"./loop-layout-BF8xMiNv.js";import{t as De}from"./lib-C7Mhm-gT.js";import{n as Oe}from"./job-time-BCL7wee9.js";var ke=s(`chevrons-down-up`,[[`path`,{d:`m7 20 5-5 5 5`,key:`13a0gw`}],[`path`,{d:`m7 4 5 5 5-5`,key:`1kwcof`}]]),Ae=s(`chevrons-up-down`,[[`path`,{d:`m7 15 5 5 5-5`,key:`1hf1tw`}],[`path`,{d:`m7 9 5-5 5 5`,key:`sgt6xg`}]]),je=s(`circle-dot`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`circle`,{cx:`12`,cy:`12`,r:`1`,key:`41hilf`}]]),Me=s(`circle-pause`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`10`,x2:`10`,y1:`15`,y2:`9`,key:`c1nkhi`}],[`line`,{x1:`14`,x2:`14`,y1:`15`,y2:`9`,key:`h65svq`}]]),Ne=s(`clock`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 6v6l4 2`,key:`mmk7yg`}]]),Pe=s(`hourglass`,[[`path`,{d:`M5 22h14`,key:`ehvnwv`}],[`path`,{d:`M5 2h14`,key:`pdyrp9`}],[`path`,{d:`M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22`,key:`1d314k`}],[`path`,{d:`M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2`,key:`1vvvr6`}]]),Fe=s(`message-circle-question-mark`,[[`path`,{d:`M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719`,key:`1sd12s`}],[`path`,{d:`M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3`,key:`1u773s`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),G=e(t(),1),K=n();function Ie({phases:e,phaseDefinitions:t}){return t.length===0?null:(0,K.jsx)(`div`,{className:`flex items-center`,children:t.map((n,r)=>{let i=e[n.key]??`idle`,a=r<t.length-1?e[t[r+1].key]??`idle`:null;return(0,K.jsxs)(`div`,{className:`flex items-center`,children:[(0,K.jsxs)(H,{children:[(0,K.jsx)(W,{asChild:!0,children:(0,K.jsxs)(`div`,{className:`flex flex-col items-center gap-1.5 cursor-default px-4`,children:[(0,K.jsx)(Le,{state:i}),(0,K.jsx)(`span`,{className:P(`text-xs font-medium transition-colors`,i===`running`?`text-blue-400 aurora-light:text-accent-info`:i===`done`?`text-emerald-400 aurora-light:text-accent-success`:i===`error`?`text-red-400 aurora-light:text-destructive`:`text-muted-foreground/40`),children:n.label})]})}),(0,K.jsxs)(me,{side:`bottom`,className:`max-w-[200px]`,children:[(0,K.jsx)(`p`,{className:`font-medium`,children:n.label}),(0,K.jsx)(`p`,{className:`text-muted-foreground mt-0.5`,children:n.description})]})]}),a!==null&&(0,K.jsx)(`div`,{className:P(`h-px w-12 -mt-5 shrink-0 transition-all duration-300`,a===`done`||i===`done`?`bg-emerald-500/30 aurora-light:bg-accent-success/40`:a===`running`?`bg-blue-400/40 aurora-light:bg-accent-info/40`:`bg-border/30`)})]},n.key)})})}function Le({state:e}){return(0,K.jsxs)(`div`,{className:P(`flex items-center justify-center w-10 h-10 rounded-full transition-all duration-300`,e===`running`?`bg-blue-500/10 aurora-light:bg-accent-info/10 ring-1 ring-blue-400/30 aurora-light:ring-accent-info/30 animate-pulse`:e===`done`?`bg-emerald-500/10 aurora-light:bg-accent-success/10`:e===`error`?`bg-red-500/10 aurora-light:bg-destructive/10`:`bg-muted/20`),children:[e===`running`&&(0,K.jsx)(x,{className:`w-6 h-6 text-blue-400 aurora-light:text-accent-info animate-spin`}),e===`done`&&(0,K.jsx)(B,{className:`w-6 h-6 text-emerald-400 aurora-light:text-accent-success`}),e===`error`&&(0,K.jsx)(y,{className:`w-6 h-6 text-red-400 aurora-light:text-destructive`}),e===`idle`&&(0,K.jsx)(f,{className:`w-6 h-6 text-muted-foreground/20`})]})}function Re(e,t){let n=Oe(e??null),r=(typeof t==`number`?t:Oe(t??null)?.getTime()??NaN)-(n?.getTime()??NaN);if(!Number.isFinite(r)||r<0)return`—`;let i=Math.round(r/1e3);if(i<60)return`${i}s`;let a=Math.floor(i/60),o=i%60;return a<60?`${a}m ${o}s`:`${Math.floor(a/60)}h ${a%60}m`}function ze(e){let t=new Set;for(let n of e)if(n.event_type===`log`)try{let e=(JSON.parse(n.payload).line??``).match(/(?:Writing|Editing|Created?|Updated?)\s+(?:file:\s*)?([\w./\-]+\.\w+)/i);e&&t.add(e[1])}catch{}return Array.from(t).slice(0,20)}var Be={steps:0,actionKey:``,actionArg:``,turns:0,tokens:0,lastSeenIdx:0};function Ve(e){if(e.event_type!==`assistant`)return null;try{let t=JSON.parse(e.payload);if(!t||typeof t!=`object`||Array.isArray(t))return null;let n=t.message,r=(n&&typeof n==`object`&&!Array.isArray(n)?n:t).usage;if(!r||typeof r!=`object`||Array.isArray(r))return null;let i=r,a=e=>typeof e==`number`&&Number.isFinite(e)?e:0;return a(i.input_tokens)+a(i.output_tokens)+a(i.cache_read_input_tokens)+a(i.cache_creation_input_tokens)}catch{return null}}function He(e,t){if(t.type===`reset`)return Be;if(t.type===`consume`){let{events:n}=t,r=e.lastSeenIdx>n.length?n.length:e.lastSeenIdx;if(n.length<=r)return r===e.lastSeenIdx?e:{...e,lastSeenIdx:r};let{steps:i,actionKey:a,actionArg:o,turns:s,tokens:c}=e;for(let e=r;e<n.length;e++){let t=ye(n[e]);t.step&&(i+=t.stepCount??1),t.actionKey&&(a=t.actionKey,o=t.actionArg??``);let r=Ve(n[e]);r!=null&&(s+=1,c+=r)}return{steps:i,actionKey:a,actionArg:o,turns:s,tokens:c,lastSeenIdx:n.length}}return e}function Ue(e,t){let[n,r]=(0,G.useReducer)(He,Be),i=(0,G.useRef)(e);return(0,G.useEffect)(()=>{i.current!==e&&(i.current=e,r({type:`reset`})),r({type:`consume`,events:t})},[e,t]),n}function We(e,t){let n=t&&e.steps===0?`connecting`:e.actionKey||`thinking`,r=n===`delegating`||be.has(n),i=r&&e.actionArg!==``;return{key:r&&!i?`working`:n,arg:i?e.actionArg:null}}function Ge(e){return`${(e/1e3).toFixed(1)}k`}function Ke(e){let t=!!e.total_cost_usd_estimated,n=e.total_cost_usd==null?null:`${t?`~`:``}$${e.total_cost_usd.toFixed(4)}`,r=e.num_turns==null?null:String(e.num_turns),i=e.tokens_in==null?null:(e.tokens_in??0)+(e.tokens_out??0)+(e.tokens_cache_read??0)+(e.tokens_cache_create??0);return{cost:n,turns:r,tokens:i==null?null:Ge(i)}}function qe(e){if(e.length<=1)return null;let t=e=>e.tokens_in==null&&e.tokens_out==null&&e.tokens_cache_read==null&&e.tokens_cache_create==null;return{totalCostUsd:e.reduce((e,t)=>e+(t.total_cost_usd??0),0),hasNullCost:e.some(e=>e.total_cost_usd==null),costEstimated:e.some(e=>!!e.total_cost_usd_estimated),nullCostCount:e.filter(e=>e.total_cost_usd==null).length,costUnavailable:e.every(e=>e.total_cost_usd==null),totalTokensIn:e.reduce((e,t)=>e+(t.tokens_in??0),0),totalTokensOut:e.reduce((e,t)=>e+(t.tokens_out??0),0),totalTokensCacheRead:e.reduce((e,t)=>e+(t.tokens_cache_read??0),0),totalTokensCacheCreate:e.reduce((e,t)=>e+(t.tokens_cache_create??0),0),nullTokenCount:e.filter(t).length,tokensUnavailable:e.every(t),jobCount:e.length}}function Je(e){return e.costUnavailable?`—`:`${e.costEstimated?`~`:``}${e.hasNullCost?`≥`:``}$${e.totalCostUsd.toFixed(4)}`}function Ye(e){if(e.tokensUnavailable)return`—`;let t=e.totalTokensIn+e.totalTokensOut+e.totalTokensCacheRead+e.totalTokensCacheCreate;return`${(e.nullTokenCount??0)>0?`≥`:``}${Ge(t)}`}var Xe=`specrails-desktop:job-run-details`;function Ze(e){try{let t=localStorage.getItem(Xe);return t?JSON.parse(t)?.[e]===!0:!1}catch{return!1}}function Qe(e,t){try{let n=localStorage.getItem(Xe),r={};if(n)try{let e=JSON.parse(n);e&&typeof e==`object`&&(r=e)}catch{}r[e]=t,localStorage.setItem(Xe,JSON.stringify(r))}catch{}}var $e={running:{variant:`running`,labelKey:`statusLabel.running`,tooltipKey:`statusTooltip.running`},completed:{variant:`success`,labelKey:`statusLabel.completed`,tooltipKey:`statusTooltip.completed`},failed:{variant:`failed`,labelKey:`statusLabel.failed`,tooltipKey:`statusTooltip.failed`},canceled:{variant:`canceled`,labelKey:`statusLabel.canceled`,tooltipKey:`statusTooltip.canceled`},queued:{variant:`queued`,labelKey:`statusLabel.queued`,tooltipKey:`statusTooltip.queued`},zombie_terminated:{variant:`failed`,labelKey:`statusLabel.zombie`,tooltipKey:`statusTooltip.zombie`},skipped:{variant:`queued`,labelKey:`statusLabel.skipped`,tooltipKey:`statusTooltip.skipped`}};function et({job:e,events:t,phases:n,phaseDefinitions:r,projectId:i,variant:a,pipelineTotals:s,actions:c,onOpenRun:l}){let{t:u}=o(`jobs`),{t:d}=o(`agentRuntime`),f=e.status===`running`,p=e.status===`queued`,m=e.command.startsWith(`loop:`),_=$e[e.status]??$e.queued,[v,y]=(0,G.useState)(()=>Date.now());(0,G.useEffect)(()=>{if(!f)return;y(Date.now());let e=window.setInterval(()=>y(Date.now()),1e3);return()=>window.clearInterval(e)},[f]);let b=e.finished_at?Re(e.started_at,e.finished_at):f?Re(e.started_at,v):`—`,S=Ue(e.id,t),C=ee(i,{jobId:e.id,enabled:!!i}),w=C.runs[0],[T,E]=(0,G.useState)(()=>Ze(a)),D=e=>{E(e),Qe(a,e)},O=(0,G.useMemo)(()=>r.find(e=>n[e.key]===`running`)?.label??null,[n,r]),k=w?.nextStep?d(`roles.${w.nextStep}`,{defaultValue:w.nextStep}):null,A=O??k,{key:j,arg:M}=We(S,f),N=M==null?u(`statusPanel.activity.${j}`):u(`statusPanel.activity.${j}`,{arg:M}),F=f?A?u(`runHeader.phaseActivity`,{phase:A,activity:N}):N:w&&!w.active&&w.nextStep&&(w.canResume||w.pendingQuestion||w.pendingApproval)?u(`runHeader.phaseActivity`,{phase:d(`runs.status.${w.status}`,{defaultValue:w.status}),activity:d(`runs.phase`,{phase:k})}):null,I=m&&f&&S.steps>0?u(`statusPanel.steps`,{count:S.steps}):null,R=Ke(e),z=!f&&!p,te=(0,G.useMemo)(()=>z?ze(t):[],[t,z]),re=f&&S.turns>0,B=C.runs.length>0?C.error:``,V=!!w?.pendingQuestion&&!!w.canResume&&!w.recoverableSteps.length,ae=z||re||!!w&&!!i||!!B,U=C.busy!==null,se=w?(0,K.jsxs)(K.Fragment,{children:[w.canResume&&!V&&(w.engineVersion===2&&w.recoverableSteps.length>0?(0,K.jsx)(ie,{run:w,busy:U,onRecover:e=>void C.act(w,`recover`,e)},`${i}:${w.runId}`):(0,K.jsx)(L,{size:`sm`,className:`h-7`,disabled:U,onClick:()=>void C.act(w,w.recoverableSteps.length?`recover`:w.pendingApproval?`approve`:`resume`),children:w.recoverableSteps.length?d(`runs.recover`):w.pendingApproval?d(`runs.approve`):d(`runs.resume`)})),V&&(0,K.jsxs)(L,{size:`sm`,variant:`outline`,className:`h-7 border-accent-warning/40 text-accent-warning hover:bg-accent-warning/10`,onClick:()=>D(!0),children:[(0,K.jsx)(Fe,{className:`w-3.5 h-3.5 mr-1.5`,"aria-hidden":!0}),u(`runHeader.questionPending`)]}),w.canSettle&&(0,K.jsx)(L,{size:`sm`,className:`h-7`,disabled:U,onClick:()=>void C.act(w,`settle`),children:d(`runs.prepareDelivery`)}),w.forkSuccessor&&l&&(0,K.jsx)(L,{size:`sm`,variant:`outline`,onClick:()=>l(w.forkSuccessor),children:u(`loopExplorer.openFork`)}),w.canCancel&&(0,K.jsx)(L,{size:`sm`,variant:`secondary`,className:`h-7`,disabled:U,onClick:()=>void C.act(w,`cancel`),children:d(`runs.cancel`)})]}):null;return(0,K.jsxs)(`div`,{"data-testid":`job-run-header`,className:P(`shrink-0`,a===`glass`?`border-b border-border/30 bg-surface/30`:`border-b border-border bg-background`),children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap px-3 py-2 min-w-0`,children:[(0,K.jsxs)(H,{children:[(0,K.jsx)(W,{asChild:!0,children:(0,K.jsx)(`div`,{children:(0,K.jsx)(fe,{variant:_.variant,children:u(_.labelKey)})})}),(0,K.jsx)(me,{children:u(_.tooltipKey)})]}),(0,K.jsxs)(`span`,{className:P(`inline-flex items-center gap-1.5 text-xs tabular-nums`,f?`text-accent-info font-medium`:`text-muted-foreground`),title:u(f?`statusPanel.liveTooltip`:`statusPanel.duration`),children:[f&&(0,K.jsx)(`span`,{className:`inline-block w-1.5 h-1.5 rounded-full bg-accent-info animate-pulse`,"aria-hidden":!0}),b]}),F&&(0,K.jsxs)(`span`,{className:`flex items-center gap-1.5 min-w-0 flex-1 basis-40 text-xs text-muted-foreground`,children:[f&&(0,K.jsx)(x,{className:`w-3 h-3 shrink-0 text-accent-info animate-spin`,"aria-hidden":!0}),(0,K.jsx)(`span`,{className:`truncate`,"data-testid":`job-run-activity`,children:F})]}),!F&&(0,K.jsx)(`span`,{className:`flex-1`}),I&&(0,K.jsx)(`span`,{className:`text-[11px] text-muted-foreground/70 tabular-nums shrink-0`,children:I}),(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 shrink-0 ml-auto`,children:[se,c,ae&&(0,K.jsxs)(`button`,{type:`button`,onClick:()=>D(!T),"aria-expanded":T,className:`inline-flex items-center gap-1 h-7 px-2 rounded-md text-[11px] text-muted-foreground hover:text-foreground hover:bg-surface/60 transition-colors`,children:[u(`runHeader.details`),(0,K.jsx)(g,{className:P(`w-3.5 h-3.5 transition-transform duration-150`,T&&`rotate-180`),"aria-hidden":!0})]})]})]}),r.length>0&&(0,K.jsx)(`div`,{className:`px-3 pb-2 overflow-x-auto`,children:(0,K.jsx)(Ie,{phases:n,phaseDefinitions:r})}),ae&&T&&(0,K.jsxs)(`div`,{"data-testid":`job-run-details`,className:`px-3 pb-3 space-y-3 border-t border-border/20 pt-3 text-xs`,children:[re&&(0,K.jsxs)(`div`,{children:[(0,K.jsxs)(`div`,{className:`grid grid-cols-2 gap-2 max-w-sm`,children:[(0,K.jsx)(q,{label:u(`statusPanel.turns`),value:String(S.turns)}),(0,K.jsx)(q,{label:u(`statusPanel.tokens`),value:Ge(S.tokens)})]}),(0,K.jsx)(`p`,{className:`text-[10px] text-muted-foreground/60 mt-1`,children:u(`runHeader.liveReported`)})]}),z&&(0,K.jsxs)(`div`,{className:`grid grid-cols-3 gap-2 max-w-lg`,children:[(0,K.jsx)(q,{label:u(`statusPanel.cost`),value:R.cost,valueClass:`text-yellow-400 aurora-light:text-accent-warning`,naCaption:h(e.provider)?u(`statusPanel.costUnknownLocal`):u(`statusPanel.notAvailable`),naTooltip:h(e.provider)?u(`statusPanel.costUnknownLocalTooltip`):void 0}),(0,K.jsx)(q,{label:u(`statusPanel.turns`),value:R.turns,naCaption:u(`statusPanel.notAvailable`)}),(0,K.jsx)(q,{label:u(`statusPanel.tokens`),value:R.tokens,naCaption:u(`statusPanel.notAvailable`)})]}),z&&s&&(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`p`,{className:`text-[10px] text-muted-foreground/50 uppercase tracking-wider mb-1.5`,children:u(`statusPanel.pipelineTotal`,{count:s.jobCount})}),(0,K.jsxs)(`div`,{className:`grid grid-cols-2 gap-2 max-w-sm`,children:[(0,K.jsx)(q,{label:u(`statusPanel.totalCost`),value:Je(s),valueClass:`text-yellow-400 aurora-light:text-accent-warning`}),(0,K.jsx)(q,{label:u(`statusPanel.totalTokens`),value:Ye(s)})]}),s.hasNullCost&&!s.costUnavailable&&(0,K.jsx)(`p`,{"data-testid":`pipeline-partial-hint`,className:`text-[10px] text-muted-foreground/70 mt-1.5`,title:u(`statusPanel.pipelinePartialTooltip`),children:u(`statusPanel.pipelinePartial`,{count:s.nullCostCount??0})}),s.costUnavailable&&(0,K.jsx)(`p`,{"data-testid":`pipeline-cost-unavailable`,className:`text-[10px] text-muted-foreground/70 mt-1.5`,children:u(`statusPanel.pipelineCostUnavailable`)}),(s.nullTokenCount??0)>0&&(0,K.jsx)(`p`,{"data-testid":`pipeline-usage-coverage-hint`,className:`text-[10px] text-muted-foreground/70 mt-1`,title:u(`statusPanel.pipelineUsageTooltip`),children:s.tokensUnavailable?u(`statusPanel.pipelineUsageUnavailable`):u(`statusPanel.pipelineUsagePartial`,{count:s.nullTokenCount??0})})]}),te.length>0&&(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`p`,{className:`text-[10px] text-muted-foreground/50 uppercase tracking-wider mb-1.5`,children:u(`statusPanel.filesModified`)}),(0,K.jsx)(`div`,{className:`flex flex-wrap gap-1.5`,children:te.map(e=>(0,K.jsx)(`code`,{className:`text-[10px] font-mono bg-muted/30 px-2 py-0.5 rounded text-cyan-400/80 aurora-light:text-accent-info`,children:e},e))})]}),(w||B)&&i&&(0,K.jsxs)(`section`,{"aria-label":d(`runs.implementation`),className:`space-y-2`,onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),children:[B&&(0,K.jsx)(`p`,{role:`alert`,className:`text-destructive`,children:B}),w?.historical&&(0,K.jsx)(`p`,{className:`text-muted-foreground`,children:d(`evidence.historical`)}),w?.status===`succeeded`&&(0,K.jsx)(`p`,{className:`text-muted-foreground`,children:d(`runs.reviewDelivery`)}),w?.canResume&&(0,K.jsx)(`p`,{className:`text-muted-foreground`,children:d(`runs.preserveProgress`)}),w?.error&&(0,K.jsx)(`p`,{className:`text-destructive`,children:w.error}),w?.pendingApproval?.reason&&(0,K.jsx)(`p`,{className:`text-muted-foreground`,children:w.pendingApproval.reason}),w?.pendingQuestion&&(0,K.jsxs)(`div`,{className:`space-y-2`,children:[(0,K.jsx)(`p`,{className:`font-medium`,children:d(`runs.question`)}),(0,K.jsx)(`p`,{className:`whitespace-pre-wrap`,children:w.pendingQuestion.question}),V&&(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(`label`,{className:`block space-y-1`,children:[d(`runs.answerLabel`),(0,K.jsx)(`textarea`,{className:`min-h-20 w-full rounded-md border border-input bg-background px-2 py-1 text-sm`,maxLength:2e4,placeholder:d(`runs.answerPlaceholder`),value:C.answers[w.runId]??``,onChange:e=>C.setAnswer(w.runId,e.target.value)})]}),(0,K.jsx)(L,{size:`sm`,disabled:U||!C.answers[w.runId]?.trim(),onClick:()=>void C.act(w,`answer`),children:d(`runs.answer`)})]})]}),w?.metrics&&(0,K.jsx)(ne,{metrics:w.metrics}),w&&(0,K.jsx)(oe,{projectId:i,runId:w.runId,summary:w.efficiencySummary,historical:w.historical}),w&&(0,K.jsx)(ve,{projectId:i,run:w,onAccepted:C.refresh})]})]})]})}function q({label:e,value:t,valueClass:n,naCaption:r,naTooltip:i}){return(0,K.jsxs)(`div`,{className:`bg-muted/20 rounded-lg px-2.5 py-1.5`,title:t==null?i:void 0,children:[(0,K.jsx)(`p`,{className:`text-[10px] text-muted-foreground/50 uppercase tracking-wider`,children:e}),(0,K.jsx)(`p`,{className:P(`text-sm font-semibold tabular-nums`,t==null?`text-muted-foreground`:n),children:t??`—`}),t==null&&r&&(0,K.jsx)(`p`,{className:`text-[10px] text-muted-foreground/40`,children:r})]})}function tt(e){let t=e.trimStart();return!!(/^#{1,6}\s/.test(t)||/^[-*+]\s/.test(t)||/^\d+\.\s/.test(t)||/^\|.+\|/.test(t)||t.startsWith("```")||t.startsWith(`> `)||/\*\*[^*]+\*\*/.test(e)||/`[^`]+`/.test(e)||/\[.+\]\(.+\)/.test(e)||/^(-{3,}|_{3,}|\*{3,})$/.test(t)||/^- \[[ x]\]\s/.test(t))}var nt=new Set;function rt({ticketId:e,onOpen:t,children:n}){let{t:r}=o(`agent`),i=r(`refs.openTicket`,{id:e});return(0,K.jsx)(`button`,{type:`button`,"data-testid":`log-ticket-ref`,onClick:n=>{n.stopPropagation(),t(e)},title:i,"aria-label":i,className:`inline cursor-pointer p-0 align-baseline text-accent-primary/90 underline decoration-accent-primary/50 decoration-dotted underline-offset-2 transition-colors hover:text-accent-primary hover:decoration-solid`,children:n})}function it(e){if(!e.includes(`#`))return null;let t=_e(e,nt);return t.some(e=>e.kind===`ticket`)?t:null}function at(e,t){let n=it(e);return n?n.map((e,n)=>e.kind===`ticket`?(0,K.jsx)(rt,{ticketId:e.ticketId,onOpen:t,children:e.label},n):(0,K.jsx)(G.Fragment,{children:e.kind===`text`?e.text:e.label},n)):e}var ot=new Set([`code`,`inlineCode`,`link`,`linkReference`,`image`,`imageReference`,`definition`,`html`]);function st(e){return e.kind===`ticket`?{type:`link`,url:z({kind:`ticket`,ticketId:e.ticketId}),children:[{type:`text`,value:e.label}]}:{type:`text`,value:e.kind===`text`?e.text:e.label}}function ct(e){let t=e.children;if(t)for(let e=t.length-1;e>=0;e--){let n=t[e];if(!ot.has(n.type))if(n.type===`text`&&typeof n.value==`string`){let r=_e(n.value,nt);r.some(e=>e.kind===`ticket`)&&t.splice(e,1,...r.map(st))}else ct(n)}}function lt(){return e=>ct(e)}function ut(e){let{activeProjectId:t}=l(),{openRef:n}=he(),r=e??t??void 0;return(0,G.useMemo)(()=>r?e=>{n(r,{kind:`ticket`,ticketId:e})}:void 0,[r,n])}function dt(e,t){let n=`${e.id??t}`,i=e.timestamp;if(e.event_type===`log`)try{let t=JSON.parse(e.payload).line??``;return t.trim()?t.startsWith(`▸`)||t.match(/^(architect|developer|reviewer|ship|analyst)\s*:/i)?{id:n,content:t,type:`phase`,timestamp:i}:e.source===`stderr`?{id:n,content:t,type:`stderr`,timestamp:i}:tt(t)?{id:n,content:t,type:`assistant`,timestamp:i}:{id:n,content:t,type:`plain`,timestamp:i}:null}catch{return null}if(e.event_type!==`log`&&e.event_type!==`result`)return null;if(e.event_type===`result`)try{let t=JSON.parse(e.payload),a=[];return t.duration_ms&&a.push(`${(t.duration_ms/1e3).toFixed(1)}s`),t.total_cost_usd&&a.push(`$${t.total_cost_usd.toFixed(4)}`),t.num_turns&&a.push(r.t(`jobs:logViewer.turns`,{count:t.num_turns})),{id:n,content:`▸ ${r.t(`jobs:logViewer.completed`)}${a.length?` — ${a.join(` · `)}`:``}`,type:`result`,timestamp:i}}catch{return null}return null}function ft(e){let t=`none`,n=[];for(let r of e){let e=r.type;if(e!==`plain`&&e!==`log`){t=`none`,n.push(r);continue}let i=r.content;i.startsWith(`--- `)?(t=`saw_minus`,n.push({...r,type:`diff-meta`})):t===`saw_minus`&&i.startsWith(`+++ `)?(t=`active`,n.push({...r,type:`diff-meta`})):t===`active`&&i.startsWith(`@@ `)?n.push({...r,type:`diff-hunk`}):t===`active`&&i.startsWith(`+`)&&!i.startsWith(`+++`)?n.push({...r,type:`diff-add`}):t===`active`&&i.startsWith(`-`)&&!i.startsWith(`---`)?n.push({...r,type:`diff-remove`}):(t===`active`&&(i.startsWith(` `)||i===``)||(t=`none`),n.push(r))}return n}function pt(e){let t=[];for(let n of e){let e=t.length>0?t[t.length-1]:null;n.type===`assistant`&&e?.type===`assistant`?e.content+=`
2
- `+n.content:t.push({...n})}return t}function mt(e){let t=[{key:`__preamble__`,header:null,lines:[]}];for(let n of e)n.type===`phase`?t.push({key:n.id,header:n,lines:[]}):t[t.length-1].lines.push(n);return t.filter(e=>e.header!==null||e.lines.length>0)}function ht({events:e,isLoading:t,projectId:n}){let{t:r,i18n:i}=o(`jobs`),[a,s]=(0,G.useState)(``),[c,l]=(0,G.useState)(!0),[d,f]=(0,G.useState)(new Set),p=(0,G.useRef)(null),m=(0,G.useRef)(null),h=ut(n),{processedLines:_,groups:v,totalLines:y}=(0,G.useMemo)(()=>{let t=ft(pt(e.map((e,t)=>dt(e,t)).filter(e=>e!==null)));return{processedLines:t,groups:mt(t),totalLines:t.length}},[e,i.language]),b=(0,G.useMemo)(()=>{if(!a)return y;let e=a.toLowerCase();return _.filter(t=>t.content.toLowerCase().includes(e)).length},[a,_,y]),x=(0,G.useCallback)(()=>{let e=m.current;e&&(e.scrollTop=e.scrollHeight)},[]);(0,G.useEffect)(()=>{c&&x()},[e.length,c,x]);function S(){let e=m.current;if(!e)return;let t=e.scrollHeight-e.scrollTop-e.clientHeight<50;l(t)}function C(e){f(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})}return t?(0,K.jsx)(`div`,{className:`flex-1 flex items-center justify-center`,children:(0,K.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r(`logViewer.loading`)})}):y===0?(0,K.jsx)(`div`,{className:`flex-1 flex items-center justify-center`,children:(0,K.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r(`logViewer.empty`)})}):(0,K.jsxs)(`div`,{className:`flex flex-col h-full`,children:[(0,K.jsxs)(`div`,{className:`px-4 py-2 border-b border-border flex items-center gap-2`,children:[(0,K.jsxs)(`div`,{className:`relative flex-1 max-w-xs`,children:[(0,K.jsx)(T,{className:`absolute left-2.5 top-1/2 -translate-y-1/2 w-3 h-3 text-muted-foreground`}),(0,K.jsx)(se,{placeholder:r(`logViewer.filterPlaceholder`),value:a,onChange:e=>s(e.target.value),className:`pl-7 h-7`})]}),(0,K.jsx)(L,{variant:`ghost`,size:`sm`,className:`h-7 px-2 text-muted-foreground/50 hover:text-foreground`,onClick:()=>{let e=_.map(e=>e.content).join(`
3
- `);navigator.clipboard.writeText(e).then(()=>{u.success(r(`logViewer.copySuccess`))}).catch(()=>{u.error(r(`logViewer.copyFailed`))})},children:(0,K.jsx)(V,{className:`w-3.5 h-3.5`})}),(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:r(`logViewer.lineCount`,{filtered:b,total:y})})]}),(0,K.jsxs)(`div`,{ref:m,className:`flex-1 overflow-y-auto p-2 text-xs relative`,onScroll:S,children:[v.map(e=>(0,K.jsx)(gt,{group:e,filter:a,collapsed:d.has(e.key),onToggle:()=>C(e.key),onOpenTicket:h},e.key)),(0,K.jsx)(`div`,{ref:p})]}),!c&&(0,K.jsxs)(L,{size:`sm`,variant:`secondary`,onClick:()=>{l(!0),x()},className:`absolute bottom-16 right-6 h-7 gap-1 shadow-lg`,children:[(0,K.jsx)(g,{className:`w-3 h-3`}),r(`logViewer.jumpToBottom`)]})]})}var gt=(0,G.memo)(function({group:e,filter:t,collapsed:n,onToggle:r,onOpenTicket:i}){let{t:a}=o(`jobs`),s=t?e.lines.filter(e=>e.content.toLowerCase().includes(t.toLowerCase())):e.lines;if(e.header===null)return s.length===0?null:(0,K.jsx)(`div`,{children:s.map((e,t)=>(0,K.jsx)(bt,{line:e,even:t%2==0,onOpenTicket:i},e.id))});let c=e.header.content;return(0,K.jsxs)(`div`,{className:`mt-3 rounded-md overflow-hidden border border-border/20`,children:[(0,K.jsxs)(`button`,{type:`button`,onClick:r,className:P(`flex items-center gap-2 w-full text-left px-3 py-2`,`bg-primary/5 border-b border-primary/20`,`hover:bg-primary/10 transition-colors duration-150 cursor-pointer`),children:[(0,K.jsx)(v,{className:P(`w-3 h-3 text-primary/60 shrink-0 transition-transform duration-150`,!n&&`rotate-90`)}),(0,K.jsx)(`span`,{className:`flex-1 text-[12px] font-semibold text-foreground leading-none`,children:c}),e.header.timestamp&&(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground/40 font-mono tabular-nums shrink-0`,children:new Date(e.header.timestamp).toLocaleTimeString(`en`,{hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1})}),(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground/40 shrink-0`,children:a(`logViewer.phaseLines`,{count:e.lines.length})})]}),!n&&(0,K.jsx)(`div`,{className:`bg-muted/5`,children:s.length===0?(0,K.jsx)(`p`,{className:`px-4 py-2 text-[10px] text-muted-foreground/40 italic`,children:a(t?`logViewer.noMatchingLines`:`logViewer.noOutput`)}):s.map((e,t)=>(0,K.jsx)(bt,{line:e,even:t%2==0,onOpenTicket:i},e.id))})]})}),_t=[De],vt=[I],yt=[I,lt],bt=(0,G.memo)(function({line:e,even:t,onOpenTicket:n}){let r=e.type===`assistant`,i=e.type===`diff-add`,a=e.type===`diff-remove`,o=e.type===`diff-meta`,s=e.type===`diff-hunk`,c=i||a||o||s,l=n!=null&&(e.type===`plain`||e.type===`log`),u=(0,G.useMemo)(()=>l&&n?at(e.content,n):e.content,[l,n,e.content]),d=r&&n?yt:vt,f=(0,G.useMemo)(()=>n?{a:({href:e,children:t})=>{let r=ue(e);return r?.kind===`ticket`?(0,K.jsx)(rt,{ticketId:r.ticketId,onOpen:n,children:t}):(0,K.jsx)(`a`,{href:e,children:t})}}:void 0,[n]);return(0,K.jsxs)(`div`,{className:P(`flex items-start gap-2 group px-2 py-0.5 rounded-sm`,!c&&(t?`bg-muted/20`:`bg-transparent`),e.type===`result`&&`bg-emerald-500/5 aurora-light:bg-accent-success/10 border-l-2 border-emerald-500/40 aurora-light:border-accent-success/40 mt-2 py-2`,i&&`bg-emerald-500/8 aurora-light:bg-accent-success/10 border-l-2 border-emerald-500/50 aurora-light:border-accent-success/50`,a&&`bg-red-500/8 aurora-light:bg-destructive/10 border-l-2 border-red-500/50 aurora-light:border-destructive/50`,o&&`bg-accent-primary/5 border-l-2 border-accent-primary/30`,s&&`bg-accent-info/5 border-l-2 border-accent-info/30`),children:[e.timestamp&&(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground/40 shrink-0 mt-0.5 w-[52px] font-mono tabular-nums`,children:new Date(e.timestamp).toLocaleTimeString(`en`,{hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1})}),r?(0,K.jsx)(`div`,{className:`flex-1 min-w-0 prose prose-invert prose-xs max-w-none
4
- prose-p:my-1 prose-p:leading-relaxed
5
- prose-headings:mt-2 prose-headings:mb-1 prose-headings:text-sm prose-headings:font-semibold
6
- prose-ul:my-1 prose-ol:my-1 prose-li:my-0
7
- prose-code:text-cyan-300 prose-code:text-[11px] prose-code:bg-muted/40 prose-code:px-1 prose-code:py-0.5 prose-code:rounded
8
- prose-pre:my-1 prose-pre:bg-muted/30 prose-pre:rounded-md prose-pre:p-2 prose-pre:text-[11px]
9
- prose-strong:text-foreground prose-em:text-foreground/70
10
- prose-a:text-blue-400 prose-a:no-underline hover:prose-a:underline
11
- prose-table:my-2 prose-table:text-[11px]
12
- prose-thead:border-border prose-thead:bg-muted/30
13
- prose-th:px-3 prose-th:py-1.5 prose-th:text-left prose-th:font-semibold prose-th:text-foreground/90
14
- prose-td:px-3 prose-td:py-1.5 prose-td:border-border
15
- prose-tr:border-border
16
- text-foreground/80`,children:(0,K.jsx)(F,{remarkPlugins:d,rehypePlugins:_t,components:f,children:e.content})}):(0,K.jsx)(`span`,{className:P(`flex-1 break-all leading-relaxed whitespace-pre-wrap font-mono`,e.type===`tool-use`&&`text-cyan-400/80 aurora-light:text-accent-info text-[11px]`,e.type===`stderr`&&`text-orange-400 aurora-light:text-accent-warning`,e.type===`result`&&`text-emerald-400 aurora-light:text-accent-success font-medium`,e.type===`log`&&`text-foreground/60`,e.type===`plain`&&`text-foreground/70`,e.type===`tool-result`&&`text-muted-foreground/50`,i&&`text-emerald-400 aurora-light:text-accent-success`,a&&`text-red-400 aurora-light:text-destructive`,o&&`text-accent-primary/80`,s&&`text-accent-info/80`),children:u})]})}),xt=e=>!!e&&typeof e==`object`&&!Array.isArray(e);function St(e){if(!xt(e)||typeof e.entry!=`string`||!Array.isArray(e.nodes)||e.nodes.length>1e4)return null;let t=[];for(let n of e.nodes){if(!xt(n)||typeof n.id!=`string`||!n.id||typeof n.kind!=`string`||typeof n.label!=`string`||!xt(n.ends)||Object.values(n.ends).some(e=>e!==null&&typeof e!=`string`)||n.component!==void 0&&typeof n.component!=`string`)return null;t.push({id:n.id,kind:n.kind,label:n.label,ends:n.ends,...typeof n.component==`string`?{component:n.component}:{}})}let n=new Set(t.map(e=>e.id));return n.size!==t.length||!n.has(e.entry)||t.some(e=>Object.values(e.ends).some(e=>e!==null&&!n.has(e)))?null:{entry:e.entry,nodes:t}}function Ct(e){let t=St(e);if(!t||!xt(e)||e.components!==void 0&&!xt(e.components))return null;let n=Object.create(null);for(let[t,r]of Object.entries(e.components??{})){let e=St(r);if(!e)return null;n[t]=e}return{...t,components:n}}var J=e=>typeof e==`object`&&!!e&&!Array.isArray(e),Y=e=>typeof e==`number`&&Number.isFinite(e)&&e>=0,wt=e=>Array.isArray(e)&&e.every(e=>typeof e==`string`);function Tt(e){if(!J(e)||e.version!==1||typeof e.execution!=`string`||!Y(e.steps)||!Y(e.deciderEvaluations)||!(e.turns===null||Y(e.turns))||!(e.costUsd===null||Y(e.costUsd))||typeof e.costUncertain!=`boolean`||e.engineVersion===2&&e.completion!==void 0&&(!J(e.completion)||typeof e.completion.ok!=`boolean`||typeof e.completion.verified!=`boolean`||!wt(e.completion.reasons)))return null;if(e.core!==null){let t=e.core;if(!J(t)||typeof t.change!=`string`||typeof t.recordedAt!=`string`||!J(t.completion)||![`implementation`,`validation`,`archive`,`delivery`].every(e=>typeof t.completion==`object`&&typeof t.completion[e]==`string`)||!wt(t.completion.reasons)||!wt(t.findings)||!Array.isArray(t.exceptions)||!Array.isArray(t.checks)||!Array.isArray(t.phases)||!t.exceptions.every(e=>J(e)&&[`requirement`,`reason`,`impact`,`acceptedBy`,`approvalEvidence`].every(t=>typeof e[t]==`string`))||!t.checks.every(e=>J(e)&&[`name`,`status`,`scope`,`limitations`].every(t=>typeof e[t]==`string`)&&typeof e.required==`boolean`&&wt(e.evidence))||!t.phases.every(e=>J(e)&&typeof e.name==`string`&&typeof e.status==`string`&&(e.durationMs===null||Y(e.durationMs))&&(e.attempts===null||Y(e.attempts))))return null}return e}function X(e){try{let t=JSON.parse(e);if(t&&typeof t==`object`&&!Array.isArray(t))return t}catch{}return null}var Et=/^\s*━+\s*Step\s+\d+\s*·/,Dt=/\s*\(iteration\s+\d+\)\s*$/i;function Ot(e){return e.replace(/^[\s\uFE0F\p{Extended_Pictographic}]+/u,``).trim()||e.trim()}function kt(e){let t=Ot(e.title);return e.iteration==null?t:t.replace(Dt,``)}function At(e){return e.meta.nodeId??`${e.meta.kind}::${Ot(e.meta.title).replace(Dt,``)}`}function jt(e){let t=null,n=0,r=null,i=[[]],a=new Map,o=[];for(let s=0;s<e.length;s++){let c=e[s];if(c.event_type===`loop_completion`){r=Tt(X(c.payload));continue}if(c.event_type===`runtime-graph`){let e=X(c.payload);if(e&&Array.isArray(e.nodes)&&Array.isArray(e.edges)){let n=e.nodes.filter(e=>!!(e&&typeof e==`object`&&typeof e.path==`string`)),r=e.edges.filter(e=>!!(e&&typeof e==`object`&&typeof e.from==`string`&&typeof e.to==`string`)),i=t;t={...i??{},runtimeTopology:Ct(e.graph)??void 0,loopId:typeof e.workflowId==`string`?e.workflowId:i?.loopId,graph:{nodes:n.map((e,t)=>({id:String(e.path),type:`core`,position:{x:0,y:t*100},data:{label:String(e.label??e.path),kind:e.kind}})),edges:r.map((e,t)=>({id:`core-edge-${t}`,source:String(e.from),target:String(e.to),label:String(e.label)})),config:i?.graph.config??{maxIterations:1,timeoutMinutes:0}}}}continue}if(c.event_type===`loop_graph`){let e=X(c.payload);e&&e.graph&&typeof e.graph==`object`&&!Array.isArray(e.graph)&&(t={graph:e.graph,loopId:typeof e.loopId==`string`?e.loopId:void 0,loopName:typeof e.loopName==`string`?e.loopName:void 0,provider:typeof e.provider==`string`?e.provider:void 0,model:typeof e.model==`string`?e.model:void 0,iterationLimit:typeof e.iterationLimit==`number`?e.iterationLimit:void 0});continue}if(c.event_type===`loop_step`){let e=X(c.payload);if(!e||typeof e.index!=`number`)continue;let t=typeof e.iteration==`number`?e.iteration:null;t!=null&&t>n&&(n=t),o.push({meta:{index:e.index,traceId:typeof e.traceId==`string`?e.traceId:void 0,spanId:typeof e.spanId==`string`?e.spanId:void 0,nodePath:typeof e.nodePath==`string`?e.nodePath:void 0,scopeId:typeof e.scopeId==`string`?e.scopeId:void 0,branch:typeof e.branch==`string`?e.branch:void 0,attemptId:typeof e.attemptId==`string`?e.attemptId:void 0,attempt:typeof e.attempt==`number`?e.attempt:void 0,kind:typeof e.kind==`string`?e.kind:`ai-step`,title:typeof e.title==`string`?e.title:``,nodeId:typeof e.nodeId==`string`?e.nodeId:null,iteration:t,template:typeof e.template==`string`&&e.template?e.template:void 0,command:typeof e.command==`string`&&e.command?e.command:void 0},end:null,lastActivity:null}),typeof e.attemptId==`string`&&a.set(e.attemptId,o.length-1),i.push([]);continue}if(c.event_type===`loop_step_end`){let e=X(c.payload);if(!e||typeof e.index!=`number`)continue;for(let t=o.length-1;t>=0;t--)if(o[t].meta.index===e.index){o[t].end={index:e.index,nodeId:typeof e.nodeId==`string`?e.nodeId:null,status:e.status===`paused`?`paused`:e.status===`interrupted`?`interrupted`:e.status===`stalled`?`stalled`:e.status===`failed`?`failed`:`ok`,exitCode:typeof e.exitCode==`number`?e.exitCode:null,durationMs:typeof e.durationMs==`number`?e.durationMs:null,decision:e.decision===`continue`||e.decision===`stop`?e.decision:void 0,...e.reason===`idle_timeout`||e.reason===`provider_limit`?{reason:e.reason}:{},...typeof e.idleMs==`number`?{idleMs:e.idleMs}:{}};break}continue}let l=X(c.payload),u=l?.attemptId??(l?.event&&typeof l.event==`object`?l.event.attemptId:void 0),d=typeof u==`string`?a.get(u)??-1:-1,f=d>=0?d:u===void 0?o.length-1:-1,p=f>=0,m=dt(c,s);if(m&&!(p&&Et.test(m.content))&&i[f+1].push(m),p){let e=ye(c);e.step&&e.actionKey&&(o[f].lastActivity={actionKey:e.actionKey,actionArg:e.actionArg})}}let s=e=>ft(pt(e)),c=s(i[0]),l=o.map((e,t)=>({key:`step-${t}-${e.meta.index}`,meta:e.meta,lines:s(i[t+1]),end:e.end,lastActivity:e.lastActivity})),u=c.length+l.reduce((e,t)=>e+t.lines.length,0);return{graphMeta:t,setup:c,segments:l,maxIteration:n,totalLines:u,...r?{completion:r}:{}}}function Mt(e,t){return e.end?e.end.status:t.isLast||e.meta.attemptId?t.jobSettled?`interrupted`:`running`:`unknown`}function Nt(e){return e===`continue`?0:e===`stop`?2:1}function Pt(e){let t=new Map(e.nodes.map(e=>[e.id,e])),n=new Set,r=[],i=a=>{if(n.has(a))return;let o=t.get(a);if(!o)return;n.add(a),r.push(o);let s=e.edges.filter(e=>e.source===a).slice().sort((e,t)=>Nt(e.branch)-Nt(t.branch));for(let e of s)i(e.target)},a=e.nodes.find(e=>e.type===`start`);a&&i(a.id);for(let t of e.nodes)i(t.id);return r}function Ft(e){let t=e.data?.label;return typeof t==`string`&&t.trim()?t.trim():null}function It(e,t){let n=e.segments.length-1,r=new Map,i=new Map;e.segments.forEach((e,t)=>{let n=At(e);r.set(n,{seg:e,idx:t}),e.meta.kind===`decider`&&e.end?.decision&&i.set(n,e.end.decision)});let a=e=>{let r=Mt(e.seg,{isLast:e.idx===n,jobSettled:t.jobSettled});return r===`unknown`?`ok`:r===`stalled`?`failed`:r};if(e.graphMeta)return Pt(e.graphMeta.graph).map(e=>{if(e.type===`start`)return{key:e.id,kind:`start`,label:Ft(e),state:`ok`,latestSegmentKey:null};if(e.type===`end`)return{key:e.id,kind:`end`,label:Ft(e),state:t.jobSettled?t.jobFailed?`failed`:`ok`:`pending`,latestSegmentKey:null};let n=r.get(e.id);return n?{key:e.id,kind:e.type,label:Ft(e)??kt(n.seg.meta),state:a(n),decision:e.type===`decider`?i.get(e.id):void 0,latestSegmentKey:n.seg.key}:{key:e.id,kind:e.type,label:Ft(e),state:`pending`,latestSegmentKey:null}});let o=[],s=new Map;return e.segments.forEach((e,t)=>{let n=At(e),r={seg:e,idx:t},c=s.get(n),l=e.meta.kind===`decider`?i.get(n):void 0;if(c!=null){let t=o[c];t.state=a(r),t.decision=l,t.latestSegmentKey=e.key}else s.set(n,o.length),o.push({key:n,kind:e.meta.kind,label:kt(e.meta)||null,state:a(r),decision:l,latestSegmentKey:e.key})}),o}function Lt(e){if(!Number.isFinite(e)||e<0)return`—`;if(e<1e3)return`${Math.round(e)}ms`;let t=e/1e3;if(t<60)return`${t.toFixed(1)}s`;let n=Math.floor(t/60),r=Math.round(t%60);return n<60?`${n}m ${r}s`:`${Math.floor(n/60)}h ${n%60}m`}function Rt({topology:e,segments:t,settled:n,onFocus:r,onFork:i,forkBusy:a}){let{t:s}=o(`jobs`),c=ge(),[l,u]=(0,G.useState)(!1),[p,m]=(0,G.useState)(!1),[h,g]=(0,G.useState)([]),[_,v]=(0,G.useState)(null),b=h[h.length-1]??{path:``,body:e},S=e=>b.path?`${b.path}/${e}`:e,C=t.filter(e=>(e.meta.nodePath??e.meta.nodeId)===_),w=(0,G.useMemo)(()=>{let e=b.body.nodes.flatMap(e=>Object.entries(e.ends).flatMap(([t,n])=>n===null?[]:[{id:`${e.id}:${t}`,source:e.id,target:n,label:t,markerEnd:{type:we.ArrowClosed}}])),r=new Map;for(let e of t){let t=e.meta.nodePath??e.meta.nodeId;if(!t)continue;let n=r.get(t)??new Map;n.set(e.meta.scopeId??`legacy`,e),r.set(t,n)}let i=b.body.nodes.map(e=>{let i=b.path?`${b.path}/${e.id}`:e.id,a=[...(r.get(i)??new Map).values()].map(e=>Mt(e,{isLast:e===t[t.length-1],jobSettled:n})),o=[`running`,`paused`,`failed`,`stalled`,`interrupted`].find(e=>a.includes(e))??(a.length?a.every(e=>e===`ok`)?`ok`:`unknown`:`pending`),c=o===`running`?`var(--color-accent-primary)`:o===`ok`?`var(--color-accent-success)`:o===`failed`?`var(--color-destructive)`:[`paused`,`stalled`,`interrupted`].includes(o)?`var(--color-accent-warning)`:`var(--color-border)`,l=o===`running`?x:o===`ok`?B:o===`failed`?y:[`paused`,`stalled`,`interrupted`].includes(o)?Me:o===`unknown`?d:f;return{id:e.id,type:`default`,position:{x:0,y:0},data:{kind:`core`,label:(0,K.jsxs)(`span`,{className:`block text-left`,"data-state":o,children:[(0,K.jsxs)(`strong`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(l,{"aria-hidden":!0,className:`h-4 w-4 shrink-0 ${o===`running`?`motion-safe:animate-spin`:``}`,style:{color:o===`pending`||o===`unknown`?`var(--color-muted-foreground)`:c}}),e.label]}),(0,K.jsxs)(`span`,{className:`mt-1 block text-[10px]`,children:[e.kind,` · `,s(`loopExplorer.graphState.${o}`)]})]})},style:{background:o===`pending`||o===`unknown`?`var(--color-background)`:`color-mix(in srgb, ${c} 12%, var(--color-background))`,color:`var(--color-foreground)`,borderColor:c,borderWidth:o===`pending`||o===`unknown`?1:2,boxShadow:o===`running`?`0 0 0 2px color-mix(in srgb, ${c} 30%, transparent), 0 0 22px color-mix(in srgb, ${c} 35%, transparent)`:void 0}}});return i.sort((e,t)=>e.id===b.body.entry?-1:+(t.id===b.body.entry)),{nodes:Ee(i,e,`vertical`),edges:e}},[b.body,b.path,t,n,s]),T=b.body.nodes.find(e=>S(e.id)===_),E=T?.component?e.components[T.component]:void 0,D=e=>(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2 py-2 text-xs`,children:[h.length>0&&(0,K.jsx)(L,{size:`sm`,variant:`ghost`,onClick:()=>{g(e=>e.slice(0,-1)),v(null)},children:s(`loopExplorer.graphBack`)}),(0,K.jsx)(`code`,{children:b.path||`/`}),e?(0,K.jsx)(A,{asChild:!0,children:(0,K.jsx)(L,{className:`ml-auto`,size:`sm`,variant:`ghost`,"aria-label":s(`loopExplorer.graphExitFullscreen`),title:s(`loopExplorer.graphExitFullscreen`),children:(0,K.jsx)(pe,{className:`h-4 w-4`})})}):(0,K.jsx)(N,{asChild:!0,children:(0,K.jsx)(L,{className:`ml-auto`,size:`sm`,variant:`ghost`,"aria-label":s(`loopExplorer.graphFullscreen`),title:s(`loopExplorer.graphFullscreen`),children:(0,K.jsx)(te,{className:`h-4 w-4`})})})]}),(0,K.jsx)(`div`,{className:e?`min-h-0 flex-1 rounded border border-border`:`h-72 rounded border border-border`,"aria-label":s(`loopExplorer.runtimeGraph`),children:(0,K.jsxs)(Se,{colorMode:c.scheme===`dark`?`dark`:`light`,nodes:w.nodes,edges:w.edges,nodesDraggable:!1,nodesConnectable:!1,edgesReconnectable:!1,deleteKeyCode:null,fitView:!0,minZoom:.1,onNodeClick:(e,t)=>v(S(t.id)),children:[(0,K.jsx)(Ce,{}),(0,K.jsx)(Te,{showInteractive:!1})]},`${b.path}:${e}`)}),_&&(0,K.jsxs)(`div`,{className:`shrink-0 space-y-2 py-2 text-xs`,children:[(0,K.jsx)(`code`,{className:`break-all`,children:_}),E&&h.length<16&&(0,K.jsx)(L,{size:`sm`,variant:`outline`,onClick:()=>{g(e=>[...e,{path:_,body:E}]),v(null)},children:s(`loopExplorer.graphOpenComponent`)}),C.length===0?(0,K.jsx)(`p`,{children:s(`loopExplorer.graphNoAttempts`)}):(0,K.jsx)(`ul`,{className:`max-h-40 space-y-1 overflow-auto`,children:C.map(e=>(0,K.jsxs)(`li`,{children:[(0,K.jsxs)(`button`,{className:`text-left underline underline-offset-2`,onClick:()=>r(e.key),children:[e.meta.scopeId??`/`,` · `,e.meta.attemptId??e.meta.index,` · `,s(`loopExplorer.graphState.${Mt(e,{isLast:!0,jobSettled:n})}`)]}),i&&e.end&&e.meta.nodePath&&e.meta.scopeId&&e.meta.iteration!=null&&(0,K.jsx)(L,{className:`ml-2`,size:`sm`,variant:`outline`,disabled:a,onClick:()=>i(e),children:s(`loopExplorer.repeatFromHere`)}),e.meta.traceId&&(0,K.jsxs)(`code`,{className:`block break-all text-[10px] text-muted-foreground`,children:[`traceId: `,e.meta.traceId,e.meta.spanId?` · spanId: ${e.meta.spanId}`:``]})]},e.key))})]})]});return(0,K.jsxs)(M,{open:p,onOpenChange:m,children:[(0,K.jsxs)(`details`,{className:`shrink-0 border-b border-border p-2`,onToggle:e=>u(e.currentTarget.open),children:[(0,K.jsx)(`summary`,{className:`cursor-pointer text-xs font-medium`,children:s(`loopExplorer.runtimeGraph`)}),l&&D(!1)]}),(0,K.jsxs)(j,{overlayClassName:`z-[2147483646]`,className:`z-[2147483647] flex w-screen max-w-none !max-h-none flex-col gap-0 rounded-none p-3 sm:rounded-none`,style:{height:`calc(100dvh - ${O()}px)`},showCloseButton:!1,"aria-describedby":void 0,children:[(0,K.jsx)(k,{className:`shrink-0 text-sm`,children:s(`loopExplorer.runtimeGraph`)}),D(!0)]})]})}function zt({result:e}){let{t}=o(`jobs`),{t:n}=o(`loops`),r=e.core,i=e=>t(`completion.status.${e}`,{defaultValue:e});return(0,K.jsxs)(`section`,{"aria-label":t(`completion.title`),className:`border-b border-border/40 px-4 py-3 text-xs space-y-2`,"data-testid":`loop-completion`,children:[(0,K.jsxs)(`p`,{className:`font-medium`,children:[t(`completion.execution`),`: `,i(e.execution)]}),e.completion?(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(`p`,{className:e.completion.ok?`text-accent-success`:`text-accent-warning`,children:[n(`core.acceptance`),`: `,i(e.completion.ok?`complete`:`blocked`)]}),(0,K.jsxs)(`p`,{children:[n(`core.verified`),`: `,i(e.completion.verified?`verified`:`unverified`)]}),e.completion.reasons.map((e,t)=>(0,K.jsx)(`p`,{className:`text-foreground/70`,children:e},t))]}):r?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(`dl`,{className:`grid grid-cols-2 gap-2 md:grid-cols-4`,children:[`implementation`,`validation`,`archive`,`delivery`].map(e=>(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`dt`,{className:`text-foreground/70`,children:t(`completion.${e}`)}),(0,K.jsx)(`dd`,{className:r.completion[e]===`with-exceptions`||r.completion[e]===`blocked`?`text-accent-warning font-medium`:`font-medium`,children:i(r.completion[e])})]},e))}),(0,K.jsxs)(`details`,{children:[(0,K.jsx)(`summary`,{className:`cursor-pointer`,children:t(`completion.evidence`)}),(0,K.jsxs)(`div`,{className:`space-y-2 pt-2 break-words`,children:[(0,K.jsx)(`p`,{className:`text-foreground/70`,children:t(`completion.snapshot`,{change:r.change,at:r.recordedAt})}),r.completion.reasons.map((e,t)=>(0,K.jsx)(`p`,{children:e},`reason-${t}`)),r.exceptions.map((e,n)=>(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`p`,{className:`font-medium`,children:e.requirement}),(0,K.jsxs)(`p`,{children:[e.reason,` — `,e.impact]}),(0,K.jsxs)(`p`,{children:[t(`completion.acceptedBy`,{by:e.acceptedBy}),`: `,e.approvalEvidence]})]},`exception-${n}`)),r.checks.map((e,n)=>(0,K.jsxs)(`div`,{children:[(0,K.jsxs)(`p`,{className:`font-medium`,children:[e.name,`: `,i(e.status),` (`,t(e.required?`completion.required`:`completion.supplementary`),`)`]}),(0,K.jsxs)(`p`,{children:[e.scope,` — `,e.limitations]}),(0,K.jsx)(`p`,{className:`text-foreground/70`,children:e.evidence.join(`; `)})]},`check-${n}`)),r.findings.map((e,t)=>(0,K.jsx)(`p`,{children:e},`finding-${t}`)),r.phases.map(e=>(0,K.jsxs)(`p`,{children:[e.name,`: `,i(e.status),` · `,e.durationMs==null?t(`completion.unavailable`):`${(e.durationMs/1e3).toFixed(1)}s`,` · `,e.attempts==null?t(`completion.unavailable`):t(`completion.attempts`,{count:e.attempts})]},e.name)),(0,K.jsx)(`p`,{className:`text-foreground/70`,children:t(`completion.phaseCostUnavailable`)})]})]})]}):(0,K.jsx)(`p`,{className:`text-foreground/70`,children:t(`completion.noCoreEvidence`)})]})}var Bt={start:S,"ai-step":ce,shell:de,decider:b,condition:b,end:xe},Vt=C,Ht={start:`text-accent-success`,"ai-step":`text-accent-primary`,shell:`text-accent-warning`,decider:`text-accent-highlight`,condition:`text-accent-info`,end:`text-accent-secondary`},Ut={start:`border-accent-success/60`,"ai-step":`border-accent-primary/60`,shell:`border-accent-warning/60`,decider:`border-accent-highlight/60`,condition:`border-accent-info/60`,end:`border-accent-secondary/60`};function Wt(e){return Bt[e]??Vt}function Gt({chips:e,iteration:t,onChipClick:n,variant:r}){let{t:i}=o(`jobs`);return e.length===0&&!t?null:(0,K.jsxs)(`div`,{"data-testid":`loop-overview-strip`,role:`list`,"aria-label":i(`loopExplorer.stepMapAria`),className:P(`flex items-center gap-1 overflow-x-auto border-b border-border/30 bg-surface/20`,r===`glass`?`px-3 py-1.5`:`px-4 py-2`),children:[e.map((e,t)=>{let r=Wt(e.kind),a=Ht[e.kind]??`text-foreground`,o=Ut[e.kind]??`border-border/40`,s=e.label??i(`loops:builder.nodes.${e.kind}`,{defaultValue:e.kind}),c=e.latestSegmentKey!=null;return(0,K.jsxs)(G.Fragment,{children:[t>0&&(0,K.jsx)(v,{className:`w-3 h-3 text-muted-foreground/30 shrink-0`}),(0,K.jsxs)(`button`,{type:`button`,role:`listitem`,"data-testid":`loop-node-chip`,"data-state":e.state,"data-kind":e.kind,"data-decision":e.decision,"aria-label":`${s} — ${e.state}`,disabled:!c,onClick:()=>e.latestSegmentKey&&n(e.latestSegmentKey),className:P(`relative flex items-center gap-1.5 shrink-0 rounded-full border bg-surface/40 px-2.5 py-1 text-[11px] transition-colors`,o,e.state===`pending`&&`opacity-45 border-border/40`,(e.state===`interrupted`||e.state===`paused`)&&`border-dashed border-accent-warning/50`,c?`cursor-pointer hover:bg-surface/70`:`cursor-default`),children:[e.state===`running`&&(0,K.jsx)(`span`,{"aria-hidden":!0,className:`absolute -inset-px rounded-full ring-2 ring-accent-primary/50 motion-safe:animate-pulse pointer-events-none`}),(0,K.jsx)(r,{className:P(`w-3 h-3 shrink-0`,a)}),(0,K.jsx)(`span`,{className:P(`max-w-[120px] truncate font-medium text-foreground/90`,e.state===`running`&&`title-shimmer`),children:s}),e.state===`paused`&&(0,K.jsx)(`span`,{className:`text-accent-warning`,children:i(`loopExplorer.paused`)}),e.state===`ok`&&(0,K.jsx)(_,{className:`w-3 h-3 text-accent-success shrink-0`}),e.state===`failed`&&(0,K.jsx)(D,{className:`w-3 h-3 text-destructive shrink-0`}),e.decision===`continue`&&(0,K.jsx)(p,{className:`w-3 h-3 text-accent-highlight shrink-0`}),e.decision===`stop`&&(0,K.jsx)(m,{className:`w-3 h-3 text-accent-success shrink-0`})]})]},e.key)}),t&&(0,K.jsxs)(`span`,{"data-testid":`loop-iteration-chip`,className:`ml-auto flex items-center gap-1.5 shrink-0 rounded-full border border-accent-highlight/40 bg-accent-highlight/10 px-2.5 py-1 text-[10px] font-medium text-accent-highlight tabular-nums`,children:[(0,K.jsx)(re,{className:`w-3 h-3`}),t.limit==null?i(`loopExplorer.iterationBadge`,{count:t.current}):i(`loopExplorer.iteration`,{current:t.current,limit:t.limit})]})]})}var Kt=(0,G.memo)(Gt);function qt({className:e}){return(0,K.jsxs)(`span`,{className:P(`relative flex h-2 w-2 shrink-0`,e),children:[(0,K.jsx)(`span`,{className:`motion-safe:animate-ping absolute inline-flex h-full w-full rounded-full bg-accent-primary opacity-60`}),(0,K.jsx)(`span`,{className:`relative inline-flex rounded-full h-2 w-2 bg-accent-primary`})]})}function Jt(e,t){if(!t)return e;let n=t.toLowerCase();return e.filter(e=>e.content.toLowerCase().includes(n))}function Yt(e,t,n,r){return e.length===0?(0,K.jsx)(`p`,{className:`px-4 py-2 text-[10px] text-muted-foreground/40 italic`,children:n(t?`logViewer.noMatchingLines`:`logViewer.noOutput`)}):e.map((e,t)=>(0,K.jsx)(bt,{line:e,even:t%2==0,onOpenTicket:r},e.id))}function Xt({label:e,value:t,copyLabel:n}){let[r,i]=(0,G.useState)(!1),a=async()=>{try{await navigator.clipboard.writeText(t),i(!0),window.setTimeout(()=>i(!1),1500)}catch{}};return(0,K.jsxs)(`div`,{className:`min-w-0`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,K.jsx)(`span`,{className:`text-[9px] font-semibold uppercase tracking-wider text-muted-foreground/50`,children:e}),(0,K.jsx)(`button`,{type:`button`,onClick:()=>void a(),"aria-label":`${n} — ${e}`,title:n,className:`p-0.5 text-muted-foreground/40 hover:text-foreground transition-colors cursor-pointer`,children:r?(0,K.jsx)(_,{className:`w-2.5 h-2.5 text-accent-success`}):(0,K.jsx)(V,{className:`w-2.5 h-2.5`})})]}),(0,K.jsx)(`pre`,{className:`mt-0.5 text-[10px] font-mono leading-relaxed text-foreground/75 whitespace-pre-wrap break-words`,children:t})]})}function Zt({segment:e,status:t,collapsed:n,filter:r,onToggle:i,onCopy:a,setRef:s,onOpenTicket:c}){let{t:l}=o(`jobs`),{meta:u,lines:d,end:f,lastActivity:p}=e,m=Wt(u.kind),h=Ht[u.kind]??`text-foreground`,g=Jt(d,r),y=t===`running`,b=!!(u.template||u.command),[x,S]=(0,G.useState)(!1);return(0,K.jsxs)(`div`,{ref:t=>s(e.key,t),"data-testid":`loop-step-section`,"data-status":t,"data-step-index":u.index,className:P(`mt-3 rounded-md overflow-hidden border animate-in fade-in duration-200`,t===`running`&&`border-accent-primary/40`,t===`failed`&&`border-destructive/30`,t===`stalled`&&`border-dashed border-destructive/40`,(t===`interrupted`||t===`paused`)&&`border-dashed border-accent-warning/40`,(t===`ok`||t===`unknown`)&&`border-border/20`),children:[(0,K.jsxs)(`div`,{className:P(`flex items-stretch bg-primary/5 border-b`,t===`failed`||t===`stalled`?`border-destructive/20`:`border-primary/20`),children:[(0,K.jsxs)(`button`,{type:`button`,onClick:()=>i(e.key),className:`flex items-center gap-2 flex-1 min-w-0 text-left px-3 py-2 hover:bg-primary/10 transition-colors duration-150 cursor-pointer`,children:[(0,K.jsx)(v,{className:P(`w-3 h-3 text-primary/60 shrink-0 transition-transform duration-150`,!n&&`rotate-90`)}),(0,K.jsx)(`span`,{className:`text-[10px] font-mono tabular-nums text-muted-foreground/60 shrink-0 w-5 text-right`,children:u.index}),(0,K.jsx)(m,{className:P(`w-3.5 h-3.5 shrink-0`,h)}),(0,K.jsx)(`span`,{className:`text-[12px] font-semibold text-foreground leading-none truncate`,children:kt(u)}),u.branch&&(0,K.jsx)(`span`,{className:`max-w-40 truncate font-mono text-[10px] text-muted-foreground`,title:u.scopeId,children:u.branch}),t===`paused`&&(0,K.jsx)(`span`,{className:`text-[10px] text-accent-warning`,children:l(`loopExplorer.paused`,{defaultValue:`Paused`})}),u.iteration!=null&&u.iteration>=1&&(0,K.jsx)(`span`,{className:`shrink-0 rounded-full bg-muted/60 px-1.5 py-0.5 text-[9px] font-medium text-muted-foreground tabular-nums`,children:l(`loopExplorer.iterationBadge`,{count:u.iteration})}),y&&(0,K.jsxs)(`span`,{className:`flex items-center gap-1.5 min-w-0 shrink-0 max-w-[40%]`,children:[(0,K.jsx)(qt,{}),p&&(0,K.jsx)(`span`,{className:`title-shimmer text-[10px] truncate`,children:l(`statusPanel.activity.${p.actionKey}`,{arg:p.actionArg??``})})]}),t===`ok`&&(0,K.jsx)(_,{className:`w-3.5 h-3.5 text-accent-success shrink-0`}),t===`failed`&&f?.reason===`provider_limit`&&(0,K.jsx)(`span`,{className:`shrink-0 rounded border border-dashed border-destructive/50 px-1.5 py-0.5 text-[9px] font-medium uppercase tracking-wide text-destructive`,title:l(`loopExplorer.providerLimitHint`),"data-testid":`loop-step-provider-limit`,children:l(`loopExplorer.providerLimit`)}),t===`failed`&&(0,K.jsx)(D,{className:`w-3.5 h-3.5 text-destructive shrink-0`}),t===`stalled`&&(0,K.jsx)(`span`,{className:`shrink-0 rounded border border-dashed border-destructive/50 px-1.5 py-0.5 text-[9px] font-medium uppercase tracking-wide text-destructive`,title:f?.idleMs==null?void 0:l(`loopExplorer.stalledIdle`,{count:Math.max(1,Math.round(f.idleMs/6e4))}),children:l(`loopExplorer.stalled`)}),t===`interrupted`&&(0,K.jsx)(`span`,{className:`shrink-0 rounded border border-dashed border-accent-warning/50 px-1.5 py-0.5 text-[9px] font-medium uppercase tracking-wide text-accent-warning`,children:l(`loopExplorer.interrupted`)}),(0,K.jsx)(`span`,{className:`flex-1`}),f?.durationMs!=null&&(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground/50 font-mono tabular-nums shrink-0`,children:Lt(f.durationMs)}),t===`failed`&&f?.exitCode!=null&&f.exitCode!==0&&(0,K.jsx)(`span`,{className:`text-[10px] text-destructive/70 font-mono shrink-0`,children:l(`activeJob.exitCode`,{code:f.exitCode})}),(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground/40 shrink-0`,children:l(`logViewer.phaseLines`,{count:d.length})})]}),b&&(0,K.jsx)(`button`,{type:`button`,onClick:()=>S(e=>!e),"aria-label":l(`loopExplorer.stepDetail`),"aria-expanded":x,title:l(`loopExplorer.stepDetail`),className:P(`px-2 flex items-center transition-colors cursor-pointer`,x?`text-foreground bg-primary/10`:`text-muted-foreground/40 hover:text-foreground hover:bg-primary/10`),children:(0,K.jsx)(ae,{className:`w-3 h-3`})}),(0,K.jsx)(`button`,{type:`button`,onClick:()=>a(e.key),"aria-label":l(`loopExplorer.copyStep`),title:l(`loopExplorer.copyStep`),className:`px-2.5 flex items-center text-muted-foreground/40 hover:text-foreground hover:bg-primary/10 transition-colors cursor-pointer`,children:(0,K.jsx)(V,{className:`w-3 h-3`})})]}),x&&b&&(0,K.jsxs)(`div`,{"data-testid":`loop-step-detail`,className:P(`px-4 py-2.5 space-y-2.5 bg-muted/10 border-b animate-in fade-in duration-150`,t===`failed`?`border-destructive/20`:`border-primary/10`),children:[u.template&&(0,K.jsx)(Xt,{label:l(`loopExplorer.stepDetailTemplate`),value:u.template,copyLabel:l(`loopExplorer.copyCommand`)}),u.command&&(0,K.jsx)(Xt,{label:l(`loopExplorer.stepDetailCommand`),value:u.command,copyLabel:l(`loopExplorer.copyCommand`)})]}),!n&&(0,K.jsx)(`div`,{className:`bg-muted/5`,children:Yt(g,r,l,c)})]})}var Qt=(0,G.memo)(Zt,(e,t)=>e.segment.key===t.segment.key&&e.segment.lines.length===t.segment.lines.length&&e.segment.lines[e.segment.lines.length-1]?.content===t.segment.lines[t.segment.lines.length-1]?.content&&e.segment.meta.template===t.segment.meta.template&&e.segment.meta.command===t.segment.meta.command&&e.segment.end?.status===t.segment.end?.status&&e.segment.end?.durationMs===t.segment.end?.durationMs&&e.segment.end?.decision===t.segment.end?.decision&&e.segment.end?.exitCode===t.segment.end?.exitCode&&e.segment.lastActivity?.actionKey===t.segment.lastActivity?.actionKey&&e.segment.lastActivity?.actionArg===t.segment.lastActivity?.actionArg&&e.status===t.status&&e.collapsed===t.collapsed&&e.filter===t.filter&&e.onOpenTicket===t.onOpenTicket),$t=`__setup__`;function en({lines:e,collapsed:t,filter:n,onToggle:r,setRef:i,onOpenTicket:a}){let{t:s}=o(`jobs`),c=Jt(e,n);return(0,K.jsxs)(`div`,{ref:e=>i($t,e),"data-testid":`loop-setup-section`,className:`rounded-md overflow-hidden border border-border/20`,children:[(0,K.jsxs)(`button`,{type:`button`,onClick:()=>r($t),className:`flex items-center gap-2 w-full text-left px-3 py-2 bg-muted/10 border-b border-border/20 hover:bg-muted/20 transition-colors duration-150 cursor-pointer`,children:[(0,K.jsx)(v,{className:P(`w-3 h-3 text-muted-foreground/60 shrink-0 transition-transform duration-150`,!t&&`rotate-90`)}),(0,K.jsx)(S,{className:`w-3.5 h-3.5 text-accent-success/70 shrink-0`}),(0,K.jsx)(`span`,{className:`text-[11px] font-semibold text-muted-foreground leading-none uppercase tracking-wide`,children:s(`loopExplorer.setup`)}),(0,K.jsx)(`span`,{className:`flex-1`}),(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground/40 shrink-0`,children:s(`logViewer.phaseLines`,{count:e.length})})]}),!t&&(0,K.jsx)(`div`,{className:`bg-muted/5`,children:Yt(c,n,s,a)})]})}var tn=(0,G.memo)(en,(e,t)=>e.lines.length===t.lines.length&&e.lines[e.lines.length-1]?.content===t.lines[t.lines.length-1]?.content&&e.collapsed===t.collapsed&&e.filter===t.filter&&e.onOpenTicket===t.onOpenTicket);function nn(e,t){let{t:n}=o(`jobs`),[r,i]=(0,G.useState)(!1),[a,s]=(0,G.useState)(``),[l,u]=(0,G.useState)(null),d=`${t??`active`}:${e??``}`,f=(0,G.useRef)(d),p=(0,G.useRef)(!1);f.current=d,(0,G.useEffect)(()=>(f.current=d,i(!1),s(``),u(null),p.current=!1,()=>{f.current=``}),[d]);async function m(r){if(!e||p.current||!r.meta.nodePath||!r.meta.scopeId||!r.meta.iteration)return;let a=d;p.current=!0,i(!0),s(``);try{let i=`${t?R(t):c()}/loop-runs/${encodeURIComponent(e)}`,o=await fetch(`${i}/recovery`,{cache:`no-store`});if(!o.ok)throw Error(n(`loopExplorer.forkFailed`));let s=await o.json();if(f.current!==a)return;if(s.forkAdopted&&s.forkRunId){u(s.forkRunId);return}let l={fromNodePath:r.meta.nodePath,scopeId:r.meta.scopeId,visit:r.meta.iteration};if(s.forkRequest&&(s.forkRequest.fromNodePath!==l.fromNodePath||s.forkRequest.scopeId!==l.scopeId||s.forkRequest.visit!==l.visit))throw Error(n(`loopExplorer.forkPending`));let d=s.forkRequest??{...l,requestId:crypto.randomUUID()},p=await fetch(`${i}/fork`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(d)}),m=await p.json();if(!p.ok||!m.loopRunId)throw Error(m.detail??n(`loopExplorer.forkFailed`));f.current===a&&u(m.loopRunId)}catch(e){f.current===a&&s(e instanceof Error?e.message:n(`loopExplorer.forkFailed`))}finally{f.current===a&&(p.current=!1,i(!1))}}return{busy:r,error:a,created:l,fork:m}}function rn(){return(0,K.jsxs)(`span`,{className:`relative flex h-1.5 w-1.5 shrink-0`,children:[(0,K.jsx)(`span`,{className:`motion-safe:animate-ping absolute inline-flex h-full w-full rounded-full bg-accent-primary opacity-60`}),(0,K.jsx)(`span`,{className:`relative inline-flex rounded-full h-1.5 w-1.5 bg-accent-primary`})]})}function an({events:e,jobStatus:t,isLoading:n,variant:r=`page`,projectId:i,onOpenRun:a}){let{t:s,i18n:c}=o(`jobs`),[d,f]=(0,G.useState)(``),[p,m]=(0,G.useState)(`follow`),[h,g]=(0,G.useState)(new Set),_=(0,G.useRef)(null),v=(0,G.useRef)(new Map),y=ut(i),{activeProjectId:b}=l(),x=nn(e[0]?.job_id,i??b??void 0),S=(0,G.useMemo)(()=>jt(e),[e,c.language]),C=t!=null&&t!==`running`&&t!==`queued`,w=t===`running`,E=(0,G.useMemo)(()=>S.segments.map((e,t)=>Mt(e,{isLast:t===S.segments.length-1,jobSettled:C})),[S,C]),D=(0,G.useMemo)(()=>{let e=S.segments.map(e=>e.key);return S.setup.length>0&&e.push($t),e},[S]),O=S.segments.length>0?S.segments[S.segments.length-1].key:$t,k=(0,G.useMemo)(()=>d?new Set(D):p===`follow`?new Set([O]):h,[d,p,O,h,D]),A=(0,G.useRef)(k);A.current=k;let j=(0,G.useRef)(S);j.current=S;let M=(0,G.useCallback)(e=>{let t=new Set(A.current);e?.(t),g(t),m(`manual`)},[]),N=(0,G.useCallback)(e=>{M(t=>{t.has(e)?t.delete(e):t.add(e)})},[M]),F=(0,G.useCallback)(e=>{M(t=>t.add(e)),requestAnimationFrame(()=>{v.current.get(e)?.scrollIntoView?.({behavior:`smooth`,block:`start`})})},[M]),I=(0,G.useCallback)(()=>{let e=_.current;e&&(e.scrollTop=e.scrollHeight)},[]),R=(0,G.useCallback)(()=>{m(`follow`),requestAnimationFrame(I)},[I]),ee=(0,G.useCallback)(()=>{g(new Set(D)),m(`manual`)},[D]),z=(0,G.useCallback)(()=>{g(new Set),m(`manual`)},[]);(0,G.useEffect)(()=>{p===`follow`&&!d&&I()},[S.totalLines,S.segments.length,p,d,I]);let te=(0,G.useCallback)(()=>{let e=_.current;!e||p!==`follow`||e.scrollHeight-e.scrollTop-e.clientHeight>80&&M()},[p,M]),ne=(0,G.useCallback)((e,t)=>{t?v.current.set(e,t):v.current.delete(e)},[]),re=(0,G.useCallback)(e=>{let t=j.current.segments.find(t=>t.key===e),n=e===`__setup__`?j.current.setup.map(e=>e.content).join(`
17
- `):(t?.lines??[]).map(e=>e.content).join(`
18
- `);navigator.clipboard.writeText(n).then(()=>u.success(s(`loopExplorer.copied`))).catch(()=>u.error(s(`logViewer.copyFailed`)))},[s]),ie=(0,G.useCallback)(()=>{let e=j.current,t=e.setup.map(e=>e.content);for(let n of e.segments){t.push(`── Step ${n.meta.index} · ${Ot(n.meta.title)} ──`);for(let e of n.lines)t.push(e.content)}navigator.clipboard.writeText(t.join(`
19
- `)).then(()=>u.success(s(`logViewer.copySuccess`))).catch(()=>u.error(s(`logViewer.copyFailed`)))},[s]),B=(0,G.useMemo)(()=>It(S,{jobSettled:C,jobFailed:t===`failed`}),[S,C,t]),H=S.graphMeta?.iterationLimit??S.graphMeta?.graph.config.maxIterations??null,ae=S.maxIteration>0?{current:S.maxIteration,limit:H}:null,U=(0,G.useMemo)(()=>{if(!d)return S.totalLines;let e=d.toLowerCase(),t=S.setup.filter(t=>t.content.toLowerCase().includes(e)).length;for(let n of S.segments)t+=n.lines.filter(t=>t.content.toLowerCase().includes(e)).length;return t},[d,S]),oe=S.segments[S.segments.length-1],W=w&&(S.segments.length===0||oe?.end!=null);return n?(0,K.jsx)(`div`,{className:`flex-1 flex items-center justify-center h-full`,children:(0,K.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:s(`logViewer.loading`)})}):S.totalLines===0&&S.segments.length===0?(0,K.jsx)(`div`,{"data-testid":`loop-step-explorer`,className:`flex-1 flex items-center justify-center h-full`,children:(0,K.jsxs)(`p`,{className:`text-xs text-muted-foreground flex items-center gap-2`,children:[w&&(0,K.jsx)(rn,{}),s(w?`loopExplorer.waiting`:`logViewer.empty`)]})}):(0,K.jsxs)(`div`,{"data-testid":`loop-step-explorer`,className:`relative flex min-h-0 flex-col h-full`,children:[(0,K.jsxs)(`div`,{className:P(`border-b border-border flex items-center gap-2`,r===`glass`?`px-3 py-1.5`:`px-4 py-2`),children:[(0,K.jsxs)(`div`,{className:`relative flex-1 max-w-xs`,children:[(0,K.jsx)(T,{className:`absolute left-2.5 top-1/2 -translate-y-1/2 w-3 h-3 text-muted-foreground`}),(0,K.jsx)(se,{placeholder:s(`logViewer.filterPlaceholder`),value:d,onChange:e=>f(e.target.value),className:`pl-7 h-7`})]}),(0,K.jsx)(L,{variant:`ghost`,size:`sm`,className:`h-7 px-2 text-muted-foreground/50 hover:text-foreground`,onClick:ee,"aria-label":s(`loopExplorer.expandAll`),title:s(`loopExplorer.expandAll`),children:(0,K.jsx)(Ae,{className:`w-3.5 h-3.5`})}),(0,K.jsx)(L,{variant:`ghost`,size:`sm`,className:`h-7 px-2 text-muted-foreground/50 hover:text-foreground`,onClick:z,"aria-label":s(`loopExplorer.collapseAll`),title:s(`loopExplorer.collapseAll`),children:(0,K.jsx)(ke,{className:`w-3.5 h-3.5`})}),p===`follow`&&w&&(0,K.jsxs)(`span`,{className:`flex items-center gap-1.5 text-[10px] text-accent-primary shrink-0`,children:[(0,K.jsx)(rn,{}),s(`loopExplorer.follow`)]}),(0,K.jsx)(`span`,{className:`flex-1`}),(0,K.jsx)(L,{variant:`ghost`,size:`sm`,className:`h-7 px-2 text-muted-foreground/50 hover:text-foreground`,onClick:ie,"aria-label":s(`logViewer.copySuccess`),children:(0,K.jsx)(V,{className:`w-3.5 h-3.5`})}),(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:s(`logViewer.lineCount`,{filtered:U,total:S.totalLines})})]}),S.completion&&(0,K.jsx)(`div`,{"data-testid":`loop-completion-scroll`,className:r===`glass`?`max-h-[45%] min-h-0 shrink-0 overflow-y-auto overscroll-contain`:void 0,tabIndex:r===`glass`?0:void 0,children:(0,K.jsx)(zt,{result:S.completion})}),S.graphMeta?.runtimeTopology&&(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(Rt,{topology:S.graphMeta.runtimeTopology,segments:S.segments,settled:C,onFocus:F,onFork:x.fork,forkBusy:x.busy}),x.error&&(0,K.jsx)(`p`,{role:`alert`,className:`px-2 text-xs text-destructive`,children:x.error}),x.created&&(0,K.jsxs)(`div`,{className:`p-2 text-xs`,children:[(0,K.jsx)(`p`,{children:s(`loopExplorer.forkCreated`)}),(0,K.jsx)(L,{size:`sm`,variant:`outline`,onClick:()=>a?.(x.created),disabled:!a,children:s(`loopExplorer.openFork`)}),(0,K.jsx)(`code`,{className:`ml-2`,children:x.created})]})]}),(0,K.jsx)(Kt,{chips:B,iteration:ae,onChipClick:F,variant:r}),(0,K.jsxs)(`div`,{ref:_,onScroll:te,className:`min-h-0 flex-1 overflow-y-auto p-2 text-xs`,children:[S.setup.length>0&&(0,K.jsx)(tn,{lines:S.setup,collapsed:!k.has(`__setup__`),filter:d,onToggle:N,setRef:ne,onOpenTicket:y}),S.segments.map((e,t)=>(0,K.jsx)(Qt,{segment:e,status:E[t],collapsed:!k.has(e.key),filter:d,onToggle:N,onCopy:re,setRef:ne,onOpenTicket:y},e.key)),W&&(0,K.jsxs)(`div`,{"data-testid":`loop-waiting-row`,className:`mt-3 flex items-center gap-2 px-3 py-2 text-[11px] text-muted-foreground/70 italic`,children:[(0,K.jsx)(rn,{}),s(`loopExplorer.waiting`)]})]}),p===`manual`&&w&&!d&&(0,K.jsxs)(`button`,{type:`button`,"data-testid":`resume-follow-pill`,onClick:R,className:`absolute bottom-4 left-1/2 -translate-x-1/2 z-10 flex items-center gap-1.5 rounded-full glass-card border border-accent-primary/30 px-3 py-1.5 text-[11px] font-medium text-foreground shadow-lg hover:border-accent-primary/60 transition-colors cursor-pointer animate-in fade-in slide-in-from-bottom-2 duration-200`,children:[(0,K.jsx)(rn,{}),s(`loopExplorer.resumeFollow`)]})]})}var on=new Set(`grep.rg.ag.ack.find.fd.ls.cat.head.tail.sed.awk.cut.sort.uniq.wc.jq.yq.tr.xargs.tee.column.less.more.cd.pwd.echo.printf.which.type.test.true.false.env.export.set.source.date.basename.dirname.realpath.readlink.stat.file.tree.diff.sleep.seq.hostname.whoami.uname.mkdir.rmdir.cp.mv.rm.touch.ln.chmod.chown.install.[[.[.]].].for.while.until.if.then.else.elif.fi.do.done.case.esac.exec.eval.trap.read.shift.wait`.split(`.`)),sn=new Set([`status`,`diff`,`log`,`show`,`branch`,`rev-parse`,`ls-files`,`blame`,`describe`]),cn=new Set([...sn,`commit`,`add`,`stage`,`push`,`pull`,`fetch`,`checkout`,`switch`,`merge`,`rebase`,`reset`,`stash`,`tag`,`clone`,`worktree`,`cherry-pick`,`restore`,`apply`,`init`,`remote`,`config`,`update-ref`,`for-each-ref`]),ln=new Set([`run`,`run-script`,`test`,`install`,`ci`,`i`,`add`,`exec`,`start`,`dlx`]),un=[[/^(test|tests|test:.*|vitest|jest|spec)$/,`activity.testing`],[/^(build|compile|bundle|dist)$/,`activity.building`],[/^(typecheck|tsc|types?)$/,`activity.typechecking`],[/^(lint|lint:.*|eslint|format|fmt|prettier)$/,`activity.linting`]],dn=new Set([`vitest`,`jest`,`pytest`,`mocha`,`ava`,`rspec`,`phpunit`]);function fn(e){for(let[t,n]of un)if(t.test(e))return n;return null}function pn(e){return e.split(/\s+/).map(e=>e.replace(/^['"`]+/,``).replace(/['"`]+$/,``)).filter(e=>e.length>0&&!e.startsWith(`-`))}function mn(e){let t=pn(e);if(t.length===0)return{kind:`plumbing`};let n=t[0].split(`/`).pop()??t[0],r=t.slice(1);if(on.has(n))return{kind:`plumbing`};if(dn.has(n))return{kind:`intent`,code:`activity.testing`};if((n===`npx`||n===`pnpm`||n===`yarn`||n===`bunx`)&&r.length>0){let e=r[0]===`dlx`||r[0]===`exec`?r[1]??``:r[0];if(dn.has(e))return{kind:`intent`,code:`activity.testing`};let t=fn(e===`run`?r[r.indexOf(`run`)+1]??``:e);if(t)return{kind:`intent`,code:t};if(e===`tsc`)return{kind:`intent`,code:`activity.typechecking`}}if(n===`npm`||n===`yarn`||n===`pnpm`||n===`bun`){let e=r.findIndex(e=>ln.has(e)),t=e===-1?``:r[e];if(t===`install`||t===`ci`||t===`i`||t===`add`)return{kind:`intent`,code:`activity.installing`};let i=fn(t===`run`||t===`run-script`?r[e+1]??``:t);return i?{kind:`intent`,code:i}:{kind:`named`,tool:n}}if(n===`git`){let e=r.find(e=>cn.has(e))??``;return sn.has(e)?{kind:`plumbing`}:e===`commit`||e===`add`||e===`stage`?{kind:`intent`,code:`activity.savingWork`}:{kind:`named`,tool:n}}if(n===`cargo`||n===`go`||n===`dotnet`||n===`mvn`||n===`mvnw`||n===`gradle`||n===`gradlew`){let e=r.find(e=>e===`test`||e===`build`||e===`compile`)??``;return e===`test`?{kind:`intent`,code:`activity.testing`}:e===`build`||e===`compile`?{kind:`intent`,code:`activity.building`}:{kind:`named`,tool:n}}return n===`tsc`?{kind:`intent`,code:`activity.typechecking`}:n===`openspec`?{kind:`intent`,code:`activity.checkingSpec`}:{kind:`named`,tool:n}}function hn(e){try{let t=JSON.parse(e);return t&&typeof t==`object`&&!Array.isArray(t)?t:{}}catch{return{}}}function gn(e,t){return e&&/^main-\d+$/.test(e)?`step.role.work`:e===`verify`?`step.role.verify`:e===`decide`||t===`decider`?`step.role.decide`:e===`fix`?`step.role.fix`:null}function _n(e){return e.replace(/^[^\p{L}\p{N}(]+/u,``).trim()}var Z=e=>typeof e==`number`&&Number.isFinite(e)?e:null,Q=e=>typeof e==`string`&&e.length>0?e:null,vn=new Set([`thinking`,`reasoning`]),yn=/^(MEMORY\.md|confidence-score\.json|design-confidence\.json|\d{4}-\d{2}-\d{2}-.+|feedback_.+)$/,bn=/^(proposal|design|tasks|spec|context-bundle)\.md$/,xn=new Set([`reading`,`writing`,`editing`]);function $(e,t,n,r,i,a=``){for(let t=e.length-1;t>=0;t--){let o=e[t];if(o.values.phaseBoundary===1)break;if(o.kind!==`activity`){if(o.stepIndex!==n)break;continue}if(o.stepIndex!==n)break;if((o.values.repository??``)===a&&o.values.action===r&&o.values.target===i){o.values.repeats=Number(o.values.repeats??1)+1;return}}e.push({seq:t,kind:`activity`,code:r===`intent`?i:i?`activity.${r}`:`activity.${r}Bare`,values:{action:r,target:i,repeats:1,repository:a},stepIndex:n,tone:`neutral`})}var Sn=new Set([`architect`,`developer`,`fixer`,`verify`,`reviewer`,`archive`]),Cn=3;function wn(e,t,n,r,i,a=``){for(let t=e.length-1;t>=0;t--){let o=e[t];if(o.values.phaseBoundary===1||o.stepIndex!==n)break;if(o.kind!==`activity`||(o.values.repository??``)!==a||o.values.action!==r||o.values.fileGroup!==1)continue;let s=String(o.values.allNames??``).split(`\0`).filter(Boolean),c=!!i&&!s.includes(i);c&&s.push(i),o.values.allNames=s.join(`\0`),o.values.files=s.length;let l=String(o.values.names??``).split(`, `).filter(Boolean);c&&l.length<Cn&&(l.push(i),o.values.names=l.join(`, `)),o.code=s.length>1?`activity.${r}Files`:i?`activity.${r}`:`activity.${r}Bare`,o.values.repeats=s.length>1?1:Number(o.values.repeats??1)+1;return}e.push({seq:t,kind:`activity`,code:i?`activity.${r}`:`activity.${r}Bare`,values:{action:r,target:i,names:i,allNames:i,repository:a,files:+!!i,fileGroup:1,repeats:1},stepIndex:n,tone:`neutral`})}function Tn({events:e,settled:t}){let n=[],r=new Map,i=new Set,a=null,o=!1,s=!1,c=e.some(e=>e.event_type===`workflow-event`);for(let t of e){if(t.event_type===`loop_graph`){o=!0;continue}if(t.event_type===`loop_step`){let e=hn(t.payload),i=Z(e.index);if(i===null)continue;o=!0;let s=Q(e.kind)??`ai-step`,l={index:i,title:_n(Q(e.title)??``),roleCode:c?null:gn(Q(e.nodeId),s),kind:s,iteration:Z(e.iteration),ended:!1};r.set(i,l),a=i;let u=Z(e.attempt);n.push({seq:t.seq,kind:`step-start`,code:u!==null&&u>1?`step.startResume`:l.iteration&&l.iteration>1?`step.startRetry`:`step.start`,values:{step:i,title:l.title,iteration:l.iteration??1,...u!==null&&u>1?{attempt:u}:{},...l.roleCode?{roleCode:l.roleCode}:{}},stepIndex:i,tone:`neutral`});continue}if(t.event_type===`loop_step_end`){let e=hn(t.payload),i=Z(e.index);if(i===null)continue;let a=i===null?void 0:r.get(i);a&&(a.ended=!0);let o=Q(e.status),s=Z(e.durationMs),c=Z(e.exitCode),l=Z(e.idleMs),u=o===`stalled`,d=o===`failed`||u,f=o===`failed`&&Q(e.reason)===`provider_limit`;n.push({seq:t.seq,kind:`step-end`,code:e.recovered===!0&&o===`ok`?`step.recovered`:u?`step.stalled`:f?`step.providerLimit`:d?`step.failed`:s===null?`step.done`:s>=9e4?`step.doneTimedMin`:`step.doneTimed`,values:{step:i,title:a?.title??``,seconds:s===null?0:Math.max(1,Math.round(s/1e3)),minutes:s===null?0:Math.max(1,Math.round(s/6e4)),...u?{idleMinutes:l===null?0:Math.max(1,Math.round(l/6e4))}:{},...a?.roleCode?{roleCode:a.roleCode}:{},...c===null?{}:{exitCode:c}},stepIndex:i,tone:d?`bad`:`good`});let p=Q(e.decision);(p===`continue`||p===`stop`)&&n.push({seq:t.seq,kind:`decision`,code:p===`continue`?`decision.another`:`decision.satisfied`,values:{step:i},stepIndex:i,tone:p===`continue`?`neutral`:`good`});continue}if(t.event_type===`runtime-efficiency-event`){let e=hn(t.payload),r=e.payload&&typeof e.payload==`object`&&!Array.isArray(e.payload)?e.payload:{},o=Q(e.eventId),s=Q(e.kind);if(e.schemaVersion!==1||!o||i.has(o))continue;i.add(o);let c=Q(r.label),l=Q(r.repositoryId);if(!c||!l||c.length>256||l.length>256)continue;let u=s===`check-started`?`started`:s===`check-reused`?`reused`:s===`check-invalidated`?`invalidated`:s===`check-finished`&&typeof r.exitCode==`number`?r.exitCode===0?`passed`:`failed`:null;u&&n.push({seq:t.seq,kind:`activity`,code:`activity.check.${u}`,values:{target:c,repository:l},stepIndex:a,tone:u===`failed`?`bad`:`neutral`});continue}if(t.event_type===`workflow-event`){let e=hn(t.payload),r=e.event&&typeof e.event==`object`&&!Array.isArray(e.event)?e.event:{},i=Q(r.type),o=Q(r.stepId);if(i===`workflow_resumed`)s=!1,n.push({seq:t.seq,kind:`activity`,code:`activity.phase.resumed`,values:{phaseBoundary:1},stepIndex:a,tone:`neutral`});else if(i===`step_started`&&o&&Sn.has(o)){let e=o===`developer`&&s;o===`developer`&&(s=!0),n.push({seq:t.seq,kind:`activity`,code:e?`activity.phase.corrections`:`activity.phase.${o}`,values:{phaseBoundary:1},stepIndex:a,tone:`neutral`})}else i===`step_succeeded`&&o===`verify`&&typeof r.message!=`string`||i===`step_blocked`||(i===`workflow_failed`||i===`workflow_blocked`||i===`workflow_cancelled`)&&n.push({seq:t.seq,kind:`activity`,code:`activity.phase.stopped`,values:{action:`intent`,target:Q(r.message)??i,repeats:1},stepIndex:a,tone:`bad`});continue}let e=t.event_type===`agent-event`?hn(t.payload):{},l=Array.isArray(e.repositories)?e.repositories.map(e=>typeof e?.name==`string`?e.name:``).filter(Boolean).join(` + `):``,u=ye(t);if(!(!u.step||!u.actionKey)&&!vn.has(u.actionKey)&&!(c&&u.actionKey===`working`)){if(c&&u.actionKey===`searching`){$(n,t.seq,a,`searching`,``,l);continue}if(u.actionKey===`running`){let e=le(t),r=e?mn(e):{kind:`named`,tool:u.actionArg??``};if(r.kind===`plumbing`){$(n,t.seq,a,`exploring`,``,l);continue}if(r.kind===`intent`){$(n,t.seq,a,`intent`,r.code,l);continue}$(n,t.seq,a,`running`,c?``:r.tool,l);continue}if(xn.has(u.actionKey)){let e=u.actionArg??``;if(yn.test(e)){$(n,t.seq,a,`intent`,`activity.bookkeeping`,l);continue}if(bn.test(e)){$(n,t.seq,a,`intent`,`activity.writingSpec`,l);continue}wn(n,t.seq,a,u.actionKey,e,l);continue}$(n,t.seq,a,u.actionKey,u.actionArg??``,l)}}if(t)for(let e of r.values())e.ended||n.push({seq:2**53-1-(1e3-e.index),kind:`step-interrupted`,code:`step.interrupted`,values:{step:e.index,title:e.title},stepIndex:e.index,tone:`bad`});return{milestones:n,stepCount:r.size,plainJob:!o}}var En={"step-start":je,"step-end":_,"step-interrupted":E,decision:w,activity:je},Dn={neutral:`text-muted-foreground`,good:`text-accent-success`,bad:`text-accent-warning`};function On({events:e,settled:t,durationRange:n,elapsedMs:r,variant:i=`page`}){let{t:a}=o(`narration`),s=(0,G.useMemo)(()=>Tn({events:e,settled:t}),[e,t]),c=(0,G.useMemo)(()=>e.some(e=>e.event_type===`workflow-event`),[e]),l=(0,G.useMemo)(()=>[...s.milestones].sort((e,t)=>e.seq-t.seq),[s.milestones]);return(0,K.jsxs)(`div`,{className:i===`glass`?`flex h-full flex-col overflow-hidden`:`flex flex-col`,children:[(0,K.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 border-b border-border/50 px-3 py-2 text-[11px] text-muted-foreground`,children:[typeof r==`number`&&r>0?(0,K.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,K.jsx)(Ne,{className:`size-3`,"aria-hidden":!0}),a(`waiting.elapsed`,{minutes:Math.max(1,Math.round(r/6e4))})]}):null,n?(0,K.jsx)(`span`,{"data-testid":`narration-range`,children:a(`waiting.range`,{low:Math.max(1,Math.round(n.p25Ms/6e4)),high:Math.max(1,Math.round(n.p75Ms/6e4)),count:n.sampleCount})}):null,(0,K.jsx)(`span`,{className:`ml-auto italic opacity-70`,children:a(`aiNote`)})]}),(0,K.jsx)(`ol`,{className:`flex-1 space-y-1 px-3 py-2 ${i===`glass`?`overflow-y-auto`:``}`,"data-testid":`narration-list`,children:l.length===0?(0,K.jsx)(`li`,{className:`py-6 text-center text-xs text-muted-foreground`,children:a(t?`emptySettled`:`emptyLive`)}):l.map((e,t)=>{let n=En[e.kind],r=e.kind===`step-start`||e.kind===`step-end`||e.kind===`step-interrupted`,i=Number(e.values.files??0)>1||c?1:Number(e.values.repeats??1);return(0,K.jsxs)(`li`,{className:`flex items-start gap-2 text-sm ${r||e.values.phaseBoundary===1?`font-medium text-foreground`:`text-muted-foreground`} ${e.kind===`step-start`&&t>0?`pt-2`:``}`,children:[(0,K.jsx)(n,{className:`mt-0.5 size-3.5 shrink-0 ${Dn[e.tone]}`,"aria-hidden":!0}),(0,K.jsxs)(`span`,{className:`min-w-0 break-words`,children:[typeof e.values.repository==`string`&&e.values.repository&&(0,K.jsx)(`span`,{className:`mr-2 inline-block rounded border border-border px-1.5 py-0.5 text-xs font-medium text-foreground`,children:e.values.repository}),e.kind===`step-start`&&typeof e.values.roleCode==`string`?a(e.code,{...e.values,title:a(e.values.roleCode),defaultValue:e.code}):a(e.code,{...e.values,defaultValue:e.code}),i>1?(0,K.jsx)(`span`,{className:`ml-1.5 text-[11px] opacity-70`,children:a(`repeats`,{count:i})}):null]})]},`${e.seq}-${e.code}-${t}`)})})]})}var kn=`specrails-desktop:job-log-mode`;function An(){try{let e=localStorage.getItem(kn);return e===`log`||e===`narrated`?e:`narrated`}catch{return`narrated`}}function jn(e){try{localStorage.setItem(kn,e)}catch{}}var Mn=8e3,Nn=new Set([`loop_graph`,`runtime-graph`,`loop_step`,`loop_step_end`,`loop_completion`,`workflow-event`,`runtime-result`,`runtime-efficiency-event`,`result`]);function Pn(e){return e.event_type!==`verification-output`}function Fn(e,t=!1){let n=[],r=Mn;for(let i=e.length-1;i>=0;i--){let a=e[i];Pn(a)&&(Nn.has(a.event_type)?n.push(a):r>0?(n.push(a),r--):t=!0)}return{events:n.reverse(),omitted:t}}function In(e,t){return!e.omitted||!e.events.length?e.events:[{...e.events[0],id:-1,seq:-1,event_type:`log`,source:`stdout`,payload:JSON.stringify({line:t})},...e.events]}function Ln(e,t){switch(t.type){case`turn-user`:return{...e,streaming:!0,accepting:!0,queued:t.queued?e.queued+1:e.queued};case`turn-done`:{let n=Math.max(0,e.queued-1);return{...e,totals:t.totals,queued:n,streaming:e.queued>0}}case`finalized`:return{...e,streaming:!1,finalizing:!1,accepting:!1,queued:0,totals:t.totals??e.totals};case`accepting`:return t.accepting?{...e,accepting:!0}:{...e,accepting:!1,streaming:!1,queued:0};case`finalize-request`:return{...e,finalizing:!0};case`finalize-reject`:return{...e,finalizing:!1};case`blocked`:return{...e,accepting:!1,streaming:!1};default:return e}}function Rn(){try{return a()}catch{return null}}function zn({jobId:e,projectId:t,settleMode:n,initialAcceptingTurns:r,pendingInterrupts:a,kind:s=`job`,variant:l=`page`,onFinalized:d}){let{t:f}=o(`jobs`),{t:p}=o(`loops`),[m,h]=(0,G.useState)(a??[]),[g,_]=(0,G.useState)(a?.length===1?a[0].id:``);(0,G.useEffect)(()=>{h(a??[]),_(a?.length===1?a[0].id:``)},[a]);let v=m.find(e=>e.id===g),y=v!==void 0&&v.kind!==`question`,b=n??`finalize`,S=()=>t?`${i}/api/projects/${t}`:c(),[C,w]=(0,G.useReducer)(Ln,{streaming:!1,queued:0,totals:null,accepting:r??!0,finalizing:!1}),[T,E]=(0,G.useState)(``),[D,O]=(0,G.useState)(!1),k=(0,G.useRef)(null);(0,G.useEffect)(()=>{r!==void 0&&w({type:`accepting`,accepting:r})},[r]);let A=(0,G.useRef)(d);A.current=d;let j=Rn(),M=(0,G.useId)();(0,G.useEffect)(()=>{if(!j)return;let t=`interactive-composer-${e}-${M}`;return j.registerHandler(t,t=>{let n=t;if(n.jobId===e){if(n.type===`job.turn_user`)w({type:`turn-user`,queued:!!n.queued});else if(n.type===`job.turn_done`)w({type:`turn-done`,totals:n.totals});else if(n.type===`job.finalized`)w({type:`finalized`,totals:n.totals??null}),A.current?.();else if(n.type===`job.interactive`&&(w({type:`accepting`,accepting:!!n.acceptingTurns}),Array.isArray(n.pendingInterrupts))){let e=n.pendingInterrupts;h(e),_(e.length===1?e[0].id:``)}}}),()=>j.unregisterHandler(t)},[j,e,M]);let N=s===`loop-step`&&!C.accepting;async function F(t=!1){let n=T.trim();if(!(!n&&!t||D||N||m.length>0&&!v||y&&!t)){O(!0);try{let r=await fetch(`${S()}/jobs/${e}/messages`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({text:n,...v?{interruptId:v.id}:{},...t?{approve:!0}:{}})});if(r.ok)E(``),v&&(h([]),_(``),w({type:`accepting`,accepting:!1})),requestAnimationFrame(()=>k.current?.focus());else if(r.status===409&&s===`loop-step`&&!m.length)w({type:`blocked`});else{let e=await r.json().catch(()=>({}));u.error(f(`detail.toast.sendFailed`),{description:e.error})}}catch{u.error(f(`detail.toast.networkError`))}finally{O(!1)}}}async function I(){if(!C.finalizing){w({type:`finalize-request`});try{let t=await fetch(`${S()}/jobs/${e}/finalize`,{method:`POST`});if(t.ok)u.success(f(b===`finalize`?`detail.toast.finalizeScheduled`:s===`loop-step`?`detail.toast.wrapUpStepScheduled`:`detail.toast.wrapUpScheduled`));else if(t.status===409&&s===`loop-step`)w({type:`blocked`}),w({type:`finalize-reject`});else{let e=await t.json().catch(()=>({}));u.error(f(`detail.toast.finalizeFailed`),{description:e.error}),w({type:`finalize-reject`})}}catch{u.error(f(`detail.toast.networkError`)),w({type:`finalize-reject`})}}}let R=D||N||!T.trim()||y||m.length>0&&!v,ee=f(`detail.interactive.working`);return(0,K.jsxs)(`div`,{"data-testid":`interactive-job-composer`,className:P(`shrink-0 border-t px-3 py-2 space-y-1.5`,`motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-bottom-2 motion-safe:duration-300`,l===`glass`?`border-border/30 bg-surface/30`:`border-border/40 bg-surface/40`),children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between gap-3 text-[11px] text-muted-foreground`,children:[(0,K.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2`,children:[N?(0,K.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,K.jsx)(Pe,{className:`h-3 w-3 motion-safe:animate-pulse`}),f(`detail.interactive.waitingForStepShort`)]}):C.streaming?(0,K.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,K.jsx)(x,{className:`h-3 w-3 animate-spin text-accent-primary`}),(0,K.jsxs)(`span`,{className:`relative`,children:[ee,(0,K.jsx)(`span`,{"aria-hidden":!0,className:`title-shimmer pointer-events-none absolute inset-0`,children:ee})]})]}):(0,K.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,K.jsx)(`span`,{className:`h-1.5 w-1.5 rounded-full bg-accent-success motion-safe:animate-pulse`}),f(`detail.interactive.ready`)]}),C.queued>0&&(0,K.jsx)(`span`,{className:`rounded-full border border-accent-info/30 bg-accent-info/10 px-1.5 py-px text-[10px] tabular-nums text-accent-info motion-safe:animate-in motion-safe:fade-in`,children:f(`detail.interactive.queued`,{count:C.queued})})]}),(0,K.jsxs)(`span`,{className:`flex shrink-0 items-center gap-3`,children:[C.totals&&(0,K.jsx)(`span`,{className:`tabular-nums`,children:f(`detail.interactive.liveTotals`,{turns:C.totals.num_turns??f(`completion.unavailable`),cost:C.totals.total_cost_usd?.toFixed(4)??f(`completion.unavailable`)})}),m.length?null:b===`finalize`?(0,K.jsxs)(H,{children:[(0,K.jsx)(W,{asChild:!0,children:(0,K.jsxs)(L,{variant:`outline`,size:`sm`,onClick:()=>void I(),disabled:C.finalizing,className:`h-7 border-accent-success/40 text-accent-success hover:bg-accent-success/10`,children:[(0,K.jsx)(B,{className:`mr-1.5 h-3.5 w-3.5`}),C.finalizing?f(`detail.finalizing`):f(`detail.finalizeJob`)]})}),(0,K.jsx)(me,{children:f(`detail.finalizeJobTooltip`)})]}):(0,K.jsxs)(H,{children:[(0,K.jsx)(W,{asChild:!0,children:(0,K.jsx)(`button`,{type:`button`,onClick:()=>void I(),disabled:C.finalizing||N,className:P(`text-[11px] underline-offset-2 transition-colors`,N?`cursor-not-allowed text-muted-foreground/40`:`text-muted-foreground hover:text-accent-success hover:underline`),children:C.finalizing?f(`detail.interactive.wrappingUp`):f(s===`loop-step`?`detail.interactive.wrapUpStep`:`detail.interactive.wrapUp`)})}),(0,K.jsx)(me,{children:f(s===`loop-step`?`detail.interactive.wrapUpStepTooltip`:`detail.interactive.wrapUpTooltip`)})]})]})]}),m.length>0&&(0,K.jsxs)(`div`,{className:`space-y-2 rounded-md border border-accent-warning/30 bg-accent-warning/5 p-3`,children:[(0,K.jsxs)(`label`,{className:`block text-sm`,children:[p(`core.selectInterrupt`),(0,K.jsxs)(`select`,{"aria-label":p(`core.selectInterrupt`),className:`mt-1 w-full rounded border border-border bg-background p-2`,value:g,onChange:e=>_(e.target.value),children:[(0,K.jsx)(`option`,{value:``,children:p(`core.selectInterrupt`)}),m.map(e=>(0,K.jsxs)(`option`,{value:e.id,children:[e.nodePath,` · `,p(`core.${e.kind===`question`?`answerQuestion`:`approval`}`)]},e.id))]})]}),v&&typeof v.value==`object`&&v.value!==null&&typeof v.value.prompt==`string`&&(0,K.jsx)(`p`,{className:`whitespace-pre-wrap text-sm`,children:String(v.value.prompt)}),y&&(0,K.jsx)(L,{onClick:()=>void F(!0),disabled:D||N,children:p(`core.approveContinue`)})]}),b===`auto`&&!m.length&&(0,K.jsx)(`p`,{className:`text-[11px] leading-snug text-muted-foreground/60`,children:f(N?`detail.interactive.waitingForStep`:`detail.interactive.autoHint`)}),(0,K.jsxs)(`div`,{className:`flex items-end gap-2`,children:[(0,K.jsx)(`textarea`,{ref:k,value:T,onChange:e=>E(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(!e.shiftKey||e.metaKey||e.ctrlKey)&&(e.preventDefault(),F())},rows:2,placeholder:f(N?`detail.interactive.waitingForStepShort`:`detail.interactive.placeholder`),"aria-label":f(`detail.interactive.placeholder`),disabled:N,className:P(`flex-1 resize-none rounded-md border border-border/50 bg-background px-2.5 py-1.5 text-sm transition-opacity focus:outline-none focus:ring-2 focus:ring-ring`,N&&`opacity-60`)}),(0,K.jsxs)(H,{children:[(0,K.jsx)(W,{asChild:!0,children:(0,K.jsx)(`span`,{className:`shrink-0`,children:(0,K.jsxs)(L,{size:`sm`,onClick:()=>void F(),disabled:R,className:`h-9`,children:[(0,K.jsx)(U,{className:`mr-1.5 h-3.5 w-3.5`}),f(`detail.interactive.send`)]})})}),R&&!D&&(0,K.jsx)(me,{children:f(N?`detail.interactive.sendDisabledWaiting`:`detail.interactive.sendDisabledEmpty`)})]})]})]})}export{An as a,an as c,qe as d,Fn as i,ht as l,Pn as n,jn as o,In as r,On as s,zn as t,et as u};
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{d as r,u as i}from"./chunk-KS7C4IRE-DEKu087k.js";import{n as a,t as o}from"./createLucideIcon-Bjbbp_KS.js";import{a as s,r as c,s as l}from"./useDesktop-DpiS8Uov.js";import{r as u}from"./provider-capabilities-lePfeT_Y.js";import{n as d,r as f,t as p}from"./save-OsUqVn99.js";import{t as m}from"./external-link-D6XxC_Cu.js";import{t as h}from"./git-branch-BRM0F5GN.js";import{n as g,t as _}from"./square-Ci-PFcFe.js";import{t as v}from"./plus-CsnjfkmX.js";import{t as ee}from"./rotate-ccw-Wh4id13q.js";import{t as y}from"./trash-2-BOU3WdZZ.js";import{t as te}from"./triangle-alert-H9T4jAmh.js";import{t as ne}from"./upload-DYMjAQ6M.js";import{t as re}from"./x-CBMI9ejn.js";import{a as ie,i as ae,l as oe,o as b,r as x,t as se}from"./dialog-CMgps2MY.js";import{t as S}from"./utils-BC4DHlz2.js";import{t as C}from"./button-D1xExSTF.js";import{n as w,t as T}from"./project-repositories-BkyT8AjU.js";import{Ft as ce,J as le,K as ue,Mt as de,U as E,Ut as fe,Vt as pe,Y as me,Yt as he,bt as ge,c as D,d as _e,f as ve,gt as O,in as ye,it as k,l as A,m as j,ot as M,p as be,q as xe,rn as Se,rt as Ce,tn as we,u as N,xt as P,zt as Te}from"./index-g8S62tpS.js";import{a as Ee,c as De,d as Oe,f as ke,i as F,l as Ae,m as I,n as je,o as Me,p as Ne,r as Pe,s as Fe,t as Ie,u as Le}from"./loop-layout-BF8xMiNv.js";var Re=o(`grid-3x3`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M3 9h18`,key:`1pudct`}],[`path`,{d:`M3 15h18`,key:`5xshup`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}],[`path`,{d:`M15 3v18`,key:`14nvp0`}]]),ze=o(`move-horizontal`,[[`path`,{d:`m18 8 4 4-4 4`,key:`1ak13k`}],[`path`,{d:`M2 12h20`,key:`9i4pu4`}],[`path`,{d:`m6 8-4 4 4 4`,key:`15zrgr`}]]),Be=o(`move-vertical`,[[`path`,{d:`M12 2v20`,key:`t6zp3m`}],[`path`,{d:`m8 18 4 4 4-4`,key:`bh5tu3`}],[`path`,{d:`m8 6 4-4 4 4`,key:`ybng9g`}]]),L=e(t(),1),R=n(),z=`h-9 w-full rounded-md border border-input bg-background px-2 text-sm`;function Ve({roles:e={},provider:t,supported:n,onChange:r,renderEngine:i,visibleRoleIds:o,manageRoles:s=!0}){let{t:c}=a(`agentRuntime`),[l,u]=(0,L.useState)(``),[d,f]=(0,L.useState)(!1),p=Object.entries(e).filter(([e])=>!ve.includes(e)&&(!o||o.includes(e)));function m(){if(!D.test(l)||l===`fixer`||ve.includes(l)||Object.prototype.hasOwnProperty.call(e,l)){f(!0);return}r({...e,[l]:{provider:t,access:`read`,artifacts:`none`}}),u(``),f(!1)}return(0,R.jsxs)(`section`,{className:`space-y-3`,"aria-labelledby":`custom-runtime-roles`,children:[s&&(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{id:`custom-runtime-roles`,className:`text-sm font-medium`,children:c(`customRoles.title`)}),(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:c(`customRoles.hint`)})]}),!n&&(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:c(`customRoles.unsupported`)}),p.map(([t,a])=>{let o=n=>r({...e,[t]:{...a,...n}});return(0,R.jsxs)(`fieldset`,{className:`space-y-3 rounded-lg border p-3`,"aria-label":t,children:[(0,R.jsx)(`legend`,{className:`px-1 font-mono text-sm`,children:t}),s&&(0,R.jsx)(`div`,{className:`flex justify-end`,children:(0,R.jsx)(C,{size:`sm`,variant:`ghost`,onClick:()=>{let n={...e};delete n[t],r(n)},children:c(`customRoles.remove`,{id:t})})}),(0,R.jsxs)(`fieldset`,{disabled:!n,className:`space-y-3`,children:[i(t),(0,R.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,R.jsxs)(`label`,{className:`space-y-1 text-xs`,children:[c(`customRoles.access`),(0,R.jsxs)(`select`,{className:z,value:a.access,onChange:e=>o({access:e.target.value}),children:[(0,R.jsx)(`option`,{value:`read`,children:c(`customRoles.read`)}),(0,R.jsx)(`option`,{value:`write`,children:c(`customRoles.write`)})]})]}),(0,R.jsxs)(`label`,{className:`space-y-1 text-xs`,children:[c(`customRoles.artifacts`),(0,R.jsxs)(`select`,{className:z,value:a.artifacts,onChange:e=>o({artifacts:e.target.value}),children:[(0,R.jsx)(`option`,{value:`none`,children:c(`customRoles.none`)}),(0,R.jsx)(`option`,{value:`tasks-checkboxes`,children:c(`customRoles.tasks`)}),(0,R.jsx)(`option`,{value:`all`,children:c(`customRoles.all`)})]})]})]}),(0,R.jsxs)(`label`,{className:`block space-y-1 text-xs`,children:[c(`customRoles.skill`),(0,R.jsxs)(`select`,{className:z,value:a.openspecSkill??``,onChange:e=>o({openspecSkill:e.target.value||void 0}),children:[(0,R.jsx)(`option`,{value:``,children:c(`customRoles.noSkill`)}),[`openspec-ff-change`,`openspec-apply-change`,`openspec-verify-change`].map(e=>(0,R.jsx)(`option`,{value:e,children:e},e))]})]}),(0,R.jsxs)(`label`,{className:`block space-y-1 text-xs`,children:[c(`customRoles.prompt`),(0,R.jsx)(`textarea`,{className:`w-full rounded-md border border-input bg-background px-3 py-2 text-sm`,value:a.prompt??``,rows:5,maxLength:2e4,onChange:e=>o({prompt:e.target.value||void 0})})]})]})]},t)}),s&&(0,R.jsxs)(`fieldset`,{disabled:!n||!t,className:`flex items-end gap-2`,children:[(0,R.jsxs)(`label`,{className:`min-w-0 flex-1 space-y-1 text-xs`,children:[c(`customRoles.id`),(0,R.jsx)(E,{value:l,maxLength:64,placeholder:`security-reviewer`,onChange:e=>{u(e.target.value),f(!1)}})]}),(0,R.jsx)(C,{variant:`secondary`,onClick:m,children:c(`customRoles.add`)})]}),d&&(0,R.jsx)(`p`,{role:`alert`,className:`text-xs text-destructive`,children:c(`customRoles.invalidId`)})]})}var He={architect:fe,developer:ce,host:O};function Ue({projectId:e,catalogUrl:t,guardrails:n,onChange:r}){let{t:i,i18n:o}=a(`agentRuntime`),[s,c]=(0,L.useState)(!0),[l,u]=(0,L.useState)({status:`loading`});(0,L.useEffect)(()=>{let n=!1;return u({status:`loading`}),fetch(t??`${w(e)}/agent-runtime/guardrails`,{cache:`no-store`}).then(async e=>{if(!e.ok)throw Error(`guardrails`);let r=await e.json(),i=t?r.guardrails:r;if(!be(i))throw Error(`guardrails`);n||u({status:`ready`,supported:i.supported,catalog:i.catalog})}).catch(()=>{n||u({status:`unsupported`})}),()=>{n=!0}},[e,t]);let f=l.status===`ready`?l.catalog:[],p=l.status===`ready`&&l.supported,m=f.filter(e=>n?.[e.id]===!1).length,h=f.length,g=e=>o.exists(`agentRuntime:guardrails.items.${e}.title`),_=`pipeline-guardrails-body`;return(0,R.jsxs)(`fieldset`,{id:`pipeline-guardrails`,"data-testid":`phase-card-guardrails`,className:`scroll-mt-4 rounded-lg border border-border transition-shadow`,children:[(0,R.jsx)(`legend`,{className:`sr-only`,children:i(`guardrails.title`)}),(0,R.jsxs)(`button`,{type:`button`,"aria-expanded":s,"aria-controls":_,"aria-label":`${i(s?`pipeline.collapse`:`pipeline.open`)}: ${i(`guardrails.title`)}`,onClick:()=>c(e=>!e),className:`flex w-full flex-wrap items-center gap-2 rounded-t-lg px-3 py-2 text-left hover:bg-muted/40`,children:[(0,R.jsx)(`span`,{className:`flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-accent-success/15 text-accent-success`,children:(0,R.jsx)(ge,{className:`h-3.5 w-3.5`,"aria-hidden":!0})}),(0,R.jsx)(`span`,{className:`text-xs font-medium`,children:i(`guardrails.title`)}),(0,R.jsxs)(`span`,{className:`ml-auto flex items-center gap-2`,children:[l.status===`ready`&&p&&(0,R.jsx)(`span`,{"data-testid":`guardrails-active`,className:S(`inline-flex items-center rounded-md border px-1.5 py-0.5 text-[11px] leading-4`,m?`border-accent-warning/40 bg-accent-warning/10 text-accent-warning`:`border-accent-success/30 bg-accent-success/10 text-accent-success`),children:i(`guardrails.active`,{on:h-m,total:h})}),(0,R.jsx)(d,{className:`h-3.5 w-3.5 text-muted-foreground transition-transform ${s?``:`-rotate-90`}`,"aria-hidden":!0})]})]}),(0,R.jsxs)(`div`,{id:_,hidden:!s,className:`space-y-3 px-3 pb-3`,children:[(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:i(`guardrails.intro`)}),l.status===`loading`&&(0,R.jsx)(`p`,{role:`status`,className:`text-xs text-muted-foreground`,children:i(`loading`)}),(l.status===`unsupported`||l.status===`ready`&&!p)&&(0,R.jsx)(`p`,{role:`status`,className:`rounded-md border border-accent-warning/40 p-3 text-xs text-accent-warning`,children:i(`guardrails.unsupported`)}),l.status===`ready`&&(0,R.jsxs)(`fieldset`,{disabled:!p,className:`space-y-3 disabled:opacity-60`,children:[m>0&&(0,R.jsx)(`div`,{className:`flex justify-end`,children:(0,R.jsx)(`button`,{type:`button`,className:`text-[11px] text-accent-primary underline-offset-2 hover:underline`,onClick:()=>r(void 0),children:i(`guardrails.reset`)})}),A.map(e=>{let t=f.filter(t=>t.phase===e);if(!t.length)return null;let a=He[e];return(0,R.jsxs)(`div`,{className:`space-y-2`,"data-testid":`guardrails-phase-${e}`,children:[(0,R.jsxs)(`p`,{className:`flex items-center gap-1.5 text-[11px] font-medium uppercase tracking-wide text-muted-foreground`,children:[(0,R.jsx)(a,{className:`h-3.5 w-3.5`,"aria-hidden":!0}),i(`guardrails.phases.${e}`)]}),(0,R.jsx)(`ul`,{className:`divide-y divide-border/60 rounded-md border border-border/60`,children:t.map(e=>{let t=n?.[e.id]!==!1,a=g(e.id)?i(`guardrails.items.${e.id}.title`):e.id,o=g(e.id)?i(`guardrails.items.${e.id}.description`):i(`guardrails.unknown`),s=g(e.id)?i(`guardrails.items.${e.id}.why`):null,c=`guardrail-${e.id}-title`;return(0,R.jsxs)(`li`,{className:`flex items-start gap-3 px-3 py-2`,children:[(0,R.jsx)(`button`,{type:`button`,role:`switch`,"aria-checked":t,"aria-labelledby":c,"data-testid":`guardrail-${e.id}`,onClick:()=>r(j(n,e.id,!t)),className:S(`relative mt-0.5 inline-flex h-4 w-7 shrink-0 items-center rounded-full transition-colors`,t?`bg-accent-primary/70`:`bg-muted-foreground/30`),children:(0,R.jsx)(`span`,{className:S(`absolute h-3 w-3 rounded-full bg-background shadow transition-transform`,t?`translate-x-3.5`:`translate-x-0.5`)})}),(0,R.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,R.jsx)(`p`,{id:c,className:S(`text-xs font-medium`,!t&&`text-muted-foreground line-through decoration-muted-foreground/50`),children:a}),(0,R.jsx)(`p`,{className:`mt-0.5 text-[11px] leading-4 text-muted-foreground`,children:o}),s&&(0,R.jsx)(`p`,{className:`mt-0.5 text-[10px] italic leading-4 text-muted-foreground/70`,children:s})]})]},e.id)})})]},e)})]})]})]})}var We=`h-9 w-full rounded-md border border-input bg-background px-2 text-sm`;function B({config:e,onChange:t}){let{t:n}=a(`agentRuntime`),r=e.efficiency??{schemaVersion:1};return(0,R.jsxs)(`section`,{className:`space-y-3`,"aria-label":n(`efficiency.title`),children:[(0,R.jsx)(`h3`,{className:`text-sm font-medium`,children:n(`efficiency.title`)}),(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:n(`efficiency.scope`)}),(0,R.jsx)(`div`,{className:`grid gap-3 sm:grid-cols-3`,children:[`contextMode`,`reviewMode`,`planning`].map(i=>(0,R.jsxs)(`label`,{className:`block space-y-1 text-xs`,children:[n(`efficiency.${i}`),(0,R.jsxs)(`select`,{className:We,value:r[i]??(i===`planning`?`proportional`:`incremental`),onChange:n=>t({...e,efficiency:{...r,[i]:n.target.value}}),children:[(0,R.jsx)(`option`,{value:i===`planning`?`proportional`:`incremental`,children:n(`efficiency.adaptive`)}),(0,R.jsx)(`option`,{value:`full`,children:n(`efficiency.full`)})]})]},i))}),(0,R.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:r.acceptDeveloperChecks!==!1,onChange:n=>t({...e,efficiency:{...r,acceptDeveloperChecks:n.target.checked}})}),n(`efficiency.developerChecks`)]}),(0,R.jsxs)(`label`,{className:`block space-y-1 text-xs`,children:[n(`efficiency.concurrency`),(0,R.jsx)(E,{type:`number`,min:`1`,max:`4`,step:`1`,value:r.verification?.maxConcurrency??1,onChange:n=>t({...e,efficiency:{...r,verification:{...r.verification,maxConcurrency:Number(n.target.value)}}})})]}),(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:n(`efficiency.concurrencyHint`)})]})}function Ge(e){let t=[],n=0;function r(i,a,o){if(!(o.length>=32||t.length>=1e4))for(let s of i.nodes){if(++n>1e4)return;if(s.type!==`core`)continue;let i=a+s.id,c=s.data?.kind,l=V(s.data?.params);(c===`role-turn`||c===`implementation-step`&&l.phase===`reviewer`)&&t.push(i);let u=c===`component`?l.ref:c===`map`?l.body:void 0;typeof u==`string`&&!o.includes(u)&&e.components?.[u]&&r(e.components[u],i+`/`,[...o,u])}}return r(e,``,[]),t.sort()}var V=e=>typeof e==`object`&&e&&!Array.isArray(e)?e:{};function H(e){return typeof e.type==`string`?e.type:e.properties||e.additionalProperties?`object`:e.items?`array`:`string`}function U(e){if(`default`in e)return structuredClone(e.default);if(`const`in e)return structuredClone(e.const);if(Array.isArray(e.enum))return structuredClone(e.enum[0]);let t=e.oneOf??e.anyOf;if(Array.isArray(t)&&!e.properties)return U(V(t[0]));switch(H(e)){case`boolean`:return!1;case`number`:case`integer`:return typeof e.minimum==`number`?e.minimum:0;case`array`:return[];case`object`:{let t=V(e.properties);return Object.fromEntries((Array.isArray(e.required)?e.required:[]).filter(e=>typeof e==`string`).map(e=>[e,U(V(t[e]))]))}default:return``}}function Ke(e){let t=V(U(e.paramsSchema));return e.kind===`prompt`&&(t.text=``,t.engine={provider:`claude`},t.access=`read`),e.kind===`shell`&&(t.argv=[``]),e.kind===`assign`&&(t.set={}),{kind:`core`,coreKind:e.kind,params:t}}function qe(e,t,n={}){if(!e)return[];let r=e.outcomes;return e.kind===`prompt`&&(r=t.sentinel===`verification`?[`pass`,`fail`,`failed`]:t.sentinel===`blocked`?[`next`,`blocked`,`failed`]:[`next`,`failed`]),e.kind===`role-turn`&&(r=t.structuredOutput?[`next`,`invalid`,`failed`]:[`next`,`failed`]),e.kind===`component`?n[String(t.ref)]?.outputs??[`next`,`failed`]:r.filter(t=>e.outcomes.includes(t))}var Je=e=>[`prompt`,`role-turn`,`decider`,`implementation`,`implementation-step`].includes(e)?`ai`:[`verify`,`shell`].includes(e)?`verification`:e===`artifact-contract`||e.startsWith(`openspec-`)?`openspec`:`control`;function Ye(e,t,n){return t===`implementation`?[`architect`,`developer`,`reviewer`,`fixer`]:t===`implementation-step`?[`architect`,`developer`,`reviewer`,`fixer`].includes(String(n.phase))?[String(n.phase)]:[]:t===`prompt`?[e===`fix`?`fixer`:e===`prepare`?`architect`:n.access===`read`?`reviewer`:`developer`]:(t===`role-turn`||t===`decider`)&&typeof n.roleId==`string`?[n.roleId]:[]}function Xe(e){let t=new Set,n=new Set;function r(i){for(let a of i.nodes){if(a.type!==`core`)continue;let i=V(a.data?.params),o=a.data?.kind;Ye(a.id,o,i).forEach(e=>t.add(e));let s=o===`component`?i.ref:o===`map`?i.body:void 0;typeof s==`string`&&!n.has(s)&&e.components?.[s]&&(n.add(s),r(e.components[s]))}}return r(e),[...t]}var W=`w-full rounded-md border border-input bg-background px-2 py-1 text-xs`,G=[`architect`,`developer`,`reviewer`,`fixer`];function Ze({value:e,onChange:t,selectedRole:n,graph:r,mode:i=`all`}){let{t:o}=a(`agentRuntime`),{activeProjectId:l}=c(),d=(0,L.useRef)(l);d.current=l;let[f,p]=(0,L.useState)([]),[m,h]=(0,L.useState)({}),[g,_]=(0,L.useState)(),[v,ee]=(0,L.useState)(null),[y,te]=(0,L.useState)(``),[ne,re]=(0,L.useState)(!1),[ie,ae]=(0,L.useState)(!1),oe=r?Xe(r):[...G,...Object.keys(e?.roles??{})],b=i===`step`?[n??``]:ie?void 0:oe,x=i!==`workflow`,se=i!==`step`,S=i===`step`?`loopAgents.stepTitle`:i===`workflow`?`loopAgents.policy`:`loopAgents.title`,w=[...G,...Object.keys(e?.roles??{})].some(e=>!oe.includes(e));(0,L.useEffect)(()=>{let e=new AbortController;return Promise.all([`/api/runtime-providers`,`/api/loop-agent-defaults`].map(t=>fetch(t,{signal:e.signal}).then(async e=>{if(!e.ok)throw Error(o(`loadFailed`));return e.json()}))).then(([t,n])=>{e.signal.aborted||(p(t.providers??[]),_(n.agents),ee(n.rolePromptDefaults??null),h(Object.fromEntries(Object.entries(t.status??{}).map(([e,t])=>[e,t.models??[]]))))}).catch(()=>{e.signal.aborted||te(o(`loadFailed`))}),()=>e.abort()},[o]);async function T(){let e=l;re(!0),te(``);try{let n=s(),[r,i]=await Promise.all([fetch(`${n}/agent-runtime/config`),fetch(`${n}/agent-runtime/loop-roles`)]);if(!r.ok||!i.ok)throw Error(o(`loadFailed`));let a=await r.json(),c=await i.json(),{agents:l,fixer:u,roles:f,rolePrompts:p,limits:m,review:h,architect:_,approvalBeforeArchive:v,efficiency:ee,guardrails:y}=a.config;if(!e||d.current!==e)return;t({schemaVersion:1,agents:l,fixer:u,roles:{...g?.roles,...Object.fromEntries(Object.entries(f??{}).map(([e,t])=>[e,{...t,prompt:p?.[e]??t.prompt}])),...c.roles?.decider?{"loop-decider":{...g.roles[`loop-decider`],...c.roles.decider}}:{}},rolePrompts:Object.fromEntries(Object.entries({...g?.rolePrompts,...p}).filter(([e])=>G.includes(e))),limits:m,review:h,architect:_,approvalBeforeArchive:v,efficiency:ee,guardrails:y})}catch{te(o(`loadFailed`))}finally{re(!1)}}function ce(n){if(!e)return null;let r=G.includes(n),i=n===`fixer`?e.fixer??e.agents.developer:r?e.agents[n]:e.roles?.[n];if(!i)return null;let a=i=>t(n===`fixer`?{...e,fixer:i}:r?{...e,agents:{...e.agents,[n]:i}}:{...e,roles:{...e.roles,[n]:{...e.roles[n],...i}}}),s=f.find(e=>e.id===i.provider),c=s?.kind===`cli`?M(s.cli).map(e=>e.value):m[i.provider]??[];return(0,R.jsxs)(`div`,{className:`space-y-2`,children:[(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`agents.provider`),(0,R.jsxs)(`select`,{className:W,value:i.provider,onChange:e=>a({provider:e.target.value,maxTurns:i.maxTurns}),children:[(0,R.jsx)(`option`,{value:`inherit`,children:o(`loopAgents.inheritProvider`)}),!s&&i.provider!==`inherit`&&u(i.provider)&&(0,R.jsx)(`option`,{value:i.provider,children:i.provider}),f.filter(e=>u(e.kind===`cli`?e.cli:e.id)).map(e=>(0,R.jsx)(`option`,{value:e.id,children:e.kind===`openai-compatible`?e.label??e.id:e.id},e.id))]})]}),(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`agents.model`),(0,R.jsx)(E,{value:i.model??``,list:`loop-models-${n}`,onChange:e=>a({...i,model:e.target.value||void 0})}),(0,R.jsx)(`datalist`,{id:`loop-models-${n}`,children:c.map(e=>(0,R.jsx)(`option`,{value:e},e))})]}),(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`loopAgents.effort`),(0,R.jsx)(E,{value:i.effort??``,onChange:e=>a({...i,effort:e.target.value||void 0})})]}),(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`agents.maxTurns`,{turns:100}),(0,R.jsx)(E,{type:`number`,min:1,value:i.maxTurns??``,onChange:e=>a({...i,maxTurns:e.target.value?Number(e.target.value):void 0})})]}),(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`agents.thinking`),(0,R.jsxs)(`select`,{className:W,value:i.thinking??``,onChange:e=>a({...i,thinking:e.target.value?e.target.value:void 0}),children:[(0,R.jsx)(`option`,{value:``,children:o(`loopAgents.default`)}),(0,R.jsx)(`option`,{value:`off`,children:o(`agents.thinking_off`)}),(0,R.jsx)(`option`,{value:`on`,children:o(`agents.thinking_on`)})]})]}),(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`loopAgents.escalationModel`),(0,R.jsx)(E,{value:i.escalation?.model??``,onChange:e=>a({...i,escalation:e.target.value?{...i.escalation,model:e.target.value}:void 0})})]}),i.escalation&&(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`loopAgents.escalationEffort`),(0,R.jsx)(E,{value:i.escalation.effort??``,onChange:e=>a({...i,escalation:{model:i.escalation.model,effort:e.target.value||void 0}})})]})]})}let le=e?{...e,enabled:!0,providers:f,verification:[]}:void 0;return(0,R.jsxs)(`section`,{className:`space-y-3 border-b border-border pb-4`,"aria-label":o(S),children:[(0,R.jsx)(`h3`,{className:`text-sm font-medium`,children:o(S)}),x&&(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:o(i===`step`?`loopAgents.stepHint`:`loopAgents.hint`)}),y&&(0,R.jsx)(`p`,{role:`alert`,className:`text-xs text-destructive`,children:y}),!e&&(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`p`,{className:`text-xs text-accent-warning`,children:o(`loopAgents.legacy`)}),(0,R.jsx)(C,{size:`sm`,disabled:!g,onClick:()=>g&&t(structuredClone(g)),children:o(`loopAgents.enable`)})]}),i!==`step`&&(0,R.jsx)(C,{size:`sm`,variant:`secondary`,disabled:!l||!g||ne,onClick:()=>void T(),children:o(`loopAgents.import`)}),e&&(0,R.jsxs)(R.Fragment,{children:[i===`all`&&w&&(0,R.jsxs)(`label`,{className:`flex gap-2 text-xs`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:ie,onChange:e=>ae(e.target.checked)}),o(`loopAgents.showUnused`)]}),x&&G.filter(e=>!b||b.includes(e)).map(r=>(0,R.jsxs)(`details`,{open:n===r,className:`rounded-md border border-border p-2`,children:[(0,R.jsx)(`summary`,{className:`cursor-pointer text-sm font-medium`,children:r}),(0,R.jsxs)(`div`,{className:`mt-3 space-y-3`,children:[ce(r),e.rolePrompts?.[r]===`inherit`?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:o(`loopAgents.inheritDefinition`)}),(0,R.jsx)(`textarea`,{readOnly:!0,"aria-label":o(`customRoles.prompt`),className:`${W} opacity-80`,rows:8,value:v?.[r]??o(`loopAgents.coreDefinitionUnavailable`)}),(0,R.jsx)(C,{size:`sm`,variant:`ghost`,disabled:!v?.[r],onClick:()=>t({...e,rolePrompts:{...e.rolePrompts,[r]:v?.[r]??``}}),children:o(`loopAgents.customizeDefinition`)})]}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`customRoles.prompt`),(0,R.jsx)(`textarea`,{className:W,rows:10,maxLength:2e4,value:e.rolePrompts?.[r]??``,onChange:n=>t({...e,rolePrompts:{...e.rolePrompts,[r]:n.target.value}})})]}),(0,R.jsx)(C,{size:`sm`,variant:`ghost`,onClick:()=>t({...e,rolePrompts:{...e.rolePrompts,[r]:`inherit`}}),children:o(`loopAgents.restoreDefinition`)})]})]})]},r)),i===`step`&&n&&![...G,`archive`,`verify`].includes(n)&&!e.roles?.[n]&&(0,R.jsx)(C,{size:`sm`,disabled:!f.length,onClick:()=>t({...e,roles:{...e.roles,[n]:{provider:`inherit`,access:`read`,artifacts:`none`}}}),children:o(`customRoles.add`)}),(x||i===`workflow`)&&(0,R.jsx)(Ve,{manageRoles:i!==`step`,visibleRoleIds:i===`workflow`?[]:b,roles:e.roles,provider:`inherit`,supported:!0,onChange:n=>{Object.keys(n).some(t=>!e.roles?.[t])&&ae(!0),t({...e,roles:n,rolePrompts:Object.fromEntries(Object.entries(e.rolePrompts??{}).filter(([e])=>G.includes(e)))})},renderEngine:ce}),(0,R.jsxs)(`div`,{className:`space-y-3`,children:[se&&(0,R.jsxs)(`details`,{className:`rounded-md border border-border p-2`,children:[(0,R.jsx)(`summary`,{className:`cursor-pointer text-sm`,children:o(`loopAgents.policy`)}),(0,R.jsxs)(`div`,{className:`mt-3 space-y-3`,children:[[`maxAttempts`,`maxTokens`,`maxCostUsd`,`timeoutMs`].map(n=>(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`loopAgents.${n}`),(0,R.jsx)(E,{type:`number`,min:1,value:e.limits?.[n]??``,onChange:r=>t({...e,limits:{...e.limits,[n]:r.target.value?Number(r.target.value):void 0}})})]},n)),(0,R.jsx)(Ue,{catalogUrl:`/api/loop-agent-defaults`,guardrails:e.guardrails,onChange:n=>t({...e,guardrails:n})}),le&&(0,R.jsx)(B,{config:le,onChange:n=>t({...e,efficiency:n.efficiency})})]})]}),(i===`all`||i===`step`&&n===`reviewer`)&&(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`review.minScore`,{score:70}),(0,R.jsx)(E,{type:`number`,min:70,max:100,value:e.review?.minScore??``,onChange:n=>t({...e,review:{...e.review,minScore:n.target.value?Number(n.target.value):void 0}})})]}),N.map(n=>(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`review.aspects.${n}`,{score:_e.aspects[n]}),(0,R.jsx)(E,{type:`number`,min:_e.aspects[n],max:100,value:e.review?.aspects?.[n]??``,onChange:r=>t({...e,review:{...e.review,aspects:{...e.review?.aspects,[n]:r.target.value?Number(r.target.value):void 0}}})})]},n))]}),(i===`all`||i===`step`&&n===`architect`)&&(0,R.jsxs)(`label`,{className:`block text-xs`,children:[o(`architect.onLowConfidence`),(0,R.jsxs)(`select`,{className:W,value:e.architect?.onLowConfidence??`ask`,onChange:n=>t({...e,architect:{onLowConfidence:n.target.value}}),children:[(0,R.jsx)(`option`,{value:`ask`,children:o(`architect.ask`)}),(0,R.jsx)(`option`,{value:`proceed`,children:o(`architect.proceed`)})]})]}),(i===`all`||i===`step`&&n===`archive`)&&(0,R.jsxs)(`label`,{className:`flex gap-2 text-xs`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:e.approvalBeforeArchive??!1,onChange:n=>t({...e,approvalBeforeArchive:n.target.checked})}),o(`approvalBeforeArchive`)]})]})]})]})}var K=`w-full min-w-0 rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-primary`;function q({schema:e,value:t,onChange:n,path:r=`params`,choices:i={},depth:o=0}){let{t:s}=a(`loops`),c=(0,L.useId)(),[l,u]=(0,L.useState)(``);if(o>24)return(0,R.jsx)(`p`,{role:`alert`,className:`text-xs text-destructive`,children:s(`builder.core.tooDeep`)});let d=typeof e.title==`string`?e.title:r.split(`.`).slice(-1)[0],f=(e,n,a,s)=>(0,R.jsx)(q,{schema:n,value:a,onChange:s,path:`${r}.${e}`,choices:{...i,selectedProvider:typeof V(t).provider==`string`?String(V(t).provider):i.selectedProvider},depth:o+1},e),p=e.oneOf??e.anyOf;if(Array.isArray(p)&&!e.properties){let e=p.map(V),r=Math.max(0,e.findIndex(e=>`const`in e?t===e.const:Array.isArray(e.enum)?e.enum.includes(t):H(e)===(Array.isArray(t)?`array`:typeof t)));return(0,R.jsxs)(`fieldset`,{className:`space-y-2`,children:[(0,R.jsx)(`legend`,{className:`text-xs font-medium`,children:d}),(0,R.jsx)(`label`,{className:`sr-only`,htmlFor:c,children:s(`builder.core.variant`,{name:d})}),(0,R.jsx)(`select`,{id:c,className:K,value:r,onChange:t=>n(U(e[Number(t.target.value)])),children:e.map((e,t)=>(0,R.jsx)(`option`,{value:t,children:String(e.title??e.const??(Array.isArray(e.enum)?e.enum.join(` / `):H(e)))},t))}),f(`value`,e[r],t,n)]})}if(`const`in e)return(0,R.jsxs)(`p`,{className:`text-xs`,children:[(0,R.jsxs)(`span`,{className:`text-muted-foreground`,children:[d,`: `]}),String(e.const)]});if(Array.isArray(e.enum))return(0,R.jsxs)(`label`,{className:`block space-y-1 text-xs`,children:[d,(0,R.jsxs)(`select`,{className:K,value:JSON.stringify(t),onChange:e=>n(JSON.parse(e.target.value)),children:[!e.enum.includes(t)&&(0,R.jsx)(`option`,{value:JSON.stringify(t)??``,children:s(`builder.core.select`)}),e.enum.map((e,t)=>(0,R.jsx)(`option`,{value:JSON.stringify(e),children:String(e)},t))]})]});let m=H(e);if(m===`object`){let r=V(t),i=V(e.properties),a=new Set(Array.isArray(e.required)?e.required:[]),o=[...Object.keys(i),...Object.keys(r).filter(e=>!(e in i))],c=(e,t)=>{let a={...r};e===`provider`&&t!==r.provider&&i.model&&(delete a.model,delete a.effort),t===void 0?delete a[e]:Object.defineProperty(a,e,{value:t,enumerable:!0,configurable:!0,writable:!0}),n(a)},m=Array.isArray(p)?p.map(e=>V(e).required).filter(e=>Array.isArray(e)&&e.every(e=>typeof e==`string`)):[],h=t=>{let a={...r};if(m.some(e=>e.includes(t)))for(let e of m)for(let n of e)n!==t&&delete a[n];Object.defineProperty(a,t,{value:U(V(i[t]??e.additionalProperties)),enumerable:!0,configurable:!0,writable:!0}),n(a)};return(0,R.jsxs)(`fieldset`,{className:`space-y-2 min-w-0`,children:[(0,R.jsx)(`legend`,{className:`text-xs font-semibold text-foreground mb-1`,children:d}),o.map(t=>{let n=Object.prototype.hasOwnProperty.call(r,t),o=a.has(t);return!n&&!o?(0,R.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1 text-xs rounded border border-border px-2 py-1 mr-1 hover:bg-muted`,onClick:()=>h(t),"aria-label":s(`builder.core.addField`,{name:t}),children:[(0,R.jsx)(v,{className:`h-3 w-3`}),t]},t):(0,R.jsxs)(`div`,{className:`relative border-l border-border pl-2 space-y-1`,children:[!o&&(0,R.jsx)(`button`,{type:`button`,className:`float-right text-muted-foreground hover:text-destructive`,onClick:()=>c(t,void 0),"aria-label":s(`builder.core.removeField`,{name:t}),children:(0,R.jsx)(re,{className:`h-3.5 w-3.5`})}),f(t,V(i[t]??e.additionalProperties),r[t],e=>c(t,e))]},t)}),e.additionalProperties!==!1&&(0,R.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,R.jsx)(`input`,{className:K,value:l,placeholder:s(`builder.core.fieldName`),"aria-label":s(`builder.core.fieldName`),onChange:e=>u(e.target.value)}),(0,R.jsx)(`button`,{type:`button`,className:`p-1.5 text-accent-primary disabled:opacity-40`,disabled:!l.trim()||Object.prototype.hasOwnProperty.call(r,l.trim())||[`__proto__`,`constructor`,`prototype`].includes(l.trim()),onClick:()=>{h(l.trim()),u(``)},"aria-label":s(`builder.core.addField`,{name:l}),children:(0,R.jsx)(v,{className:`h-4 w-4`})})]})]})}if(m===`array`){let r=Array.isArray(t)?t:[],i=V(e.items);return(0,R.jsxs)(`fieldset`,{className:`space-y-2`,children:[(0,R.jsx)(`legend`,{className:`text-xs font-semibold`,children:d}),r.map((e,t)=>(0,R.jsxs)(`div`,{className:`border-l border-border pl-2`,children:[(0,R.jsx)(`button`,{type:`button`,className:`float-right text-muted-foreground hover:text-destructive`,onClick:()=>n(r.filter((e,n)=>n!==t)),"aria-label":s(`builder.core.removeField`,{name:`${d} ${t+1}`}),children:(0,R.jsx)(re,{className:`h-3.5 w-3.5`})}),f(String(t+1),i,e,e=>n(r.map((n,r)=>r===t?e:n)))]},t)),(0,R.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1 text-xs text-accent-primary`,disabled:typeof e.maxItems==`number`&&r.length>=e.maxItems,onClick:()=>n([...r,U(i)]),children:[(0,R.jsx)(v,{className:`h-3 w-3`}),s(`builder.core.addItem`)]})]})}if(!Object.keys(e).length){let e=t===null?`null`:Array.isArray(t)?`array`:typeof t,r=[`object`,`array`,`boolean`,`number`,`null`].includes(e)?e:`string`;return(0,R.jsxs)(`div`,{className:`space-y-1`,children:[(0,R.jsxs)(`label`,{className:`text-xs`,children:[s(`builder.core.valueType`),(0,R.jsx)(`select`,{className:K,value:r,onChange:e=>n(e.target.value===`null`?null:U({type:e.target.value})),children:[`string`,`number`,`boolean`,`object`,`array`,`null`].map(e=>(0,R.jsx)(`option`,{children:e},e))})]}),r===`null`?(0,R.jsx)(`span`,{className:`text-xs`,children:`null`}):f(`value`,{type:r},t,n)]})}if(m===`boolean`)return(0,R.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:t===!0,onChange:e=>n(e.target.checked),className:`accent-accent-primary`}),d]});if(m===`number`||m===`integer`)return(0,R.jsxs)(`label`,{className:`block space-y-1 text-xs`,children:[d,(0,R.jsx)(`input`,{type:`number`,className:K,value:typeof t==`number`?t:``,min:typeof e.minimum==`number`?e.minimum:void 0,max:typeof e.maximum==`number`?e.maximum:void 0,step:m===`integer`?1:`any`,onChange:e=>n(e.target.value===``?void 0:Number(e.target.value))})]});let h=d===`provider`?i.providers:d===`roleId`?i.roles:[`ref`,`body`].includes(d)?i.components:void 0,g=d===`model`?i.models?.[i.selectedProvider??``]:void 0,_=[`text`,`prompt`,`question`,`message`,`goal`,`expr`,`commandLine`,`reason`].includes(d);return(0,R.jsxs)(`label`,{className:`block space-y-1 text-xs`,children:[d,h?.length&&d!==`roleId`?(0,R.jsxs)(`select`,{className:K,value:typeof t==`string`?t:``,onChange:e=>n(e.target.value),children:[(0,R.jsx)(`option`,{value:``,children:s(`builder.core.select`)}),t&&!h.includes(String(t))?(0,R.jsx)(`option`,{value:String(t),children:String(t)}):null,h.map(e=>(0,R.jsx)(`option`,{children:e},e))]}):_?(0,R.jsx)(`textarea`,{className:`${K} min-h-24 resize-y font-mono`,value:typeof t==`string`?t:``,maxLength:typeof e.maxLength==`number`?e.maxLength:void 0,onChange:e=>n(e.target.value)}):(0,R.jsx)(`input`,{list:g?.length||d===`roleId`&&h?.length?c:void 0,className:K,value:typeof t==`string`?t:``,maxLength:typeof e.maxLength==`number`?e.maxLength:void 0,onChange:e=>n(e.target.value)}),g?.length||d===`roleId`&&h?.length?(0,R.jsx)(`datalist`,{id:c,children:(g??h??[]).map(e=>(0,R.jsx)(`option`,{value:e},e))}):null,typeof e.description==`string`&&(0,R.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:e.description})]})}var J=`w-full min-w-0 rounded border border-border bg-background px-2 py-1 text-xs`,Qe=[`journal`,`change`,`maxTokens`,`maxTransitions`,`policies`];function $e({graph:e,canvas:t,schema:n,onChange:r,onOpenCanvas:i}){let{t:o}=a(`loops`),[s,c]=(0,L.useState)(``),l=V(n.properties),u={type:`object`,additionalProperties:!1,properties:{...Object.fromEntries(Qe.filter(e=>l[e]).map(e=>[e,l[e]])),...V(V(l.budget).properties).maxTokens?{maxTokens:V(V(l.budget).properties).maxTokens}:{}}},d=Object.fromEntries(Object.entries(e.config).filter(([e])=>Qe.includes(e))),f=t?e.components?.[t]:void 0,p=t?[]:Ge(e);return(0,R.jsxs)(R.Fragment,{children:[!t&&(0,R.jsxs)(`label`,{className:`block space-y-1 text-xs`,children:[(0,R.jsx)(`span`,{children:o(`builder.core.reviewerStep`)}),(0,R.jsxs)(`select`,{className:J,value:e.config.reviewerStepId??``,onChange:t=>r({...e,config:{...e.config,reviewerStepId:t.target.value||void 0}}),children:[(0,R.jsx)(`option`,{value:``,children:o(`builder.core.reviewerAutomatic`)}),e.config.reviewerStepId&&!p.includes(e.config.reviewerStepId)&&(0,R.jsx)(`option`,{value:e.config.reviewerStepId,children:e.config.reviewerStepId}),p.map(e=>(0,R.jsx)(`option`,{value:e,children:e},e))]}),(0,R.jsx)(`span`,{className:`block text-muted-foreground`,children:o(`builder.core.reviewerHint`)})]}),(0,R.jsx)(q,{schema:u,value:d,path:o(`builder.core.options`),onChange:t=>{let n=Object.fromEntries(Object.entries(e.config).filter(([e])=>!Qe.includes(e)));r({...e,config:{...n,...t}})}}),(0,R.jsxs)(`section`,{className:`space-y-2`,children:[(0,R.jsx)(`p`,{className:`text-xs font-semibold`,children:o(`builder.core.components`)}),(0,R.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:Object.keys(e.components??{}).map(e=>(0,R.jsx)(`button`,{type:`button`,onClick:()=>i(e),className:`text-xs rounded border border-border px-2 py-1 hover:bg-muted`,children:e},e))}),(0,R.jsxs)(`div`,{className:`flex gap-1`,children:[(0,R.jsx)(`input`,{className:J,value:s,"aria-label":o(`builder.core.componentName`),placeholder:o(`builder.core.componentName`),onChange:e=>c(e.target.value)}),(0,R.jsx)(`button`,{type:`button`,disabled:!/^[a-z][a-z0-9-]{0,63}$/.test(s)||!!e.components?.[s],onClick:()=>{i(s,!0),c(``)},"aria-label":o(`builder.core.addComponent`),className:`text-accent-primary disabled:opacity-40`,children:(0,R.jsx)(v,{className:`w-4 h-4`})})]}),f&&t&&(0,R.jsx)(q,{schema:{type:`object`,additionalProperties:!1,required:[`inputs`,`outputs`],properties:{inputs:{type:`array`,items:{type:`string`}},outputs:{type:`array`,items:{type:`string`}}}},value:{inputs:f.inputs??[],outputs:f.outputs??[`next`,`failed`]},path:t,onChange:n=>{r({...e,components:{...e.components,[t]:{...f,...n}}})}})]})]})}function et({nodeId:e,data:t,piece:n,choices:r,schema:i,onChange:o,onDelete:s,onOpenCanvas:c}){let{t:l}=a(`loops`),u=t.params?.ref??t.params?.body,d=V(V(i.$defs).retry),f=n?.paramsSchema??{},p=t.coreKind===`assign`?{set:l(`builder.core.assignment.set`),increment:l(`builder.core.assignment.increment`)}:t.coreKind===`decider`?{continueWhen:l(`builder.core.requiredContinue`)}:{},m=Object.keys(p).length?{...f,properties:Object.fromEntries(Object.entries(V(f.properties)).map(([e,t])=>[e,p[e]?{...V(t),title:p[e]}:t]))}:f;return(0,R.jsxs)(`div`,{className:`space-y-3`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,R.jsx)(`h3`,{className:`text-sm font-semibold`,children:l(`builder.core.pieces.${t.coreKind}`)}),(0,R.jsx)(`button`,{type:`button`,onClick:s,"aria-label":l(`common:actions.delete`),className:`text-muted-foreground hover:text-destructive`,children:(0,R.jsx)(y,{className:`h-4 w-4`})})]}),(0,R.jsxs)(`label`,{className:`block text-xs`,children:[l(`builder.inspector.label`),(0,R.jsx)(`input`,{className:J,value:String(t.label??``),onChange:e=>o({label:e.target.value})})]}),[`implementation`,`implementation-step`].includes(t.coreKind??``)&&(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:l(`builder.core.legacyImplementation`)}),n?(0,R.jsx)(q,{schema:m,value:t.params??{},onChange:e=>o({params:e}),choices:r},e):(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:l(`builder.core.unavailable`)}),[`component`,`map`].includes(t.coreKind)&&typeof u==`string`&&(0,R.jsx)(`button`,{type:`button`,className:`text-xs text-accent-primary`,onClick:()=>c(u),children:l(`builder.core.openComponent`)}),Object.keys(d).length>0&&(0,R.jsx)(q,{schema:d,value:t.retry??{},path:`retry`,onChange:e=>o({retry:e})})]})}function tt(e){return e===`continue`||e===`stop`?e:void 0}function nt(e){switch(e){case`core`:return{kind:e,coreKind:`prompt`,params:{text:``,access:`write`,sessionContinuity:`run`}};case`ai-step`:return{kind:e,prompt:``,provider:`claude`,model:``,effort:`medium`,maxTurns:0};case`shell`:return{kind:e,command:``};case`decider`:return{kind:e,goal:``};case`condition`:return{kind:e,join:`AND`};case`end`:return{kind:e,outcome:`success`};default:return{kind:e}}}function Y(){return globalThis.crypto?.randomUUID?.()??`n-${Date.now()}-${Math.floor(Math.random()*1e9)}`}function rt(e,t){return{id:Y(),type:`loop`,position:t,data:nt(e)}}function it(e){let t=(e.nodes??[]).map(e=>({id:e.id,type:`loop`,position:e.position??{x:0,y:0},data:{...e.data??{},...e.type===`core`?{coreKind:e.data?.kind}:{},kind:e.type}})),n=new Map((e.nodes??[]).map(e=>[e.id,e.type]));return{nodes:t,edges:(e.edges??[]).map(e=>{let t=e.branch??(n.get(e.source)===`decider`?n.get(e.target)===`end`?`stop`:`continue`:void 0);return{id:e.id,source:e.source,target:e.target,sourceHandle:e.label??t??void 0,type:`smoothstep`,markerEnd:{type:Ne.ArrowClosed,width:16,height:16},label:e.label??e.join,data:{...e.join?{join:e.join}:{},...t?{branch:t}:{},...e.label?{label:e.label}:{}},...t?{style:{stroke:t===`stop`?`var(--color-accent-success)`:`var(--color-accent-highlight)`}}:{}}})}}function at(e,t,n,r){let i={...n};return i.legacyDeciderRole&&!e.some(e=>e.data.coreKind===`decider`&&e.data.params?.roleId===i.legacyDeciderRole)&&delete i.legacyDeciderRole,{nodes:e.map(e=>{let{kind:t,coreKind:n,...r}=e.data,i={id:e.id,type:t,position:e.position};return(Object.keys(r).length>0||n)&&(i.data={...r,...t===`core`?{kind:n}:{}}),i}),edges:t.map(t=>{let n=t.data?.join;if(e.find(e=>e.id===t.source)?.data.kind===`core`){let e=t.sourceHandle??t.data?.label;return{id:t.id,source:t.source,target:t.target,...e?{label:e}:{}}}let r=tt(t.sourceHandle)??tt(t.data?.branch);return{id:t.id,source:t.source,target:t.target,...n?{join:n}:{},...r?{branch:r}:{}}}),config:i,...r?{components:r}:{}}}var ot=`specrailsNodes`;function st(e,t){let n=e.filter(e=>e.selected);if(n.length===0)return null;let r=new Set(n.map(e=>e.id));return{specrailsNodes:1,nodes:n,edges:t.filter(e=>r.has(e.source)&&r.has(e.target))}}function ct(e){if(!e)return null;let t;try{t=JSON.parse(e)}catch{return null}let n=t;return!n||n[ot]==null||!Array.isArray(n.nodes)?null:{nodes:n.nodes,edges:Array.isArray(n.edges)?n.edges:[]}}function lt(e,t){let n=t.offset??{x:40,y:40},r=new Set(t.excludeKinds??[]),i=new Map;return{nodes:e.nodes.filter(e=>!r.has(String(e.data?.kind))).map(e=>{let r=t.mintId();return i.set(e.id,r),{...e,id:r,position:{x:e.position.x+n.x,y:e.position.y+n.y},selected:!0}}),edges:e.edges.filter(e=>i.has(e.source)&&i.has(e.target)).map(e=>({...e,id:t.mintId(),source:i.get(e.source),target:i.get(e.target),selected:!1}))}}function ut(e){return typeof e!=`string`||e.trim().length===0}function dt(e,t){let n=e.find(e=>e.data.kind===`start`),r=new Set;if(!n)return r;let i=new Map;for(let e of t)(i.get(e.source)??i.set(e.source,[]).get(e.source)).push(e.target);let a=[n.id];for(;a.length;){let e=a.shift();if(!r.has(e)){r.add(e);for(let t of i.get(e)??[])r.has(t)||a.push(t)}}return r}function ft(e,t){let n=[],r=e.filter(e=>e.data.kind===`start`);r.length===0&&n.push({severity:`error`,code:`NO_START`});for(let e of r.slice(1))n.push({severity:`error`,code:`MULTIPLE_START`,nodeId:e.id});if(e.some(e=>e.data.kind===`end`||e.data.kind===`core`&&e.data.coreKind===`end`)||n.push({severity:`error`,code:`NO_END`}),e.some(e=>e.data.kind===`core`)&&e.some(e=>![`start`,`core`,`end`].includes(e.data.kind))&&n.push({severity:`error`,code:`MIXED_ENGINES`}),r.length===1){let r=dt(e,t);for(let t of e)r.has(t.id)||n.push({severity:`error`,code:`ORPHAN`,nodeId:t.id})}let i=new Map;for(let e of t)(i.get(e.source)??i.set(e.source,[]).get(e.source)).push(e);for(let t of e){let e=i.get(t.id)??[];switch(t.data.kind){case`core`:{(!t.data.coreKind||!t.data.params||typeof t.data.params!=`object`||Array.isArray(t.data.params))&&n.push({severity:`error`,code:`CORE_PIECE`,nodeId:t.id});let r=e.map(e=>e.sourceHandle??e.data?.label);(t.data.coreKind===`end`?e.length>0:!r.length||r.some(e=>!e||!/^[a-z][a-z0-9-]{0,31}$/.test(e))||new Set(r).size!==r.length)&&n.push({severity:`error`,code:`CORE_OUTCOMES`,nodeId:t.id});break}case`decider`:{let r=new Set(e.map(e=>e.sourceHandle??e.data?.branch));(!r.has(`continue`)||!r.has(`stop`))&&n.push({severity:`error`,code:`DECIDER_BRANCHES`,nodeId:t.id}),ut(t.data.goal)&&n.push({severity:`warning`,code:`EMPTY_GOAL`,nodeId:t.id});break}case`ai-step`:ut(t.data.prompt)&&n.push({severity:`warning`,code:`EMPTY_PROMPT`,nodeId:t.id}),e.length===0&&n.push({severity:`warning`,code:`DEAD_END`,nodeId:t.id});break;case`shell`:ut(t.data.command)&&n.push({severity:`warning`,code:`EMPTY_COMMAND`,nodeId:t.id}),e.length===0&&n.push({severity:`warning`,code:`DEAD_END`,nodeId:t.id});break;case`start`:e.length===0&&n.push({severity:`warning`,code:`DEAD_END`,nodeId:t.id});break;default:break}}return n}function pt(e){let t=new Map;for(let n of e)n.nodeId&&(n.severity===`error`||!t.has(n.nodeId))&&t.set(n.nodeId,n.severity);return t}var mt=(0,L.createContext)(new Map),ht=(0,L.createContext)({pieces:[]}),gt=[`start`,`ai-step`,`shell`,`decider`,`end`],_t={core:he,start:g,"ai-step":he,shell:O,decider:h,condition:h,end:Te},vt={core:`border-accent-primary/60`,start:`border-accent-success/60`,"ai-step":`border-accent-primary/60`,shell:`border-accent-warning/60`,decider:`border-accent-highlight/60`,condition:`border-accent-info/60`,end:`border-accent-secondary/60`};function yt({id:e,data:t,selected:n}){let{t:r}=a(`loops`),i=t.kind,o=_t[i]??_,s=String(t.label??``).trim(),c=(0,L.useContext)(mt).get(e),l=(0,L.useContext)(ht),u=qe(l.pieces.find(e=>e.kind===t.coreKind),t.params??{},l.components),d=i===`core`?String(t.params?.roleId??t.params?.ref??t.params?.body??t.params?.text??t.params?.expr??``):i===`ai-step`?String(t.model||t.provider||``):i===`shell`?String(t.command||``):i===`decider`?String(t.goal||``):i===`condition`?String(t.join||`AND`):i===`end`?String(t.outcome||`success`):``;return(0,R.jsxs)(`div`,{className:S(`rounded-md border-2 bg-card px-3 py-2 min-w-[140px] shadow-sm`,vt[i],c===`error`?`ring-2 ring-destructive`:n?`ring-2 ring-accent-primary`:c===`warning`?`ring-2 ring-accent-warning`:``),children:[i!==`start`&&(0,R.jsx)(F,{type:`target`,position:I.Top}),(0,R.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,R.jsx)(o,{className:`w-3.5 h-3.5 text-foreground flex-shrink-0`}),(0,R.jsx)(`span`,{className:`text-xs font-semibold text-foreground truncate max-w-[150px]`,children:s||r(i===`core`?`builder.core.pieces.${t.coreKind}`:`builder.nodes.${i}`)}),s&&(0,R.jsx)(`span`,{className:`text-[9px] text-muted-foreground/70 flex-shrink-0`,children:r(i===`core`?`builder.core.pieces.${t.coreKind}`:`builder.nodes.${i}`)})]}),d&&(0,R.jsx)(`p`,{className:`text-[10px] text-muted-foreground mt-1 truncate max-w-[160px]`,children:d}),i===`core`?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`div`,{className:`flex justify-around gap-2 mt-2 text-[9px] text-accent-primary`,children:u.map(e=>(0,R.jsx)(`span`,{children:e},e))}),u.map((e,t)=>(0,R.jsx)(F,{id:e,type:`source`,position:I.Bottom,style:{left:`${(t+1)*100/(u.length+1)}%`},"aria-label":e},e))]}):i===`decider`?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`div`,{className:`mt-1.5 flex items-center justify-between gap-2 text-[9px] font-medium`,children:[(0,R.jsx)(`span`,{className:`text-accent-highlight`,children:r(`builder.branch.continue`)}),(0,R.jsx)(`span`,{className:`text-accent-success`,children:r(`builder.branch.stop`)})]}),(0,R.jsx)(F,{id:`continue`,type:`source`,position:I.Bottom,style:{left:`30%`},className:`!bg-accent-highlight`}),(0,R.jsx)(F,{id:`stop`,type:`source`,position:I.Bottom,style:{left:`70%`},className:`!bg-accent-success`})]}):i===`end`?null:(0,R.jsx)(F,{type:`source`,position:I.Bottom})]})}function bt({loopId:e,onExit:t,onWindowOpened:n}){let{t:o}=a(`loops`),u=i(),{id:d}=r(),h=e??d,g=(0,L.useCallback)(()=>{t?t():u(`/loops`)},[t,u]),_=we(),{fitView:y,screenToFlowPosition:re}=ke(),{activeProjectId:w}=c(),[T,ce]=(0,L.useState)([]),[E,fe]=(0,L.useState)({}),[he,ge]=(0,L.useState)(!1),[D,_e]=(0,L.useState)({}),[ve,O]=(0,L.useState)([]),[A,j]=(0,L.useState)(null),[M,be]=(0,L.useState)(null);(0,L.useEffect)(()=>{let e=!1;return k.catalog().then(t=>{e||(ce(t.nodeKinds),fe(t.definitionSchema??{}),ge(!1))}).catch(()=>{e||ge(!0)}),()=>{e=!0}},[]),(0,L.useEffect)(()=>{let e=new AbortController;_e({});let t=t=>fetch(t,{signal:e.signal}).then(e=>e.ok?e.json():null).catch(()=>null);return Promise.all([w&&A&&!A.config.agents?t(`${s()}/agent-runtime/config`):Promise.resolve(null),t(`/api/runtime-providers`)]).then(([t,n])=>{e.signal.aborted||_e({providers:(t?.config?.providers??n?.providers??[]).map(e=>e.id),roles:[...new Set([...Object.keys(t?.config?.agents??{}),...Object.keys(t?.config?.roles??{}),...Object.keys(t?.workflowRoleDefaults??{})])],models:Object.fromEntries(Object.entries(n?.status??{}).map(([e,t])=>[e,t.models??[]]))})}),()=>e.abort()},[w,!!A,!!A?.config.agents]);let[N,P,Te]=Oe([]),[F,I,Fe]=Le([]),[z,Ve]=(0,L.useState)(``),[He,Ue]=(0,L.useState)(!1),[We,B]=(0,L.useState)(!1),[Ge,V]=(0,L.useState)(10),[H,U]=(0,L.useState)(30),[Xe,W]=(0,L.useState)(null),[G,K]=(0,L.useState)(null),[q,J]=(0,L.useState)(!1);(0,L.useEffect)(()=>J(!1),[h]);let[Qe,tt]=(0,L.useState)(!0),[nt,ot]=(0,L.useState)(!1),[ut,dt]=(0,L.useState)(!1),[vt,bt]=(0,L.useState)(null),[xt,St]=(0,L.useState)(!1),X=(0,L.useMemo)(()=>[...ft(N,F),...ve.map(e=>({severity:`error`,code:`CORE_VALIDATION`,nodeId:e.nodeId,message:e.message}))],[N,F,ve]),Ct=(0,L.useMemo)(()=>pt(X),[X]),wt=X.filter(e=>e.severity===`error`).length,[Ot,kt]=(0,L.useState)(`manual`),At=(0,L.useRef)(new Map),[jt,Mt]=(0,L.useState)([]),[Nt,Pt]=(0,L.useState)(!1),Ft=(0,L.useCallback)(async()=>{try{Mt(await k.loopConstants())}catch{}},[]);(0,L.useEffect)(()=>{Ft()},[Ft]);let It=(0,L.useMemo)(()=>({loop:yt}),[]),Lt=(0,L.useCallback)(e=>{j(e.graph),be(null);let{nodes:t,edges:n}=it(e.graph);At.current=new Map(t.map(e=>[e.id,{...e.position}]));let r=e.graph.config?.layout,i=r===`vertical`||r===`horizontal`||r===`grid`?r:`manual`;kt(i),P(i===`manual`?t:Ie(t,n,i)),I(n),Ve(e.name),V(e.graph.config?.maxIterations??10),U(e.graph.config?.timeoutMinutes??30),W(typeof e.graph.config?.maxCostUsd==`number`?e.graph.config.maxCostUsd:null),Ue(!!e.builtinId)},[P,I]);(0,L.useEffect)(()=>{if(!h)return;let e=!1;return k.get(h).then(t=>{e||Lt(t)}).catch(()=>l.error(o(`errors.load`))).finally(()=>{e||tt(!1)}),()=>{e=!0}},[h,Lt,o]);let Rt=(0,L.useCallback)(async()=>{if(h){B(!1);try{Lt(await k.restoreBuiltin(h)),O([]),l.success(o(`builder.builtin.restored`))}catch(e){l.error(e instanceof Error&&e.message?e.message:o(`errors.save`))}}},[h,Lt,o]),zt=(0,L.useCallback)(e=>{if(O([]),N.find(t=>t.id===e.source)?.data.kind===`core`){I(t=>De({...e,label:e.sourceHandle,data:{label:e.sourceHandle}},t));return}let t=e.sourceHandle===`continue`||e.sourceHandle===`stop`?e.sourceHandle:void 0,n=t?{...e,data:{branch:t},style:{stroke:t===`stop`?`var(--color-accent-success)`:`var(--color-accent-highlight)`}}:e;I(e=>De(n,e))},[I,N]),Bt=(0,L.useCallback)(e=>{if(!e.source||!e.target)return!1;let t=N.find(t=>t.id===e.source)?.data.kind,n=N.find(t=>t.id===e.target)?.data.kind;if(!t||!n||e.source===e.target&&t!==`core`||t===`end`)return!1;if(t===`core`){let t=N.find(t=>t.id===e.source),n=qe(T.find(e=>e.kind===t.data.coreKind),t.data.params??{},A?.components);if(!e.sourceHandle||!n.includes(e.sourceHandle)||F.some(t=>t.source===e.source&&t.sourceHandle===e.sourceHandle))return!1}return!(t===`start`&&F.some(t=>t.source===e.source)||n===`start`)},[N,F,T,A]),Vt=(0,L.useCallback)(e=>{kt(e==="default"?`manual`:e),P(t=>e==="default"?t.map(e=>{let t=At.current.get(e.id);return t?{...e,position:{...t}}:e}):Ie(t,F,e)),requestAnimationFrame(()=>y({padding:.25,maxZoom:.85,duration:300}))},[P,F,y]),Ht=(0,L.useCallback)(e=>{e.some(e=>e.type===`position`&&e.dragging===!1)&&kt(`manual`),Te(e)},[Te]),Ut=(0,L.useRef)(N);Ut.current=N;let Wt=(0,L.useRef)(F);Wt.current=F,(0,L.useEffect)(()=>{let e=()=>{let e=window.document.activeElement;return!!e&&(e.tagName===`INPUT`||e.tagName===`TEXTAREA`||e.isContentEditable)},t=t=>{if(e())return;let n=st(Ut.current,Wt.current);!n||!t.clipboardData||(t.clipboardData.setData(`text/plain`,JSON.stringify(n)),t.preventDefault())},n=t=>{if(e())return;let n=ct(t.clipboardData?.getData(`text/plain`)??``);if(!n)return;t.preventDefault();let r=lt(n,{mintId:Y,offset:{x:40,y:40},excludeKinds:Ut.current.some(e=>e.data.kind===`start`)?[`start`]:[]});r.nodes.length!==0&&(P(e=>[...e.map(e=>({...e,selected:!1})),...r.nodes]),I(e=>[...e,...r.edges]),kt(`manual`),l.success(o(`builder.paste.done`,{count:r.nodes.length})))};return window.addEventListener(`copy`,t),window.addEventListener(`paste`,n),()=>{window.removeEventListener(`copy`,t),window.removeEventListener(`paste`,n)}},[P,I,o]);let Gt=(0,L.useCallback)(e=>{let t=rt(e,{x:120+Math.random()*120,y:80+Math.random()*240});P(e=>[...e,t]),J(!1),K(t.id)},[P]),Kt=(0,L.useCallback)(e=>{O([]),P(t=>t.map(t=>t.id===G?{...t,data:{...t.data,...e}}:t))},[G,P]),qt=(0,L.useCallback)(()=>{G&&(P(e=>e.filter(e=>e.id!==G)),I(e=>e.filter(e=>e.source!==G&&e.target!==G)),K(null))},[G,P,I]),Z=!!A&&!N.some(e=>![`start`,`core`,`end`].includes(e.data.kind)),Q=(0,L.useCallback)(()=>{let e={...A?.config,maxIterations:Ge,timeoutMinutes:H,maxCostUsd:Xe??void 0,layout:Ot},t=M?A?.components?.[M]:A,n={...t,...at(N,F,M?t?.config??e:e)};return M?{...A,config:e,components:{...A?.components,[M]:n}}:{...n,components:A?.components}},[A,M,N,F,Ge,H,Xe,Ot]),Jt=(0,L.useCallback)((e,t=!1)=>{let n=Q();e&&t&&!n.components?.[e]&&(n.components={...n.components,[e]:{nodes:[{id:Y(),type:`start`,position:{x:160,y:40}},{id:Y(),type:`core`,position:{x:160,y:220},data:{kind:`end`,params:{outcome:`success`}}}],edges:[],config:{maxIterations:10,timeoutMinutes:0},inputs:[],outputs:[`next`,`failed`]}});let r=e?n.components?.[e]:n;if(!r)return;let i=it(r);j(n),be(e),P(i.nodes),I(i.edges),K(null),O([]),requestAnimationFrame(()=>y({padding:.25}))},[Q,P,I,y]),Yt=(0,L.useCallback)((e,t)=>{let n={id:Y(),type:`loop`,position:t??{x:160+N.length*20,y:100+N.length*30},data:Ke(e)};if(e.kind===`role-turn`&&A){let e=D.providers?.[0]??`claude`,t=(`agent-`+n.id.replace(/[^a-z0-9-]/g,`-`)).slice(0,64),r=A.config.agents??{schemaVersion:1,agents:{architect:{provider:e},developer:{provider:e},reviewer:{provider:e}}};n.data.params={roleId:t,prompt:o(`builder.core.agentTaskDefault`)},j({...A,config:{...A.config,agents:{...r,roles:{...r.roles,[t]:{provider:e,access:`write`,artifacts:`none`,prompt:``}}}}})}e.kind===`prompt`&&D.providers?.length&&(n.data.params.engine={provider:D.providers[0]}),P(e=>[...e,n]),J(!1),K(n.id)},[N.length,P,D.providers,A,o]),Xt=(0,L.useCallback)(async()=>{St(!0);try{let e=Q(),{steps:t}=await k.previewLoop(e);bt(t)}catch{l.error(o(`builder.preview.error`))}finally{St(!1)}},[Q,o]),Zt=(0,L.useCallback)(async()=>{if(!h)return!1;ot(!0);try{let e=Q();return await k.update(h,{name:z,graph:e}),!0}catch(e){return l.error(e instanceof Error&&e.message?e.message:o(`errors.save`)),!1}finally{ot(!1)}},[h,Q,z,o]),Qt=(0,L.useCallback)(async()=>{if(h&&await Zt())try{await k.publish(h),l.success(o(`builder.published`)),g()}catch(e){e instanceof Ce?(O(e.errors),dt(!0),l.error(o(`errors.publishInvalid`))):l.error(e instanceof Error&&e.message?e.message:o(`errors.save`))}},[h,Zt,g,o]),$=N.find(e=>e.id===G)??null;return(0,R.jsx)(mt.Provider,{value:Ct,children:(0,R.jsx)(ht.Provider,{value:{pieces:T,components:A?.components},children:(0,R.jsxs)(`div`,{className:`h-full flex flex-col`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-between gap-3 px-4 h-12 border-b border-border flex-shrink-0`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[(0,R.jsx)(`button`,{type:`button`,onClick:g,className:`text-muted-foreground hover:text-foreground`,"aria-label":o(`builder.back`),children:(0,R.jsx)(f,{className:`w-4 h-4`})}),(0,R.jsx)(`input`,{value:z,onChange:e=>Ve(e.target.value),className:`text-sm font-semibold bg-transparent text-foreground border-b border-transparent focus:border-border focus:outline-none min-w-0`,"aria-label":`name`})]}),(0,R.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,R.jsxs)(le,{delayDuration:150,children:[(0,R.jsxs)(`label`,{className:`text-[10px] text-muted-foreground flex items-center gap-1`,children:[o(`builder.config.maxIterations`),(0,R.jsxs)(ue,{children:[(0,R.jsx)(me,{asChild:!0,children:(0,R.jsx)(`button`,{type:`button`,onClick:e=>e.preventDefault(),className:`text-muted-foreground/60 hover:text-foreground`,"aria-label":o(`builder.config.maxIterations`),children:(0,R.jsx)(de,{className:`w-3 h-3`})})}),(0,R.jsx)(xe,{className:`max-w-xs leading-relaxed`,children:o(`builder.config.maxIterationsHint`)})]}),(0,R.jsx)(`input`,{type:`number`,min:1,value:Ge,onChange:e=>V(Math.max(1,Number(e.target.value)||1)),className:`w-14 h-6 text-xs rounded border border-border bg-transparent px-1 text-foreground`})]}),(0,R.jsxs)(`label`,{className:`text-[10px] text-muted-foreground flex items-center gap-1`,children:[o(`builder.config.timeout`),(0,R.jsxs)(ue,{children:[(0,R.jsx)(me,{asChild:!0,children:(0,R.jsx)(`button`,{type:`button`,onClick:e=>e.preventDefault(),className:`text-muted-foreground/60 hover:text-foreground`,"aria-label":o(`builder.config.timeout`),children:(0,R.jsx)(de,{className:`w-3 h-3`})})}),(0,R.jsx)(xe,{className:`max-w-xs leading-relaxed`,children:o(`builder.config.timeoutHint`)})]}),(0,R.jsx)(`input`,{type:`number`,min:0,"aria-label":o(`builder.config.timeout`),value:H,onChange:e=>U(Math.max(0,Number(e.target.value)||0)),className:`w-14 h-6 text-xs rounded border border-border bg-transparent px-1 text-foreground`})]}),(0,R.jsxs)(`label`,{className:`text-[10px] text-muted-foreground flex items-center gap-1`,children:[o(`builder.config.maxCost`),(0,R.jsxs)(ue,{children:[(0,R.jsx)(me,{asChild:!0,children:(0,R.jsx)(`button`,{type:`button`,onClick:e=>e.preventDefault(),className:`text-muted-foreground/60 hover:text-foreground`,"aria-label":o(`builder.config.maxCost`),children:(0,R.jsx)(de,{className:`w-3 h-3`})})}),(0,R.jsx)(xe,{className:`max-w-xs leading-relaxed`,children:o(`builder.config.maxCostHint`)})]}),(0,R.jsx)(`input`,{type:`number`,min:0,step:.5,placeholder:`∞`,value:Xe??``,onChange:e=>{let t=Number(e.target.value);W(e.target.value===``||!(t>0)?null:t)},className:`w-16 h-6 text-xs rounded border border-border bg-transparent px-1 text-foreground`})]})]}),Z&&(0,R.jsx)(`button`,{type:`button`,"aria-pressed":q,onClick:()=>J(e=>!e),className:`inline-flex items-center gap-1.5 h-7 px-2.5 rounded-md text-xs border border-border hover:bg-muted text-foreground`,children:o(`builder.loopSettings`)}),He&&(0,R.jsxs)(`button`,{type:`button`,onClick:()=>B(!0),disabled:nt,"data-testid":`builder-restore-builtin`,className:`inline-flex items-center gap-1.5 h-7 px-2.5 rounded-md text-xs border border-border hover:bg-muted text-foreground disabled:opacity-50`,children:[(0,R.jsx)(ee,{className:`w-3 h-3`}),` `,o(`actions.restoreBuiltin`)]}),(0,R.jsxs)(`button`,{type:`button`,onClick:()=>void Xt(),disabled:xt,className:`inline-flex items-center gap-1.5 h-7 px-2.5 rounded-md text-xs border border-border hover:bg-muted text-foreground disabled:opacity-50`,children:[(0,R.jsx)(pe,{className:`w-3 h-3`}),` `,o(`builder.preview.label`)]}),!Se()&&(0,R.jsxs)(`button`,{type:`button`,disabled:nt,onClick:()=>void Zt().then(async e=>{if(!(!e||!h))try{await ye(w,h),n?n():g()}catch(e){l.error(String(e))}}),className:`inline-flex items-center gap-1.5 h-7 px-2.5 rounded-md text-xs border border-border hover:bg-muted disabled:opacity-50`,children:[(0,R.jsx)(m,{className:`w-3 h-3`}),o(`window.open`)]}),(0,R.jsxs)(`button`,{type:`button`,onClick:()=>void Zt().then(e=>e&&l.success(o(`builder.saved`))),disabled:nt,className:`inline-flex items-center gap-1.5 h-7 px-2.5 rounded-md text-xs border border-border hover:bg-muted text-foreground disabled:opacity-50`,children:[(0,R.jsx)(p,{className:`w-3 h-3`}),` `,o(`builder.save`)]}),(0,R.jsxs)(`button`,{type:`button`,onClick:()=>void Qt(),disabled:nt,className:`inline-flex items-center gap-1.5 h-7 px-2.5 rounded-md text-xs bg-accent-primary text-white hover:bg-accent-primary/90 disabled:opacity-50`,children:[(0,R.jsx)(ne,{className:`w-3 h-3`}),` `,o(`builder.publish`)]})]})]}),He&&(0,R.jsx)(`div`,{role:`note`,"data-testid":`builder-builtin-note`,className:`px-4 py-1.5 border-b border-border bg-accent-info/10 text-[11px] text-accent-info flex-shrink-0`,children:o(`builder.builtin.note`)}),(0,R.jsx)(se,{open:We,onOpenChange:e=>{e||B(!1)},children:(0,R.jsxs)(x,{className:`max-w-sm`,children:[(0,R.jsxs)(b,{children:[(0,R.jsx)(oe,{children:o(`builder.builtin.confirmTitle`)}),(0,R.jsx)(ae,{children:o(`builder.builtin.confirmBody`)})]}),(0,R.jsxs)(ie,{children:[(0,R.jsx)(C,{variant:`ghost`,onClick:()=>B(!1),children:o(`common:actions.cancel`)}),(0,R.jsx)(C,{"data-testid":`builder-restore-confirm`,onClick:()=>void Rt(),children:o(`actions.restoreBuiltin`)})]})]})}),(0,R.jsxs)(`div`,{className:`flex-1 flex min-h-0`,children:[(0,R.jsxs)(`div`,{className:`w-44 border-r border-border p-2 space-y-1 flex-shrink-0 overflow-y-auto`,children:[(0,R.jsx)(`p`,{className:`text-[10px] font-semibold uppercase tracking-wide text-muted-foreground px-1 mb-1`,children:o(`builder.addNode`)}),Z&&he&&(0,R.jsx)(`p`,{role:`status`,className:`text-xs text-muted-foreground px-1`,children:o(`builder.core.unavailable`)}),Z&&T.length>0&&[`ai`,`verification`,`openspec`,`control`].map(e=>(0,R.jsxs)(`div`,{className:`pt-2`,children:[(0,R.jsx)(`p`,{className:`text-[10px] uppercase text-muted-foreground px-1`,children:o(`builder.core.groups.${e}`)}),T.filter(t=>![`implementation`,`implementation-step`].includes(t.kind)&&Je(t.kind)===e).map(e=>(0,R.jsxs)(`button`,{type:`button`,draggable:!0,onDragStart:t=>{t.dataTransfer.setData(`application/specrails-core-piece`,e.kind),t.dataTransfer.effectAllowed=`copy`},onClick:()=>Yt(e),className:`flex items-center gap-2 w-full min-h-8 px-2 rounded text-left text-xs hover:bg-muted focus-visible:ring-2 focus-visible:ring-accent-primary`,children:[(0,R.jsx)(v,{className:`h-3 w-3 flex-shrink-0`}),o(`builder.core.pieces.${e.kind}`)]},e.kind))]},e)),(Z?[`start`]:gt).map(e=>{let t=_t[e];return(0,R.jsxs)(`button`,{type:`button`,onClick:()=>Gt(e),disabled:e===`start`&&N.some(e=>e.data.kind===`start`),className:`flex items-center gap-2 w-full h-8 px-2 rounded-md text-xs text-muted-foreground hover:text-foreground hover:bg-muted/50`,children:[(0,R.jsx)(t,{className:`w-3.5 h-3.5 flex-shrink-0`}),(0,R.jsx)(`span`,{className:`truncate`,children:o(`builder.nodes.${e}`)}),(0,R.jsx)(v,{className:`w-3 h-3 ml-auto opacity-50`})]},e)})]}),(0,R.jsx)(`div`,{className:`flex-1 min-w-0 relative`,onDragOver:e=>{e.dataTransfer.types.includes(`application/specrails-core-piece`)&&(e.preventDefault(),e.dataTransfer.dropEffect=`copy`)},onDrop:e=>{let t=T.find(t=>t.kind===e.dataTransfer.getData(`application/specrails-core-piece`));!t||!Z||(e.preventDefault(),Yt(t,re({x:e.clientX,y:e.clientY})))},children:Qe?(0,R.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,R.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`…`})}):(0,R.jsxs)(Ae,{nodes:N,edges:F,onNodesChange:Ht,onEdgesChange:Fe,onConnect:zt,isValidConnection:Bt,onNodeClick:(e,t)=>{J(!1),K(t.id)},onPaneClick:()=>{J(!1),K(null)},nodeTypes:It,colorMode:_.scheme===`dark`?`dark`:`light`,fitView:!0,fitViewOptions:{padding:.25,maxZoom:.85},minZoom:.2,defaultEdgeOptions:{type:`smoothstep`,markerEnd:{type:Ne.ArrowClosed,width:16,height:16}},proOptions:{hideAttribution:!0},children:[Z&&(0,R.jsx)(Me,{position:`top-center`,children:(0,R.jsxs)(`nav`,{className:`flex items-center gap-1 rounded border border-border bg-card/95 p-1 text-xs`,"aria-label":o(`builder.core.breadcrumbs`),children:[(0,R.jsx)(`button`,{type:`button`,onClick:()=>Jt(null),className:`px-2 py-1 hover:bg-muted`,children:z||o(`builder.core.root`)}),M&&(0,R.jsxs)(`span`,{"aria-current":`page`,children:[`/ `,M]})]})}),(0,R.jsx)(je,{}),(0,R.jsx)(Pe,{}),(0,R.jsx)(Ee,{pannable:!0,zoomable:!0}),(0,R.jsx)(Me,{position:`top-left`,children:(0,R.jsx)(`div`,{className:`flex items-center gap-0.5 rounded-md border border-border bg-card/90 backdrop-blur p-0.5`,role:`group`,"aria-label":o(`builder.arrange.label`),children:[[`vertical`,Be],[`horizontal`,ze],[`grid`,Re],[`default`,ee]].map(([e,t])=>{let n=e==="default"?`reset`:e,r=e==="default"?Ot===`manual`:Ot===e;return(0,R.jsx)(`button`,{type:`button`,title:o(`builder.arrange.${n}`),"aria-label":o(`builder.arrange.${n}`),"aria-pressed":r,onClick:()=>Vt(e),className:S(`inline-flex items-center justify-center w-7 h-7 rounded hover:bg-muted`,r?`bg-muted text-accent-primary`:`text-muted-foreground hover:text-foreground`),children:(0,R.jsx)(t,{className:`w-3.5 h-3.5`})},e)})})}),(0,R.jsx)(Me,{position:`top-right`,children:(0,R.jsx)(le,{delayDuration:150,children:(0,R.jsxs)(ue,{children:[(0,R.jsx)(me,{asChild:!0,children:(0,R.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1 h-6 px-2 rounded-md text-[10px] border border-border bg-card/90 text-muted-foreground hover:text-foreground backdrop-blur`,children:[(0,R.jsx)(de,{className:`w-3 h-3`}),o(`builder.edgesHelp.label`)]})}),(0,R.jsx)(xe,{className:`max-w-xs leading-relaxed`,children:o(`builder.edgesHelp.body`)})]})})}),X.length>0&&(0,R.jsx)(Me,{position:`bottom-center`,children:(0,R.jsxs)(`div`,{className:`rounded-md border border-border bg-card/95 backdrop-blur text-xs overflow-hidden max-w-md mb-2`,children:[(0,R.jsxs)(`button`,{type:`button`,onClick:()=>dt(e=>!e),className:S(`flex items-center gap-1.5 w-full px-2.5 py-1.5 font-medium`,wt>0?`text-destructive`:`text-accent-warning`),children:[(0,R.jsx)(te,{className:`w-3.5 h-3.5`}),o(`builder.problems.count`,{count:X.length})]}),ut&&(0,R.jsx)(`ul`,{className:`border-t border-border max-h-40 overflow-y-auto py-1`,children:X.map((e,t)=>(0,R.jsx)(`li`,{children:(0,R.jsxs)(`button`,{type:`button`,disabled:!e.nodeId,onClick:()=>{e.nodeId&&(J(!1),K(e.nodeId))},className:`flex items-start gap-1.5 w-full text-left px-2.5 py-1 hover:bg-muted disabled:cursor-default`,children:[(0,R.jsx)(`span`,{className:S(`mt-1 w-1.5 h-1.5 rounded-full flex-shrink-0`,e.severity===`error`?`bg-destructive`:`bg-accent-warning`)}),(0,R.jsx)(`span`,{className:`text-foreground`,children:`message`in e?String(e.message):o(`builder.problems.${e.code}`)})]})},`${e.code}-${e.nodeId??t}`))})]})})]})}),(0,R.jsxs)(`div`,{className:`w-80 border-l border-border p-3 flex-shrink-0 overflow-y-auto space-y-4`,children:[!q&&($?$.data.kind===`core`?(0,R.jsx)(et,{nodeId:$.id,data:$.data,piece:T.find(e=>e.kind===$.data.coreKind),choices:{...D,roles:A?.config.agents?[...Object.keys(A.config.agents.agents),...Object.keys(A.config.agents.roles??{})]:D.roles,components:Object.keys(A?.components??{})},schema:E,onChange:Kt,onDelete:qt,onOpenCanvas:Jt}):(0,R.jsx)(Dt,{data:$.data,onChange:Kt,onDelete:qt,constants:jt,onManageConstants:()=>Pt(!0)}):(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:o(`builder.inspector.selectNode`)})),!q&&Z&&A&&$&&(Ye($.id,$.data.coreKind,$.data.params??{}).length>0||$.data.coreKind===`implementation-step`&&$.data.params?.phase===`archive`)&&(0,R.jsx)(Ze,{mode:$.data.coreKind===`implementation`?`all`:`step`,graph:Q(),value:A.config.agents,selectedRole:String($.data.params?.phase??Ye($.id,$.data.coreKind,$.data.params??{})[0]??``),onChange:e=>j({...A,config:{...A.config,agents:e}})},`${h}:${$.id}`),q&&Z&&A&&(0,R.jsx)(Ze,{mode:`workflow`,graph:Q(),value:A.config.agents,selectedRole:$?Ye($.id,$.data.coreKind,$.data.params??{})[0]:void 0,onChange:e=>j({...A,config:{...A.config,agents:e}})},h),q&&Z&&A&&(0,R.jsx)($e,{graph:A,canvas:M,schema:E,onChange:j,onOpenCanvas:Jt})]})]}),(0,R.jsx)(Tt,{open:Nt,onClose:()=>Pt(!1),constants:jt,onChanged:Ft,t:o}),(0,R.jsx)(Et,{steps:vt,onClose:()=>bt(null),t:o})]})})})}var xt=[{labelKey:`builder.inspector.tokensSpec`,tokens:[{token:`{{spec.title}}`,label:`spec.title`},{token:`{{spec.description}}`,label:`spec.description`},{token:`{{spec.id}}`,label:`spec.id`},{token:`{{spec.status}}`,label:`spec.status`},{token:`{{spec.priority}}`,label:`spec.priority`},{token:`{{spec.labels}}`,label:`spec.labels`}]},{labelKey:`builder.inspector.tokensJira`,tokens:[{token:`{{spec.jira_key}}`,label:`spec.jira_key`},{token:`{{spec.jira_url}}`,label:`spec.jira_url`}]}];function St({token:e,label:t,description:n,onInsert:r}){return(0,R.jsx)(`button`,{type:`button`,draggable:!0,onDragStart:t=>t.dataTransfer.setData(`text/plain`,e),onClick:()=>r(e),title:n?`${e} — ${n}`:e,className:`px-1.5 py-0.5 rounded border border-border bg-surface/40 text-[10px] font-mono text-accent-primary hover:bg-accent-primary/10 cursor-grab active:cursor-grabbing`,children:t})}function X({t:e,onInsert:t}){let[n,r]=(0,L.useState)([]);return(0,L.useEffect)(()=>{let e=!1;return k.loopCommands().then(t=>{e||r(t)}).catch(()=>{}),()=>{e=!0}},[]),(0,R.jsxs)(`div`,{className:`mb-2 space-y-1.5`,children:[xt.map(n=>(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{className:`block text-[9px] uppercase tracking-wide text-muted-foreground/70 mb-0.5`,children:e(n.labelKey)}),(0,R.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:n.tokens.map(e=>(0,R.jsx)(St,{token:e.token,label:e.label,onInsert:t},e.token))})]},n.labelKey)),n.length>0&&(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{className:`block text-[9px] uppercase tracking-wide text-muted-foreground/70 mb-0.5`,children:e(`builder.inspector.tokensCommands`)}),(0,R.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:n.map(e=>(0,R.jsx)(St,{token:`{{cmd:${e.name}}}`,label:`⚡ ${e.label}`,description:e.description,onInsert:t},e.name))})]})]})}function Ct({t:e,constants:t,onInsert:n,onManage:r}){return(0,R.jsxs)(`div`,{className:`mb-2`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-between mb-0.5`,children:[(0,R.jsx)(`span`,{className:`text-[9px] uppercase tracking-wide text-muted-foreground/70`,children:e(`builder.constants.label`)}),(0,R.jsx)(`button`,{type:`button`,onClick:r,title:e(`builder.constants.manage`),"aria-label":e(`builder.constants.manage`),className:`text-muted-foreground hover:text-foreground`,children:(0,R.jsx)(P,{className:`w-3 h-3`})})]}),(0,R.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:t.map(e=>(0,R.jsx)(St,{token:`{{const:${e.name}}}`,label:e.builtin?`🔒 ${e.name}`:e.name,description:e.value,onInsert:n},e.id))})]})}function wt({c:e,onSave:t,onDelete:n}){let[r,i]=(0,L.useState)(e.value);return(0,R.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,R.jsx)(`code`,{className:`text-[10px] font-mono text-accent-primary w-28 truncate`,title:e.name,children:e.name}),(0,R.jsx)(`input`,{className:`flex-1 text-xs rounded border border-border bg-transparent px-2 py-1 text-foreground`,value:r,onChange:e=>i(e.target.value)}),(0,R.jsx)(`button`,{type:`button`,disabled:r===e.value||!r,onClick:()=>t(r),className:`text-muted-foreground hover:text-foreground disabled:opacity-40`,"aria-label":`save`,children:(0,R.jsx)(p,{className:`w-3.5 h-3.5`})}),(0,R.jsx)(`button`,{type:`button`,onClick:n,className:`text-muted-foreground hover:text-destructive`,"aria-label":`delete`,children:(0,R.jsx)(y,{className:`w-3.5 h-3.5`})})]})}function Tt({open:e,onClose:t,constants:n,onChanged:r,t:i}){let[a,o]=(0,L.useState)(``),[s,c]=(0,L.useState)(``),[l,u]=(0,L.useState)(null),[d,f]=(0,L.useState)(!1),p=n.filter(e=>e.builtin),m=n.filter(e=>!e.builtin),h=async()=>{f(!0),u(null);try{await k.createConstant(a.trim(),s),o(``),c(``),await r()}catch(e){u(e instanceof Error?e.message:`error`)}finally{f(!1)}},g=`text-xs rounded border border-border bg-transparent px-2 py-1 text-foreground focus:outline-none focus:ring-1 focus:ring-accent-primary/40`;return(0,R.jsx)(se,{open:e,onOpenChange:e=>{e||t()},children:(0,R.jsxs)(x,{className:`max-w-md`,children:[(0,R.jsx)(b,{children:(0,R.jsx)(oe,{children:i(`builder.constants.title`)})}),(0,R.jsxs)(`div`,{className:`space-y-3`,children:[(0,R.jsxs)(`div`,{className:`space-y-1.5`,children:[m.length===0&&(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:i(`builder.constants.empty`)}),m.map(e=>(0,R.jsx)(wt,{c:e,onSave:t=>void k.updateConstant(e.id,t).then(r),onDelete:()=>void k.deleteConstant(e.id).then(r)},e.id))]}),(0,R.jsxs)(`div`,{className:`flex items-center gap-1.5 border-t border-border pt-2`,children:[(0,R.jsx)(`input`,{className:`${g} w-28`,placeholder:i(`builder.constants.name`),value:a,onChange:e=>o(e.target.value)}),(0,R.jsx)(`input`,{className:`${g} flex-1`,placeholder:i(`builder.constants.value`),value:s,onChange:e=>c(e.target.value)}),(0,R.jsx)(C,{size:`sm`,disabled:d||!a.trim()||!s,onClick:()=>void h(),children:i(`builder.constants.add`)})]}),l&&(0,R.jsx)(`p`,{className:`text-[10px] text-destructive`,children:l}),p.length>0&&(0,R.jsxs)(`div`,{className:`border-t border-border pt-2 space-y-1`,children:[(0,R.jsx)(`span`,{className:`text-[9px] uppercase tracking-wide text-muted-foreground/70`,children:i(`builder.constants.builtinBadge`)}),p.map(e=>(0,R.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[10px]`,children:[(0,R.jsx)(`code`,{className:`font-mono text-accent-primary w-28 truncate`,title:e.name,children:e.name}),(0,R.jsx)(`span`,{className:`text-muted-foreground truncate`,children:e.value})]},e.id))]})]}),(0,R.jsx)(ie,{children:(0,R.jsx)(C,{variant:`ghost`,onClick:t,children:i(`common:actions.close`)})})]})})}function Et({steps:e,onClose:t,t:n}){return(0,R.jsx)(se,{open:e!==null,onOpenChange:e=>{e||t()},children:(0,R.jsxs)(x,{className:`max-w-2xl`,children:[(0,R.jsx)(b,{children:(0,R.jsx)(oe,{children:n(`builder.preview.title`)})}),(0,R.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:n(`builder.preview.sampleNote`)}),(0,R.jsxs)(`div`,{className:`space-y-2 max-h-[60vh] overflow-y-auto`,children:[e&&e.length===0&&(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:n(`builder.preview.empty`)}),e?.map((e,t)=>(0,R.jsxs)(`div`,{className:`rounded-md border border-border`,children:[(0,R.jsxs)(`div`,{className:`px-2.5 py-1 text-[10px] border-b border-border flex items-center gap-1.5`,children:[(0,R.jsx)(`span`,{className:`font-medium text-foreground`,children:e.label||n([`start`,`end`,`ai-step`,`shell`,`decider`,`condition`].includes(e.kind)?`builder.nodes.${e.kind}`:`builder.core.pieces.${e.kind}`)}),(0,R.jsxs)(`span`,{className:`text-muted-foreground`,children:[`· `,n([`start`,`end`,`ai-step`,`shell`,`decider`,`condition`].includes(e.kind)?`builder.nodes.${e.kind}`:`builder.core.pieces.${e.kind}`)]})]}),(0,R.jsx)(`pre`,{className:`px-2.5 py-2 text-[11px] text-foreground whitespace-pre-wrap break-words font-mono`,children:e.text||`—`})]},`${e.nodeId}-${t}`))]}),(0,R.jsx)(ie,{children:(0,R.jsx)(C,{variant:`ghost`,onClick:t,children:n(`common:actions.close`)})})]})})}function Dt({data:e,onChange:t,onDelete:n,constants:r,onManageConstants:i}){let{t:o}=a(`loops`),{activeProjectId:s,projects:l}=c(),u=T(l.find(e=>e.id===s)),d=e.kind,f=`block text-[10px] font-medium text-muted-foreground mb-1`,p=`w-full text-xs rounded border border-border bg-transparent px-2 py-1 text-foreground focus:outline-none focus:ring-1 focus:ring-accent-primary/40`,m=(0,L.useRef)(null),h=(0,L.useRef)(null),g=(n,r,i)=>{let a=n.current,o=String(e[r]??``);if(!a){t({[r]:o+i});return}let s=a.selectionStart??o.length,c=a.selectionEnd??o.length;t({[r]:o.slice(0,s)+i+o.slice(c)}),requestAnimationFrame(()=>{a.focus();let e=s+i.length;a.setSelectionRange(e,e)})},_=e=>g(m,`prompt`,e);return(0,R.jsxs)(`div`,{className:`space-y-3`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,R.jsx)(`span`,{className:`text-xs font-semibold text-foreground`,children:o(`builder.nodes.${d}`)}),(0,R.jsx)(`button`,{type:`button`,onClick:n,"aria-label":o(`builder.deleteNode`),className:`text-muted-foreground hover:text-destructive`,children:(0,R.jsx)(y,{className:`w-3.5 h-3.5`})})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`label`,{className:f,children:o(`builder.inspector.label`)}),(0,R.jsx)(`input`,{className:p,value:String(e.label??``),onChange:e=>t({label:e.target.value}),placeholder:o(`builder.nodes.${d}`)})]}),d===`ai-step`&&(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`label`,{className:f,children:o(`builder.inspector.prompt`)}),(0,R.jsx)(X,{t:o,onInsert:_}),(0,R.jsx)(Ct,{t:o,constants:r,onInsert:_,onManage:i}),(0,R.jsx)(`textarea`,{ref:m,rows:7,className:p,value:String(e.prompt??``),onChange:e=>t({prompt:e.target.value})}),(0,R.jsx)(`p`,{className:`text-[10px] text-muted-foreground mt-1`,children:o(`builder.inspector.promptHint`)})]}),d===`shell`&&(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`label`,{className:f,children:o(`builder.inspector.command`)}),(0,R.jsx)(`input`,{className:p,value:String(e.command??``),onChange:e=>t({command:e.target.value}),placeholder:`npm test`}),(0,R.jsxs)(`label`,{className:`${f} mt-3`,children:[o(`common:repositories.shellTarget`),(0,R.jsxs)(`select`,{className:p,value:String(e.repositoryId??``),onChange:e=>t({repositoryId:e.target.value||void 0}),children:[(0,R.jsx)(`option`,{value:``,children:o(`common:repositories.shellDefault`)}),u.filter(e=>e.kind===`git`).map(e=>(0,R.jsx)(`option`,{value:e.id,children:e.name},e.id)),!!e.repositoryId&&!u.some(t=>t.id===e.repositoryId)&&(0,R.jsx)(`option`,{value:String(e.repositoryId),children:String(e.repositoryId)})]})]}),(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:o(`common:repositories.shellHint`)})]}),d===`decider`&&(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`label`,{className:f,children:o(`builder.inspector.goal`)}),(0,R.jsx)(Ct,{t:o,constants:r,onInsert:e=>g(h,`goal`,e),onManage:i}),(0,R.jsx)(`textarea`,{ref:h,rows:4,className:p,value:String(e.goal??``),onChange:e=>t({goal:e.target.value})})]}),d===`condition`&&(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`label`,{className:f,children:o(`builder.inspector.join`)}),(0,R.jsxs)(`select`,{className:p,value:String(e.join??`AND`),onChange:e=>t({join:e.target.value}),children:[(0,R.jsx)(`option`,{value:`AND`,children:`AND`}),(0,R.jsx)(`option`,{value:`OR`,children:`OR`})]})]}),d===`end`&&(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`label`,{className:f,children:o(`builder.inspector.outcome`)}),(0,R.jsxs)(`select`,{className:p,value:String(e.outcome??`success`),onChange:e=>t({outcome:e.target.value}),children:[(0,R.jsx)(`option`,{value:`success`,children:`success`}),(0,R.jsx)(`option`,{value:`failure`,children:`failure`})]})]}),d===`start`&&(0,R.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:o(`builder.inspector.startNote`)})]})}function Ot({loopId:e,onExit:t,onWindowOpened:n}={}){return(0,R.jsx)(Fe,{children:(0,R.jsx)(bt,{loopId:e,onExit:t,onWindowOpened:n})})}export{Ot as default};
@@ -1 +0,0 @@
1
- var e=`Moteur d’agents`,t=`Architecte, développeur et relecteur s’exécutent en phases séparées avec une vérification déterministe entre elles. Choisissez un fournisseur par rôle ; tout le reste a une valeur par défaut qui fonctionne.`,n=`Chargement des paramètres…`,r=`Impossible de charger les paramètres. Réessayez avant de les modifier.`,i=`Réessayer`,a=`Cette installation de Core ne contient pas le moteur d’agents. Mettez Core à jour avant de l’activer ; vous pouvez préparer les paramètres en attendant.`,o=`Enregistrer les paramètres`,s=`Enregistrement…`,c=`Paramètres enregistrés`,l=`Impossible d’enregistrer les paramètres.`,u=`Demander une approbation avant de terminer le workflow`,d={title:`Fournisseurs`,hint:`Les CLI utilisent leur connexion existante. Pour les API, indiquez uniquement un nom de variable d’environnement, jamais une clé. Il peut rester vide en local. Réaffectez les rôles avant de supprimer leur fournisseur.`,entry:`Fournisseur {{index}}`,id:`ID du fournisseur`,kind:`Type de connexion`,cli:`CLI de programmation installé`,compatible:`API compatible OpenAI`,command:`CLI de programmation`,baseUrl:`URL de base de l’API`,apiKeyEnv:`Variable d’environnement de la clé (facultative)`,remove:`Supprimer le fournisseur`,addCli:`Ajouter un fournisseur CLI`,addLocal:`Ajouter un fournisseur local / API`,show:`Afficher les connexions aux fournisseurs`,hide:`Masquer les connexions aux fournisseurs`,globalTitle:`Fournisseurs d'IA`,globalHint:`Deux types de fournisseurs alimentent chaque projet : les CLI de programmation détectées sur cette machine et les moteurs locaux compatibles OpenAI que vous enregistrez ici. Attribuez-les aux phases du pipeline dans Paramètres du projet ▸ Moteur des agents. Les changements s’appliquent aux nouvelles exécutions.`,label:`Nom affiché (facultatif)`,labelPlaceholder:`ex. Machine LAN`,defaultModel:`Modèle par défaut`,defaultModelNone:`Aucun défaut (premier découvert)`,defaultModelPlaceholder:`ID du modèle ou alias personnalisé`,customModel:`Alias personnalisé…`,discoveredModels:`Modèles découverts`,noModels:`Aucun modèle découvert pour l'instant : testez la connexion.`,rates:`Tarifs (USD par 1M de jetons, facultatif)`,ratesHint:`Les coûts sont affichés comme des estimations ; laissez les deux vides et le coût reste inconnu.`,inputRate:`Entrée par 1M`,outputRate:`Sortie par 1M`,ratesInvalid:`Saisissez les deux tarifs comme nombres non négatifs, ou laissez les deux vides.`,reasoningEffort:`Le service accepte l'effort de raisonnement`,reasoningEffortHint:`Envoie le champ reasoning_effort d'OpenAI : l'effort configuré du rôle à chaque appel, porté à élevé pendant que l'architecte compact rédige le plan. Laissez désactivé sauf si le serveur le prend en charge.`,apiKeyEnvMissing:`{{name}} n'est pas définie dans le processus de l'app. Définissez-la dans l'environnement qui lance l'app.`,test:`Tester la connexion`,testing:`Test en cours…`,testFailed:`Impossible de tester la connexion.`,rename:`Renommer`,renameHint:`Le renommage conserve les affectations de rôles vers cette connexion.`,idLocked:`L'id est verrouillé après l'enregistrement. Utilisez Renommer pour le modifier.`,localBadge:`Moteur local`,cliBadge:`CLI`,notDetected:`Non détecté sur cette machine`,unsaved:`Modifications non enregistrées`,empty:`Aucune connexion pour l'instant. Ajoutez un fournisseur local / API pour commencer.`,fixBeforeSave:`Corrigez les champs signalés avant d'enregistrer.`,status:{probing:`Vérification…`,reachable:`Joignable`,unauthorized:`Non autorisé`,unreachable:`Injoignable`,untested:`Jamais testé`},auth:{authenticated:`Connecté`,unauthenticated:`Non connecté`,unknown:`Connexion inconnue`},agentLoop:`Boucle de l'agent`,agentLoopHint:`comment le pipeline implement pilote ce modèle`,agentLoop_compact:`Compacte`,agentLoop_compactHint:`Micro-étapes pilotées par l'application avec sortie structurée. Recommandé pour les modèles de moins de ~30B.`,agentLoop_free:`Libre`,agentLoop_freeHint:`Une boucle agentique par rôle, comme un fournisseur CLI. Nécessite un modèle puissant.`,contextWindow:`Fenêtre de contexte (tokens)`,contextWindowHint:`Alignez sur la taille de contexte du serveur (n_ctx / num_ctx). Sert à compacter les anciens résultats d'outils avant de remplir la fenêtre. Par défaut 32768.`,maxOutput:`Budget de sortie par tour (tokens)`,maxOutputHint:`max_tokens d'un tour d'outils ; un tour coupé est retenté une fois au double. Compte dans la fenêtre de contexte, donc toujours plafonné à l'espace restant — augmentez-le si le modèle raisonne en privé (le thinking le consomme). Par défaut 8192.`,reasoningEffortRailHint:`Désactivé : le sélecteur d'effort de raisonnement n'apparaît pas dans l'en-tête du rail pour ce moteur.`,presetTitle:`Configuration rapide`,presetSmallModel:`Recommandé pour les petits modèles`,presetSmallModelApplied:`Préréglage petits modèles appliqué`,presetSmallModelHint:`Active la boucle Compacte, transmet l'effort de raisonnement et fixe une fenêtre de contexte de 32k : la combinaison validée avec des modèles de 7–14B. Chaque champ reste modifiable.`,cliGroup:`Outils CLI`,cliGroupHint:`Détectés sur cette machine : ils utilisent leur propre connexion, rien à configurer.`,localGroup:`Moteurs locaux`,localGroupHint:`Points de terminaison compatibles OpenAI (llama.cpp, Ollama, vLLM, LM Studio…) accessibles depuis cette application.`,models_one:`{{count}} modèle`,models_other:`{{count}} modèles`,expand:`Afficher les paramètres`,collapse:`Masquer les paramètres`,overflow:`Plus d'actions`,addLocalHero:`Ajouter un moteur local`,emptyLocalPitch:`Aucun moteur local pour l'instant. Pointez l'application vers un point de terminaison compatible OpenAI pour exécuter le pipeline sur votre propre matériel : le coût reste sous votre contrôle et rien ne quitte votre réseau.`,defaultsGroup:`Valeurs par défaut du fournisseur`},f={claude:`Claude`,codex:`Codex`,gemini:`Gemini`,kimi:`Kimi`},p={architect:`Architecte`,developer:`Développeur`,reviewer:`Réviseur`,fixer:`Correcteur`,verify:`Vérification`,archive:`Finalisation`},m={title:`Attribution des rôles`,hint:`Chaque rôle peut utiliser un fournisseur et un modèle différents. Connexions : Paramètres généraux → Fournisseurs d'IA. Limite par défaut : {{turns}} tours par agent.`,provider:`Fournisseur`,model:`Modèle`,modelPlaceholder:`ID du modèle ou modèle par défaut du CLI`,maxTurns:`Nombre maximal de tours (par défaut {{turns}})`,defaultModel:`Par défaut ({{model}})`,thinking:`Raisonnement privé`,thinking_off:`Désactivé`,thinking_on:`Activé`,thinkingHint:`Désactivé par défaut : le raisonnement caché consomme le budget de sortie et des minutes par tour dans une boucle pilotée par l'hôte. Activez-le pour un rôle qui profite de la délibération (envoyé comme chat_template_kwargs.enable_thinking ; ignoré par les endpoints qui ne le connaissent pas).`},h={title:`Limites du workflow`,hint:`Les champs vides utilisent les valeurs de Core : {{attempts}} tentatives de correction et {{minutes}} minutes par étape de rôle. Sur les moteurs locaux, le délai s'applique à chaque unité de travail (un groupe de tâches, un artefact, une revue) — 45 minutes par défaut — plus une surveillance d'inactivité de 20 minutes ; une étape qui dépasse son temps bloque l'exécution et peut reprendre au prochain groupe ouvert. Les plafonds de tokens et USD sont facultatifs ; ceux en USD exigent Claude pour tous les rôles.`,maxAttempts:`Tentatives maximales du développeur (par défaut {{attempts}})`,timeoutMinutes:`Délai en minutes (par défaut {{minutes}} ; moteurs locaux 45 par groupe de tâches)`,maxTokens:`Jetons maximum`,maxCostUsd:`Coût maximum (USD)`,unlimited:`Sans limite`},g={title:`Commandes de vérification`,hint:`Facultatif. Elles s’exécutent quand le développeur a terminé et leurs échecs lui reviennent. Liste vide : l’architecte propose les vérifications propres au projet à chaque exécution ; les dépôts sans vérification automatique sont quand même relus.`,detect:`Détecter les vérifications du projet`,detecting:`Détection…`,detected:`Rempli avec les vérifications que ce projet définit déjà.`,nothingDetected:`Aucune commande de test, de vérification de types ou de build trouvée. Ce n’est pas grave : l’architecte propose des vérifications à chaque exécution quand c’est possible.`,detectFailed:`Impossible d’inspecter les dépôts du projet.`,repository:`Dépôt`,command:`Commande`,reason:`Détecté depuis {{reason}}`,remove:`Retirer`,add:`Ajouter une commande`,invalidLine:`Commande de vérification vide ou guillemet non fermé : {{line}}`,label:`Libellé du contrôle (facultatif)`,moveUp:`Monter`,moveDown:`Descendre`},_={title:`Exécutions enregistrées`,refresh:`Actualiser`,hint:`Continue dans le worktree d’origine avec le périmètre et les paramètres enregistrés ; la progression apparaît dans le journal de ce job. Ne publie pas et ne relance pas la livraison Desktop. Les exécutions actives s’arrêtent depuis les contrôles du job.`,empty:`Aucune exécution enregistrée.`,loadFailed:`Impossible de charger les exécutions.`,actionFailed:`Impossible de mettre à jour cette exécution.`,phase:`Phase suivante : {{phase}}`,approve:`Approuver la fin`,recover:`Récupérer la phase interrompue`,resume:`Reprendre`,cancel:`Annuler la reprise`,status:{running:`Reprise en cours…`,succeeded:`Réussi`,failed:`Échec`,blocked:`Bloqué`,paused:`En pause`,cancelled:`Annulé`,interrupted:`Interrompu`,unavailable:`Indisponible`,expired:`Expiré`},question:`L'architecte demande :`,answerLabel:`Votre réponse`,answerPlaceholder:`Répondez à la question ; l'architecte poursuit avec elle.`,answer:`Répondre et reprendre`,viewLog:`Voir le journal du job`,implementation:`Implémentation`,preserveProgress:`Reprendre à la phase indiquée en conservant le travail et les paramètres enregistrés.`,reviewDelivery:`Implémentation terminée. Vérifiez le résultat dans le journal avant la livraison ; cette reprise ne l’a pas publié.`,prepareDelivery:`Préparer la livraison`,dismiss:`Ignorer`,selectRecovery:`Sélectionnez les tentatives interrompues à reprendre`},v={architect:`Lit le code et rédige la proposition, la conception, les tâches et la spec. Lecture seule.`,developer:`Implémente les tâches avec des tests. Peut modifier des fichiers et exécuter des commandes dans le bac à sable du CLI.`,reviewer:`Vérifie le résultat par rapport à la spec et aux preuves de vérification. Lecture seule.`},y={title:`Seuil de revue`,hint:`Les champs vides utilisent le seuil de Core. Les valeurs ne peuvent que le relever : score global d'au moins {{score}}, sécurité d'au moins {{security}}, autres aspects d'au moins {{aspect}}.`,minScore:`Score global minimal (par défaut {{score}})`,aspects:{type_correctness:`Exactitude des types (par défaut {{score}})`,pattern_adherence:`Respect des patrons (par défaut {{score}})`,test_coverage:`Couverture de tests (par défaut {{score}})`,security:`Sécurité (par défaut {{score}})`,architectural_alignment:`Alignement architectural (par défaut {{score}})`}},b={title:`Confiance de l'architecte`,hint:`Après une passe d'investigation autonome, une conception encore peu sûre se met en pause avec la question de l'architecte ou continue sur des hypothèses explicites.`,onLowConfidence:`En cas de faible confiance`,ask:`Demander (pause avec la question)`,proceed:`Continuer sur des hypothèses explicites`},x={title:`Consommation et durée`,hint:`Inclut les corrections et les appels échoués. La durée des agents inclut les outils. Les tokens en cache font partie des tokens en entrée.`,unknown:`Indisponible`,duration:`Durée d’exécution`,agentTime:`Durée des agents`,cost:`Coût déclaré`,providerCalls:`Appels aux agents`,toolCalls:`Appels aux outils`,input:`Tokens en entrée`,output:`Tokens en sortie`,uncached:`Entrée sans cache`,cacheRead:`Lectures du cache`,cacheWrite:`Écritures du cache`,partial:`Certains essais ne disposent pas de mesures détaillées.`,phases:`Consommation par phase`,phase:`Phase`,attempts:`Essais`},S={title:`Prompts des rôles des agents`,description:`Consultez et modifiez les instructions de chaque rôle. Elles sont partagées par tous les projets et fournisseurs ; les modifications s’appliquent aux nouveaux travaux. Les travaux repris conservent leurs prompts d’origine.`,definition:`Définition de {{role}}`,default:`Valeur par défaut`,custom:`Personnalisé`,restore:`Rétablir la valeur par défaut`,contracts:`Le contexte de la spec, le workflow OpenSpec et le format de réponse requis sont ajoutés automatiquement et ne sont pas modifiables ici.`,invalid:`Chaque définition doit contenir entre 1 et 20 000 caractères, du texte non vide et aucun octet nul.`,saved:`Prompts des rôles enregistrés`,unsaved:`Modifications non enregistrées`,discard:`Annuler les modifications`,save:`Enregistrer les prompts`,fixerHint:`Utilisé uniquement lors des tours de correction : après une vérification échouée ou une revue rejetée. Tourne sur le moteur du développeur sauf si Réglages ▸ Moteur des agents ▸ Correcteur en désigne un. Un fournisseur CLI qui reprend la session du développeur reçoit le court suivi de correction ; la définition s'applique dès qu'une session neuve démarre (moteurs locaux, moteur correcteur, session perdue).`},C={title:`Efficacité de l’implémentation`,scope:`S’applique aux nouvelles exécutions. Les exécutions enregistrées conservent leur configuration et leur moteur.`,effort:`Effort de raisonnement`,providerDefault:`Valeur du fournisseur`,unconfirmed:`Non confirmé`,unknownSupport:`La prise en charge de ce modèle et de ce transport reste à confirmer.`,escalation:`Autoriser un niveau supérieur avec le même fournisseur`,baseRequired:`Sélectionnez d’abord un modèle de base explicite.`,escalationModel:`Modèle supérieur`,triggers:{architect:`Seule l’investigation approfondie existante peut sélectionner ce niveau.`,developer:`Après deux candidats en échec, la prochaine tentative autorisée peut sélectionner ce niveau.`,reviewer:`Uniquement pour réparer une réponse mal formée, jamais pour un refus du code.`,fixer:`Seul un tour de correction peut atteindre ce palier ; les premiers passages n'exécutent jamais le correcteur.`},contextMode:`Contexte du dépôt`,reviewMode:`Revue des corrections`,planning:`Profondeur de planification`,adaptive:`Adaptatif`,full:`Complet`,developerChecks:`Accepter les contrôles supplémentaires proposés par le développeur`,concurrency:`Contrôles simultanés maximum`,concurrencyHint:`Par défaut : 1. Seuls les contrôles indépendants déclarés par l’hôte dans différents dépôts peuvent s’exécuter ensemble. Aucune réutilisation par défaut.`,checkCapabilities:`Vérifier la compatibilité des modèles`,capabilitiesFailed:`Compatibilité non confirmée. Mettez à jour Core ou conservez les valeurs du fournisseur.`},w={title:`Preuves de vérification`,acceptance:`Acceptation technique`,acceptanceStatus:{pending:`En attente`,validated:`Validé`,"with-exceptions":`Avec exceptions`,blocked:`Bloqué`},calls:`Appels aux agents`,executed:`Contrôles exécutés`,reused:`Contrôles réutilisés`,unknown:`Indisponible`,unavailable:`Preuves indisponibles. Le résultat enregistré ne prouve pas la validité actuelle.`,current:`Candidat et plan actuels`,historical:`Résultat historique`,moreChecks:`Plus de contrôles`,output:`Sortie de vérification`,empty:`Aucune sortie`,truncated:`Page limitée ou capture tronquée.`,nextPage:`Page de sortie suivante`,status:{passed:`Réussi`,failed:`Échec`,cancelled:`Annulé`,interrupted:`Interrompu`},disposition:{executed:`Exécuté`,reused:`Réutilisé`,"not-run":`Non exécuté`},origin:`Origine`,origins:{host:`Hôte`,architect:`Architecte`,developer:`Développeur`,"frozen-runtime-config":`Configuration enregistrée`,"project-role":`Rôle du projet`,default:`Par défaut`,"explicit-launch-override":`Fournisseur choisi pour le lancement`,"loop-role":`Rôle de la boucle`},reuseDisabled:`Réutilisation désactivée pour ce contrôle.`,reuseConfirmed:`Réutilisé après confirmation des entrées et outils identiques.`,inputsChanged:`Entrées modifiées pendant la vérification ; résultat invalidé.`,reuseUnproven:`Aucun résultat actuel avec des entrées identiques prouvées ; contrôle relancé.`,original:`Exécution originale`,requested:`Demandé`,reported:`Rapporté`},T={title:`Rôles de boucle`,hint:`Moteurs des rôles côté boucle lorsqu'un rail est lancé avec le moteur « Rôles ». Les rôles du pipeline ci-dessus (architect, developer, reviewer) proviennent déjà de cette configuration du runtime.`,verifier:`Vérificateur`,verifierHint:`Chaque étape IA de la boucle hors core : verify, fix et étapes IA personnalisées.`,decider:`Décideur`,deciderHint:`Le Loop Decider qui lit le verdict et choisit l'étape suivante — un modèle rapide et peu coûteux est le choix naturel.`,inherit:`Hériter du principal`,model:`Modèle`,effort:`Effort de raisonnement`,disabled:`Le runtime des agents est désactivé : les rails lancés avec le moteur « Rôles » sont refusés tant qu'il n'est pas activé.`,saveFailed:`Impossible d'enregistrer les rôles de boucle.`},E={title:`Pipeline d'implémentation`,explainer:`Ces phases s'exécutent dans cet ordre à chaque implémentation. Quand le moteur du rail est « {{roles}} », chaque phase utilise le moteur configuré ci-dessous : fournisseur, modèle et effort différents par phase. Choisir un moteur précis sur le rail exécute toutes les phases avec ce moteur.`,host:`Hôte`,noCommand:`aucune commande`,inherits:`Hérite du principal`,inheritsDeveloper:`Hérite du développeur`,open:`Ouvrir`,collapse:`Réduire`,groups:{core:{title:`Pipeline principal`,hint:`S'exécute dans chaque implémentation : planifier, construire, vérifier, corriger, relire.`},loop:{title:`Étapes de la boucle`,hint:`Étapes IA de la boucle du rail qui entoure l'exécution (vérifier → décider → corriger) et des boucles personnalisées ; elles héritent du moteur principal sauf réglage.`,chip:`boucle du rail`}},phases:{architect:{name:`Architecte`,purpose:`Lit le code et rédige la proposition, la conception et les tâches.`},developer:{name:`Développeur`,purpose:`Implémente les tâches avec des tests.`},verification:{name:`Vérification`,purpose:`L'hôte exécute vos contrôles ; les échecs reviennent au développeur.`},fixer:{name:`Correcteur`,purpose:`Corrige ce que la vérification ou la revue rejettent ; hérite du développeur s'il n'est pas configuré.`},reviewer:{name:`Relecteur`,purpose:`Confronte le résultat à la spec et aux preuves.`},verifier:{name:`Vérificateur`,purpose:`Étapes IA verify, fix et personnalisées de la boucle.`},decider:{name:`Décideur`,purpose:`Lit le verdict et choisit l'étape suivante de la boucle.`}}},D={title:`Moteur du correcteur`,inherit:`Hériter du développeur`,own:`Moteur dédié`,hint:`Ne s'exécute que lors des tours de correction : après une vérification échouée ou une revue rejetée ; les premiers passages restent sur le développeur. Un modèle plus puissant ou cloud ici est rentable quand le développeur est un modèle local bon marché.`},O={title:`Garde-fous`,intro:`Règles de processus que l'hôte applique autour des modèles locaux pour qu'un petit modèle ne déraille pas. Toutes actives par défaut ; n'en désactivez une que pour ajuster le processus. Les fournisseurs CLI ne sont jamais concernés.`,unsupported:`Cette installation de Core n'expose pas de garde-fous configurables. Mettez Core à jour pour les ajuster ; les règles intégrées s'appliquent toujours.`,active:`{{on}} sur {{total}} actifs`,reset:`Rétablir les valeurs par défaut`,phases:{architect:`Architecte`,developer:`Développeur`,host:`Hôte`},unknown:`Un garde-fou ajouté par un Core plus récent ; cette application n'a pas encore de description pour lui.`,items:{"plan-validation":{title:`Plan de tâches validé`,description:`Rejette les plans qui ciblent openspec/, listent de simples noms de fichiers comme tâches, ont trop peu de tâches/groupes pour la spec ou laissent des critères d'acceptation non couverts ; l'architecte réessaie.`,why:`Un plan vague ou incomplet est la raison nº 1 pour laquelle un petit modèle développeur écrit des stubs.`},"genuine-blocking-question":{title:`Uniquement de vraies questions bloquantes`,description:`L'architecte ne peut mettre l'exécution en pause qu'avec une vraie question terminée par « ? », jamais avec un texte d'exemple copié.`,why:`Les petits modèles répètent les espaces réservés du prompt et bloqueraient chaque exécution.`},"plan-language-hint":{title:`Planifier dans le langage du dépôt`,description:`Indique à l'architecte le langage principal pour que les noms de fichiers des tâches portent la bonne extension.`,why:`Un plan JS sur un dépôt TypeScript rend les tâches impossibles à cocher.`},"frozen-plan-writes":{title:`Les artefacts de planification sont figés`,description:`Le développeur ne peut pas écrire sous openspec/ ; le plan appartient à l'hôte.`,why:`Les modèles « implémentent » en modifiant le plan au lieu du code.`},"primary-language":{title:`Rappel du langage principal`,description:`Chaque groupe de tâches reçoit le langage principal du dépôt ; les nouveaux fichiers doivent l'utiliser.`,why:`Évite une seconde implémentation dans un autre langage.`},"duplicate-sibling":{title:`Pas de modules jumeaux entre langages`,description:`Refuse board.js quand board.ts existe déjà ; étendez plutôt le module existant.`,why:`Les jumeaux compilent tous les deux et les tests importent le mauvais.`},"one-test-per-module":{title:`Un fichier de test par module`,description:`Refuse board.tick.test.ts quand board.test.ts existe ; étendez-le plutôt.`,why:`Sinon chaque passe de correction ajoute une nouvelle suite.`},"empty-write":{title:`Pas d'écrasements vides`,description:`Une écriture vide sur un fichier rempli est refusée ; écrivez le contenu complet ou appliquez un patch.`,why:`Une passe de « nettoyage » a un jour laissé index.ts à 0 ligne.`},"evidence-gated-ticking":{title:`Des preuves avant de cocher une tâche`,description:`Une tâche nommant des fichiers n'est terminée que s'ils existent et ne sont pas des stubs (extensions sœurs acceptées).`,why:`Sans cela, « terminé » n'est qu'une affirmation et la vérification s'exécute sur rien.`},"inventory-retry":{title:`Réessayer avec le vrai inventaire`,description:`Quand le modèle abandonne en prétendant que le dépôt est vide alors qu'il ne l'est pas, réessaie une fois avec la liste des fichiers.`,why:`Une seconde chance peu coûteuse plutôt qu'une étape échouée.`},"synthetic-corrections":{title:`Transformer le retour en tâches`,description:`Quand toutes les tâches sont cochées mais que la revue/vérification a échoué, le retour devient des tâches de correction concrètes.`,why:`Sinon le développeur répond « déjà fait » et rien ne change.`},"silent-group-closure":{title:`Fermer les groupes silencieux, garder leurs fichiers`,description:`Un groupe dont le modèle cesse de répondre est fermé en créditant les fichiers écrits et en laissant ses tâches ouvertes, au lieu de faire échouer l'exécution.`,why:`Un modèle 9B a écrit cinq modules, s'est tu, et toute l'exécution a échoué.`},"environment-repair":{title:`L'hôte répare l'environnement`,description:`Les dépendances ou outils de test manquants (npm install, ts-jest, @types/jest, modules de config Jest) sont installés par l'hôte, puis la vérification est relancée une fois.`,why:`Le modèle ne peut pas réparer l'environnement et gaspille des corrections à essayer.`},"lockfile-repair":{title:`Supprimer les lockfiles écrits à la main`,description:`Un package-lock.json inventé par le modèle (EINTEGRITY/ETARGET) est supprimé et l'installation retentée une fois.`,why:`Des hachages inventés ne s'installent jamais.`},"verify-idle-timeout":{title:`Arrêter les tests bloqués`,description:`Une commande de vérification sans sortie pendant 5 minutes est arrêtée et signalée comme blocage probable (dernière sortie incluse).`,why:`Sinon une boucle while dans un test retient l'exécution jusqu'à la limite de 15 minutes.`},"verify-per-group":{title:`Vérifier après chaque groupe`,description:`Lance la commande de test du dépôt juste après chaque groupe de tâches ; un échec reçoit une correction immédiate tant que le contexte du groupe est frais.`,why:`Cinq suites cassées à la fin sont bien plus dures à corriger qu'une à la fois.`},"test-reachability":{title:`Chaque nouveau test doit vraiment s'exécuter`,description:"Un fichier de test écrit par le developer que la commande de test du dépôt n'exécute jamais (un script `test` énumératif qui omet le nouveau fichier) fait échouer la vérification en nommant le fichier exact, d'abord au niveau du groupe puis à la vérification de l'hôte.",why:`Une suite de 622 lignes avec six cas en échec est passée au vert parce que rien ne l'avait jamais lancée.`},"exit-code-honesty":{title:`Se méfier d'un code de sortie 0 qui signale des échecs`,description:"Une commande de vérification qui sort avec 0 alors que sa sortie affiche des échecs (lignes `FAIL:`, « 3 failed », une AssertionError) est traitée comme ÉCHOUÉE et transmise au correcteur, le harnais étant désigné comme le défaut.",why:`Un lanceur de tests maison qui ne fixait jamais de code de sortie non nul a livré trois tests rouges comme verts.`}}},k=`Modifications non enregistrées`,A={title:`Rôles personnalisés`,hint:`Définissez des instructions réutilisables et des permissions explicites pour les rôles du workflow.`,unsupported:`Mettez Core à jour pour modifier les rôles personnalisés.`,remove:`Supprimer {{id}}`,access:`Accès au code`,read:`Lecture seule`,write:`Lecture et écriture`,artifacts:`Accès aux artefacts OpenSpec`,none:`Aucun`,tasks:`Cases des tâches uniquement`,all:`Tous les artefacts du changement`,skill:`Skill OpenSpec`,noSkill:`Aucun skill associé`,prompt:`Instructions du rôle`,id:`ID du rôle`,add:`Ajouter un rôle`,invalidId:`Utilisez un ID unique en minuscules commençant par une lettre, avec au plus 64 lettres, chiffres ou tirets. Les IDs intégrés sont réservés.`,escalationHint:`Seule une réparation autorisée du protocole peut utiliser le modèle supérieur. Aucun nouvel essai n’est ajouté.`},j={title:`Instructions d’exécution`,hint:`Core conserve ces instructions pour le prochain tour d’agent compatible. Leur envoi ne répond pas aux questions et ne donne aucune approbation.`,label:`Instructions supplémentaires`,send:`Envoyer les instructions`,accepted:`Reçues par Core ; en attente de traitement.`,pending:`En attente d’un tour d’agent`,consumed:`Prises en compte par un agent`,counts:`En attente : {{pending}} · Traitées : {{consumed}}`,failed:`Impossible d’envoyer les instructions. Réessayez pour confirmer le même message.`,unavailable:`Les détails des reçus sont indisponibles.`,unreported:`Cette version de Core ne signale pas la prise en compte.`,truncated:`Seuls les reçus récents et les messages en attente sont affichés.`},M={title:`Valeurs par défaut du rôle Core`,hint:`Ces valeurs du fichier s’appliquent aux nouveaux workflows. Les paramètres explicites du projet sont prioritaires ; les exécutions enregistrées conservent leurs paramètres figés.`,invalid:`Corrigez l’en-tête YAML dans l’éditeur avant de modifier les champs du rôle.`,escalationEffort:`Effort de raisonnement du modèle supérieur`},N={title:`Conservation de l’historique`,description:`Supprimez les historiques expirés et les versions de Core inutilisées. Un historique supprimé ne peut plus être repris ni bifurqué. Les exécutions actives ou récupérables et les livraisons en attente restent protégées ; les journaux et les coûts sont conservés.`,forever:`Conserver indéfiniment`,days:`Jours de conservation`,save:`Enregistrer la conservation`,preview:`Aperçu du nettoyage`,collect:`Supprimer les historiques expirés`,previewSummary:`Éligibles : {{runs}} historiques et {{packages}} versions de Core inutilisées.`,collectedSummary:`Expirés : {{runs}} historiques. Supprimées : {{packages}} versions de Core inutilisées.`,more:`{{count}} exécutions supplémentaires.`,failed:`Impossible de consulter ou modifier la conservation.`,expired:`Cet historique a expiré selon la politique du projet. Le journal et la comptabilité restent disponibles.`,loading:`Chargement de la politique…`,states:{protected:`Conservé`,eligible:`Éligible`,expired:`Expiré`,cleanup_pending:`Nettoyage en attente`,busy:`Utilisé`,error:`Échec de vérification`},reasons:{disabled:`Conservation indéfinie`,recoverable:`Récupération encore possible`,active:`Exécution active`,human_pending:`Réponse humaine attendue`,interrupted_writes:`Écritures interrompues à examiner`,delivery_pending:`Livraison en attente`,fork_pending:`Bifurcation dépendante restante`,unknown_terminal_time:`Date de fin inconnue`,within_retention:`Durée de conservation non dépassée`}},P={title:`Loop agents`,hint:`These definitions are shared by every project using this loop. Duplicate the loop to customize a separate workflow.`,legacy:`This saved loop still uses historical project agents. Import them or enable loop agents before changing its configuration.`,enable:`Use loop agents`,import:`Import current project agents`,restoreDefinition:`Utiliser la définition de Core`,default:`Provider default`,effort:`Reasoning effort`,escalationModel:`Escalation model`,escalationEffort:`Escalation effort`,policy:`Workflow policy`,maxAttempts:`Maximum correction attempts`,maxTokens:`Token budget`,maxCostUsd:`Cost budget (USD)`,timeoutMs:`Run timeout (ms)`,projectHint:`Configure repository checks here. Agent definitions, models and workflow policy are configured in the loop editor. Historical project agents can be imported into a duplicated loop.`,showUnused:`Also show agents not used in this loop`,stepTitle:`Step agent and options`,stepHint:`Edit this step’s agent definition and engine. Steps using the same role in this loop share these settings.`,inheritProvider:`Hériter du fournisseur de la mission`,inheritDefinition:`Suit la définition de Core : chaque mise à niveau de Core la met à jour automatiquement.`,customizeDefinition:`Personnaliser pour cette boucle`,coreDefinitionUnavailable:`Aperçu indisponible tant qu’aucun runtime Core n’est installé.`},F={title:e,description:t,loading:n,loadFailed:r,retry:i,unavailable:a,save:o,saving:s,saved:c,saveFailed:l,approvalBeforeArchive:u,providers:d,cliNames:f,roles:p,agents:m,limits:h,verification:g,runs:_,roleHints:v,review:y,architect:b,metrics:x,prompts:S,efficiency:C,evidence:w,loopRoles:T,pipeline:E,fixer:D,guardrails:O,unsavedChanges:k,customRoles:A,steering:j,studioRole:M,retention:N,loopAgents:P};export{m as agents,u as approvalBeforeArchive,b as architect,f as cliNames,A as customRoles,F as default,t as description,C as efficiency,w as evidence,D as fixer,O as guardrails,h as limits,r as loadFailed,n as loading,P as loopAgents,T as loopRoles,x as metrics,E as pipeline,S as prompts,d as providers,N as retention,i as retry,y as review,v as roleHints,p as roles,_ as runs,o as save,l as saveFailed,c as saved,s as saving,j as steering,M as studioRole,e as title,a as unavailable,k as unsavedChanges,g as verification};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-CNC7AqOf.js";var t=e({agents:()=>g,approvalBeforeArchive:()=>f,architect:()=>S,cliNames:()=>m,customRoles:()=>M,default:()=>L,description:()=>r,efficiency:()=>T,evidence:()=>E,fixer:()=>k,guardrails:()=>A,limits:()=>_,loadFailed:()=>a,loading:()=>i,loopAgents:()=>I,loopRoles:()=>D,metrics:()=>C,pipeline:()=>O,prompts:()=>w,providers:()=>p,retention:()=>F,retry:()=>o,review:()=>x,roleHints:()=>b,roles:()=>h,runs:()=>y,save:()=>c,saveFailed:()=>d,saved:()=>u,saving:()=>l,steering:()=>N,studioRole:()=>P,title:()=>n,unavailable:()=>s,unsavedChanges:()=>j,verification:()=>v}),n=`Agent runtime`,r=`Architect, developer and reviewer run as separate phases with deterministic verification in between. Pick a provider per role; everything else has a working default.`,i=`Loading runtime settings…`,a=`Could not load runtime settings. Retry before making changes.`,o=`Retry`,s=`This Core installation does not include the agent runtime. Update Core before enabling it; you can prepare settings while disabled.`,c=`Save runtime settings`,l=`Saving…`,u=`Runtime settings saved`,d=`Could not save runtime settings.`,f=`Pause for approval before completing the workflow`,p={title:`Providers`,hint:`CLI providers use their existing login. API providers accept an environment variable name only, never an API key. Local endpoints can leave it blank. Assign another provider to a role before removing its current provider.`,entry:`Provider {{index}}`,id:`Provider ID`,kind:`Connection type`,cli:`Installed coding CLI`,compatible:`OpenAI-compatible endpoint`,command:`Coding CLI`,baseUrl:`API base URL`,apiKeyEnv:`API key environment variable (optional)`,remove:`Remove provider`,addCli:`Add CLI provider`,addLocal:`Add local / API provider`,show:`Show provider connections`,hide:`Hide provider connections`,globalTitle:`AI providers`,globalHint:`Two kinds of provider power every project: coding CLIs detected on this machine and local OpenAI-compatible engines you register here. Assign them to the pipeline phases in Project settings ▸ Agent engine. Changes apply to new executions.`,label:`Display name (optional)`,labelPlaceholder:`e.g. LAN box`,defaultModel:`Default model`,defaultModelNone:`No default (first discovered)`,defaultModelPlaceholder:`Model id or custom alias`,customModel:`Custom alias…`,discoveredModels:`Discovered models`,noModels:`No models discovered yet — test the connection.`,rates:`Rates (USD per 1M tokens, optional)`,ratesHint:`Costs are shown as estimates; leave both empty and cost stays unknown.`,inputRate:`Input per 1M`,outputRate:`Output per 1M`,ratesInvalid:`Enter both rates as non-negative numbers, or leave both empty.`,reasoningEffort:`Endpoint accepts reasoning effort`,reasoningEffortHint:`Sends the OpenAI reasoning_effort field: the role's configured effort on every call, raised to high while the Compact architect writes the plan. Leave off unless the server honours it.`,apiKeyEnvMissing:`{{name}} is not set in the app process. Set it in the environment the app is launched from.`,test:`Test connection`,testing:`Testing…`,testFailed:`Could not test the connection.`,rename:`Rename`,renameHint:`Renaming keeps role assignments pointing at this connection.`,idLocked:`The id is locked once saved. Use Rename to change it.`,localBadge:`Local engine`,cliBadge:`CLI`,notDetected:`Not detected on this machine`,unsaved:`Unsaved changes`,empty:`No connections yet. Add a local / API provider to get started.`,fixBeforeSave:`Fix the highlighted fields before saving.`,status:{probing:`Probing…`,reachable:`Reachable`,unauthorized:`Not authorized`,unreachable:`Unreachable`,untested:`Never tested`},auth:{authenticated:`Signed in`,unauthenticated:`Not signed in`,unknown:`Sign-in unknown`},agentLoop:`Agent loop`,agentLoopHint:`how the implement pipeline drives this model`,agentLoop_compact:`Compact`,agentLoop_compactHint:`Host-driven micro-steps with structured output. Recommended for models under ~30B.`,agentLoop_free:`Free`,agentLoop_freeHint:`One agentic loop per role, like a CLI provider. Needs a strong model.`,contextWindow:`Context window (tokens)`,contextWindowHint:`Match the server's context size (n_ctx / num_ctx). Used to compact old tool results before the window fills. Default 32768.`,maxOutput:`Output budget per turn (tokens)`,maxOutputHint:`max_tokens of one tool turn; a turn cut off by it is retried once at double. Counts inside the context window, so it is always capped to the room left — raise it when the model thinks privately (thinking counts against it). Default 8192.`,reasoningEffortRailHint:`Off: the reasoning-effort selector is hidden in the rail header for this engine.`,presetTitle:`Quick setup`,presetSmallModel:`Recommended for small models`,presetSmallModelApplied:`Small-model preset applied`,presetSmallModelHint:`Sets Compact loop, forwards reasoning effort and a 32k context window — the combination validated with 7–14B models. You can still change each field.`,cliGroup:`CLI tools`,cliGroupHint:`Detected on this machine — they use their own login, nothing to configure.`,localGroup:`Local engines`,localGroupHint:`OpenAI-compatible endpoints (llama.cpp, Ollama, vLLM, LM Studio…) reachable from this app.`,models_one:`{{count}} model`,models_other:`{{count}} models`,expand:`Show settings`,collapse:`Hide settings`,overflow:`More actions`,addLocalHero:`Add local engine`,emptyLocalPitch:`No local engine yet. Point the app at an OpenAI-compatible endpoint to run the pipeline on your own hardware — cost stays under your control and nothing leaves your network.`,defaultsGroup:`Provider defaults`},m={claude:`Claude`,codex:`Codex`,gemini:`Gemini`,kimi:`Kimi`},h={architect:`Architect`,developer:`Developer`,reviewer:`Reviewer`,fixer:`Fixer`,verify:`Verification`,archive:`Completion`},g={title:`Role assignments`,hint:`Each role can use a different provider and model. Manage connections in General settings → AI providers. Default limit: {{turns}} turns per agent.`,provider:`Provider`,model:`Model`,modelPlaceholder:`Model ID or CLI default`,maxTurns:`Maximum turns (default {{turns}})`,defaultModel:`Default ({{model}})`,thinking:`Private thinking`,thinking_off:`Off`,thinking_on:`On`,thinkingHint:`Off by default: hidden reasoning spends the output budget and minutes per turn in a host-driven loop. Turn it on for a role that benefits from deliberation (sent as chat_template_kwargs.enable_thinking; ignored by endpoints that do not know it).`},_={title:`Workflow limits`,hint:`Empty fields use Core defaults: {{attempts}} correction attempts and {{minutes}} minutes per role step. On local engines the timeout applies to each unit of work (a task group, an artifact, a review) — 45 minutes by default — plus a 20-minute idle watchdog; a step that runs out of time blocks the run and can be resumed from the next open task group. Token and USD caps are optional; USD caps require Claude for every AI role.`,maxAttempts:`Maximum developer attempts (default {{attempts}})`,timeoutMinutes:`Timeout in minutes (default {{minutes}}; local engines 45 per task group)`,maxTokens:`Maximum tokens`,maxCostUsd:`Maximum cost (USD)`,unlimited:`No limit`},v={title:`Verification commands`,hint:`Optional. These run after the developer finishes and their failures go back to the developer. Leave the list empty and the architect proposes the project's own checks on each run; repositories without any automated check are still reviewed.`,detect:`Detect project checks`,detecting:`Detecting…`,detected:`Filled in from the checks this project already defines.`,nothingDetected:`No test, type-check or build command was found. That is fine: the architect proposes checks at run time when possible.`,detectFailed:`Could not inspect the project repositories.`,repository:`Repository`,command:`Command`,reason:`Detected from {{reason}}`,remove:`Remove`,add:`Add command`,invalidLine:`Verification command is empty or has an unterminated quote: {{line}}`,label:`Check label (optional)`,moveUp:`Move up`,moveDown:`Move down`},y={title:`Saved executions`,refresh:`Refresh`,hint:`Continue in the original worktree with the frozen scope and settings; progress appears in that job's log. This does not publish or restart Desktop delivery. Active rail executions are stopped from their job controls.`,empty:`No saved runtime executions.`,loadFailed:`Could not load saved executions.`,actionFailed:`Could not update this execution.`,phase:`Next phase: {{phase}}`,approve:`Approve completion`,recover:`Recover interrupted phase`,resume:`Resume`,cancel:`Cancel continuation`,status:{running:`Continuing…`,succeeded:`Succeeded`,failed:`Failed`,blocked:`Blocked`,paused:`Paused`,cancelled:`Cancelled`,interrupted:`Interrupted`,unavailable:`Unavailable`,expired:`Expired`},question:`The architect asks:`,answerLabel:`Your answer`,answerPlaceholder:`Answer the question; the architect continues with it.`,answer:`Answer and resume`,viewLog:`View job log`,implementation:`Implementation`,preserveProgress:`Continue from the indicated phase, preserving your existing work and saved settings.`,reviewDelivery:`Implementation completed. Review the result in this job log before arranging delivery; this continuation has not published it.`,prepareDelivery:`Prepare delivery`,dismiss:`Dismiss`,selectRecovery:`Select the interrupted attempts to recover`},b={architect:`Reads the code and writes the proposal, design, tasks and spec. Read-only.`,developer:`Implements the tasks with tests. Can edit files and run commands inside the CLI sandbox.`,reviewer:`Checks the result against the spec and the verification evidence. Read-only.`},x={title:`Review gate`,hint:`Empty fields use Core's gate. Values can only raise it: overall score at least {{score}}, security at least {{security}}, other aspects at least {{aspect}}.`,minScore:`Minimum overall score (default {{score}})`,aspects:{type_correctness:`Type correctness (default {{score}})`,pattern_adherence:`Pattern adherence (default {{score}})`,test_coverage:`Test coverage (default {{score}})`,security:`Security (default {{score}})`,architectural_alignment:`Architectural alignment (default {{score}})`}},S={title:`Architect confidence`,hint:`After one autonomous investigation pass, a design that is still low in confidence either pauses with the architect's question or proceeds on stated assumptions.`,onLowConfidence:`On low confidence`,ask:`Ask (pause with the question)`,proceed:`Proceed on stated assumptions`},C={title:`Usage and time`,hint:`Includes corrections and failed calls. Agent time includes tool work. Cached tokens are part of input tokens.`,unknown:`Unavailable`,duration:`Execution time`,agentTime:`Agent time`,cost:`Reported cost`,providerCalls:`Agent calls`,toolCalls:`Tool calls`,input:`Input tokens`,output:`Output tokens`,uncached:`Uncached input`,cacheRead:`Cache reads`,cacheWrite:`Cache writes`,partial:`Some attempts have no detailed measurements.`,phases:`Usage by phase`,phase:`Phase`,attempts:`Attempts`},w={title:`Agent role prompts`,description:`View and edit the instructions for each role. Shared by all projects and providers; changes apply to new jobs. Resumed jobs keep their original prompts.`,definition:`{{role}} definition`,default:`Factory default`,custom:`Customized`,restore:`Restore default`,contracts:`Spec context, OpenSpec workflow and required response format are added automatically and are not edited here.`,invalid:`Each definition must contain 1–20,000 characters, with nonblank text and no null bytes.`,saved:`Role prompts saved`,unsaved:`Unsaved changes`,discard:`Discard changes`,save:`Save prompts`,fixerHint:`Used on correction rounds only — after a failed verification or a rejected review. Runs on the developer's engine unless Settings ▸ Agent engine ▸ Fixer names its own. A CLI provider that resumes the developer's session receives the short correction follow-up instead; the definition applies whenever a fresh session starts (local engines, the fixer engine, a lost session).`},T={title:`Implementation efficiency`,scope:`Applies to new runs. Saved runs retain their original configuration and runtime.`,effort:`Reasoning effort`,providerDefault:`Provider default`,unconfirmed:`Unconfirmed`,unknownSupport:`Support is not confirmed for this model and transport. Provider default remains available.`,escalation:`Allow one higher tier with the same provider`,baseRequired:`Select an explicit base model first.`,escalationModel:`Higher-tier model`,triggers:{architect:`Only the existing deeper investigation pass can select this tier.`,developer:`After two failed candidates, the next permitted attempt can select this tier.`,reviewer:`Only a malformed-response repair can select this tier; rejecting code does not trigger it.`,fixer:`Only a correction round can reach this tier; first passes never run the fixer.`},contextMode:`Repository context`,reviewMode:`Correction review`,planning:`Planning depth`,adaptive:`Adaptive`,full:`Full`,developerChecks:`Accept additional checks proposed by the developer`,concurrency:`Maximum concurrent checks`,concurrencyHint:`Default 1. Only host-declared independent checks across different repositories may run together. Checks are never reused by default.`,checkCapabilities:`Check model compatibility`,capabilitiesFailed:`Could not confirm model capabilities. Update the paired Core runtime or keep provider defaults.`},E={title:`Verification evidence`,acceptance:`Technical acceptance`,acceptanceStatus:{pending:`Pending`,validated:`Validated`,"with-exceptions":`With exceptions`,blocked:`Blocked`},calls:`Agent calls`,executed:`Executed checks`,reused:`Reused checks`,unknown:`Unavailable`,unavailable:`Evidence is unavailable for this execution. Its recorded outcome is not proof of current validity.`,current:`Current candidate and plan`,historical:`Historical result`,moreChecks:`More checks`,output:`Verification output`,empty:`No output`,truncated:`This is a bounded page or a truncated capture.`,nextPage:`Next output page`,status:{passed:`Passed`,failed:`Failed`,cancelled:`Cancelled`,interrupted:`Interrupted`},disposition:{executed:`Executed`,reused:`Reused`,"not-run":`Not run`},origin:`Origin`,origins:{host:`Host`,architect:`Architect`,developer:`Developer`,"frozen-runtime-config":`Frozen configuration`,"project-role":`Project role`,default:`Default`,"explicit-launch-override":`Selected launch provider`,"loop-role":`Loop role`},reuseDisabled:`Reuse disabled for this check.`,reuseConfirmed:`Reused after verifying matching inputs and toolchain.`,inputsChanged:`Inputs changed during verification; result invalidated.`,reuseUnproven:`No current result with proven matching inputs; the check ran again.`,original:`Original execution`,requested:`Requested`,reported:`Reported`},D={title:`Loop roles`,hint:`Engines for the loop-side roles when a rail launches with the "Roles" engine. The pipeline roles above (architect, developer, reviewer) already come from this runtime configuration.`,verifier:`Verifier`,verifierHint:`Every non-core AI step of the loop: verify, fix and custom AI steps.`,decider:`Decider`,deciderHint:`The Loop Decider that reads the verdict and routes the next step — a cheap, fast model is the natural pick.`,inherit:`Inherit primary`,model:`Model`,effort:`Reasoning effort`,disabled:`The agent runtime is disabled — rails launched with the "Roles" engine are refused until it is enabled.`,saveFailed:`Could not save the loop roles.`},O={title:`Implement pipeline`,explainer:`These phases run in this order on every implementation. When the rail's engine is "{{roles}}", each phase runs on the engine configured below — a different provider, model and effort per phase. Picking a concrete engine on the rail runs every phase on that engine instead.`,host:`Host`,noCommand:`no command`,inherits:`Inherits primary`,inheritsDeveloper:`Inherits developer`,open:`Open`,collapse:`Collapse`,groups:{core:{title:`Core pipeline`,hint:`Runs inside every implement: plan, build, verify, fix, review.`},loop:{title:`Loop steps`,hint:`AI steps of the rail's loop around the run (verify → decide → fix) and of custom loops; they inherit the primary engine unless set.`,chip:`rail loop`}},phases:{architect:{name:`Architect`,purpose:`Reads the code and writes the proposal, design and tasks.`},developer:{name:`Developer`,purpose:`Implements the tasks with tests.`},verification:{name:`Verification`,purpose:`The host runs your checks; failures go back to the developer.`},fixer:{name:`Fixer`,purpose:`Corrects what verification or review reject; inherits the developer when not configured.`},reviewer:{name:`Reviewer`,purpose:`Checks the result against the spec and the evidence.`},verifier:{name:`Verifier`,purpose:`Verify, fix and custom AI steps of the loop.`},decider:{name:`Decider`,purpose:`Reads the verdict and routes the next loop step.`}}},k={title:`Fixer engine`,inherit:`Inherit developer`,own:`Own engine`,hint:`Runs only on correction rounds — after a failed verification or a rejected review; first passes stay on the developer. A stronger or cloud model here pays off when the developer is a cheap local model.`},A={title:`Guardrails`,intro:`Process rules the host applies around local models so a small model does not derail. All on by default; switch one off only to tune the process. CLI providers are never affected.`,unsupported:`This Core installation does not expose configurable guardrails. Update Core to tune them; the built-in rules still apply.`,active:`{{on}} of {{total}} active`,reset:`Reset to defaults`,phases:{architect:`Architect`,developer:`Developer`,host:`Host`},unknown:`A guardrail added by a newer Core; this app has no description for it yet.`,items:{"plan-validation":{title:`Validated task plan`,description:`Rejects plans that target openspec/, list bare file names as tasks, have too few tasks/groups for the spec, or leave acceptance criteria uncovered; the architect retries.`,why:`A vague or incomplete plan is the #1 reason a small developer model writes stubs.`},"genuine-blocking-question":{title:`Only real blocking questions`,description:`The architect can pause the run only with an actual question ending in '?', never with copied example text.`,why:`Small models echo prompt placeholders and would block every run.`},"plan-language-hint":{title:`Plan in the repository's language`,description:`Tells the architect the primary language so task file names carry the right extension.`,why:`A JS plan on a TypeScript repo makes tasks impossible to tick.`},"frozen-plan-writes":{title:`Planning artifacts are frozen`,description:`The developer cannot write under openspec/; the plan is the host's.`,why:`Models 'implement' by editing the plan instead of the code.`},"primary-language":{title:`Primary language reminder`,description:`Each task group is told the repository's primary language; new files should use it.`,why:`Prevents a second implementation in another language.`},"duplicate-sibling":{title:`No twin modules across languages`,description:`Refuses board.js when board.ts already exists; extend the existing module instead.`,why:`Twins compile both and the tests import the wrong one.`},"one-test-per-module":{title:`One test file per module`,description:`Refuses board.tick.test.ts when board.test.ts exists; extend it instead.`,why:`Correction passes otherwise add a new suite per attempt.`},"empty-write":{title:`No empty overwrites`,description:`An empty write over a populated file is refused; write the full content or patch it.`,why:`A 'cleanup' pass once left index.ts at 0 lines.`},"evidence-gated-ticking":{title:`Evidence before ticking a task`,description:`A task naming files is done only when they exist and are not stubs (sibling extensions accepted).`,why:`Without it 'done' is just a claim and verify runs against nothing.`},"inventory-retry":{title:`Retry with the real inventory`,description:`When the model gives up claiming the repo is empty while it is not, retry once with the file list.`,why:`Cheap second chance instead of a failed step.`},"synthetic-corrections":{title:`Turn feedback into tasks`,description:`When every task is ticked but review/verify failed, the feedback becomes concrete correction tasks.`,why:`Otherwise the developer reports 'already done' and nothing changes.`},"silent-group-closure":{title:`Close silent groups, keep their files`,description:`A group whose model stops answering is closed with the files it wrote credited and its tasks left open, instead of failing the run.`,why:`A 9B model wrote five modules, went silent, and the whole run failed.`},"environment-repair":{title:`Host repairs the environment`,description:`Missing dependencies or test tooling (npm install, ts-jest, @types/jest, Jest config modules) are installed by the host, then verify re-runs once.`,why:`The model cannot fix the environment and burns corrections trying.`},"lockfile-repair":{title:`Drop hand-written lockfiles`,description:`A package-lock.json the model invented (EINTEGRITY/ETARGET) is removed and the install retried once.`,why:`Invented hashes never install.`},"verify-idle-timeout":{title:`Stop hanging tests`,description:`A verification command with no output for 5 minutes is stopped and reported as a probable hang (last output included).`,why:`A while-loop in a test otherwise holds the run until the 15-minute wall clock.`},"verify-per-group":{title:`Verify after each group`,description:`Runs the repository's own test command right after each task group; a failure gets one in-place fix round while the group's context is still fresh.`,why:`Five broken suites at the end are much harder to fix than one at a time.`},"test-reachability":{title:`Every new test must actually run`,description:"A test file the developer writes that the repository's test command never executes (an enumerating `test` script that skips the new file) fails verification with the exact file, at group altitude first and again at the host verify.",why:`A 622-line test suite with six failing cases once shipped green because nothing ever ran it.`},"exit-code-honesty":{title:`Distrust a green exit code that reports failures`,description:'A verification command that exits 0 while its output prints failures (`FAIL:` lines, "3 failed", an AssertionError) is treated as FAILED and handed to the fixer with the harness named as the defect.',why:`A hand-rolled test runner that never sets a non-zero exit code once shipped three red tests as green.`}}},j=`Unsaved changes`,M={title:`Custom roles`,hint:`Declare reusable instructions and explicit permissions for workflow roles.`,unsupported:`Update Core to edit custom roles.`,remove:`Remove {{id}}`,access:`Source access`,read:`Read only`,write:`Read and write`,artifacts:`OpenSpec artifact access`,none:`None`,tasks:`Task checkboxes only`,all:`All change artifacts`,skill:`OpenSpec skill`,noSkill:`No skill binding`,prompt:`Role instructions`,id:`Role ID`,add:`Add role`,invalidId:`Use a unique lowercase ID beginning with a letter, up to 64 letters, digits or hyphens. Built-in IDs are reserved.`,escalationHint:`Only a permitted protocol repair may use the escalation model. No extra retry is added.`},N={title:`Run instructions`,hint:`Core saves these instructions for the next eligible agent turn. Sending does not answer a question or grant approval.`,label:`Additional instructions`,send:`Send instructions`,accepted:`Accepted by Core; awaiting consumption.`,pending:`Awaiting an agent turn`,consumed:`Consumed by an agent`,counts:`Pending: {{pending}} · Consumed: {{consumed}}`,failed:`Could not send instructions. Retry to confirm the same message.`,unavailable:`Receipt details are unavailable.`,unreported:`This Core version does not report consumption.`,truncated:`Only the most recent receipts and pending messages are shown.`},P={title:`Core role defaults`,hint:`These file defaults apply to new workflows. Explicit project settings take precedence; saved runs keep their frozen settings.`,invalid:`Fix the YAML frontmatter in the editor before changing role fields.`,escalationEffort:`Higher-tier reasoning effort`},F={title:`History retention`,description:`Delete expired execution histories and unused Core versions. Deleted histories cannot be resumed or forked. Active or recoverable runs and pending deliveries stay protected; job logs and cost records remain.`,forever:`Keep history indefinitely`,days:`Retention days`,save:`Save retention`,preview:`Preview cleanup`,collect:`Delete expired history`,previewSummary:`Eligible: {{runs}} histories and {{packages}} unused Core versions.`,collectedSummary:`Expired: {{runs}} histories. Removed: {{packages}} unused Core versions.`,more:`{{count}} additional executions.`,failed:`Could not inspect or update retention.`,expired:`This execution history expired under the project policy. Its job log and accounting remain available.`,loading:`Loading retention policy…`,states:{protected:`Kept`,eligible:`Eligible`,expired:`Expired`,cleanup_pending:`Cleanup pending`,busy:`In use`,error:`Inspection failed`},reasons:{disabled:`Indefinite retention`,recoverable:`Recovery remains available`,active:`Active execution`,human_pending:`Waiting for a human`,interrupted_writes:`Interrupted writes need review`,delivery_pending:`Delivery is pending`,fork_pending:`A dependent fork remains`,unknown_terminal_time:`Completion time is unknown`,within_retention:`Still within the retention period`}},I={title:`Loop agents`,hint:`These definitions are shared by every project using this loop. Duplicate the loop to customize a separate workflow.`,legacy:`This saved loop still uses historical project agents. Import them or enable loop agents before changing its configuration.`,enable:`Use loop agents`,import:`Import current project agents`,restoreDefinition:`Use the Core definition`,default:`Provider default`,effort:`Reasoning effort`,escalationModel:`Escalation model`,escalationEffort:`Escalation effort`,policy:`Workflow policy`,maxAttempts:`Maximum correction attempts`,maxTokens:`Token budget`,maxCostUsd:`Cost budget (USD)`,timeoutMs:`Run timeout (ms)`,projectHint:`Configure repository checks here. Agent definitions, models and workflow policy are configured in the loop editor. Historical project agents can be imported into a duplicated loop.`,showUnused:`Also show agents not used in this loop`,stepTitle:`Step agent and options`,stepHint:`Edit this step’s agent definition and engine. Steps using the same role in this loop share these settings.`,inheritProvider:`Inherit mission provider`,inheritDefinition:`Follows the Core definition: every Core upgrade updates it automatically.`,customizeDefinition:`Customize for this loop`,coreDefinitionUnavailable:`Preview unavailable until a Core runtime is installed.`},L={title:n,description:r,loading:i,loadFailed:a,retry:o,unavailable:s,save:c,saving:l,saved:u,saveFailed:d,approvalBeforeArchive:f,providers:p,cliNames:m,roles:h,agents:g,limits:_,verification:v,runs:y,roleHints:b,review:x,architect:S,metrics:C,prompts:w,efficiency:T,evidence:E,loopRoles:D,pipeline:O,fixer:k,guardrails:A,unsavedChanges:j,customRoles:M,steering:N,studioRole:P,retention:F,loopAgents:I};export{t};