@wular/coder 0.3.15 → 0.3.16

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.
@@ -0,0 +1,25 @@
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,V as p,W as m,f as h,i as g,j as _,l as v,m as y,o as b,r as x,s as ee,u as te,v as ne,w as re,y as ie}from"./app-server-bHl6RBZ2.js";import{createRequire as ae}from"node:module";import S from"node:process";import C from"node:fs";import w from"node:path";import{spawn as T,spawnSync as E}from"node:child_process";import D from"node:os";import{fileURLToPath as oe,pathToFileURL as se}from"node:url";import*as O from"zod/mini";import ce from"node:net";import le,{randomUUID as k}from"node:crypto";import{AsyncLocalStorage as ue}from"node:async_hooks";function de(e){let t=S.env.FORCE_COLOR,n=t!=null&&t!==``&&t!==`0`||t!==`0`&&e.isTTY&&!S.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 A=de(S.stdout),j=de(S.stderr);function fe(e,t=j){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 pe(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];S.stderr.write(`${j.red(e)}\n`),i.length&&S.stderr.write(`\n${fe(i,j)}\n`),S.exit(n)}function M(e){S.stdout.write(`${JSON.stringify(e,null,2)}\n`)}function me(e,t=A){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 he(e){let t=Date.parse(e??``);return Number.isFinite(t)?Math.max(0,Date.now()-t):0}function N(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 ge(e){let t=Math.max(0,Math.round(e/1e3)),n=t%60,r=Math.floor(t/60)%60,i=Math.floor(t/3600),a=e=>String(e).padStart(2,`0`);return i?`${i}:${a(r)}:${a(n)}`:`${r}:${a(n)}`}function P(e){return e<1e3?String(e):e<1e6?`${(e/1e3).toFixed(+(e<1e4))}k`:`${(e/1e6).toFixed(1)}M`}function _e(e,t){let n=[`in ${P(e.input)}`,...e.cachedInput?[`cached ${P(e.cachedInput)}`]:[],`out ${P(e.output)}`];return`${P(e.total)} (${n.join(` · `)}) on ${t||`default model`}`}function ve(e){return`ctx ${P(e.input+e.cachedInput)} · out ${P(e.output)}`}function ye(e,t,n,r=A){let i=e?.error?.message??t;return e?.finalMessage||(i?`${r.red(`error:`)} ${i}`:n)}function be(e,t=A,{truncate:n=!0}={}){let r=e=>e.split(`
5
+ `).map(e=>` ${t.dim(e)}`);return!n||e.length<=1e3?[t.dim(`prompt:`),...r(e)]:[t.dim(`prompt:`),...r(e.slice(0,500).trimEnd()),t.light(` … <${e.length-1e3} chars trimmed> …`),...r(e.slice(-500).trimStart())]}function xe(e){return[e.agent??`-`,e.model,e.model?e.effort:null].filter(Boolean).join(`/`)}function Se(e,t=A){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 Ce(e,t){if(t)return e.createdAt?`started ${N(he(e.createdAt))} ago`:``;let n=e.createdAt&&e.completedAt?Date.parse(e.completedAt)-Date.parse(e.createdAt):null;return[e.completedAt?`finished ${N(he(e.completedAt))} ago`:``,n!==null&&n>=0?`took ${N(n)}`:``].filter(Boolean).join(` · `)}function we(e,{status:t,tokens:n,tokenModel:r,files:i,live:a=!1,style:o=A}){let s=Ce(e,p.includes(e.status)||t===`waiting-approval`),c=e=>o.dim(e.padEnd(8));return[`${c(`task`)} ${o.cyan(e.id)}`,...e.name?[`${c(`name`)} ${e.name}`]:[],`${c(`status`)} ${qe(t)}${s?` ${o.dim(`(${s})`)}`:``}`,`${c(`agent`)} ${xe(e)}`,...Se(e,o),...n?[`${c(`tokens`)} ${a?ve(n):_e(n,r??e.model)}${a?o.dim(` (so far)`):``}`]:[],...i?.length?[`${c(`files`)} ${i.join(`, `)}`]:[]]}function Te(e,{tokens:t,tokenModel:n,files:r,statusChanged:i=!0,style:a=A}){let o=e=>a.dim(e.padEnd(8)),s=e.createdAt&&e.completedAt?Date.parse(e.completedAt)-Date.parse(e.createdAt):null;return[...i?[`${o(`status`)} ${qe(e.status)}${s!==null&&s>=0?` ${a.dim(`(took ${N(s)})`)}`:``}`]:[],...t?[`${o(`tokens`)} ${_e(t,n??e.model)}`]:[],...r?.length?[`${o(`files`)} ${r.join(`, `)}`]:[]]}function Ee(e,t=300,{plain:n=!1,style:r=A}={}){if(e.length<=t)return e;let i=`<${e.length-t} more chars>`;return`${e.slice(0,t)} ${n?i:r.dim(i)}`}const De=` `.repeat(8),Oe={assistant:`●`,reasoning:`✻`,tool:`→`,"tool-result":` `,usage:`·`,status:`·`,info:`·`,error:`✘`,steer:`⚑`};function ke(e){return e.includes(`approval`)||e===`sidecar-decision`}function Ae(e,t){return t?e.split(`${t}/`).join(``).split(t).join(`.`):e}function je(e,t){let n=e.kind===`sidecar-decision`?`sidecar`:`approval`,r=String(e.decision??``),i=e.summary?String(e.summary):``,a=i.slice(i.indexOf(`: `)+2),o=i&&a&&t.includes(a)?``:i,s=o?``:String(e.method??``),c=e.reason?` — ${String(e.reason)}`:``;return`${[n,r,s].filter(Boolean).join(` `)}${o?` · ${o}`:``}${c}`}function Me(e,t,n,r){let i=e;i.length>t&&(i=`${i.slice(0,t)} ${r.light(`<${e.length-t} more chars>`)}`);let a=i.split(`
6
+ `);return a.length>n&&(i=`${a.slice(0,n).join(`
7
+ `)}\n${r.light(`… +${a.length-n} more lines`)}`),i}function Ne(e,t){return e.split(`
8
+ `).map(e=>e.includes(`\x1B`)?e:t.dim(e)).join(`
9
+ `)}var Pe=class{opts;prevKind=null;lastAssistant=``;lastTool=null;lastToolText=``;lastUsageTotal=0;entryAt=null;style;constructor(e={}){this.opts=e,this.style=e.style??A}get lastAssistantMessage(){return this.lastAssistant}render(e){let t=this.style,n=String(e.kind??`status`),r=Date.parse(String(e.at??``));this.entryAt=Number.isFinite(r)?r:null;let i=this.opts.trim??500,a=this.opts.explicitTrim||i===1/0?1/0:6;if(n===`usage`){let r=e.tokens;if(!r)return[];let i=this.lastUsageTotal>0,a=r.total-this.lastUsageTotal;return!i||a<Math.max(2e4,this.lastUsageTotal*.2)?(this.lastUsageTotal=Math.max(this.lastUsageTotal,r.total),[]):(this.lastUsageTotal=r.total,this.compose(n,t.dim(ve(r)),!1))}let o=e.message?String(e.message):ke(n)?je(e,this.lastToolText):String(e.kind??``);if(!o&&!(n===`tool-result`&&(e.exitCode!=null||e.isError)))return[];let s=Ae(o,this.opts.cwd);if(n===`assistant`)return this.lastAssistant=s,this.compose(n,s,!0);if(n===`steer`)return this.compose(n,t.yellow(s),!0);if(n===`error`)return this.compose(n,t.red(s),!0);if(n===`reasoning`){let r=typeof e.durationMs==`number`?Math.round(e.durationMs/1e3):0,o=r>=1?t.dim(`thought ${N(r*1e3)} · `):``,c=a===1/0?Me(s,i,1/0,t):this.clip(s.split(`
10
+ `)[0]??``);return this.compose(n,`${o}${Ne(c,t)}`,!1)}if(n===`tool`)return this.lastTool=e.tool?String(e.tool):null,this.lastToolText=s,this.compose(n,t.light(this.clip(s.replace(/\s*\n\s*/g,` `))),!1);if(n===`tool-result`){let r=typeof e.exitCode==`number`?e.exitCode:null,o=r!==null&&r!==0||e.isError===!0,c=typeof e.durationMs==`number`?e.durationMs:0,l=e.tool?String(e.tool):null,u=[l&&l!==this.lastTool?t.dim(`from ${l}`):``,o?t.red(r===null?`failed`:`exit ${r}`):``,c>=3e3?t.dim(N(c)):``].filter(Boolean),d=Me(s,i,a,t),f=[...u.length?[u.join(t.dim(` · `))]:[],...d?[Ne(d,t)]:[]];return this.compose(n,f.join(`
11
+ `),!1)}return this.compose(n,t.dim(this.clip(s)),!1)}spaced(e){return this.prevKind===null?!1:e===`assistant`||e===`error`||e===`steer`?!0:e===`reasoning`?this.prevKind!==`reasoning`:e===`tool`?this.prevKind===`assistant`||this.prevKind===`reasoning`:!1}clip(e){let t=this.opts.width;return t&&Ue(e)>t-1?We(e,t-1):e}compose(e,t,n){let r=this.spaced(e)?[``]:[];this.prevKind=e;let i=Oe[e]??(ke(e)?`⚑`:`·`),[a=``,...o]=t.split(`
12
+ `);return[...r,`${this.gutter(e)}${this.style.dim(i)} ${a}`,...o.map(e=>n?e:`${De}${e}`)]}gutter(e){let t=` `.repeat(6);return e===`tool-result`||!this.opts.startedAt||this.entryAt===null?t:`${this.style.dim(ge(this.entryAt-this.opts.startedAt).padStart(5))} `}};const Fe=6e5,Ie=12e4;function Le(e,t){return e.length>t?`${e.slice(0,t-1)}…`:e.padEnd(t)}function Re(e){return` ${A.bold(A.green(`✔`))} ${e}`}function ze(e){return` ${A.bold(A.red(`✘`))} ${e}`}function Be(e=S.stdout){try{return e.getWindowSize?.()[0]??e.columns}catch{return e.columns}}function Ve(e=S.stdout){try{return e.getWindowSize?.()[1]??e.rows}catch{return e.rows}}function He(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 Ue(e){let t=0;for(let n of e.replace(/\x1b\[[0-9;]*m/g,``))t+=He(n.codePointAt(0));return t}function We(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=He(o);if(n+c>t-1)return`${r}\x1b[0m${A.dim(`…`)}`;r+=s,n+=c,i+=s.length}return r}function Ge(){let e=S.stdin;if(!e.isTTY||!S.stdout.isTTY)return()=>{};e.setRawMode(!0),e.resume();let t=e=>{e.includes(3)&&S.kill(S.pid,`SIGINT`),e.includes(26)&&S.kill(S.pid,`SIGTSTP`)};return e.on(`data`,t),e.unref(),()=>{e.off(`data`,t),e.isTTY&&e.setRawMode(!1),e.pause()}}var Ke=class{stream;quietMs;lines=[];painted=[];paintedWidths=[];paintedCols;resizeTimer;tty;constructor(e=S.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=Be(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=Be(this.stream),t=e?this.lines.map(t=>We(t,e-1)):this.lines,n=Ve(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(Ue),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 qe(e,t=0){let n=e.padEnd(t);return e===`running`?A.green(n):e===`waiting-approval`?A.yellow(n):e===`failed`||e===`cancelled`?A.red(n):e===`completed`?A.blue(n):A.dim(n)}function Je(e,t,n=!1){n?M({taskId:e,status:`awaiting-approval`,approval:t}):(S.stdout.write(`Approval needed for task ${e}: ${t.summary}\n`),S.stderr.write(`\n${fe([`Approve: coder approve ${e} ${t.id}`,`Deny: coder approve ${e} ${t.id} --deny`,`Then: coder task result ${e} --wait`],j)}\n`)),S.exit(4)}function Ye(e,t,n){if(e.length>t){let r=e.slice(t);pe(`Unexpected argument${r.length>1?`s`:``}: ${r.join(` `)}`,{hint:`Help: coder ${n} --help`})}}function F(e){return e.cwd?w.resolve(String(e.cwd)):S.cwd()}function Xe(e,t){let r=n(e,t);return r||pe(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 I=`@wular/coder`,Ze=`https://registry.npmjs.org/${I}/latest`;function Qe(){return w.join(r(),`update-check.json`)}function $e(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 et(){try{return JSON.parse(C.readFileSync(Qe(),`utf8`))}catch{return null}}function tt(e){try{C.mkdirSync(r(),{recursive:!0}),C.writeFileSync(Qe(),JSON.stringify(e))}catch{}}function nt(){try{C.rmSync(Qe(),{force:!0})}catch{}}function rt(e,t){if(S.env.CODER_NO_UPDATE_CHECK||S.env.CI)return;let n=et();if(n?.latest&&$e(n.latest,e)>0&&S.stderr.write(j.dim(`coder ${e} -> `)+j.bold(n.latest)+j.dim(` available. run: coder upgrade
13
+
14
+ `)),!n?.checkedAt||Date.now()-n.checkedAt>864e5)try{T(S.execPath,[t,`_refreshUpdate`],{detached:!0,stdio:`ignore`}).unref()}catch{}}async function it(e){let t=et()?.latest??null;try{let e=new AbortController,n=setTimeout(()=>e.abort(),3e3),r=await fetch(Ze,{signal:e.signal,headers:{accept:`application/json`}});if(clearTimeout(n),r.ok){let e=await r.json();e?.version&&(t=e.version)}}catch{}tt({checkedAt:Date.now(),latest:t,current:e})}function at(e){let t=e;try{t=C.realpathSync(e)}catch{}let n=t.replace(/\\/g,`/`);return/\/\.bun\//.test(n)?{pm:`bun`,command:[`bun`,`add`,`-g`,`${I}@latest`]}:/\/\.pnpm\//.test(n)||/\/pnpm(-global)?\//i.test(n)||/\/Library\/pnpm\//.test(n)?{pm:`pnpm`,command:[`pnpm`,`add`,`-g`,`${I}@latest`]}:/\/\.config\/yarn\/global\//.test(n)||/\/yarn\/global\//.test(n)||/\/Yarn\/Data\/global\//.test(n)?{pm:`yarn`,command:[`yarn`,`global`,`add`,`${I}@latest`]}:{pm:`npm`,command:[`npm`,`install`,`-g`,`${I}@latest`]}}function L(e,t){if(!t)return``;if(!w.isAbsolute(t))return t;let n=w.relative(e,t);return n&&!n.startsWith(`..`)?n:t}function R(e){try{return JSON.parse(C.readFileSync(e,`utf8`))}catch{return null}}function ot(e,t){let n=`${e}.tmp`;C.writeFileSync(n,`${JSON.stringify(t,null,2)}\n`,`utf8`),C.renameSync(n,e)}function st(e){let t=0,n=``;return()=>{let r;try{r=C.statSync(e).size}catch{return[]}if(r<t&&(t=0,n=``),r===t)return[];let i;try{i=C.openSync(e,`r`)}catch{return[]}try{let e=Buffer.alloc(r-t),a=C.readSync(i,e,0,e.length,t);t+=a;let o=(n+e.toString(`utf8`,0,a)).split(`
15
+ `);return n=o.pop()??``,o.filter(Boolean)}finally{C.closeSync(i)}}}const ct=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(`.`)),lt=[/\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)/],ut=new Set([`status`,`log`,`diff`,`show`,`blame`,`rev-parse`,`ls-files`,`ls-tree`,`cat-file`,`describe`,`shortlog`,`grep`,`branch`,`stash`]);function dt(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 ft(e){return e.trim().split(/\s+/).filter(Boolean)}function pt(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 ut.has(t)?{decision:`accept`,reason:`git ${t} is read-only`}:ct.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 mt(e,t={}){let n=dt(String(e??``));if(!n.trim())return{decision:`escalate`,reason:`empty command`};for(let e of lt)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=mt(n,t);if(r.decision===`decline`)return r;r.decision===`escalate`&&(e=r)}return e}let i=ft(n),a=w.basename(i[0]??``);if(a===`git`)return pt(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 ht(e,t){if(!e.length)return{decision:`escalate`,reason:`file change with no resolvable paths`};for(let n of e){let e=w.resolve(t,n),r=w.relative(t,e);if(r.startsWith(`..`)||w.isAbsolute(r))return{decision:`escalate`,reason:`path outside workspace: ${n}`};if(r===`.git`||r.startsWith(`.git${w.sep}`))return{decision:`decline`,reason:`direct .git modification: ${n}`}}return{decision:`accept`,reason:`all paths inside workspace`}}function gt(e){return w.join(e,`approvals`)}function _t(e){let t=gt(e);return C.existsSync(t)?C.readdirSync(t).filter(e=>e.endsWith(`.request.json`)).flatMap(e=>{let n=e.replace(/\.request\.json$/,``),r=R(w.join(t,e));if(!r)return[];let i=R(w.join(t,`${n}.response.json`));return[{...r,id:n,response:i}]}).sort((e,t)=>String(e.createdAt??``).localeCompare(String(t.createdAt??``))):[]}function vt(e,t,n){let r=gt(e),i=w.join(r,`${t}.request.json`);if(!C.existsSync(i))throw Error(`No pending approval "${t}" for this job.`);C.writeFileSync(w.join(r,`${t}.response.json`),`${JSON.stringify({decision:n,answeredAt:new Date().toISOString()},null,2)}\n`,`utf8`)}async function yt(e,t,{timeoutMs:n,onEvent:r}){let i=gt(e);C.mkdirSync(i,{recursive:!0});let a=`apr-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`;C.writeFileSync(w.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 ${w.basename(e)} ${a} [--deny]`});let o=w.join(i,`${a}.response.json`),s=Date.now()+n;for(;Date.now()<s;){if(C.existsSync(o))try{let e=JSON.parse(C.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 bt(e,t={}){return yt(e,{method:`simulate`,summary:`simulated approval probe (--simulate-approval)`},{timeoutMs:t.timeoutMs??12e4,onEvent:t.onEvent??null})}function xt({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=mt(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 yt(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=ht(i,e);return a?.({kind:`approval-decision`,method:o,decision:u.decision,reason:u.reason,summary:l}),u.decision===`escalate`?{decision:await yt(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 St(e,t,n=400){let r=t;for(;;){if(a.includes(r.status))return{job:r,reason:`terminal`};let t=_t(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,_(e,r.id)??r)}}function Ct(e,t){let n=`${e}.${process.pid}.${k()}.tmp`;C.writeFileSync(n,`${JSON.stringify(t)}\n`,`utf8`),C.renameSync(n,e)}function wt(e){let t=e instanceof Error?e.message:String(e);return/no active turn|active turn.*(?:ended|completed)|turn.*(?:already )?(?:ended|completed)|turn.*not active/i.test(t)}function z(e,t,n){return Object.assign(Error(e),{retryable:t,...n===void 0?{}:{rpcCode:n}})}function Tt(e,t,n,r){if(!e||e.id!==t||e.method!==`turn/steer`&&e.method!==`turn/interrupt`)throw z(`Invalid Codex control request.`,!1);let i=e.params;if(!i||typeof i!=`object`||i.threadId!==n)throw z(`Codex control request does not match its owning thread.`,!1);if(e.method===`turn/interrupt`){if(i.turnId!==r)throw z(`Codex turn/interrupt request does not match its owning active turn.`,!1);return{method:e.method,params:i}}if(i.expectedTurnId!==r)throw z(`Codex turn/steer request does not match its owning active turn.`,!1);let a=i.input;if(!Array.isArray(a)||a.length!==1||a[0]?.type!==`text`||typeof a[0]?.text!=`string`||!a[0].text.trim())throw z(`Invalid Codex turn/steer input schema.`,!1);return{method:e.method,params:i}}async function Et(e,{threadId:t,turnId:n}){let r=C.mkdtempSync(w.join(D.tmpdir(),`coder-codex-control-`)),i=`file:${r}`,a=new Set,o=!1,s=!1,c=(i=!1)=>{if(!(o&&!i||s)){s=!0;try{for(let i of C.readdirSync(r).filter(e=>e.endsWith(`.request.json`))){let s=w.join(r,i),c=`${s}.${process.pid}.processing`;try{C.renameSync(s,c)}catch{continue}let l=i.slice(0,-13),u=w.join(r,`${l}.response.json`),d=(async()=>{let r;try{if(o)throw z(`Codex owner endpoint is shutting down.`,!0);let i=Tt(JSON.parse(C.readFileSync(c,`utf8`)),l,t,n);try{let t=await e.request(i.method,i.params);r={id:l,result:t}}catch(e){let t=e;r={id:l,error:{message:e instanceof Error?e.message:String(e),retryable:wt(e),...t.rpcCode===void 0?{}:{rpcCode:t.rpcCode}}}}}catch(e){let t=e;r={id:l,error:{message:t.message,retryable:t.retryable===!0,...t.rpcCode===void 0?{}:{rpcCode:t.rpcCode}}}}try{Ct(u,r)}finally{try{C.unlinkSync(c)}catch{}}})();a.add(d),d.then(()=>a.delete(d),()=>a.delete(d))}}catch{}finally{s=!1}}},l=setInterval(c,10);return l.unref?.(),{endpoint:i,async close(){o||(o=!0,clearInterval(l),c(!0),await Promise.allSettled([...a]),await new Promise(e=>setTimeout(e,50)),C.rmSync(r,{recursive:!0,force:!0}))}}}function Dt(e){if(e?.startsWith(`file:`)&&e.length>5){let t=w.resolve(e.slice(5)),n=w.resolve(D.tmpdir());w.dirname(t)===n&&w.basename(t).startsWith(`coder-codex-control-`)&&C.rmSync(t,{recursive:!0,force:!0})}}async function Ot(e,t,n,r=3e3){if(!e)return{ok:!1,retryable:!0,detail:`Codex owner endpoint is not ready.`};if(!e.startsWith(`file:`)||e.length===5)return{ok:!1,retryable:!1,detail:`Unsupported Codex control endpoint: ${e}`};let i=e.slice(5);if(!C.existsSync(i))return{ok:!1,retryable:!0,detail:`Codex owner endpoint is no longer available.`};let a=k(),o=w.join(i,`${a}.request.json`),s=w.join(i,`${a}.response.json`);try{Ct(o,{id:a,method:t,params:n})}catch(e){return{ok:!1,retryable:e.code===`ENOENT`,detail:e instanceof Error?e.message:String(e)}}let c=Date.now();for(;Date.now()-c<r;){try{let e=JSON.parse(C.readFileSync(s,`utf8`));try{C.unlinkSync(s)}catch{}return e?.id===a?e?.error?{ok:!1,retryable:e.error.retryable===!0,detail:String(e.error.message??`Malformed Codex owner error response.`)}:`result`in e?{ok:!0,retryable:!1,result:e.result,detail:`Codex owner accepted control.`}:{ok:!1,retryable:!1,detail:`Malformed Codex owner response.`}:{ok:!1,retryable:!1,detail:`Malformed Codex owner response id.`}}catch(e){if(e.code!==`ENOENT`)return{ok:!1,retryable:!1,detail:`Invalid Codex owner response: ${e instanceof Error?e.message:String(e)}`};if(!C.existsSync(i))return{ok:!1,retryable:!1,detail:`Codex owner endpoint closed after control publication; acceptance is unknown.`}}await new Promise(e=>setTimeout(e,10))}return{ok:!1,retryable:!1,detail:`Timed out waiting for Codex owner acknowledgement.`}}const kt=`Coder Task`;function At(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(`
16
+ `)}function jt(e,t=72){let n=String(e??``).trim().replace(/\s+/g,` `);return n?n.length<=t?n:`${n.slice(0,t-3)}...`:``}function Mt(e){let t=jt(e,56);return t?`${kt}: ${t}`:kt}function Nt(e){return e?.params?.threadId??null}function Pt(e){return e?.params?.turnId?e.params.turnId:e?.params?.turn?.id?e.params.turn.id:null}function Ft(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 It(e,t){let n=[];for(let r of e.matchAll(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/gm)){let e=t===`delete`,i=Number(e?r[1]:r[3]),a=Number((e?r[2]:r[4])??1);!Number.isFinite(i)||!Number.isFinite(a)||n.push(a<=1?`L${i}`:`L${i}-L${i+a-1}`)}return n}function Lt(e){try{let t=C.readFileSync(e,`utf8`),n=t?t.split(/\r\n|\r|\n/).length-+!!t.endsWith(`
17
+ `):0;return n>0?[n===1?`L1`:`L1-L${n}`]:[]}catch{return[]}}function Rt(e,t,n){let r=typeof e.kind==`string`?e.kind:e.kind?.type??`change`,i=e.path||`(unknown path)`,a=It(e.diff??``,r),o=a.length||r!==`add`||!t?a:Lt(i),s=typeof e.kind==`object`&&e.kind?.move_path?` -> ${n?L(n,e.kind.move_path):e.kind.move_path}`:``;return`${r} ${n?L(n,i):i}${s}${o.length?` ${o.join(`, `)}`:``}`}function zt(e,t=!1,n){return(e.changes??[]).map(e=>Rt(e,t,n)).join(`; `)}function Bt(e){let t=e.trim().split(` `)[0]??``;return t===`/dev/null`?``:t.replace(/^[ab]\//,``)}function Vt(e,t){let n=new Map,r=``,i=``;for(let t of e.split(/\r?\n/)){if(t.startsWith(`--- `)){r=Bt(t.slice(4));continue}if(t.startsWith(`+++ `)){i=Bt(t.slice(4));continue}let e=/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/.exec(t);if(!e)continue;let a=Number(e[1]),o=Number(e[2]??1),s=Number(e[3]),c=Number(e[4]??1),l=c===0,u=(l?r:i)||i||r||`(unknown path)`,d=l?a:s,f=l?o:c,p=f<=1?`L${d}`:`L${d}-L${d+f-1}`,m=n.get(u)??[];m.push(p),n.set(u,m)}return[...n].map(([e,n])=>`${t?L(t,e):e} ${n.join(`, `)}`).join(`; `)}function Ht(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 Ut(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 Wt(e){return String(e??``).replace(/\s+/g,` `).trim()}function B(e){if(!e)return[];if(typeof e==`string`){let t=Wt(e);return t?[t]:[]}if(Array.isArray(e))return e.flatMap(e=>B(e));if(typeof e==`object`){let t=e;if(typeof t.text==`string`)return B(t.text);if(`summary`in t)return B(t.summary);if(`content`in t)return B(t.content);if(`parts`in t)return B(t.parts)}return[]}function Gt(e,t){let n=[];for(let r of[...e,...t]){let e=Wt(r);!e||n.includes(e)||n.push(e)}return n}function V(e,t,n=null,r={}){!e||t==null||e({message:t,phase:n,...r})}function Kt(e,t){t&&V(e,t.message,t.phase??null,t.extra??{})}function qt(e){return e.replace(/^\/(?:usr\/)?bin\/\w*sh\s+-l?c\s+/,``)}function Jt(e,t){switch(e.type){case`commandExecution`:return{message:qt(String(e.command??``).trim()),phase:`running`,extra:{kind:`tool`,tool:`command`}};case`fileChange`:return null;case`mcpToolCall`:return{message:`${e.server}/${e.tool}`,phase:`investigating`,extra:{kind:`tool`,tool:String(e.tool??``)}};case`dynamicToolCall`:return{message:String(e.tool??``),phase:`investigating`,extra:{kind:`tool`,tool:String(e.tool??``)}};case`webSearch`:return{message:`search: ${String(e.query??``).trim()}`,phase:`investigating`,extra:{kind:`tool`,tool:`search`}};default:return null}}function Yt(e,t){switch(e.type){case`agentMessage`:{let t=String(e.text??``).trim();return t?{message:t,phase:null,extra:{kind:`assistant`}}:null}case`reasoning`:{let t=B(e.summary).join(`
18
+ `);return t?{message:t,phase:null,extra:{kind:`reasoning`}}:null}case`commandExecution`:{let t=typeof e.exitCode==`number`?e.exitCode:null;return{message:String(e.aggregatedOutput??``).trim(),phase:`running`,extra:{kind:`tool-result`,tool:`command`,command:String(e.command??``).trim(),...t===null?{isError:e.status!==`completed`}:{exitCode:t}}}}case`fileChange`:return{message:zt(e,!0,t)||`(details unavailable)`,phase:`editing`,extra:{kind:`tool`,tool:`edit`}};case`mcpToolCall`:return{message:`${e.server}/${e.tool} ${e.status}`,phase:`investigating`,extra:{kind:`tool-result`,isError:e.status!==`completed`}};case`dynamicToolCall`:return{message:`${e.tool} ${e.status}`,phase:`investigating`,extra:{kind:`tool-result`,isError:e.status!==`completed`}};default:return null}}function Xt(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,lastDiffSummary:``,loggedTokens:0,reportedChanges:new Set,cwd:t.cwd??``,itemIndex:new Map,onProgress:t.onProgress??null,onHeartbeat:t.onHeartbeat??null}}function Zt(e){e.completionTimer&&=(clearTimeout(e.completionTimer),null)}function Qt(e,t=null){e.completed||(Zt(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 $t(e){e.completed||e.finalTurn||!e.finalAnswerSeen||e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||(Zt(e),e.completionTimer=setTimeout(()=>{e.completionTimer=null,!(e.completed||e.finalTurn||!e.finalAnswerSeen)&&(e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||Qt(e,null))},250),e.completionTimer.unref?.())}function en(e,t){let n=Nt(t);if(!n||!e.threadIds.has(n))return!1;let r=e.threadTurnIds.get(n)??null,i=Pt(t);return r===null||i===null||i===r}function tn(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),$t(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,$t(e)));return}if(t.type===`reasoning`&&n===`completed`){e.reasoningSummary=Gt(e.reasoningSummary,B(t.summary));return}if(t.type===`fileChange`&&n===`completed`){e.fileChanges.push(t);return}t.type===`commandExecution`&&n===`completed`&&e.commandExecutions.push(t)}function nn(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),V(e.onProgress,`Turn started (${t.params.turn.id}).`,`starting`,{kind:`status`,threadId:t.params.threadId??null,turnId:t.params.turn.id??null});break;case`item/started`:tn(e,t.params.item,`started`,t.params.threadId??null),Kt(e.onProgress,Jt(t.params.item,e.cwd));break;case`item/completed`:{tn(e,t.params.item,`completed`,t.params.threadId??null);let n=t.params.item;if(n?.type===`fileChange`)for(let t of n.changes??[])t.path&&e.reportedChanges.add(L(e.cwd,t.path));Kt(e.onProgress,Yt(n,e.cwd));break}case`thread/tokenUsage/updated`:{let n=Ht(t.params?.tokenUsage?.total??t.params?.tokenUsage),r=Nt(t);if(n&&r){e.tokenUsageByThread.set(r,n);let t=Ut(e);t&&(!e.loggedTokens||t.total-e.loggedTokens>=1e3)&&(e.loggedTokens=t.total,e.onProgress?.({kind:`usage`,tokens:t}))}break}case`turn/diff/updated`:{let n=Vt(String(t.params?.diff??``),e.cwd).split(`; `).filter(t=>!e.reportedChanges.has(t.split(` `)[0]??``)).join(`; `);n&&n!==e.lastDiffSummary&&(e.lastDiffSummary=n,V(e.onProgress,`changed: ${n}`,`editing`,{kind:`status`}));break}case`item/autoApprovalReview/completed`:{let n=t.params?.review??{},r=t.params?.action??{},i=r.command??r.type??``;V(e.onProgress,`auto-review ${n.status}${n.riskLevel?` (${n.riskLevel} risk)`:``}: ${jt(i)}${n.rationale?` — ${jt(n.rationale,120)}`:``}`,null);break}case`error`:e.error=t.params.error,V(e.onProgress,`Codex error: ${t.params.error.message}`,`failed`,{kind:`error`});break;case`turn/completed`:if((t.params.threadId??null)!==e.threadId){e.activeSubagentTurns.delete(t.params.threadId),$t(e);break}V(e.onProgress,`Turn ${t.params.turn.status}.`,`finalizing`,{kind:`status`}),Qt(e,t.params.turn)}}async function rn(e,t,n,r={}){let i=Xt(t,r),a=e.notificationHandler;e.setNotificationHandler(e=>{if(!i.turnId){i.bufferedNotifications.push(e);return}if(e.method===`thread/started`){nn(i,e);return}if(!en(i,e)){a?.(e);return}nn(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),await r.onTurnStarted?.(i.turnId));for(let e of i.bufferedNotifications)en(i,e)?nn(i,e):a?.(e);return i.bufferedNotifications.length=0,e.turn?.status&&e.turn.status!==`inProgress`&&Qt(i,e.turn),await i.completion}finally{Zt(i),e.setNotificationHandler(a??null),e.setServerRequestHandler(null)}}async function an(e,t,n={}){let r=n.connect??x.connect,i=null;try{i=await r(e);let n=await t(i);return await i.close(),n}catch(n){let a=n,o=i?.transport===`broker`||!!process.env.CODER_APP_SERVER_ENDPOINT,s=i?.transport===`broker`&&a?.rpcCode===-32001||o&&(a?.code===`ENOENT`||a?.code===`ECONNREFUSED`);if(i&&=(await i.close().catch(()=>{}),null),!s)throw n;let c=await r(e,{disableBroker:!0});try{return await t(c)}finally{await c.close()}}}function H(e){let t=g(`codex`,[`--version`],{cwd:e});if(!t.available)return t;let n=g(`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 on(e){let t=H(e);if(!t.available)return{available:!1,loggedIn:!1,detail:t.detail};let n=null;try{n=await x.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=E(`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 sn(e,{endpoint:t,threadId:n,turnId:r}){if(!n||!r)return{interrupted:!1,detail:`missing threadId or turnId`};let i=await Ot(t,`turn/interrupt`,{threadId:n,turnId:r});return i.ok?{interrupted:!0,detail:`Interrupted ${r} on ${n}.`}:{interrupted:!1,detail:i.detail}}async function cn(e,{endpoint:t,threadId:n,turnId:r,text:i}){if(!n)return{steered:!1,retryable:!0,detail:`missing active threadId`};if(!r)return{steered:!1,retryable:!0,detail:`missing active turnId`};let a=i.trim();if(!a)return{steered:!1,retryable:!1,detail:`empty follow-up`};let o=await Ot(t,`turn/steer`,{threadId:n,input:[{type:`text`,text:a,text_elements:[]}],expectedTurnId:r});return o.ok?o.result?.turnId===r?{steered:!0,retryable:!1,detail:`Steered follow-up into ${r} on ${n}.`}:{steered:!1,retryable:!1,detail:`turn/steer returned unexpected turnId ${String(o.result?.turnId??`(missing)`)}; expected ${r}`}:{steered:!1,retryable:o.retryable,detail:o.detail}}async function ln(e,t={}){let n=H(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 an(e,async n=>{let a=null,o;if(t.resumeThreadId)V(t.onProgress,`Resuming thread ${t.resumeThreadId}.`,`starting`,{kind:`status`}),m(t.resumeThreadId)&&await i(t.resumeThreadId),o=(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`,...t.approvalsReviewer?{approvalsReviewer:t.approvalsReviewer}:{}})).thread.id;else if(V(t.onProgress,`Starting Codex task thread.`,`starting`,{kind:`status`}),o=(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`,...t.approvalsReviewer?{approvalsReviewer:t.approvalsReviewer}:{},serviceName:`coder_runtime`,ephemeral:t.ephemeral??!1})).thread.id,!(t.ephemeral??!1))try{await n.request(`thread/name/set`,{threadId:o,name:Mt(r)})}catch(e){let t=String(e?.message??e??``);if(!t.includes(`unknown variant`)&&!t.includes(`unknown method`))throw e}V(t.onProgress,`Thread ready (${o}).`,`starting`,{kind:`status`,threadId:o});let s;try{s=await rn(n,o,()=>n.request(`turn/start`,{threadId:o,input:[{type:`text`,text:r,text_elements:[]}],model:t.model??null,effort:t.effort??null,outputSchema:t.outputSchema??null}),{cwd:e,onProgress:t.onProgress,onHeartbeat:t.onHeartbeat,onApprovalRequest:t.onApprovalRequest,onTurnStarted:t.onControlReady?async e=>{a=await Et(n,{threadId:o,turnId:e}),t.onControlReady?.(a.endpoint,o,e)}:void 0})}finally{await a?.close()}return{status:s.finalTurn?.status===`completed`?0:1,threadId:o,turnId:s.turnId,finalMessage:s.lastAgentMessage,reasoningSummary:s.reasoningSummary,turn:s.finalTurn,error:s.error,stderr:At(n.stderr),fileChanges:s.fileChanges,touchedFiles:Ft(s.fileChanges),tokens:Ut(s),model:t.model??null,commandExecutions:s.commandExecutions}})}const un={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:[]}},U={spark:`gpt-5.3-codex-spark`,luna:`gpt-5.6-luna`,terra:`gpt-5.6-terra`,sol:`gpt-5.6-sol`},dn=new Set([`low`,`medium`,`high`]),W={haiku:`haiku`,sonnet:`sonnet`,opus:`opus`,fable:`fable`},fn=new Set([`low`,`medium`,`high`]),pn={"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`}},mn={"read-only":[`--permission-mode`,`dontAsk`,`--disallowedTools`,`Edit`,`Write`,`NotebookEdit`],"workspace-write":[`--permission-mode`,`acceptEdits`],auto:[`--permission-mode`,`auto`]},hn=[`--permission-mode`,`dontAsk`,`--disallowedTools`,`Edit`,`Write`,`NotebookEdit`,`Bash`,`WebFetch`,`WebSearch`,`Task`],gn=/failIfUnavailable|sandbox\b[^.\n]*?(?:failed|could ?n[o']t|cannot|unavailable|not available|not supported)/i;function _n(e){return e.flatMap(e=>ce.isIPv6(e)?[`[${e}]`]:e.startsWith(`[`)||e.includes(`:`)||ce.isIP(e)?[e]:[e,`*.${e}`])}function vn(e,t,n=[],r=[]){return JSON.stringify(e===`read-only`?{...r.length?{permissions:{additionalDirectories:r}}:{},sandbox:{enabled:!0,failIfUnavailable:!0,autoAllowBashIfSandboxed:!0,filesystem:{denyWrite:[t,...r]}}}:{sandbox:{enabled:!0,autoAllowBashIfSandboxed:!0,...e===`auto`&&n.length?{network:{allowedDomains:_n(n)}}:{}}})}const yn=O.enum([`codex`,`claude`]),bn=O.enum([`codex`,`claude`,`custom`]),xn=O.enum([`low`,`medium`,`high`]),Sn=O.enum([`read-only`,`workspace-write`,`auto`]),Cn=O.partial(O.strictObject({model:O.string().check(O.minLength(1)),effort:xn,permissions:Sn})),wn=O.strictObject({baseUrl:O.url(),model:O.string().check(O.minLength(1)),envKey:O.optional(O.string().check(O.minLength(1))),wireApi:O.optional(O.enum([`chat`,`responses`])),disabled:O.optional(O.boolean())}),Tn=O.strictObject({provider:yn,model:O.string().check(O.minLength(1)),effort:O.optional(xn),disabled:O.optional(O.boolean())}),En=O.strictObject({disabled:O.boolean()}),Dn=O.union([wn,Tn,En]),On=O.strictObject({escalationTimeoutMs:O.number().check(O.positive()),allowedNetworkHosts:O.array(O.string())}),kn=O.strictObject({chain:O.array(bn).check(O.minLength(1)),agents:O.partial(O.strictObject({codex:Cn,claude:Cn,custom:Cn})),models:O.optional(O.record(O.string().check(O.regex(/^[a-z0-9][a-z0-9./_-]*$/i,`model name`)),Dn)),approvals:On}),An=O.partial(O.extend(kn,{approvals:O.partial(On)}));function G(e){return`baseUrl`in e}function jn(e){return`provider`in e}function Mn(e){let t=An.safeParse(e);if(!t.success)return t.error.issues.map(e=>`${e.path.join(`.`)||`config`}: ${e.message}`);let n=Pn(un,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(jn(i)){let t=n.models?.[i.model];t&&!G(t)&&r.push(`models.${e}: alias target "${i.model}" is itself a config entry`)}}return r}function Nn(e){if(!C.existsSync(e))return null;try{return JSON.parse(C.readFileSync(e,`utf8`))}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`Invalid JSON in ${e}: ${n}`)}}function Pn(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`?Pn(r[e],i):i;return n}function Fn(){return w.join(r(),`config.json`)}function In(e){let t=s(e),n=un;for(let e of[Fn(),w.join(t,`coder.config.json`)]){let t=Nn(e);if(!t)continue;let r=Mn(t);if(r.length)throw Error(`Invalid config in ${e}:\n ${r.join(`
19
+ `)}`);n=Pn(n,t)}let r=Mn(n);if(r.length)throw Error(`Invalid merged config:\n ${r.join(`
20
+ `)}`);return n}function Ln(e){return e.replace(/\/+$/,``).replace(/\/(chat\/completions|completions|responses)$/,``)}function Rn(e,t,n){let r=[w.join(s(e),`coder.config.json`),Fn()];for(let e of r){let r;try{r=Nn(e)}catch{continue}if(r?.models?.[t])return Object.assign(r.models[t],n),!Mn(r).length&&(C.writeFileSync(e,`${JSON.stringify(r,null,2)}\n`,`utf8`),!0)}return!1}function zn(e){return/\/(chat\/completions|completions|responses)\/*$/.test(e)}function Bn(e,t){let n=Ln(e);return zn(e)||/\/v\d+(alpha|beta)?$/.test(n)?[`${n}/${t}`]:[`${n}/${t}`,`${n}/v1/${t}`]}function Vn(e,t,n){let r=t?e.models?.[t]:void 0;if(!t||!r||!G(r))return null;let i=`coder-${t}`;return{model:r.model,modelProvider:i,configOverrides:{[`model_providers.${i}`]:{name:t,base_url:n?.url??Ln(r.baseUrl),...r.envKey&&!n?{env_key:r.envKey}:{},wire_api:`responses`}}}}function Hn(e){return e?U[e]??e:null}function Un(e){return e in U||e in W}function Wn(e,t){return!!(t&&e.models?.[t]?.disabled)}function Gn(e,t){if(Wn(e,t))throw Error(`model "${t}" is disabled in config`)}function Kn(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=>dn.has(e)||fn.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&&jn(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 W?`claude`:i&&s&&G(s)?`custom`:`codex`;let c=t.agents[r]??{},l=i??c.model??null;return Gn(t,l),{agent:r,model:l,effort:a??c.effort??null}}function qn(e){let t=Fn();return C.mkdirSync(w.dirname(t),{recursive:!0}),C.writeFileSync(t,`${JSON.stringify(e,null,2)}\n`,`utf8`),t}const Jn=new Set([`Write`,`Edit`,`MultiEdit`,`NotebookEdit`]);function Yn(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 Xn(e){if(!e)return 0;let t=e.split(/\r\n|\r|\n/);return t.at(-1)===``&&t.pop(),Math.max(1,t.length)}function Zn(e,t,n=!1){if(!t)return[];let r;try{r=C.readFileSync(e,`utf8`)}catch{return[]}let i=[],a=0;for(;a<=r.length;){let e=r.indexOf(t,a);if(e<0)break;let o=Xn(r.slice(0,e))+1,s=Math.max(1,Xn(t));if(i.push(s===1?`L${o}`:`L${o}-L${o+s-1}`),!n)break;a=e+Math.max(t.length,1)}return i.length>4?[...i.slice(0,4),`+${i.length-4} matches`]:i}function Qn(e){let t=(typeof e==`string`?e:JSON.stringify(e)??String(e)).replace(/\s+/g,` `).trim();return t.length>80?`${t.slice(0,80)}…`:t}function $n(e,t,n){let r=String(t.file_path??t.notebook_path??t.path??``),i=r?w.isAbsolute(r)?r:w.resolve(n,r):``,a=r?L(n,i)||r:`(unknown path)`,o=t.path?` in ${L(n,String(t.path))}`:``;if(e===`Write`){let e=Xn(String(t.content??``));return`Write ${a} ${e?`L1-L${e}`:`(empty file)`}`}if(e===`Edit`){let e=Zn(i,String(t.old_string??``),t.replace_all===!0);return`Edit ${a}${e.length?` ${e.join(`, `)}`:``}`}if(e===`MultiEdit`){let e=Array.isArray(t.edits)?t.edits:[],n=e.flatMap(e=>Zn(i,String(e?.old_string??``),e?.replace_all===!0));return`MultiEdit ${a}${n.length?` ${n.join(`, `)}`:``} (${e.length} edits)`}if(e===`NotebookEdit`){let e=t.cell_id??t.cell_number;return`NotebookEdit ${a}${e==null?``:` cell ${e}`}`}if(e===`Read`){let e=Number(t.offset??0),n=Number(t.limit??0);return`Read ${a}${e&&n?` L${e}-L${e+n-1}`:e?` from L${e}`:``}`}if(e===`Bash`)return`Bash ${String(t.command??``).trim()||`(no command)`}`;if(e===`Glob`)return`Glob ${String(t.pattern??``)}${o}`;if(e===`Grep`){let e=t.glob?` (${String(t.glob)})`:``;return`Grep ${String(t.pattern??``)}${o}${e}`}if(e===`Task`)return`Task ${t.subagent_type?`${String(t.subagent_type)}: `:``}${Qn(t.description??t.prompt??``)}`;if(e===`WebFetch`)return`WebFetch ${String(t.url??``)}`;if(e===`WebSearch`)return`WebSearch ${String(t.query??``)}`;if(e===`TodoWrite`){let e=Array.isArray(t.todos)?t.todos:[];return`TodoWrite ${e.length} item${e.length===1?``:`s`}`}let s=Object.entries(t??{}).map(([e,t])=>`${e}=${Qn(t)}`).join(` `);return s?`${e} ${s}`:e}function er(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 tr(){let e=E(`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 nr(){let e=E(`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`}}}function rr(e,t,n){let r=[`-p`,`--input-format`,`stream-json`,`--output-format`,`stream-json`,`--verbose`,`--replay-user-messages`];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`,a=i===`read-only`?t.additionalDirectories??[]:[],o=i===`read-only`?t.readOnlyAllowedTools??[]:[];if(i===`auto`&&t.approvalJobId){let n=JSON.stringify({mcpServers:{coder:{type:`stdio`,command:S.execPath,args:[h,`_mcp`,t.approvalJobId,`--cwd`,e]}}});r.push(`--permission-mode`,`default`,`--mcp-config`,n,`--permission-prompt-tool`,`mcp__coder__approval_prompt`)}else o.length?r.push(...hn,`--allowedTools`,...o):r.push(...mn[i]??mn.auto);for(let e of a)r.push(`--add-dir`,e);let s=vn(i,e,t.allowedNetworkHosts??[],a);return s&&r.push(`--settings`,s),r}function ir(e,t){return Object.assign(Error(e),{retryable:t})}function ar(e){return{type:`user`,message:{role:`user`,content:[{type:`text`,text:e}]}}}function or(e){let t=!0;return{sendInitial(t){return new Promise((n,r)=>{e(`${JSON.stringify(ar(t))}\n`,e=>{e?r(e):n()})})},sendSteer(n){return t?new Promise((t,r)=>{e(`${JSON.stringify(ar(n))}\n`,e=>{if(!e){t();return}let n=e.code,i=n===`EPIPE`||n===`ERR_STREAM_DESTROYED`||n===`ERR_STREAM_WRITE_AFTER_END`;r(ir(`Failed to write Claude live steer: ${e.message}`,i))})}):Promise.reject(ir(`Claude turn is no longer accepting live input.`,!0))},stopAccepting(){t=!1}}}function sr(e,t){let n=`${e}.${S.pid}.${k()}.tmp`;C.writeFileSync(n,`${JSON.stringify(t)}\n`,`utf8`),C.renameSync(n,e)}async function cr(e){let t=C.mkdtempSync(w.join(D.tmpdir(),`coder-claude-steer-`)),n=`file:${t}`,r=new Set,i=!1,a=!1,o=(n=!1)=>{if(!(i&&!n||a)){a=!0;try{for(let n of C.readdirSync(t).filter(e=>e.endsWith(`.request.json`))){let i=w.join(t,n),a=`${i}.${S.pid}.processing`;try{C.renameSync(i,a)}catch{continue}let o=n.slice(0,-13),s=w.join(t,`${o}.response.json`),c=(async()=>{let t;try{let n=JSON.parse(C.readFileSync(a,`utf8`)),r=typeof n?.params?.text==`string`?n.params.text.trim():``;if(n?.method!==`turn/steer`||!r||n?.id!==o)t={id:o,error:{message:`Invalid Claude steer request.`,retryable:!1}};else try{await e(r),t={id:o,result:{accepted:!0}}}catch(e){let n=e;t={id:o,error:{message:n.message,retryable:n.retryable===!0}}}}catch(e){t={id:o,error:{message:`Invalid Claude steer JSON: ${e instanceof Error?e.message:String(e)}`,retryable:!1}}}try{sr(s,t)}finally{try{C.unlinkSync(a)}catch{}}})();r.add(c),c.then(()=>r.delete(c),()=>r.delete(c))}}catch{}finally{a=!1}}},s=setInterval(o,10);return{endpoint:n,async close(){i=!0,clearInterval(s),o(!0),await Promise.allSettled([...r]),await new Promise(e=>setTimeout(e,50)),C.rmSync(t,{recursive:!0,force:!0})}}}async function lr(e,t,n=3e3){if(!e)return{steered:!1,retryable:!0,detail:`Claude live steer endpoint is not ready.`};let r=t.trim();if(!r)return{steered:!1,retryable:!1,detail:`empty follow-up`};if(!e.startsWith(`file:`)||e.length===5)return{steered:!1,retryable:!1,detail:`Unsupported Claude steer endpoint: ${e}`};let i=e.slice(5);if(!C.existsSync(i))return{steered:!1,retryable:!0,detail:`Claude live steer endpoint is no longer available.`};let a=k(),o=w.join(i,`${a}.request.json`),s=w.join(i,`${a}.response.json`);try{sr(o,{id:a,method:`turn/steer`,params:{text:r}})}catch(e){return{steered:!1,retryable:e.code===`ENOENT`,detail:e instanceof Error?e.message:String(e)}}let c=Date.now();for(;Date.now()-c<n;){try{let e=JSON.parse(C.readFileSync(s,`utf8`));try{C.unlinkSync(s)}catch{}return e?.result?.accepted===!0?{steered:!0,retryable:!1,detail:`Claude accepted the live follow-up.`}:{steered:!1,retryable:e?.error?.retryable===!0,detail:String(e?.error?.message??`Malformed Claude steer response.`)}}catch(e){if(e.code!==`ENOENT`)return{steered:!1,retryable:!1,detail:`Invalid Claude steer response: ${e instanceof Error?e.message:String(e)}`}}await new Promise(e=>setTimeout(e,10))}return{steered:!1,retryable:!1,detail:`Timed out waiting for Claude live steer acknowledgement.`}}async function ur(e,t){let n=t.resumeSessionId??k(),r=rr(e,t,n);return t.onProgress?.({kind:`status`,message:`claude turn started (session ${n})`,threadId:n}),new Promise((i,a)=>{let o=T(t.executable??`claude`,r,{cwd:e,stdio:[`pipe`,`pipe`,`pipe`]}),s=``,c=``,l=[],u=null,d=n,f=null,p=!1,m=or((e,t)=>o.stdin.write(e,t)),h=Date.now(),g=new Map,_=0,v=0,y=new Set,b=n=>{if(!(!n||typeof n!=`object`)){if(t.onHeartbeat?.(),n.type===`system`&&n.subtype===`init`&&n.session_id)d=n.session_id;else if(n.type===`assistant`){let r=er(n.message?.usage);if(r){_+=r.output;let e=r.input+r.cachedInput+_;(!v||e-v>=1e3)&&(v=e,t.onProgress?.({kind:`usage`,tokens:{...r,output:_,total:e},threadId:d}))}for(let r of n.message?.content??[])if(r?.type===`tool_use`){let n=String(r.name??`Tool`);if(r.id&&g.set(String(r.id),{name:n,at:Date.now()}),Jn.has(n)){let t=String(r.input?.file_path??r.input?.notebook_path??``);t&&y.add(w.isAbsolute(t)?t:w.resolve(e,t))}t.onProgress?.({kind:`tool`,tool:n,message:$n(n,r.input??{},e),threadId:d})}else r?.type===`text`&&typeof r.text==`string`&&r.text.trim()?t.onProgress?.({kind:`assistant`,message:r.text.trim(),threadId:d}):r?.type===`thinking`&&typeof r.thinking==`string`&&r.thinking.trim()&&t.onProgress?.({kind:`reasoning`,message:r.thinking.trim(),durationMs:Math.max(1e3,Date.now()-h),threadId:d})}else if(n.type===`user`){for(let e of n.message?.content??[])if(e?.type===`tool_result`){let n=Yn(e.content).trim(),r=e.is_error===!0;if(!n&&!r)continue;let i=e.tool_use_id?g.get(String(e.tool_use_id)):void 0;e.tool_use_id&&g.delete(String(e.tool_use_id)),t.onProgress?.({kind:`tool-result`,...i?{tool:i.name,durationMs:Date.now()-i.at}:{},...r?{isError:!0}:{},message:n||`(tool failed with no output)`,threadId:d})}}else n.type===`result`&&(u=n,n.session_id&&(d=n.session_id),m.stopAccepting(),o.stdin.end());h=Date.now()}};o.stdout.on(`data`,e=>{s+=e;let t;for(;(t=s.indexOf(`
21
+ `))>=0;){let e=s.slice(0,t).trim();if(s=s.slice(t+1),e)try{b(JSON.parse(e))}catch(e){l.push(`Invalid Claude stream-json output: ${e instanceof Error?e.message:String(e)}`)}}}),o.stderr.on(`data`,e=>{c+=e});let x=()=>{m.stopAccepting(),o.kill(`SIGTERM`);let e=f?.endpoint;e?.startsWith(`file:`)&&C.rmSync(e.slice(5),{recursive:!0,force:!0}),S.exit(143)};S.on(`SIGTERM`,x),(async()=>{t.onSteerReady&&(f=await cr(e=>m.sendSteer(e))),await m.sendInitial(t.prompt),f&&t.onSteerReady?.(f.endpoint)})().catch(e=>{p||(p=!0,m.stopAccepting(),o.kill(`SIGTERM`),S.removeListener(`SIGTERM`,x),f?.close(),a(e))}),o.on(`error`,e=>{p||(p=!0,m.stopAccepting(),S.removeListener(`SIGTERM`,x),f?.close(),a(Error(`claude spawn failed: ${e.message}`)))}),o.on(`close`,async e=>{if(p)return;p=!0,m.stopAccepting(),S.removeListener(`SIGTERM`,x),await f?.close();let n=s.trim();if(n)try{b(JSON.parse(n))}catch(e){l.push(`Invalid trailing Claude stream-json output: ${e instanceof Error?e.message:String(e)}`)}let r=u?.result??``,a=e!==0||u?.is_error===!0||u==null||l.length>0;i({status:+!!a,threadId:u?.session_id??d,turnId:null,finalMessage:r,touchedFiles:[...y],tokens:er(u?.usage),model:u?.modelUsage&&Object.keys(u.modelUsage).join(`+`)||t.model||null,error:a?{message:l[0]||r||c.trim()||`claude exited ${e}`}:null})})})}function dr(e){E(`claude`,[`plugin`,`marketplace`,`remove`,`coder-plugins`],{encoding:`utf8`});let t=E(`claude`,[`plugin`,`marketplace`,`add`,e],{encoding:`utf8`}),n=E(`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 fr(){return w.join(D.homedir(),`.agents`,`skills`,`coder`)}function pr(){try{let e=C.readFileSync(w.join(fr(),`SKILL.md`),`utf8`);return/^\s*version:\s*(\S+)/m.exec(e)?.[1]??null}catch{return null}}function mr(e){let t=fr();try{let n=w.join(e,`plugins`,`agents`,`skills`,`coder`);C.rmSync(t,{recursive:!0,force:!0}),C.mkdirSync(t,{recursive:!0}),C.cpSync(n,t,{recursive:!0});let r=w.join(t,`SKILL.md`),i=C.readFileSync(r,`utf8`).replace(`
22
+ ---
23
+ `,`\nmetadata:\n version: ${y()}\n---\n`);return C.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 hr(e){if(e.available)return null;let t=E(`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 gr(e){let t=/(\d+\.\d+\.\d+)/.exec(String(e??``));return t?t[1]:null}function _r(e){if(!e.available)return null;let t=gr(e.detail);if(!t||$e(t,`0.144.0`)>=0)return null;let n=E(`codex`,[`update`],{encoding:`utf8`});return n.status!==0&&(n=E(`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 vr=/usage|quota|rate.?limit|429|401|unauthorized|not authenticated|login|insufficient|exhausted|not available|ENOENT/i,yr=`CODER_WORKER`;var K=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)}},br=class extends Error{agent;detail;constructor(e,t){super(t),this.agent=e,this.detail=t}};function xr(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&&jn(n)?n:void 0},s=e=>{let n=e?t.models?.[e]:void 0;return n&&G(n)?n:void 0};if(o(i)){let e;try{e=Kn(i,t)}catch(e){throw new K(`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 W?n=`claude`:i in U?n=`codex`:s(i)&&(n=`custom`)),n=n??t.chain[0]??`codex`,n!==`codex`&&n!==`claude`&&n!==`custom`){let e=n in U||n in W||n in(t.models??{})?` "${n}" is a model; use --model ${n}.`:``;throw new K(`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=Kn(l,t)}catch(e){throw new K(`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{Gn(t,l)}catch(e){throw new K(`invalid-option`,e instanceof Error?e.message:String(e))}if(n===`custom`){let e=Object.entries(t.models??{}).filter(([,e])=>G(e)).map(([e])=>e);if(!l&&e.length===1&&(l=e[0]),!l||!s(l))throw new K(`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 pn))throw new K(`invalid-option`,`Invalid --permissions "${d}". Use one of: ${Object.keys(pn).join(`, `)}`);if(f===`codex`&&u&&!dn.has(u))throw new K(`invalid-option`,`Invalid codex --effort "${u}". Use one of: ${[...dn].join(`, `)}`);if(f===`claude`&&u&&!fn.has(u))throw new K(`invalid-option`,`Invalid claude --effort "${u}". Use one of: ${[...fn].join(`, `)}`);return{engine:f,agent:n,model:l,effort:u,permissions:d}}function Sr(e,t){return e===`read-only`&&gn.test(t??``)}function Cr(e,n){let r=o(e,n),i=C.openSync(w.join(r,`worker.log`),`a`),a=T(S.execPath,[h,`_worker`,n,`--cwd`,e],{cwd:e,detached:!0,stdio:[`ignore`,i,i],env:{...S.env,[yr]:`1`}});a.unref(),C.closeSync(i),t(e,n,{pid:a.pid??null})}async function wr(e,r,i,a){let s=i.cwd,l=r.engine===`codex`?H(s):tr(),u=r.model?e.models?.[r.model]:void 0;if(!l.available&&u&&G(u)){let e=hr(l);i.onInstallNote?.(e.note),l=H(s)}if(!l.available)throw new br(r.agent,l.detail);let d=null;a.resume&&(d=n(s,a.resume)?.threadId??a.resume);let f=re(),p=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}:{}});Cr(s,f);let m=2**53-1,h=new Set([`status`,`usage`]),g=()=>c(s,f,m).filter(e=>{let{phase:t,kind:n}=e;return t!==`starting`&&!h.has(String(n??``))}).length,v=Date.now()+15e3,y=p,b=null,x=null;for(;Date.now()<(x??v)&&(y=_(s,f)??y,y.status!==`failed`&&y.status!==`completed`);){if(y.threadId&&b===null&&(b=g(),x=Date.now()+5e3),b!==null&&g()>b){y=_(s,f)??y;break}await new Promise(e=>setTimeout(e,150))}if(y.status===`failed`){let e=R(w.join(o(s,f),`result.json`))?.error?.message??``,t=c(s,f,5).map(e=>e.message??``).join(`
24
+ `),n=e||t;throw Sr(r.permissions,n)?new K(`read-only-unavailable`,n):vr.test(n)?new br(r.agent,n):new K(`startup-failed`,n,{taskId:f})}return{taskId:f,job:y,agent:r.agent,startupCheck:y.threadId?`passed`:`pending`}}function Tr(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 Er(e){if(S.env.CODER_WORKER)throw new K(`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 K(`invalid-option`,`Missing task text.`,{hint:[`Usage: coder run "<task text>"`,`Help: coder task run --help`]});let t=In(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=xr(n,t);try{return await wr(t,i,e,r)}catch(a){if(!(a instanceof br))throw a;let o=t.chain[t.chain.indexOf(a.agent)+1];if(!o){let t=Tr(a.agent,a.detail,i.permissions,e.system,e.prompt);throw new K(`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 Dr(e,t){if(t.status!==`failed`)return;let n=t.result;if(!n||!vr.test(n.error?.message??``)||!(!n.touchedFiles?.length&&!n.fileChanges?.length&&!n.commandExecutions?.length))return;let r=In(e).chain;return r[r.indexOf(t.job.agent)+1]}function Or(e,t){return R(w.join(o(e,t),`result.json`))}function kr(e,t,n=0){return n===0?[]:c(e,t,n===`all`?2**53-1:n)}function Ar(e,t,n={}){let r=_(e,t);if(!r)throw Error(`No task found for "${t}".`);return{taskId:t,status:r.status,result:Or(e,t),steps:kr(e,t,n.tail),turns:l(e,t),job:r}}async function jr(e,t,n={}){let r=_(e,t);if(!r)throw Error(`No task found for "${t}".`);let i=await St(e,r);if(i.reason===`approval`){let e=i.approval;throw new K(`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:Or(e,t),steps:kr(e,t,n.tail),turns:l(e,t),job:a}}const Mr=[`.ts`,`.mjs`,`.js`];function Nr(e,t){let n=[];try{n=C.readdirSync(e)}catch{return[]}let r=[];for(let i of n.sort()){let n=w.extname(i);Mr.includes(n)&&r.push({name:w.basename(i,n),path:w.join(e,i),scope:t})}return r}function Pr(e){let t=s(e),n=[],i=w.resolve(e);for(;n.push({dir:w.join(i,`.coder`,`flows`),scope:`workspace`}),i!==t&&w.dirname(i)!==i;)i=w.dirname(i);return n.push({dir:w.join(r(),`flows`),scope:`global`}),n}function Fr(e){let t=new Set,n=[];for(let{dir:r,scope:i}of Pr(e))for(let e of Nr(r,i))t.has(e.name)||(t.add(e.name),n.push(e));return n}function Ir(e){return e.includes(`/`)||Mr.includes(w.extname(e))}function Lr(e,t){if(Ir(e)){let n=w.resolve(t,e);if(C.existsSync(n))return{name:w.basename(n,w.extname(n)),path:n};throw Error(`Flow file not found: ${e}`)}let n=Fr(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 Rr(e,t,n={}){if(t.length)try{T(S.execPath,[h,`_archiveSweep`,`--cwd`,e,...n.flows?[`--flows`]:[],...t],{detached:!0,stdio:`ignore`}).unref()}catch{}}async function zr(e){let{options:t,positionals:r}=v(e,O.object({cwd:te,flows:ee})),i=F(t);for(let e of r){if(t.flows){let t=Z(e);t&&Oi(t);continue}let r=n(i,e);r&&ne(i,r)}}async function Br(e){let{options:t,positionals:n}=v(e,O.object({...b,"all-stopped":ee}));Ye(n,1,`task archive`);let r=F(t);if(t[`all-stopped`]){let e=u(r).filter(e=>a.includes(e.status));for(let t of e)ne(r,t);let n=e.map(e=>e.id);if(t.json){M({archived:n,count:n.length});return}S.stdout.write(n.length?`Archived ${n.length} stopped task${n.length===1?``:`s`}.\n`:`${A.dim(`No stopped tasks to archive.`)}\n`);return}let i=n[0];i||pe(`Missing task id.`,{hint:[`Archive one: coder task archive <task-id>`,`Archive all stopped: coder task archive --all-stopped`]});let o=Xe(r,i);if(ne(r,o),t.json){M({taskId:o.id,archived:!0});return}S.stdout.write(`Archived task ${A.cyan(o.id)}.\n`)}async function Vr(e,n,r={}){let i=n.engine===`claude`?{detail:`claude worker terminated`}:await(r.interrupt??sn)(e,{endpoint:n.steerEndpoint,threadId:n.threadId,turnId:n.turnId});if(n.engine!==`claude`&&Dt(n.steerEndpoint),n.pid&&n.status===`running`)try{S.kill(n.pid,`SIGTERM`)}catch{}return t(e,n.id,{status:`cancelled`,steerEndpoint:null,completedAt:new Date().toISOString()}),{taskId:n.id,status:`cancelled`,interrupt:i.detail}}async function Hr(e){let{options:t,positionals:n}=v(e,O.object(b));Ye(n,1,`task stop`);let r=F(t),i=Xe(r,n[0]),{interrupt:a}=await Vr(r,i);if(t.json){M({taskId:i.id,status:`cancelled`,interrupt:a});return}S.stdout.write(`Stopped task ${A.cyan(i.id)} ${A.dim(`(${a})`)}\n`)}function Ur(e){return typeof e!=`object`||!e?JSON.stringify(e)??`null`:Array.isArray(e)?`[${e.map(Ur).join(`,`)}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${Ur(e[t])}`).join(`,`)}}`}function Wr(e,t){return le.createHash(`sha256`).update(`${e}\0${Ur(t)}`).digest(`hex`)}function Gr(e){return C.existsSync(e)?C.readFileSync(e,`utf8`).split(/\r?\n/).filter(Boolean).map(e=>{try{return JSON.parse(e)}catch{return null}}).filter(e=>e!==null):[]}var Kr=class{file;recorded;seq=0;constructor(e,t){this.file=t,this.recorded=e.map(e=>({...e})),C.writeFileSync(t,``,`utf8`)}write(e){e.seq=this.seq++,C.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 qr=globalThis,q=qr.__coderFlowCtxALS??=new ue,J=qr.__coderFlowScopeALS??=new ue;function Jr(){return J.getStore()?.args}function Yr(){return J.getStore()?.depth??0}var Xr=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 Zr(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 Qr(e,t){if(!t.tokens)return;let n=t.model??`default`;e.ledger[n]=Zr(e.ledger[n]??null,t.tokens)}function $r(e){return!!e&&typeof e.safeParse==`function`}async function ei(e){try{let t=await import(`zod`);if(typeof t.toJSONSchema==`function`)return t.toJSONSchema(e)}catch{}return null}async function ti(e){let t=await ei(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 ni(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 ri(e,t){if(!$r(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 ii(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 ai(e,t,n,r){let i=t.cwd?w.resolve(t.cwd):n?.cwd??S.cwd(),a;for(;;){let o=await Er({prompt:e,...ii(t,i,n),...a?{agent:a,model:void 0,effort:void 0,resume:void 0}:{resume:r??t.resume},onFallback:e=>hi(`${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=_(i,o.taskId),c=s?xe(s):void 0;n?.hooks.onTaskStart?.({taskId:o.taskId,name:t.name,prompt:e,agent:c,depth:Yr()});let l;try{l=await jr(i,o.taskId)}finally{n?.running.delete(o.taskId)}let u=Dr(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 oi(e,t,n){let r=e;if(t.returns&&(r=`${e}\n\n${await ti(t.returns)}`),n?.dryRun){S.stdout.write(`\n[dry-run] task${t.name?` (${t.name})`:``}:\n${r}\n`);let e={...t,returns:t.returns?`<schema>`:void 0};return S.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 ai(r,t,n);if(i.status!==`completed`){let e={...i,data:void 0};throw new K(`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=ri(t.returns,ni(a))}catch(t){e={ok:!1,errors:t instanceof Error?t.message:String(t)}}if(e.ok)s=e.data;else{let r=await ai(`Your previous reply did not match the required format: ${e.errors}\n\n${await ti(t.returns)}`,t,n,i.taskId);a=r.output||a,o=Zr(o,r.tokens);try{let e=ri(t.returns,ni(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 K(`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 si(e){if(e)return await ei(e)??`<schema>`}async function ci(e,t={}){let n=q.getStore();if(!n)return oi(e,t);let r=Wr(`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 si(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 oi(e,t,n)}catch(e){let t=e instanceof K?e.result:void 0;throw t&&n.hooks.onTaskEnd?.({taskId:t.taskId,status:t.status===`completed`?`failed`:t.status,tokens:t.tokens}),e}return Qr(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 li=262144;let ui=0;function di(e){let t=[];for(let n=e;;){t.push(w.join(n,`node_modules`,`.bin`));let e=w.dirname(n);if(e===n)break;n=e}let n=S.platform===`win32`?`;`:`:`;return{...S.env,PATH:[...t,S.env.PATH??``].join(n)}}async function fi(e,t){return new Promise(n=>{let r=T(e,{shell:!0,cwd:t,env:di(t)}),i=``,a=e=>{i.length>=li||(i+=e,i.length>=li&&(i=`${i.slice(0,li)}\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 pi(e,t={}){let n=q.getStore(),r=t.cwd?w.resolve(t.cwd):n?.cwd??S.cwd();if(!n)return fi(e,r);let i=Wr(`gate`,{cmd:e,cwd:t.cwd}),a=n.journal.replay(i);if(a)return a.result;if(n.dryRun){S.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-${S.pid}-${ui+=1}`,c=Yr();n.hooks.onGateStart?.({gateId:s,cmd:e,depth:c});let l=await fi(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 mi(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 hi(e){let t=q.getStore();if(t)try{C.appendFileSync(w.join(t.runDir,`flow.log`),`${JSON.stringify({at:new Date().toISOString(),message:e})}\n`,`utf8`)}catch{}t?.hooks.onLog?t.hooks.onLog(e,Yr()):(S.stderr.isTTY||!t)&&S.stderr.write(`[flow] ${e}\n`)}const gi=ae(import.meta.url);function _i(e){let t=w.dirname(oe(import.meta.url));for(;w.basename(t)!==`dist`&&w.dirname(t)!==t;)t=w.dirname(t);return w.basename(t)===`dist`?se(w.join(t,e)).href:null}function vi(e){if(!(e===`@wular/coder`||e===`@wular/coder/flow`||e===`zod`||e.startsWith(`zod/`)))return null;try{return se(gi.resolve(e)).href}catch{}return e===`@wular/coder/flow`?_i(`flow/index.js`):e===`@wular/coder`?_i(`sdk.js`):null}const yi=/(\bfrom\s+|\bimport\s+|\bimport\s*\(\s*)(['"])([^'"]+)\2/g;function bi(e){return e.replace(yi,(e,t,n,r)=>{let i=vi(r);return i?`${t}${n}${i}${n}`:e})}async function xi(e,t,n){try{return await import(se(e).href)}catch(e){let r=e instanceof Error?e.message:String(e);throw t===`.ts`&&!S.versions?.bun&&/Unknown file extension|Unexpected token|SyntaxError|Cannot parse|import type|interface/i.test(r)?Error(`Could not run ${w.basename(n)}: TypeScript flows need bun. Run under \`bun\`, or write the flow as .mjs/.js.`):e}}async function Si(e){let t=w.extname(e),n;try{n=C.readFileSync(e,`utf8`)}catch{throw Error(`Cannot read flow file: ${e}`)}let r=bi(n);if(r===n)return xi(e,t,e);let i=w.dirname(e);try{for(let e of C.readdirSync(i)){if(!e.startsWith(`.__coderflow_`))continue;let t=w.join(i,e);Date.now()-C.statSync(t).mtimeMs>6e5&&C.unlinkSync(t)}}catch{}let a=`${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`,o=w.join(i,`.__coderflow_${a}${t}`),s=`__coderflow_loaded_${a}`,c=new Promise(e=>{globalThis[s]=e});C.writeFileSync(o,`globalThis[${JSON.stringify(s)}]?.();${r}`,`utf8`);let l=xi(o,t,e);try{await Promise.race([c,l.then(()=>void 0,()=>void 0)])}finally{delete globalThis[s];try{C.unlinkSync(o)}catch{}}return await l}async function Ci(e,t){let n=J.getStore();n.args=t??{};let r=await Si(e),i=r.args,a=n.args;if($r(i)){let e=i.safeParse(t??{});if(!e.success){let e=ri(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 wi(e,t){let n=q.getStore(),r=Lr(e,n?.cwd??S.cwd());if(!n)return J.run({args:t??{},depth:0},()=>Ci(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=Wr(`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},()=>Ci(r.path,t));return n.journal.record({kind:`flow`,fingerprint:a,result:c,startedAt:s,endedAt:new Date().toISOString()}),c}function Ti(){return`flow-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Y(){return w.join(r(),`state`,`global`,`flows`)}function Ei(){return w.join(r(),`state`,`global`,`flows-archived`)}function X(e){ie(e,`flow run id`);let t=w.join(Y(),e);if(C.existsSync(w.join(t,`flow.json`)))return t;let n=w.join(Ei(),e);return C.existsSync(w.join(n,`flow.json`))?n:t}function Di(e){if(e.archived)return e;let t={...e,archived:!0,archivedAt:new Date().toISOString()};return Q(X(e.runId),t),t}function Oi(e){let t=Di(e),n=X(e.runId),r=w.join(Ei(),e.runId);if(n!==r)try{C.mkdirSync(Ei(),{recursive:!0}),C.renameSync(n,r)}catch{}return t}function ki(e){let t=X(e.runId),n=w.join(Y(),e.runId);if(t!==n)try{C.mkdirSync(Y(),{recursive:!0}),C.renameSync(t,n)}catch{}let r={...e,archived:void 0,archivedAt:void 0};return Q(X(e.runId),r),r}function Ai(e){let t=X(e);return C.existsSync(w.join(t,`flow.json`))?(C.rmSync(t,{recursive:!0,force:!0}),!0):!1}function ji(e){if(!f(e))return null;let t=w.join(X(e),`flow.json`);if(!C.existsSync(t))return null;try{return JSON.parse(C.readFileSync(t,`utf8`))}catch{return null}}function Mi(e){return e.status!==`running`||!e.pid||Wi(e)?e:(Vi(e.runId,`orchestrator died`),ji(e.runId)??e)}function Z(e){let t=ji(e);return t?Mi(t):null}function Q(e,t){C.writeFileSync(w.join(e,`flow.json`),`${JSON.stringify(t,null,2)}\n`,`utf8`)}function Ni(e){let t=[];try{t=C.readdirSync(e)}catch{return[]}let n=[];for(let r of t)try{n.push(Mi(JSON.parse(C.readFileSync(w.join(e,r,`flow.json`),`utf8`))))}catch{}return n}const Pi=(e,t)=>String(t.startedAt).localeCompare(String(e.startedAt));function Fi(){let e=[];for(let t of Ni(Y()))t.archived?Oi(t):e.push(t);return e.sort(Pi)}function Ii(e){let t=e?.migrate??!0,n=Ni(Ei()),r=new Set(n.map(e=>e.runId));for(let e of Ni(Y()))e.archived&&!r.has(e.runId)&&n.push(t?Oi(e):e);return n.sort(Pi)}function Li(){return[...Fi(),...Ii()].sort(Pi)[0]??null}function Ri(e,t=`all`){if(t===0)return[];let n=Gr(w.join(X(e),`journal.jsonl`)).filter(e=>e.kind===`task`),r=u(S.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 zi(e={}){let t;if(e.archived)t=Ii();else{let e=[];t=Fi().filter(t=>t.status===`running`||t.status===`queued`||he(t.endedAt??t.startedAt)<=6e5||(Di(t),e.push(t.runId),!1)),Rr(S.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 Bi(e,t={},n){let r,i,a;if(n){let e=Z(n);if(!e)throw Error(`No flow run "${n}".`);e.archived&&ki(e),r=e.name,i=e.script,a=t.args??e.args}else{let n=Lr(e,t.cwd?w.resolve(t.cwd):S.cwd());r=n.name,i=n.path,a=t.args??{}}let o=n??Ti(),s=X(o);C.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??D.cpus().length),maxTasks:Math.max(1,t.maxTasks??D.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 Vi(e,t){let n=ji(e);!n||n.status!==`running`||$(X(e),n,{status:`failed`,error:t})}const Hi=`stop-keep-tasks`;function Ui(e){try{return S.kill(e,0),!0}catch{return!1}}function Wi(t){if(!t.pid||!Ui(t.pid))return!1;let n=e(t.pid),r=Date.parse(t.pidStartedAt??``);return n===null||!Number.isFinite(r)||n<=r+6e4}function Gi(e){let t=u(S.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 Gr(w.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 Ki(e,t=[]){let n=S.cwd(),r=[];for(let i of new Set([...Gi(e),...t])){let e=_(n,i);if(!(!e||a.includes(e.status)))try{await Vr(n,e),r.push(i)}catch{}}return r}async function qi(e,t={}){let n=e?Z(e):Li();if(!n)throw new K(`flow-failed`,e?`No flow run "${e}".`:`No flow runs.`,{hint:`Run one: coder flow run <name>`});if(n.status!==`running`)throw new K(`flow-failed`,`Run ${n.runId} is not running.`,{runId:n.runId,hint:`Result: coder flow result ${n.runId}`});let r=X(n.runId);if(!Wi(n))return $(r,n,{status:`failed`,error:`orchestrator died`}),{runId:n.runId,status:`failed`,stoppedTasks:[],keptTasks:Gi(n.runId)};let i=Gi(n.runId),o=w.join(r,Hi);t.keepTasks&&C.writeFileSync(o,``,`utf8`);try{S.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 K(`flow-failed`,`Run ${n.runId} did not stop within 5s.`,{runId:n.runId,hint:`Check it: coder flow result ${n.runId}`});let t=S.cwd(),r=[],o=[];for(let e of i){let n=_(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{C.unlinkSync(o)}catch{}}}async function*Ji(e,t,n={}){let r=w.join(X(e),`events.jsonl`),i=n.tail??`all`,a=0;if(i!==`all`)try{a=Math.max(0,C.readFileSync(r,`utf8`).split(`
25
+ `).length-1-i)}catch{}let o=st(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?!Wi(c):t!==void 0&&!Ui(t);if(c&&(c.pid||t!==void 0)&&n){Vi(e,`orchestrator died`);break}await new Promise(e=>setTimeout(e,400)),c=Z(e)??c}yield*s()}function Yi(e,t,n,r){let i={...Bi(e,t,r),pid:S.pid,pidStartedAt:new Date().toISOString()},{runId:a}=i,o=X(a);Q(o,i);let s=w.join(o,`journal.jsonl`),c=r?Gr(s):[],l=new Kr(c,s),u={runId:a,runDir:o,cwd:t.cwd?w.resolve(t.cwd):S.cwd(),journal:l,semaphore:new Xr(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 Xi(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},()=>Ci(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 K(`flow-failed`,e instanceof Error?e.message:String(e),{runId:o})}}async function Zi(e,t={},n={}){let{started:r}=Yi(e,t,n),i=Z(r.runId).script;return n.onStart?.({runId:r.runId,requestStop:r.markStopped,runningIds:()=>[...r.ctx.running]}),Xi(r,i,Z(r.runId).name,t.args??{})}async function Qi(e,t={},n={}){let{started:r,args:i,name:a,replayable:o}=Yi(``,t,n,e),s=Z(e).script;return n.onStart?.({runId:e,requestStop:r.markStopped,runningIds:()=>[...r.ctx.running]}),o&&n.onReplay?.(o),Xi(r,s,a,i)}export{hn as $,A as $t,Fr as A,R as At,jr as B,Fe as Bt,ci as C,xt as Ct,Br as D,_t as Dt,Vr as E,yt as Et,Tr as F,rt as Ft,dr as G,ye as Gt,hr as H,ze as Ht,Er as I,it as It,tr as J,me as Jt,pr as K,N as Kt,Sr as L,Ie as Lt,K as M,ot as Mt,vr as N,nt as Nt,zr as O,bt as Ot,yr as P,at as Pt,W as Q,Ge as Qt,Ar as R,Ke as Rt,Ji as S,vt as St,Hr as T,ht as Tt,_r as U,Le as Ut,fr as V,he as Vt,mr as W,pe as Wt,lr as X,_e as Xt,ur as Y,P as Yt,fn as Z,Re as Zt,Qi as _,on as _t,Ai as a,F as an,jn as at,Ki as b,cn as bt,pi as c,Te as cn,In as ct,Fi as d,Ee as dn,Rn as dt,qe as en,dn as et,hi as f,Hn as ft,Z as g,qn as gt,Bi as h,Mn as ht,Jr as i,Xe as in,Bn as it,Lr as j,L as jt,Rr as k,st as kt,Li as l,Be as ln,Ln as lt,mi as m,Fn as mt,Oi as n,be as nn,un as nt,wi as o,Je as on,Un as ot,Vi as p,Vn as pt,nr as q,fe as qt,zi as r,Ye as rn,pn as rt,Ri as s,we as sn,G as st,Hi as t,M as tn,U as tt,Ii as u,Ve as un,Kn as ut,X as v,H as vt,Gr as w,mt as wt,qi as x,St as xt,Zi as y,ln as yt,Cr as z,Pe 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,Dt as a,E as o,I as s,M as c,R as l,St as u}from"./runtime-DtukZ1m8.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-cC4ahBbt.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 s({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}):l(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 o(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 a(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{c 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
+ import{C as e,I as t,v as n,x as r}from"./app-server-bHl6RBZ2.js";import{B as i,Dt as a,E as o,I as s,M as c,R as l,St as u}from"./runtime-SneScSWY.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-Cjbeytvs.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 s({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}):l(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 o(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 a(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{c 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};
@@ -0,0 +1,37 @@
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{$t as E,At as D,Dt as ee,G as te,Gt as ne,H as re,Ht as O,J as ie,K as ae,Kt as oe,Nt as se,Pt as ce,Q as k,U as le,Ut as ue,V as de,Vt as fe,W as pe,Wt as A,X as me,Y as he,Z as ge,Zt as j,_t as _e,an as M,at as N,bt as ve,cn as ye,ct as P,dn as be,en as xe,et as Se,ft as Ce,g as we,gt as Te,ht as Ee,in as F,it as I,jt as De,k as Oe,kt as ke,ln as Ae,lt as L,mt as R,nn as je,nt as Me,ot as z,pt as Ne,q as Pe,qt as B,rn as V,sn as Fe,st as H,tn as U,tt as W,ut as Ie,vt as G,yt as Le,z as Re,zt as ze}from"./runtime-SneScSWY.js";import K from"node:process";import q from"node:fs";import J from"node:path";import{spawnSync as Be}from"node:child_process";import Ve from"node:os";import{fileURLToPath as He}from"node:url";import*as Y from"zod/mini";import Ue from"node:crypto";import We from"node:http";let Ge=0;function Ke(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 qe(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:Ke(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 Je=class{send;model;responseId=`resp_bridge_${++Ge}`;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
+ `);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 Ye(e,t=`chat`){let n=t===`responses`,r=I(e.baseUrl,n?`responses`:`chat/completions`),i=null,a=e.envKey?K.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=Ue.randomBytes(16).toString(`hex`),c=We.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(qe(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 Je(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 Xe(e,t,n){let r=e.envKey?K.env[e.envKey]:void 0,i=!1;for(let a of I(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 Ze(e){let t=await Xe(e,`responses`,{model:e.model,input:[],stream:!1});if(`baseUrl`in t)return{wireApi:`responses`,baseUrl:t.baseUrl};let n=await Xe(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*Qe(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=ke(J.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 $e(e){let{options:t,positionals:n}=v(e,Y.object({...b,tail:p,trim:Y.optional(Y.union([Y.literal(`none`),Y.coerce.number().check(Y.int(),Y.positive())],{error:`expected a positive integer or "none"`}))}));V(n,1,`task watch`);let r=M(t),a=F(r,n[0]),o=t.tail,c=t.trim,l=c===void 0?500:c===`none`?1/0:c,d=new ze({cwd:a.cwd??r,startedAt:Date.parse(a.createdAt??``)||void 0,trim:l,explicitTrim:c!==void 0,width:Ae()});if(!t.json){let e=[...Fe(a,{status:a.status}),...u.includes(a.status)?[E.dim(`watching — Ctrl-C to stop`)]:[],...a.prompt?je(a.prompt,E,{truncate:!1}):[],``];K.stdout.write(`${e.join(`
3
+ `)}\n`)}let f=null,m=null,h=e=>{let t=d.render(e);t.length&&K.stdout.write(`${t.join(`
4
+ `)}\n`)};for await(let e of Qe(r,a.id,{tail:o})){if(e.kind===`usage`&&e.tokens&&(f=e.tokens),t.json){let t=e.kind===`steer`?1/0:l,n=e.message?{...e,message:be(e.message,t,{plain:!0})}:e;K.stdout.write(`${JSON.stringify(n)}\n`);continue}e.kind!==`usage`&&(m&&=(h(m),null),e.kind===`assistant`?m=e:h(e))}let _=s(r,g(r,a.id)??a),y=D(J.join(i(r,a.id),`result.json`));if(t.json)U({taskId:a.id,status:_.status,result:y});else{let e=_.status===`completed`?`(no final message)`:`(task ${_.status})`,t=ye(_,{tokens:y?.tokens??f,tokenModel:y?.model,files:y?.touchedFiles?.map(e=>De(a.cwd??r,e)),statusChanged:_.status!==a.status});t.length&&K.stderr.write(`\n${t.join(`
5
+ `)}\n`);let n=ne(y,_.error,e),i=m?String(m.message??``):``;K.stdout.write(`\n${n.trim()?n:i}\n`)}K.exit(_.status===`completed`?0:1)}async function et(e,t,n,r={}){if(t.status!==`running`)return null;let i=t.engine===`claude`?await(r.claude??me)(t.steerEndpoint,n):await(r.codex??ve)(e,{endpoint:t.steerEndpoint,threadId:t.threadId,turnId:t.turnId,text:n});if(i.steered)return d(e,t.id,{kind:`steer`,message:`Steer accepted live:\n${n}`}),{taskId:t.id,steered:`live`};if(!i.retryable)throw d(e,t.id,{kind:`error`,message:`Live steer failed: ${i.detail}`}),Error(`Could not steer running task ${t.id}: ${i.detail}`);let a=g(e,t.id)??t;return u.includes(a.status)?(c(e,a.id,n),d(e,a.id,{kind:`steer`,message:`Steer queued for the next turn:\n${n}`}),{taskId:a.id,steered:`queued`}):null}async function tt(e,t,n,r={},i={}){if(!t.threadId)throw Error(`Task ${t.id} has no thread to steer yet (status: ${t.status}).`);return await et(e,t,n,i)||(nt(e,t,n,r),{taskId:t.id,steered:`resumed`})}function nt(t,n,r,i){e(t,n.id,{status:`queued`,resumedAt:new Date().toISOString(),currentPrompt:r,resumeThreadId:n.threadId,steerEndpoint:null,model:i.model??n.model??null,effort:i.effort??n.effort??null,permissions:i.permissions??n.permissions,error:void 0}),d(t,n.id,{kind:`steer`,message:`Resuming with steer:\n${r}`}),Re(n.cwd??t,n.id)}async function rt(e){let{options:t,positionals:n}=v(e,Y.object({...b,model:C,effort:C,permissions:C,background:S,wait:S})),r=M(t),[i,...a]=n,o=a.join(` `).trim();(!i||!o)&&A(`Missing task id or follow-up text.`,{hint:[`Usage: coder task steer <task-id> "<follow-up>" [--wait]`,`Help: coder task steer --help`]});let s=F(r,i);s.threadId||A(`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 tt(r,s,o,{model:t.model,effort:t.effort,permissions:t.permissions});return it(r,c.taskId,{steered:c.steered,options:t})}async function it(e,t,{steered:n,options:r}){if(n===`queued`){if(r.json){U({taskId:t,steered:`queued`});return}K.stdout.write(`${E.dim(`[coder]`)} follow-up queued for task ${E.cyan(t)}; it runs when the current turn finishes.\n`),r.wait&&K.stdout.write(`\n${E.dim(`[coder] --wait is not available for a queued follow-up; check: coder task result ${t}`)}\n`);return}if(!r.wait){if(r.json){U({taskId:t,steered:n});return}K.stdout.write(n===`live`?`${E.dim(`[coder]`)} steered follow-up into running task ${E.cyan(t)}.\n`:`${E.dim(`[coder]`)} resumed task ${E.cyan(t)} with the follow-up (same thread, same id).\n`),K.stdout.write(`\n${E.dim(` result: coder task result ${t}`)}\n`);return}let a=g(e,t),o=a?await T(e,a):null,s=D(J.join(i(e,t),`result.json`));r.json?U({taskId:t,status:o?.status??null,finalMessage:s?.finalMessage??null}):(K.stdout.write(`\n${s?.finalMessage||`(no final message)`}\n\n`),K.stderr.write(`${E.dim(`[coder] task=${t} status=${o?.status??`unknown`}`)}\n`)),K.exitCode=o?.status===`completed`?0:1}const at=[`Read`,`Glob`,`Grep`];function ot(e,t,n){return`You are a read-only sidecar answering a question ABOUT a coder task.
6
+ You are not the task: never continue, redo, or fix its work — only answer the question. The task never sees this question or your answer.
7
+
8
+ Task metadata:
9
+ ${[`id: ${e.id}`,...e.name?[`name: ${e.name}`]:[],`status: ${e.status}`,`agent: ${e.agent}${e.model?`/${e.model}`:``}${e.effort?`/${e.effort}`:``}`,...e.cwd?[`workspace: ${e.cwd}`]:[],...e.createdAt?[`created: ${e.createdAt}`]:[],...e.completedAt?[`finished: ${e.completedAt}`]:[]].join(`
10
+ `)}
11
+
12
+ Task prompt:
13
+ ${e.prompt??`(unknown)`}
14
+
15
+ Inspect as needed (grep/read selectively; events can be large):
16
+ - progress log (jsonl, one event per line): ${J.join(t,`log.jsonl`)}
17
+ - final result: ${J.join(t,`result.json`)}
18
+ - worker output: ${J.join(t,`worker.log`)}
19
+ ${e.cwd?`- the task's workspace (its code and changes): ${e.cwd}`:``}
20
+
21
+ Question: ${n}
22
+
23
+ Answer the question directly and concisely.`}function st(e,t,n,r){return{prompt:n,model:r.model??e.model,effort:r.effort,permissions:`read-only`,additionalDirectories:[t],readOnlyAllowedTools:at}}async function ct(e,t,n,r={}){let a=i(e,t.id),o=ot(t,a,n),s=r.effort??t.effort??null;if(t.engine===`claude`)return he(t.cwd??e,st(t,a,o,{model:r.model,effort:s}));let c=P(e),l=r.model??t.model,u=l?c.models?.[l]:void 0,d=u&&H(u)?u:void 0;if(d?.envKey&&!K.env[d.envKey])throw Error(`Missing environment variable: \`${d.envKey}\`.`);let f=d?await Ye(d,d.wireApi??`chat`):null,p=Ne(c,l,f??void 0);try{return await Le(t.cwd??e,{prompt:o,model:p?.model??Ce(l??null),modelProvider:p?.modelProvider??null,configOverrides:p?.configOverrides??null,effort:s,sandbox:`read-only`,approvalPolicy:`never`,ephemeral:!0})}finally{await f?.close()}}async function lt(e){let{options:t,positionals:n}=v(e,Y.object({...b,model:C,effort:C})),r=M(t),[i,...a]=n,o=a.join(` `).trim();(!i||!o)&&A(`Missing task id or question.`,{hint:[`Usage: coder task ask <task-id> "<question>"`,`Help: coder task ask --help`]});let s=F(r,i);t.json||K.stderr.write(`${E.dim(`[coder]`)} asking about task ${E.cyan(s.id)} (read-only sidecar; the task is not interrupted)...\n`);let c=await ct(r,s,o,{model:t.model,effort:t.effort}),l=c.finalMessage||``;if(t.json)U({taskId:s.id,answer:l||null,...c.error?{error:c.error.message}:{}});else if(l)K.stdout.write(`\n${l}\n`);else{let e=c.error?.message?` ${E.red(c.error.message)}`:``;K.stdout.write(`${E.dim(`(no answer)`)}${e}\n`)}K.exitCode=c.status===0?0:1}function ut(e,n={}){let i=n.limit===`all`?void 0:n.limit,s=e=>r.includes(e.status),c=[],l=o(e).filter(t=>{if(!s(t))return!0;let n=t.completedAt??t.updatedAt??t.createdAt;return fe(n)<=6e5||(_(e,t),c.push(t.id),!1)});if(Oe(e,c),n.archived?l=t(e):n.running?l=l.filter(e=>u.includes(e.status)):n.stopped&&(l=l.filter(s)),n.dir){let e=a(J.resolve(String(n.dir)));l=l.filter(t=>t.cwd&&a(t.cwd)===e)}if(!n.archived&&!n.running&&!n.stopped){let e=e=>e.status===`failed`?0:u.includes(e.status)?1:e.status===`completed`?3:2;l=[...l].sort((t,n)=>e(t)-e(n))}let d=i===void 0?0:Math.max(0,l.length-i);return i!==void 0&&(l=l.slice(0,i)),{jobs:l,clipped:d}}async function dt(e){let{options:r,positionals:a}=v(e,Y.object({cwd:C,dir:C,limit:f,json:S,running:S,stopped:S,archived:S}));V(a,0,`task list`);let o=M(r),s=r.limit===`all`?void 0:r.limit,{jobs:c,clipped:l}=ut(o,{running:r.running,stopped:r.stopped,archived:r.archived,dir:r.dir??r.cwd,limit:r.limit}),d=c.map(e=>{let t=u.includes(e.status)?ee(i(o,e.id)).filter(e=>!e.response).length:0;return{taskId:e.id,status:t?`waiting-approval`:e.status,pendingApprovals:t,agent:e.agent??null,model:e.model??null,effort:e.effort??null,name:e.name??null,cwd:e.cwd??null,prompt:String(e.prompt??``).replace(/\s+/g,` `).trim().slice(0,80),updatedAt:e.updatedAt,archived:e.archived??!1,flowRunId:e.flowRunId??null,idleMs:u.includes(e.status)?fe(n(o,e)):null}});if(r.json){U(d);return}if(!d.length){let e=r.archived?`archived tasks`:r.running?`running tasks`:r.stopped?`recently stopped tasks`:`recent tasks`;K.stdout.write(`No ${e}.\n`);let n=[];if(!r.archived){let e=t(o,{migrate:!1}).length;e&&n.push(`${e} archived: coder task list --archived [--limit N]`)}n.length&&K.stdout.write(`\n${B(n,E)}\n`);return}let p=E,m=e=>(e.agent===`custom`&&e.model?e.model:(e.agent??`-`)+(e.model?`/${e.model}`:``))+(e.effort?`/${e.effort}`:``),h=e=>e.cwd?J.basename(e.cwd):`-`,g=(e,t,n)=>Math.min(t,Math.max(e,...n.map(e=>e.length))),_={id:g(7,28,d.map(e=>e.taskId)),status:g(6,16,d.map(e=>e.status)),who:g(5,26,d.map(m)),cwd:g(3,24,d.map(h))},y=e=>{let t=e.archived?` ${p.dim(`(archived)`)}`:``,n=e.name?e.name:p.light(e.prompt),r=e.idleMs!==null&&e.idleMs>=12e4?` ${(e.idleMs>6e5?p.red:p.dim)(`· idle ${oe(e.idleMs)}`)}`:``;K.stdout.write(`${p.cyan(e.taskId.padEnd(_.id))} ${xe(e.status,_.status)} ${p.light(ue(m(e),_.who))} ${p.light(ue(h(e),_.cwd))} ${n}${r}${t}\n`)};K.stdout.write(p.bold(p.light(`${`task-id`.padEnd(_.id)} ${`status`.padEnd(_.status)} ${`agent`.padEnd(_.who)} ${`cwd`.padEnd(_.cwd)} name\n`)));let b=new Map;for(let e of d)e.flowRunId&&(b.get(e.flowRunId)??b.set(e.flowRunId,[]).get(e.flowRunId)).push(e);let x=new Set,w=!1,T=!1;for(let e of d){if(!e.flowRunId){T&&K.stdout.write(`
24
+ `),y(e),w=!0,T=!1;continue}if(x.has(e.flowRunId))continue;x.add(e.flowRunId);let t=we(e.flowRunId),n=t?`(${p.bold(e.flowRunId)} ${t.status} — flow ${t.name})`:`(${p.bold(e.flowRunId)} flow)`;K.stdout.write(`${w?`
25
+ `:``}${n}\n`);for(let t of b.get(e.flowRunId))y(t);w=!0,T=!0}l&&K.stdout.write(p.dim(`\n... ${l} more not shown (--limit ${s})\n`));let D=[`Result: coder task result <task-id>`];r.archived||D.push(`Older tasks: coder task list --archived [--limit N]`),K.stdout.write(`\n${B(D,p)}\n`)}function ft(){let e=process.env.CLAUDE_CONFIG_DIR||J.join(Ve.homedir(),`.claude`);return J.join(e,`projects`)}function pt(e){if(!e)return!1;let t=ft(),n=!1;try{for(let r of q.readdirSync(t)){let i=J.join(t,r,`${e}.jsonl`);q.existsSync(i)&&(q.rmSync(i,{force:!0}),n=!0)}}catch{}return n}function X(e){e.threadId&&(e.engine===`codex`?l(e.threadId):e.engine===`claude`&&pt(e.threadId))}async function mt(e){let{options:n,positionals:r}=v(e,Y.object({...b,"all-archived":S}));V(r,1,`task delete`);let i=M(n);if(n[`all-archived`]){let e=t(i).filter(e=>(X(e),w(i,e.id))).map(e=>e.id);if(n.json){U({deleted:e,count:e.length});return}K.stdout.write(e.length?`Deleted ${e.length} archived task${e.length===1?``:`s`}.\n`:`${E.dim(`No archived tasks to delete.`)}\n`);return}let a=r[0];a||A(`Missing task id.`,{hint:[`Delete one: coder task delete <task-id>`,`Delete all archived: coder task delete --all-archived`]});let o=F(i,a);if(o.status===`running`&&A(`Task ${o.id} is still running.`,{hint:`Stop it first: coder task stop ${o.id}`}),X(o),w(i,o.id),n.json){U({taskId:o.id,deleted:!0});return}K.stdout.write(`Deleted task ${E.cyan(o.id)}.\n`)}function ht(e,t){return t.split(`.`).reduce((e,t)=>e?.[t],e)}function gt(e,t){return t?J.join(a(e),`coder.config.json`):R()}function _t(e,t){let n=P(e);return t?ht(n,t):n}function vt(e,t,n,r={}){let i=gt(e,r.workspace),a=q.existsSync(i)?JSON.parse(q.readFileSync(i,`utf8`)):{},o=t.split(`.`),s=o.at(-1),c=a;for(let e of o.slice(0,-1))(typeof c[e]!=`object`||c[e]===null)&&(c[e]={}),c=c[e];r.unset?delete c[s]:c[s]=n;let l=Ee(a);if(l.length)throw Error(`Refusing to write invalid config:\n ${l.join(`
26
+ `)}`);return q.mkdirSync(J.dirname(i),{recursive:!0}),q.writeFileSync(i,`${JSON.stringify(a,null,2)}\n`,`utf8`),{file:i,key:t,effective:ht(P(e),t)??null,...r.unset?{unset:!0}:{value:n}}}async function yt(e){let{options:t,positionals:n}=v(e,Y.object({...b,workspace:S})),r=M(t),[i=`list`,a,...o]=n,s=gt(r,t.workspace);if(i===`list`){let e=P(r);if(t.json){U(e);return}let n=E,i=e=>[e?.model,e?.effort,e?.permissions].filter(Boolean).join(`/`)||`-`;K.stdout.write([`${n.dim(`chain`)} ${e.chain.join(` -> `)}`,`${n.dim(`codex`)} ${i(e.agents.codex)}`,`${n.dim(`claude`)} ${i(e.agents.claude)}`,`${n.dim(`approvals`)} timeout=${e.approvals.escalationTimeoutMs}ms hosts=[${e.approvals.allowedNetworkHosts.join(`, `)}]`,`${n.dim(`file`)} ${R()}`].join(`
27
+ `)+`
28
+ `);return}if(i===`get`){a||A(`Usage: coder config get <key> (e.g. chain, agents.codex.model)`);let e=ht(P(r),a);if(t.json||e===null||typeof e==`object`&&e!==void 0){U(e===void 0?null:e);return}K.stdout.write(`${e===void 0?`(unset)`:String(e)}\n`);return}i!==`set`&&i!==`unset`&&A(`Usage: coder config [get|set|unset] <key> [value] [--workspace]`),(!a||i===`set`&&o.length===0)&&A(`Usage: coder config ${i} <key>${i===`set`?` <value>`:``}`);let c=o.join(` `),l;try{l=JSON.parse(c)}catch{l=c.includes(`,`)?c.split(`,`).map(e=>e.trim()).filter(Boolean):c}let u;try{({effective:u}=vt(r,a,l,{workspace:t.workspace,unset:i===`unset`}))}catch(e){A(e instanceof Error?e.message:String(e))}if(t.json){U({file:s,key:a,...i===`set`?{value:l}:{unset:!0},effective:u});return}let d=E,f=i===`set`?`${d.cyan(a)} = ${JSON.stringify(l)}`:`unset ${d.cyan(a)}`;K.stdout.write(`${f} ${d.dim(`(${s})`)}\n`)}async function bt(e,t={}){let n=G(e),r=le(n);r?.updated&&(n=G(e));let i=n.available?await _e(e):{loggedIn:!1,detail:n.detail},a=ie(),o=a.available?Pe():{loggedIn:!1,detail:a.detail},s=R();if(!q.existsSync(s)){let e=n.available?[`codex`,`claude`]:a.available?[`claude`,`codex`]:[`codex`,`claude`];Te({...Me,chain:e})}let c=h(),l=t.claude?te(c):null,u=t.agents||t.codex?pe(c):null,d=P(e),f=n.available&&i.loggedIn||a.available&&o.loggedIn;return{codex:{available:n.available,detail:n.detail,auth:i.detail,loggedIn:i.loggedIn},...r?{codexUpdate:r}:{},claude:{available:a.available,detail:a.detail,auth:o.detail,loggedIn:o.loggedIn},configFile:s,runtime:He(new URL(`../bin/coder.mjs`,import.meta.url)),...l?{claudePlugin:l}:{},...u?{agentsSkill:u}:{},config:d,ready:f}}async function xt(e){let{options:t,positionals:n}=v(e,Y.object({...b,codex:S,claude:S,agents:S})),r=M(t),i=[`claude`,`codex`,`agents`];for(let e of n)i.includes(e)||A(`Unknown host "${e}". Use claude, codex, or agents.`,{hint:`Codex, Pi, OpenCode, and other Agent Skills hosts: coder setup-host agents`}),t[e]=!0;let a=E.bold,o=E.dim;t.json||K.stdout.write(`${a(`Coder host setup`)}\n\n`);let s=await bt(r,{claude:t.claude,codex:t.codex,agents:t.agents});if(t.json){U(s);return}let{codex:c,claude:l,codexUpdate:u,config:d,configFile:f,claudePlugin:p,agentsSkill:m,ready:h}=s,g=[],_=c.available?c.loggedIn?j(`codex ${o(`${c.detail}; ${c.auth}`)}`):O(`codex not logged in ${o(`(${c.auth})`)} - run: codex login`):O(`codex CLI not installed - run: npm install -g @openai/codex`),y=l.available?l.loggedIn?j(`claude ${o(`${l.detail}; ${l.auth}`)}`):O(`claude not logged in - run: claude auth login`):O(`claude CLI not installed - run: npm install -g @anthropic-ai/claude-code`);g.push(a(`Available Engines`),_,y,` ${o(`custom models (local/provider endpoints): coder model --help`)}`),u?.updated?g.push(j(`codex ${o(`updated ${u.from} -> ${c.detail} (GPT-5.6 support)`)}`)):u&&g.push(O(`codex ${u.note}`)),g.push(``);let x=e=>{let t=d.agents?.[e]??{};return[t.model,t.effort,t.permissions].filter(Boolean).join(`/`)};g.push(a(`Config`),` chain: ${(d.chain??[]).join(` -> `)} codex: ${x(`codex`)} claude: ${x(`claude`)}`,` ${o(f)} ${o(`(coder config set <key> <value> to change)`)}`,``);let C=[[`claude plugin`,p??null],[`agents skill `,m??null]];for(let[e,t]of C)t&&g.push(t.installed?j(`${e} ${o(t.note)}`):O(`${e} ${t.note}`),``);g.push(h?j(`ready - try: coder run --wait "explain this repo's layout"`):O(`not ready - install an engine CLI to run tasks: codex (npm install -g @openai/codex, then codex login) or claude (npm install -g @anthropic-ai/claude-code, then claude auth login)`)),K.stdout.write(`${g.join(`
29
+ `)}\n`)}const St=new Set([`codex`,`claude`,`custom`]);async function Ct(e){let t=e.envKey?K.env[e.envKey]:void 0,n=I(e.baseUrl,`models`),r=null;for(let i of n)try{let n=await fetch(i,{headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(5e3)});if(!n.ok){r=n.status===404?{reachable:!0,modelListed:null,detail:`endpoint reachable (no model list to verify against)`}:{reachable:!1,modelListed:null,detail:`${i} -> HTTP ${n.status}`};continue}let a=await n.json().catch(()=>null),o=Array.isArray(a?.data)?a.data.map(e=>e.id):null;if(!o)return{reachable:!0,modelListed:null,detail:`endpoint reachable`};let s=o.includes(e.model);return{reachable:!0,modelListed:s,detail:s?`endpoint reachable; model "${e.model}" listed`:`endpoint reachable, but "${e.model}" is not in its model list`}}catch(e){r={reachable:!1,modelListed:null,detail:`${i} unreachable (${e instanceof Error?e.message:String(e)})`}}return r}function wt(e,t){let n=q.existsSync(e)?JSON.parse(q.readFileSync(e,`utf8`)):{};t(n),n.models&&Object.keys(n.models).length===0&&delete n.models;let r=Ee(n);r.length&&A(`Refusing to write invalid config:\n ${r.join(`
30
+ `)}`),q.mkdirSync(J.dirname(e),{recursive:!0}),q.writeFileSync(e,`${JSON.stringify(n,null,2)}\n`,`utf8`)}function Z(e,t){wt(e,e=>{e.models=e.models??{},t(e.models)})}const Q=Y.object({...b,"base-url":C,model:C,"env-key":C,workspace:S});function $(e,t){return e.workspace?J.join(a(t),`coder.config.json`):R()}function Tt(e){let t=e.models??{},n=Object.entries(t).filter(e=>H(e[1])),r=e=>`${e.provider}:${e.model}${e.effort?`:${e.effort}`:``}`,i=Object.entries(t).filter(e=>N(e[1])).map(([e,t])=>{let n=t.provider===`claude`?k:W,i=n[t.model]??t.model,a=z(e)?e:Object.entries(n).find(([,e])=>e===i)?.[0];return{name:e,spec:r(t),replaces:a,disabled:!!t.disabled}}),a=new Map;for(let e of i)e.replaces&&(e.name===e.replaces||!a.has(e.replaces))&&a.get(e.replaces)?.name!==e.replaces&&a.set(e.replaces,e);let o=e=>!!t[e]?.disabled,s=i.filter(e=>![...a.values()].some(t=>t.name===e.name));return{models:t,endpoints:n,providerRows:(e,t)=>[...Object.entries(t).map(([e,t])=>{let n=a.get(e);return n?{alias:n.name,spec:n.spec,overrides:e,disabled:n.disabled}:{alias:e,model:t,builtin:!0,disabled:o(e)}}),...s.filter(t=>t.spec.startsWith(`${e}:`)).map(({name:e,spec:t,disabled:n})=>({alias:e,spec:t,disabled:n}))],toggledSlugs:Object.entries(t).filter(([e,t])=>!H(t)&&!N(t)&&!z(e)).map(([e,t])=>({name:e,disabled:!!t.disabled})),disabled:o}}async function Et(e){let{endpoints:t,providerRows:n,toggledSlugs:r}=Tt(P(e)),i=await Promise.all(t.map(async([e,t])=>({name:e,...t,probe:await Ct(t)})));return{codex:n(`codex`,W),claude:n(`claude`,k),custom:i,...r.length?{toggles:r}:{}}}async function Dt(e){let{options:t,positionals:n}=v(e,Q);n.length&&A(`model list takes no arguments.`,{hint:`Usage: coder model list [--json]`});let r=M(t),i=E,{endpoints:a,providerRows:o,toggledSlugs:s,disabled:c}=Tt(P(r));if(t.json){U(await Et(r));return}let l=e=>c(e)?i.dim(`∅`):i.green(`✔`),u=e=>c(e)?` ${i.dim(`(disabled)`)}`:``,d=[],f=(e,t,n)=>{d.push(i.bold(e));for(let e of o(t,n))`overrides`in e?d.push(` ${e.disabled?i.dim(`∅`):i.cyan(`↳`)} ${e.alias.padEnd(14)} ${i.dim(`-> ${e.spec} (overrides ${e.overrides})`)}${e.disabled?` ${i.dim(`(disabled)`)}`:``}`):`builtin`in e?d.push(` ${l(e.alias)} ${e.alias.padEnd(14)} ${i.dim(`-> ${e.model}`)}${u(e.alias)}`):d.push(` ${e.disabled?i.dim(`∅`):i.cyan(`↳`)} ${e.alias.padEnd(14)} ${i.dim(`-> ${e.spec}`)}${e.disabled?` ${i.dim(`(disabled)`)}`:``}`);d.push(``)};if(f(`Codex models`,`codex`,W),f(`Claude models`,`claude`,k),d.push(i.bold(`Custom models`),``),!a.length)d.push(i.dim(` none — coder model add <name> --base-url <url> --model <id> [--env-key VAR]`));else for(let[e,t]of a){let n=await Ct(t),r=t.disabled?i.dim(`∅`):n.reachable?i.green(`✔`):i.red(`✘`);d.push(` ${r} ${e.padEnd(14)} ${t.model} ${i.dim(`@ ${t.baseUrl} — ${n.detail}`)}${u(e)}`)}if(d.push(``),s.length){d.push(i.bold(`Other`),``);for(let e of s)d.push(` ${e.disabled?i.dim(`∅`):i.green(`✔`)} ${e.name.padEnd(14)} ${i.dim(`raw model id`)}${e.disabled?` ${i.dim(`(disabled)`)}`:``}`);d.push(``)}d.push(i.dim(`Alias one: coder model alias <name> <spec> (e.g. fast codex:spark)`),i.dim(`Use one: coder run --model <name> "<task>" (or coder run --agent custom)`)),K.stdout.write(`${d.join(`
31
+ `)}\n`)}async function Ot(e,t,n,r){let i=await Ze(t),a=i?.wireApi===`responses`;i?(t.wireApi=i.wireApi,t.baseUrl=i.baseUrl??t.baseUrl):delete t.wireApi,Z(n,n=>{n[e]=t});let o=await Ct(t),s=re(G(r)),c=G(r);return{name:e,entry:t,file:n,probe:o,codex:c,install:s,nativeResponses:a,keyMissing:!!(t.envKey&&!K.env[t.envKey]),ready:o.reachable&&c.available}}async function kt(e,t,n,r,i){let a=$(n,r),o=E,{probe:s,codex:c,install:l,nativeResponses:u,keyMissing:d}=await Ot(e,t,a,r);if(n.json){U({name:e,...t,file:a,probe:s,codex:c,...l?{codexInstall:l}:{},ready:s.reachable&&c.available});return}let f=e=>` ${o.green(`✔`)} ${e}`,p=e=>` ${o.red(`✘`)} ${e}`,m=[`${i} ${o.cyan(e)} -> ${t.model} @ ${t.baseUrl} ${o.dim(`(${a})`)}`,``,s.reachable?f(`${s.detail} ${o.dim(`(${u?`responses api, direct`:`chat api, auto-translated`})`)}`):p(s.detail),c.available?f(l?.installed?`${l.note} ${o.dim(`(${c.detail})`)}`:`codex engine ${o.dim(`(${c.detail})`)}`):p(l?.note??`codex CLI not installed - run: npm install -g @openai/codex`)];d&&m.push(p(`env var ${t.envKey} is not set in this shell`)),m.push(``,o.dim([`Use it: coder run --model ${e} "<task>"`,`Make default: coder config set agents.custom.model ${e}`].join(`
32
+ `))),K.stdout.write(`${m.join(`
33
+ `)}\n`)}function At(e,t,n){return e||A(`Missing model name.`,{hint:t}),/^[a-z][a-z0-9-]*$/.test(e)||A(`Invalid model name "${e}". Use lowercase kebab-case (e.g. qwen-local).`),(St.has(e)||n===`model`&&z(e))&&A(`"${e}" is reserved; pick another name.`),e}async function jt(e){let t=`Usage: coder model add <name> --base-url <url> --model <id> [--env-key VAR]`,{options:n,positionals:r}=v(e,Q),i=M(n),a=At(r[0],t,`model`),o=P(i).models?.[a];o&&A(H(o)?`Custom model "${a}" already exists.`:`"${a}" is already configured as an ${N(o)?`alias`:`entry`}; remove it first.`,{hint:`Change it: coder model update ${a} [--base-url|--model|--env-key], or remove it first.`}),(!n[`base-url`]||!n.model)&&A(`Missing --base-url or --model.`,{hint:t}),await kt(a,{baseUrl:L(n[`base-url`]),model:n.model,...n[`env-key`]?{envKey:n[`env-key`]}:{}},n,i,`saved`)}async function Mt(e){let t=`Usage: coder model update <name> [--base-url <url>] [--model <id>] [--env-key VAR]`,{options:n,positionals:r}=v(e,Q),i=M(n),a=r[0],o=a?P(i).models?.[a]:void 0,s=o&&H(o)?o:void 0;(!a||!s)&&A(a?`No custom model named "${a}".`:`Missing model name.`,{hint:a?`List them: coder model list`:t}),!n[`base-url`]&&!n.model&&!n[`env-key`]&&A(`Nothing to update: pass --base-url, --model, or --env-key.`,{hint:t}),await kt(a,{...s,...n[`base-url`]?{baseUrl:L(n[`base-url`])}:{},...n.model?{model:n.model}:{},...n[`env-key`]?{envKey:n[`env-key`]}:{}},n,i,`updated`)}async function Nt(e){let{options:t,positionals:n}=v(e,Q),r=M(t),i=n[0],a;try{a=Ht(r,i??``,{workspace:t.workspace})}catch(e){A(e instanceof Error?e.message:String(e),{hint:i?`List them: coder model list`:`Usage: coder model remove <name>`})}if(t.json){U(a);return}K.stdout.write(`removed ${E.cyan(a.removed)} ${E.dim(`(${a.file})`)}\n`)}async function Pt(e){await It(e,!0)}async function Ft(e){await It(e,!1)}async function It(e,t){let n=t?`disable`:`enable`,r=`Usage: coder model ${n} <name>`,{options:i,positionals:a}=v(e,Q),o=M(i),s=a[0];s||A(`Missing model name.`,{hint:r});let{file:c}=Gt(o,s,t,{workspace:i.workspace});if(i.json){U({[t?`disabled`:`enabled`]:s,file:c});return}K.stdout.write(`${n}d ${E.cyan(s)} ${E.dim(`(${c})`)}\n`)}async function Lt(e){let t=`Usage: coder model alias <name> <spec> (e.g. coder model alias fast codex:spark)`,{options:n,positionals:r}=v(e,Q),i=M(n),a=At(r[0],t,`alias`),o=P(i).models?.[a];o&&H(o)&&A(`"${a}" is a custom model name; pick another alias name.`);let s=r[1];s||A(`Missing alias spec.`,{hint:t});let c;try{c=Ut(i,a,s,{workspace:n.workspace})}catch(e){let n=e instanceof Error?e.message:String(e);A(n,n.includes(`already dispatchable by name`)?{}:{hint:t})}if(n.json){U(c);return}let l=E,u=`${c.provider} ${c.model}${c.effort?` (${c.effort})`:``}`;K.stdout.write(`aliased ${l.cyan(a)} -> ${c.provider}:${c.model}${c.effort?`:${c.effort}`:``} ${l.dim(`= ${u}`)} ${l.dim(`(${c.file})`)}\n`)}async function Rt(e){let{options:t,positionals:n}=v(e,Q),r=M(t),i=n[0],a=i?P(r).models?.[i]:void 0;(!i||!a||!N(a))&&A(i?`No alias named "${i}".`:`Missing alias name.`,{hint:i?`List them: coder model list`:`Usage: coder model unalias <name>`});let{file:o}=Wt(r,i,{workspace:t.workspace});if(t.json){U({unaliased:i,file:o});return}K.stdout.write(`unaliased ${E.cyan(i)} ${E.dim(`(${o})`)}\n`)}function zt(e,t){if(!e)throw Error(`Missing model name.`);if(!/^[a-z][a-z0-9-]*$/.test(e))throw Error(`Invalid model name "${e}". Use lowercase kebab-case (e.g. qwen-local).`);if(St.has(e)||t===`model`&&z(e))throw Error(`"${e}" is reserved; pick another name.`)}async function Bt(e,t,n){if(zt(t,`model`),P(e).models?.[t])throw Error(`Custom model "${t}" already exists.`);if(!n.baseUrl||!n.model)throw Error(`Missing baseUrl or model.`);return Ot(t,{baseUrl:L(n.baseUrl),model:n.model,...n.envKey?{envKey:n.envKey}:{}},$({workspace:n.workspace},e),e)}async function Vt(e,t,n){let r=P(e).models?.[t],i=r&&H(r)?r:void 0;if(!i)throw Error(`No custom model named "${t}".`);if(!n.baseUrl&&!n.model&&!n.envKey)throw Error(`Nothing to update: pass baseUrl, model, or envKey.`);return Ot(t,{...i,...n.baseUrl?{baseUrl:L(n.baseUrl)}:{},...n.model?{model:n.model}:{},...n.envKey?{envKey:n.envKey}:{}},$({workspace:n.workspace},e),e)}function Ht(e,t,n={}){if(!t||!P(e).models?.[t])throw Error(t?`No custom model named "${t}".`:`Missing model name.`);let r=$({workspace:n.workspace},e);return Z(r,e=>{delete e[t]}),{removed:t,file:r}}function Ut(e,t,n,r={}){zt(t,`alias`);let i=P(e),a=i.models?.[t];if(a&&H(a))throw Error(`"${t}" is a custom model name; pick another alias name.`);if(!n)throw Error(`Missing alias spec.`);let o=Ie(n,i);if(!o||!o.model)throw Error(`Alias spec "${n}" does not resolve to a model.`);if(o.agent===`custom`)throw Error(`"${n}" names a custom model, which is already dispatchable by name; aliases target codex/claude models.`);let s=n.split(`:`).some(e=>Se.has(e.trim())||ge.has(e.trim())),c=o.agent===`claude`?k:W,l={provider:o.agent,model:c[o.model]??o.model,...s&&o.effort?{effort:o.effort}:{}},u=$({workspace:r.workspace},e);return Z(u,e=>{e[t]=l}),{alias:t,...l,file:u}}function Wt(e,t,n={}){let r=t?P(e).models?.[t]:void 0;if(!t||!r||!N(r))throw Error(t?`No alias named "${t}".`:`Missing alias name.`);let i=$({workspace:n.workspace},e);return Z(i,e=>{delete e[t]}),{unaliased:t,file:i}}function Gt(e,t,n,r={}){if(!t)throw Error(`Missing model name.`);let i=!!P(e).models?.[t],a=$({workspace:r.workspace},e);return Z(a,e=>{let r=e[t];if(!r){n?e[t]={disabled:!0}:i&&(e[t]={disabled:!1});return}H(r)||N(r)?n?r.disabled=!0:delete r.disabled:n?r.disabled=!0:delete e[t]}),{name:t,disabled:n,file:a}}const Kt={list:Dt,add:jt,setup:jt,update:Mt,remove:Nt,disable:Pt,enable:Ft,alias:Lt,unalias:Rt};async function qt(e){let[t,...n]=e;if(t===void 0||t.startsWith(`-`)){await Dt(e);return}let r=Kt[t];r||A(`Unknown model subcommand "${t}". Use list, add, update, remove, disable, enable, alias, or unalias.`,{hint:`Help: coder model --help`}),await r(n)}const Jt=[{name:`readme`,file:`README.md`,description:`What Coder is and how to get started.`},{name:`skill`,file:`plugins/agents/skills/coder/SKILL.md`,description:`How a host agent should drive Coder.`}];function Yt(e){let t=J.join(e,`docs`),n=[];try{n=q.readdirSync(t).filter(e=>e.endsWith(`.md`)).sort()}catch{n=[]}let r=n.map(t=>{let n=J.join(`docs`,t);return{name:J.basename(t,`.md`),file:n,description:Xt(J.join(e,n))}}),i=Jt.map(e=>({name:e.name,file:e.file,description:e.description}));return[...r,...i]}function Xt(e){let t=``;try{t=q.readFileSync(e,`utf8`)}catch{return``}let n=t.split(`
34
+ `),r=``,i=``,a=!1;for(let e of n){let t=e.trim();if(t.startsWith("```")){a=!a;continue}if(!(a||t===``)){if(t.startsWith(`#`)){r||=t.replace(/^#+\s*/,``);continue}i=t;break}}return Zt(i)||r}function Zt(e){if(!e)return``;let t=e.match(/^.*?[.!?](?=\s|$)/);return(t?t[0]:e).trim()}function Qt(e,t={}){let n=h(),r=Yt(n);if(!e)return{topics:r.map(e=>({name:e.name,description:e.description}))};let i=r.find(t=>t.name===e.toLowerCase());if(i?.name===`skill`&&t.claude&&(i={...i,file:`plugins/claude/skills/dispatch/SKILL.md`}),!i)throw Error(`Unknown docs topic "${e}". Available: ${r.map(e=>e.name).join(`, `)}`);let a=J.join(n,i.file),o;try{o=q.readFileSync(a,`utf8`)}catch{throw Error(`Could not read docs for "${i.name}" (${i.file}).`)}return{name:i.name,content:o}}async function $t(e){let{options:t,positionals:n}=v(e,Y.object({json:S,claude:S})),[r]=n,i;try{i=Qt(r,{claude:t.claude})}catch(e){let t=e instanceof Error?e.message:String(e);return A(t,t.startsWith(`Unknown docs topic`)?{hint:`List topics: coder docs`}:{})}if(`content`in i){K.stdout.write(i.content.endsWith(`
35
+ `)?i.content:`${i.content}\n`);return}if(t.json){U(i);return}let a=E,o=Math.max(0,...i.topics.map(e=>e.name.length)),s=i.topics.map(e=>` ${a.cyan(e.name.padEnd(o))} ${a.dim(e.description)}`);K.stdout.write([a.bold(`Docs:`),...s,``,B([`Read a topic: coder docs <topic>`],a)].join(`
36
+ `)+`
37
+ `)}async function en(e={},t){let n=!e.pluginsOnly,r=!e.cliOnly,i=h(),a=J.join(i,`plugins/claude/.claude-plugin/plugin.json`),o={cli:y(),claude:x(a)},s={};if(n){let n=ce(m),[r,...i]=e.pm===`npm`?[`npm`,`install`,`-g`,`@wular/coder@latest`]:e.pm===`pnpm`?[`pnpm`,`add`,`-g`,`@wular/coder@latest`]:e.pm===`yarn`?[`yarn`,`global`,`add`,`@wular/coder@latest`]:e.pm===`bun`?[`bun`,`add`,`-g`,`@wular/coder@latest`]:n.command,a=e.pm??n.pm;t?.(`via ${a}`);let c=Be(r,i,{encoding:`utf8`});if(c.error?.code===`ENOENT`)throw Error(`${a} not found on PATH. Re-run with --pm <npm|pnpm|yarn|bun>, or update manually: ${r} ${i.join(` `)}`);if(c.status!==0){let e=(c.stderr||c.stdout||``).trim();throw Error(`CLI update failed (${a}).${e?`\n${e}`:``}\nRun manually: ${r} ${i.join(` `)}`)}se();let l=y();s.cli={pm:a,from:o.cli,to:l,changed:l!==o.cli}}if(r){if(e.claude||!e.codex&&ie().available){let e=te(i);s.claudePlugin={installed:e.installed,note:e.note,from:o.claude,to:x(a)}}if(q.existsSync(de())){let e=ae(),t=pe(i);s.agentsSkill={installed:t.installed,note:t.note,from:e,to:ae()}}}return s}async function tn(e){let{options:t}=v(e,Y.object({pm:C,"cli-only":S,"plugins-only":S,codex:S,claude:S})),n=E.bold,r=E.dim,i=(e,t)=>t&&e&&t!==e?`${e} ${r(`->`)} ${n(t)}`:`${t??e??`?`} ${r(`(unchanged)`)}`,a;try{a=await en({cliOnly:t[`cli-only`],pluginsOnly:t[`plugins-only`],pm:t.pm,codex:t.codex,claude:t.claude},e=>K.stdout.write(`${n(`Updating coder CLI`)} ${r(`${e}...`)}\n`))}catch(e){A(e instanceof Error?e.message:String(e))}if(a.cli&&K.stdout.write(a.cli.changed?`${j(`coder CLI ${i(a.cli.from,a.cli.to)}`)}\n`:`${j(`coder CLI ${a.cli.from} ${r(`(already latest)`)}`)}\n`),a.claudePlugin){let e=a.claudePlugin;K.stdout.write(`${e.installed?j(`claude plugin ${i(e.from,e.to)} ${r(`- ${e.note}`)}`):O(`claude plugin ${e.note}`)}\n`)}if(a.agentsSkill){let e=a.agentsSkill;K.stdout.write(`${e.installed?j(`agents skill ${i(e.from,e.to)} ${r(`- ${e.note}`)}`):O(`agents skill ${e.note}`)}\n`)}}export{lt as C,Qe as D,$e as E,Ze as O,ct as S,tt as T,vt as _,qt as a,ut as b,Et as c,Wt as d,Vt as f,_t as g,yt as h,Qt as i,Ye as k,Ht as l,bt as m,en as n,Bt as o,xt as p,$t as r,Ut as s,tn as t,Gt as u,mt as v,rt as w,dt as x,X as y};
package/docs/sdk.md CHANGED
@@ -63,11 +63,13 @@ const results = await Promise.all(
63
63
  );
64
64
  ```
65
65
 
66
- Follow a task live:
66
+ Follow a task live. Every event carries a `kind` — `assistant`, `reasoning`,
67
+ `tool`, `tool-result`, `usage`, `status`, `steer`, `error` — plus the fields
68
+ that kind implies (`tool`, `exitCode`, `durationMs`, `tokens`):
67
69
 
68
70
  ```ts
69
71
  for await (const event of task.stream(taskId)) {
70
- console.log(event.kind, event.text);
72
+ if (event.kind === 'assistant') console.log(event.message);
71
73
  }
72
74
  ```
73
75
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wular/coder",
3
- "version": "0.3.15",
3
+ "version": "0.3.16",
4
4
  "description": "Delegating coding-agent runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/sdk.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coder",
3
- "version": "0.3.15",
3
+ "version": "0.3.16",
4
4
  "description": "Delegate coding tasks to supervised Coder subagents running on Codex, Claude, or any OpenAI-compatible model. Your main context stays clean.",
5
5
  "author": {
6
6
  "name": "muzam1l"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "coder",
3
3
  "displayName": "Coder",
4
- "version": "0.3.15",
4
+ "version": "0.3.16",
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"