coder-config 0.44.36 → 0.44.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/constants.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coder-config",
|
|
3
|
-
"version": "0.44.
|
|
3
|
+
"version": "0.44.37",
|
|
4
4
|
"description": "Configuration manager for AI coding tools - Claude Code, Gemini CLI, Codex CLI, Antigravity. Manage MCPs, rules, permissions, memory, and workstreams.",
|
|
5
5
|
"author": "regression.io",
|
|
6
6
|
"main": "config-loader.js",
|
|
@@ -3003,7 +3003,7 @@ ${jr.plan}
|
|
|
3003
3003
|
|
|
3004
3004
|
`),jr.iterationHistory&&(vs+=`=== Recent Iterations ===
|
|
3005
3005
|
${jr.iterationHistory}
|
|
3006
|
-
`),jr.transcript=vs;const ys=await pe.tuneLoopPrompt(Vr,Be.projectPath||(e==null?void 0:e.path)||(e==null?void 0:e.dir)||null,jr);ys.success?(await pe.updateLoop(Be.id,{task:{original:ys.tunedPrompt}}),q.success("Prompt tuned and loop updated"),$e(!1),await tl(Be.id),Sr()):q.error(ys.error||"Failed to tune prompt")}catch(Vr){q.error(Vr.message)}finally{se(!1),ue(null)}},vr=async()=>{Be&&($e(!1),await $c(Be.id),ue(null))},nr=async te=>{try{V(!0);const Le=await pe.createLoop(te,{workstreamId:H||null,projectPath:(e==null?void 0:e.path)||(e==null?void 0:e.dir)||null,maxIterations:parseInt(J,10)||50,completionPromise:F||"DONE"});Le.success?(q.success("Loop created"),y(!1),Y(""),G(""),K(ze),R(dr),ae(!1),Sr()):q.error(Le.error||"Failed to create loop")}catch(Le){q.error(Le.message)}finally{V(!1)}},yr=async te=>{if(Qr.needsInstall){zt(te),Hr("start"),rt(!0);return}await Zr(te)},Zr=async te=>{try{const Le=await pe.startLoop(te);Le.success&&Le.loop?(q.success("Loop started - launching Claude Code"),Wr(Le.loop),Wt(!0),Sr()):q.error(Le.error||"Failed to start loop")}catch(Le){q.error(Le.message)}},Rs=async()=>{try{sr(!0);const te=await pe.installRalphLoopPlugin();te.success?(q.success("ralph-loop plugin installed"),ps({installed:!0,scope:"user",needsInstall:!1}),rt(!1),$t&&(gr==="resume"?await tl($t):await Zr($t),zt(null),Hr(null))):q.error(te.error||"Failed to install plugin")}catch(te){q.error(te.message)}finally{sr(!1)}},kr=()=>{rt(!1),zt(null),Hr(null)},$o=_.useCallback(async(te,Le)=>{var Vt,Xt,Vr,kt,br,jr,vs,ys,Ds,Jn,so,zc,Hc,Go;if(yt)try{const ft=(await pe.getLoop(yt.id)).loop;if(ft.taskComplete||ft.status==="completed")q.success("Loop completed successfully!"),Nn({id:ft.id,name:ft.name,task:(Vt=ft.task)==null?void 0:Vt.original,status:"completed",iterations:((Xt=ft.iterations)==null?void 0:Xt.current)||0,maxIterations:((Vr=ft.iterations)==null?void 0:Vr.max)||50,phase:ft.phase,startedAt:ft.startedAt,completedAt:ft.completedAt||new Date().toISOString()}),gs(!0),Wt(!1),Wr(null);else if(ft.status==="paused")q.info(`Loop paused: ${ft.pauseReason||"user requested"}`),Nn({id:ft.id,name:ft.name,task:(kt=ft.task)==null?void 0:kt.original,status:"paused",pauseReason:ft.pauseReason,iterations:((br=ft.iterations)==null?void 0:br.current)||0,maxIterations:((jr=ft.iterations)==null?void 0:jr.max)||50,phase:ft.phase,startedAt:ft.startedAt,completedAt:new Date().toISOString()}),gs(!0);else if(te===0&&!Le)await pe.completeLoop(ft.id),q.success("Loop completed successfully!"),Nn({id:ft.id,name:ft.name,task:(vs=ft.task)==null?void 0:vs.original,status:"completed",iterations:((ys=ft.iterations)==null?void 0:ys.current)||0,maxIterations:((Ds=ft.iterations)==null?void 0:Ds.max)||50,phase:"execute",startedAt:ft.startedAt,completedAt:new Date().toISOString()}),gs(!0),Wt(!1),Wr(null);else if(((Jn=ft.iterations)==null?void 0:Jn.current)>=((so=ft.iterations)==null?void 0:so.max))q.warning("Loop reached max iterations"),await pe.pauseLoop(ft.id);else{const Wc=Le?`Signal: ${Le}`:`Exit code: ${te}`;Nn({id:ft.id,name:ft.name,task:(zc=ft.task)==null?void 0:zc.original,status:"paused",pauseReason:Wc,iterations:((Hc=ft.iterations)==null?void 0:Hc.current)||0,maxIterations:((Go=ft.iterations)==null?void 0:Go.max)||50,phase:ft.phase,startedAt:ft.startedAt,completedAt:new Date().toISOString()}),gs(!0)}Sr()}catch(no){console.error("Failed to check loop status:",no)}},[yt]),Ms=async te=>{try{const Le=await pe.pauseLoop(te);Le.success?(q.success("Loop paused"),Sr()):q.error(Le.error||"Failed to pause loop")}catch(Le){q.error(Le.message)}},$c=async te=>{if(Qr.needsInstall){zt(te),Hr("resume"),rt(!0);return}await tl(te)},tl=async te=>{try{const Le=await pe.resumeLoop(te);Le.success&&Le.loop?(q.success("Loop resumed - launching Claude Code"),Wr(Le.loop),Wt(!0),Sr()):q.error(Le.error||"Failed to resume loop")}catch(Le){q.error(Le.message)}},kh=async te=>{if(confirm("Cancel this loop?"))try{const Le=await pe.cancelLoop(te);Le.success?(q.success("Loop cancelled"),Sr()):q.error(Le.error||"Failed to cancel loop")}catch(Le){q.error(Le.message)}},zo=async te=>{if(confirm("Delete this loop and all its data?"))try{const Le=await pe.deleteLoop(te);Le.success?(q.success("Loop deleted"),Sr()):q.error(Le.error||"Failed to delete loop")}catch(Le){q.error(Le.message)}},Ho=te=>{var Le,Vt;B(te),dt(te.name||""),be(((Le=te.task)==null?void 0:Le.original)||""),Se(((Vt=te.iterations)==null?void 0:Vt.max)||50),oe(te.completionPromise||"DONE"),Pe(te.workstreamId||""),I(!0)},eo=async()=>{if(L)try{V(!0);const te={name:Xe,task:{original:we},iterations:{max:parseInt(Oe,10)},completionPromise:Ee,workstreamId:xe||null},Le=await pe.updateLoop(L.id,te);Le.success?(q.success("Loop updated"),I(!1),B(null),Sr()):q.error(Le.error||"Failed to update loop")}catch(te){q.error(te.message)}finally{V(!1)}},Wo=async te=>{var Le,Vt;try{V(!0);const Xt=await pe.createLoop(((Le=te.task)==null?void 0:Le.original)||"",{name:`${te.name} (copy)`,workstreamId:te.workstreamId||null,projectPath:te.projectPath||(e==null?void 0:e.path)||(e==null?void 0:e.dir)||null,maxIterations:((Vt=te.iterations)==null?void 0:Vt.max)||50,completionPromise:te.completionPromise||"DONE"});Xt.success?(q.success("Loop copied"),Sr()):q.error(Xt.error||"Failed to copy loop")}catch(Xt){q.error(Xt.message)}finally{V(!1)}},jh=async te=>{try{const Le=await pe.approveLoop(te);Le.success?(q.success("Plan approved"),Sr()):q.error(Le.error||"Failed to approve plan")}catch(Le){q.error(Le.message)}},Nh=async()=>{try{V(!0);const te=await pe.updateLoopConfig({maxIterations:parseInt(ze,10),autoApprovePlan:St,completionPromise:dr});te.success?(q.success("Configuration saved"),g(!1),yi()):q.error(te.error||"Failed to save configuration")}catch(te){q.error(te.message)}finally{V(!1)}},rl=async()=>{try{kn(!0);const te=await pe.installLoopHooks();te.success?(q.success("Hooks installed successfully"),bi()):q.error(te.error||"Failed to install hooks")}catch(te){q.error(te.message)}finally{kn(!1)}},sl=async te=>{try{const Le=await pe.getLoop(te.id);N({...Le.loop,clarifications:Le.clarifications,plan:Le.plan}),P(!0)}catch{q.error("Failed to load loop details")}},nl=te=>{navigator.clipboard.writeText(te),q.success("Copied to clipboard")},En=te=>te?new Date(te).toLocaleString():"-",Eh=te=>te.iterations?Math.min(100,te.iterations.current/te.iterations.max*100):0,il=((Vo=zr.stopHook)==null?void 0:Vo.registered)&&((al=zr.prepromptHook)==null?void 0:al.registered),At=te=>{if(!te)return null;const Le=f.find(Vt=>Vt.id===te);return(Le==null?void 0:Le.name)||te},ol=w?t.filter(te=>te.workstreamId===w):t,to=(te,Le=!1)=>{var jr,vs;const Vt=((jr=te.task)==null?void 0:jr.original)||"",Xt=((vs=te.iterations)==null?void 0:vs.max)||50,Vr=te.completionPromise||"DONE";if(Le){const ys=Vt.replace(/\n+/g," ").substring(0,100),Ds=Vt.length>100?"...":"";return`claude --dangerously-skip-permissions "/ralph-loop ${ys.replace(/"/g,'\\"')}${Ds} --max-iterations ${Xt} --completion-promise ${Vr}"`}const kt="claude --dangerously-skip-permissions",br=`/ralph-loop ${Vt} --max-iterations ${Xt} --completion-promise ${Vr}`;return{startCmd:kt,skillCmd:br}};return r.jsxs("div",{className:"p-6 space-y-6 max-w-6xl mx-auto",children:[r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsxs("div",{children:[r.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[r.jsx(lc,{className:"w-6 h-6"}),"Ralph Loops"]}),r.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Autonomous development loops using the official ralph-loop plugin"})]}),r.jsxs("div",{className:"flex items-center gap-2",children:[f.length>0&&r.jsxs("div",{className:"flex items-center gap-1",children:[r.jsx(Rg,{className:"w-4 h-4 text-muted-foreground"}),r.jsxs("select",{className:"text-sm border rounded px-2 py-1 bg-background",value:w,onChange:te=>j(te.target.value),children:[r.jsx("option",{value:"",children:"All workstreams"}),f.map(te=>r.jsx("option",{value:te.id,children:te.name},te.id))]})]}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsxs(re,{variant:"outline",size:"sm",onClick:()=>{Zi(),k(!0)},children:[r.jsx(Cu,{className:"w-4 h-4 mr-1"}),"History"]})}),r.jsx(Mt,{children:"View completed loops"})]})}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsxs(re,{variant:"outline",size:"sm",onClick:()=>g(!0),children:[r.jsx(on,{className:"w-4 h-4 mr-1"}),"Config"]})}),r.jsx(Mt,{children:"Configure loop defaults"})]})}),r.jsxs(re,{onClick:()=>y(!0),children:[r.jsx(Rt,{className:"w-4 h-4 mr-1"}),"New Loop"]})]})]}),!il&&r.jsxs("div",{className:"bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4 flex items-center justify-between",children:[r.jsxs("div",{className:"flex items-center gap-3",children:[r.jsx(Ws,{className:"w-5 h-5 text-yellow-600"}),r.jsxs("div",{children:[r.jsx("p",{className:"font-medium text-yellow-800 dark:text-yellow-200",children:"Hooks not installed"}),r.jsx("p",{className:"text-sm text-yellow-700 dark:text-yellow-300",children:"Install the Ralph Loop hooks to enable automatic loop continuation"})]})]}),r.jsxs(re,{variant:"outline",size:"sm",onClick:rl,disabled:Cr,children:[Cr?r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}):null,"Install Hooks"]})]}),n?r.jsx("div",{className:"flex items-center justify-center py-12",children:r.jsx(Qe,{className:"w-6 h-6 animate-spin text-muted-foreground"})}):ol.length===0?r.jsxs("div",{className:"text-center py-12 text-muted-foreground",children:[r.jsx(lc,{className:"w-12 h-12 mx-auto mb-4 opacity-50"}),r.jsx("p",{className:"text-lg font-medium",children:w?"No loops in this workstream":"No loops yet"}),r.jsx("p",{className:"text-sm mt-1",children:"Create a loop to start autonomous development"})]}):r.jsx("div",{className:"space-y-3",children:ol.map(te=>{var Le,Vt,Xt,Vr,kt;return r.jsxs("div",{className:"border rounded-lg bg-card overflow-hidden",children:[r.jsxs("div",{className:"p-4 cursor-pointer hover:bg-muted/50 transition-colors",onClick:()=>u(d===te.id?null:te.id),children:[r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsxs("div",{className:"flex items-center gap-3",children:[d===te.id?r.jsx(Ar,{className:"w-4 h-4 text-muted-foreground"}):r.jsx(fs,{className:"w-4 h-4 text-muted-foreground"}),ba[te.status]||ba.pending,r.jsxs("div",{children:[r.jsx("h3",{className:"font-medium",children:te.name}),r.jsx("p",{className:"text-sm text-muted-foreground truncate max-w-md",children:((Le=te.task)==null?void 0:Le.original)||"No task"})]})]}),r.jsxs("div",{className:"flex items-center gap-3",children:[te.workstreamId&&r.jsxs("span",{className:"text-xs px-2 py-0.5 rounded-full bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200 flex items-center gap-1",children:[r.jsx(In,{className:"w-3 h-3"}),At(te.workstreamId)]}),r.jsx("span",{className:`text-xs px-2 py-0.5 rounded-full ${d_[te.phase]||"bg-gray-100 dark:bg-gray-800"}`,children:te.phase}),r.jsxs("span",{className:"text-sm text-muted-foreground",children:[((Vt=te.iterations)==null?void 0:Vt.current)||0,"/",((Xt=te.iterations)==null?void 0:Xt.max)||50]}),r.jsxs("div",{className:"flex items-center gap-1",onClick:br=>br.stopPropagation(),children:[te.status==="pending"&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>yr(te.id),children:r.jsx(tS,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Start loop"})]})}),te.status==="running"&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>Ms(te.id),children:r.jsx(xp,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Pause loop"})]})}),te.status==="paused"&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>Nt(te),children:r.jsx(Gd,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Resume loop"})]})}),(te.status==="cancelled"||te.status==="failed")&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>Nt(te),children:r.jsx(Gd,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Restart loop"})]})}),te.phase==="plan"&&te.status==="running"&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>jh(te.id),children:r.jsx(Ft,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Approve plan"})]})}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>Ho(te),children:r.jsx(Ku,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Edit loop"})]})}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>Wo(te),children:r.jsx(Oa,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Duplicate loop"})]})}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>sl(te),children:r.jsx(Ag,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"View details"})]})}),(te.status==="running"||te.status==="paused")&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>kh(te.id),children:r.jsx(Ea,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Cancel loop"})]})}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>zo(te.id),children:r.jsx(Ps,{className:"w-4 h-4 text-red-500"})})}),r.jsx(Mt,{children:"Delete loop"})]})})]})]})]}),r.jsxs("div",{className:"mt-3",children:[r.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground mb-1",children:[r.jsx("span",{children:"Iterations"}),r.jsxs("span",{children:[((Vr=te.iterations)==null?void 0:Vr.current)||0," / ",((kt=te.iterations)==null?void 0:kt.max)||50]})]}),r.jsx("div",{className:"h-1.5 bg-muted rounded-full overflow-hidden",children:r.jsx("div",{className:"h-full bg-blue-500 transition-all",style:{width:`${Eh(te)}%`}})})]})]}),d===te.id&&r.jsxs("div",{className:"border-t p-4 bg-muted/30 space-y-4",children:[r.jsxs("div",{className:"grid grid-cols-2 gap-4 text-sm",children:[r.jsxs("div",{children:[r.jsx("span",{className:"text-muted-foreground",children:"ID:"}),r.jsx("span",{className:"ml-2 font-mono",children:te.id}),r.jsx(re,{variant:"ghost",size:"sm",className:"h-6 w-6 p-0 ml-1",onClick:()=>nl(te.id),children:r.jsx(Oa,{className:"w-3 h-3"})})]}),r.jsxs("div",{children:[r.jsx("span",{className:"text-muted-foreground",children:"Status:"}),r.jsxs("span",{className:"ml-2",children:[te.status,te.pauseReason?` (${te.pauseReason})`:""]})]}),r.jsxs("div",{children:[r.jsx("span",{className:"text-muted-foreground",children:"Created:"}),r.jsx("span",{className:"ml-2",children:En(te.createdAt)})]}),r.jsxs("div",{children:[r.jsx("span",{className:"text-muted-foreground",children:"Updated:"}),r.jsx("span",{className:"ml-2",children:En(te.updatedAt)})]}),te.workstreamId&&r.jsxs("div",{className:"col-span-2",children:[r.jsx("span",{className:"text-muted-foreground",children:"Workstream:"}),r.jsxs("span",{className:"ml-2 inline-flex items-center gap-1",children:[r.jsx(In,{className:"w-3 h-3 text-purple-500"}),At(te.workstreamId)]})]})]}),r.jsxs("div",{className:"bg-muted p-3 rounded-md",children:[r.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[r.jsx(Kt,{className:"w-4 h-4"}),r.jsx("span",{className:"text-sm font-medium",children:"Run this loop (uses official ralph-loop plugin):"})]}),r.jsx("code",{className:"text-xs bg-background p-2 rounded block whitespace-pre-wrap",children:to(te,!0)})]})]})]},te.id)})}),r.jsx(wt,{open:C,onOpenChange:y,children:r.jsxs(gt,{className:"sm:max-w-lg",children:[r.jsx(xt,{children:r.jsx(vt,{children:"Create New Loop"})}),r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{children:[r.jsxs("div",{className:"flex items-center justify-between mb-1",children:[r.jsx("label",{className:"text-sm font-medium",children:"Task Description"}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsxs(re,{variant:"outline",size:"sm",onClick:je,disabled:$||!z.trim(),className:"h-7 text-xs",children:[$?r.jsx(Qe,{className:"w-3 h-3 animate-spin mr-1"}):r.jsx(os,{className:"w-3 h-3 mr-1"}),"Tune with AI"]})}),r.jsx(Mt,{children:r.jsx("p",{className:"max-w-xs",children:"Use Claude to optimize your prompt for Ralph Loop execution - adds clear completion signals, verification steps, and acceptance criteria."})})]})})]}),r.jsx(Ct,{placeholder:"Describe what you want Claude to accomplish...",value:z,onChange:te=>{Y(te.target.value),ae(!1)},rows:4}),r.jsxs("div",{className:"flex items-center justify-between mt-1",children:[r.jsx("p",{className:"text-xs text-muted-foreground",children:"Be specific about the goal. The loop will continue until this task is completed."}),Q&&r.jsxs("span",{className:"text-xs text-green-600 dark:text-green-400 flex items-center gap-1",children:[r.jsx(qt,{className:"w-3 h-3"}),"AI-tuned"]})]})]}),r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Project"}),r.jsx("div",{className:"text-sm p-2 bg-muted rounded-md",children:e?r.jsx("span",{className:"font-mono",children:e.name||e.path||e.dir}):r.jsx("span",{className:"text-muted-foreground",children:"No project selected - loop will run in server directory"})})]}),r.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Max Iterations"}),r.jsx(ct,{type:"number",value:J,onChange:te=>K(te.target.value),min:1,max:1e3}),r.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Safety limit for the loop"})]}),r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Completion Promise"}),r.jsx(ct,{value:F,onChange:te=>R(te.target.value),placeholder:"DONE"}),r.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Text that signals completion"})]})]}),f.length>0&&r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Workstream (optional)"}),r.jsxs("select",{className:"w-full border rounded-md p-2 bg-background",value:H,onChange:te=>G(te.target.value),children:[r.jsx("option",{value:"",children:"No workstream"}),f.map(te=>r.jsx("option",{value:te.id,children:te.name},te.id))]})]})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:()=>y(!1),children:"Cancel"}),r.jsxs(re,{onClick:Z,disabled:O||!z.trim(),children:[O?r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}):null,"Create Loop"]})]})]})}),r.jsx(wt,{open:M,onOpenChange:I,children:r.jsxs(gt,{className:"sm:max-w-lg",children:[r.jsx(xt,{children:r.jsx(vt,{children:"Edit Loop"})}),r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Name"}),r.jsx(ct,{placeholder:"Loop name",value:Xe,onChange:te=>dt(te.target.value)})]}),r.jsxs("div",{children:[r.jsxs("div",{className:"flex items-center justify-between mb-1",children:[r.jsx("label",{className:"text-sm font-medium",children:"Task Description"}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsxs(re,{variant:"outline",size:"sm",onClick:async()=>{if(!we.trim()){q.error("Enter a task description first");return}try{se(!0),ne(we),Ze("edit");const te=await pe.tuneLoopPrompt(we,(L==null?void 0:L.projectPath)||(e==null?void 0:e.path)||(e==null?void 0:e.dir)||null);te.success?(W(te.tunedPrompt),fe(!0)):q.error(te.error||"Failed to tune prompt")}catch(te){q.error(te.message)}finally{se(!1)}},disabled:$||!we.trim(),className:"h-7 text-xs",children:[$?r.jsx(Qe,{className:"w-3 h-3 animate-spin mr-1"}):r.jsx(os,{className:"w-3 h-3 mr-1"}),"Tune with AI"]})}),r.jsx(Mt,{children:r.jsx("p",{className:"max-w-xs",children:"Use Claude to optimize your prompt for Ralph Loop execution."})})]})})]}),r.jsx(Ct,{placeholder:"Describe what you want Claude to accomplish...",value:we,onChange:te=>be(te.target.value),rows:4})]}),r.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Max Iterations"}),r.jsx(ct,{type:"number",value:Oe,onChange:te=>Se(te.target.value),min:1,max:1e3})]}),r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Completion Promise"}),r.jsx(ct,{value:Ee,onChange:te=>oe(te.target.value),placeholder:"DONE"})]})]}),f.length>0&&r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Workstream"}),r.jsxs("select",{className:"w-full border rounded-md p-2 bg-background",value:xe,onChange:te=>Pe(te.target.value),children:[r.jsx("option",{value:"",children:"No workstream"}),f.map(te=>r.jsx("option",{value:te.id,children:te.name},te.id))]})]}),L&&r.jsxs("div",{className:"text-xs text-muted-foreground",children:[r.jsxs("span",{children:["ID: ",L.id]}),r.jsx("span",{className:"mx-2",children:"|"}),r.jsxs("span",{children:["Status: ",L.status]}),r.jsx("span",{className:"mx-2",children:"|"}),r.jsxs("span",{children:["Phase: ",L.phase]})]})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:()=>I(!1),children:"Cancel"}),r.jsxs(re,{onClick:eo,disabled:O||!we.trim(),children:[O?r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}):null,"Save Changes"]})]})]})}),r.jsx(wt,{open:v,onOpenChange:g,children:r.jsxs(gt,{className:"sm:max-w-md",children:[r.jsx(xt,{children:r.jsx(vt,{children:"Loop Configuration"})}),r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Max Iterations"}),r.jsx(ct,{type:"number",value:ze,onChange:te=>He(te.target.value),min:1,max:1e3}),r.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Loop will pause after this many iterations"})]}),r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Default Completion Promise"}),r.jsx(ct,{value:dr,onChange:te=>ls(te.target.value),placeholder:"DONE"}),r.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Default text that signals loop completion (used with official ralph-loop plugin)"})]}),r.jsxs("div",{className:"flex items-center gap-2",children:[r.jsx("input",{type:"checkbox",id:"autoApprovePlan",checked:St,onChange:te=>ut(te.target.checked),className:"rounded"}),r.jsx("label",{htmlFor:"autoApprovePlan",className:"text-sm",children:"Auto-approve plans (skip manual plan approval)"})]})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:()=>g(!1),children:"Cancel"}),r.jsxs(re,{onClick:Nh,disabled:O,children:[O?r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}):null,"Save"]})]})]})}),r.jsx(wt,{open:b,onOpenChange:k,children:r.jsxs(gt,{className:"sm:max-w-2xl max-h-[80vh] overflow-y-auto",children:[r.jsx(xt,{children:r.jsx(vt,{children:"Loop History"})}),r.jsx("div",{className:"space-y-3 py-4",children:Jr.length===0?r.jsx("p",{className:"text-center text-muted-foreground py-8",children:"No completed loops yet"}):Jr.slice().reverse().map(te=>r.jsxs("div",{className:"border rounded-lg p-3",children:[r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsxs("div",{className:"flex items-center gap-2",children:[ba[te.status]||ba.completed,r.jsx("span",{className:"font-medium",children:te.name})]}),r.jsx("span",{className:"text-xs text-muted-foreground",children:En(te.completedAt)})]}),r.jsx("p",{className:"text-sm text-muted-foreground mt-1 truncate",children:te.task}),r.jsx("div",{className:"mt-2 text-xs text-muted-foreground",children:r.jsxs("span",{children:["Iterations: ",te.totalIterations]})})]},te.id))})]})}),r.jsx(wt,{open:E,onOpenChange:P,children:r.jsxs(gt,{className:"sm:max-w-3xl max-h-[80vh] overflow-y-auto",children:[r.jsx(xt,{children:r.jsx(vt,{children:(A==null?void 0:A.name)||"Loop Details"})}),A&&r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{className:"grid grid-cols-3 gap-4 text-sm",children:[r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Phase"}),r.jsx("span",{className:`text-sm px-2 py-0.5 rounded-full ${d_[A.phase]||""}`,children:A.phase})]}),r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Status"}),r.jsxs("div",{className:"flex items-center gap-1",children:[ba[A.status],r.jsx("span",{children:A.status})]})]}),r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Progress"}),r.jsxs("span",{children:[((ll=A.iterations)==null?void 0:ll.current)||0," / ",((cl=A.iterations)==null?void 0:cl.max)||50]})]})]}),r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Task"}),r.jsx("div",{className:"bg-muted p-3 rounded text-sm",children:(Uo=A.task)==null?void 0:Uo.original})]}),A.clarifications&&r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Clarifications"}),r.jsx("div",{className:"bg-muted p-3 rounded text-sm whitespace-pre-wrap max-h-40 overflow-y-auto",children:A.clarifications})]}),A.plan&&r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Plan"}),r.jsx("div",{className:"bg-muted p-3 rounded text-sm whitespace-pre-wrap max-h-60 overflow-y-auto font-mono",children:A.plan})]}),r.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Max Iterations"}),r.jsx("div",{className:"bg-muted p-2 rounded text-sm",children:((ro=A.iterations)==null?void 0:ro.max)||50})]}),r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Completion Promise"}),r.jsxs("div",{className:"bg-muted p-2 rounded text-sm font-mono",children:["<promise>",A.completionPromise||"DONE","</promise>"]})]})]}),r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Run Command (uses official ralph-loop plugin)"}),r.jsx("code",{className:"text-xs bg-muted p-3 rounded block whitespace-pre-wrap",children:to(A,!0)})]})]})]})}),r.jsx(wt,{open:jn,onOpenChange:rt,children:r.jsxs(gt,{className:"sm:max-w-md",children:[r.jsx(xt,{children:r.jsxs(vt,{className:"flex items-center gap-2",children:[r.jsx(fi,{className:"w-5 h-5"}),"Install ralph-loop Plugin"]})}),r.jsxs("div",{className:"py-4",children:[r.jsxs("p",{className:"text-sm text-muted-foreground mb-4",children:["The ",r.jsx("code",{className:"bg-muted px-1 rounded",children:"ralph-loop"})," plugin is required to run loops. This plugin provides the ",r.jsx("code",{className:"bg-muted px-1 rounded",children:"/ralph-loop"})," command that enables autonomous iteration."]}),Qr.scope==="project"&&r.jsx("div",{className:"bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded p-3 mb-4",children:r.jsxs("p",{className:"text-sm text-yellow-800 dark:text-yellow-200",children:["Plugin is currently installed only for project: ",r.jsx("br",{}),r.jsx("code",{className:"text-xs",children:Qr.projectPath})]})}),r.jsx("p",{className:"text-sm",children:"Install the plugin globally (user scope) to use loops from any project?"})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:kr,disabled:Ht,children:"Cancel"}),r.jsx(re,{onClick:Rs,disabled:Ht,children:Ht?r.jsxs(r.Fragment,{children:[r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}),"Installing..."]}):r.jsxs(r.Fragment,{children:[r.jsx(fi,{className:"w-4 h-4 mr-1"}),"Install Plugin"]})})]})]})}),r.jsx(Aj,{open:cs,onOpenChange:te=>{Wt(te),te||(Wr(null),Sr())},title:yt?`Loop: ${yt.name}`:"Running Loop",description:yt?((un=(dn=yt.task)==null?void 0:dn.original)==null?void 0:un.substring(0,100))+(((wi=(hn=yt.task)==null?void 0:hn.original)==null?void 0:wi.length)>100?"...":""):"",cwd:yt==null?void 0:yt.projectPath,initialCommand:yt?to(yt).startCmd:"",delayedCommand:yt?to(yt).skillCmd:"",delayedCommandDelay:3e3,env:yt?{CODER_LOOP_ID:yt.id,...yt.workstreamId&&{CODER_WORKSTREAM:yt.workstreamId}}:{},onExit:$o,headerExtra:r.jsxs("label",{className:"flex items-center gap-2 text-sm cursor-pointer select-none",children:[r.jsx("input",{type:"checkbox",checked:xr,onChange:te=>Xn(te.target.checked),className:"rounded"}),"Auto-close when done"]})}),r.jsx(wt,{open:de,onOpenChange:fe,children:r.jsxs(gt,{className:"sm:max-w-2xl max-h-[80vh] overflow-y-auto",children:[r.jsx(xt,{children:r.jsxs(vt,{className:"flex items-center gap-2",children:[r.jsx(os,{className:"w-5 h-5 text-purple-500"}),"AI-Tuned Prompt"]})}),r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2 text-muted-foreground",children:"Original Prompt"}),r.jsx("div",{className:"bg-muted p-3 rounded text-sm whitespace-pre-wrap max-h-32 overflow-y-auto",children:ce})]}),r.jsxs("div",{children:[r.jsxs("h4",{className:"text-sm font-medium mb-2 flex items-center gap-2",children:[r.jsx(qt,{className:"w-4 h-4 text-purple-500"}),"Tuned Prompt"]}),r.jsx(Ct,{value:X,onChange:te=>W(te.target.value),rows:10,className:"font-mono text-sm"}),r.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"You can edit the tuned prompt before accepting it."})]})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:Ue,children:"Keep Original"}),r.jsxs(re,{onClick:Ie,children:[r.jsx(Ft,{className:"w-4 h-4 mr-1"}),"Use Tuned Prompt"]})]})]})}),r.jsx(wt,{open:Ce,onOpenChange:$e,children:r.jsxs(gt,{className:"sm:max-w-md",children:[r.jsx(xt,{children:r.jsxs(vt,{className:"flex items-center gap-2",children:[r.jsx(Gd,{className:"w-5 h-5"}),"Resume Loop"]})}),r.jsx("div",{className:"py-4",children:Be&&r.jsxs(r.Fragment,{children:[r.jsxs("p",{className:"text-sm mb-4",children:["This loop ",Be.status==="failed"?"failed":Be.status==="cancelled"?"was cancelled":"was paused",Be.pauseReason&&`: ${Be.pauseReason}`]}),r.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:"Would you like to tune the prompt with AI before resuming? This can help add guardrails based on what went wrong."}),r.jsx("div",{className:"bg-muted p-3 rounded text-sm max-h-32 overflow-y-auto",children:(_i=Be.task)==null?void 0:_i.original})]})}),r.jsxs(jt,{className:"flex-col sm:flex-row gap-2",children:[r.jsx(re,{variant:"outline",onClick:()=>{$e(!1),ue(null)},children:"Cancel"}),r.jsx(re,{variant:"secondary",onClick:vr,children:"Resume As-Is"}),r.jsxs(re,{onClick:Et,disabled:$,children:[$?r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}):r.jsx(os,{className:"w-4 h-4 mr-1"}),"Tune & Resume"]})]})]})}),r.jsx(wt,{open:el,onOpenChange:gs,children:r.jsxs(gt,{className:"sm:max-w-md",children:[r.jsx(xt,{children:r.jsxs(vt,{className:"flex items-center gap-2",children:[(et==null?void 0:et.status)==="completed"&&r.jsxs(r.Fragment,{children:[r.jsx(No,{className:"w-5 h-5 text-green-600"})," Loop Completed"]}),(et==null?void 0:et.status)==="paused"&&r.jsxs(r.Fragment,{children:[r.jsx(xp,{className:"w-5 h-5 text-yellow-500"})," Loop Paused"]}),(et==null?void 0:et.status)==="failed"&&r.jsxs(r.Fragment,{children:[r.jsx(Ea,{className:"w-5 h-5 text-red-500"})," Loop Failed"]}),(et==null?void 0:et.status)==="cancelled"&&r.jsxs(r.Fragment,{children:[r.jsx(Ea,{className:"w-5 h-5 text-gray-500"})," Loop Cancelled"]})]})}),et&&r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-1",children:"Task"}),r.jsx("p",{className:"text-sm text-muted-foreground bg-muted p-2 rounded",children:et.task})]}),et.pauseReason&&r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-1",children:"Reason"}),r.jsx("p",{className:"text-sm text-muted-foreground bg-muted p-2 rounded",children:et.pauseReason})]}),r.jsxs("div",{className:"grid grid-cols-3 gap-3 text-sm",children:[r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Status"}),r.jsxs("div",{className:"font-medium flex items-center gap-1",children:[ba[et.status],r.jsx("span",{className:"capitalize",children:et.status})]})]}),r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Iterations"}),r.jsxs("div",{className:"font-medium",children:[et.iterations," / ",et.maxIterations]})]}),r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Duration"}),r.jsx("div",{className:"font-medium",children:et.duration!=null?et.duration<60?`${et.duration}s`:et.duration<3600?`${Math.floor(et.duration/60)}m ${et.duration%60}s`:`${Math.floor(et.duration/3600)}h ${Math.floor(et.duration%3600/60)}m`:"-"})]})]}),r.jsxs("div",{className:"text-xs text-muted-foreground",children:[et.status==="completed"?"Completed":"Stopped"," at ",En(et.completedAt)]})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:()=>gs(!1),children:"Close"}),((et==null?void 0:et.status)==="paused"||(et==null?void 0:et.status)==="failed"||(et==null?void 0:et.status)==="cancelled")&&r.jsxs(re,{onClick:()=>{if(gs(!1),et!=null&&et.id){const te=t.find(Le=>Le.id===et.id);te&&Nt(te)}},children:[r.jsx(Gd,{className:"w-4 h-4 mr-1"}),(et==null?void 0:et.status)==="paused"?"Resume":"Restart"]}),r.jsx(re,{variant:"secondary",onClick:()=>{if(gs(!1),et!=null&&et.id){const te=t.find(Le=>Le.id===et.id);te&&sl(te)}},children:"View Details"})]})]})})]})}function tW(e,t=[]){let s=[];function n(d,u){const l=_.createContext(u);l.displayName=d+"Context";const c=s.length;s=[...s,u];const f=h=>{var v;const{scope:x,children:w,...j}=h,C=((v=x==null?void 0:x[e])==null?void 0:v[c])||l,y=_.useMemo(()=>j,Object.values(j));return r.jsx(C.Provider,{value:y,children:w})};f.displayName=d+"Provider";function m(h,x){var C;const w=((C=x==null?void 0:x[e])==null?void 0:C[c])||l,j=_.useContext(w);if(j)return j;if(u!==void 0)return u;throw new Error(`\`${h}\` must be used within \`${d}\``)}return[f,m]}const o=()=>{const d=s.map(u=>_.createContext(u));return function(l){const c=(l==null?void 0:l[e])||d;return _.useMemo(()=>({[`__scope${e}`]:{...l,[e]:c}}),[l,c])}};return o.scopeName=e,[n,rW(o,...t)]}function rW(...e){const t=e[0];if(e.length===1)return t;const s=()=>{const n=e.map(o=>({useScope:o(),scopeName:o.scopeName}));return function(d){const u=n.reduce((l,{useScope:c,scopeName:f})=>{const h=c(d)[`__scope${f}`];return{...l,...h}},{});return _.useMemo(()=>({[`__scope${t.scopeName}`]:u}),[u])}};return s.scopeName=t.scopeName,s}var sW=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],u2=sW.reduce((e,t)=>{const s=qu(`Primitive.${t}`),n=_.forwardRef((o,d)=>{const{asChild:u,...l}=o,c=u?s:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),r.jsx(c,{...l,ref:d})});return n.displayName=`Primitive.${t}`,{...e,[t]:n}},{}),Hx="Progress",Wx=100,[nW]=tW(Hx),[iW,oW]=nW(Hx),h2=_.forwardRef((e,t)=>{const{__scopeProgress:s,value:n=null,max:o,getValueLabel:d=aW,...u}=e;(o||o===0)&&!u_(o)&&console.error(lW(`${o}`,"Progress"));const l=u_(o)?o:Wx;n!==null&&!h_(n,l)&&console.error(cW(`${n}`,"Progress"));const c=h_(n,l)?n:null,f=Fu(c)?d(c,l):void 0;return r.jsx(iW,{scope:s,value:c,max:l,children:r.jsx(u2.div,{"aria-valuemax":l,"aria-valuemin":0,"aria-valuenow":Fu(c)?c:void 0,"aria-valuetext":f,role:"progressbar","data-state":p2(c,l),"data-value":c??void 0,"data-max":l,...u,ref:t})})});h2.displayName=Hx;var f2="ProgressIndicator",m2=_.forwardRef((e,t)=>{const{__scopeProgress:s,...n}=e,o=oW(f2,s);return r.jsx(u2.div,{"data-state":p2(o.value,o.max),"data-value":o.value??void 0,"data-max":o.max,...n,ref:t})});m2.displayName=f2;function aW(e,t){return`${Math.round(e/t*100)}%`}function p2(e,t){return e==null?"indeterminate":e===t?"complete":"loading"}function Fu(e){return typeof e=="number"}function u_(e){return Fu(e)&&!isNaN(e)&&e>0}function h_(e,t){return Fu(e)&&!isNaN(e)&&e<=t&&e>=0}function lW(e,t){return`Invalid prop \`max\` of value \`${e}\` supplied to \`${t}\`. Only numbers greater than 0 are valid max values. Defaulting to \`${Wx}\`.`}function cW(e,t){return`Invalid prop \`value\` of value \`${e}\` supplied to \`${t}\`. The \`value\` prop must be:
|
|
3006
|
+
`),jr.transcript=vs;const ys=await pe.tuneLoopPrompt(Vr,Be.projectPath||(e==null?void 0:e.path)||(e==null?void 0:e.dir)||null,jr);ys.success?(await pe.updateLoop(Be.id,{task:{original:ys.tunedPrompt}}),q.success("Prompt tuned and loop updated"),$e(!1),await tl(Be.id),Sr()):q.error(ys.error||"Failed to tune prompt")}catch(Vr){q.error(Vr.message)}finally{se(!1),ue(null)}},vr=async()=>{Be&&($e(!1),await $c(Be.id),ue(null))},nr=async te=>{try{V(!0);const Le=await pe.createLoop(te,{workstreamId:H||null,projectPath:(e==null?void 0:e.path)||(e==null?void 0:e.dir)||null,maxIterations:parseInt(J,10)||50,completionPromise:F||"DONE"});Le.success?(q.success("Loop created"),y(!1),Y(""),G(""),K(ze),R(dr),ae(!1),Sr()):q.error(Le.error||"Failed to create loop")}catch(Le){q.error(Le.message)}finally{V(!1)}},yr=async te=>{if(Qr.needsInstall){zt(te),Hr("start"),rt(!0);return}await Zr(te)},Zr=async te=>{try{const Le=await pe.startLoop(te);Le.success&&Le.loop?(q.success("Loop started - launching Claude Code"),Wr(Le.loop),Wt(!0),Sr()):q.error(Le.error||"Failed to start loop")}catch(Le){q.error(Le.message)}},Rs=async()=>{try{sr(!0);const te=await pe.installRalphLoopPlugin();te.success?(q.success("ralph-loop plugin installed"),ps({installed:!0,scope:"user",needsInstall:!1}),rt(!1),$t&&(gr==="resume"?await tl($t):await Zr($t),zt(null),Hr(null))):q.error(te.error||"Failed to install plugin")}catch(te){q.error(te.message)}finally{sr(!1)}},kr=()=>{rt(!1),zt(null),Hr(null)},$o=_.useCallback(async(te,Le)=>{var Vt,Xt,Vr,kt,br,jr,vs,ys,Ds,Jn,so,zc,Hc,Go;if(yt)try{const ft=(await pe.getLoop(yt.id)).loop;if(ft.taskComplete||ft.status==="completed")q.success("Loop completed successfully!"),Nn({id:ft.id,name:ft.name,task:(Vt=ft.task)==null?void 0:Vt.original,status:"completed",iterations:((Xt=ft.iterations)==null?void 0:Xt.current)||0,maxIterations:((Vr=ft.iterations)==null?void 0:Vr.max)||50,phase:ft.phase,startedAt:ft.startedAt,completedAt:ft.completedAt||new Date().toISOString()}),gs(!0),Wt(!1),Wr(null);else if(ft.status==="paused")q.info(`Loop paused: ${ft.pauseReason||"user requested"}`),Nn({id:ft.id,name:ft.name,task:(kt=ft.task)==null?void 0:kt.original,status:"paused",pauseReason:ft.pauseReason,iterations:((br=ft.iterations)==null?void 0:br.current)||0,maxIterations:((jr=ft.iterations)==null?void 0:jr.max)||50,phase:ft.phase,startedAt:ft.startedAt,completedAt:new Date().toISOString()}),gs(!0);else if(te===0&&!Le)await pe.completeLoop(ft.id),q.success("Loop completed successfully!"),Nn({id:ft.id,name:ft.name,task:(vs=ft.task)==null?void 0:vs.original,status:"completed",iterations:((ys=ft.iterations)==null?void 0:ys.current)||0,maxIterations:((Ds=ft.iterations)==null?void 0:Ds.max)||50,phase:"execute",startedAt:ft.startedAt,completedAt:new Date().toISOString()}),gs(!0),Wt(!1),Wr(null);else if(((Jn=ft.iterations)==null?void 0:Jn.current)>=((so=ft.iterations)==null?void 0:so.max))q.warning("Loop reached max iterations"),await pe.pauseLoop(ft.id);else{const Wc=Le?`Signal: ${Le}`:`Exit code: ${te}`;Nn({id:ft.id,name:ft.name,task:(zc=ft.task)==null?void 0:zc.original,status:"paused",pauseReason:Wc,iterations:((Hc=ft.iterations)==null?void 0:Hc.current)||0,maxIterations:((Go=ft.iterations)==null?void 0:Go.max)||50,phase:ft.phase,startedAt:ft.startedAt,completedAt:new Date().toISOString()}),gs(!0)}Sr()}catch(no){console.error("Failed to check loop status:",no)}},[yt]),Ms=async te=>{try{const Le=await pe.pauseLoop(te);Le.success?(q.success("Loop paused"),Sr()):q.error(Le.error||"Failed to pause loop")}catch(Le){q.error(Le.message)}},$c=async te=>{if(Qr.needsInstall){zt(te),Hr("resume"),rt(!0);return}await tl(te)},tl=async te=>{try{const Le=await pe.resumeLoop(te);Le.success&&Le.loop?(q.success("Loop resumed - launching Claude Code"),Wr(Le.loop),Wt(!0),Sr()):q.error(Le.error||"Failed to resume loop")}catch(Le){q.error(Le.message)}},kh=async te=>{if(confirm("Cancel this loop?"))try{const Le=await pe.cancelLoop(te);Le.success?(q.success("Loop cancelled"),Sr()):q.error(Le.error||"Failed to cancel loop")}catch(Le){q.error(Le.message)}},zo=async te=>{if(confirm("Delete this loop and all its data?"))try{const Le=await pe.deleteLoop(te);Le.success?(q.success("Loop deleted"),Sr()):q.error(Le.error||"Failed to delete loop")}catch(Le){q.error(Le.message)}},Ho=te=>{var Le,Vt;B(te),dt(te.name||""),be(((Le=te.task)==null?void 0:Le.original)||""),Se(((Vt=te.iterations)==null?void 0:Vt.max)||50),oe(te.completionPromise||"DONE"),Pe(te.workstreamId||""),I(!0)},eo=async()=>{if(L)try{V(!0);const te={name:Xe,task:{original:we},iterations:{max:parseInt(Oe,10)},completionPromise:Ee,workstreamId:xe||null},Le=await pe.updateLoop(L.id,te);Le.success?(q.success("Loop updated"),I(!1),B(null),Sr()):q.error(Le.error||"Failed to update loop")}catch(te){q.error(te.message)}finally{V(!1)}},Wo=async te=>{var Le,Vt;try{V(!0);const Xt=await pe.createLoop(((Le=te.task)==null?void 0:Le.original)||"",{name:`${te.name} (copy)`,workstreamId:te.workstreamId||null,projectPath:te.projectPath||(e==null?void 0:e.path)||(e==null?void 0:e.dir)||null,maxIterations:((Vt=te.iterations)==null?void 0:Vt.max)||50,completionPromise:te.completionPromise||"DONE"});Xt.success?(q.success("Loop copied"),Sr()):q.error(Xt.error||"Failed to copy loop")}catch(Xt){q.error(Xt.message)}finally{V(!1)}},jh=async te=>{try{const Le=await pe.approveLoop(te);Le.success?(q.success("Plan approved"),Sr()):q.error(Le.error||"Failed to approve plan")}catch(Le){q.error(Le.message)}},Nh=async()=>{try{V(!0);const te=await pe.updateLoopConfig({maxIterations:parseInt(ze,10),autoApprovePlan:St,completionPromise:dr});te.success?(q.success("Configuration saved"),g(!1),yi()):q.error(te.error||"Failed to save configuration")}catch(te){q.error(te.message)}finally{V(!1)}},rl=async()=>{try{kn(!0);const te=await pe.installLoopHooks();te.success?(q.success("Hooks installed successfully"),bi()):q.error(te.error||"Failed to install hooks")}catch(te){q.error(te.message)}finally{kn(!1)}},sl=async te=>{try{const Le=await pe.getLoop(te.id);N({...Le.loop,clarifications:Le.clarifications,plan:Le.plan}),P(!0)}catch{q.error("Failed to load loop details")}},nl=te=>{navigator.clipboard.writeText(te),q.success("Copied to clipboard")},En=te=>te?new Date(te).toLocaleString():"-",Eh=te=>te.iterations?Math.min(100,te.iterations.current/te.iterations.max*100):0,il=((Vo=zr.stopHook)==null?void 0:Vo.registered)&&((al=zr.prepromptHook)==null?void 0:al.registered),At=te=>{if(!te)return null;const Le=f.find(Vt=>Vt.id===te);return(Le==null?void 0:Le.name)||te},ol=w?t.filter(te=>te.workstreamId===w):t,to=(te,Le=!1)=>{var jr,vs;const Vt=((jr=te.task)==null?void 0:jr.original)||"",Xt=((vs=te.iterations)==null?void 0:vs.max)||50,Vr=te.completionPromise||"DONE";if(Le){const ys=Vt.replace(/\n+/g," ").substring(0,100),Ds=Vt.length>100?"...":"";return`claude --dangerously-skip-permissions "/ralph-loop ${ys.replace(/"/g,'\\"')}${Ds} --max-iterations ${Xt} --completion-promise ${Vr}"`}const kt="claude --dangerously-skip-permissions",br=`/ralph-loop ${Vt} --max-iterations ${Xt} --completion-promise ${Vr}`;return{startCmd:kt,skillCmd:br}};return r.jsxs("div",{className:"p-6 space-y-6 max-w-6xl mx-auto",children:[r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsxs("div",{children:[r.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[r.jsx(lc,{className:"w-6 h-6"}),"Ralph Loops"]}),r.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Autonomous development loops using the official ralph-loop plugin"})]}),r.jsxs("div",{className:"flex items-center gap-2",children:[f.length>0&&r.jsxs("div",{className:"flex items-center gap-1",children:[r.jsx(Rg,{className:"w-4 h-4 text-muted-foreground"}),r.jsxs("select",{className:"text-sm border rounded px-2 py-1 bg-background",value:w,onChange:te=>j(te.target.value),children:[r.jsx("option",{value:"",children:"All workstreams"}),f.map(te=>r.jsx("option",{value:te.id,children:te.name},te.id))]})]}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsxs(re,{variant:"outline",size:"sm",onClick:()=>{Zi(),k(!0)},children:[r.jsx(Cu,{className:"w-4 h-4 mr-1"}),"History"]})}),r.jsx(Mt,{children:"View completed loops"})]})}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsxs(re,{variant:"outline",size:"sm",onClick:()=>g(!0),children:[r.jsx(on,{className:"w-4 h-4 mr-1"}),"Config"]})}),r.jsx(Mt,{children:"Configure loop defaults"})]})}),r.jsxs(re,{onClick:()=>y(!0),children:[r.jsx(Rt,{className:"w-4 h-4 mr-1"}),"New Loop"]})]})]}),!il&&r.jsxs("div",{className:"bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4 flex items-center justify-between",children:[r.jsxs("div",{className:"flex items-center gap-3",children:[r.jsx(Ws,{className:"w-5 h-5 text-yellow-600"}),r.jsxs("div",{children:[r.jsx("p",{className:"font-medium text-yellow-800 dark:text-yellow-200",children:"Hooks not installed"}),r.jsx("p",{className:"text-sm text-yellow-700 dark:text-yellow-300",children:"Install the Ralph Loop hooks to enable automatic loop continuation"})]})]}),r.jsxs(re,{variant:"outline",size:"sm",onClick:rl,disabled:Cr,children:[Cr?r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}):null,"Install Hooks"]})]}),n?r.jsx("div",{className:"flex items-center justify-center py-12",children:r.jsx(Qe,{className:"w-6 h-6 animate-spin text-muted-foreground"})}):ol.length===0?r.jsxs("div",{className:"text-center py-12 text-muted-foreground",children:[r.jsx(lc,{className:"w-12 h-12 mx-auto mb-4 opacity-50"}),r.jsx("p",{className:"text-lg font-medium",children:w?"No loops in this workstream":"No loops yet"}),r.jsx("p",{className:"text-sm mt-1",children:"Create a loop to start autonomous development"})]}):r.jsx("div",{className:"space-y-3",children:ol.map(te=>{var Le,Vt,Xt,Vr,kt;return r.jsxs("div",{className:"border rounded-lg bg-card overflow-hidden",children:[r.jsxs("div",{className:"p-4 cursor-pointer hover:bg-muted/50 transition-colors",onClick:()=>u(d===te.id?null:te.id),children:[r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsxs("div",{className:"flex items-center gap-3",children:[d===te.id?r.jsx(Ar,{className:"w-4 h-4 text-muted-foreground"}):r.jsx(fs,{className:"w-4 h-4 text-muted-foreground"}),ba[te.status]||ba.pending,r.jsxs("div",{children:[r.jsx("h3",{className:"font-medium",children:te.name}),r.jsx("p",{className:"text-sm text-muted-foreground truncate max-w-md",children:((Le=te.task)==null?void 0:Le.original)||"No task"})]})]}),r.jsxs("div",{className:"flex items-center gap-3",children:[te.workstreamId&&r.jsxs("span",{className:"text-xs px-2 py-0.5 rounded-full bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200 flex items-center gap-1",children:[r.jsx(In,{className:"w-3 h-3"}),At(te.workstreamId)]}),r.jsx("span",{className:`text-xs px-2 py-0.5 rounded-full ${d_[te.phase]||"bg-gray-100 dark:bg-gray-800"}`,children:te.phase}),r.jsxs("span",{className:"text-sm text-muted-foreground",children:[((Vt=te.iterations)==null?void 0:Vt.current)||0,"/",((Xt=te.iterations)==null?void 0:Xt.max)||50]}),r.jsxs("div",{className:"flex items-center gap-1",onClick:br=>br.stopPropagation(),children:[te.status==="pending"&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>yr(te.id),children:r.jsx(tS,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Start loop"})]})}),te.status==="running"&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>Ms(te.id),children:r.jsx(xp,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Pause loop"})]})}),te.status==="paused"&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>Nt(te),children:r.jsx(Gd,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Resume loop"})]})}),(te.status==="cancelled"||te.status==="failed")&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>Nt(te),children:r.jsx(Gd,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Restart loop"})]})}),te.phase==="plan"&&te.status==="running"&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>jh(te.id),children:r.jsx(Ft,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Approve plan"})]})}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>Ho(te),children:r.jsx(Ku,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Edit loop"})]})}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>Wo(te),children:r.jsx(Oa,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Duplicate loop"})]})}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>sl(te),children:r.jsx(Ag,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"View details"})]})}),(te.status==="running"||te.status==="paused")&&r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>kh(te.id),children:r.jsx(Ea,{className:"w-4 h-4"})})}),r.jsx(Mt,{children:"Cancel loop"})]})}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsx(re,{variant:"ghost",size:"sm",onClick:()=>zo(te.id),children:r.jsx(Ps,{className:"w-4 h-4 text-red-500"})})}),r.jsx(Mt,{children:"Delete loop"})]})})]})]})]}),r.jsxs("div",{className:"mt-3",children:[r.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground mb-1",children:[r.jsx("span",{children:"Iterations"}),r.jsxs("span",{children:[((Vr=te.iterations)==null?void 0:Vr.current)||0," / ",((kt=te.iterations)==null?void 0:kt.max)||50]})]}),r.jsx("div",{className:"h-1.5 bg-muted rounded-full overflow-hidden",children:r.jsx("div",{className:"h-full bg-blue-500 transition-all",style:{width:`${Eh(te)}%`}})})]})]}),d===te.id&&r.jsxs("div",{className:"border-t p-4 bg-muted/30 space-y-4",children:[r.jsxs("div",{className:"grid grid-cols-2 gap-4 text-sm",children:[r.jsxs("div",{children:[r.jsx("span",{className:"text-muted-foreground",children:"ID:"}),r.jsx("span",{className:"ml-2 font-mono",children:te.id}),r.jsx(re,{variant:"ghost",size:"sm",className:"h-6 w-6 p-0 ml-1",onClick:()=>nl(te.id),children:r.jsx(Oa,{className:"w-3 h-3"})})]}),r.jsxs("div",{children:[r.jsx("span",{className:"text-muted-foreground",children:"Status:"}),r.jsxs("span",{className:"ml-2",children:[te.status,te.pauseReason?` (${te.pauseReason})`:""]})]}),r.jsxs("div",{children:[r.jsx("span",{className:"text-muted-foreground",children:"Created:"}),r.jsx("span",{className:"ml-2",children:En(te.createdAt)})]}),r.jsxs("div",{children:[r.jsx("span",{className:"text-muted-foreground",children:"Updated:"}),r.jsx("span",{className:"ml-2",children:En(te.updatedAt)})]}),te.workstreamId&&r.jsxs("div",{className:"col-span-2",children:[r.jsx("span",{className:"text-muted-foreground",children:"Workstream:"}),r.jsxs("span",{className:"ml-2 inline-flex items-center gap-1",children:[r.jsx(In,{className:"w-3 h-3 text-purple-500"}),At(te.workstreamId)]})]})]}),r.jsxs("div",{className:"bg-muted p-3 rounded-md",children:[r.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[r.jsx(Kt,{className:"w-4 h-4"}),r.jsx("span",{className:"text-sm font-medium",children:"Run this loop (uses official ralph-loop plugin):"})]}),r.jsx("code",{className:"text-xs bg-background p-2 rounded block whitespace-pre-wrap",children:to(te,!0)})]})]})]},te.id)})}),r.jsx(wt,{open:C,onOpenChange:y,children:r.jsxs(gt,{className:"sm:max-w-lg",children:[r.jsx(xt,{children:r.jsx(vt,{children:"Create New Loop"})}),r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{children:[r.jsxs("div",{className:"flex items-center justify-between mb-1",children:[r.jsx("label",{className:"text-sm font-medium",children:"Task Description"}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsxs(re,{variant:"outline",size:"sm",onClick:je,disabled:$||!z.trim(),className:"h-7 text-xs",children:[$?r.jsx(Qe,{className:"w-3 h-3 animate-spin mr-1"}):r.jsx(os,{className:"w-3 h-3 mr-1"}),"Tune with AI"]})}),r.jsx(Mt,{children:r.jsx("p",{className:"max-w-xs",children:"Use Claude to optimize your prompt for Ralph Loop execution - adds clear completion signals, verification steps, and acceptance criteria."})})]})})]}),r.jsx(Ct,{placeholder:"Describe what you want Claude to accomplish...",value:z,onChange:te=>{Y(te.target.value),ae(!1)},rows:4}),r.jsxs("div",{className:"flex items-center justify-between mt-1",children:[r.jsx("p",{className:"text-xs text-muted-foreground",children:"Be specific about the goal. The loop will continue until this task is completed."}),Q&&r.jsxs("span",{className:"text-xs text-green-600 dark:text-green-400 flex items-center gap-1",children:[r.jsx(qt,{className:"w-3 h-3"}),"AI-tuned"]})]})]}),r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Project"}),r.jsx("div",{className:"text-sm p-2 bg-muted rounded-md",children:e?r.jsx("span",{className:"font-mono",children:e.name||e.path||e.dir}):r.jsx("span",{className:"text-muted-foreground",children:"No project selected - loop will run in server directory"})})]}),r.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Max Iterations"}),r.jsx(ct,{type:"number",value:J,onChange:te=>K(te.target.value),min:1,max:1e3}),r.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Safety limit for the loop"})]}),r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Completion Promise"}),r.jsx(ct,{value:F,onChange:te=>R(te.target.value),placeholder:"DONE"}),r.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Text that signals completion"})]})]}),f.length>0&&r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Workstream (optional)"}),r.jsxs("select",{className:"w-full border rounded-md p-2 bg-background",value:H,onChange:te=>G(te.target.value),children:[r.jsx("option",{value:"",children:"No workstream"}),f.map(te=>r.jsx("option",{value:te.id,children:te.name},te.id))]})]})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:()=>y(!1),children:"Cancel"}),r.jsxs(re,{onClick:Z,disabled:O||!z.trim(),children:[O?r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}):null,"Create Loop"]})]})]})}),r.jsx(wt,{open:M,onOpenChange:I,children:r.jsxs(gt,{className:"sm:max-w-lg",children:[r.jsx(xt,{children:r.jsx(vt,{children:"Edit Loop"})}),r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Name"}),r.jsx(ct,{placeholder:"Loop name",value:Xe,onChange:te=>dt(te.target.value)})]}),r.jsxs("div",{children:[r.jsxs("div",{className:"flex items-center justify-between mb-1",children:[r.jsx("label",{className:"text-sm font-medium",children:"Task Description"}),r.jsx(ar,{children:r.jsxs(Lt,{children:[r.jsx(Ot,{asChild:!0,children:r.jsxs(re,{variant:"outline",size:"sm",onClick:async()=>{if(!we.trim()){q.error("Enter a task description first");return}try{se(!0),ne(we),Ze("edit");const te=await pe.tuneLoopPrompt(we,(L==null?void 0:L.projectPath)||(e==null?void 0:e.path)||(e==null?void 0:e.dir)||null);te.success?(W(te.tunedPrompt),fe(!0)):q.error(te.error||"Failed to tune prompt")}catch(te){q.error(te.message)}finally{se(!1)}},disabled:$||!we.trim(),className:"h-7 text-xs",children:[$?r.jsx(Qe,{className:"w-3 h-3 animate-spin mr-1"}):r.jsx(os,{className:"w-3 h-3 mr-1"}),"Tune with AI"]})}),r.jsx(Mt,{children:r.jsx("p",{className:"max-w-xs",children:"Use Claude to optimize your prompt for Ralph Loop execution."})})]})})]}),r.jsx(Ct,{placeholder:"Describe what you want Claude to accomplish...",value:we,onChange:te=>be(te.target.value),rows:4})]}),r.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Max Iterations"}),r.jsx(ct,{type:"number",value:Oe,onChange:te=>Se(te.target.value),min:1,max:1e3})]}),r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Completion Promise"}),r.jsx(ct,{value:Ee,onChange:te=>oe(te.target.value),placeholder:"DONE"})]})]}),f.length>0&&r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Workstream"}),r.jsxs("select",{className:"w-full border rounded-md p-2 bg-background",value:xe,onChange:te=>Pe(te.target.value),children:[r.jsx("option",{value:"",children:"No workstream"}),f.map(te=>r.jsx("option",{value:te.id,children:te.name},te.id))]})]}),L&&r.jsxs("div",{className:"text-xs text-muted-foreground",children:[r.jsxs("span",{children:["ID: ",L.id]}),r.jsx("span",{className:"mx-2",children:"|"}),r.jsxs("span",{children:["Status: ",L.status]}),r.jsx("span",{className:"mx-2",children:"|"}),r.jsxs("span",{children:["Phase: ",L.phase]})]})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:()=>I(!1),children:"Cancel"}),r.jsxs(re,{onClick:eo,disabled:O||!we.trim(),children:[O?r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}):null,"Save Changes"]})]})]})}),r.jsx(wt,{open:v,onOpenChange:g,children:r.jsxs(gt,{className:"sm:max-w-md",children:[r.jsx(xt,{children:r.jsx(vt,{children:"Loop Configuration"})}),r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Max Iterations"}),r.jsx(ct,{type:"number",value:ze,onChange:te=>He(te.target.value),min:1,max:1e3}),r.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Loop will pause after this many iterations"})]}),r.jsxs("div",{children:[r.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Default Completion Promise"}),r.jsx(ct,{value:dr,onChange:te=>ls(te.target.value),placeholder:"DONE"}),r.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Default text that signals loop completion (used with official ralph-loop plugin)"})]}),r.jsxs("div",{className:"flex items-center gap-2",children:[r.jsx("input",{type:"checkbox",id:"autoApprovePlan",checked:St,onChange:te=>ut(te.target.checked),className:"rounded"}),r.jsx("label",{htmlFor:"autoApprovePlan",className:"text-sm",children:"Auto-approve plans (skip manual plan approval)"})]})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:()=>g(!1),children:"Cancel"}),r.jsxs(re,{onClick:Nh,disabled:O,children:[O?r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}):null,"Save"]})]})]})}),r.jsx(wt,{open:b,onOpenChange:k,children:r.jsxs(gt,{className:"sm:max-w-2xl max-h-[80vh] overflow-y-auto",children:[r.jsx(xt,{children:r.jsx(vt,{children:"Loop History"})}),r.jsx("div",{className:"space-y-3 py-4",children:Jr.length===0?r.jsx("p",{className:"text-center text-muted-foreground py-8",children:"No completed loops yet"}):Jr.slice().reverse().map(te=>r.jsxs("div",{className:"border rounded-lg p-3",children:[r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsxs("div",{className:"flex items-center gap-2",children:[ba[te.status]||ba.completed,r.jsx("span",{className:"font-medium",children:te.name})]}),r.jsx("span",{className:"text-xs text-muted-foreground",children:En(te.completedAt)})]}),r.jsx("p",{className:"text-sm text-muted-foreground mt-1 truncate",children:te.task}),r.jsx("div",{className:"mt-2 text-xs text-muted-foreground",children:r.jsxs("span",{children:["Iterations: ",te.totalIterations]})})]},te.id))})]})}),r.jsx(wt,{open:E,onOpenChange:P,children:r.jsxs(gt,{className:"sm:max-w-3xl max-h-[80vh] overflow-y-auto",children:[r.jsx(xt,{children:r.jsx(vt,{children:(A==null?void 0:A.name)||"Loop Details"})}),A&&r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{className:"grid grid-cols-3 gap-4 text-sm",children:[r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Phase"}),r.jsx("span",{className:`text-sm px-2 py-0.5 rounded-full ${d_[A.phase]||""}`,children:A.phase})]}),r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Status"}),r.jsxs("div",{className:"flex items-center gap-1",children:[ba[A.status],r.jsx("span",{children:A.status})]})]}),r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Progress"}),r.jsxs("span",{children:[((ll=A.iterations)==null?void 0:ll.current)||0," / ",((cl=A.iterations)==null?void 0:cl.max)||50]})]})]}),r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Task"}),r.jsx("div",{className:"bg-muted p-3 rounded text-sm",children:(Uo=A.task)==null?void 0:Uo.original})]}),A.clarifications&&r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Clarifications"}),r.jsx("div",{className:"bg-muted p-3 rounded text-sm whitespace-pre-wrap max-h-40 overflow-y-auto",children:A.clarifications})]}),A.plan&&r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Plan"}),r.jsx("div",{className:"bg-muted p-3 rounded text-sm whitespace-pre-wrap max-h-60 overflow-y-auto font-mono",children:A.plan})]}),r.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Max Iterations"}),r.jsx("div",{className:"bg-muted p-2 rounded text-sm",children:((ro=A.iterations)==null?void 0:ro.max)||50})]}),r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Completion Promise"}),r.jsxs("div",{className:"bg-muted p-2 rounded text-sm font-mono",children:["<promise>",A.completionPromise||"DONE","</promise>"]})]})]}),r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2",children:"Run Command (uses official ralph-loop plugin)"}),r.jsx("code",{className:"text-xs bg-muted p-3 rounded block whitespace-pre-wrap",children:to(A,!0)})]})]})]})}),r.jsx(wt,{open:jn,onOpenChange:rt,children:r.jsxs(gt,{className:"sm:max-w-md",children:[r.jsx(xt,{children:r.jsxs(vt,{className:"flex items-center gap-2",children:[r.jsx(fi,{className:"w-5 h-5"}),"Install ralph-loop Plugin"]})}),r.jsxs("div",{className:"py-4",children:[r.jsxs("p",{className:"text-sm text-muted-foreground mb-4",children:["The ",r.jsx("code",{className:"bg-muted px-1 rounded",children:"ralph-loop"})," plugin is required to run loops. This plugin provides the ",r.jsx("code",{className:"bg-muted px-1 rounded",children:"/ralph-loop"})," command that enables autonomous iteration."]}),Qr.scope==="project"&&r.jsx("div",{className:"bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded p-3 mb-4",children:r.jsxs("p",{className:"text-sm text-yellow-800 dark:text-yellow-200",children:["Plugin is currently installed only for project: ",r.jsx("br",{}),r.jsx("code",{className:"text-xs",children:Qr.projectPath})]})}),r.jsx("p",{className:"text-sm",children:"Install the plugin globally (user scope) to use loops from any project?"})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:kr,disabled:Ht,children:"Cancel"}),r.jsx(re,{onClick:Rs,disabled:Ht,children:Ht?r.jsxs(r.Fragment,{children:[r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}),"Installing..."]}):r.jsxs(r.Fragment,{children:[r.jsx(fi,{className:"w-4 h-4 mr-1"}),"Install Plugin"]})})]})]})}),r.jsx(Aj,{open:cs,onOpenChange:te=>{Wt(te),te||(Wr(null),Sr())},title:yt?`Loop: ${yt.name}`:"Running Loop",description:yt?((un=(dn=yt.task)==null?void 0:dn.original)==null?void 0:un.substring(0,100))+(((wi=(hn=yt.task)==null?void 0:hn.original)==null?void 0:wi.length)>100?"...":""):"",cwd:yt==null?void 0:yt.projectPath,initialCommand:yt?to(yt).startCmd:"",delayedCommand:yt?to(yt).skillCmd:"",delayedCommandDelay:5e3,env:yt?{CODER_LOOP_ID:yt.id,...yt.workstreamId&&{CODER_WORKSTREAM:yt.workstreamId}}:{},onExit:$o,headerExtra:r.jsxs("label",{className:"flex items-center gap-2 text-sm cursor-pointer select-none",children:[r.jsx("input",{type:"checkbox",checked:xr,onChange:te=>Xn(te.target.checked),className:"rounded"}),"Auto-close when done"]})}),r.jsx(wt,{open:de,onOpenChange:fe,children:r.jsxs(gt,{className:"sm:max-w-2xl max-h-[80vh] overflow-y-auto",children:[r.jsx(xt,{children:r.jsxs(vt,{className:"flex items-center gap-2",children:[r.jsx(os,{className:"w-5 h-5 text-purple-500"}),"AI-Tuned Prompt"]})}),r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-2 text-muted-foreground",children:"Original Prompt"}),r.jsx("div",{className:"bg-muted p-3 rounded text-sm whitespace-pre-wrap max-h-32 overflow-y-auto",children:ce})]}),r.jsxs("div",{children:[r.jsxs("h4",{className:"text-sm font-medium mb-2 flex items-center gap-2",children:[r.jsx(qt,{className:"w-4 h-4 text-purple-500"}),"Tuned Prompt"]}),r.jsx(Ct,{value:X,onChange:te=>W(te.target.value),rows:10,className:"font-mono text-sm"}),r.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"You can edit the tuned prompt before accepting it."})]})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:Ue,children:"Keep Original"}),r.jsxs(re,{onClick:Ie,children:[r.jsx(Ft,{className:"w-4 h-4 mr-1"}),"Use Tuned Prompt"]})]})]})}),r.jsx(wt,{open:Ce,onOpenChange:$e,children:r.jsxs(gt,{className:"sm:max-w-md",children:[r.jsx(xt,{children:r.jsxs(vt,{className:"flex items-center gap-2",children:[r.jsx(Gd,{className:"w-5 h-5"}),"Resume Loop"]})}),r.jsx("div",{className:"py-4",children:Be&&r.jsxs(r.Fragment,{children:[r.jsxs("p",{className:"text-sm mb-4",children:["This loop ",Be.status==="failed"?"failed":Be.status==="cancelled"?"was cancelled":"was paused",Be.pauseReason&&`: ${Be.pauseReason}`]}),r.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:"Would you like to tune the prompt with AI before resuming? This can help add guardrails based on what went wrong."}),r.jsx("div",{className:"bg-muted p-3 rounded text-sm max-h-32 overflow-y-auto",children:(_i=Be.task)==null?void 0:_i.original})]})}),r.jsxs(jt,{className:"flex-col sm:flex-row gap-2",children:[r.jsx(re,{variant:"outline",onClick:()=>{$e(!1),ue(null)},children:"Cancel"}),r.jsx(re,{variant:"secondary",onClick:vr,children:"Resume As-Is"}),r.jsxs(re,{onClick:Et,disabled:$,children:[$?r.jsx(Qe,{className:"w-4 h-4 animate-spin mr-1"}):r.jsx(os,{className:"w-4 h-4 mr-1"}),"Tune & Resume"]})]})]})}),r.jsx(wt,{open:el,onOpenChange:gs,children:r.jsxs(gt,{className:"sm:max-w-md",children:[r.jsx(xt,{children:r.jsxs(vt,{className:"flex items-center gap-2",children:[(et==null?void 0:et.status)==="completed"&&r.jsxs(r.Fragment,{children:[r.jsx(No,{className:"w-5 h-5 text-green-600"})," Loop Completed"]}),(et==null?void 0:et.status)==="paused"&&r.jsxs(r.Fragment,{children:[r.jsx(xp,{className:"w-5 h-5 text-yellow-500"})," Loop Paused"]}),(et==null?void 0:et.status)==="failed"&&r.jsxs(r.Fragment,{children:[r.jsx(Ea,{className:"w-5 h-5 text-red-500"})," Loop Failed"]}),(et==null?void 0:et.status)==="cancelled"&&r.jsxs(r.Fragment,{children:[r.jsx(Ea,{className:"w-5 h-5 text-gray-500"})," Loop Cancelled"]})]})}),et&&r.jsxs("div",{className:"space-y-4 py-4",children:[r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-1",children:"Task"}),r.jsx("p",{className:"text-sm text-muted-foreground bg-muted p-2 rounded",children:et.task})]}),et.pauseReason&&r.jsxs("div",{children:[r.jsx("h4",{className:"text-sm font-medium mb-1",children:"Reason"}),r.jsx("p",{className:"text-sm text-muted-foreground bg-muted p-2 rounded",children:et.pauseReason})]}),r.jsxs("div",{className:"grid grid-cols-3 gap-3 text-sm",children:[r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Status"}),r.jsxs("div",{className:"font-medium flex items-center gap-1",children:[ba[et.status],r.jsx("span",{className:"capitalize",children:et.status})]})]}),r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Iterations"}),r.jsxs("div",{className:"font-medium",children:[et.iterations," / ",et.maxIterations]})]}),r.jsxs("div",{className:"border rounded p-3",children:[r.jsx("div",{className:"text-muted-foreground text-xs mb-1",children:"Duration"}),r.jsx("div",{className:"font-medium",children:et.duration!=null?et.duration<60?`${et.duration}s`:et.duration<3600?`${Math.floor(et.duration/60)}m ${et.duration%60}s`:`${Math.floor(et.duration/3600)}h ${Math.floor(et.duration%3600/60)}m`:"-"})]})]}),r.jsxs("div",{className:"text-xs text-muted-foreground",children:[et.status==="completed"?"Completed":"Stopped"," at ",En(et.completedAt)]})]}),r.jsxs(jt,{children:[r.jsx(re,{variant:"outline",onClick:()=>gs(!1),children:"Close"}),((et==null?void 0:et.status)==="paused"||(et==null?void 0:et.status)==="failed"||(et==null?void 0:et.status)==="cancelled")&&r.jsxs(re,{onClick:()=>{if(gs(!1),et!=null&&et.id){const te=t.find(Le=>Le.id===et.id);te&&Nt(te)}},children:[r.jsx(Gd,{className:"w-4 h-4 mr-1"}),(et==null?void 0:et.status)==="paused"?"Resume":"Restart"]}),r.jsx(re,{variant:"secondary",onClick:()=>{if(gs(!1),et!=null&&et.id){const te=t.find(Le=>Le.id===et.id);te&&sl(te)}},children:"View Details"})]})]})})]})}function tW(e,t=[]){let s=[];function n(d,u){const l=_.createContext(u);l.displayName=d+"Context";const c=s.length;s=[...s,u];const f=h=>{var v;const{scope:x,children:w,...j}=h,C=((v=x==null?void 0:x[e])==null?void 0:v[c])||l,y=_.useMemo(()=>j,Object.values(j));return r.jsx(C.Provider,{value:y,children:w})};f.displayName=d+"Provider";function m(h,x){var C;const w=((C=x==null?void 0:x[e])==null?void 0:C[c])||l,j=_.useContext(w);if(j)return j;if(u!==void 0)return u;throw new Error(`\`${h}\` must be used within \`${d}\``)}return[f,m]}const o=()=>{const d=s.map(u=>_.createContext(u));return function(l){const c=(l==null?void 0:l[e])||d;return _.useMemo(()=>({[`__scope${e}`]:{...l,[e]:c}}),[l,c])}};return o.scopeName=e,[n,rW(o,...t)]}function rW(...e){const t=e[0];if(e.length===1)return t;const s=()=>{const n=e.map(o=>({useScope:o(),scopeName:o.scopeName}));return function(d){const u=n.reduce((l,{useScope:c,scopeName:f})=>{const h=c(d)[`__scope${f}`];return{...l,...h}},{});return _.useMemo(()=>({[`__scope${t.scopeName}`]:u}),[u])}};return s.scopeName=t.scopeName,s}var sW=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],u2=sW.reduce((e,t)=>{const s=qu(`Primitive.${t}`),n=_.forwardRef((o,d)=>{const{asChild:u,...l}=o,c=u?s:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),r.jsx(c,{...l,ref:d})});return n.displayName=`Primitive.${t}`,{...e,[t]:n}},{}),Hx="Progress",Wx=100,[nW]=tW(Hx),[iW,oW]=nW(Hx),h2=_.forwardRef((e,t)=>{const{__scopeProgress:s,value:n=null,max:o,getValueLabel:d=aW,...u}=e;(o||o===0)&&!u_(o)&&console.error(lW(`${o}`,"Progress"));const l=u_(o)?o:Wx;n!==null&&!h_(n,l)&&console.error(cW(`${n}`,"Progress"));const c=h_(n,l)?n:null,f=Fu(c)?d(c,l):void 0;return r.jsx(iW,{scope:s,value:c,max:l,children:r.jsx(u2.div,{"aria-valuemax":l,"aria-valuemin":0,"aria-valuenow":Fu(c)?c:void 0,"aria-valuetext":f,role:"progressbar","data-state":p2(c,l),"data-value":c??void 0,"data-max":l,...u,ref:t})})});h2.displayName=Hx;var f2="ProgressIndicator",m2=_.forwardRef((e,t)=>{const{__scopeProgress:s,...n}=e,o=oW(f2,s);return r.jsx(u2.div,{"data-state":p2(o.value,o.max),"data-value":o.value??void 0,"data-max":o.max,...n,ref:t})});m2.displayName=f2;function aW(e,t){return`${Math.round(e/t*100)}%`}function p2(e,t){return e==null?"indeterminate":e===t?"complete":"loading"}function Fu(e){return typeof e=="number"}function u_(e){return Fu(e)&&!isNaN(e)&&e>0}function h_(e,t){return Fu(e)&&!isNaN(e)&&e<=t&&e>=0}function lW(e,t){return`Invalid prop \`max\` of value \`${e}\` supplied to \`${t}\`. Only numbers greater than 0 are valid max values. Defaulting to \`${Wx}\`.`}function cW(e,t){return`Invalid prop \`value\` of value \`${e}\` supplied to \`${t}\`. The \`value\` prop must be:
|
|
3007
3007
|
- a positive number
|
|
3008
3008
|
- less than the value passed to \`max\` (or ${Wx} if no \`max\` prop is set)
|
|
3009
3009
|
- \`null\` or \`undefined\` if the progress is indeterminate.
|
package/ui/dist/index.html
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
<!-- PWA Manifest -->
|
|
21
21
|
<link rel="manifest" href="/manifest.json">
|
|
22
|
-
<script type="module" crossorigin src="/assets/index-
|
|
22
|
+
<script type="module" crossorigin src="/assets/index-CZMA0Sz_.js"></script>
|
|
23
23
|
<link rel="stylesheet" crossorigin href="/assets/index-ChBU02w_.css">
|
|
24
24
|
</head>
|
|
25
25
|
<body>
|
package/ui/terminal-server.cjs
CHANGED
|
@@ -86,11 +86,43 @@ class TerminalServer {
|
|
|
86
86
|
setTimeout(() => {
|
|
87
87
|
ptyProcess.write(cmd + '\r');
|
|
88
88
|
|
|
89
|
-
// If delayed command provided, send it
|
|
90
|
-
//
|
|
89
|
+
// If delayed command provided, send it when claude is ready
|
|
90
|
+
// Watch for claude's ready indicator in output
|
|
91
91
|
if (delayedCmd) {
|
|
92
|
+
let delayedCmdSent = false;
|
|
93
|
+
let outputBuffer = '';
|
|
94
|
+
|
|
95
|
+
const checkReady = (data) => {
|
|
96
|
+
if (delayedCmdSent) return;
|
|
97
|
+
outputBuffer += data;
|
|
98
|
+
|
|
99
|
+
// Claude shows various ready indicators:
|
|
100
|
+
// - ">" prompt character
|
|
101
|
+
// - "Claude" in output after startup
|
|
102
|
+
// - Input area becomes active
|
|
103
|
+
// Look for the prompt or "Claude" appearing after some output
|
|
104
|
+
if (outputBuffer.length > 100 &&
|
|
105
|
+
(outputBuffer.includes('>') ||
|
|
106
|
+
outputBuffer.includes('Claude') ||
|
|
107
|
+
outputBuffer.includes('?') ||
|
|
108
|
+
outputBuffer.includes('│'))) {
|
|
109
|
+
delayedCmdSent = true;
|
|
110
|
+
// Small delay after detecting ready state
|
|
111
|
+
setTimeout(() => {
|
|
112
|
+
ptyProcess.write(delayedCmd + '\r');
|
|
113
|
+
}, 300);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// Listen for output to detect readiness
|
|
118
|
+
ptyProcess.onData(checkReady);
|
|
119
|
+
|
|
120
|
+
// Fallback timeout in case detection fails
|
|
92
121
|
setTimeout(() => {
|
|
93
|
-
|
|
122
|
+
if (!delayedCmdSent) {
|
|
123
|
+
delayedCmdSent = true;
|
|
124
|
+
ptyProcess.write(delayedCmd + '\r');
|
|
125
|
+
}
|
|
94
126
|
}, delayedCmdDelay);
|
|
95
127
|
}
|
|
96
128
|
}, 500);
|