@wular/coder 0.3.13 → 0.3.15

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 CHANGED
@@ -1,82 +1,83 @@
1
1
  #!/usr/bin/env node
2
- import{B as e,E as t,H as n,I as r,L as i,M as a,N as o,O as s,R as c,V as l,_ as u,b as d,c as f,d as p,f as m,j as h,l as g,m as _,o as v,s as y,u as b}from"./app-server-bHl6RBZ2.js";import{$t as x,A as ee,At as S,B as C,Bt as w,Ct as T,D as E,Dt as te,Et as ne,F as re,Gt as D,Ht as ie,I as O,It as k,Jt as ae,Kt as oe,L as se,M as A,N as ce,Nt as le,O as ue,Pt as de,Q as fe,Qt as j,R as pe,Rt as M,S as me,St as he,T as ge,Tt as _e,Ut as N,Vt as P,Wt as ve,Xt as ye,Y as be,Zt as xe,_ as Se,a as Ce,an as we,b as Te,bt as Ee,cn as De,d as Oe,dt as ke,en as F,ft as Ae,g as I,h as je,in as L,j as Me,kt as Ne,l as Pe,n as Fe,nn as R,nt as z,on as Ie,ot as Le,p as Re,qt as ze,r as Be,rn as Ve,s as He,sn as Ue,st as B,t as We,tn as Ge,u as Ke,ut as qe,v as V,vt as Je,w as Ye,wt as Xe,x as Ze,xt as Qe,y as $e}from"./runtime-DrTVUIwM.js";import{C as et,E as H,O as tt,a as nt,h as rt,k as it,p as at,r as ot,t as st,v as ct,w as lt,x as ut}from"./upgrade-DfGOKVRK.js";import U from"node:process";import W from"node:fs";import G from"node:path";import{spawn as dt,spawnSync as ft}from"node:child_process";import pt from"node:os";import*as K from"zod/mini";import mt from"node:readline";import{randomUUID as ht}from"node:crypto";const gt=[[`--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>`,`spark/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`]],q=[`--cwd <dir>`,`workspace directory (default: current)`],J=[`--json`,`JSON output`],_t=[{sub:`run`,usage:`run "<text>"`,blurb:`run a task (background; --wait blocks)`,alias:`run`},{sub:`list`,usage:`list`,blurb:`list recent tasks (running + just stopped)`,alias:`list`},{sub:`result`,usage:`result [task-id]`,blurb:`status + final answer (--wait blocks)`,alias:`result`},{sub:`watch`,usage:`watch [task-id]`,blurb:`watch a task live (progress log)`,alias:`watch`},{sub:`steer`,usage:`steer <task-id> "<follow-up>"`,blurb:`continue a task's thread`},{sub:`ask`,usage:`ask <task-id> "<question>"`,blurb:`ask about a task without interrupting it`},{sub:`stop`,usage:`stop <task-id>`,blurb:`interrupt a running task`},{sub:`archive`,usage:`archive <task-id>`,blurb:`archive a session (or --all-stopped)`},{sub:`delete`,usage:`delete <task-id>`,blurb:`delete a session (or --all-archived)`},{sub:`approvals`,usage:`approvals [task-id]`,blurb:`pending approvals (all tasks, or one)`},{sub:`approve`,usage:`approve <id>`,blurb:`answer an escalated permission`}],Y={"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
2
+ import{B as e,E as t,H as n,I as r,L as i,M as a,N as o,O as s,R as c,V as l,_ as u,b as d,c as f,d as p,f as m,j as h,l as g,m as _,o as v,s as y,u as b}from"./app-server-bHl6RBZ2.js";import{$ as ee,$t as x,A as S,At as C,B as te,Ct as w,D as T,Dt as ne,Et as re,F as E,Ft as ie,Gt as ae,Ht as D,I as oe,Jt as se,Kt as O,L as ce,Lt as le,M as k,N as ue,O as de,Ot as fe,Pt as pe,Qt as me,R as he,S as ge,St as _e,T as ve,Tt as ye,Ut as be,Vt as A,Wt as j,Y as xe,Yt as Se,Zt as Ce,_ as we,a as Te,an as M,b as Ee,cn as De,ct as N,d as Oe,dt as ke,en as P,ft as Ae,g as F,h as je,in as Me,j as Ne,jt as Pe,l as Fe,ln as Ie,n as Le,nn as Re,on as ze,p as Be,pt as Ve,qt as He,r as Ue,rn as I,rt as L,s as We,sn as Ge,st as Ke,t as qe,tn as R,u as Je,v as z,w as Ye,wt as Xe,x as Ze,xt as Qe,y as $e,yt as et,zt as B}from"./runtime-DtukZ1m8.js";import{C as tt,E as V,O as nt,a as rt,h as it,k as at,p as ot,r as st,t as ct,v as lt,w as ut,x as dt}from"./upgrade-cC4ahBbt.js";import H from"node:process";import U from"node:fs";import W from"node:path";import{spawn as ft,spawnSync as pt}from"node:child_process";import mt from"node:os";import*as G from"zod/mini";import ht from"node:readline";import{randomUUID as gt}from"node:crypto";const _t=[[`--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>`,`spark/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`]],K=[`--cwd <dir>`,`workspace directory (default: current)`],q=[`--json`,`JSON output`],vt=[{sub:`run`,usage:`run "<text>"`,blurb:`run a task (background; --wait blocks)`,alias:`run`},{sub:`list`,usage:`list`,blurb:`list recent tasks (running + just stopped)`,alias:`list`},{sub:`result`,usage:`result [task-id]`,blurb:`status + final answer (--wait blocks)`,alias:`result`},{sub:`watch`,usage:`watch [task-id]`,blurb:`watch a task live (progress log)`,alias:`watch`},{sub:`steer`,usage:`steer <task-id> "<follow-up>"`,blurb:`continue a task's thread`},{sub:`ask`,usage:`ask <task-id> "<question>"`,blurb:`ask about a task without interrupting it`},{sub:`stop`,usage:`stop <task-id>`,blurb:`interrupt a running task`},{sub:`archive`,usage:`archive <task-id>`,blurb:`archive a session (or --all-stopped)`},{sub:`delete`,usage:`delete <task-id>`,blurb:`delete a session (or --all-archived)`},{sub:`approvals`,usage:`approvals [task-id]`,blurb:`pending approvals (all tasks, or one)`},{sub:`approve`,usage:`approve <id>`,blurb:`answer an escalated permission`}],J={"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)`],...gt,q],examples:[[`coder run "add a /health endpoint"`,`dispatch in the background, print a task id`],[`coder result <task-id> --wait`,`then block until it finishes and print the answer`],[`coder run --wait "fix the failing test"`,`or block on the run itself`],[`coder task run --model spark --system "tests live in test/, don't touch anything outside of it" "rename foo to bar"`,`pick an engine via its model alias; --system adds standing instructions`]],seeAlso:`task result · task steer · task stop · task watch`},"task list":{list:[`task list [--running|--stopped|--archived]`,`list recent tasks (running + just stopped)`],usage:`coder task list [--running] [--stopped] [--archived [--limit N]]`,summary:`List recent tasks across all workspaces, most recent first: running tasks plus
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)`],..._t,K],examples:[[`coder run "add a /health endpoint"`,`dispatch in the background, print a task id`],[`coder result <task-id> --wait`,`then block until it finishes and print the answer`],[`coder run --wait "fix the failing test"`,`or block on the run itself`],[`coder task run --model spark --system "tests live in test/, don't touch anything outside of it" "rename foo to bar"`,`pick an engine via its model alias; --system adds standing instructions`]],seeAlso:`task result · task steer · task stop · task watch`},"task list":{list:[`task list [--running|--stopped|--archived]`,`list recent tasks (running + just stopped)`],usage:`coder task list [--running] [--stopped] [--archived [--limit N]]`,summary:`List recent tasks across all workspaces, most recent first: running tasks plus
5
5
  ones stopped within the last 10 minutes. Older stopped tasks auto-archive and
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`],J],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
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`],q],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>
8
8
  includes the last n progress-log steps (--tail all for the whole transcript).
9
- Defaults to the most recent task. Shortcut: \`coder result\`.`,flags:[[`--wait`,`block until the task finishes, then print`],[`--turns`,`every turn's answer (a steered task accretes turns)`],[`--tail <n|all>`,`include the last n progress-log steps (default: 0, final result only)`],J,q],examples:[[`coder result <task-id> --wait`,`block until the task finishes, print the answer`],[`coder result <task-id> --turns`,`every turn's answer for a steered task`]],seeAlso:`task list · task steer · task watch`},"task watch":{list:[`task watch [task-id]`,`watch a task live (progress log)`],usage:`coder task watch [task-id]`,summary:`Watch a running task's progress log live (for you/debugging), then print its
9
+ Defaults to the most recent task. Shortcut: \`coder result\`.`,flags:[[`--wait`,`block until the task finishes, then print`],[`--turns`,`every turn's answer (a steered task accretes turns)`],[`--tail <n|all>`,`include the last n progress-log steps (default: 0, final result only)`],q,K],examples:[[`coder result <task-id> --wait`,`block until the task finishes, print the answer`],[`coder result <task-id> --turns`,`every turn's answer for a steered task`]],seeAlso:`task list · task steer · task watch`},"task watch":{list:[`task watch [task-id]`,`watch a task live (progress log)`],usage:`coder task watch [task-id]`,summary:`Watch a running task's progress log live (for you/debugging), then print its
10
10
  final answer. Replays the last line first so the current step is visible;
11
11
  --tail <n> replays the last n lines (--tail all for the whole transcript).
12
12
  Blocks until it finishes; exits 0 on success, 1 otherwise. For the answer
13
- alone, prefer \`coder result\`. Alias: stream.`,flags:[[`--tail <n|all>`,`replay the last n log lines first (default: 1)`],[`--trim <n|none>`,`cap each step at n chars, text and JSON alike (default: 128)`],[`--json`,`emit each log entry as a JSON line, then the result`],q],examples:[[`coder watch`,`follow the most recent task to completion`]],seeAlso:`task result · task run`},"task ask":{list:[`task ask <task-id> "<question>"`,`ask about a task without interrupting it`],usage:`coder task ask <task-id> "<question>"`,summary:`Answer a question ABOUT a task without touching it: a read-only sidecar reads
13
+ alone, prefer \`coder result\`. Alias: stream.`,flags:[[`--tail <n|all>`,`replay the last n log lines first (default: 1)`],[`--trim <n|none>`,`cap each step at n chars, text and JSON alike (default: 128)`],[`--json`,`emit each log entry as a JSON line, then the result`],K],examples:[[`coder watch`,`follow the most recent task to completion`]],seeAlso:`task result · task run`},"task ask":{list:[`task ask <task-id> "<question>"`,`ask about a task without interrupting it`],usage:`coder task ask <task-id> "<question>"`,summary:`Answer a question ABOUT a task without touching it: a read-only sidecar reads
14
14
  the task's progress log, result, and workspace and answers; the task never
15
15
  sees the question and its thread is not steered. Works whether the task is
16
- running or stopped. To change what the task does, use \`coder task steer\`.`,flags:[[`--model <alias|slug>`,`sidecar model (default: the task's own)`],[`--effort <low|medium|high>`,`sidecar reasoning effort`],J,q],examples:[[`coder task ask task-abc "what approach did you take and why?"`,`probe a decision without derailing the task`]],seeAlso:`task steer · task result · task watch`},"task steer":{list:[`task steer <task-id> "<follow-up>"`,`continue a task's thread`],usage:`coder task steer <task-id> "<follow-up instructions>" [--wait]`,summary:`Continue a task's thread with new instructions: injected into the live turn
17
- (codex), queued for after it (claude), or — for a stopped task — resumed on the
18
- same task id. Reuses the task's engine, model, and permissions unless overridden.`,flags:[[`--wait`,`run in the foreground and block until the answer is ready`],[`--model <alias|slug>`,`override the task's model for this follow-up`],[`--effort <low|medium|high>`,`override the task's reasoning effort`],[`--permissions <mode>`,`read-only · workspace-write · auto`],q],examples:[[`coder task steer task-abc "now add tests"`,`continue that task with a follow-up`]],seeAlso:`task run · task stop`},"task stop":{list:[`task stop <task-id>`,`interrupt a running task`],usage:`coder task stop <task-id>`,summary:`Interrupt a running task and mark it cancelled.`,flags:[J,q],seeAlso:`task result · task steer`},"task archive":{list:[`task archive <task-id> | --all-stopped`,`hide a task (or all stopped) from the list`],usage:`coder task archive <task-id> | coder task archive --all-stopped`,summary:`Archive a task session so it drops out of the default list (see it again with
16
+ running or stopped. To change what the task does, use \`coder task steer\`.`,flags:[[`--model <alias|slug>`,`sidecar model (default: the task's own)`],[`--effort <low|medium|high>`,`sidecar reasoning effort`],q,K],examples:[[`coder task ask task-abc "what approach did you take and why?"`,`probe a decision without derailing the task`]],seeAlso:`task steer · task result · task watch`},"task steer":{list:[`task steer <task-id> "<follow-up>"`,`continue a task's thread`],usage:`coder task steer <task-id> "<follow-up instructions>" [--wait]`,summary:`Continue a task's thread with new instructions: injected into a live Codex or
17
+ Claude turn at its next tool boundary, queued across a startup/completion race,
18
+ or — for a stopped task — resumed on the same task id. Reuses the task's engine,
19
+ model, and permissions unless overridden.`,flags:[[`--wait`,`run in the foreground and block until the answer is ready`],[`--model <alias|slug>`,`override the task's model for this follow-up`],[`--effort <low|medium|high>`,`override the task's reasoning effort`],[`--permissions <mode>`,`read-only · workspace-write · auto`],K],examples:[[`coder task steer task-abc "now add tests"`,`continue that task with a follow-up`]],seeAlso:`task run · task stop`},"task stop":{list:[`task stop <task-id>`,`interrupt a running task`],usage:`coder task stop <task-id>`,summary:`Interrupt a running task and mark it cancelled.`,flags:[q,K],seeAlso:`task result · task steer`},"task archive":{list:[`task archive <task-id> | --all-stopped`,`hide a task (or all stopped) from the list`],usage:`coder task archive <task-id> | coder task archive --all-stopped`,summary:`Archive a task session so it drops out of the default list (see it again with
19
20
  \`coder task list --archived [--limit N]\`). Pass --all-stopped to archive every
20
- finished task.`,flags:[[`--all-stopped`,`archive every stopped (finished) task`],J,q],seeAlso:`task list · task delete`},"task delete":{list:[`task delete <task-id> | --all-archived`,`delete a task session (or all archived)`],usage:`coder task delete <task-id> | coder task delete --all-archived`,summary:`Delete a task's session from disk. This is permanent. Pass --all-archived to
21
- delete every archived task at once. A running task must be stopped first.`,flags:[[`--all-archived`,`delete every archived task`],J,q],seeAlso:`task archive · task stop`},"task approvals":{list:[`task approvals [task-id]`,`pending approvals (all tasks, or one)`],usage:`coder task approvals [task-id]`,summary:"Without a task id: pending approvals across all tasks. With one: that task's\npermission escalations and how each was answered. Shortcut: `coder approvals`.",flags:[J,q],seeAlso:`task approve`},"task approve":{list:[`task approve <id> [--deny]`,`answer an escalated permission`],usage:`coder task approve [task-id] <approval-id> [--deny]`,summary:"Answer an escalated permission request. Accepts by default; --deny rejects it.\nApproval ids are unique, so the task id is optional. Shortcut: `coder approve`.",flags:[[`--deny`,`reject the request instead of accepting`],J,q],seeAlso:`task approvals · task result`},"flow run":{list:[`flow run <name|path> [--args | key=value...]`,`run a flow (orchestrate a wave of tasks)`],usage:`coder flow run <name|path> [--args '<json>' | key=value...] [--wait] [--concurrency N] [--max-tasks N] [--json] [--dry-run]`,summary:`Run a flow: a TypeScript file that orchestrates many coder tasks with gates,
21
+ finished task.`,flags:[[`--all-stopped`,`archive every stopped (finished) task`],q,K],seeAlso:`task list · task delete`},"task delete":{list:[`task delete <task-id> | --all-archived`,`delete a task session (or all archived)`],usage:`coder task delete <task-id> | coder task delete --all-archived`,summary:`Delete a task's session from disk. This is permanent. Pass --all-archived to
22
+ delete every archived task at once. A running task must be stopped first.`,flags:[[`--all-archived`,`delete every archived task`],q,K],seeAlso:`task archive · task stop`},"task approvals":{list:[`task approvals [task-id]`,`pending approvals (all tasks, or one)`],usage:`coder task approvals [task-id]`,summary:"Without a task id: pending approvals across all tasks. With one: that task's\npermission escalations and how each was answered. Shortcut: `coder approvals`.",flags:[q,K],seeAlso:`task approve`},"task approve":{list:[`task approve <id> [--deny]`,`answer an escalated permission`],usage:`coder task approve [task-id] <approval-id> [--deny]`,summary:"Answer an escalated permission request. Accepts by default; --deny rejects it.\nApproval ids are unique, so the task id is optional. Shortcut: `coder approve`.",flags:[[`--deny`,`reject the request instead of accepting`],q,K],seeAlso:`task approvals · task result`},"flow run":{list:[`flow run <name|path> [--args | key=value...]`,`run a flow (orchestrate a wave of tasks)`],usage:`coder flow run <name|path> [--args '<json>' | key=value...] [--wait] [--concurrency N] [--max-tasks N] [--json] [--dry-run]`,summary:`Run a flow: a TypeScript file that orchestrates many coder tasks with gates,
22
23
  journaling, and resume. Prints the run id and orchestrates in the background;
23
24
  --wait follows the run in the foreground with live progress (Ctrl-C detaches;
24
25
  it keeps running), and \`coder flow watch\` shows the same lines any time.
25
- Stop a run with \`coder flow stop\`.`,flags:[[`--wait`,`follow the run in the foreground (Ctrl-C detaches; it keeps running)`],[`--args <json>`,`the flow's input as a JSON value (or pass bare key=value pairs)`],[`--concurrency <n>`,`tasks running at once (default: CPU count)`],[`--max-tasks <n>`,`total tasks the run may dispatch (default: CPU count x 10)`],[`--dry-run`,`print every resolved prompt and gate command without dispatching`],J,q],examples:[[`coder flow run audit-routes --wait`,`run a discovered flow`],[`coder flow run ./scratch/one-off.ts --wait`,`run a flow by path`],[`coder flow run verify --args '{"clusters":["a","b"]}' --wait`,`pass structured input`]],seeAlso:`flow list · flow discover · flow result · flow resume`},"flow list":{list:[`flow list`,`recent flow runs (running + just stopped)`],usage:`coder flow list [--archived] [--limit N] [--json]`,summary:`List recent flow runs, most recent first: running runs plus ones that ended
26
- within the last 10 minutes. Older runs auto-archive and move to --archived.`,flags:[[`--archived`,`show archived runs (auto-archived or via flow archive)`],[`--limit <n|all>`,`show at most n runs (default all)`],J,q],seeAlso:`flow run · flow result · flow resume`},"flow discover":{list:[`flow discover`,`list flows runnable here (workspace + global)`],usage:`coder flow discover [--json]`,summary:`List every flow discoverable from the current directory: workspace flows in
27
- .coder/flows/ (walking up to the repo root) and global flows in ~/.coder/flows/.`,flags:[J,q],seeAlso:`flow run · flow result`},"flow result":{list:[`flow result [run-id]`,`progress and result of a flow run`],usage:`coder flow result [run-id] [--tail <n|all>] [--json]`,summary:`Show a flow run's status and result, with its tasks, gates, and token ledger.
26
+ Stop a run with \`coder flow stop\`.`,flags:[[`--wait`,`follow the run in the foreground (Ctrl-C detaches; it keeps running)`],[`--args <json>`,`the flow's input as a JSON value (or pass bare key=value pairs)`],[`--concurrency <n>`,`tasks running at once (default: CPU count)`],[`--max-tasks <n>`,`total tasks the run may dispatch (default: CPU count x 10)`],[`--dry-run`,`print every resolved prompt and gate command without dispatching`],q,K],examples:[[`coder flow run audit-routes --wait`,`run a discovered flow`],[`coder flow run ./scratch/one-off.ts --wait`,`run a flow by path`],[`coder flow run verify --args '{"clusters":["a","b"]}' --wait`,`pass structured input`]],seeAlso:`flow list · flow discover · flow result · flow resume`},"flow list":{list:[`flow list`,`recent flow runs (running + just stopped)`],usage:`coder flow list [--archived] [--limit N] [--json]`,summary:`List recent flow runs, most recent first: running runs plus ones that ended
27
+ within the last 10 minutes. Older runs auto-archive and move to --archived.`,flags:[[`--archived`,`show archived runs (auto-archived or via flow archive)`],[`--limit <n|all>`,`show at most n runs (default all)`],q,K],seeAlso:`flow run · flow result · flow resume`},"flow discover":{list:[`flow discover`,`list flows runnable here (workspace + global)`],usage:`coder flow discover [--json]`,summary:`List every flow discoverable from the current directory: workspace flows in
28
+ .coder/flows/ (walking up to the repo root) and global flows in ~/.coder/flows/.`,flags:[q,K],seeAlso:`flow run · flow result`},"flow result":{list:[`flow result [run-id]`,`progress and result of a flow run`],usage:`coder flow result [run-id] [--tail <n|all>] [--json]`,summary:`Show a flow run's status and result, with its tasks, gates, and token ledger.
28
29
  --tail <n> caps the step rows (0 for the result alone). Defaults to the most
29
- recent run. To watch a run live, prefer \`coder flow watch\`.`,flags:[[`--tail <n|all>`,`show the last n step rows (default: all; 0 hides them)`],J,q],examples:[[`coder flow result --tail 0`,`the most recent run's result, no step rows`]],seeAlso:`flow run · flow watch · flow resume`},"flow watch":{list:[`flow watch [run-id]`,`watch a flow run live (replay + follow)`],usage:`coder flow watch [run-id] [--tail <n|all>] [--json]`,summary:`Watch a flow run live: replay its progress lines from the start, then keep
30
+ recent run. To watch a run live, prefer \`coder flow watch\`.`,flags:[[`--tail <n|all>`,`show the last n step rows (default: all; 0 hides them)`],q,K],examples:[[`coder flow result --tail 0`,`the most recent run's result, no step rows`]],seeAlso:`flow run · flow watch · flow resume`},"flow watch":{list:[`flow watch [run-id]`,`watch a flow run live (replay + follow)`],usage:`coder flow watch [run-id] [--tail <n|all>] [--json]`,summary:`Watch a flow run live: replay its progress lines from the start, then keep
30
31
  following while it runs (Ctrl-C detaches; it keeps running). Blocks until it
31
32
  finishes; exits 0 on success, 1 otherwise. Defaults to the most recent run.
32
- For the result alone, prefer \`coder flow result\`. Alias: stream.`,flags:[[`--tail <n|all>`,`replay only the last n events first (default: all)`],[`--json`,`emit each event as a JSON line, then the result`],q],examples:[[`coder flow watch`,`follow the most recent run to completion`]],seeAlso:`flow result · flow run`},"flow stop":{list:[`flow stop [run-id]`,`stop a run and its still-running tasks`],usage:`coder flow stop [run-id] [--keep-tasks] [--json]`,summary:`Stop a running flow: signal the orchestrator so it stops dispatching, stamp the
33
+ For the result alone, prefer \`coder flow result\`. Alias: stream.`,flags:[[`--tail <n|all>`,`replay only the last n events first (default: all)`],[`--json`,`emit each event as a JSON line, then the result`],K],examples:[[`coder flow watch`,`follow the most recent run to completion`]],seeAlso:`flow result · flow run`},"flow stop":{list:[`flow stop [run-id]`,`stop a run and its still-running tasks`],usage:`coder flow stop [run-id] [--keep-tasks] [--json]`,summary:`Stop a running flow: signal the orchestrator so it stops dispatching, stamp the
33
34
  run stopped, and stop its still-running tasks. Defaults to the most recent run;
34
35
  the journal stays ready for \`coder flow resume\`.`,flags:[[`--keep-tasks`,`leave the run's still-running tasks running`],[`--json`,`print { runId, status, stoppedTasks, keptTasks }`]],seeAlso:`flow resume · flow result`},"flow resume":{list:[`flow resume [run-id]`,`continue a stopped or edited run`],usage:`coder flow resume [run-id] [--wait] [--json] [--dry-run]`,summary:`Re-run a flow from its journal: finished steps replay instantly, the first
35
36
  changed or new step onward runs live. Defaults to the most recent run.
36
- Accepts the same flags as flow run.`,flags:[[`--wait`,`follow the run in the foreground (Ctrl-C detaches; it keeps running)`],[`--concurrency <n>`,`tasks running at once`],[`--max-tasks <n>`,`total tasks the run may dispatch`],J,q],examples:[[`coder flow resume`,`continue the most recent run`]],seeAlso:`flow run · flow result`},"flow archive":{list:[`flow archive <run-id> | --all-stopped`,`hide a run (or all stopped) from the list`],usage:`coder flow archive <run-id> | coder flow archive --all-stopped`,summary:`Archive a flow run so it drops out of the default list (see it again with
37
+ Accepts the same flags as flow run.`,flags:[[`--wait`,`follow the run in the foreground (Ctrl-C detaches; it keeps running)`],[`--concurrency <n>`,`tasks running at once`],[`--max-tasks <n>`,`total tasks the run may dispatch`],q,K],examples:[[`coder flow resume`,`continue the most recent run`]],seeAlso:`flow run · flow result`},"flow archive":{list:[`flow archive <run-id> | --all-stopped`,`hide a run (or all stopped) from the list`],usage:`coder flow archive <run-id> | coder flow archive --all-stopped`,summary:`Archive a flow run so it drops out of the default list (see it again with
37
38
  \`coder flow list --archived [--limit N]\`). Pass --all-stopped to archive every
38
- finished run. A running run must be stopped first.`,flags:[[`--all-stopped`,`archive every stopped (finished) run`],J],seeAlso:`flow list · flow delete`},"flow delete":{list:[`flow delete <run-id> | --all-archived`,`delete a run's record (or all archived)`],usage:`coder flow delete <run-id> | coder flow delete --all-archived`,summary:`Delete a flow run's record from disk (its journal, events, and logs). This is
39
+ finished run. A running run must be stopped first.`,flags:[[`--all-stopped`,`archive every stopped (finished) run`],q],seeAlso:`flow list · flow delete`},"flow delete":{list:[`flow delete <run-id> | --all-archived`,`delete a run's record (or all archived)`],usage:`coder flow delete <run-id> | coder flow delete --all-archived`,summary:`Delete a flow run's record from disk (its journal, events, and logs). This is
39
40
  permanent; the run's tasks are ordinary tasks and are not touched. Pass
40
41
  --all-archived to delete every archived run at once. A running run must be
41
- stopped first.`,flags:[[`--all-archived`,`delete every archived run`],J],seeAlso:`flow archive · flow stop`},config:{list:[`config [get|set|unset] <key> [value]`,`read or write config`],usage:`coder config [get|set|unset] <key> [value] [--workspace]`,summary:`Read or write configuration. No args prints the effective config; get/set/unset
42
- target a dotted key (e.g. agents.codex.model). Writes go to ~/.coder/config.json.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],J,q],examples:[[`coder config`,`print the effective config`],[`coder config set chain codex,claude`,`set the engine fallback chain`],[`coder config get agents.codex.model`,`read one value`]]},"setup-host":{list:[`setup-host [claude|codex|agents]`,`set up the host: check engines, write config, install plugin`],usage:`coder setup-host [claude] [codex] [agents] [--json]`,summary:`Set up coder in your host: check engines and auth, seed the config, and
42
+ stopped first.`,flags:[[`--all-archived`,`delete every archived run`],q],seeAlso:`flow archive · flow stop`},config:{list:[`config [get|set|unset] <key> [value]`,`read or write config`],usage:`coder config [get|set|unset] <key> [value] [--workspace]`,summary:`Read or write configuration. No args prints the effective config; get/set/unset
43
+ target a dotted key (e.g. agents.codex.model). Writes go to ~/.coder/config.json.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],q,K],examples:[[`coder config`,`print the effective config`],[`coder config set chain codex,claude`,`set the engine fallback chain`],[`coder config get agents.codex.model`,`read one value`]]},"setup-host":{list:[`setup-host [claude|codex|agents]`,`set up the host: check engines, write config, install plugin`],usage:`coder setup-host [claude] [codex] [agents] [--json]`,summary:`Set up coder in your host: check engines and auth, seed the config, and
43
44
  install the host plugin/skill for the named host(s). Claude Code gets its
44
45
  marketplace plugin; "agents" installs a skill into ~/.agents/skills for
45
46
  every host that reads the Agent Skills standard dir (Codex, Pi, OpenCode,
46
- ...). "codex" is an alias for agents. With no host, checks and seeds.`,flags:[[`--json`,`machine-readable output`]],examples:[[`coder setup-host claude`,`install the Claude Code plugin`],[`coder setup-host agents`,`install the skill into ~/.agents/skills (Codex, Pi, OpenCode, ...)`]]},"model list":{list:[`model list`,`list built-ins, custom models, and aliases`],usage:`coder model list [--json]`,summary:"List built-in aliases, configured custom models, and user aliases. Only custom\nmodels are probed. Also the default when `coder model` is run bare.",flags:[J,q],seeAlso:`model add · model remove`},"model add":{list:[`model add <name> --base-url <url> --model <id>`,`connect a local or third-party model (OpenAI-compatible)`],usage:`coder model add <name> --base-url <url> --model <id> [--env-key VAR]`,summary:`Connect a custom model behind an OpenAI-compatible endpoint (Ollama, LM Studio,
47
+ ...). "codex" is an alias for agents. With no host, checks and seeds.`,flags:[[`--json`,`machine-readable output`]],examples:[[`coder setup-host claude`,`install the Claude Code plugin`],[`coder setup-host agents`,`install the skill into ~/.agents/skills (Codex, Pi, OpenCode, ...)`]]},"model list":{list:[`model list`,`list built-ins, custom models, and aliases`],usage:`coder model list [--json]`,summary:"List built-in aliases, configured custom models, and user aliases. Only custom\nmodels are probed. Also the default when `coder model` is run bare.",flags:[q,K],seeAlso:`model add · model remove`},"model add":{list:[`model add <name> --base-url <url> --model <id>`,`connect a local or third-party model (OpenAI-compatible)`],usage:`coder model add <name> --base-url <url> --model <id> [--env-key VAR]`,summary:`Connect a custom model behind an OpenAI-compatible endpoint (Ollama, LM Studio,
47
48
  vLLM, OpenRouter, ...). It currently runs on the codex engine pointed at your
48
49
  URL and is usable anywhere a model is: --model <name>, --agent custom, or as an
49
- 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`],J],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
50
- 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`],J],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`],J],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`],J],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`],J],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:spark. An alias may reuse a
51
- built-in name to override it.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],J],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`],J],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
50
+ 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`],q],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
51
+ 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`],q],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`],q],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`],q],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`],q],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:spark. An alias may reuse a
52
+ built-in name to override it.`,flags:[[`--workspace`,`target <repo>/coder.config.json instead of the user file`],q],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`],q],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
52
53
  topic, print that doc's raw markdown to stdout (unstyled, for an agent to
53
54
  consume). \`coder docs skill\` prints the host skill so an agent can load it
54
55
  once per session (--claude for the Claude Code flavor).`,flags:[[`--claude`,`with the skill topic: print the Claude Code flavor`],[`--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
55
- 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`]]}},vt={run:`task run`,list:`task list`,watch:`task watch`,stream:`task watch`,result:`task result`,steer:`task steer`,ask:`task ask`,stop:`task stop`,archive:`task archive`,delete:`task delete`,approvals:`task approvals`,approve:`task approve`,setup:`setup-host`,"host-setup":`setup-host`,update:`upgrade`},yt=[{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:spark`},{usage:`unalias <name>`,blurb:`remove an alias`}],bt=[{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:`watch [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 X(){let e=j,t=bt.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(`
56
- `)}\n`}function xt(){let e=j,t=yt.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:spark); 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(`
57
- `)}\n`}function St(e,t){return e.map(([e,n])=>` ${t.cyan(e.padEnd(30))}${t.dim(n)}`)}function Z(e){let t=Y[e];if(!t)return null;let n=j,r=[n.bold(`Usage:`),` ${t.usage}`];if(t.summary&&r.push(``,t.summary),t.flags?.length&&r.push(``,n.bold(`Flags:`),...St(t.flags,n)),t.examples?.length){r.push(``,n.bold(`Examples:`));for(let[e,i]of t.examples)r.push(` ${n.cyan(e)}`,` ${n.dim(i)}`)}return t.seeAlso&&r.push(``,n.dim(`Related: ${t.seeAlso}`)),`${r.join(`
58
- `)}\n`}function Ct(){let e=j,t=_t.map(t=>{let n=t.alias?e.dim(` (coder ${t.alias})`):``;return` ${e.cyan(t.usage.padEnd(30))}${e.dim(t.blurb)}${n}`});return`${[e.bold(`Usage:`),` coder task <subcommand>`,``,e.bold(`Subcommands:`),...t,``,e.dim(`Run 'coder task <subcommand> --help' for details on any subcommand.`)].join(`
59
- `)}\n`}function wt(){let e=j,t=([t,n])=>` ${e.cyan(t.padEnd(41))}${e.dim(n)}`,n=_t.filter(e=>e.alias).map(e=>t([e.usage.replace(/^\S+/,e.alias),e.blurb]));return`${[`${e.bold(`Coder`)} ${e.dim(`v${_()}`)}`,`Delegate a coding task to the best available engine and steer it while it runs.`,``,e.bold(`Get started:`),` ${e.cyan(`coder setup-host claude`)} ${e.dim(`# or agents (Codex, Pi, ...); installs the host plugin/skill`)}`,` ${e.cyan(`coder run "explain this repo's layout"`)}`,``,e.dim("Agents: load the skill once with `coder docs skill [--claude]`."),``,e.bold(`Usage:`),` coder <command>`,``,e.bold(`Commands:`),...n,` ${e.cyan(`task <cmd>`.padEnd(41))}${e.dim(`more task commands (steer, stop, approve, ...): `)}${e.light(`coder task --help`)}`,` ${e.cyan(`flow <cmd>`.padEnd(41))}${e.dim(`orchestrate a wave of tasks: `)}${e.light(`coder flow --help`)}`,t(Y.config.list),t([`model <list|add|alias|disable>`,`manage models: built-ins, aliases, custom endpoints`]),t(Y.docs.list),t(Y.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(q)].join(`
60
- `)}\n`}function Tt(e){let t=e.indexOf(`--`),n=t===-1?e:e.slice(0,t);return n.includes(`-h`)||n.includes(`--help`)}const Et=`CODER_FLOW_ATTACH`;function Dt(e){let t={};for(let n of e){let e=n.indexOf(`=`);e===-1&&P(`Invalid argument "${n}": expected key=value.`,{hint:`Help: coder flow run --help`});let r=n.slice(0,e),i=n.slice(e+1);try{t[r]=JSON.parse(i)}catch{t[r]=i}}return t}function Ot(e,t){if(e!==void 0)try{return JSON.parse(e)}catch(e){P(`Invalid --args JSON: ${e instanceof Error?e.message:String(e)}`)}return t.length?Dt(t):{}}function kt(){try{return ft(`bun`,[`--version`],{stdio:`ignore`}).status===0}catch{return!1}}function At(e){if(!e.endsWith(`.ts`)||U.versions.bun||U.features.typescript)return;kt()||P(`This flow is a TypeScript file (${e}) and this Node cannot run TypeScript.`,{hint:[`Upgrade to Node 23.6+ or install bun: https://bun.sh`,`Or write the flow as .mjs / .js`]});let t=ft(`bun`,[m,...U.argv.slice(2)],{stdio:`inherit`});U.exit(t.status??1)}function jt(e){U.once(`SIGINT`,()=>{(async()=>{let{runId:t}=e,n=W.existsSync(G.join(V(t),We));if(U.stderr.write(`\n[flow] stopping run ${t} — no new tasks will dispatch.\n`),n){let t=e.runningIds();t.length&&U.stderr.write(`[flow] left running: ${t.join(`, `)}\n`)}else{let n=await Te(t,e.runningIds());n.length&&U.stderr.write(`[flow] stopped tasks: ${n.join(`, `)}\n`)}U.stderr.write(`[flow] resume with: coder flow resume ${t}\n`),e.requestStop(),U.exit(130)})()})}const Mt=[`⣾`,`⣽`,`⣻`,`⢿`,`⡿`,`⣟`,`⣯`,`⣷`];function Q(e,t=!1){let n=j;return t?w(`[${Pt(e)}]`,10):e===`completed`?n.bold(n.green(`✔`)):e===`failed`||e===`cancelled`||e===`stopped`?n.bold(n.red(`✘`)):e===`running`?n.bold(n.cyan(`●`)):n.dim(`○`)}function Nt(){return w(`[start]`,10)}function Pt(e){return e===`completed`?`done`:e===`cancelled`?`failed`:e}function Ft(e,t){return e??t.replace(/\s+/g,` `).trim().slice(0,60)}function $(e,t,n,r,i,a){let o=j,s=w(t??n,32);return[`${e} ${a?o.bold(s):s}`,o.dim(w(n,24)),o.light(w(i??``,20)),r?o.light(`${ze(r.total)} tok`):``].join(` `).trimEnd()}function It(e){let t=G.join(V(e),`events.jsonl`);return W.existsSync(t)?W.readFileSync(t,`utf8`).split(`
61
- `).filter(Boolean).flatMap(e=>{try{return[JSON.parse(e)]}catch{return[]}}):[]}function Lt(e,t=!1){let n=j;return`${Q(e.ok?`completed`:`failed`,t)} ${n.dim(`gate`)} ${n.light(e.cmd)}${e.ok?``:n.dim(` · exit ${e.code}`)}`}function Rt(e,t,n){let r=j,i=n!==void 0&&n>=1e3?r.dim(` · ${N(n)}`):``;return`${t} ${r.dim(`gate`)} ${r.light(e)}${i}`}function zt(e,t=!1){return j.dim(`${`│ `.repeat(e)}${t?`└─`:`├─`}`)}function Bt(e){return j.dim(`${`│ `.repeat(e)}│ `)}function Vt(e){return`${` `.repeat(e.depth)}${e.log?`${w(`[log]`,10)} `:``}${e.body}`}function Ht(e,t,n=!1){return n?Vt(e):`${e.log?Bt(e.depth):zt(e.depth,t)} ${e.body}`}function Ut(e){return j.dim(`${`│ `.repeat(Math.max(0,e))}│`)}function Wt(e,t=!1){let n=j;if(t)return e.map(Vt);let r=(t,n)=>{for(let r=t+1;r<e.length;r+=1){let t=e[r].depth;if(t<n)return!1;if(t===n)return!0}return!1};return e.map((e,t)=>{let i=``;for(let n=0;n<e.depth;n+=1)i+=r(t,n)?`│ `:` `;return i+=e.log?`│ `:r(t,e.depth)?`├─`:`└─`,`${n.dim(i)} ${e.body}`})}var Gt=class{stream;names=new Map;active=new Map;activeGates=new Map;pending;previews=new Map;frame=0;hasCommitted=!1;timer;tty;region;constructor(e=U.stdout){this.stream=e,this.tty=!!e.isTTY,this.region=new k(e)}emit(e){let t=j;switch(e.kind){case`task-start`:{let t={name:Ft(e.name,e.prompt),agent:e.agent,depth:e.depth??0};if(this.names.set(e.taskId,t),!this.tty){this.final(t.depth,$(Nt(),t.name,e.taskId,null,t.agent));return}this.active.set(e.taskId,t),this.spin(!0),this.repaint();return}case`task-end`:{this.active.delete(e.taskId),this.previews.delete(e.taskId),this.idle();let t=this.names.get(e.taskId);this.final(t?.depth??0,$(Q(e.status,!this.tty),t?.name??null,e.taskId,e.tokens,t?.agent));return}case`gate-start`:{let t={cmd:e.cmd,depth:e.depth??0,startedAt:Date.now()};if(!this.tty){this.final(t.depth,Rt(t.cmd,Nt()));return}this.activeGates.set(e.gateId,t),this.spin(!0),this.repaint();return}case`gate`:e.gateId&&this.activeGates.delete(e.gateId),this.idle(),this.final(e.depth??0,Lt(e,!this.tty));return;case`log`:for(let n of e.message.split(`
62
- `))this.final(e.depth??0,t.light(n),!0);return;case`flow-start`:this.final(e.depth-1,t.bold(`flow ${e.name}`));return;case`replay`:this.final(0,t.dim(`replayed ${e.count} steps from journal`),!0)}}done(){this.spin(!1),this.flush(0),this.tty&&this.repaint(),this.region.done()}flush(e){this.pending&&=(this.region.commit(`${Ht(this.pending,e<this.pending.depth,!this.tty)}\n`),this.hasCommitted=!0,void 0)}final(e,t,n=!1){if(!this.tty){this.region.commit(`${Vt({depth:e,body:t,log:n})}\n`),this.hasCommitted=!0;return}this.flush(e),this.pending={depth:e,body:t,log:n},this.tty&&this.repaint()}repaint(){let e=[],t=[];if(this.pending){let n=Ht(this.pending,!1);e.push(n),t.push(n)}let n=this.timer?j.bold(j.cyan(Mt[this.frame%Mt.length])):Q(`running`);for(let[r,i]of this.active){let a=`${zt(i.depth??0)} ${$(n,i.name,r,null,i.agent,!0)}`;(e.length||this.hasCommitted)&&e.push(Ut(i.depth??0)),e.push(a),t.push(a);let o=this.previews.get(r);o&&e.push(`${Bt(i.depth??0)} ${j.dim(o)}`)}for(let r of this.activeGates.values()){let i=`${zt(r.depth)} ${Rt(r.cmd,n,Date.now()-r.startedAt)}`;(e.length||this.hasCommitted)&&e.push(Ut(r.depth)),e.push(i),t.push(i)}let r=(Ue(this.stream)??1/0)-1,i=e.length<=r?e:t;if(i.length>r){let e=Math.max(0,r-1);i=[j.dim(`… +${i.length-e} more running`),...i.slice(-e)]}this.region.set(i)}refreshPreviews(){for(let e of this.active.keys())try{let t=a(U.cwd(),e,1)[0]?.message?.replace(/\s+/g,` `).trim();if(!t)continue;let n=(Ie(this.stream)??120)-8;this.previews.set(e,t.length>n?`${t.slice(0,n-1)}…`:t)}catch{}}idle(){!this.active.size&&!this.activeGates.size&&this.spin(!1)}spin(e){e&&!this.timer?this.timer=setInterval(()=>{this.frame++,this.frame%4==0&&this.refreshPreviews(),this.repaint()},120).unref():!e&&this.timer&&(clearInterval(this.timer),this.timer=void 0)}};function Kt(e){if(e.json)return{};let t=new Gt,n=e=>t.emit(e);return{onTaskStart:e=>n({kind:`task-start`,...e}),onTaskEnd:e=>n({kind:`task-end`,...e}),onGateStart:e=>n({kind:`gate-start`,...e}),onGate:e=>n({kind:`gate`,...e}),onLog:(e,t)=>n({kind:`log`,message:e,depth:t}),onFlowStart:e=>n({kind:`flow-start`,...e}),onReplay:e=>n({kind:`replay`,count:e})}}function qt(e){let t=G.join(V(e),`events.jsonl`),n=e=>{try{W.appendFileSync(t,`${JSON.stringify(e)}\n`,`utf8`)}catch{}};return{onStart:e=>jt(e),onTaskStart:e=>n({kind:`task-start`,...e}),onTaskEnd:e=>n({kind:`task-end`,...e}),onGateStart:e=>n({kind:`gate-start`,...e}),onGate:e=>n({kind:`gate`,...e}),onLog:(e,t)=>n({kind:`log`,message:e,depth:t}),onFlowStart:e=>n({kind:`flow-start`,...e}),onReplay:e=>n({kind:`replay`,count:e})}}async function Jt(e,t){try{await Se(e,t,qt(e)),U.exit(0)}catch(t){Re(e,t instanceof Error?t.message:String(t)),U.exit(1)}}function Yt(e,t){let n=V(e.runId);W.writeFileSync(G.join(n,`events.jsonl`),``,`utf8`);let r=W.openSync(G.join(n,`flow.log`),`a`),i=dt(U.execPath,[m,...U.argv.slice(2)],{detached:!0,stdio:[`ignore`,r,r],env:{...U.env,[Et]:e.runId}});return i.unref(),W.closeSync(r),t.wait?i.pid:t.json?(F({runId:e.runId,status:`running`}),i.pid):(U.stdout.write(`${j.dim(`[flow]`)} run ${j.cyan(e.runId)} started in the background (running).\n`),U.stdout.write(`\n${D([`Result: coder flow result ${e.runId}`,`Runs: coder flow list`],j)}\n`),i.pid)}async function Xt(e,t,n){let r=!!(t.stream&&t.json);!t.json&&(I(e)?.status??`running`)===`running`&&U.stderr.write(`${j.dim(`[flow]`)} run ${j.cyan(e)} started (running); waiting for it to finish — Ctrl-C to detach (it keeps running).\n\n`);let i=t.json?()=>{}:xe(),a=()=>{i(),r||(U.stderr.write(`\n${j.dim(`[flow] detached — run still going.`)}\n`),U.stderr.write(`\n${D([`Result: coder flow result ${e}`,`Stop it: coder flow stop ${e}`],j)}\n`)),U.exit(130)};U.on(`SIGINT`,a);let o=new Gt;for await(let i of me(e,n,{tail:t.tail}))r?U.stdout.write(`${JSON.stringify(i)}\n`):t.json||o.emit(i);o.done(),i(),U.off(`SIGINT`,a);let s=I(e);s||P(`[flow] run ${e} vanished while following.`,{hint:`Recent runs: coder flow list`}),r&&(U.stdout.write(`${JSON.stringify(sn(s))}\n`),U.exit(s.status===`completed`?0:1)),s.status===`completed`&&(en({runId:e,name:s.name,status:`completed`,result:s.result,tokens:s.ledger,taskCount:s.taskCount},t.json),U.exit(0)),s.status===`stopped`&&(t.json?F({runId:e,name:s.name,status:`stopped`,taskCount:s.taskCount}):U.stdout.write(`\n${j.dim(`[flow] run ${e} stopped — resume: coder flow resume ${e}`)}\n`),U.exit(1)),U.stdout.write(`\n${j.red(`error:`)} ${s.error??`unknown error`}\n`),U.stdout.write(`\n${D([`Resume: coder flow resume ${e}`],j)}\n`),U.exit(1)}const Zt={cwd:b,json:y,args:b,wait:y,concurrency:b,"max-tasks":b,"dry-run":y},Qt=e=>e?Number(e):void 0;async function $t(e,t,n){let r=U.env[Et];if(r&&(delete U.env[Et],await Jt(r,t)),e[`dry-run`])return!1;let i=n(),a=Yt(i,e);return e.wait&&await Xt(i.runId,e,a),!0}function en(e,t){if(t){F(e);return}let n=!U.stdout.isTTY,r=n?``:`${j.dim(`└─`)} `;U.stdout.write(`${r}${Q(`completed`,n)} run ${j.cyan(e.runId)} completed ${j.dim(`(${e.taskCount} tasks)`)}\n`),U.stdout.write(`\n${oe(e.result)}\n`),rn(e.tokens)}function tn(e,t,n){if(e instanceof A&&e.code===`flow-failed`){let r=n?`
63
- [flow] dry-run ended early: a downstream step depends on real task output (stub it or run for real).`:``;P(`[flow] ${t} ${e.runId} failed: ${e.message}${r}`,{hint:`Resume${t===`resume`?` again`:``}: coder flow resume ${e.runId}`})}throw e}async function nn(e){let{options:t,positionals:n}=g(e,K.object(Zt)),[r,...i]=n;r||P(`Missing flow name or path.`,{hint:[`Usage: coder flow run <name|path>`,`List: coder flow discover`]});let a=L(t);At(Me(r,a).path);let o={args:Ot(t.args,i),cwd:a,dryRun:t[`dry-run`],concurrency:Qt(t.concurrency),maxTasks:Qt(t[`max-tasks`])};if(!await $t(t,o,()=>je(r,o)))try{en(await $e(r,o,Kt(t)),t.json)}catch(e){tn(e,`run`,o.dryRun)}}function rn(e){let t=Object.keys(e);if(t.length){U.stdout.write(`\n${j.bold(`Tokens:`)}\n`);for(let n of t)U.stdout.write(` ${j.dim(ae(e[n],n))}\n`)}}async function an(e){let{options:t,positionals:n}=g(e,K.object({cwd:b,json:y,archived:y,limit:f}));R(n,0,`flow list`);let r=t.limit===`all`?void 0:t.limit,{runs:i,clipped:a}=Be({archived:t.archived,limit:r});if(t.json){F(i);return}if(!i.length){U.stdout.write(t.archived?`No archived flow runs.
56
+ 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`]]}},yt={run:`task run`,list:`task list`,watch:`task watch`,stream:`task watch`,result:`task result`,steer:`task steer`,ask:`task ask`,stop:`task stop`,archive:`task archive`,delete:`task delete`,approvals:`task approvals`,approve:`task approve`,setup:`setup-host`,"host-setup":`setup-host`,update:`upgrade`},bt=[{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:spark`},{usage:`unalias <name>`,blurb:`remove an alias`}],xt=[{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:`watch [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 Y(){let e=x,t=xt.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(`
57
+ `)}\n`}function St(){let e=x,t=bt.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:spark); 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(`
58
+ `)}\n`}function Ct(e,t){return e.map(([e,n])=>` ${t.cyan(e.padEnd(30))}${t.dim(n)}`)}function X(e){let t=J[e];if(!t)return null;let n=x,r=[n.bold(`Usage:`),` ${t.usage}`];if(t.summary&&r.push(``,t.summary),t.flags?.length&&r.push(``,n.bold(`Flags:`),...Ct(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(`
59
+ `)}\n`}function Z(){let e=x,t=vt.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(`
60
+ `)}\n`}function wt(){let e=x,t=([t,n])=>` ${e.cyan(t.padEnd(41))}${e.dim(n)}`,n=vt.filter(e=>e.alias).map(e=>t([e.usage.replace(/^\S+/,e.alias),e.blurb]));return`${[`${e.bold(`Coder`)} ${e.dim(`v${_()}`)}`,`Delegate a coding task to the best available engine and steer it while it runs.`,``,e.bold(`Get started:`),` ${e.cyan(`coder setup-host claude`)} ${e.dim(`# or agents (Codex, Pi, ...); installs the host plugin/skill`)}`,` ${e.cyan(`coder run "explain this repo's layout"`)}`,``,e.dim("Agents: load the skill once with `coder docs skill [--claude]`."),``,e.bold(`Usage:`),` coder <command>`,``,e.bold(`Commands:`),...n,` ${e.cyan(`task <cmd>`.padEnd(41))}${e.dim(`more task commands (steer, stop, approve, ...): `)}${e.light(`coder task --help`)}`,` ${e.cyan(`flow <cmd>`.padEnd(41))}${e.dim(`orchestrate a wave of tasks: `)}${e.light(`coder flow --help`)}`,t(J.config.list),t([`model <list|add|alias|disable>`,`manage models: built-ins, aliases, custom endpoints`]),t(J.docs.list),t(J.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(K)].join(`
61
+ `)}\n`}function Tt(e){let t=e.indexOf(`--`),n=t===-1?e:e.slice(0,t);return n.includes(`-h`)||n.includes(`--help`)}const Et=`CODER_FLOW_ATTACH`;function Dt(e){let t={};for(let n of e){let e=n.indexOf(`=`);e===-1&&D(`Invalid argument "${n}": expected key=value.`,{hint:`Help: coder flow run --help`});let r=n.slice(0,e),i=n.slice(e+1);try{t[r]=JSON.parse(i)}catch{t[r]=i}}return t}function Ot(e,t){if(e!==void 0)try{return JSON.parse(e)}catch(e){D(`Invalid --args JSON: ${e instanceof Error?e.message:String(e)}`)}return t.length?Dt(t):{}}function kt(){try{return pt(`bun`,[`--version`],{stdio:`ignore`}).status===0}catch{return!1}}function At(e){if(!e.endsWith(`.ts`)||H.versions.bun||H.features.typescript)return;kt()||D(`This flow is a TypeScript file (${e}) and this Node cannot run TypeScript.`,{hint:[`Upgrade to Node 23.6+ or install bun: https://bun.sh`,`Or write the flow as .mjs / .js`]});let t=pt(`bun`,[m,...H.argv.slice(2)],{stdio:`inherit`});H.exit(t.status??1)}function jt(e){H.once(`SIGINT`,()=>{(async()=>{let{runId:t}=e,n=U.existsSync(W.join(z(t),qe));if(H.stderr.write(`\n[flow] stopping run ${t} — no new tasks will dispatch.\n`),n){let t=e.runningIds();t.length&&H.stderr.write(`[flow] left running: ${t.join(`, `)}\n`)}else{let n=await Ee(t,e.runningIds());n.length&&H.stderr.write(`[flow] stopped tasks: ${n.join(`, `)}\n`)}H.stderr.write(`[flow] resume with: coder flow resume ${t}\n`),e.requestStop(),H.exit(130)})()})}const Mt=[`⣾`,`⣽`,`⣻`,`⢿`,`⡿`,`⣟`,`⣯`,`⣷`];function Q(e,t=!1){let n=x;return t?A(`[${Pt(e)}]`,10):e===`completed`?n.bold(n.green(`✔`)):e===`failed`||e===`cancelled`||e===`stopped`?n.bold(n.red(`✘`)):e===`running`?n.bold(n.cyan(`●`)):n.dim(`○`)}function Nt(){return A(`[start]`,10)}function Pt(e){return e===`completed`?`done`:e===`cancelled`?`failed`:e}function Ft(e,t){return e??t.replace(/\s+/g,` `).trim().slice(0,60)}function $(e,t,n,r,i,a){let o=x,s=A(t??n,32);return[`${e} ${a?o.bold(s):s}`,o.dim(A(n,24)),o.light(A(i??``,20)),r?o.light(`${se(r.total)} tok`):``].join(` `).trimEnd()}function It(e){let t=W.join(z(e),`events.jsonl`);return U.existsSync(t)?U.readFileSync(t,`utf8`).split(`
62
+ `).filter(Boolean).flatMap(e=>{try{return[JSON.parse(e)]}catch{return[]}}):[]}function Lt(e,t=!1){let n=x;return`${Q(e.ok?`completed`:`failed`,t)} ${n.dim(`gate`)} ${n.light(e.cmd)}${e.ok?``:n.dim(` · exit ${e.code}`)}`}function Rt(e,t,n){let r=x,i=n!==void 0&&n>=1e3?r.dim(` · ${j(n)}`):``;return`${t} ${r.dim(`gate`)} ${r.light(e)}${i}`}function zt(e,t=!1){return x.dim(`${`│ `.repeat(e)}${t?`└─`:`├─`}`)}function Bt(e){return x.dim(`${`│ `.repeat(e)}│ `)}function Vt(e){return`${` `.repeat(e.depth)}${e.log?`${A(`[log]`,10)} `:``}${e.body}`}function Ht(e,t,n=!1){return n?Vt(e):`${e.log?Bt(e.depth):zt(e.depth,t)} ${e.body}`}function Ut(e){return x.dim(`${`│ `.repeat(Math.max(0,e))}│`)}function Wt(e,t=!1){let n=x;if(t)return e.map(Vt);let r=(t,n)=>{for(let r=t+1;r<e.length;r+=1){let t=e[r].depth;if(t<n)return!1;if(t===n)return!0}return!1};return e.map((e,t)=>{let i=``;for(let n=0;n<e.depth;n+=1)i+=r(t,n)?`│ `:` `;return i+=e.log?`│ `:r(t,e.depth)?`├─`:`└─`,`${n.dim(i)} ${e.body}`})}var Gt=class{stream;names=new Map;active=new Map;activeGates=new Map;pending;previews=new Map;frame=0;hasCommitted=!1;timer;tty;region;constructor(e=H.stdout){this.stream=e,this.tty=!!e.isTTY,this.region=new le(e)}emit(e){let t=x;switch(e.kind){case`task-start`:{let t={name:Ft(e.name,e.prompt),agent:e.agent,depth:e.depth??0};if(this.names.set(e.taskId,t),!this.tty){this.final(t.depth,$(Nt(),t.name,e.taskId,null,t.agent));return}this.active.set(e.taskId,t),this.spin(!0),this.repaint();return}case`task-end`:{this.active.delete(e.taskId),this.previews.delete(e.taskId),this.idle();let t=this.names.get(e.taskId);this.final(t?.depth??0,$(Q(e.status,!this.tty),t?.name??null,e.taskId,e.tokens,t?.agent));return}case`gate-start`:{let t={cmd:e.cmd,depth:e.depth??0,startedAt:Date.now()};if(!this.tty){this.final(t.depth,Rt(t.cmd,Nt()));return}this.activeGates.set(e.gateId,t),this.spin(!0),this.repaint();return}case`gate`:e.gateId&&this.activeGates.delete(e.gateId),this.idle(),this.final(e.depth??0,Lt(e,!this.tty));return;case`log`:for(let n of e.message.split(`
63
+ `))this.final(e.depth??0,t.light(n),!0);return;case`flow-start`:this.final(e.depth-1,t.bold(`flow ${e.name}`));return;case`replay`:this.final(0,t.dim(`replayed ${e.count} steps from journal`),!0)}}done(){this.spin(!1),this.flush(0),this.tty&&this.repaint(),this.region.done()}flush(e){this.pending&&=(this.region.commit(`${Ht(this.pending,e<this.pending.depth,!this.tty)}\n`),this.hasCommitted=!0,void 0)}final(e,t,n=!1){if(!this.tty){this.region.commit(`${Vt({depth:e,body:t,log:n})}\n`),this.hasCommitted=!0;return}this.flush(e),this.pending={depth:e,body:t,log:n},this.tty&&this.repaint()}repaint(){let e=[],t=[];if(this.pending){let n=Ht(this.pending,!1);e.push(n),t.push(n)}let n=this.timer?x.bold(x.cyan(Mt[this.frame%Mt.length])):Q(`running`);for(let[r,i]of this.active){let a=`${zt(i.depth??0)} ${$(n,i.name,r,null,i.agent,!0)}`;(e.length||this.hasCommitted)&&e.push(Ut(i.depth??0)),e.push(a),t.push(a);let o=this.previews.get(r);o&&e.push(`${Bt(i.depth??0)} ${x.dim(o)}`)}for(let r of this.activeGates.values()){let i=`${zt(r.depth)} ${Rt(r.cmd,n,Date.now()-r.startedAt)}`;(e.length||this.hasCommitted)&&e.push(Ut(r.depth)),e.push(i),t.push(i)}let r=(De(this.stream)??1/0)-1,i=e.length<=r?e:t;if(i.length>r){let e=Math.max(0,r-1);i=[x.dim(`… +${i.length-e} more running`),...i.slice(-e)]}this.region.set(i)}refreshPreviews(){for(let e of this.active.keys())try{let t=a(H.cwd(),e,1)[0]?.message?.replace(/\s+/g,` `).trim();if(!t)continue;let n=(Ge(this.stream)??120)-8;this.previews.set(e,t.length>n?`${t.slice(0,n-1)}…`:t)}catch{}}idle(){!this.active.size&&!this.activeGates.size&&this.spin(!1)}spin(e){e&&!this.timer?this.timer=setInterval(()=>{this.frame++,this.frame%4==0&&this.refreshPreviews(),this.repaint()},120).unref():!e&&this.timer&&(clearInterval(this.timer),this.timer=void 0)}};function Kt(e){if(e.json)return{};let t=new Gt,n=e=>t.emit(e);return{onTaskStart:e=>n({kind:`task-start`,...e}),onTaskEnd:e=>n({kind:`task-end`,...e}),onGateStart:e=>n({kind:`gate-start`,...e}),onGate:e=>n({kind:`gate`,...e}),onLog:(e,t)=>n({kind:`log`,message:e,depth:t}),onFlowStart:e=>n({kind:`flow-start`,...e}),onReplay:e=>n({kind:`replay`,count:e})}}function qt(e){let t=W.join(z(e),`events.jsonl`),n=e=>{try{U.appendFileSync(t,`${JSON.stringify(e)}\n`,`utf8`)}catch{}};return{onStart:e=>jt(e),onTaskStart:e=>n({kind:`task-start`,...e}),onTaskEnd:e=>n({kind:`task-end`,...e}),onGateStart:e=>n({kind:`gate-start`,...e}),onGate:e=>n({kind:`gate`,...e}),onLog:(e,t)=>n({kind:`log`,message:e,depth:t}),onFlowStart:e=>n({kind:`flow-start`,...e}),onReplay:e=>n({kind:`replay`,count:e})}}async function Jt(e,t){try{await we(e,t,qt(e)),H.exit(0)}catch(t){Be(e,t instanceof Error?t.message:String(t)),H.exit(1)}}function Yt(e,t){let n=z(e.runId);U.writeFileSync(W.join(n,`events.jsonl`),``,`utf8`);let r=U.openSync(W.join(n,`flow.log`),`a`),i=ft(H.execPath,[m,...H.argv.slice(2)],{detached:!0,stdio:[`ignore`,r,r],env:{...H.env,[Et]:e.runId}});return i.unref(),U.closeSync(r),t.wait?i.pid:t.json?(R({runId:e.runId,status:`running`}),i.pid):(H.stdout.write(`${x.dim(`[flow]`)} run ${x.cyan(e.runId)} started in the background (running).\n`),H.stdout.write(`\n${O([`Result: coder flow result ${e.runId}`,`Runs: coder flow list`],x)}\n`),i.pid)}async function Xt(e,t,n){let r=!!(t.stream&&t.json);!t.json&&(F(e)?.status??`running`)===`running`&&H.stderr.write(`${x.dim(`[flow]`)} run ${x.cyan(e)} started (running); waiting for it to finish — Ctrl-C to detach (it keeps running).\n\n`);let i=t.json?()=>{}:me(),a=()=>{i(),r||(H.stderr.write(`\n${x.dim(`[flow] detached — run still going.`)}\n`),H.stderr.write(`\n${O([`Result: coder flow result ${e}`,`Stop it: coder flow stop ${e}`],x)}\n`)),H.exit(130)};H.on(`SIGINT`,a);let o=new Gt;for await(let i of ge(e,n,{tail:t.tail}))r?H.stdout.write(`${JSON.stringify(i)}\n`):t.json||o.emit(i);o.done(),i(),H.off(`SIGINT`,a);let s=F(e);s||D(`[flow] run ${e} vanished while following.`,{hint:`Recent runs: coder flow list`}),r&&(H.stdout.write(`${JSON.stringify(sn(s))}\n`),H.exit(s.status===`completed`?0:1)),s.status===`completed`&&(en({runId:e,name:s.name,status:`completed`,result:s.result,tokens:s.ledger,taskCount:s.taskCount},t.json),H.exit(0)),s.status===`stopped`&&(t.json?R({runId:e,name:s.name,status:`stopped`,taskCount:s.taskCount}):H.stdout.write(`\n${x.dim(`[flow] run ${e} stopped — resume: coder flow resume ${e}`)}\n`),H.exit(1)),H.stdout.write(`\n${x.red(`error:`)} ${s.error??`unknown error`}\n`),H.stdout.write(`\n${O([`Resume: coder flow resume ${e}`],x)}\n`),H.exit(1)}const Zt={cwd:b,json:y,args:b,wait:y,concurrency:b,"max-tasks":b,"dry-run":y},Qt=e=>e?Number(e):void 0;async function $t(e,t,n){let r=H.env[Et];if(r&&(delete H.env[Et],await Jt(r,t)),e[`dry-run`])return!1;let i=n(),a=Yt(i,e);return e.wait&&await Xt(i.runId,e,a),!0}function en(e,t){if(t){R(e);return}let n=!H.stdout.isTTY,r=n?``:`${x.dim(`└─`)} `;H.stdout.write(`${r}${Q(`completed`,n)} run ${x.cyan(e.runId)} completed ${x.dim(`(${e.taskCount} tasks)`)}\n`),H.stdout.write(`\n${He(e.result)}\n`),rn(e.tokens)}function tn(e,t,n){if(e instanceof k&&e.code===`flow-failed`){let r=n?`
64
+ [flow] dry-run ended early: a downstream step depends on real task output (stub it or run for real).`:``;D(`[flow] ${t} ${e.runId} failed: ${e.message}${r}`,{hint:`Resume${t===`resume`?` again`:``}: coder flow resume ${e.runId}`})}throw e}async function nn(e){let{options:t,positionals:n}=g(e,G.object(Zt)),[r,...i]=n;r||D(`Missing flow name or path.`,{hint:[`Usage: coder flow run <name|path>`,`List: coder flow discover`]});let a=M(t);At(Ne(r,a).path);let o={args:Ot(t.args,i),cwd:a,dryRun:t[`dry-run`],concurrency:Qt(t.concurrency),maxTasks:Qt(t[`max-tasks`])};if(!await $t(t,o,()=>je(r,o)))try{en(await $e(r,o,Kt(t)),t.json)}catch(e){tn(e,`run`,o.dryRun)}}function rn(e){let t=Object.keys(e);if(t.length){H.stdout.write(`\n${x.bold(`Tokens:`)}\n`);for(let n of t)H.stdout.write(` ${x.dim(Se(e[n],n))}\n`)}}async function an(e){let{options:t,positionals:n}=g(e,G.object({cwd:b,json:y,archived:y,limit:f}));I(n,0,`flow list`);let r=t.limit===`all`?void 0:t.limit,{runs:i,clipped:a}=Ue({archived:t.archived,limit:r});if(t.json){R(i);return}if(!i.length){H.stdout.write(t.archived?`No archived flow runs.
64
65
  `:`No recent flow runs.
65
- `),U.stdout.write(`\n${D([`Run one: coder flow run <name>`,`Runnable flows: coder flow discover`],j)}\n`);return}let o=j,s=(e,t,n)=>Math.min(t,Math.max(e,...n.map(e=>e.length))),c={id:s(6,28,i.map(e=>e.runId)),name:s(4,30,i.map(e=>e.name))};U.stdout.write(o.bold(o.light(`${`run-id`.padEnd(c.id)} ${`name`.padEnd(c.name)} ${`status`.padEnd(10)} ${`tasks`.padEnd(9)} ${`tokens`.padEnd(10)} age\n`)));for(let e of i){let t=Object.values(e.ledger).reduce((e,t)=>e+t.total,0);U.stdout.write(`${o.cyan(w(e.runId,c.id))} ${w(e.name,c.name)} ${x(e.status,10)} ${o.light(w(`${e.taskCount} tasks`,9))} ${o.light(w(t?`${ze(t)} tok`:`-`,10))} ${o.light(N(M(e.startedAt)))}\n`)}a&&U.stdout.write(o.dim(`\n... ${a} more not shown (--limit ${r})\n`)),U.stdout.write(`\n${D([`Result: coder flow result <run-id>`,`Tasks: coder list`,`Runnable flows: coder flow discover`],o)}\n`)}async function on(e){let{options:t,positionals:n}=g(e,K.object({cwd:b,json:y}));R(n,0,`flow discover`);let r=L(t),i=ee(r);if(t.json){F(i);return}if(!i.length){U.stdout.write(`No flows found in .coder/flows/ (workspace) or ~/.coder/flows/ (global).
66
- `),U.stdout.write(`\n${D([`Authoring guide: coder docs flows`],j)}\n`);return}let a=j;U.stdout.write(a.bold(a.light(`${`name`.padEnd(24)} ${`scope`.padEnd(10)} path\n`)));for(let e of i){let t=e.scope===`workspace`?G.relative(r,e.path)||e.path:e.path.replace(pt.homedir(),`~`);U.stdout.write(`${a.cyan(e.name.padEnd(24))} ${a.light(e.scope.padEnd(10))} ${a.light(t)}\n`)}U.stdout.write(`\n${D([`Run one: coder flow run <name>`,`Recent runs: coder flow list`],a)}\n`)}function sn(e){let t=Ye(`${V(e.runId)}/journal.jsonl`);return{...e,journal:t.map(e=>({kind:e.kind,taskId:e.taskId,tokens:e.tokens}))}}function cn(e,t,r=`all`){if(t){F(sn(e));return}let i=j,a=!U.stdout.isTTY;U.stdout.write(`${i.bold(`Flow`)} ${i.cyan(e.name)} ${i.dim(`(${e.runId})`)} — ${i.bold(x(e.status))}\n`);let o=He(e.runId),s=o.filter(e=>n.includes(e.status)).length,c=e.status===`running`?`${s}/${o.length} tasks`:`${e.taskCount} tasks`;if(U.stdout.write(`${i.dim(`started ${e.startedAt}${e.endedAt?` · ended ${e.endedAt}`:``} · ${c}`)}\n`),r!==0){let t=It(e.runId),n=new Map,s=new Map,c=new Map,l=[];for(let e of t)if(e.kind===`task-start`){let t={name:Ft(e.name,e.prompt),agent:e.agent,depth:e.depth??0};n.set(e.taskId,t),s.set(e.taskId,t)}else if(e.kind===`task-end`){s.delete(e.taskId);let t=n.get(e.taskId);l.push({depth:t?.depth??0,body:$(Q(e.status,a),t?.name??null,e.taskId,e.tokens,t?.agent)})}else if(e.kind===`gate-start`)c.set(e.gateId,{cmd:e.cmd,depth:e.depth??0});else if(e.kind===`gate`)e.gateId&&c.delete(e.gateId),l.push({depth:e.depth??0,body:Lt(e,a)});else if(e.kind===`log`)for(let t of e.message.split(`
67
- `))l.push({depth:e.depth??0,body:i.light(t),log:!0});else e.kind===`flow-start`&&l.push({depth:e.depth-1,body:i.bold(`flow ${e.name}`)});for(let[e,t]of s)l.push({depth:t.depth??0,body:$(Q(`running`,a),t.name,e,null,t.agent)+(a?``:` ${i.light(`running`)}`)});for(let e of c.values())l.push({depth:e.depth,body:Rt(e.cmd,Q(`running`,a))+(a?``:` ${i.light(`running`)}`)});if(!l.length)for(let t of r===`all`?o:He(e.runId,r))l.push({depth:0,body:$(Q(t.status,a),t.name,t.taskId??`-`,t.tokens)});let u=Wt(l,a),d=r===`all`?u:u.slice(-r);d.length&&U.stdout.write(`\n${d.join(`
68
- `)}\n`)}e.endedAt&&e.result!==void 0&&U.stdout.write(`\n${i.bold(`Result:`)}\n${oe(e.result)}\n`),e.error&&U.stdout.write(`\n${i.red(`error:`)} ${e.error}\n`),rn(e.ledger);let l=e.status===`running`?[`Follow live: coder flow watch ${e.runId}`,`Stop it: coder flow stop ${e.runId}`]:e.status===`stopped`||e.status===`failed`?[`Resume: coder flow resume ${e.runId}`]:[];l.length&&U.stdout.write(`\n${D(l,i)}\n`)}async function ln(e){let{options:t,positionals:n}=g(e,K.object({cwd:b,json:y,tail:p})),r=n[0]?I(n[0]):Pe();if(!r){if(t.json){F(null);return}P(n[0]?`No flow run "${n[0]}".`:`No flow runs yet.`,{hint:`Run one: coder flow run <name>`})}cn(r,!!t.json,t.tail)}async function un(e){let{options:t,positionals:n}=g(e,K.object({cwd:b,json:y,tail:p})),r=n[0]?I(n[0]):Pe();r||P(n[0]?`No flow run "${n[0]}".`:`No flow runs yet.`,{hint:`Run one: coder flow run <name>`}),await Xt(r.runId,{json:t.json,stream:!0,tail:t.tail})}async function dn(e){let{options:t,positionals:n}=g(e,K.object({cwd:b,json:y,"keep-tasks":y}));R(n,1,`flow stop`);try{let e=await Ze(n[0],{keepTasks:t[`keep-tasks`]});if(t.json){F(e);return}let r=j;e.status===`failed`?U.stdout.write(`${r.dim(`[flow]`)} run ${r.cyan(e.runId)} orchestrator died — marked ${x(`failed`)}.\n`):U.stdout.write(`${r.dim(`[flow]`)} run ${r.cyan(e.runId)} ${x(e.status)}.\n`),e.stoppedTasks.length&&U.stdout.write(`${r.dim(`[flow]`)} stopped tasks: ${e.stoppedTasks.join(`, `)}\n`),e.keptTasks.length&&U.stdout.write(`${r.dim(`[flow]`)} left running: ${e.keptTasks.join(`, `)}\n`),U.stdout.write(`\n${D([`Resume: coder flow resume ${e.runId}`],r)}\n`)}catch(e){throw e instanceof A&&e.code===`flow-failed`&&P(e.message,e.hint?{hint:e.hint}:{}),e}}async function fn(e){let{options:t,positionals:n}=g(e,K.object(Zt)),r=n[0]?I(n[0]):Pe();r||P(n[0]?`No flow run "${n[0]}".`:`No flow runs to resume.`,{hint:`Run one: coder flow run <name>`}),At(r.script);let i={cwd:L(t),dryRun:t[`dry-run`],concurrency:Qt(t.concurrency),maxTasks:Qt(t[`max-tasks`]),...t.args===void 0?{}:{args:Ot(t.args,[])}};if(!await $t(t,i,()=>je(``,i,r.runId)))try{en(await Se(r.runId,i,Kt(t)),t.json)}catch(e){tn(e,`resume`,i.dryRun)}}function pn(e){let t=I(e);return t||P(`No flow run "${e}".`,{hint:`Recent runs: coder flow list`}),(t.status===`running`||t.status===`queued`)&&P(`Run ${t.runId} is still running.`,{hint:`Stop it first: coder flow stop ${t.runId}`}),t}async function mn(e){let{options:t,positionals:n}=g(e,K.object({cwd:b,json:y,"all-stopped":y}));if(R(n,1,`flow archive`),t[`all-stopped`]){let e=Oe().filter(e=>e.status!==`running`&&e.status!==`queued`);for(let t of e)Fe(t);let n=e.map(e=>e.runId);if(t.json){F({archived:n,count:n.length});return}U.stdout.write(n.length?`Archived ${n.length} stopped run${n.length===1?``:`s`}.\n`:`${j.dim(`No stopped runs to archive.`)}\n`);return}let r=n[0];r||P(`Missing run id.`,{hint:[`Archive one: coder flow archive <run-id>`,`Archive all stopped: coder flow archive --all-stopped`]});let i=pn(r);if(Fe(i),t.json){F({runId:i.runId,archived:!0});return}U.stdout.write(`Archived run ${j.cyan(i.runId)}.\n`)}async function hn(e){let{options:t,positionals:n}=g(e,K.object({cwd:b,json:y,"all-archived":y}));if(R(n,1,`flow delete`),t[`all-archived`]){let e=Ke().filter(e=>Ce(e.runId)).map(e=>e.runId);if(t.json){F({deleted:e,count:e.length});return}U.stdout.write(e.length?`Deleted ${e.length} archived run${e.length===1?``:`s`}.\n`:`${j.dim(`No archived runs to delete.`)}\n`);return}let r=n[0];r||P(`Missing run id.`,{hint:[`Delete one: coder flow delete <run-id>`,`Delete all archived: coder flow delete --all-archived`]});let i=pn(r);if(Ce(i.runId),t.json){F({runId:i.runId,deleted:!0});return}U.stdout.write(`Deleted run ${j.cyan(i.runId)}.\n`)}const gn={run:nn,list:an,discover:on,result:ln,watch:un,stream:un,stop:dn,resume:fn,archive:mn,delete:hn};async function _n(e){let[t,...n]=e;if(t===void 0||t===`help`||t===`-h`||t===`--help`){U.stdout.write(X());return}let r=gn[t];if(r||(U.stdout.write(X()),U.stdout.write(`
69
- `),P(`Unknown flow subcommand "${t}".`,{hint:`Run a flow: coder flow run <name>`})),Tt(n)){let e=t===`stream`?`watch`:t;U.stdout.write(Z(`flow ${e}`)??X());return}await r(n)}function vn(e){return e.resumeThreadId?e.currentPrompt??e.prompt??``:`<system>
66
+ `),H.stdout.write(`\n${O([`Run one: coder flow run <name>`,`Runnable flows: coder flow discover`],x)}\n`);return}let o=x,s=(e,t,n)=>Math.min(t,Math.max(e,...n.map(e=>e.length))),c={id:s(6,28,i.map(e=>e.runId)),name:s(4,30,i.map(e=>e.name))};H.stdout.write(o.bold(o.light(`${`run-id`.padEnd(c.id)} ${`name`.padEnd(c.name)} ${`status`.padEnd(10)} ${`tasks`.padEnd(9)} ${`tokens`.padEnd(10)} age\n`)));for(let e of i){let t=Object.values(e.ledger).reduce((e,t)=>e+t.total,0);H.stdout.write(`${o.cyan(A(e.runId,c.id))} ${A(e.name,c.name)} ${P(e.status,10)} ${o.light(A(`${e.taskCount} tasks`,9))} ${o.light(A(t?`${se(t)} tok`:`-`,10))} ${o.light(j(B(e.startedAt)))}\n`)}a&&H.stdout.write(o.dim(`\n... ${a} more not shown (--limit ${r})\n`)),H.stdout.write(`\n${O([`Result: coder flow result <run-id>`,`Tasks: coder list`,`Runnable flows: coder flow discover`],o)}\n`)}async function on(e){let{options:t,positionals:n}=g(e,G.object({cwd:b,json:y}));I(n,0,`flow discover`);let r=M(t),i=S(r);if(t.json){R(i);return}if(!i.length){H.stdout.write(`No flows found in .coder/flows/ (workspace) or ~/.coder/flows/ (global).
67
+ `),H.stdout.write(`\n${O([`Authoring guide: coder docs flows`],x)}\n`);return}let a=x;H.stdout.write(a.bold(a.light(`${`name`.padEnd(24)} ${`scope`.padEnd(10)} path\n`)));for(let e of i){let t=e.scope===`workspace`?W.relative(r,e.path)||e.path:e.path.replace(mt.homedir(),`~`);H.stdout.write(`${a.cyan(e.name.padEnd(24))} ${a.light(e.scope.padEnd(10))} ${a.light(t)}\n`)}H.stdout.write(`\n${O([`Run one: coder flow run <name>`,`Recent runs: coder flow list`],a)}\n`)}function sn(e){let t=Ye(`${z(e.runId)}/journal.jsonl`);return{...e,journal:t.map(e=>({kind:e.kind,taskId:e.taskId,tokens:e.tokens}))}}function cn(e,t,r=`all`){if(t){R(sn(e));return}let i=x,a=!H.stdout.isTTY;H.stdout.write(`${i.bold(`Flow`)} ${i.cyan(e.name)} ${i.dim(`(${e.runId})`)} — ${i.bold(P(e.status))}\n`);let o=We(e.runId),s=o.filter(e=>n.includes(e.status)).length,c=e.status===`running`?`${s}/${o.length} tasks`:`${e.taskCount} tasks`;if(H.stdout.write(`${i.dim(`started ${e.startedAt}${e.endedAt?` · ended ${e.endedAt}`:``} · ${c}`)}\n`),r!==0){let t=It(e.runId),n=new Map,s=new Map,c=new Map,l=[];for(let e of t)if(e.kind===`task-start`){let t={name:Ft(e.name,e.prompt),agent:e.agent,depth:e.depth??0};n.set(e.taskId,t),s.set(e.taskId,t)}else if(e.kind===`task-end`){s.delete(e.taskId);let t=n.get(e.taskId);l.push({depth:t?.depth??0,body:$(Q(e.status,a),t?.name??null,e.taskId,e.tokens,t?.agent)})}else if(e.kind===`gate-start`)c.set(e.gateId,{cmd:e.cmd,depth:e.depth??0});else if(e.kind===`gate`)e.gateId&&c.delete(e.gateId),l.push({depth:e.depth??0,body:Lt(e,a)});else if(e.kind===`log`)for(let t of e.message.split(`
68
+ `))l.push({depth:e.depth??0,body:i.light(t),log:!0});else e.kind===`flow-start`&&l.push({depth:e.depth-1,body:i.bold(`flow ${e.name}`)});for(let[e,t]of s)l.push({depth:t.depth??0,body:$(Q(`running`,a),t.name,e,null,t.agent)+(a?``:` ${i.light(`running`)}`)});for(let e of c.values())l.push({depth:e.depth,body:Rt(e.cmd,Q(`running`,a))+(a?``:` ${i.light(`running`)}`)});if(!l.length)for(let t of r===`all`?o:We(e.runId,r))l.push({depth:0,body:$(Q(t.status,a),t.name,t.taskId??`-`,t.tokens)});let u=Wt(l,a),d=r===`all`?u:u.slice(-r);d.length&&H.stdout.write(`\n${d.join(`
69
+ `)}\n`)}e.endedAt&&e.result!==void 0&&H.stdout.write(`\n${i.bold(`Result:`)}\n${He(e.result)}\n`),e.error&&H.stdout.write(`\n${i.red(`error:`)} ${e.error}\n`),rn(e.ledger);let l=e.status===`running`?[`Follow live: coder flow watch ${e.runId}`,`Stop it: coder flow stop ${e.runId}`]:e.status===`stopped`||e.status===`failed`?[`Resume: coder flow resume ${e.runId}`]:[];l.length&&H.stdout.write(`\n${O(l,i)}\n`)}async function ln(e){let{options:t,positionals:n}=g(e,G.object({cwd:b,json:y,tail:p})),r=n[0]?F(n[0]):Fe();if(!r){if(t.json){R(null);return}D(n[0]?`No flow run "${n[0]}".`:`No flow runs yet.`,{hint:`Run one: coder flow run <name>`})}cn(r,!!t.json,t.tail)}async function un(e){let{options:t,positionals:n}=g(e,G.object({cwd:b,json:y,tail:p})),r=n[0]?F(n[0]):Fe();r||D(n[0]?`No flow run "${n[0]}".`:`No flow runs yet.`,{hint:`Run one: coder flow run <name>`}),await Xt(r.runId,{json:t.json,stream:!0,tail:t.tail})}async function dn(e){let{options:t,positionals:n}=g(e,G.object({cwd:b,json:y,"keep-tasks":y}));I(n,1,`flow stop`);try{let e=await Ze(n[0],{keepTasks:t[`keep-tasks`]});if(t.json){R(e);return}let r=x;e.status===`failed`?H.stdout.write(`${r.dim(`[flow]`)} run ${r.cyan(e.runId)} orchestrator died — marked ${P(`failed`)}.\n`):H.stdout.write(`${r.dim(`[flow]`)} run ${r.cyan(e.runId)} ${P(e.status)}.\n`),e.stoppedTasks.length&&H.stdout.write(`${r.dim(`[flow]`)} stopped tasks: ${e.stoppedTasks.join(`, `)}\n`),e.keptTasks.length&&H.stdout.write(`${r.dim(`[flow]`)} left running: ${e.keptTasks.join(`, `)}\n`),H.stdout.write(`\n${O([`Resume: coder flow resume ${e.runId}`],r)}\n`)}catch(e){throw e instanceof k&&e.code===`flow-failed`&&D(e.message,e.hint?{hint:e.hint}:{}),e}}async function fn(e){let{options:t,positionals:n}=g(e,G.object(Zt)),r=n[0]?F(n[0]):Fe();r||D(n[0]?`No flow run "${n[0]}".`:`No flow runs to resume.`,{hint:`Run one: coder flow run <name>`}),At(r.script);let i={cwd:M(t),dryRun:t[`dry-run`],concurrency:Qt(t.concurrency),maxTasks:Qt(t[`max-tasks`]),...t.args===void 0?{}:{args:Ot(t.args,[])}};if(!await $t(t,i,()=>je(``,i,r.runId)))try{en(await we(r.runId,i,Kt(t)),t.json)}catch(e){tn(e,`resume`,i.dryRun)}}function pn(e){let t=F(e);return t||D(`No flow run "${e}".`,{hint:`Recent runs: coder flow list`}),(t.status===`running`||t.status===`queued`)&&D(`Run ${t.runId} is still running.`,{hint:`Stop it first: coder flow stop ${t.runId}`}),t}async function mn(e){let{options:t,positionals:n}=g(e,G.object({cwd:b,json:y,"all-stopped":y}));if(I(n,1,`flow archive`),t[`all-stopped`]){let e=Oe().filter(e=>e.status!==`running`&&e.status!==`queued`);for(let t of e)Le(t);let n=e.map(e=>e.runId);if(t.json){R({archived:n,count:n.length});return}H.stdout.write(n.length?`Archived ${n.length} stopped run${n.length===1?``:`s`}.\n`:`${x.dim(`No stopped runs to archive.`)}\n`);return}let r=n[0];r||D(`Missing run id.`,{hint:[`Archive one: coder flow archive <run-id>`,`Archive all stopped: coder flow archive --all-stopped`]});let i=pn(r);if(Le(i),t.json){R({runId:i.runId,archived:!0});return}H.stdout.write(`Archived run ${x.cyan(i.runId)}.\n`)}async function hn(e){let{options:t,positionals:n}=g(e,G.object({cwd:b,json:y,"all-archived":y}));if(I(n,1,`flow delete`),t[`all-archived`]){let e=Je().filter(e=>Te(e.runId)).map(e=>e.runId);if(t.json){R({deleted:e,count:e.length});return}H.stdout.write(e.length?`Deleted ${e.length} archived run${e.length===1?``:`s`}.\n`:`${x.dim(`No archived runs to delete.`)}\n`);return}let r=n[0];r||D(`Missing run id.`,{hint:[`Delete one: coder flow delete <run-id>`,`Delete all archived: coder flow delete --all-archived`]});let i=pn(r);if(Te(i.runId),t.json){R({runId:i.runId,deleted:!0});return}H.stdout.write(`Deleted run ${x.cyan(i.runId)}.\n`)}const gn={run:nn,list:an,discover:on,result:ln,watch:un,stream:un,stop:dn,resume:fn,archive:mn,delete:hn};async function _n(e){let[t,...n]=e;if(t===void 0||t===`help`||t===`-h`||t===`--help`){H.stdout.write(Y());return}let r=gn[t];if(r||(H.stdout.write(Y()),H.stdout.write(`
70
+ `),D(`Unknown flow subcommand "${t}".`,{hint:`Run a flow: coder flow run <name>`})),Tt(n)){let e=t===`stream`?`watch`:t;H.stdout.write(X(`flow ${e}`)??Y());return}await r(n)}function vn(e){return e.resumeThreadId?e.currentPrompt??e.prompt??``:`<system>
70
71
  You are running inside a coder task: do the work yourself, directly.
71
72
  Do not load the coder skill (recursive), and never dispatch through the \`coder\` CLI - nested dispatch is disabled.
72
73
  When finished, provide a concise implementation result summary.
73
74
  Your turn is one-shot: background processes will not re-invoke you after it ends, so verify synchronously before finishing.${e.system?`\n-------\n${e.system}`:``}
74
75
  </system>
75
76
 
76
- ${e.prompt??``}`}function yn(e,t){let n=0;return()=>{Date.now()-n>=1e4&&(n=Date.now(),c(e,t))}}function bn(e,t,{echo:n}){return r=>{let i=typeof r==`string`?{message:r}:r;u(e,t,i),n&&i.message&&U.stderr.write(`[coder] ${i.message}\n`)}}async function xn(t,n,{echo:a}){let o=i(t),s=r(t,n.id),c=B(t),l=bn(t,n.id,{echo:a}),d=z[n.permissions??`auto`]??z.auto,f=d.approvalPolicy===`never`?void 0:he({workspaceRoot:o,jobDir:s,mode:d.approvalMode,escalationTimeoutMs:c.approvals.escalationTimeoutMs,allowedNetworkHosts:c.approvals.allowedNetworkHosts,onEvent:e=>{u(t,n.id,e),a&&e.message&&U.stderr.write(`[coder] ${e.message}\n`)}}),p=n.model?c.models?.[n.model]:void 0,m=p&&Le(p)?p:void 0;if(m&&!m.wireApi&&n.model){let e=await tt(m);e&&(m={...m,...e},c.models[n.model]=m,qe(t,n.model,e),u(t,n.id,{kind:`info`,message:`detected wire api for ${n.model}: ${e.wireApi} @ ${m.baseUrl}`}))}if(m?.envKey&&!U.env[m.envKey])throw Error(`Missing environment variable: \`${m.envKey}\`.`);let h=m?await it(m,m.wireApi??`chat`):null,g=Ae(c,n.model,h??void 0);try{let r=await Je(t,{prompt:vn(n),model:g?.model??ke(n.model),modelProvider:g?.modelProvider??null,configOverrides:g?.configOverrides??null,effort:n.effort,sandbox:d.sandbox,approvalPolicy:d.approvalPolicy,approvalsReviewer:d.approvalMode===`auto`?`auto_review`:null,onApprovalRequest:f,onHeartbeat:yn(t,n.id),resumeThreadId:n.resumeThreadId??null,onProgress:r=>{l(r);let i=typeof r==`object`?r.threadId:null,a=typeof r==`object`?r.turnId:null;(i||a)&&e(t,n.id,{status:`running`,...i?{threadId:i}:{},...a?{turnId:a}:{}})}});return e(t,n.id,{status:r.status===0?`completed`:`failed`,threadId:r.threadId,turnId:r.turnId,completedAt:new Date().toISOString()}),Cn(t,n,s,r),r}finally{await h?.close()}}async function Sn(t,n,{echo:i}){let a=r(t,n.id),o=B(t),s=bn(t,n.id,{echo:i}),c=z[n.permissions??`auto`]??z.auto,l=await be(t,{prompt:vn(n),model:n.model,effort:n.effort,permissions:n.permissions,approvalJobId:c.approvalMode===`auto`?n.id:null,allowedNetworkHosts:o.approvals.allowedNetworkHosts,resumeSessionId:n.resumeThreadId??null,onHeartbeat:yn(t,n.id),onProgress:r=>{s(r),r.threadId&&e(t,n.id,{status:`running`,threadId:r.threadId})}});return e(t,n.id,{status:l.status===0?`completed`:`failed`,threadId:l.threadId,completedAt:new Date().toISOString()}),Cn(t,n,a,l),l}function Cn(e,t,n,r){S(G.join(n,`result.json`),r);let i={at:new Date().toISOString(),prompt:t.currentPrompt??t.prompt??null,...r};W.appendFileSync(G.join(n,`results.jsonl`),`${JSON.stringify(i)}\n`,`utf8`)}function wn(e){return e.engine===`claude`?Sn:xn}async function Tn(t,n){for(let r=0;r<2;){let i=h(t,n);if(!i||i.status===`failed`||i.status===`cancelled`)return;let a=d(t,n);if(a.length===0){r+=1,await new Promise(e=>setTimeout(e,300));continue}r=0;for(let r of a){let a=e(t,n,{status:`running`,currentPrompt:r,resumeThreadId:i.threadId??null});u(t,n,{message:`Running steered follow-up.`});try{await wn(a)(t,a,{echo:!1})}catch(r){let i=r instanceof Error?r.message:String(r);e(t,n,{status:`failed`,error:i}),u(t,n,{kind:`error`,message:i});return}}}}function En(e,t){if(e instanceof A)switch(e.code){case`chain-exhausted`:F(e.payload),U.exit(3);case`read-only-unavailable`:Dn(e.message,t);break;case`startup-failed`:t.json&&(F({taskId:e.taskId,status:`failed`,detail:e.message}),U.exit(1)),P(`Task ${e.taskId} failed to start.${e.message?`\n${e.message}`:``}`,{hint:`See: coder task result ${e.taskId}`});break;default:P(e.message,e.hint?{hint:e.hint}:{})}throw e}function Dn(e,t){let n=`read-only unavailable on this host: the OS sandbox failed to start (Linux/WSL2 needs bubblewrap + socat). Re-dispatch with --permissions auto (or workspace-write) if writes are acceptable, or install the sandbox deps.`;t.json?F({error:n,code:`read-only-unavailable`,detail:e}):U.stderr.write(`[coder] ${n}\n`),U.exit(1)}async function On(e){U.env.CODER_WORKER&&P(`Nested dispatch refused: this shell is already inside a coder task. Do the work yourself, directly in this session - ignore any skill or instruction telling you to orchestrate via the coder CLI.`);let{options:t,positionals:n}=g(e,K.object({...v,agent:b,model:b,effort:b,permissions:b,resume:b,host:b,name:b,system:b,background:y,wait:y,"simulate-approval":y})),r=L(t),i=n.join(` `).trim();i||P(`Missing task text.`,{hint:[`Usage: coder run "<task text>"`,`Help: coder task run --help`]});let a={prompt:i,cwd:r,agent:t.agent,model:t.model,effort:t.effort,permissions:t.permissions,name:t.name,system:t.system,resume:t.resume,wait:t.wait,simulateApproval:t[`simulate-approval`],onFallback:({agent:e,detail:t,next:n})=>U.stderr.write(`[coder] ${e} failed to start (${t}); falling back to ${n}.\n`),onInstallNote:e=>U.stderr.write(`[coder] ${e}\n`)},o;try{o=await O(a)}catch(e){En(e,t)}if(t.wait)for(;;){let e=o.taskId,n=o.job,s=[` result: coder task result ${e}`,` steer: coder task steer ${e} "<follow-up>"`].join(`
77
- `);t.json||(U.stderr.write(`${j.dim(`[coder]`)} task ${j.cyan(e)} started (${n.status}); waiting for it to finish — Ctrl-C to detach (it keeps running).\n`),U.stderr.write(`${j.dim(s)}\n`));let c=()=>{U.stderr.write(`\n${j.dim(`[coder] detached — task still running: coder task result ${e}`)}\n`),U.exit(130)};U.on(`SIGINT`,c);let l;try{l=await C(r,e)}catch(n){throw U.off(`SIGINT`,c),n instanceof A&&n.code===`approval-pending`&&we(e,n.approval,t.json),n}U.off(`SIGINT`,c);let u=l.job,d=l.result,f=d?.error?.message??``;if(u.status===`failed`&&se(u.permissions??`auto`,f)&&Dn(f,t),u.status===`failed`&&ce.test(f)){let e=B(r).chain,n=e[e.indexOf(o.agent)+1];n||(F(re(o.agent,f,u.permissions??`auto`,t.system,i)),U.exit(3)),U.stderr.write(`[coder] ${o.agent} failed to start (${f}); falling back to ${n}.\n`);try{o=await O({...a,agent:n,model:void 0,effort:void 0,name:void 0,resume:void 0,simulateApproval:void 0})}catch(e){En(e,t)}continue}if(t.json)F({taskId:e,status:u.status,finalMessage:d?.finalMessage,...f?{error:f}:{},tokens:d?.tokens??null,model:d?.model??u.model??null});else{U.stdout.write(`\n${d?.finalMessage||(f?`${j.red(`error:`)} ${f}`:`(no final message)`)}\n\n`);let t=d?.tokens?` tokens=${ae(d.tokens,d.model??u.model)}`:``;U.stderr.write(`${j.dim(`[coder] task=${e} status=${u.status}${t}`)}\n`)}U.exit(u.status===`completed`?0:1)}let s=o.taskId,c=o.job,l=[` result: coder task result ${s}`,` steer: coder task steer ${s} "<follow-up>"`].join(`
78
- `);if(t.json){F({taskId:s,status:c.status,startupCheck:o.startupCheck,commands:{result:`coder task result ${s}`,steer:`coder task steer ${s} "<follow-up>"`,stop:`coder task stop ${s}`,watch:`coder task watch ${s}`}});return}U.stdout.write(`${j.dim(`[coder]`)} task ${j.cyan(s)} started in the background (${c.status}).\n`),U.stdout.write(`${j.dim(l)}\n`)}async function kn(t){let{options:n,positionals:i}=g(t,K.object({cwd:b})),a=L(n),o=i[0],s=h(a,o);s||P(`Worker: task ${o} not found.`),e(a,o,{status:`running`,pid:U.pid});try{if(s.simulateApproval){let t=await te(r(a,o),{onEvent:e=>u(a,o,e)});if(u(a,o,{message:`simulated approval: ${t}`}),t===`decline`){e(a,o,{status:`cancelled`,completedAt:new Date().toISOString(),error:`simulated approval denied`});return}}await wn(s)(a,s,{echo:!1}),await Tn(a,o)}catch(t){let n=t instanceof Error?t.message:String(t);e(a,o,{status:`failed`,error:n}),u(a,o,{kind:`error`,message:n}),U.exit(1)}}async function An(e){let{options:n,positionals:i}=g(e,K.object({...v,tail:p,wait:y,turns:y}));R(i,1,`task result`);let s=L(n),c=Ve(s,i[0]);if(n.wait){l.includes(c.status)&&U.stderr.write(`${j.dim(`[coder] waiting for task ${c.id} to finish...`)}\n`);let e=await Ee(s,c);c=e.job,e.reason===`approval`&&we(c.id,e.approval,n.json)}let{steps:u,result:d}=pe(s,c.id,{tail:n.tail}),f=o(s,c.id),m=ne(r(s,c.id)).filter(e=>!e.response),h=l.includes(c.status),_=h&&m.length?`waiting-approval`:c.status,b=h?a(s,c.id,1)[0]:void 0,ee=h?t(s,c):c.updatedAt,S=M(ee),C=h&&m.length===0&&S>6e5,w=()=>{n.wait&&U.exit(c.status===`completed`?0:1)};if(n.json)return F({taskId:c.id,name:c.name??null,prompt:c.prompt??null,system:c.system??null,status:_,agent:c.agent,model:c.model??null,effort:c.effort??null,permissions:c.permissions??null,cwd:c.cwd??null,createdAt:c.createdAt??null,completedAt:c.completedAt??null,...h?{idleMs:S,lastActivityAt:ee??null,stalled:C}:{},pendingApprovals:m.map(e=>({id:e.id,summary:e.summary})),...u.length?{steps:u}:{},turnCount:f.length,...n.turns?{turns:f}:{},result:d}),w();let T=j,E=c.createdAt?M(c.createdAt):null,te=!h&&c.completedAt?M(c.completedAt):null,re=c.createdAt&&c.completedAt?Date.parse(c.completedAt)-Date.parse(c.createdAt):null,O=h?E===null?``:`started ${N(E)} ago`:[te===null?``:`finished ${N(te)} ago`,re!==null&&re>=0?`took ${N(re)}`:``].filter(Boolean).join(` · `),k=[`${T.dim(`task`)} ${T.cyan(c.id)}`,...c.name?[`${T.dim(`name`)} ${c.name}`]:[],`${T.dim(`status`)} ${x(_)}${O?` ${T.dim(`(${O})`)}`:``}`,`${T.dim(`agent`)} ${ve(c)}`,...ye(c,T),...d?.tokens?[`${T.dim(`tokens`)} ${ae(d.tokens,d.model??c.model)}`]:[]];if(c.prompt&&k.push(``,...Ge(c.prompt,T)),m.length){k.push(``,T.dim(`pending approvals:`));for(let e of m)k.push(` ${T.cyan(e.id)} ${e.summary}`),k.push(` ${T.bold(`coder approve ${c.id} ${e.id}`)} ${T.dim(`(--deny to reject)`)}`)}if(u.length){k.push(``,T.dim(`steps:`));for(let e of u){let t=e.message??e.kind;t&&k.push(` ${T.dim(De(t))}`)}}if(k.push(``),n.turns&&f.length?f.forEach((e,t)=>{t&&k.push(``),k.push(T.dim(`— turn ${t+1} of ${f.length}: ${De(String(e.prompt??``))}`)),k.push(String(e.finalMessage||T.dim(`(no final message)`)))}):d?(k.push(ie({...d,error:d.error??void 0},c.error,`(no final message)`,T)),f.length>1&&k.push(T.dim(`(turn ${f.length} of ${f.length} — all answers: coder task result ${c.id} --turns)`))):h?k.push(T.dim(C?`Result pending, but no progress for ${N(S)} — the task may be stalled.${b?` Last: ${De(b.message??b.kind??``)}`:``}`:`Result pending — task is still running.`)):k.push(T.dim(`(no result)`)),h&&!n.wait){let e=[`Wait for it: coder task result ${c.id} --wait`,`Follow live: coder task watch ${c.id}`];C&&e.push(`Check the transcript: coder task result ${c.id} --tail all`),k.push(``,D(e,T))}return U.stdout.write(`${k.join(`
79
- `)}\n`),d?.touchedFiles?.length&&U.stderr.write(`[coder] touched files: ${d.touchedFiles.join(`, `)}\n`),w()}function jn(e){return s(e).filter(e=>l.includes(e.status)).flatMap(t=>ne(r(e,t.id)).filter(e=>!e.response).map(e=>({taskId:t.id,id:e.id,summary:String(e.summary??``),createdAt:e.createdAt?String(e.createdAt):void 0})))}async function Mn(e){let{options:t,positionals:n}=g(e,K.object(v));R(n,1,`task approvals`);let i=L(t),a=j;if(n[0]){let e=Ve(i,n[0]),o=ne(r(i,e.id)).map(e=>({id:e.id,summary:e.summary,createdAt:e.createdAt,answered:e.response?.decision??null}));if(t.json){F(o);return}if(!o.length){U.stdout.write(`${a.dim(`No approvals for task ${e.id}.`)}\n`);return}for(let e of o){let t=e.answered??`pending`;U.stdout.write(`${a.cyan(e.id)} ${t.padEnd(8)} ${a.dim(String(e.summary??``))}\n`)}let s=o.filter(e=>!e.answered);if(s.length){let e=s.length===1?s[0].id:`<approval-id>`;U.stdout.write(`\n${D([`Answer: coder approve ${e} [--deny]`],a)}\n`)}return}let o=jn(i);if(t.json){F(o);return}if(!o.length){U.stdout.write(`${a.dim(`No pending approvals.`)}\n`);return}let s={id:Math.max(11,...o.map(e=>e.id.length)),task:Math.max(7,...o.map(e=>e.taskId.length))};U.stdout.write(a.bold(a.light(`${`approval-id`.padEnd(s.id)} ${`task-id`.padEnd(s.task)} age summary\n`)));for(let e of o){let t=e.createdAt?N(M(e.createdAt)):`-`;U.stdout.write(`${a.cyan(e.id.padEnd(s.id))} ${a.cyan(e.taskId.padEnd(s.task))} ${t.padEnd(5)} ${a.light(e.summary)}\n`)}let c=o.length===1?o[0].id:`<approval-id>`;U.stdout.write(`\n${D([`Answer: coder approve ${c} [--deny]`],a)}\n`)}async function Nn(e){let{options:t,positionals:n}=g(e,K.object({...v,deny:y}));R(n,2,`task approve`);let i=L(t),[a,o]=n;a&&!o&&a.startsWith(`apr-`)&&(o=a,a=jn(i).find(e=>e.id===o)?.taskId,a||P(`No pending approval "${o}".`,{hint:`List them: coder approvals`})),(!a||!o)&&P(`Missing approval id.`,{hint:[`List them: coder approvals`,`Usage: coder approve [task-id] <approval-id> [--deny]`]});let s=Ve(i,a),c=t.deny?`decline`:`accept`;if(Qe(r(i,s.id),o,c),t.json){F({taskId:s.id,approvalId:o,decision:c});return}U.stdout.write(`${t.deny?`Denied`:`Approved`} ${j.cyan(o)} on task ${j.cyan(s.id)}.\n`)}function Pn(e){return G.join(e,`sidecar.json`)}function Fn(e){return Ne(Pn(e))??{sessionId:null,declineStreak:0}}async function In(e){let t=G.join(e,`sidecar.lock`),n=Date.now()+12e4;for(;;)try{return W.mkdirSync(t),()=>{try{W.rmdirSync(t)}catch{}}}catch{try{if(Date.now()-W.statSync(t).mtimeMs>9e4){W.rmdirSync(t);continue}}catch{continue}if(Date.now()>n)throw Error(`sidecar lock wait timed out`);await new Promise(e=>setTimeout(e,250))}}function Ln(e,t,n,r){return[`-p`,r,`--output-format`,`json`,`--model`,`sonnet`,`--effort`,`low`,n?`--resume`:`--session-id`,t,...fe,`--add-dir`,e]}function Rn(e,t,n,r,i){let a=Ln(t,n,r,i);return new Promise((t,n)=>{let r=dt(`claude`,a,{cwd:e,stdio:[`ignore`,`pipe`,`pipe`]}),i=``,o=``,s=setTimeout(()=>{r.kill(`SIGKILL`),n(Error(`sidecar call timed out`))},12e4);r.stdout.on(`data`,e=>i+=e),r.stderr.on(`data`,e=>o+=e),r.on(`error`,e=>{clearTimeout(s),n(e)}),r.on(`close`,e=>{if(clearTimeout(s),e!==0){n(Error(`sidecar claude exited ${e}: ${o.trim().slice(0,200)}`));return}try{let e=JSON.parse(i);if(e.is_error){n(Error(`sidecar turn errored: ${String(e.result??``).slice(0,200)}`));return}t(String(e.result??``))}catch{n(Error(`sidecar returned unparseable output`))}})})}function zn(e){let t=e.match(/\{[^{}]*"decision"[^{}]*\}/);if(!t)return null;try{let e=JSON.parse(t[0]);if(e.decision===`accept`||e.decision===`decline`||e.decision===`escalate`)return{decision:e.decision,reason:String(e.reason??``)}}catch{}return null}async function Bn(e,t,n){let r=null;try{r=await In(t);let i=Fn(t);if(i.declineStreak>=3)return{decision:`escalate`,reason:`sidecar decline streak; needs human review`};if(!i.sessionId){let r=ht();await Rn(e,t,r,!1,`You are the approval reviewer for a "coder" background coding task. The task runs inside an OS sandbox; you review only actions that escape it.
77
+ ${e.prompt??``}`}function yn(e,t){let n=0;return()=>{Date.now()-n>=1e4&&(n=Date.now(),c(e,t))}}function bn(e,t,{echo:n}){return r=>{let i=typeof r==`string`?{message:r}:r;u(e,t,i),n&&i.message&&H.stderr.write(`[coder] ${i.message}\n`)}}async function xn(t,n,{echo:a}){let o=i(t),s=r(t,n.id),c=N(t),l=bn(t,n.id,{echo:a}),d=L[n.permissions??`auto`]??L.auto,f=d.approvalPolicy===`never`?void 0:w({workspaceRoot:o,jobDir:s,mode:d.approvalMode,escalationTimeoutMs:c.approvals.escalationTimeoutMs,allowedNetworkHosts:c.approvals.allowedNetworkHosts,onEvent:e=>{u(t,n.id,e),a&&e.message&&H.stderr.write(`[coder] ${e.message}\n`)}}),p=n.model?c.models?.[n.model]:void 0,m=p&&Ke(p)?p:void 0;if(m&&!m.wireApi&&n.model){let e=await nt(m);e&&(m={...m,...e},c.models[n.model]=m,ke(t,n.model,e),u(t,n.id,{kind:`info`,message:`detected wire api for ${n.model}: ${e.wireApi} @ ${m.baseUrl}`}))}if(m?.envKey&&!H.env[m.envKey])throw Error(`Missing environment variable: \`${m.envKey}\`.`);let h=m?await at(m,m.wireApi??`chat`):null,g=Ve(c,n.model,h??void 0);try{let r=await et(t,{prompt:vn(n),model:g?.model??Ae(n.model),modelProvider:g?.modelProvider??null,configOverrides:g?.configOverrides??null,effort:n.effort,sandbox:d.sandbox,approvalPolicy:d.approvalPolicy,approvalsReviewer:d.approvalMode===`auto`?`auto_review`:null,onApprovalRequest:f,onHeartbeat:yn(t,n.id),resumeThreadId:n.resumeThreadId??null,onControlReady:(r,i,a)=>{e(t,n.id,{status:`running`,steerEndpoint:r,threadId:i,turnId:a})},onProgress:r=>{l(r);let i=typeof r==`object`?r.threadId:null,a=typeof r==`object`?r.turnId:null;(i||a)&&e(t,n.id,{status:`running`,...i?{threadId:i}:{},...a?{turnId:a}:{}})}});return e(t,n.id,{status:r.status===0?`completed`:`failed`,threadId:r.threadId,turnId:r.turnId,steerEndpoint:null,completedAt:new Date().toISOString()}),Cn(t,n,s,r),r}finally{e(t,n.id,{steerEndpoint:null}),await h?.close()}}async function Sn(t,n,{echo:i}){let a=r(t,n.id),o=N(t),s=bn(t,n.id,{echo:i}),c=L[n.permissions??`auto`]??L.auto;try{let r=await xe(t,{prompt:vn(n),model:n.model,effort:n.effort,permissions:n.permissions,approvalJobId:c.approvalMode===`auto`?n.id:null,allowedNetworkHosts:o.approvals.allowedNetworkHosts,resumeSessionId:n.resumeThreadId??null,onHeartbeat:yn(t,n.id),onSteerReady:r=>{e(t,n.id,{status:`running`,steerEndpoint:r})},onProgress:r=>{s(r),r.threadId&&e(t,n.id,{status:`running`,threadId:r.threadId})}});return e(t,n.id,{status:r.status===0?`completed`:`failed`,threadId:r.threadId,steerEndpoint:null,completedAt:new Date().toISOString()}),Cn(t,n,a,r),r}finally{e(t,n.id,{steerEndpoint:null})}}function Cn(e,t,n,r){Pe(W.join(n,`result.json`),r);let i={at:new Date().toISOString(),prompt:t.currentPrompt??t.prompt??null,...r};U.appendFileSync(W.join(n,`results.jsonl`),`${JSON.stringify(i)}\n`,`utf8`)}function wn(e){return e.engine===`claude`?Sn:xn}async function Tn(t,n){for(let r=0;r<2;){let i=h(t,n);if(!i||i.status===`failed`||i.status===`cancelled`)return;let a=d(t,n);if(a.length===0){r+=1,await new Promise(e=>setTimeout(e,300));continue}r=0;for(let r of a){let a=e(t,n,{status:`running`,currentPrompt:r,resumeThreadId:i.threadId??null});u(t,n,{message:`Running steered follow-up.`});try{await wn(a)(t,a,{echo:!1})}catch(r){let i=r instanceof Error?r.message:String(r);e(t,n,{status:`failed`,error:i}),u(t,n,{kind:`error`,message:i});return}}}}function En(e,t){if(e instanceof k)switch(e.code){case`chain-exhausted`:R(e.payload),H.exit(3);case`read-only-unavailable`:Dn(e.message,t);break;case`startup-failed`:t.json&&(R({taskId:e.taskId,status:`failed`,detail:e.message}),H.exit(1)),D(`Task ${e.taskId} failed to start.${e.message?`\n${e.message}`:``}`,{hint:`See: coder task result ${e.taskId}`});break;default:D(e.message,e.hint?{hint:e.hint}:{})}throw e}function Dn(e,t){let n=`read-only unavailable on this host: the OS sandbox failed to start (Linux/WSL2 needs bubblewrap + socat). Re-dispatch with --permissions auto (or workspace-write) if writes are acceptable, or install the sandbox deps.`;t.json?R({error:n,code:`read-only-unavailable`,detail:e}):H.stderr.write(`[coder] ${n}\n`),H.exit(1)}async function On(e){H.env.CODER_WORKER&&D(`Nested dispatch refused: this shell is already inside a coder task. Do the work yourself, directly in this session - ignore any skill or instruction telling you to orchestrate via the coder CLI.`);let{options:t,positionals:n}=g(e,G.object({...v,agent:b,model:b,effort:b,permissions:b,resume:b,host:b,name:b,system:b,background:y,wait:y,"simulate-approval":y})),r=M(t),i=n.join(` `).trim();i||D(`Missing task text.`,{hint:[`Usage: coder run "<task text>"`,`Help: coder task run --help`]});let a={prompt:i,cwd:r,agent:t.agent,model:t.model,effort:t.effort,permissions:t.permissions,name:t.name,system:t.system,resume:t.resume,wait:t.wait,simulateApproval:t[`simulate-approval`],onFallback:({agent:e,detail:t,next:n})=>H.stderr.write(`[coder] ${e} failed to start (${t}); falling back to ${n}.\n`),onInstallNote:e=>H.stderr.write(`[coder] ${e}\n`)},o;try{o=await oe(a)}catch(e){En(e,t)}if(t.wait)for(;;){let e=o.taskId,n=o.job,s=[` result: coder task result ${e}`,` steer: coder task steer ${e} "<follow-up>"`].join(`
78
+ `);t.json||(H.stderr.write(`${x.dim(`[coder]`)} task ${x.cyan(e)} started (${n.status}); waiting for it to finish — Ctrl-C to detach (it keeps running).\n`),H.stderr.write(`${x.dim(s)}\n`));let c=()=>{H.stderr.write(`\n${x.dim(`[coder] detached — task still running: coder task result ${e}`)}\n`),H.exit(130)};H.on(`SIGINT`,c);let l;try{l=await te(r,e)}catch(n){throw H.off(`SIGINT`,c),n instanceof k&&n.code===`approval-pending`&&ze(e,n.approval,t.json),n}H.off(`SIGINT`,c);let u=l.job,d=l.result,f=d?.error?.message??``;if(u.status===`failed`&&ce(u.permissions??`auto`,f)&&Dn(f,t),u.status===`failed`&&ue.test(f)){let e=N(r).chain,n=e[e.indexOf(o.agent)+1];n||(R(E(o.agent,f,u.permissions??`auto`,t.system,i)),H.exit(3)),H.stderr.write(`[coder] ${o.agent} failed to start (${f}); falling back to ${n}.\n`);try{o=await oe({...a,agent:n,model:void 0,effort:void 0,name:void 0,resume:void 0,simulateApproval:void 0})}catch(e){En(e,t)}continue}if(t.json)R({taskId:e,status:u.status,finalMessage:d?.finalMessage,...f?{error:f}:{},tokens:d?.tokens??null,model:d?.model??u.model??null});else{H.stdout.write(`\n${d?.finalMessage||(f?`${x.red(`error:`)} ${f}`:`(no final message)`)}\n\n`);let t=d?.tokens?` tokens=${Se(d.tokens,d.model??u.model)}`:``;H.stderr.write(`${x.dim(`[coder] task=${e} status=${u.status}${t}`)}\n`)}H.exit(u.status===`completed`?0:1)}let s=o.taskId,c=o.job,l=[` result: coder task result ${s}`,` steer: coder task steer ${s} "<follow-up>"`].join(`
79
+ `);if(t.json){R({taskId:s,status:c.status,startupCheck:o.startupCheck,commands:{result:`coder task result ${s}`,steer:`coder task steer ${s} "<follow-up>"`,stop:`coder task stop ${s}`,watch:`coder task watch ${s}`}});return}H.stdout.write(`${x.dim(`[coder]`)} task ${x.cyan(s)} started in the background (${c.status}).\n`),H.stdout.write(`${x.dim(l)}\n`)}async function kn(t){let{options:n,positionals:i}=g(t,G.object({cwd:b})),a=M(n),o=i[0],s=h(a,o);s||D(`Worker: task ${o} not found.`),e(a,o,{status:`running`,pid:H.pid});try{if(s.simulateApproval){let t=await fe(r(a,o),{onEvent:e=>u(a,o,e)});if(u(a,o,{message:`simulated approval: ${t}`}),t===`decline`){e(a,o,{status:`cancelled`,completedAt:new Date().toISOString(),error:`simulated approval denied`});return}}await wn(s)(a,s,{echo:!1}),await Tn(a,o)}catch(t){let n=t instanceof Error?t.message:String(t);e(a,o,{status:`failed`,error:n}),u(a,o,{kind:`error`,message:n}),H.exit(1)}}async function An(e){let{options:n,positionals:i}=g(e,G.object({...v,tail:p,wait:y,turns:y}));I(i,1,`task result`);let s=M(n),c=Me(s,i[0]);if(n.wait){l.includes(c.status)&&H.stderr.write(`${x.dim(`[coder] waiting for task ${c.id} to finish...`)}\n`);let e=await Qe(s,c);c=e.job,e.reason===`approval`&&ze(c.id,e.approval,n.json)}let{steps:u,result:d}=he(s,c.id,{tail:n.tail}),f=o(s,c.id),m=ne(r(s,c.id)).filter(e=>!e.response),h=l.includes(c.status),_=h&&m.length?`waiting-approval`:c.status,b=h?a(s,c.id,1)[0]:void 0,ee=h?t(s,c):c.updatedAt,S=B(ee),C=h&&m.length===0&&S>6e5,te=()=>{n.wait&&H.exit(c.status===`completed`?0:1)};if(n.json)return R({taskId:c.id,name:c.name??null,prompt:c.prompt??null,system:c.system??null,status:_,agent:c.agent,model:c.model??null,effort:c.effort??null,permissions:c.permissions??null,cwd:c.cwd??null,createdAt:c.createdAt??null,completedAt:c.completedAt??null,...h?{idleMs:S,lastActivityAt:ee??null,stalled:C}:{},pendingApprovals:m.map(e=>({id:e.id,summary:e.summary})),...u.length?{steps:u}:{},turnCount:f.length,...n.turns?{turns:f}:{},result:d}),te();let w=x,T=c.createdAt?B(c.createdAt):null,re=!h&&c.completedAt?B(c.completedAt):null,E=c.createdAt&&c.completedAt?Date.parse(c.completedAt)-Date.parse(c.createdAt):null,ie=h?T===null?``:`started ${j(T)} ago`:[re===null?``:`finished ${j(re)} ago`,E!==null&&E>=0?`took ${j(E)}`:``].filter(Boolean).join(` · `),D=[`${w.dim(`task`)} ${w.cyan(c.id)}`,...c.name?[`${w.dim(`name`)} ${c.name}`]:[],`${w.dim(`status`)} ${P(_)}${ie?` ${w.dim(`(${ie})`)}`:``}`,`${w.dim(`agent`)} ${ae(c)}`,...Ce(c,w),...d?.tokens?[`${w.dim(`tokens`)} ${Se(d.tokens,d.model??c.model)}`]:[]];if(c.prompt&&D.push(``,...Re(c.prompt,w)),m.length){D.push(``,w.dim(`pending approvals:`));for(let e of m)D.push(` ${w.cyan(e.id)} ${e.summary}`),D.push(` ${w.bold(`coder approve ${c.id} ${e.id}`)} ${w.dim(`(--deny to reject)`)}`)}if(u.length){D.push(``,w.dim(`steps:`));for(let e of u){let t=e.message??e.kind;t&&D.push(` ${w.dim(Ie(t))}`)}}if(D.push(``),n.turns&&f.length?f.forEach((e,t)=>{t&&D.push(``),D.push(w.dim(`— turn ${t+1} of ${f.length}: ${Ie(String(e.prompt??``))}`)),D.push(String(e.finalMessage||w.dim(`(no final message)`)))}):d?(D.push(be({...d,error:d.error??void 0},c.error,`(no final message)`,w)),f.length>1&&D.push(w.dim(`(turn ${f.length} of ${f.length} — all answers: coder task result ${c.id} --turns)`))):h?D.push(w.dim(C?`Result pending, but no progress for ${j(S)} — the task may be stalled.${b?` Last: ${Ie(b.message??b.kind??``)}`:``}`:`Result pending — task is still running.`)):D.push(w.dim(`(no result)`)),h&&!n.wait){let e=[`Wait for it: coder task result ${c.id} --wait`,`Follow live: coder task watch ${c.id}`];C&&e.push(`Check the transcript: coder task result ${c.id} --tail all`),D.push(``,O(e,w))}return H.stdout.write(`${D.join(`
80
+ `)}\n`),d?.touchedFiles?.length&&H.stderr.write(`[coder] touched files: ${d.touchedFiles.join(`, `)}\n`),te()}function jn(e){return s(e).filter(e=>l.includes(e.status)).flatMap(t=>ne(r(e,t.id)).filter(e=>!e.response).map(e=>({taskId:t.id,id:e.id,summary:String(e.summary??``),createdAt:e.createdAt?String(e.createdAt):void 0})))}async function Mn(e){let{options:t,positionals:n}=g(e,G.object(v));I(n,1,`task approvals`);let i=M(t),a=x;if(n[0]){let e=Me(i,n[0]),o=ne(r(i,e.id)).map(e=>({id:e.id,summary:e.summary,createdAt:e.createdAt,answered:e.response?.decision??null}));if(t.json){R(o);return}if(!o.length){H.stdout.write(`${a.dim(`No approvals for task ${e.id}.`)}\n`);return}for(let e of o){let t=e.answered??`pending`;H.stdout.write(`${a.cyan(e.id)} ${t.padEnd(8)} ${a.dim(String(e.summary??``))}\n`)}let s=o.filter(e=>!e.answered);if(s.length){let e=s.length===1?s[0].id:`<approval-id>`;H.stdout.write(`\n${O([`Answer: coder approve ${e} [--deny]`],a)}\n`)}return}let o=jn(i);if(t.json){R(o);return}if(!o.length){H.stdout.write(`${a.dim(`No pending approvals.`)}\n`);return}let s={id:Math.max(11,...o.map(e=>e.id.length)),task:Math.max(7,...o.map(e=>e.taskId.length))};H.stdout.write(a.bold(a.light(`${`approval-id`.padEnd(s.id)} ${`task-id`.padEnd(s.task)} age summary\n`)));for(let e of o){let t=e.createdAt?j(B(e.createdAt)):`-`;H.stdout.write(`${a.cyan(e.id.padEnd(s.id))} ${a.cyan(e.taskId.padEnd(s.task))} ${t.padEnd(5)} ${a.light(e.summary)}\n`)}let c=o.length===1?o[0].id:`<approval-id>`;H.stdout.write(`\n${O([`Answer: coder approve ${c} [--deny]`],a)}\n`)}async function Nn(e){let{options:t,positionals:n}=g(e,G.object({...v,deny:y}));I(n,2,`task approve`);let i=M(t),[a,o]=n;a&&!o&&a.startsWith(`apr-`)&&(o=a,a=jn(i).find(e=>e.id===o)?.taskId,a||D(`No pending approval "${o}".`,{hint:`List them: coder approvals`})),(!a||!o)&&D(`Missing approval id.`,{hint:[`List them: coder approvals`,`Usage: coder approve [task-id] <approval-id> [--deny]`]});let s=Me(i,a),c=t.deny?`decline`:`accept`;if(_e(r(i,s.id),o,c),t.json){R({taskId:s.id,approvalId:o,decision:c});return}H.stdout.write(`${t.deny?`Denied`:`Approved`} ${x.cyan(o)} on task ${x.cyan(s.id)}.\n`)}function Pn(e){return W.join(e,`sidecar.json`)}function Fn(e){return C(Pn(e))??{sessionId:null,declineStreak:0}}async function In(e){let t=W.join(e,`sidecar.lock`),n=Date.now()+12e4;for(;;)try{return U.mkdirSync(t),()=>{try{U.rmdirSync(t)}catch{}}}catch{try{if(Date.now()-U.statSync(t).mtimeMs>9e4){U.rmdirSync(t);continue}}catch{continue}if(Date.now()>n)throw Error(`sidecar lock wait timed out`);await new Promise(e=>setTimeout(e,250))}}function Ln(e,t,n,r){return[`-p`,r,`--output-format`,`json`,`--model`,`sonnet`,`--effort`,`low`,n?`--resume`:`--session-id`,t,...ee,`--add-dir`,e]}function Rn(e,t,n,r,i){let a=Ln(t,n,r,i);return new Promise((t,n)=>{let r=ft(`claude`,a,{cwd:e,stdio:[`ignore`,`pipe`,`pipe`]}),i=``,o=``,s=setTimeout(()=>{r.kill(`SIGKILL`),n(Error(`sidecar call timed out`))},12e4);r.stdout.on(`data`,e=>i+=e),r.stderr.on(`data`,e=>o+=e),r.on(`error`,e=>{clearTimeout(s),n(e)}),r.on(`close`,e=>{if(clearTimeout(s),e!==0){n(Error(`sidecar claude exited ${e}: ${o.trim().slice(0,200)}`));return}try{let e=JSON.parse(i);if(e.is_error){n(Error(`sidecar turn errored: ${String(e.result??``).slice(0,200)}`));return}t(String(e.result??``))}catch{n(Error(`sidecar returned unparseable output`))}})})}function zn(e){let t=e.match(/\{[^{}]*"decision"[^{}]*\}/);if(!t)return null;try{let e=JSON.parse(t[0]);if(e.decision===`accept`||e.decision===`decline`||e.decision===`escalate`)return{decision:e.decision,reason:String(e.reason??``)}}catch{}return null}async function Bn(e,t,n){let r=null;try{r=await In(t);let i=Fn(t);if(i.declineStreak>=3)return{decision:`escalate`,reason:`sidecar decline streak; needs human review`};if(!i.sessionId){let r=gt();await Rn(e,t,r,!1,`You are the approval reviewer for a "coder" background coding task. The task runs inside an OS sandbox; you review only actions that escape it.
80
81
 
81
82
  Rules:
82
83
  - git stays read-only: decline any git write (commit/push/checkout/reset/...).
@@ -87,5 +88,5 @@ Rules:
87
88
 
88
89
  You may Read/Grep files to inform a decision: the workspace (your cwd) to judge whether an action fits the code, and the task's progress log noted below to see what the task has been doing. Do this only when the action line alone is not enough — most decisions should not need it.
89
90
 
90
- Reply with ONLY one line of JSON: {"decision":"accept"|"decline"|"escalate","reason":"<short>"}. Acknowledge now with {"decision":"escalate","reason":"ready"}.${n.taskGoal?`\n\nTask goal: ${n.taskGoal.replace(/\s+/g,` `).slice(0,500)}`:``}${`\nTask progress log: ${G.join(t,`log.jsonl`)}`}`),i.sessionId=r,S(Pn(t),i)}let a=zn(await Rn(e,t,i.sessionId,!0,`action: ${n.summary.slice(0,500)}`));return a?.decision===`decline`?i.declineStreak+=1:a?.decision===`accept`&&(i.declineStreak=0),S(Pn(t),i),a??{decision:`escalate`,reason:`sidecar verdict unparseable`}}catch(e){return{decision:`escalate`,reason:`sidecar unavailable: ${e instanceof Error?e.message:String(e)}`}}finally{r?.()}}const Vn=new Set([`Write`,`Edit`,`MultiEdit`,`NotebookEdit`]);async function Hn(e,t,n){let a=String(n.tool_name??``),o=n.input??n.tool_input??{},s=i(e),c=r(e,t),l=B(e),d=n=>u(e,t,n),f,p;if(a===`Bash`){let e=String(o.command??``);p=`run command: ${e||`(unknown command)`}`,f=T(e,{allowedNetworkHosts:l.approvals.allowedNetworkHosts})}else if(Vn.has(a)){let e=String(o.file_path??o.notebook_path??``);p=`${a}: ${e||`(unknown path)`}`,f=Xe(e?[e]:[],s)}else p=`${a||`(unknown tool)`}: ${JSON.stringify(o).slice(0,200)}`,f={decision:`escalate`,reason:`tool needs approval: ${a}`};d({kind:`approval-decision`,method:a,decision:f.decision,reason:f.reason,summary:p});let m=f.decision,g=f.reason;if(m===`escalate`){let n=await Bn(e,c,{taskGoal:h(e,t)?.prompt??null,summary:p});d({kind:`sidecar-decision`,decision:n.decision,reason:n.reason,summary:p}),n.decision===`escalate`?(m=await _e(c,{method:`claude/${a}`,summary:p,params:{tool_name:a,input:o}},{timeoutMs:l.approvals.escalationTimeoutMs,onEvent:d}),g=`escalated for human review`):(m=n.decision,g=n.reason)}return m===`accept`?{behavior:`allow`,updatedInput:o}:{behavior:`deny`,message:`Denied by coder policy: ${g}`}}const Un={approval_prompt:{description:`Coder approval policy for claude permission prompts.`,inputSchema:{type:`object`,additionalProperties:!0},handler:Hn}};async function Wn(e){let{options:t,positionals:n}=g(e,K.object({cwd:b})),r=L(t),i=n[0],a=e=>U.stdout.write(`${JSON.stringify(e)}\n`),o=mt.createInterface({input:U.stdin,terminal:!1});for await(let e of o){if(!e.trim())continue;let t;try{t=JSON.parse(e)}catch{continue}let{id:n,method:o,params:s}=t;if(o===`initialize`)a({jsonrpc:`2.0`,id:n,result:{protocolVersion:s?.protocolVersion??`2024-11-05`,capabilities:{tools:{}},serverInfo:{name:`coder`,version:_()}}});else if(o===`tools/list`)a({jsonrpc:`2.0`,id:n,result:{tools:Object.entries(Un).map(([e,t])=>({name:e,description:t.description,inputSchema:t.inputSchema}))}});else if(o===`tools/call`){let e=Un[String(s?.name??``)],t;try{if(!e)throw Error(`unknown tool: ${s?.name}`);t=await e.handler(r,i,s?.arguments??{})}catch(e){t={behavior:`deny`,message:`coder mcp tool failed: ${e instanceof Error?e.message:String(e)}`}}a({jsonrpc:`2.0`,id:n,result:{content:[{type:`text`,text:JSON.stringify(t)}]}})}else n!==void 0&&a({jsonrpc:`2.0`,id:n,result:{}})}}U.stdout.on(`error`,e=>{throw e.code===`EPIPE`&&U.exit(0),e});const Gn={run:On,list:ut,watch:H,stream:H,result:An,steer:lt,ask:et,stop:ge,archive:E,delete:ct,approvals:Mn,approve:Nn};async function Kn(e){let[t,...n]=e;if(t===void 0||t===`help`||t===`-h`||t===`--help`){U.stdout.write(Ct());return}let r=Gn[t];if(r||(U.stdout.write(Ct()),P(`Unknown task subcommand "${t}".`,{hint:`Run a task: coder run "<text>"`})),Tt(n)){let e=t===`stream`?`watch`:t;U.stdout.write(Z(`task ${e}`)??Ct());return}await r(n)}const qn={task:Kn,flow:_n,run:On,list:ut,watch:H,result:An,stream:H,steer:lt,ask:et,stop:ge,archive:E,delete:ct,approvals:Mn,approve:Nn,config:rt,"setup-host":at,"host-setup":at,setup:at,model:nt,docs:ot,upgrade:st,update:st,_worker:kn,_mcp:Wn,_refreshUpdate:async()=>de(_()),_archiveSweep:ue};async function Jn(){let[e,...t]=U.argv.slice(2);if(e===`--version`||e===`-v`){U.stdout.write(`${_()}\n`);return}if(e===void 0||e===`help`||e===`--help`||e===`-h`){if(t[0]===`task`&&t[1]===void 0){U.stdout.write(Ct());return}if(t[0]===`model`&&t[1]===void 0){U.stdout.write(xt());return}if(t[0]===`flow`&&t[1]===void 0){U.stdout.write(X());return}let e=t.map(e=>(e===`task`||e===`model`||e===`flow`)&&t[1]?`${e} ${t[1]}`:vt[e]??e).find(e=>Y[e]);U.stdout.write(e&&Z(e)||wt());return}e!==`_worker`&&e!==`_mcp`&&e!==`_refreshUpdate`&&e!==`_archiveSweep`&&le(_(),m);let n=qn[e];if(n||(U.stdout.write(wt()),U.stdout.write(`
91
- `),P(`Unknown command "${e}".`,{hint:`See all commands: coder --help`})),e===`model`&&Tt(t)){let e=t.find(e=>!e.startsWith(`-`));U.stdout.write(e&&Z(`model ${e}`)||xt());return}if(e!==`task`&&e!==`flow`&&Tt(t)){let t=vt[e]??e;U.stdout.write(Z(t)??wt());return}try{await n(t)}catch(t){let n=t instanceof Error?t.message:String(t);if(/^(Unknown option|Missing value)/.test(n)){let t=vt[e]??e;Y[t]&&P(n,{hint:`Help: coder ${e} --help`})}throw t}}Jn().catch(e=>{U.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),U.exit(1)});export{};
91
+ Reply with ONLY one line of JSON: {"decision":"accept"|"decline"|"escalate","reason":"<short>"}. Acknowledge now with {"decision":"escalate","reason":"ready"}.${n.taskGoal?`\n\nTask goal: ${n.taskGoal.replace(/\s+/g,` `).slice(0,500)}`:``}${`\nTask progress log: ${W.join(t,`log.jsonl`)}`}`),i.sessionId=r,Pe(Pn(t),i)}let a=zn(await Rn(e,t,i.sessionId,!0,`action: ${n.summary.slice(0,500)}`));return a?.decision===`decline`?i.declineStreak+=1:a?.decision===`accept`&&(i.declineStreak=0),Pe(Pn(t),i),a??{decision:`escalate`,reason:`sidecar verdict unparseable`}}catch(e){return{decision:`escalate`,reason:`sidecar unavailable: ${e instanceof Error?e.message:String(e)}`}}finally{r?.()}}const Vn=new Set([`Write`,`Edit`,`MultiEdit`,`NotebookEdit`]);async function Hn(e,t,n){let a=String(n.tool_name??``),o=n.input??n.tool_input??{},s=i(e),c=r(e,t),l=N(e),d=n=>u(e,t,n),f,p;if(a===`Bash`){let e=String(o.command??``);p=`run command: ${e||`(unknown command)`}`,f=Xe(e,{allowedNetworkHosts:l.approvals.allowedNetworkHosts})}else if(Vn.has(a)){let e=String(o.file_path??o.notebook_path??``);p=`${a}: ${e||`(unknown path)`}`,f=ye(e?[e]:[],s)}else p=`${a||`(unknown tool)`}: ${JSON.stringify(o).slice(0,200)}`,f={decision:`escalate`,reason:`tool needs approval: ${a}`};d({kind:`approval-decision`,method:a,decision:f.decision,reason:f.reason,summary:p});let m=f.decision,g=f.reason;if(m===`escalate`){let n=await Bn(e,c,{taskGoal:h(e,t)?.prompt??null,summary:p});d({kind:`sidecar-decision`,decision:n.decision,reason:n.reason,summary:p}),n.decision===`escalate`?(m=await re(c,{method:`claude/${a}`,summary:p,params:{tool_name:a,input:o}},{timeoutMs:l.approvals.escalationTimeoutMs,onEvent:d}),g=`escalated for human review`):(m=n.decision,g=n.reason)}return m===`accept`?{behavior:`allow`,updatedInput:o}:{behavior:`deny`,message:`Denied by coder policy: ${g}`}}const Un={approval_prompt:{description:`Coder approval policy for claude permission prompts.`,inputSchema:{type:`object`,additionalProperties:!0},handler:Hn}};async function Wn(e){let{options:t,positionals:n}=g(e,G.object({cwd:b})),r=M(t),i=n[0],a=e=>H.stdout.write(`${JSON.stringify(e)}\n`),o=ht.createInterface({input:H.stdin,terminal:!1});for await(let e of o){if(!e.trim())continue;let t;try{t=JSON.parse(e)}catch{continue}let{id:n,method:o,params:s}=t;if(o===`initialize`)a({jsonrpc:`2.0`,id:n,result:{protocolVersion:s?.protocolVersion??`2024-11-05`,capabilities:{tools:{}},serverInfo:{name:`coder`,version:_()}}});else if(o===`tools/list`)a({jsonrpc:`2.0`,id:n,result:{tools:Object.entries(Un).map(([e,t])=>({name:e,description:t.description,inputSchema:t.inputSchema}))}});else if(o===`tools/call`){let e=Un[String(s?.name??``)],t;try{if(!e)throw Error(`unknown tool: ${s?.name}`);t=await e.handler(r,i,s?.arguments??{})}catch(e){t={behavior:`deny`,message:`coder mcp tool failed: ${e instanceof Error?e.message:String(e)}`}}a({jsonrpc:`2.0`,id:n,result:{content:[{type:`text`,text:JSON.stringify(t)}]}})}else n!==void 0&&a({jsonrpc:`2.0`,id:n,result:{}})}}H.stdout.on(`error`,e=>{throw e.code===`EPIPE`&&H.exit(0),e});const Gn={run:On,list:dt,watch:V,stream:V,result:An,steer:ut,ask:tt,stop:ve,archive:T,delete:lt,approvals:Mn,approve:Nn};async function Kn(e){let[t,...n]=e;if(t===void 0||t===`help`||t===`-h`||t===`--help`){H.stdout.write(Z());return}let r=Gn[t];if(r||(H.stdout.write(Z()),D(`Unknown task subcommand "${t}".`,{hint:`Run a task: coder run "<text>"`})),Tt(n)){let e=t===`stream`?`watch`:t;H.stdout.write(X(`task ${e}`)??Z());return}await r(n)}const qn={task:Kn,flow:_n,run:On,list:dt,watch:V,result:An,stream:V,steer:ut,ask:tt,stop:ve,archive:T,delete:lt,approvals:Mn,approve:Nn,config:it,"setup-host":ot,"host-setup":ot,setup:ot,model:rt,docs:st,upgrade:ct,update:ct,_worker:kn,_mcp:Wn,_refreshUpdate:async()=>ie(_()),_archiveSweep:de};async function Jn(){let[e,...t]=H.argv.slice(2);if(e===`--version`||e===`-v`){H.stdout.write(`${_()}\n`);return}if(e===void 0||e===`help`||e===`--help`||e===`-h`){if(t[0]===`task`&&t[1]===void 0){H.stdout.write(Z());return}if(t[0]===`model`&&t[1]===void 0){H.stdout.write(St());return}if(t[0]===`flow`&&t[1]===void 0){H.stdout.write(Y());return}let e=t.map(e=>(e===`task`||e===`model`||e===`flow`)&&t[1]?`${e} ${t[1]}`:yt[e]??e).find(e=>J[e]);H.stdout.write(e&&X(e)||wt());return}e!==`_worker`&&e!==`_mcp`&&e!==`_refreshUpdate`&&e!==`_archiveSweep`&&pe(_(),m);let n=qn[e];if(n||(H.stdout.write(wt()),H.stdout.write(`
92
+ `),D(`Unknown command "${e}".`,{hint:`See all commands: coder --help`})),e===`model`&&Tt(t)){let e=t.find(e=>!e.startsWith(`-`));H.stdout.write(e&&X(`model ${e}`)||St());return}if(e!==`task`&&e!==`flow`&&Tt(t)){let t=yt[e]??e;H.stdout.write(X(t)??wt());return}try{await n(t)}catch(t){let n=t instanceof Error?t.message:String(t);if(/^(Unknown option|Missing value)/.test(n)){let t=yt[e]??e;J[t]&&D(n,{hint:`Help: coder ${e} --help`})}throw t}}Jn().catch(e=>{H.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),H.exit(1)});export{};
@@ -1,2 +1,2 @@
1
- import { _ as FlowStep, b as GateResult, d as log, f as pipeline, h as FlowEvent, l as flow, n as flowSdk, p as task, r as CoderError, t as args, u as gate, v as FlowTaskOptions, y as FlowTaskResult } from "../index-CTrgzW3M.js";
1
+ import { _ as FlowStep, b as GateResult, d as log, f as pipeline, h as FlowEvent, l as flow, n as flowSdk, p as task, r as CoderError, t as args, u as gate, v as FlowTaskOptions, y as FlowTaskResult } from "../index-BQ-b77or.js";
2
2
  export { CoderError, type FlowEvent, type FlowStep, type FlowTaskOptions, type FlowTaskResult, type GateResult, args, flowSdk as default, flowSdk, flow, gate, log, pipeline, task };
@@ -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-DrTVUIwM.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};
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-DtukZ1m8.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};
@@ -144,6 +144,7 @@ interface Job {
144
144
  pid?: number | null;
145
145
  threadId?: string | null;
146
146
  turnId?: string | null;
147
+ steerEndpoint?: string | null;
147
148
  completedAt?: string;
148
149
  resumedAt?: string;
149
150
  error?: string;
@@ -0,0 +1,19 @@
1
+ import{A as e,B as t,C as n,F as r,G as i,H as a,I as o,L as s,M as c,N as l,O as u,P as d,T as f,W as p,f as m,i as h,j as g,l as _,m as v,o as y,r as ee,s as te,u as ne,v as re,w as ie,y as ae}from"./app-server-bHl6RBZ2.js";import{createRequire as oe}from"node:module";import b from"node:process";import x from"node:fs";import S from"node:path";import{spawn as C,spawnSync as w}from"node:child_process";import T from"node:os";import{fileURLToPath as se,pathToFileURL as ce}from"node:url";import*as E from"zod/mini";import le from"node:net";import ue,{randomUUID as D}from"node:crypto";import{AsyncLocalStorage as de}from"node:async_hooks";function fe(e){let t=b.env.FORCE_COLOR,n=t!=null&&t!==``&&t!==`0`||t!==`0`&&e.isTTY&&!b.env.NO_COLOR,r=(e,t)=>n?`\x1b[${e}m${t}\x1b[0m`:t;return{blue:e=>r(`34`,e),bold:e=>r(`1`,e),cyan:e=>r(`36`,e),dim:e=>r(`38;5;246`,e),light:e=>r(`38;5;249`,e),green:e=>r(`32`,e),red:e=>r(`31`,e),yellow:e=>r(`33`,e)}}const O=fe(b.stdout),k=fe(b.stderr);function pe(e,t=k){let n=e.map(e=>{let t=e.indexOf(`coder `);return t===-1?{label:e,cmd:``}:{label:e.slice(0,t),cmd:e.slice(t)}}),r=Math.max(0,...n.map(e=>e.label.length));return n.map(({label:e,cmd:n})=>n?` ${t.dim(e.padEnd(r))}${t.bold(n)}`:` ${t.dim(e)}`).join(`
2
+ `)}function A(e,t={}){let n=typeof t==`number`?t:t.code??1,r=typeof t==`object`?t.hint:null,i=r==null?[]:Array.isArray(r)?r:[r];b.stderr.write(`${k.red(e)}\n`),i.length&&b.stderr.write(`\n${pe(i,k)}\n`),b.exit(n)}function j(e){b.stdout.write(`${JSON.stringify(e,null,2)}\n`)}function me(e,t=O){return(JSON.stringify(e,null,2)??`null`).split(`
3
+ `).map(e=>e.replace(/"((?:[^"\\]|\\.)*)":/g,(e,n)=>`${t.light(`"${n}"`)}:`).replace(/: (-?\d[\d.eE+-]*|true|false|null)(,?)$/,(e,n,r)=>`: ${t.blue(n)}${r}`)).join(`
4
+ `)}function he(e){let t=Date.parse(e??``);return Number.isFinite(t)?Math.max(0,Date.now()-t):0}function ge(e){let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m`:`${Math.floor(n/60)}h${n%60}m`}function M(e){return e<1e3?String(e):e<1e6?`${(e/1e3).toFixed(+(e<1e4))}k`:`${(e/1e6).toFixed(1)}M`}function _e(e,t){let n=[`in ${M(e.input)}`,...e.cachedInput?[`cached ${M(e.cachedInput)}`]:[],`out ${M(e.output)}`];return`${M(e.total)} (${n.join(` · `)}) on ${t||`default model`}`}function ve(e,t,n,r=O){let i=e?.error?.message??t;return e?.finalMessage||(i?`${r.red(`error:`)} ${i}`:n)}function ye(e,t=O,{truncate:n=!0}={}){let r=e=>e.split(`
5
+ `).map(e=>` ${t.dim(e)}`);return!n||e.length<=1e3?[t.dim(`prompt:`),...r(e)]:[t.dim(`prompt:`),...r(e.slice(0,500).trimEnd()),t.light(` … <${e.length-1e3} chars trimmed> …`),...r(e.slice(-500).trimStart())]}function be(e){return[e.agent??`-`,e.model,e.model?e.effort:null].filter(Boolean).join(`/`)}function xe(e,t=O){let n=[];return e.permissions&&n.push([`perms`,e.permissions]),e.cwd&&n.push([`cwd`,e.cwd]),n.map(([e,n])=>`${t.dim(e.padEnd(8))} ${n}`)}function Se(e,t=300,{plain:n=!1,style:r=O}={}){if(e.length<=t)return e;let i=`<${e.length-t} more chars>`;return`${e.slice(0,t)} ${n?i:r.dim(i)}`}const Ce=6e5,we=12e4;function Te(e,t){return e.length>t?`${e.slice(0,t-1)}…`:e.padEnd(t)}function Ee(e){return` ${O.bold(O.green(`✔`))} ${e}`}function De(e){return` ${O.bold(O.red(`✘`))} ${e}`}function Oe(e=b.stdout){try{return e.getWindowSize?.()[0]??e.columns}catch{return e.columns}}function ke(e=b.stdout){try{return e.getWindowSize?.()[1]??e.rows}catch{return e.rows}}function Ae(e){return e>=768&&e<=879||e>=8203&&e<=8207||e>=65024&&e<=65039?0:e>=4352&&e<=4447||e>=11904&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65072&&e<=65103||e>=65280&&e<=65376||e>=65504&&e<=65510||e>=127744&&e<=129791||e>=131072&&e<=262141?2:1}function je(e){let t=0;for(let n of e.replace(/\x1b\[[0-9;]*m/g,``))t+=Ae(n.codePointAt(0));return t}function Me(e,t){let n=0,r=``;for(let i=0;i<e.length;){let a=e[i]===`\x1B`?/^\x1b\[[0-9;]*m/.exec(e.slice(i)):null;if(a){r+=a[0],i+=a[0].length;continue}let o=e.codePointAt(i),s=String.fromCodePoint(o),c=Ae(o);if(n+c>t-1)return`${r}\x1b[0m${O.dim(`…`)}`;r+=s,n+=c,i+=s.length}return r}function Ne(){let e=b.stdin;if(!e.isTTY||!b.stdout.isTTY)return()=>{};e.setRawMode(!0),e.resume();let t=e=>{e.includes(3)&&b.kill(b.pid,`SIGINT`),e.includes(26)&&b.kill(b.pid,`SIGTSTP`)};return e.on(`data`,t),e.unref(),()=>{e.off(`data`,t),e.isTTY&&e.setRawMode(!1),e.pause()}}var Pe=class{stream;quietMs;lines=[];painted=[];paintedWidths=[];paintedCols;resizeTimer;tty;constructor(e=b.stdout,t=250){this.stream=e,this.quietMs=t,this.tty=!!e.isTTY,this.tty&&e.on(`resize`,this.onResize)}set(e){this.lines=e,!(!this.tty||this.resizeTimer)&&this.paint()}commit(e){this.clear(),this.stream.write(e)}clear(){if(!this.painted.length)return;let e=Oe(this.stream),t=this.painted.length;e&&this.paintedCols&&e!==this.paintedCols&&(t=this.paintedWidths.reduce((t,n)=>t+Math.max(1,Math.ceil(n/e)),0)),this.stream.write(`\x1b[${t}A\x1b[0J`),this.painted=[],this.paintedWidths=[]}done(){this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=void 0,this.paint()),this.tty&&this.stream.off(`resize`,this.onResize)}paint(){this.clear();let e=Oe(this.stream),t=e?this.lines.map(t=>Me(t,e-1)):this.lines,n=ke(this.stream);n&&t.length>n-1&&(t=n>1?t.slice(-(n-1)):[]);for(let e of t)this.stream.write(`${e}\n`);this.painted=t,this.paintedWidths=t.map(je),this.paintedCols=e}onResize=()=>{this.clear(),this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout(()=>{this.resizeTimer=void 0,this.paint()},this.quietMs),this.resizeTimer.unref?.()}};function Fe(e,t=0){let n=e.padEnd(t);return e===`running`?O.green(n):e===`waiting-approval`?O.yellow(n):e===`failed`||e===`cancelled`?O.red(n):e===`completed`?O.blue(n):O.dim(n)}function Ie(e,t,n=!1){n?j({taskId:e,status:`awaiting-approval`,approval:t}):(b.stdout.write(`Approval needed for task ${e}: ${t.summary}\n`),b.stderr.write(`\n${pe([`Approve: coder approve ${e} ${t.id}`,`Deny: coder approve ${e} ${t.id} --deny`,`Then: coder task result ${e} --wait`],k)}\n`)),b.exit(4)}function Le(e,t,n){if(e.length>t){let r=e.slice(t);A(`Unexpected argument${r.length>1?`s`:``}: ${r.join(` `)}`,{hint:`Help: coder ${n} --help`})}}function N(e){return e.cwd?S.resolve(String(e.cwd)):b.cwd()}function Re(e,t){let r=n(e,t);return r||A(t?`No task found for "${t}".`:`No tasks found for this workspace.`,{hint:t?[`List tasks: coder task list`,`Start one: coder run "<text>"`]:[`Start one: coder run "<text>"`]}),r}const P=`@wular/coder`,ze=`https://registry.npmjs.org/${P}/latest`;function Be(){return S.join(r(),`update-check.json`)}function Ve(e,t){let n=String(e).split(`.`).map(e=>parseInt(e,10)||0),r=String(t).split(`.`).map(e=>parseInt(e,10)||0);for(let e=0;e<3;e+=1){if((n[e]??0)>(r[e]??0))return 1;if((n[e]??0)<(r[e]??0))return-1}return 0}function He(){try{return JSON.parse(x.readFileSync(Be(),`utf8`))}catch{return null}}function Ue(e){try{x.mkdirSync(r(),{recursive:!0}),x.writeFileSync(Be(),JSON.stringify(e))}catch{}}function We(){try{x.rmSync(Be(),{force:!0})}catch{}}function Ge(e,t){if(b.env.CODER_NO_UPDATE_CHECK||b.env.CI)return;let n=He();if(n?.latest&&Ve(n.latest,e)>0&&b.stderr.write(k.dim(`coder ${e} -> `)+k.bold(n.latest)+k.dim(` available. run: coder upgrade
6
+
7
+ `)),!n?.checkedAt||Date.now()-n.checkedAt>864e5)try{C(b.execPath,[t,`_refreshUpdate`],{detached:!0,stdio:`ignore`}).unref()}catch{}}async function 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=x.realpathSync(e)}catch{}let n=t.replace(/\\/g,`/`);return/\/\.bun\//.test(n)?{pm:`bun`,command:[`bun`,`add`,`-g`,`${P}@latest`]}:/\/\.pnpm\//.test(n)||/\/pnpm(-global)?\//i.test(n)||/\/Library\/pnpm\//.test(n)?{pm:`pnpm`,command:[`pnpm`,`add`,`-g`,`${P}@latest`]}:/\/\.config\/yarn\/global\//.test(n)||/\/yarn\/global\//.test(n)||/\/Yarn\/Data\/global\//.test(n)?{pm:`yarn`,command:[`yarn`,`global`,`add`,`${P}@latest`]}:{pm:`npm`,command:[`npm`,`install`,`-g`,`${P}@latest`]}}function F(e){try{return JSON.parse(x.readFileSync(e,`utf8`))}catch{return null}}function Je(e,t){let n=`${e}.tmp`;x.writeFileSync(n,`${JSON.stringify(t,null,2)}\n`,`utf8`),x.renameSync(n,e)}function Ye(e){let t=0,n=``;return()=>{let r;try{r=x.statSync(e).size}catch{return[]}if(r<t&&(t=0,n=``),r===t)return[];let i;try{i=x.openSync(e,`r`)}catch{return[]}try{let e=Buffer.alloc(r-t),a=x.readSync(i,e,0,e.length,t);t+=a;let o=(n+e.toString(`utf8`,0,a)).split(`
8
+ `);return n=o.pop()??``,o.filter(Boolean)}finally{x.closeSync(i)}}}const 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=S.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=S.resolve(t,n),r=S.relative(t,e);if(r.startsWith(`..`)||S.isAbsolute(r))return{decision:`escalate`,reason:`path outside workspace: ${n}`};if(r===`.git`||r.startsWith(`.git${S.sep}`))return{decision:`decline`,reason:`direct .git modification: ${n}`}}return{decision:`accept`,reason:`all paths inside workspace`}}function it(e){return S.join(e,`approvals`)}function at(e){let t=it(e);return x.existsSync(t)?x.readdirSync(t).filter(e=>e.endsWith(`.request.json`)).flatMap(e=>{let n=e.replace(/\.request\.json$/,``),r=F(S.join(t,e));if(!r)return[];let i=F(S.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=S.join(r,`${t}.request.json`);if(!x.existsSync(i))throw Error(`No pending approval "${t}" for this job.`);x.writeFileSync(S.join(r,`${t}.response.json`),`${JSON.stringify({decision:n,answeredAt:new Date().toISOString()},null,2)}\n`,`utf8`)}async function I(e,t,{timeoutMs:n,onEvent:r}){let i=it(e);x.mkdirSync(i,{recursive:!0});let a=`apr-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`;x.writeFileSync(S.join(i,`${a}.request.json`),`${JSON.stringify({...t,createdAt:new Date().toISOString()},null,2)}\n`,`utf8`),r?.({kind:`approval-escalated`,approvalId:a,summary:t.summary,message:`Approval needed (${a}): ${t.summary}. Answer with: coder approve ${S.basename(e)} ${a} [--deny]`});let o=S.join(i,`${a}.response.json`),s=Date.now()+n;for(;Date.now()<s;){if(x.existsSync(o))try{let e=JSON.parse(x.readFileSync(o,`utf8`)).decision===`accept`?`accept`:`decline`;return r?.({kind:`approval-answered`,approvalId:a,decision:e}),e}catch{}await new Promise(e=>setTimeout(e,400))}return r?.({kind:`approval-timeout`,approvalId:a,message:`Approval ${a} timed out; declining.`}),`decline`}function st(e,t={}){return I(e,{method:`simulate`,summary:`simulated approval probe (--simulate-approval)`},{timeoutMs:t.timeoutMs??12e4,onEvent:t.onEvent??null})}function ct({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 I(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 I(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 lt(e,t,n=400){let r=t;for(;;){if(a.includes(r.status))return{job:r,reason:`terminal`};let t=at(o(e,r.id)).filter(e=>!e.response);if(t[0])return{job:r,reason:`approval`,approval:{id:t[0].id,summary:String(t[0].summary??``)}};await new Promise(e=>setTimeout(e,n)),r=d(e,g(e,r.id)??r)}}function ut(e,t){let n=`${e}.${process.pid}.${D()}.tmp`;x.writeFileSync(n,`${JSON.stringify(t)}\n`,`utf8`),x.renameSync(n,e)}function dt(e){let t=e instanceof Error?e.message:String(e);return/no active turn|active turn.*(?:ended|completed)|turn.*(?:already )?(?:ended|completed)|turn.*not active/i.test(t)}function L(e,t,n){return Object.assign(Error(e),{retryable:t,...n===void 0?{}:{rpcCode:n}})}function ft(e,t,n,r){if(!e||e.id!==t||e.method!==`turn/steer`&&e.method!==`turn/interrupt`)throw L(`Invalid Codex control request.`,!1);let i=e.params;if(!i||typeof i!=`object`||i.threadId!==n)throw L(`Codex control request does not match its owning thread.`,!1);if(e.method===`turn/interrupt`){if(i.turnId!==r)throw L(`Codex turn/interrupt request does not match its owning active turn.`,!1);return{method:e.method,params:i}}if(i.expectedTurnId!==r)throw L(`Codex turn/steer request does not match its owning active turn.`,!1);let a=i.input;if(!Array.isArray(a)||a.length!==1||a[0]?.type!==`text`||typeof a[0]?.text!=`string`||!a[0].text.trim())throw L(`Invalid Codex turn/steer input schema.`,!1);return{method:e.method,params:i}}async function pt(e,{threadId:t,turnId:n}){let r=x.mkdtempSync(S.join(T.tmpdir(),`coder-codex-control-`)),i=`file:${r}`,a=new Set,o=!1,s=!1,c=(i=!1)=>{if(!(o&&!i||s)){s=!0;try{for(let i of x.readdirSync(r).filter(e=>e.endsWith(`.request.json`))){let s=S.join(r,i),c=`${s}.${process.pid}.processing`;try{x.renameSync(s,c)}catch{continue}let l=i.slice(0,-13),u=S.join(r,`${l}.response.json`),d=(async()=>{let r;try{if(o)throw L(`Codex owner endpoint is shutting down.`,!0);let i=ft(JSON.parse(x.readFileSync(c,`utf8`)),l,t,n);try{let t=await e.request(i.method,i.params);r={id:l,result:t}}catch(e){let t=e;r={id:l,error:{message:e instanceof Error?e.message:String(e),retryable:dt(e),...t.rpcCode===void 0?{}:{rpcCode:t.rpcCode}}}}}catch(e){let t=e;r={id:l,error:{message:t.message,retryable:t.retryable===!0,...t.rpcCode===void 0?{}:{rpcCode:t.rpcCode}}}}try{ut(u,r)}finally{try{x.unlinkSync(c)}catch{}}})();a.add(d),d.then(()=>a.delete(d),()=>a.delete(d))}}catch{}finally{s=!1}}},l=setInterval(c,10);return l.unref?.(),{endpoint:i,async close(){o||(o=!0,clearInterval(l),c(!0),await Promise.allSettled([...a]),await new Promise(e=>setTimeout(e,50)),x.rmSync(r,{recursive:!0,force:!0}))}}}function mt(e){if(e?.startsWith(`file:`)&&e.length>5){let t=S.resolve(e.slice(5)),n=S.resolve(T.tmpdir());S.dirname(t)===n&&S.basename(t).startsWith(`coder-codex-control-`)&&x.rmSync(t,{recursive:!0,force:!0})}}async function ht(e,t,n,r=3e3){if(!e)return{ok:!1,retryable:!0,detail:`Codex owner endpoint is not ready.`};if(!e.startsWith(`file:`)||e.length===5)return{ok:!1,retryable:!1,detail:`Unsupported Codex control endpoint: ${e}`};let i=e.slice(5);if(!x.existsSync(i))return{ok:!1,retryable:!0,detail:`Codex owner endpoint is no longer available.`};let a=D(),o=S.join(i,`${a}.request.json`),s=S.join(i,`${a}.response.json`);try{ut(o,{id:a,method:t,params:n})}catch(e){return{ok:!1,retryable:e.code===`ENOENT`,detail:e instanceof Error?e.message:String(e)}}let c=Date.now();for(;Date.now()-c<r;){try{let e=JSON.parse(x.readFileSync(s,`utf8`));try{x.unlinkSync(s)}catch{}return e?.id===a?e?.error?{ok:!1,retryable:e.error.retryable===!0,detail:String(e.error.message??`Malformed Codex owner error response.`)}:`result`in e?{ok:!0,retryable:!1,result:e.result,detail:`Codex owner accepted control.`}:{ok:!1,retryable:!1,detail:`Malformed Codex owner response.`}:{ok:!1,retryable:!1,detail:`Malformed Codex owner response id.`}}catch(e){if(e.code!==`ENOENT`)return{ok:!1,retryable:!1,detail:`Invalid Codex owner response: ${e instanceof Error?e.message:String(e)}`};if(!x.existsSync(i))return{ok:!1,retryable:!1,detail:`Codex owner endpoint closed after control publication; acceptance is unknown.`}}await new Promise(e=>setTimeout(e,10))}return{ok:!1,retryable:!1,detail:`Timed out waiting for Codex owner acknowledgement.`}}const gt=`Coder Task`;function _t(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 vt(e,t=72){let n=String(e??``).trim().replace(/\s+/g,` `);return n?n.length<=t?n:`${n.slice(0,t-3)}...`:``}function yt(e){let t=vt(e,56);return t?`${gt}: ${t}`:gt}function bt(e){return e?.params?.threadId??null}function xt(e){return e?.params?.turnId?e.params.turnId:e?.params?.turn?.id?e.params.turn.id:null}function St(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 Ct(e,t){let n=[];for(let r of e.matchAll(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/gm)){let e=t===`delete`,i=Number(e?r[1]:r[3]),a=Number((e?r[2]:r[4])??1);!Number.isFinite(i)||!Number.isFinite(a)||n.push(a<=1?`L${i}`:`L${i}-L${i+a-1}`)}return n}function wt(e){try{let t=x.readFileSync(e,`utf8`),n=t?t.split(/\r\n|\r|\n/).length-+!!t.endsWith(`
10
+ `):0;return n>0?[n===1?`L1`:`L1-L${n}`]:[]}catch{return[]}}function Tt(e,t){let n=typeof e.kind==`string`?e.kind:e.kind?.type??`change`,r=e.path||`(unknown path)`,i=Ct(e.diff??``,n),a=i.length||n!==`add`||!t?i:wt(r);return`${n} ${r}${typeof e.kind==`object`&&e.kind?.move_path?` -> ${e.kind.move_path}`:``}${a.length?` ${a.join(`, `)}`:``}`}function Et(e,t=!1){return(e.changes??[]).map(e=>Tt(e,t)).join(`; `)}function Dt(e){let t=e.trim().split(` `)[0]??``;return t===`/dev/null`?``:t.replace(/^[ab]\//,``)}function Ot(e){let t=new Map,n=``,r=``;for(let i of e.split(/\r?\n/)){if(i.startsWith(`--- `)){n=Dt(i.slice(4));continue}if(i.startsWith(`+++ `)){r=Dt(i.slice(4));continue}let e=/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/.exec(i);if(!e)continue;let a=Number(e[1]),o=Number(e[2]??1),s=Number(e[3]),c=Number(e[4]??1),l=c===0,u=(l?n:r)||r||n||`(unknown path)`,d=l?a:s,f=l?o:c,p=f<=1?`L${d}`:`L${d}-L${d+f-1}`,m=t.get(u)??[];m.push(p),t.set(u,m)}return[...t].map(([e,t])=>`${e} ${t.join(`, `)}`).join(`; `)}function kt(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 At(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 jt(e){return String(e??``).replace(/\s+/g,` `).trim()}function R(e){if(!e)return[];if(typeof e==`string`){let t=jt(e);return t?[t]:[]}if(Array.isArray(e))return e.flatMap(e=>R(e));if(typeof e==`object`){let t=e;if(typeof t.text==`string`)return R(t.text);if(`summary`in t)return R(t.summary);if(`content`in t)return R(t.content);if(`parts`in t)return R(t.parts)}return[]}function Mt(e,t){let n=[];for(let r of[...e,...t]){let e=jt(r);!e||n.includes(e)||n.push(e)}return n}function z(e,t,n=null,r={}){!e||!t||e({message:t,phase:n,...r})}function Nt(e){switch(e.type){case`commandExecution`:return{message:`Running command: ${String(e.command??``).trim()}`,phase:`running`};case`fileChange`:return{message:`Applying file changes: ${Et(e)||`(details unavailable)`}.`,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 Pt(e){switch(e.type){case`agentMessage`:{let t=String(e.text??``).trim();return t?{message:t,phase:null}:null}case`reasoning`:{let t=R(e.summary)[0]?.split(`
11
+ `)[0]??``;return t?{message:`Thinking: ${t.length>100?`${t.slice(0,100)}…`:t}`,phase:null}:null}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}: ${Et(e,!0)||`(details unavailable)`}.`,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 Ft(e,t={}){let n,r,i=new Promise((e,t)=>{n=e,r=t});return{threadId:e,rootThreadId:e,threadIds:new Set([e]),threadTurnIds:new Map,turnId:null,bufferedNotifications:[],completion:i,resolveCompletion:n,rejectCompletion:r,finalTurn:null,completed:!1,finalAnswerSeen:!1,pendingCollaborations:new Set,activeSubagentTurns:new Set,completionTimer:null,lastAgentMessage:``,reasoningSummary:[],error:null,fileChanges:[],commandExecutions:[],tokenUsageByThread:new Map,lastDiffSummary:``,itemIndex:new Map,onProgress:t.onProgress??null,onHeartbeat:t.onHeartbeat??null}}function It(e){e.completionTimer&&=(clearTimeout(e.completionTimer),null)}function Lt(e,t=null){e.completed||(It(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 Rt(e){e.completed||e.finalTurn||!e.finalAnswerSeen||e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||(It(e),e.completionTimer=setTimeout(()=>{e.completionTimer=null,!(e.completed||e.finalTurn||!e.finalAnswerSeen)&&(e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||Lt(e,null))},250),e.completionTimer.unref?.())}function zt(e,t){let n=bt(t);if(!n||!e.threadIds.has(n))return!1;let r=e.threadTurnIds.get(n)??null,i=xt(t);return r===null||i===null||i===r}function Bt(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),Rt(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,Rt(e)));return}if(t.type===`reasoning`&&n===`completed`){e.reasoningSummary=Mt(e.reasoningSummary,R(t.summary));return}if(t.type===`fileChange`&&n===`completed`){e.fileChanges.push(t);return}t.type===`commandExecution`&&n===`completed`&&e.commandExecutions.push(t)}function Vt(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),z(e.onProgress,`Turn started (${t.params.turn.id}).`,`starting`,{threadId:t.params.threadId??null,turnId:t.params.turn.id??null});break;case`item/started`:Bt(e,t.params.item,`started`,t.params.threadId??null);{let n=Nt(t.params.item);z(e.onProgress,n?.message,n?.phase??null)}break;case`item/completed`:Bt(e,t.params.item,`completed`,t.params.threadId??null);{let n=Pt(t.params.item);z(e.onProgress,n?.message,n?.phase??null)}break;case`thread/tokenUsage/updated`:{let n=kt(t.params?.tokenUsage?.total??t.params?.tokenUsage),r=bt(t);n&&r&&e.tokenUsageByThread.set(r,n);break}case`turn/diff/updated`:{let n=Ot(String(t.params?.diff??``));n&&n!==e.lastDiffSummary&&(e.lastDiffSummary=n,z(e.onProgress,`Changed lines: ${n}.`,`editing`));break}case`item/autoApprovalReview/completed`:{let n=t.params?.review??{},r=t.params?.action??{},i=r.command??r.type??``;z(e.onProgress,`auto-review ${n.status}${n.riskLevel?` (${n.riskLevel} risk)`:``}: ${vt(i)}${n.rationale?` — ${vt(n.rationale,120)}`:``}`,null);break}case`error`:e.error=t.params.error,z(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),Rt(e);break}z(e.onProgress,`Turn ${t.params.turn.status}.`,`finalizing`),Lt(e,t.params.turn)}}async function Ht(e,t,n,r={}){let i=Ft(t,r),a=e.notificationHandler;e.setNotificationHandler(e=>{if(!i.turnId){i.bufferedNotifications.push(e);return}if(e.method===`thread/started`){Vt(i,e);return}if(!zt(i,e)){a?.(e);return}Vt(i,e)});let o=r.onApprovalRequest;o&&e.setServerRequestHandler((e,t)=>o(e,t,i));try{let e=await n();i.turnId=e.turn?.id??null,i.turnId&&(i.threadTurnIds.set(i.threadId,i.turnId),await r.onTurnStarted?.(i.turnId));for(let e of i.bufferedNotifications)zt(i,e)?Vt(i,e):a?.(e);return i.bufferedNotifications.length=0,e.turn?.status&&e.turn.status!==`inProgress`&&Lt(i,e.turn),await i.completion}finally{It(i),e.setNotificationHandler(a??null),e.setServerRequestHandler(null)}}async function Ut(e,t,n={}){let r=n.connect??ee.connect,i=null;try{i=await r(e);let n=await t(i);return await i.close(),n}catch(n){let a=n,o=i?.transport===`broker`||!!process.env.CODER_APP_SERVER_ENDPOINT,s=i?.transport===`broker`&&a?.rpcCode===-32001||o&&(a?.code===`ENOENT`||a?.code===`ECONNREFUSED`);if(i&&=(await i.close().catch(()=>{}),null),!s)throw n;let c=await r(e,{disableBroker:!0});try{return await t(c)}finally{await c.close()}}}function B(e){let t=h(`codex`,[`--version`],{cwd:e});if(!t.available)return t;let n=h(`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 Wt(e){let t=B(e);if(!t.available)return{available:!1,loggedIn:!1,detail:t.detail};let n=null;try{n=await ee.connect(e,{reuseExistingBroker:!0});let t=await n.request(`account/read`,{refreshToken:!1}),r=t?.account??null;return r?.type===`chatgpt`?{available:!0,loggedIn:!0,detail:r.email?`ChatGPT login active for ${r.email}`:`ChatGPT login active`}:r?.type===`apiKey`?{available:!0,loggedIn:!0,detail:`API key configured`}:t?.requiresOpenaiAuth===!1?{available:!0,loggedIn:!0,detail:`Active provider does not require OpenAI authentication`}:{available:!0,loggedIn:!1,detail:"Not authenticated. Run `codex login`."}}catch(e){let t=w(`codex`,[`login`,`status`],{encoding:`utf8`}),n=`${t.stdout??``}${t.stderr??``}`.trim();return t.status===0?{available:!0,loggedIn:!0,detail:n||`Logged in`}:{available:!0,loggedIn:!1,detail:n||(e instanceof Error?e.message:String(e))}}finally{await n?.close().catch(()=>{})}}async function Gt(e,{endpoint:t,threadId:n,turnId:r}){if(!n||!r)return{interrupted:!1,detail:`missing threadId or turnId`};let i=await ht(t,`turn/interrupt`,{threadId:n,turnId:r});return i.ok?{interrupted:!0,detail:`Interrupted ${r} on ${n}.`}:{interrupted:!1,detail:i.detail}}async function Kt(e,{endpoint:t,threadId:n,turnId:r,text:i}){if(!n)return{steered:!1,retryable:!0,detail:`missing active threadId`};if(!r)return{steered:!1,retryable:!0,detail:`missing active turnId`};let a=i.trim();if(!a)return{steered:!1,retryable:!1,detail:`empty follow-up`};let o=await ht(t,`turn/steer`,{threadId:n,input:[{type:`text`,text:a,text_elements:[]}],expectedTurnId:r});return o.ok?o.result?.turnId===r?{steered:!0,retryable:!1,detail:`Steered follow-up into ${r} on ${n}.`}:{steered:!1,retryable:!1,detail:`turn/steer returned unexpected turnId ${String(o.result?.turnId??`(missing)`)}; expected ${r}`}:{steered:!1,retryable:o.retryable,detail:o.detail}}async function qt(e,t={}){let n=B(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 Ut(e,async n=>{let a=null,o;if(t.resumeThreadId)z(t.onProgress,`Resuming thread ${t.resumeThreadId}.`,`starting`),p(t.resumeThreadId)&&await i(t.resumeThreadId),o=(await n.request(`thread/resume`,{threadId:t.resumeThreadId,cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`,...t.approvalsReviewer?{approvalsReviewer:t.approvalsReviewer}:{}})).thread.id;else if(z(t.onProgress,`Starting Codex task thread.`,`starting`),o=(await n.request(`thread/start`,{cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`,...t.approvalsReviewer?{approvalsReviewer:t.approvalsReviewer}:{},serviceName:`coder_runtime`,ephemeral:t.ephemeral??!1})).thread.id,!(t.ephemeral??!1))try{await n.request(`thread/name/set`,{threadId:o,name:yt(r)})}catch(e){let t=String(e?.message??e??``);if(!t.includes(`unknown variant`)&&!t.includes(`unknown method`))throw e}z(t.onProgress,`Thread ready (${o}).`,`starting`,{threadId:o});let s;try{s=await Ht(n,o,()=>n.request(`turn/start`,{threadId:o,input:[{type:`text`,text:r,text_elements:[]}],model:t.model??null,effort:t.effort??null,outputSchema:t.outputSchema??null}),{onProgress:t.onProgress,onHeartbeat:t.onHeartbeat,onApprovalRequest:t.onApprovalRequest,onTurnStarted:t.onControlReady?async e=>{a=await pt(n,{threadId:o,turnId:e}),t.onControlReady?.(a.endpoint,o,e)}:void 0})}finally{await a?.close()}return{status:s.finalTurn?.status===`completed`?0:1,threadId:o,turnId:s.turnId,finalMessage:s.lastAgentMessage,reasoningSummary:s.reasoningSummary,turn:s.finalTurn,error:s.error,stderr:_t(n.stderr),fileChanges:s.fileChanges,touchedFiles:St(s.fileChanges),tokens:At(s),model:t.model??null,commandExecutions:s.commandExecutions}})}const Jt={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:[]}},V={spark:`gpt-5.3-codex-spark`,luna:`gpt-5.6-luna`,terra:`gpt-5.6-terra`,sol:`gpt-5.6-sol`},H=new Set([`low`,`medium`,`high`]),U={haiku:`haiku`,sonnet:`sonnet`,opus:`opus`,fable:`fable`},W=new Set([`low`,`medium`,`high`]),Yt={"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`}},Xt={"read-only":[`--permission-mode`,`dontAsk`,`--disallowedTools`,`Edit`,`Write`,`NotebookEdit`],"workspace-write":[`--permission-mode`,`acceptEdits`],auto:[`--permission-mode`,`auto`]},Zt=[`--permission-mode`,`dontAsk`,`--disallowedTools`,`Edit`,`Write`,`NotebookEdit`,`Bash`,`WebFetch`,`WebSearch`,`Task`],Qt=/failIfUnavailable|sandbox\b[^.\n]*?(?:failed|could ?n[o']t|cannot|unavailable|not available|not supported)/i;function $t(e){return e.flatMap(e=>le.isIPv6(e)?[`[${e}]`]:e.startsWith(`[`)||e.includes(`:`)||le.isIP(e)?[e]:[e,`*.${e}`])}function en(e,t,n=[],r=[]){return JSON.stringify(e===`read-only`?{...r.length?{permissions:{additionalDirectories:r}}:{},sandbox:{enabled:!0,failIfUnavailable:!0,autoAllowBashIfSandboxed:!0,filesystem:{denyWrite:[t,...r]}}}:{sandbox:{enabled:!0,autoAllowBashIfSandboxed:!0,...e===`auto`&&n.length?{network:{allowedDomains:$t(n)}}:{}}})}const tn=E.enum([`codex`,`claude`]),nn=E.enum([`codex`,`claude`,`custom`]),rn=E.enum([`low`,`medium`,`high`]),an=E.enum([`read-only`,`workspace-write`,`auto`]),on=E.partial(E.strictObject({model:E.string().check(E.minLength(1)),effort:rn,permissions:an})),sn=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())}),cn=E.strictObject({provider:tn,model:E.string().check(E.minLength(1)),effort:E.optional(rn),disabled:E.optional(E.boolean())}),ln=E.strictObject({disabled:E.boolean()}),un=E.union([sn,cn,ln]),dn=E.strictObject({escalationTimeoutMs:E.number().check(E.positive()),allowedNetworkHosts:E.array(E.string())}),fn=E.strictObject({chain:E.array(nn).check(E.minLength(1)),agents:E.partial(E.strictObject({codex:on,claude:on,custom:on})),models:E.optional(E.record(E.string().check(E.regex(/^[a-z0-9][a-z0-9./_-]*$/i,`model name`)),un)),approvals:dn}),pn=E.partial(E.extend(fn,{approvals:E.partial(dn)}));function G(e){return`baseUrl`in e}function mn(e){return`provider`in e}function hn(e){let t=pn.safeParse(e);if(!t.success)return t.error.issues.map(e=>`${e.path.join(`.`)||`config`}: ${e.message}`);let n=_n(Jt,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(mn(i)){let t=n.models?.[i.model];t&&!G(t)&&r.push(`models.${e}: alias target "${i.model}" is itself a config entry`)}}return r}function gn(e){if(!x.existsSync(e))return null;try{return JSON.parse(x.readFileSync(e,`utf8`))}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`Invalid JSON in ${e}: ${n}`)}}function _n(e,t){if(!t||typeof t!=`object`||Array.isArray(t))return t??e;let n={...e},r=e;for(let[e,i]of Object.entries(t))n[e]=i&&typeof i==`object`&&!Array.isArray(i)&&r?.[e]&&typeof r[e]==`object`?_n(r[e],i):i;return n}function vn(){return S.join(r(),`config.json`)}function yn(e){let t=s(e),n=Jt;for(let e of[vn(),S.join(t,`coder.config.json`)]){let t=gn(e);if(!t)continue;let r=hn(t);if(r.length)throw Error(`Invalid config in ${e}:\n ${r.join(`
12
+ `)}`);n=_n(n,t)}let r=hn(n);if(r.length)throw Error(`Invalid merged config:\n ${r.join(`
13
+ `)}`);return n}function bn(e){return e.replace(/\/+$/,``).replace(/\/(chat\/completions|completions|responses)$/,``)}function xn(e,t,n){let r=[S.join(s(e),`coder.config.json`),vn()];for(let e of r){let r;try{r=gn(e)}catch{continue}if(r?.models?.[t])return Object.assign(r.models[t],n),!hn(r).length&&(x.writeFileSync(e,`${JSON.stringify(r,null,2)}\n`,`utf8`),!0)}return!1}function Sn(e){return/\/(chat\/completions|completions|responses)\/*$/.test(e)}function Cn(e,t){let n=bn(e);return Sn(e)||/\/v\d+(alpha|beta)?$/.test(n)?[`${n}/${t}`]:[`${n}/${t}`,`${n}/v1/${t}`]}function wn(e,t,n){let r=t?e.models?.[t]:void 0;if(!t||!r||!G(r))return null;let i=`coder-${t}`;return{model:r.model,modelProvider:i,configOverrides:{[`model_providers.${i}`]:{name:t,base_url:n?.url??bn(r.baseUrl),...r.envKey&&!n?{env_key:r.envKey}:{},wire_api:`responses`}}}}function Tn(e){return e?V[e]??e:null}function En(e){return e in V||e in U}function Dn(e,t){return!!(t&&e.models?.[t]?.disabled)}function On(e,t){if(Dn(e,t))throw Error(`model "${t}" is disabled in config`)}function kn(e,t){if(!e)return null;let n=String(e).trim().split(`:`).map(e=>e.trim());if(!n.length||n.length>3||n.some(e=>!e))throw Error(`Invalid agent spec "${e}".`);let r=null,i=null,a=null,o=e=>H.has(e)||W.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&&mn(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 U?`claude`:i&&s&&G(s)?`custom`:`codex`;let c=t.agents[r]??{},l=i??c.model??null;return On(t,l),{agent:r,model:l,effort:a??c.effort??null}}function An(e){let t=vn();return x.mkdirSync(S.dirname(t),{recursive:!0}),x.writeFileSync(t,`${JSON.stringify(e,null,2)}\n`,`utf8`),t}function jn(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 Mn(e){if(!e)return 0;let t=e.split(/\r\n|\r|\n/);return t.at(-1)===``&&t.pop(),Math.max(1,t.length)}function Nn(e,t,n=!1){if(!t)return[];let r;try{r=x.readFileSync(e,`utf8`)}catch{return[]}let i=[],a=0;for(;a<=r.length;){let e=r.indexOf(t,a);if(e<0)break;let o=Mn(r.slice(0,e))+1,s=Math.max(1,Mn(t));if(i.push(s===1?`L${o}`:`L${o}-L${o+s-1}`),!n)break;a=e+Math.max(t.length,1)}return i.length>4?[...i.slice(0,4),`+${i.length-4} matches`]:i}function Pn(e,t,n){let r=String(t.file_path??t.notebook_path??``),i=r?S.isAbsolute(r)?r:S.resolve(n,r):``;if(e===`Write`){let e=Mn(String(t.content??``));return`Write ${r||`(unknown path)`} ${e?`L1-L${e}`:`(empty file)`}`}if(e===`Edit`){let e=Nn(i,String(t.old_string??``),t.replace_all===!0);return`Edit ${r||`(unknown path)`}${e.length?` ${e.join(`, `)}`:``}`}if(e===`MultiEdit`){let e=Array.isArray(t.edits)?t.edits:[],n=e.flatMap(e=>Nn(i,String(e?.old_string??``),e?.replace_all===!0));return`MultiEdit ${r||`(unknown path)`}${n.length?` ${n.join(`, `)}`:``} (${e.length} edits)`}if(e===`NotebookEdit`){let e=t.cell_id??t.cell_number;return`NotebookEdit ${r||`(unknown path)`}${e==null?``:` cell ${e}`}`}return`${e} ${JSON.stringify(t??{})}`}function Fn(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 In(){let e=w(`claude`,[`--version`],{encoding:`utf8`});return e.error||e.status!==0?{available:!1,detail:`claude CLI not found on PATH (npm install -g @anthropic-ai/claude-code)`}:{available:!0,detail:String(e.stdout||``).trim()}}function Ln(){let e=w(`claude`,[`auth`,`status`,`--json`],{encoding:`utf8`});if(e.error||e.status!==0)return{loggedIn:!1,detail:`not logged in`};try{let t=JSON.parse(String(e.stdout||``));return t.loggedIn?{loggedIn:!0,detail:[t.email,t.subscriptionType].filter(Boolean).join(`, `)||`logged in`}:{loggedIn:!1,detail:`not logged in`}}catch{return{loggedIn:!1,detail:`unknown`}}}function Rn(e,t,n){let r=[`-p`,`--input-format`,`stream-json`,`--output-format`,`stream-json`,`--verbose`,`--replay-user-messages`];r.push(t.resumeSessionId?`--resume`:`--session-id`,n),t.model&&r.push(`--model`,t.model),t.effort&&r.push(`--effort`,t.effort);let i=t.permissions??`auto`,a=i===`read-only`?t.additionalDirectories??[]:[],o=i===`read-only`?t.readOnlyAllowedTools??[]:[];if(i===`auto`&&t.approvalJobId){let n=JSON.stringify({mcpServers:{coder:{type:`stdio`,command:b.execPath,args:[m,`_mcp`,t.approvalJobId,`--cwd`,e]}}});r.push(`--permission-mode`,`default`,`--mcp-config`,n,`--permission-prompt-tool`,`mcp__coder__approval_prompt`)}else o.length?r.push(...Zt,`--allowedTools`,...o):r.push(...Xt[i]??Xt.auto);for(let e of a)r.push(`--add-dir`,e);let s=en(i,e,t.allowedNetworkHosts??[],a);return s&&r.push(`--settings`,s),r}function zn(e,t){return Object.assign(Error(e),{retryable:t})}function Bn(e){return{type:`user`,message:{role:`user`,content:[{type:`text`,text:e}]}}}function Vn(e){let t=!0;return{sendInitial(t){return new Promise((n,r)=>{e(`${JSON.stringify(Bn(t))}\n`,e=>{e?r(e):n()})})},sendSteer(n){return t?new Promise((t,r)=>{e(`${JSON.stringify(Bn(n))}\n`,e=>{if(!e){t();return}let n=e.code,i=n===`EPIPE`||n===`ERR_STREAM_DESTROYED`||n===`ERR_STREAM_WRITE_AFTER_END`;r(zn(`Failed to write Claude live steer: ${e.message}`,i))})}):Promise.reject(zn(`Claude turn is no longer accepting live input.`,!0))},stopAccepting(){t=!1}}}function Hn(e,t){let n=`${e}.${b.pid}.${D()}.tmp`;x.writeFileSync(n,`${JSON.stringify(t)}\n`,`utf8`),x.renameSync(n,e)}async function Un(e){let t=x.mkdtempSync(S.join(T.tmpdir(),`coder-claude-steer-`)),n=`file:${t}`,r=new Set,i=!1,a=!1,o=(n=!1)=>{if(!(i&&!n||a)){a=!0;try{for(let n of x.readdirSync(t).filter(e=>e.endsWith(`.request.json`))){let i=S.join(t,n),a=`${i}.${b.pid}.processing`;try{x.renameSync(i,a)}catch{continue}let o=n.slice(0,-13),s=S.join(t,`${o}.response.json`),c=(async()=>{let t;try{let n=JSON.parse(x.readFileSync(a,`utf8`)),r=typeof n?.params?.text==`string`?n.params.text.trim():``;if(n?.method!==`turn/steer`||!r||n?.id!==o)t={id:o,error:{message:`Invalid Claude steer request.`,retryable:!1}};else try{await e(r),t={id:o,result:{accepted:!0}}}catch(e){let n=e;t={id:o,error:{message:n.message,retryable:n.retryable===!0}}}}catch(e){t={id:o,error:{message:`Invalid Claude steer JSON: ${e instanceof Error?e.message:String(e)}`,retryable:!1}}}try{Hn(s,t)}finally{try{x.unlinkSync(a)}catch{}}})();r.add(c),c.then(()=>r.delete(c),()=>r.delete(c))}}catch{}finally{a=!1}}},s=setInterval(o,10);return{endpoint:n,async close(){i=!0,clearInterval(s),o(!0),await Promise.allSettled([...r]),await new Promise(e=>setTimeout(e,50)),x.rmSync(t,{recursive:!0,force:!0})}}}async function Wn(e,t,n=3e3){if(!e)return{steered:!1,retryable:!0,detail:`Claude live steer endpoint is not ready.`};let r=t.trim();if(!r)return{steered:!1,retryable:!1,detail:`empty follow-up`};if(!e.startsWith(`file:`)||e.length===5)return{steered:!1,retryable:!1,detail:`Unsupported Claude steer endpoint: ${e}`};let i=e.slice(5);if(!x.existsSync(i))return{steered:!1,retryable:!0,detail:`Claude live steer endpoint is no longer available.`};let a=D(),o=S.join(i,`${a}.request.json`),s=S.join(i,`${a}.response.json`);try{Hn(o,{id:a,method:`turn/steer`,params:{text:r}})}catch(e){return{steered:!1,retryable:e.code===`ENOENT`,detail:e instanceof Error?e.message:String(e)}}let c=Date.now();for(;Date.now()-c<n;){try{let e=JSON.parse(x.readFileSync(s,`utf8`));try{x.unlinkSync(s)}catch{}return e?.result?.accepted===!0?{steered:!0,retryable:!1,detail:`Claude accepted the live follow-up.`}:{steered:!1,retryable:e?.error?.retryable===!0,detail:String(e?.error?.message??`Malformed Claude steer response.`)}}catch(e){if(e.code!==`ENOENT`)return{steered:!1,retryable:!1,detail:`Invalid Claude steer response: ${e instanceof Error?e.message:String(e)}`}}await new Promise(e=>setTimeout(e,10))}return{steered:!1,retryable:!1,detail:`Timed out waiting for Claude live steer acknowledgement.`}}async function Gn(e,t){let n=t.resumeSessionId??D(),r=Rn(e,t,n);return t.onProgress?.({message:`claude turn started (session ${n})`,threadId:n}),new Promise((i,a)=>{let o=C(t.executable??`claude`,r,{cwd:e,stdio:[`pipe`,`pipe`,`pipe`]}),s=``,c=``,l=[],u=null,d=n,f=null,p=!1,m=Vn((e,t)=>o.stdin.write(e,t)),h=Date.now(),g=n=>{if(!(!n||typeof n!=`object`)){if(t.onHeartbeat?.(),n.type===`system`&&n.subtype===`init`&&n.session_id)d=n.session_id;else if(n.type===`assistant`){for(let r of n.message?.content??[])if(r?.type===`tool_use`)t.onProgress?.({message:Pn(String(r.name??`Tool`),r.input??{},e),threadId:d});else if(r?.type===`text`&&typeof r.text==`string`&&r.text.trim())t.onProgress?.({message:r.text.trim(),threadId:d});else if(r?.type===`thinking`&&typeof r.thinking==`string`&&r.thinking.trim()){let e=Math.max(1,Math.round((Date.now()-h)/1e3)),n=r.thinking.trim().split(`
14
+ `)[0],i=n.length>100?`${n.slice(0,100)}…`:n;t.onProgress?.({message:`Thought for ${e}s: ${i}`,threadId:d})}}else if(n.type===`user`){for(let e of n.message?.content??[])if(e?.type===`tool_result`){let n=jn(e.content).trim();n&&t.onProgress?.({message:n,threadId:d})}}else n.type===`result`&&(u=n,n.session_id&&(d=n.session_id),m.stopAccepting(),o.stdin.end());h=Date.now()}};o.stdout.on(`data`,e=>{s+=e;let t;for(;(t=s.indexOf(`
15
+ `))>=0;){let e=s.slice(0,t).trim();if(s=s.slice(t+1),e)try{g(JSON.parse(e))}catch(e){l.push(`Invalid Claude stream-json output: ${e instanceof Error?e.message:String(e)}`)}}}),o.stderr.on(`data`,e=>{c+=e});let _=()=>{m.stopAccepting(),o.kill(`SIGTERM`);let e=f?.endpoint;e?.startsWith(`file:`)&&x.rmSync(e.slice(5),{recursive:!0,force:!0}),b.exit(143)};b.on(`SIGTERM`,_),(async()=>{t.onSteerReady&&(f=await Un(e=>m.sendSteer(e))),await m.sendInitial(t.prompt),f&&t.onSteerReady?.(f.endpoint)})().catch(e=>{p||(p=!0,m.stopAccepting(),o.kill(`SIGTERM`),b.removeListener(`SIGTERM`,_),f?.close(),a(e))}),o.on(`error`,e=>{p||(p=!0,m.stopAccepting(),b.removeListener(`SIGTERM`,_),f?.close(),a(Error(`claude spawn failed: ${e.message}`)))}),o.on(`close`,async e=>{if(p)return;p=!0,m.stopAccepting(),b.removeListener(`SIGTERM`,_),await f?.close();let n=s.trim();if(n)try{g(JSON.parse(n))}catch(e){l.push(`Invalid trailing Claude stream-json output: ${e instanceof Error?e.message:String(e)}`)}let r=u?.result??``,a=e!==0||u?.is_error===!0||u==null||l.length>0;i({status:+!!a,threadId:u?.session_id??d,turnId:null,finalMessage:r,tokens:Fn(u?.usage),model:u?.modelUsage&&Object.keys(u.modelUsage).join(`+`)||t.model||null,error:a?{message:l[0]||r||c.trim()||`claude exited ${e}`}:null})})})}function Kn(e){w(`claude`,[`plugin`,`marketplace`,`remove`,`coder-plugins`],{encoding:`utf8`});let t=w(`claude`,[`plugin`,`marketplace`,`add`,e],{encoding:`utf8`}),n=w(`claude`,[`plugin`,`install`,`coder@coder-plugins`],{encoding:`utf8`}),r=t.status===0&&n.status===0;return{marketplace:e,installed:r,note:r?`Plugin installed; restart any running Claude Code session to load it.`:`Automatic install failed (${(n.stderr||t.stderr||`claude not found`).trim()}); run: claude plugin marketplace add "${e}" && claude plugin install coder@coder-plugins`}}function qn(){return S.join(T.homedir(),`.agents`,`skills`,`coder`)}function Jn(){try{let e=x.readFileSync(S.join(qn(),`SKILL.md`),`utf8`);return/^\s*version:\s*(\S+)/m.exec(e)?.[1]??null}catch{return null}}function Yn(e){let t=qn();try{let n=S.join(e,`plugins`,`agents`,`skills`,`coder`);x.rmSync(t,{recursive:!0,force:!0}),x.mkdirSync(t,{recursive:!0}),x.cpSync(n,t,{recursive:!0});let r=S.join(t,`SKILL.md`),i=x.readFileSync(r,`utf8`).replace(`
16
+ ---
17
+ `,`\nmetadata:\n version: ${v()}\n---\n`);return x.writeFileSync(r,i),{marketplace:t,installed:!0,note:`Skill installed to ~/.agents/skills/coder; restart running sessions to load it.`}}catch(e){return{marketplace:t,installed:!1,note:`Skill install failed: ${e instanceof Error?e.message:String(e)}`}}}function Xn(e){if(e.available)return null;let t=w(`npm`,[`install`,`-g`,`@openai/codex@latest`],{encoding:`utf8`});return t.status===0?{installed:!0,note:`codex CLI installed (runs your custom models; no login needed for them)`}:{installed:!1,note:`custom models run on the codex CLI and it is not installed; auto-install failed: ${(t.stderr||`npm not found`).trim()}. Run: npm install -g @openai/codex`}}function Zn(e){let t=/(\d+\.\d+\.\d+)/.exec(String(e??``));return t?t[1]:null}function Qn(e){if(!e.available)return null;let t=Zn(e.detail);if(!t||Ve(t,`0.144.0`)>=0)return null;let n=w(`codex`,[`update`],{encoding:`utf8`});return n.status!==0&&(n=w(`npm`,[`install`,`-g`,`@openai/codex@latest`],{encoding:`utf8`})),n.status===0?{updated:!0,from:t}:{updated:!1,from:t,note:`codex ${t} is too old for the default GPT-5.6 model (needs >= 0.144.0); auto-update failed: ${(n.stderr||`codex/npm not found`).trim()}. Run: codex update`}}const $n=/usage|quota|rate.?limit|429|401|unauthorized|not authenticated|login|insufficient|exhausted|not available|ENOENT/i,er=`CODER_WORKER`;var K=class extends Error{code;hint;taskId;payload;approval;result;runId;constructor(e,t,n={}){super(t),this.name=`CoderError`,this.code=e,Object.assign(this,n)}},tr=class extends Error{agent;detail;constructor(e,t){super(t),this.agent=e,this.detail=t}};function nr(e,t){let n=e.agent,r=!!n,i=e.model,a=e.effort,o=e=>{let n=e?t.models?.[e]:void 0;return n&&mn(n)?n:void 0},s=e=>{let n=e?t.models?.[e]:void 0;return n&&G(n)?n:void 0};if(o(i)){let e;try{e=kn(i,t)}catch(e){throw new K(`invalid-option`,e instanceof Error?e.message:String(e))}e&&(r||(n=e.agent),i=e.model??void 0,a=a??e.effort??void 0)}if(!n&&i&&(i in U?n=`claude`:i in V?n=`codex`:s(i)&&(n=`custom`)),n=n??t.chain[0]??`codex`,n!==`codex`&&n!==`claude`&&n!==`custom`){let e=n in V||n in U||n in(t.models??{})?` "${n}" is a model; use --model ${n}.`:``;throw new K(`invalid-option`,`Invalid --agent "${n}". Use codex, claude, or custom.${e}`)}let c=t.agents[n]??{},l=i??c.model??null,u=a??c.effort??null;if(o(l)){let e;try{e=kn(l,t)}catch(e){throw new K(`invalid-option`,e instanceof Error?e.message:String(e))}e&&(r||(n=e.agent),l=e.model,u=a??e.effort??u)}let d=e.permissions??c.permissions??`auto`;try{On(t,l)}catch(e){throw new K(`invalid-option`,e instanceof Error?e.message:String(e))}if(n===`custom`){let e=Object.entries(t.models??{}).filter(([,e])=>G(e)).map(([e])=>e);if(!l&&e.length===1&&(l=e[0]),!l||!s(l))throw new K(`invalid-option`,l?`No custom model named "${l}". Configured: ${e.join(`, `)||`none`}.`:`No custom model to run: pass --model <name> or set agents.custom.model.`,{hint:`Add one: coder model add <name> --base-url <url> --model <id>`})}let f=n===`claude`?`claude`:`codex`;if(!(d in Yt))throw new K(`invalid-option`,`Invalid --permissions "${d}". Use one of: ${Object.keys(Yt).join(`, `)}`);if(f===`codex`&&u&&!H.has(u))throw new K(`invalid-option`,`Invalid codex --effort "${u}". Use one of: ${[...H].join(`, `)}`);if(f===`claude`&&u&&!W.has(u))throw new K(`invalid-option`,`Invalid claude --effort "${u}". Use one of: ${[...W].join(`, `)}`);return{engine:f,agent:n,model:l,effort:u,permissions:d}}function rr(e,t){return e===`read-only`&&Qt.test(t??``)}function ir(e,n){let r=o(e,n),i=x.openSync(S.join(r,`worker.log`),`a`),a=C(b.execPath,[m,`_worker`,n,`--cwd`,e],{cwd:e,detached:!0,stdio:[`ignore`,i,i],env:{...b.env,[er]:`1`}});a.unref(),x.closeSync(i),t(e,n,{pid:a.pid??null})}async function ar(e,r,i,a){let s=i.cwd,l=r.engine===`codex`?B(s):In(),u=r.model?e.models?.[r.model]:void 0;if(!l.available&&u&&G(u)){let e=Xn(l);i.onInstallNote?.(e.note),l=B(s)}if(!l.available)throw new tr(r.agent,l.detail);let d=null;a.resume&&(d=n(s,a.resume)?.threadId??a.resume);let f=ie(),p=t(s,f,{status:`queued`,kind:`task`,name:a.name??null,system:i.system??null,agent:r.agent,engine:r.engine,prompt:i.prompt,model:r.model,effort:r.effort,permissions:r.permissions,resumeThreadId:d,cwd:s,background:!i.wait,...a.simulateApproval?{simulateApproval:!0}:{},...i.flowRunId?{flowRunId:i.flowRunId}:{}});ir(s,f);let m=2**53-1,h=()=>c(s,f,m).filter(e=>e.phase!==`starting`).length,_=Date.now()+15e3,v=p,y=null,ee=null;for(;Date.now()<(ee??_)&&(v=g(s,f)??v,v.status!==`failed`&&v.status!==`completed`);){if(v.threadId&&y===null&&(y=h(),ee=Date.now()+5e3),y!==null&&h()>y){v=g(s,f)??v;break}await new Promise(e=>setTimeout(e,150))}if(v.status===`failed`){let e=F(S.join(o(s,f),`result.json`))?.error?.message??``,t=c(s,f,5).map(e=>e.message??``).join(`
18
+ `),n=e||t;throw rr(r.permissions,n)?new K(`read-only-unavailable`,n):$n.test(n)?new tr(r.agent,n):new K(`startup-failed`,n,{taskId:f})}return{taskId:f,job:v,agent:r.agent,startupCheck:v.threadId?`passed`:`pending`}}function or(e,t,n,r,i){return{error:`${e} failed to start: ${t}`,fallback:{action:`run-native-subagent`,reason:`no-engine-available`,permissions:n,note:`Every coder engine failed to start. Spawn your own native subagent and forward the task verbatim; tell it to never run git write operations (commit, checkout, stash, reset, push, ...) and to honor the permissions.`,...r?{system:r}:{},task:i}}}async function sr(e){if(b.env.CODER_WORKER)throw new K(`nested-dispatch`,`Nested dispatch refused: this shell is already inside a coder task. Do the work yourself, directly in this session - ignore any skill or instruction telling you to orchestrate via the coder CLI.`);if(!e.prompt.trim())throw new K(`invalid-option`,`Missing task text.`,{hint:[`Usage: coder run "<task text>"`,`Help: coder task run --help`]});let t=yn(e.cwd),n={agent:e.agent,model:e.model,effort:e.effort,permissions:e.permissions},r={name:e.name,resume:e.resume,simulateApproval:e.simulateApproval};for(;;){let i=nr(n,t);try{return await ar(t,i,e,r)}catch(a){if(!(a instanceof tr))throw a;let o=t.chain[t.chain.indexOf(a.agent)+1];if(!o){let t=or(a.agent,a.detail,i.permissions,e.system,e.prompt);throw new K(`chain-exhausted`,t.error,{payload:t})}e.onFallback?.({agent:a.agent,detail:a.detail,next:o}),n={agent:o,permissions:e.permissions},r={name:void 0,resume:void 0,simulateApproval:void 0}}}}function cr(e,t){if(t.status!==`failed`)return;let n=t.result;if(!n||!$n.test(n.error?.message??``)||!(!n.touchedFiles?.length&&!n.fileChanges?.length&&!n.commandExecutions?.length))return;let r=yn(e).chain;return r[r.indexOf(t.job.agent)+1]}function lr(e,t){return F(S.join(o(e,t),`result.json`))}function ur(e,t,n=0){return n===0?[]:c(e,t,n===`all`?2**53-1:n)}function dr(e,t,n={}){let r=g(e,t);if(!r)throw Error(`No task found for "${t}".`);return{taskId:t,status:r.status,result:lr(e,t),steps:ur(e,t,n.tail),turns:l(e,t),job:r}}async function fr(e,t,n={}){let r=g(e,t);if(!r)throw Error(`No task found for "${t}".`);let i=await lt(e,r);if(i.reason===`approval`){let e=i.approval;throw new K(`approval-pending`,`Approval needed for task ${t}: ${e.summary}`,{taskId:t,approval:e})}n.onSettle?.();let a=i.job;return{taskId:t,status:a.status,result:lr(e,t),steps:ur(e,t,n.tail),turns:l(e,t),job:a}}const pr=[`.ts`,`.mjs`,`.js`];function mr(e,t){let n=[];try{n=x.readdirSync(e)}catch{return[]}let r=[];for(let i of n.sort()){let n=S.extname(i);pr.includes(n)&&r.push({name:S.basename(i,n),path:S.join(e,i),scope:t})}return r}function hr(e){let t=s(e),n=[],i=S.resolve(e);for(;n.push({dir:S.join(i,`.coder`,`flows`),scope:`workspace`}),i!==t&&S.dirname(i)!==i;)i=S.dirname(i);return n.push({dir:S.join(r(),`flows`),scope:`global`}),n}function gr(e){let t=new Set,n=[];for(let{dir:r,scope:i}of hr(e))for(let e of mr(r,i))t.has(e.name)||(t.add(e.name),n.push(e));return n}function _r(e){return e.includes(`/`)||pr.includes(S.extname(e))}function vr(e,t){if(_r(e)){let n=S.resolve(t,e);if(x.existsSync(n))return{name:S.basename(n,S.extname(n)),path:n};throw Error(`Flow file not found: ${e}`)}let n=gr(t).find(t=>t.name===e);if(!n)throw Error(`No flow named "${e}". Run \`coder flow discover\` to see available flows.`);return{name:n.name,path:n.path}}function yr(e,t,n={}){if(t.length)try{C(b.execPath,[m,`_archiveSweep`,`--cwd`,e,...n.flows?[`--flows`]:[],...t],{detached:!0,stdio:`ignore`}).unref()}catch{}}async function br(e){let{options:t,positionals:r}=_(e,E.object({cwd:ne,flows:te})),i=N(t);for(let e of r){if(t.flows){let t=Z(e);t&&li(t);continue}let r=n(i,e);r&&re(i,r)}}async function xr(e){let{options:t,positionals:n}=_(e,E.object({...y,"all-stopped":te}));Le(n,1,`task archive`);let r=N(t);if(t[`all-stopped`]){let e=u(r).filter(e=>a.includes(e.status));for(let t of e)re(r,t);let n=e.map(e=>e.id);if(t.json){j({archived:n,count:n.length});return}b.stdout.write(n.length?`Archived ${n.length} stopped task${n.length===1?``:`s`}.\n`:`${O.dim(`No stopped tasks to archive.`)}\n`);return}let i=n[0];i||A(`Missing task id.`,{hint:[`Archive one: coder task archive <task-id>`,`Archive all stopped: coder task archive --all-stopped`]});let o=Re(r,i);if(re(r,o),t.json){j({taskId:o.id,archived:!0});return}b.stdout.write(`Archived task ${O.cyan(o.id)}.\n`)}async function Sr(e,n,r={}){let i=n.engine===`claude`?{detail:`claude worker terminated`}:await(r.interrupt??Gt)(e,{endpoint:n.steerEndpoint,threadId:n.threadId,turnId:n.turnId});if(n.engine!==`claude`&&mt(n.steerEndpoint),n.pid&&n.status===`running`)try{b.kill(n.pid,`SIGTERM`)}catch{}return t(e,n.id,{status:`cancelled`,steerEndpoint:null,completedAt:new Date().toISOString()}),{taskId:n.id,status:`cancelled`,interrupt:i.detail}}async function Cr(e){let{options:t,positionals:n}=_(e,E.object(y));Le(n,1,`task stop`);let r=N(t),i=Re(r,n[0]),{interrupt:a}=await Sr(r,i);if(t.json){j({taskId:i.id,status:`cancelled`,interrupt:a});return}b.stdout.write(`Stopped task ${O.cyan(i.id)} ${O.dim(`(${a})`)}\n`)}function wr(e){return typeof e!=`object`||!e?JSON.stringify(e)??`null`:Array.isArray(e)?`[${e.map(wr).join(`,`)}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${wr(e[t])}`).join(`,`)}}`}function Tr(e,t){return ue.createHash(`sha256`).update(`${e}\0${wr(t)}`).digest(`hex`)}function Er(e){return x.existsSync(e)?x.readFileSync(e,`utf8`).split(/\r?\n/).filter(Boolean).map(e=>{try{return JSON.parse(e)}catch{return null}}).filter(e=>e!==null):[]}var Dr=class{file;recorded;seq=0;constructor(e,t){this.file=t,this.recorded=e.map(e=>({...e})),x.writeFileSync(t,``,`utf8`)}write(e){e.seq=this.seq++,x.appendFileSync(this.file,`${JSON.stringify(e)}\n`,`utf8`)}replay(e){let t=this.recorded.find(t=>!t.consumed&&t.fingerprint===e);if(!t)return null;t.consumed=!0;let{consumed:n,...r}=t;return this.write(r),r}record(e){this.write({...e,seq:0})}};const Or=globalThis,q=Or.__coderFlowCtxALS??=new de,J=Or.__coderFlowScopeALS??=new de;function kr(){return J.getStore()?.args}function Ar(){return J.getStore()?.depth??0}var jr=class{limit;active=0;queue=[];constructor(e){this.limit=e}async run(e){this.active<this.limit?this.active+=1:await new Promise(e=>this.queue.push(e));try{return await e()}finally{let e=this.queue.shift();e?e():--this.active}}};function Mr(e,t){return t?e?{input:e.input+t.input,cachedInput:e.cachedInput+t.cachedInput,output:e.output+t.output,total:e.total+t.total}:{...t}:e}function Nr(e,t){if(!t.tokens)return;let n=t.model??`default`;e.ledger[n]=Mr(e.ledger[n]??null,t.tokens)}function Pr(e){return!!e&&typeof e.safeParse==`function`}async function Fr(e){try{let t=await import(`zod`);if(typeof t.toJSONSchema==`function`)return t.toJSONSchema(e)}catch{}return null}async function Ir(e){let t=await Fr(e);return`Reply with ONLY a single JSON object ${t?`matching this JSON Schema:\n${JSON.stringify(t,null,2)}`:`matching the requested shape`}\nNo prose, no markdown fences — just the JSON object.`}function Lr(e){let t=e.trim(),n=t.match(/```(?:json)?\s*([\s\S]*?)```/i);n&&(t=n[1].trim());let r=t.indexOf(`{`);if(r===-1)throw Error(`no JSON object found in reply`);let i=0,a=!1,o=!1;for(let e=r;e<t.length;e+=1){let n=t[e];if(a){o?o=!1:n===`\\`?o=!0:n===`"`&&(a=!1);continue}if(n===`"`)a=!0;else if(n===`{`)i+=1;else if(n===`}`&&(--i,i===0))return JSON.parse(t.slice(r,e+1))}throw Error(`unterminated JSON object in reply`)}function Rr(e,t){if(!Pr(e))return{ok:!0,data:t};let n=e.safeParse(t);if(n.success)return{ok:!0,data:n.data};let r=n.error?.issues??n.error?.errors??[];return{ok:!1,errors:Array.isArray(r)?r.map(e=>`${(e.path??[]).join(`.`)||`(root)`}: ${e.message}`).join(`; `):String(n.error)}}function zr(e,t,n){return{cwd:t,agent:e.agent,model:e.model,effort:e.effort,permissions:e.permissions,name:e.name,system:e.system,wait:!0,flowRunId:n?.runId}}async function Br(e,t,n,r){let i=t.cwd?S.resolve(t.cwd):n?.cwd??b.cwd(),a;for(;;){let o=await sr({prompt:e,...zr(t,i,n),...a?{agent:a,model:void 0,effort:void 0,resume:void 0}:{resume:r??t.resume},onFallback:e=>Xr(`${e.agent} failed to start — falling back to ${e.next} (${e.detail.replace(/\s+/g,` `).slice(0,140)})`)});n?.running.add(o.taskId);let s=g(i,o.taskId),c=s?be(s):void 0;n?.hooks.onTaskStart?.({taskId:o.taskId,name:t.name,prompt:e,agent:c,depth:Ar()});let l;try{l=await fr(i,o.taskId)}finally{n?.running.delete(o.taskId)}let u=cr(i,l);if(u){n?.hooks.onTaskEnd?.({taskId:o.taskId,status:`failed`,tokens:null}),a=u;continue}return{taskId:o.taskId,status:l.status,output:l.result?.finalMessage||l.result?.error?.message||``,tokens:l.result?.tokens??null,model:l.result?.model??l.job.model??null}}}async function Vr(e,t,n){let r=e;if(t.returns&&(r=`${e}\n\n${await Ir(t.returns)}`),n?.dryRun){b.stdout.write(`\n[dry-run] task${t.name?` (${t.name})`:``}:\n${r}\n`);let e={...t,returns:t.returns?`<schema>`:void 0};return b.stdout.write(`[dry-run] opts: ${JSON.stringify(e)}\n`),{taskId:`dry`,status:`completed`,output:`[dry-run]`,data:void 0,tokens:null,model:t.model??null}}let i=await Br(r,t,n);if(i.status!==`completed`){let e={...i,data:void 0};throw new K(`task-failed`,`Task ${i.taskId} ${i.status}: ${i.output||`no output`}`,{taskId:i.taskId,result:e})}let a=i.output,o=i.tokens,s;if(t.returns){let e;try{e=Rr(t.returns,Lr(a))}catch(t){e={ok:!1,errors:t instanceof Error?t.message:String(t)}}if(e.ok)s=e.data;else{let r=await Br(`Your previous reply did not match the required format: ${e.errors}\n\n${await Ir(t.returns)}`,t,n,i.taskId);a=r.output||a,o=Mr(o,r.tokens);try{let e=Rr(t.returns,Lr(a));if(!e.ok)throw Error(e.errors);s=e.data}catch(e){let t={taskId:i.taskId,status:`completed`,output:a,data:void 0,tokens:o,model:i.model};throw new K(`task-failed`,`Task ${i.taskId} produced no valid structured output: ${e instanceof Error?e.message:String(e)}`,{taskId:i.taskId,result:t})}}}return{taskId:i.taskId,status:`completed`,output:a,data:s,tokens:o,model:i.model}}async function Hr(e){if(e)return await Fr(e)??`<schema>`}async function Ur(e,t={}){let n=q.getStore();if(!n)return Vr(e,t);let r=Tr(`task`,{prompt:e,agent:t.agent,model:t.model,effort:t.effort,permissions:t.permissions,name:t.name,system:t.system,resume:t.resume,cwd:t.cwd,returns:await Hr(t.returns)}),i=n.journal.replay(r);if(i)return i.result;if(n.taskCount+=1,n.taskCount>n.maxTasks)throw Error(`Flow exceeded --max-tasks (${n.maxTasks}). Raise it with --max-tasks, or fix a runaway loop; the run is resumable.`);return n.semaphore.run(async()=>{let i=new Date().toISOString(),a;try{a=await Vr(e,t,n)}catch(e){let t=e instanceof K?e.result:void 0;throw t&&n.hooks.onTaskEnd?.({taskId:t.taskId,status:t.status===`completed`?`failed`:t.status,tokens:t.tokens}),e}return Nr(n,a),n.dryRun||n.hooks.onTaskEnd?.({taskId:a.taskId,status:a.status,tokens:a.tokens}),n.journal.record({kind:`task`,fingerprint:r,result:a,taskId:a.taskId,tokens:a.tokens,startedAt:i,endedAt:new Date().toISOString()}),a})}const Wr=262144;let Gr=0;function Kr(e){let t=[];for(let n=e;;){t.push(S.join(n,`node_modules`,`.bin`));let e=S.dirname(n);if(e===n)break;n=e}let n=b.platform===`win32`?`;`:`:`;return{...b.env,PATH:[...t,b.env.PATH??``].join(n)}}async function qr(e,t){return new Promise(n=>{let r=C(e,{shell:!0,cwd:t,env:Kr(t)}),i=``,a=e=>{i.length>=Wr||(i+=e,i.length>=Wr&&(i=`${i.slice(0,Wr)}\n... [gate output truncated]`))};r.stdout?.on(`data`,a),r.stderr?.on(`data`,a),r.on(`error`,e=>n({ok:!1,code:1,output:String(e.message??e).trim()})),r.on(`close`,e=>n({ok:e===0,code:e??0,output:i.trim()}))})}async function Jr(e,t={}){let n=q.getStore(),r=t.cwd?S.resolve(t.cwd):n?.cwd??b.cwd();if(!n)return qr(e,r);let i=Tr(`gate`,{cmd:e,cwd:t.cwd}),a=n.journal.replay(i);if(a)return a.result;if(n.dryRun){b.stdout.write(`\n[dry-run] gate: ${e}\n`);let t={ok:!0,code:0,output:``};return n.journal.record({kind:`gate`,fingerprint:i,result:t,startedAt:new Date().toISOString(),endedAt:new Date().toISOString()}),t}let o=new Date().toISOString(),s=`gate-${b.pid}-${Gr+=1}`,c=Ar();n.hooks.onGateStart?.({gateId:s,cmd:e,depth:c});let l=await qr(e,r);return n.hooks.onGate?.({gateId:s,cmd:e,ok:l.ok,code:l.code,depth:c}),n.journal.record({kind:`gate`,fingerprint:i,result:l,startedAt:o,endedAt:new Date().toISOString()}),l}async function Yr(e,...t){return Promise.all(e.map(async(e,n)=>{let r=e;for(let i of t)try{r=await i(r,e,n)}catch{return null}return r}))}function Xr(e){let t=q.getStore();if(t)try{x.appendFileSync(S.join(t.runDir,`flow.log`),`${JSON.stringify({at:new Date().toISOString(),message:e})}\n`,`utf8`)}catch{}t?.hooks.onLog?t.hooks.onLog(e,Ar()):(b.stderr.isTTY||!t)&&b.stderr.write(`[flow] ${e}\n`)}const Zr=oe(import.meta.url);function Qr(e){let t=S.dirname(se(import.meta.url));for(;S.basename(t)!==`dist`&&S.dirname(t)!==t;)t=S.dirname(t);return S.basename(t)===`dist`?ce(S.join(t,e)).href:null}function $r(e){if(!(e===`@wular/coder`||e===`@wular/coder/flow`||e===`zod`||e.startsWith(`zod/`)))return null;try{return ce(Zr.resolve(e)).href}catch{}return e===`@wular/coder/flow`?Qr(`flow/index.js`):e===`@wular/coder`?Qr(`sdk.js`):null}const ei=/(\bfrom\s+|\bimport\s+|\bimport\s*\(\s*)(['"])([^'"]+)\2/g;function ti(e){return e.replace(ei,(e,t,n,r)=>{let i=$r(r);return i?`${t}${n}${i}${n}`:e})}async function ni(e,t,n){try{return await import(ce(e).href)}catch(e){let r=e instanceof Error?e.message:String(e);throw t===`.ts`&&!b.versions?.bun&&/Unknown file extension|Unexpected token|SyntaxError|Cannot parse|import type|interface/i.test(r)?Error(`Could not run ${S.basename(n)}: TypeScript flows need bun. Run under \`bun\`, or write the flow as .mjs/.js.`):e}}async function ri(e){let t=S.extname(e),n;try{n=x.readFileSync(e,`utf8`)}catch{throw Error(`Cannot read flow file: ${e}`)}let r=ti(n);if(r===n)return ni(e,t,e);let i=S.dirname(e);try{for(let e of x.readdirSync(i)){if(!e.startsWith(`.__coderflow_`))continue;let t=S.join(i,e);Date.now()-x.statSync(t).mtimeMs>6e5&&x.unlinkSync(t)}}catch{}let a=`${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`,o=S.join(i,`.__coderflow_${a}${t}`),s=`__coderflow_loaded_${a}`,c=new Promise(e=>{globalThis[s]=e});x.writeFileSync(o,`globalThis[${JSON.stringify(s)}]?.();${r}`,`utf8`);let l=ni(o,t,e);try{await Promise.race([c,l.then(()=>void 0,()=>void 0)])}finally{delete globalThis[s];try{x.unlinkSync(o)}catch{}}return await l}async function ii(e,t){let n=J.getStore();n.args=t??{};let r=await ri(e),i=r.args,a=n.args;if(Pr(i)){let e=i.safeParse(t??{});if(!e.success){let e=Rr(i,t??{});throw Error(`Invalid flow args: ${e.errors??`validation failed`}`)}a=e.data,n.args=a}let o=r.default;return typeof o==`function`?o(a):o}async function ai(e,t){let n=q.getStore(),r=vr(e,n?.cwd??b.cwd());if(!n)return J.run({args:t??{},depth:0},()=>ii(r.path,t));let i=J.getStore();if(i&&i.depth>=1)throw Error(`flow("${e}") nesting is one level deep; a sub-flow cannot call flow().`);let a=Tr(`flow`,{name:r.name,args:t??{}}),o=n.journal.replay(a);if(o)return o.result;let s=new Date().toISOString();n.hooks.onFlowStart?.({name:r.name,depth:(i?.depth??0)+1});let c=await J.run({args:t??{},depth:(i?.depth??0)+1},()=>ii(r.path,t));return n.journal.record({kind:`flow`,fingerprint:a,result:c,startedAt:s,endedAt:new Date().toISOString()}),c}function oi(){return`flow-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Y(){return S.join(r(),`state`,`global`,`flows`)}function si(){return S.join(r(),`state`,`global`,`flows-archived`)}function X(e){ae(e,`flow run id`);let t=S.join(Y(),e);if(x.existsSync(S.join(t,`flow.json`)))return t;let n=S.join(si(),e);return x.existsSync(S.join(n,`flow.json`))?n:t}function ci(e){if(e.archived)return e;let t={...e,archived:!0,archivedAt:new Date().toISOString()};return Q(X(e.runId),t),t}function li(e){let t=ci(e),n=X(e.runId),r=S.join(si(),e.runId);if(n!==r)try{x.mkdirSync(si(),{recursive:!0}),x.renameSync(n,r)}catch{}return t}function ui(e){let t=X(e.runId),n=S.join(Y(),e.runId);if(t!==n)try{x.mkdirSync(Y(),{recursive:!0}),x.renameSync(t,n)}catch{}let r={...e,archived:void 0,archivedAt:void 0};return Q(X(e.runId),r),r}function di(e){let t=X(e);return x.existsSync(S.join(t,`flow.json`))?(x.rmSync(t,{recursive:!0,force:!0}),!0):!1}function fi(e){if(!f(e))return null;let t=S.join(X(e),`flow.json`);if(!x.existsSync(t))return null;try{return JSON.parse(x.readFileSync(t,`utf8`))}catch{return null}}function pi(e){return e.status!==`running`||!e.pid||Ti(e)?e:(Si(e.runId,`orchestrator died`),fi(e.runId)??e)}function Z(e){let t=fi(e);return t?pi(t):null}function Q(e,t){x.writeFileSync(S.join(e,`flow.json`),`${JSON.stringify(t,null,2)}\n`,`utf8`)}function mi(e){let t=[];try{t=x.readdirSync(e)}catch{return[]}let n=[];for(let r of t)try{n.push(pi(JSON.parse(x.readFileSync(S.join(e,r,`flow.json`),`utf8`))))}catch{}return n}const hi=(e,t)=>String(t.startedAt).localeCompare(String(e.startedAt));function gi(){let e=[];for(let t of mi(Y()))t.archived?li(t):e.push(t);return e.sort(hi)}function _i(e){let t=e?.migrate??!0,n=mi(si()),r=new Set(n.map(e=>e.runId));for(let e of mi(Y()))e.archived&&!r.has(e.runId)&&n.push(t?li(e):e);return n.sort(hi)}function vi(){return[...gi(),..._i()].sort(hi)[0]??null}function yi(e,t=`all`){if(t===0)return[];let n=Er(S.join(X(e),`journal.jsonl`)).filter(e=>e.kind===`task`),r=u(b.cwd()),i=new Map(r.map(e=>[e.id,e])),a=e=>e?.name??e?.prompt?.replace(/\s+/g,` `).trim().slice(0,60)??null,o=n.map(e=>{let t=e.taskId?i.get(e.taskId):void 0;return{taskId:e.taskId??null,name:a(t),status:t?.status??e.result?.status??`?`,tokens:e.tokens??null}}),s=new Set(o.map(e=>e.taskId));for(let t of r)t.flowRunId===e&&!s.has(t.id)&&o.push({taskId:t.id,name:a(t),status:t.status,tokens:null});return t===`all`?o:o.slice(-t)}function bi(e={}){let t;if(e.archived)t=_i();else{let e=[];t=gi().filter(t=>t.status===`running`||t.status===`queued`||he(t.endedAt??t.startedAt)<=6e5||(ci(t),e.push(t.runId),!1)),yr(b.cwd(),e,{flows:!0})}let n=e.limit===void 0?0:Math.max(0,t.length-e.limit);return{runs:e.limit===void 0?t:t.slice(0,e.limit),clipped:n}}function xi(e,t={},n){let r,i,a;if(n){let e=Z(n);if(!e)throw Error(`No flow run "${n}".`);e.archived&&ui(e),r=e.name,i=e.script,a=t.args??e.args}else{let n=vr(e,t.cwd?S.resolve(t.cwd):b.cwd());r=n.name,i=n.path,a=t.args??{}}let o=n??oi(),s=X(o);x.mkdirSync(s,{recursive:!0});let c={runId:o,name:r,script:i,args:a,status:`running`,startedAt:new Date().toISOString(),concurrency:Math.max(1,t.concurrency??T.cpus().length),maxTasks:Math.max(1,t.maxTasks??T.cpus().length*10),taskCount:0,ledger:{}};return Q(s,c),c}function $(e,t,n){Q(e,{...t,endedAt:new Date().toISOString(),pid:void 0,pidStartedAt:void 0,...n})}function Si(e,t){let n=fi(e);!n||n.status!==`running`||$(X(e),n,{status:`failed`,error:t})}const Ci=`stop-keep-tasks`;function wi(e){try{return b.kill(e,0),!0}catch{return!1}}function Ti(t){if(!t.pid||!wi(t.pid))return!1;let n=e(t.pid),r=Date.parse(t.pidStartedAt??``);return n===null||!Number.isFinite(r)||n<=r+6e4}function Ei(e){let t=u(b.cwd()),n=new Map(t.map(e=>[e.id,e])),r=new Set(t.filter(t=>t.flowRunId===e).map(e=>e.id));for(let t of Er(S.join(X(e),`journal.jsonl`)))t.kind===`task`&&t.taskId&&r.add(t.taskId);return[...r].filter(e=>{let t=n.get(e);return!!t&&!a.includes(t.status)})}async function Di(e,t=[]){let n=b.cwd(),r=[];for(let i of new Set([...Ei(e),...t])){let e=g(n,i);if(!(!e||a.includes(e.status)))try{await Sr(n,e),r.push(i)}catch{}}return r}async function Oi(e,t={}){let n=e?Z(e):vi();if(!n)throw new K(`flow-failed`,e?`No flow run "${e}".`:`No flow runs.`,{hint:`Run one: coder flow run <name>`});if(n.status!==`running`)throw new K(`flow-failed`,`Run ${n.runId} is not running.`,{runId:n.runId,hint:`Result: coder flow result ${n.runId}`});let r=X(n.runId);if(!Ti(n))return $(r,n,{status:`failed`,error:`orchestrator died`}),{runId:n.runId,status:`failed`,stoppedTasks:[],keptTasks:Ei(n.runId)};let i=Ei(n.runId),o=S.join(r,Ci);t.keepTasks&&x.writeFileSync(o,``,`utf8`);try{b.kill(n.pid,`SIGINT`);let e=Z(n.runId);for(let t=0;t<25&&e?.status===`running`;t+=1)await new Promise(e=>setTimeout(e,200)),e=Z(n.runId);if(!e||e.status===`running`)throw new K(`flow-failed`,`Run ${n.runId} did not stop within 5s.`,{runId:n.runId,hint:`Check it: coder flow result ${n.runId}`});let t=b.cwd(),r=[],o=[];for(let e of i){let n=g(t,e);n&&(n.status===`cancelled`?r.push(e):a.includes(n.status)||o.push(e))}return{runId:n.runId,status:e.status,stoppedTasks:r,keptTasks:o}}finally{if(t.keepTasks)try{x.unlinkSync(o)}catch{}}}async function*ki(e,t,n={}){let r=S.join(X(e),`events.jsonl`),i=n.tail??`all`,a=0;if(i!==`all`)try{a=Math.max(0,x.readFileSync(r,`utf8`).split(`
19
+ `).length-1-i)}catch{}let o=Ye(r),s=()=>{let e=[];for(let t of o()){if(a>0){--a;continue}try{e.push(JSON.parse(t))}catch{}}return e},c=Z(e);for(;!c||c.status===`running`;){yield*s();let n=c?.pid?!Ti(c):t!==void 0&&!wi(t);if(c&&(c.pid||t!==void 0)&&n){Si(e,`orchestrator died`);break}await new Promise(e=>setTimeout(e,400)),c=Z(e)??c}yield*s()}function Ai(e,t,n,r){let i={...xi(e,t,r),pid:b.pid,pidStartedAt:new Date().toISOString()},{runId:a}=i,o=X(a);Q(o,i);let s=S.join(o,`journal.jsonl`),c=r?Er(s):[],l=new Dr(c,s),u={runId:a,runDir:o,cwd:t.cwd?S.resolve(t.cwd):b.cwd(),journal:l,semaphore:new jr(i.concurrency),maxTasks:i.maxTasks,dryRun:t.dryRun??!1,ledger:{},running:new Set,taskCount:0,stopping:!1,hooks:n};return{started:{runId:a,runDir:o,ctx:u,markStopped:()=>{u.stopping=!0,$(o,i,{status:`stopped`,taskCount:u.taskCount,ledger:u.ledger})}},args:i.args,name:i.name,replayable:c.length}}async function ji(e,t,n,r){let{ctx:i,runDir:a,runId:o}=e,s=Z(o);try{let e=await q.run(i,()=>J.run({args:r??{},depth:0},()=>ii(t,r)));return $(a,s,{status:`completed`,taskCount:i.taskCount,ledger:i.ledger,result:e}),{runId:o,name:n,status:`completed`,result:e,tokens:i.ledger,taskCount:i.taskCount}}catch(e){throw i.stopping||$(a,s,{status:`failed`,taskCount:i.taskCount,ledger:i.ledger,error:e instanceof Error?e.message:String(e)}),new K(`flow-failed`,e instanceof Error?e.message:String(e),{runId:o})}}async function Mi(e,t={},n={}){let{started:r}=Ai(e,t,n),i=Z(r.runId).script;return n.onStart?.({runId:r.runId,requestStop:r.markStopped,runningIds:()=>[...r.ctx.running]}),ji(r,i,Z(r.runId).name,t.args??{})}async function Ni(e,t={},n={}){let{started:r,args:i,name:a,replayable:o}=Ai(``,t,n,e),s=Z(e).script;return n.onStart?.({runId:e,requestStop:r.markStopped,runningIds:()=>[...r.ctx.running]}),o&&n.onReplay?.(o),ji(r,s,a,i)}export{Zt as $,O as $t,gr as A,F as At,fr as B,De as Bt,Ur as C,ct as Ct,xr as D,at as Dt,Sr as E,I as Et,or as F,Ke as Ft,Kn as G,be as Gt,Xn as H,A as Ht,sr as I,we as It,In as J,M as Jt,Jn as K,pe as Kt,rr as L,Pe as Lt,K as M,We as Mt,$n as N,qe as Nt,br as O,st as Ot,er as P,Ge as Pt,U as Q,Ne as Qt,dr as R,Ce as Rt,ki as S,ot as St,Cr as T,rt as Tt,Qn as U,ve as Ut,qn as V,Te as Vt,Yn as W,ge as Wt,Wn as X,Ee as Xt,Gn as Y,_e as Yt,W as Z,xe as Zt,Ni as _,Wt as _t,di as a,N as an,mn as at,Di as b,Kt as bt,Jr as c,ke as cn,yn as ct,gi as d,xn as dt,Fe as en,H as et,Xr as f,Tn as ft,Z as g,An as gt,xi as h,hn as ht,kr as i,Re as in,Cn as it,vr as j,Je as jt,yr as k,Ye as kt,vi as l,Se as ln,bn as lt,Yr as m,vn as mt,li as n,ye as nn,Jt as nt,ai as o,Ie as on,En as ot,Si as p,wn as pt,Ln as q,me as qt,bi as r,Le as rn,Yt as rt,yi as s,Oe as sn,G as st,Ci as t,j as tn,V as tt,_i as u,kn as ut,X as v,B as vt,Er as w,nt as wt,Oi as x,lt as xt,Mi as y,qt as yt,ir as z,he as zt};
package/dist/sdk.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as Job, E as CustomModelConfig, S as Availability, T as CoderConfig, _ as FlowStep, a as JobLogEntry, c as StopSummary, g as FlowRecord, h as FlowEvent, i as TaskResult, m as DiscoveredFlow, n as flowSdk, o as RunOptions, r as CoderError, s as RunSummary, w as TurnResult, x as Approval } from "./index-CTrgzW3M.js";
1
+ import { C as Job, E as CustomModelConfig, S as Availability, T as CoderConfig, _ as FlowStep, a as JobLogEntry, c as StopSummary, g as FlowRecord, h as FlowEvent, i as TaskResult, m as DiscoveredFlow, n as flowSdk, o as RunOptions, r as CoderError, s as RunSummary, w as TurnResult, x as Approval } from "./index-BQ-b77or.js";
2
2
  //#region src/lib/codex-core.d.ts
3
3
  declare function getCodexAvailability(cwd: string): Availability;
4
4
  //#endregion
package/dist/sdk.js CHANGED
@@ -1 +1 @@
1
- import{C as e,I as t,v as n,x as r}from"./app-server-bHl6RBZ2.js";import{B as i,E as a,Et as o,I as s,M as c,R as l,xt as u}from"./runtime-DrTVUIwM.js";import{D as d,S as f,T as p,_ as m,b as h,c as g,d as _,f as v,g as y,i as b,l as x,m as S,n as C,o as w,s as T,u as E,y as D}from"./upgrade-DfGOKVRK.js";import O from"./flow/index.js";import k from"node:process";import A from"node:path";function j(e){return e?A.resolve(e):k.cwd()}function M(t,n){let r=e(t,n);if(!r)throw Error(n?`No task found for "${n}".`:`No tasks found for this workspace.`);return r}const N={async run(e,t={}){let{taskId:n}=await s({prompt:e,cwd:j(t.cwd),agent:t.agent,model:t.model,effort:t.effort,permissions:t.permissions,name:t.name,system:t.system,resume:t.resume});return{taskId:n}},async result(e,t={}){let n=j(t.cwd),r=e??M(n).id;return t.wait?i(n,r,{tail:t.tail}):l(n,r,{tail:t.tail})},list(e={}){return h(j(e.cwd),e).jobs},async steer(e,t,n={}){let r=j(n.cwd);return p(r,M(r,e),t,{model:n.model,effort:n.effort,permissions:n.permissions})},async ask(e,t,n={}){let r=j(n.cwd),i=M(r,e),a=await f(r,i,t,{model:n.model,effort:n.effort});return{taskId:i.id,answer:a.finalMessage||null}},async stop(e,t={}){let n=j(t.cwd);return a(n,M(n,e))},archive(e,t={}){let r=j(t.cwd);return n(r,M(r,e)),{taskId:e,archived:!0}},delete(e,t={}){let n=j(t.cwd),i=M(n,e);if(i.status===`running`)throw Error(`Task ${i.id} is still running.`);D(i);let a=r(n,i.id);return{taskId:i.id,deleted:a}},approve(e,n,r={}){let i=j(r.cwd),a=M(i,e),o=r.deny?`decline`:`accept`;return u(t(i,a.id),n,o),{taskId:a.id,approvalId:n,decision:o}},approvals(e,n={}){let r=j(n.cwd),i=e?M(r,e):M(r);return o(t(r,i.id))},stream(e,t={}){let n=j(t.cwd);return d(n,e??M(n).id,{tail:t.tail})}},P={add:(e,t)=>w(j(t.cwd),e,t),update:(e,t)=>v(j(t.cwd),e,t),remove:(e,t={})=>x(j(t.cwd),e,t),list:(e={})=>g(j(e.cwd)),alias:(e,t,n={})=>T(j(n.cwd),e,t,n),unalias:(e,t={})=>_(j(t.cwd),e,t),disable:(e,t={})=>E(j(t.cwd),e,!0,t),enable:(e,t={})=>E(j(t.cwd),e,!1,t)},F={get:(e,t={})=>y(j(t.cwd),e),set:(e,t,n={})=>m(j(n.cwd),e,t,n)};function I(e=[],t={}){return S(j(t.cwd),{claude:e.includes(`claude`),codex:e.includes(`codex`),agents:e.includes(`agents`)})}function L(e={}){return C(e)}function R(e){return b(e)}var z={task:N,flow:O,model:P,config:F,setupHost:I,upgrade:L,docs:R};export{c as CoderError,F as config,z as default,R as docs,O as flow,P as model,I as setupHost,N as task,L as upgrade};
1
+ import{C as e,I as t,v as n,x as r}from"./app-server-bHl6RBZ2.js";import{B as i,Dt as a,E as o,I as s,M as c,R as l,St as u}from"./runtime-DtukZ1m8.js";import{D as d,S as f,T as p,_ as m,b as h,c as g,d as _,f as v,g as y,i as b,l as x,m as S,n as C,o as w,s as T,u as E,y as D}from"./upgrade-cC4ahBbt.js";import O from"./flow/index.js";import k from"node:process";import A from"node:path";function j(e){return e?A.resolve(e):k.cwd()}function M(t,n){let r=e(t,n);if(!r)throw Error(n?`No task found for "${n}".`:`No tasks found for this workspace.`);return r}const N={async run(e,t={}){let{taskId:n}=await s({prompt:e,cwd:j(t.cwd),agent:t.agent,model:t.model,effort:t.effort,permissions:t.permissions,name:t.name,system:t.system,resume:t.resume});return{taskId:n}},async result(e,t={}){let n=j(t.cwd),r=e??M(n).id;return t.wait?i(n,r,{tail:t.tail}):l(n,r,{tail:t.tail})},list(e={}){return h(j(e.cwd),e).jobs},async steer(e,t,n={}){let r=j(n.cwd);return p(r,M(r,e),t,{model:n.model,effort:n.effort,permissions:n.permissions})},async ask(e,t,n={}){let r=j(n.cwd),i=M(r,e),a=await f(r,i,t,{model:n.model,effort:n.effort});return{taskId:i.id,answer:a.finalMessage||null}},async stop(e,t={}){let n=j(t.cwd);return o(n,M(n,e))},archive(e,t={}){let r=j(t.cwd);return n(r,M(r,e)),{taskId:e,archived:!0}},delete(e,t={}){let n=j(t.cwd),i=M(n,e);if(i.status===`running`)throw Error(`Task ${i.id} is still running.`);D(i);let a=r(n,i.id);return{taskId:i.id,deleted:a}},approve(e,n,r={}){let i=j(r.cwd),a=M(i,e),o=r.deny?`decline`:`accept`;return u(t(i,a.id),n,o),{taskId:a.id,approvalId:n,decision:o}},approvals(e,n={}){let r=j(n.cwd),i=e?M(r,e):M(r);return a(t(r,i.id))},stream(e,t={}){let n=j(t.cwd);return d(n,e??M(n).id,{tail:t.tail})}},P={add:(e,t)=>w(j(t.cwd),e,t),update:(e,t)=>v(j(t.cwd),e,t),remove:(e,t={})=>x(j(t.cwd),e,t),list:(e={})=>g(j(e.cwd)),alias:(e,t,n={})=>T(j(n.cwd),e,t,n),unalias:(e,t={})=>_(j(t.cwd),e,t),disable:(e,t={})=>E(j(t.cwd),e,!0,t),enable:(e,t={})=>E(j(t.cwd),e,!1,t)},F={get:(e,t={})=>y(j(t.cwd),e),set:(e,t,n={})=>m(j(n.cwd),e,t,n)};function I(e=[],t={}){return S(j(t.cwd),{claude:e.includes(`claude`),codex:e.includes(`codex`),agents:e.includes(`agents`)})}function L(e={}){return C(e)}function R(e){return b(e)}var z={task:N,flow:O,model:P,config:F,setupHost:I,upgrade:L,docs:R};export{c as CoderError,F as config,z as default,R as docs,O as flow,P as model,I as setupHost,N as task,L as upgrade};
@@ -0,0 +1,36 @@
1
+ import{B as e,D as t,E as n,H as r,I as i,L as a,O as o,P as s,S as c,U as l,V as u,_ as d,c as f,d as p,f as m,h,j as g,k as _,l as v,m as y,o as b,p as x,s as S,u as C,x as w,z as T}from"./app-server-bHl6RBZ2.js";import{$t as E,At as D,Bt as O,Dt as ee,G as te,Gt as ne,H as re,Ht as k,J as ie,K as ae,Kt as A,Mt as oe,Nt as se,Q as j,U as ce,Ut as le,V as ue,Vt as de,W as fe,Wt as pe,X as me,Xt as M,Y as he,Yt as ge,Z as _e,Zt as ve,_t as ye,an as N,at as P,bt as be,ct as F,en as xe,et as Se,ft as Ce,g as we,gt as Te,ht as Ee,in as I,it as De,k as Oe,kt as ke,ln as Ae,lt as L,mt as R,nn as je,nt as Me,ot as z,pt as Ne,q as Pe,rn as B,st as V,tn as H,tt as U,ut as Fe,vt as W,yt as Ie,z as Le,zt as Re}from"./runtime-DtukZ1m8.js";import G from"node:process";import K from"node:fs";import q from"node:path";import{spawnSync as ze}from"node:child_process";import Be from"node:os";import{fileURLToPath as Ve}from"node:url";import*as J from"zod/mini";import He from"node:crypto";import Ue from"node:http";let We=0;function Ge(e){let t=[];typeof e.instructions==`string`&&e.instructions&&t.push({role:`system`,content:e.instructions});let n=Array.isArray(e.input)?e.input:[];for(let e of n)switch(e?.type){case`message`:{let n=Array.isArray(e.content)?e.content.map(e=>e?.text??``).join(``):String(e.content??``);t.push({role:e.role===`developer`?`system`:e.role,content:n});break}case`function_call`:{let n={id:e.call_id,type:`function`,function:{name:e.name,arguments:e.arguments??`{}`}},r=t.at(-1);r?.role===`assistant`&&r.tool_calls?r.tool_calls.push(n):t.push({role:`assistant`,content:null,tool_calls:[n]});break}case`function_call_output`:{let n=e.output;t.push({role:`tool`,tool_call_id:e.call_id,content:typeof n==`string`?n:JSON.stringify(n??``)});break}}return t}function Ke(e){let t=(Array.isArray(e.tools)?e.tools:[]).filter(e=>e?.type===`function`).map(e=>({type:`function`,function:{name:e.name,description:e.description??``,parameters:e.parameters??{type:`object`,properties:{}}}})),n=e.text?.format;return{model:e.model,messages:Ge(e),...t.length?{tools:t,tool_choice:e.tool_choice??`auto`}:{},...typeof e.parallel_tool_calls==`boolean`?{parallel_tool_calls:e.parallel_tool_calls}:{},...n?.type===`json_schema`?{response_format:{type:`json_schema`,json_schema:{name:n.name,schema:n.schema,strict:n.strict??!1}}}:{},stream:!0,stream_options:{include_usage:!0}}}var qe=class{send;model;responseId=`resp_bridge_${++We}`;text=``;textOpen=!1;toolCalls=new Map;usage=null;buffer=``;constructor(e,t){this.model=e,this.send=t,this.send({type:`response.created`,response:{id:this.responseId,object:`response`,status:`in_progress`,model:e,output:[]}})}push(e){this.buffer+=e;let t=this.buffer.split(`
2
+ `);this.buffer=t.pop()??``;for(let e of t){let t=e.trim();if(!t.startsWith(`data:`))continue;let n=t.slice(5).trim();if(!n||n===`[DONE]`)continue;let r;try{r=JSON.parse(n)}catch{continue}r.usage&&(this.usage=r.usage);let i=r.choices?.[0]?.delta;if(i){typeof i.content==`string`&&i.content&&(this.textOpen||(this.textOpen=!0,this.send({type:`response.output_item.added`,output_index:0,item:{type:`message`,id:`msg_bridge_0`,status:`in_progress`,role:`assistant`,content:[]}})),this.text+=i.content,this.send({type:`response.output_text.delta`,item_id:`msg_bridge_0`,output_index:0,content_index:0,delta:i.content}));for(let e of i.tool_calls??[]){let t=this.toolCalls.get(e.index)??{id:``,name:``,args:``};e.id&&(t.id=e.id),e.function?.name&&(t.name+=e.function.name),e.function?.arguments&&(t.args+=e.function.arguments),this.toolCalls.set(e.index,t)}}}}finish(){let e=[];if(this.text){let t={type:`message`,id:`msg_bridge_0`,status:`completed`,role:`assistant`,content:[{type:`output_text`,text:this.text,annotations:[]}]};e.push(t),this.send({type:`response.output_item.done`,output_index:0,item:t})}let t=e.length;for(let n of this.toolCalls.values()){let r={type:`function_call`,id:`fc_bridge_${t}`,call_id:n.id||`call_bridge_${t}`,name:n.name,arguments:n.args||`{}`,status:`completed`};e.push(r),this.send({type:`response.output_item.done`,output_index:t,item:r}),t+=1}this.send({type:`response.completed`,response:{id:this.responseId,object:`response`,status:`completed`,model:this.model,output:e,usage:{input_tokens:this.usage?.prompt_tokens??0,input_tokens_details:{cached_tokens:this.usage?.prompt_tokens_details?.cached_tokens??0},output_tokens:this.usage?.completion_tokens??0,output_tokens_details:{reasoning_tokens:this.usage?.completion_tokens_details?.reasoning_tokens??0},total_tokens:this.usage?.total_tokens??0}}})}};async function Je(e,t=`chat`){let n=t===`responses`,r=De(e.baseUrl,n?`responses`:`chat/completions`),i=null,a=e.envKey?G.env[e.envKey]:void 0;async function o(e){let t=i?[i]:r,n=null;for(let r of t)if(n=await fetch(r,{method:`POST`,headers:{"content-type":`application/json`,...a?{authorization:`Bearer ${a}`}:{}},body:e}),n.status!==404)return i=r,n;return n}let s=He.randomBytes(16).toString(`hex`),c=Ue.createServer((e,t)=>{if(e.method!==`POST`||!e.url?.startsWith(`/${s}/`)||!e.url.replace(/\/+$/,``).endsWith(`/responses`)){t.writeHead(404,{"content-type":`application/json`}),t.end(JSON.stringify({error:{message:`coder chat bridge: only POST /responses is supported`}}));return}let r=``;e.on(`data`,e=>r+=e),e.on(`end`,async()=>{let e;try{e=JSON.parse(r)}catch{t.writeHead(400,{"content-type":`application/json`}),t.end(JSON.stringify({error:{message:`invalid JSON`}}));return}try{if(n){let e=await o(r);if(t.writeHead(e.status,{"content-type":e.headers.get(`content-type`)??`application/json`,"cache-control":`no-store`}),e.body)for await(let n of e.body)t.write(n);t.end();return}let i=await o(JSON.stringify(Ke(e)));if(!i.ok||!i.body){let e=await i.text().catch(()=>``);t.writeHead(i.status,{"content-type":`application/json`}),t.end(e||JSON.stringify({error:{message:`upstream HTTP ${i.status}`}}));return}t.writeHead(200,{"content-type":`text/event-stream`,"cache-control":`no-store`});let a=new qe(e.model,e=>t.write(`data: ${JSON.stringify(e)}\n\n`)),s=new TextDecoder;for await(let e of i.body)a.push(s.decode(e,{stream:!0}));a.finish(),t.end()}catch(e){let n=e instanceof Error?e.message:String(e);t.writeHead(502,{"content-type":`application/json`}),t.end(JSON.stringify({error:{message:`coder chat bridge: ${n}`}}))}})});await new Promise(e=>c.listen(0,`127.0.0.1`,e));let l=c.address();return{url:`http://127.0.0.1:${typeof l==`object`&&l?l.port:0}/${s}/v1`,close:()=>new Promise(e=>{c.close(()=>e()),c.closeAllConnections?.()})}}async function Ye(e,t,n){let r=e.envKey?G.env[e.envKey]:void 0,i=!1;for(let a of De(e.baseUrl,t))try{let e=await fetch(a,{method:`POST`,headers:{"content-type":`application/json`,...r?{Authorization:`Bearer ${r}`}:{}},body:JSON.stringify(n),signal:AbortSignal.timeout(5e3)});if(i=!0,e.status!==404&&e.status!==405&&e.status!==501)return{baseUrl:a.slice(0,-(t.length+1))}}catch{}return{reachable:i}}async function Xe(e){let t=await Ye(e,`responses`,{model:e.model,input:[],stream:!1});if(`baseUrl`in t)return{wireApi:`responses`,baseUrl:t.baseUrl};let n=await Ye(e,`chat/completions`,{model:e.model,messages:[],stream:!1});return`baseUrl`in n?{wireApi:`chat`,baseUrl:n.baseUrl}:t.reachable||n.reachable?{wireApi:`chat`}:null}async function*Ze(e,t,n={}){let r=new Set([`completed`,`failed`,`cancelled`]),a=g(e,t);if(!a)throw Error(`No task found for "${t}".`);let o=n.tail??1,c=ke(q.join(i(e,t),`log.jsonl`)),l=!0,u=()=>{let e=c();return l&&(l=!1,o!==`all`&&(e=o===0?[]:e.slice(-o))),e.map(e=>{try{return JSON.parse(e)}catch{return{message:e}}})};for(yield*u();!r.has(a.status);)await new Promise(e=>setTimeout(e,400)),a=s(e,g(e,t)??a),yield*u();yield*u()}async function Qe(e){let{options:t,positionals:n}=v(e,J.object({...b,tail:p,trim:J.optional(J.union([J.literal(`none`),J.coerce.number().check(J.int(),J.positive())],{error:`expected a positive integer or "none"`}))}));B(n,1,`task watch`);let r=N(t),a=I(r,n[0]),o=t.tail,c=t.trim,l=c===void 0?300:c===`none`?2**53-1:c;if(!t.json){G.stdout.write(`${E.dim(`[coder] task ${a.id} ${a.status} — watching (Ctrl-C to stop)`)}\n`);let e=[`${E.dim(`agent`.padEnd(8))} ${ne(a)}`,...ve(a,E)];G.stdout.write(`${e.join(`
3
+ `)}\n`),a.prompt&&G.stdout.write(`${je(a.prompt,E,{truncate:!1}).join(`
4
+ `)}\n`)}for await(let e of Ze(r,a.id,{tail:o})){let n=e.kind===`steer`?2**53-1:l;if(t.json){let t=e.message?{...e,message:Ae(e.message,n,{plain:!0})}:e;G.stdout.write(`${JSON.stringify(t)}\n`)}else{let t=e.message??e.kind;t&&G.stdout.write(`${E.dim(`[coder]`)} ${Ae(t,n)}\n`)}}let u=s(r,g(r,a.id)??a),d=D(q.join(i(r,a.id),`result.json`));if(t.json)H({taskId:a.id,status:u.status,result:d});else{let e=u.status===`completed`?`(no final message)`:`(task ${u.status})`;G.stdout.write(`\n${le(d,u.error,e)}\n`);let t=d?.tokens?` tokens=${ge(d.tokens,d.model??u.model)}`:``;G.stderr.write(`${E.dim(`[coder] task=${a.id} status=${u.status}${t}`)}\n`)}G.exit(u.status===`completed`?0:1)}async function $e(e,t,n,r={}){if(t.status!==`running`)return null;let i=t.engine===`claude`?await(r.claude??me)(t.steerEndpoint,n):await(r.codex??be)(e,{endpoint:t.steerEndpoint,threadId:t.threadId,turnId:t.turnId,text:n});if(i.steered)return d(e,t.id,{kind:`steer`,message:`Steer accepted live:\n${n}`}),{taskId:t.id,steered:`live`};if(!i.retryable)throw d(e,t.id,{kind:`error`,message:`Live steer failed: ${i.detail}`}),Error(`Could not steer running task ${t.id}: ${i.detail}`);let a=g(e,t.id)??t;return u.includes(a.status)?(c(e,a.id,n),d(e,a.id,{kind:`steer`,message:`Steer queued for the next turn:\n${n}`}),{taskId:a.id,steered:`queued`}):null}async function et(e,t,n,r={},i={}){if(!t.threadId)throw Error(`Task ${t.id} has no thread to steer yet (status: ${t.status}).`);return await $e(e,t,n,i)||(tt(e,t,n,r),{taskId:t.id,steered:`resumed`})}function tt(t,n,r,i){e(t,n.id,{status:`queued`,resumedAt:new Date().toISOString(),currentPrompt:r,resumeThreadId:n.threadId,steerEndpoint:null,model:i.model??n.model??null,effort:i.effort??n.effort??null,permissions:i.permissions??n.permissions,error:void 0}),d(t,n.id,{kind:`steer`,message:`Resuming with steer:\n${r}`}),Le(n.cwd??t,n.id)}async function nt(e){let{options:t,positionals:n}=v(e,J.object({...b,model:C,effort:C,permissions:C,background:S,wait:S})),r=N(t),[i,...a]=n,o=a.join(` `).trim();(!i||!o)&&k(`Missing task id or follow-up text.`,{hint:[`Usage: coder task steer <task-id> "<follow-up>" [--wait]`,`Help: coder task steer --help`]});let s=I(r,i);s.threadId||k(`Task ${s.id} has no thread to steer yet (status: ${s.status}).`,{hint:`Wait for it to start: coder task watch ${s.id}`});let c=await et(r,s,o,{model:t.model,effort:t.effort,permissions:t.permissions});return rt(r,c.taskId,{steered:c.steered,options:t})}async function rt(e,t,{steered:n,options:r}){if(n===`queued`){if(r.json){H({taskId:t,steered:`queued`});return}G.stdout.write(`${E.dim(`[coder]`)} follow-up queued for task ${E.cyan(t)}; it runs when the current turn finishes.\n`),r.wait&&G.stdout.write(`\n${E.dim(`[coder] --wait is not available for a queued follow-up; check: coder task result ${t}`)}\n`);return}if(!r.wait){if(r.json){H({taskId:t,steered:n});return}G.stdout.write(n===`live`?`${E.dim(`[coder]`)} steered follow-up into running task ${E.cyan(t)}.\n`:`${E.dim(`[coder]`)} resumed task ${E.cyan(t)} with the follow-up (same thread, same id).\n`),G.stdout.write(`\n${E.dim(` result: coder task result ${t}`)}\n`);return}let a=g(e,t),o=a?await T(e,a):null,s=D(q.join(i(e,t),`result.json`));r.json?H({taskId:t,status:o?.status??null,finalMessage:s?.finalMessage??null}):(G.stdout.write(`\n${s?.finalMessage||`(no final message)`}\n\n`),G.stderr.write(`${E.dim(`[coder] task=${t} status=${o?.status??`unknown`}`)}\n`)),G.exitCode=o?.status===`completed`?0:1}const it=[`Read`,`Glob`,`Grep`];function at(e,t,n){return`You are a read-only sidecar answering a question ABOUT a coder task.
5
+ You are not the task: never continue, redo, or fix its work — only answer the question. The task never sees this question or your answer.
6
+
7
+ Task metadata:
8
+ ${[`id: ${e.id}`,...e.name?[`name: ${e.name}`]:[],`status: ${e.status}`,`agent: ${e.agent}${e.model?`/${e.model}`:``}${e.effort?`/${e.effort}`:``}`,...e.cwd?[`workspace: ${e.cwd}`]:[],...e.createdAt?[`created: ${e.createdAt}`]:[],...e.completedAt?[`finished: ${e.completedAt}`]:[]].join(`
9
+ `)}
10
+
11
+ Task prompt:
12
+ ${e.prompt??`(unknown)`}
13
+
14
+ Inspect as needed (grep/read selectively; events can be large):
15
+ - progress log (jsonl, one event per line): ${q.join(t,`log.jsonl`)}
16
+ - final result: ${q.join(t,`result.json`)}
17
+ - worker output: ${q.join(t,`worker.log`)}
18
+ ${e.cwd?`- the task's workspace (its code and changes): ${e.cwd}`:``}
19
+
20
+ Question: ${n}
21
+
22
+ Answer the question directly and concisely.`}function ot(e,t,n,r){return{prompt:n,model:r.model??e.model,effort:r.effort,permissions:`read-only`,additionalDirectories:[t],readOnlyAllowedTools:it}}async function st(e,t,n,r={}){let a=i(e,t.id),o=at(t,a,n),s=r.effort??t.effort??null;if(t.engine===`claude`)return he(t.cwd??e,ot(t,a,o,{model:r.model,effort:s}));let c=F(e),l=r.model??t.model,u=l?c.models?.[l]:void 0,d=u&&V(u)?u:void 0;if(d?.envKey&&!G.env[d.envKey])throw Error(`Missing environment variable: \`${d.envKey}\`.`);let f=d?await Je(d,d.wireApi??`chat`):null,p=Ne(c,l,f??void 0);try{return await Ie(t.cwd??e,{prompt:o,model:p?.model??Ce(l??null),modelProvider:p?.modelProvider??null,configOverrides:p?.configOverrides??null,effort:s,sandbox:`read-only`,approvalPolicy:`never`,ephemeral:!0})}finally{await f?.close()}}async function ct(e){let{options:t,positionals:n}=v(e,J.object({...b,model:C,effort:C})),r=N(t),[i,...a]=n,o=a.join(` `).trim();(!i||!o)&&k(`Missing task id or question.`,{hint:[`Usage: coder task ask <task-id> "<question>"`,`Help: coder task ask --help`]});let s=I(r,i);t.json||G.stderr.write(`${E.dim(`[coder]`)} asking about task ${E.cyan(s.id)} (read-only sidecar; the task is not interrupted)...\n`);let c=await st(r,s,o,{model:t.model,effort:t.effort}),l=c.finalMessage||``;if(t.json)H({taskId:s.id,answer:l||null,...c.error?{error:c.error.message}:{}});else if(l)G.stdout.write(`\n${l}\n`);else{let e=c.error?.message?` ${E.red(c.error.message)}`:``;G.stdout.write(`${E.dim(`(no answer)`)}${e}\n`)}G.exitCode=c.status===0?0:1}function lt(e,n={}){let i=n.limit===`all`?void 0:n.limit,s=e=>r.includes(e.status),c=[],l=o(e).filter(t=>{if(!s(t))return!0;let n=t.completedAt??t.updatedAt??t.createdAt;return Re(n)<=6e5||(_(e,t),c.push(t.id),!1)});if(Oe(e,c),n.archived?l=t(e):n.running?l=l.filter(e=>u.includes(e.status)):n.stopped&&(l=l.filter(s)),n.dir){let e=a(q.resolve(String(n.dir)));l=l.filter(t=>t.cwd&&a(t.cwd)===e)}if(!n.archived&&!n.running&&!n.stopped){let e=e=>e.status===`failed`?0:u.includes(e.status)?1:e.status===`completed`?3:2;l=[...l].sort((t,n)=>e(t)-e(n))}let d=i===void 0?0:Math.max(0,l.length-i);return i!==void 0&&(l=l.slice(0,i)),{jobs:l,clipped:d}}async function ut(e){let{options:r,positionals:a}=v(e,J.object({cwd:C,dir:C,limit:f,json:S,running:S,stopped:S,archived:S}));B(a,0,`task list`);let o=N(r),s=r.limit===`all`?void 0:r.limit,{jobs:c,clipped:l}=lt(o,{running:r.running,stopped:r.stopped,archived:r.archived,dir:r.dir??r.cwd,limit:r.limit}),d=c.map(e=>{let t=u.includes(e.status)?ee(i(o,e.id)).filter(e=>!e.response).length:0;return{taskId:e.id,status:t?`waiting-approval`:e.status,pendingApprovals:t,agent:e.agent??null,model:e.model??null,effort:e.effort??null,name:e.name??null,cwd:e.cwd??null,prompt:String(e.prompt??``).replace(/\s+/g,` `).trim().slice(0,80),updatedAt:e.updatedAt,archived:e.archived??!1,flowRunId:e.flowRunId??null,idleMs:u.includes(e.status)?Re(n(o,e)):null}});if(r.json){H(d);return}if(!d.length){let e=r.archived?`archived tasks`:r.running?`running tasks`:r.stopped?`recently stopped tasks`:`recent tasks`;G.stdout.write(`No ${e}.\n`);let n=[];if(!r.archived){let e=t(o,{migrate:!1}).length;e&&n.push(`${e} archived: coder task list --archived [--limit N]`)}n.length&&G.stdout.write(`\n${A(n,E)}\n`);return}let p=E,m=e=>(e.agent===`custom`&&e.model?e.model:(e.agent??`-`)+(e.model?`/${e.model}`:``))+(e.effort?`/${e.effort}`:``),h=e=>e.cwd?q.basename(e.cwd):`-`,g=(e,t,n)=>Math.min(t,Math.max(e,...n.map(e=>e.length))),_={id:g(7,28,d.map(e=>e.taskId)),status:g(6,16,d.map(e=>e.status)),who:g(5,26,d.map(m)),cwd:g(3,24,d.map(h))},y=e=>{let t=e.archived?` ${p.dim(`(archived)`)}`:``,n=e.name?e.name:p.light(e.prompt),r=e.idleMs!==null&&e.idleMs>=12e4?` ${(e.idleMs>6e5?p.red:p.dim)(`· idle ${pe(e.idleMs)}`)}`:``;G.stdout.write(`${p.cyan(e.taskId.padEnd(_.id))} ${xe(e.status,_.status)} ${p.light(de(m(e),_.who))} ${p.light(de(h(e),_.cwd))} ${n}${r}${t}\n`)};G.stdout.write(p.bold(p.light(`${`task-id`.padEnd(_.id)} ${`status`.padEnd(_.status)} ${`agent`.padEnd(_.who)} ${`cwd`.padEnd(_.cwd)} name\n`)));let b=new Map;for(let e of d)e.flowRunId&&(b.get(e.flowRunId)??b.set(e.flowRunId,[]).get(e.flowRunId)).push(e);let x=new Set,w=!1,T=!1;for(let e of d){if(!e.flowRunId){T&&G.stdout.write(`
23
+ `),y(e),w=!0,T=!1;continue}if(x.has(e.flowRunId))continue;x.add(e.flowRunId);let t=we(e.flowRunId),n=t?`(${p.bold(e.flowRunId)} ${t.status} — flow ${t.name})`:`(${p.bold(e.flowRunId)} flow)`;G.stdout.write(`${w?`
24
+ `:``}${n}\n`);for(let t of b.get(e.flowRunId))y(t);w=!0,T=!0}l&&G.stdout.write(p.dim(`\n... ${l} more not shown (--limit ${s})\n`));let D=[`Result: coder task result <task-id>`];r.archived||D.push(`Older tasks: coder task list --archived [--limit N]`),G.stdout.write(`\n${A(D,p)}\n`)}function dt(){let e=process.env.CLAUDE_CONFIG_DIR||q.join(Be.homedir(),`.claude`);return q.join(e,`projects`)}function ft(e){if(!e)return!1;let t=dt(),n=!1;try{for(let r of K.readdirSync(t)){let i=q.join(t,r,`${e}.jsonl`);K.existsSync(i)&&(K.rmSync(i,{force:!0}),n=!0)}}catch{}return n}function Y(e){e.threadId&&(e.engine===`codex`?l(e.threadId):e.engine===`claude`&&ft(e.threadId))}async function pt(e){let{options:n,positionals:r}=v(e,J.object({...b,"all-archived":S}));B(r,1,`task delete`);let i=N(n);if(n[`all-archived`]){let e=t(i).filter(e=>(Y(e),w(i,e.id))).map(e=>e.id);if(n.json){H({deleted:e,count:e.length});return}G.stdout.write(e.length?`Deleted ${e.length} archived task${e.length===1?``:`s`}.\n`:`${E.dim(`No archived tasks to delete.`)}\n`);return}let a=r[0];a||k(`Missing task id.`,{hint:[`Delete one: coder task delete <task-id>`,`Delete all archived: coder task delete --all-archived`]});let o=I(i,a);if(o.status===`running`&&k(`Task ${o.id} is still running.`,{hint:`Stop it first: coder task stop ${o.id}`}),Y(o),w(i,o.id),n.json){H({taskId:o.id,deleted:!0});return}G.stdout.write(`Deleted task ${E.cyan(o.id)}.\n`)}function X(e,t){return t.split(`.`).reduce((e,t)=>e?.[t],e)}function mt(e,t){return t?q.join(a(e),`coder.config.json`):R()}function ht(e,t){let n=F(e);return t?X(n,t):n}function gt(e,t,n,r={}){let i=mt(e,r.workspace),a=K.existsSync(i)?JSON.parse(K.readFileSync(i,`utf8`)):{},o=t.split(`.`),s=o.at(-1),c=a;for(let e of o.slice(0,-1))(typeof c[e]!=`object`||c[e]===null)&&(c[e]={}),c=c[e];r.unset?delete c[s]:c[s]=n;let l=Ee(a);if(l.length)throw Error(`Refusing to write invalid config:\n ${l.join(`
25
+ `)}`);return K.mkdirSync(q.dirname(i),{recursive:!0}),K.writeFileSync(i,`${JSON.stringify(a,null,2)}\n`,`utf8`),{file:i,key:t,effective:X(F(e),t)??null,...r.unset?{unset:!0}:{value:n}}}async function _t(e){let{options:t,positionals:n}=v(e,J.object({...b,workspace:S})),r=N(t),[i=`list`,a,...o]=n,s=mt(r,t.workspace);if(i===`list`){let e=F(r);if(t.json){H(e);return}let n=E,i=e=>[e?.model,e?.effort,e?.permissions].filter(Boolean).join(`/`)||`-`;G.stdout.write([`${n.dim(`chain`)} ${e.chain.join(` -> `)}`,`${n.dim(`codex`)} ${i(e.agents.codex)}`,`${n.dim(`claude`)} ${i(e.agents.claude)}`,`${n.dim(`approvals`)} timeout=${e.approvals.escalationTimeoutMs}ms hosts=[${e.approvals.allowedNetworkHosts.join(`, `)}]`,`${n.dim(`file`)} ${R()}`].join(`
26
+ `)+`
27
+ `);return}if(i===`get`){a||k(`Usage: coder config get <key> (e.g. chain, agents.codex.model)`);let e=X(F(r),a);if(t.json||e===null||typeof e==`object`&&e!==void 0){H(e===void 0?null:e);return}G.stdout.write(`${e===void 0?`(unset)`:String(e)}\n`);return}i!==`set`&&i!==`unset`&&k(`Usage: coder config [get|set|unset] <key> [value] [--workspace]`),(!a||i===`set`&&o.length===0)&&k(`Usage: coder config ${i} <key>${i===`set`?` <value>`:``}`);let c=o.join(` `),l;try{l=JSON.parse(c)}catch{l=c.includes(`,`)?c.split(`,`).map(e=>e.trim()).filter(Boolean):c}let u;try{({effective:u}=gt(r,a,l,{workspace:t.workspace,unset:i===`unset`}))}catch(e){k(e instanceof Error?e.message:String(e))}if(t.json){H({file:s,key:a,...i===`set`?{value:l}:{unset:!0},effective:u});return}let d=E,f=i===`set`?`${d.cyan(a)} = ${JSON.stringify(l)}`:`unset ${d.cyan(a)}`;G.stdout.write(`${f} ${d.dim(`(${s})`)}\n`)}async function vt(e,t={}){let n=W(e),r=ce(n);r?.updated&&(n=W(e));let i=n.available?await ye(e):{loggedIn:!1,detail:n.detail},a=ie(),o=a.available?Pe():{loggedIn:!1,detail:a.detail},s=R();if(!K.existsSync(s)){let e=n.available?[`codex`,`claude`]:a.available?[`claude`,`codex`]:[`codex`,`claude`];Te({...Me,chain:e})}let c=h(),l=t.claude?te(c):null,u=t.agents||t.codex?fe(c):null,d=F(e),f=n.available&&i.loggedIn||a.available&&o.loggedIn;return{codex:{available:n.available,detail:n.detail,auth:i.detail,loggedIn:i.loggedIn},...r?{codexUpdate:r}:{},claude:{available:a.available,detail:a.detail,auth:o.detail,loggedIn:o.loggedIn},configFile:s,runtime:Ve(new URL(`../bin/coder.mjs`,import.meta.url)),...l?{claudePlugin:l}:{},...u?{agentsSkill:u}:{},config:d,ready:f}}async function yt(e){let{options:t,positionals:n}=v(e,J.object({...b,codex:S,claude:S,agents:S})),r=N(t),i=[`claude`,`codex`,`agents`];for(let e of n)i.includes(e)||k(`Unknown host "${e}". Use claude, codex, or agents.`,{hint:`Codex, Pi, OpenCode, and other Agent Skills hosts: coder setup-host agents`}),t[e]=!0;let a=E.bold,o=E.dim;t.json||G.stdout.write(`${a(`Coder host setup`)}\n\n`);let s=await vt(r,{claude:t.claude,codex:t.codex,agents:t.agents});if(t.json){H(s);return}let{codex:c,claude:l,codexUpdate:u,config:d,configFile:f,claudePlugin:p,agentsSkill:m,ready:h}=s,g=[],_=c.available?c.loggedIn?M(`codex ${o(`${c.detail}; ${c.auth}`)}`):O(`codex not logged in ${o(`(${c.auth})`)} - run: codex login`):O(`codex CLI not installed - run: npm install -g @openai/codex`),y=l.available?l.loggedIn?M(`claude ${o(`${l.detail}; ${l.auth}`)}`):O(`claude not logged in - run: claude auth login`):O(`claude CLI not installed - run: npm install -g @anthropic-ai/claude-code`);g.push(a(`Available Engines`),_,y,` ${o(`custom models (local/provider endpoints): coder model --help`)}`),u?.updated?g.push(M(`codex ${o(`updated ${u.from} -> ${c.detail} (GPT-5.6 support)`)}`)):u&&g.push(O(`codex ${u.note}`)),g.push(``);let x=e=>{let t=d.agents?.[e]??{};return[t.model,t.effort,t.permissions].filter(Boolean).join(`/`)};g.push(a(`Config`),` chain: ${(d.chain??[]).join(` -> `)} codex: ${x(`codex`)} claude: ${x(`claude`)}`,` ${o(f)} ${o(`(coder config set <key> <value> to change)`)}`,``);let C=[[`claude plugin`,p??null],[`agents skill `,m??null]];for(let[e,t]of C)t&&g.push(t.installed?M(`${e} ${o(t.note)}`):O(`${e} ${t.note}`),``);g.push(h?M(`ready - try: coder run --wait "explain this repo's layout"`):O(`not ready - install an engine CLI to run tasks: codex (npm install -g @openai/codex, then codex login) or claude (npm install -g @anthropic-ai/claude-code, then claude auth login)`)),G.stdout.write(`${g.join(`
28
+ `)}\n`)}const bt=new Set([`codex`,`claude`,`custom`]);async function xt(e){let t=e.envKey?G.env[e.envKey]:void 0,n=De(e.baseUrl,`models`),r=null;for(let i of n)try{let n=await fetch(i,{headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(5e3)});if(!n.ok){r=n.status===404?{reachable:!0,modelListed:null,detail:`endpoint reachable (no model list to verify against)`}:{reachable:!1,modelListed:null,detail:`${i} -> HTTP ${n.status}`};continue}let a=await n.json().catch(()=>null),o=Array.isArray(a?.data)?a.data.map(e=>e.id):null;if(!o)return{reachable:!0,modelListed:null,detail:`endpoint reachable`};let s=o.includes(e.model);return{reachable:!0,modelListed:s,detail:s?`endpoint reachable; model "${e.model}" listed`:`endpoint reachable, but "${e.model}" is not in its model list`}}catch(e){r={reachable:!1,modelListed:null,detail:`${i} unreachable (${e instanceof Error?e.message:String(e)})`}}return r}function St(e,t){let n=K.existsSync(e)?JSON.parse(K.readFileSync(e,`utf8`)):{};t(n),n.models&&Object.keys(n.models).length===0&&delete n.models;let r=Ee(n);r.length&&k(`Refusing to write invalid config:\n ${r.join(`
29
+ `)}`),K.mkdirSync(q.dirname(e),{recursive:!0}),K.writeFileSync(e,`${JSON.stringify(n,null,2)}\n`,`utf8`)}function Z(e,t){St(e,e=>{e.models=e.models??{},t(e.models)})}const Q=J.object({...b,"base-url":C,model:C,"env-key":C,workspace:S});function $(e,t){return e.workspace?q.join(a(t),`coder.config.json`):R()}function Ct(e){let t=e.models??{},n=Object.entries(t).filter(e=>V(e[1])),r=e=>`${e.provider}:${e.model}${e.effort?`:${e.effort}`:``}`,i=Object.entries(t).filter(e=>P(e[1])).map(([e,t])=>{let n=t.provider===`claude`?j:U,i=n[t.model]??t.model,a=z(e)?e:Object.entries(n).find(([,e])=>e===i)?.[0];return{name:e,spec:r(t),replaces:a,disabled:!!t.disabled}}),a=new Map;for(let e of i)e.replaces&&(e.name===e.replaces||!a.has(e.replaces))&&a.get(e.replaces)?.name!==e.replaces&&a.set(e.replaces,e);let o=e=>!!t[e]?.disabled,s=i.filter(e=>![...a.values()].some(t=>t.name===e.name));return{models:t,endpoints:n,providerRows:(e,t)=>[...Object.entries(t).map(([e,t])=>{let n=a.get(e);return n?{alias:n.name,spec:n.spec,overrides:e,disabled:n.disabled}:{alias:e,model:t,builtin:!0,disabled:o(e)}}),...s.filter(t=>t.spec.startsWith(`${e}:`)).map(({name:e,spec:t,disabled:n})=>({alias:e,spec:t,disabled:n}))],toggledSlugs:Object.entries(t).filter(([e,t])=>!V(t)&&!P(t)&&!z(e)).map(([e,t])=>({name:e,disabled:!!t.disabled})),disabled:o}}async function wt(e){let{endpoints:t,providerRows:n,toggledSlugs:r}=Ct(F(e)),i=await Promise.all(t.map(async([e,t])=>({name:e,...t,probe:await xt(t)})));return{codex:n(`codex`,U),claude:n(`claude`,j),custom:i,...r.length?{toggles:r}:{}}}async function Tt(e){let{options:t,positionals:n}=v(e,Q);n.length&&k(`model list takes no arguments.`,{hint:`Usage: coder model list [--json]`});let r=N(t),i=E,{endpoints:a,providerRows:o,toggledSlugs:s,disabled:c}=Ct(F(r));if(t.json){H(await wt(r));return}let l=e=>c(e)?i.dim(`∅`):i.green(`✔`),u=e=>c(e)?` ${i.dim(`(disabled)`)}`:``,d=[],f=(e,t,n)=>{d.push(i.bold(e));for(let e of o(t,n))`overrides`in e?d.push(` ${e.disabled?i.dim(`∅`):i.cyan(`↳`)} ${e.alias.padEnd(14)} ${i.dim(`-> ${e.spec} (overrides ${e.overrides})`)}${e.disabled?` ${i.dim(`(disabled)`)}`:``}`):`builtin`in e?d.push(` ${l(e.alias)} ${e.alias.padEnd(14)} ${i.dim(`-> ${e.model}`)}${u(e.alias)}`):d.push(` ${e.disabled?i.dim(`∅`):i.cyan(`↳`)} ${e.alias.padEnd(14)} ${i.dim(`-> ${e.spec}`)}${e.disabled?` ${i.dim(`(disabled)`)}`:``}`);d.push(``)};if(f(`Codex models`,`codex`,U),f(`Claude models`,`claude`,j),d.push(i.bold(`Custom models`),``),!a.length)d.push(i.dim(` none — coder model add <name> --base-url <url> --model <id> [--env-key VAR]`));else for(let[e,t]of a){let n=await xt(t),r=t.disabled?i.dim(`∅`):n.reachable?i.green(`✔`):i.red(`✘`);d.push(` ${r} ${e.padEnd(14)} ${t.model} ${i.dim(`@ ${t.baseUrl} — ${n.detail}`)}${u(e)}`)}if(d.push(``),s.length){d.push(i.bold(`Other`),``);for(let e of s)d.push(` ${e.disabled?i.dim(`∅`):i.green(`✔`)} ${e.name.padEnd(14)} ${i.dim(`raw model id`)}${e.disabled?` ${i.dim(`(disabled)`)}`:``}`);d.push(``)}d.push(i.dim(`Alias one: coder model alias <name> <spec> (e.g. fast codex:spark)`),i.dim(`Use one: coder run --model <name> "<task>" (or coder run --agent custom)`)),G.stdout.write(`${d.join(`
30
+ `)}\n`)}async function Et(e,t,n,r){let i=await Xe(t),a=i?.wireApi===`responses`;i?(t.wireApi=i.wireApi,t.baseUrl=i.baseUrl??t.baseUrl):delete t.wireApi,Z(n,n=>{n[e]=t});let o=await xt(t),s=re(W(r)),c=W(r);return{name:e,entry:t,file:n,probe:o,codex:c,install:s,nativeResponses:a,keyMissing:!!(t.envKey&&!G.env[t.envKey]),ready:o.reachable&&c.available}}async function Dt(e,t,n,r,i){let a=$(n,r),o=E,{probe:s,codex:c,install:l,nativeResponses:u,keyMissing:d}=await Et(e,t,a,r);if(n.json){H({name:e,...t,file:a,probe:s,codex:c,...l?{codexInstall:l}:{},ready:s.reachable&&c.available});return}let f=e=>` ${o.green(`✔`)} ${e}`,p=e=>` ${o.red(`✘`)} ${e}`,m=[`${i} ${o.cyan(e)} -> ${t.model} @ ${t.baseUrl} ${o.dim(`(${a})`)}`,``,s.reachable?f(`${s.detail} ${o.dim(`(${u?`responses api, direct`:`chat api, auto-translated`})`)}`):p(s.detail),c.available?f(l?.installed?`${l.note} ${o.dim(`(${c.detail})`)}`:`codex engine ${o.dim(`(${c.detail})`)}`):p(l?.note??`codex CLI not installed - run: npm install -g @openai/codex`)];d&&m.push(p(`env var ${t.envKey} is not set in this shell`)),m.push(``,o.dim([`Use it: coder run --model ${e} "<task>"`,`Make default: coder config set agents.custom.model ${e}`].join(`
31
+ `))),G.stdout.write(`${m.join(`
32
+ `)}\n`)}function Ot(e,t,n){return e||k(`Missing model name.`,{hint:t}),/^[a-z][a-z0-9-]*$/.test(e)||k(`Invalid model name "${e}". Use lowercase kebab-case (e.g. qwen-local).`),(bt.has(e)||n===`model`&&z(e))&&k(`"${e}" is reserved; pick another name.`),e}async function kt(e){let t=`Usage: coder model add <name> --base-url <url> --model <id> [--env-key VAR]`,{options:n,positionals:r}=v(e,Q),i=N(n),a=Ot(r[0],t,`model`),o=F(i).models?.[a];o&&k(V(o)?`Custom model "${a}" already exists.`:`"${a}" is already configured as an ${P(o)?`alias`:`entry`}; remove it first.`,{hint:`Change it: coder model update ${a} [--base-url|--model|--env-key], or remove it first.`}),(!n[`base-url`]||!n.model)&&k(`Missing --base-url or --model.`,{hint:t}),await Dt(a,{baseUrl:L(n[`base-url`]),model:n.model,...n[`env-key`]?{envKey:n[`env-key`]}:{}},n,i,`saved`)}async function At(e){let t=`Usage: coder model update <name> [--base-url <url>] [--model <id>] [--env-key VAR]`,{options:n,positionals:r}=v(e,Q),i=N(n),a=r[0],o=a?F(i).models?.[a]:void 0,s=o&&V(o)?o:void 0;(!a||!s)&&k(a?`No custom model named "${a}".`:`Missing model name.`,{hint:a?`List them: coder model list`:t}),!n[`base-url`]&&!n.model&&!n[`env-key`]&&k(`Nothing to update: pass --base-url, --model, or --env-key.`,{hint:t}),await Dt(a,{...s,...n[`base-url`]?{baseUrl:L(n[`base-url`])}:{},...n.model?{model:n.model}:{},...n[`env-key`]?{envKey:n[`env-key`]}:{}},n,i,`updated`)}async function jt(e){let{options:t,positionals:n}=v(e,Q),r=N(t),i=n[0],a;try{a=Bt(r,i??``,{workspace:t.workspace})}catch(e){k(e instanceof Error?e.message:String(e),{hint:i?`List them: coder model list`:`Usage: coder model remove <name>`})}if(t.json){H(a);return}G.stdout.write(`removed ${E.cyan(a.removed)} ${E.dim(`(${a.file})`)}\n`)}async function Mt(e){await Pt(e,!0)}async function Nt(e){await Pt(e,!1)}async function Pt(e,t){let n=t?`disable`:`enable`,r=`Usage: coder model ${n} <name>`,{options:i,positionals:a}=v(e,Q),o=N(i),s=a[0];s||k(`Missing model name.`,{hint:r});let{file:c}=Ut(o,s,t,{workspace:i.workspace});if(i.json){H({[t?`disabled`:`enabled`]:s,file:c});return}G.stdout.write(`${n}d ${E.cyan(s)} ${E.dim(`(${c})`)}\n`)}async function Ft(e){let t=`Usage: coder model alias <name> <spec> (e.g. coder model alias fast codex:spark)`,{options:n,positionals:r}=v(e,Q),i=N(n),a=Ot(r[0],t,`alias`),o=F(i).models?.[a];o&&V(o)&&k(`"${a}" is a custom model name; pick another alias name.`);let s=r[1];s||k(`Missing alias spec.`,{hint:t});let c;try{c=Vt(i,a,s,{workspace:n.workspace})}catch(e){let n=e instanceof Error?e.message:String(e);k(n,n.includes(`already dispatchable by name`)?{}:{hint:t})}if(n.json){H(c);return}let l=E,u=`${c.provider} ${c.model}${c.effort?` (${c.effort})`:``}`;G.stdout.write(`aliased ${l.cyan(a)} -> ${c.provider}:${c.model}${c.effort?`:${c.effort}`:``} ${l.dim(`= ${u}`)} ${l.dim(`(${c.file})`)}\n`)}async function It(e){let{options:t,positionals:n}=v(e,Q),r=N(t),i=n[0],a=i?F(r).models?.[i]:void 0;(!i||!a||!P(a))&&k(i?`No alias named "${i}".`:`Missing alias name.`,{hint:i?`List them: coder model list`:`Usage: coder model unalias <name>`});let{file:o}=Ht(r,i,{workspace:t.workspace});if(t.json){H({unaliased:i,file:o});return}G.stdout.write(`unaliased ${E.cyan(i)} ${E.dim(`(${o})`)}\n`)}function Lt(e,t){if(!e)throw Error(`Missing model name.`);if(!/^[a-z][a-z0-9-]*$/.test(e))throw Error(`Invalid model name "${e}". Use lowercase kebab-case (e.g. qwen-local).`);if(bt.has(e)||t===`model`&&z(e))throw Error(`"${e}" is reserved; pick another name.`)}async function Rt(e,t,n){if(Lt(t,`model`),F(e).models?.[t])throw Error(`Custom model "${t}" already exists.`);if(!n.baseUrl||!n.model)throw Error(`Missing baseUrl or model.`);return Et(t,{baseUrl:L(n.baseUrl),model:n.model,...n.envKey?{envKey:n.envKey}:{}},$({workspace:n.workspace},e),e)}async function zt(e,t,n){let r=F(e).models?.[t],i=r&&V(r)?r:void 0;if(!i)throw Error(`No custom model named "${t}".`);if(!n.baseUrl&&!n.model&&!n.envKey)throw Error(`Nothing to update: pass baseUrl, model, or envKey.`);return Et(t,{...i,...n.baseUrl?{baseUrl:L(n.baseUrl)}:{},...n.model?{model:n.model}:{},...n.envKey?{envKey:n.envKey}:{}},$({workspace:n.workspace},e),e)}function Bt(e,t,n={}){if(!t||!F(e).models?.[t])throw Error(t?`No custom model named "${t}".`:`Missing model name.`);let r=$({workspace:n.workspace},e);return Z(r,e=>{delete e[t]}),{removed:t,file:r}}function Vt(e,t,n,r={}){Lt(t,`alias`);let i=F(e),a=i.models?.[t];if(a&&V(a))throw Error(`"${t}" is a custom model name; pick another alias name.`);if(!n)throw Error(`Missing alias spec.`);let o=Fe(n,i);if(!o||!o.model)throw Error(`Alias spec "${n}" does not resolve to a model.`);if(o.agent===`custom`)throw Error(`"${n}" names a custom model, which is already dispatchable by name; aliases target codex/claude models.`);let s=n.split(`:`).some(e=>Se.has(e.trim())||_e.has(e.trim())),c=o.agent===`claude`?j:U,l={provider:o.agent,model:c[o.model]??o.model,...s&&o.effort?{effort:o.effort}:{}},u=$({workspace:r.workspace},e);return Z(u,e=>{e[t]=l}),{alias:t,...l,file:u}}function Ht(e,t,n={}){let r=t?F(e).models?.[t]:void 0;if(!t||!r||!P(r))throw Error(t?`No alias named "${t}".`:`Missing alias name.`);let i=$({workspace:n.workspace},e);return Z(i,e=>{delete e[t]}),{unaliased:t,file:i}}function Ut(e,t,n,r={}){if(!t)throw Error(`Missing model name.`);let i=!!F(e).models?.[t],a=$({workspace:r.workspace},e);return Z(a,e=>{let r=e[t];if(!r){n?e[t]={disabled:!0}:i&&(e[t]={disabled:!1});return}V(r)||P(r)?n?r.disabled=!0:delete r.disabled:n?r.disabled=!0:delete e[t]}),{name:t,disabled:n,file:a}}const Wt={list:Tt,add:kt,setup:kt,update:At,remove:jt,disable:Mt,enable:Nt,alias:Ft,unalias:It};async function Gt(e){let[t,...n]=e;if(t===void 0||t.startsWith(`-`)){await Tt(e);return}let r=Wt[t];r||k(`Unknown model subcommand "${t}". Use list, add, update, remove, disable, enable, alias, or unalias.`,{hint:`Help: coder model --help`}),await r(n)}const Kt=[{name:`readme`,file:`README.md`,description:`What Coder is and how to get started.`},{name:`skill`,file:`plugins/agents/skills/coder/SKILL.md`,description:`How a host agent should drive Coder.`}];function qt(e){let t=q.join(e,`docs`),n=[];try{n=K.readdirSync(t).filter(e=>e.endsWith(`.md`)).sort()}catch{n=[]}let r=n.map(t=>{let n=q.join(`docs`,t);return{name:q.basename(t,`.md`),file:n,description:Jt(q.join(e,n))}}),i=Kt.map(e=>({name:e.name,file:e.file,description:e.description}));return[...r,...i]}function Jt(e){let t=``;try{t=K.readFileSync(e,`utf8`)}catch{return``}let n=t.split(`
33
+ `),r=``,i=``,a=!1;for(let e of n){let t=e.trim();if(t.startsWith("```")){a=!a;continue}if(!(a||t===``)){if(t.startsWith(`#`)){r||=t.replace(/^#+\s*/,``);continue}i=t;break}}return Yt(i)||r}function Yt(e){if(!e)return``;let t=e.match(/^.*?[.!?](?=\s|$)/);return(t?t[0]:e).trim()}function Xt(e,t={}){let n=h(),r=qt(n);if(!e)return{topics:r.map(e=>({name:e.name,description:e.description}))};let i=r.find(t=>t.name===e.toLowerCase());if(i?.name===`skill`&&t.claude&&(i={...i,file:`plugins/claude/skills/dispatch/SKILL.md`}),!i)throw Error(`Unknown docs topic "${e}". Available: ${r.map(e=>e.name).join(`, `)}`);let a=q.join(n,i.file),o;try{o=K.readFileSync(a,`utf8`)}catch{throw Error(`Could not read docs for "${i.name}" (${i.file}).`)}return{name:i.name,content:o}}async function Zt(e){let{options:t,positionals:n}=v(e,J.object({json:S,claude:S})),[r]=n,i;try{i=Xt(r,{claude:t.claude})}catch(e){let t=e instanceof Error?e.message:String(e);return k(t,t.startsWith(`Unknown docs topic`)?{hint:`List topics: coder docs`}:{})}if(`content`in i){G.stdout.write(i.content.endsWith(`
34
+ `)?i.content:`${i.content}\n`);return}if(t.json){H(i);return}let a=E,o=Math.max(0,...i.topics.map(e=>e.name.length)),s=i.topics.map(e=>` ${a.cyan(e.name.padEnd(o))} ${a.dim(e.description)}`);G.stdout.write([a.bold(`Docs:`),...s,``,A([`Read a topic: coder docs <topic>`],a)].join(`
35
+ `)+`
36
+ `)}async function Qt(e={},t){let n=!e.pluginsOnly,r=!e.cliOnly,i=h(),a=q.join(i,`plugins/claude/.claude-plugin/plugin.json`),o={cli:y(),claude:x(a)},s={};if(n){let n=se(m),[r,...i]=e.pm===`npm`?[`npm`,`install`,`-g`,`@wular/coder@latest`]:e.pm===`pnpm`?[`pnpm`,`add`,`-g`,`@wular/coder@latest`]:e.pm===`yarn`?[`yarn`,`global`,`add`,`@wular/coder@latest`]:e.pm===`bun`?[`bun`,`add`,`-g`,`@wular/coder@latest`]:n.command,a=e.pm??n.pm;t?.(`via ${a}`);let c=ze(r,i,{encoding:`utf8`});if(c.error?.code===`ENOENT`)throw Error(`${a} not found on PATH. Re-run with --pm <npm|pnpm|yarn|bun>, or update manually: ${r} ${i.join(` `)}`);if(c.status!==0){let e=(c.stderr||c.stdout||``).trim();throw Error(`CLI update failed (${a}).${e?`\n${e}`:``}\nRun manually: ${r} ${i.join(` `)}`)}oe();let l=y();s.cli={pm:a,from:o.cli,to:l,changed:l!==o.cli}}if(r){if(e.claude||!e.codex&&ie().available){let e=te(i);s.claudePlugin={installed:e.installed,note:e.note,from:o.claude,to:x(a)}}if(K.existsSync(ue())){let e=ae(),t=fe(i);s.agentsSkill={installed:t.installed,note:t.note,from:e,to:ae()}}}return s}async function $t(e){let{options:t}=v(e,J.object({pm:C,"cli-only":S,"plugins-only":S,codex:S,claude:S})),n=E.bold,r=E.dim,i=(e,t)=>t&&e&&t!==e?`${e} ${r(`->`)} ${n(t)}`:`${t??e??`?`} ${r(`(unchanged)`)}`,a;try{a=await Qt({cliOnly:t[`cli-only`],pluginsOnly:t[`plugins-only`],pm:t.pm,codex:t.codex,claude:t.claude},e=>G.stdout.write(`${n(`Updating coder CLI`)} ${r(`${e}...`)}\n`))}catch(e){k(e instanceof Error?e.message:String(e))}if(a.cli&&G.stdout.write(a.cli.changed?`${M(`coder CLI ${i(a.cli.from,a.cli.to)}`)}\n`:`${M(`coder CLI ${a.cli.from} ${r(`(already latest)`)}`)}\n`),a.claudePlugin){let e=a.claudePlugin;G.stdout.write(`${e.installed?M(`claude plugin ${i(e.from,e.to)} ${r(`- ${e.note}`)}`):O(`claude plugin ${e.note}`)}\n`)}if(a.agentsSkill){let e=a.agentsSkill;G.stdout.write(`${e.installed?M(`agents skill ${i(e.from,e.to)} ${r(`- ${e.note}`)}`):O(`agents skill ${e.note}`)}\n`)}}export{ct as C,Ze as D,Qe as E,Xe as O,st as S,et as T,gt as _,Gt as a,lt as b,wt as c,Ht as d,zt as f,ht as g,_t as h,Xt as i,Je as k,Bt as l,vt as m,Qt as n,Rt as o,yt as p,Zt as r,Vt as s,$t as t,Ut as u,pt as v,nt as w,ut as x,Y as y};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wular/coder",
3
- "version": "0.3.13",
3
+ "version": "0.3.15",
4
4
  "description": "Delegating coding-agent runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/sdk.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coder",
3
- "version": "0.3.13",
3
+ "version": "0.3.15",
4
4
  "description": "Delegate coding tasks to supervised Coder subagents running on Codex, Claude, or any OpenAI-compatible model. Your main context stays clean.",
5
5
  "author": {
6
6
  "name": "muzam1l"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "coder",
3
3
  "displayName": "Coder",
4
- "version": "0.3.13",
4
+ "version": "0.3.15",
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"
@@ -1,18 +0,0 @@
1
- import{A as e,B as t,C as n,F as r,G as i,H as a,I as o,L as s,M as c,N as l,O as u,P as d,T as f,W as p,f as ee,i as m,j as h,l as te,m as g,o as _,r as v,s as ne,u as re,v as ie,w as ae,y as oe}from"./app-server-bHl6RBZ2.js";import{createRequire as se}from"node:module";import y from"node:process";import b from"node:fs";import x from"node:path";import{spawn as S,spawnSync as C}from"node:child_process";import ce from"node:os";import{fileURLToPath as le,pathToFileURL as ue}from"node:url";import*as w from"zod/mini";import de from"node:net";import fe,{randomUUID as pe}from"node:crypto";import{AsyncLocalStorage as me}from"node:async_hooks";function he(e){let t=y.env.FORCE_COLOR,n=t!=null&&t!==``&&t!==`0`||t!==`0`&&e.isTTY&&!y.env.NO_COLOR,r=(e,t)=>n?`\x1b[${e}m${t}\x1b[0m`:t;return{blue:e=>r(`34`,e),bold:e=>r(`1`,e),cyan:e=>r(`36`,e),dim:e=>r(`38;5;246`,e),light:e=>r(`38;5;249`,e),green:e=>r(`32`,e),red:e=>r(`31`,e),yellow:e=>r(`33`,e)}}const T=he(y.stdout),E=he(y.stderr);function ge(e,t=E){let n=e.map(e=>{let t=e.indexOf(`coder `);return t===-1?{label:e,cmd:``}:{label:e.slice(0,t),cmd:e.slice(t)}}),r=Math.max(0,...n.map(e=>e.label.length));return n.map(({label:e,cmd:n})=>n?` ${t.dim(e.padEnd(r))}${t.bold(n)}`:` ${t.dim(e)}`).join(`
2
- `)}function D(e,t={}){let n=typeof t==`number`?t:t.code??1,r=typeof t==`object`?t.hint:null,i=r==null?[]:Array.isArray(r)?r:[r];y.stderr.write(`${E.red(e)}\n`),i.length&&y.stderr.write(`\n${ge(i,E)}\n`),y.exit(n)}function O(e){y.stdout.write(`${JSON.stringify(e,null,2)}\n`)}function _e(e,t=T){return(JSON.stringify(e,null,2)??`null`).split(`
3
- `).map(e=>e.replace(/"((?:[^"\\]|\\.)*)":/g,(e,n)=>`${t.light(`"${n}"`)}:`).replace(/: (-?\d[\d.eE+-]*|true|false|null)(,?)$/,(e,n,r)=>`: ${t.blue(n)}${r}`)).join(`
4
- `)}function ve(e){let t=Date.parse(e??``);return Number.isFinite(t)?Math.max(0,Date.now()-t):0}function ye(e){let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m`:`${Math.floor(n/60)}h${n%60}m`}function k(e){return e<1e3?String(e):e<1e6?`${(e/1e3).toFixed(+(e<1e4))}k`:`${(e/1e6).toFixed(1)}M`}function be(e,t){let n=[`in ${k(e.input)}`,...e.cachedInput?[`cached ${k(e.cachedInput)}`]:[],`out ${k(e.output)}`];return`${k(e.total)} (${n.join(` · `)}) on ${t||`default model`}`}function xe(e,t,n,r=T){let i=e?.error?.message??t;return e?.finalMessage||(i?`${r.red(`error:`)} ${i}`:n)}function Se(e,t=T,{truncate:n=!0}={}){let r=e=>e.split(`
5
- `).map(e=>` ${t.dim(e)}`);return!n||e.length<=1e3?[t.dim(`prompt:`),...r(e)]:[t.dim(`prompt:`),...r(e.slice(0,500).trimEnd()),t.light(` … <${e.length-1e3} chars trimmed> …`),...r(e.slice(-500).trimStart())]}function Ce(e){return[e.agent??`-`,e.model,e.model?e.effort:null].filter(Boolean).join(`/`)}function we(e,t=T){let n=[];return e.permissions&&n.push([`perms`,e.permissions]),e.cwd&&n.push([`cwd`,e.cwd]),n.map(([e,n])=>`${t.dim(e.padEnd(8))} ${n}`)}function Te(e,t=300,{plain:n=!1,style:r=T}={}){if(e.length<=t)return e;let i=`<${e.length-t} more chars>`;return`${e.slice(0,t)} ${n?i:r.dim(i)}`}const Ee=6e5,De=12e4;function Oe(e,t){return e.length>t?`${e.slice(0,t-1)}…`:e.padEnd(t)}function ke(e){return` ${T.bold(T.green(`✔`))} ${e}`}function Ae(e){return` ${T.bold(T.red(`✘`))} ${e}`}function je(e=y.stdout){try{return e.getWindowSize?.()[0]??e.columns}catch{return e.columns}}function Me(e=y.stdout){try{return e.getWindowSize?.()[1]??e.rows}catch{return e.rows}}function Ne(e){return e>=768&&e<=879||e>=8203&&e<=8207||e>=65024&&e<=65039?0:e>=4352&&e<=4447||e>=11904&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65072&&e<=65103||e>=65280&&e<=65376||e>=65504&&e<=65510||e>=127744&&e<=129791||e>=131072&&e<=262141?2:1}function Pe(e){let t=0;for(let n of e.replace(/\x1b\[[0-9;]*m/g,``))t+=Ne(n.codePointAt(0));return t}function Fe(e,t){let n=0,r=``;for(let i=0;i<e.length;){let a=e[i]===`\x1B`?/^\x1b\[[0-9;]*m/.exec(e.slice(i)):null;if(a){r+=a[0],i+=a[0].length;continue}let o=e.codePointAt(i),s=String.fromCodePoint(o),c=Ne(o);if(n+c>t-1)return`${r}\x1b[0m${T.dim(`…`)}`;r+=s,n+=c,i+=s.length}return r}function Ie(){let e=y.stdin;if(!e.isTTY||!y.stdout.isTTY)return()=>{};e.setRawMode(!0),e.resume();let t=e=>{e.includes(3)&&y.kill(y.pid,`SIGINT`),e.includes(26)&&y.kill(y.pid,`SIGTSTP`)};return e.on(`data`,t),e.unref(),()=>{e.off(`data`,t),e.isTTY&&e.setRawMode(!1),e.pause()}}var Le=class{stream;quietMs;lines=[];painted=[];paintedWidths=[];paintedCols;resizeTimer;tty;constructor(e=y.stdout,t=250){this.stream=e,this.quietMs=t,this.tty=!!e.isTTY,this.tty&&e.on(`resize`,this.onResize)}set(e){this.lines=e,!(!this.tty||this.resizeTimer)&&this.paint()}commit(e){this.clear(),this.stream.write(e)}clear(){if(!this.painted.length)return;let e=je(this.stream),t=this.painted.length;e&&this.paintedCols&&e!==this.paintedCols&&(t=this.paintedWidths.reduce((t,n)=>t+Math.max(1,Math.ceil(n/e)),0)),this.stream.write(`\x1b[${t}A\x1b[0J`),this.painted=[],this.paintedWidths=[]}done(){this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=void 0,this.paint()),this.tty&&this.stream.off(`resize`,this.onResize)}paint(){this.clear();let e=je(this.stream),t=e?this.lines.map(t=>Fe(t,e-1)):this.lines,n=Me(this.stream);n&&t.length>n-1&&(t=n>1?t.slice(-(n-1)):[]);for(let e of t)this.stream.write(`${e}\n`);this.painted=t,this.paintedWidths=t.map(Pe),this.paintedCols=e}onResize=()=>{this.clear(),this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout(()=>{this.resizeTimer=void 0,this.paint()},this.quietMs),this.resizeTimer.unref?.()}};function Re(e,t=0){let n=e.padEnd(t);return e===`running`?T.green(n):e===`waiting-approval`?T.yellow(n):e===`failed`||e===`cancelled`?T.red(n):e===`completed`?T.blue(n):T.dim(n)}function ze(e,t,n=!1){n?O({taskId:e,status:`awaiting-approval`,approval:t}):(y.stdout.write(`Approval needed for task ${e}: ${t.summary}\n`),y.stderr.write(`\n${ge([`Approve: coder approve ${e} ${t.id}`,`Deny: coder approve ${e} ${t.id} --deny`,`Then: coder task result ${e} --wait`],E)}\n`)),y.exit(4)}function Be(e,t,n){if(e.length>t){let r=e.slice(t);D(`Unexpected argument${r.length>1?`s`:``}: ${r.join(` `)}`,{hint:`Help: coder ${n} --help`})}}function A(e){return e.cwd?x.resolve(String(e.cwd)):y.cwd()}function Ve(e,t){let r=n(e,t);return r||D(t?`No task found for "${t}".`:`No tasks found for this workspace.`,{hint:t?[`List tasks: coder task list`,`Start one: coder run "<text>"`]:[`Start one: coder run "<text>"`]}),r}const j=`@wular/coder`,He=`https://registry.npmjs.org/${j}/latest`;function Ue(){return x.join(r(),`update-check.json`)}function We(e,t){let n=String(e).split(`.`).map(e=>parseInt(e,10)||0),r=String(t).split(`.`).map(e=>parseInt(e,10)||0);for(let e=0;e<3;e+=1){if((n[e]??0)>(r[e]??0))return 1;if((n[e]??0)<(r[e]??0))return-1}return 0}function Ge(){try{return JSON.parse(b.readFileSync(Ue(),`utf8`))}catch{return null}}function Ke(e){try{b.mkdirSync(r(),{recursive:!0}),b.writeFileSync(Ue(),JSON.stringify(e))}catch{}}function qe(){try{b.rmSync(Ue(),{force:!0})}catch{}}function Je(e,t){if(y.env.CODER_NO_UPDATE_CHECK||y.env.CI)return;let n=Ge();if(n?.latest&&We(n.latest,e)>0&&y.stderr.write(E.dim(`coder ${e} -> `)+E.bold(n.latest)+E.dim(` available. run: coder upgrade
6
-
7
- `)),!n?.checkedAt||Date.now()-n.checkedAt>864e5)try{S(y.execPath,[t,`_refreshUpdate`],{detached:!0,stdio:`ignore`}).unref()}catch{}}async function Ye(e){let t=Ge()?.latest??null;try{let e=new AbortController,n=setTimeout(()=>e.abort(),3e3),r=await fetch(He,{signal:e.signal,headers:{accept:`application/json`}});if(clearTimeout(n),r.ok){let e=await r.json();e?.version&&(t=e.version)}}catch{}Ke({checkedAt:Date.now(),latest:t,current:e})}function Xe(e){let t=e;try{t=b.realpathSync(e)}catch{}let n=t.replace(/\\/g,`/`);return/\/\.bun\//.test(n)?{pm:`bun`,command:[`bun`,`add`,`-g`,`${j}@latest`]}:/\/\.pnpm\//.test(n)||/\/pnpm(-global)?\//i.test(n)||/\/Library\/pnpm\//.test(n)?{pm:`pnpm`,command:[`pnpm`,`add`,`-g`,`${j}@latest`]}:/\/\.config\/yarn\/global\//.test(n)||/\/yarn\/global\//.test(n)||/\/Yarn\/Data\/global\//.test(n)?{pm:`yarn`,command:[`yarn`,`global`,`add`,`${j}@latest`]}:{pm:`npm`,command:[`npm`,`install`,`-g`,`${j}@latest`]}}function M(e){try{return JSON.parse(b.readFileSync(e,`utf8`))}catch{return null}}function Ze(e,t){let n=`${e}.tmp`;b.writeFileSync(n,`${JSON.stringify(t,null,2)}\n`,`utf8`),b.renameSync(n,e)}function Qe(e){let t=0,n=``;return()=>{let r;try{r=b.statSync(e).size}catch{return[]}if(r<t&&(t=0,n=``),r===t)return[];let i;try{i=b.openSync(e,`r`)}catch{return[]}try{let e=Buffer.alloc(r-t),a=b.readSync(i,e,0,e.length,t);t+=a;let o=(n+e.toString(`utf8`,0,a)).split(`
8
- `);return n=o.pop()??``,o.filter(Boolean)}finally{b.closeSync(i)}}}const $e=new Set(`commit.checkout.switch.restore.stash.reset.rebase.merge.push.pull.cherry-pick.revert.clean.am.apply.tag.branch.worktree.filter-branch.filter-repo.gc.prune.reflog.remote.submodule.config`.split(`.`)),et=[/\bsudo\b/,/\brm\s+(-[a-zA-Z]*r[a-zA-Z]*f|-[a-zA-Z]*f[a-zA-Z]*r)\b.*\s(\/\*?|~\/?|\$HOME\/?)(\s|$)/,/\b(shutdown|reboot|halt|poweroff)\b/,/\bmkfs\b|\bdiskutil\s+erase/i,/\b(chmod|chown)\b.*-R.*\s\/(\s|$)/,/\bkill(all)?\s+-9\s+1\b/,/curl[^|;&]*\|\s*(ba|z|da)?sh\b/,/wget[^|;&]*\|\s*(ba|z|da)?sh\b/,/\blaunchctl\b|\bsystemctl\b/,/\bdefaults\s+write\b/,/>\s*\/dev\/(sd|disk)/],tt=new Set([`status`,`log`,`diff`,`show`,`blame`,`rev-parse`,`ls-files`,`ls-tree`,`cat-file`,`describe`,`shortlog`,`grep`,`branch`,`stash`]);function nt(e){let t=e.match(/^\s*(?:ba|z|da)?sh\s+(?:-[a-zA-Z]+\s+)*(?:-c\s+)?(["'])([\s\S]*)\1\s*$/);return t?t[2]:e}function rt(e){return e.trim().split(/\s+/).filter(Boolean)}function it(e){let t=e.find((e,t)=>t>0&&!e.startsWith(`-`));if(!t)return{decision:`accept`,reason:`bare git`};if(t===`branch`&&e.some(e=>/^-(d|D|m|M|c|C|f|u)|^--(delete|move|copy|force|set-upstream)/.test(e)))return{decision:`decline`,reason:`git branch write operation (git is read-only for Coder)`};if(t===`stash`){let t=e.find((e,t)=>t>1&&!e.startsWith(`-`));return t===`list`||t===`show`?{decision:`accept`,reason:`git stash ${t} is read-only`}:{decision:`decline`,reason:`git stash write operation (git is read-only for Coder)`}}return tt.has(t)?{decision:`accept`,reason:`git ${t} is read-only`}:$e.has(t)?{decision:`decline`,reason:`git ${t} is a write operation (git is read-only for Coder)`}:{decision:`escalate`,reason:`unrecognized git subcommand: ${t}`}}function at(e,t={}){let n=nt(String(e??``));if(!n.trim())return{decision:`escalate`,reason:`empty command`};for(let e of et)if(e.test(n))return{decision:`decline`,reason:`matches hard-deny pattern ${e}`};if(/\$\(|`|<\(/.test(n))return{decision:`escalate`,reason:`contains command substitution`};let r=n.split(/&&|\|\||;|\||\r?\n/).map(e=>e.trim()).filter(Boolean);if(r.length>1){let e={decision:`accept`,reason:`all segments safe`};for(let n of r){let r=at(n,t);if(r.decision===`decline`)return r;r.decision===`escalate`&&(e=r)}return e}let i=rt(n),a=x.basename(i[0]??``);if(a===`git`)return it(i);let o=t.networkHost;return o?(t.allowedNetworkHosts??[]).some(e=>o===e||o.endsWith(`.${e}`))?{decision:`accept`,reason:`network host ${o} is allowlisted`}:{decision:`escalate`,reason:`network access to ${o}`}:{decision:`escalate`,reason:`command needs approval: ${a||`(unknown)`}`}}function ot(e,t){if(!e.length)return{decision:`escalate`,reason:`file change with no resolvable paths`};for(let n of e){let e=x.resolve(t,n),r=x.relative(t,e);if(r.startsWith(`..`)||x.isAbsolute(r))return{decision:`escalate`,reason:`path outside workspace: ${n}`};if(r===`.git`||r.startsWith(`.git${x.sep}`))return{decision:`decline`,reason:`direct .git modification: ${n}`}}return{decision:`accept`,reason:`all paths inside workspace`}}function st(e){return x.join(e,`approvals`)}function ct(e){let t=st(e);return b.existsSync(t)?b.readdirSync(t).filter(e=>e.endsWith(`.request.json`)).flatMap(e=>{let n=e.replace(/\.request\.json$/,``),r=M(x.join(t,e));if(!r)return[];let i=M(x.join(t,`${n}.response.json`));return[{...r,id:n,response:i}]}).sort((e,t)=>String(e.createdAt??``).localeCompare(String(t.createdAt??``))):[]}function lt(e,t,n){let r=st(e),i=x.join(r,`${t}.request.json`);if(!b.existsSync(i))throw Error(`No pending approval "${t}" for this job.`);b.writeFileSync(x.join(r,`${t}.response.json`),`${JSON.stringify({decision:n,answeredAt:new Date().toISOString()},null,2)}\n`,`utf8`)}async function N(e,t,{timeoutMs:n,onEvent:r}){let i=st(e);b.mkdirSync(i,{recursive:!0});let a=`apr-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`;b.writeFileSync(x.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 ${x.basename(e)} ${a} [--deny]`});let o=x.join(i,`${a}.response.json`),s=Date.now()+n;for(;Date.now()<s;){if(b.existsSync(o))try{let e=JSON.parse(b.readFileSync(o,`utf8`)).decision===`accept`?`accept`:`decline`;return r?.({kind:`approval-answered`,approvalId:a,decision:e}),e}catch{}await new Promise(e=>setTimeout(e,400))}return r?.({kind:`approval-timeout`,approvalId:a,message:`Approval ${a} timed out; declining.`}),`decline`}function ut(e,t={}){return N(e,{method:`simulate`,summary:`simulated approval probe (--simulate-approval)`},{timeoutMs:t.timeoutMs??12e4,onEvent:t.onEvent??null})}function dt({workspaceRoot:e,jobDir:t,mode:n=`auto`,escalationTimeoutMs:r=12e4,allowedNetworkHosts:i=[],onEvent:a=null}){return async(o,s,c)=>{if(o===`item/commandExecution/requestApproval`){let e=s.command??c?.itemIndex?.get(s.itemId??``)?.command??``,l=`run command: ${e||`(unknown command)`}${s.reason?` — ${s.reason}`:``}`;if(n===`deny`)return a?.({kind:`approval-decision`,method:o,decision:`decline`,reason:`deny mode`,summary:l}),{decision:`decline`};let u=at(e,{networkHost:s.networkApprovalContext?.host??null,allowedNetworkHosts:i});return a?.({kind:`approval-decision`,method:o,decision:u.decision,reason:u.reason,summary:l}),u.decision===`escalate`?{decision:await N(t,{method:o,summary:l,command:e,params:s},{timeoutMs:r,onEvent:a})}:{decision:u.decision}}if(o===`item/fileChange/requestApproval`){let i=(c?.itemIndex?.get(s.itemId??``)?.changes??[]).map(e=>e.path).filter(e=>!!e),l=`apply file changes: ${i.join(`, `)||`(unknown paths)`}${s.reason?` — ${s.reason}`:``}`;if(n===`deny`)return a?.({kind:`approval-decision`,method:o,decision:`decline`,reason:`deny mode`,summary:l}),{decision:`decline`};let u=ot(i,e);return a?.({kind:`approval-decision`,method:o,decision:u.decision,reason:u.reason,summary:l}),u.decision===`escalate`?{decision:await N(t,{method:o,summary:l,paths:i,params:s},{timeoutMs:r,onEvent:a})}:{decision:u.decision}}throw a?.({kind:`approval-unsupported`,method:o}),Error(`Coder does not handle server request ${o}; treating as denied.`)}}async function ft(e,t,n=400){let r=t;for(;;){if(a.includes(r.status))return{job:r,reason:`terminal`};let t=ct(o(e,r.id)).filter(e=>!e.response);if(t[0])return{job:r,reason:`approval`,approval:{id:t[0].id,summary:String(t[0].summary??``)}};await new Promise(e=>setTimeout(e,n)),r=d(e,h(e,r.id)??r)}}const pt=`Coder Task`;function mt(e){return e.split(/\r?\n/).map(e=>e.trimEnd()).filter(e=>e&&!e.startsWith(`WARNING: proceeding, even though we could not update PATH:`)).join(`
9
- `)}function ht(e,t=72){let n=String(e??``).trim().replace(/\s+/g,` `);return n?n.length<=t?n:`${n.slice(0,t-3)}...`:``}function gt(e){let t=ht(e,56);return t?`${pt}: ${t}`:pt}function _t(e){return e?.params?.threadId??null}function vt(e){return e?.params?.turnId?e.params.turnId:e?.params?.turn?.id?e.params.turn.id:null}function yt(e){let t=new Set;for(let n of e)for(let e of n.changes??[])e.path&&t.add(e.path);return[...t]}function bt(e){if(!e||typeof e!=`object`)return null;let t=e=>typeof e==`number`&&Number.isFinite(e)?e:0,n=t(e.inputTokens),r=t(e.cachedInputTokens),i=t(e.outputTokens);return{input:n,cachedInput:r,output:i,total:t(e.totalTokens)||n+r+i}}function xt(e){if(e.tokenUsageByThread.size===0)return null;let t={input:0,cachedInput:0,output:0,total:0};for(let n of e.tokenUsageByThread.values())t.input+=n.input,t.cachedInput+=n.cachedInput,t.output+=n.output,t.total+=n.total;return t}function St(e){return String(e??``).replace(/\s+/g,` `).trim()}function P(e){if(!e)return[];if(typeof e==`string`){let t=St(e);return t?[t]:[]}if(Array.isArray(e))return e.flatMap(e=>P(e));if(typeof e==`object`){let t=e;if(typeof t.text==`string`)return P(t.text);if(`summary`in t)return P(t.summary);if(`content`in t)return P(t.content);if(`parts`in t)return P(t.parts)}return[]}function Ct(e,t){let n=[];for(let r of[...e,...t]){let e=St(r);!e||n.includes(e)||n.push(e)}return n}function F(e,t,n=null,r={}){!e||!t||e({message:t,phase:n,...r})}function wt(e){switch(e.type){case`commandExecution`:return{message:`Running command: ${String(e.command??``).trim()}`,phase:`running`};case`fileChange`:return{message:`Applying ${e.changes.length} file change(s).`,phase:`editing`};case`mcpToolCall`:return{message:`Calling ${e.server}/${e.tool}.`,phase:`investigating`};case`dynamicToolCall`:return{message:`Running tool: ${e.tool}.`,phase:`investigating`};case`webSearch`:return{message:`Searching: ${String(e.query??``).trim()}`,phase:`investigating`};default:return null}}function Tt(e){switch(e.type){case`agentMessage`:{let t=String(e.text??``).trim();return t?{message:t,phase:null}:null}case`reasoning`:{let t=P(e.summary)[0]?.split(`
10
- `)[0]??``;return t?{message:`Thinking: ${t.length>100?`${t.slice(0,100)}…`:t}`,phase:null}:null}case`commandExecution`:{let t=String(e.aggregatedOutput??``).trim();return{message:`Command ${e.status===`completed`?`completed`:e.status}: ${String(e.command??``).trim()} (exit ${e.exitCode??`?`})`+(t?`\n${t}`:``),phase:`running`}}case`fileChange`:return{message:`File changes ${e.status}.`,phase:`editing`};case`mcpToolCall`:return{message:`Tool ${e.server}/${e.tool} ${e.status}.`,phase:`investigating`};case`dynamicToolCall`:return{message:`Tool ${e.tool} ${e.status}.`,phase:`investigating`};default:return null}}function Et(e,t={}){let n,r,i=new Promise((e,t)=>{n=e,r=t});return{threadId:e,rootThreadId:e,threadIds:new Set([e]),threadTurnIds:new Map,turnId:null,bufferedNotifications:[],completion:i,resolveCompletion:n,rejectCompletion:r,finalTurn:null,completed:!1,finalAnswerSeen:!1,pendingCollaborations:new Set,activeSubagentTurns:new Set,completionTimer:null,lastAgentMessage:``,reasoningSummary:[],error:null,fileChanges:[],commandExecutions:[],tokenUsageByThread:new Map,itemIndex:new Map,onProgress:t.onProgress??null,onHeartbeat:t.onHeartbeat??null}}function Dt(e){e.completionTimer&&=(clearTimeout(e.completionTimer),null)}function Ot(e,t=null){e.completed||(Dt(e),e.completed=!0,t?(e.finalTurn=t,e.turnId||=t.id??null):e.finalTurn||={id:e.turnId??`inferred-turn`,status:`completed`},e.resolveCompletion(e))}function kt(e){e.completed||e.finalTurn||!e.finalAnswerSeen||e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||(Dt(e),e.completionTimer=setTimeout(()=>{e.completionTimer=null,!(e.completed||e.finalTurn||!e.finalAnswerSeen)&&(e.pendingCollaborations.size>0||e.activeSubagentTurns.size>0||Ot(e,null))},250),e.completionTimer.unref?.())}function At(e,t){let n=_t(t);if(!n||!e.threadIds.has(n))return!1;let r=e.threadTurnIds.get(n)??null,i=vt(t);return r===null||i===null||i===r}function jt(e,t,n,r=null){if(t.id&&e.itemIndex.set(t.id,t),t.type===`collabAgentToolCall`){(!r||r===e.threadId)&&(n===`started`||t.status===`inProgress`?e.pendingCollaborations.add(t.id):n===`completed`&&(e.pendingCollaborations.delete(t.id),kt(e)));for(let n of t.receiverThreadIds??[])e.threadIds.add(n)}if(t.type===`agentMessage`){t.text&&(!r||r===e.threadId)&&(e.lastAgentMessage=t.text,n===`completed`&&t.phase===`final_answer`&&(e.finalAnswerSeen=!0,kt(e)));return}if(t.type===`reasoning`&&n===`completed`){e.reasoningSummary=Ct(e.reasoningSummary,P(t.summary));return}if(t.type===`fileChange`&&n===`completed`){e.fileChanges.push(t);return}t.type===`commandExecution`&&n===`completed`&&e.commandExecutions.push(t)}function Mt(e,t){switch(e.onHeartbeat?.(),t.method){case`thread/started`:e.threadIds.add(t.params.thread.id);break;case`turn/started`:e.threadIds.add(t.params.threadId),e.threadTurnIds.set(t.params.threadId,t.params.turn.id),(t.params.threadId??null)!==e.threadId&&e.activeSubagentTurns.add(t.params.threadId),F(e.onProgress,`Turn started (${t.params.turn.id}).`,`starting`,{threadId:t.params.threadId??null,turnId:t.params.turn.id??null});break;case`item/started`:jt(e,t.params.item,`started`,t.params.threadId??null);{let n=wt(t.params.item);F(e.onProgress,n?.message,n?.phase??null)}break;case`item/completed`:jt(e,t.params.item,`completed`,t.params.threadId??null);{let n=Tt(t.params.item);F(e.onProgress,n?.message,n?.phase??null)}break;case`thread/tokenUsage/updated`:{let n=bt(t.params?.tokenUsage?.total??t.params?.tokenUsage),r=_t(t);n&&r&&e.tokenUsageByThread.set(r,n);break}case`item/autoApprovalReview/completed`:{let n=t.params?.review??{},r=t.params?.action??{},i=r.command??r.type??``;F(e.onProgress,`auto-review ${n.status}${n.riskLevel?` (${n.riskLevel} risk)`:``}: ${ht(i)}${n.rationale?` — ${ht(n.rationale,120)}`:``}`,null);break}case`error`:e.error=t.params.error,F(e.onProgress,`Codex error: ${t.params.error.message}`,`failed`);break;case`turn/completed`:if((t.params.threadId??null)!==e.threadId){e.activeSubagentTurns.delete(t.params.threadId),kt(e);break}F(e.onProgress,`Turn ${t.params.turn.status}.`,`finalizing`),Ot(e,t.params.turn)}}async function Nt(e,t,n,r={}){let i=Et(t,r),a=e.notificationHandler;e.setNotificationHandler(e=>{if(!i.turnId){i.bufferedNotifications.push(e);return}if(e.method===`thread/started`){Mt(i,e);return}if(!At(i,e)){a?.(e);return}Mt(i,e)});let o=r.onApprovalRequest;o&&e.setServerRequestHandler((e,t)=>o(e,t,i));try{let e=await n();i.turnId=e.turn?.id??null,i.turnId&&i.threadTurnIds.set(i.threadId,i.turnId);for(let e of i.bufferedNotifications)At(i,e)?Mt(i,e):a?.(e);return i.bufferedNotifications.length=0,e.turn?.status&&e.turn.status!==`inProgress`&&Ot(i,e.turn),await i.completion}finally{Dt(i),e.setNotificationHandler(a??null),e.setServerRequestHandler(null)}}async function Pt(e,t){let n=null;try{n=await v.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 v.connect(e,{disableBroker:!0});try{return await t(s)}finally{await s.close()}}}function I(e){let t=m(`codex`,[`--version`],{cwd:e});if(!t.available)return t;let n=m(`codex`,[`app-server`,`--help`],{cwd:e});return n.available?{available:!0,detail:`${t.detail}; app-server runtime available`}:{available:!1,detail:`${t.detail}; app-server runtime unavailable: ${n.detail}`}}async function Ft(e){let t=I(e);if(!t.available)return{available:!1,loggedIn:!1,detail:t.detail};let n=null;try{n=await v.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=C(`codex`,[`login`,`status`],{encoding:`utf8`}),n=`${t.stdout??``}${t.stderr??``}`.trim();return t.status===0?{available:!0,loggedIn:!0,detail:n||`Logged in`}:{available:!0,loggedIn:!1,detail:n||(e instanceof Error?e.message:String(e))}}finally{await n?.close().catch(()=>{})}}async function It(e,{threadId:t,turnId:n}){if(!t||!n)return{interrupted:!1,detail:`missing threadId or turnId`};let r=null;try{return r=await v.connect(e,{reuseExistingBroker:!0}),await r.request(`turn/interrupt`,{threadId:t,turnId:n}),{interrupted:!0,detail:`Interrupted ${n} on ${t}.`}}catch(e){return{interrupted:!1,detail:e instanceof Error?e.message:String(e)}}finally{await r?.close().catch(()=>{})}}async function Lt(e,{threadId:t,text:n}){if(!t)return{steered:!1,detail:`missing threadId`};let r=n.trim();if(!r)return{steered:!1,detail:`empty follow-up`};let i=null;try{return i=await v.connect(e,{reuseExistingBroker:!0}),await i.request(`turn/steer`,{threadId:t,input:[{type:`text`,text:r,text_elements:[]}]}),{steered:!0,detail:`Steered follow-up into the active turn on ${t}.`}}catch(e){return{steered:!1,detail:e instanceof Error?e.message:String(e)}}finally{await i?.close().catch(()=>{})}}async function Rt(e,t={}){let n=I(e);if(!n.available)throw Error(`Codex CLI is not available: ${n.detail}`);let r=t.prompt?.trim();if(!r)throw Error(`A prompt is required.`);return Pt(e,async n=>{let a;if(t.resumeThreadId)F(t.onProgress,`Resuming thread ${t.resumeThreadId}.`,`starting`),p(t.resumeThreadId)&&await i(t.resumeThreadId),a=(await n.request(`thread/resume`,{threadId:t.resumeThreadId,cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`,...t.approvalsReviewer?{approvalsReviewer:t.approvalsReviewer}:{}})).thread.id;else if(F(t.onProgress,`Starting Codex task thread.`,`starting`),a=(await n.request(`thread/start`,{cwd:e,model:t.model??null,modelProvider:t.modelProvider??null,config:t.configOverrides??null,approvalPolicy:t.approvalPolicy??`never`,sandbox:t.sandbox??`read-only`,...t.approvalsReviewer?{approvalsReviewer:t.approvalsReviewer}:{},serviceName:`coder_runtime`,ephemeral:t.ephemeral??!1})).thread.id,!(t.ephemeral??!1))try{await n.request(`thread/name/set`,{threadId:a,name:gt(r)})}catch(e){let t=String(e?.message??e??``);if(!t.includes(`unknown variant`)&&!t.includes(`unknown method`))throw e}F(t.onProgress,`Thread ready (${a}).`,`starting`,{threadId:a});let o=await Nt(n,a,()=>n.request(`turn/start`,{threadId:a,input:[{type:`text`,text:r,text_elements:[]}],model:t.model??null,effort:t.effort??null,outputSchema:t.outputSchema??null}),{onProgress:t.onProgress,onHeartbeat:t.onHeartbeat,onApprovalRequest:t.onApprovalRequest});return{status:o.finalTurn?.status===`completed`?0:1,threadId:a,turnId:o.turnId,finalMessage:o.lastAgentMessage,reasoningSummary:o.reasoningSummary,turn:o.finalTurn,error:o.error,stderr:mt(n.stderr),fileChanges:o.fileChanges,touchedFiles:yt(o.fileChanges),tokens:xt(o),model:t.model??null,commandExecutions:o.commandExecutions}})}const zt={chain:[`codex`,`claude`],agents:{codex:{model:`gpt-5.6-terra`,effort:`high`,permissions:`auto`},claude:{model:`opus`,effort:`medium`,permissions:`auto`}},models:{},approvals:{escalationTimeoutMs:12e4,allowedNetworkHosts:[]}},L={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={haiku:`haiku`,sonnet:`sonnet`,opus:`opus`,fable:`fable`},B=new Set([`low`,`medium`,`high`]),Bt={"read-only":{sandbox:`read-only`,approvalPolicy:`never`,approvalMode:null},"workspace-write":{sandbox:`workspace-write`,approvalPolicy:`never`,approvalMode:null},auto:{sandbox:`workspace-write`,approvalPolicy:`on-request`,approvalMode:`auto`}},Vt={"read-only":[`--permission-mode`,`dontAsk`,`--disallowedTools`,`Edit`,`Write`,`NotebookEdit`],"workspace-write":[`--permission-mode`,`acceptEdits`],auto:[`--permission-mode`,`auto`]},Ht=[`--permission-mode`,`dontAsk`,`--disallowedTools`,`Edit`,`Write`,`NotebookEdit`,`Bash`,`WebFetch`,`WebSearch`,`Task`],Ut=/failIfUnavailable|sandbox\b[^.\n]*?(?:failed|could ?n[o']t|cannot|unavailable|not available|not supported)/i;function Wt(e){return e.flatMap(e=>de.isIPv6(e)?[`[${e}]`]:e.startsWith(`[`)||e.includes(`:`)||de.isIP(e)?[e]:[e,`*.${e}`])}function Gt(e,t,n=[],r=[]){return JSON.stringify(e===`read-only`?{...r.length?{permissions:{additionalDirectories:r}}:{},sandbox:{enabled:!0,failIfUnavailable:!0,autoAllowBashIfSandboxed:!0,filesystem:{denyWrite:[t,...r]}}}:{sandbox:{enabled:!0,autoAllowBashIfSandboxed:!0,...e===`auto`&&n.length?{network:{allowedDomains:Wt(n)}}:{}}})}const Kt=w.enum([`codex`,`claude`]),qt=w.enum([`codex`,`claude`,`custom`]),Jt=w.enum([`low`,`medium`,`high`]),Yt=w.enum([`read-only`,`workspace-write`,`auto`]),Xt=w.partial(w.strictObject({model:w.string().check(w.minLength(1)),effort:Jt,permissions:Yt})),Zt=w.strictObject({baseUrl:w.url(),model:w.string().check(w.minLength(1)),envKey:w.optional(w.string().check(w.minLength(1))),wireApi:w.optional(w.enum([`chat`,`responses`])),disabled:w.optional(w.boolean())}),Qt=w.strictObject({provider:Kt,model:w.string().check(w.minLength(1)),effort:w.optional(Jt),disabled:w.optional(w.boolean())}),$t=w.strictObject({disabled:w.boolean()}),en=w.union([Zt,Qt,$t]),tn=w.strictObject({escalationTimeoutMs:w.number().check(w.positive()),allowedNetworkHosts:w.array(w.string())}),nn=w.strictObject({chain:w.array(qt).check(w.minLength(1)),agents:w.partial(w.strictObject({codex:Xt,claude:Xt,custom:Xt})),models:w.optional(w.record(w.string().check(w.regex(/^[a-z0-9][a-z0-9./_-]*$/i,`model name`)),en)),approvals:tn}),rn=w.partial(w.extend(nn,{approvals:w.partial(tn)}));function V(e){return`baseUrl`in e}function H(e){return`provider`in e}function U(e){let t=rn.safeParse(e);if(!t.success)return t.error.issues.map(e=>`${e.path.join(`.`)||`config`}: ${e.message}`);let n=on(zt,t.data),r=[];for(let[e,i]of Object.entries(t.data.models??{})){if(e===`codex`||e===`claude`||e===`custom`){r.push(`models.${e}: reserved agent name`);continue}if(H(i)){let t=n.models?.[i.model];t&&!V(t)&&r.push(`models.${e}: alias target "${i.model}" is itself a config entry`)}}return r}function an(e){if(!b.existsSync(e))return null;try{return JSON.parse(b.readFileSync(e,`utf8`))}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`Invalid JSON in ${e}: ${n}`)}}function on(e,t){if(!t||typeof t!=`object`||Array.isArray(t))return t??e;let n={...e},r=e;for(let[e,i]of Object.entries(t))n[e]=i&&typeof i==`object`&&!Array.isArray(i)&&r?.[e]&&typeof r[e]==`object`?on(r[e],i):i;return n}function W(){return x.join(r(),`config.json`)}function sn(e){let t=s(e),n=zt;for(let e of[W(),x.join(t,`coder.config.json`)]){let t=an(e);if(!t)continue;let r=U(t);if(r.length)throw Error(`Invalid config in ${e}:\n ${r.join(`
11
- `)}`);n=on(n,t)}let r=U(n);if(r.length)throw Error(`Invalid merged config:\n ${r.join(`
12
- `)}`);return n}function cn(e){return e.replace(/\/+$/,``).replace(/\/(chat\/completions|completions|responses)$/,``)}function ln(e,t,n){let r=[x.join(s(e),`coder.config.json`),W()];for(let e of r){let r;try{r=an(e)}catch{continue}if(r?.models?.[t])return Object.assign(r.models[t],n),!U(r).length&&(b.writeFileSync(e,`${JSON.stringify(r,null,2)}\n`,`utf8`),!0)}return!1}function un(e){return/\/(chat\/completions|completions|responses)\/*$/.test(e)}function dn(e,t){let n=cn(e);return un(e)||/\/v\d+(alpha|beta)?$/.test(n)?[`${n}/${t}`]:[`${n}/${t}`,`${n}/v1/${t}`]}function fn(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??cn(r.baseUrl),...r.envKey&&!n?{env_key:r.envKey}:{},wire_api:`responses`}}}}function pn(e){return e?L[e]??e:null}function mn(e){return e in L||e in z}function hn(e,t){return!!(t&&e.models?.[t]?.disabled)}function gn(e,t){if(hn(e,t))throw Error(`model "${t}" is disabled in config`)}function _n(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 gn(t,l),{agent:r,model:l,effort:a??c.effort??null}}function vn(e){let t=W();return b.mkdirSync(x.dirname(t),{recursive:!0}),b.writeFileSync(t,`${JSON.stringify(e,null,2)}\n`,`utf8`),t}function yn(e){return typeof e==`string`?e:Array.isArray(e)?e.map(e=>typeof e?.text==`string`?e.text:``).join(``):e==null?``:JSON.stringify(e)}function bn(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 xn(){let e=C(`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 Sn(){let e=C(`claude`,[`auth`,`status`,`--json`],{encoding:`utf8`});if(e.error||e.status!==0)return{loggedIn:!1,detail:`not logged in`};try{let t=JSON.parse(String(e.stdout||``));return t.loggedIn?{loggedIn:!0,detail:[t.email,t.subscriptionType].filter(Boolean).join(`, `)||`logged in`}:{loggedIn:!1,detail:`not logged in`}}catch{return{loggedIn:!1,detail:`unknown`}}}function Cn(e,t,n){let 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`,a=i===`read-only`?t.additionalDirectories??[]:[],o=i===`read-only`?t.readOnlyAllowedTools??[]:[];if(i===`auto`&&t.approvalJobId){let n=JSON.stringify({mcpServers:{coder:{type:`stdio`,command:process.execPath,args:[ee,`_mcp`,t.approvalJobId,`--cwd`,e]}}});r.push(`--permission-mode`,`default`,`--mcp-config`,n,`--permission-prompt-tool`,`mcp__coder__approval_prompt`)}else o.length?r.push(...Ht,`--allowedTools`,...o):r.push(...Vt[i]??Vt.auto);for(let e of a)r.push(`--add-dir`,e);let s=Gt(i,e,t.allowedNetworkHosts??[],a);return s&&r.push(`--settings`,s),r}async function wn(e,t){let n=t.resumeSessionId??pe(),r=Cn(e,t,n);return t.onProgress?.({message:`claude turn started (session ${n})`,threadId:n}),new Promise((i,a)=>{let o=S(`claude`,r,{cwd:e,stdio:[`ignore`,`pipe`,`pipe`]}),s=``,c=``,l=null,u=n,d=Date.now(),f=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??[])if(n?.type===`tool_use`)t.onProgress?.({message:`${n.name} ${JSON.stringify(n.input??{})}`,threadId:u});else if(n?.type===`text`&&typeof n.text==`string`&&n.text.trim())t.onProgress?.({message:n.text.trim(),threadId:u});else if(n?.type===`thinking`&&typeof n.thinking==`string`&&n.thinking.trim()){let e=Math.max(1,Math.round((Date.now()-d)/1e3)),r=n.thinking.trim().split(`
13
- `)[0],i=r.length>100?`${r.slice(0,100)}…`:r;t.onProgress?.({message:`Thought for ${e}s: ${i}`,threadId:u})}}else if(e.type===`user`){for(let n of e.message?.content??[])if(n?.type===`tool_result`){let e=yn(n.content).trim();e&&t.onProgress?.({message:e,threadId:u})}}else e.type===`result`&&(l=e,e.session_id&&(u=e.session_id));d=Date.now()}};o.stdout.on(`data`,e=>{s+=e;let t;for(;(t=s.indexOf(`
14
- `))>=0;){let e=s.slice(0,t).trim();if(s=s.slice(t+1),e)try{f(JSON.parse(e))}catch{}}}),o.stderr.on(`data`,e=>{c+=e});let p=()=>{o.kill(`SIGTERM`),process.exit(143)};process.on(`SIGTERM`,p),o.on(`error`,e=>{process.removeListener(`SIGTERM`,p),a(Error(`claude spawn failed: ${e.message}`))}),o.on(`close`,e=>{process.removeListener(`SIGTERM`,p);let n=s.trim();if(n)try{f(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:bn(l?.usage),model:l?.modelUsage&&Object.keys(l.modelUsage).join(`+`)||t.model||null,error:a?{message:r||c.trim()||`claude exited ${e}`}:null})})})}function Tn(e){C(`claude`,[`plugin`,`marketplace`,`remove`,`coder-plugins`],{encoding:`utf8`});let t=C(`claude`,[`plugin`,`marketplace`,`add`,e],{encoding:`utf8`}),n=C(`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 En(){return x.join(ce.homedir(),`.agents`,`skills`,`coder`)}function Dn(){try{let e=b.readFileSync(x.join(En(),`SKILL.md`),`utf8`);return/^\s*version:\s*(\S+)/m.exec(e)?.[1]??null}catch{return null}}function On(e){let t=En();try{let n=x.join(e,`plugins`,`agents`,`skills`,`coder`);b.rmSync(t,{recursive:!0,force:!0}),b.mkdirSync(t,{recursive:!0}),b.cpSync(n,t,{recursive:!0});let r=x.join(t,`SKILL.md`),i=b.readFileSync(r,`utf8`).replace(`
15
- ---
16
- `,`\nmetadata:\n version: ${g()}\n---\n`);return b.writeFileSync(r,i),{marketplace:t,installed:!0,note:`Skill installed to ~/.agents/skills/coder; restart running sessions to load it.`}}catch(e){return{marketplace:t,installed:!1,note:`Skill install failed: ${e instanceof Error?e.message:String(e)}`}}}function kn(e){if(e.available)return null;let t=C(`npm`,[`install`,`-g`,`@openai/codex@latest`],{encoding:`utf8`});return t.status===0?{installed:!0,note:`codex CLI installed (runs your custom models; no login needed for them)`}:{installed:!1,note:`custom models run on the codex CLI and it is not installed; auto-install failed: ${(t.stderr||`npm not found`).trim()}. Run: npm install -g @openai/codex`}}function An(e){let t=/(\d+\.\d+\.\d+)/.exec(String(e??``));return t?t[1]:null}function jn(e){if(!e.available)return null;let t=An(e.detail);if(!t||We(t,`0.144.0`)>=0)return null;let n=C(`codex`,[`update`],{encoding:`utf8`});return n.status!==0&&(n=C(`npm`,[`install`,`-g`,`@openai/codex@latest`],{encoding:`utf8`})),n.status===0?{updated:!0,from:t}:{updated:!1,from:t,note:`codex ${t} is too old for the default GPT-5.6 model (needs >= 0.144.0); auto-update failed: ${(n.stderr||`codex/npm not found`).trim()}. Run: codex update`}}const Mn=/usage|quota|rate.?limit|429|401|unauthorized|not authenticated|login|insufficient|exhausted|not available|ENOENT/i,Nn=`CODER_WORKER`;var G=class extends Error{code;hint;taskId;payload;approval;result;runId;constructor(e,t,n={}){super(t),this.name=`CoderError`,this.code=e,Object.assign(this,n)}},Pn=class extends Error{agent;detail;constructor(e,t){super(t),this.agent=e,this.detail=t}};function Fn(e,t){let n=e.agent,r=!!n,i=e.model,a=e.effort,o=e=>{let n=e?t.models?.[e]:void 0;return n&&H(n)?n:void 0},s=e=>{let n=e?t.models?.[e]:void 0;return n&&V(n)?n:void 0};if(o(i)){let e;try{e=_n(i,t)}catch(e){throw new G(`invalid-option`,e instanceof Error?e.message:String(e))}e&&(r||(n=e.agent),i=e.model??void 0,a=a??e.effort??void 0)}if(!n&&i&&(i in z?n=`claude`:i in L?n=`codex`:s(i)&&(n=`custom`)),n=n??t.chain[0]??`codex`,n!==`codex`&&n!==`claude`&&n!==`custom`){let e=n in L||n in z||n in(t.models??{})?` "${n}" is a model; use --model ${n}.`:``;throw new G(`invalid-option`,`Invalid --agent "${n}". Use codex, claude, or custom.${e}`)}let c=t.agents[n]??{},l=i??c.model??null,u=a??c.effort??null;if(o(l)){let e;try{e=_n(l,t)}catch(e){throw new G(`invalid-option`,e instanceof Error?e.message:String(e))}e&&(r||(n=e.agent),l=e.model,u=a??e.effort??u)}let d=e.permissions??c.permissions??`auto`;try{gn(t,l)}catch(e){throw new G(`invalid-option`,e instanceof Error?e.message:String(e))}if(n===`custom`){let e=Object.entries(t.models??{}).filter(([,e])=>V(e)).map(([e])=>e);if(!l&&e.length===1&&(l=e[0]),!l||!s(l))throw new G(`invalid-option`,l?`No custom model named "${l}". Configured: ${e.join(`, `)||`none`}.`:`No custom model to run: pass --model <name> or set agents.custom.model.`,{hint:`Add one: coder model add <name> --base-url <url> --model <id>`})}let f=n===`claude`?`claude`:`codex`;if(!(d in Bt))throw new G(`invalid-option`,`Invalid --permissions "${d}". Use one of: ${Object.keys(Bt).join(`, `)}`);if(f===`codex`&&u&&!R.has(u))throw new G(`invalid-option`,`Invalid codex --effort "${u}". Use one of: ${[...R].join(`, `)}`);if(f===`claude`&&u&&!B.has(u))throw new G(`invalid-option`,`Invalid claude --effort "${u}". Use one of: ${[...B].join(`, `)}`);return{engine:f,agent:n,model:l,effort:u,permissions:d}}function In(e,t){return e===`read-only`&&Ut.test(t??``)}function Ln(e,n){let r=o(e,n),i=b.openSync(x.join(r,`worker.log`),`a`),a=S(y.execPath,[ee,`_worker`,n,`--cwd`,e],{cwd:e,detached:!0,stdio:[`ignore`,i,i],env:{...y.env,[Nn]:`1`}});a.unref(),b.closeSync(i),t(e,n,{pid:a.pid??null})}async function Rn(e,r,i,a){let s=i.cwd,l=r.engine===`codex`?I(s):xn(),u=r.model?e.models?.[r.model]:void 0;if(!l.available&&u&&V(u)){let e=kn(l);i.onInstallNote?.(e.note),l=I(s)}if(!l.available)throw new Pn(r.agent,l.detail);let d=null;a.resume&&(d=n(s,a.resume)?.threadId??a.resume);let f=ae(),p=t(s,f,{status:`queued`,kind:`task`,name:a.name??null,system:i.system??null,agent:r.agent,engine:r.engine,prompt:i.prompt,model:r.model,effort:r.effort,permissions:r.permissions,resumeThreadId:d,cwd:s,background:!i.wait,...a.simulateApproval?{simulateApproval:!0}:{},...i.flowRunId?{flowRunId:i.flowRunId}:{}});Ln(s,f);let ee=2**53-1,m=()=>c(s,f,ee).filter(e=>e.phase!==`starting`).length,te=Date.now()+15e3,g=p,_=null,v=null;for(;Date.now()<(v??te)&&(g=h(s,f)??g,g.status!==`failed`&&g.status!==`completed`);){if(g.threadId&&_===null&&(_=m(),v=Date.now()+5e3),_!==null&&m()>_){g=h(s,f)??g;break}await new Promise(e=>setTimeout(e,150))}if(g.status===`failed`){let e=M(x.join(o(s,f),`result.json`))?.error?.message??``,t=c(s,f,5).map(e=>e.message??``).join(`
17
- `),n=e||t;throw In(r.permissions,n)?new G(`read-only-unavailable`,n):Mn.test(n)?new Pn(r.agent,n):new G(`startup-failed`,n,{taskId:f})}return{taskId:f,job:g,agent:r.agent,startupCheck:g.threadId?`passed`:`pending`}}function zn(e,t,n,r,i){return{error:`${e} failed to start: ${t}`,fallback:{action:`run-native-subagent`,reason:`no-engine-available`,permissions:n,note:`Every coder engine failed to start. Spawn your own native subagent and forward the task verbatim; tell it to never run git write operations (commit, checkout, stash, reset, push, ...) and to honor the permissions.`,...r?{system:r}:{},task:i}}}async function Bn(e){if(y.env.CODER_WORKER)throw new G(`nested-dispatch`,`Nested dispatch refused: this shell is already inside a coder task. Do the work yourself, directly in this session - ignore any skill or instruction telling you to orchestrate via the coder CLI.`);if(!e.prompt.trim())throw new G(`invalid-option`,`Missing task text.`,{hint:[`Usage: coder run "<task text>"`,`Help: coder task run --help`]});let t=sn(e.cwd),n={agent:e.agent,model:e.model,effort:e.effort,permissions:e.permissions},r={name:e.name,resume:e.resume,simulateApproval:e.simulateApproval};for(;;){let i=Fn(n,t);try{return await Rn(t,i,e,r)}catch(a){if(!(a instanceof Pn))throw a;let o=t.chain[t.chain.indexOf(a.agent)+1];if(!o){let t=zn(a.agent,a.detail,i.permissions,e.system,e.prompt);throw new G(`chain-exhausted`,t.error,{payload:t})}e.onFallback?.({agent:a.agent,detail:a.detail,next:o}),n={agent:o,permissions:e.permissions},r={name:void 0,resume:void 0,simulateApproval:void 0}}}}function Vn(e,t){if(t.status!==`failed`)return;let n=t.result;if(!n||!Mn.test(n.error?.message??``)||!(!n.touchedFiles?.length&&!n.fileChanges?.length&&!n.commandExecutions?.length))return;let r=sn(e).chain;return r[r.indexOf(t.job.agent)+1]}function Hn(e,t){return M(x.join(o(e,t),`result.json`))}function Un(e,t,n=0){return n===0?[]:c(e,t,n===`all`?2**53-1:n)}function Wn(e,t,n={}){let r=h(e,t);if(!r)throw Error(`No task found for "${t}".`);return{taskId:t,status:r.status,result:Hn(e,t),steps:Un(e,t,n.tail),turns:l(e,t),job:r}}async function Gn(e,t,n={}){let r=h(e,t);if(!r)throw Error(`No task found for "${t}".`);let i=await ft(e,r);if(i.reason===`approval`){let e=i.approval;throw new G(`approval-pending`,`Approval needed for task ${t}: ${e.summary}`,{taskId:t,approval:e})}n.onSettle?.();let a=i.job;return{taskId:t,status:a.status,result:Hn(e,t),steps:Un(e,t,n.tail),turns:l(e,t),job:a}}const Kn=[`.ts`,`.mjs`,`.js`];function qn(e,t){let n=[];try{n=b.readdirSync(e)}catch{return[]}let r=[];for(let i of n.sort()){let n=x.extname(i);Kn.includes(n)&&r.push({name:x.basename(i,n),path:x.join(e,i),scope:t})}return r}function Jn(e){let t=s(e),n=[],i=x.resolve(e);for(;n.push({dir:x.join(i,`.coder`,`flows`),scope:`workspace`}),i!==t&&x.dirname(i)!==i;)i=x.dirname(i);return n.push({dir:x.join(r(),`flows`),scope:`global`}),n}function Yn(e){let t=new Set,n=[];for(let{dir:r,scope:i}of Jn(e))for(let e of qn(r,i))t.has(e.name)||(t.add(e.name),n.push(e));return n}function Xn(e){return e.includes(`/`)||Kn.includes(x.extname(e))}function Zn(e,t){if(Xn(e)){let n=x.resolve(t,e);if(b.existsSync(n))return{name:x.basename(n,x.extname(n)),path:n};throw Error(`Flow file not found: ${e}`)}let n=Yn(t).find(t=>t.name===e);if(!n)throw Error(`No flow named "${e}". Run \`coder flow discover\` to see available flows.`);return{name:n.name,path:n.path}}function Qn(e,t,n={}){if(t.length)try{S(y.execPath,[ee,`_archiveSweep`,`--cwd`,e,...n.flows?[`--flows`]:[],...t],{detached:!0,stdio:`ignore`}).unref()}catch{}}async function $n(e){let{options:t,positionals:r}=te(e,w.object({cwd:re,flows:ne})),i=A(t);for(let e of r){if(t.flows){let t=Z(e);t&&Vr(t);continue}let r=n(i,e);r&&ie(i,r)}}async function er(e){let{options:t,positionals:n}=te(e,w.object({..._,"all-stopped":ne}));Be(n,1,`task archive`);let r=A(t);if(t[`all-stopped`]){let e=u(r).filter(e=>a.includes(e.status));for(let t of e)ie(r,t);let n=e.map(e=>e.id);if(t.json){O({archived:n,count:n.length});return}y.stdout.write(n.length?`Archived ${n.length} stopped task${n.length===1?``:`s`}.\n`:`${T.dim(`No stopped tasks to archive.`)}\n`);return}let i=n[0];i||D(`Missing task id.`,{hint:[`Archive one: coder task archive <task-id>`,`Archive all stopped: coder task archive --all-stopped`]});let o=Ve(r,i);if(ie(r,o),t.json){O({taskId:o.id,archived:!0});return}y.stdout.write(`Archived task ${T.cyan(o.id)}.\n`)}async function tr(e,n){let r=n.engine===`claude`?{detail:`claude worker terminated`}:await It(e,{threadId:n.threadId,turnId:n.turnId});if(n.pid&&n.status===`running`)try{y.kill(n.pid,`SIGTERM`)}catch{}return t(e,n.id,{status:`cancelled`,completedAt:new Date().toISOString()}),{taskId:n.id,status:`cancelled`,interrupt:r.detail}}async function nr(e){let{options:t,positionals:n}=te(e,w.object(_));Be(n,1,`task stop`);let r=A(t),i=Ve(r,n[0]),{interrupt:a}=await tr(r,i);if(t.json){O({taskId:i.id,status:`cancelled`,interrupt:a});return}y.stdout.write(`Stopped task ${T.cyan(i.id)} ${T.dim(`(${a})`)}\n`)}function rr(e){return typeof e!=`object`||!e?JSON.stringify(e)??`null`:Array.isArray(e)?`[${e.map(rr).join(`,`)}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${rr(e[t])}`).join(`,`)}}`}function ir(e,t){return fe.createHash(`sha256`).update(`${e}\0${rr(t)}`).digest(`hex`)}function K(e){return b.existsSync(e)?b.readFileSync(e,`utf8`).split(/\r?\n/).filter(Boolean).map(e=>{try{return JSON.parse(e)}catch{return null}}).filter(e=>e!==null):[]}var ar=class{file;recorded;seq=0;constructor(e,t){this.file=t,this.recorded=e.map(e=>({...e})),b.writeFileSync(t,``,`utf8`)}write(e){e.seq=this.seq++,b.appendFileSync(this.file,`${JSON.stringify(e)}\n`,`utf8`)}replay(e){let t=this.recorded.find(t=>!t.consumed&&t.fingerprint===e);if(!t)return null;t.consumed=!0;let{consumed:n,...r}=t;return this.write(r),r}record(e){this.write({...e,seq:0})}};const or=globalThis,q=or.__coderFlowCtxALS??=new me,J=or.__coderFlowScopeALS??=new me;function sr(){return J.getStore()?.args}function cr(){return J.getStore()?.depth??0}var lr=class{limit;active=0;queue=[];constructor(e){this.limit=e}async run(e){this.active<this.limit?this.active+=1:await new Promise(e=>this.queue.push(e));try{return await e()}finally{let e=this.queue.shift();e?e():--this.active}}};function ur(e,t){return t?e?{input:e.input+t.input,cachedInput:e.cachedInput+t.cachedInput,output:e.output+t.output,total:e.total+t.total}:{...t}:e}function dr(e,t){if(!t.tokens)return;let n=t.model??`default`;e.ledger[n]=ur(e.ledger[n]??null,t.tokens)}function fr(e){return!!e&&typeof e.safeParse==`function`}async function pr(e){try{let t=await import(`zod`);if(typeof t.toJSONSchema==`function`)return t.toJSONSchema(e)}catch{}return null}async function mr(e){let t=await pr(e);return`Reply with ONLY a single JSON object ${t?`matching this JSON Schema:\n${JSON.stringify(t,null,2)}`:`matching the requested shape`}\nNo prose, no markdown fences — just the JSON object.`}function hr(e){let t=e.trim(),n=t.match(/```(?:json)?\s*([\s\S]*?)```/i);n&&(t=n[1].trim());let r=t.indexOf(`{`);if(r===-1)throw Error(`no JSON object found in reply`);let i=0,a=!1,o=!1;for(let e=r;e<t.length;e+=1){let n=t[e];if(a){o?o=!1:n===`\\`?o=!0:n===`"`&&(a=!1);continue}if(n===`"`)a=!0;else if(n===`{`)i+=1;else if(n===`}`&&(--i,i===0))return JSON.parse(t.slice(r,e+1))}throw Error(`unterminated JSON object in reply`)}function gr(e,t){if(!fr(e))return{ok:!0,data:t};let n=e.safeParse(t);if(n.success)return{ok:!0,data:n.data};let r=n.error?.issues??n.error?.errors??[];return{ok:!1,errors:Array.isArray(r)?r.map(e=>`${(e.path??[]).join(`.`)||`(root)`}: ${e.message}`).join(`; `):String(n.error)}}function _r(e,t,n){return{cwd:t,agent:e.agent,model:e.model,effort:e.effort,permissions:e.permissions,name:e.name,system:e.system,wait:!0,flowRunId:n?.runId}}async function vr(e,t,n,r){let i=t.cwd?x.resolve(t.cwd):n?.cwd??y.cwd(),a;for(;;){let o=await Bn({prompt:e,..._r(t,i,n),...a?{agent:a,model:void 0,effort:void 0,resume:void 0}:{resume:r??t.resume},onFallback:e=>Or(`${e.agent} failed to start — falling back to ${e.next} (${e.detail.replace(/\s+/g,` `).slice(0,140)})`)});n?.running.add(o.taskId);let s=h(i,o.taskId),c=s?Ce(s):void 0;n?.hooks.onTaskStart?.({taskId:o.taskId,name:t.name,prompt:e,agent:c,depth:cr()});let l;try{l=await Gn(i,o.taskId)}finally{n?.running.delete(o.taskId)}let u=Vn(i,l);if(u){n?.hooks.onTaskEnd?.({taskId:o.taskId,status:`failed`,tokens:null}),a=u;continue}return{taskId:o.taskId,status:l.status,output:l.result?.finalMessage||l.result?.error?.message||``,tokens:l.result?.tokens??null,model:l.result?.model??l.job.model??null}}}async function yr(e,t,n){let r=e;if(t.returns&&(r=`${e}\n\n${await mr(t.returns)}`),n?.dryRun){y.stdout.write(`\n[dry-run] task${t.name?` (${t.name})`:``}:\n${r}\n`);let e={...t,returns:t.returns?`<schema>`:void 0};return y.stdout.write(`[dry-run] opts: ${JSON.stringify(e)}\n`),{taskId:`dry`,status:`completed`,output:`[dry-run]`,data:void 0,tokens:null,model:t.model??null}}let i=await vr(r,t,n);if(i.status!==`completed`){let e={...i,data:void 0};throw new G(`task-failed`,`Task ${i.taskId} ${i.status}: ${i.output||`no output`}`,{taskId:i.taskId,result:e})}let a=i.output,o=i.tokens,s;if(t.returns){let e;try{e=gr(t.returns,hr(a))}catch(t){e={ok:!1,errors:t instanceof Error?t.message:String(t)}}if(e.ok)s=e.data;else{let r=await vr(`Your previous reply did not match the required format: ${e.errors}\n\n${await mr(t.returns)}`,t,n,i.taskId);a=r.output||a,o=ur(o,r.tokens);try{let e=gr(t.returns,hr(a));if(!e.ok)throw Error(e.errors);s=e.data}catch(e){let t={taskId:i.taskId,status:`completed`,output:a,data:void 0,tokens:o,model:i.model};throw new G(`task-failed`,`Task ${i.taskId} produced no valid structured output: ${e instanceof Error?e.message:String(e)}`,{taskId:i.taskId,result:t})}}}return{taskId:i.taskId,status:`completed`,output:a,data:s,tokens:o,model:i.model}}async function br(e){if(e)return await pr(e)??`<schema>`}async function xr(e,t={}){let n=q.getStore();if(!n)return yr(e,t);let r=ir(`task`,{prompt:e,agent:t.agent,model:t.model,effort:t.effort,permissions:t.permissions,name:t.name,system:t.system,resume:t.resume,cwd:t.cwd,returns:await br(t.returns)}),i=n.journal.replay(r);if(i)return i.result;if(n.taskCount+=1,n.taskCount>n.maxTasks)throw Error(`Flow exceeded --max-tasks (${n.maxTasks}). Raise it with --max-tasks, or fix a runaway loop; the run is resumable.`);return n.semaphore.run(async()=>{let i=new Date().toISOString(),a;try{a=await yr(e,t,n)}catch(e){let t=e instanceof G?e.result:void 0;throw t&&n.hooks.onTaskEnd?.({taskId:t.taskId,status:t.status===`completed`?`failed`:t.status,tokens:t.tokens}),e}return dr(n,a),n.dryRun||n.hooks.onTaskEnd?.({taskId:a.taskId,status:a.status,tokens:a.tokens}),n.journal.record({kind:`task`,fingerprint:r,result:a,taskId:a.taskId,tokens:a.tokens,startedAt:i,endedAt:new Date().toISOString()}),a})}const Sr=262144;let Cr=0;function wr(e){let t=[];for(let n=e;;){t.push(x.join(n,`node_modules`,`.bin`));let e=x.dirname(n);if(e===n)break;n=e}let n=y.platform===`win32`?`;`:`:`;return{...y.env,PATH:[...t,y.env.PATH??``].join(n)}}async function Tr(e,t){return new Promise(n=>{let r=S(e,{shell:!0,cwd:t,env:wr(t)}),i=``,a=e=>{i.length>=Sr||(i+=e,i.length>=Sr&&(i=`${i.slice(0,Sr)}\n... [gate output truncated]`))};r.stdout?.on(`data`,a),r.stderr?.on(`data`,a),r.on(`error`,e=>n({ok:!1,code:1,output:String(e.message??e).trim()})),r.on(`close`,e=>n({ok:e===0,code:e??0,output:i.trim()}))})}async function Er(e,t={}){let n=q.getStore(),r=t.cwd?x.resolve(t.cwd):n?.cwd??y.cwd();if(!n)return Tr(e,r);let i=ir(`gate`,{cmd:e,cwd:t.cwd}),a=n.journal.replay(i);if(a)return a.result;if(n.dryRun){y.stdout.write(`\n[dry-run] gate: ${e}\n`);let t={ok:!0,code:0,output:``};return n.journal.record({kind:`gate`,fingerprint:i,result:t,startedAt:new Date().toISOString(),endedAt:new Date().toISOString()}),t}let o=new Date().toISOString(),s=`gate-${y.pid}-${Cr+=1}`,c=cr();n.hooks.onGateStart?.({gateId:s,cmd:e,depth:c});let l=await Tr(e,r);return n.hooks.onGate?.({gateId:s,cmd:e,ok:l.ok,code:l.code,depth:c}),n.journal.record({kind:`gate`,fingerprint:i,result:l,startedAt:o,endedAt:new Date().toISOString()}),l}async function Dr(e,...t){return Promise.all(e.map(async(e,n)=>{let r=e;for(let i of t)try{r=await i(r,e,n)}catch{return null}return r}))}function Or(e){let t=q.getStore();if(t)try{b.appendFileSync(x.join(t.runDir,`flow.log`),`${JSON.stringify({at:new Date().toISOString(),message:e})}\n`,`utf8`)}catch{}t?.hooks.onLog?t.hooks.onLog(e,cr()):(y.stderr.isTTY||!t)&&y.stderr.write(`[flow] ${e}\n`)}const kr=se(import.meta.url);function Ar(e){let t=x.dirname(le(import.meta.url));for(;x.basename(t)!==`dist`&&x.dirname(t)!==t;)t=x.dirname(t);return x.basename(t)===`dist`?ue(x.join(t,e)).href:null}function jr(e){if(!(e===`@wular/coder`||e===`@wular/coder/flow`||e===`zod`||e.startsWith(`zod/`)))return null;try{return ue(kr.resolve(e)).href}catch{}return e===`@wular/coder/flow`?Ar(`flow/index.js`):e===`@wular/coder`?Ar(`sdk.js`):null}const Mr=/(\bfrom\s+|\bimport\s+|\bimport\s*\(\s*)(['"])([^'"]+)\2/g;function Nr(e){return e.replace(Mr,(e,t,n,r)=>{let i=jr(r);return i?`${t}${n}${i}${n}`:e})}async function Pr(e,t,n){try{return await import(ue(e).href)}catch(e){let r=e instanceof Error?e.message:String(e);throw t===`.ts`&&!y.versions?.bun&&/Unknown file extension|Unexpected token|SyntaxError|Cannot parse|import type|interface/i.test(r)?Error(`Could not run ${x.basename(n)}: TypeScript flows need bun. Run under \`bun\`, or write the flow as .mjs/.js.`):e}}async function Fr(e){let t=x.extname(e),n;try{n=b.readFileSync(e,`utf8`)}catch{throw Error(`Cannot read flow file: ${e}`)}let r=Nr(n);if(r===n)return Pr(e,t,e);let i=x.dirname(e);try{for(let e of b.readdirSync(i)){if(!e.startsWith(`.__coderflow_`))continue;let t=x.join(i,e);Date.now()-b.statSync(t).mtimeMs>6e5&&b.unlinkSync(t)}}catch{}let a=`${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`,o=x.join(i,`.__coderflow_${a}${t}`),s=`__coderflow_loaded_${a}`,c=new Promise(e=>{globalThis[s]=e});b.writeFileSync(o,`globalThis[${JSON.stringify(s)}]?.();${r}`,`utf8`);let l=Pr(o,t,e);try{await Promise.race([c,l.then(()=>void 0,()=>void 0)])}finally{delete globalThis[s];try{b.unlinkSync(o)}catch{}}return await l}async function Ir(e,t){let n=J.getStore();n.args=t??{};let r=await Fr(e),i=r.args,a=n.args;if(fr(i)){let e=i.safeParse(t??{});if(!e.success){let e=gr(i,t??{});throw Error(`Invalid flow args: ${e.errors??`validation failed`}`)}a=e.data,n.args=a}let o=r.default;return typeof o==`function`?o(a):o}async function Lr(e,t){let n=q.getStore(),r=Zn(e,n?.cwd??y.cwd());if(!n)return J.run({args:t??{},depth:0},()=>Ir(r.path,t));let i=J.getStore();if(i&&i.depth>=1)throw Error(`flow("${e}") nesting is one level deep; a sub-flow cannot call flow().`);let a=ir(`flow`,{name:r.name,args:t??{}}),o=n.journal.replay(a);if(o)return o.result;let s=new Date().toISOString();n.hooks.onFlowStart?.({name:r.name,depth:(i?.depth??0)+1});let c=await J.run({args:t??{},depth:(i?.depth??0)+1},()=>Ir(r.path,t));return n.journal.record({kind:`flow`,fingerprint:a,result:c,startedAt:s,endedAt:new Date().toISOString()}),c}function Rr(){return`flow-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Y(){return x.join(r(),`state`,`global`,`flows`)}function zr(){return x.join(r(),`state`,`global`,`flows-archived`)}function X(e){oe(e,`flow run id`);let t=x.join(Y(),e);if(b.existsSync(x.join(t,`flow.json`)))return t;let n=x.join(zr(),e);return b.existsSync(x.join(n,`flow.json`))?n:t}function Br(e){if(e.archived)return e;let t={...e,archived:!0,archivedAt:new Date().toISOString()};return Q(X(e.runId),t),t}function Vr(e){let t=Br(e),n=X(e.runId),r=x.join(zr(),e.runId);if(n!==r)try{b.mkdirSync(zr(),{recursive:!0}),b.renameSync(n,r)}catch{}return t}function Hr(e){let t=X(e.runId),n=x.join(Y(),e.runId);if(t!==n)try{b.mkdirSync(Y(),{recursive:!0}),b.renameSync(t,n)}catch{}let r={...e,archived:void 0,archivedAt:void 0};return Q(X(e.runId),r),r}function Ur(e){let t=X(e);return b.existsSync(x.join(t,`flow.json`))?(b.rmSync(t,{recursive:!0,force:!0}),!0):!1}function Wr(e){if(!f(e))return null;let t=x.join(X(e),`flow.json`);if(!b.existsSync(t))return null;try{return JSON.parse(b.readFileSync(t,`utf8`))}catch{return null}}function Gr(e){return e.status!==`running`||!e.pid||ri(e)?e:(ei(e.runId,`orchestrator died`),Wr(e.runId)??e)}function Z(e){let t=Wr(e);return t?Gr(t):null}function Q(e,t){b.writeFileSync(x.join(e,`flow.json`),`${JSON.stringify(t,null,2)}\n`,`utf8`)}function Kr(e){let t=[];try{t=b.readdirSync(e)}catch{return[]}let n=[];for(let r of t)try{n.push(Gr(JSON.parse(b.readFileSync(x.join(e,r,`flow.json`),`utf8`))))}catch{}return n}const qr=(e,t)=>String(t.startedAt).localeCompare(String(e.startedAt));function Jr(){let e=[];for(let t of Kr(Y()))t.archived?Vr(t):e.push(t);return e.sort(qr)}function Yr(e){let t=e?.migrate??!0,n=Kr(zr()),r=new Set(n.map(e=>e.runId));for(let e of Kr(Y()))e.archived&&!r.has(e.runId)&&n.push(t?Vr(e):e);return n.sort(qr)}function Xr(){return[...Jr(),...Yr()].sort(qr)[0]??null}function Zr(e,t=`all`){if(t===0)return[];let n=K(x.join(X(e),`journal.jsonl`)).filter(e=>e.kind===`task`),r=u(y.cwd()),i=new Map(r.map(e=>[e.id,e])),a=e=>e?.name??e?.prompt?.replace(/\s+/g,` `).trim().slice(0,60)??null,o=n.map(e=>{let t=e.taskId?i.get(e.taskId):void 0;return{taskId:e.taskId??null,name:a(t),status:t?.status??e.result?.status??`?`,tokens:e.tokens??null}}),s=new Set(o.map(e=>e.taskId));for(let t of r)t.flowRunId===e&&!s.has(t.id)&&o.push({taskId:t.id,name:a(t),status:t.status,tokens:null});return t===`all`?o:o.slice(-t)}function Qr(e={}){let t;if(e.archived)t=Yr();else{let e=[];t=Jr().filter(t=>t.status===`running`||t.status===`queued`||ve(t.endedAt??t.startedAt)<=6e5||(Br(t),e.push(t.runId),!1)),Qn(y.cwd(),e,{flows:!0})}let n=e.limit===void 0?0:Math.max(0,t.length-e.limit);return{runs:e.limit===void 0?t:t.slice(0,e.limit),clipped:n}}function $r(e,t={},n){let r,i,a;if(n){let e=Z(n);if(!e)throw Error(`No flow run "${n}".`);e.archived&&Hr(e),r=e.name,i=e.script,a=t.args??e.args}else{let n=Zn(e,t.cwd?x.resolve(t.cwd):y.cwd());r=n.name,i=n.path,a=t.args??{}}let o=n??Rr(),s=X(o);b.mkdirSync(s,{recursive:!0});let c={runId:o,name:r,script:i,args:a,status:`running`,startedAt:new Date().toISOString(),concurrency:Math.max(1,t.concurrency??ce.cpus().length),maxTasks:Math.max(1,t.maxTasks??ce.cpus().length*10),taskCount:0,ledger:{}};return Q(s,c),c}function $(e,t,n){Q(e,{...t,endedAt:new Date().toISOString(),pid:void 0,pidStartedAt:void 0,...n})}function ei(e,t){let n=Wr(e);!n||n.status!==`running`||$(X(e),n,{status:`failed`,error:t})}const ti=`stop-keep-tasks`;function ni(e){try{return y.kill(e,0),!0}catch{return!1}}function ri(t){if(!t.pid||!ni(t.pid))return!1;let n=e(t.pid),r=Date.parse(t.pidStartedAt??``);return n===null||!Number.isFinite(r)||n<=r+6e4}function ii(e){let t=u(y.cwd()),n=new Map(t.map(e=>[e.id,e])),r=new Set(t.filter(t=>t.flowRunId===e).map(e=>e.id));for(let t of K(x.join(X(e),`journal.jsonl`)))t.kind===`task`&&t.taskId&&r.add(t.taskId);return[...r].filter(e=>{let t=n.get(e);return!!t&&!a.includes(t.status)})}async function ai(e,t=[]){let n=y.cwd(),r=[];for(let i of new Set([...ii(e),...t])){let e=h(n,i);if(!(!e||a.includes(e.status)))try{await tr(n,e),r.push(i)}catch{}}return r}async function oi(e,t={}){let n=e?Z(e):Xr();if(!n)throw new G(`flow-failed`,e?`No flow run "${e}".`:`No flow runs.`,{hint:`Run one: coder flow run <name>`});if(n.status!==`running`)throw new G(`flow-failed`,`Run ${n.runId} is not running.`,{runId:n.runId,hint:`Result: coder flow result ${n.runId}`});let r=X(n.runId);if(!ri(n))return $(r,n,{status:`failed`,error:`orchestrator died`}),{runId:n.runId,status:`failed`,stoppedTasks:[],keptTasks:ii(n.runId)};let i=ii(n.runId),o=x.join(r,ti);t.keepTasks&&b.writeFileSync(o,``,`utf8`);try{y.kill(n.pid,`SIGINT`);let e=Z(n.runId);for(let t=0;t<25&&e?.status===`running`;t+=1)await new Promise(e=>setTimeout(e,200)),e=Z(n.runId);if(!e||e.status===`running`)throw new G(`flow-failed`,`Run ${n.runId} did not stop within 5s.`,{runId:n.runId,hint:`Check it: coder flow result ${n.runId}`});let t=y.cwd(),r=[],o=[];for(let e of i){let n=h(t,e);n&&(n.status===`cancelled`?r.push(e):a.includes(n.status)||o.push(e))}return{runId:n.runId,status:e.status,stoppedTasks:r,keptTasks:o}}finally{if(t.keepTasks)try{b.unlinkSync(o)}catch{}}}async function*si(e,t,n={}){let r=x.join(X(e),`events.jsonl`),i=n.tail??`all`,a=0;if(i!==`all`)try{a=Math.max(0,b.readFileSync(r,`utf8`).split(`
18
- `).length-1-i)}catch{}let o=Qe(r),s=()=>{let e=[];for(let t of o()){if(a>0){--a;continue}try{e.push(JSON.parse(t))}catch{}}return e},c=Z(e);for(;!c||c.status===`running`;){yield*s();let n=c?.pid?!ri(c):t!==void 0&&!ni(t);if(c&&(c.pid||t!==void 0)&&n){ei(e,`orchestrator died`);break}await new Promise(e=>setTimeout(e,400)),c=Z(e)??c}yield*s()}function ci(e,t,n,r){let i={...$r(e,t,r),pid:y.pid,pidStartedAt:new Date().toISOString()},{runId:a}=i,o=X(a);Q(o,i);let s=x.join(o,`journal.jsonl`),c=r?K(s):[],l=new ar(c,s),u={runId:a,runDir:o,cwd:t.cwd?x.resolve(t.cwd):y.cwd(),journal:l,semaphore:new lr(i.concurrency),maxTasks:i.maxTasks,dryRun:t.dryRun??!1,ledger:{},running:new Set,taskCount:0,stopping:!1,hooks:n};return{started:{runId:a,runDir:o,ctx:u,markStopped:()=>{u.stopping=!0,$(o,i,{status:`stopped`,taskCount:u.taskCount,ledger:u.ledger})}},args:i.args,name:i.name,replayable:c.length}}async function li(e,t,n,r){let{ctx:i,runDir:a,runId:o}=e,s=Z(o);try{let e=await q.run(i,()=>J.run({args:r??{},depth:0},()=>Ir(t,r)));return $(a,s,{status:`completed`,taskCount:i.taskCount,ledger:i.ledger,result:e}),{runId:o,name:n,status:`completed`,result:e,tokens:i.ledger,taskCount:i.taskCount}}catch(e){throw i.stopping||$(a,s,{status:`failed`,taskCount:i.taskCount,ledger:i.ledger,error:e instanceof Error?e.message:String(e)}),new G(`flow-failed`,e instanceof Error?e.message:String(e),{runId:o})}}async function ui(e,t={},n={}){let{started:r}=ci(e,t,n),i=Z(r.runId).script;return n.onStart?.({runId:r.runId,requestStop:r.markStopped,runningIds:()=>[...r.ctx.running]}),li(r,i,Z(r.runId).name,t.args??{})}async function di(e,t={},n={}){let{started:r,args:i,name:a,replayable:o}=ci(``,t,n,e),s=Z(e).script;return n.onStart?.({runId:e,requestStop:r.markStopped,runningIds:()=>[...r.ctx.running]}),o&&n.onReplay?.(o),li(r,s,a,i)}export{R as $,Re as $t,Yn as A,Ze as At,Gn as B,Oe as Bt,xr as C,at as Ct,er as D,ut as Dt,tr as E,ct as Et,zn as F,De as Ft,Tn as G,ge as Gt,kn as H,xe as Ht,Bn as I,Le as It,xn as J,be as Jt,Dn as K,_e as Kt,In as L,Ee as Lt,G as M,Xe as Mt,Mn as N,Je as Nt,$n as O,Qe as Ot,Nn as P,Ye as Pt,Ht as Q,T as Qt,Wn as R,ve as Rt,si as S,dt as St,nr as T,N as Tt,jn as U,ye as Ut,En as V,D as Vt,On as W,Ce as Wt,B as X,we as Xt,wn as Y,ke as Yt,z as Z,Ie as Zt,di as _,I as _t,Ur as a,ze as an,mn as at,ai as b,ft as bt,Er as c,Te as cn,cn as ct,Jr as d,pn as dt,O as en,L as et,Or as f,fn as ft,Z as g,Ft as gt,$r as h,vn as ht,sr as i,A as in,H as it,Zn as j,qe as jt,Qn as k,M as kt,Xr as l,_n as lt,Dr as m,U as mt,Vr as n,Be as nn,Bt as nt,Lr as o,je as on,V as ot,ei as p,W as pt,Sn as q,k as qt,Qr as r,Ve as rn,dn as rt,Zr as s,Me as sn,sn as st,ti as t,Se as tn,zt as tt,Yr as u,ln as ut,X as v,Rt as vt,K as w,ot as wt,oi as x,lt as xt,ui as y,Lt as yt,Ln as z,Ae as zt};
@@ -1,36 +0,0 @@
1
- import{B as e,D as t,E as n,H as r,I as i,L as a,O as o,P as s,S as c,U as l,V as u,_ as d,c as f,d as p,f as m,h,j as g,k as _,l as v,m as y,o as b,p as x,s as S,u as C,x as w,z as T}from"./app-server-bHl6RBZ2.js";import{$ as ee,$t as te,Bt as ne,Et as re,G as ie,Gt as E,H as ae,Ht as oe,J as se,Jt as ce,K as le,Mt as ue,Ot as de,Qt as D,Rt as fe,U as pe,Ut as me,V as he,Vt as O,W as ge,Wt as _e,X as ve,Xt as ye,Y as be,Yt as k,Z as A,_t as j,at as M,cn as xe,ct as N,dt as Se,en as P,et as F,ft as Ce,g as we,gt as Te,ht as Ee,in as I,it as L,jt as De,k as Oe,kt as ke,lt as Ae,mt as je,nn as Me,ot as R,pt as z,q as Ne,rn as B,rt as V,st as H,tn as Pe,tt as Fe,vt as Ie,yt as Le,z as Re,zt as U}from"./runtime-DrTVUIwM.js";import W from"node:process";import G from"node:fs";import K from"node:path";import{spawnSync as ze}from"node:child_process";import Be from"node:os";import{fileURLToPath as Ve}from"node:url";import*as q from"zod/mini";import He from"node:crypto";import Ue from"node:http";let We=0;function Ge(e){let t=[];typeof e.instructions==`string`&&e.instructions&&t.push({role:`system`,content:e.instructions});let n=Array.isArray(e.input)?e.input:[];for(let e of n)switch(e?.type){case`message`:{let n=Array.isArray(e.content)?e.content.map(e=>e?.text??``).join(``):String(e.content??``);t.push({role:e.role===`developer`?`system`:e.role,content:n});break}case`function_call`:{let n={id:e.call_id,type:`function`,function:{name:e.name,arguments:e.arguments??`{}`}},r=t.at(-1);r?.role===`assistant`&&r.tool_calls?r.tool_calls.push(n):t.push({role:`assistant`,content:null,tool_calls:[n]});break}case`function_call_output`:{let n=e.output;t.push({role:`tool`,tool_call_id:e.call_id,content:typeof n==`string`?n:JSON.stringify(n??``)});break}}return t}function Ke(e){let t=(Array.isArray(e.tools)?e.tools:[]).filter(e=>e?.type===`function`).map(e=>({type:`function`,function:{name:e.name,description:e.description??``,parameters:e.parameters??{type:`object`,properties:{}}}})),n=e.text?.format;return{model:e.model,messages:Ge(e),...t.length?{tools:t,tool_choice:e.tool_choice??`auto`}:{},...typeof e.parallel_tool_calls==`boolean`?{parallel_tool_calls:e.parallel_tool_calls}:{},...n?.type===`json_schema`?{response_format:{type:`json_schema`,json_schema:{name:n.name,schema:n.schema,strict:n.strict??!1}}}:{},stream:!0,stream_options:{include_usage:!0}}}var qe=class{send;model;responseId=`resp_bridge_${++We}`;text=``;textOpen=!1;toolCalls=new Map;usage=null;buffer=``;constructor(e,t){this.model=e,this.send=t,this.send({type:`response.created`,response:{id:this.responseId,object:`response`,status:`in_progress`,model:e,output:[]}})}push(e){this.buffer+=e;let t=this.buffer.split(`
2
- `);this.buffer=t.pop()??``;for(let e of t){let t=e.trim();if(!t.startsWith(`data:`))continue;let n=t.slice(5).trim();if(!n||n===`[DONE]`)continue;let r;try{r=JSON.parse(n)}catch{continue}r.usage&&(this.usage=r.usage);let i=r.choices?.[0]?.delta;if(i){typeof i.content==`string`&&i.content&&(this.textOpen||(this.textOpen=!0,this.send({type:`response.output_item.added`,output_index:0,item:{type:`message`,id:`msg_bridge_0`,status:`in_progress`,role:`assistant`,content:[]}})),this.text+=i.content,this.send({type:`response.output_text.delta`,item_id:`msg_bridge_0`,output_index:0,content_index:0,delta:i.content}));for(let e of i.tool_calls??[]){let t=this.toolCalls.get(e.index)??{id:``,name:``,args:``};e.id&&(t.id=e.id),e.function?.name&&(t.name+=e.function.name),e.function?.arguments&&(t.args+=e.function.arguments),this.toolCalls.set(e.index,t)}}}}finish(){let e=[];if(this.text){let t={type:`message`,id:`msg_bridge_0`,status:`completed`,role:`assistant`,content:[{type:`output_text`,text:this.text,annotations:[]}]};e.push(t),this.send({type:`response.output_item.done`,output_index:0,item:t})}let t=e.length;for(let n of this.toolCalls.values()){let r={type:`function_call`,id:`fc_bridge_${t}`,call_id:n.id||`call_bridge_${t}`,name:n.name,arguments:n.args||`{}`,status:`completed`};e.push(r),this.send({type:`response.output_item.done`,output_index:t,item:r}),t+=1}this.send({type:`response.completed`,response:{id:this.responseId,object:`response`,status:`completed`,model:this.model,output:e,usage:{input_tokens:this.usage?.prompt_tokens??0,input_tokens_details:{cached_tokens:this.usage?.prompt_tokens_details?.cached_tokens??0},output_tokens:this.usage?.completion_tokens??0,output_tokens_details:{reasoning_tokens:this.usage?.completion_tokens_details?.reasoning_tokens??0},total_tokens:this.usage?.total_tokens??0}}})}};async function Je(e,t=`chat`){let n=t===`responses`,r=V(e.baseUrl,n?`responses`:`chat/completions`),i=null,a=e.envKey?W.env[e.envKey]:void 0;async function o(e){let t=i?[i]:r,n=null;for(let r of t)if(n=await fetch(r,{method:`POST`,headers:{"content-type":`application/json`,...a?{authorization:`Bearer ${a}`}:{}},body:e}),n.status!==404)return i=r,n;return n}let s=He.randomBytes(16).toString(`hex`),c=Ue.createServer((e,t)=>{if(e.method!==`POST`||!e.url?.startsWith(`/${s}/`)||!e.url.replace(/\/+$/,``).endsWith(`/responses`)){t.writeHead(404,{"content-type":`application/json`}),t.end(JSON.stringify({error:{message:`coder chat bridge: only POST /responses is supported`}}));return}let r=``;e.on(`data`,e=>r+=e),e.on(`end`,async()=>{let e;try{e=JSON.parse(r)}catch{t.writeHead(400,{"content-type":`application/json`}),t.end(JSON.stringify({error:{message:`invalid JSON`}}));return}try{if(n){let e=await o(r);if(t.writeHead(e.status,{"content-type":e.headers.get(`content-type`)??`application/json`,"cache-control":`no-store`}),e.body)for await(let n of e.body)t.write(n);t.end();return}let i=await o(JSON.stringify(Ke(e)));if(!i.ok||!i.body){let e=await i.text().catch(()=>``);t.writeHead(i.status,{"content-type":`application/json`}),t.end(e||JSON.stringify({error:{message:`upstream HTTP ${i.status}`}}));return}t.writeHead(200,{"content-type":`text/event-stream`,"cache-control":`no-store`});let a=new qe(e.model,e=>t.write(`data: ${JSON.stringify(e)}\n\n`)),s=new TextDecoder;for await(let e of i.body)a.push(s.decode(e,{stream:!0}));a.finish(),t.end()}catch(e){let n=e instanceof Error?e.message:String(e);t.writeHead(502,{"content-type":`application/json`}),t.end(JSON.stringify({error:{message:`coder chat bridge: ${n}`}}))}})});await new Promise(e=>c.listen(0,`127.0.0.1`,e));let l=c.address();return{url:`http://127.0.0.1:${typeof l==`object`&&l?l.port:0}/${s}/v1`,close:()=>new Promise(e=>{c.close(()=>e()),c.closeAllConnections?.()})}}async function Ye(e,t,n){let r=e.envKey?W.env[e.envKey]:void 0,i=!1;for(let a of V(e.baseUrl,t))try{let e=await fetch(a,{method:`POST`,headers:{"content-type":`application/json`,...r?{Authorization:`Bearer ${r}`}:{}},body:JSON.stringify(n),signal:AbortSignal.timeout(5e3)});if(i=!0,e.status!==404&&e.status!==405&&e.status!==501)return{baseUrl:a.slice(0,-(t.length+1))}}catch{}return{reachable:i}}async function Xe(e){let t=await Ye(e,`responses`,{model:e.model,input:[],stream:!1});if(`baseUrl`in t)return{wireApi:`responses`,baseUrl:t.baseUrl};let n=await Ye(e,`chat/completions`,{model:e.model,messages:[],stream:!1});return`baseUrl`in n?{wireApi:`chat`,baseUrl:n.baseUrl}:t.reachable||n.reachable?{wireApi:`chat`}:null}async function*Ze(e,t,n={}){let r=new Set([`completed`,`failed`,`cancelled`]),a=g(e,t);if(!a)throw Error(`No task found for "${t}".`);let o=n.tail??1,c=de(K.join(i(e,t),`log.jsonl`)),l=!0,u=()=>{let e=c();return l&&(l=!1,o!==`all`&&(e=o===0?[]:e.slice(-o))),e.map(e=>{try{return JSON.parse(e)}catch{return{message:e}}})};for(yield*u();!r.has(a.status);)await new Promise(e=>setTimeout(e,400)),a=s(e,g(e,t)??a),yield*u();yield*u()}async function Qe(e){let{options:t,positionals:n}=v(e,q.object({...b,tail:p,trim:q.optional(q.union([q.literal(`none`),q.coerce.number().check(q.int(),q.positive())],{error:`expected a positive integer or "none"`}))}));Me(n,1,`task watch`);let r=I(t),a=B(r,n[0]),o=t.tail,c=t.trim,l=c===void 0?300:c===`none`?2**53-1:c;if(!t.json){W.stdout.write(`${D.dim(`[coder] task ${a.id} ${a.status} — watching (Ctrl-C to stop)`)}\n`);let e=[`${D.dim(`agent`.padEnd(8))} ${_e(a)}`,...ye(a,D)];W.stdout.write(`${e.join(`
3
- `)}\n`),a.prompt&&W.stdout.write(`${Pe(a.prompt,D,{truncate:!1}).join(`
4
- `)}\n`)}for await(let e of Ze(r,a.id,{tail:o}))if(t.json){let t=e.message?{...e,message:xe(e.message,l,{plain:!0})}:e;W.stdout.write(`${JSON.stringify(t)}\n`)}else{let t=e.message??e.kind;t&&W.stdout.write(`${D.dim(`[coder]`)} ${xe(t,l)}\n`)}let u=s(r,g(r,a.id)??a),d=ke(K.join(i(r,a.id),`result.json`));if(t.json)P({taskId:a.id,status:u.status,result:d});else{let e=u.status===`completed`?`(no final message)`:`(task ${u.status})`;W.stdout.write(`\n${oe(d,u.error,e)}\n`);let t=d?.tokens?` tokens=${ce(d.tokens,d.model??u.model)}`:``;W.stderr.write(`${D.dim(`[coder] task=${a.id} status=${u.status}${t}`)}\n`)}W.exit(u.status===`completed`?0:1)}async function $e(e,t,n){if(t.status!==`running`)return null;if(t.engine!==`claude`&&(await Le(e,{threadId:t.threadId,text:n})).steered)return{taskId:t.id,steered:`live`};let r=g(e,t.id)??t;return u.includes(r.status)?(c(e,r.id,n),{taskId:r.id,steered:`queued`}):null}async function et(e,t,n,r={}){if(!t.threadId)throw Error(`Task ${t.id} has no thread to steer yet (status: ${t.status}).`);return await $e(e,t,n)||(tt(e,t,n,r),{taskId:t.id,steered:`resumed`})}function tt(t,n,r,i){e(t,n.id,{status:`queued`,resumedAt:new Date().toISOString(),currentPrompt:r,resumeThreadId:n.threadId,model:i.model??n.model??null,effort:i.effort??n.effort??null,permissions:i.permissions??n.permissions,error:void 0}),d(t,n.id,{message:`Resuming with steered follow-up.`}),Re(n.cwd??t,n.id)}async function nt(e){let{options:t,positionals:n}=v(e,q.object({...b,model:C,effort:C,permissions:C,background:S,wait:S})),r=I(t),[i,...a]=n,o=a.join(` `).trim();(!i||!o)&&O(`Missing task id or follow-up text.`,{hint:[`Usage: coder task steer <task-id> "<follow-up>" [--wait]`,`Help: coder task steer --help`]});let s=B(r,i);s.threadId||O(`Task ${s.id} has no thread to steer yet (status: ${s.status}).`,{hint:`Wait for it to start: coder task watch ${s.id}`});let c=await et(r,s,o,{model:t.model,effort:t.effort,permissions:t.permissions});return rt(r,c.taskId,{steered:c.steered,options:t})}async function rt(e,t,{steered:n,options:r}){if(n===`queued`){if(r.json){P({taskId:t,steered:`queued`});return}W.stdout.write(`${D.dim(`[coder]`)} follow-up queued for task ${D.cyan(t)}; it runs when the current turn finishes.\n`),r.wait&&W.stdout.write(`\n${D.dim(`[coder] --wait is not available for a queued follow-up; check: coder task result ${t}`)}\n`);return}if(!r.wait){if(r.json){P({taskId:t,steered:n});return}W.stdout.write(n===`live`?`${D.dim(`[coder]`)} steered follow-up into running task ${D.cyan(t)}.\n`:`${D.dim(`[coder]`)} resumed task ${D.cyan(t)} with the follow-up (same thread, same id).\n`),W.stdout.write(`\n${D.dim(` result: coder task result ${t}`)}\n`);return}let a=g(e,t),o=a?await T(e,a):null,s=ke(K.join(i(e,t),`result.json`));r.json?P({taskId:t,status:o?.status??null,finalMessage:s?.finalMessage??null}):(W.stdout.write(`\n${s?.finalMessage||`(no final message)`}\n\n`),W.stderr.write(`${D.dim(`[coder] task=${t} status=${o?.status??`unknown`}`)}\n`)),W.exitCode=o?.status===`completed`?0:1}const it=[`Read`,`Glob`,`Grep`];function at(e,t,n){return`You are a read-only sidecar answering a question ABOUT a coder task.
5
- You are not the task: never continue, redo, or fix its work — only answer the question. The task never sees this question or your answer.
6
-
7
- Task metadata:
8
- ${[`id: ${e.id}`,...e.name?[`name: ${e.name}`]:[],`status: ${e.status}`,`agent: ${e.agent}${e.model?`/${e.model}`:``}${e.effort?`/${e.effort}`:``}`,...e.cwd?[`workspace: ${e.cwd}`]:[],...e.createdAt?[`created: ${e.createdAt}`]:[],...e.completedAt?[`finished: ${e.completedAt}`]:[]].join(`
9
- `)}
10
-
11
- Task prompt:
12
- ${e.prompt??`(unknown)`}
13
-
14
- Inspect as needed (grep/read selectively; events can be large):
15
- - progress log (jsonl, one event per line): ${K.join(t,`log.jsonl`)}
16
- - final result: ${K.join(t,`result.json`)}
17
- - worker output: ${K.join(t,`worker.log`)}
18
- ${e.cwd?`- the task's workspace (its code and changes): ${e.cwd}`:``}
19
-
20
- Question: ${n}
21
-
22
- Answer the question directly and concisely.`}function ot(e,t,n,r){return{prompt:n,model:r.model??e.model,effort:r.effort,permissions:`read-only`,additionalDirectories:[t],readOnlyAllowedTools:it}}async function st(e,t,n,r={}){let a=i(e,t.id),o=at(t,a,n),s=r.effort??t.effort??null;if(t.engine===`claude`)return be(t.cwd??e,ot(t,a,o,{model:r.model,effort:s}));let c=H(e),l=r.model??t.model,u=l?c.models?.[l]:void 0,d=u&&R(u)?u:void 0;if(d?.envKey&&!W.env[d.envKey])throw Error(`Missing environment variable: \`${d.envKey}\`.`);let f=d?await Je(d,d.wireApi??`chat`):null,p=Ce(c,l,f??void 0);try{return await Ie(t.cwd??e,{prompt:o,model:p?.model??Se(l??null),modelProvider:p?.modelProvider??null,configOverrides:p?.configOverrides??null,effort:s,sandbox:`read-only`,approvalPolicy:`never`,ephemeral:!0})}finally{await f?.close()}}async function ct(e){let{options:t,positionals:n}=v(e,q.object({...b,model:C,effort:C})),r=I(t),[i,...a]=n,o=a.join(` `).trim();(!i||!o)&&O(`Missing task id or question.`,{hint:[`Usage: coder task ask <task-id> "<question>"`,`Help: coder task ask --help`]});let s=B(r,i);t.json||W.stderr.write(`${D.dim(`[coder]`)} asking about task ${D.cyan(s.id)} (read-only sidecar; the task is not interrupted)...\n`);let c=await st(r,s,o,{model:t.model,effort:t.effort}),l=c.finalMessage||``;if(t.json)P({taskId:s.id,answer:l||null,...c.error?{error:c.error.message}:{}});else if(l)W.stdout.write(`\n${l}\n`);else{let e=c.error?.message?` ${D.red(c.error.message)}`:``;W.stdout.write(`${D.dim(`(no answer)`)}${e}\n`)}W.exitCode=c.status===0?0:1}function lt(e,n={}){let i=n.limit===`all`?void 0:n.limit,s=e=>r.includes(e.status),c=[],l=o(e).filter(t=>{if(!s(t))return!0;let n=t.completedAt??t.updatedAt??t.createdAt;return fe(n)<=6e5||(_(e,t),c.push(t.id),!1)});if(Oe(e,c),n.archived?l=t(e):n.running?l=l.filter(e=>u.includes(e.status)):n.stopped&&(l=l.filter(s)),n.dir){let e=a(K.resolve(String(n.dir)));l=l.filter(t=>t.cwd&&a(t.cwd)===e)}if(!n.archived&&!n.running&&!n.stopped){let e=e=>e.status===`failed`?0:u.includes(e.status)?1:e.status===`completed`?3:2;l=[...l].sort((t,n)=>e(t)-e(n))}let d=i===void 0?0:Math.max(0,l.length-i);return i!==void 0&&(l=l.slice(0,i)),{jobs:l,clipped:d}}async function ut(e){let{options:r,positionals:a}=v(e,q.object({cwd:C,dir:C,limit:f,json:S,running:S,stopped:S,archived:S}));Me(a,0,`task list`);let o=I(r),s=r.limit===`all`?void 0:r.limit,{jobs:c,clipped:l}=lt(o,{running:r.running,stopped:r.stopped,archived:r.archived,dir:r.dir??r.cwd,limit:r.limit}),d=c.map(e=>{let t=u.includes(e.status)?re(i(o,e.id)).filter(e=>!e.response).length:0;return{taskId:e.id,status:t?`waiting-approval`:e.status,pendingApprovals:t,agent:e.agent??null,model:e.model??null,effort:e.effort??null,name:e.name??null,cwd:e.cwd??null,prompt:String(e.prompt??``).replace(/\s+/g,` `).trim().slice(0,80),updatedAt:e.updatedAt,archived:e.archived??!1,flowRunId:e.flowRunId??null,idleMs:u.includes(e.status)?fe(n(o,e)):null}});if(r.json){P(d);return}if(!d.length){let e=r.archived?`archived tasks`:r.running?`running tasks`:r.stopped?`recently stopped tasks`:`recent tasks`;W.stdout.write(`No ${e}.\n`);let n=[];if(!r.archived){let e=t(o,{migrate:!1}).length;e&&n.push(`${e} archived: coder task list --archived [--limit N]`)}n.length&&W.stdout.write(`\n${E(n,D)}\n`);return}let p=D,m=e=>(e.agent===`custom`&&e.model?e.model:(e.agent??`-`)+(e.model?`/${e.model}`:``))+(e.effort?`/${e.effort}`:``),h=e=>e.cwd?K.basename(e.cwd):`-`,g=(e,t,n)=>Math.min(t,Math.max(e,...n.map(e=>e.length))),_={id:g(7,28,d.map(e=>e.taskId)),status:g(6,16,d.map(e=>e.status)),who:g(5,26,d.map(m)),cwd:g(3,24,d.map(h))},y=e=>{let t=e.archived?` ${p.dim(`(archived)`)}`:``,n=e.name?e.name:p.light(e.prompt),r=e.idleMs!==null&&e.idleMs>=12e4?` ${(e.idleMs>6e5?p.red:p.dim)(`· idle ${me(e.idleMs)}`)}`:``;W.stdout.write(`${p.cyan(e.taskId.padEnd(_.id))} ${te(e.status,_.status)} ${p.light(ne(m(e),_.who))} ${p.light(ne(h(e),_.cwd))} ${n}${r}${t}\n`)};W.stdout.write(p.bold(p.light(`${`task-id`.padEnd(_.id)} ${`status`.padEnd(_.status)} ${`agent`.padEnd(_.who)} ${`cwd`.padEnd(_.cwd)} name\n`)));let b=new Map;for(let e of d)e.flowRunId&&(b.get(e.flowRunId)??b.set(e.flowRunId,[]).get(e.flowRunId)).push(e);let x=new Set,w=!1,T=!1;for(let e of d){if(!e.flowRunId){T&&W.stdout.write(`
23
- `),y(e),w=!0,T=!1;continue}if(x.has(e.flowRunId))continue;x.add(e.flowRunId);let t=we(e.flowRunId),n=t?`(${p.bold(e.flowRunId)} ${t.status} — flow ${t.name})`:`(${p.bold(e.flowRunId)} flow)`;W.stdout.write(`${w?`
24
- `:``}${n}\n`);for(let t of b.get(e.flowRunId))y(t);w=!0,T=!0}l&&W.stdout.write(p.dim(`\n... ${l} more not shown (--limit ${s})\n`));let ee=[`Result: coder task result <task-id>`];r.archived||ee.push(`Older tasks: coder task list --archived [--limit N]`),W.stdout.write(`\n${E(ee,p)}\n`)}function dt(){let e=process.env.CLAUDE_CONFIG_DIR||K.join(Be.homedir(),`.claude`);return K.join(e,`projects`)}function ft(e){if(!e)return!1;let t=dt(),n=!1;try{for(let r of G.readdirSync(t)){let i=K.join(t,r,`${e}.jsonl`);G.existsSync(i)&&(G.rmSync(i,{force:!0}),n=!0)}}catch{}return n}function J(e){e.threadId&&(e.engine===`codex`?l(e.threadId):e.engine===`claude`&&ft(e.threadId))}async function pt(e){let{options:n,positionals:r}=v(e,q.object({...b,"all-archived":S}));Me(r,1,`task delete`);let i=I(n);if(n[`all-archived`]){let e=t(i).filter(e=>(J(e),w(i,e.id))).map(e=>e.id);if(n.json){P({deleted:e,count:e.length});return}W.stdout.write(e.length?`Deleted ${e.length} archived task${e.length===1?``:`s`}.\n`:`${D.dim(`No archived tasks to delete.`)}\n`);return}let a=r[0];a||O(`Missing task id.`,{hint:[`Delete one: coder task delete <task-id>`,`Delete all archived: coder task delete --all-archived`]});let o=B(i,a);if(o.status===`running`&&O(`Task ${o.id} is still running.`,{hint:`Stop it first: coder task stop ${o.id}`}),J(o),w(i,o.id),n.json){P({taskId:o.id,deleted:!0});return}W.stdout.write(`Deleted task ${D.cyan(o.id)}.\n`)}function Y(e,t){return t.split(`.`).reduce((e,t)=>e?.[t],e)}function mt(e,t){return t?K.join(a(e),`coder.config.json`):z()}function ht(e,t){let n=H(e);return t?Y(n,t):n}function gt(e,t,n,r={}){let i=mt(e,r.workspace),a=G.existsSync(i)?JSON.parse(G.readFileSync(i,`utf8`)):{},o=t.split(`.`),s=o.at(-1),c=a;for(let e of o.slice(0,-1))(typeof c[e]!=`object`||c[e]===null)&&(c[e]={}),c=c[e];r.unset?delete c[s]:c[s]=n;let l=je(a);if(l.length)throw Error(`Refusing to write invalid config:\n ${l.join(`
25
- `)}`);return G.mkdirSync(K.dirname(i),{recursive:!0}),G.writeFileSync(i,`${JSON.stringify(a,null,2)}\n`,`utf8`),{file:i,key:t,effective:Y(H(e),t)??null,...r.unset?{unset:!0}:{value:n}}}async function _t(e){let{options:t,positionals:n}=v(e,q.object({...b,workspace:S})),r=I(t),[i=`list`,a,...o]=n,s=mt(r,t.workspace);if(i===`list`){let e=H(r);if(t.json){P(e);return}let n=D,i=e=>[e?.model,e?.effort,e?.permissions].filter(Boolean).join(`/`)||`-`;W.stdout.write([`${n.dim(`chain`)} ${e.chain.join(` -> `)}`,`${n.dim(`codex`)} ${i(e.agents.codex)}`,`${n.dim(`claude`)} ${i(e.agents.claude)}`,`${n.dim(`approvals`)} timeout=${e.approvals.escalationTimeoutMs}ms hosts=[${e.approvals.allowedNetworkHosts.join(`, `)}]`,`${n.dim(`file`)} ${z()}`].join(`
26
- `)+`
27
- `);return}if(i===`get`){a||O(`Usage: coder config get <key> (e.g. chain, agents.codex.model)`);let e=Y(H(r),a);if(t.json||e===null||typeof e==`object`&&e!==void 0){P(e===void 0?null:e);return}W.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}=gt(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=D,f=i===`set`?`${d.cyan(a)} = ${JSON.stringify(l)}`:`unset ${d.cyan(a)}`;W.stdout.write(`${f} ${d.dim(`(${s})`)}\n`)}async function vt(e,t={}){let n=j(e),r=pe(n);r?.updated&&(n=j(e));let i=n.available?await Te(e):{loggedIn:!1,detail:n.detail},a=se(),o=a.available?Ne():{loggedIn:!1,detail:a.detail},s=z();if(!G.existsSync(s)){let e=n.available?[`codex`,`claude`]:a.available?[`claude`,`codex`]:[`codex`,`claude`];Ee({...Fe,chain:e})}let c=h(),l=t.claude?ie(c):null,u=t.agents||t.codex?ge(c):null,d=H(e),f=n.available&&i.loggedIn||a.available&&o.loggedIn;return{codex:{available:n.available,detail:n.detail,auth:i.detail,loggedIn:i.loggedIn},...r?{codexUpdate:r}:{},claude:{available:a.available,detail:a.detail,auth:o.detail,loggedIn:o.loggedIn},configFile:s,runtime:Ve(new URL(`../bin/coder.mjs`,import.meta.url)),...l?{claudePlugin:l}:{},...u?{agentsSkill:u}:{},config:d,ready:f}}async function yt(e){let{options:t,positionals:n}=v(e,q.object({...b,codex:S,claude:S,agents:S})),r=I(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=D.bold,o=D.dim;t.json||W.stdout.write(`${a(`Coder host setup`)}\n\n`);let s=await vt(r,{claude:t.claude,codex:t.codex,agents:t.agents});if(t.json){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?k(`codex ${o(`${c.detail}; ${c.auth}`)}`):U(`codex not logged in ${o(`(${c.auth})`)} - run: codex login`):U(`codex CLI not installed - run: npm install -g @openai/codex`),y=l.available?l.loggedIn?k(`claude ${o(`${l.detail}; ${l.auth}`)}`):U(`claude not logged in - run: claude auth login`):U(`claude CLI not installed - run: npm install -g @anthropic-ai/claude-code`);g.push(a(`Available Engines`),_,y,` ${o(`custom models (local/provider endpoints): coder model --help`)}`),u?.updated?g.push(k(`codex ${o(`updated ${u.from} -> ${c.detail} (GPT-5.6 support)`)}`)):u&&g.push(U(`codex ${u.note}`)),g.push(``);let x=e=>{let t=d.agents?.[e]??{};return[t.model,t.effort,t.permissions].filter(Boolean).join(`/`)};g.push(a(`Config`),` chain: ${(d.chain??[]).join(` -> `)} codex: ${x(`codex`)} claude: ${x(`claude`)}`,` ${o(f)} ${o(`(coder config set <key> <value> to change)`)}`,``);let C=[[`claude plugin`,p??null],[`agents skill `,m??null]];for(let[e,t]of C)t&&g.push(t.installed?k(`${e} ${o(t.note)}`):U(`${e} ${t.note}`),``);g.push(h?k(`ready - try: coder run --wait "explain this repo's layout"`):U(`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)`)),W.stdout.write(`${g.join(`
28
- `)}\n`)}const bt=new Set([`codex`,`claude`,`custom`]);async function xt(e){let t=e.envKey?W.env[e.envKey]:void 0,n=V(e.baseUrl,`models`),r=null;for(let i of n)try{let n=await fetch(i,{headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(5e3)});if(!n.ok){r=n.status===404?{reachable:!0,modelListed:null,detail:`endpoint reachable (no model list to verify against)`}:{reachable:!1,modelListed:null,detail:`${i} -> HTTP ${n.status}`};continue}let a=await n.json().catch(()=>null),o=Array.isArray(a?.data)?a.data.map(e=>e.id):null;if(!o)return{reachable:!0,modelListed:null,detail:`endpoint reachable`};let s=o.includes(e.model);return{reachable:!0,modelListed:s,detail:s?`endpoint reachable; model "${e.model}" listed`:`endpoint reachable, but "${e.model}" is not in its model list`}}catch(e){r={reachable:!1,modelListed:null,detail:`${i} unreachable (${e instanceof Error?e.message:String(e)})`}}return r}function St(e,t){let n=G.existsSync(e)?JSON.parse(G.readFileSync(e,`utf8`)):{};t(n),n.models&&Object.keys(n.models).length===0&&delete n.models;let r=je(n);r.length&&O(`Refusing to write invalid config:\n ${r.join(`
29
- `)}`),G.mkdirSync(K.dirname(e),{recursive:!0}),G.writeFileSync(e,`${JSON.stringify(n,null,2)}\n`,`utf8`)}function X(e,t){St(e,e=>{e.models=e.models??{},t(e.models)})}const Z=q.object({...b,"base-url":C,model:C,"env-key":C,workspace:S});function Q(e,t){return e.workspace?K.join(a(t),`coder.config.json`):z()}function Ct(e){let t=e.models??{},n=Object.entries(t).filter(e=>R(e[1])),r=e=>`${e.provider}:${e.model}${e.effort?`:${e.effort}`:``}`,i=Object.entries(t).filter(e=>L(e[1])).map(([e,t])=>{let n=t.provider===`claude`?A:F,i=n[t.model]??t.model,a=M(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])=>!R(t)&&!L(t)&&!M(e)).map(([e,t])=>({name:e,disabled:!!t.disabled})),disabled:o}}async function wt(e){let{endpoints:t,providerRows:n,toggledSlugs:r}=Ct(H(e)),i=await Promise.all(t.map(async([e,t])=>({name:e,...t,probe:await xt(t)})));return{codex:n(`codex`,F),claude:n(`claude`,A),custom:i,...r.length?{toggles:r}:{}}}async function Tt(e){let{options:t,positionals:n}=v(e,Z);n.length&&O(`model list takes no arguments.`,{hint:`Usage: coder model list [--json]`});let r=I(t),i=D,{endpoints:a,providerRows:o,toggledSlugs:s,disabled:c}=Ct(H(r));if(t.json){P(await wt(r));return}let l=e=>c(e)?i.dim(`∅`):i.green(`✔`),u=e=>c(e)?` ${i.dim(`(disabled)`)}`:``,d=[],f=(e,t,n)=>{d.push(i.bold(e));for(let e of o(t,n))`overrides`in e?d.push(` ${e.disabled?i.dim(`∅`):i.cyan(`↳`)} ${e.alias.padEnd(14)} ${i.dim(`-> ${e.spec} (overrides ${e.overrides})`)}${e.disabled?` ${i.dim(`(disabled)`)}`:``}`):`builtin`in e?d.push(` ${l(e.alias)} ${e.alias.padEnd(14)} ${i.dim(`-> ${e.model}`)}${u(e.alias)}`):d.push(` ${e.disabled?i.dim(`∅`):i.cyan(`↳`)} ${e.alias.padEnd(14)} ${i.dim(`-> ${e.spec}`)}${e.disabled?` ${i.dim(`(disabled)`)}`:``}`);d.push(``)};if(f(`Codex models`,`codex`,F),f(`Claude models`,`claude`,A),d.push(i.bold(`Custom models`),``),!a.length)d.push(i.dim(` none — coder model add <name> --base-url <url> --model <id> [--env-key VAR]`));else for(let[e,t]of a){let n=await xt(t),r=t.disabled?i.dim(`∅`):n.reachable?i.green(`✔`):i.red(`✘`);d.push(` ${r} ${e.padEnd(14)} ${t.model} ${i.dim(`@ ${t.baseUrl} — ${n.detail}`)}${u(e)}`)}if(d.push(``),s.length){d.push(i.bold(`Other`),``);for(let e of s)d.push(` ${e.disabled?i.dim(`∅`):i.green(`✔`)} ${e.name.padEnd(14)} ${i.dim(`raw model id`)}${e.disabled?` ${i.dim(`(disabled)`)}`:``}`);d.push(``)}d.push(i.dim(`Alias one: coder model alias <name> <spec> (e.g. fast codex:spark)`),i.dim(`Use one: coder run --model <name> "<task>" (or coder run --agent custom)`)),W.stdout.write(`${d.join(`
30
- `)}\n`)}async function $(e,t,n,r){let i=await Xe(t),a=i?.wireApi===`responses`;i?(t.wireApi=i.wireApi,t.baseUrl=i.baseUrl??t.baseUrl):delete t.wireApi,X(n,n=>{n[e]=t});let o=await xt(t),s=ae(j(r)),c=j(r);return{name:e,entry:t,file:n,probe:o,codex:c,install:s,nativeResponses:a,keyMissing:!!(t.envKey&&!W.env[t.envKey]),ready:o.reachable&&c.available}}async function Et(e,t,n,r,i){let a=Q(n,r),o=D,{probe:s,codex:c,install:l,nativeResponses:u,keyMissing:d}=await $(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(`
31
- `))),W.stdout.write(`${m.join(`
32
- `)}\n`)}function Dt(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).`),(bt.has(e)||n===`model`&&M(e))&&O(`"${e}" is reserved; pick another name.`),e}async function Ot(e){let t=`Usage: coder model add <name> --base-url <url> --model <id> [--env-key VAR]`,{options:n,positionals:r}=v(e,Z),i=I(n),a=Dt(r[0],t,`model`),o=H(i).models?.[a];o&&O(R(o)?`Custom model "${a}" already exists.`:`"${a}" is already configured as an ${L(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 Et(a,{baseUrl:N(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}=v(e,Z),i=I(n),a=r[0],o=a?H(i).models?.[a]:void 0,s=o&&R(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 Et(a,{...s,...n[`base-url`]?{baseUrl:N(n[`base-url`])}:{},...n.model?{model:n.model}:{},...n[`env-key`]?{envKey:n[`env-key`]}:{}},n,i,`updated`)}async function At(e){let{options:t,positionals:n}=v(e,Z),r=I(t),i=n[0],a;try{a=zt(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}W.stdout.write(`removed ${D.cyan(a.removed)} ${D.dim(`(${a.file})`)}\n`)}async function jt(e){await Nt(e,!0)}async function Mt(e){await Nt(e,!1)}async function Nt(e,t){let n=t?`disable`:`enable`,r=`Usage: coder model ${n} <name>`,{options:i,positionals:a}=v(e,Z),o=I(i),s=a[0];s||O(`Missing model name.`,{hint:r});let{file:c}=Ht(o,s,t,{workspace:i.workspace});if(i.json){P({[t?`disabled`:`enabled`]:s,file:c});return}W.stdout.write(`${n}d ${D.cyan(s)} ${D.dim(`(${c})`)}\n`)}async function Pt(e){let t=`Usage: coder model alias <name> <spec> (e.g. coder model alias fast codex:spark)`,{options:n,positionals:r}=v(e,Z),i=I(n),a=Dt(r[0],t,`alias`),o=H(i).models?.[a];o&&R(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=Bt(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=D,u=`${c.provider} ${c.model}${c.effort?` (${c.effort})`:``}`;W.stdout.write(`aliased ${l.cyan(a)} -> ${c.provider}:${c.model}${c.effort?`:${c.effort}`:``} ${l.dim(`= ${u}`)} ${l.dim(`(${c.file})`)}\n`)}async function Ft(e){let{options:t,positionals:n}=v(e,Z),r=I(t),i=n[0],a=i?H(r).models?.[i]:void 0;(!i||!a||!L(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}=Vt(r,i,{workspace:t.workspace});if(t.json){P({unaliased:i,file:o});return}W.stdout.write(`unaliased ${D.cyan(i)} ${D.dim(`(${o})`)}\n`)}function It(e,t){if(!e)throw Error(`Missing model name.`);if(!/^[a-z][a-z0-9-]*$/.test(e))throw Error(`Invalid model name "${e}". Use lowercase kebab-case (e.g. qwen-local).`);if(bt.has(e)||t===`model`&&M(e))throw Error(`"${e}" is reserved; pick another name.`)}async function Lt(e,t,n){if(It(t,`model`),H(e).models?.[t])throw Error(`Custom model "${t}" already exists.`);if(!n.baseUrl||!n.model)throw Error(`Missing baseUrl or model.`);return $(t,{baseUrl:N(n.baseUrl),model:n.model,...n.envKey?{envKey:n.envKey}:{}},Q({workspace:n.workspace},e),e)}async function Rt(e,t,n){let r=H(e).models?.[t],i=r&&R(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 $(t,{...i,...n.baseUrl?{baseUrl:N(n.baseUrl)}:{},...n.model?{model:n.model}:{},...n.envKey?{envKey:n.envKey}:{}},Q({workspace:n.workspace},e),e)}function zt(e,t,n={}){if(!t||!H(e).models?.[t])throw Error(t?`No custom model named "${t}".`:`Missing model name.`);let r=Q({workspace:n.workspace},e);return X(r,e=>{delete e[t]}),{removed:t,file:r}}function Bt(e,t,n,r={}){It(t,`alias`);let i=H(e),a=i.models?.[t];if(a&&R(a))throw Error(`"${t}" is a custom model name; pick another alias name.`);if(!n)throw Error(`Missing alias spec.`);let o=Ae(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=>ee.has(e.trim())||ve.has(e.trim())),c=o.agent===`claude`?A:F,l={provider:o.agent,model:c[o.model]??o.model,...s&&o.effort?{effort:o.effort}:{}},u=Q({workspace:r.workspace},e);return X(u,e=>{e[t]=l}),{alias:t,...l,file:u}}function Vt(e,t,n={}){let r=t?H(e).models?.[t]:void 0;if(!t||!r||!L(r))throw Error(t?`No alias named "${t}".`:`Missing alias name.`);let i=Q({workspace:n.workspace},e);return X(i,e=>{delete e[t]}),{unaliased:t,file:i}}function Ht(e,t,n,r={}){if(!t)throw Error(`Missing model name.`);let i=!!H(e).models?.[t],a=Q({workspace:r.workspace},e);return X(a,e=>{let r=e[t];if(!r){n?e[t]={disabled:!0}:i&&(e[t]={disabled:!1});return}R(r)||L(r)?n?r.disabled=!0:delete r.disabled:n?r.disabled=!0:delete e[t]}),{name:t,disabled:n,file:a}}const Ut={list:Tt,add:Ot,setup:Ot,update:kt,remove:At,disable:jt,enable:Mt,alias:Pt,unalias:Ft};async function Wt(e){let[t,...n]=e;if(t===void 0||t.startsWith(`-`)){await Tt(e);return}let r=Ut[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 Gt=[{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 Kt(e){let t=K.join(e,`docs`),n=[];try{n=G.readdirSync(t).filter(e=>e.endsWith(`.md`)).sort()}catch{n=[]}let r=n.map(t=>{let n=K.join(`docs`,t);return{name:K.basename(t,`.md`),file:n,description:qt(K.join(e,n))}}),i=Gt.map(e=>({name:e.name,file:e.file,description:e.description}));return[...r,...i]}function qt(e){let t=``;try{t=G.readFileSync(e,`utf8`)}catch{return``}let n=t.split(`
33
- `),r=``,i=``,a=!1;for(let e of n){let t=e.trim();if(t.startsWith("```")){a=!a;continue}if(!(a||t===``)){if(t.startsWith(`#`)){r||=t.replace(/^#+\s*/,``);continue}i=t;break}}return Jt(i)||r}function Jt(e){if(!e)return``;let t=e.match(/^.*?[.!?](?=\s|$)/);return(t?t[0]:e).trim()}function Yt(e,t={}){let n=h(),r=Kt(n);if(!e)return{topics:r.map(e=>({name:e.name,description:e.description}))};let i=r.find(t=>t.name===e.toLowerCase());if(i?.name===`skill`&&t.claude&&(i={...i,file:`plugins/claude/skills/dispatch/SKILL.md`}),!i)throw Error(`Unknown docs topic "${e}". Available: ${r.map(e=>e.name).join(`, `)}`);let a=K.join(n,i.file),o;try{o=G.readFileSync(a,`utf8`)}catch{throw Error(`Could not read docs for "${i.name}" (${i.file}).`)}return{name:i.name,content:o}}async function Xt(e){let{options:t,positionals:n}=v(e,q.object({json:S,claude:S})),[r]=n,i;try{i=Yt(r,{claude:t.claude})}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){W.stdout.write(i.content.endsWith(`
34
- `)?i.content:`${i.content}\n`);return}if(t.json){P(i);return}let a=D,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)}`);W.stdout.write([a.bold(`Docs:`),...s,``,E([`Read a topic: coder docs <topic>`],a)].join(`
35
- `)+`
36
- `)}async function Zt(e={},t){let n=!e.pluginsOnly,r=!e.cliOnly,i=h(),a=K.join(i,`plugins/claude/.claude-plugin/plugin.json`),o={cli:y(),claude:x(a)},s={};if(n){let n=ue(m),[r,...i]=e.pm===`npm`?[`npm`,`install`,`-g`,`@wular/coder@latest`]:e.pm===`pnpm`?[`pnpm`,`add`,`-g`,`@wular/coder@latest`]:e.pm===`yarn`?[`yarn`,`global`,`add`,`@wular/coder@latest`]:e.pm===`bun`?[`bun`,`add`,`-g`,`@wular/coder@latest`]:n.command,a=e.pm??n.pm;t?.(`via ${a}`);let c=ze(r,i,{encoding:`utf8`});if(c.error?.code===`ENOENT`)throw Error(`${a} not found on PATH. Re-run with --pm <npm|pnpm|yarn|bun>, or update manually: ${r} ${i.join(` `)}`);if(c.status!==0){let e=(c.stderr||c.stdout||``).trim();throw Error(`CLI update failed (${a}).${e?`\n${e}`:``}\nRun manually: ${r} ${i.join(` `)}`)}De();let l=y();s.cli={pm:a,from:o.cli,to:l,changed:l!==o.cli}}if(r){if(e.claude||!e.codex&&se().available){let e=ie(i);s.claudePlugin={installed:e.installed,note:e.note,from:o.claude,to:x(a)}}if(G.existsSync(he())){let e=le(),t=ge(i);s.agentsSkill={installed:t.installed,note:t.note,from:e,to:le()}}}return s}async function Qt(e){let{options:t}=v(e,q.object({pm:C,"cli-only":S,"plugins-only":S,codex:S,claude:S})),n=D.bold,r=D.dim,i=(e,t)=>t&&e&&t!==e?`${e} ${r(`->`)} ${n(t)}`:`${t??e??`?`} ${r(`(unchanged)`)}`,a;try{a=await Zt({cliOnly:t[`cli-only`],pluginsOnly:t[`plugins-only`],pm:t.pm,codex:t.codex,claude:t.claude},e=>W.stdout.write(`${n(`Updating coder CLI`)} ${r(`${e}...`)}\n`))}catch(e){O(e instanceof Error?e.message:String(e))}if(a.cli&&W.stdout.write(a.cli.changed?`${k(`coder CLI ${i(a.cli.from,a.cli.to)}`)}\n`:`${k(`coder CLI ${a.cli.from} ${r(`(already latest)`)}`)}\n`),a.claudePlugin){let e=a.claudePlugin;W.stdout.write(`${e.installed?k(`claude plugin ${i(e.from,e.to)} ${r(`- ${e.note}`)}`):U(`claude plugin ${e.note}`)}\n`)}if(a.agentsSkill){let e=a.agentsSkill;W.stdout.write(`${e.installed?k(`agents skill ${i(e.from,e.to)} ${r(`- ${e.note}`)}`):U(`agents skill ${e.note}`)}\n`)}}export{ct as C,Ze as D,Qe as E,Xe as O,st as S,et as T,gt as _,Wt as a,lt as b,wt as c,Vt as d,Rt as f,ht as g,_t as h,Yt as i,Je as k,zt as l,vt as m,Zt as n,Lt as o,yt as p,Xt as r,Bt as s,Qt as t,Ht as u,pt as v,nt as w,ut as x,J as y};