@wular/coder 0.3.14 → 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.
@@ -1,36 +0,0 @@
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,Bt as O,Dt as ee,G as te,Gt as ne,H as re,Ht as k,J as ie,K as ae,Kt as A,Mt as oe,Nt as se,Q as j,U as ce,Ut as le,V as ue,Vt as de,W as fe,Wt as pe,X as me,Xt as M,Y as he,Yt as ge,Z as _e,Zt as ve,_t as ye,an as N,at as P,bt as be,ct as F,en as xe,et as Se,ft as Ce,g as we,gt as Te,ht as Ee,in as I,it 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,rn as B,st as V,tn as H,tt as U,ut as Fe,vt as W,yt as Ie,z as Le,zt as Re}from"./runtime-9CD0_h4s.js";import G from"node:process";import K from"node:fs";import q from"node:path";import{spawnSync as ze}from"node:child_process";import Be from"node:os";import{fileURLToPath as Ve}from"node:url";import*as J from"zod/mini";import He from"node:crypto";import Ue from"node:http";let We=0;function Ge(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 Ke(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:Ge(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 qe=class{send;model;responseId=`resp_bridge_${++We}`;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 Je(e,t=`chat`){let n=t===`responses`,r=De(e.baseUrl,n?`responses`:`chat/completions`),i=null,a=e.envKey?G.env[e.envKey]:void 0;async function o(e){let t=i?[i]:r,n=null;for(let r of t)if(n=await fetch(r,{method:`POST`,headers:{"content-type":`application/json`,...a?{authorization:`Bearer ${a}`}:{}},body:e}),n.status!==404)return i=r,n;return n}let s=He.randomBytes(16).toString(`hex`),c=Ue.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(Ke(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 qe(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 Ye(e,t,n){let r=e.envKey?G.env[e.envKey]:void 0,i=!1;for(let a of De(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 Xe(e){let t=await Ye(e,`responses`,{model:e.model,input:[],stream:!1});if(`baseUrl`in t)return{wireApi:`responses`,baseUrl:t.baseUrl};let n=await Ye(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*Ze(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(q.join(i(e,t),`log.jsonl`)),l=!0,u=()=>{let e=c();return l&&(l=!1,o!==`all`&&(e=o===0?[]:e.slice(-o))),e.map(e=>{try{return JSON.parse(e)}catch{return{message:e}}})};for(yield*u();!r.has(a.status);)await new Promise(e=>setTimeout(e,400)),a=s(e,g(e,t)??a),yield*u();yield*u()}async function Qe(e){let{options:t,positionals:n}=v(e,J.object({...b,tail:p,trim:J.optional(J.union([J.literal(`none`),J.coerce.number().check(J.int(),J.positive())],{error:`expected a positive integer or "none"`}))}));B(n,1,`task watch`);let r=N(t),a=I(r,n[0]),o=t.tail,c=t.trim,l=c===void 0?300:c===`none`?2**53-1:c;if(!t.json){G.stdout.write(`${E.dim(`[coder] task ${a.id} ${a.status} — watching (Ctrl-C to stop)`)}\n`);let e=[`${E.dim(`agent`.padEnd(8))} ${ne(a)}`,...ve(a,E)];G.stdout.write(`${e.join(`
3
- `)}\n`),a.prompt&&G.stdout.write(`${je(a.prompt,E,{truncate:!1}).join(`
4
- `)}\n`)}for await(let e of Ze(r,a.id,{tail:o})){let n=e.kind===`steer`?2**53-1:l;if(t.json){let t=e.message?{...e,message:Ae(e.message,n,{plain:!0})}:e;G.stdout.write(`${JSON.stringify(t)}\n`)}else{let t=e.message??e.kind;t&&G.stdout.write(`${E.dim(`[coder]`)} ${Ae(t,n)}\n`)}}let u=s(r,g(r,a.id)??a),d=D(q.join(i(r,a.id),`result.json`));if(t.json)H({taskId:a.id,status:u.status,result:d});else{let e=u.status===`completed`?`(no final message)`:`(task ${u.status})`;G.stdout.write(`\n${le(d,u.error,e)}\n`);let t=d?.tokens?` tokens=${ge(d.tokens,d.model??u.model)}`:``;G.stderr.write(`${E.dim(`[coder] task=${a.id} status=${u.status}${t}`)}\n`)}G.exit(u.status===`completed`?0:1)}async function $e(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??be)(e,{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 et(e,t,n,r={},i={}){if(!t.threadId)throw Error(`Task ${t.id} has no thread to steer yet (status: ${t.status}).`);return await $e(e,t,n,i)||(tt(e,t,n,r),{taskId:t.id,steered:`resumed`})}function tt(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}`}),Le(n.cwd??t,n.id)}async function nt(e){let{options:t,positionals:n}=v(e,J.object({...b,model:C,effort:C,permissions:C,background:S,wait:S})),r=N(t),[i,...a]=n,o=a.join(` `).trim();(!i||!o)&&k(`Missing task id or follow-up text.`,{hint:[`Usage: coder task steer <task-id> "<follow-up>" [--wait]`,`Help: coder task steer --help`]});let s=I(r,i);s.threadId||k(`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 et(r,s,o,{model:t.model,effort:t.effort,permissions:t.permissions});return rt(r,c.taskId,{steered:c.steered,options:t})}async function rt(e,t,{steered:n,options:r}){if(n===`queued`){if(r.json){H({taskId:t,steered:`queued`});return}G.stdout.write(`${E.dim(`[coder]`)} follow-up queued for task ${E.cyan(t)}; it runs when the current turn finishes.\n`),r.wait&&G.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){H({taskId:t,steered:n});return}G.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`),G.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(q.join(i(e,t),`result.json`));r.json?H({taskId:t,status:o?.status??null,finalMessage:s?.finalMessage??null}):(G.stdout.write(`\n${s?.finalMessage||`(no final message)`}\n\n`),G.stderr.write(`${E.dim(`[coder] task=${t} status=${o?.status??`unknown`}`)}\n`)),G.exitCode=o?.status===`completed`?0:1}const it=[`Read`,`Glob`,`Grep`];function at(e,t,n){return`You are a read-only sidecar answering a question ABOUT a coder task.
5
- 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.
6
-
7
- Task metadata:
8
- ${[`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(`
9
- `)}
10
-
11
- Task prompt:
12
- ${e.prompt??`(unknown)`}
13
-
14
- Inspect as needed (grep/read selectively; events can be large):
15
- - progress log (jsonl, one event per line): ${q.join(t,`log.jsonl`)}
16
- - final result: ${q.join(t,`result.json`)}
17
- - worker output: ${q.join(t,`worker.log`)}
18
- ${e.cwd?`- the task's workspace (its code and changes): ${e.cwd}`:``}
19
-
20
- Question: ${n}
21
-
22
- Answer the question directly and concisely.`}function ot(e,t,n,r){return{prompt:n,model:r.model??e.model,effort:r.effort,permissions:`read-only`,additionalDirectories:[t],readOnlyAllowedTools:it}}async function st(e,t,n,r={}){let a=i(e,t.id),o=at(t,a,n),s=r.effort??t.effort??null;if(t.engine===`claude`)return he(t.cwd??e,ot(t,a,o,{model:r.model,effort:s}));let c=F(e),l=r.model??t.model,u=l?c.models?.[l]:void 0,d=u&&V(u)?u:void 0;if(d?.envKey&&!G.env[d.envKey])throw Error(`Missing environment variable: \`${d.envKey}\`.`);let f=d?await Je(d,d.wireApi??`chat`):null,p=Ne(c,l,f??void 0);try{return await Ie(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 ct(e){let{options:t,positionals:n}=v(e,J.object({...b,model:C,effort:C})),r=N(t),[i,...a]=n,o=a.join(` `).trim();(!i||!o)&&k(`Missing task id or question.`,{hint:[`Usage: coder task ask <task-id> "<question>"`,`Help: coder task ask --help`]});let s=I(r,i);t.json||G.stderr.write(`${E.dim(`[coder]`)} asking about task ${E.cyan(s.id)} (read-only sidecar; the task is not interrupted)...\n`);let c=await st(r,s,o,{model:t.model,effort:t.effort}),l=c.finalMessage||``;if(t.json)H({taskId:s.id,answer:l||null,...c.error?{error:c.error.message}:{}});else if(l)G.stdout.write(`\n${l}\n`);else{let e=c.error?.message?` ${E.red(c.error.message)}`:``;G.stdout.write(`${E.dim(`(no answer)`)}${e}\n`)}G.exitCode=c.status===0?0:1}function lt(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 Re(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(q.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 ut(e){let{options:r,positionals:a}=v(e,J.object({cwd:C,dir:C,limit:f,json:S,running:S,stopped:S,archived:S}));B(a,0,`task list`);let o=N(r),s=r.limit===`all`?void 0:r.limit,{jobs:c,clipped:l}=lt(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)?Re(n(o,e)):null}});if(r.json){H(d);return}if(!d.length){let e=r.archived?`archived tasks`:r.running?`running tasks`:r.stopped?`recently stopped tasks`:`recent tasks`;G.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&&G.stdout.write(`\n${A(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?q.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 ${pe(e.idleMs)}`)}`:``;G.stdout.write(`${p.cyan(e.taskId.padEnd(_.id))} ${xe(e.status,_.status)} ${p.light(de(m(e),_.who))} ${p.light(de(h(e),_.cwd))} ${n}${r}${t}\n`)};G.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&&G.stdout.write(`
23
- `),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)`;G.stdout.write(`${w?`
24
- `:``}${n}\n`);for(let t of b.get(e.flowRunId))y(t);w=!0,T=!0}l&&G.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]`),G.stdout.write(`\n${A(D,p)}\n`)}function dt(){let e=process.env.CLAUDE_CONFIG_DIR||q.join(Be.homedir(),`.claude`);return q.join(e,`projects`)}function ft(e){if(!e)return!1;let t=dt(),n=!1;try{for(let r of K.readdirSync(t)){let i=q.join(t,r,`${e}.jsonl`);K.existsSync(i)&&(K.rmSync(i,{force:!0}),n=!0)}}catch{}return n}function Y(e){e.threadId&&(e.engine===`codex`?l(e.threadId):e.engine===`claude`&&ft(e.threadId))}async function pt(e){let{options:n,positionals:r}=v(e,J.object({...b,"all-archived":S}));B(r,1,`task delete`);let i=N(n);if(n[`all-archived`]){let e=t(i).filter(e=>(Y(e),w(i,e.id))).map(e=>e.id);if(n.json){H({deleted:e,count:e.length});return}G.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||k(`Missing task id.`,{hint:[`Delete one: coder task delete <task-id>`,`Delete all archived: coder task delete --all-archived`]});let o=I(i,a);if(o.status===`running`&&k(`Task ${o.id} is still running.`,{hint:`Stop it first: coder task stop ${o.id}`}),Y(o),w(i,o.id),n.json){H({taskId:o.id,deleted:!0});return}G.stdout.write(`Deleted task ${E.cyan(o.id)}.\n`)}function X(e,t){return t.split(`.`).reduce((e,t)=>e?.[t],e)}function mt(e,t){return t?q.join(a(e),`coder.config.json`):R()}function ht(e,t){let n=F(e);return t?X(n,t):n}function gt(e,t,n,r={}){let i=mt(e,r.workspace),a=K.existsSync(i)?JSON.parse(K.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(`
25
- `)}`);return K.mkdirSync(q.dirname(i),{recursive:!0}),K.writeFileSync(i,`${JSON.stringify(a,null,2)}\n`,`utf8`),{file:i,key:t,effective:X(F(e),t)??null,...r.unset?{unset:!0}:{value:n}}}async function _t(e){let{options:t,positionals:n}=v(e,J.object({...b,workspace:S})),r=N(t),[i=`list`,a,...o]=n,s=mt(r,t.workspace);if(i===`list`){let e=F(r);if(t.json){H(e);return}let n=E,i=e=>[e?.model,e?.effort,e?.permissions].filter(Boolean).join(`/`)||`-`;G.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(`
26
- `)+`
27
- `);return}if(i===`get`){a||k(`Usage: coder config get <key> (e.g. chain, agents.codex.model)`);let e=X(F(r),a);if(t.json||e===null||typeof e==`object`&&e!==void 0){H(e===void 0?null:e);return}G.stdout.write(`${e===void 0?`(unset)`:String(e)}\n`);return}i!==`set`&&i!==`unset`&&k(`Usage: coder config [get|set|unset] <key> [value] [--workspace]`),(!a||i===`set`&&o.length===0)&&k(`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}=gt(r,a,l,{workspace:t.workspace,unset:i===`unset`}))}catch(e){k(e instanceof Error?e.message:String(e))}if(t.json){H({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)}`;G.stdout.write(`${f} ${d.dim(`(${s})`)}\n`)}async function vt(e,t={}){let n=W(e),r=ce(n);r?.updated&&(n=W(e));let i=n.available?await ye(e):{loggedIn:!1,detail:n.detail},a=ie(),o=a.available?Pe():{loggedIn:!1,detail:a.detail},s=R();if(!K.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?fe(c):null,d=F(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:Ve(new URL(`../bin/coder.mjs`,import.meta.url)),...l?{claudePlugin:l}:{},...u?{agentsSkill:u}:{},config:d,ready:f}}async function yt(e){let{options:t,positionals:n}=v(e,J.object({...b,codex:S,claude:S,agents:S})),r=N(t),i=[`claude`,`codex`,`agents`];for(let e of n)i.includes(e)||k(`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||G.stdout.write(`${a(`Coder host setup`)}\n\n`);let s=await vt(r,{claude:t.claude,codex:t.codex,agents:t.agents});if(t.json){H(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?M(`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?M(`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(M(`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?M(`${e} ${o(t.note)}`):O(`${e} ${t.note}`),``);g.push(h?M(`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)`)),G.stdout.write(`${g.join(`
28
- `)}\n`)}const bt=new Set([`codex`,`claude`,`custom`]);async function xt(e){let t=e.envKey?G.env[e.envKey]:void 0,n=De(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 St(e,t){let n=K.existsSync(e)?JSON.parse(K.readFileSync(e,`utf8`)):{};t(n),n.models&&Object.keys(n.models).length===0&&delete n.models;let r=Ee(n);r.length&&k(`Refusing to write invalid config:\n ${r.join(`
29
- `)}`),K.mkdirSync(q.dirname(e),{recursive:!0}),K.writeFileSync(e,`${JSON.stringify(n,null,2)}\n`,`utf8`)}function Z(e,t){St(e,e=>{e.models=e.models??{},t(e.models)})}const Q=J.object({...b,"base-url":C,model:C,"env-key":C,workspace:S});function $(e,t){return e.workspace?q.join(a(t),`coder.config.json`):R()}function Ct(e){let t=e.models??{},n=Object.entries(t).filter(e=>V(e[1])),r=e=>`${e.provider}:${e.model}${e.effort?`:${e.effort}`:``}`,i=Object.entries(t).filter(e=>P(e[1])).map(([e,t])=>{let n=t.provider===`claude`?j:U,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])=>!V(t)&&!P(t)&&!z(e)).map(([e,t])=>({name:e,disabled:!!t.disabled})),disabled:o}}async function wt(e){let{endpoints:t,providerRows:n,toggledSlugs:r}=Ct(F(e)),i=await Promise.all(t.map(async([e,t])=>({name:e,...t,probe:await xt(t)})));return{codex:n(`codex`,U),claude:n(`claude`,j),custom:i,...r.length?{toggles:r}:{}}}async function Tt(e){let{options:t,positionals:n}=v(e,Q);n.length&&k(`model list takes no arguments.`,{hint:`Usage: coder model list [--json]`});let r=N(t),i=E,{endpoints:a,providerRows:o,toggledSlugs:s,disabled:c}=Ct(F(r));if(t.json){H(await wt(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`,U),f(`Claude models`,`claude`,j),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 xt(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)`)),G.stdout.write(`${d.join(`
30
- `)}\n`)}async function Et(e,t,n,r){let i=await Xe(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 xt(t),s=re(W(r)),c=W(r);return{name:e,entry:t,file:n,probe:o,codex:c,install:s,nativeResponses:a,keyMissing:!!(t.envKey&&!G.env[t.envKey]),ready:o.reachable&&c.available}}async function Dt(e,t,n,r,i){let a=$(n,r),o=E,{probe:s,codex:c,install:l,nativeResponses:u,keyMissing:d}=await Et(e,t,a,r);if(n.json){H({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(`
31
- `))),G.stdout.write(`${m.join(`
32
- `)}\n`)}function Ot(e,t,n){return e||k(`Missing model name.`,{hint:t}),/^[a-z][a-z0-9-]*$/.test(e)||k(`Invalid model name "${e}". Use lowercase kebab-case (e.g. qwen-local).`),(bt.has(e)||n===`model`&&z(e))&&k(`"${e}" is reserved; pick another name.`),e}async function kt(e){let t=`Usage: coder model add <name> --base-url <url> --model <id> [--env-key VAR]`,{options:n,positionals:r}=v(e,Q),i=N(n),a=Ot(r[0],t,`model`),o=F(i).models?.[a];o&&k(V(o)?`Custom model "${a}" already exists.`:`"${a}" is already configured as an ${P(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)&&k(`Missing --base-url or --model.`,{hint:t}),await Dt(a,{baseUrl:L(n[`base-url`]),model:n.model,...n[`env-key`]?{envKey:n[`env-key`]}:{}},n,i,`saved`)}async function At(e){let t=`Usage: coder model update <name> [--base-url <url>] [--model <id>] [--env-key VAR]`,{options:n,positionals:r}=v(e,Q),i=N(n),a=r[0],o=a?F(i).models?.[a]:void 0,s=o&&V(o)?o:void 0;(!a||!s)&&k(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`]&&k(`Nothing to update: pass --base-url, --model, or --env-key.`,{hint:t}),await Dt(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 jt(e){let{options:t,positionals:n}=v(e,Q),r=N(t),i=n[0],a;try{a=Bt(r,i??``,{workspace:t.workspace})}catch(e){k(e instanceof Error?e.message:String(e),{hint:i?`List them: coder model list`:`Usage: coder model remove <name>`})}if(t.json){H(a);return}G.stdout.write(`removed ${E.cyan(a.removed)} ${E.dim(`(${a.file})`)}\n`)}async function Mt(e){await Pt(e,!0)}async function Nt(e){await Pt(e,!1)}async function Pt(e,t){let n=t?`disable`:`enable`,r=`Usage: coder model ${n} <name>`,{options:i,positionals:a}=v(e,Q),o=N(i),s=a[0];s||k(`Missing model name.`,{hint:r});let{file:c}=Ut(o,s,t,{workspace:i.workspace});if(i.json){H({[t?`disabled`:`enabled`]:s,file:c});return}G.stdout.write(`${n}d ${E.cyan(s)} ${E.dim(`(${c})`)}\n`)}async function Ft(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=N(n),a=Ot(r[0],t,`alias`),o=F(i).models?.[a];o&&V(o)&&k(`"${a}" is a custom model name; pick another alias name.`);let s=r[1];s||k(`Missing alias spec.`,{hint:t});let c;try{c=Vt(i,a,s,{workspace:n.workspace})}catch(e){let n=e instanceof Error?e.message:String(e);k(n,n.includes(`already dispatchable by name`)?{}:{hint:t})}if(n.json){H(c);return}let l=E,u=`${c.provider} ${c.model}${c.effort?` (${c.effort})`:``}`;G.stdout.write(`aliased ${l.cyan(a)} -> ${c.provider}:${c.model}${c.effort?`:${c.effort}`:``} ${l.dim(`= ${u}`)} ${l.dim(`(${c.file})`)}\n`)}async function It(e){let{options:t,positionals:n}=v(e,Q),r=N(t),i=n[0],a=i?F(r).models?.[i]:void 0;(!i||!a||!P(a))&&k(i?`No alias named "${i}".`:`Missing alias name.`,{hint:i?`List them: coder model list`:`Usage: coder model unalias <name>`});let{file:o}=Ht(r,i,{workspace:t.workspace});if(t.json){H({unaliased:i,file:o});return}G.stdout.write(`unaliased ${E.cyan(i)} ${E.dim(`(${o})`)}\n`)}function Lt(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(bt.has(e)||t===`model`&&z(e))throw Error(`"${e}" is reserved; pick another name.`)}async function Rt(e,t,n){if(Lt(t,`model`),F(e).models?.[t])throw Error(`Custom model "${t}" already exists.`);if(!n.baseUrl||!n.model)throw Error(`Missing baseUrl or model.`);return Et(t,{baseUrl:L(n.baseUrl),model:n.model,...n.envKey?{envKey:n.envKey}:{}},$({workspace:n.workspace},e),e)}async function zt(e,t,n){let r=F(e).models?.[t],i=r&&V(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 Et(t,{...i,...n.baseUrl?{baseUrl:L(n.baseUrl)}:{},...n.model?{model:n.model}:{},...n.envKey?{envKey:n.envKey}:{}},$({workspace:n.workspace},e),e)}function Bt(e,t,n={}){if(!t||!F(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 Vt(e,t,n,r={}){Lt(t,`alias`);let i=F(e),a=i.models?.[t];if(a&&V(a))throw Error(`"${t}" is a custom model name; pick another alias name.`);if(!n)throw Error(`Missing alias spec.`);let o=Fe(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())||_e.has(e.trim())),c=o.agent===`claude`?j:U,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 Ht(e,t,n={}){let r=t?F(e).models?.[t]:void 0;if(!t||!r||!P(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 Ut(e,t,n,r={}){if(!t)throw Error(`Missing model name.`);let i=!!F(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}V(r)||P(r)?n?r.disabled=!0:delete r.disabled:n?r.disabled=!0:delete e[t]}),{name:t,disabled:n,file:a}}const Wt={list:Tt,add:kt,setup:kt,update:At,remove:jt,disable:Mt,enable:Nt,alias:Ft,unalias:It};async function Gt(e){let[t,...n]=e;if(t===void 0||t.startsWith(`-`)){await Tt(e);return}let r=Wt[t];r||k(`Unknown model subcommand "${t}". Use list, add, update, remove, disable, enable, alias, or unalias.`,{hint:`Help: coder model --help`}),await r(n)}const Kt=[{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 qt(e){let t=q.join(e,`docs`),n=[];try{n=K.readdirSync(t).filter(e=>e.endsWith(`.md`)).sort()}catch{n=[]}let r=n.map(t=>{let n=q.join(`docs`,t);return{name:q.basename(t,`.md`),file:n,description:Jt(q.join(e,n))}}),i=Kt.map(e=>({name:e.name,file:e.file,description:e.description}));return[...r,...i]}function Jt(e){let t=``;try{t=K.readFileSync(e,`utf8`)}catch{return``}let n=t.split(`
33
- `),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 Yt(i)||r}function Yt(e){if(!e)return``;let t=e.match(/^.*?[.!?](?=\s|$)/);return(t?t[0]:e).trim()}function Xt(e,t={}){let n=h(),r=qt(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=q.join(n,i.file),o;try{o=K.readFileSync(a,`utf8`)}catch{throw Error(`Could not read docs for "${i.name}" (${i.file}).`)}return{name:i.name,content:o}}async function Zt(e){let{options:t,positionals:n}=v(e,J.object({json:S,claude:S})),[r]=n,i;try{i=Xt(r,{claude:t.claude})}catch(e){let t=e instanceof Error?e.message:String(e);return k(t,t.startsWith(`Unknown docs topic`)?{hint:`List topics: coder docs`}:{})}if(`content`in i){G.stdout.write(i.content.endsWith(`
34
- `)?i.content:`${i.content}\n`);return}if(t.json){H(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)}`);G.stdout.write([a.bold(`Docs:`),...s,``,A([`Read a topic: coder docs <topic>`],a)].join(`
35
- `)+`
36
- `)}async function Qt(e={},t){let n=!e.pluginsOnly,r=!e.cliOnly,i=h(),a=q.join(i,`plugins/claude/.claude-plugin/plugin.json`),o={cli:y(),claude:x(a)},s={};if(n){let n=se(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=ze(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(` `)}`)}oe();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(K.existsSync(ue())){let e=ae(),t=fe(i);s.agentsSkill={installed:t.installed,note:t.note,from:e,to:ae()}}}return s}async function $t(e){let{options:t}=v(e,J.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 Qt({cliOnly:t[`cli-only`],pluginsOnly:t[`plugins-only`],pm:t.pm,codex:t.codex,claude:t.claude},e=>G.stdout.write(`${n(`Updating coder CLI`)} ${r(`${e}...`)}\n`))}catch(e){k(e instanceof Error?e.message:String(e))}if(a.cli&&G.stdout.write(a.cli.changed?`${M(`coder CLI ${i(a.cli.from,a.cli.to)}`)}\n`:`${M(`coder CLI ${a.cli.from} ${r(`(already latest)`)}`)}\n`),a.claudePlugin){let e=a.claudePlugin;G.stdout.write(`${e.installed?M(`claude plugin ${i(e.from,e.to)} ${r(`- ${e.note}`)}`):O(`claude plugin ${e.note}`)}\n`)}if(a.agentsSkill){let e=a.agentsSkill;G.stdout.write(`${e.installed?M(`agents skill ${i(e.from,e.to)} ${r(`- ${e.note}`)}`):O(`agents skill ${e.note}`)}\n`)}}export{ct as C,Ze as D,Qe as E,Xe as O,st as S,et as T,gt as _,Gt as a,lt as b,wt as c,Ht as d,zt as f,ht as g,_t as h,Xt as i,Je as k,Bt as l,vt as m,Qt as n,Rt as o,yt as p,Zt as r,Vt as s,$t as t,Ut as u,pt as v,nt as w,ut as x,Y as y};