@wular/coder 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +5 -5
- package/dist/flow/index.js +1 -1
- package/dist/{runtime-BitZWgom.js → runtime-DRtQOCSz.js} +1 -1
- package/dist/sdk.d.ts +2 -2
- package/dist/sdk.js +1 -1
- package/dist/{upgrade-glYqFjxk.js → upgrade-DFAtgbtD.js} +3 -3
- package/docs/config.md +3 -3
- package/docs/models.md +4 -4
- package/package.json +1 -1
- package/plugins/agents/skills/coder/SKILL.md +0 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/skills/dispatch/SKILL.md +0 -1
- package/plugins/cursor/.cursor-plugin/plugin.json +1 -1
- package/plugins/cursor/skills/coder/SKILL.md +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{B as e,E as t,F as n,M as r,V as i,c as a,d as o,f as s,l as c,m as l,o as u,s as d,u as f}from"./app-server-Dwd7IcQH.js";import{$t as p,A as m,Bt as h,D as g,Ft as _,Gt as ee,Ht as v,It as y,Jt as b,Kt as x,Lt as te,M as S,Nt as ne,O as C,Ot as w,Qt as T,R as re,Rt as E,S as D,T as O,Ut as ie,Vt as ae,Xt as oe,Yt as k,Zt as A,_ as se,a as ce,b as le,d as ue,en as de,g as j,h as fe,j as pe,jt as me,kt as he,l as M,n as ge,nn as _e,p as ve,qt as N,r as ye,rn as be,s as xe,t as Se,tn as Ce,u as we,v as P,vt as Te,w as Ee,x as De,xt as Oe,y as ke,yt as Ae,zt as je}from"./runtime-
|
|
2
|
+
import{B as e,E as t,F as n,M as r,V as i,c as a,d as o,f as s,l as c,m as l,o as u,s as d,u as f}from"./app-server-Dwd7IcQH.js";import{$t as p,A as m,Bt as h,D as g,Ft as _,Gt as ee,Ht as v,It as y,Jt as b,Kt as x,Lt as te,M as S,Nt as ne,O as C,Ot as w,Qt as T,R as re,Rt as E,S as D,T as O,Ut as ie,Vt as ae,Xt as oe,Yt as k,Zt as A,_ as se,a as ce,b as le,d as ue,en as de,g as j,h as fe,j as pe,jt as me,kt as he,l as M,n as ge,nn as _e,p as ve,qt as N,r as ye,rn as be,s as xe,t as Se,tn as Ce,u as we,v as P,vt as Te,w as Ee,x as De,xt as Oe,y as ke,yt as Ae,zt as je}from"./runtime-DRtQOCSz.js";import{D as Me,E as Ne,S as Pe,a as Fe,h as Ie,p as F,r as Le,t as Re,v as ze,w as I,x as Be}from"./upgrade-DFAtgbtD.js";import L from"node:process";import R from"node:fs";import z from"node:path";import{spawn as Ve,spawnSync as He}from"node:child_process";import Ue from"node:os";import*as B from"zod/mini";const We=[[`--wait`,`run in the foreground and block until the answer is ready`],[`--agent <codex|claude|custom>`,`engine to use; custom runs your configured custom models (default: first in the chain)`],[`--model <alias|slug>`,`mini/luna/terra/sol (codex) · haiku/sonnet/opus/fable (claude) · a custom model (coder model list)`],[`--effort <low|medium|high>`,`reasoning effort`],[`--permissions <mode>`,`read-only · workspace-write · auto (default: auto)`],[`--resume <task-id>`,`continue that task's thread instead of a fresh run`],[`--json`,`machine-readable JSON output`]],V=[`--cwd <dir>`,`workspace directory (default: current)`],H=[`--json`,`JSON output`],Ge=[{sub:`run`,usage:`run "<text>"`,blurb:`run a task (background; --wait blocks)`,alias:`run`},{sub:`list`,usage:`list`,blurb:`list recent tasks (running + just stopped)`,alias:`list`},{sub:`result`,usage:`result [task-id]`,blurb:`status + final answer (--wait blocks)`,alias:`result`},{sub:`stream`,usage:`stream [task-id]`,blurb:`watch a task live (progress log)`,alias:`stream`},{sub:`steer`,usage:`steer <task-id> "<follow-up>"`,blurb:`continue a task's thread`},{sub:`stop`,usage:`stop <task-id>`,blurb:`interrupt a running task`},{sub:`archive`,usage:`archive <task-id>`,blurb:`archive a session (or --all-stopped)`},{sub:`delete`,usage:`delete <task-id>`,blurb:`delete a session (or --all-archived)`},{sub:`approvals`,usage:`approvals <task-id>`,blurb:`list escalated approvals`},{sub:`approve`,usage:`approve <task-id> <id>`,blurb:`answer an escalated permission`}],U={"task run":{list:[`task run "<text>"`,`run a coding task (background; --wait blocks)`],usage:`coder task run "<task text>"`,summary:`Dispatch a coding task to the configured engine. Backgrounds by default and
|
|
3
3
|
prints a task id; --wait runs in the foreground and prints the answer.
|
|
4
|
-
Shortcut: \`coder run "<text>"\`.`,flags:[[`--name <name>`,`label the task (shown in list/result)`],[`--system <text>`,`standing instructions prepended to the task (kept out of prompt previews)`],...We,V],examples:[[`coder run "add a /health endpoint"`,`dispatch in the background, print a task id`],[`coder run --wait "fix the failing test"`,`block until done, print the answer`],[`coder task run --model
|
|
4
|
+
Shortcut: \`coder run "<text>"\`.`,flags:[[`--name <name>`,`label the task (shown in list/result)`],[`--system <text>`,`standing instructions prepended to the task (kept out of prompt previews)`],...We,V],examples:[[`coder run "add a /health endpoint"`,`dispatch in the background, print a task id`],[`coder run --wait "fix the failing test"`,`block until done, print the answer`],[`coder task run --model mini --system "tests live in test/, don't touch anything outside of it" "rename foo to bar"`,`pick an engine via its model alias; --system adds standing instructions`]],seeAlso:`task result · task steer · task stop · task stream`},"task list":{list:[`task list [--running|--stopped|--archived]`,`list recent tasks (running + just stopped)`],usage:`coder task list [--running] [--stopped] [--archived [--limit N]]`,summary:`List recent tasks across all workspaces, most recent first: running tasks plus
|
|
5
5
|
ones stopped within the last 10 minutes. Older stopped tasks auto-archive and
|
|
6
6
|
move to --archived. Shortcut: \`coder list\`.`,flags:[[`--running`,`show only running tasks`],[`--stopped`,`show only recently stopped tasks (not yet archived)`],[`--archived`,`show only archived tasks (auto-archived or via task archive)`],[`--limit <n|all>`,`show at most n tasks (default all)`],[`--dir <dir>`,`only tasks launched in that workspace`],H],seeAlso:`task result · task archive · task delete`},"task result":{list:[`task result [task-id]`,`status + final answer of a task`],usage:`coder task result [task-id]`,summary:`Show a task's status and its final answer (result pending while it runs), plus
|
|
7
7
|
any pending approvals. --wait blocks until it finishes, then prints. --tail <n>
|
|
@@ -43,12 +43,12 @@ every host that reads the Agent Skills standard dir (Codex, Pi, OpenCode,
|
|
|
43
43
|
vLLM, OpenRouter, ...). It currently runs on the codex engine pointed at your
|
|
44
44
|
URL and is usable anywhere a model is: --model <name>, --agent custom, or as an
|
|
45
45
|
agent default in config. Alias: \`coder model setup\`.`,flags:[[`--base-url <url>`,`OpenAI-compatible API base (e.g. http://localhost:11434/v1)`],[`--model <id>`,`the provider's model id (e.g. qwen2.5-coder:32b)`],[`--env-key <VAR>`,`env var holding the API key (omit for keyless local endpoints)`],[`--workspace`,`write to <repo>/coder.config.json instead of the user file`],H],examples:[[`coder model add qwen --base-url http://localhost:11434/v1 --model qwen2.5-coder:32b`,`local Ollama model, no key`],[`coder model add kimi --base-url https://openrouter.ai/api/v1 --model moonshotai/kimi-k2 --env-key OPENROUTER_API_KEY`,`third-party provider via OpenRouter`],[`coder run --model qwen "explain this repo"`,`dispatch a task on it`]],seeAlso:`model list · model update · setup-host · config`},"model update":{list:[`model update <name> [--base-url|--model|--env-key]`,`change a custom model in place`],usage:`coder model update <name> [--base-url <url>] [--model <id>] [--env-key VAR]`,summary:`Update a configured custom model. Only the flags you pass change; the endpoint
|
|
46
|
-
is re-probed and the wire protocol re-detected.`,flags:[[`--base-url <url>`,`new API base`],[`--model <id>`,`new provider model id`],[`--env-key <VAR>`,`new API-key env var`],[`--workspace`,`write to <repo>/coder.config.json instead of the user file`],H],seeAlso:`model list · model remove`},"model remove":{list:[`model remove <name>`,`delete a custom model`],usage:`coder model remove <name>`,summary:`Remove a configured custom model.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],H],seeAlso:`model list · model add`},"model disable":{list:[`model disable <name>`,`turn off a model (built-in, custom, or alias)`],usage:`coder model disable <name> [--workspace]`,summary:`Disable a model - built-in, custom, or alias. Requests for it fail until re-enabled.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],H],seeAlso:`model enable · model list`},"model enable":{list:[`model enable <name>`,`re-enable a disabled model`],usage:`coder model enable <name> [--workspace]`,summary:`Re-enable a disabled model.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],H],seeAlso:`model disable · model list`},"model alias":{list:[`model alias <name> <spec>`,`add or replace a user alias`],usage:`coder model alias <name> <spec> [--workspace]`,summary:`Save an alias for an agent spec, e.g. fast -> codex:
|
|
46
|
+
is re-probed and the wire protocol re-detected.`,flags:[[`--base-url <url>`,`new API base`],[`--model <id>`,`new provider model id`],[`--env-key <VAR>`,`new API-key env var`],[`--workspace`,`write to <repo>/coder.config.json instead of the user file`],H],seeAlso:`model list · model remove`},"model remove":{list:[`model remove <name>`,`delete a custom model`],usage:`coder model remove <name>`,summary:`Remove a configured custom model.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],H],seeAlso:`model list · model add`},"model disable":{list:[`model disable <name>`,`turn off a model (built-in, custom, or alias)`],usage:`coder model disable <name> [--workspace]`,summary:`Disable a model - built-in, custom, or alias. Requests for it fail until re-enabled.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],H],seeAlso:`model enable · model list`},"model enable":{list:[`model enable <name>`,`re-enable a disabled model`],usage:`coder model enable <name> [--workspace]`,summary:`Re-enable a disabled model.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],H],seeAlso:`model disable · model list`},"model alias":{list:[`model alias <name> <spec>`,`add or replace a user alias`],usage:`coder model alias <name> <spec> [--workspace]`,summary:`Save an alias for an agent spec, e.g. fast -> codex:mini. An alias may reuse a
|
|
47
47
|
built-in name to override it.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],H],seeAlso:`model unalias · model list`},"model unalias":{list:[`model unalias <name>`,`remove a user alias`],usage:`coder model unalias <name> [--workspace]`,summary:`Remove a user-defined alias.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],H],seeAlso:`model alias · model list`},docs:{list:[`docs [topic]`,`print bundled documentation (for agents to read)`],usage:`coder docs [topic] [--json]`,summary:`Print bundled documentation. With no topic, list the available topics; with a
|
|
48
48
|
topic, print that doc's raw markdown to stdout (unstyled, for an agent to
|
|
49
49
|
consume).`,flags:[[`--json`,`list topics as JSON (bare listing only)`]],examples:[[`coder docs`,`list the available topics`],[`coder docs flows`,`print the Flows doc`]]},upgrade:{list:[`upgrade [--cli-only|--plugins-only]`,`update the CLI and host plugins (alias: update)`],usage:`coder upgrade [--cli-only] [--plugins-only] [--codex] [--claude] [--pm <mgr>]`,summary:`Update the coder CLI through whichever package manager installed it, then refresh
|
|
50
|
-
the host plugins to match. Alias: update.`,flags:[[`--cli-only`,`update just the CLI`],[`--plugins-only`,`refresh just the host plugins`],[`--codex`,`limit the refresh to the Agent Skills copy (Codex, Pi, ...)`],[`--claude`,`limit the refresh to the Claude Code plugin`],[`--pm <npm|pnpm|yarn|bun>`,`force a package manager instead of auto-detecting`]]}},W={run:`task run`,list:`task list`,stream:`task stream`,watch:`task stream`,result:`task result`,steer:`task steer`,stop:`task stop`,archive:`task archive`,delete:`task delete`,approvals:`task approvals`,approve:`task approve`,setup:`setup-host`,"host-setup":`setup-host`,update:`upgrade`},Ke=[{usage:`list`,blurb:`list built-ins, custom models, and aliases`},{usage:`add <name> --base-url <url> --model <id> [--env-key VAR]`,blurb:`connect a model (alias: setup)`},{usage:`update <name> [--base-url|--model|--env-key]`,blurb:`change a model in place`},{usage:`remove <name>`,blurb:`delete a custom model`},{usage:`disable <name>`,blurb:`turn off a model (built-in, custom, or alias)`},{usage:`enable <name>`,blurb:`re-enable a disabled model`},{usage:`alias <name> <spec>`,blurb:`name a spec, e.g. fast codex:
|
|
51
|
-
`)}\n`}function Je(){let e=N,t=Ke.map(t=>` ${e.cyan(t.usage.padEnd(60))}${e.dim(t.blurb)}`);return`${[e.bold(`Usage:`),` coder model <subcommand>`,``,"Manage the models coder can dispatch to. `add` connects any OpenAI-compatible",`endpoint (Ollama, vLLM, OpenRouter, ...) as the custom agent, alongside the`,"built-in codex/claude models. Name your own shortcuts with `alias`",`(e.g. fast -> codex:
|
|
50
|
+
the host plugins to match. Alias: update.`,flags:[[`--cli-only`,`update just the CLI`],[`--plugins-only`,`refresh just the host plugins`],[`--codex`,`limit the refresh to the Agent Skills copy (Codex, Pi, ...)`],[`--claude`,`limit the refresh to the Claude Code plugin`],[`--pm <npm|pnpm|yarn|bun>`,`force a package manager instead of auto-detecting`]]}},W={run:`task run`,list:`task list`,stream:`task stream`,watch:`task stream`,result:`task result`,steer:`task steer`,stop:`task stop`,archive:`task archive`,delete:`task delete`,approvals:`task approvals`,approve:`task approve`,setup:`setup-host`,"host-setup":`setup-host`,update:`upgrade`},Ke=[{usage:`list`,blurb:`list built-ins, custom models, and aliases`},{usage:`add <name> --base-url <url> --model <id> [--env-key VAR]`,blurb:`connect a model (alias: setup)`},{usage:`update <name> [--base-url|--model|--env-key]`,blurb:`change a model in place`},{usage:`remove <name>`,blurb:`delete a custom model`},{usage:`disable <name>`,blurb:`turn off a model (built-in, custom, or alias)`},{usage:`enable <name>`,blurb:`re-enable a disabled model`},{usage:`alias <name> <spec>`,blurb:`name a spec, e.g. fast codex:mini`},{usage:`unalias <name>`,blurb:`remove an alias`}],qe=[{usage:`run <name|path> [--wait] [--args ...]`,blurb:`run a flow in the background (--wait to follow it live)`},{usage:`list`,blurb:`recent flow runs (running + just stopped)`},{usage:`discover`,blurb:`list flows runnable here (workspace + global)`},{usage:`result [run-id]`,blurb:`progress and result of a run`},{usage:`stream [run-id]`,blurb:`watch a run live (replay + follow)`},{usage:`stop [run-id]`,blurb:`stop a run and its still-running tasks`},{usage:`resume [run-id]`,blurb:`continue a stopped or edited run`},{usage:`archive <run-id> | --all-stopped`,blurb:`hide a run (or all stopped) from the list`},{usage:`delete <run-id> | --all-archived`,blurb:`delete a run's record (or all archived)`}];function G(){let e=N,t=qe.map(t=>` ${e.cyan(t.usage.padEnd(44))}${e.dim(t.blurb)}`);return`${[e.bold(`Usage:`),` coder flow <subcommand>`,``,`Orchestrate many coder tasks with a plain TypeScript file: dispatch, gates,`,`concurrency, journaling, and resume. Flows live in .coder/flows/ (workspace)`,"or ~/.coder/flows/ (global). See `coder docs flows`.",``,e.bold(`Subcommands:`),...t,``,e.dim(`Run 'coder flow <subcommand> --help' for details on any subcommand.`)].join(`
|
|
51
|
+
`)}\n`}function Je(){let e=N,t=Ke.map(t=>` ${e.cyan(t.usage.padEnd(60))}${e.dim(t.blurb)}`);return`${[e.bold(`Usage:`),` coder model <subcommand>`,``,"Manage the models coder can dispatch to. `add` connects any OpenAI-compatible",`endpoint (Ollama, vLLM, OpenRouter, ...) as the custom agent, alongside the`,"built-in codex/claude models. Name your own shortcuts with `alias`",`(e.g. fast -> codex:mini); disable/enable turns any model off and on.`,``,e.bold(`Subcommands:`),...t,``,e.dim(`Run 'coder model <subcommand> --help' for details on any subcommand.`)].join(`
|
|
52
52
|
`)}\n`}function Ye(e,t){return e.map(([e,n])=>` ${t.cyan(e.padEnd(30))}${t.dim(n)}`)}function K(e){let t=U[e];if(!t)return null;let n=N,r=[n.bold(`Usage:`),` ${t.usage}`];if(t.summary&&r.push(``,t.summary),t.flags?.length&&r.push(``,n.bold(`Flags:`),...Ye(t.flags,n)),t.examples?.length){r.push(``,n.bold(`Examples:`));for(let[e,i]of t.examples)r.push(` ${n.cyan(e)}`,` ${n.dim(i)}`)}return t.seeAlso&&r.push(``,n.dim(`Related: ${t.seeAlso}`)),`${r.join(`
|
|
53
53
|
`)}\n`}function q(){let e=N,t=Ge.map(t=>{let n=t.alias?e.dim(` (coder ${t.alias})`):``;return` ${e.cyan(t.usage.padEnd(30))}${e.dim(t.blurb)}${n}`});return`${[e.bold(`Usage:`),` coder task <subcommand>`,``,e.bold(`Subcommands:`),...t,``,e.dim(`Run 'coder task <subcommand> --help' for details on any subcommand.`)].join(`
|
|
54
54
|
`)}\n`}function J(){let e=N,t=([t,n])=>` ${e.cyan(t.padEnd(41))}${e.dim(n)}`,n=Ge.filter(e=>e.alias).map(e=>t([e.usage.replace(/^\S+/,e.alias),e.blurb]));return`${[`${e.bold(`Coder`)} ${e.dim(`v${l()}`)}`,`Delegate a coding task to the best available engine and steer it while it runs.`,``,e.bold(`Get started:`),` ${e.cyan(`coder setup-host claude`)} ${e.dim(`# or agents (Codex, Pi, ...); installs the host plugin/skill`)}`,` ${e.cyan(`coder run "explain this repo's layout"`)}`,``,e.bold(`Usage:`),` coder <command>`,``,e.bold(`Commands:`),...n,` ${e.cyan(`task <cmd>`.padEnd(41))}${e.dim(`more task commands (steer, stop, approve, ...): `)}${e.light(`coder task --help`)}`,` ${e.cyan(`flow <cmd>`.padEnd(41))}${e.dim(`orchestrate a wave of tasks: `)}${e.light(`coder flow --help`)}`,t(U.config.list),t([`model <list|add|alias|disable>`,`manage models: built-ins, aliases, custom endpoints`]),t(U.docs.list),t(U.upgrade.list),``,e.bold(`Global:`),t([`-h, --help`,`show help (top-level, or for a command)`]),t([`-v, --version`,`print the coder version`]),t([`--json`,`JSON output instead of human-readable text`]),t(V)].join(`
|
package/dist/flow/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as e,C as t,M as n,S as r,_ as i,a,c as o,d as s,f as c,g as l,i as u,m as d,n as f,o as p,r as m,s as h,x as g,y as _}from"../runtime-
|
|
1
|
+
import{A as e,C as t,M as n,S as r,_ as i,a,c as o,d as s,f as c,g as l,i as u,m as d,n as f,o as p,r as m,s as h,x as g,y as _}from"../runtime-DRtQOCSz.js";const v=new Proxy({},{get(e,t){return u()?.[t]},has(e,t){let n=u();return n!=null&&t in Object(n)},ownKeys(){let e=u();return e?Reflect.ownKeys(Object(e)):[]},getOwnPropertyDescriptor(e,t){let n=u();if(n!=null&&t in Object(n))return{enumerable:!0,configurable:!0,value:n[t]}}});function y(e){let t=l(e);if(!t)throw new n(`flow-failed`,`No flow run "${e}".`,{hint:`Recent runs: coder flow list`});if(t.status===`running`||t.status===`queued`)throw new n(`flow-failed`,`Run ${t.runId} is still running.`,{runId:t.runId,hint:`Stop it first: coder flow stop ${t.runId}`});return t}const b={run(e,t={}){return _(e,t)},list(e={}){return m(e).runs},discover(t){return e(t??process.cwd())},result(e,t={}){let n=e?l(e):s()[0]??null;return n?{...n,steps:h(n.runId,t.tail)}:null},stream(e,t={}){let n=e??s()[0]?.runId;if(!n)throw Error(`No flow runs to stream.`);return r(n,void 0,{tail:t.tail})},stop(e,t={}){return g(e,t)},resume(e,t={}){let n=e??s()[0]?.runId;if(!n)throw Error(`No flow runs to resume.`);return i(n,t)},archive(e){return f(y(e)),{runId:e,archived:!0}},delete(e){return y(e),{runId:e,deleted:a(e)}}};export{n as CoderError,v as args,b as default,b as flowSdk,p as flow,o as gate,c as log,d as pipeline,t as task};
|
|
@@ -6,7 +6,7 @@ import{A as e,C as t,F as n,I as r,M as i,N as a,O as o,P as s,T as c,U as l,V a
|
|
|
6
6
|
|
|
7
7
|
`)),!n?.checkedAt||Date.now()-n.checkedAt>864e5)try{w(x.execPath,[t,`_refreshUpdate`],{detached:!0,stdio:`ignore`}).unref()}catch{}}async function Ke(e){let t=He()?.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{}Ue({checkedAt:Date.now(),latest:t,current:e})}function qe(e){let t=e;try{t=S.realpathSync(e)}catch{}let n=t.replace(/\\/g,`/`);return/\/\.bun\//.test(n)?{pm:`bun`,command:[`bun`,`add`,`-g`,`${M}@latest`]}:/\/\.pnpm\//.test(n)||/\/pnpm(-global)?\//i.test(n)||/\/Library\/pnpm\//.test(n)?{pm:`pnpm`,command:[`pnpm`,`add`,`-g`,`${M}@latest`]}:/\/\.config\/yarn\/global\//.test(n)||/\/yarn\/global\//.test(n)||/\/Yarn\/Data\/global\//.test(n)?{pm:`yarn`,command:[`yarn`,`global`,`add`,`${M}@latest`]}:{pm:`npm`,command:[`npm`,`install`,`-g`,`${M}@latest`]}}function N(e){try{return JSON.parse(S.readFileSync(e,`utf8`))}catch{return null}}function Je(e,t){let n=`${e}.tmp`;S.writeFileSync(n,`${JSON.stringify(t,null,2)}\n`,`utf8`),S.renameSync(n,e)}function Ye(e){let t=0,n=``;return()=>{let r;try{r=S.statSync(e).size}catch{return[]}if(r<t&&(t=0,n=``),r===t)return[];let i;try{i=S.openSync(e,`r`)}catch{return[]}try{let e=Buffer.alloc(r-t),a=S.readSync(i,e,0,e.length,t);t+=a;let o=(n+e.toString(`utf8`,0,a)).split(`
|
|
8
8
|
`);return n=o.pop()??``,o.filter(Boolean)}finally{S.closeSync(i)}}}const Xe=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(`.`)),Ze=[/\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)/],Qe=new Set([`status`,`log`,`diff`,`show`,`blame`,`rev-parse`,`ls-files`,`ls-tree`,`cat-file`,`describe`,`shortlog`,`grep`,`branch`,`stash`]);function $e(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 et(e){return e.trim().split(/\s+/).filter(Boolean)}function tt(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 Qe.has(t)?{decision:`accept`,reason:`git ${t} is read-only`}:Xe.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 nt(e,t={}){let n=$e(String(e??``));if(!n.trim())return{decision:`escalate`,reason:`empty command`};for(let e of Ze)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=nt(n,t);if(r.decision===`decline`)return r;r.decision===`escalate`&&(e=r)}return e}let i=et(n),a=C.basename(i[0]??``);if(a===`git`)return tt(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 rt(e,t){if(!e.length)return{decision:`escalate`,reason:`file change with no resolvable paths`};for(let n of e){let e=C.resolve(t,n),r=C.relative(t,e);if(r.startsWith(`..`)||C.isAbsolute(r))return{decision:`escalate`,reason:`path outside workspace: ${n}`};if(r===`.git`||r.startsWith(`.git${C.sep}`))return{decision:`decline`,reason:`direct .git modification: ${n}`}}return{decision:`accept`,reason:`all paths inside workspace`}}function it(e){return C.join(e,`approvals`)}function at(e){let t=it(e);return S.existsSync(t)?S.readdirSync(t).filter(e=>e.endsWith(`.request.json`)).flatMap(e=>{let n=e.replace(/\.request\.json$/,``),r=N(C.join(t,e));if(!r)return[];let i=N(C.join(t,`${n}.response.json`));return[{...r,id:n,response:i}]}).sort((e,t)=>String(e.createdAt??``).localeCompare(String(t.createdAt??``))):[]}function ot(e,t,n){let r=it(e),i=C.join(r,`${t}.request.json`);if(!S.existsSync(i))throw Error(`No pending approval "${t}" for this job.`);S.writeFileSync(C.join(r,`${t}.response.json`),`${JSON.stringify({decision:n,answeredAt:new Date().toISOString()},null,2)}\n`,`utf8`)}async function st(e,t,{timeoutMs:n,onEvent:r}){let i=it(e);S.mkdirSync(i,{recursive:!0});let a=`apr-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`;S.writeFileSync(C.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 <job> ${a} [--deny]`});let o=C.join(i,`${a}.response.json`),s=Date.now()+n;for(;Date.now()<s;){if(S.existsSync(o))try{let e=JSON.parse(S.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 ct(e,t={}){return st(e,{method:`simulate`,summary:`simulated approval probe (--simulate-approval)`},{timeoutMs:t.timeoutMs??12e4,onEvent:t.onEvent??null})}function lt({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=nt(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 st(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=rt(i,e);return a?.({kind:`approval-decision`,method:o,decision:u.decision,reason:u.reason,summary:l}),u.decision===`escalate`?{decision:await st(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 ut(e,t,r=400){let i=t;for(;;){if(u.includes(i.status))return{job:i,reason:`terminal`};let t=at(n(e,i.id)).filter(e=>!e.response);if(t[0])return{job:i,reason:`approval`,approval:{id:t[0].id,summary:String(t[0].summary??``)}};await new Promise(e=>setTimeout(e,r)),i=a(e,p(e,i.id)??i)}}const dt=`Coder Task`;function ft(e){return e.split(/\r?\n/).map(e=>e.trimEnd()).filter(e=>e&&!e.startsWith(`WARNING: proceeding, even though we could not update PATH:`)).join(`
|
|
9
|
-
`)}function pt(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=pt(e,56);return t?`${dt}: ${t}`:dt}function ht(e){return e?.params?.threadId??null}function gt(e){return e?.params?.turnId?e.params.turnId:e?.params?.turn?.id?e.params.turn.id:null}function _t(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 vt(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 yt(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 bt(e){return String(e??``).replace(/\s+/g,` `).trim()}function P(e){if(!e)return[];if(typeof e==`string`){let t=bt(e);return t?[t]:[]}if(Array.isArray(e))return e.flatMap(e=>P(e));if(typeof e==`object`){let t=e;if(typeof t.text==`string`)return P(t.text);if(`summary`in t)return P(t.summary);if(`content`in t)return P(t.content);if(`parts`in t)return P(t.parts)}return[]}function xt(e,t){let n=[];for(let r of[...e,...t]){let e=bt(r);!e||n.includes(e)||n.push(e)}return n}function F(e,t,n=null,r={}){!e||!t||e({message:t,phase:n,...r})}function St(e){switch(e.type){case`commandExecution`:return{message:`Running command: ${String(e.command??``).trim()}`,phase:`running`};case`fileChange`:return{message:`Applying ${e.changes.length} file change(s).`,phase:`editing`};case`mcpToolCall`:return{message:`Calling ${e.server}/${e.tool}.`,phase:`investigating`};case`dynamicToolCall`:return{message:`Running tool: ${e.tool}.`,phase:`investigating`};case`webSearch`:return{message:`Searching: ${String(e.query??``).trim()}`,phase:`investigating`};default:return null}}function Ct(e){switch(e.type){case`commandExecution`:{let t=String(e.aggregatedOutput??``).trim();return{message:`Command ${e.status===`completed`?`completed`:e.status}: ${String(e.command??``).trim()} (exit ${e.exitCode??`?`})`+(t?`\n${t}`:``),phase:`running`}}case`fileChange`:return{message:`File changes ${e.status}.`,phase:`editing`};case`mcpToolCall`:return{message:`Tool ${e.server}/${e.tool} ${e.status}.`,phase:`investigating`};case`dynamicToolCall`:return{message:`Tool ${e.tool} ${e.status}.`,phase:`investigating`};default:return null}}function wt(e,t={}){let n,r,i=new Promise((e,t)=>{n=e,r=t});return{threadId:e,rootThreadId:e,threadIds:new Set([e]),threadTurnIds:new Map,turnId:null,bufferedNotifications:[],completion:i,resolveCompletion:n,rejectCompletion:r,finalTurn:null,completed:!1,finalAnswerSeen:!1,pendingCollaborations:new Set,activeSubagentTurns:new Set,completionTimer:null,lastAgentMessage:``,reasoningSummary:[],error:null,fileChanges:[],commandExecutions:[],tokenUsageByThread:new Map,itemIndex:new Map,onProgress:t.onProgress??null,onHeartbeat:t.onHeartbeat??null}}function Tt(e){e.completionTimer&&=(clearTimeout(e.completionTimer),null)}function Et(e,t=null){e.completed||(Tt(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 Dt(e){e.completed||e.finalTurn||!e.finalAnswerSeen||e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||(Tt(e),e.completionTimer=setTimeout(()=>{e.completionTimer=null,!(e.completed||e.finalTurn||!e.finalAnswerSeen)&&(e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||Et(e,null))},250),e.completionTimer.unref?.())}function Ot(e,t){let n=ht(t);if(!n||!e.threadIds.has(n))return!1;let r=e.threadTurnIds.get(n)??null,i=gt(t);return r===null||i===null||i===r}function kt(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),Dt(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,Dt(e)));return}if(t.type===`reasoning`&&n===`completed`){e.reasoningSummary=xt(e.reasoningSummary,P(t.summary));return}if(t.type===`fileChange`&&n===`completed`){e.fileChanges.push(t);return}t.type===`commandExecution`&&n===`completed`&&e.commandExecutions.push(t)}function At(e,t){switch(e.onHeartbeat?.(),t.method){case`thread/started`:e.threadIds.add(t.params.thread.id);break;case`turn/started`:e.threadIds.add(t.params.threadId),e.threadTurnIds.set(t.params.threadId,t.params.turn.id),(t.params.threadId??null)!==e.threadId&&e.activeSubagentTurns.add(t.params.threadId),F(e.onProgress,`Turn started (${t.params.turn.id}).`,`starting`,{threadId:t.params.threadId??null,turnId:t.params.turn.id??null});break;case`item/started`:kt(e,t.params.item,`started`,t.params.threadId??null);{let n=St(t.params.item);F(e.onProgress,n?.message,n?.phase??null)}break;case`item/completed`:kt(e,t.params.item,`completed`,t.params.threadId??null);{let n=Ct(t.params.item);F(e.onProgress,n?.message,n?.phase??null)}break;case`thread/tokenUsage/updated`:{let n=vt(t.params?.tokenUsage?.total??t.params?.tokenUsage),r=ht(t);n&&r&&e.tokenUsageByThread.set(r,n);break}case`error`:e.error=t.params.error,F(e.onProgress,`Codex error: ${t.params.error.message}`,`failed`);break;case`turn/completed`:if((t.params.threadId??null)!==e.threadId){e.activeSubagentTurns.delete(t.params.threadId),Dt(e);break}F(e.onProgress,`Turn ${t.params.turn.status}.`,`finalizing`),Et(e,t.params.turn);break;default:break}}async function jt(e,t,n,r={}){let i=wt(t,r),a=e.notificationHandler;e.setNotificationHandler(e=>{if(!i.turnId){i.bufferedNotifications.push(e);return}if(e.method===`thread/started`){At(i,e);return}if(!Ot(i,e)){a?.(e);return}At(i,e)});let o=r.onApprovalRequest;o&&e.setServerRequestHandler((e,t)=>o(e,t,i));try{let e=await n();i.turnId=e.turn?.id??null,i.turnId&&i.threadTurnIds.set(i.threadId,i.turnId);for(let e of i.bufferedNotifications)Ot(i,e)?At(i,e):a?.(e);return i.bufferedNotifications.length=0,e.turn?.status&&e.turn.status!==`inProgress`&&Et(i,e.turn),await i.completion}finally{Tt(i),e.setNotificationHandler(a??null),e.setServerRequestHandler(null)}}async function Mt(e,t){let n=null;try{n=await _.connect(e);let r=await t(n);return await n.close(),r}catch(r){let i=r,a=n?.transport===`broker`||!!process.env.CODER_APP_SERVER_ENDPOINT,o=n?.transport===`broker`&&i?.rpcCode===-32001||a&&(i?.code===`ENOENT`||i?.code===`ECONNREFUSED`);if(n&&=(await n.close().catch(()=>{}),null),!o)throw r;let s=await _.connect(e,{disableBroker:!0});try{return await t(s)}finally{await s.close()}}}function I(e){let t=ee(`codex`,[`--version`],{cwd:e});if(!t.available)return t;let n=ee(`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 Nt(e){let t=I(e);if(!t.available)return{available:!1,loggedIn:!1,detail:t.detail};let n=null;try{n=await _.connect(e,{reuseExistingBroker:!0});let t=await n.request(`account/read`,{refreshToken:!1}),r=t?.account??null;return r?.type===`chatgpt`?{available:!0,loggedIn:!0,detail:r.email?`ChatGPT login active for ${r.email}`:`ChatGPT login active`}:r?.type===`apiKey`?{available:!0,loggedIn:!0,detail:`API key configured`}:t?.requiresOpenaiAuth===!1?{available:!0,loggedIn:!0,detail:`Active provider does not require OpenAI authentication`}:{available:!0,loggedIn:!1,detail:"Not authenticated. Run `codex login`."}}catch(e){let t=T(`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 Pt(e,{threadId:t,turnId:n}){if(!t||!n)return{interrupted:!1,detail:`missing threadId or turnId`};let r=null;try{return r=await _.connect(e,{reuseExistingBroker:!0}),await r.request(`turn/interrupt`,{threadId:t,turnId:n}),{interrupted:!0,detail:`Interrupted ${n} on ${t}.`}}catch(e){return{interrupted:!1,detail:e instanceof Error?e.message:String(e)}}finally{await r?.close().catch(()=>{})}}async function Ft(e,{threadId:t,text:n}){if(!t)return{steered:!1,detail:`missing threadId`};let r=n.trim();if(!r)return{steered:!1,detail:`empty follow-up`};let i=null;try{return i=await _.connect(e,{reuseExistingBroker:!0}),await i.request(`turn/steer`,{threadId:t,input:[{type:`text`,text:r,text_elements:[]}]}),{steered:!0,detail:`Steered follow-up into the active turn on ${t}.`}}catch(e){return{steered:!1,detail:e instanceof Error?e.message:String(e)}}finally{await i?.close().catch(()=>{})}}async function It(e,t={}){let n=I(e);if(!n.available)throw Error(`Codex CLI is not available: ${n.detail}`);let r=t.prompt?.trim();if(!r)throw Error(`A prompt is required.`);return Mt(e,async n=>{let i;if(t.resumeThreadId)F(t.onProgress,`Resuming thread ${t.resumeThreadId}.`,`starting`),l(t.resumeThreadId)&&await d(t.resumeThreadId),i=(await n.request(`thread/resume`,{threadId:t.resumeThreadId,cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`})).thread.id;else{F(t.onProgress,`Starting Codex task thread.`,`starting`),i=(await n.request(`thread/start`,{cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`,serviceName:`coder_runtime`,ephemeral:t.ephemeral??!1})).thread.id;try{await n.request(`thread/name/set`,{threadId:i,name:mt(r)})}catch(e){let t=String(e?.message??e??``);if(!t.includes(`unknown variant`)&&!t.includes(`unknown method`))throw e}}F(t.onProgress,`Thread ready (${i}).`,`starting`,{threadId:i});let a=await jt(n,i,()=>n.request(`turn/start`,{threadId:i,input:[{type:`text`,text:r,text_elements:[]}],model:t.model??null,effort:t.effort??null,outputSchema:t.outputSchema??null}),{onProgress:t.onProgress,onHeartbeat:t.onHeartbeat,onApprovalRequest:t.onApprovalRequest});return{status:a.finalTurn?.status===`completed`?0:1,threadId:i,turnId:a.turnId,finalMessage:a.lastAgentMessage,reasoningSummary:a.reasoningSummary,turn:a.finalTurn,error:a.error,stderr:ft(n.stderr),fileChanges:a.fileChanges,touchedFiles:_t(a.fileChanges),tokens:yt(a),model:t.model??null,commandExecutions:a.commandExecutions}})}const Lt={chain:[`codex`,`claude`],agents:{codex:{model:`gpt-5.6-terra`,effort:`high`,permissions:`auto`},claude:{model:`opus`,effort:`medium`,permissions:`auto`}},models:{},approvals:{escalationTimeoutMs:12e4,allowedNetworkHosts:[]}},L={spark:`gpt-5.3-codex-spark`,luna:`gpt-5.6-luna`,terra:`gpt-5.6-terra`,sol:`gpt-5.6-sol`},R=new Set([`low`,`medium`,`high`]),z={sonnet:`sonnet`,opus:`opus`,fable:`fable`},B=new Set([`low`,`medium`,`high`]),Rt={"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`}},zt={"read-only":[`--permission-mode`,`dontAsk`,`--disallowedTools`,`Edit`,`Write`,`NotebookEdit`],"workspace-write":[`--permission-mode`,`acceptEdits`],auto:[`--permission-mode`,`auto`]},Bt=/failIfUnavailable|sandbox\b[^.\n]*?(?:failed|could ?n[o']t|cannot|unavailable|not available|not supported)/i;function Vt(e,t){return e===`read-only`?JSON.stringify({sandbox:{enabled:!0,failIfUnavailable:!0,autoAllowBashIfSandboxed:!0,filesystem:{denyWrite:[t]}}}):null}const Ht=E.enum([`codex`,`claude`]),Ut=E.enum([`codex`,`claude`,`custom`]),Wt=E.enum([`low`,`medium`,`high`]),Gt=E.enum([`read-only`,`workspace-write`,`auto`]),Kt=E.partial(E.strictObject({model:E.string().check(E.minLength(1)),effort:Wt,permissions:Gt})),qt=E.strictObject({baseUrl:E.url(),model:E.string().check(E.minLength(1)),envKey:E.optional(E.string().check(E.minLength(1))),wireApi:E.optional(E.enum([`chat`,`responses`])),disabled:E.optional(E.boolean())}),Jt=E.strictObject({provider:Ht,model:E.string().check(E.minLength(1)),effort:E.optional(Wt),disabled:E.optional(E.boolean())}),Yt=E.strictObject({disabled:E.boolean()}),Xt=E.union([qt,Jt,Yt]),Zt=E.strictObject({escalationTimeoutMs:E.number().check(E.positive()),allowedNetworkHosts:E.array(E.string())}),Qt=E.strictObject({chain:E.array(Ut).check(E.minLength(1)),agents:E.partial(E.strictObject({codex:Kt,claude:Kt,custom:Kt})),models:E.optional(E.record(E.string().check(E.regex(/^[a-z0-9][a-z0-9./_-]*$/i,`model name`)),Xt)),approvals:Zt}),$t=E.partial(E.extend(Qt,{approvals:E.partial(Zt)}));function V(e){return`baseUrl`in e}function H(e){return`provider`in e}function U(e){let t=$t.safeParse(e);if(!t.success)return t.error.issues.map(e=>`${e.path.join(`.`)||`config`}: ${e.message}`);let n=tn(Lt,t.data),r=[];for(let[e,i]of Object.entries(t.data.models??{})){if(e===`codex`||e===`claude`||e===`custom`){r.push(`models.${e}: reserved agent name`);continue}if(H(i)){let t=n.models?.[i.model];t&&!V(t)&&r.push(`models.${e}: alias target "${i.model}" is itself a config entry`)}}return r}function en(e){if(!S.existsSync(e))return null;try{return JSON.parse(S.readFileSync(e,`utf8`))}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`Invalid JSON in ${e}: ${n}`)}}function tn(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))i&&typeof i==`object`&&!Array.isArray(i)&&r?.[e]&&typeof r[e]==`object`?n[e]=tn(r[e],i):n[e]=i;return n}function W(){return C.join(s(),`config.json`)}function nn(e){let t=r(e),n=Lt;for(let e of[W(),C.join(t,`coder.config.json`)]){let t=en(e);if(!t)continue;let r=U(t);if(r.length)throw Error(`Invalid config in ${e}:\n ${r.join(`
|
|
9
|
+
`)}function pt(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=pt(e,56);return t?`${dt}: ${t}`:dt}function ht(e){return e?.params?.threadId??null}function gt(e){return e?.params?.turnId?e.params.turnId:e?.params?.turn?.id?e.params.turn.id:null}function _t(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 vt(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 yt(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 bt(e){return String(e??``).replace(/\s+/g,` `).trim()}function P(e){if(!e)return[];if(typeof e==`string`){let t=bt(e);return t?[t]:[]}if(Array.isArray(e))return e.flatMap(e=>P(e));if(typeof e==`object`){let t=e;if(typeof t.text==`string`)return P(t.text);if(`summary`in t)return P(t.summary);if(`content`in t)return P(t.content);if(`parts`in t)return P(t.parts)}return[]}function xt(e,t){let n=[];for(let r of[...e,...t]){let e=bt(r);!e||n.includes(e)||n.push(e)}return n}function F(e,t,n=null,r={}){!e||!t||e({message:t,phase:n,...r})}function St(e){switch(e.type){case`commandExecution`:return{message:`Running command: ${String(e.command??``).trim()}`,phase:`running`};case`fileChange`:return{message:`Applying ${e.changes.length} file change(s).`,phase:`editing`};case`mcpToolCall`:return{message:`Calling ${e.server}/${e.tool}.`,phase:`investigating`};case`dynamicToolCall`:return{message:`Running tool: ${e.tool}.`,phase:`investigating`};case`webSearch`:return{message:`Searching: ${String(e.query??``).trim()}`,phase:`investigating`};default:return null}}function Ct(e){switch(e.type){case`commandExecution`:{let t=String(e.aggregatedOutput??``).trim();return{message:`Command ${e.status===`completed`?`completed`:e.status}: ${String(e.command??``).trim()} (exit ${e.exitCode??`?`})`+(t?`\n${t}`:``),phase:`running`}}case`fileChange`:return{message:`File changes ${e.status}.`,phase:`editing`};case`mcpToolCall`:return{message:`Tool ${e.server}/${e.tool} ${e.status}.`,phase:`investigating`};case`dynamicToolCall`:return{message:`Tool ${e.tool} ${e.status}.`,phase:`investigating`};default:return null}}function wt(e,t={}){let n,r,i=new Promise((e,t)=>{n=e,r=t});return{threadId:e,rootThreadId:e,threadIds:new Set([e]),threadTurnIds:new Map,turnId:null,bufferedNotifications:[],completion:i,resolveCompletion:n,rejectCompletion:r,finalTurn:null,completed:!1,finalAnswerSeen:!1,pendingCollaborations:new Set,activeSubagentTurns:new Set,completionTimer:null,lastAgentMessage:``,reasoningSummary:[],error:null,fileChanges:[],commandExecutions:[],tokenUsageByThread:new Map,itemIndex:new Map,onProgress:t.onProgress??null,onHeartbeat:t.onHeartbeat??null}}function Tt(e){e.completionTimer&&=(clearTimeout(e.completionTimer),null)}function Et(e,t=null){e.completed||(Tt(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 Dt(e){e.completed||e.finalTurn||!e.finalAnswerSeen||e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||(Tt(e),e.completionTimer=setTimeout(()=>{e.completionTimer=null,!(e.completed||e.finalTurn||!e.finalAnswerSeen)&&(e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||Et(e,null))},250),e.completionTimer.unref?.())}function Ot(e,t){let n=ht(t);if(!n||!e.threadIds.has(n))return!1;let r=e.threadTurnIds.get(n)??null,i=gt(t);return r===null||i===null||i===r}function kt(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),Dt(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,Dt(e)));return}if(t.type===`reasoning`&&n===`completed`){e.reasoningSummary=xt(e.reasoningSummary,P(t.summary));return}if(t.type===`fileChange`&&n===`completed`){e.fileChanges.push(t);return}t.type===`commandExecution`&&n===`completed`&&e.commandExecutions.push(t)}function At(e,t){switch(e.onHeartbeat?.(),t.method){case`thread/started`:e.threadIds.add(t.params.thread.id);break;case`turn/started`:e.threadIds.add(t.params.threadId),e.threadTurnIds.set(t.params.threadId,t.params.turn.id),(t.params.threadId??null)!==e.threadId&&e.activeSubagentTurns.add(t.params.threadId),F(e.onProgress,`Turn started (${t.params.turn.id}).`,`starting`,{threadId:t.params.threadId??null,turnId:t.params.turn.id??null});break;case`item/started`:kt(e,t.params.item,`started`,t.params.threadId??null);{let n=St(t.params.item);F(e.onProgress,n?.message,n?.phase??null)}break;case`item/completed`:kt(e,t.params.item,`completed`,t.params.threadId??null);{let n=Ct(t.params.item);F(e.onProgress,n?.message,n?.phase??null)}break;case`thread/tokenUsage/updated`:{let n=vt(t.params?.tokenUsage?.total??t.params?.tokenUsage),r=ht(t);n&&r&&e.tokenUsageByThread.set(r,n);break}case`error`:e.error=t.params.error,F(e.onProgress,`Codex error: ${t.params.error.message}`,`failed`);break;case`turn/completed`:if((t.params.threadId??null)!==e.threadId){e.activeSubagentTurns.delete(t.params.threadId),Dt(e);break}F(e.onProgress,`Turn ${t.params.turn.status}.`,`finalizing`),Et(e,t.params.turn);break;default:break}}async function jt(e,t,n,r={}){let i=wt(t,r),a=e.notificationHandler;e.setNotificationHandler(e=>{if(!i.turnId){i.bufferedNotifications.push(e);return}if(e.method===`thread/started`){At(i,e);return}if(!Ot(i,e)){a?.(e);return}At(i,e)});let o=r.onApprovalRequest;o&&e.setServerRequestHandler((e,t)=>o(e,t,i));try{let e=await n();i.turnId=e.turn?.id??null,i.turnId&&i.threadTurnIds.set(i.threadId,i.turnId);for(let e of i.bufferedNotifications)Ot(i,e)?At(i,e):a?.(e);return i.bufferedNotifications.length=0,e.turn?.status&&e.turn.status!==`inProgress`&&Et(i,e.turn),await i.completion}finally{Tt(i),e.setNotificationHandler(a??null),e.setServerRequestHandler(null)}}async function Mt(e,t){let n=null;try{n=await _.connect(e);let r=await t(n);return await n.close(),r}catch(r){let i=r,a=n?.transport===`broker`||!!process.env.CODER_APP_SERVER_ENDPOINT,o=n?.transport===`broker`&&i?.rpcCode===-32001||a&&(i?.code===`ENOENT`||i?.code===`ECONNREFUSED`);if(n&&=(await n.close().catch(()=>{}),null),!o)throw r;let s=await _.connect(e,{disableBroker:!0});try{return await t(s)}finally{await s.close()}}}function I(e){let t=ee(`codex`,[`--version`],{cwd:e});if(!t.available)return t;let n=ee(`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 Nt(e){let t=I(e);if(!t.available)return{available:!1,loggedIn:!1,detail:t.detail};let n=null;try{n=await _.connect(e,{reuseExistingBroker:!0});let t=await n.request(`account/read`,{refreshToken:!1}),r=t?.account??null;return r?.type===`chatgpt`?{available:!0,loggedIn:!0,detail:r.email?`ChatGPT login active for ${r.email}`:`ChatGPT login active`}:r?.type===`apiKey`?{available:!0,loggedIn:!0,detail:`API key configured`}:t?.requiresOpenaiAuth===!1?{available:!0,loggedIn:!0,detail:`Active provider does not require OpenAI authentication`}:{available:!0,loggedIn:!1,detail:"Not authenticated. Run `codex login`."}}catch(e){let t=T(`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 Pt(e,{threadId:t,turnId:n}){if(!t||!n)return{interrupted:!1,detail:`missing threadId or turnId`};let r=null;try{return r=await _.connect(e,{reuseExistingBroker:!0}),await r.request(`turn/interrupt`,{threadId:t,turnId:n}),{interrupted:!0,detail:`Interrupted ${n} on ${t}.`}}catch(e){return{interrupted:!1,detail:e instanceof Error?e.message:String(e)}}finally{await r?.close().catch(()=>{})}}async function Ft(e,{threadId:t,text:n}){if(!t)return{steered:!1,detail:`missing threadId`};let r=n.trim();if(!r)return{steered:!1,detail:`empty follow-up`};let i=null;try{return i=await _.connect(e,{reuseExistingBroker:!0}),await i.request(`turn/steer`,{threadId:t,input:[{type:`text`,text:r,text_elements:[]}]}),{steered:!0,detail:`Steered follow-up into the active turn on ${t}.`}}catch(e){return{steered:!1,detail:e instanceof Error?e.message:String(e)}}finally{await i?.close().catch(()=>{})}}async function It(e,t={}){let n=I(e);if(!n.available)throw Error(`Codex CLI is not available: ${n.detail}`);let r=t.prompt?.trim();if(!r)throw Error(`A prompt is required.`);return Mt(e,async n=>{let i;if(t.resumeThreadId)F(t.onProgress,`Resuming thread ${t.resumeThreadId}.`,`starting`),l(t.resumeThreadId)&&await d(t.resumeThreadId),i=(await n.request(`thread/resume`,{threadId:t.resumeThreadId,cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`})).thread.id;else{F(t.onProgress,`Starting Codex task thread.`,`starting`),i=(await n.request(`thread/start`,{cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`,serviceName:`coder_runtime`,ephemeral:t.ephemeral??!1})).thread.id;try{await n.request(`thread/name/set`,{threadId:i,name:mt(r)})}catch(e){let t=String(e?.message??e??``);if(!t.includes(`unknown variant`)&&!t.includes(`unknown method`))throw e}}F(t.onProgress,`Thread ready (${i}).`,`starting`,{threadId:i});let a=await jt(n,i,()=>n.request(`turn/start`,{threadId:i,input:[{type:`text`,text:r,text_elements:[]}],model:t.model??null,effort:t.effort??null,outputSchema:t.outputSchema??null}),{onProgress:t.onProgress,onHeartbeat:t.onHeartbeat,onApprovalRequest:t.onApprovalRequest});return{status:a.finalTurn?.status===`completed`?0:1,threadId:i,turnId:a.turnId,finalMessage:a.lastAgentMessage,reasoningSummary:a.reasoningSummary,turn:a.finalTurn,error:a.error,stderr:ft(n.stderr),fileChanges:a.fileChanges,touchedFiles:_t(a.fileChanges),tokens:yt(a),model:t.model??null,commandExecutions:a.commandExecutions}})}const Lt={chain:[`codex`,`claude`],agents:{codex:{model:`gpt-5.6-terra`,effort:`high`,permissions:`auto`},claude:{model:`opus`,effort:`medium`,permissions:`auto`}},models:{},approvals:{escalationTimeoutMs:12e4,allowedNetworkHosts:[]}},L={mini:`gpt-5.4-mini`,luna:`gpt-5.6-luna`,terra:`gpt-5.6-terra`,sol:`gpt-5.6-sol`},R=new Set([`low`,`medium`,`high`]),z={haiku:`haiku`,sonnet:`sonnet`,opus:`opus`,fable:`fable`},B=new Set([`low`,`medium`,`high`]),Rt={"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`}},zt={"read-only":[`--permission-mode`,`dontAsk`,`--disallowedTools`,`Edit`,`Write`,`NotebookEdit`],"workspace-write":[`--permission-mode`,`acceptEdits`],auto:[`--permission-mode`,`auto`]},Bt=/failIfUnavailable|sandbox\b[^.\n]*?(?:failed|could ?n[o']t|cannot|unavailable|not available|not supported)/i;function Vt(e,t){return e===`read-only`?JSON.stringify({sandbox:{enabled:!0,failIfUnavailable:!0,autoAllowBashIfSandboxed:!0,filesystem:{denyWrite:[t]}}}):null}const Ht=E.enum([`codex`,`claude`]),Ut=E.enum([`codex`,`claude`,`custom`]),Wt=E.enum([`low`,`medium`,`high`]),Gt=E.enum([`read-only`,`workspace-write`,`auto`]),Kt=E.partial(E.strictObject({model:E.string().check(E.minLength(1)),effort:Wt,permissions:Gt})),qt=E.strictObject({baseUrl:E.url(),model:E.string().check(E.minLength(1)),envKey:E.optional(E.string().check(E.minLength(1))),wireApi:E.optional(E.enum([`chat`,`responses`])),disabled:E.optional(E.boolean())}),Jt=E.strictObject({provider:Ht,model:E.string().check(E.minLength(1)),effort:E.optional(Wt),disabled:E.optional(E.boolean())}),Yt=E.strictObject({disabled:E.boolean()}),Xt=E.union([qt,Jt,Yt]),Zt=E.strictObject({escalationTimeoutMs:E.number().check(E.positive()),allowedNetworkHosts:E.array(E.string())}),Qt=E.strictObject({chain:E.array(Ut).check(E.minLength(1)),agents:E.partial(E.strictObject({codex:Kt,claude:Kt,custom:Kt})),models:E.optional(E.record(E.string().check(E.regex(/^[a-z0-9][a-z0-9./_-]*$/i,`model name`)),Xt)),approvals:Zt}),$t=E.partial(E.extend(Qt,{approvals:E.partial(Zt)}));function V(e){return`baseUrl`in e}function H(e){return`provider`in e}function U(e){let t=$t.safeParse(e);if(!t.success)return t.error.issues.map(e=>`${e.path.join(`.`)||`config`}: ${e.message}`);let n=tn(Lt,t.data),r=[];for(let[e,i]of Object.entries(t.data.models??{})){if(e===`codex`||e===`claude`||e===`custom`){r.push(`models.${e}: reserved agent name`);continue}if(H(i)){let t=n.models?.[i.model];t&&!V(t)&&r.push(`models.${e}: alias target "${i.model}" is itself a config entry`)}}return r}function en(e){if(!S.existsSync(e))return null;try{return JSON.parse(S.readFileSync(e,`utf8`))}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`Invalid JSON in ${e}: ${n}`)}}function tn(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))i&&typeof i==`object`&&!Array.isArray(i)&&r?.[e]&&typeof r[e]==`object`?n[e]=tn(r[e],i):n[e]=i;return n}function W(){return C.join(s(),`config.json`)}function nn(e){let t=r(e),n=Lt;for(let e of[W(),C.join(t,`coder.config.json`)]){let t=en(e);if(!t)continue;let r=U(t);if(r.length)throw Error(`Invalid config in ${e}:\n ${r.join(`
|
|
10
10
|
`)}`);n=tn(n,t)}let i=U(n);if(i.length)throw Error(`Invalid merged config:\n ${i.join(`
|
|
11
11
|
`)}`);return n}function rn(e){return e.replace(/\/+$/,``).replace(/\/(chat\/completions|completions|responses)$/,``)}function an(e,t,n){let i=[C.join(r(e),`coder.config.json`),W()];for(let e of i){let r;try{r=en(e)}catch{continue}if(r?.models?.[t])return Object.assign(r.models[t],n),U(r).length?!1:(S.writeFileSync(e,`${JSON.stringify(r,null,2)}\n`,`utf8`),!0)}return!1}function on(e){return/\/(chat\/completions|completions|responses)\/*$/.test(e)}function sn(e,t){let n=rn(e);return on(e)||/\/v\d+(alpha|beta)?$/.test(n)?[`${n}/${t}`]:[`${n}/${t}`,`${n}/v1/${t}`]}function cn(e,t,n){let r=t?e.models?.[t]:void 0;if(!t||!r||!V(r))return null;let i=`coder-${t}`;return{model:r.model,modelProvider:i,configOverrides:{[`model_providers.${i}`]:{name:t,base_url:n?.url??rn(r.baseUrl),...r.envKey&&!n?{env_key:r.envKey}:{},wire_api:`responses`}}}}function ln(e){return e?L[e]??e:null}function un(e){return e in L||e in z}function dn(e,t){return!!(t&&e.models?.[t]?.disabled)}function fn(e,t){if(dn(e,t))throw Error(`model "${t}" is disabled in config`)}function pn(e,t){if(!e)return null;let n=String(e).trim().split(`:`).map(e=>e.trim());if(!n.length||n.length>3||n.some(e=>!e))throw Error(`Invalid agent spec "${e}".`);let r=null,i=null,a=null,o=e=>R.has(e)||B.has(e);for(let t of n)if(t===`codex`||t===`claude`||t===`custom`){if(r)throw Error(`Invalid agent spec "${e}".`);r=t}else if(o(t)&&!a)a=t;else if(!i)i=t;else throw Error(`Invalid agent spec "${e}".`);let s=i?t.models?.[i]:void 0;if(s&&H(s)){if(s.disabled)throw Error(`model "${i}" is disabled in config`);if(r&&r!==s.provider)throw Error(`Alias "${i}" runs on ${s.provider}, not ${r}.`);r=s.provider,a=a??s.effort??null,i=s.model}r||=i&&i in z?`claude`:i&&s&&V(s)?`custom`:`codex`;let c=t.agents[r]??{},l=i??c.model??null;return fn(t,l),{agent:r,model:l,effort:a??c.effort??null}}function mn(e){let t=W();return S.mkdirSync(C.dirname(t),{recursive:!0}),S.writeFileSync(t,`${JSON.stringify(e,null,2)}\n`,`utf8`),t}function hn(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 gn(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 _n(){let e=T(`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 vn(){let e=T(`claude`,[`auth`,`status`,`--json`],{encoding:`utf8`});if(e.error||e.status!==0)return{loggedIn:!1,detail:`not logged in`};try{let t=JSON.parse(String(e.stdout||``));return t.loggedIn?{loggedIn:!0,detail:[t.email,t.subscriptionType].filter(Boolean).join(`, `)||`logged in`}:{loggedIn:!1,detail:`not logged in`}}catch{return{loggedIn:!1,detail:`unknown`}}}async function yn(e,t){let n=t.resumeSessionId??le(),r=[`-p`,t.prompt,`--output-format`,`stream-json`,`--verbose`];r.push(t.resumeSessionId?`--resume`:`--session-id`,n),t.model&&r.push(`--model`,t.model),t.effort&&r.push(`--effort`,t.effort);let i=t.permissions??`auto`;r.push(...zt[i]??zt.auto);let a=Vt(i,e);return a&&r.push(`--settings`,a),t.onProgress?.({message:`claude turn started (session ${n})`,threadId:n}),new Promise((i,a)=>{let o=w(`claude`,r,{cwd:e,stdio:[`ignore`,`pipe`,`pipe`]}),s=``,c=``,l=null,u=n,d=e=>{if(!(!e||typeof e!=`object`))if(t.onHeartbeat?.(),e.type===`system`&&e.subtype===`init`&&e.session_id)u=e.session_id;else if(e.type===`assistant`)for(let n of e.message?.content??[])n?.type===`tool_use`&&t.onProgress?.({message:`${n.name} ${JSON.stringify(n.input??{})}`,threadId:u});else if(e.type===`user`){for(let n of e.message?.content??[])if(n?.type===`tool_result`){let e=hn(n.content).trim();e&&t.onProgress?.({message:e,threadId:u})}}else e.type===`result`&&(l=e,e.session_id&&(u=e.session_id))};o.stdout.on(`data`,e=>{s+=e;let t;for(;(t=s.indexOf(`
|
|
12
12
|
`))>=0;){let e=s.slice(0,t).trim();if(s=s.slice(t+1),e)try{d(JSON.parse(e))}catch{}}}),o.stderr.on(`data`,e=>{c+=e});let f=()=>{o.kill(`SIGTERM`),process.exit(143)};process.on(`SIGTERM`,f),o.on(`error`,e=>{process.removeListener(`SIGTERM`,f),a(Error(`claude spawn failed: ${e.message}`))}),o.on(`close`,e=>{process.removeListener(`SIGTERM`,f);let n=s.trim();if(n)try{d(JSON.parse(n))}catch{}let r=l?.result??``,a=e!==0||l?.is_error===!0||l==null;i({status:+!!a,threadId:l?.session_id??u,turnId:null,finalMessage:r,tokens:gn(l?.usage),model:l?.modelUsage&&Object.keys(l.modelUsage).join(`+`)||t.model||null,error:a?{message:r||c.trim()||`claude exited ${e}`}:null})})})}function bn(e){T(`claude`,[`plugin`,`marketplace`,`remove`,`coder-plugins`],{encoding:`utf8`});let t=T(`claude`,[`plugin`,`marketplace`,`add`,e],{encoding:`utf8`}),n=T(`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 xn(){return C.join(ae.homedir(),`.agents`,`skills`,`coder`)}function Sn(){try{let e=S.readFileSync(C.join(xn(),`SKILL.md`),`utf8`);return/^\s*version:\s*(\S+)/m.exec(e)?.[1]??null}catch{return null}}function Cn(e){let t=xn();try{let n=C.join(e,`plugins`,`agents`,`skills`,`coder`);S.rmSync(t,{recursive:!0,force:!0}),S.mkdirSync(t,{recursive:!0}),S.cpSync(n,t,{recursive:!0});let r=C.join(t,`SKILL.md`),i=S.readFileSync(r,`utf8`).replace(`
|
package/dist/sdk.d.ts
CHANGED
|
@@ -318,7 +318,7 @@ declare const model: {
|
|
|
318
318
|
name: string;
|
|
319
319
|
}[];
|
|
320
320
|
}>;
|
|
321
|
-
/** Alias a name to an engine spec, e.g. alias('fast', 'codex:
|
|
321
|
+
/** Alias a name to an engine spec, e.g. alias('fast', 'codex:mini'). */
|
|
322
322
|
alias: (
|
|
323
323
|
name: string,
|
|
324
324
|
spec: string,
|
|
@@ -630,7 +630,7 @@ declare const _default: {
|
|
|
630
630
|
name: string;
|
|
631
631
|
}[];
|
|
632
632
|
}>;
|
|
633
|
-
/** Alias a name to an engine spec, e.g. alias('fast', 'codex:
|
|
633
|
+
/** Alias a name to an engine spec, e.g. alias('fast', 'codex:mini'). */
|
|
634
634
|
alias: (
|
|
635
635
|
name: string,
|
|
636
636
|
spec: string,
|
package/dist/sdk.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e,F as t,v as n,x as r}from"./app-server-Dwd7IcQH.js";import{E as i,I as a,M as o,R as s,xt as c,yt as l,z as u}from"./runtime-
|
|
1
|
+
import{C as e,F as t,v as n,x as r}from"./app-server-Dwd7IcQH.js";import{E as i,I as a,M as o,R as s,xt as c,yt as l,z as u}from"./runtime-DRtQOCSz.js";import{C as d,T as f,_ as p,b as m,c as h,d as g,f as _,g as v,i as y,l as b,m as x,n as S,o as C,s as w,u as T,y as E}from"./upgrade-DFAtgbtD.js";import D from"./flow/index.js";import O from"node:process";import k from"node:path";function A(e){return e?k.resolve(e):O.cwd()}function j(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 M={async run(e,t={}){let{taskId:n}=await a({prompt:e,cwd:A(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=A(t.cwd),r=e??j(n).id;return t.wait?u(n,r,{tail:t.tail}):s(n,r,{tail:t.tail})},list(e={}){return m(A(e.cwd),e).jobs},async steer(e,t,n={}){let r=A(n.cwd);return d(r,j(r,e),t)},async stop(e,t={}){let n=A(t.cwd);return i(n,j(n,e))},archive(e,t={}){let r=A(t.cwd);return n(r,j(r,e)),{taskId:e,archived:!0}},delete(e,t={}){let n=A(t.cwd),i=j(n,e);if(i.status===`running`)throw Error(`Task ${i.id} is still running.`);E(i);let a=r(n,i.id);return{taskId:i.id,deleted:a}},approve(e,n,r={}){let i=A(r.cwd),a=j(i,e),o=r.deny?`decline`:`accept`;return l(t(i,a.id),n,o),{taskId:a.id,approvalId:n,decision:o}},approvals(e,n={}){let r=A(n.cwd);return c(t(r,(e?j(r,e):j(r)).id))},stream(e,t={}){let n=A(t.cwd);return f(n,e??j(n).id,{tail:t.tail})}},N={add:(e,t)=>C(A(t.cwd),e,t),update:(e,t)=>_(A(t.cwd),e,t),remove:(e,t={})=>b(A(t.cwd),e,t),list:(e={})=>h(A(e.cwd)),alias:(e,t,n={})=>w(A(n.cwd),e,t,n),unalias:(e,t={})=>g(A(t.cwd),e,t),disable:(e,t={})=>T(A(t.cwd),e,!0,t),enable:(e,t={})=>T(A(t.cwd),e,!1,t)},P={get:(e,t={})=>v(A(t.cwd),e),set:(e,t,n={})=>p(A(n.cwd),e,t,n)};function F(e=[],t={}){return x(A(t.cwd),{claude:e.includes(`claude`),codex:e.includes(`codex`),agents:e.includes(`agents`)})}function I(e={}){return S(e)}function L(e){return y(e)}var R={task:M,flow:D,model:N,config:P,setupHost:F,upgrade:I,docs:L};export{o as CoderError,P as config,R as default,L as docs,D as flow,N as model,F as setupHost,M as task,I as upgrade};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{B as e,D as t,E as n,F as r,H as i,I as a,L as o,N as s,O as c,R as l,S as u,V as d,_ as f,b as p,c as m,d as h,f as g,h as _,j as v,k as y,l as b,m as x,o as S,p as ee,s as C,u as w,x as te,z as T}from"./app-server-Dwd7IcQH.js";import{$ as ne,$t as E,B as re,Bt as D,Ct as ie,Dt as ae,Et as oe,F as se,Ft as ce,G as le,Gt as ue,H as de,I as fe,It as O,J as pe,Jt as me,K as he,L as ge,Lt as _e,M as ve,N as ye,Nt as be,Pt as k,Q as A,Qt as j,Rt as xe,St as Se,Tt as Ce,U as we,Ut as Te,V as Ee,W as De,Wt as M,X as N,Xt as Oe,Y as ke,Yt as P,Z as Ae,Zt as F,_t as je,at as I,bt as Me,ct as Ne,dt as L,en as Pe,et as Fe,ft as Ie,g as Le,gt as Re,ht as R,it as z,k as ze,lt as Be,mt as Ve,nt as B,ot as V,pt as He,q as Ue,qt as H,rn as We,rt as U,st as Ge,tt as W,ut as Ke,wt as qe,z as Je,zt as Ye}from"./runtime-
|
|
1
|
+
import{B as e,D as t,E as n,F as r,H as i,I as a,L as o,N as s,O as c,R as l,S as u,V as d,_ as f,b as p,c as m,d as h,f as g,h as _,j as v,k as y,l as b,m as x,o as S,p as ee,s as C,u as w,x as te,z as T}from"./app-server-Dwd7IcQH.js";import{$ as ne,$t as E,B as re,Bt as D,Ct as ie,Dt as ae,Et as oe,F as se,Ft as ce,G as le,Gt as ue,H as de,I as fe,It as O,J as pe,Jt as me,K as he,L as ge,Lt as _e,M as ve,N as ye,Nt as be,Pt as k,Q as A,Qt as j,Rt as xe,St as Se,Tt as Ce,U as we,Ut as Te,V as Ee,W as De,Wt as M,X as N,Xt as Oe,Y as ke,Yt as P,Z as Ae,Zt as F,_t as je,at as I,bt as Me,ct as Ne,dt as L,en as Pe,et as Fe,ft as Ie,g as Le,gt as Re,ht as R,it as z,k as ze,lt as Be,mt as Ve,nt as B,ot as V,pt as He,q as Ue,qt as H,rn as We,rt as U,st as Ge,tt as W,ut as Ke,wt as qe,z as Je,zt as Ye}from"./runtime-DRtQOCSz.js";import G from"node:process";import K from"node:fs";import q from"node:path";import{spawnSync as Xe}from"node:child_process";import Ze from"node:os";import{fileURLToPath as Qe}from"node:url";import*as J from"zod/mini";import $e from"node:crypto";import et from"node:http";let tt=0;function nt(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}default:break}return t}function rt(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:nt(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 it=class{send;model;responseId=`resp_bridge_${++tt}`;text=``;textOpen=!1;toolCalls=new Map;usage=null;buffer=``;constructor(e,t){this.model=e,this.send=t,this.send({type:`response.created`,response:{id:this.responseId,object:`response`,status:`in_progress`,model:e,output:[]}})}push(e){this.buffer+=e;let t=this.buffer.split(`
|
|
2
2
|
`);this.buffer=t.pop()??``;for(let e of t){let t=e.trim();if(!t.startsWith(`data:`))continue;let n=t.slice(5).trim();if(!n||n===`[DONE]`)continue;let r;try{r=JSON.parse(n)}catch{continue}r.usage&&(this.usage=r.usage);let i=r.choices?.[0]?.delta;if(i){typeof i.content==`string`&&i.content&&(this.textOpen||(this.textOpen=!0,this.send({type:`response.output_item.added`,output_index:0,item:{type:`message`,id:`msg_bridge_0`,status:`in_progress`,role:`assistant`,content:[]}})),this.text+=i.content,this.send({type:`response.output_text.delta`,item_id:`msg_bridge_0`,output_index:0,content_index:0,delta:i.content}));for(let e of i.tool_calls??[]){let t=this.toolCalls.get(e.index)??{id:``,name:``,args:``};e.id&&(t.id=e.id),e.function?.name&&(t.name+=e.function.name),e.function?.arguments&&(t.args+=e.function.arguments),this.toolCalls.set(e.index,t)}}}}finish(){let e=[];if(this.text){let t={type:`message`,id:`msg_bridge_0`,status:`completed`,role:`assistant`,content:[{type:`output_text`,text:this.text,annotations:[]}]};e.push(t),this.send({type:`response.output_item.done`,output_index:0,item:t})}let t=e.length;for(let n of this.toolCalls.values()){let r={type:`function_call`,id:`fc_bridge_${t}`,call_id:n.id||`call_bridge_${t}`,name:n.name,arguments:n.args||`{}`,status:`completed`};e.push(r),this.send({type:`response.output_item.done`,output_index:t,item:r}),t+=1}this.send({type:`response.completed`,response:{id:this.responseId,object:`response`,status:`completed`,model:this.model,output:e,usage:{input_tokens:this.usage?.prompt_tokens??0,input_tokens_details:{cached_tokens:this.usage?.prompt_tokens_details?.cached_tokens??0},output_tokens:this.usage?.completion_tokens??0,output_tokens_details:{reasoning_tokens:this.usage?.completion_tokens_details?.reasoning_tokens??0},total_tokens:this.usage?.total_tokens??0}}})}};async function at(e,t=`chat`){let n=t===`responses`,r=W(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=$e.randomBytes(16).toString(`hex`),c=et.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(rt(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 it(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 ot(e,t,n){let r=e.envKey?G.env[e.envKey]:void 0,i=!1;for(let a of W(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 st(e){let t=await ot(e,`responses`,{model:e.model,input:[],stream:!1});if(`baseUrl`in t)return{wireApi:`responses`,baseUrl:t.baseUrl};let n=await ot(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}function ct(e){return e.resumeThreadId?e.prompt??``:`<system>
|
|
3
3
|
You are running inside a coder task: do the work yourself, directly.
|
|
4
4
|
Do not load the coder skill (recursive), and never dispatch through the \`coder\` CLI - nested dispatch is disabled.
|
|
@@ -17,10 +17,10 @@ ${e.prompt??``}`}function lt(e,t){let n=0;return()=>{Date.now()-n>=1e4&&(n=Date.
|
|
|
17
17
|
`)+`
|
|
18
18
|
`);return}if(i===`get`){a||O(`Usage: coder config get <key> (e.g. chain, agents.codex.model)`);let e=X(I(r),a);if(t.json||e===null||typeof e==`object`&&e!==void 0){P(e===void 0?null:e);return}G.stdout.write(`${e===void 0?`(unset)`:String(e)}\n`);return}i!==`set`&&i!==`unset`&&O(`Usage: coder config [get|set|unset] <key> [value] [--workspace]`),(!a||i===`set`&&o.length===0)&&O(`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}=Mt(r,a,l,{workspace:t.workspace,unset:i===`unset`}))}catch(e){O(e instanceof Error?e.message:String(e))}if(t.json){P({file:s,key:a,...i===`set`?{value:l}:{unset:!0},effective:u});return}let d=H,f=i===`set`?`${d.cyan(a)} = ${JSON.stringify(l)}`:`unset ${d.cyan(a)}`;G.stdout.write(`${f} ${d.dim(`(${s})`)}\n`)}async function Pt(e,t={}){let n=R(e),r=de(n);r?.updated&&(n=R(e));let i=n.available?await Ve(e):{loggedIn:!1,detail:n.detail},a=Ue(),o=a.available?he():{loggedIn:!1,detail:a.detail},s=L();if(!K.existsSync(s)){let e=n.available?[`codex`,`claude`]:a.available?[`claude`,`codex`]:[`codex`,`claude`];He({...ne,chain:e})}let c=_(),l=t.claude?De(c):null,u=t.agents||t.codex?we(c):null,d=I(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:Qe(new URL(`../bin/coder.mjs`,import.meta.url)),...l?{claudePlugin:l}:{},...u?{agentsSkill:u}:{},config:d,ready:f}}async function Ft(e){let{options:t,positionals:n}=b(e,J.object({...S,codex:C,claude:C,agents:C})),r=E(t),i=[`claude`,`codex`,`agents`];for(let e of n)i.includes(e)||O(`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=H.bold,o=H.dim;t.json||G.stdout.write(`${a(`Coder host setup`)}\n\n`);let s=await Pt(r,{claude:t.claude,codex:t.codex,agents:t.agents});if(t.json){P(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}`)}`):k(`codex not logged in ${o(`(${c.auth})`)} - run: codex login`):k(`codex CLI not installed - run: npm install -g @openai/codex`),v=l.available?l.loggedIn?M(`claude ${o(`${l.detail}; ${l.auth}`)}`):k(`claude not logged in - run: claude auth login`):k(`claude CLI not installed - run: npm install -g @anthropic-ai/claude-code`);g.push(a(`Available Engines`),_,v,` ${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(k(`codex ${u.note}`)),g.push(``);let y=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: ${y(`codex`)} claude: ${y(`claude`)}`,` ${o(f)} ${o(`(coder config set <key> <value> to change)`)}`,``);let x=[[`claude plugin`,p??null],[`agents skill `,m??null]];for(let[e,t]of x)t&&g.push(t.installed?M(`${e} ${o(t.note)}`):k(`${e} ${t.note}`),``);g.push(h?M(`ready - try: coder run --wait "explain this repo's layout"`):k(`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(`
|
|
19
19
|
`)}\n`)}const It=new Set([`codex`,`claude`,`custom`]);async function Lt(e){let t=e.envKey?G.env[e.envKey]:void 0,n=W(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 Rt(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=Ie(n);r.length&&O(`Refusing to write invalid config:\n ${r.join(`
|
|
20
|
-
`)}`),K.mkdirSync(q.dirname(e),{recursive:!0}),K.writeFileSync(e,`${JSON.stringify(n,null,2)}\n`,`utf8`)}function Z(e,t){Rt(e,e=>{e.models=e.models??{},t(e.models)})}const Q=J.object({...S,"base-url":w,model:w,"env-key":w,workspace:C});function $(e,t){return e.workspace?q.join(a(t),`coder.config.json`):L()}function zt(e){let t=e.models??{},n=Object.entries(t).filter(e=>z(e[1])),r=e=>`${e.provider}:${e.model}${e.effort?`:${e.effort}`:``}`,i=Object.entries(t).filter(e=>B(e[1])).map(([e,t])=>{let n=t.provider===`claude`?N:A,i=n[t.model]??t.model,a=U(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])=>!z(t)&&!B(t)&&!U(e)).map(([e,t])=>({name:e,disabled:!!t.disabled})),disabled:o}}async function Bt(e){let{endpoints:t,providerRows:n,toggledSlugs:r}=zt(I(e)),i=await Promise.all(t.map(async([e,t])=>({name:e,...t,probe:await Lt(t)})));return{codex:n(`codex`,A),claude:n(`claude`,N),custom:i,...r.length?{toggles:r}:{}}}async function Vt(e){let{options:t,positionals:n}=b(e,Q);n.length&&O(`model list takes no arguments.`,{hint:`Usage: coder model list [--json]`});let r=E(t),i=H,{endpoints:a,providerRows:o,toggledSlugs:s,disabled:c}=zt(I(r));if(t.json){P(await Bt(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`,A),f(`Claude models`,`claude`,N),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 Lt(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:
|
|
20
|
+
`)}`),K.mkdirSync(q.dirname(e),{recursive:!0}),K.writeFileSync(e,`${JSON.stringify(n,null,2)}\n`,`utf8`)}function Z(e,t){Rt(e,e=>{e.models=e.models??{},t(e.models)})}const Q=J.object({...S,"base-url":w,model:w,"env-key":w,workspace:C});function $(e,t){return e.workspace?q.join(a(t),`coder.config.json`):L()}function zt(e){let t=e.models??{},n=Object.entries(t).filter(e=>z(e[1])),r=e=>`${e.provider}:${e.model}${e.effort?`:${e.effort}`:``}`,i=Object.entries(t).filter(e=>B(e[1])).map(([e,t])=>{let n=t.provider===`claude`?N:A,i=n[t.model]??t.model,a=U(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])=>!z(t)&&!B(t)&&!U(e)).map(([e,t])=>({name:e,disabled:!!t.disabled})),disabled:o}}async function Bt(e){let{endpoints:t,providerRows:n,toggledSlugs:r}=zt(I(e)),i=await Promise.all(t.map(async([e,t])=>({name:e,...t,probe:await Lt(t)})));return{codex:n(`codex`,A),claude:n(`claude`,N),custom:i,...r.length?{toggles:r}:{}}}async function Vt(e){let{options:t,positionals:n}=b(e,Q);n.length&&O(`model list takes no arguments.`,{hint:`Usage: coder model list [--json]`});let r=E(t),i=H,{endpoints:a,providerRows:o,toggledSlugs:s,disabled:c}=zt(I(r));if(t.json){P(await Bt(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`,A),f(`Claude models`,`claude`,N),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 Lt(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:mini)`),i.dim(`Use one: coder run --model <name> "<task>" (or coder run --agent custom)`)),G.stdout.write(`${d.join(`
|
|
21
21
|
`)}\n`)}async function Ht(e,t,n,r){let i=await st(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 Lt(t),s=Ee(R(r)),c=R(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 Ut(e,t,n,r,i){let a=$(n,r),o=H,{probe:s,codex:c,install:l,nativeResponses:u,keyMissing:d}=await Ht(e,t,a,r);if(n.json){P({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(`
|
|
22
22
|
`))),G.stdout.write(`${m.join(`
|
|
23
|
-
`)}\n`)}function Wt(e,t,n){return e||O(`Missing model name.`,{hint:t}),/^[a-z][a-z0-9-]*$/.test(e)||O(`Invalid model name "${e}". Use lowercase kebab-case (e.g. qwen-local).`),(It.has(e)||n===`model`&&U(e))&&O(`"${e}" is reserved; pick another name.`),e}async function Gt(e){let t=`Usage: coder model add <name> --base-url <url> --model <id> [--env-key VAR]`,{options:n,positionals:r}=b(e,Q),i=E(n),a=Wt(r[0],t,`model`),o=I(i).models?.[a];o&&O(z(o)?`Custom model "${a}" already exists.`:`"${a}" is already configured as an ${B(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)&&O(`Missing --base-url or --model.`,{hint:t}),await Ut(a,{baseUrl:V(n[`base-url`]),model:n.model,...n[`env-key`]?{envKey:n[`env-key`]}:{}},n,i,`saved`)}async function Kt(e){let t=`Usage: coder model update <name> [--base-url <url>] [--model <id>] [--env-key VAR]`,{options:n,positionals:r}=b(e,Q),i=E(n),a=r[0],o=a?I(i).models?.[a]:void 0,s=o&&z(o)?o:void 0;(!a||!s)&&O(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`]&&O(`Nothing to update: pass --base-url, --model, or --env-key.`,{hint:t}),await Ut(a,{...s,...n[`base-url`]?{baseUrl:V(n[`base-url`])}:{},...n.model?{model:n.model}:{},...n[`env-key`]?{envKey:n[`env-key`]}:{}},n,i,`updated`)}async function qt(e){let{options:t,positionals:n}=b(e,Q),r=E(t),i=n[0],a;try{a=nn(r,i??``,{workspace:t.workspace})}catch(e){O(e instanceof Error?e.message:String(e),{hint:i?`List them: coder model list`:`Usage: coder model remove <name>`})}if(t.json){P(a);return}G.stdout.write(`removed ${H.cyan(a.removed)} ${H.dim(`(${a.file})`)}\n`)}async function Jt(e){await Xt(e,!0)}async function Yt(e){await Xt(e,!1)}async function Xt(e,t){let n=t?`disable`:`enable`,r=`Usage: coder model ${n} <name>`,{options:i,positionals:a}=b(e,Q),o=E(i),s=a[0];s||O(`Missing model name.`,{hint:r});let{file:c}=on(o,s,t,{workspace:i.workspace});if(i.json){P({[t?`disabled`:`enabled`]:s,file:c});return}G.stdout.write(`${n}d ${H.cyan(s)} ${H.dim(`(${c})`)}\n`)}async function Zt(e){let t=`Usage: coder model alias <name> <spec> (e.g. coder model alias fast codex:
|
|
23
|
+
`)}\n`)}function Wt(e,t,n){return e||O(`Missing model name.`,{hint:t}),/^[a-z][a-z0-9-]*$/.test(e)||O(`Invalid model name "${e}". Use lowercase kebab-case (e.g. qwen-local).`),(It.has(e)||n===`model`&&U(e))&&O(`"${e}" is reserved; pick another name.`),e}async function Gt(e){let t=`Usage: coder model add <name> --base-url <url> --model <id> [--env-key VAR]`,{options:n,positionals:r}=b(e,Q),i=E(n),a=Wt(r[0],t,`model`),o=I(i).models?.[a];o&&O(z(o)?`Custom model "${a}" already exists.`:`"${a}" is already configured as an ${B(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)&&O(`Missing --base-url or --model.`,{hint:t}),await Ut(a,{baseUrl:V(n[`base-url`]),model:n.model,...n[`env-key`]?{envKey:n[`env-key`]}:{}},n,i,`saved`)}async function Kt(e){let t=`Usage: coder model update <name> [--base-url <url>] [--model <id>] [--env-key VAR]`,{options:n,positionals:r}=b(e,Q),i=E(n),a=r[0],o=a?I(i).models?.[a]:void 0,s=o&&z(o)?o:void 0;(!a||!s)&&O(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`]&&O(`Nothing to update: pass --base-url, --model, or --env-key.`,{hint:t}),await Ut(a,{...s,...n[`base-url`]?{baseUrl:V(n[`base-url`])}:{},...n.model?{model:n.model}:{},...n[`env-key`]?{envKey:n[`env-key`]}:{}},n,i,`updated`)}async function qt(e){let{options:t,positionals:n}=b(e,Q),r=E(t),i=n[0],a;try{a=nn(r,i??``,{workspace:t.workspace})}catch(e){O(e instanceof Error?e.message:String(e),{hint:i?`List them: coder model list`:`Usage: coder model remove <name>`})}if(t.json){P(a);return}G.stdout.write(`removed ${H.cyan(a.removed)} ${H.dim(`(${a.file})`)}\n`)}async function Jt(e){await Xt(e,!0)}async function Yt(e){await Xt(e,!1)}async function Xt(e,t){let n=t?`disable`:`enable`,r=`Usage: coder model ${n} <name>`,{options:i,positionals:a}=b(e,Q),o=E(i),s=a[0];s||O(`Missing model name.`,{hint:r});let{file:c}=on(o,s,t,{workspace:i.workspace});if(i.json){P({[t?`disabled`:`enabled`]:s,file:c});return}G.stdout.write(`${n}d ${H.cyan(s)} ${H.dim(`(${c})`)}\n`)}async function Zt(e){let t=`Usage: coder model alias <name> <spec> (e.g. coder model alias fast codex:mini)`,{options:n,positionals:r}=b(e,Q),i=E(n),a=Wt(r[0],t,`alias`),o=I(i).models?.[a];o&&z(o)&&O(`"${a}" is a custom model name; pick another alias name.`);let s=r[1];s||O(`Missing alias spec.`,{hint:t});let c;try{c=rn(i,a,s,{workspace:n.workspace})}catch(e){let n=e instanceof Error?e.message:String(e);O(n,n.includes(`already dispatchable by name`)?{}:{hint:t})}if(n.json){P(c);return}let l=H,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 Qt(e){let{options:t,positionals:n}=b(e,Q),r=E(t),i=n[0],a=i?I(r).models?.[i]:void 0;(!i||!a||!B(a))&&O(i?`No alias named "${i}".`:`Missing alias name.`,{hint:i?`List them: coder model list`:`Usage: coder model unalias <name>`});let{file:o}=an(r,i,{workspace:t.workspace});if(t.json){P({unaliased:i,file:o});return}G.stdout.write(`unaliased ${H.cyan(i)} ${H.dim(`(${o})`)}\n`)}function $t(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(It.has(e)||t===`model`&&U(e))throw Error(`"${e}" is reserved; pick another name.`)}async function en(e,t,n){if($t(t,`model`),I(e).models?.[t])throw Error(`Custom model "${t}" already exists.`);if(!n.baseUrl||!n.model)throw Error(`Missing baseUrl or model.`);return Ht(t,{baseUrl:V(n.baseUrl),model:n.model,...n.envKey?{envKey:n.envKey}:{}},$({workspace:n.workspace},e),e)}async function tn(e,t,n){let r=I(e).models?.[t],i=r&&z(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 Ht(t,{...i,...n.baseUrl?{baseUrl:V(n.baseUrl)}:{},...n.model?{model:n.model}:{},...n.envKey?{envKey:n.envKey}:{}},$({workspace:n.workspace},e),e)}function nn(e,t,n={}){if(!t||!I(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 rn(e,t,n,r={}){$t(t,`alias`);let i=I(e),a=i.models?.[t];if(a&&z(a))throw Error(`"${t}" is a custom model name; pick another alias name.`);if(!n)throw Error(`Missing alias spec.`);let o=Ge(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=>Ae.has(e.trim())||ke.has(e.trim())),c=o.agent===`claude`?N:A,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 an(e,t,n={}){let r=t?I(e).models?.[t]:void 0;if(!t||!r||!B(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 on(e,t,n,r={}){if(!t)throw Error(`Missing model name.`);let i=!!I(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}z(r)||B(r)?n?r.disabled=!0:delete r.disabled:n?r.disabled=!0:delete e[t]}),{name:t,disabled:n,file:a}}const sn={list:Vt,add:Gt,setup:Gt,update:Kt,remove:qt,disable:Jt,enable:Yt,alias:Zt,unalias:Qt};async function cn(e){let[t,...n]=e;if(t===void 0||t.startsWith(`-`)){await Vt(e);return}let r=sn[t];r||O(`Unknown model subcommand "${t}". Use list, add, update, remove, disable, enable, alias, or unalias.`,{hint:`Help: coder model --help`}),await r(n)}const ln=[{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 un(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:dn(q.join(e,n))}}),i=ln.map(e=>({name:e.name,file:e.file,description:e.description}));return[...r,...i]}function dn(e){let t=``;try{t=K.readFileSync(e,`utf8`)}catch{return``}let n=t.split(`
|
|
24
24
|
`),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 fn(i)||r}function fn(e){if(!e)return``;let t=e.match(/^.*?[.!?](?=\s|$)/);return(t?t[0]:e).trim()}function pn(e){let t=_(),n=un(t);if(!e)return{topics:n.map(e=>({name:e.name,description:e.description}))};let r=n.find(t=>t.name===e.toLowerCase());if(!r)throw Error(`Unknown docs topic "${e}". Available: ${n.map(e=>e.name).join(`, `)}`);let i=q.join(t,r.file),a;try{a=K.readFileSync(i,`utf8`)}catch{throw Error(`Could not read docs for "${r.name}" (${r.file}).`)}return{name:r.name,content:a}}async function mn(e){let{options:t,positionals:n}=b(e,J.object({json:C})),[r]=n,i;try{i=pn(r)}catch(e){let t=e instanceof Error?e.message:String(e);return O(t,t.startsWith(`Unknown docs topic`)?{hint:`List topics: coder docs`}:{})}if(`content`in i){G.stdout.write(i.content.endsWith(`
|
|
25
25
|
`)?i.content:`${i.content}\n`);return}if(t.json){P(i);return}let a=H,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,``,D([`Read a topic: coder docs <topic>`],a)].join(`
|
|
26
26
|
`)+`
|
package/docs/config.md
CHANGED
|
@@ -27,7 +27,7 @@ coder config set agents.codex.model terra
|
|
|
27
27
|
},
|
|
28
28
|
"models": {
|
|
29
29
|
"qwen": { "baseUrl": "http://localhost:11434/v1", "model": "qwen2.5-coder:32b" },
|
|
30
|
-
"fast": { "provider": "codex", "model": "gpt-5.
|
|
30
|
+
"fast": { "provider": "codex", "model": "gpt-5.4-mini" },
|
|
31
31
|
"big": { "provider": "claude", "model": "opus", "effort": "high" },
|
|
32
32
|
"luna": { "disabled": true }
|
|
33
33
|
}
|
|
@@ -44,7 +44,7 @@ Per-agent defaults, used when a dispatch doesn't override them:
|
|
|
44
44
|
|
|
45
45
|
| Key | Values |
|
|
46
46
|
| --- | --- |
|
|
47
|
-
| `model` | codex: `
|
|
47
|
+
| `model` | codex: `mini`, `luna`, `terra`, `sol` · claude: `haiku`, `sonnet`, `opus`, `fable` · custom: any name from `models` |
|
|
48
48
|
| `effort` | `low`, `medium`, `high` |
|
|
49
49
|
| `permissions` | `read-only`, `workspace-write`, `auto` |
|
|
50
50
|
|
|
@@ -60,7 +60,7 @@ One namespace for every model you can name as `--model`, keyed by that name. An
|
|
|
60
60
|
| `{ "provider": "codex"\|"claude", "model", "effort"? }` | alias onto a built-in engine | `coder model alias/unalias` |
|
|
61
61
|
| `{ "disabled": true }` | bare toggle turning off any model name (built-in, entry from another config layer, or raw engine slug) | `coder model disable/enable` |
|
|
62
62
|
|
|
63
|
-
Every shape also accepts `"disabled": true` to park the entry without deleting it. An entry named after a built-in alias (e.g. `
|
|
63
|
+
Every shape also accepts `"disabled": true` to park the entry without deleting it. An entry named after a built-in alias (e.g. `mini`) shadows it. See [Models](models.md).
|
|
64
64
|
|
|
65
65
|
---
|
|
66
66
|
|
package/docs/models.md
CHANGED
|
@@ -51,11 +51,11 @@ coder model disable terra
|
|
|
51
51
|
coder model enable terra
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
Create an alias for an agent spec with `coder model alias fast codex:
|
|
54
|
+
Create an alias for an agent spec with `coder model alias fast codex:mini`
|
|
55
55
|
(effort can ride along: `coder model alias big claude:opus:high`); remove it
|
|
56
56
|
with `coder model unalias fast`. Aliases may reuse a built-in name, so
|
|
57
|
-
`coder model alias
|
|
58
|
-
`
|
|
57
|
+
`coder model alias mini codex:gpt-x` intentionally overrides the built-in
|
|
58
|
+
`mini`, and `model list` shows the override in its place.
|
|
59
59
|
|
|
60
60
|
## Config shape
|
|
61
61
|
|
|
@@ -67,7 +67,7 @@ engine alias, or a bare disable toggle for any model name):
|
|
|
67
67
|
{
|
|
68
68
|
"models": {
|
|
69
69
|
"qwen": { "baseUrl": "http://localhost:11434/v1", "model": "qwen2.5-coder:32b", "envKey": "MY_KEY" },
|
|
70
|
-
"fast": { "provider": "codex", "model": "gpt-5.
|
|
70
|
+
"fast": { "provider": "codex", "model": "gpt-5.4-mini" },
|
|
71
71
|
"big": { "provider": "claude", "model": "opus", "effort": "high" },
|
|
72
72
|
"terra": { "disabled": true }
|
|
73
73
|
}
|
package/package.json
CHANGED
|
@@ -39,7 +39,6 @@ If `coder` is not on PATH, install it yourself without asking (`npm install -g @
|
|
|
39
39
|
- `coder task run` exits after its startup check. Exit 0: the task started - relay the task id and fetch its result (above). Exit 1: it failed to start or the turn failed - report it, do not retry or fall back yourself. Exit 3: no engine in the chain could start and stdout carries a `run-native-subagent` payload - see below.
|
|
40
40
|
- When the first engine can't start (auth, quota, rate limit), the runtime automatically falls back to the next engine in the chain, runs the same task on it, and still exits 0 - so just fetch the result. If the failure mentions a usage-limit reset time, relay that to the user.
|
|
41
41
|
- Model choice: config holds the defaults; matching the dispatch to the task is on you - pick `--agent` / `--model` / `--effort` by the task's weight and the user's ask (light -> cheap/fast model, hard -> stronger model or higher effort). `coder task run --help` lists agents, models, and efforts; `coder model list` shows custom models.
|
|
42
|
-
- `spark` is only for the very lightest tasks (formatting, renames, quick lookups) - and it runs on a separate quota, so reach for it when the others hit a usage limit.
|
|
43
42
|
- Permissions default to auto mode (workspace-write + policy-answered escalations). Pass `--permissions read-only` when the task is read-only; `--permissions workspace-write` to forbid any escalation beyond the project.
|
|
44
43
|
|
|
45
44
|
## Flows (multi-task workflows)
|
|
@@ -37,7 +37,6 @@ If `coder` is not on PATH, install it yourself without asking (`npm install -g @
|
|
|
37
37
|
- `coder task run` exits after its startup check. Exit 0: the task started - relay the task id and fetch its result (above). Exit 1: it failed to start or the turn failed - report it, do not retry or fall back yourself. Exit 3: no engine in the chain could start and stdout carries a `run-native-subagent` payload - see below.
|
|
38
38
|
- When the first engine can't start (auth, quota, rate limit), the runtime automatically falls back to the next engine in the chain, runs the same task on it, and still exits 0 - so just fetch the result. If the failure mentions a usage-limit reset time, relay that to the user.
|
|
39
39
|
- Model choice: config holds the defaults; matching the dispatch to the task is on you - pick `--agent` / `--model` / `--effort` by the task's weight and the user's ask (light -> cheap/fast model, hard -> stronger model or higher effort). `coder task run --help` lists agents, models, and efforts; `coder model list` shows custom models.
|
|
40
|
-
- `spark` is only for the very lightest tasks (formatting, renames, quick lookups) - and it runs on a separate quota, so reach for it when the others hit a usage limit.
|
|
41
40
|
- Permissions default to auto mode (workspace-write + policy-answered escalations). Pass `--permissions read-only` when the task is read-only; `--permissions workspace-write` to forbid any escalation beyond the project.
|
|
42
41
|
|
|
43
42
|
## Flows (multi-task workflows)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coder",
|
|
3
3
|
"displayName": "Coder",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.1",
|
|
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"
|
|
@@ -38,7 +38,6 @@ If `coder` is not on PATH, install it yourself without asking (`npm install -g @
|
|
|
38
38
|
- `coder task run` exits after its startup check. Exit 0: the task started - relay the task id and fetch its result (above). Exit 1: it failed to start or the turn failed - report it, do not retry or fall back yourself. Exit 3: no engine in the chain could start and stdout carries a `run-native-subagent` payload - see below.
|
|
39
39
|
- When the first engine can't start (auth, quota, rate limit), the runtime automatically falls back to the next engine in the chain, runs the same task on it, and still exits 0 - so just fetch the result. If the failure mentions a usage-limit reset time, relay that to the user.
|
|
40
40
|
- Model choice: config holds the defaults; matching the dispatch to the task is on you - pick `--agent` / `--model` / `--effort` by the task's weight and the user's ask (light -> cheap/fast model, hard -> stronger model or higher effort). `coder task run --help` lists agents, models, and efforts; `coder model list` shows custom models.
|
|
41
|
-
- `spark` is only for the very lightest tasks (formatting, renames, quick lookups) - and it runs on a separate quota, so reach for it when the others hit a usage limit.
|
|
42
41
|
- Permissions default to auto mode (workspace-write + policy-answered escalations). Pass `--permissions read-only` when the task is read-only; `--permissions workspace-write` to forbid any escalation beyond the project.
|
|
43
42
|
|
|
44
43
|
## Flows (multi-task workflows)
|