@wular/coder 0.3.4 → 0.3.6
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/dist/cli.js +13 -13
- package/dist/flow/index.js +1 -1
- package/dist/runtime-BMO6NYyh.js +16 -0
- package/dist/sdk.js +1 -1
- package/dist/{upgrade-Dgk4Gl4g.js → upgrade-Bu0uWk5Y.js} +1 -1
- package/docs/config.md +15 -0
- package/package.json +1 -1
- package/plugins/agents/skills/coder/SKILL.md +3 -2
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/skills/dispatch/SKILL.md +3 -2
- package/plugins/cursor/.cursor-plugin/plugin.json +1 -1
- package/plugins/cursor/skills/coder/SKILL.md +3 -2
- package/dist/runtime-DVrs6VXX.js +0 -16
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{B as e,E as t,H as n,I as r,L as i,M as a,N as o,O as s,R as c,V as l,_ as u,b as d,c as f,d as p,f as m,j as h,l as g,m as _,o as v,s as y,u as b}from"./app-server-bHl6RBZ2.js";import{$t as x,A as ee,B as S,Bt as C,Ct as te,D as w,Et as ne,F as re,Ft as T,Gt as E,Ht as D,I as O,Kt as ie,L as ae,Lt as k,M as A,Mt as oe,N as se,Nt as ce,O as le,Qt as j,R as ue,S as de,St as fe,T as pe,Tt as me,Ut as he,Vt as ge,Wt as M,Xt as _e,Y as ve,Yt as ye,Zt as N,_ as be,_t as xe,a as Se,an as Ce,at as we,b as Te,bt as Ee,d as De,dt as Oe,en as ke,g as P,h as Ae,in as je,j as Me,kt as Ne,l as Pe,lt as Fe,n as Ie,nn as Le,on as Re,ot as
|
|
2
|
+
import{B as e,E as t,H as n,I as r,L as i,M as a,N as o,O as s,R as c,V as l,_ as u,b as d,c as f,d as p,f as m,j as h,l as g,m as _,o as v,s as y,u as b}from"./app-server-bHl6RBZ2.js";import{$t as x,A as ee,B as S,Bt as C,Ct as te,D as w,Et as ne,F as re,Ft as T,Gt as E,Ht as D,I as O,Kt as ie,L as ae,Lt as k,M as A,Mt as oe,N as se,Nt as ce,O as le,Qt as j,R as ue,S as de,St as fe,T as pe,Tt as me,Ut as he,Vt as ge,Wt as M,Xt as _e,Y as ve,Yt as ye,Zt as N,_ as be,_t as xe,a as Se,an as Ce,at as we,b as Te,bt as Ee,d as De,dt as Oe,en as ke,g as P,h as Ae,in as je,j as Me,kt as Ne,l as Pe,lt as Fe,n as Ie,nn as Le,on as Re,ot as F,p as ze,qt as Be,r as Ve,rn as I,s as He,sn as Ue,t as We,tn as L,tt as R,u as Ge,ut as Ke,v as z,w as qe,wt as Je,x as Ye,xt as Xe,y as Ze,yt as Qe,zt as B}from"./runtime-BMO6NYyh.js";import{C as $e,E as et,O as tt,a as nt,h as rt,k as it,p as at,r as ot,t as st,v as ct,w as lt,x as ut}from"./upgrade-Bu0uWk5Y.js";import V from"node:process";import H from"node:fs";import U from"node:path";import{spawn as dt,spawnSync as ft}from"node:child_process";import pt from"node:os";import*as W from"zod/mini";import mt from"node:readline";const ht=[[`--wait`,`run in the foreground and block until the answer is ready`],[`--agent <codex|claude|custom>`,`engine to use; custom runs your configured custom models (default: first in the chain)`],[`--model <alias|slug>`,`mini/luna/terra/sol (codex) · haiku/sonnet/opus/fable (claude) · a custom model (coder model list)`],[`--effort <low|medium|high>`,`reasoning effort`],[`--permissions <mode>`,`read-only · workspace-write · auto (default: auto)`],[`--resume <task-id>`,`continue that task's thread instead of a fresh run`],[`--json`,`machine-readable JSON output`]],G=[`--cwd <dir>`,`workspace directory (default: current)`],K=[`--json`,`JSON output`],gt=[{sub:`run`,usage:`run "<text>"`,blurb:`run a task (background; --wait blocks)`,alias:`run`},{sub:`list`,usage:`list`,blurb:`list recent tasks (running + just stopped)`,alias:`list`},{sub:`result`,usage:`result [task-id]`,blurb:`status + final answer (--wait blocks)`,alias:`result`},{sub:`watch`,usage:`watch [task-id]`,blurb:`watch a task live (progress log)`,alias:`watch`},{sub:`steer`,usage:`steer <task-id> "<follow-up>"`,blurb:`continue a task's thread`},{sub:`ask`,usage:`ask <task-id> "<question>"`,blurb:`ask about a task without interrupting it`},{sub:`stop`,usage:`stop <task-id>`,blurb:`interrupt a running task`},{sub:`archive`,usage:`archive <task-id>`,blurb:`archive a session (or --all-stopped)`},{sub:`delete`,usage:`delete <task-id>`,blurb:`delete a session (or --all-archived)`},{sub:`approvals`,usage:`approvals [task-id]`,blurb:`pending approvals (all tasks, or one)`},{sub:`approve`,usage:`approve <id>`,blurb:`answer an escalated permission`}],q={"task run":{list:[`task run "<text>"`,`run a coding task (background; --wait blocks)`],usage:`coder task run "<task text>"`,summary:`Dispatch a coding task to the configured engine. Backgrounds by default and
|
|
3
3
|
prints a task id; --wait runs in the foreground and prints the answer.
|
|
4
4
|
Shortcut: \`coder run "<text>"\`.`,flags:[[`--name <name>`,`label the task (shown in list/result)`],[`--system <text>`,`standing instructions prepended to the task (kept out of prompt previews)`],...ht,G],examples:[[`coder run "add a /health endpoint"`,`dispatch in the background, print a task id`],[`coder result <task-id> --wait`,`then block until it finishes and print the answer`],[`coder run --wait "fix the failing test"`,`or block on the run itself`],[`coder task run --model mini --system "tests live in test/, don't touch anything outside of it" "rename foo to bar"`,`pick an engine via its model alias; --system adds standing instructions`]],seeAlso:`task result · task steer · task stop · task watch`},"task list":{list:[`task list [--running|--stopped|--archived]`,`list recent tasks (running + just stopped)`],usage:`coder task list [--running] [--stopped] [--archived [--limit N]]`,summary:`List recent tasks across all workspaces, most recent first: running tasks plus
|
|
5
5
|
ones stopped within the last 10 minutes. Older stopped tasks auto-archive and
|
|
@@ -57,15 +57,15 @@ the host plugins to match. Alias: update.`,flags:[[`--cli-only`,`update just the
|
|
|
57
57
|
`)}\n`}function xt(e,t){return e.map(([e,n])=>` ${t.cyan(e.padEnd(30))}${t.dim(n)}`)}function Y(e){let t=q[e];if(!t)return null;let n=N,r=[n.bold(`Usage:`),` ${t.usage}`];if(t.summary&&r.push(``,t.summary),t.flags?.length&&r.push(``,n.bold(`Flags:`),...xt(t.flags,n)),t.examples?.length){r.push(``,n.bold(`Examples:`));for(let[e,i]of t.examples)r.push(` ${n.cyan(e)}`,` ${n.dim(i)}`)}return t.seeAlso&&r.push(``,n.dim(`Related: ${t.seeAlso}`)),`${r.join(`
|
|
58
58
|
`)}\n`}function X(){let e=N,t=gt.map(t=>{let n=t.alias?e.dim(` (coder ${t.alias})`):``;return` ${e.cyan(t.usage.padEnd(30))}${e.dim(t.blurb)}${n}`});return`${[e.bold(`Usage:`),` coder task <subcommand>`,``,e.bold(`Subcommands:`),...t,``,e.dim(`Run 'coder task <subcommand> --help' for details on any subcommand.`)].join(`
|
|
59
59
|
`)}\n`}function St(){let e=N,t=([t,n])=>` ${e.cyan(t.padEnd(41))}${e.dim(n)}`,n=gt.filter(e=>e.alias).map(e=>t([e.usage.replace(/^\S+/,e.alias),e.blurb]));return`${[`${e.bold(`Coder`)} ${e.dim(`v${_()}`)}`,`Delegate a coding task to the best available engine and steer it while it runs.`,``,e.bold(`Get started:`),` ${e.cyan(`coder setup-host claude`)} ${e.dim(`# or agents (Codex, Pi, ...); installs the host plugin/skill`)}`,` ${e.cyan(`coder run "explain this repo's layout"`)}`,``,e.dim("Agents: load the skill once with `coder docs skill [--claude]`."),``,e.bold(`Usage:`),` coder <command>`,``,e.bold(`Commands:`),...n,` ${e.cyan(`task <cmd>`.padEnd(41))}${e.dim(`more task commands (steer, stop, approve, ...): `)}${e.light(`coder task --help`)}`,` ${e.cyan(`flow <cmd>`.padEnd(41))}${e.dim(`orchestrate a wave of tasks: `)}${e.light(`coder flow --help`)}`,t(q.config.list),t([`model <list|add|alias|disable>`,`manage models: built-ins, aliases, custom endpoints`]),t(q.docs.list),t(q.upgrade.list),``,e.bold(`Global:`),t([`-h, --help`,`show help (top-level, or for a command)`]),t([`-v, --version`,`print the coder version`]),t([`--json`,`JSON output instead of human-readable text`]),t(G)].join(`
|
|
60
|
-
`)}\n`}function Z(e){let t=e.indexOf(`--`),n=t===-1?e:e.slice(0,t);return n.includes(`-h`)||n.includes(`--help`)}const Ct=`CODER_FLOW_ATTACH`;function wt(e){let t={};for(let n of e){let e=n.indexOf(`=`);e===-1&&C(`Invalid argument "${n}": expected key=value.`,{hint:`Help: coder flow run --help`});let r=n.slice(0,e),i=n.slice(e+1);try{t[r]=JSON.parse(i)}catch{t[r]=i}}return t}function Tt(e,t){if(e!==void 0)try{return JSON.parse(e)}catch(e){C(`Invalid --args JSON: ${e instanceof Error?e.message:String(e)}`)}return t.length?wt(t):{}}function Et(){try{return ft(`bun`,[`--version`],{stdio:`ignore`}).status===0}catch{return!1}}function Dt(e){if(!e.endsWith(`.ts`)||V.versions.bun||V.features.typescript)return;Et()||C(`This flow is a TypeScript file (${e}) and this Node cannot run TypeScript.`,{hint:[`Upgrade to Node 23.6+ or install bun: https://bun.sh`,`Or write the flow as .mjs / .js`]});let t=ft(`bun`,[m,...V.argv.slice(2)],{stdio:`inherit`});V.exit(t.status??1)}function Ot(e){V.once(`SIGINT`,()=>{(async()=>{let{runId:t}=e,n=H.existsSync(U.join(
|
|
61
|
-
`).filter(Boolean).flatMap(e=>{try{return[JSON.parse(e)]}catch{return[]}}):[]}function Pt(e,t=!1){let n=N;return`${Q(e.ok?`completed`:`failed`,t)} ${n.dim(`gate`)} ${n.light(e.cmd)}${e.ok?``:n.dim(` · exit ${e.code}`)}`}function Ft(e,t,n){let r=N,i=n!==void 0&&n>=1e3?r.dim(` · ${D(n)}`):``;return`${t} ${r.dim(`gate`)} ${r.light(e)}${i}`}function It(e,t=!1){return N.dim(`${`│ `.repeat(e)}${t?`└─`:`├─`}`)}function Lt(e){return N.dim(`${`│ `.repeat(e)}│ `)}function Rt(e){return`${` `.repeat(e.depth)}${e.log?`${
|
|
62
|
-
`))this.final(e.depth??0,t.light(n),!0);return;case`flow-start`:this.final(e.depth-1,t.bold(`flow ${e.name}`));return;case`replay`:this.final(0,t.dim(`replayed ${e.count} steps from journal`),!0)}}done(){this.spin(!1),this.flush(0),this.tty&&this.repaint(),this.region.done()}flush(e){this.pending&&=(this.region.commit(`${zt(this.pending,e<this.pending.depth,!this.tty)}\n`),this.hasCommitted=!0,void 0)}final(e,t,n=!1){if(!this.tty){this.region.commit(`${Rt({depth:e,body:t,log:n})}\n`),this.hasCommitted=!0;return}this.flush(e),this.pending={depth:e,body:t,log:n},this.tty&&this.repaint()}repaint(){let e=[],t=[];if(this.pending){let n=zt(this.pending,!1);e.push(n),t.push(n)}let n=this.timer?N.bold(N.cyan(kt[this.frame%kt.length])):Q(`running`);for(let[r,i]of this.active){let a=`${It(i.depth??0)} ${$(n,i.name,r,null,i.agent,!0)}`;(e.length||this.hasCommitted)&&e.push(Bt(i.depth??0)),e.push(a),t.push(a);let o=this.previews.get(r);o&&e.push(`${Lt(i.depth??0)} ${N.dim(o)}`)}for(let r of this.activeGates.values()){let i=`${It(r.depth)} ${Ft(r.cmd,n,Date.now()-r.startedAt)}`;(e.length||this.hasCommitted)&&e.push(Bt(r.depth)),e.push(i),t.push(i)}let r=(Re(this.stream)??1/0)-1,i=e.length<=r?e:t;if(i.length>r){let e=Math.max(0,r-1);i=[N.dim(`… +${i.length-e} more running`),...i.slice(-e)]}this.region.set(i)}refreshPreviews(){for(let e of this.active.keys())try{let t=a(V.cwd(),e,1)[0]?.message?.replace(/\s+/g,` `).trim();if(!t)continue;let n=(Ce(this.stream)??120)-8;this.previews.set(e,t.length>n?`${t.slice(0,n-1)}…`:t)}catch{}}idle(){!this.active.size&&!this.activeGates.size&&this.spin(!1)}spin(e){e&&!this.timer?this.timer=setInterval(()=>{this.frame++,this.frame%4==0&&this.refreshPreviews(),this.repaint()},120).unref():!e&&this.timer&&(clearInterval(this.timer),this.timer=void 0)}};function Ut(e){if(e.json)return{};let t=new Ht,n=e=>t.emit(e);return{onTaskStart:e=>n({kind:`task-start`,...e}),onTaskEnd:e=>n({kind:`task-end`,...e}),onGateStart:e=>n({kind:`gate-start`,...e}),onGate:e=>n({kind:`gate`,...e}),onLog:(e,t)=>n({kind:`log`,message:e,depth:t}),onFlowStart:e=>n({kind:`flow-start`,...e}),onReplay:e=>n({kind:`replay`,count:e})}}function Wt(e){let t=U.join(
|
|
63
|
-
[flow] dry-run ended early: a downstream step depends on real task output (stub it or run for real).`:``;C(`[flow] ${t} ${e.runId} failed: ${e.message}${r}`,{hint:`Resume${t===`resume`?` again`:``}: coder flow resume ${e.runId}`})}throw e}async function $t(e){let{options:t,positionals:n}=g(e,W.object(Jt)),[r,...i]=n;r||C(`Missing flow name or path.`,{hint:[`Usage: coder flow run <name|path>`,`List: coder flow discover`]});let a=
|
|
60
|
+
`)}\n`}function Z(e){let t=e.indexOf(`--`),n=t===-1?e:e.slice(0,t);return n.includes(`-h`)||n.includes(`--help`)}const Ct=`CODER_FLOW_ATTACH`;function wt(e){let t={};for(let n of e){let e=n.indexOf(`=`);e===-1&&C(`Invalid argument "${n}": expected key=value.`,{hint:`Help: coder flow run --help`});let r=n.slice(0,e),i=n.slice(e+1);try{t[r]=JSON.parse(i)}catch{t[r]=i}}return t}function Tt(e,t){if(e!==void 0)try{return JSON.parse(e)}catch(e){C(`Invalid --args JSON: ${e instanceof Error?e.message:String(e)}`)}return t.length?wt(t):{}}function Et(){try{return ft(`bun`,[`--version`],{stdio:`ignore`}).status===0}catch{return!1}}function Dt(e){if(!e.endsWith(`.ts`)||V.versions.bun||V.features.typescript)return;Et()||C(`This flow is a TypeScript file (${e}) and this Node cannot run TypeScript.`,{hint:[`Upgrade to Node 23.6+ or install bun: https://bun.sh`,`Or write the flow as .mjs / .js`]});let t=ft(`bun`,[m,...V.argv.slice(2)],{stdio:`inherit`});V.exit(t.status??1)}function Ot(e){V.once(`SIGINT`,()=>{(async()=>{let{runId:t}=e,n=H.existsSync(U.join(z(t),We));if(V.stderr.write(`\n[flow] stopping run ${t} — no new tasks will dispatch.\n`),n){let t=e.runningIds();t.length&&V.stderr.write(`[flow] left running: ${t.join(`, `)}\n`)}else{let n=await Te(t,e.runningIds());n.length&&V.stderr.write(`[flow] stopped tasks: ${n.join(`, `)}\n`)}V.stderr.write(`[flow] resume with: coder flow resume ${t}\n`),e.requestStop(),V.exit(130)})()})}const kt=[`⣾`,`⣽`,`⣻`,`⢿`,`⡿`,`⣟`,`⣯`,`⣷`];function Q(e,t=!1){let n=N;return t?B(`[${jt(e)}]`,10):e===`completed`?n.bold(n.green(`✔`)):e===`failed`||e===`cancelled`||e===`stopped`?n.bold(n.red(`✘`)):e===`running`?n.bold(n.cyan(`●`)):n.dim(`○`)}function At(){return B(`[start]`,10)}function jt(e){return e===`completed`?`done`:e===`cancelled`?`failed`:e}function Mt(e,t){return e??t.replace(/\s+/g,` `).trim().slice(0,60)}function $(e,t,n,r,i,a){let o=N,s=B(t??n,32);return[`${e} ${a?o.bold(s):s}`,o.dim(B(n,24)),o.light(B(i??``,20)),r?o.light(`${ie(r.total)} tok`):``].join(` `).trimEnd()}function Nt(e){let t=U.join(z(e),`events.jsonl`);return H.existsSync(t)?H.readFileSync(t,`utf8`).split(`
|
|
61
|
+
`).filter(Boolean).flatMap(e=>{try{return[JSON.parse(e)]}catch{return[]}}):[]}function Pt(e,t=!1){let n=N;return`${Q(e.ok?`completed`:`failed`,t)} ${n.dim(`gate`)} ${n.light(e.cmd)}${e.ok?``:n.dim(` · exit ${e.code}`)}`}function Ft(e,t,n){let r=N,i=n!==void 0&&n>=1e3?r.dim(` · ${D(n)}`):``;return`${t} ${r.dim(`gate`)} ${r.light(e)}${i}`}function It(e,t=!1){return N.dim(`${`│ `.repeat(e)}${t?`└─`:`├─`}`)}function Lt(e){return N.dim(`${`│ `.repeat(e)}│ `)}function Rt(e){return`${` `.repeat(e.depth)}${e.log?`${B(`[log]`,10)} `:``}${e.body}`}function zt(e,t,n=!1){return n?Rt(e):`${e.log?Lt(e.depth):It(e.depth,t)} ${e.body}`}function Bt(e){return N.dim(`${`│ `.repeat(Math.max(0,e))}│`)}function Vt(e,t=!1){let n=N;if(t)return e.map(Rt);let r=(t,n)=>{for(let r=t+1;r<e.length;r+=1){let t=e[r].depth;if(t<n)return!1;if(t===n)return!0}return!1};return e.map((e,t)=>{let i=``;for(let n=0;n<e.depth;n+=1)i+=r(t,n)?`│ `:` `;return i+=e.log?`│ `:r(t,e.depth)?`├─`:`└─`,`${n.dim(i)} ${e.body}`})}var Ht=class{stream;names=new Map;active=new Map;activeGates=new Map;pending;previews=new Map;frame=0;hasCommitted=!1;timer;tty;region;constructor(e=V.stdout){this.stream=e,this.tty=!!e.isTTY,this.region=new T(e)}emit(e){let t=N;switch(e.kind){case`task-start`:{let t={name:Mt(e.name,e.prompt),agent:e.agent,depth:e.depth??0};if(this.names.set(e.taskId,t),!this.tty){this.final(t.depth,$(At(),t.name,e.taskId,null,t.agent));return}this.active.set(e.taskId,t),this.spin(!0),this.repaint();return}case`task-end`:{this.active.delete(e.taskId),this.previews.delete(e.taskId),this.idle();let t=this.names.get(e.taskId);this.final(t?.depth??0,$(Q(e.status,!this.tty),t?.name??null,e.taskId,e.tokens,t?.agent));return}case`gate-start`:{let t={cmd:e.cmd,depth:e.depth??0,startedAt:Date.now()};if(!this.tty){this.final(t.depth,Ft(t.cmd,At()));return}this.activeGates.set(e.gateId,t),this.spin(!0),this.repaint();return}case`gate`:e.gateId&&this.activeGates.delete(e.gateId),this.idle(),this.final(e.depth??0,Pt(e,!this.tty));return;case`log`:for(let n of e.message.split(`
|
|
62
|
+
`))this.final(e.depth??0,t.light(n),!0);return;case`flow-start`:this.final(e.depth-1,t.bold(`flow ${e.name}`));return;case`replay`:this.final(0,t.dim(`replayed ${e.count} steps from journal`),!0)}}done(){this.spin(!1),this.flush(0),this.tty&&this.repaint(),this.region.done()}flush(e){this.pending&&=(this.region.commit(`${zt(this.pending,e<this.pending.depth,!this.tty)}\n`),this.hasCommitted=!0,void 0)}final(e,t,n=!1){if(!this.tty){this.region.commit(`${Rt({depth:e,body:t,log:n})}\n`),this.hasCommitted=!0;return}this.flush(e),this.pending={depth:e,body:t,log:n},this.tty&&this.repaint()}repaint(){let e=[],t=[];if(this.pending){let n=zt(this.pending,!1);e.push(n),t.push(n)}let n=this.timer?N.bold(N.cyan(kt[this.frame%kt.length])):Q(`running`);for(let[r,i]of this.active){let a=`${It(i.depth??0)} ${$(n,i.name,r,null,i.agent,!0)}`;(e.length||this.hasCommitted)&&e.push(Bt(i.depth??0)),e.push(a),t.push(a);let o=this.previews.get(r);o&&e.push(`${Lt(i.depth??0)} ${N.dim(o)}`)}for(let r of this.activeGates.values()){let i=`${It(r.depth)} ${Ft(r.cmd,n,Date.now()-r.startedAt)}`;(e.length||this.hasCommitted)&&e.push(Bt(r.depth)),e.push(i),t.push(i)}let r=(Re(this.stream)??1/0)-1,i=e.length<=r?e:t;if(i.length>r){let e=Math.max(0,r-1);i=[N.dim(`… +${i.length-e} more running`),...i.slice(-e)]}this.region.set(i)}refreshPreviews(){for(let e of this.active.keys())try{let t=a(V.cwd(),e,1)[0]?.message?.replace(/\s+/g,` `).trim();if(!t)continue;let n=(Ce(this.stream)??120)-8;this.previews.set(e,t.length>n?`${t.slice(0,n-1)}…`:t)}catch{}}idle(){!this.active.size&&!this.activeGates.size&&this.spin(!1)}spin(e){e&&!this.timer?this.timer=setInterval(()=>{this.frame++,this.frame%4==0&&this.refreshPreviews(),this.repaint()},120).unref():!e&&this.timer&&(clearInterval(this.timer),this.timer=void 0)}};function Ut(e){if(e.json)return{};let t=new Ht,n=e=>t.emit(e);return{onTaskStart:e=>n({kind:`task-start`,...e}),onTaskEnd:e=>n({kind:`task-end`,...e}),onGateStart:e=>n({kind:`gate-start`,...e}),onGate:e=>n({kind:`gate`,...e}),onLog:(e,t)=>n({kind:`log`,message:e,depth:t}),onFlowStart:e=>n({kind:`flow-start`,...e}),onReplay:e=>n({kind:`replay`,count:e})}}function Wt(e){let t=U.join(z(e),`events.jsonl`),n=e=>{try{H.appendFileSync(t,`${JSON.stringify(e)}\n`,`utf8`)}catch{}};return{onStart:e=>Ot(e),onTaskStart:e=>n({kind:`task-start`,...e}),onTaskEnd:e=>n({kind:`task-end`,...e}),onGateStart:e=>n({kind:`gate-start`,...e}),onGate:e=>n({kind:`gate`,...e}),onLog:(e,t)=>n({kind:`log`,message:e,depth:t}),onFlowStart:e=>n({kind:`flow-start`,...e}),onReplay:e=>n({kind:`replay`,count:e})}}async function Gt(e,t){try{await be(e,t,Wt(e)),V.exit(0)}catch(t){ze(e,t instanceof Error?t.message:String(t)),V.exit(1)}}function Kt(e,t){let n=z(e.runId);H.writeFileSync(U.join(n,`events.jsonl`),``,`utf8`);let r=H.openSync(U.join(n,`flow.log`),`a`),i=dt(V.execPath,[m,...V.argv.slice(2)],{detached:!0,stdio:[`ignore`,r,r],env:{...V.env,[Ct]:e.runId}});return i.unref(),H.closeSync(r),t.wait?i.pid:t.json?(x({runId:e.runId,status:`running`}),i.pid):(V.stdout.write(`${N.dim(`[flow]`)} run ${N.cyan(e.runId)} started in the background (running).\n`),V.stdout.write(`\n${M([`Result: coder flow result ${e.runId}`,`Runs: coder flow list`],N)}\n`),i.pid)}async function qt(e,t,n){let r=!!(t.stream&&t.json);!t.json&&(P(e)?.status??`running`)===`running`&&V.stderr.write(`${N.dim(`[flow]`)} run ${N.cyan(e)} started (running); waiting for it to finish — Ctrl-C to detach (it keeps running).\n\n`);let i=t.json?()=>{}:_e(),a=()=>{i(),r||(V.stderr.write(`\n${N.dim(`[flow] detached — run still going.`)}\n`),V.stderr.write(`\n${M([`Result: coder flow result ${e}`,`Stop it: coder flow stop ${e}`],N)}\n`)),V.exit(130)};V.on(`SIGINT`,a);let o=new Ht;for await(let i of de(e,n,{tail:t.tail}))r?V.stdout.write(`${JSON.stringify(i)}\n`):t.json||o.emit(i);o.done(),i(),V.off(`SIGINT`,a);let s=P(e);s||C(`[flow] run ${e} vanished while following.`,{hint:`Recent runs: coder flow list`}),r&&(V.stdout.write(`${JSON.stringify(rn(s))}\n`),V.exit(s.status===`completed`?0:1)),s.status===`completed`&&(Zt({runId:e,name:s.name,status:`completed`,result:s.result,tokens:s.ledger,taskCount:s.taskCount},t.json),V.exit(0)),s.status===`stopped`&&(t.json?x({runId:e,name:s.name,status:`stopped`,taskCount:s.taskCount}):V.stdout.write(`\n${N.dim(`[flow] run ${e} stopped — resume: coder flow resume ${e}`)}\n`),V.exit(1)),V.stdout.write(`\n${N.red(`error:`)} ${s.error??`unknown error`}\n`),V.stdout.write(`\n${M([`Resume: coder flow resume ${e}`],N)}\n`),V.exit(1)}const Jt={cwd:b,json:y,args:b,wait:y,concurrency:b,"max-tasks":b,"dry-run":y},Yt=e=>e?Number(e):void 0;async function Xt(e,t,n){let r=V.env[Ct];if(r&&(delete V.env[Ct],await Gt(r,t)),e[`dry-run`])return!1;let i=n(),a=Kt(i,e);return e.wait&&await qt(i.runId,e,a),!0}function Zt(e,t){if(t){x(e);return}let n=!V.stdout.isTTY,r=n?``:`${N.dim(`└─`)} `;V.stdout.write(`${r}${Q(`completed`,n)} run ${N.cyan(e.runId)} completed ${N.dim(`(${e.taskCount} tasks)`)}\n`),V.stdout.write(`\n${E(e.result)}\n`),en(e.tokens)}function Qt(e,t,n){if(e instanceof A&&e.code===`flow-failed`){let r=n?`
|
|
63
|
+
[flow] dry-run ended early: a downstream step depends on real task output (stub it or run for real).`:``;C(`[flow] ${t} ${e.runId} failed: ${e.message}${r}`,{hint:`Resume${t===`resume`?` again`:``}: coder flow resume ${e.runId}`})}throw e}async function $t(e){let{options:t,positionals:n}=g(e,W.object(Jt)),[r,...i]=n;r||C(`Missing flow name or path.`,{hint:[`Usage: coder flow run <name|path>`,`List: coder flow discover`]});let a=I(t);Dt(Me(r,a).path);let o={args:Tt(t.args,i),cwd:a,dryRun:t[`dry-run`],concurrency:Yt(t.concurrency),maxTasks:Yt(t[`max-tasks`])};if(!await Xt(t,o,()=>Ae(r,o)))try{Zt(await Ze(r,o,Ut(t)),t.json)}catch(e){Qt(e,`run`,o.dryRun)}}function en(e){let t=Object.keys(e);if(t.length){V.stdout.write(`\n${N.bold(`Tokens:`)}\n`);for(let n of t)V.stdout.write(` ${N.dim(Be(e[n],n))}\n`)}}async function tn(e){let{options:t,positionals:n}=g(e,W.object({cwd:b,json:y,archived:y,limit:f}));L(n,0,`flow list`);let r=t.limit===`all`?void 0:t.limit,{runs:i,clipped:a}=Ve({archived:t.archived,limit:r});if(t.json){x(i);return}if(!i.length){V.stdout.write(t.archived?`No archived flow runs.
|
|
64
64
|
`:`No recent flow runs.
|
|
65
|
-
`),V.stdout.write(`\n${M([`Run one: coder flow run <name>`,`Runnable flows: coder flow discover`],N)}\n`);return}let o=N,s=(e,t,n)=>Math.min(t,Math.max(e,...n.map(e=>e.length))),c={id:s(6,28,i.map(e=>e.runId)),name:s(4,30,i.map(e=>e.name))};V.stdout.write(o.bold(o.light(`${`run-id`.padEnd(c.id)} ${`name`.padEnd(c.name)} ${`status`.padEnd(10)} ${`tasks`.padEnd(9)} ${`tokens`.padEnd(10)} age\n`)));for(let e of i){let t=Object.values(e.ledger).reduce((e,t)=>e+t.total,0);V.stdout.write(`${o.cyan(
|
|
66
|
-
`),V.stdout.write(`\n${M([`Authoring guide: coder docs flows`],N)}\n`);return}let a=N;V.stdout.write(a.bold(a.light(`${`name`.padEnd(24)} ${`scope`.padEnd(10)} path\n`)));for(let e of i){let t=e.scope===`workspace`?U.relative(r,e.path)||e.path:e.path.replace(pt.homedir(),`~`);V.stdout.write(`${a.cyan(e.name.padEnd(24))} ${a.light(e.scope.padEnd(10))} ${a.light(t)}\n`)}V.stdout.write(`\n${M([`Run one: coder flow run <name>`,`Recent runs: coder flow list`],a)}\n`)}function rn(e){let t=
|
|
67
|
-
`))l.push({depth:e.depth??0,body:i.light(t),log:!0});else e.kind===`flow-start`&&l.push({depth:e.depth-1,body:i.bold(`flow ${e.name}`)});for(let[e,t]of s)l.push({depth:t.depth??0,body:$(Q(`running`,a),t.name,e,null,t.agent)+(a?``:` ${i.light(`running`)}`)});for(let e of c.values())l.push({depth:e.depth,body:Ft(e.cmd,Q(`running`,a))+(a?``:` ${i.light(`running`)}`)});if(!l.length)for(let t of r===`all`?o:
|
|
68
|
-
`)}\n`)}e.endedAt&&e.result!==void 0&&V.stdout.write(`\n${i.bold(`Result:`)}\n${E(e.result)}\n`),e.error&&V.stdout.write(`\n${i.red(`error:`)} ${e.error}\n`),en(e.ledger);let l=e.status===`running`?[`Follow live: coder flow watch ${e.runId}`,`Stop it: coder flow stop ${e.runId}`]:e.status===`stopped`||e.status===`failed`?[`Resume: coder flow resume ${e.runId}`]:[];l.length&&V.stdout.write(`\n${M(l,i)}\n`)}async function on(e){let{options:t,positionals:n}=g(e,W.object({cwd:b,json:y,tail:p})),r=n[0]?P(n[0]):Pe();if(!r){if(t.json){x(null);return}C(n[0]?`No flow run "${n[0]}".`:`No flow runs yet.`,{hint:`Run one: coder flow run <name>`})}an(r,!!t.json,t.tail)}async function sn(e){let{options:t,positionals:n}=g(e,W.object({cwd:b,json:y,tail:p})),r=n[0]?P(n[0]):Pe();r||C(n[0]?`No flow run "${n[0]}".`:`No flow runs yet.`,{hint:`Run one: coder flow run <name>`}),await qt(r.runId,{json:t.json,stream:!0,tail:t.tail})}async function cn(e){let{options:t,positionals:n}=g(e,W.object({cwd:b,json:y,"keep-tasks":y}));
|
|
65
|
+
`),V.stdout.write(`\n${M([`Run one: coder flow run <name>`,`Runnable flows: coder flow discover`],N)}\n`);return}let o=N,s=(e,t,n)=>Math.min(t,Math.max(e,...n.map(e=>e.length))),c={id:s(6,28,i.map(e=>e.runId)),name:s(4,30,i.map(e=>e.name))};V.stdout.write(o.bold(o.light(`${`run-id`.padEnd(c.id)} ${`name`.padEnd(c.name)} ${`status`.padEnd(10)} ${`tasks`.padEnd(9)} ${`tokens`.padEnd(10)} age\n`)));for(let e of i){let t=Object.values(e.ledger).reduce((e,t)=>e+t.total,0);V.stdout.write(`${o.cyan(B(e.runId,c.id))} ${B(e.name,c.name)} ${j(e.status,10)} ${o.light(B(`${e.taskCount} tasks`,9))} ${o.light(B(t?`${ie(t)} tok`:`-`,10))} ${o.light(D(k(e.startedAt)))}\n`)}a&&V.stdout.write(o.dim(`\n... ${a} more not shown (--limit ${r})\n`)),V.stdout.write(`\n${M([`Result: coder flow result <run-id>`,`Tasks: coder list`,`Runnable flows: coder flow discover`],o)}\n`)}async function nn(e){let{options:t,positionals:n}=g(e,W.object({cwd:b,json:y}));L(n,0,`flow discover`);let r=I(t),i=ee(r);if(t.json){x(i);return}if(!i.length){V.stdout.write(`No flows found in .coder/flows/ (workspace) or ~/.coder/flows/ (global).
|
|
66
|
+
`),V.stdout.write(`\n${M([`Authoring guide: coder docs flows`],N)}\n`);return}let a=N;V.stdout.write(a.bold(a.light(`${`name`.padEnd(24)} ${`scope`.padEnd(10)} path\n`)));for(let e of i){let t=e.scope===`workspace`?U.relative(r,e.path)||e.path:e.path.replace(pt.homedir(),`~`);V.stdout.write(`${a.cyan(e.name.padEnd(24))} ${a.light(e.scope.padEnd(10))} ${a.light(t)}\n`)}V.stdout.write(`\n${M([`Run one: coder flow run <name>`,`Recent runs: coder flow list`],a)}\n`)}function rn(e){let t=qe(`${z(e.runId)}/journal.jsonl`);return{...e,journal:t.map(e=>({kind:e.kind,taskId:e.taskId,tokens:e.tokens}))}}function an(e,t,r=`all`){if(t){x(rn(e));return}let i=N,a=!V.stdout.isTTY;V.stdout.write(`${i.bold(`Flow`)} ${i.cyan(e.name)} ${i.dim(`(${e.runId})`)} — ${i.bold(j(e.status))}\n`);let o=He(e.runId),s=o.filter(e=>n.includes(e.status)).length,c=e.status===`running`?`${s}/${o.length} tasks`:`${e.taskCount} tasks`;if(V.stdout.write(`${i.dim(`started ${e.startedAt}${e.endedAt?` · ended ${e.endedAt}`:``} · ${c}`)}\n`),r!==0){let t=Nt(e.runId),n=new Map,s=new Map,c=new Map,l=[];for(let e of t)if(e.kind===`task-start`){let t={name:Mt(e.name,e.prompt),agent:e.agent,depth:e.depth??0};n.set(e.taskId,t),s.set(e.taskId,t)}else if(e.kind===`task-end`){s.delete(e.taskId);let t=n.get(e.taskId);l.push({depth:t?.depth??0,body:$(Q(e.status,a),t?.name??null,e.taskId,e.tokens,t?.agent)})}else if(e.kind===`gate-start`)c.set(e.gateId,{cmd:e.cmd,depth:e.depth??0});else if(e.kind===`gate`)e.gateId&&c.delete(e.gateId),l.push({depth:e.depth??0,body:Pt(e,a)});else if(e.kind===`log`)for(let t of e.message.split(`
|
|
67
|
+
`))l.push({depth:e.depth??0,body:i.light(t),log:!0});else e.kind===`flow-start`&&l.push({depth:e.depth-1,body:i.bold(`flow ${e.name}`)});for(let[e,t]of s)l.push({depth:t.depth??0,body:$(Q(`running`,a),t.name,e,null,t.agent)+(a?``:` ${i.light(`running`)}`)});for(let e of c.values())l.push({depth:e.depth,body:Ft(e.cmd,Q(`running`,a))+(a?``:` ${i.light(`running`)}`)});if(!l.length)for(let t of r===`all`?o:He(e.runId,r))l.push({depth:0,body:$(Q(t.status,a),t.name,t.taskId??`-`,t.tokens)});let u=Vt(l,a),d=r===`all`?u:u.slice(-r);d.length&&V.stdout.write(`\n${d.join(`
|
|
68
|
+
`)}\n`)}e.endedAt&&e.result!==void 0&&V.stdout.write(`\n${i.bold(`Result:`)}\n${E(e.result)}\n`),e.error&&V.stdout.write(`\n${i.red(`error:`)} ${e.error}\n`),en(e.ledger);let l=e.status===`running`?[`Follow live: coder flow watch ${e.runId}`,`Stop it: coder flow stop ${e.runId}`]:e.status===`stopped`||e.status===`failed`?[`Resume: coder flow resume ${e.runId}`]:[];l.length&&V.stdout.write(`\n${M(l,i)}\n`)}async function on(e){let{options:t,positionals:n}=g(e,W.object({cwd:b,json:y,tail:p})),r=n[0]?P(n[0]):Pe();if(!r){if(t.json){x(null);return}C(n[0]?`No flow run "${n[0]}".`:`No flow runs yet.`,{hint:`Run one: coder flow run <name>`})}an(r,!!t.json,t.tail)}async function sn(e){let{options:t,positionals:n}=g(e,W.object({cwd:b,json:y,tail:p})),r=n[0]?P(n[0]):Pe();r||C(n[0]?`No flow run "${n[0]}".`:`No flow runs yet.`,{hint:`Run one: coder flow run <name>`}),await qt(r.runId,{json:t.json,stream:!0,tail:t.tail})}async function cn(e){let{options:t,positionals:n}=g(e,W.object({cwd:b,json:y,"keep-tasks":y}));L(n,1,`flow stop`);try{let e=await Ye(n[0],{keepTasks:t[`keep-tasks`]});if(t.json){x(e);return}let r=N;e.status===`failed`?V.stdout.write(`${r.dim(`[flow]`)} run ${r.cyan(e.runId)} orchestrator died — marked ${j(`failed`)}.\n`):V.stdout.write(`${r.dim(`[flow]`)} run ${r.cyan(e.runId)} ${j(e.status)}.\n`),e.stoppedTasks.length&&V.stdout.write(`${r.dim(`[flow]`)} stopped tasks: ${e.stoppedTasks.join(`, `)}\n`),e.keptTasks.length&&V.stdout.write(`${r.dim(`[flow]`)} left running: ${e.keptTasks.join(`, `)}\n`),V.stdout.write(`\n${M([`Resume: coder flow resume ${e.runId}`],r)}\n`)}catch(e){throw e instanceof A&&e.code===`flow-failed`&&C(e.message,e.hint?{hint:e.hint}:{}),e}}async function ln(e){let{options:t,positionals:n}=g(e,W.object(Jt)),r=n[0]?P(n[0]):Pe();r||C(n[0]?`No flow run "${n[0]}".`:`No flow runs to resume.`,{hint:`Run one: coder flow run <name>`}),Dt(r.script);let i={cwd:I(t),dryRun:t[`dry-run`],concurrency:Yt(t.concurrency),maxTasks:Yt(t[`max-tasks`]),...t.args===void 0?{}:{args:Tt(t.args,[])}};if(!await Xt(t,i,()=>Ae(``,i,r.runId)))try{Zt(await be(r.runId,i,Ut(t)),t.json)}catch(e){Qt(e,`resume`,i.dryRun)}}function un(e){let t=P(e);return t||C(`No flow run "${e}".`,{hint:`Recent runs: coder flow list`}),(t.status===`running`||t.status===`queued`)&&C(`Run ${t.runId} is still running.`,{hint:`Stop it first: coder flow stop ${t.runId}`}),t}async function dn(e){let{options:t,positionals:n}=g(e,W.object({cwd:b,json:y,"all-stopped":y}));if(L(n,1,`flow archive`),t[`all-stopped`]){let e=De().filter(e=>e.status!==`running`&&e.status!==`queued`);for(let t of e)Ie(t);let n=e.map(e=>e.runId);if(t.json){x({archived:n,count:n.length});return}V.stdout.write(n.length?`Archived ${n.length} stopped run${n.length===1?``:`s`}.\n`:`${N.dim(`No stopped runs to archive.`)}\n`);return}let r=n[0];r||C(`Missing run id.`,{hint:[`Archive one: coder flow archive <run-id>`,`Archive all stopped: coder flow archive --all-stopped`]});let i=un(r);if(Ie(i),t.json){x({runId:i.runId,archived:!0});return}V.stdout.write(`Archived run ${N.cyan(i.runId)}.\n`)}async function fn(e){let{options:t,positionals:n}=g(e,W.object({cwd:b,json:y,"all-archived":y}));if(L(n,1,`flow delete`),t[`all-archived`]){let e=Ge().filter(e=>Se(e.runId)).map(e=>e.runId);if(t.json){x({deleted:e,count:e.length});return}V.stdout.write(e.length?`Deleted ${e.length} archived run${e.length===1?``:`s`}.\n`:`${N.dim(`No archived runs to delete.`)}\n`);return}let r=n[0];r||C(`Missing run id.`,{hint:[`Delete one: coder flow delete <run-id>`,`Delete all archived: coder flow delete --all-archived`]});let i=un(r);if(Se(i.runId),t.json){x({runId:i.runId,deleted:!0});return}V.stdout.write(`Deleted run ${N.cyan(i.runId)}.\n`)}const pn={run:$t,list:tn,discover:nn,result:on,watch:sn,stream:sn,stop:cn,resume:ln,archive:dn,delete:fn};async function mn(e){let[t,...n]=e;if(t===void 0||t===`help`||t===`-h`||t===`--help`){V.stdout.write(J());return}let r=pn[t];if(r||(V.stdout.write(J()),V.stdout.write(`
|
|
69
69
|
`),C(`Unknown flow subcommand "${t}".`,{hint:`Run a flow: coder flow run <name>`})),Z(n)){let e=t===`stream`?`watch`:t;V.stdout.write(Y(`flow ${e}`)??J());return}await r(n)}function hn(e){return e.resumeThreadId?e.currentPrompt??e.prompt??``:`<system>
|
|
70
70
|
You are running inside a coder task: do the work yourself, directly.
|
|
71
71
|
Do not load the coder skill (recursive), and never dispatch through the \`coder\` CLI - nested dispatch is disabled.
|
|
@@ -73,8 +73,8 @@ When finished, provide a concise implementation result summary.
|
|
|
73
73
|
Your turn is one-shot: background processes will not re-invoke you after it ends, so verify synchronously before finishing.${e.system?`\n-------\n${e.system}`:``}
|
|
74
74
|
</system>
|
|
75
75
|
|
|
76
|
-
${e.prompt??``}`}function gn(e,t){let n=0;return()=>{Date.now()-n>=1e4&&(n=Date.now(),c(e,t))}}function _n(e,t,{echo:n}){return r=>{let i=typeof r==`string`?{message:r}:r;u(e,t,i),n&&i.message&&V.stderr.write(`[coder] ${i.message}\n`)}}async function vn(t,n,{echo:a}){let o=i(t),s=r(t,n.id),c=
|
|
77
|
-
`);t.json||(V.stderr.write(`${N.dim(`[coder]`)} task ${N.cyan(e)} started (${n.status}); waiting for it to finish — Ctrl-C to detach (it keeps running).\n`),V.stderr.write(`${N.dim(s)}\n`));let c=()=>{V.stderr.write(`\n${N.dim(`[coder] detached — task still running: coder task result ${e}`)}\n`),V.exit(130)};V.on(`SIGINT`,c);let l;try{l=await S(r,e)}catch(n){throw V.off(`SIGINT`,c),n instanceof A&&n.code===`approval-pending`&&je(e,n.approval,t.json),n}V.off(`SIGINT`,c);let u=l.job,d=l.result,f=d?.error?.message??``;if(u.status===`failed`&&ae(u.permissions??`auto`,f)&&wn(f,t),u.status===`failed`&&se.test(f)){let e=
|
|
78
|
-
`);if(t.json){x({taskId:s,status:c.status,startupCheck:o.startupCheck,commands:{result:`coder task result ${s}`,steer:`coder task steer ${s} "<follow-up>"`,stop:`coder task stop ${s}`,watch:`coder task watch ${s}`}});return}V.stdout.write(`${N.dim(`[coder]`)} task ${N.cyan(s)} started in the background (${c.status}).\n`),V.stdout.write(`${N.dim(l)}\n`)}async function En(t){let{options:n,positionals:i}=g(t,W.object({cwd:b})),a=
|
|
79
|
-
`)}\n`),d?.touchedFiles?.length&&V.stderr.write(`[coder] touched files: ${d.touchedFiles.join(`, `)}\n`),te()}function On(e){return s(e).filter(e=>l.includes(e.status)).flatMap(t=>me(r(e,t.id)).filter(e=>!e.response).map(e=>({taskId:t.id,id:e.id,summary:String(e.summary??``),createdAt:e.createdAt?String(e.createdAt):void 0})))}async function kn(e){let{options:t,positionals:n}=g(e,W.object(v));
|
|
76
|
+
${e.prompt??``}`}function gn(e,t){let n=0;return()=>{Date.now()-n>=1e4&&(n=Date.now(),c(e,t))}}function _n(e,t,{echo:n}){return r=>{let i=typeof r==`string`?{message:r}:r;u(e,t,i),n&&i.message&&V.stderr.write(`[coder] ${i.message}\n`)}}async function vn(t,n,{echo:a}){let o=i(t),s=r(t,n.id),c=F(t),l=_n(t,n.id,{echo:a}),d=R[n.permissions??`auto`]??R.auto,f=d.approvalPolicy===`never`?void 0:Xe({workspaceRoot:o,jobDir:s,mode:d.approvalMode,escalationTimeoutMs:c.approvals.escalationTimeoutMs,allowedNetworkHosts:c.approvals.allowedNetworkHosts,onEvent:e=>{u(t,n.id,e),a&&e.message&&V.stderr.write(`[coder] ${e.message}\n`)}}),p=n.model?c.models?.[n.model]:void 0,m=p&&we(p)?p:void 0;if(m&&!m.wireApi&&n.model){let e=await tt(m);e&&(m={...m,...e},c.models[n.model]=m,Fe(t,n.model,e),u(t,n.id,{kind:`info`,message:`detected wire api for ${n.model}: ${e.wireApi} @ ${m.baseUrl}`}))}if(m?.envKey&&!V.env[m.envKey])throw Error(`Missing environment variable: \`${m.envKey}\`.`);let h=m?await it(m,m.wireApi??`chat`):null,g=Oe(c,n.model,h??void 0);try{let r=await xe(t,{prompt:hn(n),model:g?.model??Ke(n.model),modelProvider:g?.modelProvider??null,configOverrides:g?.configOverrides??null,effort:n.effort,sandbox:d.sandbox,approvalPolicy:d.approvalPolicy,onApprovalRequest:f,onHeartbeat:gn(t,n.id),resumeThreadId:n.resumeThreadId??null,onProgress:r=>{l(r);let i=typeof r==`object`?r.threadId:null,a=typeof r==`object`?r.turnId:null;(i||a)&&e(t,n.id,{status:`running`,...i?{threadId:i}:{},...a?{turnId:a}:{}})}});return e(t,n.id,{status:r.status===0?`completed`:`failed`,threadId:r.threadId,turnId:r.turnId,completedAt:new Date().toISOString()}),bn(t,n,s,r),r}finally{await h?.close()}}async function yn(t,n,{echo:i}){let a=r(t,n.id),o=F(t),s=_n(t,n.id,{echo:i}),c=R[n.permissions??`auto`]??R.auto,l=await ve(t,{prompt:hn(n),model:n.model,effort:n.effort,permissions:n.permissions,approvalJobId:c.approvalMode===`auto`?n.id:null,allowedNetworkHosts:o.approvals.allowedNetworkHosts,resumeSessionId:n.resumeThreadId??null,onHeartbeat:gn(t,n.id),onProgress:r=>{s(r),r.threadId&&e(t,n.id,{status:`running`,threadId:r.threadId})}});return e(t,n.id,{status:l.status===0?`completed`:`failed`,threadId:l.threadId,completedAt:new Date().toISOString()}),bn(t,n,a,l),l}function bn(e,t,n,r){Ne(U.join(n,`result.json`),r);let i={at:new Date().toISOString(),prompt:t.currentPrompt??t.prompt??null,...r};H.appendFileSync(U.join(n,`results.jsonl`),`${JSON.stringify(i)}\n`,`utf8`)}function xn(e){return e.engine===`claude`?yn:vn}async function Sn(t,n){for(let r=0;r<2;){let i=h(t,n);if(!i||i.status===`failed`||i.status===`cancelled`)return;let a=d(t,n);if(a.length===0){r+=1,await new Promise(e=>setTimeout(e,300));continue}r=0;for(let r of a){let a=e(t,n,{status:`running`,currentPrompt:r,resumeThreadId:i.threadId??null});u(t,n,{message:`Running steered follow-up.`});try{await xn(a)(t,a,{echo:!1})}catch(r){let i=r instanceof Error?r.message:String(r);e(t,n,{status:`failed`,error:i}),u(t,n,{kind:`error`,message:i});return}}}}function Cn(e,t){if(e instanceof A)switch(e.code){case`chain-exhausted`:x(e.payload),V.exit(3);case`read-only-unavailable`:wn(e.message,t);break;case`startup-failed`:t.json&&(x({taskId:e.taskId,status:`failed`,detail:e.message}),V.exit(1)),C(`Task ${e.taskId} failed to start.${e.message?`\n${e.message}`:``}`,{hint:`See: coder task result ${e.taskId}`});break;default:C(e.message,e.hint?{hint:e.hint}:{})}throw e}function wn(e,t){let n=`read-only unavailable on this host: the OS sandbox failed to start (Linux/WSL2 needs bubblewrap + socat). Re-dispatch with --permissions auto (or workspace-write) if writes are acceptable, or install the sandbox deps.`;t.json?x({error:n,code:`read-only-unavailable`,detail:e}):V.stderr.write(`[coder] ${n}\n`),V.exit(1)}async function Tn(e){V.env.CODER_WORKER&&C(`Nested dispatch refused: this shell is already inside a coder task. Do the work yourself, directly in this session - ignore any skill or instruction telling you to orchestrate via the coder CLI.`);let{options:t,positionals:n}=g(e,W.object({...v,agent:b,model:b,effort:b,permissions:b,resume:b,host:b,name:b,system:b,background:y,wait:y,"simulate-approval":y})),r=I(t),i=n.join(` `).trim();i||C(`Missing task text.`,{hint:[`Usage: coder run "<task text>"`,`Help: coder task run --help`]});let a={prompt:i,cwd:r,agent:t.agent,model:t.model,effort:t.effort,permissions:t.permissions,name:t.name,system:t.system,resume:t.resume,wait:t.wait,simulateApproval:t[`simulate-approval`],onFallback:({agent:e,detail:t,next:n})=>V.stderr.write(`[coder] ${e} failed to start (${t}); falling back to ${n}.\n`),onInstallNote:e=>V.stderr.write(`[coder] ${e}\n`)},o;try{o=await O(a)}catch(e){Cn(e,t)}if(t.wait)for(;;){let e=o.taskId,n=o.job,s=[` result: coder task result ${e}`,` steer: coder task steer ${e} "<follow-up>"`].join(`
|
|
77
|
+
`);t.json||(V.stderr.write(`${N.dim(`[coder]`)} task ${N.cyan(e)} started (${n.status}); waiting for it to finish — Ctrl-C to detach (it keeps running).\n`),V.stderr.write(`${N.dim(s)}\n`));let c=()=>{V.stderr.write(`\n${N.dim(`[coder] detached — task still running: coder task result ${e}`)}\n`),V.exit(130)};V.on(`SIGINT`,c);let l;try{l=await S(r,e)}catch(n){throw V.off(`SIGINT`,c),n instanceof A&&n.code===`approval-pending`&&je(e,n.approval,t.json),n}V.off(`SIGINT`,c);let u=l.job,d=l.result,f=d?.error?.message??``;if(u.status===`failed`&&ae(u.permissions??`auto`,f)&&wn(f,t),u.status===`failed`&&se.test(f)){let e=F(r).chain,n=e[e.indexOf(o.agent)+1];n||(x(re(o.agent,f,u.permissions??`auto`,t.system,i)),V.exit(3)),V.stderr.write(`[coder] ${o.agent} failed to start (${f}); falling back to ${n}.\n`);try{o=await O({...a,agent:n,model:void 0,effort:void 0,name:void 0,resume:void 0,simulateApproval:void 0})}catch(e){Cn(e,t)}continue}if(t.json)x({taskId:e,status:u.status,finalMessage:d?.finalMessage,...f?{error:f}:{},tokens:d?.tokens??null,model:d?.model??u.model??null});else{V.stdout.write(`\n${d?.finalMessage||(f?`${N.red(`error:`)} ${f}`:`(no final message)`)}\n\n`);let t=d?.tokens?` tokens=${Be(d.tokens,d.model??u.model)}`:``;V.stderr.write(`${N.dim(`[coder] task=${e} status=${u.status}${t}`)}\n`)}V.exit(u.status===`completed`?0:1)}let s=o.taskId,c=o.job,l=[` result: coder task result ${s}`,` steer: coder task steer ${s} "<follow-up>"`].join(`
|
|
78
|
+
`);if(t.json){x({taskId:s,status:c.status,startupCheck:o.startupCheck,commands:{result:`coder task result ${s}`,steer:`coder task steer ${s} "<follow-up>"`,stop:`coder task stop ${s}`,watch:`coder task watch ${s}`}});return}V.stdout.write(`${N.dim(`[coder]`)} task ${N.cyan(s)} started in the background (${c.status}).\n`),V.stdout.write(`${N.dim(l)}\n`)}async function En(t){let{options:n,positionals:i}=g(t,W.object({cwd:b})),a=I(n),o=i[0],s=h(a,o);s||C(`Worker: task ${o} not found.`),e(a,o,{status:`running`,pid:V.pid});try{if(s.simulateApproval){let t=await ne(r(a,o),{onEvent:e=>u(a,o,e)});if(u(a,o,{message:`simulated approval: ${t}`}),t===`decline`){e(a,o,{status:`cancelled`,completedAt:new Date().toISOString(),error:`simulated approval denied`});return}}await xn(s)(a,s,{echo:!1}),await Sn(a,o)}catch(t){let n=t instanceof Error?t.message:String(t);e(a,o,{status:`failed`,error:n}),u(a,o,{kind:`error`,message:n}),V.exit(1)}}async function Dn(e){let{options:n,positionals:i}=g(e,W.object({...v,tail:p,wait:y,turns:y}));L(i,1,`task result`);let s=I(n),c=Le(s,i[0]);if(n.wait){l.includes(c.status)&&V.stderr.write(`${N.dim(`[coder] waiting for task ${c.id} to finish...`)}\n`);let e=await Qe(s,c);c=e.job,e.reason===`approval`&&je(c.id,e.approval,n.json)}let{steps:u,result:d}=ue(s,c.id,{tail:n.tail}),f=o(s,c.id),m=me(r(s,c.id)).filter(e=>!e.response),h=l.includes(c.status),_=h&&m.length?`waiting-approval`:c.status,b=h?a(s,c.id,1)[0]:void 0,ee=h?t(s,c):c.updatedAt,S=k(ee),C=h&&m.length===0&&S>6e5,te=()=>{n.wait&&V.exit(c.status===`completed`?0:1)};if(n.json)return x({taskId:c.id,name:c.name??null,prompt:c.prompt??null,system:c.system??null,status:_,agent:c.agent,model:c.model??null,effort:c.effort??null,permissions:c.permissions??null,cwd:c.cwd??null,createdAt:c.createdAt??null,completedAt:c.completedAt??null,...h?{idleMs:S,lastActivityAt:ee??null,stalled:C}:{},pendingApprovals:m.map(e=>({id:e.id,summary:e.summary})),...u.length?{steps:u}:{},turnCount:f.length,...n.turns?{turns:f}:{},result:d}),te();let w=N,ne=c.createdAt?k(c.createdAt):null,re=!h&&c.completedAt?k(c.completedAt):null,T=c.createdAt&&c.completedAt?Date.parse(c.completedAt)-Date.parse(c.createdAt):null,E=h?ne===null?``:`started ${D(ne)} ago`:[re===null?``:`finished ${D(re)} ago`,T!==null&&T>=0?`took ${D(T)}`:``].filter(Boolean).join(` · `),O=[`${w.dim(`task`)} ${w.cyan(c.id)}`,...c.name?[`${w.dim(`name`)} ${c.name}`]:[],`${w.dim(`status`)} ${j(_)}${E?` ${w.dim(`(${E})`)}`:``}`,`${w.dim(`agent`)} ${he(c)}`,...ye(c,w),...d?.tokens?[`${w.dim(`tokens`)} ${Be(d.tokens,d.model??c.model)}`]:[]];if(c.prompt&&O.push(``,...ke(c.prompt,w)),m.length){O.push(``,w.dim(`pending approvals:`));for(let e of m)O.push(` ${w.cyan(e.id)} ${e.summary}`),O.push(` ${w.bold(`coder approve ${c.id} ${e.id}`)} ${w.dim(`(--deny to reject)`)}`)}if(u.length){O.push(``,w.dim(`steps:`));for(let e of u){let t=e.message??e.kind;t&&O.push(` ${w.dim(Ue(t))}`)}}if(O.push(``),n.turns&&f.length?f.forEach((e,t)=>{t&&O.push(``),O.push(w.dim(`— turn ${t+1} of ${f.length}: ${Ue(String(e.prompt??``))}`)),O.push(String(e.finalMessage||w.dim(`(no final message)`)))}):d?(O.push(ge({...d,error:d.error??void 0},c.error,`(no final message)`,w)),f.length>1&&O.push(w.dim(`(turn ${f.length} of ${f.length} — all answers: coder task result ${c.id} --turns)`))):h?O.push(w.dim(C?`Result pending, but no progress for ${D(S)} — the task may be stalled.${b?` Last: ${Ue(b.message??b.kind??``)}`:``}`:`Result pending — task is still running.`)):O.push(w.dim(`(no result)`)),h&&!n.wait){let e=[`Wait for it: coder task result ${c.id} --wait`,`Follow live: coder task watch ${c.id}`];C&&e.push(`Check the transcript: coder task result ${c.id} --tail all`),O.push(``,M(e,w))}return V.stdout.write(`${O.join(`
|
|
79
|
+
`)}\n`),d?.touchedFiles?.length&&V.stderr.write(`[coder] touched files: ${d.touchedFiles.join(`, `)}\n`),te()}function On(e){return s(e).filter(e=>l.includes(e.status)).flatMap(t=>me(r(e,t.id)).filter(e=>!e.response).map(e=>({taskId:t.id,id:e.id,summary:String(e.summary??``),createdAt:e.createdAt?String(e.createdAt):void 0})))}async function kn(e){let{options:t,positionals:n}=g(e,W.object(v));L(n,1,`task approvals`);let i=I(t),a=N;if(n[0]){let e=Le(i,n[0]),o=me(r(i,e.id)).map(e=>({id:e.id,summary:e.summary,createdAt:e.createdAt,answered:e.response?.decision??null}));if(t.json){x(o);return}if(!o.length){V.stdout.write(`${a.dim(`No approvals for task ${e.id}.`)}\n`);return}for(let e of o){let t=e.answered??`pending`;V.stdout.write(`${a.cyan(e.id)} ${t.padEnd(8)} ${a.dim(String(e.summary??``))}\n`)}let s=o.filter(e=>!e.answered);if(s.length){let e=s.length===1?s[0].id:`<approval-id>`;V.stdout.write(`\n${M([`Answer: coder approve ${e} [--deny]`],a)}\n`)}return}let o=On(i);if(t.json){x(o);return}if(!o.length){V.stdout.write(`${a.dim(`No pending approvals.`)}\n`);return}let s={id:Math.max(11,...o.map(e=>e.id.length)),task:Math.max(7,...o.map(e=>e.taskId.length))};V.stdout.write(a.bold(a.light(`${`approval-id`.padEnd(s.id)} ${`task-id`.padEnd(s.task)} age summary\n`)));for(let e of o){let t=e.createdAt?D(k(e.createdAt)):`-`;V.stdout.write(`${a.cyan(e.id.padEnd(s.id))} ${a.cyan(e.taskId.padEnd(s.task))} ${t.padEnd(5)} ${a.light(e.summary)}\n`)}let c=o.length===1?o[0].id:`<approval-id>`;V.stdout.write(`\n${M([`Answer: coder approve ${c} [--deny]`],a)}\n`)}async function An(e){let{options:t,positionals:n}=g(e,W.object({...v,deny:y}));L(n,2,`task approve`);let i=I(t),[a,o]=n;a&&!o&&a.startsWith(`apr-`)&&(o=a,a=On(i).find(e=>e.id===o)?.taskId,a||C(`No pending approval "${o}".`,{hint:`List them: coder approvals`})),(!a||!o)&&C(`Missing approval id.`,{hint:[`List them: coder approvals`,`Usage: coder approve [task-id] <approval-id> [--deny]`]});let s=Le(i,a),c=t.deny?`decline`:`accept`;if(Ee(r(i,s.id),o,c),t.json){x({taskId:s.id,approvalId:o,decision:c});return}V.stdout.write(`${t.deny?`Denied`:`Approved`} ${N.cyan(o)} on task ${N.cyan(s.id)}.\n`)}const jn=new Set([`Write`,`Edit`,`MultiEdit`,`NotebookEdit`]);async function Mn(e,t,n){let a=String(n.tool_name??``),o=n.input??n.tool_input??{},s=i(e),c=r(e,t),l=F(e),d=n=>u(e,t,n),f,p;if(a===`Bash`){let e=String(o.command??``);p=`run command: ${e||`(unknown command)`}`,f=fe(e,{allowedNetworkHosts:l.approvals.allowedNetworkHosts})}else if(jn.has(a)){let e=String(o.file_path??o.notebook_path??``);p=`${a}: ${e||`(unknown path)`}`,f=te(e?[e]:[],s)}else p=`${a||`(unknown tool)`}: ${JSON.stringify(o).slice(0,200)}`,f={decision:`escalate`,reason:`tool needs approval: ${a}`};d({kind:`approval-decision`,method:a,decision:f.decision,reason:f.reason,summary:p});let m=f.decision;return m===`escalate`&&(m=await Je(c,{method:`claude/${a}`,summary:p,params:{tool_name:a,input:o}},{timeoutMs:l.approvals.escalationTimeoutMs,onEvent:d})),m===`accept`?{behavior:`allow`,updatedInput:o}:{behavior:`deny`,message:`Denied by coder policy: ${f.reason}`}}const Nn={approval_prompt:{description:`Coder approval policy for claude permission prompts.`,inputSchema:{type:`object`,additionalProperties:!0},handler:Mn}};async function Pn(e){let{options:t,positionals:n}=g(e,W.object({cwd:b})),r=I(t),i=n[0],a=e=>V.stdout.write(`${JSON.stringify(e)}\n`),o=mt.createInterface({input:V.stdin,terminal:!1});for await(let e of o){if(!e.trim())continue;let t;try{t=JSON.parse(e)}catch{continue}let{id:n,method:o,params:s}=t;if(o===`initialize`)a({jsonrpc:`2.0`,id:n,result:{protocolVersion:s?.protocolVersion??`2024-11-05`,capabilities:{tools:{}},serverInfo:{name:`coder`,version:_()}}});else if(o===`tools/list`)a({jsonrpc:`2.0`,id:n,result:{tools:Object.entries(Nn).map(([e,t])=>({name:e,description:t.description,inputSchema:t.inputSchema}))}});else if(o===`tools/call`){let e=Nn[String(s?.name??``)],t;try{if(!e)throw Error(`unknown tool: ${s?.name}`);t=await e.handler(r,i,s?.arguments??{})}catch(e){t={behavior:`deny`,message:`coder mcp tool failed: ${e instanceof Error?e.message:String(e)}`}}a({jsonrpc:`2.0`,id:n,result:{content:[{type:`text`,text:JSON.stringify(t)}]}})}else n!==void 0&&a({jsonrpc:`2.0`,id:n,result:{}})}}V.stdout.on(`error`,e=>{throw e.code===`EPIPE`&&V.exit(0),e});const Fn={run:Tn,list:ut,watch:et,stream:et,result:Dn,steer:lt,ask:$e,stop:pe,archive:w,delete:ct,approvals:kn,approve:An};async function In(e){let[t,...n]=e;if(t===void 0||t===`help`||t===`-h`||t===`--help`){V.stdout.write(X());return}let r=Fn[t];if(r||(V.stdout.write(X()),C(`Unknown task subcommand "${t}".`,{hint:`Run a task: coder run "<text>"`})),Z(n)){let e=t===`stream`?`watch`:t;V.stdout.write(Y(`task ${e}`)??X());return}await r(n)}const Ln={task:In,flow:mn,run:Tn,list:ut,watch:et,result:Dn,stream:et,steer:lt,ask:$e,stop:pe,archive:w,delete:ct,approvals:kn,approve:An,config:rt,"setup-host":at,"host-setup":at,setup:at,model:nt,docs:ot,upgrade:st,update:st,_worker:En,_mcp:Pn,_refreshUpdate:async()=>ce(_()),_archiveSweep:le};async function Rn(){let[e,...t]=V.argv.slice(2);if(e===`--version`||e===`-v`){V.stdout.write(`${_()}\n`);return}if(e===void 0||e===`help`||e===`--help`||e===`-h`){if(t[0]===`task`&&t[1]===void 0){V.stdout.write(X());return}if(t[0]===`model`&&t[1]===void 0){V.stdout.write(bt());return}if(t[0]===`flow`&&t[1]===void 0){V.stdout.write(J());return}let e=t.map(e=>(e===`task`||e===`model`||e===`flow`)&&t[1]?`${e} ${t[1]}`:_t[e]??e).find(e=>q[e]);V.stdout.write(e&&Y(e)||St());return}e!==`_worker`&&e!==`_mcp`&&e!==`_refreshUpdate`&&e!==`_archiveSweep`&&oe(_(),m);let n=Ln[e];if(n||(V.stdout.write(St()),V.stdout.write(`
|
|
80
80
|
`),C(`Unknown command "${e}".`,{hint:`See all commands: coder --help`})),e===`model`&&Z(t)){let e=t.find(e=>!e.startsWith(`-`));V.stdout.write(e&&Y(`model ${e}`)||bt());return}if(e!==`task`&&e!==`flow`&&Z(t)){let t=_t[e]??e;V.stdout.write(Y(t)??St());return}try{await n(t)}catch(t){let n=t instanceof Error?t.message:String(t);if(/^(Unknown option|Missing value)/.test(n)){let t=_t[e]??e;q[t]&&C(n,{hint:`Help: coder ${e} --help`})}throw t}}Rn().catch(e=>{V.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),V.exit(1)});export{};
|
package/dist/flow/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as e,C as t,M as n,S as r,_ as i,a,c as o,d as s,f as c,g as l,i as u,m as d,n as f,o as p,r as m,s as h,x as g,y as _}from"../runtime-
|
|
1
|
+
import{A as e,C as t,M as n,S as r,_ as i,a,c as o,d as s,f as c,g as l,i as u,m as d,n as f,o as p,r as m,s as h,x as g,y as _}from"../runtime-BMO6NYyh.js";const v=new Proxy({},{get(e,t){return u()?.[t]},has(e,t){let n=u();return n!=null&&t in Object(n)},ownKeys(){let e=u();return e?Reflect.ownKeys(Object(e)):[]},getOwnPropertyDescriptor(e,t){let n=u();if(n!=null&&t in Object(n))return{enumerable:!0,configurable:!0,value:n[t]}}});function y(e){let t=l(e);if(!t)throw new n(`flow-failed`,`No flow run "${e}".`,{hint:`Recent runs: coder flow list`});if(t.status===`running`||t.status===`queued`)throw new n(`flow-failed`,`Run ${t.runId} is still running.`,{runId:t.runId,hint:`Stop it first: coder flow stop ${t.runId}`});return t}const b={run(e,t={}){return _(e,t)},list(e={}){return m(e).runs},discover(t){return e(t??process.cwd())},result(e,t={}){let n=e?l(e):s()[0]??null;return n?{...n,steps:h(n.runId,t.tail)}:null},stream(e,t={}){let n=e??s()[0]?.runId;if(!n)throw Error(`No flow runs to stream.`);return r(n,void 0,{tail:t.tail})},stop(e,t={}){return g(e,t)},resume(e,t={}){let n=e??s()[0]?.runId;if(!n)throw Error(`No flow runs to resume.`);return i(n,t)},archive(e){return f(y(e)),{runId:e,archived:!0}},delete(e){return y(e),{runId:e,deleted:a(e)}}};export{n as CoderError,v as args,b as default,b as flowSdk,p as flow,o as gate,c as log,d as pipeline,t as task};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import{A as e,B as t,C as n,F as r,G as i,H as a,I as o,L as s,M as c,N as l,O as u,P as d,T as f,W as ee,f as p,i as m,j as h,l as g,m as _,o as v,r as y,s as te,u as ne,v as re,w as ie,y as ae}from"./app-server-bHl6RBZ2.js";import{createRequire as oe}from"node:module";import b from"node:process";import x from"node:fs";import S from"node:path";import{spawn as C,spawnSync as w}from"node:child_process";import se from"node:os";import{fileURLToPath as ce,pathToFileURL as le}from"node:url";import*as T from"zod/mini";import ue from"node:net";import de,{randomUUID as fe}from"node:crypto";import{AsyncLocalStorage as pe}from"node:async_hooks";function me(e){let t=b.env.FORCE_COLOR,n=t!=null&&t!==``&&t!==`0`||t!==`0`&&e.isTTY&&!b.env.NO_COLOR,r=(e,t)=>n?`\x1b[${e}m${t}\x1b[0m`:t;return{blue:e=>r(`34`,e),bold:e=>r(`1`,e),cyan:e=>r(`36`,e),dim:e=>r(`38;5;246`,e),light:e=>r(`38;5;249`,e),green:e=>r(`32`,e),red:e=>r(`31`,e),yellow:e=>r(`33`,e)}}const E=me(b.stdout),D=me(b.stderr);function he(e,t=D){let n=e.map(e=>{let t=e.indexOf(`coder `);return t===-1?{label:e,cmd:``}:{label:e.slice(0,t),cmd:e.slice(t)}}),r=Math.max(0,...n.map(e=>e.label.length));return n.map(({label:e,cmd:n})=>n?` ${t.dim(e.padEnd(r))}${t.bold(n)}`:` ${t.dim(e)}`).join(`
|
|
2
|
+
`)}function O(e,t={}){let n=typeof t==`number`?t:t.code??1,r=typeof t==`object`?t.hint:null,i=r==null?[]:Array.isArray(r)?r:[r];b.stderr.write(`${D.red(e)}\n`),i.length&&b.stderr.write(`\n${he(i,D)}\n`),b.exit(n)}function k(e){b.stdout.write(`${JSON.stringify(e,null,2)}\n`)}function ge(e,t=E){return(JSON.stringify(e,null,2)??`null`).split(`
|
|
3
|
+
`).map(e=>e.replace(/"((?:[^"\\]|\\.)*)":/g,(e,n)=>`${t.light(`"${n}"`)}:`).replace(/: (-?\d[\d.eE+-]*|true|false|null)(,?)$/,(e,n,r)=>`: ${t.blue(n)}${r}`)).join(`
|
|
4
|
+
`)}function _e(e){let t=Date.parse(e??``);return Number.isFinite(t)?Math.max(0,Date.now()-t):0}function ve(e){let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m`:`${Math.floor(n/60)}h${n%60}m`}function A(e){return e<1e3?String(e):e<1e6?`${(e/1e3).toFixed(+(e<1e4))}k`:`${(e/1e6).toFixed(1)}M`}function ye(e,t){let n=[`in ${A(e.input)}`,...e.cachedInput?[`cached ${A(e.cachedInput)}`]:[],`out ${A(e.output)}`];return`${A(e.total)} (${n.join(` · `)}) on ${t||`default model`}`}function be(e,t,n,r=E){let i=e?.error?.message??t;return e?.finalMessage||(i?`${r.red(`error:`)} ${i}`:n)}function xe(e,t=E){let n=e=>e.split(`
|
|
5
|
+
`).map(e=>` ${t.dim(e)}`);return e.length<=1e3?[t.dim(`prompt:`),...n(e)]:[t.dim(`prompt:`),...n(e.slice(0,500).trimEnd()),t.light(` … <${e.length-1e3} chars trimmed> …`),...n(e.slice(-500).trimStart())]}function Se(e){return[e.agent??`-`,e.model,e.model?e.effort:null].filter(Boolean).join(`/`)}function Ce(e,t=E){let n=[];return e.permissions&&n.push([`perms`,e.permissions]),e.cwd&&n.push([`cwd`,e.cwd]),n.map(([e,n])=>`${t.dim(e.padEnd(8))} ${n}`)}function we(e,t=300,{plain:n=!1,style:r=E}={}){if(e.length<=t)return e;let i=`<${e.length-t} more chars>`;return`${e.slice(0,t)} ${n?i:r.dim(i)}`}const Te=6e5,Ee=12e4;function De(e,t){return e.length>t?`${e.slice(0,t-1)}…`:e.padEnd(t)}function Oe(e){return` ${E.bold(E.green(`✔`))} ${e}`}function ke(e){return` ${E.bold(E.red(`✘`))} ${e}`}function Ae(e=b.stdout){try{return e.getWindowSize?.()[0]??e.columns}catch{return e.columns}}function je(e=b.stdout){try{return e.getWindowSize?.()[1]??e.rows}catch{return e.rows}}function Me(e){return e>=768&&e<=879||e>=8203&&e<=8207||e>=65024&&e<=65039?0:e>=4352&&e<=4447||e>=11904&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65072&&e<=65103||e>=65280&&e<=65376||e>=65504&&e<=65510||e>=127744&&e<=129791||e>=131072&&e<=262141?2:1}function Ne(e){let t=0;for(let n of e.replace(/\x1b\[[0-9;]*m/g,``))t+=Me(n.codePointAt(0));return t}function Pe(e,t){let n=0,r=``;for(let i=0;i<e.length;){let a=e[i]===`\x1B`?/^\x1b\[[0-9;]*m/.exec(e.slice(i)):null;if(a){r+=a[0],i+=a[0].length;continue}let o=e.codePointAt(i),s=String.fromCodePoint(o),c=Me(o);if(n+c>t-1)return`${r}\x1b[0m${E.dim(`…`)}`;r+=s,n+=c,i+=s.length}return r}function Fe(){let e=b.stdin;if(!e.isTTY||!b.stdout.isTTY)return()=>{};e.setRawMode(!0),e.resume();let t=e=>{e.includes(3)&&b.kill(b.pid,`SIGINT`),e.includes(26)&&b.kill(b.pid,`SIGTSTP`)};return e.on(`data`,t),e.unref(),()=>{e.off(`data`,t),e.isTTY&&e.setRawMode(!1),e.pause()}}var Ie=class{stream;quietMs;lines=[];painted=[];paintedWidths=[];paintedCols;resizeTimer;tty;constructor(e=b.stdout,t=250){this.stream=e,this.quietMs=t,this.tty=!!e.isTTY,this.tty&&e.on(`resize`,this.onResize)}set(e){this.lines=e,!(!this.tty||this.resizeTimer)&&this.paint()}commit(e){this.clear(),this.stream.write(e)}clear(){if(!this.painted.length)return;let e=Ae(this.stream),t=this.painted.length;e&&this.paintedCols&&e!==this.paintedCols&&(t=this.paintedWidths.reduce((t,n)=>t+Math.max(1,Math.ceil(n/e)),0)),this.stream.write(`\x1b[${t}A\x1b[0J`),this.painted=[],this.paintedWidths=[]}done(){this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=void 0,this.paint()),this.tty&&this.stream.off(`resize`,this.onResize)}paint(){this.clear();let e=Ae(this.stream),t=e?this.lines.map(t=>Pe(t,e-1)):this.lines,n=je(this.stream);n&&t.length>n-1&&(t=n>1?t.slice(-(n-1)):[]);for(let e of t)this.stream.write(`${e}\n`);this.painted=t,this.paintedWidths=t.map(Ne),this.paintedCols=e}onResize=()=>{this.clear(),this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout(()=>{this.resizeTimer=void 0,this.paint()},this.quietMs),this.resizeTimer.unref?.()}};function Le(e,t=0){let n=e.padEnd(t);return e===`running`?E.green(n):e===`waiting-approval`?E.yellow(n):e===`failed`||e===`cancelled`?E.red(n):e===`completed`?E.blue(n):E.dim(n)}function Re(e,t,n=!1){n?k({taskId:e,status:`awaiting-approval`,approval:t}):(b.stdout.write(`Approval needed for task ${e}: ${t.summary}\n`),b.stderr.write(`\n${he([`Approve: coder approve ${e} ${t.id}`,`Deny: coder approve ${e} ${t.id} --deny`,`Then: coder task result ${e} --wait`],D)}\n`)),b.exit(4)}function ze(e,t,n){if(e.length>t){let r=e.slice(t);O(`Unexpected argument${r.length>1?`s`:``}: ${r.join(` `)}`,{hint:`Help: coder ${n} --help`})}}function Be(e){return e.cwd?S.resolve(String(e.cwd)):b.cwd()}function Ve(e,t){let r=n(e,t);return r||O(t?`No task found for "${t}".`:`No tasks found for this workspace.`,{hint:t?[`List tasks: coder task list`,`Start one: coder run "<text>"`]:[`Start one: coder run "<text>"`]}),r}const j=`@wular/coder`,He=`https://registry.npmjs.org/${j}/latest`;function Ue(){return S.join(r(),`update-check.json`)}function We(e,t){let n=String(e).split(`.`).map(e=>parseInt(e,10)||0),r=String(t).split(`.`).map(e=>parseInt(e,10)||0);for(let e=0;e<3;e+=1){if((n[e]??0)>(r[e]??0))return 1;if((n[e]??0)<(r[e]??0))return-1}return 0}function Ge(){try{return JSON.parse(x.readFileSync(Ue(),`utf8`))}catch{return null}}function Ke(e){try{x.mkdirSync(r(),{recursive:!0}),x.writeFileSync(Ue(),JSON.stringify(e))}catch{}}function qe(){try{x.rmSync(Ue(),{force:!0})}catch{}}function Je(e,t){if(b.env.CODER_NO_UPDATE_CHECK||b.env.CI)return;let n=Ge();if(n?.latest&&We(n.latest,e)>0&&b.stderr.write(D.dim(`coder ${e} -> `)+D.bold(n.latest)+D.dim(` available. run: coder upgrade
|
|
6
|
+
|
|
7
|
+
`)),!n?.checkedAt||Date.now()-n.checkedAt>864e5)try{C(b.execPath,[t,`_refreshUpdate`],{detached:!0,stdio:`ignore`}).unref()}catch{}}async function Ye(e){let t=Ge()?.latest??null;try{let e=new AbortController,n=setTimeout(()=>e.abort(),3e3),r=await fetch(He,{signal:e.signal,headers:{accept:`application/json`}});if(clearTimeout(n),r.ok){let e=await r.json();e?.version&&(t=e.version)}}catch{}Ke({checkedAt:Date.now(),latest:t,current:e})}function Xe(e){let t=e;try{t=x.realpathSync(e)}catch{}let n=t.replace(/\\/g,`/`);return/\/\.bun\//.test(n)?{pm:`bun`,command:[`bun`,`add`,`-g`,`${j}@latest`]}:/\/\.pnpm\//.test(n)||/\/pnpm(-global)?\//i.test(n)||/\/Library\/pnpm\//.test(n)?{pm:`pnpm`,command:[`pnpm`,`add`,`-g`,`${j}@latest`]}:/\/\.config\/yarn\/global\//.test(n)||/\/yarn\/global\//.test(n)||/\/Yarn\/Data\/global\//.test(n)?{pm:`yarn`,command:[`yarn`,`global`,`add`,`${j}@latest`]}:{pm:`npm`,command:[`npm`,`install`,`-g`,`${j}@latest`]}}function M(e){try{return JSON.parse(x.readFileSync(e,`utf8`))}catch{return null}}function Ze(e,t){let n=`${e}.tmp`;x.writeFileSync(n,`${JSON.stringify(t,null,2)}\n`,`utf8`),x.renameSync(n,e)}function Qe(e){let t=0,n=``;return()=>{let r;try{r=x.statSync(e).size}catch{return[]}if(r<t&&(t=0,n=``),r===t)return[];let i;try{i=x.openSync(e,`r`)}catch{return[]}try{let e=Buffer.alloc(r-t),a=x.readSync(i,e,0,e.length,t);t+=a;let o=(n+e.toString(`utf8`,0,a)).split(`
|
|
8
|
+
`);return n=o.pop()??``,o.filter(Boolean)}finally{x.closeSync(i)}}}const $e=new Set(`commit.checkout.switch.restore.stash.reset.rebase.merge.push.pull.cherry-pick.revert.clean.am.apply.tag.branch.worktree.filter-branch.filter-repo.gc.prune.reflog.remote.submodule.config`.split(`.`)),et=[/\bsudo\b/,/\brm\s+(-[a-zA-Z]*r[a-zA-Z]*f|-[a-zA-Z]*f[a-zA-Z]*r)\b.*\s(\/\*?|~\/?|\$HOME\/?)(\s|$)/,/\b(shutdown|reboot|halt|poweroff)\b/,/\bmkfs\b|\bdiskutil\s+erase/i,/\b(chmod|chown)\b.*-R.*\s\/(\s|$)/,/\bkill(all)?\s+-9\s+1\b/,/curl[^|;&]*\|\s*(ba|z|da)?sh\b/,/wget[^|;&]*\|\s*(ba|z|da)?sh\b/,/\blaunchctl\b|\bsystemctl\b/,/\bdefaults\s+write\b/,/>\s*\/dev\/(sd|disk)/],tt=new Set([`status`,`log`,`diff`,`show`,`blame`,`rev-parse`,`ls-files`,`ls-tree`,`cat-file`,`describe`,`shortlog`,`grep`,`branch`,`stash`]);function nt(e){let t=e.match(/^\s*(?:ba|z|da)?sh\s+(?:-[a-zA-Z]+\s+)*(?:-c\s+)?(["'])([\s\S]*)\1\s*$/);return t?t[2]:e}function rt(e){return e.trim().split(/\s+/).filter(Boolean)}function it(e){let t=e.find((e,t)=>t>0&&!e.startsWith(`-`));if(!t)return{decision:`accept`,reason:`bare git`};if(t===`branch`&&e.some(e=>/^-(d|D|m|M|c|C|f|u)|^--(delete|move|copy|force|set-upstream)/.test(e)))return{decision:`decline`,reason:`git branch write operation (git is read-only for Coder)`};if(t===`stash`){let t=e.find((e,t)=>t>1&&!e.startsWith(`-`));return t===`list`||t===`show`?{decision:`accept`,reason:`git stash ${t} is read-only`}:{decision:`decline`,reason:`git stash write operation (git is read-only for Coder)`}}return tt.has(t)?{decision:`accept`,reason:`git ${t} is read-only`}:$e.has(t)?{decision:`decline`,reason:`git ${t} is a write operation (git is read-only for Coder)`}:{decision:`escalate`,reason:`unrecognized git subcommand: ${t}`}}function at(e,t={}){let n=nt(String(e??``));if(!n.trim())return{decision:`escalate`,reason:`empty command`};for(let e of et)if(e.test(n))return{decision:`decline`,reason:`matches hard-deny pattern ${e}`};if(/\$\(|`|<\(/.test(n))return{decision:`escalate`,reason:`contains command substitution`};let r=n.split(/&&|\|\||;|\||\r?\n/).map(e=>e.trim()).filter(Boolean);if(r.length>1){let e={decision:`accept`,reason:`all segments safe`};for(let n of r){let r=at(n,t);if(r.decision===`decline`)return r;r.decision===`escalate`&&(e=r)}return e}let i=rt(n),a=S.basename(i[0]??``);if(a===`git`)return it(i);let o=t.networkHost;return o?(t.allowedNetworkHosts??[]).some(e=>o===e||o.endsWith(`.${e}`))?{decision:`accept`,reason:`network host ${o} is allowlisted`}:{decision:`escalate`,reason:`network access to ${o}`}:{decision:`escalate`,reason:`command needs approval: ${a||`(unknown)`}`}}function ot(e,t){if(!e.length)return{decision:`escalate`,reason:`file change with no resolvable paths`};for(let n of e){let e=S.resolve(t,n),r=S.relative(t,e);if(r.startsWith(`..`)||S.isAbsolute(r))return{decision:`escalate`,reason:`path outside workspace: ${n}`};if(r===`.git`||r.startsWith(`.git${S.sep}`))return{decision:`decline`,reason:`direct .git modification: ${n}`}}return{decision:`accept`,reason:`all paths inside workspace`}}function st(e){return S.join(e,`approvals`)}function ct(e){let t=st(e);return x.existsSync(t)?x.readdirSync(t).filter(e=>e.endsWith(`.request.json`)).flatMap(e=>{let n=e.replace(/\.request\.json$/,``),r=M(S.join(t,e));if(!r)return[];let i=M(S.join(t,`${n}.response.json`));return[{...r,id:n,response:i}]}).sort((e,t)=>String(e.createdAt??``).localeCompare(String(t.createdAt??``))):[]}function lt(e,t,n){let r=st(e),i=S.join(r,`${t}.request.json`);if(!x.existsSync(i))throw Error(`No pending approval "${t}" for this job.`);x.writeFileSync(S.join(r,`${t}.response.json`),`${JSON.stringify({decision:n,answeredAt:new Date().toISOString()},null,2)}\n`,`utf8`)}async function N(e,t,{timeoutMs:n,onEvent:r}){let i=st(e);x.mkdirSync(i,{recursive:!0});let a=`apr-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`;x.writeFileSync(S.join(i,`${a}.request.json`),`${JSON.stringify({...t,createdAt:new Date().toISOString()},null,2)}\n`,`utf8`),r?.({kind:`approval-escalated`,approvalId:a,summary:t.summary,message:`Approval needed (${a}): ${t.summary}. Answer with: coder approve ${S.basename(e)} ${a} [--deny]`});let o=S.join(i,`${a}.response.json`),s=Date.now()+n;for(;Date.now()<s;){if(x.existsSync(o))try{let e=JSON.parse(x.readFileSync(o,`utf8`)).decision===`accept`?`accept`:`decline`;return r?.({kind:`approval-answered`,approvalId:a,decision:e}),e}catch{}await new Promise(e=>setTimeout(e,400))}return r?.({kind:`approval-timeout`,approvalId:a,message:`Approval ${a} timed out; declining.`}),`decline`}function ut(e,t={}){return N(e,{method:`simulate`,summary:`simulated approval probe (--simulate-approval)`},{timeoutMs:t.timeoutMs??12e4,onEvent:t.onEvent??null})}function dt({workspaceRoot:e,jobDir:t,mode:n=`auto`,escalationTimeoutMs:r=12e4,allowedNetworkHosts:i=[],onEvent:a=null}){return async(o,s,c)=>{if(o===`item/commandExecution/requestApproval`){let e=s.command??c?.itemIndex?.get(s.itemId??``)?.command??``,l=`run command: ${e||`(unknown command)`}${s.reason?` — ${s.reason}`:``}`;if(n===`deny`)return a?.({kind:`approval-decision`,method:o,decision:`decline`,reason:`deny mode`,summary:l}),{decision:`decline`};let u=at(e,{networkHost:s.networkApprovalContext?.host??null,allowedNetworkHosts:i});return a?.({kind:`approval-decision`,method:o,decision:u.decision,reason:u.reason,summary:l}),u.decision===`escalate`?{decision:await N(t,{method:o,summary:l,command:e,params:s},{timeoutMs:r,onEvent:a})}:{decision:u.decision}}if(o===`item/fileChange/requestApproval`){let i=(c?.itemIndex?.get(s.itemId??``)?.changes??[]).map(e=>e.path).filter(e=>!!e),l=`apply file changes: ${i.join(`, `)||`(unknown paths)`}${s.reason?` — ${s.reason}`:``}`;if(n===`deny`)return a?.({kind:`approval-decision`,method:o,decision:`decline`,reason:`deny mode`,summary:l}),{decision:`decline`};let u=ot(i,e);return a?.({kind:`approval-decision`,method:o,decision:u.decision,reason:u.reason,summary:l}),u.decision===`escalate`?{decision:await N(t,{method:o,summary:l,paths:i,params:s},{timeoutMs:r,onEvent:a})}:{decision:u.decision}}throw a?.({kind:`approval-unsupported`,method:o}),Error(`Coder does not handle server request ${o}; treating as denied.`)}}async function ft(e,t,n=400){let r=t;for(;;){if(a.includes(r.status))return{job:r,reason:`terminal`};let t=ct(o(e,r.id)).filter(e=>!e.response);if(t[0])return{job:r,reason:`approval`,approval:{id:t[0].id,summary:String(t[0].summary??``)}};await new Promise(e=>setTimeout(e,n)),r=d(e,h(e,r.id)??r)}}const pt=`Coder Task`;function mt(e){return e.split(/\r?\n/).map(e=>e.trimEnd()).filter(e=>e&&!e.startsWith(`WARNING: proceeding, even though we could not update PATH:`)).join(`
|
|
9
|
+
`)}function ht(e,t=72){let n=String(e??``).trim().replace(/\s+/g,` `);return n?n.length<=t?n:`${n.slice(0,t-3)}...`:``}function gt(e){let t=ht(e,56);return t?`${pt}: ${t}`:pt}function _t(e){return e?.params?.threadId??null}function vt(e){return e?.params?.turnId?e.params.turnId:e?.params?.turn?.id?e.params.turn.id:null}function yt(e){let t=new Set;for(let n of e)for(let e of n.changes??[])e.path&&t.add(e.path);return[...t]}function bt(e){if(!e||typeof e!=`object`)return null;let t=e=>typeof e==`number`&&Number.isFinite(e)?e:0,n=t(e.inputTokens),r=t(e.cachedInputTokens),i=t(e.outputTokens);return{input:n,cachedInput:r,output:i,total:t(e.totalTokens)||n+r+i}}function xt(e){if(e.tokenUsageByThread.size===0)return null;let t={input:0,cachedInput:0,output:0,total:0};for(let n of e.tokenUsageByThread.values())t.input+=n.input,t.cachedInput+=n.cachedInput,t.output+=n.output,t.total+=n.total;return t}function St(e){return String(e??``).replace(/\s+/g,` `).trim()}function P(e){if(!e)return[];if(typeof e==`string`){let t=St(e);return t?[t]:[]}if(Array.isArray(e))return e.flatMap(e=>P(e));if(typeof e==`object`){let t=e;if(typeof t.text==`string`)return P(t.text);if(`summary`in t)return P(t.summary);if(`content`in t)return P(t.content);if(`parts`in t)return P(t.parts)}return[]}function Ct(e,t){let n=[];for(let r of[...e,...t]){let e=St(r);!e||n.includes(e)||n.push(e)}return n}function F(e,t,n=null,r={}){!e||!t||e({message:t,phase:n,...r})}function wt(e){switch(e.type){case`commandExecution`:return{message:`Running command: ${String(e.command??``).trim()}`,phase:`running`};case`fileChange`:return{message:`Applying ${e.changes.length} file change(s).`,phase:`editing`};case`mcpToolCall`:return{message:`Calling ${e.server}/${e.tool}.`,phase:`investigating`};case`dynamicToolCall`:return{message:`Running tool: ${e.tool}.`,phase:`investigating`};case`webSearch`:return{message:`Searching: ${String(e.query??``).trim()}`,phase:`investigating`};default:return null}}function Tt(e){switch(e.type){case`commandExecution`:{let t=String(e.aggregatedOutput??``).trim();return{message:`Command ${e.status===`completed`?`completed`:e.status}: ${String(e.command??``).trim()} (exit ${e.exitCode??`?`})`+(t?`\n${t}`:``),phase:`running`}}case`fileChange`:return{message:`File changes ${e.status}.`,phase:`editing`};case`mcpToolCall`:return{message:`Tool ${e.server}/${e.tool} ${e.status}.`,phase:`investigating`};case`dynamicToolCall`:return{message:`Tool ${e.tool} ${e.status}.`,phase:`investigating`};default:return null}}function Et(e,t={}){let n,r,i=new Promise((e,t)=>{n=e,r=t});return{threadId:e,rootThreadId:e,threadIds:new Set([e]),threadTurnIds:new Map,turnId:null,bufferedNotifications:[],completion:i,resolveCompletion:n,rejectCompletion:r,finalTurn:null,completed:!1,finalAnswerSeen:!1,pendingCollaborations:new Set,activeSubagentTurns:new Set,completionTimer:null,lastAgentMessage:``,reasoningSummary:[],error:null,fileChanges:[],commandExecutions:[],tokenUsageByThread:new Map,itemIndex:new Map,onProgress:t.onProgress??null,onHeartbeat:t.onHeartbeat??null}}function Dt(e){e.completionTimer&&=(clearTimeout(e.completionTimer),null)}function Ot(e,t=null){e.completed||(Dt(e),e.completed=!0,t?(e.finalTurn=t,e.turnId||=t.id??null):e.finalTurn||={id:e.turnId??`inferred-turn`,status:`completed`},e.resolveCompletion(e))}function kt(e){e.completed||e.finalTurn||!e.finalAnswerSeen||e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||(Dt(e),e.completionTimer=setTimeout(()=>{e.completionTimer=null,!(e.completed||e.finalTurn||!e.finalAnswerSeen)&&(e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||Ot(e,null))},250),e.completionTimer.unref?.())}function At(e,t){let n=_t(t);if(!n||!e.threadIds.has(n))return!1;let r=e.threadTurnIds.get(n)??null,i=vt(t);return r===null||i===null||i===r}function jt(e,t,n,r=null){if(t.id&&e.itemIndex.set(t.id,t),t.type===`collabAgentToolCall`){(!r||r===e.threadId)&&(n===`started`||t.status===`inProgress`?e.pendingCollaborations.add(t.id):n===`completed`&&(e.pendingCollaborations.delete(t.id),kt(e)));for(let n of t.receiverThreadIds??[])e.threadIds.add(n)}if(t.type===`agentMessage`){t.text&&(!r||r===e.threadId)&&(e.lastAgentMessage=t.text,n===`completed`&&t.phase===`final_answer`&&(e.finalAnswerSeen=!0,kt(e)));return}if(t.type===`reasoning`&&n===`completed`){e.reasoningSummary=Ct(e.reasoningSummary,P(t.summary));return}if(t.type===`fileChange`&&n===`completed`){e.fileChanges.push(t);return}t.type===`commandExecution`&&n===`completed`&&e.commandExecutions.push(t)}function Mt(e,t){switch(e.onHeartbeat?.(),t.method){case`thread/started`:e.threadIds.add(t.params.thread.id);break;case`turn/started`:e.threadIds.add(t.params.threadId),e.threadTurnIds.set(t.params.threadId,t.params.turn.id),(t.params.threadId??null)!==e.threadId&&e.activeSubagentTurns.add(t.params.threadId),F(e.onProgress,`Turn started (${t.params.turn.id}).`,`starting`,{threadId:t.params.threadId??null,turnId:t.params.turn.id??null});break;case`item/started`:jt(e,t.params.item,`started`,t.params.threadId??null);{let n=wt(t.params.item);F(e.onProgress,n?.message,n?.phase??null)}break;case`item/completed`:jt(e,t.params.item,`completed`,t.params.threadId??null);{let n=Tt(t.params.item);F(e.onProgress,n?.message,n?.phase??null)}break;case`thread/tokenUsage/updated`:{let n=bt(t.params?.tokenUsage?.total??t.params?.tokenUsage),r=_t(t);n&&r&&e.tokenUsageByThread.set(r,n);break}case`error`:e.error=t.params.error,F(e.onProgress,`Codex error: ${t.params.error.message}`,`failed`);break;case`turn/completed`:if((t.params.threadId??null)!==e.threadId){e.activeSubagentTurns.delete(t.params.threadId),kt(e);break}F(e.onProgress,`Turn ${t.params.turn.status}.`,`finalizing`),Ot(e,t.params.turn)}}async function Nt(e,t,n,r={}){let i=Et(t,r),a=e.notificationHandler;e.setNotificationHandler(e=>{if(!i.turnId){i.bufferedNotifications.push(e);return}if(e.method===`thread/started`){Mt(i,e);return}if(!At(i,e)){a?.(e);return}Mt(i,e)});let o=r.onApprovalRequest;o&&e.setServerRequestHandler((e,t)=>o(e,t,i));try{let e=await n();i.turnId=e.turn?.id??null,i.turnId&&i.threadTurnIds.set(i.threadId,i.turnId);for(let e of i.bufferedNotifications)At(i,e)?Mt(i,e):a?.(e);return i.bufferedNotifications.length=0,e.turn?.status&&e.turn.status!==`inProgress`&&Ot(i,e.turn),await i.completion}finally{Dt(i),e.setNotificationHandler(a??null),e.setServerRequestHandler(null)}}async function Pt(e,t){let n=null;try{n=await y.connect(e);let r=await t(n);return await n.close(),r}catch(r){let i=r,a=n?.transport===`broker`||!!process.env.CODER_APP_SERVER_ENDPOINT,o=n?.transport===`broker`&&i?.rpcCode===-32001||a&&(i?.code===`ENOENT`||i?.code===`ECONNREFUSED`);if(n&&=(await n.close().catch(()=>{}),null),!o)throw r;let s=await y.connect(e,{disableBroker:!0});try{return await t(s)}finally{await s.close()}}}function I(e){let t=m(`codex`,[`--version`],{cwd:e});if(!t.available)return t;let n=m(`codex`,[`app-server`,`--help`],{cwd:e});return n.available?{available:!0,detail:`${t.detail}; app-server runtime available`}:{available:!1,detail:`${t.detail}; app-server runtime unavailable: ${n.detail}`}}async function Ft(e){let t=I(e);if(!t.available)return{available:!1,loggedIn:!1,detail:t.detail};let n=null;try{n=await y.connect(e,{reuseExistingBroker:!0});let t=await n.request(`account/read`,{refreshToken:!1}),r=t?.account??null;return r?.type===`chatgpt`?{available:!0,loggedIn:!0,detail:r.email?`ChatGPT login active for ${r.email}`:`ChatGPT login active`}:r?.type===`apiKey`?{available:!0,loggedIn:!0,detail:`API key configured`}:t?.requiresOpenaiAuth===!1?{available:!0,loggedIn:!0,detail:`Active provider does not require OpenAI authentication`}:{available:!0,loggedIn:!1,detail:"Not authenticated. Run `codex login`."}}catch(e){let t=w(`codex`,[`login`,`status`],{encoding:`utf8`}),n=`${t.stdout??``}${t.stderr??``}`.trim();return t.status===0?{available:!0,loggedIn:!0,detail:n||`Logged in`}:{available:!0,loggedIn:!1,detail:n||(e instanceof Error?e.message:String(e))}}finally{await n?.close().catch(()=>{})}}async function It(e,{threadId:t,turnId:n}){if(!t||!n)return{interrupted:!1,detail:`missing threadId or turnId`};let r=null;try{return r=await y.connect(e,{reuseExistingBroker:!0}),await r.request(`turn/interrupt`,{threadId:t,turnId:n}),{interrupted:!0,detail:`Interrupted ${n} on ${t}.`}}catch(e){return{interrupted:!1,detail:e instanceof Error?e.message:String(e)}}finally{await r?.close().catch(()=>{})}}async function Lt(e,{threadId:t,text:n}){if(!t)return{steered:!1,detail:`missing threadId`};let r=n.trim();if(!r)return{steered:!1,detail:`empty follow-up`};let i=null;try{return i=await y.connect(e,{reuseExistingBroker:!0}),await i.request(`turn/steer`,{threadId:t,input:[{type:`text`,text:r,text_elements:[]}]}),{steered:!0,detail:`Steered follow-up into the active turn on ${t}.`}}catch(e){return{steered:!1,detail:e instanceof Error?e.message:String(e)}}finally{await i?.close().catch(()=>{})}}async function Rt(e,t={}){let n=I(e);if(!n.available)throw Error(`Codex CLI is not available: ${n.detail}`);let r=t.prompt?.trim();if(!r)throw Error(`A prompt is required.`);return Pt(e,async n=>{let a;if(t.resumeThreadId)F(t.onProgress,`Resuming thread ${t.resumeThreadId}.`,`starting`),ee(t.resumeThreadId)&&await i(t.resumeThreadId),a=(await n.request(`thread/resume`,{threadId:t.resumeThreadId,cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`})).thread.id;else{F(t.onProgress,`Starting Codex task thread.`,`starting`),a=(await n.request(`thread/start`,{cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`,serviceName:`coder_runtime`,ephemeral:t.ephemeral??!1})).thread.id;try{await n.request(`thread/name/set`,{threadId:a,name:gt(r)})}catch(e){let t=String(e?.message??e??``);if(!t.includes(`unknown variant`)&&!t.includes(`unknown method`))throw e}}F(t.onProgress,`Thread ready (${a}).`,`starting`,{threadId:a});let o=await Nt(n,a,()=>n.request(`turn/start`,{threadId:a,input:[{type:`text`,text:r,text_elements:[]}],model:t.model??null,effort:t.effort??null,outputSchema:t.outputSchema??null}),{onProgress:t.onProgress,onHeartbeat:t.onHeartbeat,onApprovalRequest:t.onApprovalRequest});return{status:o.finalTurn?.status===`completed`?0:1,threadId:a,turnId:o.turnId,finalMessage:o.lastAgentMessage,reasoningSummary:o.reasoningSummary,turn:o.finalTurn,error:o.error,stderr:mt(n.stderr),fileChanges:o.fileChanges,touchedFiles:yt(o.fileChanges),tokens:xt(o),model:t.model??null,commandExecutions:o.commandExecutions}})}const zt={chain:[`codex`,`claude`],agents:{codex:{model:`gpt-5.6-terra`,effort:`high`,permissions:`auto`},claude:{model:`opus`,effort:`medium`,permissions:`auto`}},models:{},approvals:{escalationTimeoutMs:12e4,allowedNetworkHosts:[]}},L={mini:`gpt-5.4-mini`,luna:`gpt-5.6-luna`,terra:`gpt-5.6-terra`,sol:`gpt-5.6-sol`},R=new Set([`low`,`medium`,`high`]),z={haiku:`haiku`,sonnet:`sonnet`,opus:`opus`,fable:`fable`},B=new Set([`low`,`medium`,`high`]),Bt={"read-only":{sandbox:`read-only`,approvalPolicy:`never`,approvalMode:null},"workspace-write":{sandbox:`workspace-write`,approvalPolicy:`never`,approvalMode:null},auto:{sandbox:`workspace-write`,approvalPolicy:`on-request`,approvalMode:`auto`}},Vt={"read-only":[`--permission-mode`,`dontAsk`,`--disallowedTools`,`Edit`,`Write`,`NotebookEdit`],"workspace-write":[`--permission-mode`,`acceptEdits`],auto:[`--permission-mode`,`auto`]},Ht=/failIfUnavailable|sandbox\b[^.\n]*?(?:failed|could ?n[o']t|cannot|unavailable|not available|not supported)/i;function Ut(e){return e.flatMap(e=>ue.isIPv6(e)?[`[${e}]`]:e.startsWith(`[`)||e.includes(`:`)||ue.isIP(e)?[e]:[e,`*.${e}`])}function Wt(e,t,n=[]){return JSON.stringify(e===`read-only`?{sandbox:{enabled:!0,failIfUnavailable:!0,autoAllowBashIfSandboxed:!0,filesystem:{denyWrite:[t]}}}:{sandbox:{enabled:!0,autoAllowBashIfSandboxed:!0,...e===`auto`&&n.length?{network:{allowedDomains:Ut(n)}}:{}}})}const Gt=T.enum([`codex`,`claude`]),Kt=T.enum([`codex`,`claude`,`custom`]),qt=T.enum([`low`,`medium`,`high`]),Jt=T.enum([`read-only`,`workspace-write`,`auto`]),Yt=T.partial(T.strictObject({model:T.string().check(T.minLength(1)),effort:qt,permissions:Jt})),Xt=T.strictObject({baseUrl:T.url(),model:T.string().check(T.minLength(1)),envKey:T.optional(T.string().check(T.minLength(1))),wireApi:T.optional(T.enum([`chat`,`responses`])),disabled:T.optional(T.boolean())}),Zt=T.strictObject({provider:Gt,model:T.string().check(T.minLength(1)),effort:T.optional(qt),disabled:T.optional(T.boolean())}),Qt=T.strictObject({disabled:T.boolean()}),$t=T.union([Xt,Zt,Qt]),en=T.strictObject({escalationTimeoutMs:T.number().check(T.positive()),allowedNetworkHosts:T.array(T.string())}),tn=T.strictObject({chain:T.array(Kt).check(T.minLength(1)),agents:T.partial(T.strictObject({codex:Yt,claude:Yt,custom:Yt})),models:T.optional(T.record(T.string().check(T.regex(/^[a-z0-9][a-z0-9./_-]*$/i,`model name`)),$t)),approvals:en}),nn=T.partial(T.extend(tn,{approvals:T.partial(en)}));function V(e){return`baseUrl`in e}function H(e){return`provider`in e}function U(e){let t=nn.safeParse(e);if(!t.success)return t.error.issues.map(e=>`${e.path.join(`.`)||`config`}: ${e.message}`);let n=an(zt,t.data),r=[];for(let[e,i]of Object.entries(t.data.models??{})){if(e===`codex`||e===`claude`||e===`custom`){r.push(`models.${e}: reserved agent name`);continue}if(H(i)){let t=n.models?.[i.model];t&&!V(t)&&r.push(`models.${e}: alias target "${i.model}" is itself a config entry`)}}return r}function rn(e){if(!x.existsSync(e))return null;try{return JSON.parse(x.readFileSync(e,`utf8`))}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`Invalid JSON in ${e}: ${n}`)}}function an(e,t){if(!t||typeof t!=`object`||Array.isArray(t))return t??e;let n={...e},r=e;for(let[e,i]of Object.entries(t))n[e]=i&&typeof i==`object`&&!Array.isArray(i)&&r?.[e]&&typeof r[e]==`object`?an(r[e],i):i;return n}function W(){return S.join(r(),`config.json`)}function on(e){let t=s(e),n=zt;for(let e of[W(),S.join(t,`coder.config.json`)]){let t=rn(e);if(!t)continue;let r=U(t);if(r.length)throw Error(`Invalid config in ${e}:\n ${r.join(`
|
|
10
|
+
`)}`);n=an(n,t)}let r=U(n);if(r.length)throw Error(`Invalid merged config:\n ${r.join(`
|
|
11
|
+
`)}`);return n}function sn(e){return e.replace(/\/+$/,``).replace(/\/(chat\/completions|completions|responses)$/,``)}function cn(e,t,n){let r=[S.join(s(e),`coder.config.json`),W()];for(let e of r){let r;try{r=rn(e)}catch{continue}if(r?.models?.[t])return Object.assign(r.models[t],n),!U(r).length&&(x.writeFileSync(e,`${JSON.stringify(r,null,2)}\n`,`utf8`),!0)}return!1}function ln(e){return/\/(chat\/completions|completions|responses)\/*$/.test(e)}function un(e,t){let n=sn(e);return ln(e)||/\/v\d+(alpha|beta)?$/.test(n)?[`${n}/${t}`]:[`${n}/${t}`,`${n}/v1/${t}`]}function dn(e,t,n){let r=t?e.models?.[t]:void 0;if(!t||!r||!V(r))return null;let i=`coder-${t}`;return{model:r.model,modelProvider:i,configOverrides:{[`model_providers.${i}`]:{name:t,base_url:n?.url??sn(r.baseUrl),...r.envKey&&!n?{env_key:r.envKey}:{},wire_api:`responses`}}}}function fn(e){return e?L[e]??e:null}function pn(e){return e in L||e in z}function mn(e,t){return!!(t&&e.models?.[t]?.disabled)}function hn(e,t){if(mn(e,t))throw Error(`model "${t}" is disabled in config`)}function gn(e,t){if(!e)return null;let n=String(e).trim().split(`:`).map(e=>e.trim());if(!n.length||n.length>3||n.some(e=>!e))throw Error(`Invalid agent spec "${e}".`);let r=null,i=null,a=null,o=e=>R.has(e)||B.has(e);for(let t of n)if(t===`codex`||t===`claude`||t===`custom`){if(r)throw Error(`Invalid agent spec "${e}".`);r=t}else if(o(t)&&!a)a=t;else if(!i)i=t;else throw Error(`Invalid agent spec "${e}".`);let s=i?t.models?.[i]:void 0;if(s&&H(s)){if(s.disabled)throw Error(`model "${i}" is disabled in config`);if(r&&r!==s.provider)throw Error(`Alias "${i}" runs on ${s.provider}, not ${r}.`);r=s.provider,a=a??s.effort??null,i=s.model}r||=i&&i in z?`claude`:i&&s&&V(s)?`custom`:`codex`;let c=t.agents[r]??{},l=i??c.model??null;return hn(t,l),{agent:r,model:l,effort:a??c.effort??null}}function _n(e){let t=W();return x.mkdirSync(S.dirname(t),{recursive:!0}),x.writeFileSync(t,`${JSON.stringify(e,null,2)}\n`,`utf8`),t}function vn(e){return typeof e==`string`?e:Array.isArray(e)?e.map(e=>typeof e?.text==`string`?e.text:``).join(``):e==null?``:JSON.stringify(e)}function yn(e){if(!e||typeof e!=`object`)return null;let t=e=>typeof e==`number`&&Number.isFinite(e)?e:0,n=t(e.input_tokens),r=t(e.cache_read_input_tokens)+t(e.cache_creation_input_tokens),i=t(e.output_tokens);return{input:n,cachedInput:r,output:i,total:n+r+i}}function bn(){let e=w(`claude`,[`--version`],{encoding:`utf8`});return e.error||e.status!==0?{available:!1,detail:`claude CLI not found on PATH (npm install -g @anthropic-ai/claude-code)`}:{available:!0,detail:String(e.stdout||``).trim()}}function xn(){let e=w(`claude`,[`auth`,`status`,`--json`],{encoding:`utf8`});if(e.error||e.status!==0)return{loggedIn:!1,detail:`not logged in`};try{let t=JSON.parse(String(e.stdout||``));return t.loggedIn?{loggedIn:!0,detail:[t.email,t.subscriptionType].filter(Boolean).join(`, `)||`logged in`}:{loggedIn:!1,detail:`not logged in`}}catch{return{loggedIn:!1,detail:`unknown`}}}async function Sn(e,t){let n=t.resumeSessionId??fe(),r=[`-p`,t.prompt,`--output-format`,`stream-json`,`--verbose`];r.push(t.resumeSessionId?`--resume`:`--session-id`,n),t.model&&r.push(`--model`,t.model),t.effort&&r.push(`--effort`,t.effort);let i=t.permissions??`auto`;if(i===`auto`&&t.approvalJobId){let n=JSON.stringify({mcpServers:{coder:{type:`stdio`,command:process.execPath,args:[p,`_mcp`,t.approvalJobId,`--cwd`,e]}}});r.push(`--permission-mode`,`default`,`--mcp-config`,n,`--permission-prompt-tool`,`mcp__coder__approval_prompt`)}else r.push(...Vt[i]??Vt.auto);let a=Wt(i,e,t.allowedNetworkHosts??[]);return a&&r.push(`--settings`,a),t.onProgress?.({message:`claude turn started (session ${n})`,threadId:n}),new Promise((i,a)=>{let o=C(`claude`,r,{cwd:e,stdio:[`ignore`,`pipe`,`pipe`]}),s=``,c=``,l=null,u=n,d=e=>{if(!(!e||typeof e!=`object`))if(t.onHeartbeat?.(),e.type===`system`&&e.subtype===`init`&&e.session_id)u=e.session_id;else if(e.type===`assistant`)for(let n of e.message?.content??[])n?.type===`tool_use`&&t.onProgress?.({message:`${n.name} ${JSON.stringify(n.input??{})}`,threadId:u});else if(e.type===`user`){for(let n of e.message?.content??[])if(n?.type===`tool_result`){let e=vn(n.content).trim();e&&t.onProgress?.({message:e,threadId:u})}}else e.type===`result`&&(l=e,e.session_id&&(u=e.session_id))};o.stdout.on(`data`,e=>{s+=e;let t;for(;(t=s.indexOf(`
|
|
12
|
+
`))>=0;){let e=s.slice(0,t).trim();if(s=s.slice(t+1),e)try{d(JSON.parse(e))}catch{}}}),o.stderr.on(`data`,e=>{c+=e});let f=()=>{o.kill(`SIGTERM`),process.exit(143)};process.on(`SIGTERM`,f),o.on(`error`,e=>{process.removeListener(`SIGTERM`,f),a(Error(`claude spawn failed: ${e.message}`))}),o.on(`close`,e=>{process.removeListener(`SIGTERM`,f);let n=s.trim();if(n)try{d(JSON.parse(n))}catch{}let r=l?.result??``,a=e!==0||l?.is_error===!0||l==null;i({status:+!!a,threadId:l?.session_id??u,turnId:null,finalMessage:r,tokens:yn(l?.usage),model:l?.modelUsage&&Object.keys(l.modelUsage).join(`+`)||t.model||null,error:a?{message:r||c.trim()||`claude exited ${e}`}:null})})})}function Cn(e){w(`claude`,[`plugin`,`marketplace`,`remove`,`coder-plugins`],{encoding:`utf8`});let t=w(`claude`,[`plugin`,`marketplace`,`add`,e],{encoding:`utf8`}),n=w(`claude`,[`plugin`,`install`,`coder@coder-plugins`],{encoding:`utf8`}),r=t.status===0&&n.status===0;return{marketplace:e,installed:r,note:r?`Plugin installed; restart any running Claude Code session to load it.`:`Automatic install failed (${(n.stderr||t.stderr||`claude not found`).trim()}); run: claude plugin marketplace add "${e}" && claude plugin install coder@coder-plugins`}}function wn(){return S.join(se.homedir(),`.agents`,`skills`,`coder`)}function Tn(){try{let e=x.readFileSync(S.join(wn(),`SKILL.md`),`utf8`);return/^\s*version:\s*(\S+)/m.exec(e)?.[1]??null}catch{return null}}function En(e){let t=wn();try{let n=S.join(e,`plugins`,`agents`,`skills`,`coder`);x.rmSync(t,{recursive:!0,force:!0}),x.mkdirSync(t,{recursive:!0}),x.cpSync(n,t,{recursive:!0});let r=S.join(t,`SKILL.md`),i=x.readFileSync(r,`utf8`).replace(`
|
|
13
|
+
---
|
|
14
|
+
`,`\nmetadata:\n version: ${_()}\n---\n`);return x.writeFileSync(r,i),{marketplace:t,installed:!0,note:`Skill installed to ~/.agents/skills/coder; restart running sessions to load it.`}}catch(e){return{marketplace:t,installed:!1,note:`Skill install failed: ${e instanceof Error?e.message:String(e)}`}}}function Dn(e){if(e.available)return null;let t=w(`npm`,[`install`,`-g`,`@openai/codex@latest`],{encoding:`utf8`});return t.status===0?{installed:!0,note:`codex CLI installed (runs your custom models; no login needed for them)`}:{installed:!1,note:`custom models run on the codex CLI and it is not installed; auto-install failed: ${(t.stderr||`npm not found`).trim()}. Run: npm install -g @openai/codex`}}function On(e){let t=/(\d+\.\d+\.\d+)/.exec(String(e??``));return t?t[1]:null}function kn(e){if(!e.available)return null;let t=On(e.detail);if(!t||We(t,`0.144.0`)>=0)return null;let n=w(`codex`,[`update`],{encoding:`utf8`});return n.status!==0&&(n=w(`npm`,[`install`,`-g`,`@openai/codex@latest`],{encoding:`utf8`})),n.status===0?{updated:!0,from:t}:{updated:!1,from:t,note:`codex ${t} is too old for the default GPT-5.6 model (needs >= 0.144.0); auto-update failed: ${(n.stderr||`codex/npm not found`).trim()}. Run: codex update`}}const An=/usage|quota|rate.?limit|429|401|unauthorized|not authenticated|login|insufficient|exhausted|not available|ENOENT/i,jn=`CODER_WORKER`;var G=class extends Error{code;hint;taskId;payload;approval;result;runId;constructor(e,t,n={}){super(t),this.name=`CoderError`,this.code=e,Object.assign(this,n)}},Mn=class extends Error{agent;detail;constructor(e,t){super(t),this.agent=e,this.detail=t}};function Nn(e,t){let n=e.agent,r=!!n,i=e.model,a=e.effort,o=e=>{let n=e?t.models?.[e]:void 0;return n&&H(n)?n:void 0},s=e=>{let n=e?t.models?.[e]:void 0;return n&&V(n)?n:void 0};if(o(i)){let e;try{e=gn(i,t)}catch(e){throw new G(`invalid-option`,e instanceof Error?e.message:String(e))}e&&(r||(n=e.agent),i=e.model??void 0,a=a??e.effort??void 0)}if(!n&&i&&(i in z?n=`claude`:i in L?n=`codex`:s(i)&&(n=`custom`)),n=n??t.chain[0]??`codex`,n!==`codex`&&n!==`claude`&&n!==`custom`){let e=n in L||n in z||n in(t.models??{})?` "${n}" is a model; use --model ${n}.`:``;throw new G(`invalid-option`,`Invalid --agent "${n}". Use codex, claude, or custom.${e}`)}let c=t.agents[n]??{},l=i??c.model??null,u=a??c.effort??null;if(o(l)){let e;try{e=gn(l,t)}catch(e){throw new G(`invalid-option`,e instanceof Error?e.message:String(e))}e&&(r||(n=e.agent),l=e.model,u=a??e.effort??u)}let d=e.permissions??c.permissions??`auto`;try{hn(t,l)}catch(e){throw new G(`invalid-option`,e instanceof Error?e.message:String(e))}if(n===`custom`){let e=Object.entries(t.models??{}).filter(([,e])=>V(e)).map(([e])=>e);if(!l&&e.length===1&&(l=e[0]),!l||!s(l))throw new G(`invalid-option`,l?`No custom model named "${l}". Configured: ${e.join(`, `)||`none`}.`:`No custom model to run: pass --model <name> or set agents.custom.model.`,{hint:`Add one: coder model add <name> --base-url <url> --model <id>`})}let f=n===`claude`?`claude`:`codex`;if(!(d in Bt))throw new G(`invalid-option`,`Invalid --permissions "${d}". Use one of: ${Object.keys(Bt).join(`, `)}`);if(f===`codex`&&u&&!R.has(u))throw new G(`invalid-option`,`Invalid codex --effort "${u}". Use one of: ${[...R].join(`, `)}`);if(f===`claude`&&u&&!B.has(u))throw new G(`invalid-option`,`Invalid claude --effort "${u}". Use one of: ${[...B].join(`, `)}`);return{engine:f,agent:n,model:l,effort:u,permissions:d}}function Pn(e,t){return e===`read-only`&&Ht.test(t??``)}function Fn(e,n){let r=o(e,n),i=x.openSync(S.join(r,`worker.log`),`a`),a=C(b.execPath,[p,`_worker`,n,`--cwd`,e],{cwd:e,detached:!0,stdio:[`ignore`,i,i],env:{...b.env,[jn]:`1`}});a.unref(),x.closeSync(i),t(e,n,{pid:a.pid??null})}async function In(e,r,i,a){let s=i.cwd,l=r.engine===`codex`?I(s):bn(),u=r.model?e.models?.[r.model]:void 0;if(!l.available&&u&&V(u)){let e=Dn(l);i.onInstallNote?.(e.note),l=I(s)}if(!l.available)throw new Mn(r.agent,l.detail);let d=null;a.resume&&(d=n(s,a.resume)?.threadId??a.resume);let f=ie(),ee=t(s,f,{status:`queued`,kind:`task`,name:a.name??null,system:i.system??null,agent:r.agent,engine:r.engine,prompt:i.prompt,model:r.model,effort:r.effort,permissions:r.permissions,resumeThreadId:d,cwd:s,background:!i.wait,...a.simulateApproval?{simulateApproval:!0}:{},...i.flowRunId?{flowRunId:i.flowRunId}:{}});Fn(s,f);let p=2**53-1,m=()=>c(s,f,p).filter(e=>e.phase!==`starting`).length,g=Date.now()+15e3,_=ee,v=null,y=null;for(;Date.now()<(y??g)&&(_=h(s,f)??_,_.status!==`failed`&&_.status!==`completed`);){if(_.threadId&&v===null&&(v=m(),y=Date.now()+5e3),v!==null&&m()>v){_=h(s,f)??_;break}await new Promise(e=>setTimeout(e,150))}if(_.status===`failed`){let e=M(S.join(o(s,f),`result.json`))?.error?.message??``,t=c(s,f,5).map(e=>e.message??``).join(`
|
|
15
|
+
`),n=e||t;throw Pn(r.permissions,n)?new G(`read-only-unavailable`,n):An.test(n)?new Mn(r.agent,n):new G(`startup-failed`,n,{taskId:f})}return{taskId:f,job:_,agent:r.agent,startupCheck:_.threadId?`passed`:`pending`}}function Ln(e,t,n,r,i){return{error:`${e} failed to start: ${t}`,fallback:{action:`run-native-subagent`,reason:`no-engine-available`,permissions:n,note:`Every coder engine failed to start. Spawn your own native subagent and forward the task verbatim; tell it to never run git write operations (commit, checkout, stash, reset, push, ...) and to honor the permissions.`,...r?{system:r}:{},task:i}}}async function Rn(e){if(b.env.CODER_WORKER)throw new G(`nested-dispatch`,`Nested dispatch refused: this shell is already inside a coder task. Do the work yourself, directly in this session - ignore any skill or instruction telling you to orchestrate via the coder CLI.`);if(!e.prompt.trim())throw new G(`invalid-option`,`Missing task text.`,{hint:[`Usage: coder run "<task text>"`,`Help: coder task run --help`]});let t=on(e.cwd),n={agent:e.agent,model:e.model,effort:e.effort,permissions:e.permissions},r={name:e.name,resume:e.resume,simulateApproval:e.simulateApproval};for(;;){let i=Nn(n,t);try{return await In(t,i,e,r)}catch(a){if(!(a instanceof Mn))throw a;let o=t.chain[t.chain.indexOf(a.agent)+1];if(!o){let t=Ln(a.agent,a.detail,i.permissions,e.system,e.prompt);throw new G(`chain-exhausted`,t.error,{payload:t})}e.onFallback?.({agent:a.agent,detail:a.detail,next:o}),n={agent:o,permissions:e.permissions},r={name:void 0,resume:void 0,simulateApproval:void 0}}}}function zn(e,t){if(t.status!==`failed`)return;let n=t.result;if(!n||!An.test(n.error?.message??``)||!(!n.touchedFiles?.length&&!n.fileChanges?.length&&!n.commandExecutions?.length))return;let r=on(e).chain;return r[r.indexOf(t.job.agent)+1]}function Bn(e,t){return M(S.join(o(e,t),`result.json`))}function Vn(e,t,n=0){return n===0?[]:c(e,t,n===`all`?2**53-1:n)}function Hn(e,t,n={}){let r=h(e,t);if(!r)throw Error(`No task found for "${t}".`);return{taskId:t,status:r.status,result:Bn(e,t),steps:Vn(e,t,n.tail),turns:l(e,t),job:r}}async function Un(e,t,n={}){let r=h(e,t);if(!r)throw Error(`No task found for "${t}".`);let i=await ft(e,r);if(i.reason===`approval`){let e=i.approval;throw new G(`approval-pending`,`Approval needed for task ${t}: ${e.summary}`,{taskId:t,approval:e})}n.onSettle?.();let a=i.job;return{taskId:t,status:a.status,result:Bn(e,t),steps:Vn(e,t,n.tail),turns:l(e,t),job:a}}const Wn=[`.ts`,`.mjs`,`.js`];function Gn(e,t){let n=[];try{n=x.readdirSync(e)}catch{return[]}let r=[];for(let i of n.sort()){let n=S.extname(i);Wn.includes(n)&&r.push({name:S.basename(i,n),path:S.join(e,i),scope:t})}return r}function Kn(e){let t=s(e),n=[],i=S.resolve(e);for(;n.push({dir:S.join(i,`.coder`,`flows`),scope:`workspace`}),i!==t&&S.dirname(i)!==i;)i=S.dirname(i);return n.push({dir:S.join(r(),`flows`),scope:`global`}),n}function qn(e){let t=new Set,n=[];for(let{dir:r,scope:i}of Kn(e))for(let e of Gn(r,i))t.has(e.name)||(t.add(e.name),n.push(e));return n}function Jn(e){return e.includes(`/`)||Wn.includes(S.extname(e))}function Yn(e,t){if(Jn(e)){let n=S.resolve(t,e);if(x.existsSync(n))return{name:S.basename(n,S.extname(n)),path:n};throw Error(`Flow file not found: ${e}`)}let n=qn(t).find(t=>t.name===e);if(!n)throw Error(`No flow named "${e}". Run \`coder flow discover\` to see available flows.`);return{name:n.name,path:n.path}}function Xn(e,t,n={}){if(t.length)try{C(b.execPath,[p,`_archiveSweep`,`--cwd`,e,...n.flows?[`--flows`]:[],...t],{detached:!0,stdio:`ignore`}).unref()}catch{}}async function Zn(e){let{options:t,positionals:r}=g(e,T.object({cwd:ne,flows:te})),i=Be(t);for(let e of r){if(t.flows){let t=Z(e);t&&zr(t);continue}let r=n(i,e);r&&re(i,r)}}async function Qn(e){let{options:t,positionals:n}=g(e,T.object({...v,"all-stopped":te}));ze(n,1,`task archive`);let r=Be(t);if(t[`all-stopped`]){let e=u(r).filter(e=>a.includes(e.status));for(let t of e)re(r,t);let n=e.map(e=>e.id);if(t.json){k({archived:n,count:n.length});return}b.stdout.write(n.length?`Archived ${n.length} stopped task${n.length===1?``:`s`}.\n`:`${E.dim(`No stopped tasks to archive.`)}\n`);return}let i=n[0];i||O(`Missing task id.`,{hint:[`Archive one: coder task archive <task-id>`,`Archive all stopped: coder task archive --all-stopped`]});let o=Ve(r,i);if(re(r,o),t.json){k({taskId:o.id,archived:!0});return}b.stdout.write(`Archived task ${E.cyan(o.id)}.\n`)}async function $n(e,n){let r=n.engine===`claude`?{detail:`claude worker terminated`}:await It(e,{threadId:n.threadId,turnId:n.turnId});if(n.pid&&n.status===`running`)try{b.kill(n.pid,`SIGTERM`)}catch{}return t(e,n.id,{status:`cancelled`,completedAt:new Date().toISOString()}),{taskId:n.id,status:`cancelled`,interrupt:r.detail}}async function er(e){let{options:t,positionals:n}=g(e,T.object(v));ze(n,1,`task stop`);let r=Be(t),i=Ve(r,n[0]),{interrupt:a}=await $n(r,i);if(t.json){k({taskId:i.id,status:`cancelled`,interrupt:a});return}b.stdout.write(`Stopped task ${E.cyan(i.id)} ${E.dim(`(${a})`)}\n`)}function tr(e){return typeof e!=`object`||!e?JSON.stringify(e)??`null`:Array.isArray(e)?`[${e.map(tr).join(`,`)}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${tr(e[t])}`).join(`,`)}}`}function nr(e,t){return de.createHash(`sha256`).update(`${e}\0${tr(t)}`).digest(`hex`)}function K(e){return x.existsSync(e)?x.readFileSync(e,`utf8`).split(/\r?\n/).filter(Boolean).map(e=>{try{return JSON.parse(e)}catch{return null}}).filter(e=>e!==null):[]}var rr=class{file;recorded;seq=0;constructor(e,t){this.file=t,this.recorded=e.map(e=>({...e})),x.writeFileSync(t,``,`utf8`)}write(e){e.seq=this.seq++,x.appendFileSync(this.file,`${JSON.stringify(e)}\n`,`utf8`)}replay(e){let t=this.recorded.find(t=>!t.consumed&&t.fingerprint===e);if(!t)return null;t.consumed=!0;let{consumed:n,...r}=t;return this.write(r),r}record(e){this.write({...e,seq:0})}};const ir=globalThis,q=ir.__coderFlowCtxALS??=new pe,J=ir.__coderFlowScopeALS??=new pe;function ar(){return J.getStore()?.args}function or(){return J.getStore()?.depth??0}var sr=class{limit;active=0;queue=[];constructor(e){this.limit=e}async run(e){this.active<this.limit?this.active+=1:await new Promise(e=>this.queue.push(e));try{return await e()}finally{let e=this.queue.shift();e?e():--this.active}}};function cr(e,t){return t?e?{input:e.input+t.input,cachedInput:e.cachedInput+t.cachedInput,output:e.output+t.output,total:e.total+t.total}:{...t}:e}function lr(e,t){if(!t.tokens)return;let n=t.model??`default`;e.ledger[n]=cr(e.ledger[n]??null,t.tokens)}function ur(e){return!!e&&typeof e.safeParse==`function`}async function dr(e){try{let t=await import(`zod`);if(typeof t.toJSONSchema==`function`)return t.toJSONSchema(e)}catch{}return null}async function fr(e){let t=await dr(e);return`Reply with ONLY a single JSON object ${t?`matching this JSON Schema:\n${JSON.stringify(t,null,2)}`:`matching the requested shape`}\nNo prose, no markdown fences — just the JSON object.`}function pr(e){let t=e.trim(),n=t.match(/```(?:json)?\s*([\s\S]*?)```/i);n&&(t=n[1].trim());let r=t.indexOf(`{`);if(r===-1)throw Error(`no JSON object found in reply`);let i=0,a=!1,o=!1;for(let e=r;e<t.length;e+=1){let n=t[e];if(a){o?o=!1:n===`\\`?o=!0:n===`"`&&(a=!1);continue}if(n===`"`)a=!0;else if(n===`{`)i+=1;else if(n===`}`&&(--i,i===0))return JSON.parse(t.slice(r,e+1))}throw Error(`unterminated JSON object in reply`)}function mr(e,t){if(!ur(e))return{ok:!0,data:t};let n=e.safeParse(t);if(n.success)return{ok:!0,data:n.data};let r=n.error?.issues??n.error?.errors??[];return{ok:!1,errors:Array.isArray(r)?r.map(e=>`${(e.path??[]).join(`.`)||`(root)`}: ${e.message}`).join(`; `):String(n.error)}}function hr(e,t,n){return{cwd:t,agent:e.agent,model:e.model,effort:e.effort,permissions:e.permissions,name:e.name,system:e.system,wait:!0,flowRunId:n?.runId}}async function gr(e,t,n,r){let i=t.cwd?S.resolve(t.cwd):n?.cwd??b.cwd(),a;for(;;){let o=await Rn({prompt:e,...hr(t,i,n),...a?{agent:a,model:void 0,effort:void 0,resume:void 0}:{resume:r??t.resume},onFallback:e=>Er(`${e.agent} failed to start — falling back to ${e.next} (${e.detail.replace(/\s+/g,` `).slice(0,140)})`)});n?.running.add(o.taskId);let s=h(i,o.taskId),c=s?Se(s):void 0;n?.hooks.onTaskStart?.({taskId:o.taskId,name:t.name,prompt:e,agent:c,depth:or()});let l;try{l=await Un(i,o.taskId)}finally{n?.running.delete(o.taskId)}let u=zn(i,l);if(u){n?.hooks.onTaskEnd?.({taskId:o.taskId,status:`failed`,tokens:null}),a=u;continue}return{taskId:o.taskId,status:l.status,output:l.result?.finalMessage||l.result?.error?.message||``,tokens:l.result?.tokens??null,model:l.result?.model??l.job.model??null}}}async function _r(e,t,n){let r=e;if(t.returns&&(r=`${e}\n\n${await fr(t.returns)}`),n?.dryRun){b.stdout.write(`\n[dry-run] task${t.name?` (${t.name})`:``}:\n${r}\n`);let e={...t,returns:t.returns?`<schema>`:void 0};return b.stdout.write(`[dry-run] opts: ${JSON.stringify(e)}\n`),{taskId:`dry`,status:`completed`,output:`[dry-run]`,data:void 0,tokens:null,model:t.model??null}}let i=await gr(r,t,n);if(i.status!==`completed`){let e={...i,data:void 0};throw new G(`task-failed`,`Task ${i.taskId} ${i.status}: ${i.output||`no output`}`,{taskId:i.taskId,result:e})}let a=i.output,o=i.tokens,s;if(t.returns){let e;try{e=mr(t.returns,pr(a))}catch(t){e={ok:!1,errors:t instanceof Error?t.message:String(t)}}if(e.ok)s=e.data;else{let r=await gr(`Your previous reply did not match the required format: ${e.errors}\n\n${await fr(t.returns)}`,t,n,i.taskId);a=r.output||a,o=cr(o,r.tokens);try{let e=mr(t.returns,pr(a));if(!e.ok)throw Error(e.errors);s=e.data}catch(e){let t={taskId:i.taskId,status:`completed`,output:a,data:void 0,tokens:o,model:i.model};throw new G(`task-failed`,`Task ${i.taskId} produced no valid structured output: ${e instanceof Error?e.message:String(e)}`,{taskId:i.taskId,result:t})}}}return{taskId:i.taskId,status:`completed`,output:a,data:s,tokens:o,model:i.model}}async function vr(e){if(e)return await dr(e)??`<schema>`}async function yr(e,t={}){let n=q.getStore();if(!n)return _r(e,t);let r=nr(`task`,{prompt:e,agent:t.agent,model:t.model,effort:t.effort,permissions:t.permissions,name:t.name,system:t.system,resume:t.resume,cwd:t.cwd,returns:await vr(t.returns)}),i=n.journal.replay(r);if(i)return i.result;if(n.taskCount+=1,n.taskCount>n.maxTasks)throw Error(`Flow exceeded --max-tasks (${n.maxTasks}). Raise it with --max-tasks, or fix a runaway loop; the run is resumable.`);return n.semaphore.run(async()=>{let i=new Date().toISOString(),a;try{a=await _r(e,t,n)}catch(e){let t=e instanceof G?e.result:void 0;throw t&&n.hooks.onTaskEnd?.({taskId:t.taskId,status:t.status===`completed`?`failed`:t.status,tokens:t.tokens}),e}return lr(n,a),n.dryRun||n.hooks.onTaskEnd?.({taskId:a.taskId,status:a.status,tokens:a.tokens}),n.journal.record({kind:`task`,fingerprint:r,result:a,taskId:a.taskId,tokens:a.tokens,startedAt:i,endedAt:new Date().toISOString()}),a})}const br=262144;let xr=0;function Sr(e){let t=[];for(let n=e;;){t.push(S.join(n,`node_modules`,`.bin`));let e=S.dirname(n);if(e===n)break;n=e}let n=b.platform===`win32`?`;`:`:`;return{...b.env,PATH:[...t,b.env.PATH??``].join(n)}}async function Cr(e,t){return new Promise(n=>{let r=C(e,{shell:!0,cwd:t,env:Sr(t)}),i=``,a=e=>{i.length>=br||(i+=e,i.length>=br&&(i=`${i.slice(0,br)}\n... [gate output truncated]`))};r.stdout?.on(`data`,a),r.stderr?.on(`data`,a),r.on(`error`,e=>n({ok:!1,code:1,output:String(e.message??e).trim()})),r.on(`close`,e=>n({ok:e===0,code:e??0,output:i.trim()}))})}async function wr(e,t={}){let n=q.getStore(),r=t.cwd?S.resolve(t.cwd):n?.cwd??b.cwd();if(!n)return Cr(e,r);let i=nr(`gate`,{cmd:e,cwd:t.cwd}),a=n.journal.replay(i);if(a)return a.result;if(n.dryRun){b.stdout.write(`\n[dry-run] gate: ${e}\n`);let t={ok:!0,code:0,output:``};return n.journal.record({kind:`gate`,fingerprint:i,result:t,startedAt:new Date().toISOString(),endedAt:new Date().toISOString()}),t}let o=new Date().toISOString(),s=`gate-${b.pid}-${xr+=1}`,c=or();n.hooks.onGateStart?.({gateId:s,cmd:e,depth:c});let l=await Cr(e,r);return n.hooks.onGate?.({gateId:s,cmd:e,ok:l.ok,code:l.code,depth:c}),n.journal.record({kind:`gate`,fingerprint:i,result:l,startedAt:o,endedAt:new Date().toISOString()}),l}async function Tr(e,...t){return Promise.all(e.map(async(e,n)=>{let r=e;for(let i of t)try{r=await i(r,e,n)}catch{return null}return r}))}function Er(e){let t=q.getStore();if(t)try{x.appendFileSync(S.join(t.runDir,`flow.log`),`${JSON.stringify({at:new Date().toISOString(),message:e})}\n`,`utf8`)}catch{}t?.hooks.onLog?t.hooks.onLog(e,or()):(b.stderr.isTTY||!t)&&b.stderr.write(`[flow] ${e}\n`)}const Dr=oe(import.meta.url);function Or(e){let t=S.dirname(ce(import.meta.url));for(;S.basename(t)!==`dist`&&S.dirname(t)!==t;)t=S.dirname(t);return S.basename(t)===`dist`?le(S.join(t,e)).href:null}function kr(e){if(!(e===`@wular/coder`||e===`@wular/coder/flow`||e===`zod`||e.startsWith(`zod/`)))return null;try{return le(Dr.resolve(e)).href}catch{}return e===`@wular/coder/flow`?Or(`flow/index.js`):e===`@wular/coder`?Or(`sdk.js`):null}const Ar=/(\bfrom\s+|\bimport\s+|\bimport\s*\(\s*)(['"])([^'"]+)\2/g;function jr(e){return e.replace(Ar,(e,t,n,r)=>{let i=kr(r);return i?`${t}${n}${i}${n}`:e})}async function Mr(e,t,n){try{return await import(le(e).href)}catch(e){let r=e instanceof Error?e.message:String(e);throw t===`.ts`&&!b.versions?.bun&&/Unknown file extension|Unexpected token|SyntaxError|Cannot parse|import type|interface/i.test(r)?Error(`Could not run ${S.basename(n)}: TypeScript flows need bun. Run under \`bun\`, or write the flow as .mjs/.js.`):e}}async function Nr(e){let t=S.extname(e),n;try{n=x.readFileSync(e,`utf8`)}catch{throw Error(`Cannot read flow file: ${e}`)}let r=jr(n);if(r===n)return Mr(e,t,e);let i=S.dirname(e);try{for(let e of x.readdirSync(i)){if(!e.startsWith(`.__coderflow_`))continue;let t=S.join(i,e);Date.now()-x.statSync(t).mtimeMs>6e5&&x.unlinkSync(t)}}catch{}let a=`${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`,o=S.join(i,`.__coderflow_${a}${t}`),s=`__coderflow_loaded_${a}`,c=new Promise(e=>{globalThis[s]=e});x.writeFileSync(o,`globalThis[${JSON.stringify(s)}]?.();${r}`,`utf8`);let l=Mr(o,t,e);try{await Promise.race([c,l.then(()=>void 0,()=>void 0)])}finally{delete globalThis[s];try{x.unlinkSync(o)}catch{}}return await l}async function Pr(e,t){let n=J.getStore();n.args=t??{};let r=await Nr(e),i=r.args,a=n.args;if(ur(i)){let e=i.safeParse(t??{});if(!e.success){let e=mr(i,t??{});throw Error(`Invalid flow args: ${e.errors??`validation failed`}`)}a=e.data,n.args=a}let o=r.default;return typeof o==`function`?o(a):o}async function Fr(e,t){let n=q.getStore(),r=Yn(e,n?.cwd??b.cwd());if(!n)return J.run({args:t??{},depth:0},()=>Pr(r.path,t));let i=J.getStore();if(i&&i.depth>=1)throw Error(`flow("${e}") nesting is one level deep; a sub-flow cannot call flow().`);let a=nr(`flow`,{name:r.name,args:t??{}}),o=n.journal.replay(a);if(o)return o.result;let s=new Date().toISOString();n.hooks.onFlowStart?.({name:r.name,depth:(i?.depth??0)+1});let c=await J.run({args:t??{},depth:(i?.depth??0)+1},()=>Pr(r.path,t));return n.journal.record({kind:`flow`,fingerprint:a,result:c,startedAt:s,endedAt:new Date().toISOString()}),c}function Ir(){return`flow-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Y(){return S.join(r(),`state`,`global`,`flows`)}function Lr(){return S.join(r(),`state`,`global`,`flows-archived`)}function X(e){ae(e,`flow run id`);let t=S.join(Y(),e);if(x.existsSync(S.join(t,`flow.json`)))return t;let n=S.join(Lr(),e);return x.existsSync(S.join(n,`flow.json`))?n:t}function Rr(e){if(e.archived)return e;let t={...e,archived:!0,archivedAt:new Date().toISOString()};return Q(X(e.runId),t),t}function zr(e){let t=Rr(e),n=X(e.runId),r=S.join(Lr(),e.runId);if(n!==r)try{x.mkdirSync(Lr(),{recursive:!0}),x.renameSync(n,r)}catch{}return t}function Br(e){let t=X(e.runId),n=S.join(Y(),e.runId);if(t!==n)try{x.mkdirSync(Y(),{recursive:!0}),x.renameSync(t,n)}catch{}let r={...e,archived:void 0,archivedAt:void 0};return Q(X(e.runId),r),r}function Vr(e){let t=X(e);return x.existsSync(S.join(t,`flow.json`))?(x.rmSync(t,{recursive:!0,force:!0}),!0):!1}function Hr(e){if(!f(e))return null;let t=S.join(X(e),`flow.json`);if(!x.existsSync(t))return null;try{return JSON.parse(x.readFileSync(t,`utf8`))}catch{return null}}function Ur(e){return e.status!==`running`||!e.pid||ti(e)?e:(Qr(e.runId,`orchestrator died`),Hr(e.runId)??e)}function Z(e){let t=Hr(e);return t?Ur(t):null}function Q(e,t){x.writeFileSync(S.join(e,`flow.json`),`${JSON.stringify(t,null,2)}\n`,`utf8`)}function Wr(e){let t=[];try{t=x.readdirSync(e)}catch{return[]}let n=[];for(let r of t)try{n.push(Ur(JSON.parse(x.readFileSync(S.join(e,r,`flow.json`),`utf8`))))}catch{}return n}const Gr=(e,t)=>String(t.startedAt).localeCompare(String(e.startedAt));function Kr(){let e=[];for(let t of Wr(Y()))t.archived?zr(t):e.push(t);return e.sort(Gr)}function qr(e){let t=e?.migrate??!0,n=Wr(Lr()),r=new Set(n.map(e=>e.runId));for(let e of Wr(Y()))e.archived&&!r.has(e.runId)&&n.push(t?zr(e):e);return n.sort(Gr)}function Jr(){return[...Kr(),...qr()].sort(Gr)[0]??null}function Yr(e,t=`all`){if(t===0)return[];let n=K(S.join(X(e),`journal.jsonl`)).filter(e=>e.kind===`task`),r=u(b.cwd()),i=new Map(r.map(e=>[e.id,e])),a=e=>e?.name??e?.prompt?.replace(/\s+/g,` `).trim().slice(0,60)??null,o=n.map(e=>{let t=e.taskId?i.get(e.taskId):void 0;return{taskId:e.taskId??null,name:a(t),status:t?.status??e.result?.status??`?`,tokens:e.tokens??null}}),s=new Set(o.map(e=>e.taskId));for(let t of r)t.flowRunId===e&&!s.has(t.id)&&o.push({taskId:t.id,name:a(t),status:t.status,tokens:null});return t===`all`?o:o.slice(-t)}function Xr(e={}){let t;if(e.archived)t=qr();else{let e=[];t=Kr().filter(t=>t.status===`running`||t.status===`queued`||_e(t.endedAt??t.startedAt)<=6e5||(Rr(t),e.push(t.runId),!1)),Xn(b.cwd(),e,{flows:!0})}let n=e.limit===void 0?0:Math.max(0,t.length-e.limit);return{runs:e.limit===void 0?t:t.slice(0,e.limit),clipped:n}}function Zr(e,t={},n){let r,i,a;if(n){let e=Z(n);if(!e)throw Error(`No flow run "${n}".`);e.archived&&Br(e),r=e.name,i=e.script,a=t.args??e.args}else{let n=Yn(e,t.cwd?S.resolve(t.cwd):b.cwd());r=n.name,i=n.path,a=t.args??{}}let o=n??Ir(),s=X(o);x.mkdirSync(s,{recursive:!0});let c={runId:o,name:r,script:i,args:a,status:`running`,startedAt:new Date().toISOString(),concurrency:Math.max(1,t.concurrency??se.cpus().length),maxTasks:Math.max(1,t.maxTasks??se.cpus().length*10),taskCount:0,ledger:{}};return Q(s,c),c}function $(e,t,n){Q(e,{...t,endedAt:new Date().toISOString(),pid:void 0,pidStartedAt:void 0,...n})}function Qr(e,t){let n=Hr(e);!n||n.status!==`running`||$(X(e),n,{status:`failed`,error:t})}const $r=`stop-keep-tasks`;function ei(e){try{return b.kill(e,0),!0}catch{return!1}}function ti(t){if(!t.pid||!ei(t.pid))return!1;let n=e(t.pid),r=Date.parse(t.pidStartedAt??``);return n===null||!Number.isFinite(r)||n<=r+6e4}function ni(e){let t=u(b.cwd()),n=new Map(t.map(e=>[e.id,e])),r=new Set(t.filter(t=>t.flowRunId===e).map(e=>e.id));for(let t of K(S.join(X(e),`journal.jsonl`)))t.kind===`task`&&t.taskId&&r.add(t.taskId);return[...r].filter(e=>{let t=n.get(e);return!!t&&!a.includes(t.status)})}async function ri(e,t=[]){let n=b.cwd(),r=[];for(let i of new Set([...ni(e),...t])){let e=h(n,i);if(!(!e||a.includes(e.status)))try{await $n(n,e),r.push(i)}catch{}}return r}async function ii(e,t={}){let n=e?Z(e):Jr();if(!n)throw new G(`flow-failed`,e?`No flow run "${e}".`:`No flow runs.`,{hint:`Run one: coder flow run <name>`});if(n.status!==`running`)throw new G(`flow-failed`,`Run ${n.runId} is not running.`,{runId:n.runId,hint:`Result: coder flow result ${n.runId}`});let r=X(n.runId);if(!ti(n))return $(r,n,{status:`failed`,error:`orchestrator died`}),{runId:n.runId,status:`failed`,stoppedTasks:[],keptTasks:ni(n.runId)};let i=ni(n.runId),o=S.join(r,$r);t.keepTasks&&x.writeFileSync(o,``,`utf8`);try{b.kill(n.pid,`SIGINT`);let e=Z(n.runId);for(let t=0;t<25&&e?.status===`running`;t+=1)await new Promise(e=>setTimeout(e,200)),e=Z(n.runId);if(!e||e.status===`running`)throw new G(`flow-failed`,`Run ${n.runId} did not stop within 5s.`,{runId:n.runId,hint:`Check it: coder flow result ${n.runId}`});let t=b.cwd(),r=[],o=[];for(let e of i){let n=h(t,e);n&&(n.status===`cancelled`?r.push(e):a.includes(n.status)||o.push(e))}return{runId:n.runId,status:e.status,stoppedTasks:r,keptTasks:o}}finally{if(t.keepTasks)try{x.unlinkSync(o)}catch{}}}async function*ai(e,t,n={}){let r=S.join(X(e),`events.jsonl`),i=n.tail??`all`,a=0;if(i!==`all`)try{a=Math.max(0,x.readFileSync(r,`utf8`).split(`
|
|
16
|
+
`).length-1-i)}catch{}let o=Qe(r),s=()=>{let e=[];for(let t of o()){if(a>0){--a;continue}try{e.push(JSON.parse(t))}catch{}}return e},c=Z(e);for(;!c||c.status===`running`;){yield*s();let n=c?.pid?!ti(c):t!==void 0&&!ei(t);if(c&&(c.pid||t!==void 0)&&n){Qr(e,`orchestrator died`);break}await new Promise(e=>setTimeout(e,400)),c=Z(e)??c}yield*s()}function oi(e,t,n,r){let i={...Zr(e,t,r),pid:b.pid,pidStartedAt:new Date().toISOString()},{runId:a}=i,o=X(a);Q(o,i);let s=S.join(o,`journal.jsonl`),c=r?K(s):[],l=new rr(c,s),u={runId:a,runDir:o,cwd:t.cwd?S.resolve(t.cwd):b.cwd(),journal:l,semaphore:new sr(i.concurrency),maxTasks:i.maxTasks,dryRun:t.dryRun??!1,ledger:{},running:new Set,taskCount:0,stopping:!1,hooks:n};return{started:{runId:a,runDir:o,ctx:u,markStopped:()=>{u.stopping=!0,$(o,i,{status:`stopped`,taskCount:u.taskCount,ledger:u.ledger})}},args:i.args,name:i.name,replayable:c.length}}async function si(e,t,n,r){let{ctx:i,runDir:a,runId:o}=e,s=Z(o);try{let e=await q.run(i,()=>J.run({args:r??{},depth:0},()=>Pr(t,r)));return $(a,s,{status:`completed`,taskCount:i.taskCount,ledger:i.ledger,result:e}),{runId:o,name:n,status:`completed`,result:e,tokens:i.ledger,taskCount:i.taskCount}}catch(e){throw i.stopping||$(a,s,{status:`failed`,taskCount:i.taskCount,ledger:i.ledger,error:e instanceof Error?e.message:String(e)}),new G(`flow-failed`,e instanceof Error?e.message:String(e),{runId:o})}}async function ci(e,t={},n={}){let{started:r}=oi(e,t,n),i=Z(r.runId).script;return n.onStart?.({runId:r.runId,requestStop:r.markStopped,runningIds:()=>[...r.ctx.running]}),si(r,i,Z(r.runId).name,t.args??{})}async function li(e,t={},n={}){let{started:r,args:i,name:a,replayable:o}=oi(``,t,n,e),s=Z(e).script;return n.onStart?.({runId:e,requestStop:r.markStopped,runningIds:()=>[...r.ctx.running]}),o&&n.onReplay?.(o),si(r,s,a,i)}export{L as $,k as $t,qn as A,qe as At,Un as B,O as Bt,yr as C,ot as Ct,Qn as D,Qe as Dt,$n as E,ut as Et,Ln as F,Ie as Ft,Cn as G,ge as Gt,Dn as H,ve as Ht,Rn as I,Te as It,bn as J,Oe as Jt,Tn as K,A as Kt,Pn as L,_e as Lt,G as M,Je as Mt,An as N,Ye as Nt,Zn as O,M as Ot,jn as P,Ee as Pt,R as Q,Le as Qt,Hn as R,ke as Rt,ai as S,at as St,er as T,ct as Tt,kn as U,Se as Ut,wn as V,be as Vt,En as W,he as Wt,B as X,Fe as Xt,Sn as Y,Ce as Yt,z as Z,E as Zt,li as _,Rt as _t,Vr as a,Ae as an,V as at,ri as b,lt as bt,wr as c,gn as ct,Kr as d,dn as dt,xe as en,zt as et,Er as f,W as ft,Z as g,I as gt,Zr as h,Ft as ht,ar as i,Re as in,pn as it,Yn as j,Xe as jt,Xn as k,Ze as kt,Jr as l,cn as lt,Tr as m,_n as mt,zr as n,Ve as nn,un as nt,Fr as o,je as on,on as ot,Qr as p,U as pt,xn as q,ye as qt,Xr as r,Be as rn,H as rt,Yr as s,we as sn,sn as st,$r as t,ze as tn,Bt as tt,qr as u,fn as ut,X as v,Lt as vt,K as w,N as wt,ii as x,dt as xt,ci as y,ft as yt,Fn as z,De as zt};
|
package/dist/sdk.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e,I as t,v as n,x as r}from"./app-server-bHl6RBZ2.js";import{B as i,E as a,I as o,M as s,R as c,Tt as l,bt as u}from"./runtime-
|
|
1
|
+
import{C as e,I as t,v as n,x as r}from"./app-server-bHl6RBZ2.js";import{B as i,E as a,I as o,M as s,R as c,Tt as l,bt as u}from"./runtime-BMO6NYyh.js";import{D as d,S as f,T as p,_ as m,b as h,c as g,d as _,f as v,g as y,i as b,l as x,m as S,n as C,o as w,s as T,u as E,y as D}from"./upgrade-Bu0uWk5Y.js";import O from"./flow/index.js";import k from"node:process";import A from"node:path";function j(e){return e?A.resolve(e):k.cwd()}function M(t,n){let r=e(t,n);if(!r)throw Error(n?`No task found for "${n}".`:`No tasks found for this workspace.`);return r}const N={async run(e,t={}){let{taskId:n}=await o({prompt:e,cwd:j(t.cwd),agent:t.agent,model:t.model,effort:t.effort,permissions:t.permissions,name:t.name,system:t.system,resume:t.resume});return{taskId:n}},async result(e,t={}){let n=j(t.cwd),r=e??M(n).id;return t.wait?i(n,r,{tail:t.tail}):c(n,r,{tail:t.tail})},list(e={}){return h(j(e.cwd),e).jobs},async steer(e,t,n={}){let r=j(n.cwd);return p(r,M(r,e),t,{model:n.model,effort:n.effort,permissions:n.permissions})},async ask(e,t,n={}){let r=j(n.cwd),i=M(r,e),a=await f(r,i,t,{model:n.model,effort:n.effort});return{taskId:i.id,answer:a.finalMessage||null}},async stop(e,t={}){let n=j(t.cwd);return a(n,M(n,e))},archive(e,t={}){let r=j(t.cwd);return n(r,M(r,e)),{taskId:e,archived:!0}},delete(e,t={}){let n=j(t.cwd),i=M(n,e);if(i.status===`running`)throw Error(`Task ${i.id} is still running.`);D(i);let a=r(n,i.id);return{taskId:i.id,deleted:a}},approve(e,n,r={}){let i=j(r.cwd),a=M(i,e),o=r.deny?`decline`:`accept`;return u(t(i,a.id),n,o),{taskId:a.id,approvalId:n,decision:o}},approvals(e,n={}){let r=j(n.cwd),i=e?M(r,e):M(r);return l(t(r,i.id))},stream(e,t={}){let n=j(t.cwd);return d(n,e??M(n).id,{tail:t.tail})}},P={add:(e,t)=>w(j(t.cwd),e,t),update:(e,t)=>v(j(t.cwd),e,t),remove:(e,t={})=>x(j(t.cwd),e,t),list:(e={})=>g(j(e.cwd)),alias:(e,t,n={})=>T(j(n.cwd),e,t,n),unalias:(e,t={})=>_(j(t.cwd),e,t),disable:(e,t={})=>E(j(t.cwd),e,!0,t),enable:(e,t={})=>E(j(t.cwd),e,!1,t)},F={get:(e,t={})=>y(j(t.cwd),e),set:(e,t,n={})=>m(j(n.cwd),e,t,n)};function I(e=[],t={}){return S(j(t.cwd),{claude:e.includes(`claude`),codex:e.includes(`codex`),agents:e.includes(`agents`)})}function L(e={}){return C(e)}function R(e){return b(e)}var z={task:N,flow:O,model:P,config:F,setupHost:I,upgrade:L,docs:R};export{s as CoderError,F as config,z as default,R as docs,O as flow,P as model,I as setupHost,N as task,L as upgrade};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{B as e,D as t,E as n,H as r,I as i,L as a,O as o,P as s,S as c,U as l,V as u,_ as d,c as f,d as p,f as m,h,j as g,k as _,l as v,m as y,o as b,p as x,s as S,u as C,x as w,z as T}from"./app-server-bHl6RBZ2.js";import{$ as E,$t as D,At as ee,Bt as O,Dt as te,G as ne,H as re,Ht as ie,J as ae,Jt as k,K as oe,Lt as se,Ot as ce,Q as le,Qt as ue,Rt as A,Tt as de,U as fe,Ut as pe,V as me,Vt as he,W as ge,Wt as j,X as _e,Y as ve,Yt as ye,Z as M,Zt as N,_t as be,at as P,ct as xe,dt as Se,en as Ce,et as we,ft as F,g as Te,gt as I,ht as Ee,it as L,jt as De,k as Oe,mt as ke,nn as R,nt as z,ot as B,pt as Ae,q as je,qt as Me,rn as V,rt as H,sn as Ne,st as U,tn as W,ut as Pe,vt as Fe,z as Ie,zt as Le}from"./runtime-
|
|
1
|
+
import{B as e,D as t,E as n,H as r,I as i,L as a,O as o,P as s,S as c,U as l,V as u,_ as d,c as f,d as p,f as m,h,j as g,k as _,l as v,m as y,o as b,p as x,s as S,u as C,x as w,z as T}from"./app-server-bHl6RBZ2.js";import{$ as E,$t as D,At as ee,Bt as O,Dt as te,G as ne,H as re,Ht as ie,J as ae,Jt as k,K as oe,Lt as se,Ot as ce,Q as le,Qt as ue,Rt as A,Tt as de,U as fe,Ut as pe,V as me,Vt as he,W as ge,Wt as j,X as _e,Y as ve,Yt as ye,Z as M,Zt as N,_t as be,at as P,ct as xe,dt as Se,en as Ce,et as we,ft as F,g as Te,gt as I,ht as Ee,it as L,jt as De,k as Oe,mt as ke,nn as R,nt as z,ot as B,pt as Ae,q as je,qt as Me,rn as V,rt as H,sn as Ne,st as U,tn as W,ut as Pe,vt as Fe,z as Ie,zt as Le}from"./runtime-BMO6NYyh.js";import G from"node:process";import K from"node:fs";import q from"node:path";import{spawnSync as Re}from"node:child_process";import ze from"node:os";import{fileURLToPath as Be}from"node:url";import*as J from"zod/mini";import Ve from"node:crypto";import He from"node:http";let Ue=0;function We(e){let t=[];typeof e.instructions==`string`&&e.instructions&&t.push({role:`system`,content:e.instructions});let n=Array.isArray(e.input)?e.input:[];for(let e of n)switch(e?.type){case`message`:{let n=Array.isArray(e.content)?e.content.map(e=>e?.text??``).join(``):String(e.content??``);t.push({role:e.role===`developer`?`system`:e.role,content:n});break}case`function_call`:{let n={id:e.call_id,type:`function`,function:{name:e.name,arguments:e.arguments??`{}`}},r=t.at(-1);r?.role===`assistant`&&r.tool_calls?r.tool_calls.push(n):t.push({role:`assistant`,content:null,tool_calls:[n]});break}case`function_call_output`:{let n=e.output;t.push({role:`tool`,tool_call_id:e.call_id,content:typeof n==`string`?n:JSON.stringify(n??``)});break}}return t}function Ge(e){let t=(Array.isArray(e.tools)?e.tools:[]).filter(e=>e?.type===`function`).map(e=>({type:`function`,function:{name:e.name,description:e.description??``,parameters:e.parameters??{type:`object`,properties:{}}}})),n=e.text?.format;return{model:e.model,messages:We(e),...t.length?{tools:t,tool_choice:e.tool_choice??`auto`}:{},...typeof e.parallel_tool_calls==`boolean`?{parallel_tool_calls:e.parallel_tool_calls}:{},...n?.type===`json_schema`?{response_format:{type:`json_schema`,json_schema:{name:n.name,schema:n.schema,strict:n.strict??!1}}}:{},stream:!0,stream_options:{include_usage:!0}}}var Ke=class{send;model;responseId=`resp_bridge_${++Ue}`;text=``;textOpen=!1;toolCalls=new Map;usage=null;buffer=``;constructor(e,t){this.model=e,this.send=t,this.send({type:`response.created`,response:{id:this.responseId,object:`response`,status:`in_progress`,model:e,output:[]}})}push(e){this.buffer+=e;let t=this.buffer.split(`
|
|
2
2
|
`);this.buffer=t.pop()??``;for(let e of t){let t=e.trim();if(!t.startsWith(`data:`))continue;let n=t.slice(5).trim();if(!n||n===`[DONE]`)continue;let r;try{r=JSON.parse(n)}catch{continue}r.usage&&(this.usage=r.usage);let i=r.choices?.[0]?.delta;if(i){typeof i.content==`string`&&i.content&&(this.textOpen||(this.textOpen=!0,this.send({type:`response.output_item.added`,output_index:0,item:{type:`message`,id:`msg_bridge_0`,status:`in_progress`,role:`assistant`,content:[]}})),this.text+=i.content,this.send({type:`response.output_text.delta`,item_id:`msg_bridge_0`,output_index:0,content_index:0,delta:i.content}));for(let e of i.tool_calls??[]){let t=this.toolCalls.get(e.index)??{id:``,name:``,args:``};e.id&&(t.id=e.id),e.function?.name&&(t.name+=e.function.name),e.function?.arguments&&(t.args+=e.function.arguments),this.toolCalls.set(e.index,t)}}}}finish(){let e=[];if(this.text){let t={type:`message`,id:`msg_bridge_0`,status:`completed`,role:`assistant`,content:[{type:`output_text`,text:this.text,annotations:[]}]};e.push(t),this.send({type:`response.output_item.done`,output_index:0,item:t})}let t=e.length;for(let n of this.toolCalls.values()){let r={type:`function_call`,id:`fc_bridge_${t}`,call_id:n.id||`call_bridge_${t}`,name:n.name,arguments:n.args||`{}`,status:`completed`};e.push(r),this.send({type:`response.output_item.done`,output_index:t,item:r}),t+=1}this.send({type:`response.completed`,response:{id:this.responseId,object:`response`,status:`completed`,model:this.model,output:e,usage:{input_tokens:this.usage?.prompt_tokens??0,input_tokens_details:{cached_tokens:this.usage?.prompt_tokens_details?.cached_tokens??0},output_tokens:this.usage?.completion_tokens??0,output_tokens_details:{reasoning_tokens:this.usage?.completion_tokens_details?.reasoning_tokens??0},total_tokens:this.usage?.total_tokens??0}}})}};async function qe(e,t=`chat`){let n=t===`responses`,r=z(e.baseUrl,n?`responses`:`chat/completions`),i=null,a=e.envKey?G.env[e.envKey]:void 0;async function o(e){let t=i?[i]:r,n=null;for(let r of t)if(n=await fetch(r,{method:`POST`,headers:{"content-type":`application/json`,...a?{authorization:`Bearer ${a}`}:{}},body:e}),n.status!==404)return i=r,n;return n}let s=Ve.randomBytes(16).toString(`hex`),c=He.createServer((e,t)=>{if(e.method!==`POST`||!e.url?.startsWith(`/${s}/`)||!e.url.replace(/\/+$/,``).endsWith(`/responses`)){t.writeHead(404,{"content-type":`application/json`}),t.end(JSON.stringify({error:{message:`coder chat bridge: only POST /responses is supported`}}));return}let r=``;e.on(`data`,e=>r+=e),e.on(`end`,async()=>{let e;try{e=JSON.parse(r)}catch{t.writeHead(400,{"content-type":`application/json`}),t.end(JSON.stringify({error:{message:`invalid JSON`}}));return}try{if(n){let e=await o(r);if(t.writeHead(e.status,{"content-type":e.headers.get(`content-type`)??`application/json`,"cache-control":`no-store`}),e.body)for await(let n of e.body)t.write(n);t.end();return}let i=await o(JSON.stringify(Ge(e)));if(!i.ok||!i.body){let e=await i.text().catch(()=>``);t.writeHead(i.status,{"content-type":`application/json`}),t.end(e||JSON.stringify({error:{message:`upstream HTTP ${i.status}`}}));return}t.writeHead(200,{"content-type":`text/event-stream`,"cache-control":`no-store`});let a=new Ke(e.model,e=>t.write(`data: ${JSON.stringify(e)}\n\n`)),s=new TextDecoder;for await(let e of i.body)a.push(s.decode(e,{stream:!0}));a.finish(),t.end()}catch(e){let n=e instanceof Error?e.message:String(e);t.writeHead(502,{"content-type":`application/json`}),t.end(JSON.stringify({error:{message:`coder chat bridge: ${n}`}}))}})});await new Promise(e=>c.listen(0,`127.0.0.1`,e));let l=c.address();return{url:`http://127.0.0.1:${typeof l==`object`&&l?l.port:0}/${s}/v1`,close:()=>new Promise(e=>{c.close(()=>e()),c.closeAllConnections?.()})}}async function Je(e,t,n){let r=e.envKey?G.env[e.envKey]:void 0,i=!1;for(let a of z(e.baseUrl,t))try{let e=await fetch(a,{method:`POST`,headers:{"content-type":`application/json`,...r?{Authorization:`Bearer ${r}`}:{}},body:JSON.stringify(n),signal:AbortSignal.timeout(5e3)});if(i=!0,e.status!==404&&e.status!==405&&e.status!==501)return{baseUrl:a.slice(0,-(t.length+1))}}catch{}return{reachable:i}}async function Ye(e){let t=await Je(e,`responses`,{model:e.model,input:[],stream:!1});if(`baseUrl`in t)return{wireApi:`responses`,baseUrl:t.baseUrl};let n=await Je(e,`chat/completions`,{model:e.model,messages:[],stream:!1});return`baseUrl`in n?{wireApi:`chat`,baseUrl:n.baseUrl}:t.reachable||n.reachable?{wireApi:`chat`}:null}async function*Xe(e,t,n={}){let r=new Set([`completed`,`failed`,`cancelled`]),a=g(e,t);if(!a)throw Error(`No task found for "${t}".`);let o=n.tail??1,c=te(q.join(i(e,t),`log.jsonl`)),l=!0,u=()=>{let e=c();return l&&(l=!1,o!==`all`&&(e=o===0?[]:e.slice(-o))),e.map(e=>{try{return JSON.parse(e)}catch{return{message:e}}})};for(yield*u();!r.has(a.status);)await new Promise(e=>setTimeout(e,400)),a=s(e,g(e,t)??a),yield*u();yield*u()}async function Ze(e){let{options:t,positionals:n}=v(e,J.object({...b,tail:p,trim:J.optional(J.union([J.literal(`none`),J.coerce.number().check(J.int(),J.positive())],{error:`expected a positive integer or "none"`}))}));W(n,1,`task watch`);let r=V(t),a=R(r,n[0]),o=t.tail,c=t.trim,l=c===void 0?300:c===`none`?2**53-1:c;if(!t.json){G.stdout.write(`${N.dim(`[coder] task ${a.id} ${a.status} — watching (Ctrl-C to stop)`)}\n`);let e=[`${N.dim(`agent`.padEnd(8))} ${pe(a)}`,...ye(a,N)];G.stdout.write(`${e.join(`
|
|
3
3
|
`)}\n`),a.prompt&&G.stdout.write(`${Ce(a.prompt,N).join(`
|
|
4
4
|
`)}\n`)}for await(let e of Xe(r,a.id,{tail:o}))if(t.json){let t=e.message?{...e,message:Ne(e.message,l,{plain:!0})}:e;G.stdout.write(`${JSON.stringify(t)}\n`)}else{let t=e.message??e.kind;t&&G.stdout.write(`${N.dim(`[coder]`)} ${Ne(t,l)}\n`)}let u=s(r,g(r,a.id)??a),d=ce(q.join(i(r,a.id),`result.json`));if(t.json)D({taskId:a.id,status:u.status,result:d});else{let e=u.status===`completed`?`(no final message)`:`(task ${u.status})`;G.stdout.write(`\n${he(d,u.error,e)}\n`);let t=d?.tokens?` tokens=${Me(d.tokens,d.model??u.model)}`:``;G.stderr.write(`${N.dim(`[coder] task=${a.id} status=${u.status}${t}`)}\n`)}G.exit(u.status===`completed`?0:1)}async function Qe(e,t,n){if(t.status!==`running`)return null;if(t.engine!==`claude`&&(await Fe(e,{threadId:t.threadId,text:n})).steered)return{taskId:t.id,steered:`live`};let r=g(e,t.id)??t;return u.includes(r.status)?(c(e,r.id,n),{taskId:r.id,steered:`queued`}):null}async function $e(e,t,n,r={}){if(!t.threadId)throw Error(`Task ${t.id} has no thread to steer yet (status: ${t.status}).`);return await Qe(e,t,n)||(et(e,t,n,r),{taskId:t.id,steered:`resumed`})}function et(t,n,r,i){e(t,n.id,{status:`queued`,resumedAt:new Date().toISOString(),currentPrompt:r,resumeThreadId:n.threadId,model:i.model??n.model??null,effort:i.effort??n.effort??null,permissions:i.permissions??n.permissions,error:void 0}),d(t,n.id,{message:`Resuming with steered follow-up.`}),Ie(n.cwd??t,n.id)}async function tt(e){let{options:t,positionals:n}=v(e,J.object({...b,model:C,effort:C,permissions:C,background:S,wait:S})),r=V(t),[i,...a]=n,o=a.join(` `).trim();(!i||!o)&&O(`Missing task id or follow-up text.`,{hint:[`Usage: coder task steer <task-id> "<follow-up>" [--wait]`,`Help: coder task steer --help`]});let s=R(r,i);s.threadId||O(`Task ${s.id} has no thread to steer yet (status: ${s.status}).`,{hint:`Wait for it to start: coder task watch ${s.id}`});let c=await $e(r,s,o,{model:t.model,effort:t.effort,permissions:t.permissions});return nt(r,c.taskId,{steered:c.steered,options:t})}async function nt(e,t,{steered:n,options:r}){if(n===`queued`){if(r.json){D({taskId:t,steered:`queued`});return}G.stdout.write(`${N.dim(`[coder]`)} follow-up queued for task ${N.cyan(t)}; it runs when the current turn finishes.\n`),r.wait&&G.stdout.write(`\n${N.dim(`[coder] --wait is not available for a queued follow-up; check: coder task result ${t}`)}\n`);return}if(!r.wait){if(r.json){D({taskId:t,steered:n});return}G.stdout.write(n===`live`?`${N.dim(`[coder]`)} steered follow-up into running task ${N.cyan(t)}.\n`:`${N.dim(`[coder]`)} resumed task ${N.cyan(t)} with the follow-up (same thread, same id).\n`),G.stdout.write(`\n${N.dim(` result: coder task result ${t}`)}\n`);return}let a=g(e,t),o=a?await T(e,a):null,s=ce(q.join(i(e,t),`result.json`));r.json?D({taskId:t,status:o?.status??null,finalMessage:s?.finalMessage??null}):(G.stdout.write(`\n${s?.finalMessage||`(no final message)`}\n\n`),G.stderr.write(`${N.dim(`[coder] task=${t} status=${o?.status??`unknown`}`)}\n`)),G.exitCode=o?.status===`completed`?0:1}function rt(e,t,n){return`You are a read-only sidecar answering a question ABOUT a coder task.
|
package/docs/config.md
CHANGED
|
@@ -30,6 +30,10 @@ coder config set agents.codex.model terra
|
|
|
30
30
|
"fast": { "provider": "codex", "model": "gpt-5.4-mini" },
|
|
31
31
|
"big": { "provider": "claude", "model": "opus", "effort": "high" },
|
|
32
32
|
"luna": { "disabled": true }
|
|
33
|
+
},
|
|
34
|
+
"approvals": {
|
|
35
|
+
"escalationTimeoutMs": 120000,
|
|
36
|
+
"allowedNetworkHosts": ["localhost", "127.0.0.1", "registry.npmjs.org"]
|
|
33
37
|
}
|
|
34
38
|
}
|
|
35
39
|
```
|
|
@@ -62,6 +66,17 @@ One namespace for every model you can name as `--model`, keyed by that name. An
|
|
|
62
66
|
|
|
63
67
|
Every shape also accepts `"disabled": true` to park the entry without deleting it. An entry named after a built-in alias (e.g. `mini`) shadows it. See [Models](models.md).
|
|
64
68
|
|
|
69
|
+
## `approvals`
|
|
70
|
+
|
|
71
|
+
Tunes the `auto` permission mode; ignored by `read-only` and `workspace-write`.
|
|
72
|
+
|
|
73
|
+
| Key | Meaning |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| `escalationTimeoutMs` | How long an escalated approval waits for an answer before auto-denying and letting the task move on. Default `120000`. |
|
|
76
|
+
| `allowedNetworkHosts` | Hosts (and their subdomains) coders may reach without an approval. Default `[]` — all network access escalates. |
|
|
77
|
+
|
|
78
|
+
`allowedNetworkHosts` works on both engines — auto-accepted by the codex approval policy, pre-allowed in the claude sandbox. A bare hostname covers its subdomains; anything else escalates as usual.
|
|
79
|
+
|
|
65
80
|
---
|
|
66
81
|
|
|
67
82
|
Config files are validated strictly: an unknown key or bad value fails with a pointed error instead of being silently ignored.
|
package/package.json
CHANGED
|
@@ -32,7 +32,7 @@ If `coder` is not on PATH, install it yourself without asking (`npm install -g @
|
|
|
32
32
|
coder task run --system "<standing instructions>" "<task text>"
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Fetch the answer with `coder task result <task-id> --wait` - blocks until done, prints only the final result. Run it in a background shell so it does not block you
|
|
35
|
+
Fetch the answer with `coder task result <task-id> --wait` - blocks until done, prints only the final result. Run it in a background shell so it does not block you. For a fan-out, start one such background waiter per dispatched task (see Supervision loop).
|
|
36
36
|
|
|
37
37
|
- A `--wait` (on `run` or `result`) exits **4** when the task is waiting on a permission approval: relay the approval to the user, apply their decision with `coder approve <task-id> <approval-id> [--deny]`, then re-fetch with `coder task result <task-id> --wait`. (Unanswered approvals auto-deny after 120s and the task moves on.)
|
|
38
38
|
|
|
@@ -40,6 +40,7 @@ If `coder` is not on PATH, install it yourself without asking (`npm install -g @
|
|
|
40
40
|
- When the first engine can't start (auth, quota, rate limit), the runtime automatically falls back to the next engine in the chain, runs the same task on it, and still exits 0 - so just fetch the result. If the failure mentions a usage-limit reset time, relay that to the user.
|
|
41
41
|
- Model choice: config holds the defaults; matching the dispatch to the task is on you - pick `--agent` / `--model` / `--effort` by the task's weight and the user's ask (light -> cheap/fast model, hard -> stronger model or higher effort). `coder task run --help` lists agents, models, and efforts; `coder model list` shows custom models.
|
|
42
42
|
- Permissions default to auto mode (workspace-write + policy-answered escalations). Pass `--permissions read-only` when the task is read-only; `--permissions workspace-write` to forbid any escalation beyond the project.
|
|
43
|
+
- Network access escalates by default in auto mode; hosts in `approvals.allowedNetworkHosts` (coder config, subdomains included) need no approval. If a trusted host keeps escalating, suggest allowlisting it: `coder config set approvals.allowedNetworkHosts '["registry.npmjs.org"]'`.
|
|
43
44
|
|
|
44
45
|
## Flows (multi-task workflows)
|
|
45
46
|
|
|
@@ -62,7 +63,7 @@ When no coder engine can start (missing binaries, auth, quota across the whole c
|
|
|
62
63
|
|
|
63
64
|
## Supervision loop
|
|
64
65
|
|
|
65
|
-
With coders running in the background, don't fire-and-forget:
|
|
66
|
+
With coders running in the background, don't fire-and-forget: hold one background `coder task result <task-id> --wait` shell per task - each returns when its task finishes (relay the answer, dispatch newly unblocked coders) or escalates an approval (exit 4, see above; restart the waiter after answering). Only without background shells, fall back to recurring check-ins (whatever scheduling facility your harness has; interval by the work's pace, 10m default; bump `approvals.escalationTimeoutMs` above it so escalations survive between ticks): each tick `coder task list`, fetch finished results, surface pending approvals.
|
|
66
67
|
|
|
67
68
|
## Controlling tasks
|
|
68
69
|
|
|
@@ -30,7 +30,7 @@ If `coder` is not on PATH, install it yourself without asking (`npm install -g @
|
|
|
30
30
|
coder task run --system "<standing instructions>" "<task text>"
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
Fetch the answer with `coder task result <task-id> --wait` - blocks until done, prints only the final result. Run it as a background Bash call (run_in_background: true) so it does not block you and you are re-invoked on completion
|
|
33
|
+
Fetch the answer with `coder task result <task-id> --wait` - blocks until done, prints only the final result. Run it as a background Bash call (run_in_background: true) so it does not block you and you are re-invoked on completion. For a fan-out, start one such background waiter per dispatched task (see Supervision loop).
|
|
34
34
|
|
|
35
35
|
- A `--wait` (on `run` or `result`) exits **4** when the task is waiting on a permission approval: relay the approval to the user, apply their decision with `coder approve <task-id> <approval-id> [--deny]`, then re-fetch with `coder task result <task-id> --wait`. (Unanswered approvals auto-deny after 120s and the task moves on.)
|
|
36
36
|
|
|
@@ -38,6 +38,7 @@ If `coder` is not on PATH, install it yourself without asking (`npm install -g @
|
|
|
38
38
|
- When the first engine can't start (auth, quota, rate limit), the runtime automatically falls back to the next engine in the chain, runs the same task on it, and still exits 0 - so just fetch the result. If the failure mentions a usage-limit reset time, relay that to the user.
|
|
39
39
|
- Model choice: config holds the defaults; matching the dispatch to the task is on you - pick `--agent` / `--model` / `--effort` by the task's weight and the user's ask (light -> cheap/fast model, hard -> stronger model or higher effort). `coder task run --help` lists agents, models, and efforts; `coder model list` shows custom models.
|
|
40
40
|
- Permissions default to auto mode (workspace-write + policy-answered escalations). Pass `--permissions read-only` when the task is read-only; `--permissions workspace-write` to forbid any escalation beyond the project.
|
|
41
|
+
- Network access escalates by default in auto mode; hosts in `approvals.allowedNetworkHosts` (coder config, subdomains included) need no approval. If a trusted host keeps escalating, suggest allowlisting it: `coder config set approvals.allowedNetworkHosts '["registry.npmjs.org"]'`.
|
|
41
42
|
|
|
42
43
|
## Flows (multi-task workflows)
|
|
43
44
|
|
|
@@ -60,7 +61,7 @@ When no coder engine can start (missing binaries, auth, quota across the whole c
|
|
|
60
61
|
|
|
61
62
|
## Supervision loop
|
|
62
63
|
|
|
63
|
-
With coders running in the background, don't fire-and-forget:
|
|
64
|
+
With coders running in the background, don't fire-and-forget: hold one background `coder task result <task-id> --wait` per task - each re-invokes you when its task finishes (relay the answer, dispatch newly unblocked coders) or escalates an approval (exit 4, see above; restart the waiter after answering). Only without background shells, fall back to recurring check-ins (the `/loop` skill or ScheduleWakeup; interval by the work's pace, 10m default; bump `approvals.escalationTimeoutMs` above it so escalations survive between ticks): each tick `coder task list`, fetch finished results, surface pending approvals.
|
|
64
65
|
|
|
65
66
|
## Controlling tasks
|
|
66
67
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coder",
|
|
3
3
|
"displayName": "Coder",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.6",
|
|
5
5
|
"description": "Delegate coding tasks to supervised Coder subagents running on Codex, Claude, or any OpenAI-compatible model. Your main context stays clean.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "muzam1l"
|
|
@@ -31,7 +31,7 @@ If `coder` is not on PATH, install it yourself without asking (`npm install -g @
|
|
|
31
31
|
coder task run --system "<standing instructions>" "<task text>"
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
Fetch the answer with `coder task result <task-id> --wait` - blocks until done, prints only the final result. Run it in a background shell so it does not block you
|
|
34
|
+
Fetch the answer with `coder task result <task-id> --wait` - blocks until done, prints only the final result. Run it in a background shell so it does not block you. For a fan-out, start one such background waiter per dispatched task (see Supervision loop).
|
|
35
35
|
|
|
36
36
|
- A `--wait` (on `run` or `result`) exits **4** when the task is waiting on a permission approval: relay the approval to the user, apply their decision with `coder approve <task-id> <approval-id> [--deny]`, then re-fetch with `coder task result <task-id> --wait`. (Unanswered approvals auto-deny after 120s and the task moves on.)
|
|
37
37
|
|
|
@@ -39,6 +39,7 @@ If `coder` is not on PATH, install it yourself without asking (`npm install -g @
|
|
|
39
39
|
- When the first engine can't start (auth, quota, rate limit), the runtime automatically falls back to the next engine in the chain, runs the same task on it, and still exits 0 - so just fetch the result. If the failure mentions a usage-limit reset time, relay that to the user.
|
|
40
40
|
- Model choice: config holds the defaults; matching the dispatch to the task is on you - pick `--agent` / `--model` / `--effort` by the task's weight and the user's ask (light -> cheap/fast model, hard -> stronger model or higher effort). `coder task run --help` lists agents, models, and efforts; `coder model list` shows custom models.
|
|
41
41
|
- Permissions default to auto mode (workspace-write + policy-answered escalations). Pass `--permissions read-only` when the task is read-only; `--permissions workspace-write` to forbid any escalation beyond the project.
|
|
42
|
+
- Network access escalates by default in auto mode; hosts in `approvals.allowedNetworkHosts` (coder config, subdomains included) need no approval. If a trusted host keeps escalating, suggest allowlisting it: `coder config set approvals.allowedNetworkHosts '["registry.npmjs.org"]'`.
|
|
42
43
|
|
|
43
44
|
## Flows (multi-task workflows)
|
|
44
45
|
|
|
@@ -61,7 +62,7 @@ When no coder engine can start (missing binaries, auth, quota across the whole c
|
|
|
61
62
|
|
|
62
63
|
## Supervision loop
|
|
63
64
|
|
|
64
|
-
With coders running in the background, don't fire-and-forget:
|
|
65
|
+
With coders running in the background, don't fire-and-forget: hold one background `coder task result <task-id> --wait` shell per task - each returns when its task finishes (relay the answer, dispatch newly unblocked coders) or escalates an approval (exit 4, see above; restart the waiter after answering). Only without background shells, fall back to a recurring monitoring loop (interval by the work's pace, 10m default; bump `approvals.escalationTimeoutMs` above it so escalations survive between ticks): each tick `coder task list`, fetch finished results, surface pending approvals.
|
|
65
66
|
|
|
66
67
|
## Controlling tasks
|
|
67
68
|
|
package/dist/runtime-DVrs6VXX.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import{A as e,B as t,C as n,F as r,G as i,H as a,I as o,L as s,M as c,N as l,O as u,P as d,T as f,W as ee,f as te,i as p,j as m,l as ne,m as h,o as g,r as _,s as re,u as ie,v as ae,w as oe,y as se}from"./app-server-bHl6RBZ2.js";import{createRequire as ce}from"node:module";import v from"node:process";import y from"node:fs";import b from"node:path";import{spawn as x,spawnSync as S}from"node:child_process";import le from"node:os";import{fileURLToPath as ue,pathToFileURL as de}from"node:url";import*as C from"zod/mini";import fe,{randomUUID as pe}from"node:crypto";import{AsyncLocalStorage as me}from"node:async_hooks";function he(e){let t=v.env.FORCE_COLOR,n=t!=null&&t!==``&&t!==`0`||t!==`0`&&e.isTTY&&!v.env.NO_COLOR,r=(e,t)=>n?`\x1b[${e}m${t}\x1b[0m`:t;return{blue:e=>r(`34`,e),bold:e=>r(`1`,e),cyan:e=>r(`36`,e),dim:e=>r(`38;5;246`,e),light:e=>r(`38;5;249`,e),green:e=>r(`32`,e),red:e=>r(`31`,e),yellow:e=>r(`33`,e)}}const w=he(v.stdout),T=he(v.stderr);function ge(e,t=T){let n=e.map(e=>{let t=e.indexOf(`coder `);return t===-1?{label:e,cmd:``}:{label:e.slice(0,t),cmd:e.slice(t)}}),r=Math.max(0,...n.map(e=>e.label.length));return n.map(({label:e,cmd:n})=>n?` ${t.dim(e.padEnd(r))}${t.bold(n)}`:` ${t.dim(e)}`).join(`
|
|
2
|
-
`)}function E(e,t={}){let n=typeof t==`number`?t:t.code??1,r=typeof t==`object`?t.hint:null,i=r==null?[]:Array.isArray(r)?r:[r];v.stderr.write(`${T.red(e)}\n`),i.length&&v.stderr.write(`\n${ge(i,T)}\n`),v.exit(n)}function D(e){v.stdout.write(`${JSON.stringify(e,null,2)}\n`)}function _e(e,t=w){return(JSON.stringify(e,null,2)??`null`).split(`
|
|
3
|
-
`).map(e=>e.replace(/"((?:[^"\\]|\\.)*)":/g,(e,n)=>`${t.light(`"${n}"`)}:`).replace(/: (-?\d[\d.eE+-]*|true|false|null)(,?)$/,(e,n,r)=>`: ${t.blue(n)}${r}`)).join(`
|
|
4
|
-
`)}function ve(e){let t=Date.parse(e??``);return Number.isFinite(t)?Math.max(0,Date.now()-t):0}function ye(e){let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m`:`${Math.floor(n/60)}h${n%60}m`}function O(e){return e<1e3?String(e):e<1e6?`${(e/1e3).toFixed(+(e<1e4))}k`:`${(e/1e6).toFixed(1)}M`}function be(e,t){let n=[`in ${O(e.input)}`,...e.cachedInput?[`cached ${O(e.cachedInput)}`]:[],`out ${O(e.output)}`];return`${O(e.total)} (${n.join(` · `)}) on ${t||`default model`}`}function xe(e,t,n,r=w){let i=e?.error?.message??t;return e?.finalMessage||(i?`${r.red(`error:`)} ${i}`:n)}function Se(e,t=w){let n=e=>e.split(`
|
|
5
|
-
`).map(e=>` ${t.dim(e)}`);return e.length<=1e3?[t.dim(`prompt:`),...n(e)]:[t.dim(`prompt:`),...n(e.slice(0,500).trimEnd()),t.light(` … <${e.length-1e3} chars trimmed> …`),...n(e.slice(-500).trimStart())]}function Ce(e){return[e.agent??`-`,e.model,e.model?e.effort:null].filter(Boolean).join(`/`)}function we(e,t=w){let n=[];return e.permissions&&n.push([`perms`,e.permissions]),e.cwd&&n.push([`cwd`,e.cwd]),n.map(([e,n])=>`${t.dim(e.padEnd(8))} ${n}`)}function Te(e,t=300,{plain:n=!1,style:r=w}={}){if(e.length<=t)return e;let i=`<${e.length-t} more chars>`;return`${e.slice(0,t)} ${n?i:r.dim(i)}`}const Ee=6e5,De=12e4;function Oe(e,t){return e.length>t?`${e.slice(0,t-1)}…`:e.padEnd(t)}function ke(e){return` ${w.bold(w.green(`✔`))} ${e}`}function Ae(e){return` ${w.bold(w.red(`✘`))} ${e}`}function je(e=v.stdout){try{return e.getWindowSize?.()[0]??e.columns}catch{return e.columns}}function Me(e=v.stdout){try{return e.getWindowSize?.()[1]??e.rows}catch{return e.rows}}function Ne(e){return e>=768&&e<=879||e>=8203&&e<=8207||e>=65024&&e<=65039?0:e>=4352&&e<=4447||e>=11904&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65072&&e<=65103||e>=65280&&e<=65376||e>=65504&&e<=65510||e>=127744&&e<=129791||e>=131072&&e<=262141?2:1}function Pe(e){let t=0;for(let n of e.replace(/\x1b\[[0-9;]*m/g,``))t+=Ne(n.codePointAt(0));return t}function Fe(e,t){let n=0,r=``;for(let i=0;i<e.length;){let a=e[i]===`\x1B`?/^\x1b\[[0-9;]*m/.exec(e.slice(i)):null;if(a){r+=a[0],i+=a[0].length;continue}let o=e.codePointAt(i),s=String.fromCodePoint(o),c=Ne(o);if(n+c>t-1)return`${r}\x1b[0m${w.dim(`…`)}`;r+=s,n+=c,i+=s.length}return r}function Ie(){let e=v.stdin;if(!e.isTTY||!v.stdout.isTTY)return()=>{};e.setRawMode(!0),e.resume();let t=e=>{e.includes(3)&&v.kill(v.pid,`SIGINT`),e.includes(26)&&v.kill(v.pid,`SIGTSTP`)};return e.on(`data`,t),e.unref(),()=>{e.off(`data`,t),e.isTTY&&e.setRawMode(!1),e.pause()}}var Le=class{stream;quietMs;lines=[];painted=[];paintedWidths=[];paintedCols;resizeTimer;tty;constructor(e=v.stdout,t=250){this.stream=e,this.quietMs=t,this.tty=!!e.isTTY,this.tty&&e.on(`resize`,this.onResize)}set(e){this.lines=e,!(!this.tty||this.resizeTimer)&&this.paint()}commit(e){this.clear(),this.stream.write(e)}clear(){if(!this.painted.length)return;let e=je(this.stream),t=this.painted.length;e&&this.paintedCols&&e!==this.paintedCols&&(t=this.paintedWidths.reduce((t,n)=>t+Math.max(1,Math.ceil(n/e)),0)),this.stream.write(`\x1b[${t}A\x1b[0J`),this.painted=[],this.paintedWidths=[]}done(){this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=void 0,this.paint()),this.tty&&this.stream.off(`resize`,this.onResize)}paint(){this.clear();let e=je(this.stream),t=e?this.lines.map(t=>Fe(t,e-1)):this.lines,n=Me(this.stream);n&&t.length>n-1&&(t=n>1?t.slice(-(n-1)):[]);for(let e of t)this.stream.write(`${e}\n`);this.painted=t,this.paintedWidths=t.map(Pe),this.paintedCols=e}onResize=()=>{this.clear(),this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout(()=>{this.resizeTimer=void 0,this.paint()},this.quietMs),this.resizeTimer.unref?.()}};function Re(e,t=0){let n=e.padEnd(t);return e===`running`?w.green(n):e===`waiting-approval`?w.yellow(n):e===`failed`||e===`cancelled`?w.red(n):e===`completed`?w.blue(n):w.dim(n)}function ze(e,t,n=!1){n?D({taskId:e,status:`awaiting-approval`,approval:t}):(v.stdout.write(`Approval needed for task ${e}: ${t.summary}\n`),v.stderr.write(`\n${ge([`Approve: coder approve ${e} ${t.id}`,`Deny: coder approve ${e} ${t.id} --deny`,`Then: coder task result ${e} --wait`],T)}\n`)),v.exit(4)}function Be(e,t,n){if(e.length>t){let r=e.slice(t);E(`Unexpected argument${r.length>1?`s`:``}: ${r.join(` `)}`,{hint:`Help: coder ${n} --help`})}}function k(e){return e.cwd?b.resolve(String(e.cwd)):v.cwd()}function Ve(e,t){let r=n(e,t);return r||E(t?`No task found for "${t}".`:`No tasks found for this workspace.`,{hint:t?[`List tasks: coder task list`,`Start one: coder run "<text>"`]:[`Start one: coder run "<text>"`]}),r}const A=`@wular/coder`,He=`https://registry.npmjs.org/${A}/latest`;function Ue(){return b.join(r(),`update-check.json`)}function We(e,t){let n=String(e).split(`.`).map(e=>parseInt(e,10)||0),r=String(t).split(`.`).map(e=>parseInt(e,10)||0);for(let e=0;e<3;e+=1){if((n[e]??0)>(r[e]??0))return 1;if((n[e]??0)<(r[e]??0))return-1}return 0}function Ge(){try{return JSON.parse(y.readFileSync(Ue(),`utf8`))}catch{return null}}function Ke(e){try{y.mkdirSync(r(),{recursive:!0}),y.writeFileSync(Ue(),JSON.stringify(e))}catch{}}function qe(){try{y.rmSync(Ue(),{force:!0})}catch{}}function Je(e,t){if(v.env.CODER_NO_UPDATE_CHECK||v.env.CI)return;let n=Ge();if(n?.latest&&We(n.latest,e)>0&&v.stderr.write(T.dim(`coder ${e} -> `)+T.bold(n.latest)+T.dim(` available. run: coder upgrade
|
|
6
|
-
|
|
7
|
-
`)),!n?.checkedAt||Date.now()-n.checkedAt>864e5)try{x(v.execPath,[t,`_refreshUpdate`],{detached:!0,stdio:`ignore`}).unref()}catch{}}async function Ye(e){let t=Ge()?.latest??null;try{let e=new AbortController,n=setTimeout(()=>e.abort(),3e3),r=await fetch(He,{signal:e.signal,headers:{accept:`application/json`}});if(clearTimeout(n),r.ok){let e=await r.json();e?.version&&(t=e.version)}}catch{}Ke({checkedAt:Date.now(),latest:t,current:e})}function Xe(e){let t=e;try{t=y.realpathSync(e)}catch{}let n=t.replace(/\\/g,`/`);return/\/\.bun\//.test(n)?{pm:`bun`,command:[`bun`,`add`,`-g`,`${A}@latest`]}:/\/\.pnpm\//.test(n)||/\/pnpm(-global)?\//i.test(n)||/\/Library\/pnpm\//.test(n)?{pm:`pnpm`,command:[`pnpm`,`add`,`-g`,`${A}@latest`]}:/\/\.config\/yarn\/global\//.test(n)||/\/yarn\/global\//.test(n)||/\/Yarn\/Data\/global\//.test(n)?{pm:`yarn`,command:[`yarn`,`global`,`add`,`${A}@latest`]}:{pm:`npm`,command:[`npm`,`install`,`-g`,`${A}@latest`]}}function j(e){try{return JSON.parse(y.readFileSync(e,`utf8`))}catch{return null}}function Ze(e,t){let n=`${e}.tmp`;y.writeFileSync(n,`${JSON.stringify(t,null,2)}\n`,`utf8`),y.renameSync(n,e)}function Qe(e){let t=0,n=``;return()=>{let r;try{r=y.statSync(e).size}catch{return[]}if(r<t&&(t=0,n=``),r===t)return[];let i;try{i=y.openSync(e,`r`)}catch{return[]}try{let e=Buffer.alloc(r-t),a=y.readSync(i,e,0,e.length,t);t+=a;let o=(n+e.toString(`utf8`,0,a)).split(`
|
|
8
|
-
`);return n=o.pop()??``,o.filter(Boolean)}finally{y.closeSync(i)}}}const $e=new Set(`commit.checkout.switch.restore.stash.reset.rebase.merge.push.pull.cherry-pick.revert.clean.am.apply.tag.branch.worktree.filter-branch.filter-repo.gc.prune.reflog.remote.submodule.config`.split(`.`)),et=[/\bsudo\b/,/\brm\s+(-[a-zA-Z]*r[a-zA-Z]*f|-[a-zA-Z]*f[a-zA-Z]*r)\b.*\s(\/\*?|~\/?|\$HOME\/?)(\s|$)/,/\b(shutdown|reboot|halt|poweroff)\b/,/\bmkfs\b|\bdiskutil\s+erase/i,/\b(chmod|chown)\b.*-R.*\s\/(\s|$)/,/\bkill(all)?\s+-9\s+1\b/,/curl[^|;&]*\|\s*(ba|z|da)?sh\b/,/wget[^|;&]*\|\s*(ba|z|da)?sh\b/,/\blaunchctl\b|\bsystemctl\b/,/\bdefaults\s+write\b/,/>\s*\/dev\/(sd|disk)/],tt=new Set([`status`,`log`,`diff`,`show`,`blame`,`rev-parse`,`ls-files`,`ls-tree`,`cat-file`,`describe`,`shortlog`,`grep`,`branch`,`stash`]);function nt(e){let t=e.match(/^\s*(?:ba|z|da)?sh\s+(?:-[a-zA-Z]+\s+)*(?:-c\s+)?(["'])([\s\S]*)\1\s*$/);return t?t[2]:e}function rt(e){return e.trim().split(/\s+/).filter(Boolean)}function it(e){let t=e.find((e,t)=>t>0&&!e.startsWith(`-`));if(!t)return{decision:`accept`,reason:`bare git`};if(t===`branch`&&e.some(e=>/^-(d|D|m|M|c|C|f|u)|^--(delete|move|copy|force|set-upstream)/.test(e)))return{decision:`decline`,reason:`git branch write operation (git is read-only for Coder)`};if(t===`stash`){let t=e.find((e,t)=>t>1&&!e.startsWith(`-`));return t===`list`||t===`show`?{decision:`accept`,reason:`git stash ${t} is read-only`}:{decision:`decline`,reason:`git stash write operation (git is read-only for Coder)`}}return tt.has(t)?{decision:`accept`,reason:`git ${t} is read-only`}:$e.has(t)?{decision:`decline`,reason:`git ${t} is a write operation (git is read-only for Coder)`}:{decision:`escalate`,reason:`unrecognized git subcommand: ${t}`}}function at(e,t={}){let n=nt(String(e??``));if(!n.trim())return{decision:`escalate`,reason:`empty command`};for(let e of et)if(e.test(n))return{decision:`decline`,reason:`matches hard-deny pattern ${e}`};if(/\$\(|`|<\(/.test(n))return{decision:`escalate`,reason:`contains command substitution`};let r=n.split(/&&|\|\||;|\||\r?\n/).map(e=>e.trim()).filter(Boolean);if(r.length>1){let e={decision:`accept`,reason:`all segments safe`};for(let n of r){let r=at(n,t);if(r.decision===`decline`)return r;r.decision===`escalate`&&(e=r)}return e}let i=rt(n),a=b.basename(i[0]??``);if(a===`git`)return it(i);let o=t.networkHost;return o?(t.allowedNetworkHosts??[]).some(e=>o===e||o.endsWith(`.${e}`))?{decision:`accept`,reason:`network host ${o} is allowlisted`}:{decision:`escalate`,reason:`network access to ${o}`}:{decision:`escalate`,reason:`command needs approval: ${a||`(unknown)`}`}}function ot(e,t){if(!e.length)return{decision:`escalate`,reason:`file change with no resolvable paths`};for(let n of e){let e=b.resolve(t,n),r=b.relative(t,e);if(r.startsWith(`..`)||b.isAbsolute(r))return{decision:`escalate`,reason:`path outside workspace: ${n}`};if(r===`.git`||r.startsWith(`.git${b.sep}`))return{decision:`decline`,reason:`direct .git modification: ${n}`}}return{decision:`accept`,reason:`all paths inside workspace`}}function st(e){return b.join(e,`approvals`)}function ct(e){let t=st(e);return y.existsSync(t)?y.readdirSync(t).filter(e=>e.endsWith(`.request.json`)).flatMap(e=>{let n=e.replace(/\.request\.json$/,``),r=j(b.join(t,e));if(!r)return[];let i=j(b.join(t,`${n}.response.json`));return[{...r,id:n,response:i}]}).sort((e,t)=>String(e.createdAt??``).localeCompare(String(t.createdAt??``))):[]}function lt(e,t,n){let r=st(e),i=b.join(r,`${t}.request.json`);if(!y.existsSync(i))throw Error(`No pending approval "${t}" for this job.`);y.writeFileSync(b.join(r,`${t}.response.json`),`${JSON.stringify({decision:n,answeredAt:new Date().toISOString()},null,2)}\n`,`utf8`)}async function M(e,t,{timeoutMs:n,onEvent:r}){let i=st(e);y.mkdirSync(i,{recursive:!0});let a=`apr-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`;y.writeFileSync(b.join(i,`${a}.request.json`),`${JSON.stringify({...t,createdAt:new Date().toISOString()},null,2)}\n`,`utf8`),r?.({kind:`approval-escalated`,approvalId:a,summary:t.summary,message:`Approval needed (${a}): ${t.summary}. Answer with: coder approve ${b.basename(e)} ${a} [--deny]`});let o=b.join(i,`${a}.response.json`),s=Date.now()+n;for(;Date.now()<s;){if(y.existsSync(o))try{let e=JSON.parse(y.readFileSync(o,`utf8`)).decision===`accept`?`accept`:`decline`;return r?.({kind:`approval-answered`,approvalId:a,decision:e}),e}catch{}await new Promise(e=>setTimeout(e,400))}return r?.({kind:`approval-timeout`,approvalId:a,message:`Approval ${a} timed out; declining.`}),`decline`}function ut(e,t={}){return M(e,{method:`simulate`,summary:`simulated approval probe (--simulate-approval)`},{timeoutMs:t.timeoutMs??12e4,onEvent:t.onEvent??null})}function dt({workspaceRoot:e,jobDir:t,mode:n=`auto`,escalationTimeoutMs:r=12e4,allowedNetworkHosts:i=[],onEvent:a=null}){return async(o,s,c)=>{if(o===`item/commandExecution/requestApproval`){let e=s.command??c?.itemIndex?.get(s.itemId??``)?.command??``,l=`run command: ${e||`(unknown command)`}${s.reason?` — ${s.reason}`:``}`;if(n===`deny`)return a?.({kind:`approval-decision`,method:o,decision:`decline`,reason:`deny mode`,summary:l}),{decision:`decline`};let u=at(e,{networkHost:s.networkApprovalContext?.host??null,allowedNetworkHosts:i});return a?.({kind:`approval-decision`,method:o,decision:u.decision,reason:u.reason,summary:l}),u.decision===`escalate`?{decision:await M(t,{method:o,summary:l,command:e,params:s},{timeoutMs:r,onEvent:a})}:{decision:u.decision}}if(o===`item/fileChange/requestApproval`){let i=(c?.itemIndex?.get(s.itemId??``)?.changes??[]).map(e=>e.path).filter(e=>!!e),l=`apply file changes: ${i.join(`, `)||`(unknown paths)`}${s.reason?` — ${s.reason}`:``}`;if(n===`deny`)return a?.({kind:`approval-decision`,method:o,decision:`decline`,reason:`deny mode`,summary:l}),{decision:`decline`};let u=ot(i,e);return a?.({kind:`approval-decision`,method:o,decision:u.decision,reason:u.reason,summary:l}),u.decision===`escalate`?{decision:await M(t,{method:o,summary:l,paths:i,params:s},{timeoutMs:r,onEvent:a})}:{decision:u.decision}}throw a?.({kind:`approval-unsupported`,method:o}),Error(`Coder does not handle server request ${o}; treating as denied.`)}}async function ft(e,t,n=400){let r=t;for(;;){if(a.includes(r.status))return{job:r,reason:`terminal`};let t=ct(o(e,r.id)).filter(e=>!e.response);if(t[0])return{job:r,reason:`approval`,approval:{id:t[0].id,summary:String(t[0].summary??``)}};await new Promise(e=>setTimeout(e,n)),r=d(e,m(e,r.id)??r)}}const pt=`Coder Task`;function mt(e){return e.split(/\r?\n/).map(e=>e.trimEnd()).filter(e=>e&&!e.startsWith(`WARNING: proceeding, even though we could not update PATH:`)).join(`
|
|
9
|
-
`)}function ht(e,t=72){let n=String(e??``).trim().replace(/\s+/g,` `);return n?n.length<=t?n:`${n.slice(0,t-3)}...`:``}function gt(e){let t=ht(e,56);return t?`${pt}: ${t}`:pt}function _t(e){return e?.params?.threadId??null}function vt(e){return e?.params?.turnId?e.params.turnId:e?.params?.turn?.id?e.params.turn.id:null}function yt(e){let t=new Set;for(let n of e)for(let e of n.changes??[])e.path&&t.add(e.path);return[...t]}function bt(e){if(!e||typeof e!=`object`)return null;let t=e=>typeof e==`number`&&Number.isFinite(e)?e:0,n=t(e.inputTokens),r=t(e.cachedInputTokens),i=t(e.outputTokens);return{input:n,cachedInput:r,output:i,total:t(e.totalTokens)||n+r+i}}function xt(e){if(e.tokenUsageByThread.size===0)return null;let t={input:0,cachedInput:0,output:0,total:0};for(let n of e.tokenUsageByThread.values())t.input+=n.input,t.cachedInput+=n.cachedInput,t.output+=n.output,t.total+=n.total;return t}function St(e){return String(e??``).replace(/\s+/g,` `).trim()}function N(e){if(!e)return[];if(typeof e==`string`){let t=St(e);return t?[t]:[]}if(Array.isArray(e))return e.flatMap(e=>N(e));if(typeof e==`object`){let t=e;if(typeof t.text==`string`)return N(t.text);if(`summary`in t)return N(t.summary);if(`content`in t)return N(t.content);if(`parts`in t)return N(t.parts)}return[]}function Ct(e,t){let n=[];for(let r of[...e,...t]){let e=St(r);!e||n.includes(e)||n.push(e)}return n}function P(e,t,n=null,r={}){!e||!t||e({message:t,phase:n,...r})}function wt(e){switch(e.type){case`commandExecution`:return{message:`Running command: ${String(e.command??``).trim()}`,phase:`running`};case`fileChange`:return{message:`Applying ${e.changes.length} file change(s).`,phase:`editing`};case`mcpToolCall`:return{message:`Calling ${e.server}/${e.tool}.`,phase:`investigating`};case`dynamicToolCall`:return{message:`Running tool: ${e.tool}.`,phase:`investigating`};case`webSearch`:return{message:`Searching: ${String(e.query??``).trim()}`,phase:`investigating`};default:return null}}function Tt(e){switch(e.type){case`commandExecution`:{let t=String(e.aggregatedOutput??``).trim();return{message:`Command ${e.status===`completed`?`completed`:e.status}: ${String(e.command??``).trim()} (exit ${e.exitCode??`?`})`+(t?`\n${t}`:``),phase:`running`}}case`fileChange`:return{message:`File changes ${e.status}.`,phase:`editing`};case`mcpToolCall`:return{message:`Tool ${e.server}/${e.tool} ${e.status}.`,phase:`investigating`};case`dynamicToolCall`:return{message:`Tool ${e.tool} ${e.status}.`,phase:`investigating`};default:return null}}function Et(e,t={}){let n,r,i=new Promise((e,t)=>{n=e,r=t});return{threadId:e,rootThreadId:e,threadIds:new Set([e]),threadTurnIds:new Map,turnId:null,bufferedNotifications:[],completion:i,resolveCompletion:n,rejectCompletion:r,finalTurn:null,completed:!1,finalAnswerSeen:!1,pendingCollaborations:new Set,activeSubagentTurns:new Set,completionTimer:null,lastAgentMessage:``,reasoningSummary:[],error:null,fileChanges:[],commandExecutions:[],tokenUsageByThread:new Map,itemIndex:new Map,onProgress:t.onProgress??null,onHeartbeat:t.onHeartbeat??null}}function Dt(e){e.completionTimer&&=(clearTimeout(e.completionTimer),null)}function Ot(e,t=null){e.completed||(Dt(e),e.completed=!0,t?(e.finalTurn=t,e.turnId||=t.id??null):e.finalTurn||={id:e.turnId??`inferred-turn`,status:`completed`},e.resolveCompletion(e))}function kt(e){e.completed||e.finalTurn||!e.finalAnswerSeen||e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||(Dt(e),e.completionTimer=setTimeout(()=>{e.completionTimer=null,!(e.completed||e.finalTurn||!e.finalAnswerSeen)&&(e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||Ot(e,null))},250),e.completionTimer.unref?.())}function At(e,t){let n=_t(t);if(!n||!e.threadIds.has(n))return!1;let r=e.threadTurnIds.get(n)??null,i=vt(t);return r===null||i===null||i===r}function jt(e,t,n,r=null){if(t.id&&e.itemIndex.set(t.id,t),t.type===`collabAgentToolCall`){(!r||r===e.threadId)&&(n===`started`||t.status===`inProgress`?e.pendingCollaborations.add(t.id):n===`completed`&&(e.pendingCollaborations.delete(t.id),kt(e)));for(let n of t.receiverThreadIds??[])e.threadIds.add(n)}if(t.type===`agentMessage`){t.text&&(!r||r===e.threadId)&&(e.lastAgentMessage=t.text,n===`completed`&&t.phase===`final_answer`&&(e.finalAnswerSeen=!0,kt(e)));return}if(t.type===`reasoning`&&n===`completed`){e.reasoningSummary=Ct(e.reasoningSummary,N(t.summary));return}if(t.type===`fileChange`&&n===`completed`){e.fileChanges.push(t);return}t.type===`commandExecution`&&n===`completed`&&e.commandExecutions.push(t)}function Mt(e,t){switch(e.onHeartbeat?.(),t.method){case`thread/started`:e.threadIds.add(t.params.thread.id);break;case`turn/started`:e.threadIds.add(t.params.threadId),e.threadTurnIds.set(t.params.threadId,t.params.turn.id),(t.params.threadId??null)!==e.threadId&&e.activeSubagentTurns.add(t.params.threadId),P(e.onProgress,`Turn started (${t.params.turn.id}).`,`starting`,{threadId:t.params.threadId??null,turnId:t.params.turn.id??null});break;case`item/started`:jt(e,t.params.item,`started`,t.params.threadId??null);{let n=wt(t.params.item);P(e.onProgress,n?.message,n?.phase??null)}break;case`item/completed`:jt(e,t.params.item,`completed`,t.params.threadId??null);{let n=Tt(t.params.item);P(e.onProgress,n?.message,n?.phase??null)}break;case`thread/tokenUsage/updated`:{let n=bt(t.params?.tokenUsage?.total??t.params?.tokenUsage),r=_t(t);n&&r&&e.tokenUsageByThread.set(r,n);break}case`error`:e.error=t.params.error,P(e.onProgress,`Codex error: ${t.params.error.message}`,`failed`);break;case`turn/completed`:if((t.params.threadId??null)!==e.threadId){e.activeSubagentTurns.delete(t.params.threadId),kt(e);break}P(e.onProgress,`Turn ${t.params.turn.status}.`,`finalizing`),Ot(e,t.params.turn)}}async function Nt(e,t,n,r={}){let i=Et(t,r),a=e.notificationHandler;e.setNotificationHandler(e=>{if(!i.turnId){i.bufferedNotifications.push(e);return}if(e.method===`thread/started`){Mt(i,e);return}if(!At(i,e)){a?.(e);return}Mt(i,e)});let o=r.onApprovalRequest;o&&e.setServerRequestHandler((e,t)=>o(e,t,i));try{let e=await n();i.turnId=e.turn?.id??null,i.turnId&&i.threadTurnIds.set(i.threadId,i.turnId);for(let e of i.bufferedNotifications)At(i,e)?Mt(i,e):a?.(e);return i.bufferedNotifications.length=0,e.turn?.status&&e.turn.status!==`inProgress`&&Ot(i,e.turn),await i.completion}finally{Dt(i),e.setNotificationHandler(a??null),e.setServerRequestHandler(null)}}async function Pt(e,t){let n=null;try{n=await _.connect(e);let r=await t(n);return await n.close(),r}catch(r){let i=r,a=n?.transport===`broker`||!!process.env.CODER_APP_SERVER_ENDPOINT,o=n?.transport===`broker`&&i?.rpcCode===-32001||a&&(i?.code===`ENOENT`||i?.code===`ECONNREFUSED`);if(n&&=(await n.close().catch(()=>{}),null),!o)throw r;let s=await _.connect(e,{disableBroker:!0});try{return await t(s)}finally{await s.close()}}}function F(e){let t=p(`codex`,[`--version`],{cwd:e});if(!t.available)return t;let n=p(`codex`,[`app-server`,`--help`],{cwd:e});return n.available?{available:!0,detail:`${t.detail}; app-server runtime available`}:{available:!1,detail:`${t.detail}; app-server runtime unavailable: ${n.detail}`}}async function Ft(e){let t=F(e);if(!t.available)return{available:!1,loggedIn:!1,detail:t.detail};let n=null;try{n=await _.connect(e,{reuseExistingBroker:!0});let t=await n.request(`account/read`,{refreshToken:!1}),r=t?.account??null;return r?.type===`chatgpt`?{available:!0,loggedIn:!0,detail:r.email?`ChatGPT login active for ${r.email}`:`ChatGPT login active`}:r?.type===`apiKey`?{available:!0,loggedIn:!0,detail:`API key configured`}:t?.requiresOpenaiAuth===!1?{available:!0,loggedIn:!0,detail:`Active provider does not require OpenAI authentication`}:{available:!0,loggedIn:!1,detail:"Not authenticated. Run `codex login`."}}catch(e){let t=S(`codex`,[`login`,`status`],{encoding:`utf8`}),n=`${t.stdout??``}${t.stderr??``}`.trim();return t.status===0?{available:!0,loggedIn:!0,detail:n||`Logged in`}:{available:!0,loggedIn:!1,detail:n||(e instanceof Error?e.message:String(e))}}finally{await n?.close().catch(()=>{})}}async function It(e,{threadId:t,turnId:n}){if(!t||!n)return{interrupted:!1,detail:`missing threadId or turnId`};let r=null;try{return r=await _.connect(e,{reuseExistingBroker:!0}),await r.request(`turn/interrupt`,{threadId:t,turnId:n}),{interrupted:!0,detail:`Interrupted ${n} on ${t}.`}}catch(e){return{interrupted:!1,detail:e instanceof Error?e.message:String(e)}}finally{await r?.close().catch(()=>{})}}async function Lt(e,{threadId:t,text:n}){if(!t)return{steered:!1,detail:`missing threadId`};let r=n.trim();if(!r)return{steered:!1,detail:`empty follow-up`};let i=null;try{return i=await _.connect(e,{reuseExistingBroker:!0}),await i.request(`turn/steer`,{threadId:t,input:[{type:`text`,text:r,text_elements:[]}]}),{steered:!0,detail:`Steered follow-up into the active turn on ${t}.`}}catch(e){return{steered:!1,detail:e instanceof Error?e.message:String(e)}}finally{await i?.close().catch(()=>{})}}async function Rt(e,t={}){let n=F(e);if(!n.available)throw Error(`Codex CLI is not available: ${n.detail}`);let r=t.prompt?.trim();if(!r)throw Error(`A prompt is required.`);return Pt(e,async n=>{let a;if(t.resumeThreadId)P(t.onProgress,`Resuming thread ${t.resumeThreadId}.`,`starting`),ee(t.resumeThreadId)&&await i(t.resumeThreadId),a=(await n.request(`thread/resume`,{threadId:t.resumeThreadId,cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`})).thread.id;else{P(t.onProgress,`Starting Codex task thread.`,`starting`),a=(await n.request(`thread/start`,{cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`,serviceName:`coder_runtime`,ephemeral:t.ephemeral??!1})).thread.id;try{await n.request(`thread/name/set`,{threadId:a,name:gt(r)})}catch(e){let t=String(e?.message??e??``);if(!t.includes(`unknown variant`)&&!t.includes(`unknown method`))throw e}}P(t.onProgress,`Thread ready (${a}).`,`starting`,{threadId:a});let o=await Nt(n,a,()=>n.request(`turn/start`,{threadId:a,input:[{type:`text`,text:r,text_elements:[]}],model:t.model??null,effort:t.effort??null,outputSchema:t.outputSchema??null}),{onProgress:t.onProgress,onHeartbeat:t.onHeartbeat,onApprovalRequest:t.onApprovalRequest});return{status:o.finalTurn?.status===`completed`?0:1,threadId:a,turnId:o.turnId,finalMessage:o.lastAgentMessage,reasoningSummary:o.reasoningSummary,turn:o.finalTurn,error:o.error,stderr:mt(n.stderr),fileChanges:o.fileChanges,touchedFiles:yt(o.fileChanges),tokens:xt(o),model:t.model??null,commandExecutions:o.commandExecutions}})}const zt={chain:[`codex`,`claude`],agents:{codex:{model:`gpt-5.6-terra`,effort:`high`,permissions:`auto`},claude:{model:`opus`,effort:`medium`,permissions:`auto`}},models:{},approvals:{escalationTimeoutMs:12e4,allowedNetworkHosts:[]}},I={mini:`gpt-5.4-mini`,luna:`gpt-5.6-luna`,terra:`gpt-5.6-terra`,sol:`gpt-5.6-sol`},L=new Set([`low`,`medium`,`high`]),R={haiku:`haiku`,sonnet:`sonnet`,opus:`opus`,fable:`fable`},z=new Set([`low`,`medium`,`high`]),Bt={"read-only":{sandbox:`read-only`,approvalPolicy:`never`,approvalMode:null},"workspace-write":{sandbox:`workspace-write`,approvalPolicy:`never`,approvalMode:null},auto:{sandbox:`workspace-write`,approvalPolicy:`on-request`,approvalMode:`auto`}},Vt={"read-only":[`--permission-mode`,`dontAsk`,`--disallowedTools`,`Edit`,`Write`,`NotebookEdit`],"workspace-write":[`--permission-mode`,`acceptEdits`],auto:[`--permission-mode`,`auto`]},Ht=/failIfUnavailable|sandbox\b[^.\n]*?(?:failed|could ?n[o']t|cannot|unavailable|not available|not supported)/i;function Ut(e,t){return JSON.stringify(e===`read-only`?{sandbox:{enabled:!0,failIfUnavailable:!0,autoAllowBashIfSandboxed:!0,filesystem:{denyWrite:[t]}}}:{sandbox:{enabled:!0,autoAllowBashIfSandboxed:!0}})}const Wt=C.enum([`codex`,`claude`]),Gt=C.enum([`codex`,`claude`,`custom`]),Kt=C.enum([`low`,`medium`,`high`]),qt=C.enum([`read-only`,`workspace-write`,`auto`]),Jt=C.partial(C.strictObject({model:C.string().check(C.minLength(1)),effort:Kt,permissions:qt})),Yt=C.strictObject({baseUrl:C.url(),model:C.string().check(C.minLength(1)),envKey:C.optional(C.string().check(C.minLength(1))),wireApi:C.optional(C.enum([`chat`,`responses`])),disabled:C.optional(C.boolean())}),Xt=C.strictObject({provider:Wt,model:C.string().check(C.minLength(1)),effort:C.optional(Kt),disabled:C.optional(C.boolean())}),Zt=C.strictObject({disabled:C.boolean()}),Qt=C.union([Yt,Xt,Zt]),$t=C.strictObject({escalationTimeoutMs:C.number().check(C.positive()),allowedNetworkHosts:C.array(C.string())}),en=C.strictObject({chain:C.array(Gt).check(C.minLength(1)),agents:C.partial(C.strictObject({codex:Jt,claude:Jt,custom:Jt})),models:C.optional(C.record(C.string().check(C.regex(/^[a-z0-9][a-z0-9./_-]*$/i,`model name`)),Qt)),approvals:$t}),tn=C.partial(C.extend(en,{approvals:C.partial($t)}));function B(e){return`baseUrl`in e}function V(e){return`provider`in e}function H(e){let t=tn.safeParse(e);if(!t.success)return t.error.issues.map(e=>`${e.path.join(`.`)||`config`}: ${e.message}`);let n=rn(zt,t.data),r=[];for(let[e,i]of Object.entries(t.data.models??{})){if(e===`codex`||e===`claude`||e===`custom`){r.push(`models.${e}: reserved agent name`);continue}if(V(i)){let t=n.models?.[i.model];t&&!B(t)&&r.push(`models.${e}: alias target "${i.model}" is itself a config entry`)}}return r}function nn(e){if(!y.existsSync(e))return null;try{return JSON.parse(y.readFileSync(e,`utf8`))}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`Invalid JSON in ${e}: ${n}`)}}function rn(e,t){if(!t||typeof t!=`object`||Array.isArray(t))return t??e;let n={...e},r=e;for(let[e,i]of Object.entries(t))n[e]=i&&typeof i==`object`&&!Array.isArray(i)&&r?.[e]&&typeof r[e]==`object`?rn(r[e],i):i;return n}function U(){return b.join(r(),`config.json`)}function an(e){let t=s(e),n=zt;for(let e of[U(),b.join(t,`coder.config.json`)]){let t=nn(e);if(!t)continue;let r=H(t);if(r.length)throw Error(`Invalid config in ${e}:\n ${r.join(`
|
|
10
|
-
`)}`);n=rn(n,t)}let r=H(n);if(r.length)throw Error(`Invalid merged config:\n ${r.join(`
|
|
11
|
-
`)}`);return n}function on(e){return e.replace(/\/+$/,``).replace(/\/(chat\/completions|completions|responses)$/,``)}function sn(e,t,n){let r=[b.join(s(e),`coder.config.json`),U()];for(let e of r){let r;try{r=nn(e)}catch{continue}if(r?.models?.[t])return Object.assign(r.models[t],n),!H(r).length&&(y.writeFileSync(e,`${JSON.stringify(r,null,2)}\n`,`utf8`),!0)}return!1}function cn(e){return/\/(chat\/completions|completions|responses)\/*$/.test(e)}function ln(e,t){let n=on(e);return cn(e)||/\/v\d+(alpha|beta)?$/.test(n)?[`${n}/${t}`]:[`${n}/${t}`,`${n}/v1/${t}`]}function un(e,t,n){let r=t?e.models?.[t]:void 0;if(!t||!r||!B(r))return null;let i=`coder-${t}`;return{model:r.model,modelProvider:i,configOverrides:{[`model_providers.${i}`]:{name:t,base_url:n?.url??on(r.baseUrl),...r.envKey&&!n?{env_key:r.envKey}:{},wire_api:`responses`}}}}function dn(e){return e?I[e]??e:null}function fn(e){return e in I||e in R}function pn(e,t){return!!(t&&e.models?.[t]?.disabled)}function mn(e,t){if(pn(e,t))throw Error(`model "${t}" is disabled in config`)}function hn(e,t){if(!e)return null;let n=String(e).trim().split(`:`).map(e=>e.trim());if(!n.length||n.length>3||n.some(e=>!e))throw Error(`Invalid agent spec "${e}".`);let r=null,i=null,a=null,o=e=>L.has(e)||z.has(e);for(let t of n)if(t===`codex`||t===`claude`||t===`custom`){if(r)throw Error(`Invalid agent spec "${e}".`);r=t}else if(o(t)&&!a)a=t;else if(!i)i=t;else throw Error(`Invalid agent spec "${e}".`);let s=i?t.models?.[i]:void 0;if(s&&V(s)){if(s.disabled)throw Error(`model "${i}" is disabled in config`);if(r&&r!==s.provider)throw Error(`Alias "${i}" runs on ${s.provider}, not ${r}.`);r=s.provider,a=a??s.effort??null,i=s.model}r||=i&&i in R?`claude`:i&&s&&B(s)?`custom`:`codex`;let c=t.agents[r]??{},l=i??c.model??null;return mn(t,l),{agent:r,model:l,effort:a??c.effort??null}}function gn(e){let t=U();return y.mkdirSync(b.dirname(t),{recursive:!0}),y.writeFileSync(t,`${JSON.stringify(e,null,2)}\n`,`utf8`),t}function _n(e){return typeof e==`string`?e:Array.isArray(e)?e.map(e=>typeof e?.text==`string`?e.text:``).join(``):e==null?``:JSON.stringify(e)}function vn(e){if(!e||typeof e!=`object`)return null;let t=e=>typeof e==`number`&&Number.isFinite(e)?e:0,n=t(e.input_tokens),r=t(e.cache_read_input_tokens)+t(e.cache_creation_input_tokens),i=t(e.output_tokens);return{input:n,cachedInput:r,output:i,total:n+r+i}}function yn(){let e=S(`claude`,[`--version`],{encoding:`utf8`});return e.error||e.status!==0?{available:!1,detail:`claude CLI not found on PATH (npm install -g @anthropic-ai/claude-code)`}:{available:!0,detail:String(e.stdout||``).trim()}}function bn(){let e=S(`claude`,[`auth`,`status`,`--json`],{encoding:`utf8`});if(e.error||e.status!==0)return{loggedIn:!1,detail:`not logged in`};try{let t=JSON.parse(String(e.stdout||``));return t.loggedIn?{loggedIn:!0,detail:[t.email,t.subscriptionType].filter(Boolean).join(`, `)||`logged in`}:{loggedIn:!1,detail:`not logged in`}}catch{return{loggedIn:!1,detail:`unknown`}}}async function xn(e,t){let n=t.resumeSessionId??pe(),r=[`-p`,t.prompt,`--output-format`,`stream-json`,`--verbose`];r.push(t.resumeSessionId?`--resume`:`--session-id`,n),t.model&&r.push(`--model`,t.model),t.effort&&r.push(`--effort`,t.effort);let i=t.permissions??`auto`;if(i===`auto`&&t.approvalJobId){let n=JSON.stringify({mcpServers:{coder:{type:`stdio`,command:process.execPath,args:[te,`_mcp`,t.approvalJobId,`--cwd`,e]}}});r.push(`--permission-mode`,`default`,`--mcp-config`,n,`--permission-prompt-tool`,`mcp__coder__approval_prompt`)}else r.push(...Vt[i]??Vt.auto);let a=Ut(i,e);return a&&r.push(`--settings`,a),t.onProgress?.({message:`claude turn started (session ${n})`,threadId:n}),new Promise((i,a)=>{let o=x(`claude`,r,{cwd:e,stdio:[`ignore`,`pipe`,`pipe`]}),s=``,c=``,l=null,u=n,d=e=>{if(!(!e||typeof e!=`object`))if(t.onHeartbeat?.(),e.type===`system`&&e.subtype===`init`&&e.session_id)u=e.session_id;else if(e.type===`assistant`)for(let n of e.message?.content??[])n?.type===`tool_use`&&t.onProgress?.({message:`${n.name} ${JSON.stringify(n.input??{})}`,threadId:u});else if(e.type===`user`){for(let n of e.message?.content??[])if(n?.type===`tool_result`){let e=_n(n.content).trim();e&&t.onProgress?.({message:e,threadId:u})}}else e.type===`result`&&(l=e,e.session_id&&(u=e.session_id))};o.stdout.on(`data`,e=>{s+=e;let t;for(;(t=s.indexOf(`
|
|
12
|
-
`))>=0;){let e=s.slice(0,t).trim();if(s=s.slice(t+1),e)try{d(JSON.parse(e))}catch{}}}),o.stderr.on(`data`,e=>{c+=e});let f=()=>{o.kill(`SIGTERM`),process.exit(143)};process.on(`SIGTERM`,f),o.on(`error`,e=>{process.removeListener(`SIGTERM`,f),a(Error(`claude spawn failed: ${e.message}`))}),o.on(`close`,e=>{process.removeListener(`SIGTERM`,f);let n=s.trim();if(n)try{d(JSON.parse(n))}catch{}let r=l?.result??``,a=e!==0||l?.is_error===!0||l==null;i({status:+!!a,threadId:l?.session_id??u,turnId:null,finalMessage:r,tokens:vn(l?.usage),model:l?.modelUsage&&Object.keys(l.modelUsage).join(`+`)||t.model||null,error:a?{message:r||c.trim()||`claude exited ${e}`}:null})})})}function Sn(e){S(`claude`,[`plugin`,`marketplace`,`remove`,`coder-plugins`],{encoding:`utf8`});let t=S(`claude`,[`plugin`,`marketplace`,`add`,e],{encoding:`utf8`}),n=S(`claude`,[`plugin`,`install`,`coder@coder-plugins`],{encoding:`utf8`}),r=t.status===0&&n.status===0;return{marketplace:e,installed:r,note:r?`Plugin installed; restart any running Claude Code session to load it.`:`Automatic install failed (${(n.stderr||t.stderr||`claude not found`).trim()}); run: claude plugin marketplace add "${e}" && claude plugin install coder@coder-plugins`}}function Cn(){return b.join(le.homedir(),`.agents`,`skills`,`coder`)}function wn(){try{let e=y.readFileSync(b.join(Cn(),`SKILL.md`),`utf8`);return/^\s*version:\s*(\S+)/m.exec(e)?.[1]??null}catch{return null}}function Tn(e){let t=Cn();try{let n=b.join(e,`plugins`,`agents`,`skills`,`coder`);y.rmSync(t,{recursive:!0,force:!0}),y.mkdirSync(t,{recursive:!0}),y.cpSync(n,t,{recursive:!0});let r=b.join(t,`SKILL.md`),i=y.readFileSync(r,`utf8`).replace(`
|
|
13
|
-
---
|
|
14
|
-
`,`\nmetadata:\n version: ${h()}\n---\n`);return y.writeFileSync(r,i),{marketplace:t,installed:!0,note:`Skill installed to ~/.agents/skills/coder; restart running sessions to load it.`}}catch(e){return{marketplace:t,installed:!1,note:`Skill install failed: ${e instanceof Error?e.message:String(e)}`}}}function En(e){if(e.available)return null;let t=S(`npm`,[`install`,`-g`,`@openai/codex@latest`],{encoding:`utf8`});return t.status===0?{installed:!0,note:`codex CLI installed (runs your custom models; no login needed for them)`}:{installed:!1,note:`custom models run on the codex CLI and it is not installed; auto-install failed: ${(t.stderr||`npm not found`).trim()}. Run: npm install -g @openai/codex`}}function Dn(e){let t=/(\d+\.\d+\.\d+)/.exec(String(e??``));return t?t[1]:null}function On(e){if(!e.available)return null;let t=Dn(e.detail);if(!t||We(t,`0.144.0`)>=0)return null;let n=S(`codex`,[`update`],{encoding:`utf8`});return n.status!==0&&(n=S(`npm`,[`install`,`-g`,`@openai/codex@latest`],{encoding:`utf8`})),n.status===0?{updated:!0,from:t}:{updated:!1,from:t,note:`codex ${t} is too old for the default GPT-5.6 model (needs >= 0.144.0); auto-update failed: ${(n.stderr||`codex/npm not found`).trim()}. Run: codex update`}}const kn=/usage|quota|rate.?limit|429|401|unauthorized|not authenticated|login|insufficient|exhausted|not available|ENOENT/i,An=`CODER_WORKER`;var W=class extends Error{code;hint;taskId;payload;approval;result;runId;constructor(e,t,n={}){super(t),this.name=`CoderError`,this.code=e,Object.assign(this,n)}},jn=class extends Error{agent;detail;constructor(e,t){super(t),this.agent=e,this.detail=t}};function Mn(e,t){let n=e.agent,r=!!n,i=e.model,a=e.effort,o=e=>{let n=e?t.models?.[e]:void 0;return n&&V(n)?n:void 0},s=e=>{let n=e?t.models?.[e]:void 0;return n&&B(n)?n:void 0};if(o(i)){let e;try{e=hn(i,t)}catch(e){throw new W(`invalid-option`,e instanceof Error?e.message:String(e))}e&&(r||(n=e.agent),i=e.model??void 0,a=a??e.effort??void 0)}if(!n&&i&&(i in R?n=`claude`:i in I?n=`codex`:s(i)&&(n=`custom`)),n=n??t.chain[0]??`codex`,n!==`codex`&&n!==`claude`&&n!==`custom`){let e=n in I||n in R||n in(t.models??{})?` "${n}" is a model; use --model ${n}.`:``;throw new W(`invalid-option`,`Invalid --agent "${n}". Use codex, claude, or custom.${e}`)}let c=t.agents[n]??{},l=i??c.model??null,u=a??c.effort??null;if(o(l)){let e;try{e=hn(l,t)}catch(e){throw new W(`invalid-option`,e instanceof Error?e.message:String(e))}e&&(r||(n=e.agent),l=e.model,u=a??e.effort??u)}let d=e.permissions??c.permissions??`auto`;try{mn(t,l)}catch(e){throw new W(`invalid-option`,e instanceof Error?e.message:String(e))}if(n===`custom`){let e=Object.entries(t.models??{}).filter(([,e])=>B(e)).map(([e])=>e);if(!l&&e.length===1&&(l=e[0]),!l||!s(l))throw new W(`invalid-option`,l?`No custom model named "${l}". Configured: ${e.join(`, `)||`none`}.`:`No custom model to run: pass --model <name> or set agents.custom.model.`,{hint:`Add one: coder model add <name> --base-url <url> --model <id>`})}let f=n===`claude`?`claude`:`codex`;if(!(d in Bt))throw new W(`invalid-option`,`Invalid --permissions "${d}". Use one of: ${Object.keys(Bt).join(`, `)}`);if(f===`codex`&&u&&!L.has(u))throw new W(`invalid-option`,`Invalid codex --effort "${u}". Use one of: ${[...L].join(`, `)}`);if(f===`claude`&&u&&!z.has(u))throw new W(`invalid-option`,`Invalid claude --effort "${u}". Use one of: ${[...z].join(`, `)}`);return{engine:f,agent:n,model:l,effort:u,permissions:d}}function Nn(e,t){return e===`read-only`&&Ht.test(t??``)}function Pn(e,n){let r=o(e,n),i=y.openSync(b.join(r,`worker.log`),`a`),a=x(v.execPath,[te,`_worker`,n,`--cwd`,e],{cwd:e,detached:!0,stdio:[`ignore`,i,i],env:{...v.env,[An]:`1`}});a.unref(),y.closeSync(i),t(e,n,{pid:a.pid??null})}async function Fn(e,r,i,a){let s=i.cwd,l=r.engine===`codex`?F(s):yn(),u=r.model?e.models?.[r.model]:void 0;if(!l.available&&u&&B(u)){let e=En(l);i.onInstallNote?.(e.note),l=F(s)}if(!l.available)throw new jn(r.agent,l.detail);let d=null;a.resume&&(d=n(s,a.resume)?.threadId??a.resume);let f=oe(),ee=t(s,f,{status:`queued`,kind:`task`,name:a.name??null,system:i.system??null,agent:r.agent,engine:r.engine,prompt:i.prompt,model:r.model,effort:r.effort,permissions:r.permissions,resumeThreadId:d,cwd:s,background:!i.wait,...a.simulateApproval?{simulateApproval:!0}:{},...i.flowRunId?{flowRunId:i.flowRunId}:{}});Pn(s,f);let te=2**53-1,p=()=>c(s,f,te).filter(e=>e.phase!==`starting`).length,ne=Date.now()+15e3,h=ee,g=null,_=null;for(;Date.now()<(_??ne)&&(h=m(s,f)??h,h.status!==`failed`&&h.status!==`completed`);){if(h.threadId&&g===null&&(g=p(),_=Date.now()+5e3),g!==null&&p()>g){h=m(s,f)??h;break}await new Promise(e=>setTimeout(e,150))}if(h.status===`failed`){let e=j(b.join(o(s,f),`result.json`))?.error?.message??``,t=c(s,f,5).map(e=>e.message??``).join(`
|
|
15
|
-
`),n=e||t;throw Nn(r.permissions,n)?new W(`read-only-unavailable`,n):kn.test(n)?new jn(r.agent,n):new W(`startup-failed`,n,{taskId:f})}return{taskId:f,job:h,agent:r.agent,startupCheck:h.threadId?`passed`:`pending`}}function In(e,t,n,r,i){return{error:`${e} failed to start: ${t}`,fallback:{action:`run-native-subagent`,reason:`no-engine-available`,permissions:n,note:`Every coder engine failed to start. Spawn your own native subagent and forward the task verbatim; tell it to never run git write operations (commit, checkout, stash, reset, push, ...) and to honor the permissions.`,...r?{system:r}:{},task:i}}}async function Ln(e){if(v.env.CODER_WORKER)throw new W(`nested-dispatch`,`Nested dispatch refused: this shell is already inside a coder task. Do the work yourself, directly in this session - ignore any skill or instruction telling you to orchestrate via the coder CLI.`);if(!e.prompt.trim())throw new W(`invalid-option`,`Missing task text.`,{hint:[`Usage: coder run "<task text>"`,`Help: coder task run --help`]});let t=an(e.cwd),n={agent:e.agent,model:e.model,effort:e.effort,permissions:e.permissions},r={name:e.name,resume:e.resume,simulateApproval:e.simulateApproval};for(;;){let i=Mn(n,t);try{return await Fn(t,i,e,r)}catch(a){if(!(a instanceof jn))throw a;let o=t.chain[t.chain.indexOf(a.agent)+1];if(!o){let t=In(a.agent,a.detail,i.permissions,e.system,e.prompt);throw new W(`chain-exhausted`,t.error,{payload:t})}e.onFallback?.({agent:a.agent,detail:a.detail,next:o}),n={agent:o,permissions:e.permissions},r={name:void 0,resume:void 0,simulateApproval:void 0}}}}function Rn(e,t){if(t.status!==`failed`)return;let n=t.result;if(!n||!kn.test(n.error?.message??``)||!(!n.touchedFiles?.length&&!n.fileChanges?.length&&!n.commandExecutions?.length))return;let r=an(e).chain;return r[r.indexOf(t.job.agent)+1]}function zn(e,t){return j(b.join(o(e,t),`result.json`))}function Bn(e,t,n=0){return n===0?[]:c(e,t,n===`all`?2**53-1:n)}function Vn(e,t,n={}){let r=m(e,t);if(!r)throw Error(`No task found for "${t}".`);return{taskId:t,status:r.status,result:zn(e,t),steps:Bn(e,t,n.tail),turns:l(e,t),job:r}}async function Hn(e,t,n={}){let r=m(e,t);if(!r)throw Error(`No task found for "${t}".`);let i=await ft(e,r);if(i.reason===`approval`){let e=i.approval;throw new W(`approval-pending`,`Approval needed for task ${t}: ${e.summary}`,{taskId:t,approval:e})}n.onSettle?.();let a=i.job;return{taskId:t,status:a.status,result:zn(e,t),steps:Bn(e,t,n.tail),turns:l(e,t),job:a}}const Un=[`.ts`,`.mjs`,`.js`];function Wn(e,t){let n=[];try{n=y.readdirSync(e)}catch{return[]}let r=[];for(let i of n.sort()){let n=b.extname(i);Un.includes(n)&&r.push({name:b.basename(i,n),path:b.join(e,i),scope:t})}return r}function Gn(e){let t=s(e),n=[],i=b.resolve(e);for(;n.push({dir:b.join(i,`.coder`,`flows`),scope:`workspace`}),i!==t&&b.dirname(i)!==i;)i=b.dirname(i);return n.push({dir:b.join(r(),`flows`),scope:`global`}),n}function Kn(e){let t=new Set,n=[];for(let{dir:r,scope:i}of Gn(e))for(let e of Wn(r,i))t.has(e.name)||(t.add(e.name),n.push(e));return n}function qn(e){return e.includes(`/`)||Un.includes(b.extname(e))}function Jn(e,t){if(qn(e)){let n=b.resolve(t,e);if(y.existsSync(n))return{name:b.basename(n,b.extname(n)),path:n};throw Error(`Flow file not found: ${e}`)}let n=Kn(t).find(t=>t.name===e);if(!n)throw Error(`No flow named "${e}". Run \`coder flow discover\` to see available flows.`);return{name:n.name,path:n.path}}function Yn(e,t,n={}){if(t.length)try{x(v.execPath,[te,`_archiveSweep`,`--cwd`,e,...n.flows?[`--flows`]:[],...t],{detached:!0,stdio:`ignore`}).unref()}catch{}}async function Xn(e){let{options:t,positionals:r}=ne(e,C.object({cwd:ie,flows:re})),i=k(t);for(let e of r){if(t.flows){let t=Z(e);t&&Lr(t);continue}let r=n(i,e);r&&ae(i,r)}}async function Zn(e){let{options:t,positionals:n}=ne(e,C.object({...g,"all-stopped":re}));Be(n,1,`task archive`);let r=k(t);if(t[`all-stopped`]){let e=u(r).filter(e=>a.includes(e.status));for(let t of e)ae(r,t);let n=e.map(e=>e.id);if(t.json){D({archived:n,count:n.length});return}v.stdout.write(n.length?`Archived ${n.length} stopped task${n.length===1?``:`s`}.\n`:`${w.dim(`No stopped tasks to archive.`)}\n`);return}let i=n[0];i||E(`Missing task id.`,{hint:[`Archive one: coder task archive <task-id>`,`Archive all stopped: coder task archive --all-stopped`]});let o=Ve(r,i);if(ae(r,o),t.json){D({taskId:o.id,archived:!0});return}v.stdout.write(`Archived task ${w.cyan(o.id)}.\n`)}async function Qn(e,n){let r=n.engine===`claude`?{detail:`claude worker terminated`}:await It(e,{threadId:n.threadId,turnId:n.turnId});if(n.pid&&n.status===`running`)try{v.kill(n.pid,`SIGTERM`)}catch{}return t(e,n.id,{status:`cancelled`,completedAt:new Date().toISOString()}),{taskId:n.id,status:`cancelled`,interrupt:r.detail}}async function $n(e){let{options:t,positionals:n}=ne(e,C.object(g));Be(n,1,`task stop`);let r=k(t),i=Ve(r,n[0]),{interrupt:a}=await Qn(r,i);if(t.json){D({taskId:i.id,status:`cancelled`,interrupt:a});return}v.stdout.write(`Stopped task ${w.cyan(i.id)} ${w.dim(`(${a})`)}\n`)}function er(e){return typeof e!=`object`||!e?JSON.stringify(e)??`null`:Array.isArray(e)?`[${e.map(er).join(`,`)}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${er(e[t])}`).join(`,`)}}`}function tr(e,t){return fe.createHash(`sha256`).update(`${e}\0${er(t)}`).digest(`hex`)}function G(e){return y.existsSync(e)?y.readFileSync(e,`utf8`).split(/\r?\n/).filter(Boolean).map(e=>{try{return JSON.parse(e)}catch{return null}}).filter(e=>e!==null):[]}var nr=class{file;recorded;seq=0;constructor(e,t){this.file=t,this.recorded=e.map(e=>({...e})),y.writeFileSync(t,``,`utf8`)}write(e){e.seq=this.seq++,y.appendFileSync(this.file,`${JSON.stringify(e)}\n`,`utf8`)}replay(e){let t=this.recorded.find(t=>!t.consumed&&t.fingerprint===e);if(!t)return null;t.consumed=!0;let{consumed:n,...r}=t;return this.write(r),r}record(e){this.write({...e,seq:0})}};const rr=globalThis,K=rr.__coderFlowCtxALS??=new me,q=rr.__coderFlowScopeALS??=new me;function ir(){return q.getStore()?.args}function ar(){return q.getStore()?.depth??0}var or=class{limit;active=0;queue=[];constructor(e){this.limit=e}async run(e){this.active<this.limit?this.active+=1:await new Promise(e=>this.queue.push(e));try{return await e()}finally{let e=this.queue.shift();e?e():--this.active}}};function sr(e,t){return t?e?{input:e.input+t.input,cachedInput:e.cachedInput+t.cachedInput,output:e.output+t.output,total:e.total+t.total}:{...t}:e}function cr(e,t){if(!t.tokens)return;let n=t.model??`default`;e.ledger[n]=sr(e.ledger[n]??null,t.tokens)}function lr(e){return!!e&&typeof e.safeParse==`function`}async function ur(e){try{let t=await import(`zod`);if(typeof t.toJSONSchema==`function`)return t.toJSONSchema(e)}catch{}return null}async function dr(e){let t=await ur(e);return`Reply with ONLY a single JSON object ${t?`matching this JSON Schema:\n${JSON.stringify(t,null,2)}`:`matching the requested shape`}\nNo prose, no markdown fences — just the JSON object.`}function fr(e){let t=e.trim(),n=t.match(/```(?:json)?\s*([\s\S]*?)```/i);n&&(t=n[1].trim());let r=t.indexOf(`{`);if(r===-1)throw Error(`no JSON object found in reply`);let i=0,a=!1,o=!1;for(let e=r;e<t.length;e+=1){let n=t[e];if(a){o?o=!1:n===`\\`?o=!0:n===`"`&&(a=!1);continue}if(n===`"`)a=!0;else if(n===`{`)i+=1;else if(n===`}`&&(--i,i===0))return JSON.parse(t.slice(r,e+1))}throw Error(`unterminated JSON object in reply`)}function pr(e,t){if(!lr(e))return{ok:!0,data:t};let n=e.safeParse(t);if(n.success)return{ok:!0,data:n.data};let r=n.error?.issues??n.error?.errors??[];return{ok:!1,errors:Array.isArray(r)?r.map(e=>`${(e.path??[]).join(`.`)||`(root)`}: ${e.message}`).join(`; `):String(n.error)}}function mr(e,t,n){return{cwd:t,agent:e.agent,model:e.model,effort:e.effort,permissions:e.permissions,name:e.name,system:e.system,wait:!0,flowRunId:n?.runId}}async function hr(e,t,n,r){let i=t.cwd?b.resolve(t.cwd):n?.cwd??v.cwd(),a;for(;;){let o=await Ln({prompt:e,...mr(t,i,n),...a?{agent:a,model:void 0,effort:void 0,resume:void 0}:{resume:r??t.resume},onFallback:e=>Tr(`${e.agent} failed to start — falling back to ${e.next} (${e.detail.replace(/\s+/g,` `).slice(0,140)})`)});n?.running.add(o.taskId);let s=m(i,o.taskId),c=s?Ce(s):void 0;n?.hooks.onTaskStart?.({taskId:o.taskId,name:t.name,prompt:e,agent:c,depth:ar()});let l;try{l=await Hn(i,o.taskId)}finally{n?.running.delete(o.taskId)}let u=Rn(i,l);if(u){n?.hooks.onTaskEnd?.({taskId:o.taskId,status:`failed`,tokens:null}),a=u;continue}return{taskId:o.taskId,status:l.status,output:l.result?.finalMessage||l.result?.error?.message||``,tokens:l.result?.tokens??null,model:l.result?.model??l.job.model??null}}}async function gr(e,t,n){let r=e;if(t.returns&&(r=`${e}\n\n${await dr(t.returns)}`),n?.dryRun){v.stdout.write(`\n[dry-run] task${t.name?` (${t.name})`:``}:\n${r}\n`);let e={...t,returns:t.returns?`<schema>`:void 0};return v.stdout.write(`[dry-run] opts: ${JSON.stringify(e)}\n`),{taskId:`dry`,status:`completed`,output:`[dry-run]`,data:void 0,tokens:null,model:t.model??null}}let i=await hr(r,t,n);if(i.status!==`completed`){let e={...i,data:void 0};throw new W(`task-failed`,`Task ${i.taskId} ${i.status}: ${i.output||`no output`}`,{taskId:i.taskId,result:e})}let a=i.output,o=i.tokens,s;if(t.returns){let e;try{e=pr(t.returns,fr(a))}catch(t){e={ok:!1,errors:t instanceof Error?t.message:String(t)}}if(e.ok)s=e.data;else{let r=await hr(`Your previous reply did not match the required format: ${e.errors}\n\n${await dr(t.returns)}`,t,n,i.taskId);a=r.output||a,o=sr(o,r.tokens);try{let e=pr(t.returns,fr(a));if(!e.ok)throw Error(e.errors);s=e.data}catch(e){let t={taskId:i.taskId,status:`completed`,output:a,data:void 0,tokens:o,model:i.model};throw new W(`task-failed`,`Task ${i.taskId} produced no valid structured output: ${e instanceof Error?e.message:String(e)}`,{taskId:i.taskId,result:t})}}}return{taskId:i.taskId,status:`completed`,output:a,data:s,tokens:o,model:i.model}}async function _r(e){if(e)return await ur(e)??`<schema>`}async function vr(e,t={}){let n=K.getStore();if(!n)return gr(e,t);let r=tr(`task`,{prompt:e,agent:t.agent,model:t.model,effort:t.effort,permissions:t.permissions,name:t.name,system:t.system,resume:t.resume,cwd:t.cwd,returns:await _r(t.returns)}),i=n.journal.replay(r);if(i)return i.result;if(n.taskCount+=1,n.taskCount>n.maxTasks)throw Error(`Flow exceeded --max-tasks (${n.maxTasks}). Raise it with --max-tasks, or fix a runaway loop; the run is resumable.`);return n.semaphore.run(async()=>{let i=new Date().toISOString(),a;try{a=await gr(e,t,n)}catch(e){let t=e instanceof W?e.result:void 0;throw t&&n.hooks.onTaskEnd?.({taskId:t.taskId,status:t.status===`completed`?`failed`:t.status,tokens:t.tokens}),e}return cr(n,a),n.dryRun||n.hooks.onTaskEnd?.({taskId:a.taskId,status:a.status,tokens:a.tokens}),n.journal.record({kind:`task`,fingerprint:r,result:a,taskId:a.taskId,tokens:a.tokens,startedAt:i,endedAt:new Date().toISOString()}),a})}const yr=262144;let br=0;function xr(e){let t=[];for(let n=e;;){t.push(b.join(n,`node_modules`,`.bin`));let e=b.dirname(n);if(e===n)break;n=e}let n=v.platform===`win32`?`;`:`:`;return{...v.env,PATH:[...t,v.env.PATH??``].join(n)}}async function Sr(e,t){return new Promise(n=>{let r=x(e,{shell:!0,cwd:t,env:xr(t)}),i=``,a=e=>{i.length>=yr||(i+=e,i.length>=yr&&(i=`${i.slice(0,yr)}\n... [gate output truncated]`))};r.stdout?.on(`data`,a),r.stderr?.on(`data`,a),r.on(`error`,e=>n({ok:!1,code:1,output:String(e.message??e).trim()})),r.on(`close`,e=>n({ok:e===0,code:e??0,output:i.trim()}))})}async function Cr(e,t={}){let n=K.getStore(),r=t.cwd?b.resolve(t.cwd):n?.cwd??v.cwd();if(!n)return Sr(e,r);let i=tr(`gate`,{cmd:e,cwd:t.cwd}),a=n.journal.replay(i);if(a)return a.result;if(n.dryRun){v.stdout.write(`\n[dry-run] gate: ${e}\n`);let t={ok:!0,code:0,output:``};return n.journal.record({kind:`gate`,fingerprint:i,result:t,startedAt:new Date().toISOString(),endedAt:new Date().toISOString()}),t}let o=new Date().toISOString(),s=`gate-${v.pid}-${br+=1}`,c=ar();n.hooks.onGateStart?.({gateId:s,cmd:e,depth:c});let l=await Sr(e,r);return n.hooks.onGate?.({gateId:s,cmd:e,ok:l.ok,code:l.code,depth:c}),n.journal.record({kind:`gate`,fingerprint:i,result:l,startedAt:o,endedAt:new Date().toISOString()}),l}async function wr(e,...t){return Promise.all(e.map(async(e,n)=>{let r=e;for(let i of t)try{r=await i(r,e,n)}catch{return null}return r}))}function Tr(e){let t=K.getStore();if(t)try{y.appendFileSync(b.join(t.runDir,`flow.log`),`${JSON.stringify({at:new Date().toISOString(),message:e})}\n`,`utf8`)}catch{}t?.hooks.onLog?t.hooks.onLog(e,ar()):(v.stderr.isTTY||!t)&&v.stderr.write(`[flow] ${e}\n`)}const Er=ce(import.meta.url);function Dr(e){let t=b.dirname(ue(import.meta.url));for(;b.basename(t)!==`dist`&&b.dirname(t)!==t;)t=b.dirname(t);return b.basename(t)===`dist`?de(b.join(t,e)).href:null}function Or(e){if(!(e===`@wular/coder`||e===`@wular/coder/flow`||e===`zod`||e.startsWith(`zod/`)))return null;try{return de(Er.resolve(e)).href}catch{}return e===`@wular/coder/flow`?Dr(`flow/index.js`):e===`@wular/coder`?Dr(`sdk.js`):null}const kr=/(\bfrom\s+|\bimport\s+|\bimport\s*\(\s*)(['"])([^'"]+)\2/g;function Ar(e){return e.replace(kr,(e,t,n,r)=>{let i=Or(r);return i?`${t}${n}${i}${n}`:e})}async function jr(e,t,n){try{return await import(de(e).href)}catch(e){let r=e instanceof Error?e.message:String(e);throw t===`.ts`&&!v.versions?.bun&&/Unknown file extension|Unexpected token|SyntaxError|Cannot parse|import type|interface/i.test(r)?Error(`Could not run ${b.basename(n)}: TypeScript flows need bun. Run under \`bun\`, or write the flow as .mjs/.js.`):e}}async function Mr(e){let t=b.extname(e),n;try{n=y.readFileSync(e,`utf8`)}catch{throw Error(`Cannot read flow file: ${e}`)}let r=Ar(n);if(r===n)return jr(e,t,e);let i=b.dirname(e);try{for(let e of y.readdirSync(i)){if(!e.startsWith(`.__coderflow_`))continue;let t=b.join(i,e);Date.now()-y.statSync(t).mtimeMs>6e5&&y.unlinkSync(t)}}catch{}let a=`${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`,o=b.join(i,`.__coderflow_${a}${t}`),s=`__coderflow_loaded_${a}`,c=new Promise(e=>{globalThis[s]=e});y.writeFileSync(o,`globalThis[${JSON.stringify(s)}]?.();${r}`,`utf8`);let l=jr(o,t,e);try{await Promise.race([c,l.then(()=>void 0,()=>void 0)])}finally{delete globalThis[s];try{y.unlinkSync(o)}catch{}}return await l}async function Nr(e,t){let n=q.getStore();n.args=t??{};let r=await Mr(e),i=r.args,a=n.args;if(lr(i)){let e=i.safeParse(t??{});if(!e.success){let e=pr(i,t??{});throw Error(`Invalid flow args: ${e.errors??`validation failed`}`)}a=e.data,n.args=a}let o=r.default;return typeof o==`function`?o(a):o}async function Pr(e,t){let n=K.getStore(),r=Jn(e,n?.cwd??v.cwd());if(!n)return q.run({args:t??{},depth:0},()=>Nr(r.path,t));let i=q.getStore();if(i&&i.depth>=1)throw Error(`flow("${e}") nesting is one level deep; a sub-flow cannot call flow().`);let a=tr(`flow`,{name:r.name,args:t??{}}),o=n.journal.replay(a);if(o)return o.result;let s=new Date().toISOString();n.hooks.onFlowStart?.({name:r.name,depth:(i?.depth??0)+1});let c=await q.run({args:t??{},depth:(i?.depth??0)+1},()=>Nr(r.path,t));return n.journal.record({kind:`flow`,fingerprint:a,result:c,startedAt:s,endedAt:new Date().toISOString()}),c}function Fr(){return`flow-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function J(){return b.join(r(),`state`,`global`,`flows`)}function Y(){return b.join(r(),`state`,`global`,`flows-archived`)}function X(e){se(e,`flow run id`);let t=b.join(J(),e);if(y.existsSync(b.join(t,`flow.json`)))return t;let n=b.join(Y(),e);return y.existsSync(b.join(n,`flow.json`))?n:t}function Ir(e){if(e.archived)return e;let t={...e,archived:!0,archivedAt:new Date().toISOString()};return Q(X(e.runId),t),t}function Lr(e){let t=Ir(e),n=X(e.runId),r=b.join(Y(),e.runId);if(n!==r)try{y.mkdirSync(Y(),{recursive:!0}),y.renameSync(n,r)}catch{}return t}function Rr(e){let t=X(e.runId),n=b.join(J(),e.runId);if(t!==n)try{y.mkdirSync(J(),{recursive:!0}),y.renameSync(t,n)}catch{}let r={...e,archived:void 0,archivedAt:void 0};return Q(X(e.runId),r),r}function zr(e){let t=X(e);return y.existsSync(b.join(t,`flow.json`))?(y.rmSync(t,{recursive:!0,force:!0}),!0):!1}function Br(e){if(!f(e))return null;let t=b.join(X(e),`flow.json`);if(!y.existsSync(t))return null;try{return JSON.parse(y.readFileSync(t,`utf8`))}catch{return null}}function Vr(e){return e.status!==`running`||!e.pid||$r(e)?e:(Xr(e.runId,`orchestrator died`),Br(e.runId)??e)}function Z(e){let t=Br(e);return t?Vr(t):null}function Q(e,t){y.writeFileSync(b.join(e,`flow.json`),`${JSON.stringify(t,null,2)}\n`,`utf8`)}function Hr(e){let t=[];try{t=y.readdirSync(e)}catch{return[]}let n=[];for(let r of t)try{n.push(Vr(JSON.parse(y.readFileSync(b.join(e,r,`flow.json`),`utf8`))))}catch{}return n}const Ur=(e,t)=>String(t.startedAt).localeCompare(String(e.startedAt));function Wr(){let e=[];for(let t of Hr(J()))t.archived?Lr(t):e.push(t);return e.sort(Ur)}function Gr(e){let t=e?.migrate??!0,n=Hr(Y()),r=new Set(n.map(e=>e.runId));for(let e of Hr(J()))e.archived&&!r.has(e.runId)&&n.push(t?Lr(e):e);return n.sort(Ur)}function Kr(){return[...Wr(),...Gr()].sort(Ur)[0]??null}function qr(e,t=`all`){if(t===0)return[];let n=G(b.join(X(e),`journal.jsonl`)).filter(e=>e.kind===`task`),r=u(v.cwd()),i=new Map(r.map(e=>[e.id,e])),a=e=>e?.name??e?.prompt?.replace(/\s+/g,` `).trim().slice(0,60)??null,o=n.map(e=>{let t=e.taskId?i.get(e.taskId):void 0;return{taskId:e.taskId??null,name:a(t),status:t?.status??e.result?.status??`?`,tokens:e.tokens??null}}),s=new Set(o.map(e=>e.taskId));for(let t of r)t.flowRunId===e&&!s.has(t.id)&&o.push({taskId:t.id,name:a(t),status:t.status,tokens:null});return t===`all`?o:o.slice(-t)}function Jr(e={}){let t;if(e.archived)t=Gr();else{let e=[];t=Wr().filter(t=>t.status===`running`||t.status===`queued`||ve(t.endedAt??t.startedAt)<=6e5||(Ir(t),e.push(t.runId),!1)),Yn(v.cwd(),e,{flows:!0})}let n=e.limit===void 0?0:Math.max(0,t.length-e.limit);return{runs:e.limit===void 0?t:t.slice(0,e.limit),clipped:n}}function Yr(e,t={},n){let r,i,a;if(n){let e=Z(n);if(!e)throw Error(`No flow run "${n}".`);e.archived&&Rr(e),r=e.name,i=e.script,a=t.args??e.args}else{let n=Jn(e,t.cwd?b.resolve(t.cwd):v.cwd());r=n.name,i=n.path,a=t.args??{}}let o=n??Fr(),s=X(o);y.mkdirSync(s,{recursive:!0});let c={runId:o,name:r,script:i,args:a,status:`running`,startedAt:new Date().toISOString(),concurrency:Math.max(1,t.concurrency??le.cpus().length),maxTasks:Math.max(1,t.maxTasks??le.cpus().length*10),taskCount:0,ledger:{}};return Q(s,c),c}function $(e,t,n){Q(e,{...t,endedAt:new Date().toISOString(),pid:void 0,pidStartedAt:void 0,...n})}function Xr(e,t){let n=Br(e);!n||n.status!==`running`||$(X(e),n,{status:`failed`,error:t})}const Zr=`stop-keep-tasks`;function Qr(e){try{return v.kill(e,0),!0}catch{return!1}}function $r(t){if(!t.pid||!Qr(t.pid))return!1;let n=e(t.pid),r=Date.parse(t.pidStartedAt??``);return n===null||!Number.isFinite(r)||n<=r+6e4}function ei(e){let t=u(v.cwd()),n=new Map(t.map(e=>[e.id,e])),r=new Set(t.filter(t=>t.flowRunId===e).map(e=>e.id));for(let t of G(b.join(X(e),`journal.jsonl`)))t.kind===`task`&&t.taskId&&r.add(t.taskId);return[...r].filter(e=>{let t=n.get(e);return!!t&&!a.includes(t.status)})}async function ti(e,t=[]){let n=v.cwd(),r=[];for(let i of new Set([...ei(e),...t])){let e=m(n,i);if(!(!e||a.includes(e.status)))try{await Qn(n,e),r.push(i)}catch{}}return r}async function ni(e,t={}){let n=e?Z(e):Kr();if(!n)throw new W(`flow-failed`,e?`No flow run "${e}".`:`No flow runs.`,{hint:`Run one: coder flow run <name>`});if(n.status!==`running`)throw new W(`flow-failed`,`Run ${n.runId} is not running.`,{runId:n.runId,hint:`Result: coder flow result ${n.runId}`});let r=X(n.runId);if(!$r(n))return $(r,n,{status:`failed`,error:`orchestrator died`}),{runId:n.runId,status:`failed`,stoppedTasks:[],keptTasks:ei(n.runId)};let i=ei(n.runId),o=b.join(r,Zr);t.keepTasks&&y.writeFileSync(o,``,`utf8`);try{v.kill(n.pid,`SIGINT`);let e=Z(n.runId);for(let t=0;t<25&&e?.status===`running`;t+=1)await new Promise(e=>setTimeout(e,200)),e=Z(n.runId);if(!e||e.status===`running`)throw new W(`flow-failed`,`Run ${n.runId} did not stop within 5s.`,{runId:n.runId,hint:`Check it: coder flow result ${n.runId}`});let t=v.cwd(),r=[],o=[];for(let e of i){let n=m(t,e);n&&(n.status===`cancelled`?r.push(e):a.includes(n.status)||o.push(e))}return{runId:n.runId,status:e.status,stoppedTasks:r,keptTasks:o}}finally{if(t.keepTasks)try{y.unlinkSync(o)}catch{}}}async function*ri(e,t,n={}){let r=b.join(X(e),`events.jsonl`),i=n.tail??`all`,a=0;if(i!==`all`)try{a=Math.max(0,y.readFileSync(r,`utf8`).split(`
|
|
16
|
-
`).length-1-i)}catch{}let o=Qe(r),s=()=>{let e=[];for(let t of o()){if(a>0){--a;continue}try{e.push(JSON.parse(t))}catch{}}return e},c=Z(e);for(;!c||c.status===`running`;){yield*s();let n=c?.pid?!$r(c):t!==void 0&&!Qr(t);if(c&&(c.pid||t!==void 0)&&n){Xr(e,`orchestrator died`);break}await new Promise(e=>setTimeout(e,400)),c=Z(e)??c}yield*s()}function ii(e,t,n,r){let i={...Yr(e,t,r),pid:v.pid,pidStartedAt:new Date().toISOString()},{runId:a}=i,o=X(a);Q(o,i);let s=b.join(o,`journal.jsonl`),c=r?G(s):[],l=new nr(c,s),u={runId:a,runDir:o,cwd:t.cwd?b.resolve(t.cwd):v.cwd(),journal:l,semaphore:new or(i.concurrency),maxTasks:i.maxTasks,dryRun:t.dryRun??!1,ledger:{},running:new Set,taskCount:0,stopping:!1,hooks:n};return{started:{runId:a,runDir:o,ctx:u,markStopped:()=>{u.stopping=!0,$(o,i,{status:`stopped`,taskCount:u.taskCount,ledger:u.ledger})}},args:i.args,name:i.name,replayable:c.length}}async function ai(e,t,n,r){let{ctx:i,runDir:a,runId:o}=e,s=Z(o);try{let e=await K.run(i,()=>q.run({args:r??{},depth:0},()=>Nr(t,r)));return $(a,s,{status:`completed`,taskCount:i.taskCount,ledger:i.ledger,result:e}),{runId:o,name:n,status:`completed`,result:e,tokens:i.ledger,taskCount:i.taskCount}}catch(e){throw i.stopping||$(a,s,{status:`failed`,taskCount:i.taskCount,ledger:i.ledger,error:e instanceof Error?e.message:String(e)}),new W(`flow-failed`,e instanceof Error?e.message:String(e),{runId:o})}}async function oi(e,t={},n={}){let{started:r}=ii(e,t,n),i=Z(r.runId).script;return n.onStart?.({runId:r.runId,requestStop:r.markStopped,runningIds:()=>[...r.ctx.running]}),ai(r,i,Z(r.runId).name,t.args??{})}async function si(e,t={},n={}){let{started:r,args:i,name:a,replayable:o}=ii(``,t,n,e),s=Z(e).script;return n.onStart?.({runId:e,requestStop:r.markStopped,runningIds:()=>[...r.ctx.running]}),o&&n.onReplay?.(o),ai(r,s,a,i)}export{I as $,D as $t,Kn as A,qe as At,Hn as B,E as Bt,vr as C,ot as Ct,Zn as D,Qe as Dt,Qn as E,ut as Et,In as F,Le as Ft,Sn as G,_e as Gt,En as H,ye as Ht,Ln as I,Ee as It,yn as J,ke as Jt,wn as K,O as Kt,Nn as L,ve as Lt,W as M,Je as Mt,kn as N,Ye as Nt,Xn as O,j as Ot,An as P,De as Pt,L as Q,Re as Qt,Vn as R,Ae as Rt,ri as S,at as St,$n as T,ct as Tt,On as U,Ce as Ut,Cn as V,xe as Vt,Tn as W,ge as Wt,z as X,Ie as Xt,xn as Y,we as Yt,R as Z,w as Zt,si as _,Rt as _t,zr as a,je as an,B as at,ti as b,lt as bt,Cr as c,hn as ct,Wr as d,un as dt,Se as en,zt as et,Tr as f,U as ft,Z as g,F as gt,Yr as h,Ft as ht,ir as i,ze as in,fn as it,Jn as j,Xe as jt,Yn as k,Ze as kt,Kr as l,sn as lt,wr as m,gn as mt,Lr as n,Ve as nn,ln as nt,Pr as o,Me as on,an as ot,Xr as p,H as pt,bn as q,be as qt,Jr as r,k as rn,V as rt,qr as s,Te as sn,on as st,Zr as t,Be as tn,Bt as tt,Gr as u,dn as ut,X as v,Lt as vt,G as w,M as wt,ni as x,dt as xt,oi as y,ft as yt,Pn as z,Oe as zt};
|