craig-cli 0.7.4 → 0.7.5

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.
Files changed (2) hide show
  1. package/dist/cli.js +65 -65
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,38 +1,40 @@
1
1
  #!/usr/bin/env node
2
- var Na=Object.defineProperty;var mn=(e,t)=>{for(var n in t)Na(e,n,{get:t[n],enumerable:!0})};var gn={};mn(gn,{RUNNER_IDS:()=>j,assertEnabled:()=>Zr,buildCommand:()=>ns,getConfiguredProfile:()=>ht,getDefault:()=>Xr,getDisplayName:()=>ts,getEnabled:()=>wt,getProfile:()=>Ke,isRunnerType:()=>kt,parse:()=>es});var j=["codex","cursor","claude"];var Qr={codex:{id:"codex",displayName:"Codex",executable:"codex",defaultAgentTitle:"Codex"},cursor:{id:"cursor",displayName:"Cursor",executable:"cursor-agent",defaultAgentTitle:"Cursor"},claude:{id:"claude",displayName:"Claude",executable:"claude",defaultAgentTitle:"Claude"}};var Ke=e=>Qr[e];var ht=(e,t={})=>{let n=Ke(e),r=t.runners?.[e]?.path?.trim();return{...n,executable:r&&r.length>0?r:n.executable}};var wt=(e={})=>j.filter(t=>e.runners?.[t]?.enabled!==!1);var Xr=(e={})=>{let t=wt(e);if(t.length===0)throw new Error("No runners are enabled. Enable at least one runner in .craig/config.json.");return t.includes("codex")?"codex":t[0]};var Zr=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var kt=e=>j.includes(e);var es=e=>{if(!e||e.length===0)return"codex";if(!kt(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${j.join(", ")}.`);return e};var ts=e=>Ke(e).displayName;var ns=(e,t,n={})=>{let r=[ht(e,n).executable];return t&&t.length>0&&r.push(t),r};import{mkdir as Wa,readFile as _a,writeFile as Ba}from"node:fs/promises";import Ua from"node:path";var qa=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",rs=async e=>{try{return await _a(e,"utf8")}catch(t){if(qa(t))return null;throw t}},ss=async(e,t)=>{await Wa(Ua.dirname(e),{recursive:!0}),await Ba(e,t,"utf8")};var Rt=(e,t)=>{if(typeof e!="object"||e===null)throw new Error(`Craig config at ${t} is invalid. Expected a JSON object.`);let n=e;if(n.runners!==void 0){if(typeof n.runners!="object"||n.runners===null||Array.isArray(n.runners))throw new Error(`Craig config at ${t} is invalid. "runners" must be an object.`);for(let[r,s]of Object.entries(n.runners)){if(!j.includes(r))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" is not supported. Expected one of: ${j.join(", ")}.`);if(typeof s!="object"||s===null||Array.isArray(s))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" must be an object.`);let o=s;if(o.enabled!==void 0&&typeof o.enabled!="boolean")throw new Error(`Craig config at ${t} is invalid. "runners.${r}.enabled" must be a boolean.`);if(o.path!==void 0&&(typeof o.path!="string"||o.path.trim().length===0))throw new Error(`Craig config at ${t} is invalid. "runners.${r}.path" must be a non-empty string.`)}}if(n.checks!==void 0&&(typeof n.checks!="object"||n.checks===null||!Array.isArray(n.checks.commands)||!n.checks.commands.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "checks.commands" must be an array of strings.`);if(n.open!==void 0&&(typeof n.open!="object"||n.open===null||!Array.isArray(n.open.command)||!n.open.command.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "open.command" must be an array of strings.`);if(n.github!==void 0){if(typeof n.github!="object"||n.github===null)throw new Error(`Craig config at ${t} is invalid. "github" must be an object.`);if(n.github.mergeMethod!==void 0&&n.github.mergeMethod!=="merge"&&n.github.mergeMethod!=="rebase"&&n.github.mergeMethod!=="squash")throw new Error(`Craig config at ${t} is invalid. "github.mergeMethod" must be "merge", "rebase", or "squash".`);if(n.github.watchIntervalSeconds!==void 0&&(!Number.isInteger(n.github.watchIntervalSeconds)||n.github.watchIntervalSeconds<=0))throw new Error(`Craig config at ${t} is invalid. "github.watchIntervalSeconds" must be a positive integer.`)}return n};var hn=async(e,t={readConfigFile:rs})=>{let n=await t.readConfigFile(e.configFile);if(!n)return{};if(n.trimStart()[0]!=="{")throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`);let r;try{r=JSON.parse(n)}catch{throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`)}return Rt(r,e.configFile)};var wn=async(e,t,n={writeConfigFile:ss})=>{Rt(t,e.configFile),await n.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
3
- `)};var kn={};mn(kn,{checkForUpdate:()=>os,getCurrent:()=>Tt});var Tt=()=>{try{return"0.7.4"}catch{return"unknown"}};var Ka="https://registry.npmjs.org/craig-cli/latest",Va=3600*1e3,Ga={value:null},Ha=(e,t)=>{let n=d=>d.split(".").map(Number),[r=0,s=0,o=0]=n(e),[i=0,c=0,l=0]=n(t);return r!==i?r>i:s!==c?s>c:o>l},os=async(e={fetch:globalThis.fetch,getCurrent:Tt,cache:Ga})=>{let t=e.getCurrent(),n=Date.now();if(e.cache.value&&n-e.cache.value.cachedAt<Va)return e.cache.value.result;let r=null;try{let o=await e.fetch(Ka,{signal:AbortSignal.timeout(5e3)});o.ok&&(r=(await o.json()).version??null)}catch{}let s={current:t,latest:r,updateAvailable:r!==null&&r!==t&&Ha(r,t)};return e.cache.value={result:s,cachedAt:n},s};var b={load:hn,save:wn,runners:gn,version:kn};function is(e){let t=[...e];for(;t[0]==="--";)t.shift();if(t.length===0)return{mode:"interactive"};if(t.length>=3&&t[0]==="repo"&&t[1]==="add"){let n=t.slice(2).join(" ").trim();if(n.length===0)throw new Error(`Repo path cannot be empty.
2
+ var cl=Object.defineProperty;var Lr=(e,t)=>{for(var r in t)cl(e,r,{get:t[r],enumerable:!0})};var jr={};Lr(jr,{RUNNER_IDS:()=>N,assertEnabled:()=>$s,buildCommand:()=>Ms,getConfiguredProfile:()=>Ot,getDefault:()=>Ds,getDisplayName:()=>js,getEnabled:()=>Nt,getProfile:()=>Qe,isRunnerType:()=>Ft,parse:()=>Ls});var N=["codex","cursor","claude"];var As={codex:{id:"codex",displayName:"Codex",executable:"codex",defaultAgentTitle:"Codex"},cursor:{id:"cursor",displayName:"Cursor",executable:"cursor-agent",defaultAgentTitle:"Cursor"},claude:{id:"claude",displayName:"Claude",executable:"claude",defaultAgentTitle:"Claude"}};var Qe=e=>As[e];var Ot=(e,t={})=>{let r=Qe(e),n=t.runners?.[e]?.path?.trim();return{...r,executable:n&&n.length>0?n:r.executable}};var Nt=(e={})=>N.filter(t=>e.runners?.[t]?.enabled!==!1);var Ds=(e={})=>{let t=Nt(e);if(t.length===0)throw new Error("No runners are enabled. Enable at least one runner in .craig/config.json.");return t.includes("codex")?"codex":t[0]};var $s=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var Ft=e=>N.includes(e);var Ls=e=>{if(!e||e.length===0)return"codex";if(!Ft(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${N.join(", ")}.`);return e};var js=e=>Qe(e).displayName;var Ms=(e,t,r={})=>{let n=[Ot(e,r).executable];return t&&t.length>0&&n.push(t),n};import{mkdir as dl,readFile as ul,writeFile as pl}from"node:fs/promises";import fl from"node:path";var ml=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Os=async e=>{try{return await ul(e,"utf8")}catch(t){if(ml(t))return null;throw t}},Ns=async(e,t)=>{await dl(fl.dirname(e),{recursive:!0}),await pl(e,t,"utf8")};var Wt=(e,t)=>{if(typeof e!="object"||e===null)throw new Error(`Craig config at ${t} is invalid. Expected a JSON object.`);let r=e;if(r.runners!==void 0){if(typeof r.runners!="object"||r.runners===null||Array.isArray(r.runners))throw new Error(`Craig config at ${t} is invalid. "runners" must be an object.`);for(let[n,s]of Object.entries(r.runners)){if(!N.includes(n))throw new Error(`Craig config at ${t} is invalid. "runners.${n}" is not supported. Expected one of: ${N.join(", ")}.`);if(typeof s!="object"||s===null||Array.isArray(s))throw new Error(`Craig config at ${t} is invalid. "runners.${n}" must be an object.`);let o=s;if(o.enabled!==void 0&&typeof o.enabled!="boolean")throw new Error(`Craig config at ${t} is invalid. "runners.${n}.enabled" must be a boolean.`);if(o.path!==void 0&&(typeof o.path!="string"||o.path.trim().length===0))throw new Error(`Craig config at ${t} is invalid. "runners.${n}.path" must be a non-empty string.`)}}if(r.checks!==void 0&&(typeof r.checks!="object"||r.checks===null||!Array.isArray(r.checks.commands)||!r.checks.commands.every(n=>typeof n=="string")))throw new Error(`Craig config at ${t} is invalid. "checks.commands" must be an array of strings.`);if(r.open!==void 0&&(typeof r.open!="object"||r.open===null||!Array.isArray(r.open.command)||!r.open.command.every(n=>typeof n=="string")))throw new Error(`Craig config at ${t} is invalid. "open.command" must be an array of strings.`);if(r.github!==void 0){if(typeof r.github!="object"||r.github===null)throw new Error(`Craig config at ${t} is invalid. "github" must be an object.`);if(r.github.mergeMethod!==void 0&&r.github.mergeMethod!=="merge"&&r.github.mergeMethod!=="rebase"&&r.github.mergeMethod!=="squash")throw new Error(`Craig config at ${t} is invalid. "github.mergeMethod" must be "merge", "rebase", or "squash".`);if(r.github.watchIntervalSeconds!==void 0&&(!Number.isInteger(r.github.watchIntervalSeconds)||r.github.watchIntervalSeconds<=0))throw new Error(`Craig config at ${t} is invalid. "github.watchIntervalSeconds" must be a positive integer.`)}return r};var Mr=async(e,t={readConfigFile:Os})=>{let r=await t.readConfigFile(e.configFile);if(!r)return{};if(r.trimStart()[0]!=="{")throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`);let n;try{n=JSON.parse(r)}catch{throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`)}return Wt(n,e.configFile)};var Or=async(e,t,r={writeConfigFile:Ns})=>{Wt(t,e.configFile),await r.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
3
+ `)};var Nr={};Lr(Nr,{checkForUpdate:()=>Fs,getCurrent:()=>_t});var _t=()=>{try{return"0.7.5"}catch{return"unknown"}};var gl="https://registry.npmjs.org/craig-cli/latest",hl=3600*1e3,kl={value:null},wl=(e,t)=>{let r=d=>d.split(".").map(Number),[n=0,s=0,o=0]=r(e),[i=0,l=0,c=0]=r(t);return n!==i?n>i:s!==l?s>l:o>c},Fs=async(e={fetch:globalThis.fetch,getCurrent:_t,cache:kl})=>{let t=e.getCurrent(),r=Date.now();if(e.cache.value&&r-e.cache.value.cachedAt<hl)return e.cache.value.result;let n=null;try{let o=await e.fetch(gl,{signal:AbortSignal.timeout(5e3)});o.ok&&(n=(await o.json()).version??null)}catch{}let s={current:t,latest:n,updateAvailable:n!==null&&n!==t&&wl(n,t)};return e.cache.value={result:s,cachedAt:r},s};var S={load:Mr,save:Or,runners:jr,version:Nr};function Ws(e){let t=[...e];for(;t[0]==="--";)t.shift();if(t.length===0)return{mode:"interactive"};if(t.length>=3&&t[0]==="repo"&&t[1]==="add"){let r=t.slice(2).join(" ").trim();if(r.length===0)throw new Error(`Repo path cannot be empty.
4
4
 
5
- `+Q());return{mode:"command",command:{kind:"addRepo",path:n}}}if(t.length>=3&&t[0]==="workspace"&&t[1]==="add"){let n=t.slice(2).join(" ").trim();if(n.length===0)throw new Error(`Workspace path cannot be empty.
5
+ `+Z());return{mode:"command",command:{kind:"addRepo",path:r}}}if(t.length>=3&&t[0]==="workspace"&&t[1]==="add"){let r=t.slice(2).join(" ").trim();if(r.length===0)throw new Error(`Workspace path cannot be empty.
6
6
 
7
- `+Q());return{mode:"command",command:{kind:"addWorkspace",path:n}}}if(t.length===2&&t[0]==="repo"&&t[1]==="list")return{mode:"command",command:{kind:"listRepos"}};if(t.length===3&&t[0]==="repo"&&t[1]==="remove")return{mode:"command",command:{kind:"removeRepo",repoId:t[2].trim()}};if(t.length>=2&&t.length<=3&&t[0]==="workspace"&&t[1]==="list"){let n=t[2]==="--archived";if(t.length===3&&!n)throw new Error(`Unsupported command: ${t.join(" ")}
7
+ `+Z());return{mode:"command",command:{kind:"addWorkspace",path:r}}}if(t.length===2&&t[0]==="repo"&&t[1]==="list")return{mode:"command",command:{kind:"listRepos"}};if(t.length===3&&t[0]==="repo"&&t[1]==="remove")return{mode:"command",command:{kind:"removeRepo",repoId:t[2].trim()}};if(t.length>=2&&t.length<=3&&t[0]==="workspace"&&t[1]==="list"){let r=t[2]==="--archived";if(t.length===3&&!r)throw new Error(`Unsupported command: ${t.join(" ")}
8
8
 
9
- ${Q()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:n}}}if(t.length===3&&t[0]==="workspace"&&t[1]==="archive")return{mode:"command",command:{kind:"archiveWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="restore")return{mode:"command",command:{kind:"restoreWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="remove")return{mode:"command",command:{kind:"removeWorkspace",workspaceId:t[2].trim()}};if(t.length>=2&&t[0]==="task"&&t[1]==="new"){let n=t.indexOf("--repo"),r=t.indexOf("--workspace"),s=t.indexOf("--runner");if(n===-1&&r===-1)throw new Error(`Task creation now requires '--repo <repo-id>' or '--workspace <workspace-id>'.
9
+ ${Z()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:r}}}if(t.length===3&&t[0]==="workspace"&&t[1]==="archive")return{mode:"command",command:{kind:"archiveWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="restore")return{mode:"command",command:{kind:"restoreWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="remove")return{mode:"command",command:{kind:"removeWorkspace",workspaceId:t[2].trim()}};if(t.length>=2&&t[0]==="task"&&t[1]==="new"){let r=t.indexOf("--repo"),n=t.indexOf("--workspace"),s=t.indexOf("--runner");if(r===-1&&n===-1)throw new Error(`Task creation now requires '--repo <repo-id>' or '--workspace <workspace-id>'.
10
10
 
11
- `+Q());if(n!==-1&&r!==-1)throw new Error(`Task creation accepts either '--repo' or '--workspace', not both.
11
+ `+Z());if(r!==-1&&n!==-1)throw new Error(`Task creation accepts either '--repo' or '--workspace', not both.
12
12
 
13
- `+Q());let o=n===-1?void 0:t[n+1]?.trim()??"",i=r===-1?void 0:t[r+1]?.trim()??"",c=s===-1?void 0:b.runners.parse(t[s+1]?.trim()??""),d=t.filter((p,h)=>h>1&&h!==n&&h!==n+1&&h!==r&&h!==r+1&&h!==s&&h!==s+1).join(" ").trim();if(o!==void 0&&o.length===0)throw new Error(`Repo id cannot be empty.
13
+ `+Z());let o=r===-1?void 0:t[r+1]?.trim()??"",i=n===-1?void 0:t[n+1]?.trim()??"",l=s===-1?void 0:S.runners.parse(t[s+1]?.trim()??""),d=t.filter((u,g)=>g>1&&g!==r&&g!==r+1&&g!==n&&g!==n+1&&g!==s&&g!==s+1).join(" ").trim();if(o!==void 0&&o.length===0)throw new Error(`Repo id cannot be empty.
14
14
 
15
- `+Q());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
15
+ `+Z());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
16
16
 
17
- `+Q());if(d.length===0)throw new Error(`Task prompt cannot be empty.
17
+ `+Z());if(d.length===0)throw new Error(`Task prompt cannot be empty.
18
18
 
19
- `+Q());return{mode:"command",command:{kind:"createTask",...o?{repoId:o}:{},...i?{workspaceId:i}:{},prompt:d,...c?{runner:c}:{}}}}if(t.length>=2&&t.length<=4&&t[0]==="task"&&t[1]==="list"){if(t.length===2)return{mode:"command",command:{kind:"listTasks"}};if(t.length===4&&t[2]==="--repo")return{mode:"command",command:{kind:"listTasks",repoId:t[3].trim()}};throw new Error(`Unsupported command: ${t.join(" ")}
19
+ `+Z());return{mode:"command",command:{kind:"createTask",...o?{repoId:o}:{},...i?{workspaceId:i}:{},prompt:d,...l?{runner:l}:{}}}}if(t.length>=2&&t.length<=4&&t[0]==="task"&&t[1]==="list"){if(t.length===2)return{mode:"command",command:{kind:"listTasks"}};if(t.length===4&&t[2]==="--repo")return{mode:"command",command:{kind:"listTasks",repoId:t[3].trim()}};throw new Error(`Unsupported command: ${t.join(" ")}
20
20
 
21
- ${Q()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:me(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:me(t[2]),repoId:za(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:me(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
21
+ ${Z()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:ke(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:ke(t[2]),repoId:Rl(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:ke(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
22
22
 
23
- ${Q()}`)}function Q(){return["Craig commands:"," craig Show the Craig phase 0 placeholder"," craig repo add Register a repo in the current Craig workspace"," craig workspace add <path> Register a repo or parent-directory workspace"," craig repo list List registered repos"," craig repo remove Remove a registered repo"," craig workspace list List active workspaces"," craig workspace list --archived List archived workspaces"," craig workspace archive Archive a workspace"," craig workspace restore Restore an archived workspace"," craig workspace remove Remove an archived workspace"," craig task new --repo <repo-id> [--runner codex|cursor|claude] <prompt> Create a new Craig repo task"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude] <prompt> Create a new Craig workspace task"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task show Show details for a Craig task"," craig task logs Stream Craig-managed logs for a task"," craig task diff Show the current worktree diff for a task"," craig task attach Attach to a live task session"," craig task focus Focus the tmux pane for a task"," craig task open Open the task worktree or print its path"," craig task check Run configured checks for a task"," craig task commit Commit all task worktree changes"," craig link add Add a linked repo to a task"," craig link list List linked repos for a task"].join(`
24
- `)}function me(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
23
+ ${Z()}`)}function Z(){return["Craig commands:"," craig Show the Craig phase 0 placeholder"," craig repo add Register a repo in the current Craig workspace"," craig workspace add <path> Register a repo or parent-directory workspace"," craig repo list List registered repos"," craig repo remove Remove a registered repo"," craig workspace list List active workspaces"," craig workspace list --archived List archived workspaces"," craig workspace archive Archive a workspace"," craig workspace restore Restore an archived workspace"," craig workspace remove Remove an archived workspace"," craig task new --repo <repo-id> [--runner codex|cursor|claude] <prompt> Create a new Craig repo task"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude] <prompt> Create a new Craig workspace task"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task show Show details for a Craig task"," craig task logs Stream Craig-managed logs for a task"," craig task diff Show the current worktree diff for a task"," craig task attach Attach to a live task session"," craig task focus Focus the tmux pane for a task"," craig task open Open the task worktree or print its path"," craig task check Run configured checks for a task"," craig task commit Commit all task worktree changes"," craig link add Add a linked repo to a task"," craig link list List linked repos for a task"].join(`
24
+ `)}function ke(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
25
25
 
26
- ${Q()}`);return t}function za(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
26
+ ${Z()}`);return t}function Rl(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
27
27
 
28
- ${Q()}`);return t}import Ks from"node:path";import{readFile as Za,readdir as Gm,rm as Hm}from"node:fs/promises";import ec from"node:path";import{randomUUID as Ya}from"node:crypto";import{open as Ja,readFile as Um,rename as Qa,rm as Xa}from"node:fs/promises";import Rn from"node:path";async function _(e,t){let n=Rn.dirname(e),r=Rn.join(n,`.${Rn.basename(e)}.${process.pid}.${Date.now()}.${Ya()}.tmp`),s=await Ja(r,"w");try{let o=`${JSON.stringify(t,null,2)}
29
- `;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await Qa(r,e)}catch(o){throw await s.close().catch(()=>{}),await Xa(r,{force:!0}).catch(()=>{}),o}}async function Ve(e,t){let n=await Za(Tn(e,t),"utf8"),r=JSON.parse(n);return tc(r,Tn(e,t))}async function Me(e,t){await _(Tn(e,t.id),{...t,updatedAt:new Date().toISOString()})}function Tn(e,t){return ec.join(e.sessionsDir,`${t}.json`)}function tc(e,t){let n=sc(e);if(typeof n!="object"||n===null||typeof n.id!="string"||typeof n.taskId!="string"||typeof n.repoId!="string"||typeof n.workspaceId!="string"||n.substrate!=="tmux"||typeof n.sessionName!="string"||typeof n.paneId!="string"||!(n.windowTarget===null||typeof n.windowTarget=="string")||typeof n.worktreePath!="string"||!(n.logPath===null||typeof n.logPath=="string")||!Array.isArray(n.command)||!n.command.every(r=>typeof r=="string")||!["starting","running","exited","failed"].includes(n.status)||!(n.startedAt===null||typeof n.startedAt=="string")||!(n.exitedAt===null||typeof n.exitedAt=="string")||!(n.exitCode===null||typeof n.exitCode=="number")||!(n.lastAttachedAt===null||typeof n.lastAttachedAt=="string")||!rc(n.attach)||!nc(n.snapshot)||typeof n.createdAt!="string"||typeof n.updatedAt!="string")throw new Error(`Craig session record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function nc(e){return e===null||typeof e=="object"&&e!==null&&typeof e.paneId=="string"&&(typeof e.windowTarget=="string"||e.windowTarget===null)&&typeof e.alive=="boolean"&&typeof e.capturedAt=="string"}function rc(e){return typeof e=="object"&&e!==null&&e.detachChord==="ctrl+]"&&(e.lastSize===null||typeof e.lastSize=="object"&&e.lastSize!==null&&typeof e.lastSize.columns=="number"&&typeof e.lastSize.rows=="number")}function sc(e){let t=typeof e=="object"&&e!==null?e:{};return{id:t.id??"",taskId:t.taskId??"",repoId:t.repoId??"",workspaceId:t.workspaceId??"",substrate:t.substrate??"tmux",sessionName:t.sessionName??"",paneId:t.paneId??"",windowTarget:typeof t.windowTarget=="string"?t.windowTarget:null,worktreePath:t.worktreePath??"",logPath:typeof t.logPath=="string"?t.logPath:null,command:Array.isArray(t.command)?t.command.filter(n=>typeof n=="string"):[],status:t.status??"starting",startedAt:typeof t.startedAt=="string"?t.startedAt:null,exitedAt:typeof t.exitedAt=="string"?t.exitedAt:null,exitCode:typeof t.exitCode=="number"?t.exitCode:null,lastAttachedAt:typeof t.lastAttachedAt=="string"?t.lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:typeof t.attach=="object"&&t.attach!==null&&t.attach.lastSize&&typeof t.attach.lastSize.columns=="number"&&typeof t.attach.lastSize.rows=="number"?t.attach.lastSize:null},snapshot:t.snapshot&&typeof t.snapshot=="object"?{paneId:typeof t.snapshot.paneId=="string"?t.snapshot.paneId:t.paneId??"",windowTarget:typeof t.snapshot.windowTarget=="string"?t.snapshot.windowTarget:null,alive:!!t.snapshot.alive,capturedAt:typeof t.snapshot.capturedAt=="string"?t.snapshot.capturedAt:new Date().toISOString()}:null,createdAt:t.createdAt??"",updatedAt:t.updatedAt??""}}import{readFile as ac}from"node:fs/promises";import{readFile as oc}from"node:fs/promises";var ic=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return t.version===2&&typeof t.workspaceRoot=="string"&&Array.isArray(t.repoIds)&&t.repoIds.every(n=>typeof n=="string")&&Array.isArray(t.workspaceIds)&&t.workspaceIds.every(n=>typeof n=="string")&&Array.isArray(t.taskIds)&&t.taskIds.every(n=>typeof n=="string")&&Array.isArray(t.jobIds)&&t.jobIds.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},yt=(e,t,n)=>{if(!ic(e))throw new Error(`Craig index at ${n} is invalid. Remove or repair the file before rerunning Craig.`);if(e.workspaceRoot!==t)throw new Error(`Craig index at ${n} belongs to ${e.workspaceRoot}, not ${t}. Remove or repair the file before rerunning Craig.`);return e},ne=async e=>{let t=await oc(e.indexFile,"utf8");return yt(JSON.parse(t),e.workspaceRoot,e.indexFile)},Ce=async(e,t)=>{await _(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};async function B(e,t){let n=await ac(yn(e,t),"utf8"),r=JSON.parse(n);return cc(r,yn(e,t))}async function A(e,t){let n={...t,updatedAt:new Date().toISOString()};await _(yn(e,t.id),n)}async function Pn(e,t){let n=await ne(e);n.taskIds.includes(t)||await Ce(e,{...n,taskIds:[...n.taskIds,t]})}function yn(e,t){return`${e.tasksDir}/${t}.json`}function cc(e,t){let n=lc(e);if(!uc(n))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function lc(e){if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:bn(t.runner),repoId:typeof t.repoId=="string"?t.repoId:"legacy_repo",workspaceId:typeof t.workspaceId=="string"?t.workspaceId:"legacy_workspace",sessionId:typeof t.sessionId=="string"||t.sessionId===null?t.sessionId:null,selectedPtyTabId:typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null?t.selectedPtyTabId:null,linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(n=>typeof n=="string"):[],ptyTabs:mc(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:pc(t.repoTargets),runnerSession:t.runnerSession??dc(t),checks:yc(t),lastCommit:t.lastCommit??null,prs:Pc(t),artifacts:Cc(t),cleanup:xc(t)}}function dc(e){if(typeof e.title!="string")return null;let t=bn(e.runner);return{command:b.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}}function uc(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id=="string"&&typeof t.title=="string"&&typeof t.slug=="string"&&(t.type==="repo"||t.type==="project")&&typeof t.status=="string"&&b.runners.isRunnerType(t.runner??"")&&typeof t.repoId=="string"&&typeof t.workspaceId=="string"&&(typeof t.sessionId=="string"||t.sessionId===null)&&(typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null)&&Array.isArray(t.linkedRepoIds)&&t.linkedRepoIds.every(n=>typeof n=="string")&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&typeof t.branch=="string"&&cs(t.ptyTabs)&&(t.bundlePath===void 0||t.bundlePath===null||typeof t.bundlePath=="string")&&(t.selectedRepoTargetId===void 0||t.selectedRepoTargetId===null||typeof t.selectedRepoTargetId=="string")&&(t.repoTargets===void 0||fc(t.repoTargets))&&hc(t.runnerSession)&&wc(t.prompt)&&ls(t.checks)&&ds(t.lastCommit)&&Rc(t.prs)&&Tc(t.artifacts)&&ps(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"}function pc(e){if(Array.isArray(e))return e.filter(as)}function fc(e){return Array.isArray(e)&&e.every(as)}function as(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.repoId=="string"&&typeof t.branch=="string"&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&(t.status==="ready"||t.status==="unavailable"||t.status==="merged"||t.status==="closed")&&(typeof t.failureReason=="string"||t.failureReason===null)&&ls(t.checks)&&ds(t.lastCommit)&&us(t.pullRequest)&&ps(t.cleanup)}function mc(e){if(cs(e.ptyTabs))return e.ptyTabs;if(typeof e.id!="string"||typeof e.title!="string")return[];let t=typeof e.updatedAt=="string"?e.updatedAt:new Date().toISOString();return gc(e.id,e.title,t,bn(e.runner))}function gc(e,t,n,r){let s=b.runners.getProfile(r);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:b.runners.buildCommand(r),createdAt:n,updatedAt:n},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:n,updatedAt:n}]}function bn(e){return e&&b.runners.isRunnerType(e)?e:"codex"}function cs(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.id=="string"&&(t.kind==="agent"||t.kind==="terminal")&&typeof t.title=="string"&&Array.isArray(t.command)&&t.command.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string")}function hc(e){return typeof e=="object"&&e!==null&&Array.isArray(e.command)&&e.command.every(t=>typeof t=="string")&&(typeof e.pid=="number"||e.pid===null)&&(typeof e.startedAt=="string"||e.startedAt===null)&&(e.lastKnownState==="starting"||e.lastKnownState==="running"||e.lastKnownState==="exited"||e.lastKnownState==="failed")&&(typeof e.exitCode=="number"||e.exitCode===null)&&(typeof e.exitedAt=="string"||e.exitedAt===null)}function wc(e){return typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string"}function ls(e){return typeof e=="object"&&e!==null&&typeof e.source=="object"&&e.source!==null&&e.source.type==="repo_config"&&typeof e.source.path=="string"&&(typeof e.lastRunAt=="string"||e.lastRunAt===null)&&(e.status==="not_run"||e.status==="running"||e.status==="passed"||e.status==="failed")&&Array.isArray(e.commands)&&e.commands.every(t=>typeof t=="string")&&Array.isArray(e.results)&&e.results.every(t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.startedAt=="string"&&typeof t.finishedAt=="string"&&typeof t.exitCode=="number")}function ds(e){return e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string"}function us(e){return typeof e=="object"&&e!==null&&e.provider==="github"&&kc(e.requiredChecks)}function kc(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.name=="string"&&(t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown")&&(typeof t.conclusion=="string"||t.conclusion===null))}function Rc(e){return Array.isArray(e)&&e.every(us)}function Tc(e){return typeof e=="object"&&e!==null&&(typeof e.logPath=="string"||e.logPath===null)&&(typeof e.checkSummaryPath=="string"||e.checkSummaryPath===null)&&(typeof e.prDraftPath=="string"||e.prDraftPath===null)&&(typeof e.prStatusPath=="string"||e.prStatusPath===null)}function ps(e){return typeof e=="object"&&e!==null&&(typeof e.paneClosedAt=="string"||e.paneClosedAt===null)&&(typeof e.worktreeRemovedAt=="string"||e.worktreeRemovedAt===null)&&typeof e.preservedWorktree=="boolean"&&(typeof e.warning=="string"||e.warning===null)}function yc(e){return e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]}}function Pc(e){if(Array.isArray(e.prs))return e.prs.map(bc);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:fs(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:ms(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]}function bc(e){let t=e??{};return{provider:"github",owner:t.owner??null,repo:t.repo??null,number:typeof t.number=="number"?t.number:null,url:t.url??null,title:t.title??null,status:fs(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:Sc(t.reviewDecision),requiredChecks:ms(t.requiredChecks),comments:Ic(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}}function fs(e){return e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null}function Sc(e){return e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null}function Ic(e){return Array.isArray(e)?e.flatMap(t=>{if(typeof t!="object"||t===null)return[];let n=t;return typeof n.body!="string"||!n.body.trim()?[]:[{author:typeof n.author=="string"?n.author:null,body:n.body,createdAt:typeof n.createdAt=="string"?n.createdAt:null,url:typeof n.url=="string"?n.url:null}]}):[]}function ms(e){return Array.isArray(e)?e.map(t=>({...t,status:t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown"?t.status:"unknown",conclusion:t.conclusion??null})):[]}function Cc(e){let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}}function xc(e){return e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}}import{readFile as vc}from"node:fs/promises";async function Y(e){try{let t=await vc(e.uiStateFile,"utf8"),n=JSON.parse(t);return Ec(n,e.uiStateFile)}catch(t){if($c(t))return null;throw t}}async function H(e,t){await _(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function ge(){return{version:1,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null,selectedPtyTabId:null,inputMode:"control",focusedRegion:"tasks",activeTab:"agent",inspectorSection:"task",inspectionMode:"files",openInspectionKind:null,selectedFileTreePath:null,selectedFilePath:null,selectedDiffPath:null,collapsedFileTreePaths:[],selectedActionId:"commit",updatedAt:new Date().toISOString()}}function Ec(e,t){if(typeof e!="object"||e===null||e.version!==1||!(e.selectedRepoId===null||typeof e.selectedRepoId=="string")||!(e.selectedWorkspaceId===null||typeof e.selectedWorkspaceId=="string")||!(e.selectedTaskId===null||typeof e.selectedTaskId=="string")||!(e.selectedPtyTabId===void 0||e.selectedPtyTabId===null||typeof e.selectedPtyTabId=="string")||!Ge(e,"inputMode")||!Ge(e,"focusedRegion")||!Ge(e,"activeTab")||!Ge(e,"inspectorSection")||!Ge(e,"inspectionMode")||!Pt(e,"openInspectionKind")||!Pt(e,"selectedFileTreePath")||!Pt(e,"selectedFilePath")||!Pt(e,"selectedDiffPath")||!Ac(e,"collapsedFileTreePaths")||!Ge(e,"selectedActionId")||typeof e.updatedAt!="string")throw new Error(`Craig UI state at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e}function Ge(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Pt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Ac(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(n=>typeof n=="string"))}function $c(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}import{execFile as Dc}from"node:child_process";import{promisify as Mc}from"node:util";var gs=Mc(Dc);async function v(e,t,n={}){try{let r=await gs(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr}}catch(r){if(hs(r)){let s=r.stderr?.trim()||r.stdout?.trim()||r.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw r}}async function M(e,t,n={}){try{let r=await gs(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr,exitCode:0}}catch(r){if(hs(r))return{stdout:r.stdout??"",stderr:r.stderr??"",exitCode:typeof r.code=="number"?r.code:null};throw r}}function hs(e){return e instanceof Error}function bt(e){return`'${e.replace(/'/g,"'\\''")}'`}import{accessSync as Lc,constants as jc}from"node:fs";import{homedir as ws}from"node:os";import xe from"node:path";var Oc=[xe.join(ws(),".local","bin"),xe.join(ws(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function Rs(e=process.env){return Fc([...(e.PATH??"").split(xe.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:Oc])}function Le(e=process.env){return{...e,PATH:Rs(e).join(xe.delimiter)}}function Sn(e,t={}){if(e.includes(xe.sep)){let n=xe.isAbsolute(e)?e:xe.resolve(t.cwd??process.cwd(),e);return ks(n)?n:null}for(let n of Rs(t.env)){let r=xe.join(n,e);if(ks(r))return r}return null}function je(e,t={}){let n=Sn(e,t);if(n)return n;throw new Error(`Command not found: ${e}. Install it or add its directory to PATH. Craig also checks ~/.local/bin, /opt/homebrew/bin, and /usr/local/bin.`)}function ks(e){try{return Lc(e,jc.X_OK),!0}catch{return!1}}function Fc(e){return[...new Set(e)]}import{spawn as Nc}from"node:child_process";import{createHash as Wc}from"node:crypto";import _c from"node:path";var Bc="craig";async function Ts(e,t,n){let r=In(e,t),s=qc(),o=await v("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",r,"-n","runner",...s,"-c",n],{cwd:e}),i=Vc(o.stdout);return await Uc(e,r),i}async function Uc(e,t){let n=[["set-option","-t",t,"status","off"],["set-option","-t",t,"detach-on-destroy","off"],["set-window-option","-t",t,"pane-border-status","off"],["set-window-option","-t",t,"aggressive-resize","on"]];for(let r of n)await v("tmux",r,{cwd:e})}async function ys(e,t,n){await v("tmux",["resize-window","-t",t,"-x",`${n.columns}`,"-y",`${n.rows}`],{cwd:e})}async function Ps(e,t,n){await v("tmux",["send-keys","-t",e,t,"C-m"],{cwd:n})}async function bs(e,t,n){await v("tmux",["pipe-pane","-o","-t",e,`cat >> ${bt(t)}`],{cwd:n})}async function St(e,t,n,r){let s=r??Ss(e);if(n?await v("tmux",["select-window","-t",n],{cwd:e}):await v("tmux",["select-window","-t",t],{cwd:e}),await v("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await v("tmux",["switch-client","-t",s],{cwd:e});return}await Hc(e,["attach-session","-t",s])}function Ss(e){let n=_c.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",r=Wc("sha1").update(e).digest("hex").slice(0,8);return`${Bc}-${n}-${r}`}function In(e,t){return`${Ss(e)}-${t.toLowerCase()}`}function qc(){let e=Kc();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]}function Kc(){let e=[process.stdout,process.stderr,process.stdin];for(let t of e){let n="columns"in t?t.columns:void 0,r="rows"in t?t.rows:void 0;if(typeof n=="number"&&n>0&&typeof r=="number"&&r>0)return{columns:n,rows:r}}return null}function Vc(e){let t=Gc(e);if(t.length<3)throw new Error("tmux did not return the expected session, window, and pane targets for the Craig task session.");return{sessionName:t[0],windowTarget:t[1],paneId:t[2]}}function Gc(e){return e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0)}async function Hc(e,t){await new Promise((n,r)=>{let s=Nc("tmux",t,{cwd:e,stdio:"inherit"});s.on("error",r),s.on("exit",o=>{if(o===0){n();return}r(new Error(`tmux ${t.join(" ")} failed with exit code ${o??"unknown"}.`))})})}var Cn={async prepare(e,t){let n=e.runnerSession.command[0]??b.runners.buildCommand(e.runner)[0],r=Le();await v(je(n,{cwd:t.repoRoot,env:r}),["--help"],{cwd:t.repoRoot,env:r})},async launch(e,t){let n=e.runnerSession.command.length>0?e.runnerSession.command:b.runners.buildCommand(e.runner,e.prompt.value),r=je(n[0],{cwd:e.worktreePath,env:Le()});await Ps(t.session.paneId,[r,...n.slice(1)].map(s=>bt(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}};var et={async create(e,t){let n=await Ts(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await bs(n.paneId,t.logPath,t.repoRoot);let r=await Is({paneId:n.paneId,windowTarget:n.windowTarget,alive:!0}),s={id:t.sessionId,taskId:t.taskId,repoId:t.repoId,workspaceId:t.workspaceId,substrate:"tmux",sessionName:n.sessionName||In(t.repoRoot,t.taskId),paneId:n.paneId,windowTarget:n.windowTarget,worktreePath:t.worktreePath,logPath:t.logPath,command:t.command,status:"starting",startedAt:null,exitedAt:null,exitCode:null,lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:null},snapshot:r,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return await Me(e,s),s},async attach(e,t,n){let r=await et.snapshot(t,n);if(!r.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await St(n,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:r};return await Me(e,s),s},async resize(e,t,n,r){await ys(r,t.sessionName,n);let s={...t,attach:{...t.attach,lastSize:n}};return await Me(e,s),s},async write(){throw new Error("Direct session writes are owned by the terminal bridge.")},async read(){throw new Error("Direct session reads are owned by the terminal bridge.")},async terminate(e,t,n){let r={...t,status:"failed",exitedAt:new Date().toISOString(),snapshot:{...t.snapshot??{paneId:t.paneId,windowTarget:t.windowTarget,alive:!1,capturedAt:new Date().toISOString()},alive:!1,capturedAt:new Date().toISOString()},command:(n.length>0,t.command)};return await Me(e,r),r},async snapshot(e,t){return zc(e,t)}};async function zc(e,t){let n=await M("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return Is({paneId:e.paneId,windowTarget:e.windowTarget,alive:n.exitCode===0&&n.stdout.split(/\s+/).some(r=>r.trim()===e.paneId)})}async function Is(e){return{paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()}}import{mkdir as nt,rm as rl,writeFile as Ct}from"node:fs/promises";import D from"node:path";import{readFile as Yc,readdir as Jc,rm as Qc}from"node:fs/promises";import Cs from"node:path";var xn=(e,t)=>Cs.join(e.reposDir,`${t}.json`),xs=(e,t)=>{if(typeof e!="object"||e===null||typeof e.id!="string"||typeof e.name!="string"||typeof e.rootPath!="string"||typeof e.defaultBranch!="string"||typeof e.createdAt!="string"||typeof e.updatedAt!="string")throw new Error(`Craig repo record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e},de=async(e,t)=>{let n=xn(e,t),r=await Yc(n,"utf8");return xs(JSON.parse(r),n)},vn=async(e,t)=>{await _(xn(e,t.id),{...t,updatedAt:new Date().toISOString()})},tt=async e=>{let t=await Jc(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>de(e,Cs.basename(r.name,".json"))))).sort((r,s)=>r.name.localeCompare(s.name)||r.id.localeCompare(s.id))},vs=async(e,t)=>{await Qc(xn(e,t),{force:!0})};import{readFile as Xc,readdir as Zc,rm as el}from"node:fs/promises";import Es from"node:path";var En=(e,t)=>Es.join(e.workspacesDir,`${t}.json`),tl=e=>{if(typeof e!="object"||e===null)return e;let t=e,n=t.repoId??t.primaryRepoId;return{...t,kind:t.kind??"repo",name:t.name??n??t.id,rootPath:t.rootPath??"",primaryRepoId:t.primaryRepoId??n??"",repoId:t.kind==="project"?t.repoId:n,discoveredRepoIds:Array.isArray(t.discoveredRepoIds)?t.discoveredRepoIds.filter(r=>typeof r=="string"):t.kind==="project"?[]:n?[n]:[],linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(r=>typeof r=="string"):[]}},As=(e,t)=>{let n=tl(e);if(typeof n!="object"||n===null||typeof n.id!="string"||n.kind!=="repo"&&n.kind!=="project"||typeof n.name!="string"||typeof n.rootPath!="string"||typeof n.primaryRepoId!="string"||typeof n.branch!="string"||n.status!=="active"&&n.status!=="archived"||!Array.isArray(n.linkedRepoIds)||!(n.linkedRepoIds??[]).every(r=>typeof r=="string")||!(n.repoId===void 0||typeof n.repoId=="string")||!Array.isArray(n.discoveredRepoIds)||!(n.discoveredRepoIds??[]).every(r=>typeof r=="string")||!(n.archivedAt===null||typeof n.archivedAt=="string")||typeof n.createdAt!="string"||typeof n.updatedAt!="string")throw new Error(`Craig workspace record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n},Oe=async(e,t)=>{let n=En(e,t),r=await Xc(n,"utf8");return As(JSON.parse(r),n)},Fe=async(e,t)=>{await _(En(e,t.id),{...t,updatedAt:new Date().toISOString()})},re=async e=>{let t=await Zc(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>Oe(e,Es.basename(r.name,".json"))))).sort((r,s)=>r.id.localeCompare(s.id))},$s=async(e,t)=>{await el(En(e,t),{force:!0})};async function Ds(e,t){let n=await M("git",["show-ref","--verify","--quiet",`refs/heads/${t}`],{cwd:e});if(n.exitCode===0)return!0;if(n.exitCode===1)return!1;throw new Error(n.stderr.trim()||n.stdout.trim()||"Unable to check git branch state.")}async function An(e,t,n,r="main"){let s=r.trim()||"main";if((await M("git",["show-ref","--verify","--quiet",`refs/heads/${s}`],{cwd:e})).exitCode!==0)throw new Error(`Base branch '${s}' does not exist locally.`);let i=await nl(e,s);await v("git",["worktree","add","-b",t,n,i],{cwd:e})}async function nl(e,t){return(await M("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await M("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await M("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t}async function It(e){let t=await M("git",["status","--short"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"Unable to inspect git status.");return t.stdout.trim().length>0}async function Ms(e){await v("git",["add","-A"],{cwd:e})}async function Ls(e,t){await v("git",["commit","-m",t],{cwd:e})}async function js(e){let t=await v("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[n="",r=""]=t.stdout.trim().split(`
30
- `);if(!n||!r)throw new Error("Unable to read git HEAD commit metadata.");return{sha:n,message:r}}async function Os(e,t){let n=await ne(e),r=Ns(new Date),s=Ws(n.taskIds,r);for(;;){let o=`task_${r}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await Ds(t,i))return o;s+=1}}async function Fs(e){let t=await ne(e),n=Ns(new Date),r=Ws(t.taskIds,n);return`task_${n}_${String(r).padStart(2,"0")}`}function Ns(e){let t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return`${t}${n}${r}`}function Ws(e,t){let n=e.filter(r=>r.startsWith(`task_${t}_`)).map(r=>Number.parseInt(r.slice(-2),10)).filter(r=>Number.isInteger(r));return n.length===0?1:Math.max(...n)+1}var Bs=["AGENTS","md"].join(".");async function rt(e,t,n,r={}){let s=await de(e,t),o=await cl(e,s.id),i=await Os(e,s.rootPath),c=r.sessionId??null,l=`craig/${i}`,d=D.join(e.worktreesDir,s.id,i),p=D.join(e.logsDir,`${i}.log`),h=D.join(e.artifactsDir,i);await nt(D.dirname(d),{recursive:!0}),await nt(h,{recursive:!0}),await Ct(p,"","utf8");let R=sl(e,{taskId:i,repoId:s.id,workspaceId:o.id,sessionId:c,repoRoot:s.rootPath,prompt:n,runner:r.runner??"codex",config:r.config??{},branch:l,worktreePath:d});return await A(e,R),await Pn(e,i),await An(s.rootPath,l,d,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:c,workspaceId:o.id,task:R}}async function vt(e,t,n,r={}){let s=(await re(e)).find(x=>x.id===t&&x.status==="active");if(!s)throw new Error(`Workspace ${t} does not exist or is archived.`);if(s.kind!=="project"){if(!s.primaryRepoId)throw new Error(`Workspace ${t} is not task-capable.`);let x=await rt(e,s.primaryRepoId,n,r);return{...x,bundlePath:x.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await Fs(e),c=new Date().toISOString(),l=r.runner??"codex",d=r.sessionId??null,p=`craig/${i}`,h=D.join(e.craigDir,"task-bundles",i),R=D.join(e.logsDir,`${i}.log`),k=D.join(e.artifactsDir,i);await nt(h,{recursive:!0}),await nt(k,{recursive:!0}),await Ct(R,"","utf8");let I=await Promise.all(o.map(x=>de(e,x))),T=il(I),a=await Promise.all(I.map(x=>ol(e,x,i,p,D.join(h,T.get(x.id))))),G=a.find(x=>x.status==="ready")??a[0];if(!a.some(x=>x.status==="ready"))throw await rl(h,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${a.map(x=>`${x.repoId}: ${x.failureReason??"unknown error"}`).join("; ")}`);await Ct(D.join(h,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:n,repos:a.map(x=>({repoId:x.repoId,repoName:I.find($e=>$e.id===x.repoId)?.name??x.repoId,path:D.relative(h,x.worktreePath),status:x.status,worktreePath:x.worktreePath,failureReason:x.failureReason}))},null,2),"utf8"),await Ct(D.join(h,Bs),al({taskId:i,workspaceId:t,prompt:n,repos:I,repoTargets:a,bundlePath:h}),"utf8");let W=Us(i,n,c,l,r.config??{}),oe={id:i,title:n,slug:qs(n),type:"project",status:"draft",runner:l,repoId:G.repoId,workspaceId:s.id,sessionId:d,selectedPtyTabId:W[0]?.id??null,linkedRepoIds:o.filter(x=>x!==G.repoId),repoRoot:h,worktreePath:h,branch:p,bundlePath:h,selectedRepoTargetId:G.repoId,repoTargets:a,ptyTabs:W,runnerSession:{command:b.runners.buildCommand(l,n,r.config??{}),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:n},checks:G.checks,lastCommit:null,prs:[],artifacts:{logPath:D.relative(e.workspaceRoot,R),checkSummaryPath:D.relative(e.workspaceRoot,D.join(k,"check-summary.json")),prDraftPath:null,prStatusPath:D.relative(e.workspaceRoot,D.join(k,"pr-status.json"))},cleanup:xt(),lastFailureReason:a.every(x=>x.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:c,updatedAt:c};return await A(e,oe),await Pn(e,i),{repoId:G.repoId,repoRoot:h,sessionId:d,workspaceId:s.id,task:oe,bundlePath:h,repoTargets:a}}function Us(e,t,n,r="codex",s={}){let o=b.runners.getProfile(r);return[{id:`${e}:agent`,kind:"agent",title:o.defaultAgentTitle,command:b.runners.buildCommand(r,void 0,s),createdAt:n,updatedAt:n},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:n,updatedAt:n}]}function sl(e,t){let n=new Date().toISOString(),r=Us(t.taskId,t.prompt,n,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:qs(t.prompt),type:"repo",status:"draft",runner:t.runner,repoId:t.repoId,workspaceId:t.workspaceId,sessionId:t.sessionId,selectedPtyTabId:r[0]?.id??null,linkedRepoIds:[],repoRoot:t.repoRoot,worktreePath:t.worktreePath,branch:t.branch,ptyTabs:r,runnerSession:{command:b.runners.buildCommand(t.runner,t.prompt,t.config),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:t.prompt},checks:{...$n(D.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:D.relative(e.workspaceRoot,D.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:D.relative(e.workspaceRoot,D.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:D.relative(e.workspaceRoot,D.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:xt(),lastFailureReason:null,createdAt:n,updatedAt:n}}async function ol(e,t,n,r,s){await nt(D.dirname(s),{recursive:!0});try{return await An(t.rootPath,r,s,t.defaultBranch),{repoId:t.id,branch:r,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:$n(D.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:_s(),cleanup:xt()}}catch(o){return{repoId:t.id,branch:r,repoRoot:t.rootPath,worktreePath:s,status:"unavailable",failureReason:o instanceof Error?o.message:"Failed to create worktree.",checks:$n(D.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:_s(),cleanup:xt()}}}function il(e){let t=new Set(["manifest.json",Bs]),n=new Map;for(let r of e){let s=t.has(r.name)?`${r.name}-repo`:r.name,o=s,i=2;for(;t.has(o);)o=`${s}-${i}`,i+=1;t.add(o),n.set(r.id,o)}return n}function al(e){let t=new Map(e.repos.map(r=>[r.id,r.name])),n=e.repoTargets.map(r=>{let s=t.get(r.repoId)??r.repoId,o=D.relative(e.bundlePath,r.worktreePath),i=r.status==="ready"?"ready":`unavailable: ${r.failureReason??"unknown error"}`;return`- \`${o}/\` - ${s} (${r.repoId}, ${i})`}).join(`
31
- `);return["# Craig Project Task Bundle","","This directory is a Craig project task bundle. Repo work must happen inside the child repo worktrees listed below.","","Run repo Git commands from a repo worktree directory, not from the bundle root. Use `manifest.json` as the machine-readable source of truth for this bundle.","",`Task: \`${e.taskId}\``,`Workspace: \`${e.workspaceId}\``,`Prompt: ${e.prompt}`,"","## Repo Worktrees","",n,""].join(`
32
- `)}function $n(e){return{source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}}function _s(){return{provider:"github",number:null,url:null,baseBranch:null,headBranch:null,status:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,requiredChecks:[],comments:[],lastSyncedAt:null,lastSyncedHeadSha:null}}function xt(){return{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}}async function cl(e,t){let r=(await re(e)).find(s=>s.kind!=="project"&&s.primaryRepoId===t&&s.status==="active");if(!r)throw new Error(`Repo ${t} does not have an active workspace.`);return r}function qs(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-")}async function Vs(e,t,n,r={}){let s=n.trim(),o=await b.load(e),i=r.runner??b.runners.getDefault(o);if(b.runners.assertEnabled(i,o),t.trim().length===0)throw new Error(r.workspaceId?"Workspace id cannot be empty.":"Repo id cannot be empty.");if(s.length===0)throw new Error("Task prompt cannot be empty.");let c=r.workspaceId?await vt(e,r.workspaceId,s,{runner:i,config:o}):await rt(e,t,s,{runner:i,config:o}),l=c.task,d=b.runners.buildCommand(i,s,o),p=`session_${l.id}`,h=l.artifacts.logPath?Ks.resolve(e.workspaceRoot,l.artifacts.logPath):Ks.join(e.logsDir,`${l.id}.log`);try{await Cn.prepare(l,{repoRoot:c.repoRoot});let R=await et.create(e,{sessionId:p,taskId:l.id,repoId:c.repoId,workspaceId:c.workspaceId,repoRoot:c.repoRoot,worktreePath:l.worktreePath,logPath:h,command:d});await Cn.launch(l,{repoRoot:c.repoRoot,session:R});let k=new Date().toISOString();R={...R,status:"running",startedAt:k,command:d};let I={...l,status:"running",runner:i,sessionId:R.id,selectedPtyTabId:l.selectedPtyTabId,runnerSession:{command:R.command,pid:null,startedAt:k,lastKnownState:"running",exitCode:null,exitedAt:null}};return await A(e,I),await Me(e,R),await H({uiStateFile:e.uiStateFile},{...await Y({uiStateFile:e.uiStateFile})??ge(),selectedRepoId:I.repoId,selectedWorkspaceId:I.workspaceId,selectedTaskId:I.id,selectedPtyTabId:I.selectedPtyTabId}),{kind:"createTask",taskId:I.id,repoId:I.repoId,workspaceId:I.workspaceId,sessionId:R.id,status:I.status,branch:I.branch,worktreePath:I.worktreePath,runner:I.runner}}catch(R){let k={...l,sessionId:null,status:"draft",runnerSession:{...l.runnerSession,lastKnownState:"failed"},lastFailureReason:R instanceof Error?R.message:"Unknown Craig error"};throw await A(e,k),R}}async function he(e,t){let n=await ne(e),r=[],s=[];await Promise.all(n.taskIds.map(async c=>{try{r.push(await B(e,c))}catch(l){if(ll(l)){s.push(c);return}throw l}}));let i=(t?.includeClosed?r:r.filter(c=>c.status!=="closed")).filter(c=>!(t?.workspaceId&&c.workspaceId!==t.workspaceId||t?.repoId&&c.repoId!==t.repoId&&!(c.repoTargets??[]).some(l=>l.repoId===t.repoId)));return i.sort((c,l)=>c.id.localeCompare(l.id)),s.sort(),{kind:"listTasks",tasks:i,missingTaskIds:s,repoId:t?.repoId??null}}function ll(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}import{access as Dl}from"node:fs/promises";import oo from"node:path";import{mkdir as dl,readFile as gh,writeFile as hh}from"node:fs/promises";import ul from"node:path";import Gs from"node:path";function Et(e,t){return t?Gs.isAbsolute(t)?t:Gs.join(e.repoRoot,t):null}function V(e){return e.prs.length===0?null:[...e.prs].reverse().find(n=>n.status!=="merged"&&n.status!=="closed")??e.prs[e.prs.length-1]??null}function Dt(e){return e.status==="merged"||e.status==="closed"}function Hs(e,t){let n=e.prs.findIndex(s=>s.number!==null&&s.number===t.number),r=n>=0?e.prs.map((s,o)=>o===n?t:s):[...e.prs,t];return{...e,prs:r}}var zs=3,pl=1e3,fl=1e4;async function st(e){let t=await M("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")}async function Ln(e,t){let n=V(t),r=n?.number?String(n.number):t.branch,s=await v("gh",$t(r),{cwd:t.worktreePath}),o=JSON.parse(s.stdout);return On(e,t,o,n)}async function jn(e,t){let n=await M("gh",$t(t.branch),{cwd:t.worktreePath});if(n.exitCode!==0)return{discovered:!1,task:t};let r=JSON.parse(n.stdout);return{discovered:!0,task:await On(e,t,r,null)}}async function Js(e){let t=await M("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:yl(t.stdout.trim())}async function Qs(e,t,n){if(n.length===0)return[];let r=Pl(n),s=await ml(e,["api","graphql","-f",`query=${r}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`]),i=JSON.parse(s.stdout).data?.repository??{};return n.map((c,l)=>{let d=i[`item${l}`],p=bl(d);return{id:c.id,found:p!==null,view:p}})}async function ml(e,t){let n;for(let r=0;r<=zs;r+=1)try{return await v("gh",t,{cwd:e})}catch(s){if(n=s,r===zs||!gl(s))throw s;await wl(hl(r))}throw n}function gl(e){let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase();return t.includes("rate limit")||t.includes("secondary rate limit")||t.includes("abuse detection")||t.includes("api rate limit exceeded")||t.includes("you have exceeded")}function hl(e){let t=Number(process.env.CRAIG_GH_RATE_LIMIT_RETRY_BASE_MS)||pl,n=Math.min(t*2**e,fl),r=Math.floor(Math.random()*Math.max(1,Math.floor(n*.25)));return n+r}function wl(e){return new Promise(t=>setTimeout(t,e))}async function ot(e,t,n){let r=n.pullRequest.number?String(n.pullRequest.number):n.branch;if(n.pullRequest.number){let i=await v("gh",$t(r),{cwd:n.worktreePath}),c=Mn(JSON.parse(i.stdout));return n.pullRequest=c,await Dn(e,t,n.repoId,c),"synced"}let s=await M("gh",$t(r),{cwd:n.worktreePath});if(s.exitCode!==0)return"not_found";let o=Mn(JSON.parse(s.stdout));return n.pullRequest=o,await Dn(e,t,n.repoId,o),"discovered"}async function Xs(e,t,n){return On(e,t,n,V(t))}async function Zs(e,t,n,r){return Dn(e,t,n,Mn(r))}async function eo(e,t){let n=Et(e,t.artifacts.prStatusPath);n&&(await dl(ul.dirname(n),{recursive:!0}),await _(n,{taskId:t.id,prs:t.prs}))}function kl(e){return e.mergeable&&!Rl(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped")}function Rl(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Tl(e){if(e.length===0)return"checked";let t=[...e].reverse().find(n=>n.status!=="merged"&&n.status!=="closed")??e[e.length-1];return kl(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"}function $t(e){return["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"]}function yl(e){let t=e.replace(/\.git$/,""),n=t.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)$/);if(n?.[1]&&n[2])return{owner:n[1],name:n[2]};let r=t.match(/^git@github\.com:([^/]+)\/([^/]+)$/);if(r?.[1]&&r[2])return{owner:r[1],name:r[2]};let s=t.match(/^ssh:\/\/git@github\.com\/([^/]+)\/([^/]+)$/);return s?.[1]&&s[2]?{owner:s[1],name:s[2]}:null}function Pl(e){return`
28
+ ${Z()}`);return t}var G=(e,t)=>{let r=Fr(e);if(!yl(r))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},Fr=e=>{if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:Wr(t.runner),repoId:typeof t.repoId=="string"?t.repoId:"legacy_repo",workspaceId:typeof t.workspaceId=="string"?t.workspaceId:"legacy_workspace",sessionId:typeof t.sessionId=="string"||t.sessionId===null?t.sessionId:null,selectedPtyTabId:typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null?t.selectedPtyTabId:null,linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(r=>typeof r=="string"):[],ptyTabs:Sl(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:Pl(t.repoTargets),runnerSession:t.runnerSession??Tl(t),checks:Dl(t),lastCommit:t.lastCommit??null,prs:$l(t),artifacts:Ol(t),cleanup:Nl(t)}},Tl=e=>{if(typeof e.title!="string")return null;let t=Wr(e.runner);return{command:S.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}},yl=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id=="string"&&typeof t.title=="string"&&typeof t.slug=="string"&&(t.type==="repo"||t.type==="project")&&typeof t.status=="string"&&S.runners.isRunnerType(t.runner??"")&&typeof t.repoId=="string"&&typeof t.workspaceId=="string"&&(typeof t.sessionId=="string"||t.sessionId===null)&&(typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null)&&Array.isArray(t.linkedRepoIds)&&t.linkedRepoIds.every(r=>typeof r=="string")&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&typeof t.branch=="string"&&Bs(t.ptyTabs)&&(t.bundlePath===void 0||t.bundlePath===null||typeof t.bundlePath=="string")&&(t.selectedRepoTargetId===void 0||t.selectedRepoTargetId===null||typeof t.selectedRepoTargetId=="string")&&(t.repoTargets===void 0||bl(t.repoTargets))&&Cl(t.runnerSession)&&xl(t.prompt)&&Us(t.checks)&&qs(t.lastCommit)&&El(t.prs)&&Al(t.artifacts)&&Vs(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},Pl=e=>{if(Array.isArray(e))return e.filter(_s)},bl=e=>Array.isArray(e)&&e.every(_s),_s=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.repoId=="string"&&typeof t.branch=="string"&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&(t.status==="ready"||t.status==="unavailable"||t.status==="merged"||t.status==="closed")&&(typeof t.failureReason=="string"||t.failureReason===null)&&Us(t.checks)&&qs(t.lastCommit)&&Ks(t.pullRequest)&&Vs(t.cleanup)},Sl=e=>{if(Bs(e.ptyTabs))return e.ptyTabs;if(typeof e.id!="string"||typeof e.title!="string")return[];let t=typeof e.updatedAt=="string"?e.updatedAt:new Date().toISOString();return Il(e.id,e.title,t,Wr(e.runner))},Il=(e,t,r,n)=>{let s=S.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:S.runners.buildCommand(n),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},Wr=e=>e&&S.runners.isRunnerType(e)?e:"codex",Bs=e=>Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.id=="string"&&(t.kind==="agent"||t.kind==="terminal")&&typeof t.title=="string"&&Array.isArray(t.command)&&t.command.every(r=>typeof r=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"),Cl=e=>typeof e=="object"&&e!==null&&Array.isArray(e.command)&&e.command.every(t=>typeof t=="string")&&(typeof e.pid=="number"||e.pid===null)&&(typeof e.startedAt=="string"||e.startedAt===null)&&(e.lastKnownState==="starting"||e.lastKnownState==="running"||e.lastKnownState==="exited"||e.lastKnownState==="failed")&&(typeof e.exitCode=="number"||e.exitCode===null)&&(typeof e.exitedAt=="string"||e.exitedAt===null),xl=e=>typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string",Us=e=>typeof e=="object"&&e!==null&&typeof e.source=="object"&&e.source!==null&&e.source.type==="repo_config"&&typeof e.source.path=="string"&&(typeof e.lastRunAt=="string"||e.lastRunAt===null)&&(e.status==="not_run"||e.status==="running"||e.status==="passed"||e.status==="failed")&&Array.isArray(e.commands)&&e.commands.every(t=>typeof t=="string")&&Array.isArray(e.results)&&e.results.every(t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.startedAt=="string"&&typeof t.finishedAt=="string"&&typeof t.exitCode=="number"),qs=e=>e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string",Ks=e=>typeof e=="object"&&e!==null&&e.provider==="github"&&vl(e.requiredChecks),vl=e=>Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.name=="string"&&(t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown")&&(typeof t.conclusion=="string"||t.conclusion===null)),El=e=>Array.isArray(e)&&e.every(Ks),Al=e=>typeof e=="object"&&e!==null&&(typeof e.logPath=="string"||e.logPath===null)&&(typeof e.checkSummaryPath=="string"||e.checkSummaryPath===null)&&(typeof e.prDraftPath=="string"||e.prDraftPath===null)&&(typeof e.prStatusPath=="string"||e.prStatusPath===null),Vs=e=>typeof e=="object"&&e!==null&&(typeof e.paneClosedAt=="string"||e.paneClosedAt===null)&&(typeof e.worktreeRemovedAt=="string"||e.worktreeRemovedAt===null)&&typeof e.preservedWorktree=="boolean"&&(typeof e.warning=="string"||e.warning===null),Dl=e=>e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]},$l=e=>{if(Array.isArray(e.prs))return e.prs.map(Ll);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:Gs(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:Hs(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]},Ll=e=>{let t=e??{};return{provider:"github",owner:t.owner??null,repo:t.repo??null,number:typeof t.number=="number"?t.number:null,url:t.url??null,title:t.title??null,status:Gs(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:jl(t.reviewDecision),requiredChecks:Hs(t.requiredChecks),comments:Ml(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}},Gs=e=>e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null,jl=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Ml=e=>Array.isArray(e)?e.flatMap(t=>{if(typeof t!="object"||t===null)return[];let r=t;return typeof r.body!="string"||!r.body.trim()?[]:[{author:typeof r.author=="string"?r.author:null,body:r.body,createdAt:typeof r.createdAt=="string"?r.createdAt:null,url:typeof r.url=="string"?r.url:null}]}):[],Hs=e=>Array.isArray(e)?e.map(t=>({...t,status:t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown"?t.status:"unknown",conclusion:t.conclusion??null})):[],Ol=e=>{let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}},Nl=e=>e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null};import{readFile as gc}from"node:fs/promises";import{randomUUID as Fl}from"node:crypto";import{open as Wl,readFile as kg,rename as _l,rm as Bl}from"node:fs/promises";import _r from"node:path";async function B(e,t){let r=_r.dirname(e),n=_r.join(r,`.${_r.basename(e)}.${process.pid}.${Date.now()}.${Fl()}.tmp`),s=await Wl(n,"w");try{let o=`${JSON.stringify(t,null,2)}
29
+ `;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await _l(n,e)}catch(o){throw await s.close().catch(()=>{}),await Bl(n,{force:!0}).catch(()=>{}),o}}import{readFile as Ul,readdir as ql,rm as Kl}from"node:fs/promises";import zs from"node:path";var Br=(e,t)=>zs.join(e.workspacesDir,`${t}.json`),Vl=e=>{if(typeof e!="object"||e===null)return e;let t=e,r=t.repoId??t.primaryRepoId;return{...t,kind:t.kind??"repo",name:t.name??r??t.id,rootPath:t.rootPath??"",primaryRepoId:t.primaryRepoId??r??"",repoId:t.kind==="project"?t.repoId:r,discoveredRepoIds:Array.isArray(t.discoveredRepoIds)?t.discoveredRepoIds.filter(n=>typeof n=="string"):t.kind==="project"?[]:r?[r]:[],linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(n=>typeof n=="string"):[]}},Ys=(e,t)=>{let r=Vl(e);if(typeof r!="object"||r===null||typeof r.id!="string"||r.kind!=="repo"&&r.kind!=="project"||typeof r.name!="string"||typeof r.rootPath!="string"||typeof r.primaryRepoId!="string"||typeof r.branch!="string"||r.status!=="active"&&r.status!=="archived"||!Array.isArray(r.linkedRepoIds)||!(r.linkedRepoIds??[]).every(n=>typeof n=="string")||!(r.repoId===void 0||typeof r.repoId=="string")||!Array.isArray(r.discoveredRepoIds)||!(r.discoveredRepoIds??[]).every(n=>typeof n=="string")||!(r.archivedAt===null||typeof r.archivedAt=="string")||typeof r.createdAt!="string"||typeof r.updatedAt!="string")throw new Error(`Craig workspace record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},Ne=async(e,t)=>{let r=Br(e,t),n=await Ul(r,"utf8");return Ys(JSON.parse(n),r)},Fe=async(e,t)=>{await B(Br(e,t.id),{...t,updatedAt:new Date().toISOString()})},ie=async e=>{let t=await ql(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>Ne(e,zs.basename(n.name,".json"))))).sort((n,s)=>n.id.localeCompare(s.id))},Qs=async(e,t)=>{await Kl(Br(e,t),{force:!0})};import{readFile as Gl,readdir as Hl,rm as zl}from"node:fs/promises";import Js from"node:path";var Ur=(e,t)=>Js.join(e.reposDir,`${t}.json`),Xs=(e,t)=>{if(typeof e!="object"||e===null||typeof e.id!="string"||typeof e.name!="string"||typeof e.rootPath!="string"||typeof e.defaultBranch!="string"||typeof e.createdAt!="string"||typeof e.updatedAt!="string")throw new Error(`Craig repo record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e},ue=async(e,t)=>{let r=Ur(e,t),n=await Gl(r,"utf8");return Xs(JSON.parse(n),r)},qr=async(e,t)=>{await B(Ur(e,t.id),{...t,updatedAt:new Date().toISOString()})},pt=async e=>{let t=await Hl(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>ue(e,Js.basename(n.name,".json"))))).sort((n,s)=>n.name.localeCompare(s.name)||n.id.localeCompare(s.id))},Zs=async(e,t)=>{await zl(Ur(e,t),{force:!0})};import{readFile as Yl}from"node:fs/promises";var Ql=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return t.version===2&&typeof t.workspaceRoot=="string"&&Array.isArray(t.repoIds)&&t.repoIds.every(r=>typeof r=="string")&&Array.isArray(t.workspaceIds)&&t.workspaceIds.every(r=>typeof r=="string")&&Array.isArray(t.taskIds)&&t.taskIds.every(r=>typeof r=="string")&&Array.isArray(t.jobIds)&&t.jobIds.every(r=>typeof r=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},Bt=(e,t,r)=>{if(!Ql(e))throw new Error(`Craig index at ${r} is invalid. Remove or repair the file before rerunning Craig.`);if(e.workspaceRoot!==t)throw new Error(`Craig index at ${r} belongs to ${e.workspaceRoot}, not ${t}. Remove or repair the file before rerunning Craig.`);return e},ee=async e=>{let t=await Yl(e.indexFile,"utf8");return Bt(JSON.parse(t),e.workspaceRoot,e.indexFile)},ye=async(e,t)=>{await B(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};import{readdir as oc,stat as ic}from"node:fs/promises";import Ze from"node:path";import{readFile as Jl}from"node:fs/promises";async function J(e){try{let t=await Jl(e.uiStateFile,"utf8"),r=JSON.parse(t);return Xl(r,e.uiStateFile)}catch(t){if(ec(t))return null;throw t}}async function Y(e,t){await B(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function we(){return{version:1,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null,selectedPtyTabId:null,inputMode:"control",focusedRegion:"tasks",activeTab:"agent",inspectorSection:"task",inspectionMode:"files",openInspectionKind:null,selectedFileTreePath:null,selectedFilePath:null,selectedDiffPath:null,collapsedFileTreePaths:[],selectedActionId:"commit",updatedAt:new Date().toISOString()}}function Xl(e,t){if(typeof e!="object"||e===null||e.version!==1||!(e.selectedRepoId===null||typeof e.selectedRepoId=="string")||!(e.selectedWorkspaceId===null||typeof e.selectedWorkspaceId=="string")||!(e.selectedTaskId===null||typeof e.selectedTaskId=="string")||!(e.selectedPtyTabId===void 0||e.selectedPtyTabId===null||typeof e.selectedPtyTabId=="string")||!Je(e,"inputMode")||!Je(e,"focusedRegion")||!Je(e,"activeTab")||!Je(e,"inspectorSection")||!Je(e,"inspectionMode")||!Ut(e,"openInspectionKind")||!Ut(e,"selectedFileTreePath")||!Ut(e,"selectedFilePath")||!Ut(e,"selectedDiffPath")||!Zl(e,"collapsedFileTreePaths")||!Je(e,"selectedActionId")||typeof e.updatedAt!="string")throw new Error(`Craig UI state at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e}function Je(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Ut(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Zl(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(r=>typeof r=="string"))}function ec(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}import{realpath as ro}from"node:fs/promises";import no from"node:path";import{execFile as tc}from"node:child_process";import{promisify as rc}from"node:util";var eo=rc(tc);async function v(e,t,r={}){try{let n=await eo(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr}}catch(n){if(to(n)){let s=n.stderr?.trim()||n.stdout?.trim()||n.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw n}}async function M(e,t,r={}){try{let n=await eo(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr,exitCode:0}}catch(n){if(to(n))return{stdout:n.stdout??"",stderr:n.stderr??"",exitCode:typeof n.code=="number"?n.code:null};throw n}}function to(e){return e instanceof Error}var Kr=async e=>{try{let r=(await v("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[n,s]=await Promise.all([ro(r).catch(()=>no.resolve(r)),ro(e).catch(()=>no.resolve(e))]);return n===s}catch{return!1}},Vr=async e=>{let t=await M("git",["symbolic-ref","--quiet","--short","refs/remotes/origin/HEAD"],{cwd:e}),r=t.stdout.trim().replace(/^origin\//,"");if(t.exitCode===0&&r.length>0)return r;for(let o of["main","master","trunk"])if((await M("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await v("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"};import{mkdir as Re,readFile as nc}from"node:fs/promises";import te from"node:path";function Pe(e){let t=te.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:te.join(t,"index.json"),reposDir:te.join(t,"repos"),workspacesDir:te.join(t,"workspaces"),sessionsDir:te.join(t,"sessions"),runtimeDir:te.join(t,"runtime"),uiStateFile:te.join(t,"runtime","ui-state.json"),tasksDir:te.join(t,"tasks"),jobsDir:te.join(t,"jobs"),logsDir:te.join(t,"logs"),errorLogFile:te.join(t,"logs","errors.log"),artifactsDir:te.join(t,"artifacts"),worktreesDir:te.join(t,"worktrees"),configFile:te.join(t,"config.json")}}var sc=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Xe=async e=>{let t=Pe(e);await Re(t.craigDir,{recursive:!0}),await Promise.all([Re(t.reposDir,{recursive:!0}),Re(t.workspacesDir,{recursive:!0}),Re(t.sessionsDir,{recursive:!0}),Re(t.runtimeDir,{recursive:!0}),Re(t.tasksDir,{recursive:!0}),Re(t.jobsDir,{recursive:!0}),Re(t.logsDir,{recursive:!0}),Re(t.artifactsDir,{recursive:!0}),Re(t.worktreesDir,{recursive:!0})]);try{let s=await nc(t.indexFile,"utf8"),o=JSON.parse(s);return Bt(o,e,t.indexFile)}catch(s){if(!sc(s))throw s instanceof SyntaxError?new Error(`Craig index at ${t.indexFile} is malformed. Remove or repair the file before rerunning Craig.`):s}let r=new Date().toISOString(),n={version:2,workspaceRoot:e,repoIds:[],workspaceIds:[],taskIds:[],jobIds:[],createdAt:r,updatedAt:r};return await B(t.indexFile,n),n};var so=(e,t,r)=>{let n=new Date().toISOString();return{id:ac(e,Ze.basename(t)),name:Ze.basename(t),rootPath:t,defaultBranch:r,createdAt:n,updatedAt:n}},oo=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},ac=(e,t)=>{let r=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"repo",n=`repo_${r}`,s=2;for(;e.some(o=>o.id===n);)n=`repo_${r}_${s}`,s+=1;return n},lc=(e,t)=>{let r=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"workspace",n=`workspace_${r}`,s=2;for(;e.some(o=>o.id===n);)n=`workspace_${r}_${s}`,s+=1;return n},io=async(e,t)=>{let r=await ee(e);await ye(e,{...r,repoIds:[...new Set([...r.repoIds,...t.repoIds])],workspaceIds:[...new Set([...r.workspaceIds,...t.workspaceIds])]})},ao=async(e,t,r)=>{let n=await J({uiStateFile:e.uiStateFile})??we();await Y({uiStateFile:e.uiStateFile},{...n,selectedRepoId:r,selectedWorkspaceId:t.id,selectedTaskId:null})},cc=async(e,t)=>{let r=await oc(t,{withFileTypes:!0}),n=await pt(e),s=[];for(let o of r){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=Ze.join(t,o.name);if(!await Kr(i))continue;let l=n.find(d=>d.rootPath===i)??s.find(d=>d.rootPath===i),c=await Vr(i);s.push(l?oo(l,c):so([...n,...s],i,c))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))},dc=async(e,t)=>{let r=await Vr(t),n=await pt(e),s=n.find(g=>g.rootPath===t)??null,o=s?oo(s,r):so(n,t,r),i=`workspace_${o.id}`,c=(await ie(e)).find(g=>g.id===i)??null,d=new Date().toISOString(),u=c??{id:i,kind:"repo",name:o.name,rootPath:t,primaryRepoId:o.id,repoId:o.id,discoveredRepoIds:[o.id],branch:r,status:"active",linkedRepoIds:[],archivedAt:null,createdAt:d,updatedAt:d};return await qr(e,o),c||await Fe(e,u),await io(e,{repoIds:[o.id],workspaceIds:[u.id]}),await ao(e,u,o.id),{kind:"createWorkspace",workspace:u,repos:[o],created:!c}},uc=async(e,t)=>{let r=await cc(e,t);if(r.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let n=await ie(e),s=lc(n,Ze.basename(t)),o=n.find(d=>d.kind==="project"&&d.rootPath===t)??null,i=new Date().toISOString(),l=r.map(d=>d.id),c=o?{...o,discoveredRepoIds:l,primaryRepoId:l[0]??o.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:Ze.basename(t),rootPath:t,primaryRepoId:l[0]??"",discoveredRepoIds:l,branch:"project",status:"active",linkedRepoIds:l,archivedAt:null,createdAt:i,updatedAt:i};return await Promise.all(r.map(d=>qr(e,d))),await Fe(e,c),await io(e,{repoIds:l,workspaceIds:[c.id]}),await ao(e,c,l[0]??null),{kind:"createWorkspace",workspace:c,repos:r,created:!o}},ft=async(e,t)=>{await Xe(e.workspaceRoot);let r=Ze.resolve(e.workspaceRoot,t);if(!(await ic(r).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${r}`);return await Kr(r)?dc(e,r):uc(e,r)};var Gr=async(e,t,r={listWorkspaceRecords:ie,ensureCraigState:Xe})=>(await r.ensureCraigState(e.workspaceRoot),{kind:"listWorkspaces",workspaces:(await r.listWorkspaceRecords(e)).filter(s=>s.status===(t.archived?"archived":"active")),archivedOnly:t.archived});var Hr=async(e,t,r={readWorkspace:Ne,writeWorkspace:Fe,readUiState:J,writeUiState:Y})=>{let s={...await r.readWorkspace(e,t),status:"archived",archivedAt:new Date().toISOString()};await r.writeWorkspace(e,s);let o=await r.readUiState({uiStateFile:e.uiStateFile});return o&&o.selectedWorkspaceId===t&&await r.writeUiState({uiStateFile:e.uiStateFile},{...o,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null}),{kind:"archiveWorkspace",workspaceId:s.id,status:s.status,branch:s.branch}};var zr=async(e,t)=>{let n={...await Ne(e,t),status:"active",archivedAt:null};await Fe(e,n);let s=await J({uiStateFile:e.uiStateFile})??null;return await Y({uiStateFile:e.uiStateFile},{...s??we(),selectedWorkspaceId:n.id,selectedRepoId:n.kind==="project"?n.discoveredRepoIds?.[0]??null:n.primaryRepoId,selectedTaskId:null}),{kind:"restoreWorkspace",workspaceId:n.id,status:n.status,branch:n.branch}};var We=async(e,t,r={deleteWorkspace:Qs,readCraigIndex:ee,writeCraigIndex:ye})=>{await r.deleteWorkspace(e,t);let n=await r.readCraigIndex(e);await r.writeCraigIndex(e,{...n,workspaceIds:n.workspaceIds.filter(s=>s!==t)})};var pc=async(e,t)=>{let r=await J({uiStateFile:e.uiStateFile});!r||r.selectedWorkspaceId!==t||await Y({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})},Yr=async(e,t,r)=>{let n=await Ne(e,t),s=await r.listTasks(e,{workspaceId:t,includeClosed:!0});if(n.status==="active")throw new Error(`Cannot remove workspace ${t} while it is active. Archive it first.`);if(s.tasks.length>0)throw new Error(`Cannot remove workspace ${t} while task records still reference it.`);return await We(e,t),await pc(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};var Qr={};Lr(Qr,{addRepo:()=>lo,listRegisteredRepos:()=>co,removeRepo:()=>uo});import fc from"node:path";import{stat as mc}from"node:fs/promises";var lo=async(e,t)=>{let r=fc.resolve(e.workspaceRoot,t);if(!(await mc(r).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${r}`);let s=await ft(e,t),o=s.repos[0];if(!o||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${r}`);return{kind:"createRepo",repo:o,workspaceId:s.workspace.id,created:s.created}};var co=async(e,t={listRepos:pt,ensureCraigState:Xe})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var uo=async(e,t,r)=>{let n=await ue(e,t),o=(await ie(e)).filter(u=>u.primaryRepoId===t),i=o.filter(u=>u.status==="active"),l=await r.listTasks(e,{repoId:t});if(i.length>0)throw new Error(`Cannot remove repo ${t} while active workspace records still reference it.`);if(l.tasks.length>0)throw new Error(`Cannot remove repo ${t} while task records still reference it.`);await Promise.all(o.map(u=>We(e,u.id))),await Zs(e,t);let c=await ee(e);await ye(e,{...c,repoIds:c.repoIds.filter(u=>u!==t)});let d=await J({uiStateFile:e.uiStateFile});return d?.selectedRepoId===t&&await Y({uiStateFile:e.uiStateFile},{...d,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var re={addWorkspace:ft,listWorkspaces:Gr,archiveWorkspace:Hr,restoreWorkspace:zr,removeWorkspace:Yr,removeWorkspaceRecord:We,repos:Qr};var ne=async(e,t)=>{let r=await gc(Xr(e,t),"utf8");return JSON.parse(r)},pe=async(e,t)=>{let r=await ne(e,t);return G(r,Xr(e,t))},A=async(e,t)=>{let r={...t,updatedAt:new Date().toISOString()};await B(Xr(e,t.id),r)},Jr=async(e,t)=>{let r=await ee(e);r.taskIds.includes(t)||await ye(e,{...r,taskIds:[...r.taskIds,t]})},Xr=(e,t)=>`${e.tasksDir}/${t}.json`;var O=e=>e.prs.length===0?null:[...e.prs].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e.prs[e.prs.length-1]??null,Ee=e=>e.status==="merged"||e.status==="closed",et=(e,t)=>{let r=e.prs.findIndex(s=>s.number!==null&&s.number===t.number),n=r>=0?e.prs.map((s,o)=>o===r?t:s):[...e.prs,t];return{...e,prs:n}},mt=e=>{if(e.length===0)return"checked";let t=[...e].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e[e.length-1];return Kt(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"},Kt=e=>e.mergeable&&!hc(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"),hc=e=>e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED",Zr=e=>e.requiredChecks.length===0?"no required checks":e.requiredChecks.map(t=>`${t.name}:${t.status}`).join(", "),gt=(e,t)=>{let r=e.isDraft??!1,n=kc(e.state,r);return{provider:"github",owner:t?.owner??null,repo:t?.repo??null,number:e.number,url:e.url,title:e.title??t?.title??null,status:n,draft:r,baseBranch:e.baseRefName,headBranch:e.headRefName,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:wc(e.reviewDecision??null),requiredChecks:ht(e.statusCheckRollup),comments:Pc(e.comments),createdAt:e.createdAt??t?.createdAt??null,updatedAt:e.updatedAt??t?.updatedAt??null,mergedAt:e.mergedAt??t?.mergedAt??null,lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}},kc=(e,t)=>t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,wc=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,ht=e=>{let t=e.map(n=>Rc(n)).filter(n=>n!==null),r=new Map;for(let n of t){let s=r.get(n.name);(!s||Tc(s,n))&&r.set(n.name,n)}return[...r.values()].map(n=>({name:n.name,status:n.status,conclusion:n.conclusion}))},Rc=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=t.name??t.context,n=t.state??t.status??t.conclusion;return r?{name:r,status:fo(n??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:yc(t)}:null},Tc=(e,t)=>e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):qt(e)&&!qt(t)?!0:!qt(e)&&qt(t)?!1:po(t.status)>=po(e.status),qt=e=>e.conclusion?.toUpperCase()==="CANCELLED",po=e=>{switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}},yc=e=>{let t=e.completedAt??e.startedAt??e.createdAt??null;if(!t)return null;let r=new Date(t).getTime();return Number.isFinite(r)?r:null},Pc=e=>{let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(bc).filter(r=>r!==null).slice(-4):[]},bc=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=Sc(t.bodyText??t.body??"");return r?{author:typeof t.author=="string"?t.author:t.author?.login??null,body:r,createdAt:t.createdAt??null,url:t.url??null}:null},Sc=e=>e.replace(/\s+/g," ").trim(),fo=(e,t)=>{let r=e?.toUpperCase()??null,n=t?.toUpperCase()??null;return n==="SKIPPED"||r==="SKIPPED"?"skipped":r==="SUCCESS"||n==="SUCCESS"||n==="NEUTRAL"?"success":r==="PENDING"||r==="EXPECTED"||r==="IN_PROGRESS"||r==="QUEUED"||r==="REQUESTED"||r==="WAITING"?"pending":r==="FAILURE"||r==="FAILED"||r==="ERROR"||r==="TIMED_OUT"||r==="CANCELLED"||r==="ACTION_REQUIRED"||r==="STARTUP_FAILURE"||n==="FAILURE"||n==="FAILED"||n==="ERROR"||n==="TIMED_OUT"||n==="CANCELLED"||n==="ACTION_REQUIRED"||n==="STARTUP_FAILURE"?"failed":r==="COMPLETED"&&n===null?"unknown":r==="COMPLETED"&&n!==null?fo(n,n):"unknown"};import{access as Ic}from"node:fs/promises";import mo from"node:path";var $=async(e,t,r={readRawTask:ne,validateTaskRecord:G})=>{try{let n=await r.readRawTask(e,t);return r.validateTaskRecord(n,`${e.tasksDir}/${t}.json`)}catch(n){throw Ac(n)?new Error(`Craig task "${t}" was not found.`):n}},H=async e=>{if(!await en(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)},tt=(e,t)=>t.artifacts.logPath?mo.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:mo.join(e.workspaceRoot,t.artifacts.logPath):null,kt=async(e,t)=>{let r=await en(t.worktreePath),n=tt(e,t),s=n?await en(n):!1;return{worktreeExists:r,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:Cc(t),lastCommitSummary:xc(t),prSummary:vc(t),cleanupSummary:Ec(t)}},en=async e=>{try{return await Ic(e),!0}catch{return!1}},Cc=e=>{let t=e.checks.commands.length,r=t===1?"command":"commands",n=e.checks.lastRunAt?` at ${e.checks.lastRunAt}`:"";return`${e.checks.status} (${t} ${r})${n}`},xc=e=>e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed",vc=e=>{if(e.type==="project"&&e.repoTargets?.length){let s=e.repoTargets.filter(c=>c.pullRequest.number);if(s.length===0)return"not linked";let o=s.map(c=>` ${c.repoId} #${c.pullRequest.number} ${c.pullRequest.status??"unknown"}`),i=s.reduce((c,d)=>{let u=d.pullRequest.status??"unknown";return c[u]=(c[u]??0)+1,c},{}),l=Object.entries(i).map(([c,d])=>`${d} ${c}`).join(", ");return`${s.length} PR${s.length!==1?"s":""} (${l})
30
+ ${o.join(`
31
+ `)}`}let t=O(e);if(!t?.number||!t.url)return"not linked";let r=t.requiredChecks.length,n=r===1?"check":"checks";return`#${t.number} ${t.status??"unknown"} mergeable=${t.mergeable} mergeState=${t.mergeStateStatus??"unknown"} (${r} ${n})`},Ec=e=>e.status!=="merged"?"not merged":e.cleanup.warning?`warning: ${e.cleanup.warning}`:e.cleanup.preservedWorktree?"preserved worktree":e.cleanup.worktreeRemovedAt?`worktree removed at ${e.cleanup.worktreeRemovedAt}`:"cleanup pending",Ac=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var go=async(e,t)=>{let r=await M("git",["show-ref","--verify","--quiet",`refs/heads/${t}`],{cwd:e});if(r.exitCode===0)return!0;if(r.exitCode===1)return!1;throw new Error(r.stderr.trim()||r.stdout.trim()||"Unable to check git branch state.")},tn=async(e,t,r,n="main")=>{let s=n.trim()||"main";if((await M("git",["show-ref","--verify","--quiet",`refs/heads/${s}`],{cwd:e})).exitCode!==0)throw new Error(`Base branch '${s}' does not exist locally.`);let i=await Dc(e,s);await v("git",["worktree","add","-b",t,r,i],{cwd:e})},Dc=async(e,t)=>(await M("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await M("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await M("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t,Vt=async e=>{let t=await M("git",["status","--short"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"Unable to inspect git status.");return t.stdout.trim().length>0},ho=async e=>{await v("git",["add","-A"],{cwd:e})},ko=async(e,t)=>{await v("git",["commit","-m",t],{cwd:e})},wo=async e=>{let t=await v("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[r="",n=""]=t.stdout.trim().split(`
32
+ `);if(!r||!n)throw new Error("Unable to read git HEAD commit metadata.");return{sha:r,message:n}};var Ro=async(e,t)=>{await v("git",["worktree","remove","--force",t],{cwd:e})};var rn=async e=>rt(e,e.repoRoot),rt=async(e,t)=>{let r=await ee(e),n=To(new Date),s=yo(r.taskIds,n);for(;;){let o=`task_${n}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await go(t,i))return o;s+=1}},wt=async e=>{let t=await ee(e),r=To(new Date),n=yo(t.taskIds,r);return`task_${r}_${String(n).padStart(2,"0")}`},To=e=>{let t=e.getFullYear(),r=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0");return`${t}${r}${n}`},yo=(e,t)=>{let r=e.filter(n=>n.startsWith(`task_${t}_`)).map(n=>Number.parseInt(n.slice(-2),10)).filter(n=>Number.isInteger(n));return r.length===0?1:Math.max(...r)+1};var nn=async(e,t,r={readRawTask:ne,validateTaskRecord:G})=>{let n=await ee(e),s=[],o=[];await Promise.all(n.taskIds.map(async c=>{try{let d=await r.readRawTask(e,c);s.push(r.validateTaskRecord(d,`${e.tasksDir}/${c}.json`))}catch(d){if($c(d)){o.push(c);return}throw d}}));let l=(t?.includeClosed?s:s.filter(c=>c.status!=="closed")).filter(c=>!(t?.workspaceId&&c.workspaceId!==t.workspaceId||t?.repoId&&c.repoId!==t.repoId&&!(c.repoTargets??[]).some(d=>d.repoId===t.repoId)));return l.sort((c,d)=>c.id.localeCompare(d.id)),o.sort(),{kind:"listTasks",tasks:l,missingTaskIds:o,repoId:t?.repoId??null}},$c=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var Po=["merge_ready","pr_open","checked","review","running","draft"],sn=e=>[...e].sort((t,r)=>t.id.localeCompare(r.id)),on=(e,t)=>t&&e.some(n=>n.id===t)?t:e.length===0?null:[...e].sort(Lc)[0]?.id??null,Lc=(e,t)=>{let r=bo(e.status),n=bo(t.status);return r!==n?r-n:t.updatedAt.localeCompare(e.updatedAt)},bo=e=>{let t=Po.indexOf(e);return t>=0?t:Po.length};import So from"node:path";var _e=(e,t)=>t?So.isAbsolute(t)?t:So.join(e.repoRoot,t):null;import{mkdir as Rt,rm as jc,writeFile as Gt}from"node:fs/promises";import j from"node:path";var Co=["AGENTS","md"].join("."),nt=async(e,t,r,n={})=>{let s=await ue(e,t),o=await Wc(e,s.id),i=await rt(e,s.rootPath),l=n.sessionId??null,c=`craig/${i}`,d=j.join(e.worktreesDir,s.id,i),u=j.join(e.logsDir,`${i}.log`),g=j.join(e.artifactsDir,i);await Rt(j.dirname(d),{recursive:!0}),await Rt(g,{recursive:!0}),await Gt(u,"","utf8");let w=Mc(e,{taskId:i,repoId:s.id,workspaceId:o.id,sessionId:l,repoRoot:s.rootPath,prompt:r,runner:n.runner??"codex",config:n.config??{},branch:c,worktreePath:d});return await A(e,w),await Jr(e,i),await tn(s.rootPath,c,d,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:l,workspaceId:o.id,task:w}},Tt=async(e,t,r,n={})=>{let s=(await ie(e)).find(x=>x.id===t&&x.status==="active");if(!s)throw new Error(`Workspace ${t} does not exist or is archived.`);if(s.kind!=="project"){if(!s.primaryRepoId)throw new Error(`Workspace ${t} is not task-capable.`);let x=await nt(e,s.primaryRepoId,r,n);return{...x,bundlePath:x.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await wt(e),l=new Date().toISOString(),c=n.runner??"codex",d=n.sessionId??null,u=`craig/${i}`,g=j.join(e.craigDir,"task-bundles",i),w=j.join(e.logsDir,`${i}.log`),R=j.join(e.artifactsDir,i);await Rt(g,{recursive:!0}),await Rt(R,{recursive:!0}),await Gt(w,"","utf8");let I=await Promise.all(o.map(x=>ue(e,x))),T=Nc(I),a=await Promise.all(I.map(x=>Oc(e,x,i,u,j.join(g,T.get(x.id))))),z=a.find(x=>x.status==="ready")??a[0];if(!a.some(x=>x.status==="ready"))throw await jc(g,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${a.map(x=>`${x.repoId}: ${x.failureReason??"unknown error"}`).join("; ")}`);await Gt(j.join(g,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:r,repos:a.map(x=>({repoId:x.repoId,repoName:I.find(Me=>Me.id===x.repoId)?.name??x.repoId,path:j.relative(g,x.worktreePath),status:x.status,worktreePath:x.worktreePath,failureReason:x.failureReason}))},null,2),"utf8"),await Gt(j.join(g,Co),Fc({taskId:i,workspaceId:t,prompt:r,repos:I,repoTargets:a,bundlePath:g}),"utf8");let U=yt(i,r,l,c,n.config??{}),le={id:i,title:r,slug:xo(r),type:"project",status:"draft",runner:c,repoId:z.repoId,workspaceId:s.id,sessionId:d,selectedPtyTabId:U[0]?.id??null,linkedRepoIds:o.filter(x=>x!==z.repoId),repoRoot:g,worktreePath:g,branch:u,bundlePath:g,selectedRepoTargetId:z.repoId,repoTargets:a,ptyTabs:U,runnerSession:{command:S.runners.buildCommand(c,r,n.config??{}),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:r},checks:z.checks,lastCommit:null,prs:[],artifacts:{logPath:j.relative(e.workspaceRoot,w),checkSummaryPath:j.relative(e.workspaceRoot,j.join(R,"check-summary.json")),prDraftPath:null,prStatusPath:j.relative(e.workspaceRoot,j.join(R,"pr-status.json"))},cleanup:Ht(),lastFailureReason:a.every(x=>x.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:l,updatedAt:l};return await A(e,le),await Jr(e,i),{repoId:z.repoId,repoRoot:g,sessionId:d,workspaceId:s.id,task:le,bundlePath:g,repoTargets:a}},yt=(e,t,r,n="codex",s={})=>{let o=S.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:o.defaultAgentTitle,command:S.runners.buildCommand(n,void 0,s),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},Mc=(e,t)=>{let r=new Date().toISOString(),n=yt(t.taskId,t.prompt,r,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:xo(t.prompt),type:"repo",status:"draft",runner:t.runner,repoId:t.repoId,workspaceId:t.workspaceId,sessionId:t.sessionId,selectedPtyTabId:n[0]?.id??null,linkedRepoIds:[],repoRoot:t.repoRoot,worktreePath:t.worktreePath,branch:t.branch,ptyTabs:n,runnerSession:{command:S.runners.buildCommand(t.runner,t.prompt,t.config),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:t.prompt},checks:{...an(j.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:j.relative(e.workspaceRoot,j.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:j.relative(e.workspaceRoot,j.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:j.relative(e.workspaceRoot,j.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:Ht(),lastFailureReason:null,createdAt:r,updatedAt:r}},Oc=async(e,t,r,n,s)=>{await Rt(j.dirname(s),{recursive:!0});try{return await tn(t.rootPath,n,s,t.defaultBranch),{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:an(j.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:Io(),cleanup:Ht()}}catch(o){return{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"unavailable",failureReason:o instanceof Error?o.message:"Failed to create worktree.",checks:an(j.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:Io(),cleanup:Ht()}}},Nc=e=>{let t=new Set(["manifest.json",Co]),r=new Map;for(let n of e){let s=t.has(n.name)?`${n.name}-repo`:n.name,o=s,i=2;for(;t.has(o);)o=`${s}-${i}`,i+=1;t.add(o),r.set(n.id,o)}return r},Fc=e=>{let t=new Map(e.repos.map(n=>[n.id,n.name])),r=e.repoTargets.map(n=>{let s=t.get(n.repoId)??n.repoId,o=j.relative(e.bundlePath,n.worktreePath),i=n.status==="ready"?"ready":`unavailable: ${n.failureReason??"unknown error"}`;return`- \`${o}/\` - ${s} (${n.repoId}, ${i})`}).join(`
33
+ `);return["# Craig Project Task Bundle","","This directory is a Craig project task bundle. Repo work must happen inside the child repo worktrees listed below.","","Run repo Git commands from a repo worktree directory, not from the bundle root. Use `manifest.json` as the machine-readable source of truth for this bundle.","",`Task: \`${e.taskId}\``,`Workspace: \`${e.workspaceId}\``,`Prompt: ${e.prompt}`,"","## Repo Worktrees","",r,""].join(`
34
+ `)},an=e=>({source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}),Io=()=>({provider:"github",number:null,url:null,baseBranch:null,headBranch:null,status:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,requiredChecks:[],comments:[],lastSyncedAt:null,lastSyncedHeadSha:null}),Ht=()=>({paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}),Wc=async(e,t)=>{let n=(await ie(e)).find(s=>s.kind!=="project"&&s.primaryRepoId===t&&s.status==="active");if(!n)throw new Error(`Repo ${t} does not have an active workspace.`);return n},xo=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-");import Wo from"node:path";import{readFile as qc,rm as vk}from"node:fs/promises";import Kc from"node:path";function vo(e,t){let r=Uc(e);if(typeof r!="object"||r===null||typeof r.id!="string"||typeof r.taskId!="string"||typeof r.repoId!="string"||typeof r.workspaceId!="string"||r.substrate!=="tmux"||typeof r.sessionName!="string"||typeof r.paneId!="string"||!(r.windowTarget===null||typeof r.windowTarget=="string")||typeof r.worktreePath!="string"||!(r.logPath===null||typeof r.logPath=="string")||!Array.isArray(r.command)||!r.command.every(n=>typeof n=="string")||!["starting","running","exited","failed"].includes(r.status)||!(r.startedAt===null||typeof r.startedAt=="string")||!(r.exitedAt===null||typeof r.exitedAt=="string")||!(r.exitCode===null||typeof r.exitCode=="number")||!(r.lastAttachedAt===null||typeof r.lastAttachedAt=="string")||!Bc(r.attach)||!_c(r.snapshot)||typeof r.createdAt!="string"||typeof r.updatedAt!="string")throw new Error(`Craig session record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r}function _c(e){return e===null||typeof e=="object"&&e!==null&&typeof e.paneId=="string"&&(typeof e.windowTarget=="string"||e.windowTarget===null)&&typeof e.alive=="boolean"&&typeof e.capturedAt=="string"}function Bc(e){return typeof e=="object"&&e!==null&&e.detachChord==="ctrl+]"&&(e.lastSize===null||typeof e.lastSize=="object"&&e.lastSize!==null&&typeof e.lastSize.columns=="number"&&typeof e.lastSize.rows=="number")}function Uc(e){let t=typeof e=="object"&&e!==null?e:{};return{id:t.id??"",taskId:t.taskId??"",repoId:t.repoId??"",workspaceId:t.workspaceId??"",substrate:t.substrate??"tmux",sessionName:t.sessionName??"",paneId:t.paneId??"",windowTarget:typeof t.windowTarget=="string"?t.windowTarget:null,worktreePath:t.worktreePath??"",logPath:typeof t.logPath=="string"?t.logPath:null,command:Array.isArray(t.command)?t.command.filter(r=>typeof r=="string"):[],status:t.status??"starting",startedAt:typeof t.startedAt=="string"?t.startedAt:null,exitedAt:typeof t.exitedAt=="string"?t.exitedAt:null,exitCode:typeof t.exitCode=="number"?t.exitCode:null,lastAttachedAt:typeof t.lastAttachedAt=="string"?t.lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:typeof t.attach=="object"&&t.attach!==null&&t.attach.lastSize&&typeof t.attach.lastSize.columns=="number"&&typeof t.attach.lastSize.rows=="number"?t.attach.lastSize:null},snapshot:t.snapshot&&typeof t.snapshot=="object"?{paneId:typeof t.snapshot.paneId=="string"?t.snapshot.paneId:t.paneId??"",windowTarget:typeof t.snapshot.windowTarget=="string"?t.snapshot.windowTarget:null,alive:!!t.snapshot.alive,capturedAt:typeof t.snapshot.capturedAt=="string"?t.snapshot.capturedAt:new Date().toISOString()}:null,createdAt:t.createdAt??"",updatedAt:t.updatedAt??""}}var Ae=async(e,t)=>{let r=await qc(ln(e,t),"utf8"),n=JSON.parse(r);return vo(n,ln(e,t))},Be=async(e,t)=>{await B(ln(e,t.id),{...t,updatedAt:new Date().toISOString()})};var ln=(e,t)=>Kc.join(e.sessionsDir,`${t}.json`);import{spawn as Vc}from"node:child_process";import{createHash as Gc}from"node:crypto";import Hc from"node:path";function zt(e){return`'${e.replace(/'/g,"'\\''")}'`}var zc="craig",Eo=async(e,t,r)=>{let n=cn(e,t),s=Qc(),o=await v("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",n,"-n","runner",...s,"-c",r],{cwd:e}),i=Xc(o.stdout);return await Yc(e,n),i};var Yc=async(e,t)=>{let r=[["set-option","-t",t,"status","off"],["set-option","-t",t,"detach-on-destroy","off"],["set-window-option","-t",t,"pane-border-status","off"],["set-window-option","-t",t,"aggressive-resize","on"]];for(let n of r)await v("tmux",n,{cwd:e})},Ao=async(e,t,r)=>{await v("tmux",["resize-window","-t",t,"-x",`${r.columns}`,"-y",`${r.rows}`],{cwd:e})},Do=async(e,t,r)=>{await v("tmux",["send-keys","-t",e,t,"C-m"],{cwd:r})};var $o=async(e,t,r)=>{await v("tmux",["pipe-pane","-o","-t",e,`cat >> ${zt(t)}`],{cwd:r})},Yt=async(e,t,r,n)=>{let s=n??jo(e);if(r?await v("tmux",["select-window","-t",r],{cwd:e}):await v("tmux",["select-window","-t",t],{cwd:e}),await v("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await v("tmux",["switch-client","-t",s],{cwd:e});return}await ed(e,["attach-session","-t",s])};var Lo=async(e,t)=>{await v("tmux",["kill-session","-t",t],{cwd:e})};var jo=e=>{let r=Hc.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",n=Gc("sha1").update(e).digest("hex").slice(0,8);return`${zc}-${r}-${n}`},cn=(e,t)=>`${jo(e)}-${t.toLowerCase()}`,Qc=()=>{let e=Jc();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]},Jc=()=>{let e=[process.stdout,process.stderr,process.stdin];for(let t of e){let r="columns"in t?t.columns:void 0,n="rows"in t?t.rows:void 0;if(typeof r=="number"&&r>0&&typeof n=="number"&&n>0)return{columns:r,rows:n}}return null},Xc=e=>{let t=Zc(e);if(t.length<3)throw new Error("tmux did not return the expected session, window, and pane targets for the Craig task session.");return{sessionName:t[0],windowTarget:t[1],paneId:t[2]}},Zc=e=>e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0),ed=async(e,t)=>{await new Promise((r,n)=>{let s=Vc("tmux",t,{cwd:e,stdio:"inherit"});s.on("error",n),s.on("exit",o=>{if(o===0){r();return}n(new Error(`tmux ${t.join(" ")} failed with exit code ${o??"unknown"}.`))})})};import{accessSync as td,constants as rd}from"node:fs";import{homedir as Mo}from"node:os";import De from"node:path";var nd=[De.join(Mo(),".local","bin"),De.join(Mo(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function No(e=process.env){return sd([...(e.PATH??"").split(De.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:nd])}function Ue(e=process.env){return{...e,PATH:No(e).join(De.delimiter)}}function dn(e,t={}){if(e.includes(De.sep)){let r=De.isAbsolute(e)?e:De.resolve(t.cwd??process.cwd(),e);return Oo(r)?r:null}for(let r of No(t.env)){let n=De.join(r,e);if(Oo(n))return n}return null}function qe(e,t={}){let r=dn(e,t);if(r)return r;throw new Error(`Command not found: ${e}. Install it or add its directory to PATH. Craig also checks ~/.local/bin, /opt/homebrew/bin, and /usr/local/bin.`)}function Oo(e){try{return td(e,rd.X_OK),!0}catch{return!1}}function sd(e){return[...new Set(e)]}var Pt={async create(e,t){let r=await Eo(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await $o(r.paneId,t.logPath,t.repoRoot);let n=await Fo({paneId:r.paneId,windowTarget:r.windowTarget,alive:!0}),s={id:t.sessionId,taskId:t.taskId,repoId:t.repoId,workspaceId:t.workspaceId,substrate:"tmux",sessionName:r.sessionName||cn(t.repoRoot,t.taskId),paneId:r.paneId,windowTarget:r.windowTarget,worktreePath:t.worktreePath,logPath:t.logPath,command:t.command,status:"starting",startedAt:null,exitedAt:null,exitCode:null,lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:null},snapshot:n,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return await Be(e,s),s},async attach(e,t,r){let n=await Pt.snapshot(t,r);if(!n.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await Yt(r,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:n};return await Be(e,s),s},async resize(e,t,r,n){await Ao(n,t.sessionName,r);let s={...t,attach:{...t.attach,lastSize:r}};return await Be(e,s),s},async write(){throw new Error("Direct session writes are owned by the terminal bridge.")},async read(){throw new Error("Direct session reads are owned by the terminal bridge.")},async terminate(e,t,r){let n={...t,status:"failed",exitedAt:new Date().toISOString(),snapshot:{...t.snapshot??{paneId:t.paneId,windowTarget:t.windowTarget,alive:!1,capturedAt:new Date().toISOString()},alive:!1,capturedAt:new Date().toISOString()},command:t.command};return await Be(e,n),n},async snapshot(e,t){return od(e,t)}},un={async prepare(e,t){let n=e.runnerSession.command[0],s=Ue();await v(qe(n,{cwd:t.repoRoot,env:s}),["--help"],{cwd:t.repoRoot,env:s})},async launch(e,t){let r=e.runnerSession.command,n=qe(r[0],{cwd:e.worktreePath,env:Ue()});await Do(t.session.paneId,[n,...r.slice(1)].map(s=>zt(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}},od=async(e,t)=>{let r=await M("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return Fo({paneId:e.paneId,windowTarget:e.windowTarget,alive:r.exitCode===0&&r.stdout.split(/\s+/).some(n=>n.trim()===e.paneId)})},Fo=async e=>({paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()});var pn=async(e,t,r,n={})=>{let s=r.trim(),o=await S.load(e),i=n.runner??S.runners.getDefault(o);if(S.runners.assertEnabled(i,o),t.trim().length===0)throw new Error(n.workspaceId?"Workspace id cannot be empty.":"Repo id cannot be empty.");if(s.length===0)throw new Error("Task prompt cannot be empty.");let l=n.workspaceId?await Tt(e,n.workspaceId,s,{runner:i,config:o}):await nt(e,t,s,{runner:i,config:o}),c=l.task,d=S.runners.buildCommand(i,s,o),u=`session_${c.id}`,g=c.artifacts.logPath?Wo.resolve(e.workspaceRoot,c.artifacts.logPath):Wo.join(e.logsDir,`${c.id}.log`);try{await un.prepare(c,{repoRoot:l.repoRoot});let w=await Pt.create(e,{sessionId:u,taskId:c.id,repoId:l.repoId,workspaceId:l.workspaceId,repoRoot:l.repoRoot,worktreePath:c.worktreePath,logPath:g,command:d});await un.launch(c,{repoRoot:l.repoRoot,session:w});let R=new Date().toISOString();w={...w,status:"running",startedAt:R,command:d};let I={...c,status:"running",runner:i,sessionId:w.id,selectedPtyTabId:c.selectedPtyTabId,runnerSession:{command:w.command,pid:null,startedAt:R,lastKnownState:"running",exitCode:null,exitedAt:null}};return await A(e,I),await Be(e,w),await Y({uiStateFile:e.uiStateFile},{...await J({uiStateFile:e.uiStateFile})??we(),selectedRepoId:I.repoId,selectedWorkspaceId:I.workspaceId,selectedTaskId:I.id,selectedPtyTabId:I.selectedPtyTabId}),{kind:"createTask",taskId:I.id,repoId:I.repoId,workspaceId:I.workspaceId,sessionId:w.id,status:I.status,branch:I.branch,worktreePath:I.worktreePath,runner:I.runner}}catch(w){let R={...c,sessionId:null,status:"draft",runnerSession:{...c.runnerSession,lastKnownState:"failed"},lastFailureReason:w instanceof Error?w.message:"Unknown Craig error"};throw await A(e,R),w}};import{mkdir as gd}from"node:fs/promises";import hd from"node:path";var _o=3,id=1e3,ad=1e4,st=async e=>{let t=await M("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")};var Bo=async(e,t,r)=>{let n=r==="merge"?"--merge":r==="rebase"?"--rebase":"--squash";await v("gh",["pr","merge",String(t),n,"--delete-branch=false"],{cwd:e})},Qt=async(e,t)=>{let r=await v("gh",Ko(e),{cwd:t});return JSON.parse(r.stdout)},Jt=async(e,t)=>{let r=await M("gh",Ko(e),{cwd:t});return r.exitCode!==0?null:JSON.parse(r.stdout)},Uo=async(e,t,r)=>{if(r.length===0)return[];let n=fd(r),s=await ld(e,["api","graphql","-f",`query=${n}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`]),i=JSON.parse(s.stdout).data?.repository??{};return r.map((l,c)=>{let d=i[`item${c}`],u=md(d);return{id:l.id,found:u!==null,view:u}})},qo=async e=>{let t=await M("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:pd(t.stdout.trim())},ld=async(e,t)=>{let r;for(let n=0;n<=_o;n+=1)try{return await v("gh",t,{cwd:e})}catch(s){if(r=s,n===_o||!cd(s))throw s;await ud(dd(n))}throw r},cd=e=>{let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase();return t.includes("rate limit")||t.includes("secondary rate limit")||t.includes("abuse detection")||t.includes("api rate limit exceeded")||t.includes("you have exceeded")},dd=e=>{let t=Number(process.env.CRAIG_GH_RATE_LIMIT_RETRY_BASE_MS)||id,r=Math.min(t*2**e,ad),n=Math.floor(Math.random()*Math.max(1,Math.floor(r*.25)));return r+n},ud=e=>new Promise(t=>setTimeout(t,e)),Ko=e=>["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"],pd=e=>{let t=e.replace(/\.git$/,""),r=t.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)$/);if(r?.[1]&&r[2])return{owner:r[1],name:r[2]};let n=t.match(/^git@github\.com:([^/]+)\/([^/]+)$/);if(n?.[1]&&n[2])return{owner:n[1],name:n[2]};let s=t.match(/^ssh:\/\/git@github\.com\/([^/]+)\/([^/]+)$/);return s?.[1]&&s[2]?{owner:s[1],name:s[2]}:null},fd=e=>`
33
35
  query CraigPullRequestBatch($owner: String!, $name: String!) {
34
36
  repository(owner: $owner, name: $name) {
35
- ${e.map((n,r)=>{let s=`item${r}`;return n.mode==="number"?`${s}: pullRequest(number: ${Number(n.selector)}) { ...PrFields }`:`${s}: pullRequests(headRefName: ${JSON.stringify(n.selector)}, states: OPEN, first: 1, orderBy: { field: UPDATED_AT, direction: DESC }) { nodes { ...PrFields } }`}).join(`
37
+ ${e.map((r,n)=>{let s=`item${n}`;return r.mode==="number"?`${s}: pullRequest(number: ${Number(r.selector)}) { ...PrFields }`:`${s}: pullRequests(headRefName: ${JSON.stringify(r.selector)}, states: OPEN, first: 1, orderBy: { field: UPDATED_AT, direction: DESC }) { nodes { ...PrFields } }`}).join(`
36
38
  `)}
37
39
  }
38
40
  }
@@ -108,58 +110,56 @@ fragment PrFields on PullRequest {
108
110
  }
109
111
  }
110
112
  }
111
- `}function bl(e){if(!e||typeof e!="object")return null;let t="nodes"in e?e.nodes?.[0]??null:e;if(!t||typeof t!="object")return null;let n=t,r=n.statusCheckRollup?.contexts?.nodes??n.commits?.nodes?.[0]?.commit?.statusCheckRollup?.contexts?.nodes??[];return{number:n.number,url:n.url,baseRefName:n.baseRefName,headRefName:n.headRefName,headRefOid:n.headRefOid??null,state:n.state,isDraft:n.isDraft??!1,title:n.title??null,createdAt:n.createdAt??null,updatedAt:n.updatedAt??null,mergedAt:n.mergedAt??null,mergeable:n.mergeable,mergeStateStatus:n.mergeStateStatus,reviewDecision:n.reviewDecision??null,statusCheckRollup:r,comments:n.comments?.nodes??[]}}async function On(e,t,n,r){let s=Sl(n,r),o=Hs(t,s),i=Tl(o.prs),c={...o,status:i};await eo(e,c);let l=await B(e,t.id),d=l.status==="closed"?l.status:i,p=Hs({...l,status:d},s);return await A(e,p),p}async function Dn(e,t,n,r){let s=await B(e,t.id),o=(s.repoTargets??t.repoTargets??[]).map(c=>c.repoId===n?{...c,pullRequest:r}:c),i={...s,repoTargets:o};return await A(e,i),i}function Sl(e,t){let n=e.isDraft??!1,r=Il(e.state,n);return{provider:"github",owner:t?.owner??null,repo:t?.repo??null,number:e.number,url:e.url,title:e.title??t?.title??null,status:r,draft:n,baseBranch:e.baseRefName,headBranch:e.headRefName,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:no(e.reviewDecision??null),requiredChecks:to(e.statusCheckRollup),comments:ro(e.comments),createdAt:e.createdAt??t?.createdAt??null,updatedAt:e.updatedAt??t?.updatedAt??null,mergedAt:e.mergedAt??t?.mergedAt??null,lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}}function Mn(e){return{provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:Cl(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:no(e.reviewDecision??null),requiredChecks:to(e.statusCheckRollup),comments:ro(e.comments),lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}}function Il(e,t){return t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null}function Cl(e){return e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null}function to(e){let t=e.map(r=>xl(r)).filter(r=>r!==null),n=new Map;for(let r of t){let s=n.get(r.name);(!s||vl(s,r))&&n.set(r.name,r)}return[...n.values()].map(r=>({name:r.name,status:r.status,conclusion:r.conclusion}))}function xl(e){if(typeof e!="object"||e===null)return null;let t=e,n=t.name??t.context,r=t.state??t.status??t.conclusion;return n?{name:n,status:so(r??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:El(t)}:null}function vl(e,t){return e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):At(e)&&!At(t)?!0:!At(e)&&At(t)?!1:Ys(t.status)>=Ys(e.status)}function At(e){return e.conclusion?.toUpperCase()==="CANCELLED"}function Ys(e){switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}}function El(e){let t=e.completedAt??e.startedAt??e.createdAt??null;if(!t)return null;let n=new Date(t).getTime();return Number.isFinite(n)?n:null}function no(e){return e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null}function ro(e){let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(Al).filter(n=>n!==null).slice(-4):[]}function Al(e){if(typeof e!="object"||e===null)return null;let t=e,n=$l(t.bodyText??t.body??"");return n?{author:typeof t.author=="string"?t.author:t.author?.login??null,body:n,createdAt:t.createdAt??null,url:t.url??null}:null}function $l(e){return e.replace(/\s+/g," ").trim()}function so(e,t){let n=e?.toUpperCase()??null,r=t?.toUpperCase()??null;return r==="SKIPPED"||n==="SKIPPED"?"skipped":n==="SUCCESS"||r==="SUCCESS"||r==="NEUTRAL"?"success":n==="PENDING"||n==="EXPECTED"||n==="IN_PROGRESS"||n==="QUEUED"||n==="REQUESTED"||n==="WAITING"?"pending":n==="FAILURE"||n==="FAILED"||n==="ERROR"||n==="TIMED_OUT"||n==="CANCELLED"||n==="ACTION_REQUIRED"||n==="STARTUP_FAILURE"||r==="FAILURE"||r==="FAILED"||r==="ERROR"||r==="TIMED_OUT"||r==="CANCELLED"||r==="ACTION_REQUIRED"||r==="STARTUP_FAILURE"?"failed":n==="COMPLETED"&&r===null?"unknown":n==="COMPLETED"&&r!==null?so(r,r):"unknown"}async function L(e,t){try{return await B(e,t)}catch(n){throw Fl(n)?new Error(`Craig task "${t}" was not found.`):n}}async function ce(e){if(!await Fn(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)}function Nn(e,t){return t.artifacts.logPath?oo.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:oo.join(e.workspaceRoot,t.artifacts.logPath):null}async function io(e,t){let n=await Fn(t.worktreePath),r=Nn(e,t),s=r?await Fn(r):!1;return{worktreeExists:n,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:Ml(t),lastCommitSummary:Ll(t),prSummary:jl(t),cleanupSummary:Ol(t)}}async function Fn(e){try{return await Dl(e),!0}catch{return!1}}function Ml(e){let t=e.checks.commands.length,n=t===1?"command":"commands",r=e.checks.lastRunAt?` at ${e.checks.lastRunAt}`:"";return`${e.checks.status} (${t} ${n})${r}`}function Ll(e){return e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed"}function jl(e){if(e.type==="project"&&e.repoTargets?.length){let s=e.repoTargets.filter(l=>l.pullRequest.number);if(s.length===0)return"not linked";let o=s.map(l=>` ${l.repoId} #${l.pullRequest.number} ${l.pullRequest.status??"unknown"}`),i=s.reduce((l,d)=>{let p=d.pullRequest.status??"unknown";return l[p]=(l[p]??0)+1,l},{}),c=Object.entries(i).map(([l,d])=>`${d} ${l}`).join(", ");return`${s.length} PR${s.length!==1?"s":""} (${c})
112
- ${o.join(`
113
- `)}`}let t=V(e);if(!t?.number||!t.url)return"not linked";let n=t.requiredChecks.length,r=n===1?"check":"checks";return`#${t.number} ${t.status??"unknown"} mergeable=${t.mergeable} mergeState=${t.mergeStateStatus??"unknown"} (${n} ${r})`}function Ol(e){return e.status!=="merged"?"not merged":e.cleanup.warning?`warning: ${e.cleanup.warning}`:e.cleanup.preservedWorktree?"preserved worktree":e.cleanup.worktreeRemovedAt?`worktree removed at ${e.cleanup.worktreeRemovedAt}`:"cleanup pending"}function Fl(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}async function ao(e,t){let n=await L(e,t);if(!n.sessionId)throw new Error(`Task ${n.id} does not have a Craig session to attach.`);let[r,s]=await Promise.all([de(e,n.repoId),Ve(e,n.sessionId)]),o=await et.attach(e,s,r.rootPath);return{kind:"attachTask",taskId:n.id,sessionId:o.id,disposition:"attached"}}async function lo(e,t){let n=await L(e,t),r=V(n);return r?.number?(await st(n.worktreePath),Dt(r)?(await jn(e,n)).task:Ln(e,n)):n}async function Lt(e,t){let n=await L(e,t),r=(n.repoTargets??[]).filter(i=>i.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let i of r){await st(i.worktreePath);let c=i.pullRequest.number?await ot(e,n,i):await ot(e,n,i).catch(()=>"not_found");s[c==="not_found"?"notFound":c]++}let o=await B(e,n.id);return o.status!=="closed"&&(o.status=po(o),await A(e,o)),s}async function uo(e,t){let n=new Map,r=new Map;for(let s of t){let o=Wn(n,s);if(s.type==="project"&&s.repoTargets?.length){for(let d of s.repoTargets.filter(p=>p.status==="ready")){let p={id:`${s.id}:${d.repoId}`,task:s,targetRepoId:d.repoId,worktreePath:d.worktreePath,selector:d.pullRequest.number?String(d.pullRequest.number):d.branch,mode:d.pullRequest.number?"number":"head"};await co(r,p).catch(async()=>{try{let h=d.pullRequest.number?await ot(e,s,d):await ot(e,s,d).catch(()=>"not_found");Mt(o,h,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=V(s),c=i?.number&&!Dt(i),l={id:s.id,task:s,worktreePath:s.worktreePath,selector:c?String(i.number):s.branch,mode:c?"number":"head"};await co(r,l).catch(async()=>{try{let{disposition:d,task:p}=await _n(e,s.id),h=V(p);Mt(o,d,h?.number??null,h?.url??null)}catch{}})}for(let s of r.values())try{await st(s.worktreePath);let o=await Qs(s.worktreePath,s.repository,s.items),i=new Map(o.map(c=>[c.id,c]));for(let c of s.items){let l=Wn(n,c.task),d=i.get(c.id);if(!d?.found||!d.view){Mt(l,"not_found",null,null);continue}c.targetRepoId?await Zs(e,c.task,c.targetRepoId,d.view):await Xs(e,c.task,d.view),Mt(l,c.mode==="number"?"synced":"discovered",d.view.number,d.view.url)}}catch{}for(let s of t.filter(o=>o.type==="project"&&o.repoTargets?.length)){let o=await B(e,s.id);o.status!=="closed"&&(o.status=po(o),await A(e,o))}return t.map(s=>Wn(n,s))}async function _n(e,t){let n=await L(e,t);await ce(n),await st(n.worktreePath);let r=V(n);if(r?.number&&!Dt(r))return{disposition:"synced",task:await Ln(e,n)};let s=await jn(e,n);return{disposition:s.discovered?"discovered":"not_found",task:s.task}}function po(e){let t=(e.repoTargets??[]).filter(r=>r.status==="ready"),n=t.map(r=>r.pullRequest).filter(r=>!!r.number);return n.length===0?e.status:n.every(r=>r.status==="merged")?"merged":n.length===t.length&&n.every(Nl)?"merge_ready":n.some(r=>r.status==="open")?"pr_open":"checked"}async function co(e,t){let n=await Js(t.worktreePath);if(!n)throw new Error("GitHub repository remote could not be parsed.");let r=`${n.owner}/${n.name}`,s=e.get(r);if(s){s.items.push(t);return}e.set(r,{worktreePath:t.worktreePath,repository:n,items:[t]})}function Wn(e,t){let n=e.get(t.id);if(n)return n;let r={taskId:t.id,synced:0,discovered:0,notFound:0,hadPr:t.type==="project"?!!t.repoTargets?.some(s=>s.pullRequest.number):!!V(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,r),r}function Mt(e,t,n,r){if(t==="synced"){e.synced+=1;return}if(t==="discovered"){e.discovered+=1,e.firstDiscoveredPrNumber??=n,e.firstDiscoveredPrUrl??=r;return}e.notFound+=1}function Nl(e){return e.mergeable&&e.reviewDecision!=="REVIEW_REQUIRED"&&e.reviewDecision!=="CHANGES_REQUESTED"&&e.mergeStateStatus!=="REVIEW_REQUIRED"&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped")}async function Bn(e,t){let n=await L(e,t);try{n.type==="project"&&n.repoTargets?.length?(await Lt(e,t),n=await L(e,t)):n.prs.some(o=>o.number)&&(n=await lo(e,t))}catch{}let r=await io(e,n),s=n.sessionId?await Ve(e,n.sessionId).catch(()=>null):null;return{kind:"showTask",task:n,inspection:r,session:s}}import{access as Wl}from"node:fs/promises";async function Un(e,t){let n=await L(e,t),r=Nn(e,n);if(!r)throw new Error(`Task ${n.id} does not have a Craig-managed log path.`);try{await Wl(r)}catch{throw new Error(`Task ${n.id} log file does not exist yet at ${r}.`)}return{kind:"streamTaskLogs",taskId:n.id,logPath:r}}async function qn(e,t){let n=await L(e,t);if(await ce(n),(await v("git",["status","--short"],{cwd:n.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:n.id,diffText:"",isEmpty:!0};let s=await _l(n.worktreePath);return{kind:"showTaskDiff",taskId:n.id,diffText:s,isEmpty:!1}}async function _l(e){let t=[],n=await v("git",["diff","--stat","--patch","HEAD"],{cwd:e});n.stdout.trim().length>0&&t.push(n.stdout.trimEnd());let r=await Bl(e);for(let s of r){let o=await M("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(o.stdout.trimEnd())}return t.join(`
113
+ `,md=e=>{if(!e||typeof e!="object")return null;let t="nodes"in e?e.nodes?.[0]??null:e;if(!t||typeof t!="object")return null;let r=t,n=r.statusCheckRollup?.contexts?.nodes??r.commits?.nodes?.[0]?.commit?.statusCheckRollup?.contexts?.nodes??[];return{number:r.number,url:r.url,baseRefName:r.baseRefName,headRefName:r.headRefName,headRefOid:r.headRefOid??null,state:r.state,isDraft:r.isDraft??!1,title:r.title??null,createdAt:r.createdAt??null,updatedAt:r.updatedAt??null,mergedAt:r.mergedAt??null,mergeable:r.mergeable,mergeStateStatus:r.mergeStateStatus,reviewDecision:r.reviewDecision??null,statusCheckRollup:n,comments:r.comments?.nodes??[]}};var Ke=async(e,t)=>{let r=_e(e,t.artifacts.prStatusPath);r&&(await gd(hd.dirname(r),{recursive:!0}),await B(r,{taskId:t.id,prs:t.prs}))},bt=async(e,t,r,n,s={readRawTask:ne,validateTaskRecord:G,writeTask:A,writePrStatusArtifact:Ke})=>{let o=gt(r,n),i=et(t,o),l=mt(i.prs),c={...i,status:l};await s.writePrStatusArtifact(e,c);let d=await s.readRawTask(e,t.id),u=s.validateTaskRecord(d,`${e.tasksDir}/${t.id}.json`),g=u.status==="closed"?u.status:l,w=et({...u,status:g},o);return await s.writeTask(e,w),w},St=async(e,t)=>{let r=O(t),n=r?.number?String(r.number):t.branch,s=await Qt(n,t.worktreePath);return bt(e,t,s,r)},It=async(e,t)=>{let r=await Jt(t.branch,t.worktreePath);return r?{discovered:!0,task:await bt(e,t,r,null)}:{discovered:!1,task:t}};var ot=async(e,t,r)=>{let n=r.pullRequest.number?String(r.pullRequest.number):r.branch;if(r.pullRequest.number){let i=await Qt(n,r.worktreePath),l=Go(i);return r.pullRequest=l,await Vo(e,t,r.repoId,l),"synced"}let s=await Jt(n,r.worktreePath);if(!s)return"not_found";let o=Go(s);return r.pullRequest=o,await Vo(e,t,r.repoId,o),"discovered"},Vo=async(e,t,r,n)=>{let s=await ne(e,t.id),o=G(s,`${e.tasksDir}/${t.id}.json`),i=(o.repoTargets??t.repoTargets??[]).map(c=>c.repoId===r?{...c,pullRequest:n}:c),l={...o,repoTargets:i};return await A(e,l),l},Go=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:kd(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:wd(e.reviewDecision??null),requiredChecks:ht(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),kd=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,wd=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null;var Ct=async(e,t)=>{let r=await $(e,t),n=O(r);return n?.number?(await st(r.worktreePath),Ee(n)?(await It(e,r)).task:St(e,r)):r},mn=async(e,t)=>{let r=await $(e,t);if(r.type==="project"&&r.repoTargets?.length)return await it(e,t),$(e,t);let n=O(r);if(await H(r),await st(r.worktreePath),!n?.number||Ee(n)){let o=await It(e,r);if(!o.discovered&&!n?.number)throw new Error(`No PR found for ${r.branch}.`);return await Ke(e,o.task),o.task}let s=await St(e,r);return await Ke(e,s),s},it=async(e,t)=>{let r=await $(e,t),n=(r.repoTargets??[]).filter(l=>l.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let l of n){await st(l.worktreePath);let c=l.pullRequest.number?await ot(e,r,l):await ot(e,r,l).catch(()=>"not_found");s[c==="not_found"?"notFound":c]++}let o=await ne(e,r.id),i=G(o,`${e.tasksDir}/${r.id}.json`);return i.status!=="closed"&&(i.status=zo(i),await A(e,i)),s},gn=async(e,t)=>{let r=new Map,n=new Map;for(let s of t){let o=fn(r,s);if(s.type==="project"&&s.repoTargets?.length){for(let d of s.repoTargets.filter(u=>u.status==="ready")){let u={id:`${s.id}:${d.repoId}`,task:s,targetRepoId:d.repoId,worktreePath:d.worktreePath,selector:d.pullRequest.number?String(d.pullRequest.number):d.branch,mode:d.pullRequest.number?"number":"head"};await Ho(n,u).catch(async()=>{try{let g=d.pullRequest.number?await ot(e,s,d):await ot(e,s,d).catch(()=>"not_found");Xt(o,g,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=O(s),l=i?.number&&!Ee(i),c={id:s.id,task:s,worktreePath:s.worktreePath,selector:l?String(i.number):s.branch,mode:l?"number":"head"};await Ho(n,c).catch(async()=>{try{let{disposition:d,task:u}=await Zt(e,s.id),g=O(u);Xt(o,d,g?.number??null,g?.url??null)}catch{}})}for(let s of n.values())try{await st(s.worktreePath);let o=await Uo(s.worktreePath,s.repository,s.items),i=new Map(o.map(l=>[l.id,l]));for(let l of s.items){let c=fn(r,l.task),d=i.get(l.id);if(!d?.found||!d.view){Xt(c,"not_found",null,null);continue}if(l.targetRepoId){let u=await ne(e,l.task.id),g=G(u,`${e.tasksDir}/${l.task.id}.json`);await Rd(e,g,l.targetRepoId,d.view)}else{let u=await ne(e,l.task.id),g=G(u,`${e.tasksDir}/${l.task.id}.json`);await bt(e,g,d.view,O(g))}Xt(c,l.mode==="number"?"synced":"discovered",d.view.number,d.view.url)}}catch{}for(let s of t.filter(o=>o.type==="project"&&o.repoTargets?.length)){let o=await ne(e,s.id),i=G(o,`${e.tasksDir}/${s.id}.json`);i.status!=="closed"&&(i.status=zo(i),await A(e,i))}return t.map(s=>fn(r,s))},Zt=async(e,t)=>{let r=await $(e,t);await H(r),await st(r.worktreePath);let n=O(r);if(n?.number&&!Ee(n))return{disposition:"synced",task:await St(e,r)};let s=await It(e,r);return{disposition:s.discovered?"discovered":"not_found",task:s.task}},zo=e=>{let t=(e.repoTargets??[]).filter(n=>n.status==="ready"),r=t.map(n=>n.pullRequest).filter(n=>!!n.number);return r.length===0?e.status:r.every(n=>n.status==="merged")?"merged":r.length===t.length&&r.every(bd)?"merge_ready":r.some(n=>n.status==="open")?"pr_open":"checked"},Rd=async(e,t,r,n)=>{let s=Td(n),o=(t.repoTargets??[]).map(l=>l.repoId===r?{...l,pullRequest:s}:l),i={...t,repoTargets:o};return await A(e,i),i},Td=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:yd(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:Pd(e.reviewDecision??null),requiredChecks:ht(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),yd=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,Pd=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Ho=async(e,t)=>{let r=await qo(t.worktreePath);if(!r)throw new Error("GitHub repository remote could not be parsed.");let n=`${r.owner}/${r.name}`,s=e.get(n);if(s){s.items.push(t);return}e.set(n,{worktreePath:t.worktreePath,repository:r,items:[t]})},fn=(e,t)=>{let r=e.get(t.id);if(r)return r;let n={taskId:t.id,synced:0,discovered:0,notFound:0,hadPr:t.type==="project"?!!t.repoTargets?.some(s=>s.pullRequest.number):!!O(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,n),n},Xt=(e,t,r,n)=>{if(t==="synced"){e.synced+=1;return}if(t==="discovered"){e.discovered+=1,e.firstDiscoveredPrNumber??=r,e.firstDiscoveredPrUrl??=n;return}e.notFound+=1},bd=e=>e.mergeable&&e.reviewDecision!=="REVIEW_REQUIRED"&&e.reviewDecision!=="CHANGES_REQUESTED"&&e.mergeStateStatus!=="REVIEW_REQUIRED"&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped");var hn=async(e,t)=>{let r=await $(e,t);try{r.type==="project"&&r.repoTargets?.length?(await it(e,t),r=await $(e,t)):r.prs.some(o=>o.number)&&(r=await Ct(e,t))}catch{}let n=await kt(e,r),s=r.sessionId?await Ae(e,r.sessionId).catch(()=>null):null;return{kind:"showTask",task:r,inspection:n,session:s}};var kn=async(e,t)=>{let r=await $(e,t);if(await H(r),(await v("git",["status","--short"],{cwd:r.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:r.id,diffText:"",isEmpty:!0};let s=await Sd(r.worktreePath);return{kind:"showTaskDiff",taskId:r.id,diffText:s,isEmpty:!1}},Sd=async e=>{let t=[],r=await v("git",["diff","--stat","--patch","HEAD"],{cwd:e});r.stdout.trim().length>0&&t.push(r.stdout.trimEnd());let n=await Id(e);for(let s of n){let o=await M("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(o.stdout.trimEnd())}return t.join(`
114
114
 
115
- `)}async function Bl(e){return(await v("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
116
- `).map(n=>n.trim()).filter(n=>n.length>0)}async function Kn(e,t){let n=await L(e,t);if(!n.sessionId)throw new Error(`Task ${n.id} does not have a Craig session.`);let r=await Ve(e,n.sessionId).catch(s=>{throw Ul(s)?new Error(`Task ${n.id} does not have a Craig session.`):s});if(!r.paneId)throw new Error(`Task ${n.id} does not have a tmux target.`);return await St(e.repoRoot,r.paneId,r.windowTarget,r.sessionName),{kind:"focusTask",taskId:n.id,tmuxTarget:r.paneId}}function Ul(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}import{spawn as ql}from"node:child_process";async function Vn(e,t){let n=await L(e,t);await ce(n);let s=(await b.load(e)).open?.command??[];if(s.length===0)return{kind:"openTask",taskId:n.id,worktreePath:n.worktreePath,launched:!1,command:null};let o=[...s,n.worktreePath];return await Kl(o,e.repoRoot),{kind:"openTask",taskId:n.id,worktreePath:n.worktreePath,launched:!0,command:o}}async function Kl(e,t){await new Promise((n,r)=>{let[s,...o]=e,i=ql(s,o,{cwd:t,stdio:"inherit"});i.on("error",r),i.on("exit",c=>{if(c===0){n();return}r(new Error(`${e.join(" ")} failed with exit code ${c??"unknown"}.`))})})}import{mkdir as Vl}from"node:fs/promises";import Gl from"node:path";async function Gn(e,t){let n=await L(e,t);if(await ce(n),n.status==="draft"||n.status==="merged")throw new Error(`Task ${n.id} cannot run checks from status "${n.status}".`);if(n.status==="running"&&await It(n.worktreePath)&&(n.status="review"),n.status!=="review"&&n.status!=="checked")throw new Error(`Task ${n.id} cannot run checks from status "${n.status}".`);let s=(await b.load(e)).checks?.commands??[];if(s.length===0)throw new Error(`Craig config at ${e.configFile} does not define any "checks.commands".`);n.checks.status="running",n.checks.commands=[...s],n.checks.results=[],await A(e,n);let o=[];for(let i of s){let c=new Date().toISOString(),l=await M("sh",["-lc",i],{cwd:n.worktreePath}),d=new Date().toISOString(),p=l.exitCode??1;if(o.push({command:i,startedAt:c,finishedAt:d,exitCode:p}),p!==0)return n.checks.results=o,n.checks.status="failed",n.checks.lastRunAt=d,n.status="review",n.lastFailureReason=l.stderr.trim()||l.stdout.trim()||`Check command failed: ${i}`,await fo(e,n),await A(e,n),{kind:"runChecks",taskId:n.id,status:"failed",commands:s}}return n.checks.results=o,n.checks.status="passed",n.checks.lastRunAt=new Date().toISOString(),n.status="checked",n.lastFailureReason=null,await fo(e,n),await A(e,n),{kind:"runChecks",taskId:n.id,status:"passed",commands:s}}async function fo(e,t){let n=Et(e,t.artifacts.checkSummaryPath);n&&(await Vl(Gl.dirname(n),{recursive:!0}),await _(n,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))}async function Hn(e,t){let n=await L(e,t);await ce(n);let r=await It(n.worktreePath);if(n.status==="running"&&r&&(n.status="review"),n.status!=="review"&&n.status!=="checked")throw new Error(`Task ${n.id} cannot commit from status "${n.status}".`);if(!r)throw new Error(`Task ${n.id} has no uncommitted diff to commit.`);let s=n.prompt.value.trim();await Ms(n.worktreePath),await Ls(n.worktreePath,s);let o=await js(n.worktreePath);return n.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},n.lastFailureReason=null,await A(e,n),{kind:"commitTask",taskId:n.id,status:n.status,commitSha:o.sha,message:o.message}}import{readdir as Yl,stat as Jl}from"node:fs/promises";import ze from"node:path";import{realpath as mo}from"node:fs/promises";import go from"node:path";var zn=async e=>{try{let n=(await v("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[r,s]=await Promise.all([mo(n).catch(()=>go.resolve(n)),mo(e).catch(()=>go.resolve(e))]);return r===s}catch{return!1}},Yn=async e=>{let t=await M("git",["symbolic-ref","--quiet","--short","refs/remotes/origin/HEAD"],{cwd:e}),n=t.stdout.trim().replace(/^origin\//,"");if(t.exitCode===0&&n.length>0)return n;for(let o of["main","master","trunk"])if((await M("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await v("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"};import{mkdir as we,readFile as Hl}from"node:fs/promises";import X from"node:path";function Re(e){let t=X.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:X.join(t,"index.json"),reposDir:X.join(t,"repos"),workspacesDir:X.join(t,"workspaces"),sessionsDir:X.join(t,"sessions"),runtimeDir:X.join(t,"runtime"),uiStateFile:X.join(t,"runtime","ui-state.json"),tasksDir:X.join(t,"tasks"),jobsDir:X.join(t,"jobs"),logsDir:X.join(t,"logs"),errorLogFile:X.join(t,"logs","errors.log"),artifactsDir:X.join(t,"artifacts"),worktreesDir:X.join(t,"worktrees"),configFile:X.join(t,"config.json")}}var zl=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",He=async e=>{let t=Re(e);await we(t.craigDir,{recursive:!0}),await Promise.all([we(t.reposDir,{recursive:!0}),we(t.workspacesDir,{recursive:!0}),we(t.sessionsDir,{recursive:!0}),we(t.runtimeDir,{recursive:!0}),we(t.tasksDir,{recursive:!0}),we(t.jobsDir,{recursive:!0}),we(t.logsDir,{recursive:!0}),we(t.artifactsDir,{recursive:!0}),we(t.worktreesDir,{recursive:!0})]);try{let s=await Hl(t.indexFile,"utf8"),o=JSON.parse(s);return yt(o,e,t.indexFile)}catch(s){if(!zl(s))throw s instanceof SyntaxError?new Error(`Craig index at ${t.indexFile} is malformed. Remove or repair the file before rerunning Craig.`):s}let n=new Date().toISOString(),r={version:2,workspaceRoot:e,repoIds:[],workspaceIds:[],taskIds:[],jobIds:[],createdAt:n,updatedAt:n};return await _(t.indexFile,r),r};var ho=(e,t,n)=>{let r=new Date().toISOString();return{id:Ql(e,ze.basename(t)),name:ze.basename(t),rootPath:t,defaultBranch:n,createdAt:r,updatedAt:r}},wo=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},Ql=(e,t)=>{let n=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"repo",r=`repo_${n}`,s=2;for(;e.some(o=>o.id===r);)r=`repo_${n}_${s}`,s+=1;return r},Xl=(e,t)=>{let n=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"workspace",r=`workspace_${n}`,s=2;for(;e.some(o=>o.id===r);)r=`workspace_${n}_${s}`,s+=1;return r},ko=async(e,t)=>{let n=await ne(e);await Ce(e,{...n,repoIds:[...new Set([...n.repoIds,...t.repoIds])],workspaceIds:[...new Set([...n.workspaceIds,...t.workspaceIds])]})},Ro=async(e,t,n)=>{let r=await Y({uiStateFile:e.uiStateFile})??ge();await H({uiStateFile:e.uiStateFile},{...r,selectedRepoId:n,selectedWorkspaceId:t.id,selectedTaskId:null})},Zl=async(e,t)=>{let n=await Yl(t,{withFileTypes:!0}),r=await tt(e),s=[];for(let o of n){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=ze.join(t,o.name);if(!await zn(i))continue;let c=r.find(d=>d.rootPath===i)??s.find(d=>d.rootPath===i),l=await Yn(i);s.push(c?wo(c,l):ho([...r,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))},ed=async(e,t)=>{let n=await Yn(t),r=await tt(e),s=r.find(h=>h.rootPath===t)??null,o=s?wo(s,n):ho(r,t,n),i=`workspace_${o.id}`,l=(await re(e)).find(h=>h.id===i)??null,d=new Date().toISOString(),p=l??{id:i,kind:"repo",name:o.name,rootPath:t,primaryRepoId:o.id,repoId:o.id,discoveredRepoIds:[o.id],branch:n,status:"active",linkedRepoIds:[],archivedAt:null,createdAt:d,updatedAt:d};return await vn(e,o),l||await Fe(e,p),await ko(e,{repoIds:[o.id],workspaceIds:[p.id]}),await Ro(e,p,o.id),{kind:"createWorkspace",workspace:p,repos:[o],created:!l}},td=async(e,t)=>{let n=await Zl(e,t);if(n.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let r=await re(e),s=Xl(r,ze.basename(t)),o=r.find(d=>d.kind==="project"&&d.rootPath===t)??null,i=new Date().toISOString(),c=n.map(d=>d.id),l=o?{...o,discoveredRepoIds:c,primaryRepoId:c[0]??o.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:ze.basename(t),rootPath:t,primaryRepoId:c[0]??"",discoveredRepoIds:c,branch:"project",status:"active",linkedRepoIds:c,archivedAt:null,createdAt:i,updatedAt:i};return await Promise.all(n.map(d=>vn(e,d))),await Fe(e,l),await ko(e,{repoIds:c,workspaceIds:[l.id]}),await Ro(e,l,c[0]??null),{kind:"createWorkspace",workspace:l,repos:n,created:!o}},it=async(e,t)=>{await He(e.workspaceRoot);let n=ze.resolve(e.workspaceRoot,t);if(!(await Jl(n).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${n}`);return await zn(n)?ed(e,n):td(e,n)};var Jn=async(e,t,n={listWorkspaceRecords:re,ensureCraigState:He})=>(await n.ensureCraigState(e.workspaceRoot),{kind:"listWorkspaces",workspaces:(await n.listWorkspaceRecords(e)).filter(s=>s.status===(t.archived?"archived":"active")),archivedOnly:t.archived});var Qn=async(e,t,n={readWorkspace:Oe,writeWorkspace:Fe,readUiState:Y,writeUiState:H})=>{let s={...await n.readWorkspace(e,t),status:"archived",archivedAt:new Date().toISOString()};await n.writeWorkspace(e,s);let o=await n.readUiState({uiStateFile:e.uiStateFile});return o&&o.selectedWorkspaceId===t&&await n.writeUiState({uiStateFile:e.uiStateFile},{...o,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null}),{kind:"archiveWorkspace",workspaceId:s.id,status:s.status,branch:s.branch}};var Xn=async(e,t)=>{let r={...await Oe(e,t),status:"active",archivedAt:null};await Fe(e,r);let s=await Y({uiStateFile:e.uiStateFile})??null;return await H({uiStateFile:e.uiStateFile},{...s??ge(),selectedWorkspaceId:r.id,selectedRepoId:r.kind==="project"?r.discoveredRepoIds?.[0]??null:r.primaryRepoId,selectedTaskId:null}),{kind:"restoreWorkspace",workspaceId:r.id,status:r.status,branch:r.branch}};var Ne=async(e,t,n={deleteWorkspace:$s,readCraigIndex:ne,writeCraigIndex:Ce})=>{await n.deleteWorkspace(e,t);let r=await n.readCraigIndex(e);await n.writeCraigIndex(e,{...r,workspaceIds:r.workspaceIds.filter(s=>s!==t)})};var nd=async(e,t)=>{let n=await Y({uiStateFile:e.uiStateFile});!n||n.selectedWorkspaceId!==t||await H({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})},Zn=async(e,t)=>{let n=await Oe(e,t),r=await he(e,{workspaceId:t,includeClosed:!0});if(n.status==="active")throw new Error(`Cannot remove workspace ${t} while it is active. Archive it first.`);if(r.tasks.length>0)throw new Error(`Cannot remove workspace ${t} while task records still reference it.`);return await Ne(e,t),await nd(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};var er={};mn(er,{addRepo:()=>To,listRegisteredRepos:()=>yo,removeRepo:()=>Po});import rd from"node:path";import{stat as sd}from"node:fs/promises";var To=async(e,t)=>{let n=rd.resolve(e.workspaceRoot,t);if(!(await sd(n).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${n}`);let s=await it(e,t),o=s.repos[0];if(!o||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${n}`);return{kind:"createRepo",repo:o,workspaceId:s.workspace.id,created:s.created}};var yo=async(e,t={listRepos:tt,ensureCraigState:He})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var Po=async(e,t)=>{let n=await de(e,t),s=(await re(e)).filter(d=>d.primaryRepoId===t),o=s.filter(d=>d.status==="active"),i=await he(e,{repoId:t});if(o.length>0)throw new Error(`Cannot remove repo ${t} while active workspace records still reference it.`);if(i.tasks.length>0)throw new Error(`Cannot remove repo ${t} while task records still reference it.`);await Promise.all(s.map(d=>Ne(e,d.id))),await vs(e,t);let c=await ne(e);await Ce(e,{...c,repoIds:c.repoIds.filter(d=>d!==t)});let l=await Y({uiStateFile:e.uiStateFile});return l?.selectedRepoId===t&&await H({uiStateFile:e.uiStateFile},{...l,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var Z={addWorkspace:it,listWorkspaces:Jn,archiveWorkspace:Qn,restoreWorkspace:Xn,removeWorkspace:Zn,removeWorkspaceRecord:Ne,repos:er};async function bo(e,t,n){let[r,s]=await Promise.all([L(e,t),de(e,n)]);if(r.repoId===s.id)throw new Error(`Repo ${s.id} is already the primary repo for task ${r.id}.`);let o=r.linkedRepoIds.includes(s.id)?r.linkedRepoIds:[...r.linkedRepoIds,s.id];return await A(e,{...r,linkedRepoIds:o}),{kind:"addTaskLink",taskId:r.id,repoId:s.id,linkedRepoIds:o}}async function So(e,t){let n=await L(e,t),r=await Promise.all(n.linkedRepoIds.map(s=>de(e,s)));return{kind:"listTaskLinks",taskId:n.id,repos:r}}async function Io(e,t){switch(e.kind){case"addWorkspace":return Z.addWorkspace(t.paths,e.path);case"addRepo":return Z.repos.addRepo(t.paths,e.path);case"listRepos":return Z.repos.listRegisteredRepos(t.paths);case"removeRepo":return Z.repos.removeRepo(t.paths,e.repoId);case"listWorkspaces":return Z.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":return Z.archiveWorkspace(t.paths,e.workspaceId);case"restoreWorkspace":return Z.restoreWorkspace(t.paths,e.workspaceId);case"removeWorkspace":return Z.removeWorkspace(t.paths,e.workspaceId);case"createTask":return Vs(t.paths,e.repoId??e.workspaceId??"",e.prompt,{...e.runner?{runner:e.runner}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}});case"listTasks":return e.repoId||e.workspaceId?he(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):he(t.paths);case"attachTask":return ao(t.paths,e.taskId);case"addTaskLink":return bo(t.paths,e.taskId,e.repoId);case"listTaskLinks":return So(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return Bn(t.paths,e.taskId);case"showSelectedTask":return Bn(t.paths,We(t,"show"));case"streamTaskLogs":return Un(t.paths,e.taskId);case"streamSelectedTaskLogs":return Un(t.paths,We(t,"logs"));case"showTaskDiff":return qn(t.paths,e.taskId);case"showSelectedTaskDiff":return qn(t.paths,We(t,"diff"));case"focusTask":return Kn(t.paths,e.taskId);case"focusSelectedTask":return Kn(t.paths,We(t,"focus"));case"openTask":return Vn(t.paths,e.taskId);case"openSelectedTask":return Vn(t.paths,We(t,"open"));case"runChecks":return Gn(t.paths,e.taskId);case"runSelectedTaskChecks":return Gn(t.paths,We(t,"check"));case"commitTask":return Hn(t.paths,e.taskId);case"commitSelectedTask":return Hn(t.paths,We(t,"commit"));case"help":return{kind:"help",text:Q()};case"exit":return{kind:"exit"};default:return od(e)}}function od(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function We(e,t){if(e.selectedTaskId)return e.selectedTaskId;throw new Error(`No task selected. Create a task with 'task new --repo <repo-id> <prompt>' or use '${t} <id>'.`)}function Co(e){switch(e.kind){case"createWorkspace":return[`${e.created?"Registered":"Updated"} ${e.workspace.kind??"repo"} workspace ${e.workspace.id}`,`Path: ${e.workspace.rootPath??""}`,`Repos: ${e.repos.map(t=>t.id).join(", ")}`].join(`
115
+ `)},Id=async e=>(await v("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
116
+ `).map(r=>r.trim()).filter(r=>r.length>0);import{spawn as Cd}from"node:child_process";import{access as xd}from"node:fs/promises";var wn=async(e,t)=>{let r=await $(e,t),n=tt(e,r);if(!n)throw new Error(`Task ${r.id} does not have a Craig-managed log path.`);try{await xd(n)}catch{throw new Error(`Task ${r.id} log file does not exist yet at ${n}.`)}return{kind:"streamTaskLogs",taskId:r.id,logPath:n}},Rn=async e=>{await new Promise((t,r)=>{let n=!1,s=Cd("tail",["-n","+1","-f",e],{stdio:"inherit"}),o=()=>{n=!0,s.kill("SIGINT")};process.on("SIGINT",o),s.on("error",l=>{i(),r(l)}),s.on("exit",(l,c)=>{if(i(),n||c==="SIGINT"){t();return}if(l===0){t();return}r(new Error(`tail -n +1 -f ${e} failed with exit code ${l??"unknown"}.`))});function i(){process.off("SIGINT",o)}})};import{mkdir as vd}from"node:fs/promises";import Ed from"node:path";var Tn=async(e,t)=>{let r=await $(e,t);if(await H(r),r.status==="draft"||r.status==="merged")throw new Error(`Task ${r.id} cannot run checks from status "${r.status}".`);if(r.status==="running"&&await Vt(r.worktreePath)&&(r.status="review"),r.status!=="review"&&r.status!=="checked")throw new Error(`Task ${r.id} cannot run checks from status "${r.status}".`);let s=(await S.load(e)).checks?.commands??[];if(s.length===0)throw new Error(`Craig config at ${e.configFile} does not define any "checks.commands".`);r.checks.status="running",r.checks.commands=[...s],r.checks.results=[],await A(e,r);let o=[];for(let i of s){let l=new Date().toISOString(),c=await M("sh",["-lc",i],{cwd:r.worktreePath}),d=new Date().toISOString(),u=c.exitCode??1;if(o.push({command:i,startedAt:l,finishedAt:d,exitCode:u}),u!==0)return r.checks.results=o,r.checks.status="failed",r.checks.lastRunAt=d,r.status="review",r.lastFailureReason=c.stderr.trim()||c.stdout.trim()||`Check command failed: ${i}`,await Yo(e,r),await A(e,r),{kind:"runChecks",taskId:r.id,status:"failed",commands:s}}return r.checks.results=o,r.checks.status="passed",r.checks.lastRunAt=new Date().toISOString(),r.status="checked",r.lastFailureReason=null,await Yo(e,r),await A(e,r),{kind:"runChecks",taskId:r.id,status:"passed",commands:s}},Yo=async(e,t)=>{let r=_e(e,t.artifacts.checkSummaryPath);r&&(await vd(Ed.dirname(r),{recursive:!0}),await B(r,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))};var yn=async(e,t)=>{let r=await $(e,t);await H(r);let n=await Vt(r.worktreePath);if(r.status==="running"&&n&&(r.status="review"),r.status!=="review"&&r.status!=="checked")throw new Error(`Task ${r.id} cannot commit from status "${r.status}".`);if(!n)throw new Error(`Task ${r.id} has no uncommitted diff to commit.`);let s=r.prompt.value.trim();await ho(r.worktreePath),await ko(r.worktreePath,s);let o=await wo(r.worktreePath);return r.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},r.lastFailureReason=null,await A(e,r),{kind:"commitTask",taskId:r.id,status:r.status,commitSha:o.sha,message:o.message}};import{access as Ad}from"node:fs/promises";var Pn=async(e,t)=>{let r=await $(e,t),n=await Dd(r.worktreePath),s={...r,status:"closed",cleanup:{...r.cleanup,preservedWorktree:n&&r.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await A(e,s),s},Dd=async e=>{try{return await Ad(e),!0}catch{return!1}};var bn=async(e,t,r)=>{let n=[];try{if(t.sessionId){let s=await Ae(e,t.sessionId);await Lo(e.repoRoot,s.sessionName),t.cleanup.paneClosedAt=new Date().toISOString()}}catch(s){n.push(s instanceof Error?s.message:"Failed to close tmux session.")}if(t.cleanup.preservedWorktree=r.preserveWorktree,!r.preserveWorktree)try{await Ro(e.repoRoot,t.worktreePath),t.cleanup.worktreeRemovedAt=new Date().toISOString()}catch(s){n.push(s instanceof Error?s.message:"Failed to remove worktree.")}t.cleanup.warning=n.length>0?n.join(" "):null,await A(e,t)};var Sn=async(e,t,r)=>{let[n,s]=await Promise.all([$(e,t),ue(e,r)]);if(n.repoId===s.id)throw new Error(`Repo ${s.id} is already the primary repo for task ${n.id}.`);let o=n.linkedRepoIds.includes(s.id)?n.linkedRepoIds:[...n.linkedRepoIds,s.id];return await A(e,{...n,linkedRepoIds:o}),{kind:"addTaskLink",taskId:n.id,repoId:s.id,linkedRepoIds:o}},In=async(e,t)=>{let r=await $(e,t),n=await Promise.all(r.linkedRepoIds.map(s=>ue(e,s)));return{kind:"listTaskLinks",taskId:r.id,repos:n}};var Cn=async(e,t)=>{let r=await $(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session to attach.`);let[n,s]=await Promise.all([ue(e,r.repoId),Ae(e,r.sessionId)]),o=await Pt.attach(e,s,n.rootPath);return{kind:"attachTask",taskId:r.id,sessionId:o.id,disposition:"attached"}};var xn=async(e,t)=>{let r=await $(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session.`);let n=await Ae(e,r.sessionId).catch(s=>{throw $d(s)?new Error(`Task ${r.id} does not have a Craig session.`):s});if(!n.paneId)throw new Error(`Task ${r.id} does not have a tmux target.`);return await Yt(e.repoRoot,n.paneId,n.windowTarget,n.sessionName),{kind:"focusTask",taskId:r.id,tmuxTarget:n.paneId}},$d=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";import{spawn as Ld}from"node:child_process";var vn=async(e,t)=>{let r=await $(e,t);await H(r);let s=(await S.load(e)).open?.command??[];if(s.length===0)return{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!1,command:null};let o=[...s,r.worktreePath];return await jd(o,e.repoRoot),{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!0,command:o}},jd=async(e,t)=>{await new Promise((r,n)=>{let[s,...o]=e,i=Ld(s,o,{cwd:t,stdio:"inherit"});i.on("error",n),i.on("exit",l=>{if(l===0){r();return}n(new Error(`${e.join(" ")} failed with exit code ${l??"unknown"}.`))})})};var En=async(e,t,r)=>{let n=await pe(e,t);await A(e,{...n,status:n.status==="running"?"draft":n.status,runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r})},An=async(e,t,r)=>{let n=await pe(e,t),s={...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r};return await A(e,s),s},Dn=async(e,t)=>{let r=await pe(e,t),n=r.ptyTabs.find(o=>o.kind==="agent");if(!n)throw new Error(`Task ${t} is missing its agent PTY tab.`);let s={...r,status:"running",selectedPtyTabId:n.id,runnerSession:{...r.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}};return await A(e,s),s};var $n=async(e,t,r="merge",n)=>{let s=await $(e,t),o=n??O(s)?.number;if(!o)throw new Error(`Task ${s.id} has no pull request to merge.`);await Bo(s.worktreePath,o,r)};var D={listTasks:nn,getTask:$,provisionTask:nt,provisionProjectTask:Tt,createTask:pn,showTask:hn,showTaskDiff:kn,prepareTaskLogs:wn,streamTaskLogs:Rn,runChecks:Tn,commitTask:yn,closeTask:Pn,cleanupTask:bn,addTaskLink:Sn,listTaskLinks:In,sortTasksForDisplay:sn,resolveSelectedTaskId:on,allocateTaskId:rn,allocateTaskIdForRepo:rt,allocateProjectTaskId:wt,createDefaultTaskPtyTabs:yt,assertTaskWorktreeExists:H,resolveTaskLogPath:tt,buildTaskInspection:kt,resolveArtifactPath:_e,attachTask:Cn,focusTask:xn,openTask:vn,markRunnerFailed:En,recordStartupFailure:An,markTaskStarted:Dn,prs:{refresh:Ct,refreshChecks:mn,discoverOrRefresh:Zt,discoverOrRefreshAll:it,discoverOrRefreshMany:gn,merge:$n,getPrimaryPr:O,isPrTerminal:Ee,isMergeReady:Kt,deriveTaskStatus:mt,upsertPr:et,normalizePr:gt,summarizeRequiredChecks:Zr,writePrStatusArtifact:Ke}};async function Qo(e,t){switch(e.kind){case"addWorkspace":return re.addWorkspace(t.paths,e.path);case"addRepo":return re.repos.addRepo(t.paths,e.path);case"listRepos":return re.repos.listRegisteredRepos(t.paths);case"removeRepo":return re.repos.removeRepo(t.paths,e.repoId,{listTasks:D.listTasks});case"listWorkspaces":return re.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":return re.archiveWorkspace(t.paths,e.workspaceId);case"restoreWorkspace":return re.restoreWorkspace(t.paths,e.workspaceId);case"removeWorkspace":return re.removeWorkspace(t.paths,e.workspaceId,{listTasks:D.listTasks});case"createTask":return D.createTask(t.paths,e.repoId??e.workspaceId??"",e.prompt,{...e.runner?{runner:e.runner}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}});case"listTasks":return e.repoId||e.workspaceId?D.listTasks(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):D.listTasks(t.paths);case"attachTask":return D.attachTask(t.paths,e.taskId);case"addTaskLink":return D.addTaskLink(t.paths,e.taskId,e.repoId);case"listTaskLinks":return D.listTaskLinks(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return D.showTask(t.paths,e.taskId);case"showSelectedTask":return D.showTask(t.paths,Ve(t,"show"));case"streamTaskLogs":return D.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return D.prepareTaskLogs(t.paths,Ve(t,"logs"));case"showTaskDiff":return D.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return D.showTaskDiff(t.paths,Ve(t,"diff"));case"focusTask":return D.focusTask(t.paths,e.taskId);case"focusSelectedTask":return D.focusTask(t.paths,Ve(t,"focus"));case"openTask":return D.openTask(t.paths,e.taskId);case"openSelectedTask":return D.openTask(t.paths,Ve(t,"open"));case"runChecks":return D.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return D.runChecks(t.paths,Ve(t,"check"));case"commitTask":return D.commitTask(t.paths,e.taskId);case"commitSelectedTask":return D.commitTask(t.paths,Ve(t,"commit"));case"help":return{kind:"help",text:Z()};case"exit":return{kind:"exit"};default:return Md(e)}}function Md(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function Ve(e,t){if(e.selectedTaskId)return e.selectedTaskId;throw new Error(`No task selected. Create a task with 'task new --repo <repo-id> <prompt>' or use '${t} <id>'.`)}function Jo(e){switch(e.kind){case"createWorkspace":return[`${e.created?"Registered":"Updated"} ${e.workspace.kind??"repo"} workspace ${e.workspace.id}`,`Path: ${e.workspace.rootPath??""}`,`Repos: ${e.repos.map(t=>t.id).join(", ")}`].join(`
117
117
  `);case"createRepo":return[`${e.created?"Registered":"Already registered"} repo ${e.repo.id}`,`Path: ${e.repo.rootPath}`,`Branch: ${e.repo.defaultBranch}`,`Workspace: ${e.workspaceId}`].join(`
118
118
  `);case"listRepos":return e.repos.length===0?"No repos registered yet. Use 'craig repo add <path>'.":["ID NAME BRANCH PATH",...e.repos.map(t=>`${t.id} ${t.name} ${t.defaultBranch} ${t.rootPath}`)].join(`
119
119
  `);case"removeRepo":return`Removed repo ${e.repoId} (${e.rootPath})`;case"listWorkspaces":return e.workspaces.length===0?e.archivedOnly?"No archived workspaces.":"No active workspaces yet. Register one with 'craig workspace add <path>'.":["ID KIND STATUS REPOS PATH",...e.workspaces.map(t=>`${t.id} ${t.kind??"repo"} ${t.status} ${(t.discoveredRepoIds??[t.primaryRepoId]).join(",")} ${t.rootPath??""}`)].join(`
120
120
  `);case"archiveWorkspace":return`Archived workspace ${e.workspaceId} on branch ${e.branch}`;case"restoreWorkspace":return`Restored workspace ${e.workspaceId} on branch ${e.branch}`;case"removeWorkspace":return`Removed workspace ${e.workspaceId} (${e.rootPath})`;case"createTask":return[`Created task ${e.taskId}`,`Repo: ${e.repoId}`,`Workspace: ${e.workspaceId}`,`Session: ${e.sessionId}`,`Status: ${e.status}`,`Branch: ${e.branch}`,`Worktree: ${e.worktreePath}`,`Runner: ${e.runner}`].join(`
121
121
  `);case"attachTask":return`Attached to task ${e.taskId} via session ${e.sessionId}`;case"addTaskLink":return`Linked repo ${e.repoId} to task ${e.taskId}: ${e.linkedRepoIds.join(", ")}`;case"listTaskLinks":return e.repos.length===0?`Task ${e.taskId} has no linked repos.`:["ID NAME BRANCH PATH",...e.repos.map(t=>`${t.id} ${t.name} ${t.defaultBranch} ${t.rootPath}`)].join(`
122
- `);case"help":return e.text;case"exit":return"";case"listTasks":return e.tasks.length===0?`No Craig tasks yet. Use 'task new --repo <repo-id> <prompt>' to create one.${e.missingTaskIds.length>0?` (${e.missingTaskIds.length} referenced task file(s) missing from .craig/tasks)`:""}`:["ID REPO STATUS CHECKS PR TITLE",...e.tasks.map(t=>`${t.id} ${t.repoId} ${t.status} ${cd(t)} ${ld(t)} ${t.title}`)].join(`
123
- `);case"showTask":return[`${e.task.id}: ${e.task.title}`,`Status: ${e.task.status}`,`Runner: ${e.task.runner}`,`Repo: ${e.task.repoId}`,`Workspace: ${e.task.workspaceId}`,`Branch: ${e.task.branch}`,`Worktree: ${e.task.worktreePath}`,`Session: ${e.task.sessionId??"<missing>"}`,`tmux: ${e.session?.paneId??"<missing>"}`,`Linked repos: ${e.task.linkedRepoIds.length>0?e.task.linkedRepoIds.join(", "):"none"}`,`Prompt: ${e.task.prompt.source} ${JSON.stringify(e.task.prompt.value)}`,`Runner command: ${e.inspection.runnerCommandText||"<none>"}`,`Runner state: ${e.task.runnerSession.lastKnownState}`,`Started: ${e.task.runnerSession.startedAt??"not started"}`,`Exited: ${e.task.runnerSession.exitedAt??"still running"}`,`Checks: ${e.inspection.checksSummary}`,`Last commit: ${e.inspection.lastCommitSummary}`,`PR: ${e.inspection.prSummary}`,`Cleanup: ${e.inspection.cleanupSummary}`,...id(e)].join(`
122
+ `);case"help":return e.text;case"exit":return"";case"listTasks":return e.tasks.length===0?`No Craig tasks yet. Use 'task new --repo <repo-id> <prompt>' to create one.${e.missingTaskIds.length>0?` (${e.missingTaskIds.length} referenced task file(s) missing from .craig/tasks)`:""}`:["ID REPO STATUS CHECKS PR TITLE",...e.tasks.map(t=>`${t.id} ${t.repoId} ${t.status} ${Fd(t)} ${Wd(t)} ${t.title}`)].join(`
123
+ `);case"showTask":return[`${e.task.id}: ${e.task.title}`,`Status: ${e.task.status}`,`Runner: ${e.task.runner}`,`Repo: ${e.task.repoId}`,`Workspace: ${e.task.workspaceId}`,`Branch: ${e.task.branch}`,`Worktree: ${e.task.worktreePath}`,`Session: ${e.task.sessionId??"<missing>"}`,`tmux: ${e.session?.paneId??"<missing>"}`,`Linked repos: ${e.task.linkedRepoIds.length>0?e.task.linkedRepoIds.join(", "):"none"}`,`Prompt: ${e.task.prompt.source} ${JSON.stringify(e.task.prompt.value)}`,`Runner command: ${e.inspection.runnerCommandText||"<none>"}`,`Runner state: ${e.task.runnerSession.lastKnownState}`,`Started: ${e.task.runnerSession.startedAt??"not started"}`,`Exited: ${e.task.runnerSession.exitedAt??"still running"}`,`Checks: ${e.inspection.checksSummary}`,`Last commit: ${e.inspection.lastCommitSummary}`,`PR: ${e.inspection.prSummary}`,`Cleanup: ${e.inspection.cleanupSummary}`,...Od(e)].join(`
124
124
  `);case"streamTaskLogs":return`Streaming logs for ${e.taskId} from ${e.logPath}`;case"showTaskDiff":return e.isEmpty?`Task ${e.taskId} has no uncommitted diff.`:e.diffText;case"focusTask":return`Focused task ${e.taskId} on ${e.tmuxTarget}`;case"openTask":return e.launched?`Opened task ${e.taskId} at ${e.worktreePath}`:e.worktreePath;case"runChecks":return`Checks ${e.status} for ${e.taskId}: ${e.commands.join(", ")}`;case"commitTask":return[`Committed task ${e.taskId}`,`Status: ${e.status}`,`Commit: ${e.commitSha}`,`Message: ${e.message}`].join(`
125
- `);default:return ad(e)}}function id(e){let t=[];return e.inspection.worktreeExists||e.task.status==="merged"&&!e.task.cleanup.preservedWorktree&&e.task.cleanup.worktreeRemovedAt||t.push(`Warning: worktree is missing at ${e.task.worktreePath}`),e.task.cleanup.warning&&!(e.task.status==="merged"&&!e.task.cleanup.worktreeRemovedAt)&&t.push(`Cleanup warning: ${e.task.cleanup.warning}`),e.task.artifacts.logPath&&!e.inspection.logExists&&t.push(`Warning: log file is missing at ${e.task.artifacts.logPath}`),e.inspection.recentFailureReason&&t.push(`Last failure: ${e.inspection.recentFailureReason}`),t}function ad(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function cd(e){return e.checks.status}function ld(e){if(e.type==="project"&&e.repoTargets?.length){let n=e.repoTargets.filter(s=>s.pullRequest.number);if(n.length===0)return"-";let r=n.reduce((s,o)=>{let i=o.pullRequest.status??"unknown";return s[i]=(s[i]??0)+1,s},{});return Object.entries(r).map(([s,o])=>`${o} ${s}`).join(", ")}let t=e.prs[0];return t?.number?`#${t.number}:${t.status??"unknown"}`:"-"}import{createRequire as ff}from"node:module";import{readdir as mf,stat as gf}from"node:fs/promises";import Qe from"node:path";import{appendFile as dd,mkdir as ud,readFile as pd}from"node:fs/promises";import fd from"node:path";var md=80;async function gd(e,t){await ud(fd.dirname(e.errorLogFile),{recursive:!0}),await dd(e.errorLogFile,hd(t),"utf8")}async function tr(e,t){try{await gd(e,t)}catch{}}async function xo(e,t=md){try{let r=(await pd(e.errorLogFile,"utf8")).trimEnd().split(`
126
- `).filter(s=>s.length>0);return{path:e.errorLogFile,lines:r.slice(Math.max(0,r.length-t)),empty:r.length===0}}catch(n){if(wd(n))return{path:e.errorLogFile,lines:[],empty:!0};throw n}}function hd(e){let n=[`[${new Date().toISOString()}] ${e.context}`,`message: ${e.message}`];return e.details&&e.details.trim().length>0&&(n.push("details:"),n.push(...e.details.trimEnd().split(`
127
- `).map(r=>` ${r}`))),`${n.join(`
125
+ `);default:return Nd(e)}}function Od(e){let t=[];return e.inspection.worktreeExists||e.task.status==="merged"&&!e.task.cleanup.preservedWorktree&&e.task.cleanup.worktreeRemovedAt||t.push(`Warning: worktree is missing at ${e.task.worktreePath}`),e.task.cleanup.warning&&!(e.task.status==="merged"&&!e.task.cleanup.worktreeRemovedAt)&&t.push(`Cleanup warning: ${e.task.cleanup.warning}`),e.task.artifacts.logPath&&!e.inspection.logExists&&t.push(`Warning: log file is missing at ${e.task.artifacts.logPath}`),e.inspection.recentFailureReason&&t.push(`Last failure: ${e.inspection.recentFailureReason}`),t}function Nd(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function Fd(e){return e.checks.status}function Wd(e){if(e.type==="project"&&e.repoTargets?.length){let r=e.repoTargets.filter(s=>s.pullRequest.number);if(r.length===0)return"-";let n=r.reduce((s,o)=>{let i=o.pullRequest.status??"unknown";return s[i]=(s[i]??0)+1,s},{});return Object.entries(n).map(([s,o])=>`${o} ${s}`).join(", ")}let t=e.prs[0];return t?.number?`#${t.number}:${t.status??"unknown"}`:"-"}import{createRequire as Wf}from"node:module";import{readdir as _f,stat as Bf}from"node:fs/promises";import ct from"node:path";import{appendFile as _d,mkdir as Bd,readFile as Ud}from"node:fs/promises";import qd from"node:path";var Xo=80,Ln=async(e,t)=>{await Bd(qd.dirname(e.errorLogFile),{recursive:!0}),await _d(e.errorLogFile,Kd(t),"utf8")},Zo=async(e,t)=>{try{await Ln(e,t)}catch{}},jn=async(e,t=Xo)=>{try{let n=(await Ud(e.errorLogFile,"utf8")).trimEnd().split(`
126
+ `).filter(s=>s.length>0);return{path:e.errorLogFile,lines:n.slice(Math.max(0,n.length-t)),empty:n.length===0}}catch(r){if(Vd(r))return{path:e.errorLogFile,lines:[],empty:!0};throw r}},ei=async(e,t=Xo)=>jn(e,t);function Kd(e){let r=[`[${new Date().toISOString()}] ${e.context}`,`message: ${e.message}`];return e.details&&e.details.trim().length>0&&(r.push("details:"),r.push(...e.details.trimEnd().split(`
127
+ `).map(n=>` ${n}`))),`${r.join(`
128
128
  `)}
129
129
 
130
- `}function wd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}import{readFile as kd,stat as Rd}from"node:fs/promises";import nr from"node:path";var Td=200*1024,yd=500*1024,jt="100000";async function Eo(e,t,n){if(e.type==="project"&&e.repoTargets?.length)return Pd(e,t,n);try{let r=ve(n.selectedFilePath??null,t.filePaths),s=ve(n.selectedDiffPath??null,t.diffPaths),o=s?await at(e.worktreePath):null,[i,c]=await Promise.all([Ft(e.worktreePath,r),s?rr(e.worktreePath,s,t.diffRows,o):Promise.resolve(J("No diff selected","No local changes found.","empty"))]),l=s?{[s]:c}:{};return{...t,selectedFilePath:r,selectedDiffPath:s,diffContents:l,selectedFile:i,selectedDiff:c,error:null}}catch(r){let s=r instanceof Error?r.message:"Unable to inspect task worktree.";return{...t,error:s}}}async function Pd(e,t,n){let r=ve(n.selectedFilePath??null,t.filePaths),s=ve(n.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([$o(e,r),(async()=>{if(!s)return J("No diff selected","No local changes found.","empty");let l=Ot(e,s),d=l?await at(l.target.worktreePath).catch(()=>null):null;return Do(e,s,t.diffRows,d)})()]),c=s?{[s]:i}:{};return{...t,selectedFilePath:r,selectedDiffPath:s,diffContents:c,selectedFile:o,selectedDiff:i}}async function Ao(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return bd(e,t);try{await ce(e);let n=await at(e.worktreePath),[r,s]=await Promise.all([Mo(e.worktreePath),Lo(e.worktreePath,n)]),o=[...new Set(s.map(h=>h.path))],i=ve(t.selectedFilePath??null,r),c=ve(t.selectedDiffPath??null,o),[l,d]=await Promise.all([Ft(e.worktreePath,i),c?rr(e.worktreePath,c,s,n):Promise.resolve(J("No diff selected","No local changes found.","empty"))]),p=c?{[c]:d}:{};return{taskId:e.id,fileRows:Fo(r),filePaths:r,diffRows:s,diffPaths:o,diffContents:p,selectedFilePath:i,selectedDiffPath:c,selectedFile:l,selectedDiff:d,error:null}}catch(n){let r=n instanceof Error?n.message:"Unable to inspect task worktree.";return{taskId:e.id,fileRows:[],filePaths:[],diffRows:[],diffPaths:[],diffContents:{},selectedFilePath:null,selectedDiffPath:null,selectedFile:J("Files unavailable",r,"error"),selectedDiff:J("Diff unavailable",r,"error"),error:r}}}async function bd(e,t){let n=(e.repoTargets??[]).filter(R=>R.status==="ready"),r=await Promise.all(n.map(async R=>{let k=await at(R.worktreePath).catch(()=>null),[I,T]=await Promise.all([Mo(R.worktreePath).catch(()=>[]),Lo(R.worktreePath,k).catch(()=>[])]);return{target:R,baseRef:k,targetFiles:I,targetDiffRows:T}})),s=[],o=[];for(let{target:R,targetFiles:k,targetDiffRows:I}of r)s.push(...k.map(T=>`${R.repoId}/${T}`)),o.push(...I.map(T=>({...T,path:`${R.repoId}/${T.path}`})));let i=[...new Set(o.map(R=>R.path))].sort(),c=ve(t.selectedFilePath??null,s),l=ve(t.selectedDiffPath??null,i),[d,p]=await Promise.all([$o(e,c),(async()=>{if(!l)return J("No diff selected","No local changes found.","empty");let R=Ot(e,l),k=R?r.find(I=>I.target.repoId===R.target.repoId):null;return Do(e,l,o,k?.baseRef??null)})()]),h=l?{[l]:p}:{};return{taskId:e.id,fileRows:Fo(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:h,selectedFilePath:c,selectedDiffPath:l,selectedFile:d,selectedDiff:p,error:null}}async function $o(e,t){let n=Ot(e,t);if(!n)return J("No file selected","No Git-visible files found.","empty");let r=await Ft(n.target.worktreePath,n.relativePath);return{...r,path:t,title:t??r.title}}async function Do(e,t,n,r=null){let s=Ot(e,t);return s?{...await rr(s.target.worktreePath,s.relativePath,n.filter(i=>i.path.startsWith(`${s.target.repoId}/`)).map(i=>({...i,path:i.path.slice(s.target.repoId.length+1)})),r),path:t,title:t}:J(t,"Repo target is unavailable.","error",t)}function Ot(e,t){if(!t)return null;let[n,...r]=t.split("/"),s=r.join("/"),o=(e.repoTargets??[]).find(i=>i.repoId===n&&i.status==="ready")??null;return!o||s.length===0?null:{target:o,relativePath:s}}async function Mo(e){let t=await v("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return No(t.stdout)}async function Lo(e,t){let[n,r,s,o]=await Promise.all([Sd(e,t),vo(e,"staged"),vo(e,"unstaged"),Id(e)]);return[...n,...r,...s,...o]}async function Sd(e,t){if(!t)return[];let[n,r]=await Promise.all([v("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),v("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=jo(n.stdout),o=Oo(r.stdout);return s.map(i=>{let c=o.get(i.path)??{additions:null,deletions:null};return{group:"branch",path:i.path,status:i.status,additions:c.additions,deletions:c.deletions}}).sort((i,c)=>i.path.localeCompare(c.path))}async function vo(e,t){let n=t==="staged"?["diff","--cached"]:["diff"],[r,s]=await Promise.all([v("git",[...n,"--name-status"],{cwd:e}),v("git",[...n,"--numstat"],{cwd:e})]),o=jo(r.stdout),i=Oo(s.stdout);return o.map(c=>{let l=i.get(c.path)??{additions:null,deletions:null};return{group:t,path:c.path,status:c.status,additions:l.additions,deletions:l.deletions}}).sort((c,l)=>c.path.localeCompare(l.path))}async function Id(e){let t=await v("git",["ls-files","--others","--exclude-standard"],{cwd:e}),n=No(t.stdout);return await Promise.all(n.map(async s=>{let o=await Ft(e,s),i=o.status==="ready"?Cd(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function jo(e){return e.split(`
131
- `).map(t=>t.trim()).filter(t=>t.length>0).map(t=>{let[n="M",...r]=t.split(" ");return{status:n,path:r.at(-1)??""}}).filter(t=>t.path.length>0)}function Oo(e){let t=new Map;for(let n of e.split(`
132
- `)){let r=n.trim();if(!r)continue;let[s="-",o="-",...i]=r.split(" "),c=i.join(" ");c&&t.set(c,{additions:s==="-"?null:Number(s),deletions:o==="-"?null:Number(o)})}return t}async function at(e){return(await M("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await M("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function Ft(e,t){if(!t)return J("No file selected","No Git-visible files found.","empty");let n=xd(e,t);try{let r=await Rd(n);if(r.size>Td)return J(t,`File is ${r.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,r.size);let s=await kd(n);return vd(s)?J(t,"Binary file preview is not available in Craig.","binary",t,s.byteLength):{path:t,status:"ready",title:t,lines:s.toString("utf8").split(`
133
- `),byteLength:s.byteLength}}catch(r){let s=r instanceof Error?r.message:"Unable to read file.";return J(t,s,"missing",t,null)}}async function rr(e,t,n,r=null){if(!t)return J("No diff selected","No local changes found.","empty");let s=[],o=n.filter(c=>c.path===t).map(c=>c.group);if(o.includes("branch")){let c=r??await at(e);if(c){let l=await v("git",["diff","--stat","--patch",`--unified=${jt}`,`${c}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
134
- ${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let c=await v("git",["diff","--cached","--stat","--patch",`--unified=${jt}`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`staged
135
- ${c.stdout.trimEnd()}`)}if(o.includes("unstaged")){let c=await v("git",["diff","--stat","--patch",`--unified=${jt}`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`unstaged
136
- ${c.stdout.trimEnd()}`)}if(o.includes("untracked")){let c=await M("git",["diff","--no-index","--stat","--patch",`--unified=${jt}`,"--","/dev/null",t],{cwd:e});c.stdout.trim().length>0&&s.push(`untracked
137
- ${c.stdout.trimEnd()}`)}let i=s.join(`
138
-
139
- `);return i.length>yd?J(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?J(t,"Binary diff preview is not available in Craig.","binary",t,i.length):{path:t,status:i.length>0?"ready":"empty",title:t,lines:i.length>0?i.split(`
140
- `):["No diff for this file."],byteLength:i.length}}function Fo(e){let t=[],n=new Set;for(let r of e){let s=r.split("/");for(let o=0;o<s.length-1;o+=1){let i=s.slice(0,o+1).join("/");n.has(i)||(n.add(i),t.push({kind:"directory",path:i,depth:o,label:s[o]??i}))}t.push({kind:"file",path:r,depth:s.length-1,label:s.at(-1)??r})}return t}function ve(e,t){return e&&t.includes(e)?e:t[0]??null}function Cd(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function No(e){return[...new Set(e.split(`
141
- `).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,n)=>t.localeCompare(n))}function xd(e,t){let n=nr.resolve(e,t),r=nr.resolve(e);if(n!==r&&!n.startsWith(`${r}${nr.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return n}function vd(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function J(e,t,n,r=null,s=null){return{path:r,status:n,title:e,lines:[t],byteLength:s}}import{access as Ed}from"node:fs/promises";async function Wo(e,t){let n=await L(e,t),r=await Ad(n.worktreePath),s={...n,status:"closed",cleanup:{...n.cleanup,preservedWorktree:r&&n.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await A(e,s),s}async function Ad(e){try{return await Ed(e),!0}catch{return!1}}import dt from"node:path";function _o(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"\u{F06E6} ";case"js":case"jsx":case"mjs":case"cjs":return"\u{F031E} ";case"json":case"jsonc":return"\u{F0871} ";case"md":case"mdx":return"\u{F0354} ";case"yaml":case"yml":return"\u{F0B10} ";case"sh":case"bash":case"zsh":return"\u{F018D} ";case"css":case"scss":case"sass":return"\u{F031C} ";case"html":case"htm":return"\u{F031D} ";case"py":return"\u{F0320} ";case"go":return"\u{F07D3} ";case"rs":return"\u{F1617} ";case"lock":return"\u{F033E} ";case"png":case"jpg":case"jpeg":case"gif":case"svg":case"webp":return"\u{F02E9} ";default:return"\u{F0214} "}}var Bo="\u{F024B} ",Uo="\u{F0DCF} ",qo="\u25CB",sr="\uEA64",Ko="\uEAFE",Vo="\uEBDA",or="\u25CB",ir="\u25CF",ar="\u2713",cr="\u2715";function Go(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"4fc1ff";case"js":case"jsx":case"mjs":case"cjs":return"f7df1e";case"json":case"jsonc":return"fbc02d";case"md":case"mdx":return"519aba";case"yaml":case"yml":return"e06c75";case"sh":case"bash":case"zsh":return"89e051";case"css":case"scss":case"sass":return"c792ea";case"html":case"htm":return"e06c75";case"py":return"3572a5";case"go":return"00add8";case"rs":return"dea584";case"lock":return"565f89";default:return}}var $d=["tasks","center","inspector","actions"],Xo=["agent","terminal"],Zo=[],$="inspection",cR=[...Xo,...Zo],ei=["commit","push","refresh-checks","close-task"],Dd=["refresh-checks","close-task"],ti=["task","checks","pr","setup-run","actions","next-action"],ni=["diff","files","review"];function ri(e,t={}){let n=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,r=zd(e?.openInspectionKind)??n,s=b.runners.getEnabled(t);return{inputMode:Jd(e?.inputMode),focusedRegion:Gd(e?.focusedRegion),selectedRepoId:Te(e?.selectedRepoId),selectedWorkspaceId:Te(e?.selectedWorkspaceId),selectedTaskId:Te(e?.selectedTaskId),selectedPtyTabId:Te(e?.selectedPtyTabId),selectedLeftItemId:ou(Te(e?.selectedTaskId)),activeTab:n?$:Te(e?.activeTab)??"agent",preferredPtyTabKind:Yd(e?.preferredPtyTabKind),inspectorSection:ct(e?.inspectorSection,ti,"task"),inspectionMode:Hd(e?.inspectionMode,n==="diff"?"diff":"files"),openInspectionKind:r,selectedFileTreePath:Te(e?.selectedFileTreePath),selectedFilePath:Te(e?.selectedFilePath),selectedDiffPath:Te(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:ct(e?.selectedActionId,ei,"commit"),selectedProjectTargetId:null,selectedRunner:Qd(e?.selectedRunner,s,b.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,workspaceBrowser:null,terminal:Md(),centerZoomed:!1}}function Md(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function si(e,t){return{...e??ge(),selectedRepoId:t.selectedRepoId,selectedWorkspaceId:t.selectedWorkspaceId,selectedTaskId:t.selectedTaskId,selectedPtyTabId:t.selectedPtyTabId,inputMode:t.inputMode,focusedRegion:t.focusedRegion,activeTab:t.activeTab,preferredPtyTabKind:t.preferredPtyTabKind,inspectorSection:t.inspectorSection,inspectionMode:t.inspectionMode,openInspectionKind:t.openInspectionKind,selectedFileTreePath:t.selectedFileTreePath,selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath,collapsedFileTreePaths:t.collapsedFileTreePaths,selectedActionId:t.selectedActionId,selectedRunner:t.selectedRunner}}function Bt(e,t,n={}){let r=ru(e,t),s=pi(r),o=(s?.kind==="workspace"?t.workspaces?.find(p=>p.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(p=>p.id===t.tasks.find(h=>h.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(p=>p.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,c=((s?.kind==="repo"?t.repos.find(p=>p.id===s.id)??null:s?.kind==="task"?t.repos.find(p=>p.id===t.tasks.find(h=>h.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(p=>p.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(p.id))??null:null)??(o?.kind!=="project"?t.repos.find(p=>p.id===o?.primaryRepoId)??null:null)??t.repos.find(p=>p.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,l=o?t.tasks.filter(p=>p.workspaceId===o.id):c?t.tasks.filter(p=>p.repoId===c):[],d=(s?.kind==="task"?l.find(p=>p.id===s.id)??null:null)??l.find(p=>p.id===e.selectedTaskId)??l[0]??null;return{...e,inputMode:n.resetInputMode?"control":e.inputMode,selectedLeftItemId:r,selectedWorkspaceId:o?.id??null,selectedRepoId:c,selectedTaskId:d?.id??null,...Zd(d,e.activeTab,e.selectedPtyTabId),selectedFilePath:qd(e,t,d?.id??null),...eu(e,t,d?.id??null),selectedDiffPath:Ud(e,t,d?.id??null),inspectorSection:ct(e.inspectorSection,ti,"task")}}function oi(e,t,n={leftItemIds:[]}){if(e.inputMode==="terminal")return Ld(t)?S({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):S({state:e});if(t==="q"||t==="Q")return S({state:e,exit:!0});if(t==="ESCAPE")return S({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return S({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(dr(e.selectedLeftItemId)||ur(e.selectedLeftItemId)))return S({state:{...e,selectedRunner:pr(e.selectedRunner,n.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return Ho(e,1);if(t==="SHIFT_TAB"||t==="[")return Ho(e,-1);if(t==="z"||t==="Z")return S({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===$?Ee(e,-1,n):zo(e,-1,n);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===$?Ee(e,1,n):zo(e,1,n);if(t==="PAGE_UP")return Ee(e,-(n.pageRows??10),n);if(t==="PAGE_DOWN")return Ee(e,n.pageRows??10,n);if(t==="MOUSE_WHEEL_UP")return Ee(e,-3,n);if(t==="MOUSE_WHEEL_DOWN")return Ee(e,3,n);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let r=n.enabledRunnerIds??j,s=e.centerTabRunner?r.indexOf(e.centerTabRunner):-1,o=s===r.length-1?null:r[s+1];return S({state:{...e,centerTabRunner:o,actionMessage:null},changed:!0})}if((t==="+"||t==="a"||t==="A"||t==="t"||t==="T")&&e.focusedRegion==="center"&&e.selectedTaskId){let r=Xd(e,t);return S({state:{...e,preferredPtyTabKind:r,actionMessage:null},changed:!0,createPtyTab:!0,createPtyTabKind:r,createPtyTabRunner:r==="agent"?e.centerTabRunner:null})}if(t==="R"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return S({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return S({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return S({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&_t(e.selectedLeftItemId)&&e.selectedTaskId)return S({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&iu(e.selectedLeftItemId)&&e.selectedWorkspaceId)return S({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Qo(e.activeTab,n.ptyTabIds??[]))return S({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return lr(e,-1,n.centerTabIds);if(e.focusedRegion==="inspector")return Yo(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return lr(e,1,n.centerTabIds);if(e.focusedRegion==="inspector")return Yo(e,1)}if(Pe(t)){if(e.focusedRegion==="tasks"&&(dr(e.selectedLeftItemId)||ur(e.selectedLeftItemId))){let r=fi(e.selectedLeftItemId),s=mi(e.selectedLeftItemId);return S({state:{...e,selectedRepoId:r??e.selectedRepoId,selectedWorkspaceId:s??e.selectedWorkspaceId,actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0})}if(e.focusedRegion==="tasks"&&e.selectedLeftItemId==="new-workspace")return S({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&_t(e.selectedLeftItemId)&&e.selectedTaskId){let r=e.selectedPtyTabId??e.activeTab;return S({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:r,selectedPtyTabId:r,preferredPtyTabKind:lt(r)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Qo(e.activeTab,n.ptyTabIds??[])&&e.selectedTaskId)return S({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:lt(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===$)return S({state:{...e,actionMessage:null},changed:!0,refreshInspection:!0});if(e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="files"){let r=e.selectedFileTreePath??e.selectedFilePath;if(r&&(n.fileTreeDirectoryIds??[]).includes(r))return S({state:Wd({...e,selectedFileTreePath:r}),changed:!0});let s=r&&(n.fileTreeFileIds??[]).includes(r)?r:e.selectedFilePath;return S({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:$,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}return e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="diff"?S({state:{...e,activeTab:$,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.focusedRegion==="inspector"&&e.inspectionMode==="review"?e.selectedActionId==="close-task"&&!n.projectTargetIds?.length?S({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):S({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.focusedRegion!=="actions"?S({state:e}):e.selectedActionId==="refresh-checks"?S({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?S({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):S({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return S({state:e})}function _e(e,t){return{...e,terminal:t}}function ii(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function Ld(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function Pe(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
142
- `}function ai(e){return e.length===1&&e>=" "&&e!=="\x7F"}function ci(e){return li(e)||lt(e)!==null}function jd(e){return Zo.includes(e)}function li(e){return Xo.includes(e)}function di(e,t){return[...e?.ptyTabs.map(n=>n.id)??[],...t?.openInspectionKind?[$]:[]]}var Od=["tasks","center","inspector"];function Ho(e,t){return Nt(e,"focusedRegion",Od,t)}function lr(e,t,n){let r=Nt(e,"activeTab",n&&n.length>0?n:nu(e),t);return!r.changed||jd(r.state.activeTab)?r:{...r,state:{...r.state,selectedPtyTabId:r.state.activeTab,preferredPtyTabKind:lt(r.state.activeTab)??r.state.preferredPtyTabKind}}}function zo(e,t,n){if(e.focusedRegion==="tasks")return Fd(e,t,n.leftItemIds);if(e.focusedRegion==="center")return lr(e,t,n.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return ui(e,t,n);if(e.inspectionMode==="diff"){let r=Wt(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,activeTab:$,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:r}if(n.projectTargetIds?.length){let r=Wt(e,"selectedProjectTargetId",n.projectTargetIds,t);return r.changed?{...r,state:{...r.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:r}return Nt(e,"selectedActionId",Dd,t)}return Nt(e,"selectedActionId",ei,t)}function Fd(e,t,n){let r=Wt(e,"selectedLeftItemId",n,t);if(!r.changed)return r;let s=pi(r.state.selectedLeftItemId);if(s?.kind==="workspace")return{...r,state:{...r.state,selectedWorkspaceId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="task")return{...r,state:{...r.state,selectedTaskId:s.id,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="repo")return{...r,state:{...r.state,selectedRepoId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};let o=fi(r.state.selectedLeftItemId);if(o)return{...r,state:{...r.state,selectedRepoId:o}};let i=mi(r.state.selectedLeftItemId);return i?{...r,state:{...r.state,selectedWorkspaceId:i}}:r}function Ee(e,t,n){if(t===0)return S({state:e});if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return ui(e,t,n);if(e.inspectionMode==="diff"){let r=Wt(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,diffScrollOffset:0}}:r}return e.inspectionMode==="review"?Jo(e,"reviewScrollOffset",t,n.reviewRowCount??100,n.pageRows):S({state:e})}if(e.focusedRegion==="center"&&e.activeTab===$){if(e.openInspectionKind==="file")return Jo(e,"fileScrollOffset",t,n.fileLineCount??0,n.pageRows);if(e.openInspectionKind==="diff")return _d(e,t,n)}return S({state:e})}function Nd(e,t){if(e.inspectionMode===t)return S({state:e});let n=t==="diff"?"diff":t==="files"?"file":e.openInspectionKind,r=t==="diff"||t==="files"?$:e.activeTab;return S({state:{...e,inspectionMode:t,activeTab:r,openInspectionKind:n,fileScrollOffset:t==="files"?0:e.fileScrollOffset,diffScrollOffset:t==="diff"?0:e.diffScrollOffset,reviewScrollOffset:t==="review"?0:e.reviewScrollOffset,actionMessage:null},changed:!0,refreshInspection:!0})}function Yo(e,t){return Nd(e,Vd(e.inspectionMode,ni,t))}function ui(e,t,n){let r=n.fileTreeRowIds&&n.fileTreeRowIds.length>0?n.fileTreeRowIds:n.filePathIds??[];if(r.length===0)return S({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??r[0]??null,o=r.indexOf(s??""),i=ye(o===-1?0:o+t,0,r.length-1),c=r[i]??null;if(c===e.selectedFileTreePath)return S({state:e});let l=c!==null&&(n.fileTreeFileIds??n.filePathIds??[]).includes(c);return S({state:{...e,selectedFileTreePath:c,selectedFilePath:l?c:e.selectedFilePath,activeTab:l?$:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function Wd(e){if(!e.selectedFileTreePath)return e;let t=new Set(e.collapsedFileTreePaths);return t.has(e.selectedFileTreePath)?t.delete(e.selectedFileTreePath):t.add(e.selectedFileTreePath),{...e,collapsedFileTreePaths:[...t].sort((n,r)=>n.localeCompare(r)),actionMessage:null}}function Jo(e,t,n,r,s=10){let o=Math.max(0,r-Math.max(1,s)),i=ye(e[t]+n,0,o);return i===e[t]?S({state:e}):S({state:{...e,[t]:i,actionMessage:null},changed:!0})}function _d(e,t,n){if(n.diffPathRanges&&n.diffPathRanges.length>0)return Bd(e,t,n);let r=n.diffLineCount??0,s=n.pageRows??10,o=Math.max(0,r-Math.max(1,s)),i=e.diffScrollOffset+t,c=n.diffPathIds??[];if(c.length===0||!e.selectedDiffPath){let p=ye(i,0,o);return p===e.diffScrollOffset?S({state:e}):S({state:{...e,diffScrollOffset:p,actionMessage:null},changed:!0})}let l=c.indexOf(e.selectedDiffPath);if(l===-1){let p=ye(i,0,o);return p===e.diffScrollOffset?S({state:e}):S({state:{...e,diffScrollOffset:p,actionMessage:null},changed:!0})}if(t>0&&i>o){let p=c[l+1]??null;return p?S({state:{...e,selectedDiffPath:p,activeTab:$,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?S({state:e}):S({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let p=c[l-1]??null;return p?S({state:{...e,selectedDiffPath:p,activeTab:$,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?S({state:e}):S({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let d=ye(i,0,o);return d===e.diffScrollOffset?S({state:e}):S({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}function Bd(e,t,n){let r=n.diffLineCount??0,s=n.pageRows??10,o=Math.max(0,r-Math.max(1,s)),i=ye(e.diffScrollOffset+t,0,o),c=Kd(n.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&c===e.selectedDiffPath?S({state:e}):S({state:{...e,diffScrollOffset:i,selectedDiffPath:c,actionMessage:null},changed:!0})}function Ud(e,t,n){return!t.inspection||t.inspection.taskId!==n||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function qd(e,t,n){return!t.inspection||t.inspection.taskId!==n||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function Kd(e,t){return e.find(n=>t>=n.start&&t<n.end)?.path??e.at(-1)?.path??null}function Nt(e,t,n,r){let s=n.indexOf(e[t]),o=ye(s+r,0,n.length-1),i=n[o];return!i||i===e[t]?S({state:e}):S({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Wt(e,t,n,r,s=!1){if(n.length===0)return S({state:e});let o=n.indexOf(e[t]??n[0]??""),i=ye(o===-1?0:o+r,0,n.length-1),c=n[i]??null;return c===e[t]?S({state:e}):S({state:{...e,[t]:c,actionMessage:null},changed:!0,refreshInspection:s})}function Vd(e,t,n){let r=t.indexOf(e);return t[ye(r+n,0,t.length-1)]??e}function S(e){return{state:e.state,changed:e.changed??!1,exit:e.exit??!1,pause:e.pause??!1,attachTerminal:e.attachTerminal??!1,detachTerminal:e.detachTerminal??!1,beginTaskPrompt:e.beginTaskPrompt??!1,openWorkspaceBrowser:e.openWorkspaceBrowser??!1,createWorkspaceTask:e.createWorkspaceTask??!1,createPtyTab:e.createPtyTab??!1,createPtyTabKind:e.createPtyTabKind??null,createPtyTabRunner:e.createPtyTabRunner??null,closePtyTab:e.closePtyTab??!1,refreshPullRequestChecks:e.refreshPullRequestChecks??!1,closeTask:e.closeTask??!1,removeWorkspace:e.removeWorkspace??!1,refreshInspection:e.refreshInspection??!1,openPrUrl:e.openPrUrl??!1}}function ct(e,t,n){return t.includes(e??"")?e:n}function Gd(e){return e==="tabs"?"center":ct(e,$d,"tasks")}function Hd(e,t){return e==="checks"||e==="actions"||e==="review"?"review":ct(e,ni,t)}function zd(e){return e==="file"||e==="diff"?e:null}function Yd(e){return e==="terminal"?"terminal":"agent"}function Jd(e){return e==="terminal"?"terminal":"control"}function Qd(e,t=[...j],n="codex"){return e&&b.runners.isRunnerType(e)&&t.includes(e)?e:n}function pr(e,t=j){let n=t.length>0?t:j,r=n.indexOf(e);return n[(r+1)%n.length]??n[0]??"codex"}function lt(e){let t=j.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function Xd(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":lt(e.activeTab)??e.preferredPtyTabKind}function Zd(e,t,n){if(!e)return{activeTab:t===$?t:"agent",selectedPtyTabId:null};let r=e.ptyTabs.find(c=>c.id===n)??null,s=e.selectedPtyTabId?e.ptyTabs.find(c=>c.id===e.selectedPtyTabId)??null:null,o=e.ptyTabs.find(c=>c.id===t)??null;if(o)return{activeTab:o.id,selectedPtyTabId:o.id};if(li(t)){let l=e.ptyTabs.find(d=>d.kind===t)??null??s??r??e.ptyTabs[0]??null;return{activeTab:l?.id??$,selectedPtyTabId:l?.id??null}}if(t===$)return{activeTab:$,selectedPtyTabId:r?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??r??e.ptyTabs[0]??null;return{activeTab:i?.id??$,selectedPtyTabId:i?.id??null}}function eu(e,t,n){if(!t.inspection||t.inspection.taskId!==n)return{selectedFileTreePath:e.selectedFileTreePath,collapsedFileTreePaths:e.collapsedFileTreePaths};let r=e.selectedFileTreePath??t.inspection.selectedFilePath,s=e.selectedFileTreePath===null&&e.collapsedFileTreePaths.length===0?tu(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:r,collapsedFileTreePaths:s}}function tu(e,t){let n=new Set;if(t){let r=t.split("/");for(let s=1;s<r.length;s+=1)n.add(r.slice(0,s).join("/"))}return e.filter(r=>r.kind==="directory"&&!r.path.includes("/")&&!n.has(r.path)).map(r=>r.path).sort((r,s)=>r.localeCompare(s))}function nu(e){return[e.selectedPtyTabId,e.openInspectionKind?$:null].filter(t=>typeof t=="string")}function Qo(e,t){return t.includes(e)}function ru(e,t){let n=su(t);return e.selectedLeftItemId&&n.includes(e.selectedLeftItemId)?e.selectedLeftItemId:e.selectedWorkspaceId&&n.includes(`workspace:${e.selectedWorkspaceId}`)?`workspace:${e.selectedWorkspaceId}`:e.selectedTaskId&&n.includes(`task:${e.selectedTaskId}`)?`task:${e.selectedTaskId}`:e.selectedRepoId&&n.includes(`repo:${e.selectedRepoId}`)?`repo:${e.selectedRepoId}`:n[0]??null}function su(e){let t=[];if(e.workspaces?.length)for(let n of e.workspaces){t.push(`workspace:${n.id}`);for(let r of e.tasks.filter(s=>s.workspaceId===n.id))t.push(`task:${r.id}`);n.kind==="project"&&t.push(`new-task-workspace:${n.id}`),n.kind==="repo"&&t.push(`new-task:${n.primaryRepoId}`)}else for(let n of e.repos){t.push(`repo:${n.id}`);for(let r of e.tasks.filter(s=>s.repoId===n.id))t.push(`task:${r.id}`);t.push(`new-task:${n.id}`)}return t.push("new-workspace"),t}function pi(e){return e?e.startsWith("workspace:")?{kind:"workspace",id:e.slice(10)}:e.startsWith("repo:")?{kind:"repo",id:e.slice(5)}:e.startsWith("task:")?{kind:"task",id:e.slice(5)}:null:null}function Te(e){return typeof e=="string"?e:null}function ou(e){return e?`task:${e}`:null}function _t(e){return typeof e=="string"&&e.startsWith("task:")}function dr(e){return typeof e=="string"&&e.startsWith("new-task:")}function ur(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function iu(e){return typeof e=="string"&&e.startsWith("workspace:")}function fi(e){return dr(e)?e.slice(9):null}function mi(e){return ur(e)?e.slice(19):null}function ye(e,t,n){return Math.min(n,Math.max(t,e))}var qt="empty",U={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function ki(e,t){let n=lu(t,e),r=t.repos.find(T=>T.id===e.selectedRepoId)??t.repos[0]??null,s=n?t.tasks.filter(T=>T.workspaceId===n.id):t.tasks,o=n?.kind==="project"?s:r?s.filter(T=>T.repoId===r.id):[],i=o.find(T=>T.id===e.selectedTaskId)??o[0]??null,c=i?.type==="project",l=Vu(t.tasks),d=pu(e,i),p=uu(e,i,d),h=p.find(T=>T.id===d)??p[0]??{id:"agent",label:"CODEX"},R=t.inspection?.taskId===i?.id?t.inspection:null,k=r?.name??"no repo",I=i?b.runners.getDisplayName(i.runner):b.runners.getDisplayName(e.selectedRunner);return{inputMode:e.inputMode,modalInput:e.taskPromptInput!==null||e.workspaceBrowser!==null,focusedRegion:e.focusedRegion,actionMessage:e.actionMessage,footerToast:e.footerToast,terminal:e.terminal,footerText:e.workspaceBrowser!==null?`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} \u2191\u2193 move \u2192 open \u2190 up Enter add repo Esc cancel`:e.taskPromptInput!==null?`NEW TASK ${r?`[${r.name}]`:"[no repo]"} \xB7 ${b.runners.getDisplayName(e.selectedRunner)} Ctrl+R switch runner Enter create Esc cancel \u203A ${e.taskPromptInput}${e.taskPromptError?` \u2717 ${e.taskPromptError}`:""}`:e.inputMode==="terminal"?"TERMINAL \u2191\u2193/PgUp/PgDn scroll Ctrl+] return to control":e.focusedRegion==="tasks"?e.selectedLeftItemId?.startsWith("new-task:")||e.selectedLeftItemId?.startsWith("new-task-workspace:")?`r runner [${b.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:_t(e.selectedLeftItemId)?"n new task Enter attach X close task Esc pause ? help":e.selectedLeftItemId?.startsWith("workspace:")?"n new task Enter select X remove workspace Esc pause ? help":"n new task Enter select Esc pause ? help":e.focusedRegion==="center"?i===null?"n new task Tab tasks Esc pause ? help":d===$?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${b.runners.getDisplayName(e.centerTabRunner??i?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?c?"\u2191\u2193 targets Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":"Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":e.inspectionMode==="files"?"\u2191\u2193 navigate Enter open file \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 navigate \u2190/\u2192 mode Esc pause ? help",topRail:{workspacePath:dt.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${dt.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:I},leftTree:au(e,t),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(T=>Gu(T,l[T])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":h.label,taskId:e.workspaceBrowser?"new workspace":i?.id??"no task",repo:k,agent:I},centerTranscript:du(d,e,r,i,e.workspaceBrowser,R,n),tabs:p,rightContext:Ku(r,i),rightInspection:Iu(e,i,R)}}function au(e,t){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return cu(n,e,t.repos,t.tasks);let r=t.workspaces;if(r.length===0)n.push({text:"No workspaces registered.",indent:2,muted:!0});else for(let o of r){let i=e.selectedLeftItemId===`workspace:${o.id}`;n.push({id:`workspace:${o.id}`,text:`${o.kind==="project"?"\u2261":"\u2013"} ${o.name??o.id}`,selected:i,focused:i&&e.focusedRegion==="tasks"});let c=o.kind==="project"?o.discoveredRepoIds??[]:[o.primaryRepoId],l=t.tasks.filter(d=>d.workspaceId===o.id);if(l.length===0)n.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of l){let p=e.selectedLeftItemId===`task:${d.id}`,h=p?"\u25B8":"\u2022",R=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,k={id:`task:${d.id}`,taskId:d.id,text:`${h} ${R}`,indent:2,selected:p,focused:p&&e.focusedRegion==="tasks"},I=Ti(d);I&&(k.prBadge=I),n.push(k)}if(o.kind==="project"){let d=`new-task-workspace:${o.id}`,p=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Project Task [${b.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:p,focused:p&&e.focusedRegion==="tasks",muted:!p})}if(o.kind==="repo"){let d=`new-task:${o.primaryRepoId}`,p=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Task [${b.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:p,focused:p&&e.focusedRegion==="tasks",muted:!p})}else{n.push({text:` Repos (${c.length})`,indent:0,muted:!0});for(let d of c.slice(0,6)){let p=t.repos.find(h=>h.id===d);n.push({text:` \xB7 ${p?.name??d}`,indent:0,muted:!0})}c.length>6&&n.push({text:` \xB7 ${c.length-6} more`,indent:0,muted:!0})}}let s=e.selectedLeftItemId==="new-workspace";return n.push({text:"",muted:!0}),n.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&e.focusedRegion==="tasks"}),n}function cu(e,t,n,r){if(n.length===0)e.push({text:"No repos registered.",indent:2,muted:!0});else for(let o of n){let i=t.selectedLeftItemId===`repo:${o.id}`;e.push({id:`repo:${o.id}`,text:`\u2013 ${o.name}`,selected:i,focused:i&&t.focusedRegion==="tasks"});let c=r.filter(p=>p.repoId===o.id);if(c.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let p of c){let h=t.selectedLeftItemId===`task:${p.id}`,R=h?"\u25B8":"\u2022",k=p.title.length>28?`${p.title.slice(0,25)}\u2026`:p.title,I={id:`task:${p.id}`,taskId:p.id,text:`${R} ${k}`,indent:2,selected:h,focused:h&&t.focusedRegion==="tasks"},T=Ti(p);T&&(I.prBadge=T),e.push(I)}let l=`new-task:${o.id}`,d=t.selectedLeftItemId===l;e.push({id:l,text:`+ New Task [${b.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:d,focused:d&&t.focusedRegion==="tasks",muted:!d})}let s=t.selectedLeftItemId==="new-workspace";return e.push({text:"",muted:!0}),e.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&t.focusedRegion==="tasks"}),e}function lu(e,t){let n=e.workspaces??[];if(!e.workspaces)return null;let r=e.tasks.find(s=>s.id===t.selectedTaskId)??null;return r?n.find(s=>s.id===r.workspaceId)??null:t.selectedWorkspaceId?n.find(s=>s.id===t.selectedWorkspaceId)??null:n[0]??null}function du(e,t,n,r,s,o=null,i=null){if(s){let l=s.entries.length===0?["No directories or git repos here."]:s.entries.map((d,p)=>{let h=p===s.selectedIndex?"\u25B8":" ",R=d.kind==="repo"?" [git repo]":"/";return`${h} ${d.name}${R}`});return ue(["Browse for a workspace to register.",s.cwd,"",...l,"",s.error??"Use \u2191\u2193 to move, \u2192 or Enter to open, \u2190 to go up, Enter on a git repo to add it."])}if(!n)return ue(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!r){let l=i?.kind==="project",d=l?i.name??"this workspace":n.name,p=l?"Project Task":"Task";return ue([`No tasks in ${d}.`,"",`Press n or choose + New ${p} to create one with ${b.runners.getDisplayName(t.selectedRunner)}.`])}let c=r.ptyTabs.find(l=>l.id===e)??null;return c?c.kind==="agent"?ue([`${c.title} tab ready for ${r.id}.`,"","Press Enter to attach this PTY-backed agent session.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):ue([`${c.title} tab ready for ${r.id}.`,"","Press Enter to attach this plain task shell.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):e===$&&t.openInspectionKind==="file"?gu(r,o,t.fileScrollOffset):e===$&&t.openInspectionKind==="diff"?hu(r,o,t.diffScrollOffset):r.ptyTabs.length===0&&!t.openInspectionKind?ue(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):ue(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function uu(e,t,n){let r=t?.ptyTabs.map(o=>({id:o.id,label:fu(o)}))??[];if(!t)return[{id:qt,label:"EMPTY",active:n===qt,focused:e.focusedRegion==="center"&&n===qt}];let s=e.openInspectionKind||n===$?[{id:$,label:mu(e)}]:[];return[...r,...s].map(o=>({...o,active:o.id===n,focused:e.focusedRegion==="center"&&o.id===n}))}function pu(e,t){return t?t.ptyTabs.some(n=>n.id===e.activeTab)||e.activeTab===$&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(n=>n.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??$:e.selectedPtyTabId&&t.ptyTabs.some(n=>n.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??$:qt}function fu(e){return e.title.toUpperCase()}function mu(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,n=t?dt.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${n} \u0394`:n}function gu(e,t,n){if(!e)return ue(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return ue(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let r=t.selectedFile,s=Ri(r.path??r.title);return[{text:r.title},{text:`${r.byteLength===null?"size unknown":`${r.byteLength} bytes`} \xB7 ${r.lines.length} lines \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...wu(r.lines,n,s)]}function hu(e,t,n){if(!e)return ue(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return ue(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let r=t.selectedDiff,s=Ri(r.path??r.title);return[{text:r.title},{text:`${t.diffPaths.length} changed files \xB7 ${r.lines.length} rows \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...ku(r.lines,n,s)]}function ue(e){return e.map(t=>({text:t}))}function wu(e,t,n){let r=Math.max(3,String(e.length).length),s=Math.max(0,Math.min(t,Math.max(0,e.length-1)));return e.slice(s).map((o,i)=>{let c=s+i+1;return{text:`${`${String(c).padStart(r," ")} \u2502 `}${o}`,segments:[{text:String(c).padStart(r," "),style:{fg:U.lineNumber}},{text:" \u2502 ",style:{fg:U.gutter}},...fr(o,n)],tone:"default"}})}function ku(e,t,n){let r=Ru(e),s=Math.max(0,Math.min(t,Math.max(0,r.length-1)));return r.slice(s).map(o=>Tu(o,n))}function Ru(e){let t=[],n=0,r=0;for(let s of e){let o=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);if(o){n=Number.parseInt(o[1]??"0",10),r=Number.parseInt(o[2]??"0",10);continue}if(!(s.startsWith("diff --git")||s.startsWith("index ")||s.startsWith("+++ ")||s.startsWith("--- "))&&!(s==="staged"||s==="unstaged"||s==="untracked")){if(s.startsWith("-")&&!s.startsWith("---")){t.push({oldNumber:n,newNumber:null,marker:"-",text:s.slice(1),kind:"delete"}),n+=1;continue}if(s.startsWith("+")&&!s.startsWith("+++")){t.push({oldNumber:null,newNumber:r,marker:"+",text:s.slice(1),kind:"add"}),r+=1;continue}if(s.startsWith(" ")){if(n===0&&r===0)continue;t.push({oldNumber:n,newNumber:r,marker:" ",text:s.slice(1),kind:"context"}),n+=1,r+=1;continue}}}return t}function Tu(e,t){let n=gi(e.oldNumber),r=gi(e.newNumber),s=e.kind==="delete"?n:r,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:U.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:U.diffAdd}:null,i=`${s} \u2502 ${e.text}`,c=o?Pu(fr(e.text,t),o.bg,o.fallbackFg):fr(e.text,t),l=o?{fg:U.lineNumber,bg:o.bg}:{fg:U.lineNumber},d=o?{fg:U.gutter,bg:o.bg}:{fg:U.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:d},...c],fullBleed:o!==null}}function gi(e){return e===null?" ":String(e).padStart(4," ")}function Ri(e){let t=dt.extname(e).toLowerCase();return[".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(t)?"javascript":[".json",".jsonc"].includes(t)?"json":[".md",".mdx"].includes(t)?"markdown":[".css",".scss"].includes(t)?"css":"plain"}function fr(e,t){return t==="diff"?yu(e):t==="markdown"?bu(e):t==="json"?mr(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?mr(e,/("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)|\/\/.*$|\/\*.*?\*\/|\b(const|let|var|function|return|if|else|for|while|class|interface|type|import|export|from|async|await|new|extends|implements|switch|case|break|continue|try|catch|throw|true|false|null|undefined)\b|-?\b\d+(?:\.\d+)?\b/g):[{text:e}]}function yu(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:U.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:U.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:U.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:U.diffMeta}}]:[{text:e}]}function Pu(e,t,n){return e.map(r=>({text:r.text,style:{...r.style??{fg:n},bg:t}}))}function bu(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:U.markup,bold:!0}}]:mr(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function mr(e,t){let n=[],r=0;for(let s of e.matchAll(t)){let o=s[0],i=s.index??0;i>r&&n.push({text:e.slice(r,i)}),n.push({text:o,style:Su(o)}),r=i+o.length}return r<e.length&&n.push({text:e.slice(r)}),n.length>0?n:[{text:e}]}function Su(e){return e.startsWith("//")||e.startsWith("/*")?{fg:U.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:U.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:U.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:U.markup}:{fg:U.keyword}}function Iu(e,t,n){let r=e.selectedProjectTargetId??t?.repoTargets?.[0]?.repoId??null,s=t?.type==="project"&&r?t.repoTargets?.find(c=>c.repoId===r)??null:null,o=t?.type==="project"?yi(t.repoTargets??[]):s?.pullRequest??(t?V(t):null),i=[Cu(e,o),{id:"mode-spacer",text:"",muted:!0}];return e.inspectionMode==="review"?{title:"",rows:[...i,...Si(e,t)]}:e.inspectionMode==="files"?{title:"",rows:[...i,...Wu(e,n)]}:{title:"",rows:[...i,...Bu(e,n)]}}function Cu(e,t){let n=e.inspectionMode,r=[{label:"CHANGES",active:n==="diff"},{label:"FILES",active:n==="files"},{label:"REVIEW",active:n==="review"}],s=[];for(let l=0;l<r.length;l++){let d=r[l];l>0&&s.push({text:" "});let p=d.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:d.label,style:{fg:p}})}let o=gr(t),i=hr(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function hi(e){return[{text:" "},gr(e),{text:" "},hr(e)]}function Ti(e){if(e.type==="project"&&e.repoTargets?.length){let n=yi(e.repoTargets);return n?hi(n):null}let t=V(e);return t?.number?hi(t):null}function yi(e){let t=e.filter(s=>s.status==="ready"),n=t.map(s=>s.pullRequest).filter(s=>!!s.number);if(n.length===0)return null;let r=vu(n);return{number:-1,status:xu(n),draft:n.some(s=>s.draft),mergeable:n.length===t.length&&n.every(s=>s.mergeable),mergeStateStatus:null,reviewDecision:n.some(s=>s.reviewDecision==="CHANGES_REQUESTED")?"CHANGES_REQUESTED":n.some(s=>s.reviewDecision==="REVIEW_REQUIRED")?"REVIEW_REQUIRED":n.every(s=>s.reviewDecision==="APPROVED")?"APPROVED":null,requiredChecks:n.flatMap(s=>s.requiredChecks),aggregateReadiness:r}}function xu(e){return e.some(t=>t.status==="open")?"open":e.every(t=>t.status==="merged")?"merged":e.some(t=>t.status==="closed")?"closed":e[0]?.status??null}function vu(e){let t=e.map(n=>Pi(n));return t.some(n=>n==="failed")?"failed":t.some(n=>n==="pending")?"pending":t.length>0&&t.every(n=>n==="success")?"success":"none"}function gr(e){return!e||!e.number?{text:qo,style:{fg:"565f89"}}:e.status==="merged"?{text:Ko,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:Vo,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:sr,style:{fg:"565f89"}}:{text:sr,style:{fg:"9ece6a"}}}function hr(e){return e?.aggregateReadiness?wi(e.aggregateReadiness):wi(Pi(e))}function wi(e){return e==="failed"?{text:cr,style:{fg:"f7768e"}}:e==="pending"?{text:ir,style:{fg:"e0af68"}}:e==="success"?{text:ar,style:{fg:"9ece6a"}}:{text:or,style:{fg:"565f89"}}}function Pi(e){let t=e?.requiredChecks??null;return e?.status==="merged"?"success":e?.status==="closed"||!e?.number||!t||t.length===0?"none":t.some(n=>n.status==="failed")||e.reviewDecision==="CHANGES_REQUESTED"?"failed":t.every(n=>n.status==="success"||n.status==="skipped")?bi(e)?"failed":Eu(e)?"success":"pending":"pending"}function Eu(e){return!!(e.mergeable&&!e.draft&&!bi(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function bi(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Si(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return Au(e,t);let n=V(t),r=Ci("pr",t.branch,n??{number:null,url:null,baseBranch:null,headBranch:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,lastSyncedAt:null,requiredChecks:[],comments:[]}),s=t.prs.filter(o=>o!==n&&(o.status==="merged"||o.status==="closed")).length;return s>0&&r.push({id:"pr-history",text:`+ ${s} previous PR${s!==1?"s":""}`,muted:!0}),$u(r,e)}var Ut=32;function Au(e,t){let n=[],r=t.repoTargets??[],s=e.selectedProjectTargetId??r[0]?.repoId??null;for(let i of r){let c=s===i.repoId,l=e.focusedRegion==="inspector"&&c,d=i.repoId.startsWith("repo_")?i.repoId.slice(5):i.repoId;if(i.status!=="ready"){let h=i.failureReason?i.failureReason.slice(0,14):i.status,R=Ut-h.length-1,k=d.length>R?d.slice(0,R-1)+"\u2026":d,I=Ut-k.length-h.length;n.push({id:`project-review:${i.repoId}`,text:k+" ".repeat(Math.max(1,I))+h,selected:c,focused:l,muted:!0})}else{let p=gr(i.pullRequest),h=hr(i.pullRequest),R=`${p.text} ${h.text}`,k=Ut-R.length-1,I=d.length>k?d.slice(0,k-1)+"\u2026":d,T=Ut-I.length-R.length,a=I+" ".repeat(Math.max(1,T));n.push({id:`project-review:${i.repoId}`,text:a+R,selected:c,focused:l,segments:[{text:a},{...p,text:p.text},{text:" "},{...h,text:h.text}]})}}let o=r.find(i=>i.repoId===s)??null;return o?.status==="ready"&&o.pullRequest.number&&(n.push({id:"target-detail-spacer",text:""}),n.push(...Ci("target",o.branch,o.pullRequest))),n}function Ii(e,t){return Si(e,t).length}function Ci(e,t,n){let r=h=>`${e}-${h}`;if(!n.number)return[{id:r("no-pr"),text:t,muted:!0}];let s=[],o=`#${n.number}`;s.push(n.url?{id:r("pr-number"),text:`${o} Open in GitHub \u2197`,segments:[{text:o},{text:" Open in GitHub \u2197",style:{fg:"7aa2f7",underline:!0},href:n.url}]}:{id:r("pr-number"),text:o});let i=n.baseBranch??"?",c=n.headBranch??t;s.push({id:r("pr-branches"),text:`${i} \u2192 ${c}`,muted:!0});let l=Du(n.reviewDecision,n.mergeStateStatus),d=l&&l!=="review approved"?"merge blocked":n.mergeable?"merge ready":n.mergeStateStatus?`merge ${n.mergeStateStatus}`:"merge unknown";l?s.push({id:r("pr-merge"),text:`${d} \xB7 ${l}`,muted:!0,segments:[{text:d},{text:" \xB7 "},{text:l,style:{fg:Mu(n.reviewDecision,n.mergeStateStatus)}}]}):s.push({id:r("pr-merge"),text:d,muted:!0}),s.push({id:r("pr-synced"),text:`synced ${xi(n.lastSyncedAt)}`,muted:!0}),s.push({id:r("checks-spacer"),text:""}),s.push({id:r("checks-header"),text:"Checks"}),n.requiredChecks.length?s.push(...n.requiredChecks.map(Lu)):s.push({id:r("checks-none"),text:n.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let p=n.comments??[];return p.length>0&&(s.push({id:r("comments-spacer"),text:""}),s.push({id:r("comments-header"),text:`Review comments (${p.length})`}),s.push(...p.slice(-4).flatMap((h,R)=>ju(h,r(`comment:${R}`))))),s}function $u(e,t){if(t.focusedRegion!=="inspector"||t.inspectionMode!=="review"||e.length===0)return e;let n=Math.max(0,Math.min(t.reviewScrollOffset,e.length-1));return e.map((r,s)=>({...r,selected:t.reviewScrollOffset===0&&r.selected||s===n,focused:t.reviewScrollOffset===0&&r.focused||s===n}))}function Du(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function Mu(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function xi(e){if(!e)return"--";let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/1e3);if(n<60)return`${n}s ago`;let r=Math.floor(n/60);if(r<60)return`${r}m ago`;let s=Math.floor(r/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}function Lu(e){let{icon:t,color:n}=Fu(e.status),r=e.name.length>16?`${e.name.slice(0,15)}\u2026`:e.name;return{id:`pr-check:${e.name}`,text:`${t} ${r.padEnd(16," ")} ${Nu(e.status)}`,color:n,muted:!1}}function ju(e,t){let n=e.author??"unknown",r=e.createdAt?` \xB7 ${xi(e.createdAt)}`:"",s=Ou(e.body,30),o=s.slice(0,4),i=o.length<s.length,c=[{id:`${t}:author`,text:`${n}${r}`,muted:!0},...o.map((l,d)=>({id:`${t}:body:${d}`,text:` ${i&&d===o.length-1?`${l}\u2026`:l}`,muted:!0}))];return c.push({id:`${t}:spacer`,text:"",muted:!0}),c}function Ou(e,t){let n=e.split(/\s+/).filter(Boolean);if(n.length===0)return[];let r=[],s="";for(let o of n){if(!s){s=o;continue}`${s} ${o}`.length<=t?s=`${s} ${o}`:(r.push(s),s=o)}return s&&r.push(s),r}function Fu(e){switch(e){case"success":return{icon:ar,color:"9ece6a"};case"pending":return{icon:ir,color:"e0af68"};case"failed":return{icon:cr,color:"f7768e"};case"skipped":return{icon:or,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function Nu(e){return e==="success"?"passing":e==="failed"?"failing":e}function Wu(e,t){if(!t)return[{id:"empty",text:"No file index. Select a task with local changes.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.fileRows.length===0)return[{id:"empty",text:"No Git-visible files.",muted:!0}];let n=new Map(t.diffRows.map(o=>[o.path,o.status])),r=_u(t.fileRows,e.collapsedFileTreePaths),s=e.selectedFileTreePath??t.selectedFilePath;return r.map(o=>{let i=o.kind==="file"?n.get(o.path):void 0,c=i==="A"?"9ece6a":i==="M"?"e0af68":i==="D"?"f7768e":i==="??"?"565f89":void 0,l=o.kind==="directory"?e.collapsedFileTreePaths.includes(o.path)?Bo:Uo:_o(o.label),d=o.kind==="directory"?"7aa2f7":Go(o.label),p=" ".repeat(o.depth),h=d?{text:l,style:{fg:d}}:{text:l},R=o.kind==="directory"?{text:o.label,style:{fg:"7aa2f7"}}:c?{text:o.label,style:{fg:c}}:{text:o.label},k=[{text:p},h,R];return{id:o.path,text:`${p}${l}${o.label}`,selected:o.path===s,focused:o.path===s&&e.focusedRegion==="inspector",segments:k}})}function _u(e,t){let n=new Set(t);return e.filter(r=>{let s=r.path.split("/");for(let o=1;o<s.length;o+=1)if(n.has(s.slice(0,o).join("/")))return!1;return!0})}function Bu(e,t){if(!t)return[{id:"empty",text:"No task diff index.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.diffRows.length===0)return[{id:"empty",text:t.filePaths.some(s=>s.startsWith("repo_"))?"No changes in project task worktrees. Edits in the original repos are outside this task.":"No local changes.",muted:!0}];if(Uu(t))return qu(e,t);let n=[];for(let r of["branch","staged","unstaged","untracked"]){let s=t.diffRows.filter(o=>o.group===r);s.length!==0&&(n.push({id:r,text:r.toUpperCase(),muted:!0}),n.push(...s.map(o=>vi(o,e,t))))}return n}function Uu(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function qu(e,t){let n=[],r=[...new Set(t.diffRows.map(s=>s.path.split("/")[0]).filter(s=>typeof s=="string"&&s.length>0))].sort();for(let s of r){let o=t.diffRows.filter(c=>c.path.startsWith(`${s}/`)),i=s.startsWith("repo_")?s.slice(5):s;n.push({id:`repo-diff:${s}`,text:i,muted:!0});for(let c of["branch","staged","unstaged","untracked"]){let l=o.filter(d=>d.group===c);l.length!==0&&(n.push({id:`repo-diff:${s}:${c}`,text:` ${c}`,muted:!0}),n.push(...l.map(d=>vi(d,e,t,s.length+1))))}}return n}function vi(e,t,n,r=0){let s=e.additions===null?"-":`+${e.additions}`,o=e.deletions===null?"-":`-${e.deletions}`,i=e.status==="A"||e.group==="untracked"?"9ece6a":e.status==="D"?"f7768e":"e0af68",c=r>0?e.path.slice(r):e.path;return{id:`${e.group}:${e.path}`,text:` ${e.status.padEnd(2," ")} ${c} ${s}/${o}`,selected:e.path===(t.selectedDiffPath??n.selectedDiffPath),focused:e.path===(t.selectedDiffPath??n.selectedDiffPath)&&t.focusedRegion==="inspector",color:i}}function Ku(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:b.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:dt.basename(t.worktreePath)}]:[{label:"Repo",value:e.name},{label:"Branch",value:e.defaultBranch},{label:"Task",value:"none",mutedValue:!0}]:[{label:"Repo",value:"none",mutedValue:!0}]}function Vu(e){return e.reduce((t,n)=>(t[n.runner]+=1,t),{codex:0,cursor:0,claude:0})}function Gu(e,t){return{name:b.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}var Kt={width:120,height:36},pe={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function Ae(e,t){return{width:Math.max(e??Kt.width,Kt.width),height:Math.max(t??Kt.height,Kt.height)}}import{spawn as gp}from"node:child_process";import{createHash as hp}from"node:crypto";import{createServer as wp,createConnection as Fi}from"node:net";import{openSync as kp}from"node:fs";import{mkdir as Rp,readFile as br,rm as Be,writeFile as Tp}from"node:fs/promises";import{tmpdir as yp}from"node:os";import Ye from"node:path";import{createRequire as np}from"node:module";import Hu from"@xterm/headless";var zu=1e3,Yu=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function Ai(e){return new Hu.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:zu,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function $i(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function kr(e,t){return new Promise(n=>{e.write(t,n)})}function Di(e,t=0){let n=e.buffer.active,r=[],s=n.getNullCell(),o=n.baseY+n.cursorY,i=Math.max(0,n.baseY-t);for(let c=0;c<e.rows;c+=1){let l=n.getLine(i+c);if(!l){r.push({segments:[]});continue}let d=[];for(let p=0;p<e.cols;p+=1){let h=l.getCell(p,s);!h||h.getWidth()===0||d.push({text:h.getChars()||" ",style:Xu(h,i+c===o&&p===n.cursorX)})}r.push({segments:Ju(Qu(d))})}return r}function Ju(e){let t=[];for(let n of e){let r=t.at(-1);if(r&&tp(r.style,n.style)){r.text+=n.text;continue}let s={text:n.text};Mi(n.style)||(s.style=n.style),t.push(s)}return t}function Qu(e){let t=e.length;for(;t>0;){let n=e[t-1];if(!n||n.text!==" "||!Mi(n.style))break;t-=1}return e.slice(0,t)}function Xu(e,t){let n={},r=Ei(e,"fg"),s=Ei(e,"bg");return r&&(n.fg=r),s&&(n.bg=s),e.isBold()&&(n.bold=!0),e.isDim()&&(n.dim=!0),e.isItalic()&&(n.italic=!0),e.isUnderline()&&(n.underline=!0),(e.isInverse()||t)&&(n.inverse=!0),n}function Ei(e,t){if(t==="fg"?e.isFgDefault():e.isBgDefault())return;let r=t==="fg"?e.isFgRGB():e.isBgRGB(),s=t==="fg"?e.getFgColor():e.getBgColor();return r?s.toString(16).padStart(6,"0"):Yu[s]??Zu(s)}function Zu(e){if(e>=16&&e<=231){let t=e-16,n=Math.floor(t/36),r=Math.floor(t%36/6),s=t%6;return[n,r,s].map(ep).map(o=>o.toString(16).padStart(2,"0")).join("")}if(e>=232&&e<=255){let t=8+(e-232)*10;return[t,t,t].map(n=>n.toString(16).padStart(2,"0")).join("")}return"e6e6e6"}function ep(e){return e===0?0:55+e*40}function tp(e,t){return wr(e)===wr(t)}function wr(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function Mi(e){return wr(e)===""}var rp=np(import.meta.url),sp=/^CTRL_([A-Z])$/,op="\x1B[6n",ip="\x1B[c",ap="\x1B[?u",cp={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
143
- `,TAB:" ",SHIFT_TAB:"\x1B[Z",BACK_TAB:"\x1B[Z",BACKSPACE:"\x7F",DELETE:"\x1B[3~",ESCAPE:"\x1B",UP:"\x1B[A",DOWN:"\x1B[B",RIGHT:"\x1B[C",LEFT:"\x1B[D",HOME:"\x1B[H",END:"\x1B[F",PAGE_UP:"\x1B[5~",PAGE_DOWN:"\x1B[6~",CTRL_C:"",CTRL_D:""},Vt=class{sessions=new Map;shell;env;spawn;onUpdate;resolveSessionSpec;attachedTabId=null;constructor(t){this.shell=t.shell??process.env.SHELL??"/bin/zsh",this.env=t.env??process.env,this.spawn=t.spawn,this.onUpdate=t.onUpdate,this.resolveSessionSpec=t.resolveSessionSpec??(()=>({cwd:t.workspaceRoot,command:[]}))}ensureSession(t,n,r,s){let o=this.sessions.get(n);if(o)if(o.status!=="running")Rr(o),this.sessions.delete(n);else return this.attachedTabId=n,o.scrollbackLines=0,Li(o,r),this.getViewState(n);let i=this.createSession(t,n,r,s);return this.sessions.set(n,i),this.attachedTabId=n,this.getViewState(n)}write(t){let n=this.getAttachedSession();!n||n.status!=="running"||n.pty.write(t)}writeKey(t){let n=lp(t);n!==null&&this.write(n)}scrollViewport(t){let n=this.getAttachedSession();if(!n||t===0)return;let r=n.terminal.buffer.active.baseY;n.scrollbackLines=Math.max(0,Math.min(r,n.scrollbackLines-t))}resize(t){let n=this.getAttachedSession();n&&Li(n,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}disposeSession(t){let n=this.sessions.get(t);n&&(Rr(n),this.sessions.delete(t),this.attachedTabId===t&&(this.attachedTabId=null))}disposeAll(){for(let t of this.sessions.values())Rr(t);this.sessions.clear(),this.attachedTabId=null}getViewState(t){if(!t)return{status:"idle",rows:[],error:null,scrolledBack:!1};let n=this.sessions.get(t);return n?{status:n.status,rows:Di(n.terminal,n.scrollbackLines),error:n.error,scrolledBack:n.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,n,r,s){let o=this.spawn??up().spawn,i=Ai(r),c=s??this.resolveSessionSpec(t,n),l=Le({...this.env,...c.env??{}}),{executable:d,args:p}=pp(this.shell,c.command,{cwd:c.cwd,env:l}),h=o(d,p,{name:"xterm-256color",cols:r.columns,rows:r.rows,cwd:c.cwd,env:fp(l)}),R={taskId:t,tabId:n,pty:h,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0};return R.disposables.push(h.onData(k=>{mp(h,k),kr(R.terminal,k).then(()=>{this.onUpdate?.(R.tabId)})})),R.disposables.push(h.onExit(k=>{R.status="exited",kr(R.terminal,`\r
144
- [process exited ${k.exitCode}]`).then(()=>{this.onUpdate?.(R.tabId)})})),R}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}};function lp(e){if(e.length===1)return e;let t=cp[e];if(t!==void 0)return t;let n=sp.exec(e);return n?.[1]?String.fromCharCode(n[1].charCodeAt(0)-64):null}function Li(e,t){dp(e.pty,t),$i(e.terminal,t)}function Rr(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function dp(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function up(){return rp("node-pty")}function pp(e,t,n){if(t.length===0)return{executable:e,args:[]};let s=`${[je(t[0],n),...t.slice(1)].map(ji).join(" ")}; exec ${ji(e)} -l`;return{executable:e,args:["-lc",s]}}function ji(e){return`'${e.replaceAll("'","'\\''")}'`}function fp(e){let t={};for(let[n,r]of Object.entries(e))typeof r=="string"&&(t[n]=r);return t.TERM=t.TERM??"xterm-256color",t}function mp(e,t){for(let n=0;n<Tr(t,op);n+=1)e.write("\x1B[1;1R");for(let n=0;n<Tr(t,ip);n+=1)e.write("\x1B[?1;2c");for(let n=0;n<Tr(t,ap);n+=1)e.write("\x1B[?0u")}function Tr(e,t){if(t.length===0)return 0;let n=0,r=e.indexOf(t);for(;r!==-1;)n+=1,r=e.indexOf(t,r+t.length);return n}var Sr=3;async function Ni(e){let t=Ir(e.paths);await Pp(t,e.paths,e.spawnDaemon);let n=await Ki(t.socketPath),r=new yr(n,e);return await r.ready(),r}async function Wi(e,t={}){let n=Ir(e);await Rp(e.runtimeDir,{recursive:!0}),await Be(n.socketPath,{force:!0});let r=new Pr(e,t),s=wp(o=>r.handleConnection(o));await vp(s,n.socketPath),await Tp(n.pidPath,String(process.pid),"utf8"),await new Promise(o=>{let i=()=>{r.closeClients(),s.close(()=>o())};r.onShutdown=i,process.once("SIGTERM",i),process.once("SIGINT",i)}),await Be(n.socketPath,{force:!0}),await Be(n.pidPath,{force:!0}),r.disposeAll()}async function _i(e){let t=Ir(e);return await Ht(t.socketPath)?(await Ui(t.socketPath),!0):!1}var yr=class{constructor(t,n){this.socket=t;this.options=n,t.setEncoding("utf8"),t.on("data",r=>this.handleData(String(r))),t.on("error",r=>this.rejectAll(r instanceof Error?r:new Error(String(r)))),t.on("close",()=>{this.closed=!0,this.rejectAll(new Error("Craig PTY daemon connection closed."))})}socket;nextRequestId=1;pending=new Map;viewCache=new Map;attachedTabId=null;buffer="";closed=!1;options;async ready(){if((await this.send({type:"ping"})).protocolVersion!==Sr)throw new Error("Craig PTY daemon protocol mismatch.")}async ensureSession(t,n,r){let s=await this.send({type:"ensureSession",taskId:t,tabId:n,size:r,spec:this.options.resolveSessionSpec?.(t,n)??{cwd:this.options.workspaceRoot,command:[]}});this.attachedTabId=n;let o=s.view??{status:"idle",rows:[],error:null};return this.viewCache.set(n,o),o}async hydrateSessions(t){for(let n of t)try{let r=await this.send({type:"hydrateSession",tabId:n});r.view&&this.viewCache.set(n,r.view)}catch(r){let s=r instanceof Error?r.message:String(r);this.viewCache.set(n,{status:"failed",rows:[],error:s})}}async pruneStale(t){await this.send({type:"pruneStale",keepTabIds:t})}write(t){this.send({type:"write",input:t}).catch(()=>{})}writeKey(t){this.send({type:"writeKey",key:t}).catch(()=>{})}scrollViewport(t){this.send({type:"scrollViewport",lines:t}).then(n=>{this.attachedTabId&&n.view&&this.viewCache.set(this.attachedTabId,n.view)}).catch(()=>{})}resize(t){this.send({type:"resize",size:t}).then(n=>{this.attachedTabId&&n.view&&this.viewCache.set(this.attachedTabId,n.view)}).catch(()=>{})}detach(){this.attachedTabId=null,this.send({type:"detach"}).catch(()=>{})}disposeSession(t){this.viewCache.delete(t),this.attachedTabId===t&&(this.attachedTabId=null),this.send({type:"disposeSession",tabId:t}).catch(()=>{})}disposeAll(){this.attachedTabId=null,!this.closed&&(this.socket.end(),this.closed=!0)}getViewState(t){return t?this.viewCache.get(t)??{status:"idle",rows:[],error:null,scrolledBack:!1}:{status:"idle",rows:[],error:null,scrolledBack:!1}}async requestShutdown(){await this.send({type:"shutdown"})}async send(t){if(this.closed)throw new Error("Craig PTY daemon connection is closed.");let n=this.nextRequestId;this.nextRequestId+=1;let r={...t,id:n},s=new Promise((i,c)=>{this.pending.set(n,{resolve:i,reject:c})});if(this.socket.destroyed)throw this.pending.delete(n),new Error("Craig PTY daemon connection is closed.");this.socket.write(`${JSON.stringify(r)}
145
- `);let o=await s;if(!o.ok)throw new Error(o.error);return o}handleData(t){this.buffer+=t;let n=this.buffer.indexOf(`
146
- `);for(;n!==-1;){let r=this.buffer.slice(0,n);this.buffer=this.buffer.slice(n+1),this.handleMessage(r),n=this.buffer.indexOf(`
147
- `)}}handleMessage(t){if(t.trim().length===0)return;let n;try{n=JSON.parse(t)}catch{return}if("id"in n){let r=this.pending.get(n.id);if(!r)return;this.pending.delete(n.id),r.resolve(n);return}n.type==="update"&&(n.tabId&&this.viewCache.set(n.tabId,n.view),this.options.onUpdate?.(n.tabId??""))}rejectAll(t){for(let n of this.pending.values())n.reject(t);this.pending.clear()}},Pr=class{onShutdown=null;clients=new Set;runtime;attachedTabId=null;constructor(t,n){this.runtime=new Vt({...n,workspaceRoot:t.workspaceRoot,onUpdate:r=>this.broadcastUpdate(r)})}handleConnection(t){let n="";this.clients.add(t),t.setEncoding("utf8"),t.on("data",r=>{n+=String(r);let s=n.indexOf(`
148
- `);for(;s!==-1;){let o=n.slice(0,s);n=n.slice(s+1),this.handleLine(t,o),s=n.indexOf(`
149
- `)}}),t.on("close",()=>this.clients.delete(t)),t.on("error",()=>this.clients.delete(t))}disposeAll(){this.runtime.disposeAll()}closeClients(){for(let t of this.clients)t.destroy();this.clients.clear()}async handleLine(t,n){if(n.trim().length===0)return;let r;try{r=JSON.parse(n)}catch{Gt(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(r);Gt(t,{id:r.id,ok:!0,...r.type==="ping"?{protocolVersion:Sr}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);Gt(t,{id:r.id,ok:!1,error:o})}}handleRequest(t){switch(t.type){case"ping":return null;case"ensureSession":return this.attachedTabId=t.tabId,this.runtime.ensureSession(t.taskId,t.tabId,t.size,t.spec);case"hydrateSession":return this.runtime.getViewState(t.tabId);case"write":return this.runtime.write(t.input),null;case"writeKey":return this.runtime.writeKey(t.key),null;case"scrollViewport":return this.runtime.scrollViewport(t.lines),this.runtime.getViewState(this.attachedTabId);case"resize":return this.runtime.resize(t.size),this.runtime.getViewState(this.attachedTabId);case"detach":return this.runtime.detach(),this.attachedTabId=null,null;case"disposeSession":return this.runtime.disposeSession(t.tabId),this.attachedTabId===t.tabId&&(this.attachedTabId=null),null;case"pruneStale":{let n=new Set(t.keepTabIds);for(let r of this.runtime.sessionTabIds())n.has(r)||(this.runtime.disposeSession(r),this.attachedTabId===r&&(this.attachedTabId=null));return null}case"getViewState":return this.runtime.getViewState(t.tabId);case"shutdown":return setTimeout(()=>this.onShutdown?.(),0),null;default:return Ep(t)}}broadcastUpdate(t){let n=this.runtime.getViewState(t);for(let r of this.clients)Gt(r,{type:"update",tabId:t,view:n})}};function Ir(e){let t=hp("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:Ye.join(yp(),`craig-${t}.sock`),pidPath:Ye.join(e.runtimeDir,"pty-daemon.pid")}}async function Pp(e,t,n){if(await bp(e.socketPath,1e3))return;await Ht(e.socketPath)&&(await Ui(e.socketPath),await Oi(e.socketPath,1e3)),await Ht(e.socketPath)&&(await Cp(e),await Oi(e.socketPath,1e3)),await Ip(e);let r=t.workspaceRoot;if(n)n(r);else{let{command:i,args:c}=Sp(r),l=kp(Ye.join(t.runtimeDir,"pty-daemon.log"),"a");gp(i,c,{cwd:r,detached:!0,stdio:["ignore",l,l],env:process.env}).unref()}let s=Date.now();for(;Date.now()-s<5e3;){if(await Bi(e.socketPath))return;await Cr(50)}let o=await br(Ye.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
150
- ${o.slice(-2e3)}`:""}`)}async function Bi(e){let t=await xp(e).catch(()=>null);return t?.ok===!0&&t.protocolVersion===Sr}async function bp(e,t){let n=Date.now();for(;Date.now()-n<t;){if(await Bi(e))return!0;await Cr(50)}return!1}function Sp(e){let t=process.argv[1];if(t?.endsWith(".ts")){let r=Ye.resolve(Ye.dirname(t),"..","node_modules",".bin","tsx");return{command:Sn("tsx")??r,args:[t,"__craig-daemon",e]}}let n=process.argv.slice(1);return{command:process.execPath,args:[...process.execArgv,...n,"__craig-daemon",e]}}async function Ip(e){let t=await br(e.pidPath,"utf8").catch(()=>null);if(t){let n=Number(t.trim());if(Number.isInteger(n)&&n>0&&Vi(n))return}await Be(e.socketPath,{force:!0}),await Be(e.pidPath,{force:!0})}async function Ht(e){let t=await Ki(e).catch(()=>null);return t?(t.end(),!0):!1}async function Ui(e){await qi(e,{id:1,type:"shutdown"}).catch(()=>null)}async function Cp(e){let t=await br(e.pidPath,"utf8").catch(()=>null),n=Number(t?.trim());if(!Number.isInteger(n)||n<=0||!Vi(n)){await Be(e.socketPath,{force:!0});return}try{process.kill(n,"SIGTERM")}catch{await Be(e.socketPath,{force:!0})}}async function xp(e){return qi(e,{id:1,type:"ping"})}function qi(e,t){return new Promise((n,r)=>{let s=Fi(e),o="",i=setTimeout(()=>{s.destroy(),r(new Error("Craig PTY daemon request timed out."))},500),c=()=>clearTimeout(i);s.setEncoding("utf8"),s.once("connect",()=>s.write(`${JSON.stringify(t)}
151
- `)),s.once("error",l=>{c(),r(l)}),s.on("data",l=>{o+=String(l);let d=o.indexOf(`
152
- `);if(d===-1)return;let p=o.slice(0,d);c(),s.end();try{n(JSON.parse(p))}catch(h){r(h instanceof Error?h:new Error(String(h)))}}),s.once("close",()=>c())})}async function Oi(e,t){let n=Date.now();for(;Date.now()-n<t;){if(!await Ht(e))return;await Cr(50)}}function Ki(e){return new Promise((t,n)=>{let r=Fi(e);r.once("connect",()=>t(r)),r.once("error",n)})}function vp(e,t){return new Promise((n,r)=>{e.once("error",r),e.listen(t,n)})}function Gt(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
153
- `)}catch{}}function Vi(e){try{return process.kill(e,0),!0}catch{return!1}}function Cr(e){return new Promise(t=>setTimeout(t,e))}function Ep(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}import LR from"picocolors";var Ap=[" \u2584\u2588\u2588\u2588\u2588\u2584 \u2588\u2588\u2580\u2588\u2588\u2588 \u2584\u2584\u2584 \u2588\u2588\u2593 \u2584\u2588\u2588\u2588\u2588"," \u2592\u2588\u2588\u2580 \u2580\u2588 \u2593\u2588\u2588 \u2592 \u2588\u2588\u2592\u2592\u2588\u2588\u2588\u2588\u2584 \u2593\u2588\u2588\u2592 \u2588\u2588\u2592 \u2580\u2588\u2592"," \u2592\u2593\u2588 \u2584 \u2593\u2588\u2588 \u2591\u2584\u2588 \u2592\u2592\u2588\u2588 \u2580\u2588\u2584 \u2592\u2588\u2588\u2592\u2592\u2588\u2588\u2591\u2584\u2584\u2584\u2591"," \u2592\u2593\u2593\u2584 \u2584\u2588\u2588\u2592\u2592\u2588\u2588\u2580\u2580\u2588\u2584 \u2591\u2588\u2588\u2584\u2584\u2584\u2584\u2588\u2588 \u2591\u2588\u2588\u2591\u2591\u2593\u2588 \u2588\u2588\u2593"," \u2592 \u2593\u2588\u2588\u2588\u2580 \u2591\u2591\u2588\u2588\u2593 \u2592\u2588\u2588\u2592 \u2593\u2588 \u2593\u2588\u2588\u2592\u2591\u2588\u2588\u2591\u2591\u2592\u2593\u2588\u2588\u2588\u2580\u2592"," \u2591 \u2591\u2592 \u2592 \u2591\u2591 \u2592\u2593 \u2591\u2592\u2593\u2591 \u2592\u2592 \u2593\u2592\u2588\u2591\u2591\u2593 \u2591\u2592 \u2592"," \u2591 \u2592 \u2591\u2592 \u2591 \u2592\u2591 \u2592 \u2592\u2592 \u2591 \u2592 \u2591 \u2591 \u2591"," \u2591 \u2591\u2591 \u2591 \u2591 \u2592 \u2592 \u2591\u2591 \u2591 \u2591"," \u2591 \u2591 \u2591 \u2591 \u2591 \u2591 \u2591"," \u2591"];function xr(){return[...Ap]}var $p=["Start","Options","Exit"],Dp=["Resume","Options","Exit"],Jt=2,Qt=2,Xt=2,Mp=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),Lp=new RegExp("\x1B\\[(?:0)?m","g"),jp=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),Op=/https?:\/\/[^\s<>"']+/g,vr="\x1B[0m",Er="\x1B]8;;\x1B\\",E={panelBg:{bg:"0a0a0a",fg:"c0caf5"},panelMuted:{bg:"0a0a0a",fg:"565f89"},panelSelected:{bg:"1a1b26",fg:"c0caf5"},panelFocused:{bg:"1a1b26",fg:"7aa2f7"},divider:{bg:"0a0a0a",fg:"292e42"},rail:{bg:"0a0a0a",fg:"c0caf5"},overlay:{bg:"06060f",fg:"565f89"},overlayTitle:{bg:"06060f",fg:"565f89"},overlayLogo:{bg:"06060f",fg:"9ece6a"},overlaySubtitle:{bg:"06060f",fg:"41a6b5"},overlayMenuSelected:{bg:"06060f",fg:"7aa2f7"},accent:{fg:"7aa2f7"},success:{fg:"9ece6a"},pending:{fg:"e0af68"},error:{fg:"f7768e"},mutedfg:{fg:"565f89"},disabled:{fg:"3b4261"}};function zi(e,t={}){return $r(e,{subtitle:"crAIg is that you?",menuItems:$p,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function Yi(e,t={}){return $r(e,{subtitle:"Control mode is paused.",menuItems:Dp,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var zt=[" GLOBAL CENTER PANEL INSPECTOR"," ? help \u2190\u2192 / hl switch tab \u2191\u2193 / jk navigate"," Esc pause / back + new tab \u2190\u2192 / hl switch mode"," Tab cycle panels a codex tab R sync PR"," q quit t terminal tab R sync PR"," x close tab X close task"," TASKS Enter attach PTY X close task"," \u2191\u2193 / jk navigate"," n new task TERMINAL MODE"," Enter attach Ctrl+] return to control mode"," Wheel / PgUp / PgDn scroll",""," Press Esc to return."],Fp=["Help"];function Ar(e,t={}){return $r(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??Fp,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function Ji(e,t={}){let n=t.color??!0,r=E.overlay,s=new Array(e.height).fill(F(" ".repeat(e.width),n,r)),o=xr(),i=Math.max(1,Math.floor((e.height-o.length-2-zt.length)/2));for(let p=0;p<o.length&&!(i+p>=e.height);p+=1)s[i+p]=F(ta(o[p]??"",e.width),n,E.overlayLogo);let c=Math.max(...zt.map(p=>p.length)),l=Math.max(0,Math.floor((e.width-c)/2)),d=i+o.length+2;for(let p=0;p<zt.length;p+=1){let h=d+p;if(h>=e.height)break;let R=zt[p]??"";s[h]=F(ke(" ".repeat(l)+R,e.width),n,r)}return s.join(`
154
- `)}function Qi(e,t={}){let n=t.color??!0,r=E.overlay,s=new Array(e.height).fill(F(" ".repeat(e.width),n,r)),o="Error Log",i=t.errorLogPath??"",c=t.errorLogLines??[],l=Math.max(20,e.width-8),d=Math.max(0,Math.floor((e.width-l)/2)),p=[{text:o,tone:"selected"},{text:i,tone:"muted"},se(),...c.length>0?c.map(k=>({text:k})):[{text:"No Craig errors have been logged.",tone:"muted"}],se(),{text:"Esc returns to Options.",tone:"muted"}],h=ut(p,e.height-2),R=Math.max(1,Math.floor((e.height-h.length)/2));for(let k=0;k<h.length;k+=1){let I=R+k;if(I>=e.height)break;let T=h[k]??se(),a=`${" ".repeat(d)}${en(T.text,l)}`,G=T.tone==="selected"?E.overlayMenuSelected:T.tone==="muted"?E.overlay:E.panelBg;s[I]=F(ke(a,e.width),n,G)}return s.join(`
155
- `)}function Xi(e,t,n={}){let r=n.color??!0,s=pe.leftWidth,o=pe.rightWidth,i=pe.dividerWidth,c=n.centerOnly??!1,l=c?e.width:e.width-s-o-i*2,d=e.height-pe.topRailHeight-1,p=n.focusFlashActive??!1,h={bg:E.divider.bg,fg:"9ece6a"},R=p&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?h:E.divider,k=p&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?h:E.divider,I=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,T=F(ke(I,e.width),r,E.rail),a=Wp(t,s-Jt-Qt,d,r),G=_p(t,l,d,r),W=Up(t,o,d,r),oe=t.inputMode==="terminal",x=[];for(let te=0;te<d;te+=1){if(c){x.push(Yt(G[te]??se(),l,r,"center"));continue}let Se=Yt(a[te]??se(),s,r,"left"),fe=F("\u2502",r,R),Ie=Yt(G[te]??se(),l,r,"center"),ie=F("\u2502",r,k),Ue=Yt(W[te]??se(),o,r,"right");x.push(`${Se}${fe}${Ie}${ie}${Ue}`)}let $e=oe||t.modalInput?E.panelBg:E.panelMuted,be=Np(t.footerText,t.footerToast,e.width,r,$e);return[T,...x,be].join(`
156
- `)}function Np(e,t,n,r,s){let o=` ${e}`;if(!t)return F(ke(o,n),r,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,c=ee(i),l=ee(o),d=Math.max(1,n-l-c-2),p=l+d+c+2>n?en(o,Math.max(0,n-c-3)):o,h=Math.max(1,n-ee(p)-c-2),R=t.tone==="error"?cf(i,r,s):Je(i,r,s),k=`${p}${" ".repeat(h)}${R} `;return F(ke(k,n),r,s)}function $r(e,t){let n=new Array(e.height).fill(F(" ".repeat(e.width),t.color,E.overlay)),r=xr(),s=Math.max(...t.menuItems.map(d=>d.length)),o=t.menuItems.map((d,p)=>`${p===t.menuIndex?">":" "} ${d.padEnd(s)}`),i=t.optionsMessage?["",t.optionsMessage]:[],c=[...r,"",t.subtitle,"",...o,...i],l=Math.max(1,Math.floor((e.height-c.length)/2));for(let d=0;d<c.length;d+=1){let p=ta(c[d]??"",e.width);if(d<r.length){n[l+d]=F(p,t.color,E.overlayLogo);continue}if(d===r.length+1){n[l+d]=F(p,t.color,E.overlaySubtitle);continue}let h=d-(r.length+3),k=h>=0&&h<t.menuItems.length&&h===t.menuIndex?E.overlayMenuSelected:E.overlay;n[l+d]=F(p,t.color,k)}if(t.versionText){let d=t.updateText?" (update available)":"",p=`${t.versionText}${d} `,h=" ".repeat(Math.max(0,e.width-ee(p)));n[e.height-1]=F(`${h}${Dr(p,t.color,E.overlay)}`,t.color,E.overlay)}return n.join(`
157
- `)}function Wp(e,t,n,r){let s=Vp(e.runners),o=1,i=e.leftTree.map(l=>Kp(l,t,r));return[...ut(i,n-o),s]}function _p(e,t,n,r){let s=t-2,o=e.tabs.find(x=>x.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:sf(e.tabs),c=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,c)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?Je(l,r,E.panelBg):Zt(l,r,E.panelMuted)}`,p=[`${Zt(e.centerHeader.tabLabel,r,E.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),h=e.tabs.find(x=>x.active)?.id??"agent",R=e.centerHeader.tabLabel==="BROWSER"||!ci(h)?e.centerTranscript.map(x=>({...x})):Bp(e),k=Gp(e.tabs,r,e.focusedRegion==="center"),I=" engaged ",T=I.length+2,a=e.inputMode==="terminal"?Je(`${I}\u25CF `,r,E.panelBg):"",G=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-ee(k)-T)):"",oe=[{text:e.inputMode==="terminal"?`${k}${G}${a}`:k},{text:d,tone:"muted"},{text:p},se(),...R];return ut(oe,n)}function Bp(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},se(),{text:e.terminal.error},se(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(r=>r.active)?.id??"",n=t==="agent"||/:agent(?:-\d+)?$/.test(t)?"agent":"terminal";return e.terminal.rows.length===0?[{text:`Press Enter on the ${n.toUpperCase()} tab to attach a PTY.`}]:e.terminal.rows.map(r=>({text:sa(r.segments),segments:r.segments,fullBleed:!0}))}function Up(e,t,n,r){let s=e.rightInspection?qp(e.actionMessage?[...e.rightInspection.rows.slice(0,2),{id:"action-message",text:e.actionMessage},{id:"action-message-spacer",text:""},...e.rightInspection.rows.slice(2)]:e.rightInspection.rows,n):ut([{text:"CONTEXT"},se(),...e.rightContext.map(o=>Hp(o,r)),...e.actionMessage?[se(),{text:e.actionMessage}]:[]],n);return ut(s,n)}function qp(e,t){let n=e.slice(0,2),r=e.slice(2),s=Math.max(0,t-n.length),o=r.findIndex(c=>c.focused||c.selected),i=o===-1?0:af(o-Math.floor(s/2),0,Math.max(0,r.length-s));return[...n.map(c=>Gi(c)),...r.slice(i,i+s).map(c=>Gi(c))]}function Gi(e){let t=e.focused?"\u25B8 ":e.selected?"\u2022 ":" ",n=e.focused||e.selected?"selected":e.muted?"muted":"default",r=`${t}${e.text}`;if(e.segments)return{text:r,segments:[{text:t},...e.segments],tone:n};if(e.accentPrefix&&!e.muted){let s=e.text.indexOf(" "),o=s===-1?e.text:e.text.slice(0,s),i=s===-1?"":e.text.slice(s);return{text:r,segments:[{text:t},{text:o,style:{fg:"7aa2f7"}},{text:i}],tone:n}}return e.color?{text:r,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:n}:{text:r,tone:n}}function Kp(e,t,n){let r=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${Je("\u25CF",n,e.selected?E.panelSelected:E.panelBg)}`:"",c=e.prBadge?e.prBadge.reduce((k,I)=>k+ee(I.text),0):0,l=t-ee(o)-ee(s)-c,d=e.selected?e.text:e.focused?Je(e.text,n,E.panelBg):e.panelHeader?Zt(e.text,n,E.panelMuted):e.text,p=ke(`${r}${d}`,Math.max(0,l)),h=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let k=[{text:`${p}${o}${i}`},...e.prBadge];return{text:`${p}${o}${e.prBadge.map(T=>T.text).join("")}`,segments:k,tone:h}}return{text:`${p}${o}${i}`,tone:h}}function Vp(e){let t=e.map(r=>{let s=r.health>=1,o=parseInt(r.count,10),i=o>1?` (${o})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${r.name}${i}`,active:s}}),n=[];for(let r=0;r<t.length;r++){let s=t[r];r>0&&n.push({text:" "}),s.active?n.push({text:s.text,style:{fg:E.success.fg}}):n.push({text:s.text,style:{fg:E.panelMuted.fg}})}return{text:t.map(r=>r.text).join(" "),segments:n,tone:"muted"}}function Gp(e,t,n){return e.map(r=>r.active?n?Je(r.label,t,E.panelBg):Zt(r.label,t,E.panelBg):Dr(r.label,t,E.panelBg)).join(" ")}function Hp(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?Dr(e.value,t,E.panelBg):e.value}`}}function Yt(e,t,n,r){let s=zp(r,e.tone??"default"),o=Yp(e,n,s);if(r==="left"){if(e.fullBleed)return F(ke(o,t),n,s);let c=t-Jt-Qt;if(e.rightAlign){let d=ee(o),p=Math.max(0,c-d),h=`${" ".repeat(Jt)}${" ".repeat(p)}${o}${" ".repeat(Qt)}`;return F(h,n,s)}let l=`${" ".repeat(Jt)}${ke(o,c)}${" ".repeat(Qt)}`;return F(l,n,s)}return r==="center"&&e.fullBleed?Jp(e,t,n,s):F(ke(` ${o}`,t),n,s)}function zp(e,t){return t==="selected"||t==="focused"?E.panelSelected:t==="muted"?E.panelMuted:E.panelBg}function ut(e,t){let n=e.slice(0,t);for(;n.length<t;)n.push(se());return n}function se(){return{text:""}}function Yp(e,t,n){return e.segments?e.segments.map(r=>Zi(r,t,n)).join(""):e.text}function Jp(e,t,n,r){let s=" ".repeat(Xt),o=Math.max(0,t-Xt*2);if(!e.segments)return F(`${s}${ke(e.text,o)}${s}`,n,r);let i=Zp(e.segments,o),c=`${s}${i.map(l=>Zi(l,n,r)).join("")}${s}${n?Er:""}`;return F(c,n,r)}function Zi(e,t,n){let r=e.href?`${ea(e.href)}${e.text}${Er}`:Qp(e.text);return!t||!e.style?r:`${pt(nf(e.style,n))}${rf(e.style)}${r}${vr}${pt(n)}`}function Qp(e){return e.replace(Op,t=>{let[n,r]=Xp(t);return`${ea(n)}${n}${Er}${r}`})}function Xp(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function ea(e){return`\x1B]8;;${e}\x1B\\`}function Zp(e,t){let n=ef(e,t);return tf(n,t)}function ef(e,t){let n=[],r=t;for(let s of e){if(r<=0)break;let o=ee(s.text);if(o<=r){n.push(s),r-=o;continue}let i=en(s.text,r);i.length>0&&n.push({...s,text:i}),r=0}return n}function tf(e,t){let n=ee(sa(e));if(n>=t)return e;let r=e.at(-1)?.style;return r?.bg?[...e,{text:" ".repeat(t-n),style:r}]:[...e,{text:" ".repeat(t-n)}]}function nf(e,t){let n=e.inverse?e.bg??t.bg:e.fg,r=e.inverse?e.fg??t.fg:e.bg,s={},o=n??t.fg,i=r??t.bg;return o&&(s.fg=o),i&&(s.bg=i),s}function rf(e){let t=[];return e.bold&&t.push("1"),e.dim&&t.push("2"),e.italic&&t.push("3"),e.underline&&t.push("4"),t.length>0?`\x1B[${t.join(";")}m`:""}function sf(e){let t=0;for(let n of e){if(n.active)return t;t+=n.label.length+3}return 0}function ta(e,t){let n=Math.max(0,t-ee(e)),r=Math.floor(n/2),s=n-r;return`${" ".repeat(r)}${e}${" ".repeat(s)}`}function ke(e,t){let n=ee(e);return n>=t?of(e,t):e+" ".repeat(t-n)}function of(e,t){if(t<=0)return"";if(ee(e)<=t)return e;let n=ra(e);return en(n,Math.max(0,t-1))+"\u2026"}function ee(e){let t=0;for(let n of Array.from(ra(e)))t+=na(n);return t}function en(e,t){let n="",r=0;for(let s of Array.from(e)){let o=na(s);if(r+o>t)break;n+=s,r+=o}return n}function na(e){let t=e.codePointAt(0);return t===void 0||t===0||t<32||t>=127&&t<160||t>=768&&t<=879||t>=6832&&t<=6911||t>=7616&&t<=7679||t>=8400&&t<=8447||t>=65024&&t<=65039||t>=8203&&t<=8207||t>=8288&&t<=8292||t===65279?0:t>=4352&&(t<=4447||t===9001||t===9002||t>=11904&&t<=42191&&t!==12351||t>=44032&&t<=55203||t>=63744&&t<=64255||t>=65040&&t<=65049||t>=65072&&t<=65135||t>=65280&&t<=65376||t>=65504&&t<=65510||t>=127744&&t<=129791||t>=131072&&t<=262141)?2:1}function af(e,t,n){return Math.min(Math.max(e,t),n)}function ra(e){return e.replace(jp,"").replace(Mp,"")}function sa(e){return e.map(t=>t.text).join("")}function F(e,t,n){if(!t)return e;let r=pt(n),s=e.replace(Lp,`${vr}${r}`);return`${r}${s}${vr}`}function pt(e){let t=[];return e.fg&&t.push(`38;2;${Hi(e.fg).join(";")}`),e.bg&&t.push(`48;2;${Hi(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function Hi(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function Je(e,t,n){return tn(e,t,E.success.fg,n)}function cf(e,t,n){return tn(e,t,E.error.fg,n)}function Zt(e,t,n){return tn(e,t,E.accent.fg,n)}function Dr(e,t,n){return tn(e,t,E.mutedfg.fg,n)}function tn(e,t,n,r){if(!t)return e;let s=r.bg?{fg:n,bg:r.bg}:{fg:n};return`${pt(s)}${e}${pt(r)}`}var Mr=["Runners","Error Log","Help"];function Lr(e,t){return j.map(n=>{let r=b.runners.getProfile(n),s=e.runners?.[n]?.enabled!==!1,o=e.runners?.[n]?.path?.trim(),i=t.pathEdit?.runner===n?`${t.pathEdit.value}_`:o&&o.length>0?o:`default (${r.executable})`;return`${r.displayName} ${s?"enabled":"disabled"} ${i}`})}function ia(e){return e.message?e.message:e.pathEdit?"Type an executable path. Enter saves. Empty resets to default. Esc cancels.":"Enter toggles. E edits the executable path."}function aa(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Mr.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:jr(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function ca(e,t,n,r){if(e.pathEdit)return lf({...e,pathEdit:e.pathEdit},t,n);let s=Lr(t,e).length;if(n==="UP"||n==="k")return{kind:"render",state:{...e,menuIndex:Math.max(0,e.menuIndex-1),message:null}};if(n==="DOWN"||n==="j")return{kind:"render",state:{...e,menuIndex:Math.min(s-1,e.menuIndex+1),message:null}};if(n==="ESCAPE")return{kind:"back",state:e};if(n==="e"){let c=j[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:c,value:t.runners?.[c]?.path??""}}}}if(!jr(n))return{kind:"noop",state:e};let o=j[e.menuIndex]??"codex",i=t.runners?.[o]?.enabled!==!1;return i&&r.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save",config:df(t,o,!i),state:{...e,message:`${b.runners.getProfile(o).displayName} ${i?"disabled":"enabled"}.`}}}function lf(e,t,n){if(n==="ESCAPE")return{kind:"render",state:oa({...e,message:null})};if(n==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(jr(n)){let r=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:uf(t,r,s.length>0?s:null),state:oa({...e,message:s.length>0?`${b.runners.getProfile(r).displayName} executable saved.`:`${b.runners.getProfile(r).displayName} executable reset to default.`})}}return pf(n)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${n}`}}}:{kind:"noop",state:e}}function df(e,t,n){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:n}}}}function uf(e,t,n){let r={...e.runners?.[t]??{},...n?{path:n}:{}};return n||delete r.path,{...e,runners:{...e.runners??{},[t]:r}}}function oa(e){let t={...e};return delete t.pathEdit,t}function jr(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
158
- `}function pf(e){return e.length===1&&e>=" "&&e!=="\x7F"}var hf=ff(import.meta.url),wf=hf("terminal-kit"),kf=wf.terminal;async function ua(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),n=Re(t),r=await b.load(n),s=b.runners.getEnabled(r),o=e.uiStateFile?await Y({uiStateFile:e.uiStateFile}):null,i=Promise.resolve(),c=Promise.resolve(),l=await ft(t,void 0,s),d=Bt(ri(o,r),l);l=await ft(t,d,s);let p=()=>{},h={workspaceRoot:t,onUpdate:()=>p(),resolveSessionSpec:(I,T)=>Pf(l,T,t)},R=e.ptyRuntime??await Ni({...h,paths:n}),k=I=>{if(!e.uiStateFile)return;o=si(o,I);let T=o;i=i.then(()=>H({uiStateFile:e.uiStateFile},T),()=>H({uiStateFile:e.uiStateFile},T)),i.catch(()=>{})};return new Promise(I=>{let T=e.terminal??kf,a={mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:Bt(d,l)},G=!1,W=!1,oe=null,x=0,$e=0,be=null,te=null,Se=null,fe=null,Ie=null,ie=null,Ue=null,sn=!1,on=null,Fr=`Craig v${b.version.getCurrent()}`,an=null,cn=0,z=!0,ln=null,y=()=>{},N=R;p=()=>{a.mode==="main"&&(a={mode:"main",shell:Xe(a.shell)},Se||(Se=setTimeout(()=>{Se=null,a.mode==="main"&&y()},50)))};function Xe(m){return _e(m,N.getViewState(Nr(m)))}function Nr(m){let u=qe(m);return u?u.ptyTabs.some(f=>f.id===m.activeTab)?m.activeTab:m.activeTab==="agent"||m.activeTab==="terminal"?u.ptyTabs.find(f=>f.kind===m.activeTab)?.id??m.selectedPtyTabId:m.selectedPtyTabId:m.selectedPtyTabId}function P(m){return Xe(Rf(m,l))}function qe(m){return l.tasks.find(u=>u.id===m.selectedTaskId)??null}async function Wr(){let m=l.tasks.flatMap(u=>u.ptyTabs.map(f=>f.id));await N.pruneStale?.(m),await N.hydrateSessions?.(m)}function ma(){Wr().catch(()=>{}).then(()=>{a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},y())})}async function ga(m){let u=P(m),f=qe(u),g=Nr(u);if(!f||!g||!f.ptyTabs.some(O=>O.id===g))return u;let w=N.getViewState(g);if(w.status!=="idle"||w.rows.length>0||w.error)return _e(u,w);let C=await N.ensureSession(f.id,g,gt(Ae(T.width,T.height)));return _e({...u,inputMode:"control"},C)}function _r(m,u){return fe&&(clearTimeout(fe),fe=null),u?(fe=setTimeout(()=>{fe=null,!(a.mode!=="main"||a.shell.footerToast!==u)&&(a={mode:"main",shell:P({...a.shell,footerToast:null})},y())},600),{...m,footerToast:u}):{...m,footerToast:null}}function ha(m,u){return _r(m,u?{tone:"success",message:u}:null)}function q(m,u,f){let g=u instanceof Error?u.message:f,w=u instanceof Error?u.stack??u.message:String(u);return tr(n,{context:m,message:g,details:w}),g}function K(m,u){return _r(m,{tone:"error",message:u})}function De(m){let u=c.then(m,m);return c=u.then(()=>{},()=>{}),u}function Br(m){let u=qe(m),f=l.inspection,g=f&&f.taskId===u?.id?f:null,w=Tf(g?.fileRows??[],m.collapsedFileTreePaths);return{leftItemIds:yf(l),centerTabIds:di(u,m),ptyTabIds:u?.ptyTabs.map(C=>C.id)??[],filePathIds:g?.filePaths??[],fileTreeRowIds:w.map(C=>C.path),fileTreeFileIds:w.filter(C=>C.kind==="file").map(C=>C.path),fileTreeDirectoryIds:w.filter(C=>C.kind==="directory").map(C=>C.path),diffPathIds:g?.diffPaths??[],diffPathRanges:[],fileLineCount:g?.selectedFile.lines.length??0,diffLineCount:g?.selectedDiff.lines.length??0,reviewRowCount:Ii(m,u),pageRows:Math.max(5,Ae(T.width,T.height).height-pe.topRailHeight-9),enabledRunnerIds:s,projectTargetIds:u?.repoTargets?.map(C=>C.repoId)??[]}}async function wa(m){await b.save(n,m),r=m,s=b.runners.getEnabled(r),l={...l,enabledRunnerIds:s},a.mode==="main"?a={mode:"main",shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:b.runners.getDefault(r)})}:a={...a,shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:b.runners.getDefault(r)})}}async function ka(m){let u=m.selectedTaskId;u&&await De(async()=>{let f=await B(n,u);!f.ptyTabs.some(g=>g.id===m.activeTab)||f.selectedPtyTabId===m.activeTab||await A(n,{...f,selectedPtyTabId:m.activeTab})})}async function ae(){let m=(a.mode==="main",a.shell);l=await ft(t,m,s),a.mode==="main"?a={mode:"main",shell:P(a.shell)}:a={...a,shell:P(a.shell)}}async function Ur(m){let u=++cn,f=pa(l.tasks,m),g=l.inspection,w;if(f&&g?.taskId===f.id){let C={selectedFilePath:m.selectedFilePath,selectedDiffPath:m.selectedDiffPath},O=await Eo(f,g,C);if(u!==cn)return;w={...l,inspection:O}}else if(w=await ft(t,m,s),u!==cn)return;l=w,a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},k(a.shell),y())}async function dn(m){let u=await Lf(m);a.mode==="main"&&(a={mode:"main",shell:P({...a.shell,workspaceBrowser:u,activeTab:a.shell.selectedPtyTabId??a.shell.activeTab,actionMessage:null})},y())}async function qr(m){try{let u=P(m),f=qe(u),g=u.selectedPtyTabId;if(f&&u.focusedRegion==="tasks"){let O=f.ptyTabs.find(le=>le.kind==="agent")??null;O?g=O.id:(f=await Kr(f),await ae(),g=f.selectedPtyTabId)}f&&!g&&(f=await Kr(f),await ae(),g=f.selectedPtyTabId);let w=P({...u,activeTab:g??u.activeTab,selectedPtyTabId:g,focusedRegion:g?"center":u.focusedRegion});if(!w.selectedTaskId||!g){a={mode:"main",shell:w},y();return}a={mode:"main",shell:_e({...w,inputMode:"terminal"},N.getViewState(g))},k(a.shell);let C=await N.ensureSession(w.selectedTaskId,g,gt(Ae(T.width,T.height)));W=Or(g),oe=null,a={mode:"main",shell:_e({...w,inputMode:"terminal"},C)},k(a.shell)}catch(u){let f=q("attach PTY",u,"Failed to start PTY.");m.selectedTaskId&&m.selectedPtyTabId&&Or(m.selectedPtyTabId)&&(await Ra(m.selectedTaskId,f).catch(()=>{}),await ae().catch(()=>{})),a={mode:"main",shell:K(ii(P(m),f),f)},k(a.shell)}y()}async function Ra(m,u){await De(async()=>{let f=await B(n,m);await A(n,{...f,status:f.status==="running"?"draft":f.status,runnerSession:{...f.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:u})})}async function Ta(m,u,f){let g=P(m);if(!g.selectedTaskId)throw new Error("Select a task before creating a tab.");let w=await De(async()=>{let C=await B(n,g.selectedTaskId),O=u??If(C,g.activeTab,g.preferredPtyTabKind),le=la(C,O,f??void 0,r),Ze={...C,ptyTabs:[...C.ptyTabs,le],selectedPtyTabId:le.id};return await A(n,Ze),Ze});return await ae(),P({...g,activeTab:w.selectedPtyTabId??g.activeTab,selectedPtyTabId:w.selectedPtyTabId,preferredPtyTabKind:w.ptyTabs.at(-1)?.kind??g.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${w.ptyTabs.at(-1)?.title??"tab"}`})}async function ya(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:f,nextSelectedTab:g}=await De(async()=>{let w=await B(n,u.selectedTaskId),C=w.ptyTabs.findIndex(fn=>fn.id===u.activeTab);if(C===-1)throw new Error("Only PTY tabs can be closed.");let O=w.ptyTabs[C],le=w.ptyTabs.filter(fn=>fn.id!==O.id),Ze=le[Math.min(C,le.length-1)]??le[C-1]??null;return await A(n,{...w,ptyTabs:le,selectedPtyTabId:Ze?.id??null}),{closedTab:O,nextSelectedTab:Ze}});return N.disposeSession(f.id),await ae(),P({...u,activeTab:g?.id??(u.openInspectionKind?"inspection":u.activeTab),selectedPtyTabId:g?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${f.title}`})}async function Pa(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let f=qe(u),g=null,w=null;if(f?.type==="project"&&f.repoTargets?.length){let C=await Lt(n,u.selectedTaskId);await ae();let O=C.synced+C.discovered+C.notFound;w=`Refreshed ${C.synced}/${O} targets`}else{let{disposition:C,task:O}=await _n(n,u.selectedTaskId);await ae(),g=C==="not_found"?`No PR found for ${O.branch}`:null,C!=="not_found"&&(w=`Refreshed checks: ${V(O)?.requiredChecks.length??0} reported`)}return P({...ha(u,w),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:g})}async function ba(){if(sn||a.mode!=="main")return;let m=l.tasks;sn=!0;try{if(await uo(n,m),on=null,a.mode!=="main")return;l=await ft(t,a.shell,s),a={mode:"main",shell:P(a.shell)},y()}catch(u){let f=u instanceof Error?u.message:"Background PR discovery failed.";f!==on&&(on=f,tr(n,{context:"background PR polling",message:f,details:u instanceof Error?u.stack??u.message:String(u)}))}finally{sn=!1}}async function Sa(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:f,task:g}=await De(async()=>{let w=await B(n,u.selectedTaskId),C=await Wo(n,u.selectedTaskId);return{taskBeforeClose:w,task:C}});for(let w of f.ptyTabs)N.disposeSession(w.id);return await ae(),P({...u,selectedActionId:"close-task",actionMessage:g.cleanup.preservedWorktree?`Archived task ${g.id}; worktree preserved`:`Archived task ${g.id}`})}async function Ia(m){let u=P(m);if(!u.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await he(n,{workspaceId:u.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${u.selectedWorkspaceId} while task records still reference it.`);await Z.archiveWorkspace(n,u.selectedWorkspaceId);let g=await Z.removeWorkspace(n,u.selectedWorkspaceId);return await ae(),P({...u,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${g.workspaceId}`})}async function Kr(m){let u=m.ptyTabs.find(w=>w.kind==="agent")??null;if(u){let w={...m,selectedPtyTabId:u.id};return await De(async()=>{let C=await B(n,m.id),O=C.ptyTabs.find(le=>le.kind==="agent")??null;O&&await A(n,{...C,selectedPtyTabId:O.id})}),w}let f=la(m,"agent",void 0,r),g={...m,ptyTabs:[...m.ptyTabs,f],selectedPtyTabId:f.id};return await De(async()=>{let w=await B(n,m.id),C=w.ptyTabs.find(O=>O.kind==="agent")??null;if(C){await A(n,{...w,selectedPtyTabId:C.id});return}await A(n,{...w,ptyTabs:[...w.ptyTabs,f],selectedPtyTabId:f.id})}),g}y=()=>{Ca();let m=Ae(T.width,T.height),u=a.mode==="main"?Xi(m,ki(P(a.shell),l),{centerOnly:a.shell.centerZoomed,focusFlashActive:Ie!==null&&Date.now()<Ie}):a.variant==="boot"?zi(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:Fr,updateText:an}):a.variant==="pause"?Yi(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:Fr,updateText:an}):a.variant==="options"?Ar(m,{menuIndex:a.menuIndex,optionsMenuItems:Mr}):a.variant==="runners"?Ar(m,{menuIndex:mt(a).menuIndex,optionsMenuItems:Lr(r,mt(a)),optionsMessage:ia(mt(a)),optionsSubtitle:"Runners"}):a.variant==="error-log"?Qi(m,{errorLogPath:a.errorLog?.path??n.errorLogFile,errorLogLines:a.errorLog?.lines??[]}):Ji(m);z&&(T.moveTo(1,1),T.eraseDisplayBelow(),z=!1),T.noFormat(xf(u)),T.hideCursor(!0)};function Ca(){let m=a.mode==="main"&&a.shell.inputMode==="terminal"?"terminal":"control";m!==ln&&(ln=m,T.grabInput(m==="terminal"?{mouse:"button"}:!0))}let xa=()=>{process.stdout.off("resize",Yr),process.off("SIGCONT",Jr),T.removeListener("key",Vr),T.removeListener("unknown",Gr),T.removeListener("mouse",Hr),be&&(clearTimeout(be),be=null),te&&(clearTimeout(te),te=null),Se&&(clearTimeout(Se),Se=null),fe&&(clearTimeout(fe),fe=null),ie&&(clearTimeout(ie),ie=null),Ue&&(clearInterval(Ue),Ue=null),N.disposeAll(),T.grabInput(!1),T.hideCursor(!1),T.fullscreen(!1)},un=m=>{xa(),I(m)},va=async()=>{if(a.mode!=="main"||G)return;let m=a.shell,u=m.taskPromptInput?.trim()??"";if(!m.selectedRepoId&&!m.selectedWorkspaceId){a={mode:"main",shell:P({...m,taskPromptError:"Select a workspace first."})},y();return}if(u.length===0){a={mode:"main",shell:P({...m,taskPromptError:"Task prompt cannot be empty."})},y();return}G=!0,a={mode:"main",shell:P({...m,actionMessage:`Creating ${m.selectedRunner} task in ${m.selectedWorkspaceId??m.selectedRepoId}...`})},y();let f=null;try{f=await Cf(n,m.selectedRepoId,m.selectedWorkspaceId,u,m.selectedRunner),await ae();let g=P({...a.shell,selectedRepoId:f.repoId,selectedWorkspaceId:f.workspaceId,selectedTaskId:f.id,selectedPtyTabId:f.selectedPtyTabId,selectedLeftItemId:`task:${f.id}`,activeTab:f.selectedPtyTabId??"agent",inputMode:"terminal",focusedRegion:"center",taskPromptInput:null,taskPromptError:null,actionMessage:null}),w=await N.ensureSession(f.id,g.selectedPtyTabId??fa(f,"agent"),gt(Ae(T.width,T.height)));W=Or(g.selectedPtyTabId),a={mode:"main",shell:_e(g,w)},k(a.shell)}catch(g){g instanceof nn&&(f=g.task);let w=q("create task",g,"Failed to create task.");f&&(await A(n,{...f,status:"draft",runnerSession:{...f.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:w}).catch(()=>{}),await ae().catch(()=>{})),a={mode:"main",shell:K(P({...a.shell,inputMode:"control",selectedTaskId:f?.id??a.shell.selectedTaskId,selectedPtyTabId:f?.selectedPtyTabId??a.shell.selectedPtyTabId,selectedLeftItemId:f?`task:${f.id}`:a.shell.selectedLeftItemId,activeTab:f?.selectedPtyTabId??a.shell.activeTab,taskPromptInput:f?null:"",taskPromptError:w,actionMessage:null}),w)}}finally{G=!1,y()}},Ea=m=>{if(a.mode!=="main")return;let u=a.shell;if(u.taskPromptInput!==null){if(m==="ESCAPE"){a={mode:"main",shell:P({...u,taskPromptInput:null,taskPromptError:null,actionMessage:null})},y();return}if(Pe(m)){va();return}if(m==="BACKSPACE"){a={mode:"main",shell:P({...u,taskPromptInput:u.taskPromptInput.slice(0,-1),taskPromptError:null})},y();return}if(m==="CTRL_R"){a={mode:"main",shell:P({...u,selectedRunner:pr(u.selectedRunner,s),taskPromptError:null})},y();return}ai(m)&&(a={mode:"main",shell:P({...u,taskPromptInput:`${u.taskPromptInput}${m}`,taskPromptError:null})},y())}},Aa=m=>{if(a.mode!=="main")return;let u=a.shell.workspaceBrowser;if(u){if(m==="ESCAPE"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,actionMessage:null})},y();return}if(m==="UP"||m==="k"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.max(0,u.selectedIndex-1),error:null}})},y();return}if(m==="DOWN"||m==="j"){let f=Math.max(0,u.entries.length-1);a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.min(f,u.selectedIndex+1),error:null}})},y();return}if(m==="LEFT"||m==="h"){dn(Qe.dirname(u.cwd)).catch(f=>{let g=q("open parent workspace directory",f,"Failed to open parent directory.");a={mode:"main",shell:K(P({...a.shell,workspaceBrowser:{...u,error:g}}),g)},y()});return}if(m==="RIGHT"||m==="l"||Pe(m)){let f=u.entries[u.selectedIndex]??null;if(!f)return;if((m==="RIGHT"||m==="l")&&(f.kind==="directory"||f.kind==="repo")){dn(f.path).catch(g=>{let w=q("open workspace directory",g,"Failed to open directory.");a={mode:"main",shell:K(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()});return}Z.addWorkspace(n,f.path).then(async g=>{await ae();let w=g.repos[0]??null;a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${g.workspace.id}`,selectedWorkspaceId:g.workspace.id,selectedRepoId:w?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${g.workspace.name??g.workspace.id}`})},k(a.shell),y()}).catch(g=>{let w=q("add workspace",g,"Failed to add workspace.");a={mode:"main",shell:K(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()})}}},Vr=m=>{let u=typeof m=="string"?m:"";if(a.mode==="main"&&a.shell.taskPromptInput!==null){Ea(u);return}if(a.mode==="main"&&a.shell.workspaceBrowser!==null){Aa(u);return}if(a.mode==="main"&&a.shell.inputMode==="control"){if(u==="F"){La(),y();return}Ie!==null&&(Ie=null,ie&&(clearTimeout(ie),ie=null))}if(a.mode==="main"){let f=oi(a.shell,u,Br(a.shell));if(f.exit){un(0);return}if(f.detachTerminal){N.detach(),a={mode:"main",shell:P(f.state)},k(a.shell),y();return}if(a.shell.inputMode==="terminal"){if(f.changed){a={mode:"main",shell:P(f.state)},k(a.shell),y();return}if(W&&Pe(u)){W=!1;return}W&&(W=!1),oe=Ef(u)?{key:u,at:Date.now()}:null;let g=Af(u,a.shell.terminal.scrolledBack??!1);if(g!==0){pn(g);return}N.writeKey(u);return}if(u==="CTRL_C"){un(0);return}if(u==="?"&&a.shell.inputMode==="control"){a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell},z=!0,y();return}if(f.pause){a={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:P(f.state)},z=!0,y();return}if(f.beginTaskPrompt){a={mode:"main",shell:P(f.state)},k(a.shell),y();return}if(f.openWorkspaceBrowser){dn(t).catch(g=>{let w=q("browse workspaces",g,"Failed to browse workspaces.");a={mode:"main",shell:K(P({...f.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:w}}),w)},y()});return}if(f.createPtyTab){Ta(f.state,f.createPtyTabKind,f.createPtyTabRunner).then(g=>{qr(g)}).catch(g=>{let w=q("create PTY tab",g,"Failed to create tab.");a={mode:"main",shell:K(P({...f.state,actionMessage:w}),w)},y()});return}if(f.closePtyTab){ya(f.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=q("close PTY tab",g,"Failed to close tab.");a={mode:"main",shell:K(P({...f.state,actionMessage:w}),w)},y()});return}if(f.refreshPullRequestChecks){Pa(f.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=q("refresh PR checks",g,"Failed to refresh PR checks.");a={mode:"main",shell:K(P({...f.state,actionMessage:w}),w)},y()});return}if(f.openPrUrl){let g=qe(f.state),w=g?V(g)?.url??null:null;w?jf(w).catch(C=>{let O=q("open PR URL",C,"Failed to open PR in browser.");a={mode:"main",shell:K(P(f.state),O)},y()}):(a={mode:"main",shell:K(P(f.state),"No PR URL available.")},y());return}if(f.closeTask){Sa(f.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=q("close task",g,"Failed to close task.");a={mode:"main",shell:K(P({...f.state,actionMessage:w}),w)},y()});return}if(f.removeWorkspace){Ia(f.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=q("remove workspace",g,"Failed to remove workspace.");a={mode:"main",shell:K(P({...f.state,actionMessage:w}),w)},y()});return}if(f.attachTerminal){qr(f.state);return}if(f.refreshInspection){a={mode:"main",shell:P(f.state)},k(a.shell),y(),Ur(a.shell).catch(g=>{let w=q("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:K(P({...a.shell,actionMessage:w}),w)},y()});return}f.changed&&(a={mode:"main",shell:P(f.state)},ka(a.shell).catch(()=>{}),k(a.shell),y());return}if(a.variant==="help"){a.viaOptions&&a.parentVariant?a={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:a.shell,parentVariant:a.parentVariant}:a.parentVariant?a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell}:a={mode:"main",shell:P(a.shell)},z=!0,y();return}if(a.variant==="options"){$a(u);return}if(a.variant==="runners"){Ma(u);return}if(a.variant==="error-log"){if(u==="ESCAPE"||Pe(u)){let f=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:a.shell,...f!==void 0?{parentVariant:f}:{}},z=!0,y()}return}if(a.optionsMessage){(u==="ESCAPE"||Pe(u))&&(a={...a,optionsMessage:null},y());return}if(u==="UP"||u==="k"){a={...a,menuIndex:Math.max(0,a.menuIndex-1)},y();return}if(u==="DOWN"||u==="j"){a={...a,menuIndex:Math.min(2,a.menuIndex+1)},y();return}if(u==="ESCAPE"){a.variant==="pause"&&(a={mode:"main",shell:P(a.shell)},z=!0,y());return}if(Pe(u)){if(a.menuIndex===0){let f=a.variant==="boot";a={mode:"main",shell:P({...a.shell,inputMode:"control"})},z=!0,y(),f?Fa.then(()=>{if(a.mode!=="main")return;let g=a.shell;ga(g).then(w=>{a.mode!=="main"||a.shell!==g||(a={mode:"main",shell:w},k(a.shell),y())}).catch(w=>{if(a.mode!=="main"||a.shell!==g)return;let C=q("warm selected PTY",w,"Failed to start selected PTY.");a={mode:"main",shell:K(P(a.shell),C)},k(a.shell),y()})}):ma();return}if(a.menuIndex===1){let f=a.variant==="boot"||a.variant==="pause"?a.variant:void 0;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...f!==void 0?{parentVariant:f}:{}},z=!0,y();return}un(0)}};function $a(m){if(a.mode!=="overlay"||a.variant!=="options")return;let u=aa(a.menuIndex,m);if(u.kind!=="noop"){if(u.kind==="render"){a={...a,menuIndex:u.menuIndex},y();return}if(u.kind==="back"){a.parentVariant&&(a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell},z=!0,y());return}if(u.kind==="help"){let f=a.parentVariant;a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell,viaOptions:!0,...f!==void 0?{parentVariant:f}:{}},z=!0,y();return}if(u.kind==="runners"){let f=a.parentVariant;a={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:a.shell,...f!==void 0?{parentVariant:f}:{}},z=!0,y();return}if(u.kind==="error-log"){let f=a.parentVariant;Da(f)}}}async function Da(m){let u;try{u=await xo(n)}catch(f){let g=q("open error log",f,"Failed to read Craig error log.");u={path:n.errorLogFile,lines:[`Unable to read error log: ${g}`],empty:!1}}a.mode==="overlay"&&(a={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:a.shell,errorLog:u,...m!==void 0?{parentVariant:m}:{}},z=!0,y())}function Ma(m){if(a.mode!=="overlay"||a.variant!=="runners")return;let u=ca(mt(a),r,m,s);if(u.kind!=="noop"){if(u.kind==="back"){let f=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...f!==void 0?{parentVariant:f}:{}},z=!0,y();return}if(u.kind==="render"){a={...a,runnerOptions:u.state},y();return}wa(u.config).then(()=>{a.mode!=="overlay"||a.variant!=="runners"||(a={...a,runnerOptions:u.state},y())}).catch(f=>{if(a.mode!=="overlay"||a.variant!=="runners")return;let g=q("save runner option",f,"Failed to save runner option."),w=K(P(a.shell),g);a={...a,shell:w,runnerOptions:{...mt(a),message:g}},y()})}}function La(){Ie=Date.now()+600,ie&&clearTimeout(ie),ie=setTimeout(()=>{Ie=null,ie=null,y()},600)}let Gr=m=>{let u=vf(m);if(a.mode!=="main"||a.shell.inputMode!=="terminal"||u.length===0)return;if(u.includes("")){N.detach(),W=!1,oe=null,a={mode:"main",shell:P({...a.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},k(a.shell),y();return}let f=$f(u);if(f!==0){pn(f);return}let g=Df(u);if(g){W=!1,oe={key:g,at:Date.now()},N.writeKey(g);return}if(W&&u!=="\r"&&u!==`
159
- `&&u!==`\r
160
- `&&(W=!1),Mf(W,oe,u)){W=!1;return}N.write(u)},Hr=m=>{if(a.mode!=="main")return;if(a.shell.inputMode==="control"){Oa(da(m));return}let u=da(m);u!==0&&pn(u)};function pn(m){x+=m,!be&&(be=setTimeout(()=>{be=null;let u=x;x=0,u!==0&&(ja(u),y())},16))}function ja(m){N.scrollViewport(m),a={mode:"main",shell:Xe(a.shell)}}function zr(){z=!0,T.fullscreen(!0)}function Oa(m){m!==0&&($e+=m,!te&&(te=setTimeout(()=>{te=null;let u=$e;if($e=0,u===0||a.mode!=="main"||a.shell.inputMode!=="control")return;let f=Ee(a.shell,u,Br(a.shell));if(f.changed){if(f.refreshInspection){a={mode:"main",shell:P(f.state)},k(a.shell),y(),Ur(a.shell).catch(g=>{let w=q("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:K(P({...a.shell,actionMessage:w}),w)},y()});return}a={mode:"main",shell:P(f.state)},k(a.shell),y()}},16)))}let Yr=()=>{zr(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(N.resize(gt(Ae(T.width,T.height))),a={mode:"main",shell:Xe(a.shell)}),y()},Jr=()=>{zr(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(N.resize(gt(Ae(T.width,T.height))),a={mode:"main",shell:Xe(a.shell)}),y()};process.stdout.on("resize",Yr),process.on("SIGCONT",Jr),T.grabInput(!0),ln="control",T.hideCursor(!0),T.fullscreen(!0),T.on("key",Vr),T.on("unknown",Gr),T.on("mouse",Hr),Ue=setInterval(()=>{ba()},(r.github?.watchIntervalSeconds??5)*1e3),b.version.checkForUpdate().then(m=>{m.updateAvailable&&m.latest&&(an=`Update available: v${m.latest}`,y())});let Fa=Wr().catch(()=>{});y()})}async function ft(e,t,n){let r=Re(e),[s,o,i]=await Promise.all([Z.repos.listRegisteredRepos(r).then(p=>p.repos),re(r),he(r)]),c=pa(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},d=c?await Ao(c,l):null;return{workspaceRoot:e,workspaces:o.filter(p=>p.status==="active"),repos:s,tasks:i.tasks,inspection:d,...n?{enabledRunnerIds:n}:{}}}function pa(e,t){return t?.selectedTaskId?e.find(n=>n.id===t.selectedTaskId)??null:null}function Rf(e,t){return Bt(e,t)}function Tf(e,t){let n=new Set(t);return e.filter(r=>{let s=r.path.split("/");for(let o=1;o<s.length;o+=1)if(n.has(s.slice(0,o).join("/")))return!1;return!0})}function yf(e){let t=[];if(e.workspaces?.length)for(let n of e.workspaces){t.push(`workspace:${n.id}`);for(let r of e.tasks.filter(s=>s.workspaceId===n.id))t.push(`task:${r.id}`);n.kind==="project"&&t.push(`new-task-workspace:${n.id}`),n.kind==="repo"&&t.push(`new-task:${n.primaryRepoId}`)}else for(let n of e.repos){t.push(`repo:${n.id}`);for(let r of e.tasks.filter(s=>s.repoId===n.id))t.push(`task:${r.id}`);t.push(`new-task:${n.id}`)}return t.push("new-workspace"),t}function Pf(e,t,n){let r=e.tasks.find(c=>c.ptyTabs.some(l=>l.id===t))??null,s=r?.ptyTabs.find(c=>c.id===t)??null,o=r?.worktreePath??n,i=s?.kind==="agent"?Sf(s):[];return r?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:bf(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function bf(e,t){let n=(e??"").split(Qe.delimiter).filter(r=>r.length>0);return n.includes(t)?n.join(Qe.delimiter):[...n,t].join(Qe.delimiter)}function Sf(e){return e.command.length>0?e.command:["codex"]}function mt(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function If(e,t,n){return e.ptyTabs.find(r=>r.id===t)?.kind??n}function la(e,t,n,r={}){let s=n??e.runner,o=b.runners.getProfile(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",c=t==="agent"&&n&&n!==e.runner?`${e.id}:${n}`:`${e.id}:${t}`,l=new Set(e.ptyTabs.map(k=>k.id)),d=1,p=c;for(;l.has(p);)d+=1,p=`${c}-${d}`;let h=new Date().toISOString(),R=n&&n!==e.runner?n:void 0;return{id:p,kind:t,...R?{runner:R}:{},title:d===1?i:`${i} ${d}`,command:t==="agent"?b.runners.buildCommand(s,void 0,r):[],createdAt:h,updatedAt:h}}async function Cf(e,t,n,r,s){let o=await b.load(e);b.runners.assertEnabled(s,o);let i=n?await vt(e,n,r,{runner:s,config:o}):await rt(e,t??"",r,{runner:s,config:o});try{let d=Le();await v(je(b.runners.getConfiguredProfile(s,o).executable,{cwd:i.repoRoot,env:d}),["--help"],{cwd:i.repoRoot,env:d})}catch(d){let p=d instanceof Error?d.message:"Failed to start runner.",h={...i.task,status:"draft",runnerSession:{...i.task.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:p};throw await A(e,h),new nn(p,h)}let c=fa(i.task,"agent"),l={...i.task,status:"running",selectedPtyTabId:c,runnerSession:{...i.task.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}};return await A(e,l),await H({uiStateFile:e.uiStateFile},{...await Y({uiStateFile:e.uiStateFile})??ge(),version:1,selectedRepoId:l.repoId,selectedWorkspaceId:l.workspaceId,selectedTaskId:l.id,selectedPtyTabId:l.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:l.selectedPtyTabId??"agent",selectedActionId:"commit",updatedAt:new Date().toISOString()}),l}var nn=class extends Error{task;constructor(t,n){super(t),this.name="InteractiveTaskStartupError",this.task=n}};function fa(e,t){let n=e.ptyTabs.find(r=>r.kind===t);if(!n)throw new Error(`Task ${e.id} is missing its ${t} PTY tab.`);return n.id}function gt(e){return{columns:Math.max(20,e.width-pe.leftWidth-pe.rightWidth-pe.dividerWidth-Xt*2),rows:Math.max(5,e.height-pe.topRailHeight-5)}}function xf(e){return e.split(`
161
- `).map((t,n)=>`\x1B[${n+1};1H${t}`).join("")}function vf(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function Ef(e){return e.length===1||Pe(e)||e==="BACKSPACE"||e==="TAB"}function Or(e){return typeof e=="string"&&new RegExp(`:(?:agent|${j.join("|")})(?:-\\d+)?$`).test(e)}function Af(e,t){return e==="UP"&&t?-3:e==="DOWN"&&t?3:e==="PAGE_UP"?-5:e==="PAGE_DOWN"?5:e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function da(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function $f(e){let t=new RegExp("\x1B\\[<(\\d+);\\d+;\\d+[mM]").exec(e);if(!t?.[1])return 0;let n=Number.parseInt(t[1],10);return n===64?-3:n===65?3:0}function Df(e){return e==="\x1B[13;2u"?"SHIFT_ENTER":null}function Mf(e,t,n){return n.length===0?!1:e&&(n==="\r"||n===`
162
- `||n===`\r
163
- `)?!0:!t||Date.now()-t.at>=30?!1:n===t.key?!0:n.length<=4&&n.split("").every(r=>r===t.key)}async function Lf(e){let t=await mf(e,{withFileTypes:!0}),n=[];for(let r of t){if(!r.isDirectory())continue;let s=Qe.join(e,r.name);n.push({name:r.name,path:s,kind:await Of(s)?"repo":"directory"})}return n.sort((r,s)=>r.kind!==s.kind?r.kind==="repo"?-1:1:r.name.localeCompare(s.name)),{cwd:e,entries:n,selectedIndex:0,error:null}}async function jf(e){let{spawn:t}=await import("node:child_process"),n=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";await new Promise((r,s)=>{let o=t(n,[e],{stdio:"ignore",detached:!0});o.unref(),o.on("error",s),o.on("spawn",r)})}async function Of(e){let t=Qe.join(e,".git");return await gf(t).catch(()=>null)!==null}function rn(){return process.cwd()}async function Ff(){try{if(process.argv[2]==="__craig-daemon"){let i=process.argv[3]??rn(),c=Re(i);return await Wi(c),0}if(process.argv[2]==="__craig-daemon-shutdown"){let i=process.argv[3]??rn(),c=Re(i);return await _i(c),0}let e=is(process.argv.slice(2)),t=rn(),n=Re(t),r={paths:n};if(e.mode==="interactive")return await ua({uiStateFile:n.uiStateFile,workspaceRoot:n.workspaceRoot});if(!e.command)throw new Error("Command mode requires a command.");let s=await Io(e.command,r),o=Co(s);return o.length>0&&process.stdout.write(`${o}
130
+ `}function Vd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var er={appendErrorLog:Ln,appendErrorLogBestEffort:Zo,readErrorLog:jn,readRecentErrorLines:ei};import{readFile as Gd,stat as Hd}from"node:fs/promises";import Mn from"node:path";var zd=200*1024,Yd=500*1024,tr="100000";async function ri(e,t,r){if(e.type==="project"&&e.repoTargets?.length)return Qd(e,t,r);try{let n=$e(r.selectedFilePath??null,t.filePaths),s=$e(r.selectedDiffPath??null,t.diffPaths),o=s?await xt(e.worktreePath):null,[i,l]=await Promise.all([nr(e.worktreePath,n),s?On(e.worktreePath,s,t.diffRows,o):Promise.resolve(X("No diff selected","No local changes found.","empty"))]),c=s?{[s]:l}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:c,selectedFile:i,selectedDiff:l,error:null}}catch(n){let s=n instanceof Error?n.message:"Unable to inspect task worktree.";return{...t,error:s}}}async function Qd(e,t,r){let n=$e(r.selectedFilePath??null,t.filePaths),s=$e(r.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([si(e,n),(async()=>{if(!s)return X("No diff selected","No local changes found.","empty");let c=rr(e,s),d=c?await xt(c.target.worktreePath).catch(()=>null):null;return oi(e,s,t.diffRows,d)})()]),l=s?{[s]:i}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:l,selectedFile:o,selectedDiff:i}}async function ni(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return Jd(e,t);try{await H(e);let r=await xt(e.worktreePath),[n,s]=await Promise.all([ii(e.worktreePath),ai(e.worktreePath,r)]),o=[...new Set(s.map(g=>g.path))],i=$e(t.selectedFilePath??null,n),l=$e(t.selectedDiffPath??null,o),[c,d]=await Promise.all([nr(e.worktreePath,i),l?On(e.worktreePath,l,s,r):Promise.resolve(X("No diff selected","No local changes found.","empty"))]),u=l?{[l]:d}:{};return{taskId:e.id,fileRows:di(n),filePaths:n,diffRows:s,diffPaths:o,diffContents:u,selectedFilePath:i,selectedDiffPath:l,selectedFile:c,selectedDiff:d,error:null}}catch(r){let n=r instanceof Error?r.message:"Unable to inspect task worktree.";return{taskId:e.id,fileRows:[],filePaths:[],diffRows:[],diffPaths:[],diffContents:{},selectedFilePath:null,selectedDiffPath:null,selectedFile:X("Files unavailable",n,"error"),selectedDiff:X("Diff unavailable",n,"error"),error:n}}}async function Jd(e,t){let r=(e.repoTargets??[]).filter(w=>w.status==="ready"),n=await Promise.all(r.map(async w=>{let R=await xt(w.worktreePath).catch(()=>null),[I,T]=await Promise.all([ii(w.worktreePath).catch(()=>[]),ai(w.worktreePath,R).catch(()=>[])]);return{target:w,baseRef:R,targetFiles:I,targetDiffRows:T}})),s=[],o=[];for(let{target:w,targetFiles:R,targetDiffRows:I}of n)s.push(...R.map(T=>`${w.repoId}/${T}`)),o.push(...I.map(T=>({...T,path:`${w.repoId}/${T.path}`})));let i=[...new Set(o.map(w=>w.path))].sort(),l=$e(t.selectedFilePath??null,s),c=$e(t.selectedDiffPath??null,i),[d,u]=await Promise.all([si(e,l),(async()=>{if(!c)return X("No diff selected","No local changes found.","empty");let w=rr(e,c),R=w?n.find(I=>I.target.repoId===w.target.repoId):null;return oi(e,c,o,R?.baseRef??null)})()]),g=c?{[c]:u}:{};return{taskId:e.id,fileRows:di(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:g,selectedFilePath:l,selectedDiffPath:c,selectedFile:d,selectedDiff:u,error:null}}async function si(e,t){let r=rr(e,t);if(!r)return X("No file selected","No Git-visible files found.","empty");let n=await nr(r.target.worktreePath,r.relativePath);return{...n,path:t,title:t??n.title}}async function oi(e,t,r,n=null){let s=rr(e,t);return s?{...await On(s.target.worktreePath,s.relativePath,r.filter(i=>i.path.startsWith(`${s.target.repoId}/`)).map(i=>({...i,path:i.path.slice(s.target.repoId.length+1)})),n),path:t,title:t}:X(t,"Repo target is unavailable.","error",t)}function rr(e,t){if(!t)return null;let[r,...n]=t.split("/"),s=n.join("/"),o=(e.repoTargets??[]).find(i=>i.repoId===r&&i.status==="ready")??null;return!o||s.length===0?null:{target:o,relativePath:s}}async function ii(e){let t=await v("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return ui(t.stdout)}async function ai(e,t){let[r,n,s,o]=await Promise.all([Xd(e,t),ti(e,"staged"),ti(e,"unstaged"),Zd(e)]);return[...r,...n,...s,...o]}async function Xd(e,t){if(!t)return[];let[r,n]=await Promise.all([v("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),v("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=li(r.stdout),o=ci(n.stdout);return s.map(i=>{let l=o.get(i.path)??{additions:null,deletions:null};return{group:"branch",path:i.path,status:i.status,additions:l.additions,deletions:l.deletions}}).sort((i,l)=>i.path.localeCompare(l.path))}async function ti(e,t){let r=t==="staged"?["diff","--cached"]:["diff"],[n,s]=await Promise.all([v("git",[...r,"--name-status"],{cwd:e}),v("git",[...r,"--numstat"],{cwd:e})]),o=li(n.stdout),i=ci(s.stdout);return o.map(l=>{let c=i.get(l.path)??{additions:null,deletions:null};return{group:t,path:l.path,status:l.status,additions:c.additions,deletions:c.deletions}}).sort((l,c)=>l.path.localeCompare(c.path))}async function Zd(e){let t=await v("git",["ls-files","--others","--exclude-standard"],{cwd:e}),r=ui(t.stdout);return await Promise.all(r.map(async s=>{let o=await nr(e,s),i=o.status==="ready"?eu(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function li(e){return e.split(`
131
+ `).map(t=>t.trim()).filter(t=>t.length>0).map(t=>{let[r="M",...n]=t.split(" ");return{status:r,path:n.at(-1)??""}}).filter(t=>t.path.length>0)}function ci(e){let t=new Map;for(let r of e.split(`
132
+ `)){let n=r.trim();if(!n)continue;let[s="-",o="-",...i]=n.split(" "),l=i.join(" ");l&&t.set(l,{additions:s==="-"?null:Number(s),deletions:o==="-"?null:Number(o)})}return t}async function xt(e){return(await M("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await M("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function nr(e,t){if(!t)return X("No file selected","No Git-visible files found.","empty");let r=tu(e,t);try{let n=await Hd(r);if(n.size>zd)return X(t,`File is ${n.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,n.size);let s=await Gd(r);return ru(s)?X(t,"Binary file preview is not available in Craig.","binary",t,s.byteLength):{path:t,status:"ready",title:t,lines:s.toString("utf8").split(`
133
+ `),byteLength:s.byteLength}}catch(n){let s=n instanceof Error?n.message:"Unable to read file.";return X(t,s,"missing",t,null)}}async function On(e,t,r,n=null){if(!t)return X("No diff selected","No local changes found.","empty");let s=[],o=r.filter(l=>l.path===t).map(l=>l.group);if(o.includes("branch")){let l=n??await xt(e);if(l){let c=await v("git",["diff","--stat","--patch",`--unified=${tr}`,`${l}...HEAD`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`branch
134
+ ${c.stdout.trimEnd()}`)}}if(o.includes("staged")){let l=await v("git",["diff","--cached","--stat","--patch",`--unified=${tr}`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`staged
135
+ ${l.stdout.trimEnd()}`)}if(o.includes("unstaged")){let l=await v("git",["diff","--stat","--patch",`--unified=${tr}`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`unstaged
136
+ ${l.stdout.trimEnd()}`)}if(o.includes("untracked")){let l=await M("git",["diff","--no-index","--stat","--patch",`--unified=${tr}`,"--","/dev/null",t],{cwd:e});l.stdout.trim().length>0&&s.push(`untracked
137
+ ${l.stdout.trimEnd()}`)}let i=s.join(`
138
+
139
+ `);return i.length>Yd?X(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?X(t,"Binary diff preview is not available in Craig.","binary",t,i.length):{path:t,status:i.length>0?"ready":"empty",title:t,lines:i.length>0?i.split(`
140
+ `):["No diff for this file."],byteLength:i.length}}function di(e){let t=[],r=new Set;for(let n of e){let s=n.split("/");for(let o=0;o<s.length-1;o+=1){let i=s.slice(0,o+1).join("/");r.has(i)||(r.add(i),t.push({kind:"directory",path:i,depth:o,label:s[o]??i}))}t.push({kind:"file",path:n,depth:s.length-1,label:s.at(-1)??n})}return t}function $e(e,t){return e&&t.includes(e)?e:t[0]??null}function eu(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function ui(e){return[...new Set(e.split(`
141
+ `).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,r)=>t.localeCompare(r))}function tu(e,t){let r=Mn.resolve(e,t),n=Mn.resolve(e);if(r!==n&&!r.startsWith(`${n}${Mn.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return r}function ru(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function X(e,t,r,n=null,s=null){return{path:n,status:r,title:e,lines:[t],byteLength:s}}import At from"node:path";function pi(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"\u{F06E6} ";case"js":case"jsx":case"mjs":case"cjs":return"\u{F031E} ";case"json":case"jsonc":return"\u{F0871} ";case"md":case"mdx":return"\u{F0354} ";case"yaml":case"yml":return"\u{F0B10} ";case"sh":case"bash":case"zsh":return"\u{F018D} ";case"css":case"scss":case"sass":return"\u{F031C} ";case"html":case"htm":return"\u{F031D} ";case"py":return"\u{F0320} ";case"go":return"\u{F07D3} ";case"rs":return"\u{F1617} ";case"lock":return"\u{F033E} ";case"png":case"jpg":case"jpeg":case"gif":case"svg":case"webp":return"\u{F02E9} ";default:return"\u{F0214} "}}var fi="\u{F024B} ",mi="\u{F0DCF} ",gi="\u25CB",Nn="\uEA64",hi="\uEAFE",ki="\uEBDA",Fn="\u25CB",Wn="\u25CF",_n="\u2713",Bn="\u2715";function wi(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"4fc1ff";case"js":case"jsx":case"mjs":case"cjs":return"f7df1e";case"json":case"jsonc":return"fbc02d";case"md":case"mdx":return"519aba";case"yaml":case"yml":return"e06c75";case"sh":case"bash":case"zsh":return"89e051";case"css":case"scss":case"sass":return"c792ea";case"html":case"htm":return"e06c75";case"py":return"3572a5";case"go":return"00add8";case"rs":return"dea584";case"lock":return"565f89";default:return}}var nu=["tasks","center","inspector","actions"],Si=["agent","terminal"],Ii=[],L="inspection",DT=[...Si,...Ii],Ci=["commit","push","refresh-checks","close-task"],su=["refresh-checks","close-task"],xi=["task","checks","pr","setup-run","actions","next-action"],vi=["diff","files","review"];function Ei(e,t={}){let r=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,n=Tu(e?.openInspectionKind)??r,s=S.runners.getEnabled(t);return{inputMode:Pu(e?.inputMode),focusedRegion:wu(e?.focusedRegion),selectedRepoId:be(e?.selectedRepoId),selectedWorkspaceId:be(e?.selectedWorkspaceId),selectedTaskId:be(e?.selectedTaskId),selectedPtyTabId:be(e?.selectedPtyTabId),selectedLeftItemId:Du(be(e?.selectedTaskId)),activeTab:r?L:be(e?.activeTab)??"agent",preferredPtyTabKind:yu(e?.preferredPtyTabKind),inspectorSection:vt(e?.inspectorSection,xi,"task"),inspectionMode:Ru(e?.inspectionMode,r==="diff"?"diff":"files"),openInspectionKind:n,selectedFileTreePath:be(e?.selectedFileTreePath),selectedFilePath:be(e?.selectedFilePath),selectedDiffPath:be(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:vt(e?.selectedActionId,Ci,"commit"),selectedProjectTargetId:null,selectedRunner:bu(e?.selectedRunner,s,S.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,workspaceBrowser:null,terminal:ou(),centerZoomed:!1}}function ou(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function Ai(e,t){return{...e??we(),selectedRepoId:t.selectedRepoId,selectedWorkspaceId:t.selectedWorkspaceId,selectedTaskId:t.selectedTaskId,selectedPtyTabId:t.selectedPtyTabId,inputMode:t.inputMode,focusedRegion:t.focusedRegion,activeTab:t.activeTab,preferredPtyTabKind:t.preferredPtyTabKind,inspectorSection:t.inspectorSection,inspectionMode:t.inspectionMode,openInspectionKind:t.openInspectionKind,selectedFileTreePath:t.selectedFileTreePath,selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath,collapsedFileTreePaths:t.collapsedFileTreePaths,selectedActionId:t.selectedActionId,selectedRunner:t.selectedRunner}}function ar(e,t,r={}){let n=Eu(e,t),s=Fi(n),o=(s?.kind==="workspace"?t.workspaces?.find(u=>u.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(u=>u.id===t.tasks.find(g=>g.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(u=>u.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,l=((s?.kind==="repo"?t.repos.find(u=>u.id===s.id)??null:s?.kind==="task"?t.repos.find(u=>u.id===t.tasks.find(g=>g.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(u=>u.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(u.id))??null:null)??(o?.kind!=="project"?t.repos.find(u=>u.id===o?.primaryRepoId)??null:null)??t.repos.find(u=>u.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,c=o?t.tasks.filter(u=>u.workspaceId===o.id):l?t.tasks.filter(u=>u.repoId===l):[],d=(s?.kind==="task"?c.find(u=>u.id===s.id)??null:null)??c.find(u=>u.id===e.selectedTaskId)??c[0]??null;return{...e,inputMode:r.resetInputMode?"control":e.inputMode,selectedLeftItemId:n,selectedWorkspaceId:o?.id??null,selectedRepoId:l,selectedTaskId:d?.id??null,...Iu(d,e.activeTab,e.selectedPtyTabId),selectedFilePath:gu(e,t,d?.id??null),...Cu(e,t,d?.id??null),selectedDiffPath:mu(e,t,d?.id??null),inspectorSection:vt(e.inspectorSection,xi,"task")}}function Di(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return iu(t)?b({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):b({state:e});if(t==="q"||t==="Q")return b({state:e,exit:!0});if(t==="ESCAPE")return b({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return b({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(qn(e.selectedLeftItemId)||Kn(e.selectedLeftItemId)))return b({state:{...e,selectedRunner:Vn(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return Ri(e,1);if(t==="SHIFT_TAB"||t==="[")return Ri(e,-1);if(t==="z"||t==="Z")return b({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===L?Le(e,-1,r):Ti(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===L?Le(e,1,r):Ti(e,1,r);if(t==="PAGE_UP")return Le(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return Le(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return Le(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return Le(e,3,r);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let n=r.enabledRunnerIds??N,s=e.centerTabRunner?n.indexOf(e.centerTabRunner):-1,o=s===n.length-1?null:n[s+1];return b({state:{...e,centerTabRunner:o,actionMessage:null},changed:!0})}if((t==="+"||t==="a"||t==="A"||t==="t"||t==="T")&&e.focusedRegion==="center"&&e.selectedTaskId){let n=Su(e,t);return b({state:{...e,preferredPtyTabKind:n,actionMessage:null},changed:!0,createPtyTab:!0,createPtyTabKind:n,createPtyTabRunner:n==="agent"?e.centerTabRunner:null})}if(t==="R"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return b({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return b({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return b({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&ir(e.selectedLeftItemId)&&e.selectedTaskId)return b({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&$u(e.selectedLeftItemId)&&e.selectedWorkspaceId)return b({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&bi(e.activeTab,r.ptyTabIds??[]))return b({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return Un(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return yi(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return Un(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return yi(e,1)}if(Ie(t)){if(e.focusedRegion==="tasks"&&(qn(e.selectedLeftItemId)||Kn(e.selectedLeftItemId))){let n=Wi(e.selectedLeftItemId),s=_i(e.selectedLeftItemId);return b({state:{...e,selectedRepoId:n??e.selectedRepoId,selectedWorkspaceId:s??e.selectedWorkspaceId,actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0})}if(e.focusedRegion==="tasks"&&e.selectedLeftItemId==="new-workspace")return b({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&ir(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return b({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:Et(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&bi(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return b({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:Et(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===L)return b({state:{...e,actionMessage:null},changed:!0,refreshInspection:!0});if(e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="files"){let n=e.selectedFileTreePath??e.selectedFilePath;if(n&&(r.fileTreeDirectoryIds??[]).includes(n))return b({state:uu({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return b({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:L,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}return e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="diff"?b({state:{...e,activeTab:L,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.focusedRegion==="inspector"&&e.inspectionMode==="review"?e.selectedActionId==="close-task"&&!r.projectTargetIds?.length?b({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):b({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.focusedRegion!=="actions"?b({state:e}):e.selectedActionId==="refresh-checks"?b({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?b({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):b({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return b({state:e})}function Ge(e,t){return{...e,terminal:t}}function $i(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function iu(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function Ie(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
142
+ `}function Li(e){return e.length===1&&e>=" "&&e!=="\x7F"}function ji(e){return Mi(e)||Et(e)!==null}function au(e){return Ii.includes(e)}function Mi(e){return Si.includes(e)}function Oi(e,t){return[...e?.ptyTabs.map(r=>r.id)??[],...t?.openInspectionKind?[L]:[]]}var lu=["tasks","center","inspector"];function Ri(e,t){return sr(e,"focusedRegion",lu,t)}function Un(e,t,r){let n=sr(e,"activeTab",r&&r.length>0?r:vu(e),t);return!n.changed||au(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:Et(n.state.activeTab)??n.state.preferredPtyTabKind}}}function Ti(e,t,r){if(e.focusedRegion==="tasks")return cu(e,t,r.leftItemIds);if(e.focusedRegion==="center")return Un(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Ni(e,t,r);if(e.inspectionMode==="diff"){let n=or(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:L,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:n}if(r.projectTargetIds?.length){let n=or(e,"selectedProjectTargetId",r.projectTargetIds,t);return n.changed?{...n,state:{...n.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:n}return sr(e,"selectedActionId",su,t)}return sr(e,"selectedActionId",Ci,t)}function cu(e,t,r){let n=or(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=Fi(n.state.selectedLeftItemId);if(s?.kind==="workspace")return{...n,state:{...n.state,selectedWorkspaceId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="task")return{...n,state:{...n.state,selectedTaskId:s.id,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="repo")return{...n,state:{...n.state,selectedRepoId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};let o=Wi(n.state.selectedLeftItemId);if(o)return{...n,state:{...n.state,selectedRepoId:o}};let i=_i(n.state.selectedLeftItemId);return i?{...n,state:{...n.state,selectedWorkspaceId:i}}:n}function Le(e,t,r){if(t===0)return b({state:e});if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Ni(e,t,r);if(e.inspectionMode==="diff"){let n=or(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,diffScrollOffset:0}}:n}return e.inspectionMode==="review"?Pi(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):b({state:e})}if(e.focusedRegion==="center"&&e.activeTab===L){if(e.openInspectionKind==="file")return Pi(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return pu(e,t,r)}return b({state:e})}function du(e,t){if(e.inspectionMode===t)return b({state:e});let r=t==="diff"?"diff":t==="files"?"file":e.openInspectionKind,n=t==="diff"||t==="files"?L:e.activeTab;return b({state:{...e,inspectionMode:t,activeTab:n,openInspectionKind:r,fileScrollOffset:t==="files"?0:e.fileScrollOffset,diffScrollOffset:t==="diff"?0:e.diffScrollOffset,reviewScrollOffset:t==="review"?0:e.reviewScrollOffset,actionMessage:null},changed:!0,refreshInspection:!0})}function yi(e,t){return du(e,ku(e.inspectionMode,vi,t))}function Ni(e,t,r){let n=r.fileTreeRowIds&&r.fileTreeRowIds.length>0?r.fileTreeRowIds:r.filePathIds??[];if(n.length===0)return b({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??n[0]??null,o=n.indexOf(s??""),i=Se(o===-1?0:o+t,0,n.length-1),l=n[i]??null;if(l===e.selectedFileTreePath)return b({state:e});let c=l!==null&&(r.fileTreeFileIds??r.filePathIds??[]).includes(l);return b({state:{...e,selectedFileTreePath:l,selectedFilePath:c?l:e.selectedFilePath,activeTab:c?L:e.activeTab,openInspectionKind:c?"file":e.openInspectionKind,fileScrollOffset:c?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:c})}function uu(e){if(!e.selectedFileTreePath)return e;let t=new Set(e.collapsedFileTreePaths);return t.has(e.selectedFileTreePath)?t.delete(e.selectedFileTreePath):t.add(e.selectedFileTreePath),{...e,collapsedFileTreePaths:[...t].sort((r,n)=>r.localeCompare(n)),actionMessage:null}}function Pi(e,t,r,n,s=10){let o=Math.max(0,n-Math.max(1,s)),i=Se(e[t]+r,0,o);return i===e[t]?b({state:e}):b({state:{...e,[t]:i,actionMessage:null},changed:!0})}function pu(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return fu(e,t,r);let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=e.diffScrollOffset+t,l=r.diffPathIds??[];if(l.length===0||!e.selectedDiffPath){let u=Se(i,0,o);return u===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:u,actionMessage:null},changed:!0})}let c=l.indexOf(e.selectedDiffPath);if(c===-1){let u=Se(i,0,o);return u===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:u,actionMessage:null},changed:!0})}if(t>0&&i>o){let u=l[c+1]??null;return u?b({state:{...e,selectedDiffPath:u,activeTab:L,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?b({state:e}):b({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let u=l[c-1]??null;return u?b({state:{...e,selectedDiffPath:u,activeTab:L,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?b({state:e}):b({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let d=Se(i,0,o);return d===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}function fu(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=Se(e.diffScrollOffset+t,0,o),l=hu(r.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&l===e.selectedDiffPath?b({state:e}):b({state:{...e,diffScrollOffset:i,selectedDiffPath:l,actionMessage:null},changed:!0})}function mu(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function gu(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function hu(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function sr(e,t,r,n){let s=r.indexOf(e[t]),o=Se(s+n,0,r.length-1),i=r[o];return!i||i===e[t]?b({state:e}):b({state:{...e,[t]:i,actionMessage:null},changed:!0})}function or(e,t,r,n,s=!1){if(r.length===0)return b({state:e});let o=r.indexOf(e[t]??r[0]??""),i=Se(o===-1?0:o+n,0,r.length-1),l=r[i]??null;return l===e[t]?b({state:e}):b({state:{...e,[t]:l,actionMessage:null},changed:!0,refreshInspection:s})}function ku(e,t,r){let n=t.indexOf(e);return t[Se(n+r,0,t.length-1)]??e}function b(e){return{state:e.state,changed:e.changed??!1,exit:e.exit??!1,pause:e.pause??!1,attachTerminal:e.attachTerminal??!1,detachTerminal:e.detachTerminal??!1,beginTaskPrompt:e.beginTaskPrompt??!1,openWorkspaceBrowser:e.openWorkspaceBrowser??!1,createWorkspaceTask:e.createWorkspaceTask??!1,createPtyTab:e.createPtyTab??!1,createPtyTabKind:e.createPtyTabKind??null,createPtyTabRunner:e.createPtyTabRunner??null,closePtyTab:e.closePtyTab??!1,refreshPullRequestChecks:e.refreshPullRequestChecks??!1,closeTask:e.closeTask??!1,removeWorkspace:e.removeWorkspace??!1,refreshInspection:e.refreshInspection??!1,openPrUrl:e.openPrUrl??!1}}function vt(e,t,r){return t.includes(e??"")?e:r}function wu(e){return e==="tabs"?"center":vt(e,nu,"tasks")}function Ru(e,t){return e==="checks"||e==="actions"||e==="review"?"review":vt(e,vi,t)}function Tu(e){return e==="file"||e==="diff"?e:null}function yu(e){return e==="terminal"?"terminal":"agent"}function Pu(e){return e==="terminal"?"terminal":"control"}function bu(e,t=[...N],r="codex"){return e&&S.runners.isRunnerType(e)&&t.includes(e)?e:r}function Vn(e,t=N){let r=t.length>0?t:N,n=r.indexOf(e);return r[(n+1)%r.length]??r[0]??"codex"}function Et(e){let t=N.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function Su(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":Et(e.activeTab)??e.preferredPtyTabKind}function Iu(e,t,r){if(!e)return{activeTab:t===L?t:"agent",selectedPtyTabId:null};let n=e.ptyTabs.find(l=>l.id===r)??null,s=e.selectedPtyTabId?e.ptyTabs.find(l=>l.id===e.selectedPtyTabId)??null:null,o=e.ptyTabs.find(l=>l.id===t)??null;if(o)return{activeTab:o.id,selectedPtyTabId:o.id};if(Mi(t)){let c=e.ptyTabs.find(d=>d.kind===t)??null??s??n??e.ptyTabs[0]??null;return{activeTab:c?.id??L,selectedPtyTabId:c?.id??null}}if(t===L)return{activeTab:L,selectedPtyTabId:n?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??n??e.ptyTabs[0]??null;return{activeTab:i?.id??L,selectedPtyTabId:i?.id??null}}function Cu(e,t,r){if(!t.inspection||t.inspection.taskId!==r)return{selectedFileTreePath:e.selectedFileTreePath,collapsedFileTreePaths:e.collapsedFileTreePaths};let n=e.selectedFileTreePath??t.inspection.selectedFilePath,s=e.selectedFileTreePath===null&&e.collapsedFileTreePaths.length===0?xu(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:n,collapsedFileTreePaths:s}}function xu(e,t){let r=new Set;if(t){let n=t.split("/");for(let s=1;s<n.length;s+=1)r.add(n.slice(0,s).join("/"))}return e.filter(n=>n.kind==="directory"&&!n.path.includes("/")&&!r.has(n.path)).map(n=>n.path).sort((n,s)=>n.localeCompare(s))}function vu(e){return[e.selectedPtyTabId,e.openInspectionKind?L:null].filter(t=>typeof t=="string")}function bi(e,t){return t.includes(e)}function Eu(e,t){let r=Au(t);return e.selectedLeftItemId&&r.includes(e.selectedLeftItemId)?e.selectedLeftItemId:e.selectedWorkspaceId&&r.includes(`workspace:${e.selectedWorkspaceId}`)?`workspace:${e.selectedWorkspaceId}`:e.selectedTaskId&&r.includes(`task:${e.selectedTaskId}`)?`task:${e.selectedTaskId}`:e.selectedRepoId&&r.includes(`repo:${e.selectedRepoId}`)?`repo:${e.selectedRepoId}`:r[0]??null}function Au(e){let t=[];if(e.workspaces?.length)for(let r of e.workspaces){t.push(`workspace:${r.id}`);for(let n of e.tasks.filter(s=>s.workspaceId===r.id))t.push(`task:${n.id}`);r.kind==="project"&&t.push(`new-task-workspace:${r.id}`),r.kind==="repo"&&t.push(`new-task:${r.primaryRepoId}`)}else for(let r of e.repos){t.push(`repo:${r.id}`);for(let n of e.tasks.filter(s=>s.repoId===r.id))t.push(`task:${n.id}`);t.push(`new-task:${r.id}`)}return t.push("new-workspace"),t}function Fi(e){return e?e.startsWith("workspace:")?{kind:"workspace",id:e.slice(10)}:e.startsWith("repo:")?{kind:"repo",id:e.slice(5)}:e.startsWith("task:")?{kind:"task",id:e.slice(5)}:null:null}function be(e){return typeof e=="string"?e:null}function Du(e){return e?`task:${e}`:null}function ir(e){return typeof e=="string"&&e.startsWith("task:")}function qn(e){return typeof e=="string"&&e.startsWith("new-task:")}function Kn(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function $u(e){return typeof e=="string"&&e.startsWith("workspace:")}function Wi(e){return qn(e)?e.slice(9):null}function _i(e){return Kn(e)?e.slice(19):null}function Se(e,t,r){return Math.min(r,Math.max(t,e))}var cr="empty",q={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function Ki(e,t){let r=Mu(t,e),n=t.repos.find(T=>T.id===e.selectedRepoId)??t.repos[0]??null,s=r?t.tasks.filter(T=>T.workspaceId===r.id):t.tasks,o=r?.kind==="project"?s:n?s.filter(T=>T.repoId===n.id):[],i=o.find(T=>T.id===e.selectedTaskId)??o[0]??null,l=i?.type==="project",c=kp(t.tasks),d=Fu(e,i),u=Nu(e,i,d),g=u.find(T=>T.id===d)??u[0]??{id:"agent",label:"CODEX"},w=t.inspection?.taskId===i?.id?t.inspection:null,R=n?.name??"no repo",I=i?S.runners.getDisplayName(i.runner):S.runners.getDisplayName(e.selectedRunner);return{inputMode:e.inputMode,modalInput:e.taskPromptInput!==null||e.workspaceBrowser!==null,focusedRegion:e.focusedRegion,actionMessage:e.actionMessage,footerToast:e.footerToast,terminal:e.terminal,footerText:e.workspaceBrowser!==null?`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} \u2191\u2193 move \u2192 open \u2190 up Enter add repo Esc cancel`:e.taskPromptInput!==null?`NEW TASK ${n?`[${n.name}]`:"[no repo]"} \xB7 ${S.runners.getDisplayName(e.selectedRunner)} Ctrl+R switch runner Enter create Esc cancel \u203A ${e.taskPromptInput}${e.taskPromptError?` \u2717 ${e.taskPromptError}`:""}`:e.inputMode==="terminal"?"TERMINAL \u2191\u2193/PgUp/PgDn scroll Ctrl+] return to control":e.focusedRegion==="tasks"?e.selectedLeftItemId?.startsWith("new-task:")||e.selectedLeftItemId?.startsWith("new-task-workspace:")?`r runner [${S.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:ir(e.selectedLeftItemId)?"n new task Enter attach X close task Esc pause ? help":e.selectedLeftItemId?.startsWith("workspace:")?"n new task Enter select X remove workspace Esc pause ? help":"n new task Enter select Esc pause ? help":e.focusedRegion==="center"?i===null?"n new task Tab tasks Esc pause ? help":d===L?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${S.runners.getDisplayName(e.centerTabRunner??i?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?l?"\u2191\u2193 targets Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":"Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":e.inspectionMode==="files"?"\u2191\u2193 navigate Enter open file \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 navigate \u2190/\u2192 mode Esc pause ? help",topRail:{workspacePath:At.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${At.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:I},leftTree:Lu(e,t),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(T=>wp(T,c[T])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":g.label,taskId:e.workspaceBrowser?"new workspace":i?.id??"no task",repo:R,agent:I},centerTranscript:Ou(d,e,n,i,e.workspaceBrowser,w,r),tabs:u,rightContext:hp(n,i),rightInspection:Ju(e,i,w)}}function Lu(e,t){let r=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return ju(r,e,t.repos,t.tasks);let n=t.workspaces;if(n.length===0)r.push({text:"No workspaces registered.",indent:2,muted:!0});else for(let o of n){let i=e.selectedLeftItemId===`workspace:${o.id}`;r.push({id:`workspace:${o.id}`,text:`${o.kind==="project"?"\u2261":"\u2013"} ${o.name??o.id}`,selected:i,focused:i&&e.focusedRegion==="tasks"});let l=o.kind==="project"?o.discoveredRepoIds??[]:[o.primaryRepoId],c=t.tasks.filter(d=>d.workspaceId===o.id);if(c.length===0)r.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of c){let u=e.selectedLeftItemId===`task:${d.id}`,g=u?"\u25B8":"\u2022",w=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,R={id:`task:${d.id}`,taskId:d.id,text:`${g} ${w}`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks"},I=Gi(d);I&&(R.prBadge=I),r.push(R)}if(o.kind==="project"){let d=`new-task-workspace:${o.id}`,u=e.selectedLeftItemId===d;r.push({id:d,text:`+ New Project Task [${S.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}if(o.kind==="repo"){let d=`new-task:${o.primaryRepoId}`,u=e.selectedLeftItemId===d;r.push({id:d,text:`+ New Task [${S.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}else{r.push({text:` Repos (${l.length})`,indent:0,muted:!0});for(let d of l.slice(0,6)){let u=t.repos.find(g=>g.id===d);r.push({text:` \xB7 ${u?.name??d}`,indent:0,muted:!0})}l.length>6&&r.push({text:` \xB7 ${l.length-6} more`,indent:0,muted:!0})}}let s=e.selectedLeftItemId==="new-workspace";return r.push({text:"",muted:!0}),r.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&e.focusedRegion==="tasks"}),r}function ju(e,t,r,n){if(r.length===0)e.push({text:"No repos registered.",indent:2,muted:!0});else for(let o of r){let i=t.selectedLeftItemId===`repo:${o.id}`;e.push({id:`repo:${o.id}`,text:`\u2013 ${o.name}`,selected:i,focused:i&&t.focusedRegion==="tasks"});let l=n.filter(u=>u.repoId===o.id);if(l.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let u of l){let g=t.selectedLeftItemId===`task:${u.id}`,w=g?"\u25B8":"\u2022",R=u.title.length>28?`${u.title.slice(0,25)}\u2026`:u.title,I={id:`task:${u.id}`,taskId:u.id,text:`${w} ${R}`,indent:2,selected:g,focused:g&&t.focusedRegion==="tasks"},T=Gi(u);T&&(I.prBadge=T),e.push(I)}let c=`new-task:${o.id}`,d=t.selectedLeftItemId===c;e.push({id:c,text:`+ New Task [${S.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:d,focused:d&&t.focusedRegion==="tasks",muted:!d})}let s=t.selectedLeftItemId==="new-workspace";return e.push({text:"",muted:!0}),e.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&t.focusedRegion==="tasks"}),e}function Mu(e,t){let r=e.workspaces??[];if(!e.workspaces)return null;let n=e.tasks.find(s=>s.id===t.selectedTaskId)??null;return n?r.find(s=>s.id===n.workspaceId)??null:t.selectedWorkspaceId?r.find(s=>s.id===t.selectedWorkspaceId)??null:r[0]??null}function Ou(e,t,r,n,s,o=null,i=null){if(s){let c=s.entries.length===0?["No directories or git repos here."]:s.entries.map((d,u)=>{let g=u===s.selectedIndex?"\u25B8":" ",w=d.kind==="repo"?" [git repo]":"/";return`${g} ${d.name}${w}`});return me(["Browse for a workspace to register.",s.cwd,"",...c,"",s.error??"Use \u2191\u2193 to move, \u2192 or Enter to open, \u2190 to go up, Enter on a git repo to add it."])}if(!r)return me(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!n){let c=i?.kind==="project",d=c?i.name??"this workspace":r.name,u=c?"Project Task":"Task";return me([`No tasks in ${d}.`,"",`Press n or choose + New ${u} to create one with ${S.runners.getDisplayName(t.selectedRunner)}.`])}let l=n.ptyTabs.find(c=>c.id===e)??null;return l?l.kind==="agent"?me([`${l.title} tab ready for ${n.id}.`,"","Press Enter to attach this PTY-backed agent session.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):me([`${l.title} tab ready for ${n.id}.`,"","Press Enter to attach this plain task shell.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):e===L&&t.openInspectionKind==="file"?Bu(n,o,t.fileScrollOffset):e===L&&t.openInspectionKind==="diff"?Uu(n,o,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?me(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):me(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function Nu(e,t,r){let n=t?.ptyTabs.map(o=>({id:o.id,label:Wu(o)}))??[];if(!t)return[{id:cr,label:"EMPTY",active:r===cr,focused:e.focusedRegion==="center"&&r===cr}];let s=e.openInspectionKind||r===L?[{id:L,label:_u(e)}]:[];return[...n,...s].map(o=>({...o,active:o.id===r,focused:e.focusedRegion==="center"&&o.id===r}))}function Fu(e,t){return t?t.ptyTabs.some(r=>r.id===e.activeTab)||e.activeTab===L&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(r=>r.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??L:e.selectedPtyTabId&&t.ptyTabs.some(r=>r.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??L:cr}function Wu(e){return e.title.toUpperCase()}function _u(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?At.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function Bu(e,t,r){if(!e)return me(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return me(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=Vi(n.path??n.title);return[{text:n.title},{text:`${n.byteLength===null?"size unknown":`${n.byteLength} bytes`} \xB7 ${n.lines.length} lines \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...qu(n.lines,r,s)]}function Uu(e,t,r){if(!e)return me(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return me(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=Vi(n.path??n.title);return[{text:n.title},{text:`${t.diffPaths.length} changed files \xB7 ${n.lines.length} rows \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...Ku(n.lines,r,s)]}function me(e){return e.map(t=>({text:t}))}function qu(e,t,r){let n=Math.max(3,String(e.length).length),s=Math.max(0,Math.min(t,Math.max(0,e.length-1)));return e.slice(s).map((o,i)=>{let l=s+i+1;return{text:`${`${String(l).padStart(n," ")} \u2502 `}${o}`,segments:[{text:String(l).padStart(n," "),style:{fg:q.lineNumber}},{text:" \u2502 ",style:{fg:q.gutter}},...Gn(o,r)],tone:"default"}})}function Ku(e,t,r){let n=Vu(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(o=>Gu(o,r))}function Vu(e){let t=[],r=0,n=0;for(let s of e){let o=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);if(o){r=Number.parseInt(o[1]??"0",10),n=Number.parseInt(o[2]??"0",10);continue}if(!(s.startsWith("diff --git")||s.startsWith("index ")||s.startsWith("+++ ")||s.startsWith("--- "))&&!(s==="staged"||s==="unstaged"||s==="untracked")){if(s.startsWith("-")&&!s.startsWith("---")){t.push({oldNumber:r,newNumber:null,marker:"-",text:s.slice(1),kind:"delete"}),r+=1;continue}if(s.startsWith("+")&&!s.startsWith("+++")){t.push({oldNumber:null,newNumber:n,marker:"+",text:s.slice(1),kind:"add"}),n+=1;continue}if(s.startsWith(" ")){if(r===0&&n===0)continue;t.push({oldNumber:r,newNumber:n,marker:" ",text:s.slice(1),kind:"context"}),r+=1,n+=1;continue}}}return t}function Gu(e,t){let r=Bi(e.oldNumber),n=Bi(e.newNumber),s=e.kind==="delete"?r:n,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:q.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:q.diffAdd}:null,i=`${s} \u2502 ${e.text}`,l=o?zu(Gn(e.text,t),o.bg,o.fallbackFg):Gn(e.text,t),c=o?{fg:q.lineNumber,bg:o.bg}:{fg:q.lineNumber},d=o?{fg:q.gutter,bg:o.bg}:{fg:q.gutter};return{text:i,segments:[{text:s,style:c},{text:" \u2502 ",style:d},...l],fullBleed:o!==null}}function Bi(e){return e===null?" ":String(e).padStart(4," ")}function Vi(e){let t=At.extname(e).toLowerCase();return[".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(t)?"javascript":[".json",".jsonc"].includes(t)?"json":[".md",".mdx"].includes(t)?"markdown":[".css",".scss"].includes(t)?"css":"plain"}function Gn(e,t){return t==="diff"?Hu(e):t==="markdown"?Yu(e):t==="json"?Hn(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Hn(e,/("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)|\/\/.*$|\/\*.*?\*\/|\b(const|let|var|function|return|if|else|for|while|class|interface|type|import|export|from|async|await|new|extends|implements|switch|case|break|continue|try|catch|throw|true|false|null|undefined)\b|-?\b\d+(?:\.\d+)?\b/g):[{text:e}]}function Hu(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:q.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:q.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:q.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:q.diffMeta}}]:[{text:e}]}function zu(e,t,r){return e.map(n=>({text:n.text,style:{...n.style??{fg:r},bg:t}}))}function Yu(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:q.markup,bold:!0}}]:Hn(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Hn(e,t){let r=[],n=0;for(let s of e.matchAll(t)){let o=s[0],i=s.index??0;i>n&&r.push({text:e.slice(n,i)}),r.push({text:o,style:Qu(o)}),n=i+o.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function Qu(e){return e.startsWith("//")||e.startsWith("/*")?{fg:q.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:q.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:q.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:q.markup}:{fg:q.keyword}}function Ju(e,t,r){let n=e.selectedProjectTargetId??t?.repoTargets?.[0]?.repoId??null,s=t?.type==="project"&&n?t.repoTargets?.find(l=>l.repoId===n)??null:null,o=t?.type==="project"?Hi(t.repoTargets??[]):s?.pullRequest??(t?O(t):null),i=[Xu(e,o),{id:"mode-spacer",text:"",muted:!0}];return e.inspectionMode==="review"?{title:"",rows:[...i,...Qi(e,t)]}:e.inspectionMode==="files"?{title:"",rows:[...i,...up(e,r)]}:{title:"",rows:[...i,...fp(e,r)]}}function Xu(e,t){let r=e.inspectionMode,n=[{label:"CHANGES",active:r==="diff"},{label:"FILES",active:r==="files"},{label:"REVIEW",active:r==="review"}],s=[];for(let c=0;c<n.length;c++){let d=n[c];c>0&&s.push({text:" "});let u=d.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:d.label,style:{fg:u}})}let o=zn(t),i=Yn(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(c=>c.text).join(""),segments:s}}function Ui(e){return[{text:" "},zn(e),{text:" "},Yn(e)]}function Gi(e){if(e.type==="project"&&e.repoTargets?.length){let r=Hi(e.repoTargets);return r?Ui(r):null}let t=O(e);return t?.number?Ui(t):null}function Hi(e){let t=e.filter(s=>s.status==="ready"),r=t.map(s=>s.pullRequest).filter(s=>!!s.number);if(r.length===0)return null;let n=ep(r);return{number:-1,status:Zu(r),draft:r.some(s=>s.draft),mergeable:r.length===t.length&&r.every(s=>s.mergeable),mergeStateStatus:null,reviewDecision:r.some(s=>s.reviewDecision==="CHANGES_REQUESTED")?"CHANGES_REQUESTED":r.some(s=>s.reviewDecision==="REVIEW_REQUIRED")?"REVIEW_REQUIRED":r.every(s=>s.reviewDecision==="APPROVED")?"APPROVED":null,requiredChecks:r.flatMap(s=>s.requiredChecks),aggregateReadiness:n}}function Zu(e){return e.some(t=>t.status==="open")?"open":e.every(t=>t.status==="merged")?"merged":e.some(t=>t.status==="closed")?"closed":e[0]?.status??null}function ep(e){let t=e.map(r=>zi(r));return t.some(r=>r==="failed")?"failed":t.some(r=>r==="pending")?"pending":t.length>0&&t.every(r=>r==="success")?"success":"none"}function zn(e){return!e||!e.number?{text:gi,style:{fg:"565f89"}}:e.status==="merged"?{text:hi,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:ki,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:Nn,style:{fg:"565f89"}}:{text:Nn,style:{fg:"9ece6a"}}}function Yn(e){return e?.aggregateReadiness?qi(e.aggregateReadiness):qi(zi(e))}function qi(e){return e==="failed"?{text:Bn,style:{fg:"f7768e"}}:e==="pending"?{text:Wn,style:{fg:"e0af68"}}:e==="success"?{text:_n,style:{fg:"9ece6a"}}:{text:Fn,style:{fg:"565f89"}}}function zi(e){let t=e?.requiredChecks??null;return e?.status==="merged"?"success":e?.status==="closed"||!e?.number||!t||t.length===0?"none":t.some(r=>r.status==="failed")||e.reviewDecision==="CHANGES_REQUESTED"?"failed":t.every(r=>r.status==="success"||r.status==="skipped")?Yi(e)?"failed":tp(e)?"success":"pending":"pending"}function tp(e){return!!(e.mergeable&&!e.draft&&!Yi(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function Yi(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Qi(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return rp(e,t);let r=O(t),n=Xi("pr",t.branch,r??{number:null,url:null,baseBranch:null,headBranch:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,lastSyncedAt:null,requiredChecks:[],comments:[]}),s=t.prs.filter(o=>o!==r&&(o.status==="merged"||o.status==="closed")).length;return s>0&&n.push({id:"pr-history",text:`+ ${s} previous PR${s!==1?"s":""}`,muted:!0}),np(n,e)}var lr=32;function rp(e,t){let r=[],n=t.repoTargets??[],s=e.selectedProjectTargetId??n[0]?.repoId??null;for(let i of n){let l=s===i.repoId,c=e.focusedRegion==="inspector"&&l,d=i.repoId.startsWith("repo_")?i.repoId.slice(5):i.repoId;if(i.status!=="ready"){let g=i.failureReason?i.failureReason.slice(0,14):i.status,w=lr-g.length-1,R=d.length>w?d.slice(0,w-1)+"\u2026":d,I=lr-R.length-g.length;r.push({id:`project-review:${i.repoId}`,text:R+" ".repeat(Math.max(1,I))+g,selected:l,focused:c,muted:!0})}else{let u=zn(i.pullRequest),g=Yn(i.pullRequest),w=`${u.text} ${g.text}`,R=lr-w.length-1,I=d.length>R?d.slice(0,R-1)+"\u2026":d,T=lr-I.length-w.length,a=I+" ".repeat(Math.max(1,T));r.push({id:`project-review:${i.repoId}`,text:a+w,selected:l,focused:c,segments:[{text:a},{...u,text:u.text},{text:" "},{...g,text:g.text}]})}}let o=n.find(i=>i.repoId===s)??null;return o?.status==="ready"&&o.pullRequest.number&&(r.push({id:"target-detail-spacer",text:""}),r.push(...Xi("target",o.branch,o.pullRequest))),r}function Ji(e,t){return Qi(e,t).length}function Xi(e,t,r){let n=g=>`${e}-${g}`;if(!r.number)return[{id:n("no-pr"),text:t,muted:!0}];let s=[],o=`#${r.number}`;s.push(r.url?{id:n("pr-number"),text:`${o} Open in GitHub \u2197`,segments:[{text:o},{text:" Open in GitHub \u2197",style:{fg:"7aa2f7",underline:!0},href:r.url}]}:{id:n("pr-number"),text:o});let i=r.baseBranch??"?",l=r.headBranch??t;s.push({id:n("pr-branches"),text:`${i} \u2192 ${l}`,muted:!0});let c=sp(r.reviewDecision,r.mergeStateStatus),d=c&&c!=="review approved"?"merge blocked":r.mergeable?"merge ready":r.mergeStateStatus?`merge ${r.mergeStateStatus}`:"merge unknown";c?s.push({id:n("pr-merge"),text:`${d} \xB7 ${c}`,muted:!0,segments:[{text:d},{text:" \xB7 "},{text:c,style:{fg:op(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:d,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${Zi(r.lastSyncedAt)}`,muted:!0}),s.push({id:n("checks-spacer"),text:""}),s.push({id:n("checks-header"),text:"Checks"}),r.requiredChecks.length?s.push(...r.requiredChecks.map(ip)):s.push({id:n("checks-none"),text:r.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let u=r.comments??[];return u.length>0&&(s.push({id:n("comments-spacer"),text:""}),s.push({id:n("comments-header"),text:`Review comments (${u.length})`}),s.push(...u.slice(-4).flatMap((g,w)=>ap(g,n(`comment:${w}`))))),s}function np(e,t){if(t.focusedRegion!=="inspector"||t.inspectionMode!=="review"||e.length===0)return e;let r=Math.max(0,Math.min(t.reviewScrollOffset,e.length-1));return e.map((n,s)=>({...n,selected:t.reviewScrollOffset===0&&n.selected||s===r,focused:t.reviewScrollOffset===0&&n.focused||s===r}))}function sp(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function op(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function Zi(e){if(!e)return"--";let t=Date.now()-new Date(e).getTime(),r=Math.floor(t/1e3);if(r<60)return`${r}s ago`;let n=Math.floor(r/60);if(n<60)return`${n}m ago`;let s=Math.floor(n/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}function ip(e){let{icon:t,color:r}=cp(e.status),n=e.name.length>16?`${e.name.slice(0,15)}\u2026`:e.name;return{id:`pr-check:${e.name}`,text:`${t} ${n.padEnd(16," ")} ${dp(e.status)}`,color:r,muted:!1}}function ap(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${Zi(e.createdAt)}`:"",s=lp(e.body,30),o=s.slice(0,4),i=o.length<s.length,l=[{id:`${t}:author`,text:`${r}${n}`,muted:!0},...o.map((c,d)=>({id:`${t}:body:${d}`,text:` ${i&&d===o.length-1?`${c}\u2026`:c}`,muted:!0}))];return l.push({id:`${t}:spacer`,text:"",muted:!0}),l}function lp(e,t){let r=e.split(/\s+/).filter(Boolean);if(r.length===0)return[];let n=[],s="";for(let o of r){if(!s){s=o;continue}`${s} ${o}`.length<=t?s=`${s} ${o}`:(n.push(s),s=o)}return s&&n.push(s),n}function cp(e){switch(e){case"success":return{icon:_n,color:"9ece6a"};case"pending":return{icon:Wn,color:"e0af68"};case"failed":return{icon:Bn,color:"f7768e"};case"skipped":return{icon:Fn,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function dp(e){return e==="success"?"passing":e==="failed"?"failing":e}function up(e,t){if(!t)return[{id:"empty",text:"No file index. Select a task with local changes.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.fileRows.length===0)return[{id:"empty",text:"No Git-visible files.",muted:!0}];let r=new Map(t.diffRows.map(o=>[o.path,o.status])),n=pp(t.fileRows,e.collapsedFileTreePaths),s=e.selectedFileTreePath??t.selectedFilePath;return n.map(o=>{let i=o.kind==="file"?r.get(o.path):void 0,l=i==="A"?"9ece6a":i==="M"?"e0af68":i==="D"?"f7768e":i==="??"?"565f89":void 0,c=o.kind==="directory"?e.collapsedFileTreePaths.includes(o.path)?fi:mi:pi(o.label),d=o.kind==="directory"?"7aa2f7":wi(o.label),u=" ".repeat(o.depth),g=d?{text:c,style:{fg:d}}:{text:c},w=o.kind==="directory"?{text:o.label,style:{fg:"7aa2f7"}}:l?{text:o.label,style:{fg:l}}:{text:o.label},R=[{text:u},g,w];return{id:o.path,text:`${u}${c}${o.label}`,selected:o.path===s,focused:o.path===s&&e.focusedRegion==="inspector",segments:R}})}function pp(e,t){let r=new Set(t);return e.filter(n=>{let s=n.path.split("/");for(let o=1;o<s.length;o+=1)if(r.has(s.slice(0,o).join("/")))return!1;return!0})}function fp(e,t){if(!t)return[{id:"empty",text:"No task diff index.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.diffRows.length===0)return[{id:"empty",text:t.filePaths.some(s=>s.startsWith("repo_"))?"No changes in project task worktrees. Edits in the original repos are outside this task.":"No local changes.",muted:!0}];if(mp(t))return gp(e,t);let r=[];for(let n of["branch","staged","unstaged","untracked"]){let s=t.diffRows.filter(o=>o.group===n);s.length!==0&&(r.push({id:n,text:n.toUpperCase(),muted:!0}),r.push(...s.map(o=>ea(o,e,t))))}return r}function mp(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function gp(e,t){let r=[],n=[...new Set(t.diffRows.map(s=>s.path.split("/")[0]).filter(s=>typeof s=="string"&&s.length>0))].sort();for(let s of n){let o=t.diffRows.filter(l=>l.path.startsWith(`${s}/`)),i=s.startsWith("repo_")?s.slice(5):s;r.push({id:`repo-diff:${s}`,text:i,muted:!0});for(let l of["branch","staged","unstaged","untracked"]){let c=o.filter(d=>d.group===l);c.length!==0&&(r.push({id:`repo-diff:${s}:${l}`,text:` ${l}`,muted:!0}),r.push(...c.map(d=>ea(d,e,t,s.length+1))))}}return r}function ea(e,t,r,n=0){let s=e.additions===null?"-":`+${e.additions}`,o=e.deletions===null?"-":`-${e.deletions}`,i=e.status==="A"||e.group==="untracked"?"9ece6a":e.status==="D"?"f7768e":"e0af68",l=n>0?e.path.slice(n):e.path;return{id:`${e.group}:${e.path}`,text:` ${e.status.padEnd(2," ")} ${l} ${s}/${o}`,selected:e.path===(t.selectedDiffPath??r.selectedDiffPath),focused:e.path===(t.selectedDiffPath??r.selectedDiffPath)&&t.focusedRegion==="inspector",color:i}}function hp(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:S.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:At.basename(t.worktreePath)}]:[{label:"Repo",value:e.name},{label:"Branch",value:e.defaultBranch},{label:"Task",value:"none",mutedValue:!0}]:[{label:"Repo",value:"none",mutedValue:!0}]}function kp(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function wp(e,t){return{name:S.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}var dr={width:120,height:36},ge={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function je(e,t){return{width:Math.max(e??dr.width,dr.width),height:Math.max(t??dr.height,dr.height)}}import{spawn as Bp}from"node:child_process";import{createHash as Up}from"node:crypto";import{createServer as qp,createConnection as ca}from"node:net";import{openSync as Kp}from"node:fs";import{mkdir as Vp,readFile as rs,rm as He,writeFile as Gp}from"node:fs/promises";import{tmpdir as Hp}from"node:os";import at from"node:path";import{createRequire as vp}from"node:module";import Rp from"@xterm/headless";var Tp=1e3,yp=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function ra(e){return new Rp.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:Tp,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function na(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Jn(e,t){return new Promise(r=>{e.write(t,r)})}function sa(e,t=0){let r=e.buffer.active,n=[],s=r.getNullCell(),o=r.baseY+r.cursorY,i=Math.max(0,r.baseY-t);for(let l=0;l<e.rows;l+=1){let c=r.getLine(i+l);if(!c){n.push({segments:[]});continue}let d=[];for(let u=0;u<e.cols;u+=1){let g=c.getCell(u,s);!g||g.getWidth()===0||d.push({text:g.getChars()||" ",style:Sp(g,i+l===o&&u===r.cursorX)})}n.push({segments:Pp(bp(d))})}return n}function Pp(e){let t=[];for(let r of e){let n=t.at(-1);if(n&&xp(n.style,r.style)){n.text+=r.text;continue}let s={text:r.text};oa(r.style)||(s.style=r.style),t.push(s)}return t}function bp(e){let t=e.length;for(;t>0;){let r=e[t-1];if(!r||r.text!==" "||!oa(r.style))break;t-=1}return e.slice(0,t)}function Sp(e,t){let r={},n=ta(e,"fg"),s=ta(e,"bg");return n&&(r.fg=n),s&&(r.bg=s),e.isBold()&&(r.bold=!0),e.isDim()&&(r.dim=!0),e.isItalic()&&(r.italic=!0),e.isUnderline()&&(r.underline=!0),(e.isInverse()||t)&&(r.inverse=!0),r}function ta(e,t){if(t==="fg"?e.isFgDefault():e.isBgDefault())return;let n=t==="fg"?e.isFgRGB():e.isBgRGB(),s=t==="fg"?e.getFgColor():e.getBgColor();return n?s.toString(16).padStart(6,"0"):yp[s]??Ip(s)}function Ip(e){if(e>=16&&e<=231){let t=e-16,r=Math.floor(t/36),n=Math.floor(t%36/6),s=t%6;return[r,n,s].map(Cp).map(o=>o.toString(16).padStart(2,"0")).join("")}if(e>=232&&e<=255){let t=8+(e-232)*10;return[t,t,t].map(r=>r.toString(16).padStart(2,"0")).join("")}return"e6e6e6"}function Cp(e){return e===0?0:55+e*40}function xp(e,t){return Qn(e)===Qn(t)}function Qn(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function oa(e){return Qn(e)===""}var Ep=vp(import.meta.url),Ap=/^CTRL_([A-Z])$/,Dp="\x1B[6n",$p="\x1B[c",Lp="\x1B[?u",jp={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
143
+ `,TAB:" ",SHIFT_TAB:"\x1B[Z",BACK_TAB:"\x1B[Z",BACKSPACE:"\x7F",DELETE:"\x1B[3~",ESCAPE:"\x1B",UP:"\x1B[A",DOWN:"\x1B[B",RIGHT:"\x1B[C",LEFT:"\x1B[D",HOME:"\x1B[H",END:"\x1B[F",PAGE_UP:"\x1B[5~",PAGE_DOWN:"\x1B[6~",CTRL_C:"",CTRL_D:""},ur=class{sessions=new Map;shell;env;spawn;onUpdate;resolveSessionSpec;attachedTabId=null;constructor(t){this.shell=t.shell??process.env.SHELL??"/bin/zsh",this.env=t.env??process.env,this.spawn=t.spawn,this.onUpdate=t.onUpdate,this.resolveSessionSpec=t.resolveSessionSpec??(()=>({cwd:t.workspaceRoot,command:[]}))}ensureSession(t,r,n,s){let o=this.sessions.get(r);if(o)if(o.status!=="running")Xn(o),this.sessions.delete(r);else return this.attachedTabId=r,o.scrollbackLines=0,ia(o,n),this.getViewState(r);let i=this.createSession(t,r,n,s);return this.sessions.set(r,i),this.attachedTabId=r,this.getViewState(r)}write(t){let r=this.getAttachedSession();!r||r.status!=="running"||r.pty.write(t)}writeKey(t){let r=Mp(t);r!==null&&this.write(r)}scrollViewport(t){let r=this.getAttachedSession();if(!r||t===0)return;let n=r.terminal.buffer.active.baseY;r.scrollbackLines=Math.max(0,Math.min(n,r.scrollbackLines-t))}resize(t){let r=this.getAttachedSession();r&&ia(r,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}disposeSession(t){let r=this.sessions.get(t);r&&(Xn(r),this.sessions.delete(t),this.attachedTabId===t&&(this.attachedTabId=null))}disposeAll(){for(let t of this.sessions.values())Xn(t);this.sessions.clear(),this.attachedTabId=null}getViewState(t){if(!t)return{status:"idle",rows:[],error:null,scrolledBack:!1};let r=this.sessions.get(t);return r?{status:r.status,rows:sa(r.terminal,r.scrollbackLines),error:r.error,scrolledBack:r.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,r,n,s){let o=this.spawn??Np().spawn,i=ra(n),l=s??this.resolveSessionSpec(t,r),c=Ue({...this.env,...l.env??{}}),{executable:d,args:u}=Fp(this.shell,l.command,{cwd:l.cwd,env:c}),g=o(d,u,{name:"xterm-256color",cols:n.columns,rows:n.rows,cwd:l.cwd,env:Wp(c)}),w={taskId:t,tabId:r,pty:g,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0};return w.disposables.push(g.onData(R=>{_p(g,R),Jn(w.terminal,R).then(()=>{this.onUpdate?.(w.tabId)})})),w.disposables.push(g.onExit(R=>{w.status="exited",Jn(w.terminal,`\r
144
+ [process exited ${R.exitCode}]`).then(()=>{this.onUpdate?.(w.tabId)})})),w}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}};function Mp(e){if(e.length===1)return e;let t=jp[e];if(t!==void 0)return t;let r=Ap.exec(e);return r?.[1]?String.fromCharCode(r[1].charCodeAt(0)-64):null}function ia(e,t){Op(e.pty,t),na(e.terminal,t)}function Xn(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function Op(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Np(){return Ep("node-pty")}function Fp(e,t,r){if(t.length===0)return{executable:e,args:[]};let s=`${[qe(t[0],r),...t.slice(1)].map(aa).join(" ")}; exec ${aa(e)} -l`;return{executable:e,args:["-lc",s]}}function aa(e){return`'${e.replaceAll("'","'\\''")}'`}function Wp(e){let t={};for(let[r,n]of Object.entries(e))typeof n=="string"&&(t[r]=n);return t.TERM=t.TERM??"xterm-256color",t}function _p(e,t){for(let r=0;r<Zn(t,Dp);r+=1)e.write("\x1B[1;1R");for(let r=0;r<Zn(t,$p);r+=1)e.write("\x1B[?1;2c");for(let r=0;r<Zn(t,Lp);r+=1)e.write("\x1B[?0u")}function Zn(e,t){if(t.length===0)return 0;let r=0,n=e.indexOf(t);for(;n!==-1;)r+=1,n=e.indexOf(t,n+t.length);return r}var ns=3;async function da(e){let t=ss(e.paths);await zp(t,e.paths,e.spawnDaemon);let r=await ha(t.socketPath),n=new es(r,e);return await n.ready(),n}async function ua(e,t={}){let r=ss(e);await Vp(e.runtimeDir,{recursive:!0}),await He(r.socketPath,{force:!0});let n=new ts(e,t),s=qp(o=>n.handleConnection(o));await ef(s,r.socketPath),await Gp(r.pidPath,String(process.pid),"utf8"),await new Promise(o=>{let i=()=>{n.closeClients(),s.close(()=>o())};n.onShutdown=i,process.once("SIGTERM",i),process.once("SIGINT",i)}),await He(r.socketPath,{force:!0}),await He(r.pidPath,{force:!0}),n.disposeAll()}async function pa(e){let t=ss(e);return await fr(t.socketPath)?(await ma(t.socketPath),!0):!1}var es=class{constructor(t,r){this.socket=t;this.options=r,t.setEncoding("utf8"),t.on("data",n=>this.handleData(String(n))),t.on("error",n=>this.rejectAll(n instanceof Error?n:new Error(String(n)))),t.on("close",()=>{this.closed=!0,this.rejectAll(new Error("Craig PTY daemon connection closed."))})}socket;nextRequestId=1;pending=new Map;viewCache=new Map;attachedTabId=null;buffer="";closed=!1;options;async ready(){if((await this.send({type:"ping"})).protocolVersion!==ns)throw new Error("Craig PTY daemon protocol mismatch.")}async ensureSession(t,r,n){let s=await this.send({type:"ensureSession",taskId:t,tabId:r,size:n,spec:this.options.resolveSessionSpec?.(t,r)??{cwd:this.options.workspaceRoot,command:[]}});this.attachedTabId=r;let o=s.view??{status:"idle",rows:[],error:null};return this.viewCache.set(r,o),o}async hydrateSessions(t){for(let r of t)try{let n=await this.send({type:"hydrateSession",tabId:r});n.view&&this.viewCache.set(r,n.view)}catch(n){let s=n instanceof Error?n.message:String(n);this.viewCache.set(r,{status:"failed",rows:[],error:s})}}async pruneStale(t){await this.send({type:"pruneStale",keepTabIds:t})}write(t){this.send({type:"write",input:t}).catch(()=>{})}writeKey(t){this.send({type:"writeKey",key:t}).catch(()=>{})}scrollViewport(t){this.send({type:"scrollViewport",lines:t}).then(r=>{this.attachedTabId&&r.view&&this.viewCache.set(this.attachedTabId,r.view)}).catch(()=>{})}resize(t){this.send({type:"resize",size:t}).then(r=>{this.attachedTabId&&r.view&&this.viewCache.set(this.attachedTabId,r.view)}).catch(()=>{})}detach(){this.attachedTabId=null,this.send({type:"detach"}).catch(()=>{})}disposeSession(t){this.viewCache.delete(t),this.attachedTabId===t&&(this.attachedTabId=null),this.send({type:"disposeSession",tabId:t}).catch(()=>{})}disposeAll(){this.attachedTabId=null,!this.closed&&(this.socket.end(),this.closed=!0)}getViewState(t){return t?this.viewCache.get(t)??{status:"idle",rows:[],error:null,scrolledBack:!1}:{status:"idle",rows:[],error:null,scrolledBack:!1}}async requestShutdown(){await this.send({type:"shutdown"})}async send(t){if(this.closed)throw new Error("Craig PTY daemon connection is closed.");let r=this.nextRequestId;this.nextRequestId+=1;let n={...t,id:r},s=new Promise((i,l)=>{this.pending.set(r,{resolve:i,reject:l})});if(this.socket.destroyed)throw this.pending.delete(r),new Error("Craig PTY daemon connection is closed.");this.socket.write(`${JSON.stringify(n)}
145
+ `);let o=await s;if(!o.ok)throw new Error(o.error);return o}handleData(t){this.buffer+=t;let r=this.buffer.indexOf(`
146
+ `);for(;r!==-1;){let n=this.buffer.slice(0,r);this.buffer=this.buffer.slice(r+1),this.handleMessage(n),r=this.buffer.indexOf(`
147
+ `)}}handleMessage(t){if(t.trim().length===0)return;let r;try{r=JSON.parse(t)}catch{return}if("id"in r){let n=this.pending.get(r.id);if(!n)return;this.pending.delete(r.id),n.resolve(r);return}r.type==="update"&&(r.tabId&&this.viewCache.set(r.tabId,r.view),this.options.onUpdate?.(r.tabId??""))}rejectAll(t){for(let r of this.pending.values())r.reject(t);this.pending.clear()}},ts=class{onShutdown=null;clients=new Set;runtime;attachedTabId=null;constructor(t,r){this.runtime=new ur({...r,workspaceRoot:t.workspaceRoot,onUpdate:n=>this.broadcastUpdate(n)})}handleConnection(t){let r="";this.clients.add(t),t.setEncoding("utf8"),t.on("data",n=>{r+=String(n);let s=r.indexOf(`
148
+ `);for(;s!==-1;){let o=r.slice(0,s);r=r.slice(s+1),this.handleLine(t,o),s=r.indexOf(`
149
+ `)}}),t.on("close",()=>this.clients.delete(t)),t.on("error",()=>this.clients.delete(t))}disposeAll(){this.runtime.disposeAll()}closeClients(){for(let t of this.clients)t.destroy();this.clients.clear()}async handleLine(t,r){if(r.trim().length===0)return;let n;try{n=JSON.parse(r)}catch{pr(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(n);pr(t,{id:n.id,ok:!0,...n.type==="ping"?{protocolVersion:ns}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);pr(t,{id:n.id,ok:!1,error:o})}}handleRequest(t){switch(t.type){case"ping":return null;case"ensureSession":return this.attachedTabId=t.tabId,this.runtime.ensureSession(t.taskId,t.tabId,t.size,t.spec);case"hydrateSession":return this.runtime.getViewState(t.tabId);case"write":return this.runtime.write(t.input),null;case"writeKey":return this.runtime.writeKey(t.key),null;case"scrollViewport":return this.runtime.scrollViewport(t.lines),this.runtime.getViewState(this.attachedTabId);case"resize":return this.runtime.resize(t.size),this.runtime.getViewState(this.attachedTabId);case"detach":return this.runtime.detach(),this.attachedTabId=null,null;case"disposeSession":return this.runtime.disposeSession(t.tabId),this.attachedTabId===t.tabId&&(this.attachedTabId=null),null;case"pruneStale":{let r=new Set(t.keepTabIds);for(let n of this.runtime.sessionTabIds())r.has(n)||(this.runtime.disposeSession(n),this.attachedTabId===n&&(this.attachedTabId=null));return null}case"getViewState":return this.runtime.getViewState(t.tabId);case"shutdown":return setTimeout(()=>this.onShutdown?.(),0),null;default:return tf(t)}}broadcastUpdate(t){let r=this.runtime.getViewState(t);for(let n of this.clients)pr(n,{type:"update",tabId:t,view:r})}};function ss(e){let t=Up("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:at.join(Hp(),`craig-${t}.sock`),pidPath:at.join(e.runtimeDir,"pty-daemon.pid")}}async function zp(e,t,r){if(await Yp(e.socketPath,1e3))return;await fr(e.socketPath)&&(await ma(e.socketPath),await la(e.socketPath,1e3)),await fr(e.socketPath)&&(await Xp(e),await la(e.socketPath,1e3)),await Jp(e);let n=t.workspaceRoot;if(r)r(n);else{let{command:i,args:l}=Qp(n),c=Kp(at.join(t.runtimeDir,"pty-daemon.log"),"a");Bp(i,l,{cwd:n,detached:!0,stdio:["ignore",c,c],env:process.env}).unref()}let s=Date.now();for(;Date.now()-s<5e3;){if(await fa(e.socketPath))return;await os(50)}let o=await rs(at.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
150
+ ${o.slice(-2e3)}`:""}`)}async function fa(e){let t=await Zp(e).catch(()=>null);return t?.ok===!0&&t.protocolVersion===ns}async function Yp(e,t){let r=Date.now();for(;Date.now()-r<t;){if(await fa(e))return!0;await os(50)}return!1}function Qp(e){let t=process.argv[1];if(t?.endsWith(".ts")){let n=at.resolve(at.dirname(t),"..","node_modules",".bin","tsx");return{command:dn("tsx")??n,args:[t,"__craig-daemon",e]}}let r=process.argv.slice(1);return{command:process.execPath,args:[...process.execArgv,...r,"__craig-daemon",e]}}async function Jp(e){let t=await rs(e.pidPath,"utf8").catch(()=>null);if(t){let r=Number(t.trim());if(Number.isInteger(r)&&r>0&&ka(r))return}await He(e.socketPath,{force:!0}),await He(e.pidPath,{force:!0})}async function fr(e){let t=await ha(e).catch(()=>null);return t?(t.end(),!0):!1}async function ma(e){await ga(e,{id:1,type:"shutdown"}).catch(()=>null)}async function Xp(e){let t=await rs(e.pidPath,"utf8").catch(()=>null),r=Number(t?.trim());if(!Number.isInteger(r)||r<=0||!ka(r)){await He(e.socketPath,{force:!0});return}try{process.kill(r,"SIGTERM")}catch{await He(e.socketPath,{force:!0})}}async function Zp(e){return ga(e,{id:1,type:"ping"})}function ga(e,t){return new Promise((r,n)=>{let s=ca(e),o="",i=setTimeout(()=>{s.destroy(),n(new Error("Craig PTY daemon request timed out."))},500),l=()=>clearTimeout(i);s.setEncoding("utf8"),s.once("connect",()=>s.write(`${JSON.stringify(t)}
151
+ `)),s.once("error",c=>{l(),n(c)}),s.on("data",c=>{o+=String(c);let d=o.indexOf(`
152
+ `);if(d===-1)return;let u=o.slice(0,d);l(),s.end();try{r(JSON.parse(u))}catch(g){n(g instanceof Error?g:new Error(String(g)))}}),s.once("close",()=>l())})}async function la(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!await fr(e))return;await os(50)}}function ha(e){return new Promise((t,r)=>{let n=ca(e);n.once("connect",()=>t(n)),n.once("error",r)})}function ef(e,t){return new Promise((r,n)=>{e.once("error",n),e.listen(t,r)})}function pr(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
153
+ `)}catch{}}function ka(e){try{return process.kill(e,0),!0}catch{return!1}}function os(e){return new Promise(t=>setTimeout(t,e))}function tf(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}import ny from"picocolors";var rf=[" \u2584\u2588\u2588\u2588\u2588\u2584 \u2588\u2588\u2580\u2588\u2588\u2588 \u2584\u2584\u2584 \u2588\u2588\u2593 \u2584\u2588\u2588\u2588\u2588"," \u2592\u2588\u2588\u2580 \u2580\u2588 \u2593\u2588\u2588 \u2592 \u2588\u2588\u2592\u2592\u2588\u2588\u2588\u2588\u2584 \u2593\u2588\u2588\u2592 \u2588\u2588\u2592 \u2580\u2588\u2592"," \u2592\u2593\u2588 \u2584 \u2593\u2588\u2588 \u2591\u2584\u2588 \u2592\u2592\u2588\u2588 \u2580\u2588\u2584 \u2592\u2588\u2588\u2592\u2592\u2588\u2588\u2591\u2584\u2584\u2584\u2591"," \u2592\u2593\u2593\u2584 \u2584\u2588\u2588\u2592\u2592\u2588\u2588\u2580\u2580\u2588\u2584 \u2591\u2588\u2588\u2584\u2584\u2584\u2584\u2588\u2588 \u2591\u2588\u2588\u2591\u2591\u2593\u2588 \u2588\u2588\u2593"," \u2592 \u2593\u2588\u2588\u2588\u2580 \u2591\u2591\u2588\u2588\u2593 \u2592\u2588\u2588\u2592 \u2593\u2588 \u2593\u2588\u2588\u2592\u2591\u2588\u2588\u2591\u2591\u2592\u2593\u2588\u2588\u2588\u2580\u2592"," \u2591 \u2591\u2592 \u2592 \u2591\u2591 \u2592\u2593 \u2591\u2592\u2593\u2591 \u2592\u2592 \u2593\u2592\u2588\u2591\u2591\u2593 \u2591\u2592 \u2592"," \u2591 \u2592 \u2591\u2592 \u2591 \u2592\u2591 \u2592 \u2592\u2592 \u2591 \u2592 \u2591 \u2591 \u2591"," \u2591 \u2591\u2591 \u2591 \u2591 \u2592 \u2592 \u2591\u2591 \u2591 \u2591"," \u2591 \u2591 \u2591 \u2591 \u2591 \u2591 \u2591"," \u2591"];function is(){return[...rf]}var nf=["Start","Options","Exit"],sf=["Resume","Options","Exit"],hr=2,kr=2,wr=2,of=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),af=new RegExp("\x1B\\[(?:0)?m","g"),lf=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),cf=/https?:\/\/[^\s<>"']+/g,as="\x1B[0m",ls="\x1B]8;;\x1B\\",E={panelBg:{bg:"0a0a0a",fg:"c0caf5"},panelMuted:{bg:"0a0a0a",fg:"565f89"},panelSelected:{bg:"1a1b26",fg:"c0caf5"},panelFocused:{bg:"1a1b26",fg:"7aa2f7"},divider:{bg:"0a0a0a",fg:"292e42"},rail:{bg:"0a0a0a",fg:"c0caf5"},overlay:{bg:"06060f",fg:"565f89"},overlayTitle:{bg:"06060f",fg:"565f89"},overlayLogo:{bg:"06060f",fg:"9ece6a"},overlaySubtitle:{bg:"06060f",fg:"41a6b5"},overlayMenuSelected:{bg:"06060f",fg:"7aa2f7"},accent:{fg:"7aa2f7"},success:{fg:"9ece6a"},pending:{fg:"e0af68"},error:{fg:"f7768e"},mutedfg:{fg:"565f89"},disabled:{fg:"3b4261"}};function Ta(e,t={}){return ds(e,{subtitle:"crAIg is that you?",menuItems:nf,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function ya(e,t={}){return ds(e,{subtitle:"Control mode is paused.",menuItems:sf,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var mr=[" GLOBAL CENTER PANEL INSPECTOR"," ? help \u2190\u2192 / hl switch tab \u2191\u2193 / jk navigate"," Esc pause / back + new tab \u2190\u2192 / hl switch mode"," Tab cycle panels a codex tab R sync PR"," q quit t terminal tab R sync PR"," x close tab X close task"," TASKS Enter attach PTY X close task"," \u2191\u2193 / jk navigate"," n new task TERMINAL MODE"," Enter attach Ctrl+] return to control mode"," Wheel / PgUp / PgDn scroll",""," Press Esc to return."],df=["Help"];function cs(e,t={}){return ds(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??df,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function Pa(e,t={}){let r=t.color??!0,n=E.overlay,s=new Array(e.height).fill(W(" ".repeat(e.width),r,n)),o=is(),i=Math.max(1,Math.floor((e.height-o.length-2-mr.length)/2));for(let u=0;u<o.length&&!(i+u>=e.height);u+=1)s[i+u]=W(xa(o[u]??"",e.width),r,E.overlayLogo);let l=Math.max(...mr.map(u=>u.length)),c=Math.max(0,Math.floor((e.width-l)/2)),d=i+o.length+2;for(let u=0;u<mr.length;u+=1){let g=d+u;if(g>=e.height)break;let w=mr[u]??"";s[g]=W(Te(" ".repeat(c)+w,e.width),r,n)}return s.join(`
154
+ `)}function ba(e,t={}){let r=t.color??!0,n=E.overlay,s=new Array(e.height).fill(W(" ".repeat(e.width),r,n)),o="Error Log",i=t.errorLogPath??"",l=t.errorLogLines??[],c=Math.max(20,e.width-8),d=Math.max(0,Math.floor((e.width-c)/2)),u=[{text:o,tone:"selected"},{text:i,tone:"muted"},ae(),...l.length>0?l.map(R=>({text:R})):[{text:"No Craig errors have been logged.",tone:"muted"}],ae(),{text:"Esc returns to Options.",tone:"muted"}],g=Dt(u,e.height-2),w=Math.max(1,Math.floor((e.height-g.length)/2));for(let R=0;R<g.length;R+=1){let I=w+R;if(I>=e.height)break;let T=g[R]??ae(),a=`${" ".repeat(d)}${Tr(T.text,c)}`,z=T.tone==="selected"?E.overlayMenuSelected:T.tone==="muted"?E.overlay:E.panelBg;s[I]=W(Te(a,e.width),r,z)}return s.join(`
155
+ `)}function Sa(e,t,r={}){let n=r.color??!0,s=ge.leftWidth,o=ge.rightWidth,i=ge.dividerWidth,l=r.centerOnly??!1,c=l?e.width:e.width-s-o-i*2,d=e.height-ge.topRailHeight-1,u=r.focusFlashActive??!1,g={bg:E.divider.bg,fg:"9ece6a"},w=u&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?g:E.divider,R=u&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?g:E.divider,I=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,T=W(Te(I,e.width),n,E.rail),a=pf(t,s-hr-kr,d,n),z=ff(t,c,d,n),U=gf(t,o,d,n),le=t.inputMode==="terminal",x=[];for(let oe=0;oe<d;oe+=1){if(l){x.push(gr(z[oe]??ae(),c,n,"center"));continue}let xe=gr(a[oe]??ae(),s,n,"left"),he=W("\u2502",n,w),ve=gr(z[oe]??ae(),c,n,"center"),ce=W("\u2502",n,R),ze=gr(U[oe]??ae(),o,n,"right");x.push(`${xe}${he}${ve}${ce}${ze}`)}let Me=le||t.modalInput?E.panelBg:E.panelMuted,Ce=uf(t.footerText,t.footerToast,e.width,n,Me);return[T,...x,Ce].join(`
156
+ `)}function uf(e,t,r,n,s){let o=` ${e}`;if(!t)return W(Te(o,r),n,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,l=se(i),c=se(o),d=Math.max(1,r-c-l-2),u=c+d+l+2>r?Tr(o,Math.max(0,r-l-3)):o,g=Math.max(1,r-se(u)-l-2),w=t.tone==="error"?jf(i,n,s):lt(i,n,s),R=`${u}${" ".repeat(g)}${w} `;return W(Te(R,r),n,s)}function ds(e,t){let r=new Array(e.height).fill(W(" ".repeat(e.width),t.color,E.overlay)),n=is(),s=Math.max(...t.menuItems.map(d=>d.length)),o=t.menuItems.map((d,u)=>`${u===t.menuIndex?">":" "} ${d.padEnd(s)}`),i=t.optionsMessage?["",t.optionsMessage]:[],l=[...n,"",t.subtitle,"",...o,...i],c=Math.max(1,Math.floor((e.height-l.length)/2));for(let d=0;d<l.length;d+=1){let u=xa(l[d]??"",e.width);if(d<n.length){r[c+d]=W(u,t.color,E.overlayLogo);continue}if(d===n.length+1){r[c+d]=W(u,t.color,E.overlaySubtitle);continue}let g=d-(n.length+3),R=g>=0&&g<t.menuItems.length&&g===t.menuIndex?E.overlayMenuSelected:E.overlay;r[c+d]=W(u,t.color,R)}if(t.versionText){let d=t.updateText?" (update available)":"",u=`${t.versionText}${d} `,g=" ".repeat(Math.max(0,e.width-se(u)));r[e.height-1]=W(`${g}${us(u,t.color,E.overlay)}`,t.color,E.overlay)}return r.join(`
157
+ `)}function pf(e,t,r,n){let s=wf(e.runners),o=1,i=e.leftTree.map(c=>kf(c,t,n));return[...Dt(i,r-o),s]}function ff(e,t,r,n){let s=t-2,o=e.tabs.find(x=>x.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:Df(e.tabs),l=e.inputMode==="terminal"?s:o.length+1,c="\u2500".repeat(Math.max(0,l)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?lt(c,n,E.panelBg):Rr(c,n,E.panelMuted)}`,u=[`${Rr(e.centerHeader.tabLabel,n,E.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),g=e.tabs.find(x=>x.active)?.id??"agent",w=e.centerHeader.tabLabel==="BROWSER"||!ji(g)?e.centerTranscript.map(x=>({...x})):mf(e),R=Rf(e.tabs,n,e.focusedRegion==="center"),I=" engaged ",T=I.length+2,a=e.inputMode==="terminal"?lt(`${I}\u25CF `,n,E.panelBg):"",z=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-se(R)-T)):"",le=[{text:e.inputMode==="terminal"?`${R}${z}${a}`:R},{text:d,tone:"muted"},{text:u},ae(),...w];return Dt(le,r)}function mf(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},ae(),{text:e.terminal.error},ae(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(n=>n.active)?.id??"",r=t==="agent"||/:agent(?:-\d+)?$/.test(t)?"agent":"terminal";return e.terminal.rows.length===0?[{text:`Press Enter on the ${r.toUpperCase()} tab to attach a PTY.`}]:e.terminal.rows.map(n=>({text:Aa(n.segments),segments:n.segments,fullBleed:!0}))}function gf(e,t,r,n){let s=e.rightInspection?hf(e.actionMessage?[...e.rightInspection.rows.slice(0,2),{id:"action-message",text:e.actionMessage},{id:"action-message-spacer",text:""},...e.rightInspection.rows.slice(2)]:e.rightInspection.rows,r):Dt([{text:"CONTEXT"},ae(),...e.rightContext.map(o=>Tf(o,n)),...e.actionMessage?[ae(),{text:e.actionMessage}]:[]],r);return Dt(s,r)}function hf(e,t){let r=e.slice(0,2),n=e.slice(2),s=Math.max(0,t-r.length),o=n.findIndex(l=>l.focused||l.selected),i=o===-1?0:Lf(o-Math.floor(s/2),0,Math.max(0,n.length-s));return[...r.map(l=>wa(l)),...n.slice(i,i+s).map(l=>wa(l))]}function wa(e){let t=e.focused?"\u25B8 ":e.selected?"\u2022 ":" ",r=e.focused||e.selected?"selected":e.muted?"muted":"default",n=`${t}${e.text}`;if(e.segments)return{text:n,segments:[{text:t},...e.segments],tone:r};if(e.accentPrefix&&!e.muted){let s=e.text.indexOf(" "),o=s===-1?e.text:e.text.slice(0,s),i=s===-1?"":e.text.slice(s);return{text:n,segments:[{text:t},{text:o,style:{fg:"7aa2f7"}},{text:i}],tone:r}}return e.color?{text:n,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:r}:{text:n,tone:r}}function kf(e,t,r){let n=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${lt("\u25CF",r,e.selected?E.panelSelected:E.panelBg)}`:"",l=e.prBadge?e.prBadge.reduce((R,I)=>R+se(I.text),0):0,c=t-se(o)-se(s)-l,d=e.selected?e.text:e.focused?lt(e.text,r,E.panelBg):e.panelHeader?Rr(e.text,r,E.panelMuted):e.text,u=Te(`${n}${d}`,Math.max(0,c)),g=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let R=[{text:`${u}${o}${i}`},...e.prBadge];return{text:`${u}${o}${e.prBadge.map(T=>T.text).join("")}`,segments:R,tone:g}}return{text:`${u}${o}${i}`,tone:g}}function wf(e){let t=e.map(n=>{let s=n.health>=1,o=parseInt(n.count,10),i=o>1?` (${o})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${n.name}${i}`,active:s}}),r=[];for(let n=0;n<t.length;n++){let s=t[n];n>0&&r.push({text:" "}),s.active?r.push({text:s.text,style:{fg:E.success.fg}}):r.push({text:s.text,style:{fg:E.panelMuted.fg}})}return{text:t.map(n=>n.text).join(" "),segments:r,tone:"muted"}}function Rf(e,t,r){return e.map(n=>n.active?r?lt(n.label,t,E.panelBg):Rr(n.label,t,E.panelBg):us(n.label,t,E.panelBg)).join(" ")}function Tf(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?us(e.value,t,E.panelBg):e.value}`}}function gr(e,t,r,n){let s=yf(n,e.tone??"default"),o=Pf(e,r,s);if(n==="left"){if(e.fullBleed)return W(Te(o,t),r,s);let l=t-hr-kr;if(e.rightAlign){let d=se(o),u=Math.max(0,l-d),g=`${" ".repeat(hr)}${" ".repeat(u)}${o}${" ".repeat(kr)}`;return W(g,r,s)}let c=`${" ".repeat(hr)}${Te(o,l)}${" ".repeat(kr)}`;return W(c,r,s)}return n==="center"&&e.fullBleed?bf(e,t,r,s):W(Te(` ${o}`,t),r,s)}function yf(e,t){return t==="selected"||t==="focused"?E.panelSelected:t==="muted"?E.panelMuted:E.panelBg}function Dt(e,t){let r=e.slice(0,t);for(;r.length<t;)r.push(ae());return r}function ae(){return{text:""}}function Pf(e,t,r){return e.segments?e.segments.map(n=>Ia(n,t,r)).join(""):e.text}function bf(e,t,r,n){let s=" ".repeat(wr),o=Math.max(0,t-wr*2);if(!e.segments)return W(`${s}${Te(e.text,o)}${s}`,r,n);let i=Cf(e.segments,o),l=`${s}${i.map(c=>Ia(c,r,n)).join("")}${s}${r?ls:""}`;return W(l,r,n)}function Ia(e,t,r){let n=e.href?`${Ca(e.href)}${e.text}${ls}`:Sf(e.text);return!t||!e.style?n:`${$t(Ef(e.style,r))}${Af(e.style)}${n}${as}${$t(r)}`}function Sf(e){return e.replace(cf,t=>{let[r,n]=If(t);return`${Ca(r)}${r}${ls}${n}`})}function If(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function Ca(e){return`\x1B]8;;${e}\x1B\\`}function Cf(e,t){let r=xf(e,t);return vf(r,t)}function xf(e,t){let r=[],n=t;for(let s of e){if(n<=0)break;let o=se(s.text);if(o<=n){r.push(s),n-=o;continue}let i=Tr(s.text,n);i.length>0&&r.push({...s,text:i}),n=0}return r}function vf(e,t){let r=se(Aa(e));if(r>=t)return e;let n=e.at(-1)?.style;return n?.bg?[...e,{text:" ".repeat(t-r),style:n}]:[...e,{text:" ".repeat(t-r)}]}function Ef(e,t){let r=e.inverse?e.bg??t.bg:e.fg,n=e.inverse?e.fg??t.fg:e.bg,s={},o=r??t.fg,i=n??t.bg;return o&&(s.fg=o),i&&(s.bg=i),s}function Af(e){let t=[];return e.bold&&t.push("1"),e.dim&&t.push("2"),e.italic&&t.push("3"),e.underline&&t.push("4"),t.length>0?`\x1B[${t.join(";")}m`:""}function Df(e){let t=0;for(let r of e){if(r.active)return t;t+=r.label.length+3}return 0}function xa(e,t){let r=Math.max(0,t-se(e)),n=Math.floor(r/2),s=r-n;return`${" ".repeat(n)}${e}${" ".repeat(s)}`}function Te(e,t){let r=se(e);return r>=t?$f(e,t):e+" ".repeat(t-r)}function $f(e,t){if(t<=0)return"";if(se(e)<=t)return e;let r=Ea(e);return Tr(r,Math.max(0,t-1))+"\u2026"}function se(e){let t=0;for(let r of Array.from(Ea(e)))t+=va(r);return t}function Tr(e,t){let r="",n=0;for(let s of Array.from(e)){let o=va(s);if(n+o>t)break;r+=s,n+=o}return r}function va(e){let t=e.codePointAt(0);return t===void 0||t===0||t<32||t>=127&&t<160||t>=768&&t<=879||t>=6832&&t<=6911||t>=7616&&t<=7679||t>=8400&&t<=8447||t>=65024&&t<=65039||t>=8203&&t<=8207||t>=8288&&t<=8292||t===65279?0:t>=4352&&(t<=4447||t===9001||t===9002||t>=11904&&t<=42191&&t!==12351||t>=44032&&t<=55203||t>=63744&&t<=64255||t>=65040&&t<=65049||t>=65072&&t<=65135||t>=65280&&t<=65376||t>=65504&&t<=65510||t>=127744&&t<=129791||t>=131072&&t<=262141)?2:1}function Lf(e,t,r){return Math.min(Math.max(e,t),r)}function Ea(e){return e.replace(lf,"").replace(of,"")}function Aa(e){return e.map(t=>t.text).join("")}function W(e,t,r){if(!t)return e;let n=$t(r),s=e.replace(af,`${as}${n}`);return`${n}${s}${as}`}function $t(e){let t=[];return e.fg&&t.push(`38;2;${Ra(e.fg).join(";")}`),e.bg&&t.push(`48;2;${Ra(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function Ra(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function lt(e,t,r){return yr(e,t,E.success.fg,r)}function jf(e,t,r){return yr(e,t,E.error.fg,r)}function Rr(e,t,r){return yr(e,t,E.accent.fg,r)}function us(e,t,r){return yr(e,t,E.mutedfg.fg,r)}function yr(e,t,r,n){if(!t)return e;let s=n.bg?{fg:r,bg:n.bg}:{fg:r};return`${$t(s)}${e}${$t(n)}`}var ps=["Runners","Error Log","Help"];function fs(e,t){return N.map(r=>{let n=S.runners.getProfile(r),s=e.runners?.[r]?.enabled!==!1,o=e.runners?.[r]?.path?.trim(),i=t.pathEdit?.runner===r?`${t.pathEdit.value}_`:o&&o.length>0?o:`default (${n.executable})`;return`${n.displayName} ${s?"enabled":"disabled"} ${i}`})}function $a(e){return e.message?e.message:e.pathEdit?"Type an executable path. Enter saves. Empty resets to default. Esc cancels.":"Enter toggles. E edits the executable path."}function La(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(ps.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:ms(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function ja(e,t,r,n){if(e.pathEdit)return Mf({...e,pathEdit:e.pathEdit},t,r);let s=fs(t,e).length;if(r==="UP"||r==="k")return{kind:"render",state:{...e,menuIndex:Math.max(0,e.menuIndex-1),message:null}};if(r==="DOWN"||r==="j")return{kind:"render",state:{...e,menuIndex:Math.min(s-1,e.menuIndex+1),message:null}};if(r==="ESCAPE")return{kind:"back",state:e};if(r==="e"){let l=N[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:l,value:t.runners?.[l]?.path??""}}}}if(!ms(r))return{kind:"noop",state:e};let o=N[e.menuIndex]??"codex",i=t.runners?.[o]?.enabled!==!1;return i&&n.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save",config:Of(t,o,!i),state:{...e,message:`${S.runners.getProfile(o).displayName} ${i?"disabled":"enabled"}.`}}}function Mf(e,t,r){if(r==="ESCAPE")return{kind:"render",state:Da({...e,message:null})};if(r==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(ms(r)){let n=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:Nf(t,n,s.length>0?s:null),state:Da({...e,message:s.length>0?`${S.runners.getProfile(n).displayName} executable saved.`:`${S.runners.getProfile(n).displayName} executable reset to default.`})}}return Ff(r)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${r}`}}}:{kind:"noop",state:e}}function Of(e,t,r){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:r}}}}function Nf(e,t,r){let n={...e.runners?.[t]??{},...r?{path:r}:{}};return r||delete n.path,{...e,runners:{...e.runners??{},[t]:n}}}function Da(e){let t={...e};return delete t.pathEdit,t}function ms(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
158
+ `}function Ff(e){return e.length===1&&e>=" "&&e!=="\x7F"}var Uf=Wf(import.meta.url),qf=Uf("terminal-kit"),Kf=qf.terminal;async function Na(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=Pe(t),n=await S.load(r),s=S.runners.getEnabled(n),o=e.uiStateFile?await J({uiStateFile:e.uiStateFile}):null,i=Promise.resolve(),l=Promise.resolve(),c=await Lt(t,void 0,s),d=ar(Ei(o,n),c);c=await Lt(t,d,s);let u=()=>{},g={workspaceRoot:t,onUpdate:()=>u(),resolveSessionSpec:(I,T)=>zf(c,T,t)},w=e.ptyRuntime??await da({...g,paths:r}),R=I=>{if(!e.uiStateFile)return;o=Ai(o,I);let T=o;i=i.then(()=>Y({uiStateFile:e.uiStateFile},T),()=>Y({uiStateFile:e.uiStateFile},T)),i.catch(()=>{})};return new Promise(I=>{let T=e.terminal??Kf,a={mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:ar(d,c)},z=!1,U=!1,le=null,x=0,Me=0,Ce=null,oe=null,xe=null,he=null,ve=null,ce=null,ze=null,Sr=!1,Ir=null,hs=`Craig v${S.version.getCurrent()}`,Cr=null,xr=0,Q=!0,vr=null,y=()=>{},_=w;u=()=>{a.mode==="main"&&(a={mode:"main",shell:dt(a.shell)},xe||(xe=setTimeout(()=>{xe=null,a.mode==="main"&&y()},50)))};function dt(f){return Ge(f,_.getViewState(ks(f)))}function ks(f){let p=Ye(f);return p?p.ptyTabs.some(m=>m.id===f.activeTab)?f.activeTab:f.activeTab==="agent"||f.activeTab==="terminal"?p.ptyTabs.find(m=>m.kind===f.activeTab)?.id??f.selectedPtyTabId:f.selectedPtyTabId:f.selectedPtyTabId}function P(f){return dt(Vf(f,c))}function Ye(f){return c.tasks.find(p=>p.id===f.selectedTaskId)??null}async function ws(){let f=c.tasks.flatMap(p=>p.ptyTabs.map(m=>m.id));await _.pruneStale?.(f),await _.hydrateSessions?.(f)}function Wa(){ws().catch(()=>{}).then(()=>{a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},y())})}async function _a(f){let p=P(f),m=Ye(p),h=ks(p);if(!m||!h||!m.ptyTabs.some(F=>F.id===h))return p;let k=_.getViewState(h);if(k.status!=="idle"||k.rows.length>0||k.error)return Ge(p,k);let C=await _.ensureSession(m.id,h,Mt(je(T.width,T.height)));return Ge({...p,inputMode:"control"},C)}function Rs(f,p){return he&&(clearTimeout(he),he=null),p?(he=setTimeout(()=>{he=null,!(a.mode!=="main"||a.shell.footerToast!==p)&&(a={mode:"main",shell:P({...a.shell,footerToast:null})},y())},600),{...f,footerToast:p}):{...f,footerToast:null}}function Ba(f,p){return Rs(f,p?{tone:"success",message:p}:null)}function K(f,p,m){let h=p instanceof Error?p.message:m,k=p instanceof Error?p.stack??p.message:String(p);return er.appendErrorLogBestEffort(r,{context:f,message:h,details:k}),h}function V(f,p){return Rs(f,{tone:"error",message:p})}function Oe(f){let p=l.then(f,f);return l=p.then(()=>{},()=>{}),p}function Ts(f){let p=Ye(f),m=c.inspection,h=m&&m.taskId===p?.id?m:null,k=Gf(h?.fileRows??[],f.collapsedFileTreePaths);return{leftItemIds:Hf(c),centerTabIds:Oi(p,f),ptyTabIds:p?.ptyTabs.map(C=>C.id)??[],filePathIds:h?.filePaths??[],fileTreeRowIds:k.map(C=>C.path),fileTreeFileIds:k.filter(C=>C.kind==="file").map(C=>C.path),fileTreeDirectoryIds:k.filter(C=>C.kind==="directory").map(C=>C.path),diffPathIds:h?.diffPaths??[],diffPathRanges:[],fileLineCount:h?.selectedFile.lines.length??0,diffLineCount:h?.selectedDiff.lines.length??0,reviewRowCount:Ji(f,p),pageRows:Math.max(5,je(T.width,T.height).height-ge.topRailHeight-9),enabledRunnerIds:s,projectTargetIds:p?.repoTargets?.map(C=>C.repoId)??[]}}async function Ua(f){await S.save(r,f),n=f,s=S.runners.getEnabled(n),c={...c,enabledRunnerIds:s},a.mode==="main"?a={mode:"main",shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:S.runners.getDefault(n)})}:a={...a,shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:S.runners.getDefault(n)})}}async function qa(f){let p=f.selectedTaskId;p&&await Oe(async()=>{let m=await pe(r,p);!m.ptyTabs.some(h=>h.id===f.activeTab)||m.selectedPtyTabId===f.activeTab||await A(r,{...m,selectedPtyTabId:f.activeTab})})}async function de(){let f=(a.mode==="main",a.shell);c=await Lt(t,f,s),a.mode==="main"?a={mode:"main",shell:P(a.shell)}:a={...a,shell:P(a.shell)}}async function ys(f){let p=++xr,m=Fa(c.tasks,f),h=c.inspection,k;if(m&&h?.taskId===m.id){let C={selectedFilePath:f.selectedFilePath,selectedDiffPath:f.selectedDiffPath},F=await ri(m,h,C);if(p!==xr)return;k={...c,inspection:F}}else if(k=await Lt(t,f,s),p!==xr)return;c=k,a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},R(a.shell),y())}async function Er(f){let p=await am(f);a.mode==="main"&&(a={mode:"main",shell:P({...a.shell,workspaceBrowser:p,activeTab:a.shell.selectedPtyTabId??a.shell.activeTab,actionMessage:null})},y())}async function Ps(f){try{let p=P(f),m=Ye(p),h=p.selectedPtyTabId;if(m&&p.focusedRegion==="tasks"){let F=m.ptyTabs.find(fe=>fe.kind==="agent")??null;F?h=F.id:(m=await bs(m),await de(),h=m.selectedPtyTabId)}m&&!h&&(m=await bs(m),await de(),h=m.selectedPtyTabId);let k=P({...p,activeTab:h??p.activeTab,selectedPtyTabId:h,focusedRegion:h?"center":p.focusedRegion});if(!k.selectedTaskId||!h){a={mode:"main",shell:k},y();return}a={mode:"main",shell:Ge({...k,inputMode:"terminal"},_.getViewState(h))},R(a.shell);let C=await _.ensureSession(k.selectedTaskId,h,Mt(je(T.width,T.height)));U=gs(h),le=null,a={mode:"main",shell:Ge({...k,inputMode:"terminal"},C)},R(a.shell)}catch(p){let m=K("attach PTY",p,"Failed to start PTY.");f.selectedTaskId&&f.selectedPtyTabId&&gs(f.selectedPtyTabId)&&(await Ka(f.selectedTaskId,m).catch(()=>{}),await de().catch(()=>{})),a={mode:"main",shell:V($i(P(f),m),m)},R(a.shell)}y()}async function Ka(f,p){await Oe(async()=>{await D.markRunnerFailed(r,f,p)})}async function Va(f,p,m){let h=P(f);if(!h.selectedTaskId)throw new Error("Select a task before creating a tab.");let k=await Oe(async()=>{let C=await pe(r,h.selectedTaskId),F=p??Jf(C,h.activeTab,h.preferredPtyTabKind),fe=Ma(C,F,m??void 0,n),ut={...C,ptyTabs:[...C.ptyTabs,fe],selectedPtyTabId:fe.id};return await A(r,ut),ut});return await de(),P({...h,activeTab:k.selectedPtyTabId??h.activeTab,selectedPtyTabId:k.selectedPtyTabId,preferredPtyTabKind:k.ptyTabs.at(-1)?.kind??h.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${k.ptyTabs.at(-1)?.title??"tab"}`})}async function Ga(f){let p=P(f);if(!p.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:m,nextSelectedTab:h}=await Oe(async()=>{let k=await pe(r,p.selectedTaskId),C=k.ptyTabs.findIndex($r=>$r.id===p.activeTab);if(C===-1)throw new Error("Only PTY tabs can be closed.");let F=k.ptyTabs[C],fe=k.ptyTabs.filter($r=>$r.id!==F.id),ut=fe[Math.min(C,fe.length-1)]??fe[C-1]??null;return await A(r,{...k,ptyTabs:fe,selectedPtyTabId:ut?.id??null}),{closedTab:F,nextSelectedTab:ut}});return _.disposeSession(m.id),await de(),P({...p,activeTab:h?.id??(p.openInspectionKind?"inspection":p.activeTab),selectedPtyTabId:h?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${m.title}`})}async function Ha(f){let p=P(f);if(!p.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let m=Ye(p),h=null,k=null;if(m?.type==="project"&&m.repoTargets?.length){let C=await D.prs.discoverOrRefreshAll(r,p.selectedTaskId);await de();let F=C.synced+C.discovered+C.notFound;k=`Refreshed ${C.synced}/${F} targets`}else{let{disposition:C,task:F}=await D.prs.discoverOrRefresh(r,p.selectedTaskId);await de(),h=C==="not_found"?`No PR found for ${F.branch}`:null,C!=="not_found"&&(k=`Refreshed checks: ${O(F)?.requiredChecks.length??0} reported`)}return P({...Ba(p,k),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:h})}async function za(){if(Sr||a.mode!=="main")return;let f=c.tasks;Sr=!0;try{if(await D.prs.discoverOrRefreshMany(r,f),Ir=null,a.mode!=="main")return;c=await Lt(t,a.shell,s),a={mode:"main",shell:P(a.shell)},y()}catch(p){let m=p instanceof Error?p.message:"Background PR discovery failed.";m!==Ir&&(Ir=m,er.appendErrorLogBestEffort(r,{context:"background PR polling",message:m,details:p instanceof Error?p.stack??p.message:String(p)}))}finally{Sr=!1}}async function Ya(f){let p=P(f);if(!p.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:m,task:h}=await Oe(async()=>{let k=await pe(r,p.selectedTaskId),C=await D.closeTask(r,p.selectedTaskId);return{taskBeforeClose:k,task:C}});for(let k of m.ptyTabs)_.disposeSession(k.id);return await de(),P({...p,selectedActionId:"close-task",actionMessage:h.cleanup.preservedWorktree?`Archived task ${h.id}; worktree preserved`:`Archived task ${h.id}`})}async function Qa(f){let p=P(f);if(!p.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await D.listTasks(r,{workspaceId:p.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${p.selectedWorkspaceId} while task records still reference it.`);await re.archiveWorkspace(r,p.selectedWorkspaceId);let h=await re.removeWorkspace(r,p.selectedWorkspaceId,{listTasks:D.listTasks});return await de(),P({...p,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${h.workspaceId}`})}async function bs(f){let p=f.ptyTabs.find(k=>k.kind==="agent")??null;if(p){let k={...f,selectedPtyTabId:p.id};return await Oe(async()=>{let C=await pe(r,f.id),F=C.ptyTabs.find(fe=>fe.kind==="agent")??null;F&&await A(r,{...C,selectedPtyTabId:F.id})}),k}let m=Ma(f,"agent",void 0,n),h={...f,ptyTabs:[...f.ptyTabs,m],selectedPtyTabId:m.id};return await Oe(async()=>{let k=await pe(r,f.id),C=k.ptyTabs.find(F=>F.kind==="agent")??null;if(C){await A(r,{...k,selectedPtyTabId:C.id});return}await A(r,{...k,ptyTabs:[...k.ptyTabs,m],selectedPtyTabId:m.id})}),h}y=()=>{Ja();let f=je(T.width,T.height),p=a.mode==="main"?Sa(f,Ki(P(a.shell),c),{centerOnly:a.shell.centerZoomed,focusFlashActive:ve!==null&&Date.now()<ve}):a.variant==="boot"?Ta(f,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:hs,updateText:Cr}):a.variant==="pause"?ya(f,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:hs,updateText:Cr}):a.variant==="options"?cs(f,{menuIndex:a.menuIndex,optionsMenuItems:ps}):a.variant==="runners"?cs(f,{menuIndex:jt(a).menuIndex,optionsMenuItems:fs(n,jt(a)),optionsMessage:$a(jt(a)),optionsSubtitle:"Runners"}):a.variant==="error-log"?ba(f,{errorLogPath:a.errorLog?.path??r.errorLogFile,errorLogLines:a.errorLog?.lines??[]}):Pa(f);Q&&(T.moveTo(1,1),T.eraseDisplayBelow(),Q=!1),T.noFormat(em(p)),T.hideCursor(!0)};function Ja(){let f=a.mode==="main"&&a.shell.inputMode==="terminal"?"terminal":"control";f!==vr&&(vr=f,T.grabInput(f==="terminal"?{mouse:"button"}:!0))}let Xa=()=>{process.stdout.off("resize",vs),process.off("SIGCONT",Es),T.removeListener("key",Ss),T.removeListener("unknown",Is),T.removeListener("mouse",Cs),Ce&&(clearTimeout(Ce),Ce=null),oe&&(clearTimeout(oe),oe=null),xe&&(clearTimeout(xe),xe=null),he&&(clearTimeout(he),he=null),ce&&(clearTimeout(ce),ce=null),ze&&(clearInterval(ze),ze=null),_.disposeAll(),T.grabInput(!1),T.hideCursor(!1),T.fullscreen(!1)},Ar=f=>{Xa(),I(f)},Za=async()=>{if(a.mode!=="main"||z)return;let f=a.shell,p=f.taskPromptInput?.trim()??"";if(!f.selectedRepoId&&!f.selectedWorkspaceId){a={mode:"main",shell:P({...f,taskPromptError:"Select a workspace first."})},y();return}if(p.length===0){a={mode:"main",shell:P({...f,taskPromptError:"Task prompt cannot be empty."})},y();return}z=!0,a={mode:"main",shell:P({...f,actionMessage:`Creating ${f.selectedRunner} task in ${f.selectedWorkspaceId??f.selectedRepoId}...`})},y();let m=null;try{m=await Xf(r,f.selectedRepoId,f.selectedWorkspaceId,p,f.selectedRunner),await de();let h=P({...a.shell,selectedRepoId:m.repoId,selectedWorkspaceId:m.workspaceId,selectedTaskId:m.id,selectedPtyTabId:m.selectedPtyTabId,selectedLeftItemId:`task:${m.id}`,activeTab:m.selectedPtyTabId??"agent",inputMode:"terminal",focusedRegion:"center",taskPromptInput:null,taskPromptError:null,actionMessage:null}),k=await _.ensureSession(m.id,h.selectedPtyTabId??Zf(m,"agent"),Mt(je(T.width,T.height)));U=gs(h.selectedPtyTabId),a={mode:"main",shell:Ge(h,k)},R(a.shell)}catch(h){h instanceof Pr&&(m=h.task);let k=K("create task",h,"Failed to create task.");m&&(await A(r,{...m,status:"draft",runnerSession:{...m.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:k}).catch(()=>{}),await de().catch(()=>{})),a={mode:"main",shell:V(P({...a.shell,inputMode:"control",selectedTaskId:m?.id??a.shell.selectedTaskId,selectedPtyTabId:m?.selectedPtyTabId??a.shell.selectedPtyTabId,selectedLeftItemId:m?`task:${m.id}`:a.shell.selectedLeftItemId,activeTab:m?.selectedPtyTabId??a.shell.activeTab,taskPromptInput:m?null:"",taskPromptError:k,actionMessage:null}),k)}}finally{z=!1,y()}},el=f=>{if(a.mode!=="main")return;let p=a.shell;if(p.taskPromptInput!==null){if(f==="ESCAPE"){a={mode:"main",shell:P({...p,taskPromptInput:null,taskPromptError:null,actionMessage:null})},y();return}if(Ie(f)){Za();return}if(f==="BACKSPACE"){a={mode:"main",shell:P({...p,taskPromptInput:p.taskPromptInput.slice(0,-1),taskPromptError:null})},y();return}if(f==="CTRL_R"){a={mode:"main",shell:P({...p,selectedRunner:Vn(p.selectedRunner,s),taskPromptError:null})},y();return}Li(f)&&(a={mode:"main",shell:P({...p,taskPromptInput:`${p.taskPromptInput}${f}`,taskPromptError:null})},y())}},tl=f=>{if(a.mode!=="main")return;let p=a.shell.workspaceBrowser;if(p){if(f==="ESCAPE"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,actionMessage:null})},y();return}if(f==="UP"||f==="k"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...p,selectedIndex:Math.max(0,p.selectedIndex-1),error:null}})},y();return}if(f==="DOWN"||f==="j"){let m=Math.max(0,p.entries.length-1);a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...p,selectedIndex:Math.min(m,p.selectedIndex+1),error:null}})},y();return}if(f==="LEFT"||f==="h"){Er(ct.dirname(p.cwd)).catch(m=>{let h=K("open parent workspace directory",m,"Failed to open parent directory.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...p,error:h}}),h)},y()});return}if(f==="RIGHT"||f==="l"||Ie(f)){let m=p.entries[p.selectedIndex]??null;if(!m)return;if((f==="RIGHT"||f==="l")&&(m.kind==="directory"||m.kind==="repo")){Er(m.path).catch(h=>{let k=K("open workspace directory",h,"Failed to open directory.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...p,error:k}}),k)},y()});return}re.addWorkspace(r,m.path).then(async h=>{await de();let k=h.repos[0]??null;a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${h.workspace.id}`,selectedWorkspaceId:h.workspace.id,selectedRepoId:k?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${h.workspace.name??h.workspace.id}`})},R(a.shell),y()}).catch(h=>{let k=K("add workspace",h,"Failed to add workspace.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...p,error:k}}),k)},y()})}}},Ss=f=>{let p=typeof f=="string"?f:"";if(a.mode==="main"&&a.shell.taskPromptInput!==null){el(p);return}if(a.mode==="main"&&a.shell.workspaceBrowser!==null){tl(p);return}if(a.mode==="main"&&a.shell.inputMode==="control"){if(p==="F"){ol(),y();return}ve!==null&&(ve=null,ce&&(clearTimeout(ce),ce=null))}if(a.mode==="main"){let m=Di(a.shell,p,Ts(a.shell));if(m.exit){Ar(0);return}if(m.detachTerminal){_.detach(),a={mode:"main",shell:P(m.state)},R(a.shell),y();return}if(a.shell.inputMode==="terminal"){if(m.changed){a={mode:"main",shell:P(m.state)},R(a.shell),y();return}if(U&&Ie(p)){U=!1;return}U&&(U=!1),le=rm(p)?{key:p,at:Date.now()}:null;let h=nm(p,a.shell.terminal.scrolledBack??!1);if(h!==0){Dr(h);return}_.writeKey(p);return}if(p==="CTRL_C"){Ar(0);return}if(p==="?"&&a.shell.inputMode==="control"){a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell},Q=!0,y();return}if(m.pause){a={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:P(m.state)},Q=!0,y();return}if(m.beginTaskPrompt){a={mode:"main",shell:P(m.state)},R(a.shell),y();return}if(m.openWorkspaceBrowser){Er(t).catch(h=>{let k=K("browse workspaces",h,"Failed to browse workspaces.");a={mode:"main",shell:V(P({...m.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:k}}),k)},y()});return}if(m.createPtyTab){Va(m.state,m.createPtyTabKind,m.createPtyTabRunner).then(h=>{Ps(h)}).catch(h=>{let k=K("create PTY tab",h,"Failed to create tab.");a={mode:"main",shell:V(P({...m.state,actionMessage:k}),k)},y()});return}if(m.closePtyTab){Ga(m.state).then(h=>{a={mode:"main",shell:h},R(a.shell),y()}).catch(h=>{let k=K("close PTY tab",h,"Failed to close tab.");a={mode:"main",shell:V(P({...m.state,actionMessage:k}),k)},y()});return}if(m.refreshPullRequestChecks){Ha(m.state).then(h=>{a={mode:"main",shell:h},R(a.shell),y()}).catch(h=>{let k=K("refresh PR checks",h,"Failed to refresh PR checks.");a={mode:"main",shell:V(P({...m.state,actionMessage:k}),k)},y()});return}if(m.openPrUrl){let h=Ye(m.state),k=h?O(h)?.url??null:null;k?lm(k).catch(C=>{let F=K("open PR URL",C,"Failed to open PR in browser.");a={mode:"main",shell:V(P(m.state),F)},y()}):(a={mode:"main",shell:V(P(m.state),"No PR URL available.")},y());return}if(m.closeTask){Ya(m.state).then(h=>{a={mode:"main",shell:h},R(a.shell),y()}).catch(h=>{let k=K("close task",h,"Failed to close task.");a={mode:"main",shell:V(P({...m.state,actionMessage:k}),k)},y()});return}if(m.removeWorkspace){Qa(m.state).then(h=>{a={mode:"main",shell:h},R(a.shell),y()}).catch(h=>{let k=K("remove workspace",h,"Failed to remove workspace.");a={mode:"main",shell:V(P({...m.state,actionMessage:k}),k)},y()});return}if(m.attachTerminal){Ps(m.state);return}if(m.refreshInspection){a={mode:"main",shell:P(m.state)},R(a.shell),y(),ys(a.shell).catch(h=>{let k=K("refresh inspection",h,"Failed to refresh inspection.");a={mode:"main",shell:V(P({...a.shell,actionMessage:k}),k)},y()});return}m.changed&&(a={mode:"main",shell:P(m.state)},qa(a.shell).catch(()=>{}),R(a.shell),y());return}if(a.variant==="help"){a.viaOptions&&a.parentVariant?a={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:a.shell,parentVariant:a.parentVariant}:a.parentVariant?a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell}:a={mode:"main",shell:P(a.shell)},Q=!0,y();return}if(a.variant==="options"){rl(p);return}if(a.variant==="runners"){sl(p);return}if(a.variant==="error-log"){if(p==="ESCAPE"||Ie(p)){let m=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:a.shell,...m!==void 0?{parentVariant:m}:{}},Q=!0,y()}return}if(a.optionsMessage){(p==="ESCAPE"||Ie(p))&&(a={...a,optionsMessage:null},y());return}if(p==="UP"||p==="k"){a={...a,menuIndex:Math.max(0,a.menuIndex-1)},y();return}if(p==="DOWN"||p==="j"){a={...a,menuIndex:Math.min(2,a.menuIndex+1)},y();return}if(p==="ESCAPE"){a.variant==="pause"&&(a={mode:"main",shell:P(a.shell)},Q=!0,y());return}if(Ie(p)){if(a.menuIndex===0){let m=a.variant==="boot";a={mode:"main",shell:P({...a.shell,inputMode:"control"})},Q=!0,y(),m?ll.then(()=>{if(a.mode!=="main")return;let h=a.shell;_a(h).then(k=>{a.mode!=="main"||a.shell!==h||(a={mode:"main",shell:k},R(a.shell),y())}).catch(k=>{if(a.mode!=="main"||a.shell!==h)return;let C=K("warm selected PTY",k,"Failed to start selected PTY.");a={mode:"main",shell:V(P(a.shell),C)},R(a.shell),y()})}):Wa();return}if(a.menuIndex===1){let m=a.variant==="boot"||a.variant==="pause"?a.variant:void 0;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...m!==void 0?{parentVariant:m}:{}},Q=!0,y();return}Ar(0)}};function rl(f){if(a.mode!=="overlay"||a.variant!=="options")return;let p=La(a.menuIndex,f);if(p.kind!=="noop"){if(p.kind==="render"){a={...a,menuIndex:p.menuIndex},y();return}if(p.kind==="back"){a.parentVariant&&(a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell},Q=!0,y());return}if(p.kind==="help"){let m=a.parentVariant;a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell,viaOptions:!0,...m!==void 0?{parentVariant:m}:{}},Q=!0,y();return}if(p.kind==="runners"){let m=a.parentVariant;a={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:a.shell,...m!==void 0?{parentVariant:m}:{}},Q=!0,y();return}if(p.kind==="error-log"){let m=a.parentVariant;nl(m)}}}async function nl(f){let p;try{p=await er.readRecentErrorLines(r)}catch(m){let h=K("open error log",m,"Failed to read Craig error log.");p={path:r.errorLogFile,lines:[`Unable to read error log: ${h}`],empty:!1}}a.mode==="overlay"&&(a={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:a.shell,errorLog:p,...f!==void 0?{parentVariant:f}:{}},Q=!0,y())}function sl(f){if(a.mode!=="overlay"||a.variant!=="runners")return;let p=ja(jt(a),n,f,s);if(p.kind!=="noop"){if(p.kind==="back"){let m=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...m!==void 0?{parentVariant:m}:{}},Q=!0,y();return}if(p.kind==="render"){a={...a,runnerOptions:p.state},y();return}Ua(p.config).then(()=>{a.mode!=="overlay"||a.variant!=="runners"||(a={...a,runnerOptions:p.state},y())}).catch(m=>{if(a.mode!=="overlay"||a.variant!=="runners")return;let h=K("save runner option",m,"Failed to save runner option."),k=V(P(a.shell),h);a={...a,shell:k,runnerOptions:{...jt(a),message:h}},y()})}}function ol(){ve=Date.now()+600,ce&&clearTimeout(ce),ce=setTimeout(()=>{ve=null,ce=null,y()},600)}let Is=f=>{let p=tm(f);if(a.mode!=="main"||a.shell.inputMode!=="terminal"||p.length===0)return;if(p.includes("")){_.detach(),U=!1,le=null,a={mode:"main",shell:P({...a.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},R(a.shell),y();return}let m=sm(p);if(m!==0){Dr(m);return}let h=om(p);if(h){U=!1,le={key:h,at:Date.now()},_.writeKey(h);return}if(U&&p!=="\r"&&p!==`
159
+ `&&p!==`\r
160
+ `&&(U=!1),im(U,le,p)){U=!1;return}_.write(p)},Cs=f=>{if(a.mode!=="main")return;if(a.shell.inputMode==="control"){al(Oa(f));return}let p=Oa(f);p!==0&&Dr(p)};function Dr(f){x+=f,!Ce&&(Ce=setTimeout(()=>{Ce=null;let p=x;x=0,p!==0&&(il(p),y())},16))}function il(f){_.scrollViewport(f),a={mode:"main",shell:dt(a.shell)}}function xs(){Q=!0,T.fullscreen(!0)}function al(f){f!==0&&(Me+=f,!oe&&(oe=setTimeout(()=>{oe=null;let p=Me;if(Me=0,p===0||a.mode!=="main"||a.shell.inputMode!=="control")return;let m=Le(a.shell,p,Ts(a.shell));if(m.changed){if(m.refreshInspection){a={mode:"main",shell:P(m.state)},R(a.shell),y(),ys(a.shell).catch(h=>{let k=K("refresh inspection",h,"Failed to refresh inspection.");a={mode:"main",shell:V(P({...a.shell,actionMessage:k}),k)},y()});return}a={mode:"main",shell:P(m.state)},R(a.shell),y()}},16)))}let vs=()=>{xs(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(_.resize(Mt(je(T.width,T.height))),a={mode:"main",shell:dt(a.shell)}),y()},Es=()=>{xs(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(_.resize(Mt(je(T.width,T.height))),a={mode:"main",shell:dt(a.shell)}),y()};process.stdout.on("resize",vs),process.on("SIGCONT",Es),T.grabInput(!0),vr="control",T.hideCursor(!0),T.fullscreen(!0),T.on("key",Ss),T.on("unknown",Is),T.on("mouse",Cs),ze=setInterval(()=>{za()},(n.github?.watchIntervalSeconds??5)*1e3),S.version.checkForUpdate().then(f=>{f.updateAvailable&&f.latest&&(Cr=`Update available: v${f.latest}`,y())});let ll=ws().catch(()=>{});y()})}async function Lt(e,t,r){let n=Pe(e),[s,o,i]=await Promise.all([re.repos.listRegisteredRepos(n).then(u=>u.repos),ie(n),D.listTasks(n)]),l=Fa(i.tasks,t),c=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},d=l?await ni(l,c):null;return{workspaceRoot:e,workspaces:o.filter(u=>u.status==="active"),repos:s,tasks:i.tasks,inspection:d,...r?{enabledRunnerIds:r}:{}}}function Fa(e,t){return t?.selectedTaskId?e.find(r=>r.id===t.selectedTaskId)??null:null}function Vf(e,t){return ar(e,t)}function Gf(e,t){let r=new Set(t);return e.filter(n=>{let s=n.path.split("/");for(let o=1;o<s.length;o+=1)if(r.has(s.slice(0,o).join("/")))return!1;return!0})}function Hf(e){let t=[];if(e.workspaces?.length)for(let r of e.workspaces){t.push(`workspace:${r.id}`);for(let n of e.tasks.filter(s=>s.workspaceId===r.id))t.push(`task:${n.id}`);r.kind==="project"&&t.push(`new-task-workspace:${r.id}`),r.kind==="repo"&&t.push(`new-task:${r.primaryRepoId}`)}else for(let r of e.repos){t.push(`repo:${r.id}`);for(let n of e.tasks.filter(s=>s.repoId===r.id))t.push(`task:${n.id}`);t.push(`new-task:${r.id}`)}return t.push("new-workspace"),t}function zf(e,t,r){let n=e.tasks.find(l=>l.ptyTabs.some(c=>c.id===t))??null,s=n?.ptyTabs.find(l=>l.id===t)??null,o=n?.worktreePath??r,i=s?.kind==="agent"?Qf(s):[];return n?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:Yf(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function Yf(e,t){let r=(e??"").split(ct.delimiter).filter(n=>n.length>0);return r.includes(t)?r.join(ct.delimiter):[...r,t].join(ct.delimiter)}function Qf(e){return e.command.length>0?e.command:["codex"]}function jt(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function Jf(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function Ma(e,t,r,n={}){let s=r??e.runner,o=S.runners.getProfile(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",l=t==="agent"&&r&&r!==e.runner?`${e.id}:${r}`:`${e.id}:${t}`,c=new Set(e.ptyTabs.map(R=>R.id)),d=1,u=l;for(;c.has(u);)d+=1,u=`${l}-${d}`;let g=new Date().toISOString(),w=r&&r!==e.runner?r:void 0;return{id:u,kind:t,...w?{runner:w}:{},title:d===1?i:`${i} ${d}`,command:t==="agent"?S.runners.buildCommand(s,void 0,n):[],createdAt:g,updatedAt:g}}async function Xf(e,t,r,n,s){let o=await S.load(e);S.runners.assertEnabled(s,o);let i=r?await D.provisionProjectTask(e,r,n,{runner:s,config:o}):await D.provisionTask(e,t??"",n,{runner:s,config:o});try{let c=Ue();await v(qe(S.runners.getConfiguredProfile(s,o).executable,{cwd:i.repoRoot,env:c}),["--help"],{cwd:i.repoRoot,env:c})}catch(c){let d=c instanceof Error?c.message:"Failed to start runner.",u=await D.recordStartupFailure(e,i.task.id,d);throw new Pr(d,u)}let l=await D.markTaskStarted(e,i.task.id);return await Y({uiStateFile:e.uiStateFile},{...await J({uiStateFile:e.uiStateFile})??we(),version:1,selectedRepoId:l.repoId,selectedWorkspaceId:l.workspaceId,selectedTaskId:l.id,selectedPtyTabId:l.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:l.selectedPtyTabId??"agent",selectedActionId:"commit",updatedAt:new Date().toISOString()}),l}var Pr=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}};function Zf(e,t){let r=e.ptyTabs.find(n=>n.kind===t);if(!r)throw new Error(`Task ${e.id} is missing its ${t} PTY tab.`);return r.id}function Mt(e){return{columns:Math.max(20,e.width-ge.leftWidth-ge.rightWidth-ge.dividerWidth-wr*2),rows:Math.max(5,e.height-ge.topRailHeight-5)}}function em(e){return e.split(`
161
+ `).map((t,r)=>`\x1B[${r+1};1H${t}`).join("")}function tm(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function rm(e){return e.length===1||Ie(e)||e==="BACKSPACE"||e==="TAB"}function gs(e){return typeof e=="string"&&new RegExp(`:(?:agent|${N.join("|")})(?:-\\d+)?$`).test(e)}function nm(e,t){return e==="UP"&&t?-3:e==="DOWN"&&t?3:e==="PAGE_UP"?-5:e==="PAGE_DOWN"?5:e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function Oa(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function sm(e){let t=new RegExp("\x1B\\[<(\\d+);\\d+;\\d+[mM]").exec(e);if(!t?.[1])return 0;let r=Number.parseInt(t[1],10);return r===64?-3:r===65?3:0}function om(e){return e==="\x1B[13;2u"?"SHIFT_ENTER":null}function im(e,t,r){return r.length===0?!1:e&&(r==="\r"||r===`
162
+ `||r===`\r
163
+ `)?!0:!t||Date.now()-t.at>=30?!1:r===t.key?!0:r.length<=4&&r.split("").every(n=>n===t.key)}async function am(e){let t=await _f(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=ct.join(e,n.name);r.push({name:n.name,path:s,kind:await cm(s)?"repo":"directory"})}return r.sort((n,s)=>n.kind!==s.kind?n.kind==="repo"?-1:1:n.name.localeCompare(s.name)),{cwd:e,entries:r,selectedIndex:0,error:null}}async function lm(e){let{spawn:t}=await import("node:child_process"),r=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";await new Promise((n,s)=>{let o=t(r,[e],{stdio:"ignore",detached:!0});o.unref(),o.on("error",s),o.on("spawn",n)})}async function cm(e){let t=ct.join(e,".git");return await Bf(t).catch(()=>null)!==null}function br(){return process.cwd()}async function dm(){try{if(process.argv[2]==="__craig-daemon"){let i=process.argv[3]??br(),l=Pe(i);return await ua(l),0}if(process.argv[2]==="__craig-daemon-shutdown"){let i=process.argv[3]??br(),l=Pe(i);return await pa(l),0}let e=Ws(process.argv.slice(2)),t=br(),r=Pe(t),n={paths:r};if(e.mode==="interactive")return await Na({uiStateFile:r.uiStateFile,workspaceRoot:r.workspaceRoot});if(!e.command)throw new Error("Command mode requires a command.");let s=await Qo(e.command,n),o=Jo(s);return o.length>0&&process.stdout.write(`${o}
164
164
  `),0}catch(e){let t=e instanceof Error?e.message:"Unknown Craig error";return process.stderr.write(`${t}
165
- `),1}}var Nf=await Ff();process.exit(Nf);
165
+ `),1}}var um=await dm();process.exit(um);